From: Ian Lance Taylor Date: Thu, 2 Jan 2020 23:05:27 +0000 (-0800) Subject: libgo: update to Go1.14beta1 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5a8ea165926cb0737ab03bc48c18dc5198ab5305;p=gcc.git libgo: update to Go1.14beta1 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/214297 --- diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index a6127013783..dff5fb5bc70 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -a69ad9c7d1b45edcf8062a07d3a3c9b6838c04f8 +c2225a76d1e15f28056596807ebbbc526d4c58da The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gotools/ChangeLog b/gotools/ChangeLog index b0e612daae4..b6d34315562 100644 --- a/gotools/ChangeLog +++ b/gotools/ChangeLog @@ -1,3 +1,9 @@ +2020-01-21 Ian Lance Taylor + + * Makefile.am (gofmt$(EXEEXT)): Link against $(LIBGOTOOL). + (check-go-tool): Copy some vendor directories. + * Makefile.in: Regenerate. + 2019-09-06 Ian Lance Taylor * Makefile.am (check-carchive-test): Just run "go test", not "go diff --git a/gotools/Makefile.am b/gotools/Makefile.am index d36b61ca88e..47adf9bafeb 100644 --- a/gotools/Makefile.am +++ b/gotools/Makefile.am @@ -116,7 +116,7 @@ man_MANS = go.1 gofmt.1 go$(EXEEXT): $(go_cmd_go_files) $(LIBGOTOOL) $(LIBGODEP) $(GOLINK) $(go_cmd_go_files) $(LIBGOTOOL) $(LIBS) $(NET_LIBS) gofmt$(EXEEXT): $(go_cmd_gofmt_files) $(LIBGODEP) - $(GOLINK) $(go_cmd_gofmt_files) $(LIBS) $(NET_LIBS) + $(GOLINK) $(go_cmd_gofmt_files) $(LIBGOTOOL) $(LIBS) $(NET_LIBS) cgo$(EXEEXT): $(go_cmd_cgo_files) zdefaultcc.go $(LIBGOTOOL) $(LIBGODEP) $(GOLINK) $(go_cmd_cgo_files) zdefaultcc.go $(LIBGOTOOL) $(LIBS) $(NET_LIBS) vet$(EXEEXT): $(go_cmd_vet_files) $(LIBGOTOOL) $(LIBGODEP) @@ -215,6 +215,10 @@ check-go-tool: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc cp $(libgodir)/zdefaultcc.go check-go-dir/src/cmd/go/internal/cfg/ cp -r $(cmdsrcdir)/go/testdata check-go-dir/src/cmd/go/ cp -r $(cmdsrcdir)/internal check-go-dir/src/cmd/ + $(MKDIR_P) check-go-dir/src/cmd/vendor/golang.org/x + cp -r $(libgosrcdir)/golang.org/x/mod check-go-dir/src/cmd/vendor/golang.org/x/ + cp -r $(libgosrcdir)/golang.org/x/crypto check-go-dir/src/cmd/vendor/golang.org/x/ + cp -r $(libgosrcdir)/golang.org/x/xerrors check-go-dir/src/cmd/vendor/golang.org/x/ cp $(libgodir)/objabi.go check-go-dir/src/cmd/internal/objabi/ @abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \ abs_checkdir=`cd check-go-dir && $(PWD_COMMAND)`; \ diff --git a/gotools/Makefile.in b/gotools/Makefile.in index b36dbfbde1b..930189a55eb 100644 --- a/gotools/Makefile.in +++ b/gotools/Makefile.in @@ -820,7 +820,7 @@ mostlyclean-local: @NATIVE_TRUE@go$(EXEEXT): $(go_cmd_go_files) $(LIBGOTOOL) $(LIBGODEP) @NATIVE_TRUE@ $(GOLINK) $(go_cmd_go_files) $(LIBGOTOOL) $(LIBS) $(NET_LIBS) @NATIVE_TRUE@gofmt$(EXEEXT): $(go_cmd_gofmt_files) $(LIBGODEP) -@NATIVE_TRUE@ $(GOLINK) $(go_cmd_gofmt_files) $(LIBS) $(NET_LIBS) +@NATIVE_TRUE@ $(GOLINK) $(go_cmd_gofmt_files) $(LIBGOTOOL) $(LIBS) $(NET_LIBS) @NATIVE_TRUE@cgo$(EXEEXT): $(go_cmd_cgo_files) zdefaultcc.go $(LIBGOTOOL) $(LIBGODEP) @NATIVE_TRUE@ $(GOLINK) $(go_cmd_cgo_files) zdefaultcc.go $(LIBGOTOOL) $(LIBS) $(NET_LIBS) @NATIVE_TRUE@vet$(EXEEXT): $(go_cmd_vet_files) $(LIBGOTOOL) $(LIBGODEP) @@ -886,6 +886,10 @@ mostlyclean-local: @NATIVE_TRUE@ cp $(libgodir)/zdefaultcc.go check-go-dir/src/cmd/go/internal/cfg/ @NATIVE_TRUE@ cp -r $(cmdsrcdir)/go/testdata check-go-dir/src/cmd/go/ @NATIVE_TRUE@ cp -r $(cmdsrcdir)/internal check-go-dir/src/cmd/ +@NATIVE_TRUE@ $(MKDIR_P) check-go-dir/src/cmd/vendor/golang.org/x +@NATIVE_TRUE@ cp -r $(libgosrcdir)/golang.org/x/mod check-go-dir/src/cmd/vendor/golang.org/x/ +@NATIVE_TRUE@ cp -r $(libgosrcdir)/golang.org/x/crypto check-go-dir/src/cmd/vendor/golang.org/x/ +@NATIVE_TRUE@ cp -r $(libgosrcdir)/golang.org/x/xerrors check-go-dir/src/cmd/vendor/golang.org/x/ @NATIVE_TRUE@ cp $(libgodir)/objabi.go check-go-dir/src/cmd/internal/objabi/ @NATIVE_TRUE@ @abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \ @NATIVE_TRUE@ abs_checkdir=`cd check-go-dir && $(PWD_COMMAND)`; \ diff --git a/libgo/MERGE b/libgo/MERGE index 0be22963bb8..9c5763972c1 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -cc8838d645b2b7026c1f3aaceb011775c5ca3a08 +a5bfd9da1d1b24f326399b6b75558ded14514f23 The first line of this file holds the git revision number of the last merge done from the master library sources. diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 4b2dd58d40a..56d38f57e7d 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -262,7 +262,8 @@ toolexeclibgohash_DATA = \ hash/adler32.gox \ hash/crc32.gox \ hash/crc64.gox \ - hash/fnv.gox + hash/fnv.gox \ + hash/maphash.gox toolexeclibgohtmldir = $(toolexeclibgodir)/html @@ -402,6 +403,7 @@ toolexeclibgounicode_DATA = \ noinst_DATA = \ golang.org/x/net/nettest.gox \ internal/cfg.gox \ + internal/obscuretestdata.gox \ internal/testenv.gox \ internal/trace.gox \ net/internal/socktest.gox \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 72c6f9c8886..88c687464fc 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -743,7 +743,8 @@ toolexeclibgohash_DATA = \ hash/adler32.gox \ hash/crc32.gox \ hash/crc64.gox \ - hash/fnv.gox + hash/fnv.gox \ + hash/maphash.gox toolexeclibgohtmldir = $(toolexeclibgodir)/html toolexeclibgohtml_DATA = \ @@ -861,9 +862,10 @@ toolexeclibgounicode_DATA = \ # internal packages nothing will explicitly depend on them. # Force them to be built. noinst_DATA = golang.org/x/net/nettest.gox internal/cfg.gox \ - internal/testenv.gox internal/trace.gox \ - net/internal/socktest.gox os/signal/internal/pty.gox \ - runtime/pprof/internal/profile.gox zdefaultcc.go + internal/obscuretestdata.gox internal/testenv.gox \ + internal/trace.gox net/internal/socktest.gox \ + os/signal/internal/pty.gox runtime/pprof/internal/profile.gox \ + zdefaultcc.go @LIBGO_IS_RTEMS_FALSE@rtems_task_variable_add_file = @LIBGO_IS_RTEMS_TRUE@rtems_task_variable_add_file = runtime/rtems-task-variable-add.c runtime_context_asm_file = $(am__append_3) diff --git a/libgo/VERSION b/libgo/VERSION index e0f726521a4..da5318592de 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.13 +go1.14beta1 diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt index 156a2bd4593..48c4dfdbc91 100644 --- a/libgo/check-packages.txt +++ b/libgo/check-packages.txt @@ -3,7 +3,6 @@ archive/zip bufio bytes cmd/go/internal/cache -cmd/go/internal/dirhash cmd/go/internal/generate cmd/go/internal/get cmd/go/internal/imports @@ -13,13 +12,10 @@ cmd/go/internal/lockedfile/internal/filelock cmd/go/internal/modconv cmd/go/internal/modfetch cmd/go/internal/modfetch/codehost -cmd/go/internal/modfile cmd/go/internal/modload -cmd/go/internal/module cmd/go/internal/mvs cmd/go/internal/par cmd/go/internal/search -cmd/go/internal/semver cmd/go/internal/txtar cmd/go/internal/work cmd/internal/buildid @@ -96,6 +92,7 @@ hash/adler32 hash/crc32 hash/crc64 hash/fnv +hash/maphash html html/template image @@ -163,6 +160,8 @@ strings sync sync/atomic syscall +testing +testing/iotest testing/quick text/scanner text/tabwriter diff --git a/libgo/configure b/libgo/configure index 6a65a60e4a9..385ca9a65cd 100755 --- a/libgo/configure +++ b/libgo/configure @@ -2544,7 +2544,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" -libtool_VERSION=15:0:0 +libtool_VERSION=16:0:0 # Default to --enable-multilib diff --git a/libgo/configure.ac b/libgo/configure.ac index d4ee59ca685..07c03bcdf26 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -10,7 +10,7 @@ AC_INIT(package-unused, version-unused,, libgo) AC_CONFIG_SRCDIR(Makefile.am) AC_CONFIG_HEADER(config.h) -libtool_VERSION=15:0:0 +libtool_VERSION=16:0:0 AC_SUBST(libtool_VERSION) AM_ENABLE_MULTILIB(, ..) diff --git a/libgo/go/archive/tar/reader.go b/libgo/go/archive/tar/reader.go index 39437185179..4f9135b7919 100644 --- a/libgo/go/archive/tar/reader.go +++ b/libgo/go/archive/tar/reader.go @@ -433,7 +433,7 @@ func (tr *Reader) readHeader() (*Header, *block, error) { // files generated by a pre-Go1.8 toolchain. If the generated file // happened to have a prefix field that parses as valid // atime and ctime fields (e.g., when they are valid octal strings), - // then it is impossible to distinguish between an valid GNU file + // then it is impossible to distinguish between a valid GNU file // and an invalid pre-Go1.8 file. // // See https://golang.org/issues/12594 diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go index 2260b398c34..13ff9ddcf42 100644 --- a/libgo/go/archive/zip/reader.go +++ b/libgo/go/archive/zip/reader.go @@ -8,7 +8,6 @@ import ( "bufio" "encoding/binary" "errors" - "fmt" "hash" "hash/crc32" "io" @@ -84,9 +83,6 @@ func (z *Reader) init(r io.ReaderAt, size int64) error { if err != nil { return err } - if end.directoryRecords > uint64(size)/fileHeaderLen { - return fmt.Errorf("archive/zip: TOC declares impossible %d files in %d byte zip", end.directoryRecords, size) - } z.r = r z.File = make([]*File, 0, end.directoryRecords) z.Comment = end.comment diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go index 6b3f2f33bb4..adca87a8b38 100644 --- a/libgo/go/archive/zip/reader_test.go +++ b/libgo/go/archive/zip/reader_test.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/binary" "encoding/hex" + "internal/obscuretestdata" "io" "io/ioutil" "os" @@ -19,11 +20,12 @@ import ( ) type ZipTest struct { - Name string - Source func() (r io.ReaderAt, size int64) // if non-nil, used instead of testdata/ file - Comment string - File []ZipTestFile - Error error // the error that Opening this file should return + Name string + Source func() (r io.ReaderAt, size int64) // if non-nil, used instead of testdata/ file + Comment string + File []ZipTestFile + Obscured bool // needed for Apple notarization (golang.org/issue/34986) + Error error // the error that Opening this file should return } type ZipTestFile struct { @@ -189,8 +191,12 @@ var tests = []ZipTest{ }, { // created by Go, before we wrote the "optional" data - // descriptor signatures (which are required by OS X) - Name: "go-no-datadesc-sig.zip", + // descriptor signatures (which are required by macOS). + // Use obscured file to avoid Apple’s notarization service + // rejecting the toolchain due to an inability to unzip this archive. + // See golang.org/issue/34986 + Name: "go-no-datadesc-sig.zip.base64", + Obscured: true, File: []ZipTestFile{ { Name: "foo.txt", @@ -208,7 +214,7 @@ var tests = []ZipTest{ }, { // created by Go, after we wrote the "optional" data - // descriptor signatures (which are required by OS X) + // descriptor signatures (which are required by macOS) Name: "go-with-datadesc-sig.zip", File: []ZipTestFile{ { @@ -496,8 +502,18 @@ func readTestZip(t *testing.T, zt ZipTest) { rat, size := zt.Source() z, err = NewReader(rat, size) } else { + path := filepath.Join("testdata", zt.Name) + if zt.Obscured { + tf, err := obscuretestdata.DecodeToTempFile(path) + if err != nil { + t.Errorf("obscuretestdata.DecodeToTempFile(%s): %v", path, err) + return + } + defer os.Remove(tf) + path = tf + } var rc *ReadCloser - rc, err = OpenReader(filepath.Join("testdata", zt.Name)) + rc, err = OpenReader(path) if err == nil { defer rc.Close() z = &rc.Reader @@ -981,15 +997,17 @@ func TestIssue10957(t *testing.T) { } } -// Verify the number of files is sane. +// Verify that this particular malformed zip file is rejected. func TestIssue10956(t *testing.T) { data := []byte("PK\x06\x06PK\x06\a0000\x00\x00\x00\x00\x00\x00\x00\x00" + "0000PK\x05\x06000000000000" + "0000\v\x00000\x00\x00\x00\x00\x00\x00\x000") - _, err := NewReader(bytes.NewReader(data), int64(len(data))) - const want = "TOC declares impossible 3472328296227680304 files in 57 byte" - if err == nil && !strings.Contains(err.Error(), want) { - t.Errorf("error = %v; want %q", err, want) + r, err := NewReader(bytes.NewReader(data), int64(len(data))) + if err == nil { + t.Errorf("got nil error, want ErrFormat") + } + if r != nil { + t.Errorf("got non-nil Reader, want nil") } } diff --git a/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip b/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip deleted file mode 100644 index c3d593f44f9..00000000000 Binary files a/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip and /dev/null differ diff --git a/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip.base64 b/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip.base64 new file mode 100644 index 00000000000..1c2c071fbe0 --- /dev/null +++ b/libgo/go/archive/zip/testdata/go-no-datadesc-sig.zip.base64 @@ -0,0 +1 @@ +UEsDBBQACAAAAGWHaECoZTJ+BAAAAAQAAAAHABgAZm9vLnR4dFVUBQAD3lVZT3V4CwABBPUBAAAEFAAAAGZvbwqoZTJ+BAAAAAQAAABQSwMEFAAIAAAAZodoQOmzogQEAAAABAAAAAcAGABiYXIudHh0VVQFAAPgVVlPdXgLAAEE9QEAAAQUAAAAYmFyCumzogQEAAAABAAAAFBLAQIUAxQACAAAAGWHaECoZTJ+BAAAAAQAAAAHABgAAAAAAAAAAACkgQAAAABmb28udHh0VVQFAAPeVVlPdXgLAAEE9QEAAAQUAAAAUEsBAhQDFAAIAAAAZodoQOmzogQEAAAABAAAAAcAGAAAAAAAAAAAAKSBTQAAAGJhci50eHRVVAUAA+BVWU91eAsAAQT1AQAABBQAAABQSwUGAAAAAAIAAgCaAAAAmgAAAAAA diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go index 0f05d3b3221..f0810be3a44 100644 --- a/libgo/go/bufio/bufio.go +++ b/libgo/go/bufio/bufio.go @@ -432,6 +432,7 @@ func (b *Reader) ReadBytes(delim byte) ([]byte, error) { var frag []byte var full [][]byte var err error + n := 0 for { var e error frag, e = b.ReadSlice(delim) @@ -447,18 +448,15 @@ func (b *Reader) ReadBytes(delim byte) ([]byte, error) { buf := make([]byte, len(frag)) copy(buf, frag) full = append(full, buf) + n += len(buf) } - // Allocate new buffer to hold the full pieces and the fragment. - n := 0 - for i := range full { - n += len(full[i]) - } n += len(frag) - // Copy full pieces and fragment in. + // Allocate new buffer to hold the full pieces and the fragment. buf := make([]byte, n) n = 0 + // Copy full pieces and fragment in. for i := range full { n += copy(buf[n:], full[i]) } @@ -708,9 +706,14 @@ func (b *Writer) WriteString(s string) (int, error) { // supports the ReadFrom method, and b has no buffered data yet, // this calls the underlying ReadFrom without buffering. func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) { + if b.err != nil { + return 0, b.err + } if b.Buffered() == 0 { if w, ok := b.wr.(io.ReaderFrom); ok { - return w.ReadFrom(r) + n, err = w.ReadFrom(r) + b.err = err + return n, err } } var m int diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go index 782ca2149aa..9a9f102f151 100644 --- a/libgo/go/bufio/bufio_test.go +++ b/libgo/go/bufio/bufio_test.go @@ -1535,6 +1535,52 @@ func TestPartialReadEOF(t *testing.T) { } } +type writerWithReadFromError struct{} + +func (w writerWithReadFromError) ReadFrom(r io.Reader) (int64, error) { + return 0, errors.New("writerWithReadFromError error") +} + +func (w writerWithReadFromError) Write(b []byte) (n int, err error) { + return 10, nil +} + +func TestWriterReadFromMustSetUnderlyingError(t *testing.T) { + var wr = NewWriter(writerWithReadFromError{}) + if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil { + t.Fatal("expected ReadFrom returns error, got nil") + } + if _, err := wr.Write([]byte("123")); err == nil { + t.Fatal("expected Write returns error, got nil") + } +} + +type writeErrorOnlyWriter struct{} + +func (w writeErrorOnlyWriter) Write(p []byte) (n int, err error) { + return 0, errors.New("writeErrorOnlyWriter error") +} + +// Ensure that previous Write errors are immediately returned +// on any ReadFrom. See golang.org/issue/35194. +func TestWriterReadFromMustReturnUnderlyingError(t *testing.T) { + var wr = NewWriter(writeErrorOnlyWriter{}) + s := "test1" + wantBuffered := len(s) + if _, err := wr.WriteString(s); err != nil { + t.Fatalf("unexpected error: %v", err) + } + if err := wr.Flush(); err == nil { + t.Error("expected flush error, got nil") + } + if _, err := wr.ReadFrom(strings.NewReader("test2")); err == nil { + t.Fatal("expected error, got nil") + } + if buffered := wr.Buffered(); buffered != wantBuffered { + t.Fatalf("Buffered = %v; want %v", buffered, wantBuffered) + } +} + func BenchmarkReaderCopyOptimal(b *testing.B) { // Optimal case is where the underlying reader implements io.WriterTo srcBuf := bytes.NewBuffer(make([]byte, 8192)) diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go index eb132123849..e872cc20506 100644 --- a/libgo/go/bytes/bytes.go +++ b/libgo/go/bytes/bytes.go @@ -935,7 +935,8 @@ func ReplaceAll(s, old, new []byte) []byte { } // EqualFold reports whether s and t, interpreted as UTF-8 strings, -// are equal under Unicode case-folding. +// are equal under Unicode case-folding, which is a more general +// form of case-insensitivity. func EqualFold(s, t []byte) bool { for len(s) != 0 && len(t) != 0 { // Extract first rune from each. diff --git a/libgo/go/bytes/compare_test.go b/libgo/go/bytes/compare_test.go index a321f2e0861..a595d575d07 100644 --- a/libgo/go/bytes/compare_test.go +++ b/libgo/go/bytes/compare_test.go @@ -120,6 +120,39 @@ func TestCompareBytes(t *testing.T) { } } +func TestEndianBaseCompare(t *testing.T) { + // This test compares byte slices that are almost identical, except one + // difference that for some j, a[j]>b[j] and a[j+1] " + dtype.String() if checkCache { if t, ok := c.m[key]; ok { @@ -2258,7 +2265,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { // Translate to zero-length array instead. count = 0 } - sub := c.Type(dt.Type, pos) + sub := c.loadType(dt.Type, pos, key) t.Align = sub.Align t.Go = &ast.ArrayType{ Len: c.intExpr(count), @@ -2403,7 +2410,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { c.ptrs[key] = append(c.ptrs[key], t) case *dwarf.QualType: - t1 := c.Type(dt.Type, pos) + t1 := c.loadType(dt.Type, pos, key) t.Size = t1.Size t.Align = t1.Align t.Go = t1.Go @@ -2487,7 +2494,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { } name := c.Ident("_Ctype_" + dt.Name) goIdent[name.Name] = name - sub := c.Type(dt.Type, pos) + sub := c.loadType(dt.Type, pos, key) if c.badPointerTypedef(dt) { // Treat this typedef as a uintptr. s := *sub diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go index 97886e1abd0..4d66e1b24b3 100644 --- a/libgo/go/cmd/cgo/out.go +++ b/libgo/go/cmd/cgo/out.go @@ -1638,14 +1638,14 @@ func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32 func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr) //go:linkname _cgoCheckPointer runtime.cgoCheckPointer -func _cgoCheckPointer(interface{}, ...interface{}) +func _cgoCheckPointer(interface{}, interface{}) //go:linkname _cgoCheckResult runtime.cgoCheckResult func _cgoCheckResult(interface{}) ` const gccgoGoProlog = ` -func _cgoCheckPointer(interface{}, ...interface{}) +func _cgoCheckPointer(interface{}, interface{}) func _cgoCheckResult(interface{}) ` @@ -1832,16 +1832,16 @@ typedef struct __go_empty_interface { void *__object; } Eface; -extern void runtimeCgoCheckPointer(Eface, Slice) +extern void runtimeCgoCheckPointer(Eface, Eface) __asm__("runtime.cgoCheckPointer") __attribute__((weak)); -extern void localCgoCheckPointer(Eface, Slice) +extern void localCgoCheckPointer(Eface, Eface) __asm__("GCCGOSYMBOLPREF._cgoCheckPointer"); -void localCgoCheckPointer(Eface ptr, Slice args) { +void localCgoCheckPointer(Eface ptr, Eface arg) { if(runtimeCgoCheckPointer) { - runtimeCgoCheckPointer(ptr, args); + runtimeCgoCheckPointer(ptr, arg); } } diff --git a/libgo/go/cmd/go/alldocs.go b/libgo/go/cmd/go/alldocs.go index ebbead5d316..54e7a8b5b30 100644 --- a/libgo/go/cmd/go/alldocs.go +++ b/libgo/go/cmd/go/alldocs.go @@ -110,11 +110,13 @@ // The default is the number of CPUs available. // -race // enable data race detection. -// Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64. +// Supported only on linux/amd64, freebsd/amd64, darwin/amd64, windows/amd64, +// linux/ppc64le and linux/arm64 (only for 48-bit VMA). // -msan // enable interoperation with memory sanitizer. // Supported only on linux/amd64, linux/arm64 // and only with Clang/LLVM as the host C compiler. +// On linux/arm64, pie build mode will be used. // -v // print the names of packages as they are compiled. // -work @@ -143,11 +145,21 @@ // -ldflags '[pattern=]arg list' // arguments to pass on each go tool link invocation. // -linkshared -// link against shared libraries previously created with -// -buildmode=shared. +// build code that will be linked against shared libraries previously +// created with -buildmode=shared. // -mod mode -// module download mode to use: readonly or vendor. +// module download mode to use: readonly, vendor, or mod. // See 'go help modules' for more. +// -modcacherw +// leave newly-created directories in the module cache read-write +// instead of making them read-only. +// -modfile file +// in module aware mode, read (and possibly write) an alternate go.mod +// file instead of the one in the module root directory. A file named +// "go.mod" must still be present in order to determine the module root +// directory, but it is not accessed. When -modfile is specified, an +// alternate go.sum file is also used: its path is derived from the +// -modfile flag by trimming the ".mod" extension and appending ".sum". // -pkgdir dir // install and load all packages from dir instead of the usual locations. // For example, when building with a non-standard configuration, @@ -361,6 +373,8 @@ // Treat a command (package main) like a regular package. // Otherwise package main's exported symbols are hidden // when showing the package's top-level documentation. +// -short +// One-line representation for each symbol. // -src // Show the full source code for the symbol. This will // display the full Go source of its declaration and @@ -431,6 +445,9 @@ // The -n flag prints commands that would be executed. // The -x flag prints commands as they are executed. // +// The -mod flag's value sets which module download mode +// to use: readonly or vendor. See 'go help modules' for more. +// // To run gofmt with specific options, run gofmt itself. // // See also: go fix, go vet. @@ -993,7 +1010,7 @@ // // Usage: // -// go mod download [-json] [modules] +// go mod download [-x] [-json] [modules] // // Download downloads the named modules, which can be module patterns selecting // dependencies of the main module or module queries of the form path@version. @@ -1018,9 +1035,10 @@ // Dir string // absolute path to cached source root directory // Sum string // checksum for path, version (as in go.sum) // GoModSum string // checksum for go.mod (as in go.sum) -// Latest bool // would @latest resolve to this version? // } // +// The -x flag causes download to print the commands download executes. +// // See 'go help modules' for more about module queries. // // @@ -1057,12 +1075,17 @@ // add and drop an exclusion for the given module path and version. // Note that -exclude=path@version is a no-op if that exclusion already exists. // -// The -replace=old[@v]=new[@v] and -dropreplace=old[@v] flags -// add and drop a replacement of the given module path and version pair. -// If the @v in old@v is omitted, the replacement applies to all versions -// with the old module path. If the @v in new@v is omitted, the new path -// should be a local module root directory, not a module path. -// Note that -replace overrides any existing replacements for old[@v]. +// The -replace=old[@v]=new[@v] flag adds a replacement of the given +// module path and version pair. If the @v in old@v is omitted, a +// replacement without a version on the left side is added, which applies +// to all versions of the old module path. If the @v in new@v is omitted, +// the new path should be a local module root directory, not a module +// path. Note that -replace overrides any redundant replacements for old[@v], +// so omitting @v will drop existing replacements for specific versions. +// +// The -dropreplace=old[@v] flag drops a replacement of the given +// module path and version pair. If the @v is omitted, a replacement without +// a version on the left side is dropped. // // The -require, -droprequire, -exclude, -dropexclude, -replace, // and -dropreplace editing flags may be repeated, and the changes @@ -1232,7 +1255,7 @@ // If the -exec flag is not given, GOOS or GOARCH is different from the system // default, and a program named go_$GOOS_$GOARCH_exec can be found // on the current search path, 'go run' invokes the binary using that program, -// for example 'go_nacl_386_exec a.out arguments...'. This allows execution of +// for example 'go_js_wasm_exec a.out arguments...'. This allows execution of // cross-compiled programs when a simulator or other execution method is // available. // @@ -1504,8 +1527,8 @@ // extension will be passed to SWIG. Any file with a .swigcxx extension // will be passed to SWIG with the -c++ option. // -// When either cgo or SWIG is used, go build will pass any .c, .m, .s, -// or .S files to the C compiler, and any .cc, .cpp, .cxx files to the C++ +// When either cgo or SWIG is used, go build will pass any .c, .m, .s, .S +// or .sx files to the C compiler, and any .cc, .cpp, .cxx files to the C++ // compiler. The CC or CXX environment variables may be set to determine // the C or C++ compiler, respectively, to use. // @@ -1588,6 +1611,10 @@ // Because the entries are space-separated, flag values must // not contain spaces. Flags listed on the command line // are applied after this list and therefore override it. +// GOINSECURE +// Comma-separated list of glob patterns (in the syntax of Go's path.Match) +// of module path prefixes that should always be fetched in an insecure +// manner. Only applies to dependencies that are being fetched directly. // GOOS // The operating system for which to compile code. // Examples are linux, darwin, windows, netbsd. @@ -1699,8 +1726,10 @@ // GOHOSTOS // The operating system (GOOS) of the Go toolchain binaries. // GOMOD -// The absolute path to the go.mod of the main module, -// or the empty string if not using modules. +// The absolute path to the go.mod of the main module. +// If module-aware mode is enabled, but there is no go.mod, GOMOD will be +// os.DevNull ("/dev/null" on Unix-like systems, "NUL" on Windows). +// If module-aware mode is disabled, GOMOD will be the empty string. // GOTOOLDIR // The directory where the go tools (compile, cover, doc, etc...) are installed. // @@ -1724,7 +1753,7 @@ // .m // Objective-C source files. Only useful with cgo, and always // compiled with the OS-native compiler. -// .s, .S +// .s, .S, .sx // Assembler source files. // If the package uses cgo or SWIG, these will be assembled with the // OS-native assembler (typically gcc (sic)); otherwise they @@ -2060,8 +2089,8 @@ // // The GET requests sent to a Go module proxy are: // -// GET $GOPROXY//@v/list returns a list of all known versions of the -// given module, one per line. +// GET $GOPROXY//@v/list returns a list of known versions of the given +// module, one per line. // // GET $GOPROXY//@v/.info returns JSON-formatted metadata // about that version of the given module. @@ -2072,6 +2101,21 @@ // GET $GOPROXY//@v/.zip returns the zip archive // for that version of the given module. // +// GET $GOPROXY//@latest returns JSON-formatted metadata about the +// latest known version of the given module in the same format as +// /@v/.info. The latest version should be the version of +// the module the go command may use if /@v/list is empty or no +// listed version is suitable. /@latest is optional and may not +// be implemented by a module proxy. +// +// When resolving the latest version of a module, the go command will request +// /@v/list, then, if no suitable versions are found, /@latest. +// The go command prefers, in order: the semantically highest release version, +// the semantically highest pre-release version, and the chronologically +// most recent pseudo-version. In Go 1.12 and earlier, the go command considered +// pseudo-versions in /@v/list to be pre-release versions, but this is +// no longer true since Go 1.13. +// // To avoid problems when serving from case-sensitive file systems, // the and elements are case-encoded, replacing every // uppercase letter with an exclamation mark followed by the corresponding @@ -2460,6 +2504,9 @@ // directory holds the correct copies of dependencies and ignores // the dependency descriptions in go.mod. // +// If invoked with -mod=mod, the go command loads modules from the module cache +// even if there is a vendor directory present. +// // Pseudo-versions // // The go.mod file and the go command more generally use semantic versions as diff --git a/libgo/go/cmd/go/go_test.go b/libgo/go/cmd/go/go_test.go index f936d703c07..ebd0c7ad0ad 100644 --- a/libgo/go/cmd/go/go_test.go +++ b/libgo/go/cmd/go/go_test.go @@ -56,7 +56,7 @@ func tooSlow(t *testing.T) { func init() { switch runtime.GOOS { - case "android", "js", "nacl": + case "android", "js": canRun = false case "darwin": switch runtime.GOARCH { @@ -206,7 +206,7 @@ func TestMain(m *testing.M) { // (installed in GOROOT/pkg/tool/GOOS_GOARCH). // If these are not the same toolchain, then the entire standard library // will look out of date (the compilers in those two different tool directories - // are built for different architectures and have different buid IDs), + // are built for different architectures and have different build IDs), // which will cause many tests to do unnecessary rebuilds and some // tests to attempt to overwrite the installed standard library. // Bail out entirely in this case. @@ -683,8 +683,11 @@ func (tg *testgoData) creatingTemp(path string) { // If we have changed the working directory, make sure we have // an absolute path, because we are going to change directory // back before we remove the temporary. - if tg.wd != "" && !filepath.IsAbs(path) { - path = filepath.Join(tg.pwd(), path) + if !filepath.IsAbs(path) { + if tg.wd == "" || strings.HasPrefix(tg.wd, testGOROOT) { + tg.t.Fatalf("internal testsuite error: creatingTemp(%q) within GOROOT/src", path) + } + path = filepath.Join(tg.wd, path) } tg.must(robustio.RemoveAll(path)) tg.temps = append(tg.temps, path) @@ -917,6 +920,7 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { "src/runtime", "src/internal/bytealg", "src/internal/cpu", + "src/math/bits", "src/unsafe", filepath.Join("pkg", runtime.GOOS+"_"+runtime.GOARCH), filepath.Join("pkg/tool", runtime.GOOS+"_"+runtime.GOARCH), @@ -942,7 +946,7 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { return err } tg.tempFile(dest, string(data)) - if err := os.Chmod(tg.path(dest), info.Mode()); err != nil { + if err := os.Chmod(tg.path(dest), info.Mode()|0200); err != nil { return err } return nil @@ -1007,128 +1011,6 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { tg.wantNotStale("p1", "", "./testgo list claims p1 is stale after building with old release") } -func testLocalRun(tg *testgoData, exepath, local, match string) { - tg.t.Helper() - out, err := exec.Command(exepath).Output() - if err != nil { - tg.t.Fatalf("error running %v: %v", exepath, err) - } - if !regexp.MustCompile(match).Match(out) { - tg.t.Log(string(out)) - tg.t.Errorf("testdata/%s/easy.go did not generate expected output", local) - } -} - -func testLocalEasy(tg *testgoData, local string) { - tg.t.Helper() - exepath := "./easy" + exeSuffix - tg.creatingTemp(exepath) - tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easy.go")) - testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`) -} - -func testLocalEasySub(tg *testgoData, local string) { - tg.t.Helper() - exepath := "./easysub" + exeSuffix - tg.creatingTemp(exepath) - tg.run("build", "-o", exepath, filepath.Join("testdata", local, "easysub", "main.go")) - testLocalRun(tg, exepath, local, `(?m)^easysub\.Hello`) -} - -func testLocalHard(tg *testgoData, local string) { - tg.t.Helper() - exepath := "./hard" + exeSuffix - tg.creatingTemp(exepath) - tg.run("build", "-o", exepath, filepath.Join("testdata", local, "hard.go")) - testLocalRun(tg, exepath, local, `(?m)^sub\.Hello`) -} - -func testLocalInstall(tg *testgoData, local string) { - tg.t.Helper() - tg.runFail("install", filepath.Join("testdata", local, "easy.go")) -} - -func TestLocalImportsEasy(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - testLocalEasy(tg, "local") -} - -func TestLocalImportsEasySub(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - testLocalEasySub(tg, "local") -} - -func TestLocalImportsHard(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - testLocalHard(tg, "local") -} - -func TestLocalImportsGoInstallShouldFail(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - testLocalInstall(tg, "local") -} - -const badDirName = `#$%:, &()*;<=>?\^{}` - -func copyBad(tg *testgoData) { - tg.t.Helper() - if runtime.GOOS == "windows" { - tg.t.Skipf("skipping test because %q is an invalid directory name", badDirName) - } - - tg.must(filepath.Walk("testdata/local", - func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - return nil - } - var data []byte - data, err = ioutil.ReadFile(path) - if err != nil { - return err - } - newpath := strings.Replace(path, "local", badDirName, 1) - tg.tempFile(newpath, string(data)) - return nil - })) - tg.cd(tg.path(".")) -} - -func TestBadImportsEasy(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - // TODO: tg.parallel() - copyBad(tg) - testLocalEasy(tg, badDirName) -} - -func TestBadImportsEasySub(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - copyBad(tg) - testLocalEasySub(tg, badDirName) -} - -func TestBadImportsHard(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - copyBad(tg) - testLocalHard(tg, badDirName) -} - -func TestBadImportsGoInstallShouldFail(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - copyBad(tg) - testLocalInstall(tg, badDirName) -} - func TestInternalPackagesInGOROOTAreRespected(t *testing.T) { skipIfGccgo(t, "gccgo does not have GOROOT") tg := testgo(t) @@ -1166,48 +1048,6 @@ func TestRunPkg(t *testing.T) { tg.grepStderr("hello, world", "did not find hello, world") } -func testMove(t *testing.T, vcs, url, base, config string) { - testenv.MustHaveExternalNetwork(t) - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempDir("src") - tg.must(os.Mkdir(tg.path(".hg"), 0700)) - tg.must(ioutil.WriteFile(filepath.Join(tg.path(".hg"), "hgrc"), nil, 0600)) - tg.setenv("GOPATH", tg.path(".")) - tg.run("get", "-d", url) - tg.run("get", "-d", "-u", url) - switch vcs { - case "svn": - // SVN doesn't believe in text files so we can't just edit the config. - // Check out a different repo into the wrong place. - tg.must(robustio.RemoveAll(tg.path("src/code.google.com/p/rsc-svn"))) - tg.run("get", "-d", "-u", "code.google.com/p/rsc-svn2/trunk") - tg.must(os.Rename(tg.path("src/code.google.com/p/rsc-svn2"), tg.path("src/code.google.com/p/rsc-svn"))) - default: - path := tg.path(filepath.Join("src", config)) - data, err := ioutil.ReadFile(path) - tg.must(err) - data = bytes.ReplaceAll(data, []byte(base), []byte(base+"XXX")) - tg.must(ioutil.WriteFile(path, data, 0644)) - } - if vcs == "git" { - // git will ask for a username and password when we - // run go get -d -f -u. An empty username and - // password will work. Prevent asking by setting - // GIT_ASKPASS. - tg.creatingTemp("sink" + exeSuffix) - tg.tempFile("src/sink/sink.go", `package main; func main() {}`) - tg.run("build", "-o", "sink"+exeSuffix, "sink") - tg.setenv("GIT_ASKPASS", filepath.Join(tg.pwd(), "sink"+exeSuffix)) - } - tg.runFail("get", "-d", "-u", url) - tg.grepStderr("is a custom import path for", "go get -d -u "+url+" failed for wrong reason") - tg.runFail("get", "-d", "-f", "-u", url) - tg.grepStderr("validating server certificate|[nN]ot [fF]ound", "go get -d -f -u "+url+" failed for wrong reason") -} - func TestInternalPackageErrorsAreHandled(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -1222,21 +1062,6 @@ func TestInternalCache(t *testing.T) { tg.grepStderr("internal", "did not fail to build p") } -func TestMoveGit(t *testing.T) { - testenv.MustHaveExecPath(t, "git") - testMove(t, "git", "rsc.io/pdf", "pdf", "rsc.io/pdf/.git/config") -} - -func TestMoveHG(t *testing.T) { - testenv.MustHaveExecPath(t, "hg") - testMove(t, "hg", "vcs-test.golang.org/go/custom-hg-hello", "custom-hg-hello", "vcs-test.golang.org/go/custom-hg-hello/.hg/hgrc") -} - -// TODO(rsc): Set up a test case on SourceForge (?) for svn. -// func testMoveSVN(t *testing.T) { -// testMove(t, "svn", "code.google.com/p/rsc-svn/trunk", "-", "-") -// } - func TestImportCommandMatch(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -1435,17 +1260,6 @@ func TestRelativeImportsInCommandLinePackage(t *testing.T) { tg.run(append([]string{"test"}, files...)...) } -func TestNonCanonicalImportPaths(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.runFail("build", "canonical/d") - tg.grepStderr("package canonical/d", "did not report canonical/d") - tg.grepStderr("imports canonical/b", "did not report canonical/b") - tg.grepStderr("imports canonical/a/: non-canonical", "did not report canonical/a/") -} - func TestVersionControlErrorMessageIncludesCorrectDirectory(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -1502,72 +1316,6 @@ func TestRelativeGOBINFail(t *testing.T) { tg.grepStderr("cannot install, GOBIN must be an absolute path", "go install must fail if $GOBIN is a relative path") } -// Test that without $GOBIN set, binaries get installed -// into the GOPATH bin directory. -func TestInstallIntoGOPATH(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix) - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("install", "go-cmd-test") - tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test") -} - -// Issue 12407 -func TestBuildOutputToDevNull(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - fi1, err1 := os.Lstat(os.DevNull) - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("build", "-o", os.DevNull, "go-cmd-test") - fi2, err2 := os.Lstat(os.DevNull) - if err1 == nil { - if err2 != nil { - t.Errorf("second stat of /dev/null failed: %v", err2) - } else if !os.SameFile(fi1, fi2) { - t.Errorf("/dev/null changed: now %v was %v", fi1, fi2) - } - } -} - -// Issue 28549. -func TestTestOutputToDevNull(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - fi1, err1 := os.Lstat(os.DevNull) - tg.makeTempdir() - tg.setenv("GOPATH", tg.path(".")) - tg.tempFile("src/p/p.go", "package p\n") - tg.tempFile("src/p/p_test.go", "package p\nimport \"testing\"\nfunc TestX(t *testing.T) {}\n") - tg.run("test", "-o", os.DevNull, "-c", "p") - tg.mustNotExist("p.test") - fi2, err2 := os.Lstat(os.DevNull) - if err1 == nil { - if err2 != nil { - t.Errorf("second stat of /dev/null failed: %v", err2) - } else if !os.SameFile(fi1, fi2) { - t.Errorf("/dev/null changed: now %v was %v", fi1, fi2) - } - } -} - -func TestPackageMainTestImportsArchiveNotBinary(t *testing.T) { - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - gobin := filepath.Join(tg.pwd(), "testdata", "bin") - tg.creatingTemp(gobin) - tg.setenv("GOBIN", gobin) - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.must(os.Chtimes("./testdata/src/main_test/m.go", time.Now(), time.Now())) - tg.sleep() - tg.run("test", "main_test") - tg.run("install", "main_test") - tg.wantNotStale("main_test", "", "after go install, main listed as stale") - tg.run("test", "main_test") -} - func TestPackageMainTestCompilerFlags(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -1600,51 +1348,6 @@ func TestPackageNotStaleWithTrailingSlash(t *testing.T) { tg.wantNotStale("io", "", "with trailing slash in GOROOT, io listed as stale") } -// With $GOBIN set, binaries get installed to $GOBIN. -func TestInstallIntoGOBIN(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - gobin := filepath.Join(tg.pwd(), "testdata", "bin1") - tg.creatingTemp(gobin) - tg.setenv("GOBIN", gobin) - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.run("install", "go-cmd-test") - tg.wantExecutable("testdata/bin1/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin1/go-cmd-test") -} - -// Issue 11065 -func TestInstallToCurrentDirectoryCreatesExecutable(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - pkg := filepath.Join(tg.pwd(), "testdata", "src", "go-cmd-test") - tg.creatingTemp(filepath.Join(pkg, "go-cmd-test"+exeSuffix)) - tg.setenv("GOBIN", pkg) - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.cd(pkg) - tg.run("install") - tg.wantExecutable("go-cmd-test"+exeSuffix, "go install did not write to current directory") -} - -// Without $GOBIN set, installing a program outside $GOPATH should fail -// (there is nowhere to install it). -func TestInstallWithoutDestinationFails(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.runFail("install", "testdata/src/go-cmd-test/helloworld.go") - tg.grepStderr("no install location for .go files listed on command line", "wrong error") -} - -// With $GOBIN set, should install there. -func TestInstallToGOBINCommandLinePackage(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - gobin := filepath.Join(tg.pwd(), "testdata", "bin1") - tg.creatingTemp(gobin) - tg.setenv("GOBIN", gobin) - tg.run("install", "testdata/src/go-cmd-test/helloworld.go") - tg.wantExecutable("testdata/bin1/helloworld"+exeSuffix, "go install testdata/src/go-cmd-test/helloworld.go did not write testdata/bin1/helloworld") -} - func TestGoGetNonPkg(t *testing.T) { testenv.MustHaveExternalNetwork(t) testenv.MustHaveExecPath(t, "git") @@ -1674,94 +1377,6 @@ func TestGoGetTestOnlyPkg(t *testing.T) { tg.run("get", "-t", "golang.org/x/tour/content...") } -func TestInstalls(t *testing.T) { - if testing.Short() { - t.Skip("don't install into GOROOT in short mode") - } - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempDir("gobin") - tg.setenv("GOPATH", tg.path(".")) - goroot := runtime.GOROOT() - tg.setenv("GOROOT", goroot) - - // cmd/fix installs into tool - tg.run("env", "GOOS") - goos := strings.TrimSpace(tg.getStdout()) - tg.setenv("GOOS", goos) - tg.run("env", "GOARCH") - goarch := strings.TrimSpace(tg.getStdout()) - tg.setenv("GOARCH", goarch) - fixbin := filepath.Join(goroot, "pkg", "tool", goos+"_"+goarch, "fix") + exeSuffix - tg.must(robustio.RemoveAll(fixbin)) - tg.run("install", "cmd/fix") - tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool") - tg.must(os.Remove(fixbin)) - tg.setenv("GOBIN", tg.path("gobin")) - tg.run("install", "cmd/fix") - tg.wantExecutable(fixbin, "did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set") - tg.unsetenv("GOBIN") - - // gopath program installs into GOBIN - tg.tempFile("src/progname/p.go", `package main; func main() {}`) - tg.setenv("GOBIN", tg.path("gobin")) - tg.run("install", "progname") - tg.unsetenv("GOBIN") - tg.wantExecutable(tg.path("gobin/progname")+exeSuffix, "did not install progname to $GOBIN/progname") - - // gopath program installs into GOPATH/bin - tg.run("install", "progname") - tg.wantExecutable(tg.path("bin/progname")+exeSuffix, "did not install progname to $GOPATH/bin/progname") -} - -func TestRejectRelativeDotPathInGOPATHCommandLinePackage(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", ".") - tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go") - tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") -} - -func TestRejectRelativePathsInGOPATH(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - sep := string(filepath.ListSeparator) - tg.setenv("GOPATH", sep+filepath.Join(tg.pwd(), "testdata")+sep+".") - tg.runFail("build", "go-cmd-test") - tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") -} - -func TestRejectRelativePathsInGOPATHCommandLinePackage(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", "testdata") - tg.runFail("build", "testdata/src/go-cmd-test/helloworld.go") - tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") -} - -// Issue 21928. -func TestRejectBlankPathsInGOPATH(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - sep := string(filepath.ListSeparator) - tg.setenv("GOPATH", " "+sep+filepath.Join(tg.pwd(), "testdata")) - tg.runFail("build", "go-cmd-test") - tg.grepStderr("GOPATH entry is relative", "expected an error message rejecting relative GOPATH entries") -} - -// Issue 21928. -func TestIgnoreEmptyPathsInGOPATH(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.creatingTemp("testdata/bin/go-cmd-test" + exeSuffix) - sep := string(filepath.ListSeparator) - tg.setenv("GOPATH", ""+sep+filepath.Join(tg.pwd(), "testdata")) - tg.run("install", "go-cmd-test") - tg.wantExecutable("testdata/bin/go-cmd-test"+exeSuffix, "go install go-cmd-test did not write to testdata/bin/go-cmd-test") -} - // Issue 4104. func TestGoTestWithPackageListedMultipleTimes(t *testing.T) { tooSlow(t) @@ -2547,57 +2162,6 @@ func TestCoverageDotImport(t *testing.T) { checkCoverage(tg, data) } -// Check that coverage analysis uses set mode. -// Also check that coverage profiles merge correctly. -func TestCoverageUsesSetMode(t *testing.T) { - skipIfGccgo(t, "gccgo has no cover tool") - tooSlow(t) - tg := testgo(t) - defer tg.cleanup() - tg.creatingTemp("testdata/cover.out") - tg.run("test", "-short", "-cover", "encoding/binary", "errors", "-coverprofile=testdata/cover.out") - data := tg.getStdout() + tg.getStderr() - if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { - t.Error(err) - } else { - if !bytes.Contains(out, []byte("mode: set")) { - t.Error("missing mode: set") - } - if !bytes.Contains(out, []byte("errors.go")) { - t.Error("missing errors.go") - } - if !bytes.Contains(out, []byte("binary.go")) { - t.Error("missing binary.go") - } - if bytes.Count(out, []byte("mode: set")) != 1 { - t.Error("too many mode: set") - } - } - checkCoverage(tg, data) -} - -func TestCoverageUsesAtomicModeForRace(t *testing.T) { - tooSlow(t) - if !canRace { - t.Skip("skipping because race detector not supported") - } - skipIfGccgo(t, "gccgo has no cover tool") - - tg := testgo(t) - defer tg.cleanup() - tg.creatingTemp("testdata/cover.out") - tg.run("test", "-short", "-race", "-cover", "encoding/binary", "-coverprofile=testdata/cover.out") - data := tg.getStdout() + tg.getStderr() - if out, err := ioutil.ReadFile("testdata/cover.out"); err != nil { - t.Error(err) - } else { - if !bytes.Contains(out, []byte("mode: atomic")) { - t.Error("missing mode: atomic") - } - } - checkCoverage(tg, data) -} - func TestCoverageSyncAtomicImport(t *testing.T) { skipIfGccgo(t, "gccgo has no cover tool") tooSlow(t) @@ -3092,53 +2656,6 @@ func TestIssue7108(t *testing.T) { tg.runFail("test", "notest") } -// cmd/go: go test -a foo does not rebuild regexp. -func TestIssue6844(t *testing.T) { - if testing.Short() { - t.Skip("don't rebuild the standard library in short mode") - } - - tg := testgo(t) - defer tg.cleanup() - tg.creatingTemp("deps.test" + exeSuffix) - tg.run("test", "-x", "-a", "-c", "testdata/dep_test.go") - tg.grepStderr("regexp", "go test -x -a -c testdata/dep-test.go did not rebuild regexp") -} - -func TestBuildDashIInstallsDependencies(t *testing.T) { - tooSlow(t) - - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.tempFile("src/x/y/foo/foo.go", `package foo - func F() {}`) - tg.tempFile("src/x/y/bar/bar.go", `package bar - import "x/y/foo" - func F() { foo.F() }`) - tg.setenv("GOPATH", tg.path(".")) - - // don't let build -i overwrite runtime - tg.wantNotStale("runtime", "", "must be non-stale before build -i") - - checkbar := func(desc string) { - tg.run("build", "-v", "-i", "x/y/bar") - tg.grepBoth("x/y/foo", "first build -i "+desc+" did not build x/y/foo") - tg.run("build", "-v", "-i", "x/y/bar") - tg.grepBothNot("x/y/foo", "second build -i "+desc+" built x/y/foo") - } - checkbar("pkg") - - tg.creatingTemp("bar" + exeSuffix) - tg.sleep() - tg.tempFile("src/x/y/foo/foo.go", `package foo - func F() { F() }`) - tg.tempFile("src/x/y/bar/bar.go", `package main - import "x/y/foo" - func main() { foo.F() }`) - checkbar("cmd") -} - func TestGoBuildTestOnly(t *testing.T) { tg := testgo(t) defer tg.cleanup() @@ -3423,95 +2940,6 @@ func TestGoGetDotSlashDownload(t *testing.T) { tg.run("get", "./pprof_mac_fix") } -// Test that you cannot import a main package. -// See golang.org/issue/4210 and golang.org/issue/17475. -func TestImportMain(t *testing.T) { - tooSlow(t) - - tg := testgo(t) - tg.parallel() - defer tg.cleanup() - - // Importing package main from that package main's test should work. - tg.tempFile("src/x/main.go", `package main - var X int - func main() {}`) - tg.tempFile("src/x/main_test.go", `package main_test - import xmain "x" - import "testing" - var _ = xmain.X - func TestFoo(t *testing.T) {} - `) - tg.setenv("GOPATH", tg.path(".")) - tg.creatingTemp("x" + exeSuffix) - tg.run("build", "x") - tg.run("test", "x") - - // Importing package main from another package should fail. - tg.tempFile("src/p1/p.go", `package p1 - import xmain "x" - var _ = xmain.X - `) - tg.runFail("build", "p1") - tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main") - - // ... even in that package's test. - tg.tempFile("src/p2/p.go", `package p2 - `) - tg.tempFile("src/p2/p_test.go", `package p2 - import xmain "x" - import "testing" - var _ = xmain.X - func TestFoo(t *testing.T) {} - `) - tg.run("build", "p2") - tg.runFail("test", "p2") - tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main") - - // ... even if that package's test is an xtest. - tg.tempFile("src/p3/p.go", `package p - `) - tg.tempFile("src/p3/p_test.go", `package p_test - import xmain "x" - import "testing" - var _ = xmain.X - func TestFoo(t *testing.T) {} - `) - tg.run("build", "p3") - tg.runFail("test", "p3") - tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main") - - // ... even if that package is a package main - tg.tempFile("src/p4/p.go", `package main - func main() {} - `) - tg.tempFile("src/p4/p_test.go", `package main - import xmain "x" - import "testing" - var _ = xmain.X - func TestFoo(t *testing.T) {} - `) - tg.creatingTemp("p4" + exeSuffix) - tg.run("build", "p4") - tg.runFail("test", "p4") - tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main") - - // ... even if that package is a package main using an xtest. - tg.tempFile("src/p5/p.go", `package main - func main() {} - `) - tg.tempFile("src/p5/p_test.go", `package main_test - import xmain "x" - import "testing" - var _ = xmain.X - func TestFoo(t *testing.T) {} - `) - tg.creatingTemp("p5" + exeSuffix) - tg.run("build", "p5") - tg.runFail("test", "p5") - tg.grepStderr("import \"x\" is a program, not an importable package", "did not diagnose package main") -} - // Test that you cannot use a local import in a package // accessed by a non-local import (found in a GOPATH/GOROOT). // See golang.org/issue/17475. @@ -3822,7 +3250,17 @@ func TestGoTestRaceInstallCgo(t *testing.T) { cgo := strings.TrimSpace(tg.stdout.String()) old, err := os.Stat(cgo) tg.must(err) - tg.run("test", "-race", "-i", "runtime/race") + + // For this test, we don't actually care whether 'go test -race -i' succeeds. + // It may fail, for example, if GOROOT was installed from source as root and + // is now read-only. + // We only care that — regardless of whether it succeeds — it does not + // overwrite cmd/cgo. + runArgs := []string{"test", "-race", "-i", "runtime/race"} + if status := tg.doRun(runArgs); status != nil { + tg.t.Logf("go %v failure ignored: %v", runArgs, status) + } + new, err := os.Stat(cgo) tg.must(err) if !new.ModTime().Equal(old.ModTime()) { @@ -4688,23 +4126,19 @@ func copyFile(src, dst string, perm os.FileMode) error { return err2 } +// TestExecutableGOROOT verifies that the cmd/go binary itself uses +// os.Executable (when available) to locate GOROOT. func TestExecutableGOROOT(t *testing.T) { skipIfGccgo(t, "gccgo has no GOROOT") - if runtime.GOOS == "openbsd" { - t.Skipf("test case does not work on %s, missing os.Executable", runtime.GOOS) - } - // Env with no GOROOT. - var env []string - for _, e := range os.Environ() { - if !strings.HasPrefix(e, "GOROOT=") { - env = append(env, e) - } - } + // Note: Must not call tg methods inside subtests: tg is attached to outer t. + tg := testgo(t) + tg.unsetenv("GOROOT") + defer tg.cleanup() check := func(t *testing.T, exe, want string) { cmd := exec.Command(exe, "env", "GOROOT") - cmd.Env = env + cmd.Env = tg.env out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("%s env GOROOT: %v, %s", exe, err, out) @@ -4724,10 +4158,6 @@ func TestExecutableGOROOT(t *testing.T) { } } - // Note: Must not call tg methods inside subtests: tg is attached to outer t. - tg := testgo(t) - defer tg.cleanup() - tg.makeTempdir() tg.tempDir("new/bin") newGoTool := tg.path("new/bin/go" + exeSuffix) @@ -4774,8 +4204,9 @@ func TestExecutableGOROOT(t *testing.T) { } cmd := exec.Command(newGoTool, "run", "testdata/print_goroot.go") - cmd.Env = env - out, err := cmd.CombinedOutput() + cmd.Env = tg.env + cmd.Stderr = os.Stderr + out, err := cmd.Output() if err != nil { t.Fatalf("%s run testdata/print_goroot.go: %v, %s", newGoTool, err, out) } @@ -4807,36 +4238,6 @@ func TestNeedVersion(t *testing.T) { tg.grepStderr("compile", "does not match go tool version") } -// Test that user can override default code generation flags. -func TestUserOverrideFlags(t *testing.T) { - skipIfGccgo(t, "gccgo does not use -gcflags") - if !canCgo { - t.Skip("skipping because cgo not enabled") - } - if runtime.GOOS != "linux" { - // We are testing platform-independent code, so it's - // OK to skip cases that work differently. - t.Skipf("skipping on %s because test only works if c-archive implies -shared", runtime.GOOS) - } - - tg := testgo(t) - defer tg.cleanup() - // Don't call tg.parallel, as creating override.h and override.a may - // confuse other tests. - tg.tempFile("override.go", `package main - -import "C" - -//export GoFunc -func GoFunc() {} - -func main() {}`) - tg.creatingTemp("override.a") - tg.creatingTemp("override.h") - tg.run("build", "-x", "-buildmode=c-archive", "-gcflags=all=-shared=false", tg.path("override.go")) - tg.grepStderr("compile .*-shared .*-shared=false", "user can not override code generation flag") -} - func TestCgoFlagContainsSpace(t *testing.T) { tooSlow(t) if !canCgo { @@ -4939,35 +4340,31 @@ func TestTestRegexps(t *testing.T) { // BenchmarkXX is run but only with N=1, once // BenchmarkX/Y is run in full, twice want := `=== RUN TestX + TestX: x_test.go:6: LOG: X running === RUN TestX/Y - x_test.go:6: LOG: X running - x_test.go:8: LOG: Y running + TestX/Y: x_test.go:8: LOG: Y running === RUN TestXX - z_test.go:10: LOG: XX running + TestXX: z_test.go:10: LOG: XX running === RUN TestX + TestX: x_test.go:6: LOG: X running === RUN TestX/Y - x_test.go:6: LOG: X running - x_test.go:8: LOG: Y running + TestX/Y: x_test.go:8: LOG: Y running === RUN TestXX - z_test.go:10: LOG: XX running ---- BENCH: BenchmarkX/Y - x_test.go:15: LOG: Y running N=1 - x_test.go:15: LOG: Y running N=100 - x_test.go:15: LOG: Y running N=10000 - x_test.go:15: LOG: Y running N=1000000 - x_test.go:15: LOG: Y running N=100000000 - x_test.go:15: LOG: Y running N=1000000000 ---- BENCH: BenchmarkX/Y - x_test.go:15: LOG: Y running N=1 - x_test.go:15: LOG: Y running N=100 - x_test.go:15: LOG: Y running N=10000 - x_test.go:15: LOG: Y running N=1000000 - x_test.go:15: LOG: Y running N=100000000 - x_test.go:15: LOG: Y running N=1000000000 ---- BENCH: BenchmarkX - x_test.go:13: LOG: X running N=1 ---- BENCH: BenchmarkXX - z_test.go:18: LOG: XX running N=1 + TestXX: z_test.go:10: LOG: XX running + BenchmarkX: x_test.go:13: LOG: X running N=1 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=1 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=100 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=10000 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=1000000 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=100000000 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=1000000000 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=1 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=100 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=10000 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=1000000 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=100000000 + BenchmarkX/Y: x_test.go:15: LOG: Y running N=1000000000 + BenchmarkXX: z_test.go:18: LOG: XX running N=1 ` have := strings.Join(lines, "") @@ -5196,52 +4593,6 @@ func TestUpxCompression(t *testing.T) { } } -// Test that Go binaries can be run under QEMU in user-emulation mode -// (See issue #13024). -func TestQEMUUserMode(t *testing.T) { - if testing.Short() && testenv.Builder() == "" { - t.Skipf("skipping in -short mode on non-builder") - } - - testArchs := []struct { - g, qemu string - }{ - {"arm", "arm"}, - {"arm64", "aarch64"}, - } - - tg := testgo(t) - defer tg.cleanup() - tg.tempFile("main.go", `package main; import "fmt"; func main() { fmt.Print("hello qemu-user") }`) - tg.parallel() - src, obj := tg.path("main.go"), tg.path("main") - - for _, arch := range testArchs { - arch := arch - t.Run(arch.g, func(t *testing.T) { - qemu := "qemu-" + arch.qemu - testenv.MustHaveExecPath(t, qemu) - - out, err := exec.Command(qemu, "--version").CombinedOutput() - if err != nil { - t.Fatalf("%s --version failed: %v", qemu, err) - } - - tg.setenv("GOARCH", arch.g) - tg.run("build", "-o", obj, src) - - out, err = exec.Command(qemu, obj).CombinedOutput() - if err != nil { - t.Logf("%s output:\n%s\n", qemu, out) - t.Fatalf("%s failed with %v", qemu, err) - } - if want := "hello qemu-user"; string(out) != want { - t.Errorf("bad output from %s:\ngot %s; want %s", qemu, out, want) - } - }) - } -} - func TestCacheListStale(t *testing.T) { tooSlow(t) if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") { @@ -5282,38 +4633,6 @@ func TestCacheCoverage(t *testing.T) { tg.run("test", "-cover", "-short", "math", "strings") } -func TestCacheVet(t *testing.T) { - skipIfGccgo(t, "gccgo has no standard packages") - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - - if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") { - t.Skip("GODEBUG gocacheverify") - } - if testing.Short() { - // In short mode, reuse cache. - // Test failures may be masked if the cache has just the right entries already - // (not a concern during all.bash, which runs in a clean cache). - if cfg.Getenv("GOCACHE") == "off" { - tooSlow(t) - } - } else { - tg.makeTempdir() - tg.setenv("GOCACHE", tg.path("cache")) - } - - // Check that second vet reuses cgo-derived inputs. - // The first command could be build instead of vet, - // except that if the cache is empty and there's a net.a - // in GOROOT/pkg, the build will not bother to regenerate - // and cache the cgo outputs, whereas vet always will. - tg.run("vet", "os/user") - tg.run("vet", "-x", "os/user") - tg.grepStderrNot(`^(clang|gcc)`, "should not have run compiler") - tg.grepStderrNot(`[\\/]cgo `, "should not have run cgo") -} - func TestIssue22588(t *testing.T) { // Don't get confused by stderr coming from tools. tg := testgo(t) @@ -5503,122 +4822,6 @@ func TestTestCache(t *testing.T) { } } -func TestTestCacheInputs(t *testing.T) { - tooSlow(t) - - if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") { - t.Skip("GODEBUG gocacheverify") - } - tg := testgo(t) - defer tg.cleanup() - tg.parallel() - tg.makeTempdir() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.setenv("GOCACHE", tg.path("cache")) - - defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt")) - defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh")) - tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("x"), 0644)) - old := time.Now().Add(-1 * time.Minute) - tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old, old)) - info, err := os.Stat(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt")) - if err != nil { - t.Fatal(err) - } - t.Logf("file.txt: old=%v, info.ModTime=%v", old, info.ModTime()) // help debug when Chtimes lies about succeeding - tg.setenv("TESTKEY", "x") - - tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), []byte("#!/bin/sh\nexit 0\n"), 0755)) - tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), old, old)) - - tg.run("test", "testcache") - tg.run("test", "testcache") - tg.grepStdout(`\(cached\)`, "did not cache") - - tg.setenv("TESTKEY", "y") - tg.run("test", "testcache") - tg.grepStdoutNot(`\(cached\)`, "did not notice env var change") - tg.run("test", "testcache") - tg.grepStdout(`\(cached\)`, "did not cache") - - tg.run("test", "testcache", "-run=FileSize") - tg.run("test", "testcache", "-run=FileSize") - tg.grepStdout(`\(cached\)`, "did not cache") - tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("xxx"), 0644)) - tg.run("test", "testcache", "-run=FileSize") - tg.grepStdoutNot(`\(cached\)`, "did not notice file size change") - tg.run("test", "testcache", "-run=FileSize") - tg.grepStdout(`\(cached\)`, "did not cache") - - tg.run("test", "testcache", "-run=Chdir") - tg.run("test", "testcache", "-run=Chdir") - tg.grepStdout(`\(cached\)`, "did not cache") - tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("xxxxx"), 0644)) - tg.run("test", "testcache", "-run=Chdir") - tg.grepStdoutNot(`\(cached\)`, "did not notice file size change") - tg.run("test", "testcache", "-run=Chdir") - tg.grepStdout(`\(cached\)`, "did not cache") - - tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old, old)) - tg.run("test", "testcache", "-run=FileContent") - tg.run("test", "testcache", "-run=FileContent") - tg.grepStdout(`\(cached\)`, "did not cache") - tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), []byte("yyy"), 0644)) - old2 := old.Add(10 * time.Second) - tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"), old2, old2)) - tg.run("test", "testcache", "-run=FileContent") - tg.grepStdoutNot(`\(cached\)`, "did not notice file content change") - tg.run("test", "testcache", "-run=FileContent") - tg.grepStdout(`\(cached\)`, "did not cache") - - tg.run("test", "testcache", "-run=DirList") - tg.run("test", "testcache", "-run=DirList") - tg.grepStdout(`\(cached\)`, "did not cache") - tg.must(os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/file.txt"))) - tg.run("test", "testcache", "-run=DirList") - tg.grepStdoutNot(`\(cached\)`, "did not notice directory change") - tg.run("test", "testcache", "-run=DirList") - tg.grepStdout(`\(cached\)`, "did not cache") - - tg.tempFile("file.txt", "") - tg.must(ioutil.WriteFile(filepath.Join(tg.pwd(), "testdata/src/testcache/testcachetmp_test.go"), []byte(`package testcache - - import ( - "os" - "testing" - ) - - func TestExternalFile(t *testing.T) { - os.Open(`+fmt.Sprintf("%q", tg.path("file.txt"))+`) - _, err := os.Stat(`+fmt.Sprintf("%q", tg.path("file.txt"))+`) - if err != nil { - t.Fatal(err) - } - } - `), 0666)) - defer os.Remove(filepath.Join(tg.pwd(), "testdata/src/testcache/testcachetmp_test.go")) - tg.run("test", "testcache", "-run=ExternalFile") - tg.run("test", "testcache", "-run=ExternalFile") - tg.grepStdout(`\(cached\)`, "did not cache") - tg.must(os.Remove(filepath.Join(tg.tempdir, "file.txt"))) - tg.run("test", "testcache", "-run=ExternalFile") - tg.grepStdout(`\(cached\)`, "did not cache") - - switch runtime.GOOS { - case "nacl", "plan9", "windows": - // no shell scripts - default: - tg.run("test", "testcache", "-run=Exec") - tg.run("test", "testcache", "-run=Exec") - tg.grepStdout(`\(cached\)`, "did not cache") - tg.must(os.Chtimes(filepath.Join(tg.pwd(), "testdata/src/testcache/script.sh"), old2, old2)) - tg.run("test", "testcache", "-run=Exec") - tg.grepStdoutNot(`\(cached\)`, "did not notice script change") - tg.run("test", "testcache", "-run=Exec") - tg.grepStdout(`\(cached\)`, "did not cache") - } -} - func TestTestVet(t *testing.T) { tooSlow(t) tg := testgo(t) @@ -5761,14 +4964,6 @@ func TestInstallDeps(t *testing.T) { tg.mustExist(p1) } -func TestFmtLoadErrors(t *testing.T) { - tg := testgo(t) - defer tg.cleanup() - tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) - tg.runFail("fmt", "does-not-exist") - tg.run("fmt", "-n", "exclude") -} - func TestGoTestMinusN(t *testing.T) { // Intent here is to verify that 'go test -n' works without crashing. // This reuses flag_test.go, but really any test would do. diff --git a/libgo/go/cmd/go/help_test.go b/libgo/go/cmd/go/help_test.go index 9c0fa8411ee..9bcab820ce6 100644 --- a/libgo/go/cmd/go/help_test.go +++ b/libgo/go/cmd/go/help_test.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !nacl - package main_test import ( diff --git a/libgo/go/cmd/go/internal/base/flag.go b/libgo/go/cmd/go/internal/base/flag.go index 5e03e640588..6727196816b 100644 --- a/libgo/go/cmd/go/internal/base/flag.go +++ b/libgo/go/cmd/go/internal/base/flag.go @@ -33,3 +33,8 @@ func AddBuildFlagsNX(flags *flag.FlagSet) { flags.BoolVar(&cfg.BuildN, "n", false, "") flags.BoolVar(&cfg.BuildX, "x", false, "") } + +// AddLoadFlags adds the -mod build flag to the flag set. +func AddLoadFlags(flags *flag.FlagSet) { + flags.StringVar(&cfg.BuildMod, "mod", "", "") +} diff --git a/libgo/go/cmd/go/internal/base/signal_unix.go b/libgo/go/cmd/go/internal/base/signal_unix.go index 5aa7703ca3a..2b1507be27c 100644 --- a/libgo/go/cmd/go/internal/base/signal_unix.go +++ b/libgo/go/cmd/go/internal/base/signal_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js linux netbsd openbsd solaris package base diff --git a/libgo/go/cmd/go/internal/cache/cache.go b/libgo/go/cmd/go/internal/cache/cache.go index a05a08f75fc..87973987650 100644 --- a/libgo/go/cmd/go/internal/cache/cache.go +++ b/libgo/go/cmd/go/internal/cache/cache.go @@ -74,7 +74,22 @@ func (c *Cache) fileName(id [HashSize]byte, key string) string { return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key) } -var errMissing = errors.New("cache entry not found") +// An entryNotFoundError indicates that a cache entry was not found, with an +// optional underlying reason. +type entryNotFoundError struct { + Err error +} + +func (e *entryNotFoundError) Error() string { + if e.Err == nil { + return "cache entry not found" + } + return fmt.Sprintf("cache entry not found: %v", e.Err) +} + +func (e *entryNotFoundError) Unwrap() error { + return e.Err +} const ( // action entry file is "v1 \n" @@ -93,6 +108,8 @@ const ( // GODEBUG=gocacheverify=1. var verify = false +var errVerifyMode = errors.New("gocachverify=1") + // DebugTest is set when GODEBUG=gocachetest=1 is in the environment. var DebugTest = false @@ -121,7 +138,7 @@ func initEnv() { // saved file for that output ID is still available. func (c *Cache) Get(id ActionID) (Entry, error) { if verify { - return Entry{}, errMissing + return Entry{}, &entryNotFoundError{Err: errVerifyMode} } return c.get(id) } @@ -134,47 +151,60 @@ type Entry struct { // get is Get but does not respect verify mode, so that Put can use it. func (c *Cache) get(id ActionID) (Entry, error) { - missing := func() (Entry, error) { - return Entry{}, errMissing + missing := func(reason error) (Entry, error) { + return Entry{}, &entryNotFoundError{Err: reason} } f, err := os.Open(c.fileName(id, "a")) if err != nil { - return missing() + return missing(err) } defer f.Close() entry := make([]byte, entrySize+1) // +1 to detect whether f is too long - if n, err := io.ReadFull(f, entry); n != entrySize || err != io.ErrUnexpectedEOF { - return missing() + if n, err := io.ReadFull(f, entry); n > entrySize { + return missing(errors.New("too long")) + } else if err != io.ErrUnexpectedEOF { + if err == io.EOF { + return missing(errors.New("file is empty")) + } + return missing(err) + } else if n < entrySize { + return missing(errors.New("entry file incomplete")) } if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' { - return missing() + return missing(errors.New("invalid header")) } eid, entry := entry[3:3+hexSize], entry[3+hexSize:] eout, entry := entry[1:1+hexSize], entry[1+hexSize:] esize, entry := entry[1:1+20], entry[1+20:] etime, entry := entry[1:1+20], entry[1+20:] var buf [HashSize]byte - if _, err := hex.Decode(buf[:], eid); err != nil || buf != id { - return missing() + if _, err := hex.Decode(buf[:], eid); err != nil { + return missing(fmt.Errorf("decoding ID: %v", err)) + } else if buf != id { + return missing(errors.New("mismatched ID")) } if _, err := hex.Decode(buf[:], eout); err != nil { - return missing() + return missing(fmt.Errorf("decoding output ID: %v", err)) } i := 0 for i < len(esize) && esize[i] == ' ' { i++ } size, err := strconv.ParseInt(string(esize[i:]), 10, 64) - if err != nil || size < 0 { - return missing() + if err != nil { + return missing(fmt.Errorf("parsing size: %v", err)) + } else if size < 0 { + return missing(errors.New("negative size")) } i = 0 for i < len(etime) && etime[i] == ' ' { i++ } tm, err := strconv.ParseInt(string(etime[i:]), 10, 64) - if err != nil || tm < 0 { - return missing() + if err != nil { + return missing(fmt.Errorf("parsing timestamp: %v", err)) + } else if tm < 0 { + return missing(errors.New("negative timestamp")) } c.used(c.fileName(id, "a")) @@ -191,8 +221,11 @@ func (c *Cache) GetFile(id ActionID) (file string, entry Entry, err error) { } file = c.OutputFile(entry.OutputID) info, err := os.Stat(file) - if err != nil || info.Size() != entry.Size { - return "", Entry{}, errMissing + if err != nil { + return "", Entry{}, &entryNotFoundError{Err: err} + } + if info.Size() != entry.Size { + return "", Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")} } return file, entry, nil } @@ -207,7 +240,7 @@ func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) { } data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID)) if sha256.Sum256(data) != entry.OutputID { - return nil, entry, errMissing + return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")} } return data, entry, nil } diff --git a/libgo/go/cmd/go/internal/cfg/cfg.go b/libgo/go/cmd/go/internal/cfg/cfg.go index a3277a6c3f0..61dc6bdda66 100644 --- a/libgo/go/cmd/go/internal/cfg/cfg.go +++ b/libgo/go/cmd/go/internal/cfg/cfg.go @@ -27,6 +27,7 @@ var ( BuildBuildmode string // -buildmode flag BuildContext = defaultContext() BuildMod string // -mod flag + BuildModReason string // reason -mod flag is set, if set by default BuildI bool // -i flag BuildLinkshared bool // -linkshared flag BuildMSan bool // -msan flag @@ -44,6 +45,9 @@ var ( BuildWork bool // -work flag BuildX bool // -x flag + ModCacheRW bool // -modcacherw flag + ModFile string // -modfile flag + CmdName string // "build", "install", "list", "mod tidy", etc. DebugActiongraph string // -debug-actiongraph flag (undocumented, unstable) @@ -241,11 +245,12 @@ var ( GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", objabi.GOPPC64)) GOWASM = envOr("GOWASM", fmt.Sprint(objabi.GOWASM)) - GOPROXY = envOr("GOPROXY", "https://proxy.golang.org,direct") - GOSUMDB = envOr("GOSUMDB", "sum.golang.org") - GOPRIVATE = Getenv("GOPRIVATE") - GONOPROXY = envOr("GONOPROXY", GOPRIVATE) - GONOSUMDB = envOr("GONOSUMDB", GOPRIVATE) + GOPROXY = envOr("GOPROXY", "https://proxy.golang.org,direct") + GOSUMDB = envOr("GOSUMDB", "sum.golang.org") + GOPRIVATE = Getenv("GOPRIVATE") + GONOPROXY = envOr("GONOPROXY", GOPRIVATE) + GONOSUMDB = envOr("GONOSUMDB", GOPRIVATE) + GOINSECURE = Getenv("GOINSECURE") ) // GetArchEnv returns the name and setting of the diff --git a/libgo/go/cmd/go/internal/clean/clean.go b/libgo/go/cmd/go/internal/clean/clean.go index f7d80ff6dc8..5f4bf4e6c8e 100644 --- a/libgo/go/cmd/go/internal/clean/clean.go +++ b/libgo/go/cmd/go/internal/clean/clean.go @@ -102,7 +102,7 @@ func init() { // mentioned explicitly in the docs but they // are part of the build flags. - work.AddBuildFlags(CmdClean) + work.AddBuildFlags(CmdClean, work.DefaultBuildFlags) } func runClean(cmd *base.Command, args []string) { diff --git a/libgo/go/cmd/go/internal/dirhash/hash.go b/libgo/go/cmd/go/internal/dirhash/hash.go deleted file mode 100644 index 61d8face567..00000000000 --- a/libgo/go/cmd/go/internal/dirhash/hash.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package dirhash defines hashes over directory trees. -package dirhash - -import ( - "archive/zip" - "crypto/sha256" - "encoding/base64" - "errors" - "fmt" - "io" - "os" - "path/filepath" - "sort" - "strings" -) - -var DefaultHash = Hash1 - -type Hash func(files []string, open func(string) (io.ReadCloser, error)) (string, error) - -func Hash1(files []string, open func(string) (io.ReadCloser, error)) (string, error) { - h := sha256.New() - files = append([]string(nil), files...) - sort.Strings(files) - for _, file := range files { - if strings.Contains(file, "\n") { - return "", errors.New("filenames with newlines are not supported") - } - r, err := open(file) - if err != nil { - return "", err - } - hf := sha256.New() - _, err = io.Copy(hf, r) - r.Close() - if err != nil { - return "", err - } - fmt.Fprintf(h, "%x %s\n", hf.Sum(nil), file) - } - return "h1:" + base64.StdEncoding.EncodeToString(h.Sum(nil)), nil -} - -func HashDir(dir, prefix string, hash Hash) (string, error) { - files, err := DirFiles(dir, prefix) - if err != nil { - return "", err - } - osOpen := func(name string) (io.ReadCloser, error) { - return os.Open(filepath.Join(dir, strings.TrimPrefix(name, prefix))) - } - return hash(files, osOpen) -} - -func DirFiles(dir, prefix string) ([]string, error) { - var files []string - dir = filepath.Clean(dir) - err := filepath.Walk(dir, func(file string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if info.IsDir() { - return nil - } - rel := file - if dir != "." { - rel = file[len(dir)+1:] - } - f := filepath.Join(prefix, rel) - files = append(files, filepath.ToSlash(f)) - return nil - }) - if err != nil { - return nil, err - } - return files, nil -} - -func HashZip(zipfile string, hash Hash) (string, error) { - z, err := zip.OpenReader(zipfile) - if err != nil { - return "", err - } - defer z.Close() - var files []string - zfiles := make(map[string]*zip.File) - for _, file := range z.File { - files = append(files, file.Name) - zfiles[file.Name] = file - } - zipOpen := func(name string) (io.ReadCloser, error) { - f := zfiles[name] - if f == nil { - return nil, fmt.Errorf("file %q not found in zip", name) // should never happen - } - return f.Open() - } - return hash(files, zipOpen) -} diff --git a/libgo/go/cmd/go/internal/dirhash/hash_test.go b/libgo/go/cmd/go/internal/dirhash/hash_test.go deleted file mode 100644 index ed463c1949c..00000000000 --- a/libgo/go/cmd/go/internal/dirhash/hash_test.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dirhash - -import ( - "archive/zip" - "crypto/sha256" - "encoding/base64" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strings" - "testing" -) - -func h(s string) string { - return fmt.Sprintf("%x", sha256.Sum256([]byte(s))) -} - -func htop(k string, s string) string { - sum := sha256.Sum256([]byte(s)) - return k + ":" + base64.StdEncoding.EncodeToString(sum[:]) -} - -func TestHash1(t *testing.T) { - files := []string{"xyz", "abc"} - open := func(name string) (io.ReadCloser, error) { - return ioutil.NopCloser(strings.NewReader("data for " + name)), nil - } - want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "abc", h("data for xyz"), "xyz")) - out, err := Hash1(files, open) - if err != nil { - t.Fatal(err) - } - if out != want { - t.Errorf("Hash1(...) = %s, want %s", out, want) - } - - _, err = Hash1([]string{"xyz", "a\nbc"}, open) - if err == nil { - t.Error("Hash1: expected error on newline in filenames") - } -} - -func TestHashDir(t *testing.T) { - dir, err := ioutil.TempDir("", "dirhash-test-") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) - if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0666); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0666); err != nil { - t.Fatal(err) - } - want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "prefix/abc", h("data for xyz"), "prefix/xyz")) - out, err := HashDir(dir, "prefix", Hash1) - if err != nil { - t.Fatalf("HashDir: %v", err) - } - if out != want { - t.Errorf("HashDir(...) = %s, want %s", out, want) - } -} - -func TestHashZip(t *testing.T) { - f, err := ioutil.TempFile("", "dirhash-test-") - if err != nil { - t.Fatal(err) - } - defer os.Remove(f.Name()) - defer f.Close() - - z := zip.NewWriter(f) - w, err := z.Create("prefix/xyz") - if err != nil { - t.Fatal(err) - } - w.Write([]byte("data for xyz")) - w, err = z.Create("prefix/abc") - if err != nil { - t.Fatal(err) - } - w.Write([]byte("data for abc")) - if err := z.Close(); err != nil { - t.Fatal(err) - } - if err := f.Close(); err != nil { - t.Fatal(err) - } - - want := htop("h1", fmt.Sprintf("%s %s\n%s %s\n", h("data for abc"), "prefix/abc", h("data for xyz"), "prefix/xyz")) - out, err := HashZip(f.Name(), Hash1) - if err != nil { - t.Fatalf("HashDir: %v", err) - } - if out != want { - t.Errorf("HashDir(...) = %s, want %s", out, want) - } -} - -func TestDirFiles(t *testing.T) { - dir, err := ioutil.TempDir("", "dirfiles-test-") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(dir) - if err := ioutil.WriteFile(filepath.Join(dir, "xyz"), []byte("data for xyz"), 0666); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("data for abc"), 0666); err != nil { - t.Fatal(err) - } - if err := os.Mkdir(filepath.Join(dir, "subdir"), 0777); err != nil { - t.Fatal(err) - } - if err := ioutil.WriteFile(filepath.Join(dir, "subdir", "xyz"), []byte("data for subdir xyz"), 0666); err != nil { - t.Fatal(err) - } - prefix := "foo/bar@v2.3.4" - out, err := DirFiles(dir, prefix) - if err != nil { - t.Fatalf("DirFiles: %v", err) - } - for _, file := range out { - if !strings.HasPrefix(file, prefix) { - t.Errorf("Dir file = %s, want prefix %s", file, prefix) - } - } -} diff --git a/libgo/go/cmd/go/internal/doc/doc.go b/libgo/go/cmd/go/internal/doc/doc.go index bad05ff9128..4ff08bb9289 100644 --- a/libgo/go/cmd/go/internal/doc/doc.go +++ b/libgo/go/cmd/go/internal/doc/doc.go @@ -114,6 +114,8 @@ Flags: Treat a command (package main) like a regular package. Otherwise package main's exported symbols are hidden when showing the package's top-level documentation. + -short + One-line representation for each symbol. -src Show the full source code for the symbol. This will display the full Go source of its declaration and diff --git a/libgo/go/cmd/go/internal/envcmd/env.go b/libgo/go/cmd/go/internal/envcmd/env.go index 17852deed1e..d2d5ed95076 100644 --- a/libgo/go/cmd/go/internal/envcmd/env.go +++ b/libgo/go/cmd/go/internal/envcmd/env.go @@ -8,6 +8,7 @@ package envcmd import ( "encoding/json" "fmt" + "go/build" "io/ioutil" "os" "path/filepath" @@ -75,6 +76,7 @@ func MkEnv() []cfg.EnvVar { {Name: "GOFLAGS", Value: cfg.Getenv("GOFLAGS")}, {Name: "GOHOSTARCH", Value: runtime.GOARCH}, {Name: "GOHOSTOS", Value: runtime.GOOS}, + {Name: "GOINSECURE", Value: cfg.GOINSECURE}, {Name: "GONOPROXY", Value: cfg.GONOPROXY}, {Name: "GONOSUMDB", Value: cfg.GONOSUMDB}, {Name: "GOOS", Value: cfg.Goos}, @@ -237,7 +239,7 @@ func runEnv(cmd *base.Command, args []string) { base.Fatalf("go env -w: arguments must be KEY=VALUE: invalid argument: %s", arg) } key, val := arg[:i], arg[i+1:] - if err := checkEnvWrite(key, val, env); err != nil { + if err := checkEnvWrite(key, val); err != nil { base.Fatalf("go env -w: %v", err) } if _, ok := add[key]; ok { @@ -248,6 +250,21 @@ func runEnv(cmd *base.Command, args []string) { fmt.Fprintf(os.Stderr, "warning: go env -w %s=... does not override conflicting OS environment variable\n", key) } } + + goos, okGOOS := add["GOOS"] + goarch, okGOARCH := add["GOARCH"] + if okGOOS || okGOARCH { + if !okGOOS { + goos = cfg.Goos + } + if !okGOARCH { + goarch = cfg.Goarch + } + if err := work.CheckGOOSARCHPair(goos, goarch); err != nil { + base.Fatalf("go env -w: %v", err) + } + } + updateEnvFile(add, nil) return } @@ -259,11 +276,29 @@ func runEnv(cmd *base.Command, args []string) { } del := make(map[string]bool) for _, arg := range args { - if err := checkEnvWrite(arg, "", env); err != nil { + if err := checkEnvWrite(arg, ""); err != nil { base.Fatalf("go env -u: %v", err) } del[arg] = true } + if del["GOOS"] || del["GOARCH"] { + goos, goarch := cfg.Goos, cfg.Goarch + if del["GOOS"] { + goos = getOrigEnv("GOOS") + if goos == "" { + goos = build.Default.GOOS + } + } + if del["GOARCH"] { + goarch = getOrigEnv("GOARCH") + if goarch == "" { + goarch = build.Default.GOARCH + } + } + if err := work.CheckGOOSARCHPair(goos, goarch); err != nil { + base.Fatalf("go env -u: %v", err) + } + } updateEnvFile(nil, del) return } @@ -330,7 +365,16 @@ func printEnvAsJSON(env []cfg.EnvVar) { } } -func checkEnvWrite(key, val string, env []cfg.EnvVar) error { +func getOrigEnv(key string) string { + for _, v := range cfg.OrigEnv { + if strings.HasPrefix(v, key+"=") { + return strings.TrimPrefix(v, key+"=") + } + } + return "" +} + +func checkEnvWrite(key, val string) error { switch key { case "GOEXE", "GOGCCFLAGS", "GOHOSTARCH", "GOHOSTOS", "GOMOD", "GOTOOLDIR": return fmt.Errorf("%s cannot be modified", key) @@ -343,6 +387,25 @@ func checkEnvWrite(key, val string, env []cfg.EnvVar) error { return fmt.Errorf("unknown go command variable %s", key) } + // Some variables can only have one of a few valid values. If set to an + // invalid value, the next cmd/go invocation might fail immediately, + // even 'go env -w' itself. + switch key { + case "GO111MODULE": + switch val { + case "", "auto", "on", "off": + default: + return fmt.Errorf("invalid %s value %q", key, val) + } + case "GOPATH": + if strings.HasPrefix(val, "~") { + return fmt.Errorf("GOPATH entry cannot start with shell metacharacter '~': %q", val) + } + if !filepath.IsAbs(val) && val != "" { + return fmt.Errorf("GOPATH entry is relative; must be absolute path: %q", val) + } + } + if !utf8.ValidString(val) { return fmt.Errorf("invalid UTF-8 in %s=... value", key) } diff --git a/libgo/go/cmd/go/internal/fmtcmd/fmt.go b/libgo/go/cmd/go/internal/fmtcmd/fmt.go index 8e4ef372816..408af52ffa0 100644 --- a/libgo/go/cmd/go/internal/fmtcmd/fmt.go +++ b/libgo/go/cmd/go/internal/fmtcmd/fmt.go @@ -22,6 +22,7 @@ import ( func init() { base.AddBuildFlagsNX(&CmdFmt.Flag) + base.AddLoadFlags(&CmdFmt.Flag) } var CmdFmt = &base.Command{ @@ -38,6 +39,9 @@ For more about specifying packages, see 'go help packages'. The -n flag prints commands that would be executed. The -x flag prints commands as they are executed. +The -mod flag's value sets which module download mode +to use: readonly or vendor. See 'go help modules' for more. + To run gofmt with specific options, run gofmt itself. See also: go fix, go vet. @@ -68,7 +72,7 @@ func runFmt(cmd *base.Command, args []string) { continue } if pkg.Error != nil { - if strings.HasPrefix(pkg.Error.Err, "build constraints exclude all Go files") { + if strings.HasPrefix(pkg.Error.Err.Error(), "build constraints exclude all Go files") { // Skip this error, as we will format // all files regardless. } else { diff --git a/libgo/go/cmd/go/internal/generate/generate.go b/libgo/go/cmd/go/internal/generate/generate.go index f2ae80e5dc6..198ca1c1b94 100644 --- a/libgo/go/cmd/go/internal/generate/generate.go +++ b/libgo/go/cmd/go/internal/generate/generate.go @@ -149,7 +149,7 @@ var ( ) func init() { - work.AddBuildFlags(CmdGenerate) + work.AddBuildFlags(CmdGenerate, work.DefaultBuildFlags) CmdGenerate.Flag.StringVar(&generateRunFlag, "run", "", "") } diff --git a/libgo/go/cmd/go/internal/get/discovery.go b/libgo/go/cmd/go/internal/get/discovery.go index 6ba5c091e39..afa6ef455f9 100644 --- a/libgo/go/cmd/go/internal/get/discovery.go +++ b/libgo/go/cmd/go/internal/get/discovery.go @@ -11,15 +11,15 @@ import ( "strings" ) -// charsetReader returns a reader for the given charset. Currently -// it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful +// charsetReader returns a reader that converts from the given charset to UTF-8. +// Currently it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful // error which is printed by go get, so the user can find why the package // wasn't downloaded if the encoding is not supported. Note that, in // order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters // greater than 0x7f are not rejected). func charsetReader(charset string, input io.Reader) (io.Reader, error) { switch strings.ToLower(charset) { - case "ascii": + case "utf-8", "ascii": return input, nil default: return nil, fmt.Errorf("can't decode XML document using charset %q", charset) @@ -28,16 +28,16 @@ func charsetReader(charset string, input io.Reader) (io.Reader, error) { // parseMetaGoImports returns meta imports from the HTML in r. // Parsing ends at the end of the section or the beginning of the . -func parseMetaGoImports(r io.Reader, mod ModuleMode) (imports []metaImport, err error) { +func parseMetaGoImports(r io.Reader, mod ModuleMode) ([]metaImport, error) { d := xml.NewDecoder(r) d.CharsetReader = charsetReader d.Strict = false - var t xml.Token + var imports []metaImport for { - t, err = d.RawToken() + t, err := d.RawToken() if err != nil { - if err == io.EOF || len(imports) > 0 { - err = nil + if err != io.EOF && len(imports) == 0 { + return nil, err } break } diff --git a/libgo/go/cmd/go/internal/get/get.go b/libgo/go/cmd/go/internal/get/get.go index e4945fe1440..500e3e0da6d 100644 --- a/libgo/go/cmd/go/internal/get/get.go +++ b/libgo/go/cmd/go/internal/get/get.go @@ -108,7 +108,7 @@ var ( ) func init() { - work.AddBuildFlags(CmdGet) + work.AddBuildFlags(CmdGet, work.OmitModFlag|work.OmitModCommonFlags) CmdGet.Run = runGet // break init loop CmdGet.Flag.BoolVar(&Insecure, "insecure", Insecure, "") } @@ -274,7 +274,7 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) stk.Push(arg) err := downloadPackage(p) if err != nil { - base.Errorf("%s", &load.PackageError{ImportStack: stk.Copy(), Err: err.Error()}) + base.Errorf("%s", &load.PackageError{ImportStack: stk.Copy(), Err: err}) stk.Pop() return } @@ -355,7 +355,7 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) stk.Push(path) err := &load.PackageError{ ImportStack: stk.Copy(), - Err: "must be imported as " + path[j+len("vendor/"):], + Err: load.ImportErrorf(path, "%s must be imported as %s", path, path[j+len("vendor/"):]), } stk.Pop() base.Errorf("%s", err) diff --git a/libgo/go/cmd/go/internal/get/path.go b/libgo/go/cmd/go/internal/get/path.go index 67d7b8a47c2..ce2e0cdd709 100644 --- a/libgo/go/cmd/go/internal/get/path.go +++ b/libgo/go/cmd/go/internal/get/path.go @@ -11,7 +11,7 @@ import ( "unicode/utf8" ) -// The following functions are copied verbatim from cmd/go/internal/module/module.go, +// The following functions are copied verbatim from golang.org/x/mod/module/module.go, // with a change to additionally reject Windows short-names, // and one to accept arbitrary letters (golang.org/issue/29101). // @@ -44,9 +44,6 @@ func checkPath(path string, fileName bool) error { if path[0] == '-' { return fmt.Errorf("leading dash") } - if strings.Contains(path, "..") { - return fmt.Errorf("double dot") - } if strings.Contains(path, "//") { return fmt.Errorf("double slash") } diff --git a/libgo/go/cmd/go/internal/get/vcs.go b/libgo/go/cmd/go/internal/get/vcs.go index 705bb66dbe2..2e4d6388cfe 100644 --- a/libgo/go/cmd/go/internal/get/vcs.go +++ b/libgo/go/cmd/go/internal/get/vcs.go @@ -21,6 +21,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/load" "cmd/go/internal/web" ) @@ -531,12 +532,12 @@ func (v *vcsCmd) tagSync(dir, tag string) error { // A vcsPath describes how to convert an import path into a // version control system and repository name. type vcsPath struct { - prefix string // prefix this description applies to - regexp *lazyregexp.Regexp // compiled pattern for import path - repo string // repository to use (expand with match of re) - vcs string // version control system to use (expand with match of re) - check func(match map[string]string) error // additional checks - ping bool // ping for scheme to use to download repo + prefix string // prefix this description applies to + regexp *lazyregexp.Regexp // compiled pattern for import path + repo string // repository to use (expand with match of re) + vcs string // version control system to use (expand with match of re) + check func(match map[string]string) error // additional checks + schemelessRepo bool // if true, the repo pattern lacks a scheme } // vcsFromDir inspects dir and its parents to determine the @@ -657,15 +658,15 @@ const ( // RepoRootForImportPath analyzes importPath to determine the // version control system, and code repository to use. func RepoRootForImportPath(importPath string, mod ModuleMode, security web.SecurityMode) (*RepoRoot, error) { - rr, err := repoRootFromVCSPaths(importPath, "", security, vcsPaths) + rr, err := repoRootFromVCSPaths(importPath, security, vcsPaths) if err == errUnknownSite { rr, err = repoRootForImportDynamic(importPath, mod, security) if err != nil { - err = fmt.Errorf("unrecognized import path %q (%v)", importPath, err) + err = load.ImportErrorf(importPath, "unrecognized import path %q: %v", importPath, err) } } if err != nil { - rr1, err1 := repoRootFromVCSPaths(importPath, "", security, vcsPathsAfterDynamic) + rr1, err1 := repoRootFromVCSPaths(importPath, security, vcsPathsAfterDynamic) if err1 == nil { rr = rr1 err = nil @@ -676,7 +677,7 @@ func RepoRootForImportPath(importPath string, mod ModuleMode, security web.Secur if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.Root, "...") { // Do not allow wildcards in the repo root. rr = nil - err = fmt.Errorf("cannot expand ... in %q", importPath) + err = load.ImportErrorf(importPath, "cannot expand ... in %q", importPath) } return rr, err } @@ -685,8 +686,7 @@ var errUnknownSite = errors.New("dynamic lookup required to find mapping") // repoRootFromVCSPaths attempts to map importPath to a repoRoot // using the mappings defined in vcsPaths. -// If scheme is non-empty, that scheme is forced. -func repoRootFromVCSPaths(importPath, scheme string, security web.SecurityMode, vcsPaths []*vcsPath) (*RepoRoot, error) { +func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths []*vcsPath) (*RepoRoot, error) { // A common error is to use https://packagepath because that's what // hg and git require. Diagnose this helpfully. if prefix := httpPrefix(importPath); prefix != "" { @@ -701,7 +701,7 @@ func repoRootFromVCSPaths(importPath, scheme string, security web.SecurityMode, m := srv.regexp.FindStringSubmatch(importPath) if m == nil { if srv.prefix != "" { - return nil, fmt.Errorf("invalid %s import path %q", srv.prefix, importPath) + return nil, load.ImportErrorf(importPath, "invalid %s import path %q", srv.prefix, importPath) } continue } @@ -731,26 +731,28 @@ func repoRootFromVCSPaths(importPath, scheme string, security web.SecurityMode, if vcs == nil { return nil, fmt.Errorf("unknown version control system %q", match["vcs"]) } - if srv.ping { - if scheme != "" { - match["repo"] = scheme + "://" + match["repo"] - } else { - for _, scheme := range vcs.scheme { - if security == web.SecureOnly && !vcs.isSecureScheme(scheme) { + var repoURL string + if !srv.schemelessRepo { + repoURL = match["repo"] + } else { + scheme := vcs.scheme[0] // default to first scheme + repo := match["repo"] + if vcs.pingCmd != "" { + // If we know how to test schemes, scan to find one. + for _, s := range vcs.scheme { + if security == web.SecureOnly && !vcs.isSecureScheme(s) { continue } - if vcs.pingCmd != "" && vcs.ping(scheme, match["repo"]) == nil { - match["repo"] = scheme + "://" + match["repo"] - goto Found + if vcs.ping(s, repo) == nil { + scheme = s + break } } - // No scheme found. Fall back to the first one. - match["repo"] = vcs.scheme[0] + "://" + match["repo"] - Found: } + repoURL = scheme + "://" + repo } rr := &RepoRoot{ - Repo: match["repo"], + Repo: repoURL, Root: match["root"], VCS: vcs.cmd, vcs: vcs, @@ -799,6 +801,13 @@ func repoRootForImportDynamic(importPath string, mod ModuleMode, security web.Se body := resp.Body defer body.Close() imports, err := parseMetaGoImports(body, mod) + if len(imports) == 0 { + if respErr := resp.Err(); respErr != nil { + // If the server's status was not OK, prefer to report that instead of + // an XML parse error. + return nil, respErr + } + } if err != nil { return nil, fmt.Errorf("parsing %s: %v", importPath, err) } @@ -904,16 +913,23 @@ func metaImportsForPrefix(importPrefix string, mod ModuleMode, security web.Secu } resp, err := web.Get(security, url) if err != nil { - return setCache(fetchResult{url: url, err: fmt.Errorf("fetch %s: %v", resp.URL, err)}) + return setCache(fetchResult{url: url, err: fmt.Errorf("fetching %s: %v", importPrefix, err)}) } body := resp.Body defer body.Close() imports, err := parseMetaGoImports(body, mod) + if len(imports) == 0 { + if respErr := resp.Err(); respErr != nil { + // If the server's status was not OK, prefer to report that instead of + // an XML parse error. + return setCache(fetchResult{url: url, err: respErr}) + } + } if err != nil { return setCache(fetchResult{url: url, err: fmt.Errorf("parsing %s: %v", resp.URL, err)}) } if len(imports) == 0 { - err = fmt.Errorf("fetch %s: no go-import meta tag", url) + err = fmt.Errorf("fetching %s: no go-import meta tag found in %s", importPrefix, resp.URL) } return setCache(fetchResult{url: url, imports: imports, err: err}) }) @@ -962,7 +978,7 @@ func (m ImportMismatchError) Error() string { // matchGoImport returns the metaImport from imports matching importPath. // An error is returned if there are multiple matches. -// errNoMatch is returned if none match. +// An ImportMismatchError is returned if none match. func matchGoImport(imports []metaImport, importPath string) (metaImport, error) { match := -1 @@ -1061,8 +1077,8 @@ var vcsPaths = []*vcsPath{ // General syntax for any server. // Must be last. { - regexp: lazyregexp.New(`(?P(?P([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[A-Za-z0-9_.\-]+)+?)\.(?Pbzr|fossil|git|hg|svn))(/~?[A-Za-z0-9_.\-]+)*$`), - ping: true, + regexp: lazyregexp.New(`(?P(?P([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?(/~?[A-Za-z0-9_.\-]+)+?)\.(?Pbzr|fossil|git|hg|svn))(/~?[A-Za-z0-9_.\-]+)*$`), + schemelessRepo: true, }, } diff --git a/libgo/go/cmd/go/internal/help/helpdoc.go b/libgo/go/cmd/go/internal/help/helpdoc.go index dfb89d4910b..6a843f459a8 100644 --- a/libgo/go/cmd/go/internal/help/helpdoc.go +++ b/libgo/go/cmd/go/internal/help/helpdoc.go @@ -21,8 +21,8 @@ http://swig.org/. When running go build, any file with a .swig extension will be passed to SWIG. Any file with a .swigcxx extension will be passed to SWIG with the -c++ option. -When either cgo or SWIG is used, go build will pass any .c, .m, .s, -or .S files to the C compiler, and any .cc, .cpp, .cxx files to the C++ +When either cgo or SWIG is used, go build will pass any .c, .m, .s, .S +or .sx files to the C compiler, and any .cc, .cpp, .cxx files to the C++ compiler. The CC or CXX environment variables may be set to determine the C or C++ compiler, respectively, to use. `, @@ -506,6 +506,10 @@ General-purpose environment variables: Because the entries are space-separated, flag values must not contain spaces. Flags listed on the command line are applied after this list and therefore override it. + GOINSECURE + Comma-separated list of glob patterns (in the syntax of Go's path.Match) + of module path prefixes that should always be fetched in an insecure + manner. Only applies to dependencies that are being fetched directly. GOOS The operating system for which to compile code. Examples are linux, darwin, windows, netbsd. @@ -617,8 +621,10 @@ Additional information available from 'go env' but not read from the environment GOHOSTOS The operating system (GOOS) of the Go toolchain binaries. GOMOD - The absolute path to the go.mod of the main module, - or the empty string if not using modules. + The absolute path to the go.mod of the main module. + If module-aware mode is enabled, but there is no go.mod, GOMOD will be + os.DevNull ("/dev/null" on Unix-like systems, "NUL" on Windows). + If module-aware mode is disabled, GOMOD will be the empty string. GOTOOLDIR The directory where the go tools (compile, cover, doc, etc...) are installed. `, @@ -645,7 +651,7 @@ the extension of the file name. These extensions are: .m Objective-C source files. Only useful with cgo, and always compiled with the OS-native compiler. - .s, .S + .s, .S, .sx Assembler source files. If the package uses cgo or SWIG, these will be assembled with the OS-native assembler (typically gcc (sic)); otherwise they diff --git a/libgo/go/cmd/go/internal/imports/build.go b/libgo/go/cmd/go/internal/imports/build.go index 3e9fe357e07..eb070eef4c1 100644 --- a/libgo/go/cmd/go/internal/imports/build.go +++ b/libgo/go/cmd/go/internal/imports/build.go @@ -210,7 +210,7 @@ var KnownOS = map[string]bool{ "illumos": true, "js": true, "linux": true, - "nacl": true, + "nacl": true, // legacy; don't remove "netbsd": true, "openbsd": true, "plan9": true, @@ -222,7 +222,7 @@ var KnownOS = map[string]bool{ var KnownArch = map[string]bool{ "386": true, "amd64": true, - "amd64p32": true, + "amd64p32": true, // legacy; don't remove "arm": true, "armbe": true, "arm64": true, diff --git a/libgo/go/cmd/go/internal/list/list.go b/libgo/go/cmd/go/internal/list/list.go index a5f1abe64ae..b393c67ddb2 100644 --- a/libgo/go/cmd/go/internal/list/list.go +++ b/libgo/go/cmd/go/internal/list/list.go @@ -287,7 +287,7 @@ For more about modules, see 'go help modules'. func init() { CmdList.Run = runList // break init cycle - work.AddBuildFlags(CmdList) + work.AddBuildFlags(CmdList, work.DefaultBuildFlags) } var ( @@ -384,6 +384,22 @@ func runList(cmd *base.Command, args []string) { if modload.Init(); !modload.Enabled() { base.Fatalf("go list -m: not using modules") } + + modload.InitMod() // Parses go.mod and sets cfg.BuildMod. + if cfg.BuildMod == "vendor" { + for _, arg := range args { + // In vendor mode, the module graph is incomplete: it contains only the + // explicit module dependencies and the modules that supply packages in + // the import graph. Reject queries that imply more information than that. + if arg == "all" { + base.Fatalf("go list -m: can't compute 'all' using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)") + } + if strings.Contains(arg, "...") { + base.Fatalf("go list -m: can't match module patterns using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)") + } + } + } + modload.LoadBuildList() mods := modload.ListModules(args, *listU, *listVersions) diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index a50450ee054..06b6e23e633 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -7,9 +7,11 @@ package load import ( "bytes" + "encoding/json" "errors" "fmt" "go/build" + "go/scanner" "go/token" "io/ioutil" "os" @@ -40,7 +42,7 @@ var ( ModPackageModuleInfo func(path string) *modinfo.ModulePublic // return module info for Package struct ModImportPaths func(args []string) []*search.Match // expand import paths ModPackageBuildInfo func(main string, deps []string) string // return module info to embed in binary - ModInfoProg func(info string) []byte // wrap module info in .go code for binary + ModInfoProg func(info string, isgccgo bool) []byte // wrap module info in .go code for binary ModImportFromFiles func([]string) // update go.mod to add modules for imports in these files ModDirImportPath func(string) string // return effective import path for directory ) @@ -304,9 +306,9 @@ func (p *Package) copyBuild(pp *build.Package) { type PackageError struct { ImportStack []string // shortest path from package named on command line to this one Pos string // position of error - Err string // the error itself - IsImportCycle bool `json:"-"` // the error is an import cycle - Hard bool `json:"-"` // whether the error is soft or hard; soft errors are ignored in some places + Err error // the error itself + IsImportCycle bool // the error is an import cycle + Hard bool // whether the error is soft or hard; soft errors are ignored in some places } func (p *PackageError) Error() string { @@ -317,12 +319,77 @@ func (p *PackageError) Error() string { if p.Pos != "" { // Omit import stack. The full path to the file where the error // is the most important thing. - return p.Pos + ": " + p.Err + return p.Pos + ": " + p.Err.Error() } - if len(p.ImportStack) == 0 { - return p.Err + + // If the error is an ImportPathError, and the last path on the stack appears + // in the error message, omit that path from the stack to avoid repetition. + // If an ImportPathError wraps another ImportPathError that matches the + // last path on the stack, we don't omit the path. An error like + // "package A imports B: error loading C caused by B" would not be clearer + // if "imports B" were omitted. + stack := p.ImportStack + var ierr ImportPathError + if len(stack) > 0 && errors.As(p.Err, &ierr) && ierr.ImportPath() == stack[len(stack)-1] { + stack = stack[:len(stack)-1] + } + if len(stack) == 0 { + return p.Err.Error() + } + return "package " + strings.Join(stack, "\n\timports ") + ": " + p.Err.Error() +} + +// PackageError implements MarshalJSON so that Err is marshaled as a string +// and non-essential fields are omitted. +func (p *PackageError) MarshalJSON() ([]byte, error) { + perr := struct { + ImportStack []string + Pos string + Err string + }{p.ImportStack, p.Pos, p.Err.Error()} + return json.Marshal(perr) +} + +// ImportPathError is a type of error that prevents a package from being loaded +// for a given import path. When such a package is loaded, a *Package is +// returned with Err wrapping an ImportPathError: the error is attached to +// the imported package, not the importing package. +// +// The string returned by ImportPath must appear in the string returned by +// Error. Errors that wrap ImportPathError (such as PackageError) may omit +// the import path. +type ImportPathError interface { + error + ImportPath() string +} + +type importError struct { + importPath string + err error // created with fmt.Errorf +} + +var _ ImportPathError = (*importError)(nil) + +func ImportErrorf(path, format string, args ...interface{}) ImportPathError { + err := &importError{importPath: path, err: fmt.Errorf(format, args...)} + if errStr := err.Error(); !strings.Contains(errStr, path) { + panic(fmt.Sprintf("path %q not in error %q", path, errStr)) } - return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err + return err +} + +func (e *importError) Error() string { + return e.err.Error() +} + +func (e *importError) Unwrap() error { + // Don't return e.err directly, since we're only wrapping an error if %w + // was passed to ImportErrorf. + return errors.Unwrap(e.err) +} + +func (e *importError) ImportPath() string { + return e.importPath } // An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended. @@ -489,7 +556,7 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS ImportPath: path, Error: &PackageError{ ImportStack: stk.Copy(), - Err: err.Error(), + Err: err, }, }, } @@ -516,7 +583,7 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS if !cfg.ModulesEnabled && path != cleanImport(path) { p.Error = &PackageError{ ImportStack: stk.Copy(), - Err: fmt.Sprintf("non-canonical import path: %q should be %q", path, pathpkg.Clean(path)), + Err: fmt.Errorf("non-canonical import path: %q should be %q", path, pathpkg.Clean(path)), } p.Incomplete = true } @@ -527,7 +594,7 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS return setErrorPos(perr, importPos) } if mode&ResolveImport != 0 { - if perr := disallowVendor(srcDir, parent, parentPath, path, p, stk); perr != p { + if perr := disallowVendor(srcDir, path, p, stk); perr != p { return setErrorPos(perr, importPos) } } @@ -536,20 +603,22 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS perr := *p perr.Error = &PackageError{ ImportStack: stk.Copy(), - Err: fmt.Sprintf("import %q is a program, not an importable package", path), + Err: ImportErrorf(path, "import %q is a program, not an importable package", path), } return setErrorPos(&perr, importPos) } if p.Internal.Local && parent != nil && !parent.Internal.Local { perr := *p - errMsg := fmt.Sprintf("local import %q in non-local package", path) + var err error if path == "." { - errMsg = "cannot import current directory" + err = ImportErrorf(path, "%s: cannot import current directory", path) + } else { + err = ImportErrorf(path, "local import %q in non-local package", path) } perr.Error = &PackageError{ ImportStack: stk.Copy(), - Err: errMsg, + Err: err, } return setErrorPos(&perr, importPos) } @@ -602,6 +671,11 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd // we create from the full directory to the package. // Otherwise it is the usual import path. // For vendored imports, it is the expanded form. + // + // Note that when modules are enabled, local import paths are normally + // canonicalized by modload.ImportPaths before now. However, if there's an + // error resolving a local path, it will be returned untransformed + // so that 'go list -e' reports something useful. importKey := importSpec{ path: path, parentPath: parentPath, @@ -1125,7 +1199,7 @@ func reusePackage(p *Package, stk *ImportStack) *Package { if p.Error == nil { p.Error = &PackageError{ ImportStack: stk.Copy(), - Err: "import cycle not allowed", + Err: errors.New("import cycle not allowed"), IsImportCycle: true, } } @@ -1234,7 +1308,7 @@ func disallowInternal(srcDir string, importer *Package, importerPath string, p * perr := *p perr.Error = &PackageError{ ImportStack: stk.Copy(), - Err: "use of internal package " + p.ImportPath + " not allowed", + Err: ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"), } perr.Incomplete = true return &perr @@ -1259,11 +1333,10 @@ func findInternal(path string) (index int, ok bool) { return 0, false } -// disallowVendor checks that srcDir (containing package importerPath, if non-empty) -// is allowed to import p as path. +// disallowVendor checks that srcDir is allowed to import p as path. // If the import is allowed, disallowVendor returns the original package p. // If not, it returns a new package containing just an appropriate error. -func disallowVendor(srcDir string, importer *Package, importerPath, path string, p *Package, stk *ImportStack) *Package { +func disallowVendor(srcDir string, path string, p *Package, stk *ImportStack) *Package { // The stack includes p.ImportPath. // If that's the only thing on the stack, we started // with a name given on the command line, not an @@ -1281,7 +1354,7 @@ func disallowVendor(srcDir string, importer *Package, importerPath, path string, perr := *p perr.Error = &PackageError{ ImportStack: stk.Copy(), - Err: "must be imported as " + path[i+len("vendor/"):], + Err: ImportErrorf(path, "%s must be imported as %s", path, path[i+len("vendor/"):]), } perr.Incomplete = true return &perr @@ -1335,7 +1408,7 @@ func disallowVendorVisibility(srcDir string, p *Package, stk *ImportStack) *Pack perr := *p perr.Error = &PackageError{ ImportStack: stk.Copy(), - Err: "use of vendored package not allowed", + Err: errors.New("use of vendored package not allowed"), } perr.Incomplete = true return &perr @@ -1397,26 +1470,51 @@ var cgoSyscallExclude = map[string]bool{ var foldPath = make(map[string]string) -// DefaultExecName returns the default executable name -// for a package with the import path importPath. +// exeFromImportPath returns an executable name +// for a package using the import path. // -// The default executable name is the last element of the import path. +// The executable name is the last element of the import path. // In module-aware mode, an additional rule is used on import paths // consisting of two or more path elements. If the last element is // a vN path element specifying the major version, then the // second last element of the import path is used instead. -func DefaultExecName(importPath string) string { - _, elem := pathpkg.Split(importPath) +func (p *Package) exeFromImportPath() string { + _, elem := pathpkg.Split(p.ImportPath) if cfg.ModulesEnabled { // If this is example.com/mycmd/v2, it's more useful to // install it as mycmd than as v2. See golang.org/issue/24667. - if elem != importPath && isVersionElement(elem) { - _, elem = pathpkg.Split(pathpkg.Dir(importPath)) + if elem != p.ImportPath && isVersionElement(elem) { + _, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath)) } } return elem } +// exeFromFiles returns an executable name for a package +// using the first element in GoFiles or CgoFiles collections without the prefix. +// +// Returns empty string in case of empty collection. +func (p *Package) exeFromFiles() string { + var src string + if len(p.GoFiles) > 0 { + src = p.GoFiles[0] + } else if len(p.CgoFiles) > 0 { + src = p.CgoFiles[0] + } else { + return "" + } + _, elem := filepath.Split(src) + return elem[:len(elem)-len(".go")] +} + +// DefaultExecName returns the default executable name for a package +func (p *Package) DefaultExecName() string { + if p.Internal.CmdlineFiles { + return p.exeFromFiles() + } + return p.exeFromImportPath() +} + // load populates p using information from bp, err, which should // be the result of calling build.Context.Import. func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { @@ -1428,17 +1526,30 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { p.Internal.LocalPrefix = dirToImportPath(p.Dir) } + // setError sets p.Error if it hasn't already been set. We may proceed + // after encountering some errors so that 'go list -e' has more complete + // output. If there's more than one error, we should report the first. + setError := func(err error) { + if p.Error == nil { + p.Error = &PackageError{ + ImportStack: stk.Copy(), + Err: err, + } + } + } + if err != nil { if _, ok := err.(*build.NoGoError); ok { err = &NoGoError{Package: p} } p.Incomplete = true - err = base.ExpandScanner(err) - p.Error = &PackageError{ - ImportStack: stk.Copy(), - Err: err.Error(), + + setError(base.ExpandScanner(err)) + if _, isScanErr := err.(scanner.ErrorList); !isScanErr { + return } - return + // Fall through if there was an error parsing a file. 'go list -e' should + // still report imports and other metadata. } useBindir := p.Name == "main" @@ -1453,11 +1564,11 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // Report an error when the old code.google.com/p/go.tools paths are used. if InstallTargetDir(p) == StalePath { newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1) - e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath) - p.Error = &PackageError{Err: e} + e := ImportErrorf(p.ImportPath, "the %v command has moved; use %v instead.", p.ImportPath, newPath) + setError(e) return } - elem := DefaultExecName(p.ImportPath) + elem := p.DefaultExecName() full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH { // Install cross-compiled binaries to subdirectories of bin. @@ -1493,7 +1604,10 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { p.Target = "" } else { p.Target = p.Internal.Build.PkgObj - if cfg.BuildLinkshared { + if cfg.BuildLinkshared && p.Target != "" { + // TODO(bcmills): The reliance on p.Target implies that -linkshared does + // not work for any package that lacks a Target — such as a non-main + // package in module mode. We should probably fix that. shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname" shlib, err := ioutil.ReadFile(shlibnamefile) if err != nil && !os.IsNotExist(err) { @@ -1564,10 +1678,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { inputs := p.AllFiles() f1, f2 := str.FoldDup(inputs) if f1 != "" { - p.Error = &PackageError{ - ImportStack: stk.Copy(), - Err: fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2), - } + setError(fmt.Errorf("case-insensitive file name collision: %q and %q", f1, f2)) return } @@ -1580,25 +1691,16 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // so we shouldn't see any _cgo_ files anyway, but just be safe. for _, file := range inputs { if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") { - p.Error = &PackageError{ - ImportStack: stk.Copy(), - Err: fmt.Sprintf("invalid input file name %q", file), - } + setError(fmt.Errorf("invalid input file name %q", file)) return } } if name := pathpkg.Base(p.ImportPath); !SafeArg(name) { - p.Error = &PackageError{ - ImportStack: stk.Copy(), - Err: fmt.Sprintf("invalid input directory name %q", name), - } + setError(fmt.Errorf("invalid input directory name %q", name)) return } if !SafeArg(p.ImportPath) { - p.Error = &PackageError{ - ImportStack: stk.Copy(), - Err: fmt.Sprintf("invalid import path %q", p.ImportPath), - } + setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath)) return } @@ -1643,31 +1745,24 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { // code; see issue #16050). } - setError := func(msg string) { - p.Error = &PackageError{ - ImportStack: stk.Copy(), - Err: msg, - } - } - // The gc toolchain only permits C source files with cgo or SWIG. if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" { - setError(fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " "))) + setError(fmt.Errorf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " "))) return } // C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG, // regardless of toolchain. if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { - setError(fmt.Sprintf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " "))) + setError(fmt.Errorf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " "))) return } if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { - setError(fmt.Sprintf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " "))) + setError(fmt.Errorf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " "))) return } if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { - setError(fmt.Sprintf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " "))) + setError(fmt.Errorf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " "))) return } @@ -1676,17 +1771,17 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { if other := foldPath[fold]; other == "" { foldPath[fold] = p.ImportPath } else if other != p.ImportPath { - setError(fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other)) + setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other)) return } - if cfg.ModulesEnabled { + if cfg.ModulesEnabled && p.Error == nil { mainPath := p.ImportPath if p.Internal.CmdlineFiles { mainPath = "command-line-arguments" } p.Module = ModPackageModuleInfo(mainPath) - if p.Name == "main" { + if p.Name == "main" && len(p.DepsErrors) == 0 { p.Internal.BuildInfo = ModPackageBuildInfo(mainPath, p.Deps) } } @@ -1956,9 +2051,14 @@ func Packages(args []string) []*Package { // cannot be loaded at all. // The packages that fail to load will have p.Error != nil. func PackagesAndErrors(patterns []string) []*Package { - if len(patterns) > 0 { - for _, p := range patterns { - if strings.HasSuffix(p, ".go") { + for _, p := range patterns { + // Listing is only supported with all patterns referring to either: + // - Files that are part of the same directory. + // - Explicit package paths or patterns. + if strings.HasSuffix(p, ".go") { + // We need to test whether the path is an actual Go file and not a + // package path or pattern ending in '.go' (see golang.org/issue/34653). + if fi, err := os.Stat(p); err == nil && !fi.IsDir() { return []*Package{GoFilesPackage(patterns)} } } @@ -2078,7 +2178,7 @@ func GoFilesPackage(gofiles []string) *Package { pkg.Internal.CmdlineFiles = true pkg.Name = f pkg.Error = &PackageError{ - Err: fmt.Sprintf("named files must be .go files: %s", pkg.Name), + Err: fmt.Errorf("named files must be .go files: %s", pkg.Name), } return pkg } @@ -2141,11 +2241,8 @@ func GoFilesPackage(gofiles []string) *Package { pkg.Match = gofiles if pkg.Name == "main" { - _, elem := filepath.Split(gofiles[0]) - exe := elem[:len(elem)-len(".go")] + cfg.ExeSuffix - if cfg.BuildO == "" { - cfg.BuildO = exe - } + exe := pkg.DefaultExecName() + cfg.ExeSuffix + if cfg.GOBIN != "" { pkg.Target = filepath.Join(cfg.GOBIN, exe) } else if cfg.ModulesEnabled { diff --git a/libgo/go/cmd/go/internal/load/pkg_test.go b/libgo/go/cmd/go/internal/load/pkg_test.go index 9ddc20d0500..1e59fb989c5 100644 --- a/libgo/go/cmd/go/internal/load/pkg_test.go +++ b/libgo/go/cmd/go/internal/load/pkg_test.go @@ -5,39 +5,49 @@ import ( "testing" ) -func TestDefaultExecName(t *testing.T) { +func TestPkgDefaultExecName(t *testing.T) { oldModulesEnabled := cfg.ModulesEnabled defer func() { cfg.ModulesEnabled = oldModulesEnabled }() for _, tt := range []struct { in string + files []string wantMod string wantGopath string }{ - {"example.com/mycmd", "mycmd", "mycmd"}, - {"example.com/mycmd/v0", "v0", "v0"}, - {"example.com/mycmd/v1", "v1", "v1"}, - {"example.com/mycmd/v2", "mycmd", "v2"}, // Semantic import versioning, use second last element in module mode. - {"example.com/mycmd/v3", "mycmd", "v3"}, // Semantic import versioning, use second last element in module mode. - {"mycmd", "mycmd", "mycmd"}, - {"mycmd/v0", "v0", "v0"}, - {"mycmd/v1", "v1", "v1"}, - {"mycmd/v2", "mycmd", "v2"}, // Semantic import versioning, use second last element in module mode. - {"v0", "v0", "v0"}, - {"v1", "v1", "v1"}, - {"v2", "v2", "v2"}, + {"example.com/mycmd", []string{}, "mycmd", "mycmd"}, + {"example.com/mycmd/v0", []string{}, "v0", "v0"}, + {"example.com/mycmd/v1", []string{}, "v1", "v1"}, + {"example.com/mycmd/v2", []string{}, "mycmd", "v2"}, // Semantic import versioning, use second last element in module mode. + {"example.com/mycmd/v3", []string{}, "mycmd", "v3"}, // Semantic import versioning, use second last element in module mode. + {"mycmd", []string{}, "mycmd", "mycmd"}, + {"mycmd/v0", []string{}, "v0", "v0"}, + {"mycmd/v1", []string{}, "v1", "v1"}, + {"mycmd/v2", []string{}, "mycmd", "v2"}, // Semantic import versioning, use second last element in module mode. + {"v0", []string{}, "v0", "v0"}, + {"v1", []string{}, "v1", "v1"}, + {"v2", []string{}, "v2", "v2"}, + {"command-line-arguments", []string{"output.go", "foo.go"}, "output", "output"}, } { { cfg.ModulesEnabled = true - gotMod := DefaultExecName(tt.in) + pkg := new(Package) + pkg.ImportPath = tt.in + pkg.GoFiles = tt.files + pkg.Internal.CmdlineFiles = len(tt.files) > 0 + gotMod := pkg.DefaultExecName() if gotMod != tt.wantMod { - t.Errorf("DefaultExecName(%q) in module mode = %v; want %v", tt.in, gotMod, tt.wantMod) + t.Errorf("pkg.DefaultExecName with ImportPath = %q in module mode = %v; want %v", tt.in, gotMod, tt.wantMod) } } { cfg.ModulesEnabled = false - gotGopath := DefaultExecName(tt.in) + pkg := new(Package) + pkg.ImportPath = tt.in + pkg.GoFiles = tt.files + pkg.Internal.CmdlineFiles = len(tt.files) > 0 + gotGopath := pkg.DefaultExecName() if gotGopath != tt.wantGopath { - t.Errorf("DefaultExecName(%q) in gopath mode = %v; want %v", tt.in, gotGopath, tt.wantGopath) + t.Errorf("pkg.DefaultExecName with ImportPath = %q in gopath mode = %v; want %v", tt.in, gotGopath, tt.wantGopath) } } } diff --git a/libgo/go/cmd/go/internal/load/test.go b/libgo/go/cmd/go/internal/load/test.go index afff5deaaa9..fefc7d2e307 100644 --- a/libgo/go/cmd/go/internal/load/test.go +++ b/libgo/go/cmd/go/internal/load/test.go @@ -110,7 +110,7 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * // non-test copy of a package. ptestErr = &PackageError{ ImportStack: testImportStack(stk[0], p1, p.ImportPath), - Err: "import cycle not allowed in test", + Err: errors.New("import cycle not allowed in test"), IsImportCycle: true, } } @@ -271,7 +271,7 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * // afterward that gathers t.Cover information. t, err := loadTestFuncs(ptest) if err != nil && pmain.Error == nil { - pmain.Error = &PackageError{Err: err.Error()} + pmain.Error = &PackageError{Err: err} } t.Cover = cover if len(ptest.GoFiles)+len(ptest.CgoFiles) > 0 { @@ -322,7 +322,7 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * data, err := formatTestmain(t) if err != nil && pmain.Error == nil { - pmain.Error = &PackageError{Err: err.Error()} + pmain.Error = &PackageError{Err: err} } if data != nil { pmain.Internal.TestmainGo = &data @@ -399,10 +399,13 @@ func recompileForTest(pmain, preal, ptest, pxtest *Package) { } } - // Don't compile build info from a main package. This can happen - // if -coverpkg patterns include main packages, since those packages - // are imported by pmain. See golang.org/issue/30907. - if p.Internal.BuildInfo != "" && p != pmain { + // Force main packages the test imports to be built as libraries. + // Normal imports of main packages are forbidden by the package loader, + // but this can still happen if -coverpkg patterns include main packages: + // covered packages are imported by pmain. Linking multiple packages + // compiled with '-p main' causes duplicate symbol errors. + // See golang.org/issue/30907, golang.org/issue/34114. + if p.Name == "main" && p != pmain && p != ptest { split() } } diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go index 581a978ef8e..faf73446f79 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !js,!nacl,!plan9 +// +build !js,!plan9 package filelock_test diff --git a/libgo/go/cmd/go/internal/lockedfile/lockedfile.go b/libgo/go/cmd/go/internal/lockedfile/lockedfile.go index bb184b1085e..59b2dba44cd 100644 --- a/libgo/go/cmd/go/internal/lockedfile/lockedfile.go +++ b/libgo/go/cmd/go/internal/lockedfile/lockedfile.go @@ -120,3 +120,68 @@ func Write(name string, content io.Reader, perm os.FileMode) (err error) { } return err } + +// Transform invokes t with the result of reading the named file, with its lock +// still held. +// +// If t returns a nil error, Transform then writes the returned contents back to +// the file, making a best effort to preserve existing contents on error. +// +// t must not modify the slice passed to it. +func Transform(name string, t func([]byte) ([]byte, error)) (err error) { + f, err := Edit(name) + if err != nil { + return err + } + defer f.Close() + + old, err := ioutil.ReadAll(f) + if err != nil { + return err + } + + new, err := t(old) + if err != nil { + return err + } + + if len(new) > len(old) { + // The overall file size is increasing, so write the tail first: if we're + // about to run out of space on the disk, we would rather detect that + // failure before we have overwritten the original contents. + if _, err := f.WriteAt(new[len(old):], int64(len(old))); err != nil { + // Make a best effort to remove the incomplete tail. + f.Truncate(int64(len(old))) + return err + } + } + + // We're about to overwrite the old contents. In case of failure, make a best + // effort to roll back before we close the file. + defer func() { + if err != nil { + if _, err := f.WriteAt(old, 0); err == nil { + f.Truncate(int64(len(old))) + } + } + }() + + if len(new) >= len(old) { + if _, err := f.WriteAt(new[:len(old)], 0); err != nil { + return err + } + } else { + if _, err := f.WriteAt(new, 0); err != nil { + return err + } + // The overall file size is decreasing, so shrink the file to its final size + // after writing. We do this after writing (instead of before) so that if + // the write fails, enough filesystem space will likely still be reserved + // to contain the previous contents. + if err := f.Truncate(int64(len(new))); err != nil { + return err + } + } + + return nil +} diff --git a/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go b/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go index 6d5819efdb0..8f7a7d5604a 100644 --- a/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go +++ b/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.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. -// js and nacl do not support inter-process file locking. -// +build !js,!nacl +// js does not support inter-process file locking. +// +build !js package lockedfile_test diff --git a/libgo/go/cmd/go/internal/lockedfile/transform_test.go b/libgo/go/cmd/go/internal/lockedfile/transform_test.go new file mode 100644 index 00000000000..407d48ea4a3 --- /dev/null +++ b/libgo/go/cmd/go/internal/lockedfile/transform_test.go @@ -0,0 +1,104 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// js does not support inter-process file locking. +// +build !js + +package lockedfile_test + +import ( + "bytes" + "encoding/binary" + "math/rand" + "path/filepath" + "testing" + "time" + + "cmd/go/internal/lockedfile" +) + +func isPowerOf2(x int) bool { + return x > 0 && x&(x-1) == 0 +} + +func roundDownToPowerOf2(x int) int { + if x <= 0 { + panic("nonpositive x") + } + bit := 1 + for x != bit { + x = x &^ bit + bit <<= 1 + } + return x +} + +func TestTransform(t *testing.T) { + dir, remove := mustTempDir(t) + defer remove() + path := filepath.Join(dir, "blob.bin") + + const maxChunkWords = 8 << 10 + buf := make([]byte, 2*maxChunkWords*8) + for i := uint64(0); i < 2*maxChunkWords; i++ { + binary.LittleEndian.PutUint64(buf[i*8:], i) + } + if err := lockedfile.Write(path, bytes.NewReader(buf[:8]), 0666); err != nil { + t.Fatal(err) + } + + var attempts int64 = 128 + if !testing.Short() { + attempts *= 16 + } + const parallel = 32 + + var sem = make(chan bool, parallel) + + for n := attempts; n > 0; n-- { + sem <- true + go func() { + defer func() { <-sem }() + + time.Sleep(time.Duration(rand.Intn(100)) * time.Microsecond) + chunkWords := roundDownToPowerOf2(rand.Intn(maxChunkWords) + 1) + offset := rand.Intn(chunkWords) + + err := lockedfile.Transform(path, func(data []byte) (chunk []byte, err error) { + chunk = buf[offset*8 : (offset+chunkWords)*8] + + if len(data)&^7 != len(data) { + t.Errorf("read %d bytes, but each write is an integer multiple of 8 bytes", len(data)) + return chunk, nil + } + + words := len(data) / 8 + if !isPowerOf2(words) { + t.Errorf("read %d 8-byte words, but each write is a power-of-2 number of words", words) + return chunk, nil + } + + u := binary.LittleEndian.Uint64(data) + for i := 1; i < words; i++ { + next := binary.LittleEndian.Uint64(data[i*8:]) + if next != u+1 { + t.Errorf("wrote sequential integers, but read integer out of sequence at offset %d", i) + return chunk, nil + } + u = next + } + + return chunk, nil + }) + + if err != nil { + t.Errorf("unexpected error from Transform: %v", err) + } + }() + } + + for n := parallel; n > 0; n-- { + sem <- true + } +} diff --git a/libgo/go/cmd/go/internal/modcmd/download.go b/libgo/go/cmd/go/internal/modcmd/download.go index 60d0d5b6e2b..5db0e46c644 100644 --- a/libgo/go/cmd/go/internal/modcmd/download.go +++ b/libgo/go/cmd/go/internal/modcmd/download.go @@ -5,19 +5,21 @@ package modcmd import ( - "cmd/go/internal/cfg" "encoding/json" "os" "cmd/go/internal/base" + "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/module" "cmd/go/internal/par" + "cmd/go/internal/work" + + "golang.org/x/mod/module" ) var cmdDownload = &base.Command{ - UsageLine: "go mod download [-json] [modules]", + UsageLine: "go mod download [-x] [-json] [modules]", Short: "download modules to local cache", Long: ` Download downloads the named modules, which can be module patterns selecting @@ -43,9 +45,10 @@ corresponding to this Go struct: Dir string // absolute path to cached source root directory Sum string // checksum for path, version (as in go.sum) GoModSum string // checksum for go.mod (as in go.sum) - Latest bool // would @latest resolve to this version? } +The -x flag causes download to print the commands download executes. + See 'go help modules' for more about module queries. `, } @@ -54,6 +57,10 @@ var downloadJSON = cmdDownload.Flag.Bool("json", false, "") func init() { cmdDownload.Run = runDownload // break init cycle + + // TODO(jayconrod): https://golang.org/issue/35849 Apply -x to other 'go mod' commands. + cmdDownload.Flag.BoolVar(&cfg.BuildX, "x", false, "") + work.AddModCommonFlags(cmdDownload) } type moduleJSON struct { @@ -66,7 +73,6 @@ type moduleJSON struct { Dir string `json:",omitempty"` Sum string `json:",omitempty"` GoModSum string `json:",omitempty"` - Latest bool `json:",omitempty"` } func runDownload(cmd *base.Command, args []string) { @@ -79,6 +85,17 @@ func runDownload(cmd *base.Command, args []string) { } if len(args) == 0 { args = []string{"all"} + } else if modload.HasModRoot() { + modload.InitMod() // to fill Target + targetAtLatest := modload.Target.Path + "@latest" + targetAtUpgrade := modload.Target.Path + "@upgrade" + targetAtPatch := modload.Target.Path + "@patch" + for _, arg := range args { + switch arg { + case modload.Target.Path, targetAtLatest, targetAtUpgrade, targetAtPatch: + os.Stderr.WriteString("go mod download: skipping argument " + arg + " that resolves to the main module\n") + } + } } var mods []*moduleJSON @@ -90,7 +107,8 @@ func runDownload(cmd *base.Command, args []string) { info = info.Replace } if info.Version == "" && info.Error == nil { - // main module + // main module or module replaced with file path. + // Nothing to download. continue } m := &moduleJSON{ @@ -105,31 +123,6 @@ func runDownload(cmd *base.Command, args []string) { work.Add(m) } - latest := map[string]string{} // path → version - if *downloadJSON { - // We need to populate the Latest field, but if the main module depends on a - // version newer than latest — or if the version requested on the command - // line is itself newer than latest — that's not trivial to determine from - // the info returned by ListModules. Instead, we issue a separate - // ListModules request for "latest", which should be inexpensive relative to - // downloading the modules. - var latestArgs []string - for _, m := range mods { - if m.Error != "" { - continue - } - latestArgs = append(latestArgs, m.Path+"@latest") - } - - if len(latestArgs) > 0 { - for _, info := range modload.ListModules(latestArgs, listU, listVersions) { - if info.Version != "" { - latest[info.Path] = info.Version - } - } - } - } - work.Do(10, func(item interface{}) { m := item.(*moduleJSON) var err error @@ -160,9 +153,6 @@ func runDownload(cmd *base.Command, args []string) { m.Error = err.Error() return } - if latest[m.Path] == m.Version { - m.Latest = true - } }) if *downloadJSON { diff --git a/libgo/go/cmd/go/internal/modcmd/edit.go b/libgo/go/cmd/go/internal/modcmd/edit.go index 1be8b7cb2fb..dbbfb96e42b 100644 --- a/libgo/go/cmd/go/internal/modcmd/edit.go +++ b/libgo/go/cmd/go/internal/modcmd/edit.go @@ -9,17 +9,19 @@ package modcmd import ( "bytes" "encoding/json" + "errors" "fmt" - "io/ioutil" "os" - "path/filepath" "strings" "cmd/go/internal/base" + "cmd/go/internal/lockedfile" "cmd/go/internal/modfetch" - "cmd/go/internal/modfile" "cmd/go/internal/modload" - "cmd/go/internal/module" + "cmd/go/internal/work" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) var cmdEdit = &base.Command{ @@ -53,12 +55,17 @@ The -exclude=path@version and -dropexclude=path@version flags add and drop an exclusion for the given module path and version. Note that -exclude=path@version is a no-op if that exclusion already exists. -The -replace=old[@v]=new[@v] and -dropreplace=old[@v] flags -add and drop a replacement of the given module path and version pair. -If the @v in old@v is omitted, the replacement applies to all versions -with the old module path. If the @v in new@v is omitted, the new path -should be a local module root directory, not a module path. -Note that -replace overrides any existing replacements for old[@v]. +The -replace=old[@v]=new[@v] flag adds a replacement of the given +module path and version pair. If the @v in old@v is omitted, a +replacement without a version on the left side is added, which applies +to all versions of the old module path. If the @v in new@v is omitted, +the new path should be a local module root directory, not a module +path. Note that -replace overrides any redundant replacements for old[@v], +so omitting @v will drop existing replacements for specific versions. + +The -dropreplace=old[@v] flag drops a replacement of the given +module path and version pair. If the @v is omitted, a replacement without +a version on the left side is dropped. The -require, -droprequire, -exclude, -dropexclude, -replace, and -dropreplace editing flags may be repeated, and the changes @@ -130,6 +137,7 @@ func init() { cmdEdit.Flag.Var(flagFunc(flagReplace), "replace", "") cmdEdit.Flag.Var(flagFunc(flagDropExclude), "dropexclude", "") + work.AddModCommonFlags(cmdEdit) base.AddBuildFlagsNX(&cmdEdit.Flag) } @@ -157,11 +165,11 @@ func runEdit(cmd *base.Command, args []string) { if len(args) == 1 { gomod = args[0] } else { - gomod = filepath.Join(modload.ModRoot(), "go.mod") + gomod = modload.ModFilePath() } if *editModule != "" { - if err := module.CheckPath(*editModule); err != nil { + if err := module.CheckImportPath(*editModule); err != nil { base.Fatalf("go mod: invalid -module: %v", err) } } @@ -172,7 +180,7 @@ func runEdit(cmd *base.Command, args []string) { } } - data, err := ioutil.ReadFile(gomod) + data, err := lockedfile.Read(gomod) if err != nil { base.Fatalf("go: %v", err) } @@ -215,13 +223,19 @@ func runEdit(cmd *base.Command, args []string) { return } - unlock := modfetch.SideLock() - defer unlock() - lockedData, err := ioutil.ReadFile(gomod) - if err == nil && !bytes.Equal(lockedData, data) { - base.Fatalf("go: go.mod changed during editing; not overwriting") + // Make a best-effort attempt to acquire the side lock, only to exclude + // previous versions of the 'go' command from making simultaneous edits. + if unlock, err := modfetch.SideLock(); err == nil { + defer unlock() } - if err := ioutil.WriteFile(gomod, out, 0666); err != nil { + + err = lockedfile.Transform(gomod, func(lockedData []byte) ([]byte, error) { + if !bytes.Equal(lockedData, data) { + return nil, errors.New("go.mod changed during editing; not overwriting") + } + return out, nil + }) + if err != nil { base.Fatalf("go: %v", err) } } @@ -233,7 +247,7 @@ func parsePathVersion(flag, arg string) (path, version string) { base.Fatalf("go mod: -%s=%s: need path@version", flag, arg) } path, version = strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:]) - if err := module.CheckPath(path); err != nil { + if err := module.CheckImportPath(path); err != nil { base.Fatalf("go mod: -%s=%s: invalid path: %v", flag, arg, err) } @@ -255,7 +269,7 @@ func parsePath(flag, arg string) (path string) { base.Fatalf("go mod: -%s=%s: need just path, not path@version", flag, arg) } path = arg - if err := module.CheckPath(path); err != nil { + if err := module.CheckImportPath(path); err != nil { base.Fatalf("go mod: -%s=%s: invalid path: %v", flag, arg, err) } return path @@ -269,7 +283,7 @@ func parsePathVersionOptional(adj, arg string, allowDirPath bool) (path, version } else { path, version = strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:]) } - if err := module.CheckPath(path); err != nil { + if err := module.CheckImportPath(path); err != nil { if !allowDirPath || !modfile.IsDirectoryPath(path) { return path, version, fmt.Errorf("invalid %s path: %v", adj, err) } diff --git a/libgo/go/cmd/go/internal/modcmd/graph.go b/libgo/go/cmd/go/internal/modcmd/graph.go index 8fcb84f2801..27ae9354f3d 100644 --- a/libgo/go/cmd/go/internal/modcmd/graph.go +++ b/libgo/go/cmd/go/internal/modcmd/graph.go @@ -8,14 +8,16 @@ package modcmd import ( "bufio" - "cmd/go/internal/cfg" "os" "sort" "cmd/go/internal/base" + "cmd/go/internal/cfg" "cmd/go/internal/modload" - "cmd/go/internal/module" "cmd/go/internal/par" + "cmd/go/internal/work" + + "golang.org/x/mod/module" ) var cmdGraph = &base.Command{ @@ -30,6 +32,10 @@ path@version, except for the main module, which has no @version suffix. Run: runGraph, } +func init() { + work.AddModCommonFlags(cmdGraph) +} + func runGraph(cmd *base.Command, args []string) { if len(args) > 0 { base.Fatalf("go mod graph: graph takes no arguments") diff --git a/libgo/go/cmd/go/internal/modcmd/init.go b/libgo/go/cmd/go/internal/modcmd/init.go index b94453bab0c..714ff2e205a 100644 --- a/libgo/go/cmd/go/internal/modcmd/init.go +++ b/libgo/go/cmd/go/internal/modcmd/init.go @@ -9,6 +9,7 @@ package modcmd import ( "cmd/go/internal/base" "cmd/go/internal/modload" + "cmd/go/internal/work" "os" "strings" ) @@ -27,6 +28,10 @@ To override this guess, supply the module path as an argument. Run: runInit, } +func init() { + work.AddModCommonFlags(cmdInit) +} + func runInit(cmd *base.Command, args []string) { modload.CmdModInit = true if len(args) > 1 { @@ -38,7 +43,8 @@ func runInit(cmd *base.Command, args []string) { if os.Getenv("GO111MODULE") == "off" { base.Fatalf("go mod init: modules disabled by GO111MODULE=off; see 'go help modules'") } - if _, err := os.Stat("go.mod"); err == nil { + modFilePath := modload.ModFilePath() + if _, err := os.Stat(modFilePath); err == nil { base.Fatalf("go mod init: go.mod already exists") } if strings.Contains(modload.CmdModModule, "@") { diff --git a/libgo/go/cmd/go/internal/modcmd/mod.go b/libgo/go/cmd/go/internal/modcmd/mod.go index f150cc9728a..17505221587 100644 --- a/libgo/go/cmd/go/internal/modcmd/mod.go +++ b/libgo/go/cmd/go/internal/modcmd/mod.go @@ -5,7 +5,10 @@ // Package modcmd implements the ``go mod'' command. package modcmd -import "cmd/go/internal/base" +import ( + "cmd/go/internal/base" + "cmd/go/internal/cfg" +) var CmdMod = &base.Command{ UsageLine: "go mod", @@ -29,3 +32,7 @@ See 'go help modules' for an overview of module functionality. cmdWhy, }, } + +func addModFlags(cmd *base.Command) { + cmd.Flag.StringVar(&cfg.ModFile, "modfile", "", "") +} diff --git a/libgo/go/cmd/go/internal/modcmd/tidy.go b/libgo/go/cmd/go/internal/modcmd/tidy.go index 789e9366085..af2b04c0c20 100644 --- a/libgo/go/cmd/go/internal/modcmd/tidy.go +++ b/libgo/go/cmd/go/internal/modcmd/tidy.go @@ -7,14 +7,13 @@ package modcmd import ( - "fmt" - "os" - "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/module" + "cmd/go/internal/work" + + "golang.org/x/mod/module" ) var cmdTidy = &base.Command{ @@ -35,6 +34,7 @@ to standard error. func init() { cmdTidy.Run = runTidy // break init cycle cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "") + work.AddModCommonFlags(cmdTidy) } func runTidy(cmd *base.Command, args []string) { @@ -42,28 +42,8 @@ func runTidy(cmd *base.Command, args []string) { base.Fatalf("go mod tidy: no arguments allowed") } - // LoadALL adds missing modules. - // Remove unused modules. - used := make(map[module.Version]bool) - for _, pkg := range modload.LoadALL() { - used[modload.PackageModule(pkg)] = true - } - used[modload.Target] = true // note: LoadALL initializes Target - - inGoMod := make(map[string]bool) - for _, r := range modload.ModFile().Require { - inGoMod[r.Mod.Path] = true - } - - var keep []module.Version - for _, m := range modload.BuildList() { - if used[m] { - keep = append(keep, m) - } else if cfg.BuildV && inGoMod[m.Path] { - fmt.Fprintf(os.Stderr, "unused %s\n", m.Path) - } - } - modload.SetBuildList(keep) + modload.LoadALL() + modload.TidyBuildList() modTidyGoSum() // updates memory copy; WriteGoMod on next line flushes it out modload.WriteGoMod() } diff --git a/libgo/go/cmd/go/internal/modcmd/vendor.go b/libgo/go/cmd/go/internal/modcmd/vendor.go index 75513f1d9ca..0c00d1222e0 100644 --- a/libgo/go/cmd/go/internal/modcmd/vendor.go +++ b/libgo/go/cmd/go/internal/modcmd/vendor.go @@ -18,7 +18,10 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/imports" "cmd/go/internal/modload" - "cmd/go/internal/module" + "cmd/go/internal/work" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) var cmdVendor = &base.Command{ @@ -37,6 +40,7 @@ modules and packages to standard error. func init() { cmdVendor.Flag.BoolVar(&cfg.BuildV, "v", false, "") + work.AddModCommonFlags(cmdVendor) } func runVendor(cmd *base.Command, args []string) { @@ -59,19 +63,31 @@ func runVendor(cmd *base.Command, args []string) { modpkgs[m] = append(modpkgs[m], pkg) } + includeAllReplacements := false + isExplicit := map[module.Version]bool{} + if gv := modload.ModFile().Go; gv != nil && semver.Compare("v"+gv.Version, "v1.14") >= 0 { + // If the Go version is at least 1.14, annotate all explicit 'require' and + // 'replace' targets found in the go.mod file so that we can perform a + // stronger consistency check when -mod=vendor is set. + for _, r := range modload.ModFile().Require { + isExplicit[r.Mod] = true + } + includeAllReplacements = true + } + var buf bytes.Buffer for _, m := range modload.BuildList()[1:] { - if pkgs := modpkgs[m]; len(pkgs) > 0 { - repl := "" - if r := modload.Replacement(m); r.Path != "" { - repl = " => " + r.Path - if r.Version != "" { - repl += " " + r.Version - } - } - fmt.Fprintf(&buf, "# %s %s%s\n", m.Path, m.Version, repl) + if pkgs := modpkgs[m]; len(pkgs) > 0 || isExplicit[m] { + line := moduleLine(m, modload.Replacement(m)) + buf.WriteString(line) if cfg.BuildV { - fmt.Fprintf(os.Stderr, "# %s %s%s\n", m.Path, m.Version, repl) + os.Stderr.WriteString(line) + } + if isExplicit[m] { + buf.WriteString("## explicit\n") + if cfg.BuildV { + os.Stderr.WriteString("## explicit\n") + } } sort.Strings(pkgs) for _, pkg := range pkgs { @@ -83,6 +99,26 @@ func runVendor(cmd *base.Command, args []string) { } } } + + if includeAllReplacements { + // Record unused and wildcard replacements at the end of the modules.txt file: + // without access to the complete build list, the consumer of the vendor + // directory can't otherwise determine that those replacements had no effect. + for _, r := range modload.ModFile().Replace { + if len(modpkgs[r.Old]) > 0 { + // We we already recorded this replacement in the entry for the replaced + // module with the packages it provides. + continue + } + + line := moduleLine(r.Old, r.New) + buf.WriteString(line) + if cfg.BuildV { + os.Stderr.WriteString(line) + } + } + } + if buf.Len() == 0 { fmt.Fprintf(os.Stderr, "go: no dependencies to vendor\n") return @@ -92,6 +128,26 @@ func runVendor(cmd *base.Command, args []string) { } } +func moduleLine(m, r module.Version) string { + b := new(strings.Builder) + b.WriteString("# ") + b.WriteString(m.Path) + if m.Version != "" { + b.WriteString(" ") + b.WriteString(m.Version) + } + if r.Path != "" { + b.WriteString(" => ") + b.WriteString(r.Path) + if r.Version != "" { + b.WriteString(" ") + b.WriteString(r.Version) + } + } + b.WriteString("\n") + return b.String() +} + func vendorPkg(vdir, pkg string) { realPath := modload.ImportMap(pkg) if realPath != pkg && modload.ImportMap(realPath) != "" { diff --git a/libgo/go/cmd/go/internal/modcmd/verify.go b/libgo/go/cmd/go/internal/modcmd/verify.go index 81fc44dc97a..831e5cf85bb 100644 --- a/libgo/go/cmd/go/internal/modcmd/verify.go +++ b/libgo/go/cmd/go/internal/modcmd/verify.go @@ -6,16 +6,18 @@ package modcmd import ( "bytes" - "cmd/go/internal/cfg" "fmt" "io/ioutil" "os" "cmd/go/internal/base" - "cmd/go/internal/dirhash" + "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/module" + "cmd/go/internal/work" + + "golang.org/x/mod/module" + "golang.org/x/mod/sumdb/dirhash" ) var cmdVerify = &base.Command{ @@ -32,13 +34,17 @@ non-zero status. Run: runVerify, } +func init() { + work.AddModCommonFlags(cmdVerify) +} + func runVerify(cmd *base.Command, args []string) { if len(args) != 0 { // NOTE(rsc): Could take a module pattern. base.Fatalf("go mod verify: verify takes no arguments") } // Checks go mod expected behavior - if !modload.Enabled() { + if !modload.Enabled() || !modload.HasModRoot() { if cfg.Getenv("GO111MODULE") == "off" { base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") } else { diff --git a/libgo/go/cmd/go/internal/modcmd/why.go b/libgo/go/cmd/go/internal/modcmd/why.go index 03e0a039bc5..40d238519b2 100644 --- a/libgo/go/cmd/go/internal/modcmd/why.go +++ b/libgo/go/cmd/go/internal/modcmd/why.go @@ -5,11 +5,14 @@ package modcmd import ( - "cmd/go/internal/base" - "cmd/go/internal/modload" - "cmd/go/internal/module" "fmt" "strings" + + "cmd/go/internal/base" + "cmd/go/internal/modload" + "cmd/go/internal/work" + + "golang.org/x/mod/module" ) var cmdWhy = &base.Command{ @@ -54,6 +57,7 @@ var ( func init() { cmdWhy.Run = runWhy // break init cycle + work.AddModCommonFlags(cmdWhy) } func runWhy(cmd *base.Command, args []string) { diff --git a/libgo/go/cmd/go/internal/modconv/convert.go b/libgo/go/cmd/go/internal/modconv/convert.go index 558664a8b38..f465a9f395b 100644 --- a/libgo/go/cmd/go/internal/modconv/convert.go +++ b/libgo/go/cmd/go/internal/modconv/convert.go @@ -13,10 +13,11 @@ import ( "cmd/go/internal/base" "cmd/go/internal/modfetch" - "cmd/go/internal/modfile" - "cmd/go/internal/module" "cmd/go/internal/par" - "cmd/go/internal/semver" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) // ConvertLegacyConfig converts legacy config to modfile. diff --git a/libgo/go/cmd/go/internal/modconv/convert_test.go b/libgo/go/cmd/go/internal/modconv/convert_test.go index 8ff229bd148..a2a26019677 100644 --- a/libgo/go/cmd/go/internal/modconv/convert_test.go +++ b/libgo/go/cmd/go/internal/modconv/convert_test.go @@ -19,8 +19,9 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modfetch/codehost" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func TestMain(m *testing.M) { diff --git a/libgo/go/cmd/go/internal/modconv/dep.go b/libgo/go/cmd/go/internal/modconv/dep.go index ccd1fc7b759..2e673c3ab9f 100644 --- a/libgo/go/cmd/go/internal/modconv/dep.go +++ b/libgo/go/cmd/go/internal/modconv/dep.go @@ -12,9 +12,9 @@ import ( "strconv" "strings" - "cmd/go/internal/modfile" - "cmd/go/internal/module" - "cmd/go/internal/semver" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) func ParseGopkgLock(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modconv/glide.go b/libgo/go/cmd/go/internal/modconv/glide.go index 18ab57814de..d1de3f7139d 100644 --- a/libgo/go/cmd/go/internal/modconv/glide.go +++ b/libgo/go/cmd/go/internal/modconv/glide.go @@ -7,8 +7,8 @@ package modconv import ( "strings" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func ParseGlideLock(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modconv/glock.go b/libgo/go/cmd/go/internal/modconv/glock.go index 164a8e70d99..b8dc2046176 100644 --- a/libgo/go/cmd/go/internal/modconv/glock.go +++ b/libgo/go/cmd/go/internal/modconv/glock.go @@ -7,8 +7,8 @@ package modconv import ( "strings" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func ParseGLOCKFILE(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modconv/godeps.go b/libgo/go/cmd/go/internal/modconv/godeps.go index 6398dbe7cd7..09c0fa3ddab 100644 --- a/libgo/go/cmd/go/internal/modconv/godeps.go +++ b/libgo/go/cmd/go/internal/modconv/godeps.go @@ -7,8 +7,8 @@ package modconv import ( "encoding/json" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func ParseGodepsJSON(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modconv/modconv.go b/libgo/go/cmd/go/internal/modconv/modconv.go index a58673382e6..dc0607235f3 100644 --- a/libgo/go/cmd/go/internal/modconv/modconv.go +++ b/libgo/go/cmd/go/internal/modconv/modconv.go @@ -4,7 +4,7 @@ package modconv -import "cmd/go/internal/modfile" +import "golang.org/x/mod/modfile" var Converters = map[string]func(string, []byte) (*modfile.File, error){ "GLOCKFILE": ParseGLOCKFILE, diff --git a/libgo/go/cmd/go/internal/modconv/tsv.go b/libgo/go/cmd/go/internal/modconv/tsv.go index 106cddedd39..4649579f650 100644 --- a/libgo/go/cmd/go/internal/modconv/tsv.go +++ b/libgo/go/cmd/go/internal/modconv/tsv.go @@ -7,8 +7,8 @@ package modconv import ( "strings" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func ParseDependenciesTSV(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modconv/vconf.go b/libgo/go/cmd/go/internal/modconv/vconf.go index f62eba77621..9bad2baf8fb 100644 --- a/libgo/go/cmd/go/internal/modconv/vconf.go +++ b/libgo/go/cmd/go/internal/modconv/vconf.go @@ -7,8 +7,8 @@ package modconv import ( "strings" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func ParseVendorConf(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modconv/vjson.go b/libgo/go/cmd/go/internal/modconv/vjson.go index eec86b73398..1bd025c980f 100644 --- a/libgo/go/cmd/go/internal/modconv/vjson.go +++ b/libgo/go/cmd/go/internal/modconv/vjson.go @@ -7,8 +7,8 @@ package modconv import ( "encoding/json" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func ParseVendorJSON(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modconv/vmanifest.go b/libgo/go/cmd/go/internal/modconv/vmanifest.go index c0ef2a98622..bcf00083a52 100644 --- a/libgo/go/cmd/go/internal/modconv/vmanifest.go +++ b/libgo/go/cmd/go/internal/modconv/vmanifest.go @@ -7,8 +7,8 @@ package modconv import ( "encoding/json" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func ParseVendorManifest(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modconv/vyml.go b/libgo/go/cmd/go/internal/modconv/vyml.go index 8a06519932c..cfa41941d55 100644 --- a/libgo/go/cmd/go/internal/modconv/vyml.go +++ b/libgo/go/cmd/go/internal/modconv/vyml.go @@ -7,8 +7,8 @@ package modconv import ( "strings" - "cmd/go/internal/modfile" - "cmd/go/internal/module" + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) func ParseVendorYML(file string, data []byte) (*modfile.File, error) { diff --git a/libgo/go/cmd/go/internal/modfetch/bootstrap.go b/libgo/go/cmd/go/internal/modfetch/bootstrap.go index 8f31589ebfc..e4020b0b41e 100644 --- a/libgo/go/cmd/go/internal/modfetch/bootstrap.go +++ b/libgo/go/cmd/go/internal/modfetch/bootstrap.go @@ -6,7 +6,7 @@ package modfetch -import "cmd/go/internal/module" +import "golang.org/x/mod/module" func useSumDB(mod module.Version) bool { return false diff --git a/libgo/go/cmd/go/internal/modfetch/cache.go b/libgo/go/cmd/go/internal/modfetch/cache.go index c0062809d17..104fce86dda 100644 --- a/libgo/go/cmd/go/internal/modfetch/cache.go +++ b/libgo/go/cmd/go/internal/modfetch/cache.go @@ -13,26 +13,28 @@ import ( "os" "path/filepath" "strings" + "time" "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/lockedfile" "cmd/go/internal/modfetch/codehost" - "cmd/go/internal/module" "cmd/go/internal/par" "cmd/go/internal/renameio" - "cmd/go/internal/semver" -) -var QuietLookup bool // do not print about lookups + "golang.org/x/mod/module" + "golang.org/x/mod/semver" +) var PkgMod string // $GOPATH/pkg/mod; set by package modload +const logFindingDelay = 1 * time.Second + func cacheDir(path string) (string, error) { if PkgMod == "" { return "", fmt.Errorf("internal error: modfetch.PkgMod not set") } - enc, err := module.EncodePath(path) + enc, err := module.EscapePath(path) if err != nil { return "", err } @@ -50,7 +52,7 @@ func CachePath(m module.Version, suffix string) (string, error) { if module.CanonicalVersion(m.Version) != m.Version { return "", fmt.Errorf("non-canonical module version %q", m.Version) } - encVer, err := module.EncodeVersion(m.Version) + encVer, err := module.EscapeVersion(m.Version) if err != nil { return "", err } @@ -63,7 +65,7 @@ func DownloadDir(m module.Version) (string, error) { if PkgMod == "" { return "", fmt.Errorf("internal error: modfetch.PkgMod not set") } - enc, err := module.EncodePath(m.Path) + enc, err := module.EscapePath(m.Path) if err != nil { return "", err } @@ -73,7 +75,7 @@ func DownloadDir(m module.Version) (string, error) { if module.CanonicalVersion(m.Version) != m.Version { return "", fmt.Errorf("non-canonical module version %q", m.Version) } - encVer, err := module.EncodeVersion(m.Version) + encVer, err := module.EscapeVersion(m.Version) if err != nil { return "", err } @@ -93,22 +95,21 @@ func lockVersion(mod module.Version) (unlock func(), err error) { return lockedfile.MutexAt(path).Lock() } -// SideLock locks a file within the module cache that that guards edits to files -// outside the cache, such as go.sum and go.mod files in the user's working -// directory. It returns a function that must be called to unlock the file. -func SideLock() (unlock func()) { +// SideLock locks a file within the module cache that that previously guarded +// edits to files outside the cache, such as go.sum and go.mod files in the +// user's working directory. +// If err is nil, the caller MUST eventually call the unlock function. +func SideLock() (unlock func(), err error) { if PkgMod == "" { base.Fatalf("go: internal error: modfetch.PkgMod not set") } + path := filepath.Join(PkgMod, "cache", "lock") if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil { - base.Fatalf("go: failed to create cache directory %s: %v", filepath.Dir(path), err) + return nil, fmt.Errorf("failed to create cache directory: %w", err) } - unlock, err := lockedfile.MutexAt(path).Lock() - if err != nil { - base.Fatalf("go: failed to lock file at %v", path) - } - return unlock + + return lockedfile.MutexAt(path).Lock() } // A cachingRepo is a cache around an underlying Repo, @@ -139,6 +140,11 @@ func (r *cachingRepo) Versions(prefix string) ([]string, error) { err error } c := r.cache.Do("versions:"+prefix, func() interface{} { + logTimer := time.AfterFunc(logFindingDelay, func() { + fmt.Fprintf(os.Stderr, "go: finding versions for %s\n", r.path) + }) + defer logTimer.Stop() + list, err := r.r.Versions(prefix) return cached{list, err} }).(cached) @@ -161,9 +167,11 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) { return cachedInfo{info, nil} } - if !QuietLookup { + logTimer := time.AfterFunc(logFindingDelay, func() { fmt.Fprintf(os.Stderr, "go: finding %s %s\n", r.path, rev) - } + }) + defer logTimer.Stop() + info, err = r.r.Stat(rev) if err == nil { // If we resolved, say, 1234abcde to v0.0.0-20180604122334-1234abcdef78, @@ -191,9 +199,11 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) { func (r *cachingRepo) Latest() (*RevInfo, error) { c := r.cache.Do("latest:", func() interface{} { - if !QuietLookup { + logTimer := time.AfterFunc(logFindingDelay, func() { fmt.Fprintf(os.Stderr, "go: finding %s latest\n", r.path) - } + }) + defer logTimer.Stop() + info, err := r.r.Latest() // Save info for likely future Stat call. @@ -230,7 +240,9 @@ func (r *cachingRepo) GoMod(version string) ([]byte, error) { text, err = r.r.GoMod(version) if err == nil { - checkGoMod(r.path, version, text) + if err := checkGoMod(r.path, version, text); err != nil { + return cached{text, err} + } if err := writeDiskGoMod(file, text); err != nil { fmt.Fprintf(os.Stderr, "go: writing go.mod cache: %v\n", err) } @@ -490,7 +502,9 @@ func readDiskGoMod(path, rev string) (file string, data []byte, err error) { } if err == nil { - checkGoMod(path, rev, data) + if err := checkGoMod(path, rev, data); err != nil { + return "", nil, err + } } return file, data, err diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go index a4e50d692a3..5867288c966 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go @@ -73,11 +73,10 @@ type Repo interface { // ReadZip downloads a zip file for the subdir subdirectory // of the given revision to a new file in a given temporary directory. // It should refuse to read more than maxSize bytes. - // It returns a ReadCloser for a streamed copy of the zip file, - // along with the actual subdirectory (possibly shorter than subdir) - // contained in the zip file. All files in the zip file are expected to be + // It returns a ReadCloser for a streamed copy of the zip file. + // All files in the zip file are expected to be // nested in a single top-level directory, whose name is not specified. - ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, actualSubdir string, err error) + ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, err error) // RecentTag returns the most recent tag on rev or one of its predecessors // with the given prefix and major version. diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/git.go b/libgo/go/cmd/go/internal/modfetch/codehost/git.go index d382e8ac9a9..e329cbc58e7 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/git.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/git.go @@ -6,9 +6,11 @@ package codehost import ( "bytes" + "errors" "fmt" "io" "io/ioutil" + "net/url" "os" "os/exec" "path/filepath" @@ -20,7 +22,9 @@ import ( "cmd/go/internal/lockedfile" "cmd/go/internal/par" - "cmd/go/internal/semver" + "cmd/go/internal/web" + + "golang.org/x/mod/semver" ) // GitRepo returns the code repository at the given Git remote reference. @@ -34,6 +38,15 @@ func LocalGitRepo(remote string) (Repo, error) { return newGitRepoCached(remote, true) } +// A notExistError wraps another error to retain its original text +// but makes it opaquely equivalent to os.ErrNotExist. +type notExistError struct { + err error +} + +func (e notExistError) Error() string { return e.err.Error() } +func (notExistError) Is(err error) bool { return err == os.ErrNotExist } + const gitWorkDirType = "git3" var gitRepoCache par.Cache @@ -85,8 +98,9 @@ func newGitRepo(remote string, localOK bool) (Repo, error) { os.RemoveAll(r.dir) return nil, err } - r.remote = "origin" } + r.remoteURL = r.remote + r.remote = "origin" } else { // Local path. // Disallow colon (not in ://) because sometimes @@ -113,9 +127,9 @@ func newGitRepo(remote string, localOK bool) (Repo, error) { } type gitRepo struct { - remote string - local bool - dir string + remote, remoteURL string + local bool + dir string mu lockedfile.Mutex // protects fetchLevel and git repo state @@ -166,14 +180,25 @@ func (r *gitRepo) loadRefs() { // The git protocol sends all known refs and ls-remote filters them on the client side, // so we might as well record both heads and tags in one shot. // Most of the time we only care about tags but sometimes we care about heads too. - out, err := Run(r.dir, "git", "ls-remote", "-q", r.remote) - if err != nil { - if rerr, ok := err.(*RunError); ok { + out, gitErr := Run(r.dir, "git", "ls-remote", "-q", r.remote) + if gitErr != nil { + if rerr, ok := gitErr.(*RunError); ok { if bytes.Contains(rerr.Stderr, []byte("fatal: could not read Username")) { rerr.HelpText = "Confirm the import path was entered correctly.\nIf this is a private repository, see https://golang.org/doc/faq#git_https for additional information." } } - r.refsErr = err + + // If the remote URL doesn't exist at all, ideally we should treat the whole + // repository as nonexistent by wrapping the error in a notExistError. + // For HTTP and HTTPS, that's easy to detect: we'll try to fetch the URL + // ourselves and see what code it serves. + if u, err := url.Parse(r.remoteURL); err == nil && (u.Scheme == "http" || u.Scheme == "https") { + if _, err := web.GetBytes(u); errors.Is(err, os.ErrNotExist) { + gitErr = notExistError{gitErr} + } + } + + r.refsErr = gitErr return } @@ -241,13 +266,6 @@ func (r *gitRepo) findRef(hash string) (ref string, ok bool) { return "", false } -func unshallow(gitDir string) []string { - if _, err := os.Stat(filepath.Join(gitDir, "shallow")); err == nil { - return []string{"--unshallow"} - } - return []string{} -} - // minHashDigits is the minimum number of digits to require // before accepting a hex digit sequence as potentially identifying // a specific commit in a git repo. (Of course, users can always @@ -397,29 +415,27 @@ func (r *gitRepo) stat(rev string) (*RevInfo, error) { // fetchRefsLocked requires that r.mu remain locked for the duration of the call. func (r *gitRepo) fetchRefsLocked() error { if r.fetchLevel < fetchAll { - if err := r.fetchUnshallow("refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"); err != nil { + // NOTE: To work around a bug affecting Git clients up to at least 2.23.0 + // (2019-08-16), we must first expand the set of local refs, and only then + // unshallow the repository as a separate fetch operation. (See + // golang.org/issue/34266 and + // https://github.com/git/git/blob/4c86140027f4a0d2caaa3ab4bd8bfc5ce3c11c8a/transport.c#L1303-L1309.) + + if _, err := Run(r.dir, "git", "fetch", "-f", r.remote, "refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"); err != nil { return err } + + if _, err := os.Stat(filepath.Join(r.dir, "shallow")); err == nil { + if _, err := Run(r.dir, "git", "fetch", "--unshallow", "-f", r.remote); err != nil { + return err + } + } + r.fetchLevel = fetchAll } return nil } -func (r *gitRepo) fetchUnshallow(refSpecs ...string) error { - // To work around a protocol version 2 bug that breaks --unshallow, - // add -c protocol.version=0. - // TODO(rsc): The bug is believed to be server-side, meaning only - // on Google's Git servers. Once the servers are fixed, drop the - // protocol.version=0. See Google-internal bug b/110495752. - var protoFlag []string - unshallowFlag := unshallow(r.dir) - if len(unshallowFlag) > 0 { - protoFlag = []string{"-c", "protocol.version=0"} - } - _, err := Run(r.dir, "git", protoFlag, "fetch", unshallowFlag, "-f", r.remote, refSpecs) - return err -} - // statLocal returns a RevInfo describing rev in the local git repository. // It uses version as info.Version. func (r *gitRepo) statLocal(version, rev string) (*RevInfo, error) { @@ -539,39 +555,10 @@ func (r *gitRepo) ReadFileRevs(revs []string, file string, maxSize int64) (map[s } defer unlock() - var refs []string - var protoFlag []string - var unshallowFlag []string - for _, tag := range redo { - refs = append(refs, "refs/tags/"+tag+":refs/tags/"+tag) - } - if len(refs) > 1 { - unshallowFlag = unshallow(r.dir) - if len(unshallowFlag) > 0 { - // To work around a protocol version 2 bug that breaks --unshallow, - // add -c protocol.version=0. - // TODO(rsc): The bug is believed to be server-side, meaning only - // on Google's Git servers. Once the servers are fixed, drop the - // protocol.version=0. See Google-internal bug b/110495752. - protoFlag = []string{"-c", "protocol.version=0"} - } - } - if _, err := Run(r.dir, "git", protoFlag, "fetch", unshallowFlag, "-f", r.remote, refs); err != nil { + if err := r.fetchRefsLocked(); err != nil { return nil, err } - // TODO(bcmills): after the 1.11 freeze, replace the block above with: - // if r.fetchLevel <= fetchSome { - // r.fetchLevel = fetchSome - // var refs []string - // for _, tag := range redo { - // refs = append(refs, "refs/tags/"+tag+":refs/tags/"+tag) - // } - // if _, err := Run(r.dir, "git", "fetch", "--update-shallow", "-f", r.remote, refs); err != nil { - // return nil, err - // } - // } - if _, err := r.readFileRevs(redo, file, files); err != nil { return nil, err } @@ -809,7 +796,7 @@ func (r *gitRepo) DescendsFrom(rev, tag string) (bool, error) { return false, err } -func (r *gitRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, actualSubdir string, err error) { +func (r *gitRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, err error) { // TODO: Use maxSize or drop it. args := []string{} if subdir != "" { @@ -817,17 +804,17 @@ func (r *gitRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, } info, err := r.Stat(rev) // download rev into local git repo if err != nil { - return nil, "", err + return nil, err } unlock, err := r.mu.Lock() if err != nil { - return nil, "", err + return nil, err } defer unlock() if err := ensureGitAttributes(r.dir); err != nil { - return nil, "", err + return nil, err } // Incredibly, git produces different archives depending on whether @@ -838,12 +825,12 @@ func (r *gitRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, archive, err := Run(r.dir, "git", "-c", "core.autocrlf=input", "-c", "core.eol=lf", "archive", "--format=zip", "--prefix=prefix/", info.Name, args) if err != nil { if bytes.Contains(err.(*RunError).Stderr, []byte("did not match any files")) { - return nil, "", os.ErrNotExist + return nil, os.ErrNotExist } - return nil, "", err + return nil, err } - return ioutil.NopCloser(bytes.NewReader(archive)), "", nil + return ioutil.NopCloser(bytes.NewReader(archive)), nil } // ensureGitAttributes makes sure export-subst and export-ignore features are diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go b/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go index da9e7050407..cc32a1eb51c 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go @@ -78,7 +78,16 @@ func testMain(m *testing.M) int { func testRepo(remote string) (Repo, error) { if remote == "localGitRepo" { - return LocalGitRepo(filepath.ToSlash(localGitRepo)) + // Convert absolute path to file URL. LocalGitRepo will not accept + // Windows absolute paths because they look like a host:path remote. + // TODO(golang.org/issue/32456): use url.FromFilePath when implemented. + var url string + if strings.HasPrefix(localGitRepo, "/") { + url = "file://" + localGitRepo + } else { + url = "file:///" + filepath.ToSlash(localGitRepo) + } + return LocalGitRepo(url) } kind := "git" for _, k := range []string{"hg"} { @@ -246,12 +255,11 @@ func TestReadFile(t *testing.T) { } var readZipTests = []struct { - repo string - rev string - subdir string - actualSubdir string - err string - files map[string]uint64 + repo string + rev string + subdir string + err string + files map[string]uint64 }{ { repo: gitrepo1, @@ -408,7 +416,7 @@ func TestReadZip(t *testing.T) { if err != nil { t.Fatal(err) } - rc, actualSubdir, err := r.ReadZip(tt.rev, tt.subdir, 100000) + rc, err := r.ReadZip(tt.rev, tt.subdir, 100000) if err != nil { if tt.err == "" { t.Fatalf("ReadZip: unexpected error %v", err) @@ -425,9 +433,6 @@ func TestReadZip(t *testing.T) { if tt.err != "" { t.Fatalf("ReadZip: no error, wanted %v", tt.err) } - if actualSubdir != tt.actualSubdir { - t.Fatalf("ReadZip: actualSubdir = %q, want %q", actualSubdir, tt.actualSubdir) - } zipdata, err := ioutil.ReadAll(rc) if err != nil { t.Fatal(err) diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/shell.go b/libgo/go/cmd/go/internal/modfetch/codehost/shell.go index 7b813c37401..835bc53c0dd 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/shell.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/shell.go @@ -109,7 +109,7 @@ func main() { if subdir == "-" { subdir = "" } - rc, _, err := repo.ReadZip(f[1], subdir, 10<<20) + rc, err := repo.ReadZip(f[1], subdir, 10<<20) if err != nil { fmt.Fprintf(os.Stderr, "?%s\n", err) continue diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/svn.go b/libgo/go/cmd/go/internal/modfetch/codehost/svn.go new file mode 100644 index 00000000000..6ec9e59c9c6 --- /dev/null +++ b/libgo/go/cmd/go/internal/modfetch/codehost/svn.go @@ -0,0 +1,154 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package codehost + +import ( + "archive/zip" + "encoding/xml" + "fmt" + "io" + "os" + "path" + "path/filepath" + "time" +) + +func svnParseStat(rev, out string) (*RevInfo, error) { + var log struct { + Logentry struct { + Revision int64 `xml:"revision,attr"` + Date string `xml:"date"` + } `xml:"logentry"` + } + if err := xml.Unmarshal([]byte(out), &log); err != nil { + return nil, vcsErrorf("unexpected response from svn log --xml: %v\n%s", err, out) + } + + t, err := time.Parse(time.RFC3339, log.Logentry.Date) + if err != nil { + return nil, vcsErrorf("unexpected response from svn log --xml: %v\n%s", err, out) + } + + info := &RevInfo{ + Name: fmt.Sprintf("%d", log.Logentry.Revision), + Short: fmt.Sprintf("%012d", log.Logentry.Revision), + Time: t.UTC(), + Version: rev, + } + return info, nil +} + +func svnReadZip(dst io.Writer, workDir, rev, subdir, remote string) (err error) { + // The subversion CLI doesn't provide a command to write the repository + // directly to an archive, so we need to export it to the local filesystem + // instead. Unfortunately, the local filesystem might apply arbitrary + // normalization to the filenames, so we need to obtain those directly. + // + // 'svn export' prints the filenames as they are written, but from reading the + // svn source code (as of revision 1868933), those filenames are encoded using + // the system locale rather than preserved byte-for-byte from the origin. For + // our purposes, that won't do, but we don't want to go mucking around with + // the user's locale settings either — that could impact error messages, and + // we don't know what locales the user has available or what LC_* variables + // their platform supports. + // + // Instead, we'll do a two-pass export: first we'll run 'svn list' to get the + // canonical filenames, then we'll 'svn export' and look for those filenames + // in the local filesystem. (If there is an encoding problem at that point, we + // would probably reject the resulting module anyway.) + + remotePath := remote + if subdir != "" { + remotePath += "/" + subdir + } + + out, err := Run(workDir, []string{ + "svn", "list", + "--non-interactive", + "--xml", + "--incremental", + "--recursive", + "--revision", rev, + "--", remotePath, + }) + if err != nil { + return err + } + + type listEntry struct { + Kind string `xml:"kind,attr"` + Name string `xml:"name"` + Size int64 `xml:"size"` + } + var list struct { + Entries []listEntry `xml:"entry"` + } + if err := xml.Unmarshal(out, &list); err != nil { + return vcsErrorf("unexpected response from svn list --xml: %v\n%s", err, out) + } + + exportDir := filepath.Join(workDir, "export") + // Remove any existing contents from a previous (failed) run. + if err := os.RemoveAll(exportDir); err != nil { + return err + } + defer os.RemoveAll(exportDir) // best-effort + + _, err = Run(workDir, []string{ + "svn", "export", + "--non-interactive", + "--quiet", + + // Suppress any platform- or host-dependent transformations. + "--native-eol", "LF", + "--ignore-externals", + "--ignore-keywords", + + "--revision", rev, + "--", remotePath, + exportDir, + }) + if err != nil { + return err + } + + // Scrape the exported files out of the filesystem and encode them in the zipfile. + + // “All files in the zip file are expected to be + // nested in a single top-level directory, whose name is not specified.” + // We'll (arbitrarily) choose the base of the remote path. + basePath := path.Join(path.Base(remote), subdir) + + zw := zip.NewWriter(dst) + for _, e := range list.Entries { + if e.Kind != "file" { + continue + } + + zf, err := zw.Create(path.Join(basePath, e.Name)) + if err != nil { + return err + } + + f, err := os.Open(filepath.Join(exportDir, e.Name)) + if err != nil { + if os.IsNotExist(err) { + return vcsErrorf("file reported by 'svn list', but not written by 'svn export': %s", e.Name) + } + return fmt.Errorf("error opening file created by 'svn export': %v", err) + } + + n, err := io.Copy(zf, f) + f.Close() + if err != nil { + return err + } + if n != e.Size { + return vcsErrorf("file size differs between 'svn list' and 'svn export': file %s listed as %v bytes, but exported as %v bytes", e.Name, e.Size, n) + } + } + + return zw.Close() +} diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go b/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go index 48238f176c6..7284557f4ba 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go @@ -5,7 +5,7 @@ package codehost import ( - "encoding/xml" + "errors" "fmt" "internal/lazyregexp" "io" @@ -122,19 +122,20 @@ func newVCSRepo(vcs, remote string) (Repo, error) { const vcsWorkDirType = "vcs1." type vcsCmd struct { - vcs string // vcs name "hg" - init func(remote string) []string // cmd to init repo to track remote - tags func(remote string) []string // cmd to list local tags - tagRE *lazyregexp.Regexp // regexp to extract tag names from output of tags cmd - branches func(remote string) []string // cmd to list local branches - branchRE *lazyregexp.Regexp // regexp to extract branch names from output of tags cmd - badLocalRevRE *lazyregexp.Regexp // regexp of names that must not be served out of local cache without doing fetch first - statLocal func(rev, remote string) []string // cmd to stat local rev - parseStat func(rev, out string) (*RevInfo, error) // cmd to parse output of statLocal - fetch []string // cmd to fetch everything from remote - latest string // name of latest commit on remote (tip, HEAD, etc) - readFile func(rev, file, remote string) []string // cmd to read rev's file - readZip func(rev, subdir, remote, target string) []string // cmd to read rev's subdir as zip file + vcs string // vcs name "hg" + init func(remote string) []string // cmd to init repo to track remote + tags func(remote string) []string // cmd to list local tags + tagRE *lazyregexp.Regexp // regexp to extract tag names from output of tags cmd + branches func(remote string) []string // cmd to list local branches + branchRE *lazyregexp.Regexp // regexp to extract branch names from output of tags cmd + badLocalRevRE *lazyregexp.Regexp // regexp of names that must not be served out of local cache without doing fetch first + statLocal func(rev, remote string) []string // cmd to stat local rev + parseStat func(rev, out string) (*RevInfo, error) // cmd to parse output of statLocal + fetch []string // cmd to fetch everything from remote + latest string // name of latest commit on remote (tip, HEAD, etc) + readFile func(rev, file, remote string) []string // cmd to read rev's file + readZip func(rev, subdir, remote, target string) []string // cmd to read rev's subdir as zip file + doReadZip func(dst io.Writer, workDir, rev, subdir, remote string) error // arbitrary function to read rev's subdir as zip file } var re = lazyregexp.New @@ -191,7 +192,7 @@ var vcsCmds = map[string]*vcsCmd{ readFile: func(rev, file, remote string) []string { return []string{"svn", "cat", "--", remote + "/" + file + "@" + rev} }, - // TODO: zip + doReadZip: svnReadZip, }, "bzr": { @@ -417,14 +418,14 @@ func (r *vcsRepo) DescendsFrom(rev, tag string) (bool, error) { return false, vcsErrorf("DescendsFrom not implemented") } -func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, actualSubdir string, err error) { - if r.cmd.readZip == nil { - return nil, "", vcsErrorf("ReadZip not implemented for %s", r.cmd.vcs) +func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, err error) { + if r.cmd.readZip == nil && r.cmd.doReadZip == nil { + return nil, vcsErrorf("ReadZip not implemented for %s", r.cmd.vcs) } unlock, err := r.mu.Lock() if err != nil { - return nil, "", err + return nil, err } defer unlock() @@ -433,9 +434,19 @@ func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, } f, err := ioutil.TempFile("", "go-readzip-*.zip") if err != nil { - return nil, "", err + return nil, err } - if r.cmd.vcs == "fossil" { + if r.cmd.doReadZip != nil { + lw := &limitedWriter{ + W: f, + N: maxSize, + ErrLimitReached: errors.New("ReadZip: encoded file exceeds allowed size"), + } + err = r.cmd.doReadZip(lw, r.dir, rev, subdir, r.remote) + if err == nil { + _, err = f.Seek(0, io.SeekStart) + } + } else if r.cmd.vcs == "fossil" { // If you run // fossil zip -R .fossil --name prefix trunk /tmp/x.zip // fossil fails with "unable to create directory /tmp" [sic]. @@ -454,9 +465,9 @@ func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, if err != nil { f.Close() os.Remove(f.Name()) - return nil, "", err + return nil, err } - return &deleteCloser{f}, "", nil + return &deleteCloser{f}, nil } // deleteCloser is a file that gets deleted on Close. @@ -502,31 +513,6 @@ func hgParseStat(rev, out string) (*RevInfo, error) { return info, nil } -func svnParseStat(rev, out string) (*RevInfo, error) { - var log struct { - Logentry struct { - Revision int64 `xml:"revision,attr"` - Date string `xml:"date"` - } `xml:"logentry"` - } - if err := xml.Unmarshal([]byte(out), &log); err != nil { - return nil, vcsErrorf("unexpected response from svn log --xml: %v\n%s", err, out) - } - - t, err := time.Parse(time.RFC3339, log.Logentry.Date) - if err != nil { - return nil, vcsErrorf("unexpected response from svn log --xml: %v\n%s", err, out) - } - - info := &RevInfo{ - Name: fmt.Sprintf("%d", log.Logentry.Revision), - Short: fmt.Sprintf("%012d", log.Logentry.Revision), - Time: t.UTC(), - Version: rev, - } - return info, nil -} - func bzrParseStat(rev, out string) (*RevInfo, error) { var revno int64 var tm time.Time @@ -606,3 +592,25 @@ func fossilParseStat(rev, out string) (*RevInfo, error) { } return nil, vcsErrorf("unexpected response from fossil info: %q", out) } + +type limitedWriter struct { + W io.Writer + N int64 + ErrLimitReached error +} + +func (l *limitedWriter) Write(p []byte) (n int, err error) { + if l.N > 0 { + max := len(p) + if l.N < int64(max) { + max = int(l.N) + } + n, err = l.W.Write(p[:max]) + l.N -= int64(n) + if err != nil || n >= len(p) { + return n, err + } + } + + return n, l.ErrLimitReached +} diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo.go b/libgo/go/cmd/go/internal/modfetch/coderepo.go index f15ce67d460..de757ecd27b 100644 --- a/libgo/go/cmd/go/internal/modfetch/coderepo.go +++ b/libgo/go/cmd/go/internal/modfetch/coderepo.go @@ -6,19 +6,23 @@ package modfetch import ( "archive/zip" + "bytes" "errors" "fmt" "io" "io/ioutil" "os" "path" + "sort" "strings" "time" "cmd/go/internal/modfetch/codehost" - "cmd/go/internal/modfile" - "cmd/go/internal/module" - "cmd/go/internal/semver" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" + "golang.org/x/mod/semver" + modzip "golang.org/x/mod/zip" ) // A codeRepo implements modfetch.Repo using an underlying codehost.Repo. @@ -140,11 +144,13 @@ func (r *codeRepo) Versions(prefix string) ([]string, error) { } tags, err := r.code.Tags(p) if err != nil { - return nil, err + return nil, &module.ModuleError{ + Path: r.modPath, + Err: err, + } } - list := []string{} - var incompatible []string + var list, incompatible []string for _, tag := range tags { if !strings.HasPrefix(tag, p) { continue @@ -156,32 +162,114 @@ func (r *codeRepo) Versions(prefix string) ([]string, error) { if v == "" || v != module.CanonicalVersion(v) || IsPseudoVersion(v) { continue } - if err := module.MatchPathMajor(v, r.pathMajor); err != nil { + + if err := module.CheckPathMajor(v, r.pathMajor); err != nil { if r.codeDir == "" && r.pathMajor == "" && semver.Major(v) > "v1" { incompatible = append(incompatible, v) } continue } + list = append(list, v) } + SortVersions(list) + SortVersions(incompatible) + + return r.appendIncompatibleVersions(list, incompatible) +} - if len(incompatible) > 0 { - // Check for later versions that were created not following semantic import versioning, - // as indicated by the absence of a go.mod file. Those versions can be addressed - // by referring to them with a +incompatible suffix, as in v17.0.0+incompatible. - files, err := r.code.ReadFileRevs(incompatible, "go.mod", codehost.MaxGoMod) +// appendIncompatibleVersions appends "+incompatible" versions to list if +// appropriate, returning the final list. +// +// The incompatible list contains candidate versions without the '+incompatible' +// prefix. +// +// Both list and incompatible must be sorted in semantic order. +func (r *codeRepo) appendIncompatibleVersions(list, incompatible []string) ([]string, error) { + if len(incompatible) == 0 || r.pathMajor != "" { + // No +incompatible versions are possible, so no need to check them. + return list, nil + } + + // We assume that if the latest release of any major version has a go.mod + // file, all subsequent major versions will also have go.mod files (and thus + // be ineligible for use as +incompatible versions). + // If we're wrong about a major version, users will still be able to 'go get' + // specific higher versions explicitly — they just won't affect 'latest' or + // appear in 'go list'. + // + // Conversely, we assume that if the latest release of any major version lacks + // a go.mod file, all versions also lack go.mod files. If we're wrong, we may + // include a +incompatible version that isn't really valid, but most + // operations won't try to use that version anyway. + // + // These optimizations bring + // 'go list -versions -m github.com/openshift/origin' down from 1m58s to 0m37s. + // That's still not great, but a substantial improvement. + + versionHasGoMod := func(v string) (bool, error) { + _, err := r.code.ReadFile(v, "go.mod", codehost.MaxGoMod) + if err == nil { + return true, nil + } + if !os.IsNotExist(err) { + return false, &module.ModuleError{ + Path: r.modPath, + Err: err, + } + } + return false, nil + } + + if len(list) > 0 { + ok, err := versionHasGoMod(list[len(list)-1]) if err != nil { return nil, err } - for _, rev := range incompatible { - f := files[rev] - if os.IsNotExist(f.Err) { - list = append(list, rev+"+incompatible") - } + if ok { + // The latest compatible version has a go.mod file, so assume that all + // subsequent versions do as well, and do not include any +incompatible + // versions. Even if we are wrong, the author clearly intends module + // consumers to be on the v0/v1 line instead of a higher +incompatible + // version. (See https://golang.org/issue/34189.) + // + // We know of at least two examples where this behavior is desired + // (github.com/russross/blackfriday@v2.0.0 and + // github.com/libp2p/go-libp2p@v6.0.23), and (as of 2019-10-29) have no + // concrete examples for which it is undesired. + return list, nil } } - SortVersions(list) + var lastMajor string + for i, v := range incompatible { + major := semver.Major(v) + if major == lastMajor { + list = append(list, v+"+incompatible") + continue + } + + rem := incompatible[i:] + j := sort.Search(len(rem), func(j int) bool { + return semver.Major(rem[j]) != major + }) + latestAtMajor := rem[j-1] + + ok, err := versionHasGoMod(latestAtMajor) + if err != nil { + return nil, err + } + if ok { + // This major version has a go.mod file, so it is not allowed as + // +incompatible. Subsequent major versions are likely to also have + // go.mod files, so stop here. + break + } + + lastMajor = major + list = append(list, v+"+incompatible") + } + return list, nil } @@ -271,7 +359,7 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e Path: r.modPath, Err: &module.InvalidVersionError{ Version: info2.Version, - Err: notExistError(err.Error()), + Err: notExistError{err: err}, }, } } @@ -287,7 +375,7 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e } } - if err := module.MatchPathMajor(strings.TrimSuffix(info2.Version, "+incompatible"), r.pathMajor); err == nil { + if err := module.CheckPathMajor(strings.TrimSuffix(info2.Version, "+incompatible"), r.pathMajor); err == nil { return nil, invalidf("+incompatible suffix not allowed: major version %s is compatible", semver.Major(info2.Version)) } } @@ -311,7 +399,7 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e return checkGoMod() } - if err := module.MatchPathMajor(info2.Version, r.pathMajor); err != nil { + if err := module.CheckPathMajor(info2.Version, r.pathMajor); err != nil { if canUseIncompatible() { info2.Version += "+incompatible" return checkGoMod() @@ -359,7 +447,7 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e tagIsCanonical = true } - if err := module.MatchPathMajor(v, r.pathMajor); err != nil { + if err := module.CheckPathMajor(v, r.pathMajor); err != nil { if canUseIncompatible() { return v + "+incompatible", tagIsCanonical } @@ -458,7 +546,7 @@ func (r *codeRepo) validatePseudoVersion(info *codehost.RevInfo, version string) } }() - if err := module.MatchPathMajor(version, r.pathMajor); err != nil { + if err := module.CheckPathMajor(version, r.pathMajor); err != nil { return err } @@ -631,9 +719,6 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e // because of replacement modules. This might be a fork of // the real module, found at a different path, usable only in // a replace directive. - // - // TODO(bcmills): This doesn't seem right. Investigate futher. - // (Notably: why can't we replace foo/v2 with fork-of-foo/v3?) dir2 := path.Join(r.codeDir, r.pathMajor[1:]) file2 = path.Join(dir2, "go.mod") gomod2, err2 := r.code.ReadFile(rev, file2, codehost.MaxGoMod) @@ -659,11 +744,11 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e // Not v2/go.mod, so it's either go.mod or nothing. Which is it? if found1 { - // Explicit go.mod with matching module path OK. + // Explicit go.mod with matching major version ok. return rev, r.codeDir, gomod1, nil } if err1 == nil { - // Explicit go.mod with non-matching module path disallowed. + // Explicit go.mod with non-matching major version disallowed. suffix := "" if file2 != "" { suffix = fmt.Sprintf(" (and ...%s/go.mod does not exist)", r.pathMajor) @@ -674,6 +759,9 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e if r.pathMajor != "" { // ".v1", ".v2" for gopkg.in return "", "", nil, fmt.Errorf("%s has non-...%s module path %q%s at revision %s", file1, r.pathMajor, mpath1, suffix, rev) } + if _, _, ok := module.SplitPathVersion(mpath1); !ok { + return "", "", nil, fmt.Errorf("%s has malformed module path %q%s at revision %s", file1, mpath1, suffix, rev) + } return "", "", nil, fmt.Errorf("%s has post-%s module path %q%s at revision %s", file1, semver.Major(version), mpath1, suffix, rev) } @@ -690,24 +778,43 @@ func (r *codeRepo) findDir(version string) (rev, dir string, gomod []byte, err e return "", "", nil, fmt.Errorf("missing %s/go.mod at revision %s", r.pathPrefix, rev) } +// isMajor reports whether the versions allowed for mpath are compatible with +// the major version(s) implied by pathMajor, or false if mpath has an invalid +// version suffix. func isMajor(mpath, pathMajor string) bool { if mpath == "" { + // If we don't have a path, we don't know what version(s) it is compatible with. + return false + } + _, mpathMajor, ok := module.SplitPathVersion(mpath) + if !ok { + // An invalid module path is not compatible with any version. return false } if pathMajor == "" { - // mpath must NOT have version suffix. - i := len(mpath) - for i > 0 && '0' <= mpath[i-1] && mpath[i-1] <= '9' { - i-- - } - if i < len(mpath) && i >= 2 && mpath[i-1] == 'v' && mpath[i-2] == '/' { - // Found valid suffix. + // All of the valid versions for a gopkg.in module that requires major + // version v0 or v1 are compatible with the "v0 or v1" implied by an empty + // pathMajor. + switch module.PathMajorPrefix(mpathMajor) { + case "", "v0", "v1": + return true + default: return false } - return true } - // Otherwise pathMajor is ".v1", ".v2" (gopkg.in), or "/v2", "/v3" etc. - return strings.HasSuffix(mpath, pathMajor) + if mpathMajor == "" { + // Even if pathMajor is ".v0" or ".v1", we can't be sure that a module + // without a suffix is tagged appropriately. Besides, we don't expect clones + // of non-gopkg.in modules to have gopkg.in paths, so a non-empty, + // non-gopkg.in mpath is probably the wrong module for any such pathMajor + // anyway. + return false + } + // If both pathMajor and mpathMajor are non-empty, then we only care that they + // have the same major-version validation rules. A clone fetched via a /v2 + // path might replace a module with path gopkg.in/foo.v2-unstable, and that's + // ok. + return pathMajor[1:] == mpathMajor[1:] } func (r *codeRepo) GoMod(version string) (data []byte, err error) { @@ -774,19 +881,16 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error { } } - rev, dir, _, err := r.findDir(version) + rev, subdir, _, err := r.findDir(version) if err != nil { return err } - dl, actualDir, err := r.code.ReadZip(rev, dir, codehost.MaxZipFile) + dl, err := r.code.ReadZip(rev, subdir, codehost.MaxZipFile) if err != nil { return err } defer dl.Close() - if actualDir != "" && !hasPathPrefix(dir, actualDir) { - return fmt.Errorf("internal error: downloading %v %v: dir=%q but actualDir=%q", r.modPath, rev, dir, actualDir) - } - subdir := strings.Trim(strings.TrimPrefix(dir, actualDir), "/") + subdir = strings.Trim(subdir, "/") // Spool to local file. f, err := ioutil.TempFile("", "go-codehost-") @@ -817,13 +921,12 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error { return err } - zw := zip.NewWriter(dst) + var files []modzip.File if subdir != "" { subdir += "/" } haveLICENSE := false topPrefix := "" - haveGoMod := make(map[string]bool) for _, zf := range zr.File { if topPrefix == "" { i := strings.Index(zf.Name, "/") @@ -835,106 +938,61 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error { if !strings.HasPrefix(zf.Name, topPrefix) { return fmt.Errorf("zip file contains more than one top-level directory") } - dir, file := path.Split(zf.Name) - if file == "go.mod" { - haveGoMod[dir] = true - } - } - root := topPrefix + subdir - inSubmodule := func(name string) bool { - for { - dir, _ := path.Split(name) - if len(dir) <= len(root) { - return false - } - if haveGoMod[dir] { - return true - } - name = dir[:len(dir)-1] - } - } - - for _, zf := range zr.File { - if !zf.FileInfo().Mode().IsRegular() { - // Skip symlinks (golang.org/issue/27093). - continue - } - - if topPrefix == "" { - i := strings.Index(zf.Name, "/") - if i < 0 { - return fmt.Errorf("missing top-level directory prefix") - } - topPrefix = zf.Name[:i+1] - } - if strings.HasSuffix(zf.Name, "/") { // drop directory dummy entries - continue - } - if !strings.HasPrefix(zf.Name, topPrefix) { - return fmt.Errorf("zip file contains more than one top-level directory") - } name := strings.TrimPrefix(zf.Name, topPrefix) if !strings.HasPrefix(name, subdir) { continue } - if name == ".hg_archival.txt" { - // Inserted by hg archive. - // Not correct to drop from other version control systems, but too bad. - continue - } name = strings.TrimPrefix(name, subdir) - if isVendoredPackage(name) { - continue - } - if inSubmodule(zf.Name) { + if name == "" || strings.HasSuffix(name, "/") { continue } - base := path.Base(name) - if strings.ToLower(base) == "go.mod" && base != "go.mod" { - return fmt.Errorf("zip file contains %s, want all lower-case go.mod", zf.Name) - } + files = append(files, zipFile{name: name, f: zf}) if name == "LICENSE" { haveLICENSE = true } - size := int64(zf.UncompressedSize64) - if size < 0 || maxSize < size { - return fmt.Errorf("module source tree too big") - } - maxSize -= size - - rc, err := zf.Open() - if err != nil { - return err - } - w, err := zw.Create(r.modPrefix(version) + "/" + name) - if err != nil { - return err - } - lr := &io.LimitedReader{R: rc, N: size + 1} - if _, err := io.Copy(w, lr); err != nil { - return err - } - if lr.N <= 0 { - return fmt.Errorf("individual file too large") - } } if !haveLICENSE && subdir != "" { data, err := r.code.ReadFile(rev, "LICENSE", codehost.MaxLICENSE) if err == nil { - w, err := zw.Create(r.modPrefix(version) + "/LICENSE") - if err != nil { - return err - } - if _, err := w.Write(data); err != nil { - return err - } + files = append(files, dataFile{name: "LICENSE", data: data}) } } - return zw.Close() + return modzip.Create(dst, module.Version{Path: r.modPath, Version: version}, files) +} + +type zipFile struct { + name string + f *zip.File +} + +func (f zipFile) Path() string { return f.name } +func (f zipFile) Lstat() (os.FileInfo, error) { return f.f.FileInfo(), nil } +func (f zipFile) Open() (io.ReadCloser, error) { return f.f.Open() } + +type dataFile struct { + name string + data []byte +} + +func (f dataFile) Path() string { return f.name } +func (f dataFile) Lstat() (os.FileInfo, error) { return dataFileInfo{f}, nil } +func (f dataFile) Open() (io.ReadCloser, error) { + return ioutil.NopCloser(bytes.NewReader(f.data)), nil } +type dataFileInfo struct { + f dataFile +} + +func (fi dataFileInfo) Name() string { return path.Base(fi.f.name) } +func (fi dataFileInfo) Size() int64 { return int64(len(fi.f.data)) } +func (fi dataFileInfo) Mode() os.FileMode { return 0644 } +func (fi dataFileInfo) ModTime() time.Time { return time.Time{} } +func (fi dataFileInfo) IsDir() bool { return false } +func (fi dataFileInfo) Sys() interface{} { return nil } + // hasPathPrefix reports whether the path s begins with the // elements in prefix. func hasPathPrefix(s, prefix string) bool { diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go index 1f2b95bd238..39830948fb0 100644 --- a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go +++ b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go @@ -6,7 +6,11 @@ package modfetch import ( "archive/zip" + "crypto/sha256" + "encoding/hex" + "hash" "internal/testenv" + "io" "io/ioutil" "log" "os" @@ -17,6 +21,8 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/modfetch/codehost" + + "golang.org/x/mod/sumdb/dirhash" ) func TestMain(m *testing.M) { @@ -52,20 +58,22 @@ var altVgotests = map[string]string{ } type codeRepoTest struct { - vcs string - path string - lookerr string - mpath string - rev string - err string - version string - name string - short string - time time.Time - gomod string - gomoderr string - zip []string - ziperr string + vcs string + path string + lookErr string + mpath string + rev string + err string + version string + name string + short string + time time.Time + gomod string + gomodErr string + zip []string + zipErr string + zipSum string + zipFileHash string } var codeRepoTests = []codeRepoTest{ @@ -82,6 +90,8 @@ var codeRepoTests = []codeRepoTest{ "README.md", "pkg/p.go", }, + zipSum: "h1:zVEjciLdlk/TPWCOyZo7k24T+tOKRQC+u8MKq/xS80I=", + zipFileHash: "738a00ddbfe8c329dce6b48e1f23c8e22a92db50f3cfb2653caa0d62676bc09c", }, { vcs: "git", @@ -96,6 +106,8 @@ var codeRepoTests = []codeRepoTest{ "README.md", "pkg/p.go", }, + zipSum: "h1:nOznk2xKsLGkTnXe0q9t1Ewt9jxK+oadtafSUqHM3Ec=", + zipFileHash: "bacb08f391e29d2eaaef8281b5c129ee6d890e608ee65877e0003c0181a766c8", }, { vcs: "git", @@ -116,6 +128,8 @@ var codeRepoTests = []codeRepoTest{ "README.md", "pkg/p.go", }, + zipSum: "h1:e040hOoWGeuJLawDjK9DW6med+cz9FxMFYDMOVG8ctQ=", + zipFileHash: "74caab65cfbea427c341fa815f3bb0378681d8f0e3cf62a7f207014263ec7be3", }, { vcs: "git", @@ -140,6 +154,8 @@ var codeRepoTests = []codeRepoTest{ "README.md", "pkg/p.go", }, + zipSum: "h1:e040hOoWGeuJLawDjK9DW6med+cz9FxMFYDMOVG8ctQ=", + zipFileHash: "74caab65cfbea427c341fa815f3bb0378681d8f0e3cf62a7f207014263ec7be3", }, { vcs: "git", @@ -201,6 +217,8 @@ var codeRepoTests = []codeRepoTest{ "pkg/p.go", "LICENSE", }, + zipSum: "h1:iMsJ/9uQsk6MnZNnJK311f11QiSlmN92Q2aSjCywuJY=", + zipFileHash: "95801bfa69c5197ae809af512946d22f22850068527cd78100ae3f176bc8043b", }, { vcs: "git", @@ -217,16 +235,20 @@ var codeRepoTests = []codeRepoTest{ "go.mod", "pkg/p.go", }, + zipSum: "h1:M69k7q+8bQ+QUpHov45Z/NoR8rj3DsQJUnXLWvf01+Q=", + zipFileHash: "58af45fb248d320ea471f568e006379e2b8d71d6d1663f9b19b2e00fd9ac9265", }, { - vcs: "git", - path: "github.com/rsc/vgotest1/v2", - rev: "v2.0.1", - version: "v2.0.1", - name: "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9", - short: "ea65f87c8f52", - time: time.Date(2018, 2, 19, 23, 14, 23, 0, time.UTC), - gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n", + vcs: "git", + path: "github.com/rsc/vgotest1/v2", + rev: "v2.0.1", + version: "v2.0.1", + name: "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9", + short: "ea65f87c8f52", + time: time.Date(2018, 2, 19, 23, 14, 23, 0, time.UTC), + gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n", + zipSum: "h1:QmgYy/zt+uoWhDpcsgrSVzYFvKtBEjl5zT/FRz9GTzA=", + zipFileHash: "1aedf1546d322a0121879ddfd6d0e8bfbd916d2cafbeb538ddb440e04b04b9ef", }, { vcs: "git", @@ -249,25 +271,29 @@ var codeRepoTests = []codeRepoTest{ err: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4", }, { - vcs: "git", - path: "github.com/rsc/vgotest1/v2", - rev: "v2.0.5", - version: "v2.0.5", - name: "2f615117ce481c8efef46e0cc0b4b4dccfac8fea", - short: "2f615117ce48", - time: time.Date(2018, 2, 20, 0, 3, 59, 0, time.UTC), - gomod: "module \"github.com/rsc/vgotest1/v2\" // v2/go.mod\n", + vcs: "git", + path: "github.com/rsc/vgotest1/v2", + rev: "v2.0.5", + version: "v2.0.5", + name: "2f615117ce481c8efef46e0cc0b4b4dccfac8fea", + short: "2f615117ce48", + time: time.Date(2018, 2, 20, 0, 3, 59, 0, time.UTC), + gomod: "module \"github.com/rsc/vgotest1/v2\" // v2/go.mod\n", + zipSum: "h1:RIEb9q1SUSEQOzMn0zfl/LQxGFWlhWEAdeEguf1MLGU=", + zipFileHash: "7d92c2c328c5e9b0694101353705d5843746ec1d93a1e986d0da54c8a14dfe6d", }, { // redirect to github - vcs: "git", - path: "rsc.io/quote", - rev: "v1.0.0", - version: "v1.0.0", - name: "f488df80bcdbd3e5bafdc24ad7d1e79e83edd7e6", - short: "f488df80bcdb", - time: time.Date(2018, 2, 14, 0, 45, 20, 0, time.UTC), - gomod: "module \"rsc.io/quote\"\n", + vcs: "git", + path: "rsc.io/quote", + rev: "v1.0.0", + version: "v1.0.0", + name: "f488df80bcdbd3e5bafdc24ad7d1e79e83edd7e6", + short: "f488df80bcdb", + time: time.Date(2018, 2, 14, 0, 45, 20, 0, time.UTC), + gomod: "module \"rsc.io/quote\"\n", + zipSum: "h1:haUSojyo3j2M9g7CEUFG8Na09dtn7QKxvPGaPVQdGwM=", + zipFileHash: "5c08ba2c09a364f93704aaa780e7504346102c6ef4fe1333a11f09904a732078", }, { // redirect to static hosting proxy @@ -281,22 +307,26 @@ var codeRepoTests = []codeRepoTest{ }, { // redirect to googlesource - vcs: "git", - path: "golang.org/x/text", - rev: "4e4a3210bb", - version: "v0.3.1-0.20180208041248-4e4a3210bb54", - name: "4e4a3210bb54bb31f6ab2cdca2edcc0b50c420c1", - short: "4e4a3210bb54", - time: time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC), - }, - { - vcs: "git", - path: "github.com/pkg/errors", - rev: "v0.8.0", - version: "v0.8.0", - name: "645ef00459ed84a119197bfb8d8205042c6df63d", - short: "645ef00459ed", - time: time.Date(2016, 9, 29, 1, 48, 1, 0, time.UTC), + vcs: "git", + path: "golang.org/x/text", + rev: "4e4a3210bb", + version: "v0.3.1-0.20180208041248-4e4a3210bb54", + name: "4e4a3210bb54bb31f6ab2cdca2edcc0b50c420c1", + short: "4e4a3210bb54", + time: time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC), + zipSum: "h1:Yxu6pHX9X2RECiuw/Q5/4uvajuaowck8zOFKXgbfNBk=", + zipFileHash: "ac2c165a5c10aa5a7545dea60a08e019270b982fa6c8bdcb5943931de64922fe", + }, + { + vcs: "git", + path: "github.com/pkg/errors", + rev: "v0.8.0", + version: "v0.8.0", + name: "645ef00459ed84a119197bfb8d8205042c6df63d", + short: "645ef00459ed", + time: time.Date(2016, 9, 29, 1, 48, 1, 0, time.UTC), + zipSum: "h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=", + zipFileHash: "e4fa69ba057356614edbc1da881a7d3ebb688505be49f65965686bcb859e2fae", }, { // package in subdirectory - custom domain @@ -304,7 +334,7 @@ var codeRepoTests = []codeRepoTest{ // but gopkg.in is special. vcs: "git", path: "gopkg.in/yaml.v2/abc", - lookerr: "invalid module path \"gopkg.in/yaml.v2/abc\"", + lookErr: "invalid module path \"gopkg.in/yaml.v2/abc\"", }, { // package in subdirectory - github @@ -315,54 +345,52 @@ var codeRepoTests = []codeRepoTest{ err: "missing github.com/rsc/quote/buggy/go.mod at revision c4d4236f9242", }, { - vcs: "git", - path: "gopkg.in/yaml.v2", - rev: "d670f940", - version: "v2.0.0", - name: "d670f9405373e636a5a2765eea47fac0c9bc91a4", - short: "d670f9405373", - time: time.Date(2018, 1, 9, 11, 43, 31, 0, time.UTC), - gomod: "module gopkg.in/yaml.v2\n", - }, - { - vcs: "git", - path: "gopkg.in/check.v1", - rev: "20d25e280405", - version: "v1.0.0-20161208181325-20d25e280405", - name: "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec", - short: "20d25e280405", - time: time.Date(2016, 12, 8, 18, 13, 25, 0, time.UTC), - gomod: "module gopkg.in/check.v1\n", - }, - { - vcs: "git", - path: "gopkg.in/yaml.v2", - rev: "v2", - version: "v2.2.3-0.20190319135612-7b8349ac747c", - name: "7b8349ac747c6a24702b762d2c4fd9266cf4f1d6", - short: "7b8349ac747c", - time: time.Date(2019, 03, 19, 13, 56, 12, 0, time.UTC), - gomod: "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n", - }, - { - vcs: "git", - path: "vcs-test.golang.org/go/mod/gitrepo1", - rev: "master", - version: "v1.2.4-annotated", - name: "ede458df7cd0fdca520df19a33158086a8a68e81", - short: "ede458df7cd0", - time: time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC), - gomod: "module vcs-test.golang.org/go/mod/gitrepo1\n", - }, - { - vcs: "git", - path: "gopkg.in/natefinch/lumberjack.v2", - rev: "latest", - version: "v2.0.0-20170531160350-a96e63847dc3", - name: "a96e63847dc3c67d17befa69c303767e2f84e54f", - short: "a96e63847dc3", - time: time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC), - gomod: "module gopkg.in/natefinch/lumberjack.v2\n", + vcs: "git", + path: "gopkg.in/yaml.v2", + rev: "d670f940", + version: "v2.0.0", + name: "d670f9405373e636a5a2765eea47fac0c9bc91a4", + short: "d670f9405373", + time: time.Date(2018, 1, 9, 11, 43, 31, 0, time.UTC), + gomod: "module gopkg.in/yaml.v2\n", + zipSum: "h1:uUkhRGrsEyx/laRdeS6YIQKIys8pg+lRSRdVMTYjivs=", + zipFileHash: "7b0a141b1b0b49772ab4eecfd11dfd6609a94a5e868cab04a3abb1861ffaa877", + }, + { + vcs: "git", + path: "gopkg.in/check.v1", + rev: "20d25e280405", + version: "v1.0.0-20161208181325-20d25e280405", + name: "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec", + short: "20d25e280405", + time: time.Date(2016, 12, 8, 18, 13, 25, 0, time.UTC), + gomod: "module gopkg.in/check.v1\n", + zipSum: "h1:829vOVxxusYHC+IqBtkX5mbKtsY9fheQiQn0MZRVLfQ=", + zipFileHash: "9e7cb3f4f1e66d722306442b0dbe1f6f43d74d1736d54c510537bdfb1d6f432f", + }, + { + vcs: "git", + path: "vcs-test.golang.org/go/mod/gitrepo1", + rev: "master", + version: "v1.2.4-annotated", + name: "ede458df7cd0fdca520df19a33158086a8a68e81", + short: "ede458df7cd0", + time: time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC), + gomod: "module vcs-test.golang.org/go/mod/gitrepo1\n", + zipSum: "h1:YJYZRsM9BHFTlVr8YADjT0cJH8uFIDtoc5NLiVqZEx8=", + zipFileHash: "c15e49d58b7a4c37966cbe5bc01a0330cd5f2927e990e1839bda1d407766d9c5", + }, + { + vcs: "git", + path: "gopkg.in/natefinch/lumberjack.v2", + rev: "latest", + version: "v2.0.0-20170531160350-a96e63847dc3", + name: "a96e63847dc3c67d17befa69c303767e2f84e54f", + short: "a96e63847dc3", + time: time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC), + gomod: "module gopkg.in/natefinch/lumberjack.v2\n", + zipSum: "h1:AFxeG48hTWHhDTQDk/m2gorfVHUEa9vo3tp3D7TzwjI=", + zipFileHash: "b5de0da7bbbec76709eef1ac71b6c9ff423b9fbf3bb97b56743450d4937b06d5", }, { vcs: "git", @@ -381,14 +409,16 @@ var codeRepoTests = []codeRepoTest{ gomod: "module gopkg.in/natefinch/lumberjack.v2\n", }, { - vcs: "git", - path: "vcs-test.golang.org/go/v2module/v2", - rev: "v2.0.0", - version: "v2.0.0", - name: "203b91c896acd173aa719e4cdcb7d463c4b090fa", - short: "203b91c896ac", - time: time.Date(2019, 4, 3, 15, 52, 15, 0, time.UTC), - gomod: "module vcs-test.golang.org/go/v2module/v2\n\ngo 1.12\n", + vcs: "git", + path: "vcs-test.golang.org/go/v2module/v2", + rev: "v2.0.0", + version: "v2.0.0", + name: "203b91c896acd173aa719e4cdcb7d463c4b090fa", + short: "203b91c896ac", + time: time.Date(2019, 4, 3, 15, 52, 15, 0, time.UTC), + gomod: "module vcs-test.golang.org/go/v2module/v2\n\ngo 1.12\n", + zipSum: "h1:JItBZ+gwA5WvtZEGEbuDL4lUttGtLrs53lmdurq3bOg=", + zipFileHash: "9ea9ae1673cffcc44b7fdd3cc89953d68c102449b46c982dbf085e4f2e394da5", }, } @@ -411,21 +441,23 @@ func TestCodeRepo(t *testing.T) { } repo, err := Lookup("direct", tt.path) - if tt.lookerr != "" { - if err != nil && err.Error() == tt.lookerr { + if tt.lookErr != "" { + if err != nil && err.Error() == tt.lookErr { return } - t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookerr) + t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookErr) } if err != nil { t.Fatalf("Lookup(%q): %v", tt.path, err) } + if tt.mpath == "" { tt.mpath = tt.path } if mpath := repo.ModulePath(); mpath != tt.mpath { t.Errorf("repo.ModulePath() = %q, want %q", mpath, tt.mpath) } + info, err := repo.Stat(tt.rev) if err != nil { if tt.err != "" { @@ -451,56 +483,86 @@ func TestCodeRepo(t *testing.T) { if !info.Time.Equal(tt.time) { t.Errorf("info.Time = %v, want %v", info.Time, tt.time) } - if tt.gomod != "" || tt.gomoderr != "" { + + if tt.gomod != "" || tt.gomodErr != "" { data, err := repo.GoMod(tt.version) - if err != nil && tt.gomoderr == "" { + if err != nil && tt.gomodErr == "" { t.Errorf("repo.GoMod(%q): %v", tt.version, err) - } else if err != nil && tt.gomoderr != "" { - if err.Error() != tt.gomoderr { - t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomoderr) + } else if err != nil && tt.gomodErr != "" { + if err.Error() != tt.gomodErr { + t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomodErr) } - } else if tt.gomoderr != "" { - t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomoderr) + } else if tt.gomodErr != "" { + t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomodErr) } else if string(data) != tt.gomod { t.Errorf("repo.GoMod(%q) = %q, want %q", tt.version, data, tt.gomod) } } - if tt.zip != nil || tt.ziperr != "" { + + needHash := !testing.Short() && (tt.zipFileHash != "" || tt.zipSum != "") + if tt.zip != nil || tt.zipErr != "" || needHash { f, err := ioutil.TempFile(tmpdir, tt.version+".zip.") if err != nil { t.Fatalf("ioutil.TempFile: %v", err) } zipfile := f.Name() - err = repo.Zip(f, tt.version) + defer func() { + f.Close() + os.Remove(zipfile) + }() + + var w io.Writer + var h hash.Hash + if needHash { + h = sha256.New() + w = io.MultiWriter(f, h) + } else { + w = f + } + err = repo.Zip(w, tt.version) f.Close() if err != nil { - if tt.ziperr != "" { - if err.Error() == tt.ziperr { + if tt.zipErr != "" { + if err.Error() == tt.zipErr { return } - t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.ziperr) + t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.zipErr) } t.Fatalf("repo.Zip(%q): %v", tt.version, err) } - if tt.ziperr != "" { - t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.ziperr) - } - prefix := tt.path + "@" + tt.version + "/" - z, err := zip.OpenReader(zipfile) - if err != nil { - t.Fatalf("open zip %s: %v", zipfile, err) + if tt.zipErr != "" { + t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.zipErr) } - var names []string - for _, file := range z.File { - if !strings.HasPrefix(file.Name, prefix) { - t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix) - continue + + if tt.zip != nil { + prefix := tt.path + "@" + tt.version + "/" + z, err := zip.OpenReader(zipfile) + if err != nil { + t.Fatalf("open zip %s: %v", zipfile, err) + } + var names []string + for _, file := range z.File { + if !strings.HasPrefix(file.Name, prefix) { + t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix) + continue + } + names = append(names, file.Name[len(prefix):]) + } + z.Close() + if !reflect.DeepEqual(names, tt.zip) { + t.Fatalf("zip = %v\nwant %v\n", names, tt.zip) } - names = append(names, file.Name[len(prefix):]) } - z.Close() - if !reflect.DeepEqual(names, tt.zip) { - t.Fatalf("zip = %v\nwant %v\n", names, tt.zip) + + if needHash { + sum, err := dirhash.HashZip(zipfile, dirhash.Hash1) + if err != nil { + t.Errorf("repo.Zip(%q): %v", tt.version, err) + } else if sum != tt.zipSum { + t.Errorf("repo.Zip(%q): got file with sum %q, want %q", tt.version, sum, tt.zipSum) + } else if zipFileHash := hex.EncodeToString(h.Sum(nil)); zipFileHash != tt.zipFileHash { + t.Errorf("repo.Zip(%q): got file with hash %q, want %q (but content has correct sum)", tt.version, zipFileHash, tt.zipFileHash) + } } } } @@ -508,26 +570,26 @@ func TestCodeRepo(t *testing.T) { t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt)) if strings.HasPrefix(tt.path, vgotest1git) { for vcs, alt := range altVgotests { - // Note: Communicating with f through tt; should be cleaned up. - old := tt - tt.vcs = vcs - tt.path = alt + strings.TrimPrefix(tt.path, vgotest1git) - if strings.HasPrefix(tt.mpath, vgotest1git) { - tt.mpath = alt + strings.TrimPrefix(tt.mpath, vgotest1git) + altTest := tt + altTest.vcs = vcs + altTest.path = alt + strings.TrimPrefix(altTest.path, vgotest1git) + if strings.HasPrefix(altTest.mpath, vgotest1git) { + altTest.mpath = alt + strings.TrimPrefix(altTest.mpath, vgotest1git) } var m map[string]string if alt == vgotest1hg { m = hgmap } - tt.version = remap(tt.version, m) - tt.name = remap(tt.name, m) - tt.short = remap(tt.short, m) - tt.rev = remap(tt.rev, m) - tt.err = remap(tt.err, m) - tt.gomoderr = remap(tt.gomoderr, m) - tt.ziperr = remap(tt.ziperr, m) - t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt)) - tt = old + altTest.version = remap(altTest.version, m) + altTest.name = remap(altTest.name, m) + altTest.short = remap(altTest.short, m) + altTest.rev = remap(altTest.rev, m) + altTest.err = remap(altTest.err, m) + altTest.gomodErr = remap(altTest.gomodErr, m) + altTest.zipErr = remap(altTest.zipErr, m) + altTest.zipSum = "" + altTest.zipFileHash = "" + t.Run(strings.ReplaceAll(altTest.path, "/", "_")+"/"+altTest.rev, f(altTest)) } } } @@ -575,7 +637,7 @@ var codeRepoVersionsTests = []struct { { vcs: "git", path: "github.com/rsc/vgotest1", - versions: []string{"v0.0.0", "v0.0.1", "v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3", "v1.1.0", "v2.0.0+incompatible"}, + versions: []string{"v0.0.0", "v0.0.1", "v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3", "v1.1.0"}, }, { vcs: "git", diff --git a/libgo/go/cmd/go/internal/modfetch/fetch.go b/libgo/go/cmd/go/internal/modfetch/fetch.go index 51a56028c4a..54fbd92b43e 100644 --- a/libgo/go/cmd/go/internal/modfetch/fetch.go +++ b/libgo/go/cmd/go/internal/modfetch/fetch.go @@ -7,6 +7,7 @@ package modfetch import ( "archive/zip" "bytes" + "errors" "fmt" "io" "io/ioutil" @@ -18,10 +19,13 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/dirhash" - "cmd/go/internal/module" + "cmd/go/internal/lockedfile" "cmd/go/internal/par" "cmd/go/internal/renameio" + + "golang.org/x/mod/module" + "golang.org/x/mod/sumdb/dirhash" + modzip "golang.org/x/mod/zip" ) var downloadCache par.Cache @@ -69,10 +73,6 @@ func download(mod module.Version, dir string) (err error) { return err } - if cfg.CmdName != "mod download" { - fmt.Fprintf(os.Stderr, "go: extracting %s %s\n", mod.Path, mod.Version) - } - unlock, err := lockVersion(mod) if err != nil { return err @@ -114,8 +114,7 @@ func download(mod module.Version, dir string) (err error) { } }() - modpath := mod.Path + "@" + mod.Version - if err := Unzip(tmpDir, zipfile, modpath, 0); err != nil { + if err := modzip.Unzip(tmpDir, mod, zipfile); err != nil { fmt.Fprintf(os.Stderr, "-> %s\n", err) return err } @@ -124,9 +123,11 @@ func download(mod module.Version, dir string) (err error) { return err } - // Make dir read-only only *after* renaming it. - // os.Rename was observed to fail for read-only directories on macOS. - makeDirsReadOnly(dir) + if !cfg.ModCacheRW { + // Make dir read-only only *after* renaming it. + // os.Rename was observed to fail for read-only directories on macOS. + makeDirsReadOnly(dir) + } return nil } @@ -249,7 +250,9 @@ func downloadZip(mod module.Version, zipfile string) (err error) { if err != nil { return err } - checkModSum(mod, hash) + if err := checkModSum(mod, hash); err != nil { + return err + } if err := renameio.WriteFile(zipfile+"hash", []byte(hash), 0666); err != nil { return err @@ -263,6 +266,45 @@ func downloadZip(mod module.Version, zipfile string) (err error) { return nil } +// makeDirsReadOnly makes a best-effort attempt to remove write permissions for dir +// and its transitive contents. +func makeDirsReadOnly(dir string) { + type pathMode struct { + path string + mode os.FileMode + } + var dirs []pathMode // in lexical order + filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err == nil && info.Mode()&0222 != 0 { + if info.IsDir() { + dirs = append(dirs, pathMode{path, info.Mode()}) + } + } + return nil + }) + + // Run over list backward to chmod children before parents. + for i := len(dirs) - 1; i >= 0; i-- { + os.Chmod(dirs[i].path, dirs[i].mode&^0222) + } +} + +// RemoveAll removes a directory written by Download or Unzip, first applying +// any permission changes needed to do so. +func RemoveAll(dir string) error { + // Module cache has 0555 directories; make them writable in order to remove content. + filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return nil // ignore errors walking in file system + } + if info.IsDir() { + os.Chmod(path, 0777) + } + return nil + }) + return os.RemoveAll(dir) +} + var GoSumFile string // path to go.sum; set by package modload type modSum struct { @@ -281,21 +323,22 @@ var goSum struct { } // initGoSum initializes the go.sum data. -// It reports whether use of go.sum is now enabled. +// The boolean it returns reports whether the +// use of go.sum is now enabled. // The goSum lock must be held. -func initGoSum() bool { +func initGoSum() (bool, error) { if GoSumFile == "" { - return false + return false, nil } if goSum.m != nil { - return true + return true, nil } goSum.m = make(map[module.Version][]string) goSum.checked = make(map[modSum]bool) - data, err := renameio.ReadFile(GoSumFile) + data, err := lockedfile.Read(GoSumFile) if err != nil && !os.IsNotExist(err) { - base.Fatalf("go: %v", err) + return false, err } goSum.enabled = true readGoSum(goSum.m, GoSumFile, data) @@ -313,7 +356,7 @@ func initGoSum() bool { } goSum.modverify = alt } - return true + return true, nil } // emptyGoModHash is the hash of a 1-file tree containing a 0-length go.mod. @@ -323,7 +366,7 @@ const emptyGoModHash = "h1:G7mAYYxgmS0lVkHyy2hEOLQCFB0DlQFTMLWggykrydY=" // readGoSum parses data, which is the content of file, // and adds it to goSum.m. The goSum lock must be held. -func readGoSum(dst map[module.Version][]string, file string, data []byte) { +func readGoSum(dst map[module.Version][]string, file string, data []byte) error { lineno := 0 for len(data) > 0 { var line []byte @@ -340,7 +383,7 @@ func readGoSum(dst map[module.Version][]string, file string, data []byte) { continue } if len(f) != 3 { - base.Fatalf("go: malformed go.sum:\n%s:%d: wrong number of fields %v", file, lineno, len(f)) + return fmt.Errorf("malformed go.sum:\n%s:%d: wrong number of fields %v", file, lineno, len(f)) } if f[2] == emptyGoModHash { // Old bug; drop it. @@ -349,6 +392,7 @@ func readGoSum(dst map[module.Version][]string, file string, data []byte) { mod := module.Version{Path: f[0], Version: f[1]} dst[mod] = append(dst[mod], f[2]) } + return nil } // checkMod checks the given module's checksum. @@ -361,22 +405,24 @@ func checkMod(mod module.Version) { // Do the file I/O before acquiring the go.sum lock. ziphash, err := CachePath(mod, "ziphash") if err != nil { - base.Fatalf("verifying %s@%s: %v", mod.Path, mod.Version, err) + base.Fatalf("verifying %v", module.VersionError(mod, err)) } data, err := renameio.ReadFile(ziphash) if err != nil { - if os.IsNotExist(err) { + if errors.Is(err, os.ErrNotExist) { // This can happen if someone does rm -rf GOPATH/src/cache/download. So it goes. return } - base.Fatalf("verifying %s@%s: %v", mod.Path, mod.Version, err) + base.Fatalf("verifying %v", module.VersionError(mod, err)) } h := strings.TrimSpace(string(data)) if !strings.HasPrefix(h, "h1:") { - base.Fatalf("verifying %s@%s: unexpected ziphash: %q", mod.Path, mod.Version, h) + base.Fatalf("verifying %v", module.VersionError(mod, fmt.Errorf("unexpected ziphash: %q", h))) } - checkModSum(mod, h) + if err := checkModSum(mod, h); err != nil { + base.Fatalf("%s", err) + } } // goModSum returns the checksum for the go.mod contents. @@ -388,17 +434,17 @@ func goModSum(data []byte) (string, error) { // checkGoMod checks the given module's go.mod checksum; // data is the go.mod content. -func checkGoMod(path, version string, data []byte) { +func checkGoMod(path, version string, data []byte) error { h, err := goModSum(data) if err != nil { - base.Fatalf("verifying %s %s go.mod: %v", path, version, err) + return &module.ModuleError{Path: path, Version: version, Err: fmt.Errorf("verifying go.mod: %v", err)} } - checkModSum(module.Version{Path: path, Version: version + "/go.mod"}, h) + return checkModSum(module.Version{Path: path, Version: version + "/go.mod"}, h) } // checkModSum checks that the recorded checksum for mod is h. -func checkModSum(mod module.Version, h string) { +func checkModSum(mod module.Version, h string) error { // We lock goSum when manipulating it, // but we arrange to release the lock when calling checkSumDB, // so that parallel calls to checkModHash can execute parallel calls @@ -406,19 +452,24 @@ func checkModSum(mod module.Version, h string) { // Check whether mod+h is listed in go.sum already. If so, we're done. goSum.mu.Lock() - inited := initGoSum() + inited, err := initGoSum() + if err != nil { + return err + } done := inited && haveModSumLocked(mod, h) goSum.mu.Unlock() if done { - return + return nil } // Not listed, so we want to add them. // Consult checksum database if appropriate. if useSumDB(mod) { // Calls base.Fatalf if mismatch detected. - checkSumDB(mod, h) + if err := checkSumDB(mod, h); err != nil { + return err + } } // Add mod+h to go.sum, if it hasn't appeared already. @@ -427,6 +478,7 @@ func checkModSum(mod module.Version, h string) { addModSumLocked(mod, h) goSum.mu.Unlock() } + return nil } // haveModSumLocked reports whether the pair mod,h is already listed in go.sum. @@ -460,22 +512,23 @@ func addModSumLocked(mod module.Version, h string) { // checkSumDB checks the mod, h pair against the Go checksum database. // It calls base.Fatalf if the hash is to be rejected. -func checkSumDB(mod module.Version, h string) { +func checkSumDB(mod module.Version, h string) error { db, lines, err := lookupSumDB(mod) if err != nil { - base.Fatalf("verifying %s@%s: %v", mod.Path, mod.Version, err) + return module.VersionError(mod, fmt.Errorf("verifying module: %v", err)) } have := mod.Path + " " + mod.Version + " " + h prefix := mod.Path + " " + mod.Version + " h1:" for _, line := range lines { if line == have { - return + return nil } if strings.HasPrefix(line, prefix) { - base.Fatalf("verifying %s@%s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, mod.Path, mod.Version, h, db, line[len(prefix)-len("h1:"):]) + return module.VersionError(mod, fmt.Errorf("verifying module: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, h, db, line[len(prefix)-len("h1:"):])) } } + return nil } // Sum returns the checksum for the downloaded copy of the given module, @@ -516,60 +569,45 @@ func WriteGoSum() { base.Fatalf("go: updates to go.sum needed, disabled by -mod=readonly") } - // We want to avoid races between creating the lockfile and deleting it, but - // we also don't want to leave a permanent lockfile in the user's repository. - // - // On top of that, if we crash while writing go.sum, we don't want to lose the - // sums that were already present in the file, so it's important that we write - // the file by renaming rather than truncating — which means that we can't - // lock the go.sum file itself. - // - // Instead, we'll lock a distinguished file in the cache directory: that will - // only race if the user runs `go clean -modcache` concurrently with a command - // that updates go.sum, and that's already racy to begin with. - // - // We'll end up slightly over-synchronizing go.sum writes if the user runs a - // bunch of go commands that update sums in separate modules simultaneously, - // but that's unlikely to matter in practice. - - unlock := SideLock() - defer unlock() + // Make a best-effort attempt to acquire the side lock, only to exclude + // previous versions of the 'go' command from making simultaneous edits. + if unlock, err := SideLock(); err == nil { + defer unlock() + } - if !goSum.overwrite { - // Re-read the go.sum file to incorporate any sums added by other processes - // in the meantime. - data, err := renameio.ReadFile(GoSumFile) - if err != nil && !os.IsNotExist(err) { - base.Fatalf("go: re-reading go.sum: %v", err) - } - - // Add only the sums that we actually checked: the user may have edited or - // truncated the file to remove erroneous hashes, and we shouldn't restore - // them without good reason. - goSum.m = make(map[module.Version][]string, len(goSum.m)) - readGoSum(goSum.m, GoSumFile, data) - for ms := range goSum.checked { - addModSumLocked(ms.mod, ms.sum) - goSum.dirty = true + err := lockedfile.Transform(GoSumFile, func(data []byte) ([]byte, error) { + if !goSum.overwrite { + // Incorporate any sums added by other processes in the meantime. + // Add only the sums that we actually checked: the user may have edited or + // truncated the file to remove erroneous hashes, and we shouldn't restore + // them without good reason. + goSum.m = make(map[module.Version][]string, len(goSum.m)) + readGoSum(goSum.m, GoSumFile, data) + for ms := range goSum.checked { + addModSumLocked(ms.mod, ms.sum) + goSum.dirty = true + } } - } - var mods []module.Version - for m := range goSum.m { - mods = append(mods, m) - } - module.Sort(mods) - var buf bytes.Buffer - for _, m := range mods { - list := goSum.m[m] - sort.Strings(list) - for _, h := range list { - fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h) + var mods []module.Version + for m := range goSum.m { + mods = append(mods, m) } - } + module.Sort(mods) + + var buf bytes.Buffer + for _, m := range mods { + list := goSum.m[m] + sort.Strings(list) + for _, h := range list { + fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h) + } + } + return buf.Bytes(), nil + }) - if err := renameio.WriteFile(GoSumFile, buf.Bytes(), 0666); err != nil { - base.Fatalf("go: writing go.sum: %v", err) + if err != nil { + base.Fatalf("go: updating go.sum: %v", err) } goSum.checked = make(map[modSum]bool) @@ -585,7 +623,11 @@ func WriteGoSum() { func TrimGoSum(keep map[module.Version]bool) { goSum.mu.Lock() defer goSum.mu.Unlock() - if !initGoSum() { + inited, err := initGoSum() + if err != nil { + base.Fatalf("%s", err) + } + if !inited { return } diff --git a/libgo/go/cmd/go/internal/modfetch/insecure.go b/libgo/go/cmd/go/internal/modfetch/insecure.go new file mode 100644 index 00000000000..8420432d6cd --- /dev/null +++ b/libgo/go/cmd/go/internal/modfetch/insecure.go @@ -0,0 +1,16 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modfetch + +import ( + "cmd/go/internal/cfg" + "cmd/go/internal/get" + "cmd/go/internal/str" +) + +// allowInsecure reports whether we are allowed to fetch this path in an insecure manner. +func allowInsecure(path string) bool { + return get.Insecure || str.GlobsMatchPath(cfg.GOINSECURE, path) +} diff --git a/libgo/go/cmd/go/internal/modfetch/proxy.go b/libgo/go/cmd/go/internal/modfetch/proxy.go index 569ef3a57a6..dcea71adb3a 100644 --- a/libgo/go/cmd/go/internal/modfetch/proxy.go +++ b/libgo/go/cmd/go/internal/modfetch/proxy.go @@ -22,9 +22,10 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/modfetch/codehost" - "cmd/go/internal/module" - "cmd/go/internal/semver" "cmd/go/internal/web" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) var HelpGoproxy = &base.Command{ @@ -38,8 +39,8 @@ can be a module proxy. The GET requests sent to a Go module proxy are: -GET $GOPROXY//@v/list returns a list of all known versions of the -given module, one per line. +GET $GOPROXY//@v/list returns a list of known versions of the given +module, one per line. GET $GOPROXY//@v/.info returns JSON-formatted metadata about that version of the given module. @@ -50,6 +51,21 @@ for that version of the given module. GET $GOPROXY//@v/.zip returns the zip archive for that version of the given module. +GET $GOPROXY//@latest returns JSON-formatted metadata about the +latest known version of the given module in the same format as +/@v/.info. The latest version should be the version of +the module the go command may use if /@v/list is empty or no +listed version is suitable. /@latest is optional and may not +be implemented by a module proxy. + +When resolving the latest version of a module, the go command will request +/@v/list, then, if no suitable versions are found, /@latest. +The go command prefers, in order: the semantically highest release version, +the semantically highest pre-release version, and the chronologically +most recent pseudo-version. In Go 1.12 and earlier, the go command considered +pseudo-versions in /@v/list to be pre-release versions, but this is +no longer true since Go 1.13. + To avoid problems when serving from case-sensitive file systems, the and elements are case-encoded, replacing every uppercase letter with an exclamation mark followed by the corresponding @@ -150,13 +166,28 @@ func TryProxies(f func(proxy string) error) error { return f("off") } + var lastAttemptErr error for _, proxy := range proxies { err = f(proxy) if !errors.Is(err, os.ErrNotExist) { + lastAttemptErr = err break } + + // The error indicates that the module does not exist. + // In general we prefer to report the last such error, + // because it indicates the error that occurs after all other + // options have been exhausted. + // + // However, for modules in the NOPROXY list, the most useful error occurs + // first (with proxy set to "noproxy"), and the subsequent errors are all + // errNoProxy (which is not particularly helpful). Do not overwrite a more + // useful error with errNoproxy. + if lastAttemptErr == nil || !errors.Is(err, errNoproxy) { + lastAttemptErr = err + } } - return err + return lastAttemptErr } type proxyRepo struct { @@ -182,7 +213,7 @@ func newProxyRepo(baseURL, path string) (Repo, error) { return nil, fmt.Errorf("invalid proxy URL scheme (must be https, http, file): %s", web.Redacted(base)) } - enc, err := module.EncodePath(path) + enc, err := module.EscapePath(path) if err != nil { return nil, err } @@ -321,7 +352,7 @@ func (p *proxyRepo) latest() (*RevInfo, error) { } func (p *proxyRepo) Stat(rev string) (*RevInfo, error) { - encRev, err := module.EncodeVersion(rev) + encRev, err := module.EscapeVersion(rev) if err != nil { return nil, p.versionError(rev, err) } @@ -362,7 +393,7 @@ func (p *proxyRepo) GoMod(version string) ([]byte, error) { return nil, p.versionError(version, fmt.Errorf("internal error: version passed to GoMod is not canonical")) } - encVer, err := module.EncodeVersion(version) + encVer, err := module.EscapeVersion(version) if err != nil { return nil, p.versionError(version, err) } @@ -378,7 +409,7 @@ func (p *proxyRepo) Zip(dst io.Writer, version string) error { return p.versionError(version, fmt.Errorf("internal error: version passed to Zip is not canonical")) } - encVer, err := module.EncodeVersion(version) + encVer, err := module.EscapeVersion(version) if err != nil { return p.versionError(version, err) } diff --git a/libgo/go/cmd/go/internal/modfetch/pseudo.go b/libgo/go/cmd/go/internal/modfetch/pseudo.go index 8c063b9107f..57dee11d071 100644 --- a/libgo/go/cmd/go/internal/modfetch/pseudo.go +++ b/libgo/go/cmd/go/internal/modfetch/pseudo.go @@ -40,9 +40,10 @@ import ( "strings" "time" - "cmd/go/internal/module" - "cmd/go/internal/semver" "internal/lazyregexp" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) var pseudoVersionRE = lazyregexp.New(`^v[0-9]+\.(0\.0-|\d+\.\d+-([^+]*\.)?0\.)\d{14}-[A-Za-z0-9]+(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$`) diff --git a/libgo/go/cmd/go/internal/modfetch/repo.go b/libgo/go/cmd/go/internal/modfetch/repo.go index be52a8dc11f..f03bdd8d038 100644 --- a/libgo/go/cmd/go/internal/modfetch/repo.go +++ b/libgo/go/cmd/go/internal/modfetch/repo.go @@ -5,7 +5,6 @@ package modfetch import ( - "errors" "fmt" "io" "os" @@ -17,9 +16,10 @@ import ( "cmd/go/internal/get" "cmd/go/internal/modfetch/codehost" "cmd/go/internal/par" - "cmd/go/internal/semver" "cmd/go/internal/str" web "cmd/go/internal/web" + + "golang.org/x/mod/semver" ) const traceRepo = false // trace all repo actions, for debugging @@ -34,7 +34,7 @@ type Repo interface { // Pseudo-versions are not included. // Versions should be returned sorted in semver order // (implementations can use SortVersions). - Versions(prefix string) (tags []string, err error) + Versions(prefix string) ([]string, error) // Stat returns information about the revision rev. // A revision can be any identifier known to the underlying service: @@ -55,7 +55,7 @@ type Repo interface { // A Rev describes a single revision in a module repository. type RevInfo struct { - Version string // version string + Version string // suggested version string for this revision Time time.Time // commit time // These fields are used for Stat of arbitrary rev, @@ -214,7 +214,7 @@ func Lookup(proxy, path string) (Repo, error) { // lookup returns the module with the given module path. func lookup(proxy, path string) (r Repo, err error) { if cfg.BuildMod == "vendor" { - return nil, errModVendor + return nil, errLookupDisabled } if str.GlobsMatchPath(cfg.GONOPROXY, path) { @@ -238,22 +238,33 @@ func lookup(proxy, path string) (r Repo, err error) { } } +type lookupDisabledError struct{} + +func (lookupDisabledError) Error() string { + if cfg.BuildModReason == "" { + return fmt.Sprintf("module lookup disabled by -mod=%s", cfg.BuildMod) + } + return fmt.Sprintf("module lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason) +} + +var errLookupDisabled error = lookupDisabledError{} + var ( - errModVendor = errors.New("module lookup disabled by -mod=vendor") - errProxyOff = notExistError("module lookup disabled by GOPROXY=off") - errNoproxy error = notExistError("disabled by GOPRIVATE/GONOPROXY") - errUseProxy error = notExistError("path does not match GOPRIVATE/GONOPROXY") + errProxyOff = notExistErrorf("module lookup disabled by GOPROXY=off") + errNoproxy error = notExistErrorf("disabled by GOPRIVATE/GONOPROXY") + errUseProxy error = notExistErrorf("path does not match GOPRIVATE/GONOPROXY") ) func lookupDirect(path string) (Repo, error) { security := web.SecureOnly - if get.Insecure { + + if allowInsecure(path) { security = web.Insecure } rr, err := get.RepoRootForImportPath(path, get.PreferMod, security) if err != nil { // We don't know where to find code for a module with this path. - return nil, notExistError(err.Error()) + return nil, notExistError{err: err} } if rr.VCS == "mod" { @@ -292,7 +303,7 @@ func ImportRepoRev(path, rev string) (Repo, *RevInfo, error) { // version control system, we ignore meta tags about modules // and use only direct source control entries (get.IgnoreMod). security := web.SecureOnly - if get.Insecure { + if allowInsecure(path) { security = web.Insecure } rr, err := get.RepoRootForImportPath(path, get.IgnoreMod, security) @@ -397,11 +408,22 @@ func (l *loggingRepo) Zip(dst io.Writer, version string) error { } // A notExistError is like os.ErrNotExist, but with a custom message -type notExistError string +type notExistError struct { + err error +} + +func notExistErrorf(format string, args ...interface{}) error { + return notExistError{fmt.Errorf(format, args...)} +} func (e notExistError) Error() string { - return string(e) + return e.err.Error() } + func (notExistError) Is(target error) bool { return target == os.ErrNotExist } + +func (e notExistError) Unwrap() error { + return e.err +} diff --git a/libgo/go/cmd/go/internal/modfetch/sumdb.go b/libgo/go/cmd/go/internal/modfetch/sumdb.go index 1c24ec273b5..1ed71dfb85c 100644 --- a/libgo/go/cmd/go/internal/modfetch/sumdb.go +++ b/libgo/go/cmd/go/internal/modfetch/sumdb.go @@ -24,11 +24,11 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/get" "cmd/go/internal/lockedfile" - "cmd/go/internal/module" - "cmd/go/internal/note" "cmd/go/internal/str" - "cmd/go/internal/sumweb" "cmd/go/internal/web" + "golang.org/x/mod/module" + "golang.org/x/mod/sumdb" + "golang.org/x/mod/sumdb/note" ) // useSumDB reports whether to use the Go checksum database for the given module. @@ -52,11 +52,11 @@ func lookupSumDB(mod module.Version) (dbname string, lines []string, err error) var ( dbOnce sync.Once dbName string - db *sumweb.Conn + db *sumdb.Client dbErr error ) -func dbDial() (dbName string, db *sumweb.Conn, err error) { +func dbDial() (dbName string, db *sumdb.Client, err error) { // $GOSUMDB can be "key" or "key url", // and the key can be a full verifier key // or a host on our list of known keys. @@ -106,7 +106,7 @@ func dbDial() (dbName string, db *sumweb.Conn, err error) { base = u } - return name, sumweb.NewConn(&dbClient{key: key[0], name: name, direct: direct, base: base}), nil + return name, sumdb.NewClient(&dbClient{key: key[0], name: name, direct: direct, base: base}), nil } type dbClient struct { @@ -227,7 +227,7 @@ func (*dbClient) WriteConfig(file string, old, new []byte) error { return err } if len(data) > 0 && !bytes.Equal(data, old) { - return sumweb.ErrWriteConflict + return sumdb.ErrWriteConflict } if _, err := f.Seek(0, 0); err != nil { return err diff --git a/libgo/go/cmd/go/internal/modfetch/unzip.go b/libgo/go/cmd/go/internal/modfetch/unzip.go deleted file mode 100644 index ac13ede257b..00000000000 --- a/libgo/go/cmd/go/internal/modfetch/unzip.go +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package modfetch - -import ( - "archive/zip" - "fmt" - "io" - "io/ioutil" - "os" - "path" - "path/filepath" - "strings" - - "cmd/go/internal/modfetch/codehost" - "cmd/go/internal/module" - "cmd/go/internal/str" -) - -func Unzip(dir, zipfile, prefix string, maxSize int64) error { - // TODO(bcmills): The maxSize parameter is invariantly 0. Remove it. - if maxSize == 0 { - maxSize = codehost.MaxZipFile - } - - // Directory can exist, but must be empty. - files, _ := ioutil.ReadDir(dir) - if len(files) > 0 { - return fmt.Errorf("target directory %v exists and is not empty", dir) - } - if err := os.MkdirAll(dir, 0777); err != nil { - return err - } - - f, err := os.Open(zipfile) - if err != nil { - return err - } - defer f.Close() - info, err := f.Stat() - if err != nil { - return err - } - - z, err := zip.NewReader(f, info.Size()) - if err != nil { - return fmt.Errorf("unzip %v: %s", zipfile, err) - } - - foldPath := make(map[string]string) - var checkFold func(string) error - checkFold = func(name string) error { - fold := str.ToFold(name) - if foldPath[fold] == name { - return nil - } - dir := path.Dir(name) - if dir != "." { - if err := checkFold(dir); err != nil { - return err - } - } - if foldPath[fold] == "" { - foldPath[fold] = name - return nil - } - other := foldPath[fold] - return fmt.Errorf("unzip %v: case-insensitive file name collision: %q and %q", zipfile, other, name) - } - - // Check total size, valid file names. - var size int64 - for _, zf := range z.File { - if !str.HasPathPrefix(zf.Name, prefix) { - return fmt.Errorf("unzip %v: unexpected file name %s", zipfile, zf.Name) - } - if zf.Name == prefix || strings.HasSuffix(zf.Name, "/") { - continue - } - name := zf.Name[len(prefix)+1:] - if err := module.CheckFilePath(name); err != nil { - return fmt.Errorf("unzip %v: %v", zipfile, err) - } - if err := checkFold(name); err != nil { - return err - } - if path.Clean(zf.Name) != zf.Name || strings.HasPrefix(zf.Name[len(prefix)+1:], "/") { - return fmt.Errorf("unzip %v: invalid file name %s", zipfile, zf.Name) - } - s := int64(zf.UncompressedSize64) - if s < 0 || maxSize-size < s { - return fmt.Errorf("unzip %v: content too large", zipfile) - } - size += s - } - - // Unzip, enforcing sizes checked earlier. - for _, zf := range z.File { - if zf.Name == prefix || strings.HasSuffix(zf.Name, "/") { - continue - } - name := zf.Name[len(prefix):] - dst := filepath.Join(dir, name) - if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil { - return err - } - w, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0444) - if err != nil { - return fmt.Errorf("unzip %v: %v", zipfile, err) - } - r, err := zf.Open() - if err != nil { - w.Close() - return fmt.Errorf("unzip %v: %v", zipfile, err) - } - lr := &io.LimitedReader{R: r, N: int64(zf.UncompressedSize64) + 1} - _, err = io.Copy(w, lr) - r.Close() - if err != nil { - w.Close() - return fmt.Errorf("unzip %v: %v", zipfile, err) - } - if err := w.Close(); err != nil { - return fmt.Errorf("unzip %v: %v", zipfile, err) - } - if lr.N <= 0 { - return fmt.Errorf("unzip %v: content too large", zipfile) - } - } - - return nil -} - -// makeDirsReadOnly makes a best-effort attempt to remove write permissions for dir -// and its transitive contents. -func makeDirsReadOnly(dir string) { - type pathMode struct { - path string - mode os.FileMode - } - var dirs []pathMode // in lexical order - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if err == nil && info.Mode()&0222 != 0 { - if info.IsDir() { - dirs = append(dirs, pathMode{path, info.Mode()}) - } - } - return nil - }) - - // Run over list backward to chmod children before parents. - for i := len(dirs) - 1; i >= 0; i-- { - os.Chmod(dirs[i].path, dirs[i].mode&^0222) - } -} - -// RemoveAll removes a directory written by Download or Unzip, first applying -// any permission changes needed to do so. -func RemoveAll(dir string) error { - // Module cache has 0555 directories; make them writable in order to remove content. - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return nil // ignore errors walking in file system - } - if info.IsDir() { - os.Chmod(path, 0777) - } - return nil - }) - return os.RemoveAll(dir) -} diff --git a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv new file mode 100644 index 00000000000..6eb8d7fd839 --- /dev/null +++ b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/testdata/zip_sums.csv @@ -0,0 +1,2124 @@ +9fans.net/go,v0.0.2,h1:RYM6lWITV8oADrwLfdzxmt8ucfW6UtP9v1jg4qAbqts=,2c42aad9ed60e24046fbf5720f438884942897197cb790ce58cccdacedd9532d +aahframe.work,v0.12.3,h1:hc3chv+f49yLYVT/aSEhgpoqd8bS0rDKEew1un8AkSo=,0c7e3fab03920a79ace8e0a9ddf4517225f595ce39f2124ec3d9353508da5dbd +aahframework.org/essentials.v0,v0.8.0,h1:R/lcfOuhvZptG4IWX/CzAtpiVJFUjbCxLao6DfmeWBA=,d640fe6b83a31ffe09d12eea37de000be7ec8d7330c0a1d7413d6e31a675628d +bazil.org/fuse,v0.0.0-20180421153158-65cc252bf669,h1:FNCRpXiquG1aoyqcIWVFmpTSKVcx2bQD38uZZeGtdlw=,fce7ed008451861ba30974e95468d716f5ff4fde14e9605dbc2db5fac935c71d +bitbucket.org/abex/go-optional,v0.0.0-20150902044611-5304370459de,h1:iGmurCCO42qFsQ46DzROSsZJFf8/7AKFH/VpRGd2PBw=,02e1b23db09fb6945ba4ca57c0af8125b608fceae125fe625f6536b9e466e7e0 +bitbucket.org/abex/pathfinder,v0.0.0-20170507112819-bdce8b2efbc9,h1:M1jjfmrcOcmWy2/aABpm3k9h/M6NccmjgLtE5gVl+y8=,8469c0a656a895863d4714a658ee4a9634e78547142fa7239331e15d0143c679 +bitbucket.org/abex/sliceconv,v0.0.0-20151017061159-594a23261816,h1:7XPf5/Oar0LfWbnUY29doBDzSr6ToseiJRqkZtb0YOo=,e2433a32246bd5e2fb5d52bf6dc36188a75c4b59b98f76eb7607035b8525dd37 +bitbucket.org/abex/yumeko,v0.0.0-20190825151534-d98ca20ac08c,h1:ES4kIm83Q1RYr9uhhpQhqh/tqjt8H+Xz4xuSAv5Crcw=,1d352a11b3ed5850a425fde048cafa65b2c079c4e9647c52a339b28276065ba9 +bitbucket.org/liamstask/goose,v0.0.0-20150115234039-8488cc47d90c,h1:bkb2NMGo3/Du52wvYj9Whth5KZfMV6d3O0Vbr3nz/UE=,3d64cac7774bf87a9d050222b87387c112bcb6ef0ea0e2b3324a95330573a0c5 +bitbucket.org/ww/goautoneg,v0.0.0-20120707110453-75cd24fc2f2c,h1:t+Ra932MCC0eeyD/vigXqMbZTzgZjd4JOfBJWC6VSMI=,8ad2afdee1dc46b2c78e986bc2cce89cd0b8815b278a01879ef08d56585c247f +bou.ke/monkey,v1.0.1,h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U=,20cb7da509322267189d32a125d7e0f782264508bc8e17306c80424514e797ce +cloud.google.com/go,v0.47.0,h1:1JUtpcY9E7+eTospEwWS2QXP3DEn7poB3E2j0jN74mM=,7739fd24e36a536488115ef0ec9d739e608ee68448f8a469e84855c008b00ecd +cloud.google.com/go/bigquery,v1.0.1,h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU=,738d1f726ce24f618ee7563f6c9419e6307f8814548f45ad8a227cffbb1448c0 +cloud.google.com/go/datastore,v1.0.0,h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM=,41e93ec9526ae580da90300d7e421a6d39d79cb6118d62ad1d3c06422d8a71bf +cloud.google.com/go/pubsub,v1.0.1,h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8=,8bca46a7c5f0dcd576d23fa9a5f107955316d6f0d8f306ee1d6faa7de99c3d29 +cloud.google.com/go/spanner,v1.0.0,h1:jLKThep5kbWLeBhLgtEfm/OPT08n1z7itVTR82WUBQg=,90579f16545e352c662ae9f62dd02dddf834fe10b33d1dbcfbf0a8aadfcd21f8 +cloud.google.com/go/storage,v1.0.0,h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4=,baec4756c573ede58f19eb7ae4acaebd7ac3f0c56413ecbbd216ad46a589a5da +code.cloudfoundry.org/clock,v0.0.0-20180518195852-02e53af36e6c,h1:5eeuG0BHx1+DHeT3AP+ISKZ2ht1UjGhm581ljqYpVeQ=,61785787db7dadaf695506636dcb98c26bbdd0c847f589aa1fb4bbe9ef0e4455 +code.cloudfoundry.org/gofileutils,v0.0.0-20170111115228-4d0c80011a0f,h1:UrKzEwTgeiff9vxdrfdqxibzpWjxLnuXDI5m6z3GJAk=,ec71ca818158525773e53568f71db38f63423822a426e1a18f7d34318e97eb3e +code.cloudfoundry.org/lager,v2.0.0+incompatible,h1:WZwDKDB2PLd/oL+USK4b4aEjUymIej9My2nUQ9oWEwQ=,ce1da175885c2587ca091532a937108ed646e3bd6bd902640891f75ae70adb8b +code.gitea.io/gitea,v1.9.5,h1:Q3PROlfPth1NlLGaeYcr6YVqyfAy7txnFpDKe1BXo7Q=,c7b63394004fb8f355d859f11a007ff17126eac092f90507a80392335351a6df +code.gitea.io/sdk,v0.0.0-20191030144301-2a5a0e75e5cf,h1:uXUz7lXbs33QAYIu1rF0o8tNsa3DlDDSMYek/3CldIo=,6472a2b30b8108cae9b6a4914ce986d61e9ed37baade5ad35cb337270602b70a +code.gitea.io/sdk/gitea,v0.0.0-20191030144301-2a5a0e75e5cf,h1:aAwV+RyellgKMACMu21Vyv/XgSHipLvbJsXDoXP1Yv0=,62570a621e1bf13724fb1f45d7ea95c48de02abb00468cf1da4b35820203d3b4 +contrib.go.opencensus.io/exporter/aws,v0.0.0-20181029163544-2befc13012d0,h1:YsbWYxDZkC7x2OxlsDEYvvEXZ3cBI3qBgUK5BqkZvRw=,3e351a39c3caf9ce263155f2d6e5a4e0cd84177661e1bf40f0d8fd06854831e9 +contrib.go.opencensus.io/exporter/ocagent,v0.6.0,h1:Z1n6UAyr0QwM284yUuh5Zd8JlvxUGAhFZcgMJkMPrGM=,e526ae16b06c682c3661738938f912a2e301a5e2d0ba875c7a0ec40fde825491 +contrib.go.opencensus.io/exporter/stackdriver,v0.12.8,h1:iXI5hr7pUwMx0IwMphpKz5Q3If/G5JiWFVZ5MPPxP9E=,db745d331f8a0455abbbcfeb4bb33dbc5cbb73a119b4e86f833cd497cfc72559 +contrib.go.opencensus.io/integrations/ocsql,v0.1.4,h1:kfg5Yyy1nYUrqzyfW5XX+dzMASky8IJXhtHe0KTYNS4=,0a4be97a579c5212bd83d21a177b279bc5b0c04350a63c56e8f8e611ffcba09c +contrib.go.opencensus.io/resource,v0.1.1,h1:4r2CANuYhKGmYWP02+5E94rLRcS/YeD+KlxSrOsMxk0=,07ad3d36f96cb86ecba376353d02730855e117db3ffac5c2ab2c7cdf4eca25dc +cuelang.org/go,v0.0.11,h1:t7s006dOWh6tgnwPifvO3l704eg8oPuIH7AR1hfTFYk=,69bdc6b3f1000308d399f166dd0d46576019f68cbf37765bd30821584b1296de +dmitri.shuralyov.com/app/changes,v0.0.0-20180602232624-0a106ad413e3,h1:hJiie5Bf3QucGRa4ymsAUOxyhYwGEz1xrsVk0P8erlw=,a4d9079d5550094191f608c628ff2eb6999e0d0b6aea894ba59d063107777dfa +dmitri.shuralyov.com/gpu/mtl,v0.0.0-20190408044501-666a987793e9,h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=,ca5330901fcda83d09553ac362576d196c531157bc9c502e76b237cca262b400 +dmitri.shuralyov.com/html/belt,v0.0.0-20180602232347-f7d459c86be0,h1:SPOUaucgtVls75mg+X7CXigS71EnsfVUK/2CgVrwqgw=,bd6b059cceaea8ab23e65b8118fab5d22f82149417fcc5fcf930ef9a52d582f1 +dmitri.shuralyov.com/service/change,v0.0.0-20181023043359-a85b471d5412,h1:GvWw74lx5noHocd+f6HBMXK6DuggBB1dhVkuGZbv7qM=,8a1ba9c7ba7eea08389c15315a23485d19fc7166d30b5b47a35fab949c4bf886 +dmitri.shuralyov.com/state,v0.0.0-20190403024436-2cf192113e66,h1:/74W9PTF+vJhgRsWpPWlZT77+phX7vXPcelX7JXFu5s=,eda200c06f669f06c56e1d53a1879b88dd7ee99eea1f56d329028fa773cfc2dd +docker.io/go-docker,v1.0.0,h1:VdXS/aNYQxyA9wdLD5z8Q8Ro688/hG8HzKxYVEVbE6s=,b162036b1af6e1e5434e2e5a35faa7191014529259fbf2f4f1b3e7de6b816516 +fyne.io/fyne,v1.1.2,h1:a9YLFXxqN7lKNqTrk+ocw3/3ROrn6aFiofix8ATVOBc=,dc2d7fd4a4ee9852328fc79c52459a53d94d26f6ac3282ebcacc0c6cd6688d23 +git.apache.org/thrift.git,v0.13.0,h1:/3bz5WZ+sqYArk7MBBBbDufMxKKOA56/6JO6psDpUDY=,10412b7bc503ef2a7cc3bf58fe69e5a2d2594354ae3cc5ab2baa2b3ecc8c4f1d +git.fd.io/govpp.git,v0.1.0,h1:fV5H9ghURFfmNAjk7Scb/aG3OGwevLayHfSdS8GsYjE=,0a023d4b5b36131a4fde2c3d19047bbd4f5c3a7cc07c1ccf40bfb75a501f51b3 +git.torproject.org/pluggable-transports/goptlib.git,v1.1.0,h1:LMQAA8pAho+QtYrrVNimJQiINNEwcwuuD99vezD/PAo=,f6769c4813dedf933071289bfd9381aa5eb3a012b3a32d1da02aa9bebd3a3b5b +gitee.com/nggs/util,v0.0.0-20190830024003-3e49d2efc84b,h1:6KQpPEs326uPrICQy9x/PxmR8U0v/XsFzpt0k1nFKcY=,a062c99c2b560a36168fe51eab8f17f4fadf5d534238881628e83d8d61e51c2a +github.com/1and1/oneandone-cloudserver-sdk-go,v1.0.1,h1:RMTyvS5bjvSWiUcfqfr/E2pxHEMrALvU+E12n6biymg=,7f068808fc0857d7de8c8f829cc380dce1c6611a3fc819daf4421e9bcb75a07c +github.com/99designs/gqlgen,v0.10.1,h1:1BgB6XKGTHq7uH4G1/PYyKe2Kz7/vw3AlvMZlD3TEEY=,04b9e7d8a3df6543cd870325b1140ce9ac3f4bbfd8c90ebecec4f908dd420d08 +github.com/AlexStocks/log4go,v1.0.5,h1:45boeHy0qh0NFBaEhrFT/pUKzQUGf7q2Ux1iQDr/f6o=,59371c2108f62aa9a2233ca8f7de57868ad2c64313b2d68434e0ed6a1748ce2c +github.com/AndreasBriese/bbloom,v0.0.0-20190306092124-e2d15f34fcf9,h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4=,6d7c1af06f8597fde1e86166f26416057392f1b0bdb84f2af555aa461282dd18 +github.com/AsynkronIT/goconsole,v0.0.0-20160504192649-bfa12eebf716,h1:Pk/Kzi5O0T4QxfqvbaUsh8UklbJ9BklZ/ClZBptX5WU=,5a2507b89bb4436881718d785a0ef383652aa99782508b7444cf20255082dab9 +github.com/Azure/azure-amqp-common-go,v1.1.4,h1:DmPXxmLZwi/71CgRTZIKR6yiKEW3eC42S4gSBhfG7y0=,4b800793ff4fefa86a427c445e3a4671b8d1dcd87a44075f6309cace6b0e01e2 +github.com/Azure/azure-amqp-common-go/v2,v2.1.0,h1:+QbFgmWCnPzdaRMfsI0Yb6GrRdBj5jVL8N3EXuEUcBQ=,9a91c6ac9656faea0ddfb0bb497c109451faaba09b85ce3237309f5982b095a3 +github.com/Azure/azure-pipeline-go,v0.2.2,h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=,3e4f90f6ec86d4875e8758f01947adece11c1b4317b448fe0197188765c83efc +github.com/Azure/azure-sdk-for-go,v36.0.0+incompatible,h1:XIaBmA4pgKqQ7jInQPaNJQ4pOHrdJjw9gYXhbyiChaU=,71db17c798b784b96a45efdbabd18ad86d03e5f490701081a2f7bf19efa67c13 +github.com/Azure/azure-service-bus-go,v0.9.1,h1:G1qBLQvHCFDv9pcpgwgFkspzvnGknJRR0PYJ9ytY/JA=,81e42ed51354d71b53daf93b5b9f0f2c20fb7d2923f45ab88eea22419bfbc63a +github.com/Azure/azure-storage-blob-go,v0.8.0,h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFEY95rZLK0Tj6o=,3b02b720c25bbb6cdaf77f45a29a21e374e087081dedfeac2700aed6147b4b35 +github.com/Azure/go-ansiterm,v0.0.0-20170929234023-d6e3b3328b78,h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=,b7a14d18891abef8b8a2e622f62a3cebeac32f9f1223dc9d62a6f8769861aaf2 +github.com/Azure/go-autorest,v13.3.0+incompatible,h1:8Ix0VdeOllBx9jEcZ2Wb1uqWUpE1awmJiaHztwaJCPk=,44fdf420bd96bb97df7910806efb25f2fae701078c39f5592f5c4131ffce41e6 +github.com/Azure/go-autorest/autorest,v0.9.2,h1:6AWuh3uWrsZJcNoCHrCF/+g4aKPCU39kaMO6/qrnK/4=,26df5fc6c03e8c66021dd272b04242f6c2ce2a5975f87799dfcf1b9597800dba +github.com/Azure/go-autorest/autorest/adal,v0.8.0,h1:CxTzQrySOxDnKpLjFJeZAS5Qrv/qFPkgLjx5bOAi//I=,af59c00ec7e19cda9b960babaee7bfe27cf3d5f7415ac3afdb4cddc73d4b5743 +github.com/Azure/go-autorest/autorest/azure/auth,v0.4.0,h1:18ld/uw9Rr7VkNie7a7RMAcFIWrJdlUL59TWGfcu530=,2fe394de946f42c2ea8ad07f1b282eac6bb56e372f5c2a35e49dfef0cf015ccb +github.com/Azure/go-autorest/autorest/azure/cli,v0.3.0,h1:5PAqnv+CSTwW9mlZWZAizmzrazFWEgZykEZXpr2hDtY=,729d09b69a1912faa7c2395389bbf67ec22a420d42c15414823d43a380a2f09a +github.com/Azure/go-autorest/autorest/date,v0.2.0,h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=,9ec7b48c865a185b72d3822ac2dff7e0163315a23911c87a479a3db616af9853 +github.com/Azure/go-autorest/autorest/mocks,v0.3.0,h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=,d5daf74cf531c37b27b39d3bf65b6930aee4b226b5fb4ea91a87be93aaf37f10 +github.com/Azure/go-autorest/autorest/to,v0.3.0,h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8=,955ee6bde8af1314d22b51f265799147f42f7c705714b1cc1c51144441d5fa9c +github.com/Azure/go-autorest/autorest/validation,v0.2.0,h1:15vMO4y76dehZSq7pAaOLQxC6dZYsSrj2GQpflyM/L4=,10f40b0d943d4d1a0a1cbcb9fdb058b8a3a59a55ae26583566dfaa82883f86ea +github.com/Azure/go-autorest/logger,v0.1.0,h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=,5e0804944db0707502c9d29defb54961c281a19311c9eb321a246ba054ac5256 +github.com/Azure/go-autorest/tracing,v0.5.0,h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=,4951b0f4a88a44b7ed4e4834654e4e01922ade35d97899b8596998184abbc652 +github.com/Azure/go-ntlmssp,v0.0.0-20180810175552-4a21cbd618b4,h1:pSm8mp0T2OH2CPmPDPtwHPr3VAQaOwVF/JbllOPP4xA=,64cd585589154ce18d7557ccfd8d26e2c2f5c4ecf13b17bdbfb913e17863d280 +github.com/BurntSushi/locker,v0.0.0-20171006230638-a6e239ea1c69,h1:+tu3HOoMXB7RXEINRVIpxJCT+KdYiI7LAEAUrOw3dIU=,836038343df9e9126b59d54201951191898bd875ec32d93c2018d759f358fcfb +github.com/BurntSushi/toml,v0.3.1,h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=,815c6e594745f2d8842ff9a4b0569c6695e6cdfd5e07e5b3d98d06b72ca41e3c +github.com/BurntSushi/xgb,v0.0.0-20160522181843-27f122750802,h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=,f52962c7fbeca81ea8a777d1f8b1f1d25803dc437fbb490f253344232884328e +github.com/BurntSushi/xgbutil,v0.0.0-20190907113008-ad855c713046,h1:O/r2Sj+8QcMF7V5IcmiE2sMFV2q3J47BEirxbXJAdzA=,492ce6b11d7faaec4e15d1279d81e28d2e0e9844ad117f9de9411286a5b0e305 +github.com/ChrisTrenkamp/goxpath,v0.0.0-20170922090931-c385f95c6022,h1:y8Gs8CzNfDF5AZvjr+5UyGQvQEBL7pwo+v+wX6q9JI8=,8d79cd78a309a1b0f22790d354b9c4c929c64d03c7e572627ba430908fbb9d78 +github.com/CodisLabs/codis,v0.0.0-20181104082235-de1ad026e329,h1:KyRmPlfd2xewxb54vIBPNILFyCh2R3zNDwLZURDxT0E=,f61ae85688d10dddf0d62c30aaaa2701373fc11851dae4435de0212513c578c1 +github.com/DATA-DOG/go-sqlmock,v1.3.3,h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=,5dc430c2836af3bfc85f590366a6e284a251978e9397d0d54fa97db913263461 +github.com/DataDog/datadog-go,v3.2.0+incompatible,h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4=,ede4a024d3c106b2f57ca04d7bfc7610e0c83f4d8a3bace2cf87b42fd5cf66cd +github.com/DataDog/zstd,v1.4.0,h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo=,601f6fe1f4138d676946f4b27f7a714bbedea8c1785d10c1b74a03c68ad13070 +github.com/FiloSottile/b2,v0.0.0-20170207175032-b197f7a2c317,h1:1GuMjC4tjfwnWBdoTS7YqtQ3JIsEft6NRcdmXdzvYYc=,6ff3cfed3f510fc69b47f263936642950afc7892f557ed716dd8c5584f187411 +github.com/GeertJohan/go-sourcepath,v0.0.0-20150925135350-83e8b8723a9b,h1:D4H5C4VvURnduTQydyEhA6OWnNcZTLUlNX4YBw5yelY=,8bdcf0b6cc58f5ec1cef031b4052e6d699683bf1daf4a1a20f92f67d5be06b82 +github.com/GeertJohan/go.incremental,v1.0.0,h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg=,ce46b3b717f8d2927046bcfb99c6f490b1b547a681e6b23240ac2c2292a891e8 +github.com/GeertJohan/go.rice,v1.0.0,h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ=,2fc48b9422bf356c18ed3fe32ec52f6a8b87ac168f83d2eed249afaebcc3eeb8 +github.com/GoogleCloudPlatform/cloudsql-proxy,v0.0.0-20191017031552-46c5533ff5ba,h1:ZNYxMf89tMi+NydPAq7yGAxMfMNaMHgG+7WL1CEabjc=,25a1fe9f189e6a4d6e108f22abaec7dd36edc819ab5af1a3e448450b73026271 +github.com/GoogleCloudPlatform/docker-credential-gcr,v1.5.0,h1:wykTgKwhVr2t2qs+xI020s6W5dt614QqCHV+7W9dg64=,4acfcaddfe2aa53e1e643ea13ff3534a2fca1e043d008ab5bba5a0910db1f7c2 +github.com/IBM/go-sdk-core,v1.0.1,h1:vF9Lsoih6fxrAxzJp2fWqnO6Mg8x8O8fzwQAdFoUdok=,e063c8f79f94936a165355f61bdc6f2c404975472ad6be5e47bfdb87fb393c72 +github.com/Jeffail/gabs,v1.4.0,h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo=,cb193b1477109c19b0d2521fc61735619202e58ac4699605f72313d70884ca9e +github.com/Joker/hpp,v0.0.0-20180418125244-6893e659854a,h1:PiDAizhfJbwZMISZ1Itx1ZTFeOFCml89Ofmz3V8rhoU=,4e99372a7576c587c107fb16d1ae0e8662111e2ca5e5127f7cd93bb01cd02076 +github.com/Joker/jade,v1.0.0,h1:lOCEPvTAtWfLpSZYMOv/g44MGQFAolbKh2khHHGu0Kc=,c4a7f39e7483446ff7b0d7e213a4cd813c783108d6d2e7c6e9a8e968789b18bc +github.com/Knetic/govaluate,v3.0.1-0.20171022003610-9aa49832a739+incompatible,h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=,d1d4ac5b4f5759726368f68b0d47f3c17c6d8689243ec66272311359d28a865b +github.com/Kodeworks/golang-image-ico,v0.0.0-20141118225523-73f0f4cfade9,h1:1ltqoej5GtaWF8jaiA49HwsZD459jqm9YFz9ZtMFpQA=,1d677069e35c4a3e4f290e68c6e2391f6237aee9ce3f39448ed09a2ddab274b0 +github.com/Kubuxu/go-os-helper,v0.0.1,h1:EJiD2VUQyh5A9hWJLmc6iWg6yIcJ7jpBcwC8GMGXfDk=,90a16f95a8a238910ab0dc9004cb6e56242a10810bf1e296a263d2e385f002e0 +github.com/KyleBanks/depth,v1.2.1,h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=,8f3e9af2e038f561d9c34b631fddc7db39e39992a121fd087f0bf980026464d9 +github.com/MakeNowJust/heredoc,v1.0.0,h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=,062afe6e11aa3c3ac0035d08907b80d5e5b7563905603391ee774bda440abf16 +github.com/Masterminds/goutils,v1.1.0,h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=,b9520e8d2775ac1ff3fbf18c93dbc4b921133f957ae274f5b047965e9359d27d +github.com/Masterminds/semver,v1.5.0,h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=,15f6b54a695c15ffb205d5719e5ed50fab9ba9a739e1b4bdf3a0a319f51a7202 +github.com/Masterminds/semver/v3,v3.0.1,h1:2kKm5lb7dKVrt5TYUiAavE6oFc1cFT0057UVGT+JqLk=,f1eef1a1b6489d895eb32326f3369bd1615812a4c5fbfe60b2b6cc774c6340f0 +github.com/Masterminds/sprig,v2.22.0+incompatible,h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=,1b4d772334cc94e5703291b5f0fe4ac4965ac265424b1060baf18ef5ff9d845c +github.com/Masterminds/squirrel,v1.1.0,h1:baP1qLdoQCeTw3ifCdOq2dkYc6vGcmRdaociKLbEJXs=,cede1b0a054e000a5e6a8000cb02de7ab64ddca9e0f4153732274627adeed0ae +github.com/Microsoft/go-winio,v0.4.14,h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU=,7a86644691d3c86c77ae0b639fa27029706552f00cd51b445389a61694576f6b +github.com/Microsoft/hcsshim,v0.8.6,h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=,900feaaec1c41d4e111a66bbde330b41fc78902c70c0af37d611505bf42e0632 +github.com/NYTimes/gziphandler,v1.1.1,h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=,2948d9f70e4388f13f4ed9400df41dca60841059f7dcc30cf909c82796cc705a +github.com/NaverCloudPlatform/ncloud-sdk-go,v0.0.0-20180110055012-c2e73f942591,h1:/P9HCl71+Eh6vDbKNyRu+rpIIR70UCZWNOGexVV3e6k=,2e9eacfe3e6785beef75391bcebc14a6a082687c0f0582bc441c3d0106b8bf5c +github.com/NebulousLabs/entropy-mnemonics,v0.0.0-20181203154559-bc7e13c5ccd8,h1:wPFCU8DwC4k5C2LfJc/rVp4cmTqzF3vyydxRR3b3HhQ=,6a65ca779cd216db7bf326ebbb5a26a87d85ff6a6ba832eec281c5c09a8294e3 +github.com/Netflix/go-expect,v0.0.0-20180615182759-c93bf25de8e8,h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=,fbe7b2f58ecb0e1067a6670bbcf0718d54ec407aab81790cc9e58db9a6774775 +github.com/NickBall/go-aes-key-wrap,v0.0.0-20170929221519-1c3aa3e4dfc5,h1:5BIUS5hwyLM298mOf8e8TEgD3cCYqc86uaJdQCYZo/o=,fd78212ec77052b032b9fc308c028e8fc166de3d6ae4494f5eb3254930728a0b +github.com/Nvveen/Gotty,v0.0.0-20120604004816-cd527374f1e5,h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=,362ac7b59d74231419471b65b60079d167785b97fd4aa0de71575088cd192b1e +github.com/OneOfOne/xxhash,v1.2.5,h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=,7ab3c6a0e7c16c987a589e50a9a353e8877cfffea02bf9e04e370fd26a0c85e1 +github.com/OpenBazaar/jsonpb,v0.0.0-20171123000858-37d32ddf4eef,h1:+aqKrHtCJTRp8ziyrjfHbTF5puPQZfgRt65+iM7FD2w=,5f6ea1466b9d27f016c1bf2650669c788db623142cdc8a1794bc1784fc80fc4e +github.com/OpenBazaar/wallet-interface,v0.0.0-20190807004547-aa8e214acd9b,h1:KjQH45msWRtDhb5JAbBW+eU4M/9xIm11rsOSgAaqDOs=,f7ac40d665241766533b1a49a726068d9dfea5e02c7fd426df81f9e390a7003e +github.com/OpenDNS/vegadns2client,v0.0.0-20180418235048-a3fa4a771d87,h1:xPMsUicZ3iosVPSIP7bW5EcGUzjiiMl1OYTe14y/R24=,b73d6b37d519c7bf181e502b92962f1bf961bb0ca3a9ef7057c3d9a8a3c2f3cd +github.com/OwnLocal/goes,v1.0.0,h1:81QQ3z6dvLhgXlkNpLkaYhk8jiKS7saFG01xy039KaU=,ebb6c7e2c12577c590d2d5546b7a4b4e6fa75c9a408ae5244b5ba2cf09dec1d6 +github.com/PuerkitoBio/goquery,v1.5.0,h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk=,f0064ad35f21c2b9d1377b94f09ead56ec1862da3807e78c26b99c4b3a04f5e6 +github.com/PuerkitoBio/purell,v1.1.1,h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=,59e636760d7f2ab41c2f80c1784b1c73d381d44888d1999228dedd634ddcf5ed +github.com/PuerkitoBio/urlesc,v0.0.0-20170810143723-de5bf2ad4578,h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=,1793124273dd94e7089e95716d40529bcf70b9e87162d60218f68dde4d6aeb9d +github.com/Quasilyte/inltest,v0.7.0,h1:yHvFAaoXn+6iK2uKtb8mXB9KURz6SDPyszoyBAC0Xk4=,8fb4273cea3514742aec06ed58f20cea1214cc542799c70c331a80865aaf3988 +github.com/RangelReale/osin,v1.0.1,h1:JcqBe8ljQq9WQJPtioXGxBWyIcfuVMw0BX6yJ9E4HKw=,edbcc6208879bffa533369bbf417db41c1322193ca05d0deecf13075972c9d57 +github.com/RangelReale/osincli,v0.0.0-20160924135400-fababb0555f2,h1:x8Brv0YNEe6jY3V/hQglIG2nd8g5E2Zj5ubGKkPQctQ=,82fc65bad3da9fc26cc77b485e10ee117459e830547ce89592c41d92871e1129 +github.com/Rican7/retry,v0.1.0,h1:FqK94z34ly8Baa6K+G8Mmza9rYWTKOJk+yckIBB5qVk=,c0e956967f2f632ffc889eeae5b82e437f30e9be409870cdd1e7998def458843 +github.com/RoaringBitmap/roaring,v0.4.7,h1:eGUudvFzvF7Kxh7JjYvXfI1f7l22/2duFby7r5+d4oc=,515892d9b8e4350e5ac5b7a487da94d5d9ab9641071e002b778dd864b7a31c2a +github.com/SAP/go-hdb,v0.14.1,h1:hkw4ozGZ/i4eak7ZuGkY5e0hxiXFdNUBNhr4AvZVNFE=,273de28a254c39e9f24293b864c1d664488e4a5d44d535755a5e5b68ae7eed8d +github.com/Sereal/Sereal,v0.0.0-20190529075751-4d99287c2c28,h1:kmfzzWpCZIrVhxx4V/2oSGhGnhtX+/JijVIlPuKYfHg=,eebfe79e62b5a07f98a367d8a84bcf33ed69818c031e70c3ebc6e9fc34361466 +github.com/SermoDigital/jose,v0.0.0-20180104203859-803625baeddc,h1:LkkwnbY+S8WmwkWq1SVyRWMH9nYWO1P5XN3OD1tts/w=,1711f20ec5b1498c98e46b96e578f39b723557ab50183d644702d40f44a1a345 +github.com/Shopify/go-lua,v0.0.0-20181106184032-48449c60c0a9,h1:+2M9NEk3+xSg0+bWzt1kxsL6EtoEg7sgtT11CZjGwq8=,3e399584ff4a876314243c01be3cba5b98b46bba483d6996dd2d0e7f161b7ad8 +github.com/Shopify/goreferrer,v0.0.0-20181106222321-ec9c9a553398,h1:WDC6ySpJzbxGWFh4aMxFFC28wwGp5pEuoTtvA4q/qQ4=,e47cdf750e6aa39707b90e62f4f87e97abb8d64b2525a16c021c82efb24f9969 +github.com/Shopify/sarama,v1.24.1,h1:svn9vfN3R1Hz21WR2Gj0VW9ehaDGkiOS+VqlIcZOkMI=,c5e06f9c835846eeb5cbbbc540ab949f9775ff37c08cab503dd820b858b1f2e7 +github.com/Shopify/toxiproxy,v2.1.4+incompatible,h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc=,9427e70698ee6a906904dfa0652624f640619acef40652a1e5490e13b31e7f61 +github.com/Sirupsen/logrus,v1.0.6,h1:HCAGQRk48dRVPA5Y+Yh0qdCSTzPOyU1tBJ7Q9YzotII=,dc69c77019152ace477a7f5c0cd97fd25d6ab866e01e1dd06f391722f4f9fba9 +github.com/StackExchange/wmi,v0.0.0-20190523213315-cbe66965904d,h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=,68f499ad4c3f45fc6c286fd2a5966e8e15c0f3abc1f96fbf4a979245df936e16 +github.com/Stebalien/go-bitfield,v0.0.1,h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo=,9b17a2749922c810f3598606b87b5f2ba0f3c6abc70966911a8c32f0533ee827 +github.com/Telmate/proxmox-api-go,v0.0.0-20190815172943-ef9222844e60,h1:iEmbIRk4brAP3wevhCr5MGAqxHUbbIDHvE+6D1/7pRA=,55dd16e2cd8e6c1464c6456007cdc5d8676b8b096e90230312daa8c84b57b34d +github.com/TheThingsNetwork/api,v0.0.0-20190522113053-d844e8c040fc,h1:hDk+SAT2tV584ye1hqMN5+NHL6RHJDIbe97cNot6/WQ=,7931f7c4699cd1019c950a68361e3b3fec8bbb8e9204c65c08b50bd588ac506a +github.com/TheThingsNetwork/go-account-lib,v2.0.3+incompatible,h1:pnDIalIqac/VlXenPr+L1XEEf3gIq1eIoZ78S5AP1/s=,e62dcb784cbd28bcec55cf332f7dc06779c75c7df66299f4ce542cd6852358b4 +github.com/TheThingsNetwork/go-cayenne-lib,v1.0.0,h1:be7h6E/69+qaYs1iwQ2xjGjSFPXzvU3q6AWBCWayG2Y=,17091b77ac39b8e73ca6ac3f39f34909bc6a3770098ff2dd534b59a10f6e66ad +github.com/TheThingsNetwork/go-utils,v0.0.0-20190813113035-8715cf82e887,h1:DF/1gkOPk3jtwWa9dFd5tUtwb6z3bLw9tZ/UALbS5Ck=,be4c7c2955630b63300f21773efcdc991d5ff201a53b01d92b2f20fede77065c +github.com/TheThingsNetwork/ttn,v2.10.1+incompatible,h1:LQw+g+kinajii5DHJ6I2o82ObaU/Ws+YYgdLkF5eF54=,4a803fe23636f9c99926e6b5a2b956fb42e84ca38c98458a12bd7fe1c22f7439 +github.com/TheThingsNetwork/ttn/api,v0.0.0-20190516081709-034d40b328bd,h1:vCjDYImJDdW+39EXwij00yzDi1pd3TmP6XtCteDJBd0=,9cda2f899f15f57e8f649bbffb955a8153d6c25a13a4e969df8898bb61559a44 +github.com/TheThingsNetwork/ttn/core/types,v0.0.0-20191015060859-00a6f7874bb9,h1:tlWwCxI3/Zu4vJ4dLWb2wMOYSkeMBvLAxQGwJDCFXi8=,7b3895805d6ac341e5df44c2c8154b374b4bed4c8f54e248ea967abfc37186e7 +github.com/TheThingsNetwork/ttn/utils/errors,v0.0.0-20190516081709-034d40b328bd,h1:ITXOJpmUR4Jhp3Xb/xNUIJH4WR0h2/NsxZkSDzFIFiU=,d64decf456c10fdbbb887212ea63749b495264c40bb5ac047b9f0e5ccd7e540b +github.com/TheThingsNetwork/ttn/utils/random,v0.0.0-20190516081709-034d40b328bd,h1:zKTRK1r3K55XxHuUGxnqYg9aiPDduYeilHUEHua+F+Y=,c504030254919a902b3957267b7ce1870f909cbdd65f0f927819f60710e41d9b +github.com/TheThingsNetwork/ttn/utils/security,v0.0.0-20190516081709-034d40b328bd,h1:og10Wq5S/QC+f4ziON4vrxlYKv9gfEKxG8v/MDs00xw=,e6f013adee3a7a212a6f892db59c8efaf715fe49413e6dbca22229fa04f0d006 +github.com/Unknwon/cae,v0.0.0-20160715032808-c6aac99ea2ca,h1:xU8R31tsvj6TesCBog973+UgI3TXjh/LqN5clki6hcc=,15a1394a603423c5bcd4659275be09d7696774990d5f127500f4156c1a78eb85 +github.com/Unknwon/com,v0.0.0-20190321035513-0fed4efef755,h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg=,2cfba36da8f59c6dd8c7a20af59e5ccf9558f42bde7e0918a64a9b68dafcf271 +github.com/Unknwon/i18n,v0.0.0-20171114194641-b64d33658966,h1:Mp8GNJ/tdTZIEdLdZfykEJaL3mTyEYrSzYNcdoQKpJk=,a5ce1436582e797d60e967d853fd22458fc7edeb31bd390d6ace979133bedb78 +github.com/Unknwon/paginater,v0.0.0-20170405233947-45e5d631308e,h1:HnbTtNLKnRmwn85vBmyl7nNJCXUw4rh6X3UeIX5nvko=,60e3af4ba9b482892127f829ec7cc837977ca9e9e634be855d599cc08230e606 +github.com/VividCortex/ewma,v1.1.1,h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=,eebee7c0f20e96abbda1611ed2a3d26b4c2c10393caa6a2dfd1605763a5c1a12 +github.com/VividCortex/gohistogram,v1.0.0,h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=,16ebeceeb7e4066f90edbfb90282cd90d4dad0f71339199551de3fbdc7e8c545 +github.com/Workiva/go-datastructures,v1.0.50,h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo=,1ac8c9334b63ee2b089b7ecc3b6c8d45793cc4ef4c460f6ebbfd6ecea3ee83bc +github.com/a8m/mark,v0.1.1-0.20170507133748-44f2db618845,h1:hIjQrEARcc9LcH8igte3JBpWBZ7+SpinU70dOjU/afo=,048bfeb7427ff5622874d874a52d7215a2cea99f9741c031e9963348785103c2 +github.com/abbot/go-http-auth,v0.4.0,h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=,8204bca24734f55f179dd1c0b820ae5be83151268693a147086f33cd2d4d473c +github.com/abdullin/seq,v0.0.0-20160510034733-d5467c17e7af,h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=,bcbe9a2c1e3ac0b981ee436cd1bbb2da8220527511b3cea6517a28a881636814 +github.com/abronan/valkeyrie,v0.0.0-20191010124425-1ae9442de16e,h1:4SrbWyef51DHDc957/8Ms/fDM4D+3bkbXqg6OTnIEAo=,553dce6f5ff57f7ccc5ed6a94e6bf29b38b8773236f3b85bb4025dc0d10d2a92 +github.com/aead/siphash,v1.0.1,h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=,25da04ff418e0b2871b1193a3478977b4aa66c20737b9ca70a5040b876b6d3d9 +github.com/aerogo/http,v1.0.12,h1:1o5QW6TQLNuutQLuPCX0Tn7g/sSH3JMHv79UGIBpvkw=,a58d344ff2010737d2418050f4188339087cfb369c903bd31e20ccba388304a1 +github.com/afex/hystrix-go,v0.0.0-20180502004556-fa1af6a1f4f5,h1:rFw4nCn9iMW+Vajsk51NtYIcwSTkXr+JGrMd36kTDJw=,c0e0ea63b57e95784eeeb18ab8988ac2c3d3a17dc729d557c963f391f372301c +github.com/agext/levenshtein,v1.2.2,h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=,07caaae8fcdb7c83195a0afffc03c9df76275b1e9a7b69dabfe0d2f47729bc7c +github.com/agl/ed25519,v0.0.0-20170116200512-5312a6153412,h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=,98c1510ac20b7d61bf4e2c76e7184fcbd0a8b78b0fc667c2b772777912963d3f +github.com/agnivade/levenshtein,v1.0.1,h1:3oJU7J3FGFmyhn8KHjmVaZCN5hxTr7GxgRue+sxIXdQ=,cb0e7f070ba2b6a10e1c600d71f06508404801ff45046853001b83be6ebedac3 +github.com/ajg/form,v1.5.1,h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=,b063b07639670ce9b6a0065b4dc35ef9e4cebc0c601be27f5494a3e6a87eb78b +github.com/ajstarks/svgo,v0.0.0-20190826172357-de52242f3d65,h1:kZegOsPGxfV9mM8WzfllNZOx3MvM5zItmhQlvITKVvA=,1459a44f9162f463b59eacf58e4bb8873e612c5b3df45fc6e34074310d2269ae +github.com/akamai/AkamaiOPEN-edgegrid-golang,v0.9.0,h1:rXPPPxDA4GCPN0YWwyVHMzcxVpVg8gai2uGhJ3VqOSs=,91c3a4743d959b3bb2bb7359790df4688021830e482d393ea6d4f3a27aebd63d +github.com/akavel/rsrc,v0.8.0,h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw=,13954a09edc3a680d633c5ea7b4be902df3a70ca1720b349faadca44dc0c7ecc +github.com/akyoto/assert,v0.2.3,h1:ftENRGDEK5AKuKmZb9LtbDIHeE8p8cIYI4M92CbA9nE=,f0a31d5859109c37568b8702fcf92cd3a49ec4892dace74d113df5fd49491975 +github.com/akyoto/color,v1.8.11,h1:uCQi+uRyngo1cJhJSv28PQmduGFiOAGNF6F9MFoRDek=,0fa16c51743ca03e108fde20eabb070d17d25111cb287e15f8567268d439098a +github.com/akyoto/colorable,v0.1.7,h1:ge91E25hiOiT/Zu47ij/rTO3cks7wMlTrcQspua1hFM=,07c2dd4d994d9ff1dad97ad2e2650ff60d90f50ecd52380f357e562efda99613 +github.com/akyoto/stringutils,v0.2.6,h1:IP+7jtH8uofpan8MYlV/WMNaLDGBRbzgiTKYnxcAwkw=,802a3b54f91b930c1e8f2376bebf783b16894da626fc7c8064268b07ab567f7c +github.com/akyoto/tty,v0.1.3,h1:AdnLETzgooimWLvoBQLn5bT1j+i0yiB4E596BfFKnmA=,749381ec9dce8bc96bec66c5dfb0874db917a008f9685d9c65c15da43ede964c +github.com/alcortesm/tgz,v0.0.0-20161220082320-9c5fe88206d7,h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=,ccedffb2c46724216b787fb1a79ae33fb0dfdd672c669db000c4ed5a68b08014 +github.com/alecthomas/assert,v0.0.0-20170929043011-405dbfeb8e38,h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=,873d257170b1363142cbf5e16b49c6a21cccb3e4aaceb9d370c3b78b051a5663 +github.com/alecthomas/chroma,v0.6.8,h1:TW4JJaIdbAbMyUtGEd6BukFlOKYvVQz3vVhLBEUNwMU=,ebc5202e6a0ededc5a2c7396b01b76c050331bead9d047f31fe648cb63e68aa3 +github.com/alecthomas/colour,v0.0.0-20160524082231-60882d9e2721,h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=,334101c562d2e74338f6baab1de04f3bbff89021d24f4206c551ef47b96a2bfe +github.com/alecthomas/kingpin,v2.2.6+incompatible,h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI=,a88daee47262ffeca1f6e348399c16c9be160f3c5e972c0b6c9dc275d85bcdc6 +github.com/alecthomas/kong,v0.2.1-0.20190708041108-0548c6b1afae,h1:C4Q9m+oXOxcSWwYk9XzzafY2xAVAaeubZbUHJkw3PlY=,4292d9b6903d67f060d3bd57ffca0a4ebca359824ce2d32a512ac1b963fa3dc0 +github.com/alecthomas/kong-hcl,v0.1.8-0.20190615233001-b21fea9723c8,h1:atLL+K8Hg0e8863K2X+k7qu+xz3M2a/mWFIACAPf55M=,21a34d6ee62e3419601d0e083b8829001a9833899dd3c2d27a82c794426fd0ee +github.com/alecthomas/log4go,v0.0.0-20180109082532-d146e6b86faa,h1:0zdYOLyuQ3TWIgWNgEH+LnmZNMmkO1ze3wriQt093Mk=,04bdaa7d57a681072316927175c21ca7c9e7a19bd7fee2102b5f40e5b01a7559 +github.com/alecthomas/repr,v0.0.0-20181024024818-d37bc2a10ba1,h1:GDQdwm/gAcJcLAKQQZGOJ4knlw+7rfEQQcmwTbt4p5E=,c01a833ec56f68113f6cd7ed82b7da9bfaec641a10e929e0e3e5e5dadb1a85ad +github.com/alecthomas/template,v0.0.0-20190718012654-fb15b899a751,h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=,25e3be7192932d130d0af31ce5bcddae887647ba4afcfb32009c3b9b79dbbdb3 +github.com/alecthomas/units,v0.0.0-20190924025748-f65c72e2690d,h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=,e6b0ccb38bfba85d90092d1c57671d5f7996757bd71f6f1970c6ae2f9dae3f6e +github.com/alicebob/gopher-json,v0.0.0-20180125190556-5a6b3ba71ee6,h1:45bxf7AZMwWcqkLzDAQugVEwedisr5nRJ1r+7LYnv0U=,2374b534198621157afb9466a52d361b6eed33dcf9bb0674019515e64b16129e +github.com/alicebob/miniredis,v0.0.0-20180911162847-3657542c8629,h1:gLoh8jzwIxdisBnHiWRIuReqtH9cpslSE2564UWXun0=,14b5e988ec6d8357a25ba19a7adbdb34920f5f91401b2b26eb25f04fed9893b0 +github.com/aliyun/alibaba-cloud-sdk-go,v0.0.0-20191031111935-12810c79403d,h1:CmGtZPPsr0C31ZBrzdP+D2oczTbyEBbO3bYg6z5EIDY=,4f0f25f45d954ab970b24783e31b716b619b128081acc9ed7b00727cd7c2d536 +github.com/aliyun/aliyun-oss-go-sdk,v2.0.3+incompatible,h1:724q2AmQ3m1mrdD9kYqK5+1+Zr77vS21jdQ9iF9t4b8=,47ede6a440ad4bb1a1c33d71bd12f76f44aa2487f676b8770152130be3021657 +github.com/aliyun/aliyun-tablestore-go-sdk,v4.1.2+incompatible,h1:ABQ7FF+IxSFHDMOTtjCfmMDMHiCq6EsAoCV/9sFinaM=,82c8ced9cd377462c6ea5070258f97c77ffddd66621e8960b08184eb58416846 +github.com/allegro/bigcache,v1.2.1,h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=,9250edab8c7851cfa0c6c173e721cf70831e90742a7485c2eba1d6e2cc8c71eb +github.com/anacrolix/envpprof,v1.1.0,h1:hz8QWMN1fA01YNQsUtVvl9hBXQWWMxSnHHoOK9IdrNY=,97f2340bcb169956bad97c59fdc17bbd2eb7c0acefe4e2ae327c7d6bd5a5f6cf +github.com/anacrolix/log,v0.3.0,h1:Btxh7GkT4JYWvWJ1uKOwgobf+7q/1eFQaDdCUXCtssw=,e8bc14381d8746426c7e272228780047e0594d695d02e188269f1e86ef1644d4 +github.com/anacrolix/missinggo,v1.2.1,h1:0IE3TqX5y5D0IxeMwTyIgqdDew4QrzcXaaEnJQyjHvw=,2fb8cba1f6eaf69989ca5c522c2d4afd6c1071ad9459f940b6058dbfc2f3b285 +github.com/anacrolix/missinggo/perf,v1.0.0,h1:7ZOGYziGEBytW49+KmYGTaNfnwUqP1HBsy6BqESAJVw=,f4271e6359cf3dd5cba81bcf1436e8abc5d0c96c11820b881544708caa131713 +github.com/anacrolix/sync,v0.0.0-20180808010631-44578de4e778,h1:XpCDEixzXOB8yaTW/4YBzKrJdMcFI0DzpPTYNv75wzk=,bef95f54e1b17e4e7666cbf552e541e670f29fc3fd354aba0ebeee73f744ea24 +github.com/anacrolix/tagflag,v1.0.1,h1:Yd3d5DaKbRA70k7CoFuBsbmfSWIsvtZ9t80xW/x4vQY=,8fc0a5b5607cde223bacd9e4fa3b26f6166c09a09bfabe2c2c803e45e17971fa +github.com/anacrolix/utp,v0.0.0-20180219060659-9e0e1d1d0572,h1:kpt6TQTVi6gognY+svubHfxxpq0DLU9AfTQyZVc3UOc=,35c47428844d10f077225195f9a6c7587c671b7fc70bbaf59ef74cd6d8834e32 +github.com/andreyvit/diff,v0.0.0-20170406064948-c7f18ee00883,h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=,d39614ff930006640ec15865bca0bb6bf8e1ed145bccf30bab08b88c1d90f670 +github.com/andybalholm/cascadia,v1.0.0,h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=,7fd82e560ca1a453974a64c9bf6514b17322d1b7392bad730a5006d929996906 +github.com/andygrunwald/go-jira,v1.5.0,h1:/1CyYLNdwus7TvB/DHyD3udb52K12aYL9m7WaGAO9m4=,3ee973941f400bf95005cada54e09e319cb4943cd6c8d66480243d3b40895821 +github.com/anmitsu/go-shlex,v0.0.0-20161002113705-648efa622239,h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=,3b8376ff631f30d47e0348a8f847050b97c3db89483f45d1cd8f11d23c7c56a2 +github.com/antchfx/htmlquery,v1.0.0,h1:O5IXz8fZF3B3MW+B33MZWbTHBlYmcfw0BAxgErHuaMA=,81c86507bf2a226d5a3d20db547503d490f1e3b77035f267056e80cd73e240e2 +github.com/antchfx/xmlquery,v1.0.0,h1:YuEPqexGG2opZKNc9JU3Zw6zFXwC47wNcy6/F8oKsrM=,969fc21438fe076aee032574578158ac7e030979153dcf7b5ff5c133cbfa4d86 +github.com/antchfx/xpath,v0.0.0-20190129040759-c8489ed3251e,h1:ptBAamGVd6CfRsUtyHD+goy2JGhv1QC32v3gqM8mYAM=,22cb767dc0cafecba39e1b0322cc8aebbc6fd912e4b0fcda8c2c1dde2d80c4d2 +github.com/antchfx/xquery,v0.0.0-20180515051857-ad5b8c7a47b0,h1:JaCC8jz0zdMLk2m+qCCVLLLM/PL93p84w4pK3aJWj60=,9ddc9d830f2d6c7a22604035f0c621228ffa4ed6ff1f1d34655ee477c203c899 +github.com/antihax/optional,v0.0.0-20180407024304-ca021399b1a6,h1:uZuxRZCz65cG1o6K/xUqImNcYKtmk9ylqaH0itMSvzA=,7b0a2bf3eb029d9abe761db1874a501b60f267e675d72ae8c4b8c6f406ddcfd0 +github.com/apache/arrow/go/arrow,v0.0.0-20191024131854-af6fa24be0db,h1:nxAtV4VajJDhKysp2kdcJZsq8Ss1xSA0vZTkVHHJd0E=,4bd8443c24bc06843c0270df4f08f98b3eee6116604ff16d14dce34b242783cf +github.com/apache/thrift,v0.13.0,h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI=,d75265e363da943c24e7ed69104bf018429024a50968421e48a6ab3e624733c2 +github.com/apex/log,v1.1.1,h1:BwhRZ0qbjYtTob0I+2M+smavV0kOC8XgcnGZcyL9liA=,5bb0f19e5c68b104ed32a311ea9c6f6e2a5e8fa597b342695e069468e2248d83 +github.com/aphistic/golf,v0.0.0-20180712155816-02c07f170c5a,h1:2KLQMJ8msqoPHIPDufkxVcoTtcmE5+1sL9950m4R9Pk=,a0ca77a50520037607c3a2a798b66aee1d5df63f4800b4236f51be2f1e3c1d70 +github.com/aphistic/gomol,v0.0.0-20190314031446-1546845ba714,h1:ml3df+ybkktxzxTLInLXEDqfoFQUMC8kQtdfv8iwI+M=,c2fd1a9db2fb7a5ca7ba9132fbddb5d8efd64babcff7c0f66d41d3cf97b8caab +github.com/aphistic/gomol-console,v0.0.0-20180111152223-9fa1742697a8,h1:tzgowv45TOFALtZLJ9y3k+krzOh2J8IkCvJ8T//6VAU=,26a1b99db9a92a7f5d088e529c43db6de957a3a1650c27d7a872495f73a52880 +github.com/aphistic/gomol-gelf,v0.0.0-20170516042314-573e82a82082,h1:PgPqI/JnStmzwTof+PtT53Pz53dlrz2BmF7cn5CAwQM=,e44d4de8d62391c1e0e70c3b27f4c341bb0398083f33b99be46e29144fad3c50 +github.com/aphistic/gomol-json,v1.1.0,h1:XJWwW8PxYOHf0f0FquuBWcgvZBvQ89nPxZsqQ9pfpro=,0e1ab66a46afe81c4662f8a49ca38042f0c6bc8645895336399adef1eedaff59 +github.com/aphistic/sweet,v0.2.0,h1:I4z+fAUqvKfvZV/CHi5dV0QuwbmIvYYFDjG0Ss5QpAs=,02bebcef905b02cf7195137d9b20920367bb5f8c635a6e5a112b787596414f51 +github.com/aphistic/sweet-junit,v0.0.0-20190314030539-8d7e248096c2,h1:qDCG/a4+mCcRqj+QHTc1RNncar6rpg0oGz9ynH4IRME=,6a3ab195b97bd1981f2ae87a172bc24ecfb44ffbd8d28428f97bfa46e66f559b +github.com/apparentlymart/go-cidr,v1.0.1,h1:NmIwLZ/KdsjIUlhf+/Np40atNXm/+lZ5txfTJ/SpF+U=,5af128e1ecdf5f2203fda104a653f13fb2e46acc3f68b2d7634a760a8f556ea0 +github.com/apparentlymart/go-dump,v0.0.0-20190214190832-042adf3cf4a0,h1:MzVXffFUye+ZcSR6opIgz9Co7WcDx6ZcY+RjfFHoA0I=,3506757fd2dcbcf8e77aa962c923d9ceaf918538bf9b117f98aa562bc83c77ef +github.com/apparentlymart/go-textseg,v1.0.0,h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=,2572a77af285125f1980e9b751e5a7c3ae59b73c4fc97e7c2407681609991142 +github.com/appc/spec,v0.8.11,h1:BFwMCTHSDwanDlAA3ONbsLllTw4pCW85kVm290dNrV4=,4a17d699b3e2c3cc8b301de260a45c8fc31054fbb5c689e567f24e3e63bf8f79 +github.com/apple/foundationdb/bindings/go,v0.0.0-20190411004307-cd5c9d91fad2,h1:VoHKYIXEQU5LWoambPBOvYxyLqZYHuj+rj5DVnMUc3k=,a2dc6bd23d9066d3acf174c9b33378c08ae4a95cfd017abc70a16388e74ea2c3 +github.com/approvals/go-approval-tests,v0.0.0-20160714161514-ad96e53bea43,h1:ePCAQPf5tUc5IMcUvu6euhSGna7jzs7eiXtJXHig6Zc=,e3b51ab88c4f3b1c4aea2fadd0b3d3e2ec178d37232066b9fe3b0177e1c6e9aa +github.com/aquasecurity/fanal,v0.0.0-20191031102512-c1c079886da6,h1:B84l/SNXzzcqwgIORAmEv7gs4K4l+DJkdliI6ib/zNw=,7247188e1746360364e7ff77aa0c531df69074c49b23e7f67d65134ca577b0e0 +github.com/aquasecurity/go-dep-parser,v0.0.0-20190819075924-ea223f0ef24b,h1:55Ulc/gvfWm4ylhVaR7MxOwujRjA6et7KhmUbSgUFf4=,73ce01b48b9aa56349d928a27bdd4b77c149541385e645951b2e25f1d6ab5d26 +github.com/araddon/dateparse,v0.0.0-20190622164848-0fb0a474d195,h1:c4mLfegoDw6OhSJXTd2jUEQgZUQuJWtocudb97Qn9EM=,3b88bff198316e2795d11340862ef873387cd7dba97eeb17f106f41deb00d602 +github.com/araddon/gou,v0.0.0-20190110011759-c797efecbb61,h1:Xz25cuW4REGC5W5UtpMU3QItMIImag615HiQcRbxqKQ=,936e20f4c9eaa45f54586ab86bce911f0b1f935d0410dd683dc647797ed7225d +github.com/aristanetworks/fsnotify,v1.4.2,h1:it2ydpY6k0aXB7qjb4vGhOYOL6YDC/sr8vhqwokFQwQ=,9c0dd5427e82f044a9e5808a3436b43472ff032f23ac853829e5c166171044a3 +github.com/aristanetworks/glog,v0.0.0-20180419172825-c15b03b3054f,h1:Gj+4e4j6g8zOhckHfGbZnpa0k8yDrc0XRmiyQj2jzlU=,496dd08756b324a7925b670a907328433f1477763a229b76a4eef8ed254c9683 +github.com/aristanetworks/goarista,v0.0.0-20191023202215-f096da5361bb,h1:gXDS2cX8AS8KbnP32J6XMSjzC1FhHEdHfUUCy018VrA=,2c348fcdf827ac0d1238fb556f66ad1f13f05d8c5a6d2b3efe5f94be40af5021 +github.com/aristanetworks/splunk-hec-go,v0.3.3,h1:O7zlcm4ve7JvqTyEK3vSBh1LngLezraqcxv8Ya6tQFY=,545adec43ebdf1c9cdc65cd3d738d131f1b02706d25876de1fda65c4989195af +github.com/armon/circbuf,v0.0.0-20190214190532-5111143e8da2,h1:7Ip0wMmLHLRJdrloDxZfhMm0xrLXZS8+COSu2bXmEQs=,c8b7ba977844b5378a2413c123c3e55d0885fb67f64ad6cf06575a791a36b827 +github.com/armon/consul-api,v0.0.0-20180202201655-eb2c6b5be1b6,h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA=,091b79667f16ae245785956c490fe05ee26970a89f8ecdbe858ae3510d725088 +github.com/armon/go-metrics,v0.0.0-20190430140413-ec5e00d3c878,h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=,3d48bc38dda0cff4dbf0b56b9b6e2e8fc3e6be2282f2a612a96a6702cc8a9fc5 +github.com/armon/go-proxyproto,v0.0.0-20190211145416-68259f75880e,h1:h0gP0hBU6DsA5IQduhLWGOEfIUKzJS5hhXQBSgHuF/g=,1004212be9a343c99e1849425845af1ec5e3e35cc4917483721cb03620982d58 +github.com/armon/go-radix,v1.0.0,h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=,df93c816505baf12c3efe61328dc6f8fa42438f68f80b0b3725cae957d021c90 +github.com/armon/go-socks5,v0.0.0-20160902184237-e75332964ef5,h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=,f473e6dce826a0552639833cf72cfaa8bc7141daa7b537622d7f78eacfd9dfb3 +github.com/asaskevich/govalidator,v0.0.0-20190424111038-f61b66f89f4a,h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=,b5dfb936e0256459bc633c8acf433f4a01a468868db9bd6e390a67f4678185f5 +github.com/asdine/storm,v2.1.2+incompatible,h1:dczuIkyqwY2LrtXPz8ixMrU/OFgZp71kbKTHGrXYt/Q=,ffea8b759006a871732554e1e0a42753fb9a5dd9884eb150e1b42806d51cd5fd +github.com/assetsadapterstore/tivalue-adapter,v1.0.3,h1:zcFcT1x1rWDYQEaA3wI7Hr7F25Cspy+O1cr+vUMjrks=,c42adddd544495ef0ebe1d8730bad20c4251c7646e1782542782bc946c839eca +github.com/astaxie/beego,v1.12.0,h1:MRhVoeeye5N+Flul5PoVfD9CslfdoH+xqC/xvSQ5u2Y=,1f14eb5d216170c027754bea1129bbcdafc06a035650e635375c61a17be6f316 +github.com/asticode/go-astilog,v1.0.0,h1:l9tek0K7KoQCmhZ7cvBTtVu0NsKpS9hB6jBLtQyxWYk=,49fe2b286073848e780a9326f7d37771372e61827ff07b80db89667e6ac4d1d4 +github.com/aws/amazon-ssm-agent,v0.0.0-20191011205301-04bb0617297b,h1:xv695CeRjoBS0baQSS5UfQkeo63GiMjmDwiAeY09bSw=,08ede8d7aa20210a4738e0ea033f1bf8fd1ce13bba6c375431c8c1e7a8565c37 +github.com/aws/aws-lambda-go,v1.13.2,h1:8lYuRVn6rESoUNZXdbCmtGB4bBk4vcVYojiHjE4mMrM=,05b1633366a8df9e313df4409d003a277ff7ae46f1079b3ad7f6b48c0dabfb75 +github.com/aws/aws-sdk-go,v1.25.25,h1:j3HLOqcDWjNox1DyvJRs+kVQF42Ghtv6oL6cVBfXS3U=,c34d718d97487766a9a8ac818d37dd135d75d747a8d191a616b75425c32456f2 +github.com/aybabtme/rgbterm,v0.0.0-20170906152045-cc83f3b3ce59,h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo=,a4456a42277e0c987de99e9c4ba141db064107ce737ad1dd2e050aeb1149b67e +github.com/aymerick/raymond,v2.0.2+incompatible,h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0=,df6e22632cb314b76ab10dd6a1c2c66a79da44200bfec9f5e4f321100d90dc64 +github.com/baiyubin/aliyun-sts-go-sdk,v0.0.0-20180326062324-cfa1a18b161f,h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=,0965da027355d9b385358331ec359cf729ec4571ec4ca86339da925364c13559 +github.com/bartekn/go-bip39,v0.0.0-20171116152956-a05967ea095d,h1:1aAija9gr0Hyv4KfQcRcwlmFIrhkDmIj2dz5bkg/s/8=,6a278508499838d4c57c1dbdafcfc9f9f909e7358c518a8699728053b695d0c5 +github.com/bazelbuild/buildtools,v0.0.0-20191024175656-9f3978593d3e,h1:QdfIPgk+fJY8AcfjVk2/tdc2dNtl6d+7x8dhVBP72Ik=,f768dd2a38a1dedc924740f9b7a3194ca68d8a24db8fb840c547aee3911162d3 +github.com/bbangert/toml,v0.0.0-20130821181452-a2063ce2e5cf,h1:SGoM2ypzNnI+hMs01svW6wRddndk7eWRs1Bx1zOGRTI=,63690dcb3fcf13b55193cfe263b4a4fdbbe2ee9d7f93440375815dac28d34cb9 +github.com/bcext/cashutil,v0.0.0-20190126062106-1194a0af0582,h1:+sgikGWB0jvS9rzLlPww+SSFoieOLB8yieXyX9DRCF4=,4d5b42e5d472015edeef1b6bf54e253a85bab6df1ac16aabea7fd0dea4aa85e3 +github.com/bcext/gcash,v0.0.0-20190404152342-2e38815af4f2,h1:XVuqYNixmuo81vR/PnBRDDiTH7596mAwQlQ8BucvGnM=,6b24e00369a493c32e730a4d78d8c4fd122ffe0ce319c5d72f3c7d2f12ede4b7 +github.com/beego/goyaml2,v0.0.0-20130207012346-5545475820dd,h1:jZtX5jh5IOMu0fpOTC3ayh6QGSPJ/KWOv1lgPvbRw1M=,aaa4165412caaacbb2df4427207a206e09215c3f7a19f8309e9222ca9ff80691 +github.com/beego/x2j,v0.0.0-20131220205130-a0352aadc542,h1:nYXb+3jF6Oq/j8R/y90XrKpreCxIalBWfeyeKymgOPk=,f9a32026b2107f3cc3610ac6b75c4c64818646a316c35e648c8811d4276a9993 +github.com/beevik/etree,v1.1.0,h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=,614a33736f8b9262a809f101df5bf71f47777879b1191165b6247d6b67c7468c +github.com/beevik/guid,v0.0.0-20170504223318-d0ea8faecee0,h1:oLd/YLOTOgA4D4aAUhIE8vhl/LAP1ZJrj0mDQpl7GB8=,5add94fcade6c7afa236112c8da300d47ec499ad1789a5e805c8198062dd0749 +github.com/beevik/ntp,v0.2.0,h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=,42e14f30c23ba2f5ddaff76101016d87f0f0a0f1d96d3d20e42fd02842091c76 +github.com/belogik/goes,v0.0.0-20151229125003-e54d722c3aff,h1:/kO0p2RTGLB8R5gub7ps0GmYpB2O8LXEoPq8tzFDCUI=,f926f1040febe5318efa145541a6fc7898d32514bc13899e812185f05710c5db +github.com/beorn7/perks,v1.0.1,h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=,25bd9e2d94aca770e6dbc1f53725f84f6af4432f631d35dd2c46f96ef0512f1a +github.com/bep/debounce,v1.2.0,h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo=,ddc0a77e4819b6b826d69fdf1a5a153f3f867a31e030cfe28296355b670adf21 +github.com/bep/gitmap,v1.1.1,h1:Nf8ySnC3I7/xPjuWeCwzukUFv185iTUQ6nOvLy9gCJA=,364163e67741ae331d164fd881964160f19fdbdfe094e0e762314cc37aac646a +github.com/bep/go-tocss,v0.6.0,h1:lJf+nIjsQDpifUr+NgHi9QMBnrr9cFvMvEBT+uV9Q9E=,40e7175da9564796e184e4383bfce703f63244b850999b5a54fd5792bfc5baf5 +github.com/bep/tmc,v0.5.0,h1:AP43LlBcCeJuXqwuQkVbTUOG6gQCo04Et4dHqOOx4hA=,f8e0be71fb845a4ca22825f5b9c51c1a66c29e9ccff723e063781ee64c664c66 +github.com/bgentry/go-netrc,v0.0.0-20140422174119-9fd32a8b3d3d,h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=,59fbb1e8e307ccd7052f77186990d744284b186e8b1c5ebdfb12405ae8d7f935 +github.com/bgentry/speakeasy,v0.1.0,h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=,d4bfd48b9bf68c87f92c94478ac910bcdab272e15eb909d58f1fb939233f75f0 +github.com/bifurcation/mint,v0.0.0-20180715133206-93c51c6ce115,h1:fUjoj2bT6dG8LoEe+uNsKk8J+sLkDbQkJnB6Z1F02Bc=,40a4bd02b9e3477271638bc17ae8537e2675ace0a9b85d753820e979dbf97f36 +github.com/binance-chain/go-sdk,v1.0.8,h1:mC1Tai9diqIWuKTJmrFLal90OCsgtDvyLEItMvglaHA=,3d0f86f959b38f11174d8ee574e77e5d80d2c672d0720dee519f3708e873b0ca +github.com/binance-chain/ledger-cosmos-go,v0.9.9-binance.1,h1:8mAtw1Tp/BhhTrsXmXM60H1fihcvcKLfo2ZSxShaXKw=,f6dc2bfb4d29db01cad72815615301e089d727110d1d5a0de43e829953e45041 +github.com/biogo/hts,v0.0.0-20160420073057-50da7d4131a3,h1:3b+p838vN4sc37brz9W2HDphtSwZFcXZwFLyzm5Vk28=,93be93b79da8920fb5f02bb2e50a364e2b33dc831229d163e7be70c1010cdb9e +github.com/bitcoinsv/bsvd,v0.0.0-20190609155523-4c29707f7173,h1:2yTIV9u7H0BhRDGXH5xrAwAz7XibWJtX2dNezMeNsUo=,8e1e554ddc232e763fac27ddc0661cfe543163802b0d6bb9a2904bf24756ddc3 +github.com/bitcoinsv/bsvlog,v0.0.0-20181216181007-cb81b076bf2e,h1:6f+gRvaPE/4h0g39dqTNPr9/P4mikw0aB+dhiExaWN8=,89f0c34e6936d82a1629d5d255923ff27c0adeb99709269cf62071e48cb5fbd8 +github.com/bitcoinsv/bsvutil,v0.0.0-20181216182056-1d77cf353ea9,h1:hFI8rT84FCA0FFy3cFrkW5Nz4FyNKlIdCvEvvTNySKg=,4d4923e8743012e1f8ed1a1ef721786fc2d5249cc5dafd96fdd350c485378cfe +github.com/bitly/go-hostpool,v0.0.0-20171023180738-a3a6125de932,h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=,9a55584d7fa2c1639d0ea11cd5b437786c2eadc2401d825e699ad6445fc8e476 +github.com/bitly/go-simplejson,v0.5.0,h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=,53930281dc7fba8947c1b1f07c82952a38dcaefae23bd3c8e71d70a6daa6cb40 +github.com/blackducksoftware/horizon,v0.0.0-20190625151958-16cafa9109a3,h1:noI1RY2cUFZfdZMIz1+1LzT8ZeuWK703gwmH/ZC2YnQ=,ece353e9e973ce03d131b29c6c00aea53f1b2e507960b389cdfeb2cc317897ef +github.com/blacktear23/go-proxyprotocol,v0.0.0-20180807104634-af7a81e8dd0d,h1:rQlvB2AYWme2bIB18r/SipGiMEVJYE9U0z+MGoU/LtQ=,123c82a455309b3a3118504c0a70771352292abced294dca39a570b89e48adba +github.com/blakesmith/ar,v0.0.0-20190502131153-809d4375e1fb,h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=,015878daba57ba5ce7228f772b843fffa847d99c7afeb308089bef77f433c510 +github.com/blang/semver,v3.5.1+incompatible,h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=,8d032399cf835b93f7cf641b5477a31a002059eed7888a775f97bd3e9677ad3c +github.com/blevesearch/bleve,v0.8.1,h1:20zBREtGe8dvBxCC+717SaxKcUVQOWk3/Fm75vabKpU=,58a5b5ade8123d54b7510e463c25e1e59e6cd3d98acdcb4d582c42db67c03519 +github.com/blevesearch/blevex,v0.0.0-20180227211930-4b158bb555a3,h1:U6vnxZrTfItfiUiYx0lf/LgHjRSfaKK5QHSom3lEbnA=,defa5966f802eab571cc8d9315323104b776751dd13caae9d8fc0476576d57ca +github.com/blevesearch/go-porterstemmer,v0.0.0-20141230013033-23a2c8e5cf1f,h1:J9ZVHbB2X6JNxbKw/f3Y4E9Xq+Ro+zPiivzgmi3RTvg=,e13cc37d08c58870cdbad544b726934cd62ca6aa2ae35f02598f72e30d7c0f59 +github.com/blevesearch/segment,v0.0.0-20160105220820-db70c57796cc,h1:7OfDAkuAGx71ruzOIFqCkHqGIsVZU0C7PMw5u1bIrwU=,21278826e6ba0f63024a953c480467bf41d6717ae4a87c3021a9f74d2f2ae618 +github.com/blocktree/arkecosystem-adapter,v1.0.4,h1:TkZWCzAgi20CjAMlOpwTDppt6XO7X8Fn5EjSUsuB6kI=,22346af6957b0b8fae47d982605f565e5e16e86bc52a9fdd234b023067896cf2 +github.com/blocktree/bitshares-adapter,v1.0.5,h1:mzYlpip0crtYaDaXbKqtGLAxad83p19HLTVa9LLW3fc=,03ce80398ab59af79feb92b054e5da02a290ef27aef5facb93cdd86de2e0df91 +github.com/blocktree/ddmchain-adapter,v1.0.5,h1:Lx8zD0lOHb9TJ7EcGJQhyvpDkYko6OoV8uwudKRKlJA=,81e65ed5692152fcaa1dbf997f71dc43192abc72dad6fb78b721d742c05c1a7a +github.com/blocktree/eosio-adapter,v1.0.0,h1:cncKE4QbQxDsr8B+HlhU7tywbCtZRsWMln2ek8I5lbc=,cc658d6f9fa5470c5affb4caad58e17637a6d46f8e5d1b3730ed06e570e61959 +github.com/blocktree/ethereum-adapter,v1.1.10,h1:PkmQeRT5ljyCOQZPT0diJo+4G9OqOcJsnRcXeF5fitU=,cf8465db958e214c8196e6311fd5db24f8d28265a37914c2cf9d2dac54a5fd1a +github.com/blocktree/futurepia-adapter,v1.0.12,h1:mL1rDvcM55hKwLhHOkg1v2GwnCEsDniUrqrMG3PK/+4=,ae29bbdb9a4a1ec345f7d220d6a736ed827a307454d0466bb065dacf3d94200d +github.com/blocktree/go-owcdrivers,v1.1.18,h1:KCNm+HczpDfxyUf+Wrvbj/iWwQDJ+ca/FBjm3H06rIY=,65bcca1918d8b9e1048bac14b1393dec246402320b6a5dde20ee6afe84585736 +github.com/blocktree/go-owcrypt,v1.0.3,h1:qfAwJsWYp7WaI26hAwPuFUrMXhD9bWwuGXYWBOLsVes=,f365daad6adfcc5aee14faa1455f772b5e39b1c9ff3598afb1c3645587cb6b2e +github.com/blocktree/moacchain-adapter,v1.0.3,h1:k9drMeekvBsXORortW/zJXaO6CokXVv2EL0/YK3c1/A=,66c87656369c5246bad1527f7385d1cb98bbeda431383f154a23e9bf821a05a2 +github.com/blocktree/nulsio-adapter,v1.1.7,h1:d0xuovBqodBAv8BE/CPZjfe5CNma6FFSP6W3ynJRD0U=,c814c05686483abc345bf4fb997fc61595e738b99cc8a8d36742414f93e948b0 +github.com/blocktree/ontology-adapter,v1.0.8,h1:Lej35ZPPgjS6nP5CEumIUskRNASMZswgrByYSxrWPe0=,fcdeb4c6d8f37a22f52e2938ebc51b4ff1f4cf4116eebce8ecc7591995236853 +github.com/blocktree/openwallet,v1.5.3,h1:6hNj61wLfzEGqbbY0ZOeqGAjSj9snoRSBikgSlWPqZI=,1f169b69cd3ec4a4f82836c2b2178eb162464d6413c09f8170f73a838d28650b +github.com/blocktree/ripple-adapter,v1.0.13,h1:zgJt7onq5+V6pvQ7Kl3xiiSkk3uxuCF07OpwCtJTM8w=,bb7f515a6573eb185da0bebb28bf57364d175ee7f937e18af5b2eac98741464f +github.com/blocktree/virtualeconomy-adapter,v1.1.5,h1:YJ2JKUifSsCjCneM0NUky3WbG0LEm7IKUBmf9EAmAXc=,7a5085b8b0b114e2491032ec6f95e300c28fa309ec5883044d8b954d7d4db06e +github.com/blocktree/waykichain-adapter,v1.0.3,h1:qY/Txh+n4iIJA49rDMj41qpIUj3McjBir8Ls+sX8c3w=,62ea2ff873c84a32d3482c8ec1687221a1e46055b9be18fcd25be584cf2cac5d +github.com/bluele/gcache,v0.0.0-20190518031135-bc40bd653833,h1:yCfXxYaelOyqnia8F/Yng47qhmfC9nKTRIbYRrRueq4=,334accb65479b1b18fb569b08d14eebceb6478ea16abe9fbad2f1c6b6586deb6 +github.com/bluele/slack,v0.0.0-20180528010058-b4b4d354a079,h1:dm7wU6Dyf+rVGryOAB8/J/I+pYT/9AdG8dstD3kdMWU=,2b0055c292b7baa49f56eb9fc710f35f005747ddbef16427d5c985617c3b697d +github.com/bmatcuk/doublestar,v1.1.5,h1:2bNwBOmhyFEFcoB3tGvTD5xanq+4kyOZlB8wFYbMjkk=,81f592b11277591e943b91522497c323fcf0c6b4f3099f495de10f83e8c3e697 +github.com/bmizerany/assert,v0.0.0-20160611221934-b7ed37b82869,h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=,2532a167df77ade7e8012f07c0e3db4d4c15abdb7ffa7b05e1d961408da9a539 +github.com/bmizerany/pat,v0.0.0-20170815010413-6226ea591a40,h1:y4B3+GPxKlrigF1ha5FFErxK+sr6sWxQovRMzwMhejo=,ed04bed4d193e25371ebc6524984da4af9ece5c107fcc82d5aa4914b726706d2 +github.com/bndr/gotabulate,v1.1.2,h1:yC9izuZEphojb9r+KYL4W9IJKO/ceIO8HDwxMA24U4c=,2c1ecc544368e40010082f800c1ee24eaf1b8e0f96fa76a56e4f61dda4cd0d60 +github.com/boltdb/bolt,v1.3.1,h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=,ecaf17b0dbe7c85a017704c72667b2526b492b1a753ce7302a27dd2fb2e6ee79 +github.com/boombuler/barcode,v1.0.0,h1:s1TvRnXwL2xJRaccrdcBQMZxq6X7DvsMogtmJeHDdrc=,ef3832c4d22a09377323980bacd9f5f2ab43d0d20da115e1cfb139e093d7bb9b +github.com/bradfitz/go-smtpd,v0.0.0-20170404230938-deb6d6237625,h1:ckJgFhFWywOx+YLEMIJsTb+NV6NexWICk5+AMSuz3ss=,0a06dd547fed38e2744800b5f4ebae5ac00ee08717ded281510a8d319b8db8f3 +github.com/bradfitz/gomemcache,v0.0.0-20190913173617-a41fca850d0b,h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0=,eb71acfac0c4ce5f0b6537d8029de98902d83fd38fdcbfd757f06697c6323f78 +github.com/bradfitz/iter,v0.0.0-20190303215204-33e6a9893b0c,h1:FUUopH4brHNO2kJoNN3pV+OBEYmgraLT/KHZrMM69r0=,6883ce0960849ca9c024a4a4e7508ff521da2a3bb66d1974ea2f970a5265ea39 +github.com/bradfitz/latlong,v0.0.0-20140711231157-b74550508561,h1:mz4equOOUOnI4q5E7dyHlRx1x63YEaYwhlVluCDila4=,d1c124508f1825697a2bdb9fac48d2b8805b41f8e546d262fc487d8450962cec +github.com/bradhe/stopwatch,v0.0.0-20180424000511-fd55e776a960,h1:YJWTgxlTgeHlvhe7tZJm0yBcg2GhjDQs8zig5O5vup8=,c2926a4febee7eea0f523b3d4fcaa414c27effc2abc053137a3dbf0b3a4fa324 +github.com/briankassouf/jose,v0.9.2-0.20180619214549-d2569464773f,h1:ZMEzE7R0WNqgbHplzSBaYJhJi5AZWTCK9baU0ebzG6g=,c0b50157ec3c39fbd6ded9d5e6bc763890e6d909db38b337a72876124c2baeeb +github.com/brocaar/lorawan,v0.0.0-20190925120821-154a30dbdce2,h1:51WcQ+VAc/6jZ/8GBJiQ3B7FrT2aXI+YsUx2iG9tJlw=,0082cebaf26ed36c901f9b44b6d785eccc2a0c123088642eac7c9b5711b7d0ca +github.com/bsm/go-vlq,v0.0.0-20150828105119-ec6e8d4f5f4e,h1:D64GF/Xr5zSUnM3q1Jylzo4sK7szhP/ON+nb2DB5XJA=,61fc03674cd72d5a4c55413e8b58fc8eafc58fbb71fb89c719225650754b3469 +github.com/bsm/sarama-cluster,v2.1.15+incompatible,h1:RkV6WiNRnqEEbp81druK8zYhmnIgdOjqSVi0+9Cnl2A=,a8a4867f09704222362b75fa00c9894106a928dc7cf905f1b80ca7bbd1a3b8e5 +github.com/btcsuite/btclog,v0.0.0-20170628155309-84c8d2346e9f,h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=,74ad4defbabf48c98bbb547be1c40c11fa2c286f599412c774d1c5604dc1808d +github.com/btcsuite/btcutil,v0.0.0-20190425235716-9e5f4b9a998d,h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=,de1ee450ff2cfec2df220fec0d3e265cc812f214892bfad601e142632e2cf3f9 +github.com/btcsuite/go-socks,v0.0.0-20170105172521-4720035b7bfd,h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=,cc27776f56f7c58c2808af55781e9b3f7d0eb0dc08e4c19c38c6bdf2465ce0e7 +github.com/btcsuite/goleveldb,v1.0.0,h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4=,13e37462cb2fe5976221f57d357051c1c3cc63a9b0e67e6ed97f98af795d0815 +github.com/btcsuite/snappy-go,v1.0.0,h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE=,d136165bdbf91780ded5d3ebaba9026f900595e56c19aa0ef29896015eae9627 +github.com/btcsuite/websocket,v0.0.0-20150119174127-31079b680792,h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=,d45ac16f59082ac369e61c7bbe23153e289cad03619ab8041963d54cd700d6f0 +github.com/btcsuite/winsvc,v1.0.0,h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk=,6893f7a62faec17d7b0856c7464754cab14c4d913e27af5276f6a98b25f3c779 +github.com/buger/jsonparser,v0.0.0-20191004114745-ee4c978eae7e,h1:oJCXMss/3rg5F6Poy9wG3JQusc58Mzk5B9Z6wSnssNE=,7e2dda4c1b4217408903f3b4a1f2cdd93d71bc7682387ba860cfa0cc9fcf88be +github.com/bugsnag/bugsnag-go,v1.5.3,h1:yeRUT3mUE13jL1tGwvoQsKdVbAsQx9AJ+fqahKveP04=,8aaf02df2c1a4e8a5725eea1d91af69c4f9e157c2559a3452388f64a977534c0 +github.com/bugsnag/panicwrap,v1.2.0,h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA=,75357d3a5cd89dc04f1f101e02686fc1ef33b4a4f67edb82b3fa63fded3f47e9 +github.com/bwmarrin/discordgo,v0.20.1,h1:Ihh3/mVoRwy3otmaoPDUioILBJq4fdWkpsi83oj2Lmk=,616d49cc107ccd85872b6008f028c4aca021f66381828bb921f15f9e8149988a +github.com/bwmarrin/snowflake,v0.0.0-20180412010544-68117e6bbede,h1:lTJlWdyhwqq7h29GtuIDHW/xi+sMN+JOLMgYAwQ5O74=,2e13ad82f7ae64821f9851a66b4800f1589e413b27b469f28d21970957a3c6da +github.com/c-bata/go-prompt,v0.2.2,h1:uyKRz6Z6DUyj49QVijyM339UJV9yhbr70gESwbNU3e0=,ffe765d86d90afdf8519def13cb027c94a1fbafea7a18e9625210786663436c4 +github.com/c2h5oh/datasize,v0.0.0-20171227191756-4eba002a5eae,h1:2Zmk+8cNvAGuY8AyvZuWpUdpQUAXwfom4ReVMe/CTIo=,b5543f3e104a84e35ac51780968282b455dd30c88730d0da166d8d6512301da6 +github.com/caarlos0/ctrlc,v1.0.0,h1:2DtF8GSIcajgffDFJzyG15vO+1PuBWOMUdFut7NnXhw=,e4b5e9dd37cee2d47ff1c5eeba9a4b6e2b778c349a3615ca9653531f035a3ca6 +github.com/cactus/go-statsd-client/statsd,v0.0.0-20191030180650-a68a2246f89c,h1:rrLWPlpOKwnBpVUXitbgM3+Nie1eBaFfBZqfiPpxVj8=,cbb94149ec688419a91406b374955946c3679b1dde0752d7c0ffdc87432cd0b3 +github.com/caddyserver/caddy,v1.0.3,h1:i9gRhBgvc5ifchwWtSe7pDpsdS9+Q0Rw9oYQmYUTw1w=,029f14052f1ec9937c4028f3231899bf5391d5eeb7f58795d5d470a6f4c338a7 +github.com/campoy/unique,v0.0.0-20180121183637-88950e537e7e,h1:V9a67dfYqPLAvzk5hMQOXYJlZ4SLIXgyKIE+ZiHzgGQ=,4bc20f70e0b170ecdabd740a5de012d05f4c9149e2882fbdb303dc1b1793a77e +github.com/casbin/casbin,v1.9.1,h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM=,e2ef71d15eb595374d27961d255941b50691f9eaa91b5590f081fe3a4ab195c2 +github.com/cavaliercoder/go-cpio,v0.0.0-20180626203310-925f9528c45e,h1:hHg27A0RSSp2Om9lubZpiMgVbvn39bsUmW9U5h0twqc=,08b68e1d424b545418828c05c46bce5d795bbb8b534871667650ec6b3e7b33a6 +github.com/cenk/backoff,v2.2.1+incompatible,h1:djdFT7f4gF2ttuzRKPbMOWgZajgesItGLwG5FTQKmmE=,e3d1c641f85f548370aedc6bae3d4b975b09e3b2d1d9060f0e72bd5e2710d4c9 +github.com/cenkalti/backoff,v2.2.1+incompatible,h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=,f8196815a1b4d25e5b8158029d5264801fc8aa5ff128ccf30752fd169693d43b +github.com/cenkalti/backoff/v3,v3.0.0,h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=,c69bf77e7b43cb3935d763c24af3810d9869a664bbcd26ffad9d3dc1bf602006 +github.com/census-instrumentation/opencensus-proto,v0.2.1,h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=,b3c09f3e635d47b4138695a547d1f2c7138f382cbe5a8b5865b66a8e08233461 +github.com/centrify/cloud-golang-sdk,v0.0.0-20190214225812-119110094d0f,h1:gJzxrodnNd/CtPXjO3WYiakyNzHg3rtAi7rO74ejHYU=,dc3de1393d7ae63ce35393630417ff8c5421a2a03cbf1a20680c7d57a74cd311 +github.com/certifi/gocertifi,v0.0.0-20180118203423-deb3ae2ef261,h1:6/yVvBsKeAw05IUj4AzvrxaCnDjN4nUqKjW9+w5wixg=,054d6c3a6f8d78fba2f08fbc2f23ec839d5a4aead4a184270d87d095c80eb6dc +github.com/cespare/cp,v1.1.1,h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU=,25f2ed5bac9ac3c1891ff364b213f6b7b0ee2e7aed13510738ced93ea71860e3 +github.com/cespare/xxhash,v1.1.0,h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=,fe98c56670b21631f7fd3305a29a3b17e86a6cce3876a2119460717a18538e2e +github.com/cespare/xxhash/v2,v2.1.0,h1:yTUvW7Vhb89inJ+8irsUqiWjh8iT6sQPZiQzI6ReGkA=,655feb22a395d9f56315280770d386eb99cdca79a97970812dbd3b30a7940638 +github.com/chaseadamsio/goorgeous,v0.0.0-20170901132237-098da33fde5f,h1:REH9VH5ubNR0skLaOxK7TRJeRbE2dDfvaouQo8FsRcA=,f81f4ef8ac52852b232ea971d009ec88007f1258c29e10e49918a31a99c6c4cc +github.com/checkpoint-restore/go-criu,v0.0.0-20190109184317-bdb7599cd87b,h1:T4nWG1TXIxeor8mAu5bFguPJgSIGhZqv/f0z55KCrJM=,1d1f5c6e529c87259305d8ed6bf4d381dabbf85458de187981204339e251a5be +github.com/cheekybits/genny,v1.0.0,h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=,770f3e01425b9b0a87a5e0b29fc6ac2cfa67a3f1265aafb16c96a47bafc304e4 +github.com/cheekybits/is,v0.0.0-20150225183255-68e9c0620927,h1:SKI1/fuSdodxmNNyVBR8d7X/HuLnRpvvFO0AgyQk764=,f7bf9ac5b1fc574ef5a373382909af550ef1a7f01182469eaa12e18c7c5fc7cb +github.com/cheggaaa/pb,v2.0.7+incompatible,h1:gLKifR1UkZ/kLkda5gC0K6c8g+jU2sINPtBeOiNlMhU=,383b717f271a2471e57ac52f64dbb77304ec1c0b53c5efeb7a1392668f59d0b4 +github.com/cheggaaa/pb/v3,v3.0.1,h1:m0BngUk2LuSRYdx4fujDKNRXNDpbNCfptPfVT2m6OJY=,781be3118614dfaeb2df44d31d8af36c703c2aaed18e9ca49fa4ef9ba1539236 +github.com/chewxy/hm,v1.0.0,h1:zy/TSv3LV2nD3dwUEQL2VhXeoXbb9QkpmdRAVUFiA6k=,68ab03d9f8cb3d92d6c8234cfd879004be2fd69457d2c9fa6834d1c6ddb22b43 +github.com/chewxy/math32,v1.0.4,h1:dfqy3+BbCmet2zCkaDaIQv9fpMxnmYYlAEV2Iqe3DZo=,7885f637bb90729d04f125e030542b9a6999f9e5dffd3294baffbcdd548bbc3e +github.com/chrismalek/oktasdk-go,v0.0.0-20181212195951-3430665dfaa0,h1:CWU8piLyqoi9qXEUwzOh5KFKGgmSU5ZhktJyYcq6ryQ=,094a132bc1e950677f75e570b17a52f103edd6acd3ec1c0943cf9cda3cd6355a +github.com/chromedp/cdproto,v0.0.0-20191009033829-c22f49c9ff0a,h1:AuIGvB6IuWpMEdfKQ+t77D6dzLpNftzxAsktehYyWn8=,bf85eeebdc65b1e90d851b42f56a3dbf5bcff4923aa426692a1c0d0a1727a522 +github.com/chromedp/chromedp,v0.5.1,h1:PAqhoCWCHzRphYnmmxLSiYk7EEwDplCm4woTCCaV2cQ=,59cd1ab42eeb90e32cc60e77a8fbb19ca629603200d5bd40d611f780e646062b +github.com/chzyer/logex,v1.1.10,h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=,2c94771c1e335a2c58a96444b3768b8e00297747d6ce7e7c14bab2e8b39d91bd +github.com/chzyer/readline,v0.0.0-20180603132655-2972be24d48e,h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=,3dc842677887278fb33d25078d375ae6a7a94bb77a8d205ee2230b581b6947a6 +github.com/chzyer/test,v0.0.0-20180213035817-a1ea475d72b1,h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=,ad8550bed3c4a94bbef57b9fc5bb15806eaceda00925716404320580d60e2f7d +github.com/cihub/seelog,v0.0.0-20170130134532-f561c5e57575,h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs=,fc279208e6094fb22c8ea651c6e9794844069693c9b916c225276c54f7e76bfe +github.com/circonus-labs/circonus-gometrics,v2.3.1+incompatible,h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY=,d8081141497e3cd34844df66af016c7900d58b324fb689e17e57bc053d91c9ba +github.com/circonus-labs/circonusllhist,v0.1.3,h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA=,4dc805d9735dd9ca9b8875c0ad23126abb5bc969c5a40c61b5bc891808dbdcb6 +github.com/clbanning/mxj,v1.8.4,h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I=,8947cf617bdd9efc62817c8ddb17bafe497f35abdf10a3c60f295e387f633f70 +github.com/client9/misspell,v0.3.4,h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=,a3af206372e131dd10a68ac470c66a1b18eaf51c6afacb55b2e2a06e39b90728 +github.com/cloudflare/backoff,v0.0.0-20161212185259-647f3cdfc87a,h1:8d1CEOF1xldesKds5tRG3tExBsMOgWYownMHNCsev54=,2aea6d1528c42cf5f111e035bba564fd0481cb4ddb3b50f783f2481d855947cb +github.com/cloudflare/cfssl,v1.4.0,h1:TdyQbj/bDUMUHf2IkcHU2EHUmzCmRLuJ3fFd8EYMg1E=,845fc5f4a7f4c2356d676916fdd7b4b2217b76c8f9b7a960290ab8884d6f8e0e +github.com/cloudflare/cloudflare-go,v0.10.4,h1:7C1D9mtcNFZLCqmhkHK2BlwKKm9fi4cBqY6qpYtQv5E=,e8f6ee817c9b807c98559ff87d4ed7a284738d9dc253b6db7520911d93bd81e3 +github.com/cloudflare/go-metrics,v0.0.0-20151117154305-6a9aea36fb41,h1:/8sZyuGTAU2+fYv0Sz9lBcipqX0b7i4eUl8pSStk/4g=,9176a680ad7a72cf717e3e01ee1ca6b292cb576b543e12ff1770cc58957bc222 +github.com/cloudflare/golz4,v0.0.0-20150217214814-ef862a3cdc58,h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=,75832d1c2989b2a0d7eb8d2cec300f6d457254d42927a23f522b164833e791d4 +github.com/cloudflare/redoctober,v0.0.0-20171127175943-746a508df14c,h1:p0Q1GvgWtVf46XpMMibupKiE7aQxPYUIb+/jLTTK2kM=,e69334393aec994f9ba55bbdfa8a65c0cfa46080230068c44ca16a85c0a74079 +github.com/cloudfoundry-community/go-cfclient,v0.0.0-20190201205600-f136f9222381,h1:rdRS5BT13Iae9ssvcslol66gfOOXjaLYwqerEn/cl9s=,f01d41c3c911b59bf717674690799c978f3a841ef695c7ee09f4afe5f7c96e64 +github.com/cloudfoundry-incubator/candiedyaml,v0.0.0-20170901234223-a41693b7b7af,h1:6Cpkahw28+gcBdnXQL7LcMTX488+6jl6hfoTMRT6Hm4=,325af9d6827b8d120a72992c38ba776187fbd947a39c9f1928a43a1a2b262453 +github.com/cloudfoundry/bosh-agent,v2.271.0+incompatible,h1:277mM9hsUzyrd5Qd/5e1LFwiobIYorE7vTBRZohRV8s=,42e253b855d03655ec2cf59ab01a14aa0037f25029517be595dda26ff9a2a552 +github.com/cloudfoundry/bosh-utils,v0.0.0-20191026100324-0b6803ec5382,h1:Rrpgz+K2Zso//XUmqbGlnYi9rw6EtYJ4uLlTNSnSBIw=,c08bbf97e510b2de271fd64f5b2acedfa011b4fd3f30092804992084c67b68b7 +github.com/cloudfoundry/gosigar,v1.1.0,h1:V/dVCzhKOdIU3WRB5inQU20s4yIgL9Dxx/Mhi0SF8eM=,53acb43e5111c6af6af138e1144907bb5f9bf8abc28e71a703502f92c13ba274 +github.com/cloudfoundry/sonde-go,v0.0.0-20171206171820-b33733203bb4,h1:cWfya7mo/zbnwYVio6eWGsFJHqYw4/k/uhwIJ1eqRPI=,6124fdcac54e1baf09703ed2b938a4e2bb55d9cd20f78451f25c16638a95f62d +github.com/cockroachdb/apd,v1.1.0,h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=,fef7ec2fae220f84bfacb17fbfc1b04a666ab7f6fc04f3ff6d2b1e05c380777d +github.com/cockroachdb/apd/v2,v2.0.1,h1:y1Rh3tEU89D+7Tgbw+lp52T6p/GJLpDmNvr10UWqLTE=,9f1c35b8118f70f08150bf5e9da225fa1201f5d0f8c22f326468ea22ab6b791d +github.com/cockroachdb/cockroach-go,v0.0.0-20190916165215-ad57a61cc915,h1:QX2Zc22B15gdWwDCwS7BXmbeD/SWdcRK12gOfZ5BsIs=,e3faa1cdf2a15357d1e2eb200b3bdb81dae3fb084cb04534e0caf27a68487a88 +github.com/cockroachdb/datadriven,v0.0.0-20190809214429-80d97fb3cbaa,h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=,170480bf3daa133144f2578e3f051f0fd98313666642cab64cef3359753a5c32 +github.com/codahale/hdrhistogram,v0.0.0-20161010025455-3a0bb77429bd,h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=,e7e117da64da2f921b1f9dc57c524430a7f74a78c4b0bad718d85b08e8374e78 +github.com/codegangsta/inject,v0.0.0-20150114235600-33e0aa1cb7c0,h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=,0a324d56992bffd288fa70a6d10eb9b8a9467665b0b1eb749ac6ae80e8977ee2 +github.com/codegangsta/negroni,v1.0.0,h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY=,2e6301aa682a7c38305f2ee72b276181cd0990f224f9fe115a433a5beb138488 +github.com/codeskyblue/go-sh,v0.0.0-20190412065543-76bd3d59ff27,h1:HHUr4P/aKh4quafGxDT9LDasjGdlGkzLbfmmrlng3kA=,77348ab27860460a015d0e65d08f18ed2194c13981f5fd722143a6e0c2dbb589 +github.com/confluentinc/confluent-kafka-go,v1.1.0,h1:HIW7Nkm8IeKRotC34mGY06DwQMf9Mp9PZMyqDxid2wI=,bc9aee1c8052340809bc43bf015a183985ec3426d404c34acfa3970e3b245340 +github.com/container-storage-interface/spec,v1.2.0,h1:bD9KIVgaVKKkQ/UbVUY9kCaH/CJbhNxe0eeB4JeJV2s=,86ecb02d57af97c9a4de8f2f3cacbceb5c7f2f96ee007133e0cfb9525ce45177 +github.com/containerd/cgroups,v0.0.0-20191011165608-5fbad35c2a7e,h1:3bt+8T1I/CuYx+a5ww32+UT4fc9x8iRiXrhfduFTlBU=,4646f14f27a365ff08abb1266b7ca4dffc1acd5e8e74b57211acbba22b496d46 +github.com/containerd/console,v0.0.0-20181022165439-0650fd9eeb50,h1:WMpHmC6AxwWb9hMqhudkqG7A/p14KiMnl6d3r1iUMjU=,62a7f1da11b3be4c0ef4f9f03b99dcf59dc988f062749f35e4e6bb585fb4e4fe +github.com/containerd/containerd,v1.3.0,h1:xjvXQWABwS2uiv3TWgQt5Uth60Gu86LTGZXMJkjc7rY=,e3f529147f2c909c85ac461126ad092a3c5d5a2abcc4f3c22600685af6dc2f08 +github.com/containerd/continuity,v0.0.0-20190827140505-75bee3e2ccb6,h1:NmTXa/uVnDyp0TY5MKi197+3HWcnYWfnHGyaFthlnGw=,ef1a3a4c2c1508d293eb2730e47e9601cba19d939393b1018d8e476b30dfd90b +github.com/containerd/fifo,v0.0.0-20190816180239-bda0ff6ed73c,h1:KFbqHhDeaHM7IfFtXHfUHMDaUStpM2YwBR+iJCIOsKk=,0c1b858ee9dd28bd915a3f7bd108b98b1d689be3c14535e7e8aee4a60c4a72c0 +github.com/containerd/go-runc,v0.0.0-20190923131748-a2952bc25f51,h1:vmF3zULCGpZ4QJCCLsGUXX7tNXW+0x3r9owerRAmRaU=,76ce6296dc07f1f5957867e9a5925cf9e16c69ad2b635f74a4ec471e6672ee51 +github.com/containerd/ttrpc,v0.0.0-20191028202541-4f1b8fe65a5c,h1:+RqLdWzn0xFunb+sxXaEzHOg8NuEG/eaI+9C1xXX8Mw=,f43884f8f37259c4b50a4413092064f35abd03b9db3bbe2ca3264b5a4b591b04 +github.com/containerd/typeurl,v0.0.0-20190911142611-5eb25027c9fd,h1:bRLyitWw3PT/2YuVaCKTPg0cA5dOFKFwKtkfcP2dLsA=,aa4e0823acf7b686a9521617134a171c5b5813de302e3fba742cd3b7f43ba944 +github.com/containernetworking/cni,v0.7.1,h1:fE3r16wpSEyaqY4Z4oFrLMmIGfBYIKpPrHK31EJ9FzE=,b83f1b8e9bba747e41512737383da57e517cf425beb1bd58882904dae9348b1d +github.com/containers/image,v3.0.2+incompatible,h1:B1lqAE8MUPCrsBLE86J0gnXleeRq8zJnQryhiiGQNyE=,dadc25bfff923d4f2c8b570471be3b0fd1449f42251fb6c318b68e04f6d47b3a +github.com/containers/storage,v1.12.13,h1:GtaLCY8p1Drlk1Oew581jGvB137UaO+kpz0HII67T0A=,08f5ee958be629b73ff02296eb11f4b0698dbd90e585ce019c5428a8e1d371d4 +github.com/containous/flaeg,v1.4.1,h1:VTouP7EF2JeowNvknpP3fJAJLUDsQ1lDHq/QQTQc1xc=,d097191570bb92f920cd15500a93205e6e93b5ee4723a51c9b8e3bfbcfaae505 +github.com/corbym/gocrest,v1.0.3,h1:gwEdq6RkTmq+09CTuM29DfKOCtZ7G7bcyxs3IZ6EVdU=,f13221d177442318b04f468fa57ea92bd9892d86e7cf7bb7299e0c58cea9df48 +github.com/coredns/coredns,v1.1.2,h1:bAFHrSsBeTeRG5W3Nf2su3lUGw7Npw2UKeCJm/3A638=,cbf720a9af4fdc5be08b0eea67fe219bb08c75292e22dca90095bf45cbd4a926 +github.com/coreos/bbolt,v1.3.3,h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=,63ea574f28bd03b6d2a82304e0f7c96dcb30fa048311a4c8c3ad512dbacc4630 +github.com/coreos/clair,v0.0.0-20180919182544-44ae4bc9590a,h1:glxUtT0RlaVJU86kg78ygzfhwW6D+uj5H+aOK01QDgI=,3bc8c4b06a61c5673fcc69d5278b3a5313633fca1166e94a7140c363399c3dc6 +github.com/coreos/etcd,v3.3.17+incompatible,h1:f/Z3EoDSx1yjaIjLQGo1diYUlQYSBrrAQ5vP8NjwXwo=,d7ca8db509166ce05482c9b3e80cfb8d1086691901e80202f571d152da912153 +github.com/coreos/go-etcd,v2.0.0+incompatible,h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo=,4b226732835b9298af65db5d075024a5971aa11ef4b456899a3830bccd435b07 +github.com/coreos/go-iptables,v0.4.3,h1:jJg1aFuhCqWbgBl1VTqgTHG5faPM60A5JDMjQ2HYv+A=,4626df8f719f93e5d66bd995d586ae3540c24b2203c0d2aab7c6d5e60f89a3dc +github.com/coreos/go-oidc,v2.1.0+incompatible,h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM=,e2e123270614dd7d47d95ae1fce80a9102df019f9e820d4f5cf5c92c64e1ad91 +github.com/coreos/go-semver,v0.3.0,h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=,b2fc075395ffc34cff4b964681d0ae3cd22096cfcadd2970eeaa877596ceb210 +github.com/coreos/go-systemd,v0.0.0-20190719114852-fd7a80b32e1f,h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=,22237f0aed3ab6018a1025c65f4f45b4c05f9aa0c0bb9ec880294273b9a15bf2 +github.com/coreos/pkg,v0.0.0-20180928190104-399ea9e2e55f,h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=,7fe161d49439a9b4136c932233cb4b803b9e3ac7ee46f39ce247defc4f4ea8d7 +github.com/coreos/rkt,v1.30.0,h1:Kkt6sYeEGKxA3Y7SCrY+nHoXkWed6Jr2BBY42GqMymM=,436e294b735bada49407ad3c066ae251ef105ce59076ef8f0f732c586a72970e +github.com/cosiner/argv,v0.0.0-20170225145430-13bacc38a0a5,h1:rIXlvz2IWiupMFlC45cZCXZFvKX/ExBcSLrDy2G0Lp8=,deb11c1c7a2fa44b3497731d497b3d7be5a51cf696ed43280e01822e2eed9b96 +github.com/cosmos/cosmos-sdk,v0.35.0,h1:EPeie1aKHwnXtTzKggvabG7aAPN+DDmju2xquvjFwao=,ccc975b48e3b40f4eb054e28e9243ecb48c0d8ecdf52b9512da26a8200cc7c43 +github.com/cosmos/go-bip39,v0.0.0-20180819234021-555e2067c45d,h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU=,e41d7ea781b15421a4690bedf78543f2eaad00c36c439dd4973131dec1985177 +github.com/cosmos/ledger-cosmos-go,v0.10.3,h1:Qhi5yTR5Pg1CaTpd00pxlGwNl4sFRdtK1J96OTjeFFc=,f1089701d8868e4ff3fd9e9a4104476963f725a713ee2a476b4ef8094a0bca20 +github.com/cosmos/ledger-go,v0.9.2,h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI=,a77b2063a64133d8dda638d5d602071429d7e2500576bfff5c1763f8572a8517 +github.com/couchbase/go-couchbase,v0.0.0-20191031153726-96c2e23d589a,h1:eKnoG+AQQQIxHEcBIbudmwLJv3S9UQU6oGHzvqhttqE=,5dd3e610f24adb44b31e7ecc6a80a8974b769bd622d569c69fb98bd02610bbef +github.com/couchbase/gomemcached,v0.0.0-20191004160342-7b5da2ec40b2,h1:vZryARwW4PSFXd9arwegEywvMTvPuXL3/oa+4L5NTe8=,5b9a280cd2d546cd0d70fbd6828e73fa0b07fb9d3c0b6bff88d8e23d8e4256f4 +github.com/couchbase/goutils,v0.0.0-20190315194238-f9d42b11473b,h1:bZ9rKU2/V8sY+NulSfxDOnXTWcs1rySqdF1sVepihvo=,a2820e0f01d8c944b70c70515b9924f41b450f3688d19ad4d506b2b9b367c433 +github.com/couchbase/vellum,v0.0.0-20190111184608-e91b68ff3efe,h1:2o6Y7KMjJNsuMTF8f2H2eTKRhqH7+bQbjr+D+LnhE5M=,06e3ca28a98c95bcdfd909168e1dcf45a6667ef59ad59112a01e6bbdcf591e84 +github.com/couchbaselabs/go-couchbase,v0.0.0-20190708161019-23e7ca2ce2b7,h1:1XjEY/gnjQ+AfXef2U6dxCquhiRzkEpxZuWqs+QxTL8=,3429eb55dd38b07bab5e9a57a3e2451449b49bdbc6f16585f8b7557067572499 +github.com/cpu/goacmedns,v0.0.1,h1:GeIU5chKys9zmHgOAgP+bstRaLqcGQ6HJh/hLw9hrus=,12acca48bb444f3832a87b8d238e573bbfa60e5c25dfcf6787a003dfacaf055d +github.com/cpuguy83/go-md2man,v1.0.10,h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=,b9b153bb97e2a702ec5c41f6815985d4295524cdf4f2a9e5633f98e9739f4d6e +github.com/cpuguy83/go-md2man/v2,v2.0.0,h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=,f2fdd06287a80f1bea5552f572d7f2314ec829285a3040b63469e0635f66fb6d +github.com/creack/goselect,v0.1.0,h1:4QiXIhcpSQF50XGaBsFzesjwX/1qOY5bOveQPmN9CXY=,24d8028970032b1a45091ad8ff9b9c280693def1433cb5948ed92c0c975226ea +github.com/creack/pty,v1.1.7,h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=,e7ea3403784d186aefbe84caed958f8cba2e72a04f30cdb291ece19bec39c8f3 +github.com/cskr/pubsub,v1.0.2,h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=,39e40a42c10058c188f331ed0bb660a0504d7c2ddd9e835a9970786fdc35feb0 +github.com/cupcake/rdb,v0.0.0-20161107195141-43ba34106c76,h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ=,019a246ac0d7f6fcf3758587a031767730cfb824003c311686a4eb552a1dcc57 +github.com/cweill/gotests,v1.5.3,h1:k3t4wW/x/YNixWZJhUIn+mivmK5iV1tJVOwVYkx0UcU=,7ced96d4223a0afcd41922c4d3ae064493dd5bedbc72f6541716fce1cab24b7d +github.com/cxr29/aliyun-openapi-go-sdk,v0.0.0-20151123082822-0b043e4d1e0c,h1:WEWetvNRZlk7JW3M4fycSA3f/2xZGxRdrwmpgRkGoQc=,6c80128745e3acdd01f59bc6c6e3a1f24193e89eb627ad6dcc615e763878b6e4 +github.com/cyphar/filepath-securejoin,v0.2.2,h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=,d022873dbb9e8d3b7a43c9dedbea54dfc9a6c15f9632ba522a1257e8b948c100 +github.com/cznic/b,v0.0.0-20181122101859-a26611c4d92d,h1:SwD98825d6bdB+pEuTxWOXiSjBrHdOl/UVp75eI7JT8=,1c34b27ce98f70cb0e97c2bbe0bdae216cc1ea6b2617b0e984e2ce30adc06338 +github.com/cznic/fileutil,v0.0.0-20181122101858-4d67cfea8c87,h1:94XgeeTZ+3Xi9zsdgBjP1Byx/wywCImjF8FzQ7OaKdU=,109b4c91722a0f9a4f941d77eff34270684e53ca36e7d14ab2cd4a4e80841d73 +github.com/cznic/golex,v0.0.0-20181122101858-9c343928389c,h1:G8zTsaqyVfIHpgMFcGgdbhHSFhlNc77rAKkhVbQ9kQg=,d2b11a6e0e1de5125a2d550650b4cbb7bf44280ebf1cda74ef4a63e3cfa11012 +github.com/cznic/internal,v0.0.0-20181122101858-3279554c546e,h1:58AcyflCe84EONph4gkyo3eDOEQcW5HIPfQBrD76W68=,bc177d001529bca3f46aa84855db4e783a041c188d3ba237f68fa4522bdca74b +github.com/cznic/kv,v0.0.0-20181122101858-e9cdcade440e,h1:8ji4rZgRKWMQUJlPNEzfzCkX7yFAZFR829Mrh7PXxLA=,4f992bdaf6d17487c7b16669b6d55afa76b321e63f8e4b6a6d1126b44b18b0d9 +github.com/cznic/lldb,v1.1.0,h1:AIA+ham6TSJ+XkMe8imQ/g8KPzMUVWAwqUQQdtuMsHs=,ddec7228568547a5fbfbc6a91208cbcafeed4338a38c41d483448957e4bec186 +github.com/cznic/mathutil,v0.0.0-20181122101859-297441e03548,h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso=,8f69a36f60d885e011b0a90b91246a7e88223cb2883dc6e71eab3f42d653231b +github.com/cznic/parser,v0.0.0-20181122101858-d773202d5b1f,h1:DUtr2TvhM9rmiHKVJWoLqDY2+MdxljW9hlaS/oYoi1c=,18b746a4090720bd9dfe219d0f7bb7fb28565df70417208d7e99dfd79f1ea264 +github.com/cznic/ql,v1.2.0,h1:lcKp95ZtdF0XkWhGnVIXGF8dVD2X+ClS08tglKtf+ak=,05164e379d43eaada0efdd763a50a9ef8f4b7f73a5de7ab866093bb25a4fb747 +github.com/cznic/sortutil,v0.0.0-20181122101858-f5f958428db8,h1:LpMLYGyy67BoAFGda1NeOBQwqlv7nUXpm+rIVHGxZZ4=,67783879c1ae4472fdabb377b1772e4e4c5ced181528c2fc4569b565cb47a57b +github.com/cznic/strutil,v0.0.0-20181122101858-275e90344537,h1:MZRmHqDBd0vxNwenEbKSQqRVT24d3C05ft8kduSwlqM=,867902276444cbffca84d9d5f63754e8b22092d93a94480d8dfebd234ac8ffbd +github.com/cznic/y,v0.0.0-20181122101901-b05e8c2e8d7b,h1:gvFsf4zJcnW6GRN+HPGTxwuw+7sTwzmoeoBQQCZDEnk=,8c84f5e4f9dc5f0809d8ad22d057e404c3e8644dc28e8fc52abbb1d2350f8d3e +github.com/cznic/zappy,v0.0.0-20181122101859-ca47d358d4b1,h1:ytLS5Cgkxq6jObotJ+a13nsejdqzLFPliDf8CQ8OkAA=,505c19b52924ee21b65611bc45640d3ff4671e50ee04f7c17c38342190645595 +github.com/d2g/dhcp4,v0.0.0-20170904100407-a1d1b6c41b1c,h1:Xo2rK1pzOm0jO6abTPIQwbAmqBIOj132otexc1mmzFc=,15df9468cf548a626e1319e92d550432512c4319cf555bf278ea9215de3504e3 +github.com/daaku/go.zipexe,v1.0.0,h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=,74d7a0242c03c3c03220e56a59da5f97d3478743250740df538e05e6b609f553 +github.com/danwakefield/fnmatch,v0.0.0-20160403171240-cbb64ac3d964,h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=,f601e8d25a43ed32e00851e1686a93b0175dadea8f4e32c8af2f1533f20736bc +github.com/dave/jennifer,v1.2.0,h1:S15ZkFMRoJ36mGAQgWL1tnr0NQJh9rZ8qatseX/VbBc=,85b37a1b99b7d67664389b8c11b7174f521a396bb59d4e0e766df16336a7f112 +github.com/dave/services,v0.1.0,h1:7isGzpZHJWmOYTV+Pn3f6gpQUmrveJqsQpAkH0HXFbU=,e52a7ffba3aa07cca4888e08248771211abd139928b5cde9b228a61da88eddcc +github.com/davecgh/go-spew,v1.1.1,h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=,6b44a843951f371b7010c754ecc3cabefe815d5ced1c5b9409fb2d697e8a890d +github.com/davecgh/go-xdr,v0.0.0-20161123171359-e6a2ba005892,h1:qg9VbHo1TlL0KDM0vYvBG9EY0X0Yku5WYIPoFWt8f6o=,11cb87912b5288e13534cb396935694c257eb9164ffc20ce21e3bc9955edd82a +github.com/daviddengcn/go-colortext,v0.0.0-20180409174941-186a3d44e920,h1:d/cVoZOrJPJHKH1NdeUjyVAWKp4OpOT+Q+6T1sH7jeU=,159d727adf4f0763ec3dc6156fd46531a2afbffdc17feeb6b5ffe2eb54b35d41 +github.com/davyxu/cellnet,v4.1.0+incompatible,h1:zDRqhkFRhBTD7ajra2888aoRLN1qlv8LV8+qHg/emO4=,f085f088b68b2e379a6dc37501ef2c9809836cfac147a30ed3025571c2d57df7 +github.com/davyxu/golog,v0.1.0,h1:SsV3m2x37sCzFaQzq5OHc5S+PE2VMiL7XUx34JCa7mo=,a3c240bc4b958fa4b4e73caa59c28fc658afbabdb1f28b237874803ca96dcb1f +github.com/dchest/blake256,v1.0.0,h1:6gUgI5MHdz9g0TdrgKqXsoDX+Zjxmm1Sc6OsoGru50I=,9a9ed00a3024f2f7480b59c7b2ee1013cae3026d7dc2f065ce225dcce8cf357e +github.com/dchest/siphash,v1.2.1,h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=,877a468e533e28c777c59b3dfea175b38a1f0bc1f8551e3a9e1739b1821c7e3e +github.com/dchest/uniuri,v0.0.0-20160212164326-8902c56451e9,h1:74lLNRzvsdIlkTgfDSMuaPjBr4cf6k7pwQQANm/yLKU=,41db9fb52a841d11d8592a1d4f56e8a440e3991b699ae0f95ab5f5a7b2aeb24c +github.com/deckarep/golang-set,v1.7.1,h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=,86606609df42529fda55a15475b495f993f0c1cc4be6e1e50a9165a514d1ed71 +github.com/decker502/dnspod-go,v0.2.0,h1:6dwhUFCYbC5bgpebLKn7PrI43e/5mn9tpUL9YcYCdTU=,381fb0bb29ac973f318db3d464f76e5d3016d4963c78ccd7df7dbc4231a68455 +github.com/decred/base58,v1.0.0,h1:BVi1FQCThIjZ0ehG+I99NJ51o0xcc9A/fDKhmJxY6+w=,75b1a2c78759ee2e8755156806ce770c9199464c2d58541388d5ec7c000c99e1 +github.com/decred/dcrd/chaincfg,v1.5.1,h1:u1Xbq0VTnAXIHW5ECqrWe0VYSgf5vWHqpSiwoLBzxAQ=,7344cd4dc90a82342c90811c8180b1fef6c79e9c49caa38135f271cf0ecb056f +github.com/decred/dcrd/chaincfg/chainhash,v1.0.2,h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU=,a8b24e2c4e64015430b8a6502f9e8c3eeea246021638884dc510508eccda31a0 +github.com/decred/dcrd/chaincfg/v2,v2.0.2,h1:VeGY52lHuYT01tIGbvYj+OO0GaGxGaJmnh+4vGca1+U=,906dec975cf574c55f2eb588dc91a4ddd6be273eaddfbeb45288ea6aebcc6306 +github.com/decred/dcrd/crypto/blake256,v1.0.0,h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=,cd8bbdae14641f0ba44430fc66990dd37bbfcf1e21a965a9fd1871d16cac127d +github.com/decred/dcrd/dcrec,v1.0.0,h1:W+z6Es+Rai3MXYVoPAxYr5U1DGis0Co33scJ6uH2J6o=,a1e16c5ef3633f2dfa23c052778552cf9300821197f5b2dc547e20dd9d45756b +github.com/decred/dcrd/dcrec/edwards,v1.0.0,h1:UDcPNzclKiJlWqV3x1Fl8xMCJrolo4PB4X9t8LwKDWU=,7ed52f3316f5a47c5925e23bebf5016ecfd75e7ac340714b4b94b0e25bdf0611 +github.com/decred/dcrd/dcrec/secp256k1,v1.0.2,h1:awk7sYJ4pGWmtkiGHFfctztJjHMKGLV8jctGQhAbKe0=,5fa2c17fd611665a39e6435283445ec3b46a5b52d14661e04bd1f7ef295ba9d3 +github.com/decred/dcrd/dcrutil,v1.4.0,h1:xD5aUqysGQnsnP1c9J0kGeW8lDIwFGC3ja/gE3HnpCs=,6de50428375fca174f4861f8aa45549360e7733bca0184a882448f0b9f94be2e +github.com/decred/dcrd/dcrutil/v2,v2.0.0,h1:HTqn2tZ8eqBF4y3hJwjyKBmJt16y7/HjzpE82E/crhY=,fa91eb7c5062e0f3f6e7d1b9d8e1a89698f6ee6e7f8f4941929f6d89a293ec76 +github.com/decred/dcrd/wire,v1.3.0,h1:X76I2/a8esUmxXmFpJpAvXEi014IA4twgwcOBeIS8lE=,e17b78d19d0056503627826a0e599ed14a7a4fc8aa2c31c47b12ffc1864aedb1 +github.com/decred/slog,v1.0.0,h1:Dl+W8O6/JH6n2xIFN2p3DNjCmjYwvrXsjlSJTQQ4MhE=,1c27399a3f38fb7b581f4dbe11a0b3e3d5d8afcc8109880771c0e44135388bb0 +github.com/denisenkom/go-mssqldb,v0.0.0-20191001013358-cfbb681360f0,h1:epsH3lb7KVbXHYk7LYGN5EiE0MxcevHU85CKITJ0wUY=,ff2349c73cee9e54cd61e85af75d7d0537fb5f070da5a737b5abede1f7d579ac +github.com/denkhaus/bitshares,v0.6.1-0.20190502142618-5ae8c00cb394,h1:PpFS6pvAoRwH13WlqnX/mrxesu6LNFtiVwoWgfNLCeY=,af76695d3e546cad6a8b56d9d5e431bfeb12bfce643a395fb45d8827409dd9ff +github.com/denkhaus/gojson,v1.0.0,h1:p1hAlN/yAvRvzbdO1HNDQvmBslfyk64IMt3O3DtftPU=,5c0d8d98a53be88e2801d90124e28ba781d2c6a09aaf9a57272df92c5c0e0fe2 +github.com/denkhaus/logging,v0.0.0-20180714213349-14bfb935047c,h1:imM7UU8JD1sNuk2tVEk3QvrY2RZ5f/DOB+UA7c5ThGs=,5a1bb81f35dc7847b0cb8efe3f1e3bac3a34c9f11950a7c7643115c952fa3166 +github.com/denverdino/aliyungo,v0.0.0-20170926055100-d3308649c661,h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o=,e6ca432bab5a7b1d233c9c1495d32668d31b18803d65f3af27f1d8240b6547d4 +github.com/detached/gorocket,v0.0.0-20170629192631-d44bbd3f26d2,h1:zwp9mAr+YvsgLCFIVJ3/m61Z+NRX35jbD0HBa62ryHY=,f54c9dc20ba925f0b2a726cc1a22466c6e05d7e0080f6e4b5f26e60c15938712 +github.com/detailyang/go-fallocate,v0.0.0-20180908115635-432fa640bd2e,h1:lj77EKYUpYXTd8CD/+QMIf8b6OIOTsfEBSXiAzuEHTU=,dcc45102d034d78825d1aa9d2f61720b4b0d9f76314a7a53b32cf032713a0bde +github.com/devfeel/dotweb,v1.7.3,h1:tt7YtCIp9JPmAS2yksVIsw6CiUkUSz3kVLSiCzRaWDw=,7cdb6d4872bb4c82fc333722fb2be3e39fe391b121550421d240d3008c8e00a0 +github.com/devigned/tab,v0.1.1,h1:3mD6Kb1mUOYeLpJvTVSDwSg5ZsfSxfvxGRTxRsJsITA=,528e21b578f28a998453551c51abfdeed154c981486d49a8ad7c149743ea450f +github.com/dghubble/oauth1,v0.6.0,h1:m1yC01Ohc/eF38jwZ8JUjL1a+XHHXtGQgK+MxQbmSx0=,6d4be6cfc2771fab15e47d2aa9c40d347dab7166f2cae3c248aeb51b10c88b4a +github.com/dghubble/sling,v1.3.0,h1:pZHjCJq4zJvc6qVQ5wN1jo5oNZlNE0+8T/h0XeXBUKU=,880e7f44ee68eae979a34afb2f95ab1c7555712153c45be01d15cbc5991a5fe6 +github.com/dgraph-io/badger,v1.6.0,h1:DshxFxZWXUcO0xX476VJC07Xsr6ZCBVRHKZ93Oh7Evo=,8329ae390aebec6ae360356e77a2743357ad4e0d0bd4c3ae03b7d17e01ad70aa +github.com/dgraph-io/dgo,v1.0.0,h1:DRuI66G+j0XWDOXly4v5PSk2dGkbIopAZIirRjq7lzI=,dae0ee7690b0c58d72be328263d55394f88a4924a8274017021736d702be9cee +github.com/dgrijalva/jwt-go,v3.2.0+incompatible,h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=,26b028eb2d9ee3aef26a96d6790e101f4088ef901008ebab17096966bf6522ad +github.com/dgryski/go-farm,v0.0.0-20190423205320-6a90982ecee2,h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=,d1fb60f1ce562acb07569d53b43353b73f439911c27eecef716305cd2d730258 +github.com/dgryski/go-jump,v0.0.0-20170409065014-e1f439676b57,h1:qZNIK8jjHgLFHAW2wzCWPEv0ZIgcBhU7X3oDt/p3Sv0=,92666f8caf4843c5a9b6bdb0f48f261922595683351958b0909884adf064cfb2 +github.com/dgryski/go-metro,v0.0.0-20180109044635-280f6062b5bc,h1:8WFBn63wegobsYAX0YjD+8suexZDga5CctH4CCTx2+8=,3f97b3cdeaee7b4fbf4fa06b7c52e3ee6bca461a100077892e861c6c8fc03722 +github.com/dgryski/go-sip13,v0.0.0-20190329191031-25c5027a8c7b,h1:Yqiad0+sloMPdd/0Fg22actpFx0dekpzt1xJmVNVkU0=,81d318bf94b85b240278c35d7ef6015510751e31ffa89eb6287d6d236493551e +github.com/digitalocean/go-libvirt,v0.0.0-20190626172931-4d226dd6c437,h1:phR13shVFOIpa1pnLBmewI9p16NEladLPvVylLPeexo=,7748e819d19524170969d2a470c212bb3936778ff630f833adc286e8c21e37cc +github.com/digitalocean/go-qemu,v0.0.0-20181112162955-dd7bb9c771b8,h1:N7nH2py78LcMqYY3rZjjrsX6N7uCN7sjvaosgpXN9Ow=,7530507881e53214ed3c0fb770fb3faed36a57ca6eb376bd2cec91a0e5d575a6 +github.com/digitalocean/godo,v1.11.1,h1:OsTh37YFKk+g6DnAOrkXJ9oDArTkRx5UTkBJ2EWAO38=,5d1ad5b25ad252fb1a02366087fe6e94845ec2dce64dc6e875ed3253a7e0f8ff +github.com/dimchansky/utfbom,v1.1.0,h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=,27fed73a62fcf06d4ceb28846e5d40786b7e81213aa0d1f4d840e89d25f285f7 +github.com/dimfeld/httppath,v0.0.0-20170720192232-ee938bf73598,h1:MGKhKyiYrvMDZsmLR/+RGffQSXwEkXgfLSA08qDn9AI=,ff59ff07643eccf8a166cc9693fbd18c42869e0bfcc0a9c979435847a7ae4fb1 +github.com/dimfeld/httptreemux,v5.0.1+incompatible,h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA=,031da29a128234db595fdce84301cfe5ff13b4be03c1e344cfe7daadb68559e9 +github.com/disintegration/gift,v1.2.1,h1:Y005a1X4Z7Uc+0gLpSAsKhWi4qLtsdEcMIbbdvdZ6pc=,d9a688a552dc8f5b2319325541e2bbc5c0af66b6e78273058893b259fcca5a0f +github.com/disintegration/imaging,v1.6.1,h1:JnBbK6ECIZb1NsWIikP9pd8gIlTIRx7fuDNpU9fsxOE=,209474c4c0348672c6747a7a73ff887a6d9458b67df78ff342ee3fd628156412 +github.com/djherbis/atime,v1.0.0,h1:ySLvBAM0EvOGaX7TI4dAM5lWj+RdJUCKtGSEHN8SGBg=,fe677e5c1a8bb168904c0856010bed33a770d49eda9edc6dc1b567940bf20afc +github.com/dlclark/regexp2,v1.2.0,h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=,61054c243455e034d7a81e2f6a888cab5a81056a0cc43463cb3536b42cfe7cc1 +github.com/dmotylev/goproperties,v0.0.0-20140630191356-7cbffbaada47,h1:sP2APvSdZpfBiousrppBZNOvu+TE79Myq4kkmmrtSuI=,8afdf7b2989dff361cc80e560c1bd17e5c4ad37826b5caf4b65af8e152cdc6cb +github.com/dnaeon/go-vcr,v1.0.1,h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=,8f586f95ce5567ef2ae702cf98e56a09ea0cc6171f5cd959e6fcf7502e00dabc +github.com/dnsimple/dnsimple-go,v0.30.0,h1:IBIrn9jMKRMwporIRwdFyKdnHXVmwy6obnguB+ZMDIY=,5821d521b402f93dc19f6eb332d5f4159800336f53626c6dedd99ce4c351a55a +github.com/dnstap/golang-dnstap,v0.1.0,h1:hKtRrSTEHuTmG0vCLgKU8WJkXCARoAJMDrlXHTTPBK8=,fe23fd626917c7f45ead63cef4a4bd1bb366bb30ba5873d9ee5432e79b971349 +github.com/docker/cli,v0.0.0-20191031185610-968ce1ae4d45,h1:KJ4FsevlLR30Q2H1aCACmL3CEoUTAZf16PMAJj+ofXI=,145fef54aa162edc123d514ed7a20bc14564581ad95bb6aae7294c3c08df55fd +github.com/docker/distribution,v2.7.1+incompatible,h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=,be78bc43d74873b67afe05a6b244490088680dab75bdfaf26d0fd4d054595bc7 +github.com/docker/docker,v1.13.1,h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo=,1decea9f21d4165bc134de72c51055612ff6992409cd56f3c35b7f78f3b542bd +github.com/docker/docker-ce,v0.0.0-20180924210327-f53bd8bb8e43,h1:gZ4lWixV821UVbYtr+oz1ZPCHkbtE+ivfmHyZRgyl2Y=,d670d1c5faec51ee82dbc5d479a7fca60916c1b30547994c206622ab338a735a +github.com/docker/docker-credential-helpers,v0.6.3,h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=,4dd2971b28524442b7a01e118a8040c3ab90eca50d55a7a232af514d18187324 +github.com/docker/engine-api,v0.4.0,h1:D0Osr6+45yAlQqLyoczv5qJtAu+P0HB0rLCddck03wY=,0db5d01c8401192b4eee6d2f9c34aa297d1a892f25230b470efd73f8f7ab59a4 +github.com/docker/go,v1.5.1-1,h1:hr4w35acWBPhGBXlzPoHpmZ/ygPjnmFVxGxxGnMyP7k=,fd626ee84b1eaea11c2a374fda5ed5ca8ad820bb4746ee31519efeb5038077b5 +github.com/docker/go-connections,v0.4.0,h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=,570ebcee7e6fd844e00c89eeab2b1922081d6969df76078dfe4ffacd3db56ada +github.com/docker/go-events,v0.0.0-20190806004212-e31b211e4f1c,h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=,0f654eb0e7e07c237a229935ea3488728ddb5b082af2918b64452a1129dccae3 +github.com/docker/go-metrics,v0.0.1,h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=,4efab3706215f5b2d29ba823d3991fd6e2f81c02ce45ef0c73c019ebc90e020b +github.com/docker/go-units,v0.4.0,h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=,0f2be7dce7b1a0ba6a4a786eb144a3398e9a61afc0eec5799a1520d9906fc58c +github.com/docker/libkv,v0.2.1,h1:PNXYaftMVCFS5CmnDtDWTg3wbBO61Q/cEo3KX1oKxto=,7a0c81782d38b550acc2c0ef0ce397adfc13716f483be6a47d0b97fbc6eea0d5 +github.com/docker/libnetwork,v0.5.6,h1:hnGiypBsZR6PW1I8lqaBHh06U6LCJbI3IhOvfsZiymY=,7aea42c405304c495bf159e5004674eb503eb0120eb4c5d1275fdba65d88cc53 +github.com/docker/libtrust,v0.0.0-20160708172513-aabc10ec26b7,h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=,bf1c1230a3b5c0dadb2c9366aabc99181e708369d735dc83c3eb89f597f42adb +github.com/docker/machine,v0.16.2,h1:jyF9k3Zg+oIGxxSdYKPScyj3HqFZ6FjgA/3sblcASiU=,1c13210831cafddba1abbf9ef034135233252c62927df396fee6fa0a45efcb43 +github.com/docker/notary,v0.6.1,h1:6BO5SNujR+CIuj2jwT2/yD6LdD+N9f5VbzR+nfzB5ZA=,439fd6664fb75323d78c5a362483f3375a6ac61a3dd08438a503df470a34f300 +github.com/docker/spdystream,v0.0.0-20160310174837-449fdfce4d96,h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=,70964f9eef29843634539b8d6e09c8b51ed6aa96b5deda28b7a44613327a22f2 +github.com/docker/swarmkit,v1.12.0,h1:vcbNXevt9xOod0miQxkp9WZ70IsOCe8geXkmFnXP2e0=,b9d09ff080beb0db2d4d4ebca93438dd080769266eb7aab6d5182e1ad7ba2c3a +github.com/docopt/docopt-go,v0.0.0-20180111231733-ee0de3bc6815,h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=,00aad861d150c62598ca4fb01cfbe15c2eefb5186df7e5d4a59286dcf09556c8 +github.com/documize/community,v3.2.0+incompatible,h1:ilePrhqxjc+BWpDRsXPyLyMEE1BrGlqCPMg3T577mzQ=,e9e06bdbef4500c0d2cc609164fe23bc05f8234c2c8483c8c9bc3ffffe22bbf7 +github.com/dogmatiq/dogma,v0.6.0,h1:HdJ0cTcORIxZRTB5Z7RdsBXEr18gB3so7FMIHYiAhEQ=,db91004377004aa3c5f0c462205beea995e93a0be13d7d99d3232dc03209f65c +github.com/donovanhide/eventsource,v0.0.0-20171031113327-3ed64d21fb0b,h1:eR1P/A4QMYF2/LpHRhYAts9wyYEtF7qNk/tVNiYCWc8=,2b911efc5101522ce50399cd7831ef931896541893955441168783666811a1d1 +github.com/dop251/goja,v0.0.0-20190912223329-aa89e6a4c733,h1:cyNc40Dx5YNEO94idePU8rhVd3dn+sd04Arh0kDBAaw=,485156ad52ca9651f728a6039af63f9f11c5bf49846e513635d5fa35d8d39097 +github.com/dotcloud/docker,v1.13.1,h1:jjwxeyQYDwROaGy/YEodF+srQW5hJAnNnaTcfcKoU+0=,83884e41d26b32eae2387080b245792ac8fc0200f645aef02656cb5e4b3d0595 +github.com/drone/go-scm,v1.6.0,h1:PZZWLeSHHwdc6zbSQpg9n0CNoRB+8DAINzX9X/wJifY=,e26d2bc63c53a66252ab24a1b45ced06825bb4101cbd746c581683cf39e520b6 +github.com/dsnet/compress,v0.0.0-20171208185109-cc9eb1d7ad76,h1:eX+pdPPlD279OWgdx7f6KqIRSONuK7egk+jDx7OM3Ac=,25f6bcccb4c1cf6d97ad69253a394bd0a52a633caa623d75b30729aed495a73d +github.com/dsnet/golib/unitconv,v0.0.0-20190531212259-571cdbcff553,h1:mE6azeVhLnKfk6DH3Zcg56L87yJ/uv9HZ5YJOQcPC4s=,603b60f7278fe7299f59d716da2bd287441f1321b5a663828d894e67bc274bed +github.com/duosecurity/duo_api_golang,v0.0.0-20190308151101-6c680f768e74,h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M=,75c90bdd92362e2cc36297193a543fe0cd75c07f82182940ad6158a1d470cc8b +github.com/dustin/go-humanize,v1.0.0,h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=,e01916e082a6646ea12d7800d77af43045c27284ff2a0a77e3484509989cc107 +github.com/dylanmei/iso8601,v0.1.0,h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURUI=,1e682968bfcac2115e1fd706ec6bd09a0b676d7d224514d8f8dff9cadbf87e79 +github.com/dylanmei/winrmtest,v0.0.0-20190225150635-99b7fe2fddf1,h1:r1oACdS2XYiAWcfF8BJXkoU8l1J71KehGR+d99yWEDA=,5607cb987ec0a699003eeec5952f0280792fd5db7099ca277bdfae26e93b0ef3 +github.com/eapache/go-resiliency,v1.1.0,h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=,a64ebe539335e126b30f79f0f00f39ffe083e794995500a67e0a2156b334788e +github.com/eapache/go-xerial-snappy,v0.0.0-20180814174437-776d5712da21,h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=,785264afffdcfe50573a1cb0df85ff4186e9e7e4e3a04513752f52d3da1054af +github.com/eapache/queue,v1.1.0,h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=,1dc1b4972e8505c4763c65424b19604c65c944911d16c18c5cbd35aae45626fb +github.com/eclipse/paho.mqtt.golang,v1.2.0,h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0=,d36337c4b5a2752b91bcd437bd74e0907bf6c9e6c611dab88407bcca8462e918 +github.com/edgexfoundry/go-mod-core-contracts,v0.1.33,h1:lQbLbRhymV0/QDDDGU26idZ9Kv+Q0IETn81hLpHxi68=,a7a8792a8692d64daea343577a49934be6ba64acbe114b3c24262537b5a9157f +github.com/edsrzf/mmap-go,v1.0.0,h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=,851a1d4d6e30f97ab23b7e4a6a7da9d1842f126d738f7386010c6ee7bf82518e +github.com/edwingeng/doublejump,v0.0.0-20190102103700-461a0155c7be,h1:FnUE/uuuegwvhGE9z61q9krL5km5Mnwlusq3BT06yy8=,a9cb92422f0bbdd56c80d9873a8f7af6fd2d8d8154a7a11d7cb9232d9146f07c +github.com/efarrer/iothrottler,v0.0.0-20141121142253-60e7e547c7fe,h1:WAx1vRufH0I2pTWldQkXPzpc+jndCOi2FH334LFQ1PI=,04291e6136b933fd2cdcc29f3af78090a9d678534a94823590eb63f1f318db1d +github.com/efritz/backoff,v1.0.0,h1:r1DfNhA1J7p8kZ185J/hLPz2Bl5ezTicUr9KamEAOYw=,064d92e7f3e46079d158cac717e1c9bf96a230a5f31bf28940bd4a99bb91657e +github.com/efritz/glock,v0.0.0-20181228234553-f184d69dff2c,h1:Q3HKbZogL9GGZVdO3PiVCOxZmRCsQAgV1xfelXJF/dY=,716200eb117905f4df509b7260869bb97bf8833c160d2ff1d328d01aa3874bc9 +github.com/eknkc/amber,v0.0.0-20171010120322-cdade1c07385,h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=,b1dde9f3713742ad0961825a2d962bd99d9390daf8596e7680dfb5f395e54e22 +github.com/elastic/go-sysinfo,v1.0.1,h1:lzGPX2sIXaETeMXitXL2XZU8K4B7k7JBhIKWxdOdUt8=,fe0cd64aa3ac73edbb4240dcbcb660c4ec004f07c36371be6d78543c3b215d92 +github.com/elastic/go-windows,v1.0.0,h1:qLURgZFkkrYyTTkvYpsZIgf83AUsdIHfvlJaqaZ7aSY=,e487e6f1e269766b5815c36e93614b87a185ddc33f7a6f4bf23e5ee6d0d0e3c1 +github.com/elastic/gosigar,v0.10.5,h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo=,a139252942b5ca82ddc3d9ced1daa262de0149a413149d3f0234b43dc3635acf +github.com/elazarl/go-bindata-assetfs,v1.0.0,h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=,3aa225ae5ae4a8059a671fa656d8567f09861f88b88dbef9e06a291efd90013a +github.com/elazarl/goproxy,v0.0.0-20191011121108-aa519ddbe484,h1:pEtiCjIXx3RvGjlUJuCNxNOw0MNblyR9Wi+vJGBFh+8=,6c224ac5720959a46f6d88e0b15dda732c7eb180b3103a826cf6d5459a5e112f +github.com/elazarl/goproxy/ext,v0.0.0-20190711103511-473e67f1d7d2,h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=,7244c1fe7490460503559e24e0e478540bc10481d1d8f3afd0a1f6b1a470b52f +github.com/emicklei/go-restful,v2.11.1+incompatible,h1:CjKsv3uWcCMvySPQYKxO8XX3f9zD4FeZRsW4G0B4ffE=,9befcac63629841301235124e728206a96170afd83c78b632d271acafc9acccf +github.com/emicklei/go-restful-swagger12,v0.0.0-20170926063155-7524189396c6,h1:V94anc0ZG3Pa/cAMwP2m1aQW3+/FF8Qmw/GsFyTJAp4=,07fd41dbe765b7d340df21d6353db8bef782f9b6742a93696b6f4133ef1d8955 +github.com/emicklei/proto,v1.6.15,h1:XbpwxmuOPrdES97FrSfpyy67SSCV/wBIKXqgJzh6hNw=,162ad34010e5f81ebed962a33c91ee6356e19631c7a7030bc9b173e85ca34678 +github.com/emirpasic/gods,v1.12.0,h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=,729ea0bda86bf801b61ff66eb019e5b9adc559cd217944abf10bb103fca573ee +github.com/endophage/gotuf,v0.0.0-20151124190824-3b700e20e376,h1:rPyHFhsuPZMEJAe1Oj2vpRC8277wpDJJ+aabkmlHF1A=,2cd5e6d0e748e0625e8c4a08a3b9f74e311e6654a1c5411fa3a9720f5f67cf40 +github.com/envoyproxy/go-control-plane,v0.9.0,h1:67WMNTvGrl7V1dWdKCeTwxDr7nio9clKoTlLhwIPnT4=,07b3a43081c9e1cdccb95c657cba7f483d5099f9ce07b5e3f3e28ce557687521 +github.com/envoyproxy/protoc-gen-validate,v0.1.0,h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=,ec5261f3bbc426d71e2be4c76063ba12460c5d27845d630763e9e911ec4768af +github.com/eoscanada/eos-go,v0.8.10,h1:QUwHRBHEFag/qyW4PR2S9++0se0V4LjPLk1/KsNtXlo=,f1c48e793d1c7864288871a944af4b4ee3363ad6ae5298e9c2f9f42202e6d77c +github.com/erikstmartin/go-testdb,v0.0.0-20160219214506-8d10e4a1bae5,h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=,471feb426b2a7ec1df29cc21c66aef34c9e7aabea751328644d1362593983d21 +github.com/ernesto-jimenez/gogen,v0.0.0-20180125220232-d7d4131e6607,h1:cTavhURetDkezJCvxFggiyLeP40Mrk/TtVg2+ycw1Es=,1f3030cfc89653ba791ae312b19e420dc8eaf1bef51f59dca6aa390f3cd1f3d0 +github.com/etcd-io/bbolt,v1.3.3,h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=,6630d7aad4b10f76aea88ee6d9086a1edffe371651cc2432edfd0de6beb99120 +github.com/ethantkoenig/rupture,v0.0.0-20180203182544-0a76f03a811a,h1:M1bRpaZAn4GSsqu3hdK2R8H0AH9O6vqCTCbm2oAFGfE=,8559344c496621c06b612453de587e8e4c45c0fbc348a955f8eda7ea2b3d09c8 +github.com/ethereum/go-ethereum,v1.9.6,h1:EacwxMGKZezZi+m3in0Tlyk0veDQgnfZ9BjQqHAaQLM=,778c9bf77dd96bfaf5c3ea84498611490999782fb37edf8257680e27dd8976e8 +github.com/euank/go-kmsg-parser,v2.0.0+incompatible,h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY=,43cadfa5ab226f89ca7a715add32ba23c554a5dfafd3a55449856a6b7012f946 +github.com/evanphx/json-patch,v4.5.0+incompatible,h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=,5508e810685a5081a3e880aeb24e501bd87920241baa317bfb5f3946b4fa417c +github.com/exoscale/egoscale,v0.18.1,h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9EZaI=,8cb4f10504b54d31c71bc4a670171a074f7abbab67d939fd404b62ad36cb6aed +github.com/facebookgo/atomicfile,v0.0.0-20151019160806-2de1f203e7d5,h1:BBso6MBKW8ncyZLv37o+KNyy0HrrHgfnOaGQC2qvN+A=,3c9bdee73452cc12c2936b4050d638d36302a958091ceb49c45ffbaff8954218 +github.com/facebookgo/clock,v0.0.0-20150410010913-600d898af40a,h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw=,5d6b671bd5afef8459fb7561d19bcf7c7f378da9943722d36676735b3c6272fa +github.com/facebookgo/ensure,v0.0.0-20160127193407-b4ab57deab51,h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=,a96c69c2b5902e0383139ee7089877a5ae2ddcd4eba42a595d13b570907d3fdc +github.com/facebookgo/freeport,v0.0.0-20150612182905-d4adf43b75b9,h1:wWke/RUCl7VRjQhwPlR/v0glZXNYzBHdNUzf/Am2Nmg=,0f717d7eb52e276aec2138a971b091cd04da95826c8f451a20e8e78c4bb8f915 +github.com/facebookgo/grace,v0.0.0-20160926231715-5729e484473f,h1:0mlfEUWnUDVZnqWEVHGerL5bKYDKMEmT/Qk/W/3nGuo=,79f9f73ef925d457d2b70d37b12c3cec97a2e84e73a932397d2f569ec8702ee7 +github.com/facebookgo/httpdown,v0.0.0-20160323221027-a3b1354551a2,h1:3Zvf9wRhl1cOhckN1oRGWPOkIhOketmEcrQ4TeFAoR4=,dbbccf963238c5f80c54edb19aeb016f486f42dcd922fc0be5b832af9449ca4b +github.com/facebookgo/inject,v0.0.0-20161006174721-cc1aa653e50f,h1:jK9r9Ofgc/Yzdlod77G23LfYtwqAmkQCZ9MaP6779OI=,6292702ff520e1fb14231f29bb2639d8f39edc08de479d76757ad97dafbb9174 +github.com/facebookgo/stack,v0.0.0-20160209184415-751773369052,h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=,0afd18a8394caa29e94bd58a42e0d2be07939f9daf190a9ba2a947f9cbd4ba1a +github.com/facebookgo/stats,v0.0.0-20151006221625-1b76add642e4,h1:0YtRCqIZs2+Tz49QuH6cJVw/IFqzo39gEqZ0iYLxD2M=,d87443825721dc1dd5c358cd9e55b917ee1c3b6b10ab9557375f59d563b628cb +github.com/facebookgo/structtag,v0.0.0-20150214074306-217e25fb9691,h1:KnnwHN59Jxec0htA2pe/i0/WI9vxXLQifdhBrP3lqcQ=,3a9c84e9dc2b9960f1de3cc7a61d91fe2978e64e4e4859a9383259092ec91c5e +github.com/facebookgo/subset,v0.0.0-20150612182917-8dac2c3c4870,h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=,bb18c678177e1aaaae209a2de9c28b5b7acc34e58fe00517b847a9460bd42df2 +github.com/farsightsec/golang-framestream,v0.0.0-20190425193708-fa4b164d59b8,h1:/iPdQppoAsTfML+yqFSq2EBChiEMnRkh5WvhFgtWwcU=,084f0ac3684b180e3d87db3e7b36a412c750397fbf009579e126c304528c1738 +github.com/fatih/camelcase,v1.0.0,h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=,54664f64f1f24097b80c64b9f606cbe8d8bc410a755ce6cda4f45e46f1141984 +github.com/fatih/color,v1.7.0,h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=,6036f0b31167280b696b5efb43603e71bce31420fb3428afdf74a68bb3a3ebef +github.com/fatih/structs,v1.1.0,h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=,a361ecc95ad12000c66ee143d26b2aa0a4e5de3b045fd5d18a52564622a59148 +github.com/fatih/structtag,v1.0.0,h1:pTHj65+u3RKWYPSGaU290FpI/dXxTaHdVwVwbcPKmEc=,347fce3911900f5947735c12ccb4c6fbe0199c6df040bcaa4d74a8587af896d0 +github.com/fd/go-nat,v1.0.0,h1:DPyQ97sxA9ThrWYRPcWUz/z9TnpTIGRYODIQc/dy64M=,bdf011af97da57ef3c58a091ae760eb885a6322faa3539d3c37bf76d4fff536a +github.com/fernet/fernet-go,v0.0.0-20180830025343-9eac43b88a5e,h1:P10tZmVD2XclAaT9l7OduMH1OLFzTa1wUuUqHZnEdI0=,a484a3172222095507a7f1901a91ab741c28278ea6b878c21c1151c0fd40f46d +github.com/flosch/pongo2,v0.0.0-20190707114632-bbf5a6c351f4,h1:GY1+t5Dr9OKADM64SYnQjw/w99HMYvQ0A8/JoUkxVmc=,814b52f668d2e2528fe9af917506cda4894d22c927283cfb8aaf6857503dfc5a +github.com/flynn/go-shlex,v0.0.0-20150515145356-3f9db97f8568,h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=,ea68a1d391e59ebc04ce986b88e000327bb141e5e8e80ef93af950bca42bb4cc +github.com/fogleman/gg,v1.3.0,h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=,792f7a3ea9eea31b7947dabaf9d5a307389245069078e4bf435d76cb0505439c +github.com/forestgiant/sliceutil,v0.0.0-20160425183142-94783f95db6c,h1:pBgVXWDXju1m8W4lnEeIqTHPOzhTUO81a7yknM/xQR4=,bedd47c23670847642576777cc8b53b9dd8a5a8e7b0a6f2299ebc6fa3b7b6f00 +github.com/fortytw2/leaktest,v1.3.0,h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=,867e6d131510751ba6055c51e7746b0056a6b3dcb1a1b2dfdc694251cd7eb8b3 +github.com/francoispqt/gojay,v1.2.13,h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=,f41e3e4f3086400448dbce1c06c59f5848a6c5983e5466689965e3a2cabcba7c +github.com/frankban/quicktest,v1.5.0,h1:Tb4jWdSpdjKzTUicPnY61PZxKbDoGa7ABbrReT3gQVY=,515b5b2b9320b2982193ad6bd118907aaab9ff62189870e00be459cc4097073c +github.com/fsnotify/fsnotify,v1.4.7,h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=,1d09ad8f3dc41cb6e0288023b47272c1c9393ca411e48f4b5009bca6662dc3ad +github.com/fsouza/fake-gcs-server,v1.2.0,h1:FZUL/EJlyAlHxpUWZs23ae4zNwBwmHM1p5TykkoP85A=,83b547a0780693f154c30137b1eeaf0c0e9628798ae4b7e1d74ebfb8efaf61fc +github.com/fsouza/go-dockerclient,v1.5.0,h1:7OtayOe5HnoG+KWMHgyyPymwaodnB2IDYuVfseKyxbA=,c7025b816e0ba28041a88b1063003f4e31097346d06cf69811f9d55505d3d46c +github.com/fullsailor/pkcs7,v0.0.0-20190404230743-d7302db945fa,h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU=,ba36a8fc855d6eecef329d26f8e82132e38d45d06f79f88d3b0bde6d718c8fb2 +github.com/fuyufjh/splunk-hec-go,v0.3.3,h1:7PLVIODblK9FXfuAy8iPZg0lcw1YNzSQHfC+0NYgUxU=,9517f63386f64e0dceca9352f45eb7f160452682a07fa04d3c1ff90eb19ac83d +github.com/gabriel-samfira/sys,v0.0.0-20150608132119-9ddc60d56b51,h1:rUp9t/FbeJM3R3BSYkJfViN3CNQcmk44H20SqkJ/y+k=,1be262d101bd9079bb859639ad6d5eaee80646b6db0fcbeb7146d9381949d2a8 +github.com/gammazero/deque,v0.0.0-20190130191400-2afb3858e9c7,h1:D2LrfOPgGHQprIxmsTpxtzhpmF66HoM6rXSmcqaX7h8=,a1fe4ec3258f68685ee45b68e1d9188d79726af46a1b93281cf11ddc6045a864 +github.com/gammazero/workerpool,v0.0.0-20190406235159-88d534f22b56,h1:VzbudKn/nvxYKOdzgkEBS6SSreRjAgoJ+ZeS4wPFkgc=,cbb92fdf8d457e27923dc6515af4458a55af932ccf468415c8b36bf49845fc00 +github.com/garyburd/go-oauth,v0.0.0-20180319155456-bca2e7f09a17,h1:GOfMz6cRgTJ9jWV0qAezv642OhPnKEG7gtUjJSdStHE=,be051ba0d52eaced1c1985ebdf2dece3f7127ad392645b42fd06c2af9c9caea2 +github.com/garyburd/redigo,v1.6.0,h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc=,68f0d2b454f7a9a000c3335fc0f409123637e4711c6461a4c75e2f128f68f283 +github.com/gavv/monotime,v0.0.0-20161010190848-47d58efa6955,h1:gmtGRvSexPU4B1T/yYo0sLOKzER1YT+b4kPxPpm0Ty4=,c97324768edc8170e05b8925b0551778909c8e15817d4327ac405a4e0b6071f4 +github.com/gcash/bchd,v0.14.7,h1:n3gMXCT4VhU/emiCq61kmKBPADLxBzpX5IlXPnGuR2c=,871644f504d6c3f19dcfc8a7a6e6aa623e6642275a48dfffe770ec61368c2032 +github.com/gcash/bchlog,v0.0.0-20180913005452-b4f036f92fa6,h1:3pZvWJ8MSfWstGrb8Hfh4ZpLyZNcXypcGx2Ju4ZibVM=,d400c8e944edf2a67f46e75335f55c14170c523691804ea71e1a348ad45bc7e7 +github.com/gcash/bchutil,v0.0.0-20191012211144-98e73ec336ba,h1:KVa96lSrJGMYZ414NtYuAlbtCgrmW9kDnjvYXcLrr5A=,7b829a35d22ead0ee82d8a98b1e06da5e63fd07b2798fce8ba87c8da670ef04a +github.com/gcla/gowid,v1.0.0,h1:78Xf5G9+lb4/g3KCB3hX8UJ8VorymMH5PXu9Npvwf8s=,eaa7e0b7bb0912c6b24c98dee0073a2de754c24e1347ce7c5bfc63397ccf0fa6 +github.com/gdamore/encoding,v1.0.0,h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=,638a9832e2f62d118d7c511d86bdae1622a51f331de48a01d929fd24ebe6a2a6 +github.com/gdamore/tcell,v1.3.0,h1:r35w0JBADPZCVQijYebl6YMWWtHRqVEGt7kL2eBADRM=,97c1e828ff9de0cef3a5bbdb3f3def8a351ad6ca65a780d4dd4141b0ee23c88e +github.com/genuinetools/pkg,v0.0.0-20180910213200-1c141f661797,h1:SGpZXDd/CFeDIY4Rq5cFO8K/uqDblHUxjlzOmjFpvRg=,c15cbe95e0a7e38cc0a790b0098170c103ba84d56e7cbaf744a6df10c00efa45 +github.com/genuinetools/reg,v0.16.0,h1:ZhLZPT+aUGHLfy45Ub5FLWik+3Dij1iwaj8A/GyAZBw=,a505ff5357d6095540c89ee27d207a3a4dc7c73840fb6bc9a2f0f3a81e498341 +github.com/gernest/wow,v0.1.0,h1:g9xdwCwP0+xgVYlA2sopI0gZHqXe7HjI/7/LykG4fks=,b49d5efc34e19469e7319df09b35438de307ba7cd8c9333ecba190f457ca8e22 +github.com/getgauge/common,v0.0.0-20190514095629-619e107433ce,h1:/ofMj8gIhPYdb/JEXKj8iYe5Yxl3mrK8YA7yl/06t6Y=,04ab4fb7e8dcf693c3b79028693130cd51fe54f5a16f12622975a7c3eb7705f7 +github.com/getlantern/context,v0.0.0-20190109183933-c447772a6520,h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=,27515ae761018c4cfc83043194904170bef0cac037c48ff96fc497502b9bab14 +github.com/getlantern/errors,v0.0.0-20190325191628-abdb3e3e36f7,h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So=,a48d7684463e8c496fea4a2595ca71012c3b222bc77de7c2ddfbe78bc4595ac5 +github.com/getlantern/fdcount,v0.0.0-20170105153814-6a6cb5839bc5,h1:8Q9iN/V24EG01IgXEKVScth/rTXpplBxCYio/yIKtUw=,b24c26d5ede197fd6b7f981cf5db300124e22f48667942c948a9750f7a908c94 +github.com/getlantern/golog,v0.0.0-20190830074920-4ef2e798c2d7,h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk=,1eeabfbc56105f3d751e1947405f5296db5ded7e25900209fe7327f1b5d785e6 +github.com/getlantern/hex,v0.0.0-20190417191902-c6586a6fe0b7,h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0=,ea5a13f98a82c1919c59b655de531cbb35ac7dfff3c99072b43b8bfd1c29b774 +github.com/getlantern/hidden,v0.0.0-20190325191715-f02dbb02be55,h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc=,c901f2e702114d6268446a381a27737c6123e50191197fd84f17b339238191b4 +github.com/getlantern/idletiming,v0.0.0-20190529182719-d2fbc83372a5,h1:laM1s/bxUH8xbbC9TBGWsOc7A0KCAPZMa4pdwO5e6Vw=,35de51b383e926042d3f8f4859e2d961582cf9964d3b7bb513ac4733cc43162f +github.com/getlantern/mockconn,v0.0.0-20190403061815-a8ffa60494a6,h1:+aO65ByJw74kV8vXqvkj49P5RtIqyUObyeRTIxMz218=,a4a1ccdc9ec68dea571d9603d4a36150b6ccaea447ca88965e088ff0b9eeaa0d +github.com/getlantern/mtime,v0.0.0-20170117193331-ba114e4a82b0,h1:1VNkP55LM/W2IwWN+qi+5X3gZcEQHfj8X9E+FNxVgM4=,5af0b20838a808b86a2a9c87c254d47185d38d5935780dade3bc7a54dc2880f4 +github.com/getlantern/netx,v0.0.0-20190110220209-9912de6f94fd,h1:mn98vs69Kqw56iKhR82mjk16Q1q5aDFFW0E89/QbXkQ=,cb386d0527fb6f549fa0266c770a68d7d83a88bab2194d25b55355f59198fdf0 +github.com/getlantern/ops,v0.0.0-20190325191751-d70cb0d6f85f,h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA=,321694d3d2f31415653a7b9d97a4a701f36f10ccfbbdb94449f1211137d6f215 +github.com/getsentry/raven-go,v0.2.0,h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=,eaffe69939612cd05f95e1846b8ddb4043655571be34cdb6412a66b41b6826eb +github.com/gf-third/mysql,v1.4.2,h1:f1M5CNFUG3WkE07UOomtu4o0n/KJKeuUUf5Nc9ZFXs4=,14a08134ce02bd0d07667da91a89c9098d18bad8c790414e37aba906895a5a3e +github.com/gf-third/yaml,v1.0.1,h1:pqD4ix+65DqGphU1MDnToPZfGYk0tuuwRzuTSl3g0d0=,6354a95d7faa222d2e653485bc9dd555aad61a75eb5a5f970de531391ed77a2f +github.com/ghetzel/go-defaults,v1.2.0,h1:U1T64bxhBc6nVZ68QXch1hoHq43h6isqgbvG7kxY9Uc=,f339e441d08af3af184a21f518227db7c705851be82f3fcea611e762ebb633a1 +github.com/ghetzel/go-stockutil,v1.8.6,h1:VgqpePUGGXMHjgArUH5mSAYFC35aiFgkU/TdTU/ts80=,aa0cce06af82b7d1f98a20deaafd6997fa7c3d36fba9a204a34e5d91a2096fa0 +github.com/ghetzel/testify,v1.4.1,h1:wpJirdM+znAnxWruGDBdIys5aU+wGJHNUTkgEo4PYwk=,90206efc10ad71a33bf314ef768d16c6186d23ccb5aa8172663437d497dbfdd7 +github.com/ghetzel/uuid,v0.0.0-20171129191014-dec09d789f3d,h1:YVJe7KwVYazt90hCc/q2dYJVS3062AY6QdT6iHd+Kh8=,924f39fe83589fa269e652c8ca4f7b0dbc59023baada8a55c24692fe5223b67a +github.com/ghodss/yaml,v1.0.1-0.20190212211648-25d852aebe32,h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew=,9771720da98bbdd80dacdefb47b9a0e36faa75caa4745149d150325ba5390e4b +github.com/gin-contrib/gzip,v0.0.1,h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=,e994ecc5881938978d6d031e3d0c1bc5968bfe5de2a307aed7c63aecba459ecd +github.com/gin-contrib/sse,v0.1.0,h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=,512c8672f26405172077e764c4817ed8f66edc632d1bed205b5e1b8d282816ab +github.com/gin-gonic/gin,v1.4.0,h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=,b9bc661bf658179d53fee9e7c587eba4df8326d0c26ad29f785739a78313fc4b +github.com/glacjay/goini,v0.0.0-20161120062552-fd3024d87ee2,h1:+SEORW3KptcFnlhTbn7N0drG3AFnrcmBDWDyQ3Bt06o=,061319068788a9eeef67d4e5cf84a87c4649005aaa4f37c983a868c357e3df3c +github.com/gliderlabs/ssh,v0.2.2,h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=,f9f12d766ceeab9e2134504520de75819d1eeb6733b8b619b7bcd4aac4cca983 +github.com/globalsign/mgo,v0.0.0-20181015135952-eeefdecb41b8,h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is=,c07f09e0c93e6410076edfd621d2decbd361361c536c3e33ba097fa51708f360 +github.com/glycerine/go-unsnap-stream,v0.0.0-20180323001048-9f0cb55181dd,h1:r04MMPyLHj/QwZuMJ5+7tJcBr1AQjpiAK/rZWRrQT7o=,9a66d6f9bb1a268f4b824d6fe7adcd55dc17ed504683bdf2dbf67b32028d9b88 +github.com/glycerine/goconvey,v0.0.0-20190315024820-982ee783a72e,h1:SiEs4J3BKVIeaWrH3tKaz3QLZhJ68iJ/A4xrzIoE5+Y=,344fb699344a5ab09464c0283a65402ae0fe6bd6fac7d40e9c4d403cf4a7714f +github.com/gmallard/stompngo,v1.0.12,h1:uj1Bl9o+dqn0qSR33xHmaKw21W5LzhWo4Q4hS1MCpQU=,88498e4da4e0f7f3923d758a464d53f550921617b1047643def2a973c86dfd03 +github.com/go-aah/forge,v0.8.0,h1:sk4Z523B9ay3JQF4At97U7kecB5yTIm0J2UM/qRVXbQ=,e883adcfb380d6187de84c59a0f8bb3b34931487151873d7a326a1b4df556e48 +github.com/go-acme/lego,v2.7.2+incompatible,h1:ThhpPBgf6oa9X/vRd0kEmWOsX7+vmYdckmGZSb+FEp0=,1a597873ff61c0fbdab6b4f1027141d2e8dbe739bd2018473559bec954f3e651 +github.com/go-acme/lego/v3,v3.1.0,h1:yanYFoYW8azFkCvJfIk7edWWfjkYkhDxe45ZsxoW4Xk=,fbb3cfe2619281c3ccd456b213b5f8c7bf695f82ecac6c97f747dc4159dfe4b2 +github.com/go-ble/ble,v0.0.0-20190521171521-147700f13610,h1:eWay3GzFqTJUEYN1BrbqdDTFeFUGmYLps8SQkn1D7Yo=,a5fb6440935dd7ef8bb3569bc7260bd1ad44e01d41bbb684dbb96cc677fb2234 +github.com/go-chassis/foundation,v0.0.0-20190621030543-c3b63f787f4c,h1:p+Y6yq7RwHmYjEr/vwdVYGacBqFCc2lPQfNRIC3vRIs=,db38c108455e57b3f8f062c22872554d5af9dfa03a723c9fea263a009f3002e6 +github.com/go-chassis/go-archaius,v0.24.0,h1:ubNgs3Rv067PI7t37ZJoIMaPPHIBWV+ni/e7XAdW1hU=,37b0c60692eaed91abd3d2c6a0fc9366a54882f3a6b5ef81f3cc20d14882a13d +github.com/go-chassis/go-chassis,v1.7.3,h1:7fcfaE9Ij+oBbf2lHoHHIvxT9objtt1EHpwRPBUkDhw=,38f8393558528b0212674268f6dc507d5db716fc5745eff09bccf1cd98b86eb7 +github.com/go-chassis/go-chassis-config,v0.14.0,h1:OnM9sx2GalDC7vEIhPecRpQlVa8hz10NOB41+9tii5A=,afc7506eec8591a5ccbb08f073ba19312bc03d87ec15c1532f5daba02f090e00 +github.com/go-chassis/go-restful-swagger20,v1.0.1,h1:HdGto0xroWGK504XN0Um7JBc0OPMHDlWwedkd2mTGII=,2c41388f71dc766088fc3e47e91a2f8c2d7936e40f6a64afff53a12ef73e0d05 +github.com/go-chassis/paas-lager,v1.0.2-0.20190328010332-cf506050ddb2,h1:iORWPbIQ81tJPKWs9TNvcjCQnqvyTlL41F9ILgiTcyM=,a74c06554cf6835e98c4fa548a4aa3dcc317ca93567af893b89a4dba88b783af +github.com/go-chat-bot/bot,v0.0.0-20191022130543-3da6cae45477,h1:JfUELmxvEz/MXI3/iSn2UcB/5CCAvMsxKi88j783ssk=,a059cd1d050747bd0adcd3d4ba91e12b0ace2c038187484726c3d551169d9fa4 +github.com/go-chat-bot/plugins,v0.0.0-20181006134258-491b3f9878d6,h1:qNYjVQnDwznjLk+OnNdczA5SXwEa/RwjPTZSQCKofF4=,b19527108aef487fa1f4856e354f4777644a574248cc7e891bacf1bfb38bd12d +github.com/go-chat-bot/plugins-br,v0.0.0-20170316122923-eb41b30907dc,h1:v/poG4Y4O/z1cUm2cWxiIkFFgRsT3Fe1u1A33evx89g=,6b613e62d3f389f3d6f8f262903bc31c4f1eb4b3ca8d192606f78199b1af0d43 +github.com/go-check/check,v0.0.0-20190902080502-41f04d3bba15,h1:xJdCV5uP69sUzCIIzmhAw6EKKdVk3Tu48oLzM86+XPI=,93bbc1f982dd553e279fb4c7fbc060032096e2b5d0537385ae80247492a6433e +github.com/go-chi/chi,v4.0.2+incompatible,h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs=,25c94ccd43f18002c2dd07e87da1dc393ff87d615441e559bda425ea0979715b +github.com/go-cmd/cmd,v1.0.5,h1:IK23uTRWxq6UJnNWp8nKO7mVCwnPfbaxA2lhzEKfNj0=,2623aa43dbf68c24362bcfb7a216b83c2e7473d4a3e49e7955c3fa5f28b4974c +github.com/go-delve/delve,v1.3.2,h1:K8VjV+Q2YnBYlPq0ctjrvc9h7h03wXszlszzfGW5Tog=,b8a250f2b3ef87da34fbfc655bb23a051b43672bea7a8abc4e083a2b214faf09 +github.com/go-errors/errors,v1.0.1,h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=,bdbee3143e1798eadff4df919479c28ec2d3299a97d445917bc64d6eb6a3b95a +github.com/go-gl/gl,v0.0.0-20181026044259-55b76b7df9d2,h1:78Hza2KHn2PX1jdydQnffaU2A/xM0g3Nx1xmMdep9Gk=,499822d1b3bcc34b82df0fcc13ac9a0ea273c5d68b3e183e18fa76dab9793954 +github.com/go-gl/glfw,v0.0.0-20190409004039-e6da0acd62b1,h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=,96c694c42e7b866ea8e26dc48b612c4daa8582ce61fdeefbe92c1a4c46163169 +github.com/go-gl/mathgl,v0.0.0-20190713194549-592312d8590a,h1:yoAEv7yeWqfL/l9A/J5QOndXIJCldv+uuQB1DSNQbS0=,39948d90a5672c7866b5b1c01e9e8ce6c80c099306ed80e9e138350840f82110 +github.com/go-ini/ini,v1.49.0,h1:ymWFBUkwN3JFPjvjcJJ5TSTwh84M66QrH+8vOytLgRY=,4820559fd3640c6b5361a7077e8b5c1a4318a06a59df7a095cbf96514d46d432 +github.com/go-kit/kit,v0.9.0,h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=,f3da9b35b100dd32e7b10c37a0630af60d54afa37c61291e7df94bc0ac31ed03 +github.com/go-ldap/ldap,v3.0.3+incompatible,h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk=,4197e5fbebc7a1805be236cf75dea301f0b8e15a857e2373653b76157c649f93 +github.com/go-log/log,v0.1.0,h1:wudGTNsiGzrD5ZjgIkVZ517ugi2XRe9Q/xRCzwEO4/U=,ec5845d33a6d7ede81970833cfc3179d53b99019da1ebffef5e71005ff94be43 +github.com/go-logfmt/logfmt,v0.4.0,h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=,d678198dc0eeaed28736e0d71b919a0bd98501b7275c69a7917122f6de9e0d1c +github.com/go-logr/logr,v0.1.0,h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=,4c14b7c05eaa48b7f8dbf2ca38c3603dce446f4184a4c0af2f569b046d66201e +github.com/go-logr/zapr,v0.1.0,h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54=,7b60c74f722b8f215711503dd63576845987eff81ef5f9dc052fc9158d1c57e2 +github.com/go-macaron/binding,v1.0.0,h1:ILEIP1e9GaXz//fZIl1zXgHVbM9j1SN89aTGOq8340Y=,3887f50d442cd8f9eeeb0e7710c7cba41c185d8e5a82404ff33e7cbd4e16d0c7 +github.com/go-macaron/cache,v0.0.0-20151013081102-561735312776,h1:UYIHS1r0WotqB5cIa0PAiV0m6GzD9rDBcn4alp5JgCw=,a854b7844fff9ec69025db12a2b03834a2eac570a366962c4eb83984813a9fdb +github.com/go-macaron/captcha,v0.0.0-20190710000913-8dc5911259df,h1:MdgvtI3Y1u/DHNj7xUGOqAv+KGoTikjy8xQtCm12L78=,fb1c643c72ba9ef2c5d613e324e47dbb17ce45a28cbee8cb540ea48a0b3d6a23 +github.com/go-macaron/cors,v0.0.0-20190418220122-6fd6a9bfe14e,h1:auESkcVctNZnNl4EH0TuoCSJMJ7Q7ShU8FS6lDEsAC4=,0f3043631d54efca5615fe7ed819523bbe0c18726ce9e4b0cdc0ef2879aa6044 +github.com/go-macaron/csrf,v0.0.0-20180426211211-503617c6b372,h1:acrx8CnDmlKl+BPoOOLEK9Ko+SrWFB5pxRuGkKj4iqo=,90b5cbd86ff3708d41be70ad3cde77fdedd5ef485b960cc3a9ffea6f0a14902c +github.com/go-macaron/gzip,v0.0.0-20191101043656-b5609500c6fc,h1:z3gfrCJUPhdRHtd8kftnNBzI5ayZ1zQhWARPeL83JNQ=,dfcc1200b66bcb581c6984da9fa4aefc92facc3a07d182c7c37f0978b41b868f +github.com/go-macaron/i18n,v0.0.0-20160612092837-ef57533c3b0f,h1:wDKrZFc9pYJlqFOf7EzGbFMrSFFtyHt3plr2uTdo8Rg=,6c1d5fe7ed23e05ca1af7462e6deac2d993ddacd099ad794faad5c685337742d +github.com/go-macaron/inject,v0.0.0-20160627170012-d8a0b8677191,h1:NjHlg70DuOkcAMqgt0+XA+NHwtu66MkTVVgR4fFWbcI=,666bb04a5df1271326b4fcdbbdc3276400ae7e54f4ed6233792cd6e519676491 +github.com/go-macaron/session,v0.0.0-20191101041208-c5d57a35f512,h1:7ndsXTX42iYHryQz98zUsBJfStJ0kXFKgDrPmRvR400=,3581a7eb19a2a60d41aba7e85afa576c35a97659e162b83292ff67396f899845 +github.com/go-macaron/toolbox,v0.0.0-20180818072302-a77f45a7ce90,h1:3wYKrRg9IjUMfaf3H0Hh7M5Li9ge79Y7aw2yujHa2jQ=,43f2a06502408404c3b1231c3642693632cf20bc4f2cb45881bd2292b1eed714 +github.com/go-martini/martini,v0.0.0-20170121215854-22fa46961aab,h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk=,0561a4dadd68dbc1b38c09ed95bbfc5073b0a7708b9a787d38533ebd48040ec2 +github.com/go-mesh/openlogging,v1.0.1,h1:6raaXo8SK+wuQX1VoNi6QJCSf1fTOFWh7f5f6b2ZEmY=,3606bad571f959cc24382381f7d50fb321819958df37911f6ad6aa5ac3e02181 +github.com/go-ole/go-ole,v1.2.4,h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=,c8b3ef1187d2d7dbfddc4badefcc992c029cd377ae07bff2fa05ec8972836612 +github.com/go-openapi/analysis,v0.19.5,h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOXdfYzI=,22e5ff3f88802059aa86835d8f7c25386afed1159d4e951ef0f87ef62ab4a253 +github.com/go-openapi/errors,v0.19.2,h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY=,e02e448e5a2c1ff2a011f74d41d505a2f32b369551064940630d6660c600bf3d +github.com/go-openapi/inflect,v0.19.0,h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=,fbcca36e347a2f560f50ac1c9c63f7d6cd97c8dff9800f08f370b5ce09b77c57 +github.com/go-openapi/jsonpointer,v0.19.3,h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=,1fe6122c9c9d10837439398976a2ff55e8ed905fa7e4a66f3fb0e857c6e06582 +github.com/go-openapi/jsonreference,v0.19.2,h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=,00b2457c2d091a9817f91f55655a334bed8f75b2d6499ba9192f12564dd51dd9 +github.com/go-openapi/loads,v0.19.4,h1:5I4CCSqoWzT+82bBkNIvmLc0UOsoKKQ4Fz+3VxOB7SY=,adffcd0e2900bf0cca893e6bf014db55ebf161476367ac4dd365f8481c12616f +github.com/go-openapi/runtime,v0.19.7,h1:b2zcE9GCjDVtguugU7+S95vkHjwQEjz/lB+8LOuA9Nw=,4017d9c69d9d2789d0a3b50c6af509831c0f24bfc545f1b43224df2fc5194dbd +github.com/go-openapi/spec,v0.19.4,h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=,7c12cf07de1b65175474fdde12110716ab237fa862694e4e5051eb15541a964e +github.com/go-openapi/strfmt,v0.19.3,h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA=,07b9c9b2da9dffc0a830e6536b705282fd17023fe8d04aa909fe1e4e3b6306f5 +github.com/go-openapi/swag,v0.19.5,h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=,54aec6bdc63d1d6609c32b140fe74d099f8b9628d362689556537506724eaeda +github.com/go-openapi/validate,v0.19.4,h1:LGjO87VyXY3bIKjlYpXSFuLRG2mTeuYlZyeNwFFWpyM=,2b1b2612db93ed3fb411cc798150821af5c031b120097bbe6578dc4ce2d6d1df +github.com/go-playground/locales,v0.13.0,h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=,9c4b65273e135b1bdb9bafc7c0b5180a6c5936f54edecbc8807c57a9d107c6b9 +github.com/go-playground/overalls,v0.0.0-20180201144345-22ec1a223b7c,h1:3bjbKXoj7jBYdHpQFbKL2546c4dtltTHzjo+5i4CHBU=,7972d7c49470ee2e187868b30d3157ca58201f50a934caa75ce4d5b134a2a644 +github.com/go-playground/universal-translator,v0.16.0,h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=,316fba5fa26a586e39fc11698c16e67edabd122efe26f7fff71091a00a59883a +github.com/go-redis/redis,v6.15.6+incompatible,h1:H9evprGPLI8+ci7fxQx6WNZHJSb7be8FqJQRhdQZ5Sg=,e277bbc2acb8462aca5e20ef7569a733501bc765f65303a6e5153a86e6e3090c +github.com/go-sourcemap/sourcemap,v2.1.2+incompatible,h1:0b/xya7BKGhXuqFESKM4oIiRo9WOt2ebz7KxfreD6ug=,1bdaec84a31896eee149acb563f8af0b3ce7899d916383e0b597d6b480b6a622 +github.com/go-sql-driver/mysql,v1.4.1,h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=,f128045df19d340743a155ef282116130d27e27cbc62de160b6072c751b435ba +github.com/go-stack/stack,v1.8.0,h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=,78c2667c710f811307038634ffa43af442619acfeaf1efb593aa4e0ded9df48f +github.com/go-swagger/go-swagger,v0.20.1,h1:37XFujv7lYHLOKawfzLDg4STwwgB5zhPjodN33asJto=,79cc2c57c4e9d03a9399577b942eface46073ee6fa289b86651f1c5d0c513484 +github.com/go-swagger/scan-repo-boundary,v0.0.0-20180623220736-973b3573c013,h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=,51aed4b67bce9d988d64ca6be9de2169f709a29d5ea83e78ffb1c2432b346ec6 +github.com/go-telegram-bot-api/telegram-bot-api,v4.6.4+incompatible,h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU=,a0d2549e07c67e066337cc6eadd8be2a961d13b493d4325603010d4e35e519df +github.com/go-test/deep,v1.0.3,h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=,d199ce762552766bd3baf37ae4b0255bb6a6fecf144e8ae5fa3a94f1ce30a180 +github.com/go-xorm/builder,v0.3.4,h1:FxkeGB4Cggdw3tPwutLCpfjng2jugfkg6LDMrd/KsoY=,81028f69e261c29566c24f4717458d04dbe92aebc4eb93a41c1cfeef13b7c5dd +github.com/go-xorm/core,v0.6.0,h1:tp6hX+ku4OD9khFZS8VGBDRY3kfVCtelPfmkgCyHxL0=,8a8c43c039422f38e1775a835bda46e62f4a055b4b38d57967c0e7a6c9b21d23 +github.com/go-xorm/sqlfiddle,v0.0.0-20180821085327-62ce714f951a,h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=,e539a37b8fb0d23c21e9eb1fe34db0ffcf19e5e4ae3d3b7049bb23c722c4b382 +github.com/go-xorm/xorm,v0.7.9,h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0=,8836904c60cf227804fc843c707cd3e99122b95a97801d09dd2bddce4ed5a29f +github.com/go-yaml/yaml,v2.1.0+incompatible,h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=,842989ea2e54ba8e4ef49cca914a5cd37176c44ccd3bb3e8c44fcbc10cb7832e +github.com/gobuffalo/attrs,v0.1.0,h1:LY6/rbhPD/hfa+AfviaMXBmZBGb0fGHF12yg7f3dPQA=,06c6c210a26c85ae291efe9d54cab9cab26fd1453f4f48962e04c89760e775d0 +github.com/gobuffalo/buffalo,v0.15.0,h1:VsxIcfJaDm4u2UirLHGgMfQpfHVwJP3JoDmGyeeNnc0=,f4553c8809a6764cefac8eefce9a868a42ee7538bdef4eadfcc06075b865a087 +github.com/gobuffalo/buffalo-docker,v1.0.7,h1:kj+AfChcev54v4N8N6PzNFWyiVSenzu6djrgxTBvbTk=,d84d8bea93f017e3ff07eddab57e0fd7007cf2516250d6fea86c8811c36cf786 +github.com/gobuffalo/buffalo-plugins,v1.14.1,h1:ZL22sNZif+k/0I9X7LB8cpVMWh7zcVjfpiqxFlH4xSY=,556641c2c1b3a9d679a3fc46727d41da225f33c63cfbf1ff721203b24e0a9b82 +github.com/gobuffalo/buffalo-pop,v1.23.1,h1:AnxJQZu/ZN7HCm3L8YBJoNWc2UiwSe6UHv5S4DfXUDA=,00dea8b0e63d3f4110b8bd9d32c086163229f56845a9f8b221e0093876065a05 +github.com/gobuffalo/clara,v0.9.1,h1:LYjwmKG0VwwW/nOG2f5jNamvAcfdm2Ysokc/eoVhtZ8=,319f607092c02686dfed2eb047d500c332ddd962341012bdcd91202bb46d37a9 +github.com/gobuffalo/depgen,v0.2.0,h1:CYuqsR8sq+L9G9+A6uUcTEuaK8AGenAjtYOm238fN3M=,efb3db0d05f712580bc8d3dce2967bd09d6c90140ac7bca1fbd5c5c4a28e1836 +github.com/gobuffalo/envy,v1.7.1,h1:OQl5ys5MBea7OGCdvPbBJWRgnhC/fGona6QKfvFeau8=,14ac6a5cd617dc05abfcb136586800f05f861d4a03d8fa66819a18c0d9eddeec +github.com/gobuffalo/events,v1.4.0,h1:Vje/vgTWs+dyhIS0U03oLpvx1SUdAqutv/hDWIz2ErM=,f6d99c722115631805f04fcf22e8edb7a4116bc65d698ac05c58b6a7f768efdc +github.com/gobuffalo/fizz,v1.9.5,h1:Qh0GkP7MYtJs9RZwBkPJ0CzEXynVowdNfrjg8b+TOxA=,2f645d789550f8f97039e1c4ce3e3f09dfeec28d85c8977c2b20caa06cd75b0c +github.com/gobuffalo/flect,v0.1.6,h1:D7KWNRFiCknJKA495/e1BO7oxqf8tbieaLv/ehoZ/+g=,a7011c8d3f59bac18512c76de610bf1a1f022a01ac6695e0c5af7498d33be613 +github.com/gobuffalo/genny,v0.4.1,h1:ylgRyFoVGtfq92Ziq0kyi0Sdwh//pqWEwg+vD3eK1ZA=,4ecf29587a8cbe069fc6b298d9a3cb674a8008ca4e08233904a8cba91d1ba21b +github.com/gobuffalo/gitgen,v0.0.0-20190315122116-cc086187d211,h1:mSVZ4vj4khv+oThUfS+SQU3UuFIZ5Zo6UNcvK8E8Mz8=,c79975f91dd2fd691d70e29678034eb2dc94b5da2f01b0790a919de9d2a632ac +github.com/gobuffalo/github_flavored_markdown,v1.1.0,h1:8Zzj4fTRl/OP2R7sGerzSf6g2nEJnaBEJe7UAOiEvbQ=,2d73a2baad09dc0d0f0c01549c35e83ab0c18c97f859191e54a632c2fb0eaad2 +github.com/gobuffalo/gogen,v0.2.0,h1:Xx7NCe+/y++eII2aWAFZ09/81MhDCsZwvMzIFJoQRnU=,f60900e595a3779b95b299ca9e74c517523860994a0477b360ac447d3318ccbd +github.com/gobuffalo/helpers,v0.4.0,h1:DR/iYihrVCXv1cYeIGSK3EZz2CljO+DqDLQPWZAod9c=,17ae2b069c0ca73b11b4ace6793617e0620f8d8ef171b0010b91e243c4a3bbe3 +github.com/gobuffalo/here,v0.2.3,h1:1xamq7i4CKjGgICCXY0qpxPeXGdB8oVNSevkpqwd5X4=,3808d0fbc11c58cfb0e7b430b9fc30024ba3781febe8e2601a8e2b8f76e48c00 +github.com/gobuffalo/httptest,v1.4.0,h1:DaoTl/2iFRTk9Uau6b0Lh644tcbRtBNMHcWg6WhieS8=,9d1b48f3e525ab4661d02b3fac86f89fe27f648b1ff8e607f39a353c60c0f315 +github.com/gobuffalo/licenser,v1.4.0,h1:S8WY0nLT9zkBTjFYcbJ0E9MEK7SgE86aMfjsnuThQjY=,3e126adeb06dcaee29376804b463ed33af2b821579162039e8a16e45d0334cdc +github.com/gobuffalo/logger,v1.0.1,h1:ZEgyRGgAm4ZAhAO45YXMs5Fp+bzGLESFewzAVBMKuTg=,43510255e52f7472ec17a76847ca42cebab6efe0b573a5dcfd8261e00d86d3b7 +github.com/gobuffalo/makr,v1.2.0,h1:TA6ThoZEcq0F9FCrc/7xS1ycdCIL0K6Ux+5wmwYV7BY=,113259ce8e945acf3dd184534ab6135240fde6b57d5c6ee3787e7c124e313502 +github.com/gobuffalo/mapi,v1.1.0,h1:VEhxtd2aoPXFqVmliLXGSmqPh541OprxYYZFwgNcjn4=,162640cc01d04543030d55ed51841d673cb8257fd78b069a79010e52ec996b73 +github.com/gobuffalo/meta,v0.2.0,h1:QSDlR2nbGewl0OVL9kqtU8SeKq6zSonrKWB6G3EgADs=,6a44e2a02126c65d2e2f09de5f732327001ac05d542abcabb8dc286422469e9a +github.com/gobuffalo/mw-basicauth,v1.0.7,h1:9zTxCpu0ozzwpwvw5MO31w8nEoySNRNfZwM1YAWfGZs=,da5e2767a9d91e14efb25209c9b9dcf5ad07b551d6d54670c43c6225c8e94084 +github.com/gobuffalo/mw-contenttype,v0.0.0-20190129203934-2554e742333b,h1:6LKJWRvshByPo/dvV4B1E2wvsqXp1uoynVndvuuOZZc=,f9e2f7cce4e88ff8d6f86bc61076179b4f23a85eb5fd0a5f28793ef1e7889fab +github.com/gobuffalo/mw-csrf,v0.0.0-20190129204204-25460a055517,h1:pOOXwl1xPLLP8oZw3e3t2wwrc/KSzmlRBcaQwGpG9oo=,b47a0879eadba5c6774ad37c66afea4998767d9df1295b7b17f3469282cc92f2 +github.com/gobuffalo/mw-forcessl,v0.0.0-20180802152810-73921ae7a130,h1:v94+IGhlBro0Lz1gOR3lrdAVSZ0mJF2NxsdppKd7FnI=,533187beeb18b977c8436d0a5596c1bd420b30cce55589cb11af592df063470c +github.com/gobuffalo/mw-i18n,v0.0.0-20190129204410-552713a3ebb4,h1:c1fFPCxA7SozZPqMhpfZoOVa3wUpCl11gyCEZ4nYqUE=,96a1754eff9c9a75c6b48fc3bc9ab102bbf5d23c103b37a82cc88c666c0dbf9b +github.com/gobuffalo/mw-paramlogger,v0.0.0-20190129202837-395da1998525,h1:2QoD5giw2UrYJu65UKDEo9HFcz9yun387twL2zzn+/Q=,d2e3b1baa234032585cc0e7dc1950681dbc05d960ee958578e470df9fa3b8f18 +github.com/gobuffalo/mw-tokenauth,v0.0.0-20190129201951-95847f29c5c8,h1:dqwRMSzfhe3rL0vMDaRvc2ozLqxapWFBEDH6/f0nQT0=,eb6f82200a81da34baa366475479069f08ed797d5edd4976c9f2af1027d37f1c +github.com/gobuffalo/nulls,v0.1.0,h1:pR3SDzXyFcQrzyPreZj+OzNHSxI4DphSOFaQuidxrfw=,a77a09fd75234e7e5589640fae5d261c03ede9ab5ec626406f24c89dfeba2b38 +github.com/gobuffalo/packd,v0.3.0,h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4=,c7a9263fd464b9f5629bf161521f420b2c40f7780ed6a9ce88184dc4136787a5 +github.com/gobuffalo/packr,v1.30.1,h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg=,20aeea726f6db2ffc8b6dd90b1dce8991f0fd66152a270efdd21c0905b12d5f5 +github.com/gobuffalo/packr/v2,v2.7.1,h1:n3CIW5T17T8v4GGK5sWXLVWJhCz7b5aNLSxW6gYim4o=,60cd83772938a617b37c26a4924ee1f95008d53481724f801eee647e68ce22b1 +github.com/gobuffalo/plush,v3.8.3+incompatible,h1:kzvUTnFPhwyfPEsx7U7LI05/IIslZVGnAlMA1heWub8=,312e219c9827bb7d2dfc954f03fcaa275a3d9eb70687a62ecebad84ede4c51a7 +github.com/gobuffalo/plushgen,v0.1.2,h1:s4yAgNdfNMyMQ7o+Is4f1VlH2L1tKosT+m7BF28C8H4=,0efa90fac0c464409201fa74cace63c4307ac3700a23b3df7c9a9c1c976f0875 +github.com/gobuffalo/pop,v4.12.2+incompatible,h1:WFHMzzHbVLulZnEium1VlYRnWkzHz39FzVLov6rZdDI=,de2837b63e54b15d99234202839e0394183c4ff7c45b9d99162a407c95574003 +github.com/gobuffalo/release,v1.14.0,h1:+Jy7eLN5md6Fg+AMuFRUiK4sTNq4+zXxRho7/wJe1HU=,a0f34f0d3f02ea43434436936766f185b97204a073a605e720190c433c30aaa5 +github.com/gobuffalo/shoulders,v1.2.0,h1:XcPmWbzN7944VXS/I//R7o2eupUHEp3mLFWbUlk1Sco=,4c129ae195bd14520a38c608ba3a27aca674745c1f79fbcce03dacf829802ac6 +github.com/gobuffalo/syncx,v0.0.0-20190224160051-33c29581e754,h1:tpom+2CJmpzAWj5/VEHync2rJGi+epHNIeRSWjzGA+4=,ad9a571b43d72ecce24b8bed85636091710f22d8b06051e1e19ef2051f3e00da +github.com/gobuffalo/tags,v2.1.6+incompatible,h1:xaWOM48Xz8lBh+C8l5R7vSmLAZJK4KeWcLo+0pJ516g=,99bd74d4144bcdfba45fa501cd8d6dec78dc5b0404bbbfebf5bced5b976bb911 +github.com/gobuffalo/uuid,v2.0.5+incompatible,h1:c5uWRuEnYggYCrT9AJm0U2v1QTG7OVDAvxhj8tIV5Gc=,6ab82616cbb02ddd78b9b7db14f580e2e212ceeadcfccff387a973b04be8db37 +github.com/gobuffalo/validate,v2.0.3+incompatible,h1:6f4JCEz11Zi6iIlexMv7Jz10RBPvgI795AOaubtCwTE=,53d876ba454e5e0604ab8078bfb1fca54dcd3ddd859c850cafce757c5f40153d +github.com/gobuffalo/x,v0.0.0-20190224155809-6bb134105960,h1:DoUD23uwnzKJ3t5HH2SeTIszWmc13AV9TAdMhtXQts8=,2435ac54f3ea5c024aea1d4db42a87011bb877f18f0f273f7b3e19b7093c3cfd +github.com/gobwas/glob,v0.2.3,h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=,0cfe486cd63d45ed4cb5863ff1cbd14b15e4b9380dcbf80ff26991b4049f4fdf +github.com/gobwas/httphead,v0.0.0-20180130184737-2c6c146eadee,h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=,5a43ed4a7cd2b063b634f0df5311c0dfa6576683bfc1339f2c5b1b1127fc392b +github.com/gobwas/pool,v0.2.0,h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=,52604b1456b92bb310461167a3e6515562f0f4214f01ed6440e3105f78be188f +github.com/gobwas/ws,v1.0.2,h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=,f9e5c26e83278f19958c68be7b76ad6711c806b6dae766fad7692d2af867bedd +github.com/gocolly/colly,v1.2.0,h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI=,82f210242c4efda461bb6d2cd0543bbadf322c23b840043f236dc1fd74af9325 +github.com/gocql/gocql,v0.0.0-20191018090344-07ace3bab0f8,h1:ZyxBBeTImqFLu9mLtQUnXrO8K/SryXE/xjG/ygl0DxQ=,d38e5bd51d411bc942f295950d87d80e607a8eb186d51b445cc6c2b985681b18 +github.com/godbus/dbus,v4.1.0+incompatible,h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4=,107ef979cca9f2720633f118263afeb9acb0bf0703cc1e860098d5ec48efccb8 +github.com/gofrs/flock,v0.7.1,h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc=,ee433032ec18df1e38d2385d7f9448820c5a017d895cb930cd8801401940137c +github.com/gofrs/uuid,v3.2.0+incompatible,h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=,4139fd148a7a9389629659253722b302791146583e0db94e351a325ecd06abbf +github.com/gogf/gf,v1.9.10,h1:lPBf0EOxv6AXVWN46EKLID0GMHDGOrs4ZAi/RUJbt+c=,83a8cf0cc2557c1e1b3cdb2112953ca303a09cb6d457d2102b3921db1bfd6fe5 +github.com/gogits/chardet,v0.0.0-20150115103509-2404f7772561,h1:deE7ritpK04PgtpyVOS2TYcQEld9qLCD5b5EbVNOuLA=,4b5c6d4b26d381d37b9a5538b9f2dc29d11f422653b19a2047e439a268c3f5ba +github.com/gogits/cron,v0.0.0-20160810035002-7f3990acf183,h1:EBTlva3AOSb80G3JSwY6ZMdILEZJ1JKuewrbqrNjWuE=,746b3b98243fc5ae7127c5102f9ba4f0b88238d081e9cb113d61be2ec16a6241 +github.com/gogo/googleapis,v1.3.0,h1:M695OaDJ5ipWvDPcoAg/YL9c3uORAegkEfBqTQF/fTQ=,ee9e1dda02a5a415c41b5bdff7f6835e929ea89ff3dc1c766510ee909e03c6c3 +github.com/gogo/protobuf,v1.3.1,h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=,4b63e18981e30565f60b7305e3de71ff9aa42cfccf15b88b3813dd2ba6c27be1 +github.com/gogs/chardet,v0.0.0-20150115103509-2404f7772561,h1:aBzukfDxQlCTVS0NBUjI5YA3iVeaZ9Tb5PxNrrIP1xs=,53b6234983c0828d620ba418be5b4e467ef8c9d634bb3d0a2bd4056e3dfa38b3 +github.com/gogs/cron,v0.0.0-20171120032916-9f6c956d3e14,h1:yXtpJr/LV6PFu4nTLgfjQdcMdzjbqqXMEnHfq0Or6p8=,913889f3018853808015c9198e6d3a25f586d88d88493c3de36530eef967664c +github.com/gogs/git-module,v0.8.2,h1:fCi0Lt8VZuFgjCXeLpkhC3irKLArK4oZ69gFvrDXx/s=,e4010dd8fdfe88a65fa8af6ecf97d7e16d4235d0eeb6a0b4b1f4e4d201c70d23 +github.com/gogs/go-gogs-client,v0.0.0-20190710002546-4c3c18947c15,h1:tgEyCCe4+o8A2K/PEi9lF0QMA6XK+Y/j/WN01LnNbbo=,cc5dcea1cca3d3d3e90a0ad548a660250b1299a61519f6dda5dcd7f2f1412daf +github.com/gogs/go-libravatar,v0.0.0-20161120025154-cd1abbd55d09,h1:UdOSIHZpkYcajRbfebBYzFDsL3SuqObH3bvKYBqgKmI=,f81991af4a649aa273bc0c3e7251f107ba0967f5d83553f5a18ed688d937eff0 +github.com/gogs/gogs,v0.11.91,h1:p8kTD9Sn6a/14u6ain6j0dPENMZ0gVEiM7phSIAL29E=,b41695c115f4e2dfc96bfbc7443fa6f91a6d2c8b32d32db4262e6977f5d55fa7 +github.com/gogs/minwinsvc,v0.0.0-20170301035411-95be6356811a,h1:8DZwxETOVWIinYxDK+i6L+rMb7eGATGaakD6ZucfHVk=,fb48a56a9f610b061af186008072fbd6e51055a12c168e1e347ecf9a05f25767 +github.com/gohugoio/hugo,v0.59.1,h1:nxaeKEY52cdpx3wZN/EcY6dEqbgeFsZaeNkDL8azeZ8=,508257b11bfc1ec77d3993a13929de63fa08e70ae26cd7c53f03857b3db9bbdf +github.com/gohugoio/testmodBuilder/mods,v0.0.0-20190520184928-c56af20f2e95,h1:sgew0XCnZwnzpWxTt3V8LLiCO7OQi3C6dycaE67wfkU=,0d6eabbeb381b08c84e7191fcecc49027ad3382997441180b2d6eea3fafc81b6 +github.com/goji/httpauth,v0.0.0-20160601135302-2da839ab0f4d,h1:lBXNCxVENCipq4D1Is42JVOP4eQjlB8TQ6H69Yx5J9Q=,8467ed1df8ffba8da7ead144b656b6281469ab4d122adf3edf496175ad870192 +github.com/goki/freetype,v0.0.0-20181231101311-fa8a33aabaff,h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8=,80884151cd73d38904e4370afba3b870345a883a77c395194582202d805d7d74 +github.com/goki/ki,v0.9.8,h1:SzVTxJrd0ZcnkRTinZdbc41nIFmocJ7pyllEyBzNmys=,ce62e162090d566e2f9cb5b1659327a84c646dced32729e24b420cde4d5cb714 +github.com/goki/prof,v0.0.0-20180502205428-54bc71b5d09b,h1:3zU6niF8uvEaNtRBhOkmgbE/Fx7D6xuALotArTpycNc=,f46b93b6c42a97f06a2f658e49243972f4bd469b296f1010609c8d649163b73f +github.com/golang-collections/collections,v0.0.0-20130729185459-604e922904d3,h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4=,7847b09c355215616db6309597757ff6be2cf44781d800cdad1628f141dc82ee +github.com/golang-migrate/migrate/v3,v3.5.2,h1:SUWSv6PD8Lr2TGx1lmVW7W2lRoQiVny3stM4He6jczQ=,5086537ee116e958cf9647e28f843a0ac17f5de75ab642e5aef1fe2b360b0e30 +github.com/golang-sql/civil,v0.0.0-20190719163853-cb61b32ac6fe,h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=,22fcd1e01cabf6ec75c6b6c8e443de029611c9dd5cc4673818d52dac465ac688 +github.com/golang/freetype,v0.0.0-20170609003504-e2365dfdc4a0,h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=,cdcb9e6a14933dcbf167b44dcd5083fc6a2e52c4fae8fb79747c691efeb7d84e +github.com/golang/gddo,v0.0.0-20180828051604-96d2a289f41e,h1:8sV50nrSGwclVxkCGHxgWfJhY6cyXS2plGjGvUzrMIw=,9a0683005c7700bb1b7ac155597592d15d02f510a0d2c334f8564c43b9072107 +github.com/golang/glog,v0.0.0-20160126235308-23def4e6c14b,h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=,36b3c522c8102dfe74ca96e474c4c361750bf2bb85bc3cefe4f074c07d6825a9 +github.com/golang/groupcache,v0.0.0-20191027212112-611e8accdfc9,h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE=,a4815d7048e9a1dd79a72a09d4c9a946ccff837695d046c7f0f5c24037ce18b3 +github.com/golang/lint,v0.0.0-20180702182130-06c8688daad7,h1:2hRPrmiwPrp3fQX967rNJIhQPtiGXdlQWAxKbKw3VHA=,66e95adf2c1feb4de316d2c0ba9e04a22322df010a67b1054ad3d4fb2f9a1791 +github.com/golang/mock,v1.3.1,h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=,3209f2030646855a3644736b5d7ce2cd9076856cac2f50360805a19c38b7bc45 +github.com/golang/protobuf,v1.3.2,h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=,a004ba3acb85e012cb9e468e1d445a81cfeeb4b4db7e9802f30aa500a8341851 +github.com/golang/snappy,v0.0.1,h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=,0a9a73d55340a8e6d17e72684cf90618b275b6034ce83299abb55ed8fb3860bd +github.com/golangplus/bytes,v0.0.0-20160111154220-45c989fe5450,h1:7xqw01UYS+KCI25bMrPxwNYkSns2Db1ziQPpVq99FpE=,2904c49772d1bade7c81ddae2fa70e42bdce7b006c871c8106d1feb14fe2982b +github.com/golangplus/fmt,v0.0.0-20150411045040-2a5d6d7d2995,h1:f5gsjBiF9tRRVomCvrkGMMWI8W1f2OBFar2c5oakAP0=,2afd341a4d32c84532d6d44574718e1b8000aa57cfc21ced284612fc92b61217 +github.com/golangplus/testing,v0.0.0-20180327235837-af21d9c3145e,h1:KhcknUwkWHKZPbFy2P7jH5LKJ3La+0ZeknkkmrSgqb0=,fc111aa59d03741dad00f05ce869fcb44f5d75b841413e21e7301bc538a0255e +github.com/gomodule/redigo,v2.0.0+incompatible,h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=,77342da7b962489363b3661803ee2fba72b23b8e97af0241877ce6ab8a95d194 +github.com/gonum/blas,v0.0.0-20181208220705-f22b278b28ac,h1:Q0Jsdxl5jbxouNs1TQYt0gxesYMU4VXRbsTlgDloZ50=,bfcad082317ace0d0bdc0832f0835d95aaa90f91cf3fce5d2d81ccdd70c38620 +github.com/gonum/floats,v0.0.0-20181209220543-c233463c7e82,h1:EvokxLQsaaQjcWVWSV38221VAK7qc2zhaO17bKys/18=,52afb5e33a03b027f8f451e23618c2decbe4443f996a203e332858c1a348a627 +github.com/gonum/graph,v0.0.0-20190426092945-678096d81a4b,h1:LilU5ERRFWL+2D6yR1PL2oeS4n+xyTq1vfv39LFVaeE=,411fd86d898ad7ea8c1145610a27f0f13153c86b3ef5e78cb80431125082b5a6 +github.com/gonum/internal,v0.0.0-20181124074243-f884aa714029,h1:8jtTdc+Nfj9AR+0soOeia9UZSvYBvETVHZrugUowJ7M=,e7f40a97eee3574c826a1e75f80ecd94c27853feaab5c43fde7dd95ba516c9dc +github.com/gonum/lapack,v0.0.0-20181123203213-e4cdc5a0bff9,h1:7qnwS9+oeSiOIsiUMajT+0R7HR6hw5NegnKPmn/94oI=,f38b72e072728121b9acf5ae26d947aacc0024dddc09d19e382bacd8669f5997 +github.com/gonum/matrix,v0.0.0-20181209220409-c518dec07be9,h1:V2IgdyerlBa/MxaEFRbV5juy/C3MGdj4ePi+g6ePIp4=,9cea355e35e3f5718b2c69f65712b2c08a1bec13b3cfadf168d98b41b043dd63 +github.com/google/btree,v1.0.0,h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=,8dbcb36f92c7a6dc5f6aef5c26358d98b72caee69829b5b33dddabada2047785 +github.com/google/cadvisor,v0.34.0,h1:No7G6U/TasplR9uNqyc5Jj0Bet5VSYsK5xLygOf4pUw=,5a3807f43a14e6a03b7ceb9ea11f8ac241a42286be90c3b2cba49ee811111848 +github.com/google/certificate-transparency-go,v1.0.21,h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=,7ddb21b272632236d5fb35b35c837f39d38390ea8dcb97c9f0f5d5aa561c3366 +github.com/google/flatbuffers,v1.11.0,h1:O7CEyB8Cb3/DmtxODGtLHcEvpr81Jm5qLg/hsHnxA2A=,ff61e5077ecc7d46a2020c1b42e0a6405b50271f396d4dcc50c683345059af76 +github.com/google/go-cmp,v0.3.2-0.20191028172631-481baca67f93,h1:VvBteXw2zOXEgm0o3PgONTWf+bhUGsCaiNn3pbkU9LA=,6682f890f076aaa03f2c2afb6bc7304c9d602b9e23ff212f8a9a64f44f432dbc +github.com/google/go-containerregistry,v0.0.0-20191029173801-50b26ee28691,h1:9fkqC5Bq8l2FQgcW6FQbPDUeZvExyg7okl+s4Gg9Jrs=,7bef2c87f7ca8a39e04c770b38160dd5cfdd508546f96fab427225d12d40d85a +github.com/google/go-github,v17.0.0+incompatible,h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=,9831222a466bec73a21627e0c3525da9cadd969468e31d10ecae8580b0568d0e +github.com/google/go-github/v21,v21.0.0,h1:tn4/tmCgPAsezJFwZcMnE7U0R9/AtKRBGX4s4LFdDzI=,0b25aebca5386cdb52515402b81a8e0a676ac30f9843feb0a47a1944b7c8b527 +github.com/google/go-github/v24,v24.0.1,h1:KCt1LjMJEey1qvPXxa9SjaWxwTsCWSq6p2Ju57UR4Q4=,4dd0a57a527a1cc52e6619e9d2e1936534439426f0eb065bfbe1e7c03b60d465 +github.com/google/go-github/v28,v28.1.1,h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo=,621cca7f4889897317c18ed021fe0f55c279769f11357d90eb21a29c5ea78d04 +github.com/google/go-querystring,v1.0.0,h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=,1c0a0b81b921ee270e47e05cf0bf8df4475de850671e553c07740849068d4f9f +github.com/google/go-replayers/grpcreplay,v0.1.0,h1:eNb1y9rZFmY4ax45uEEECSa8fsxGRU+8Bil52ASAwic=,794ad7fb2669ea1d1305cf7717a1329146635637739bf2e26d858a318e87f99b +github.com/google/go-replayers/httpreplay,v0.1.0,h1:AX7FUb4BjrrzNvblr/OlgwrmFiep6soj5K2QSDW7BGk=,cf6d3e2262e94db5bad86d944f2f97507b1ffc2943e4385f140eb6f9a01f8e7b +github.com/google/go-tpm,v0.2.0,h1:3Z5ZjNRQ0CsUj3yWXtbbx4Vfb/sQapdSeZJvuaKuQzc=,7e90cb155fa3e7759caa1fe5df1ca43520a7f8e1a31e540573cc8290ff523a23 +github.com/google/go-tpm-tools,v0.0.0-20190906225433-1614c142f845,h1:2WNNKKRI+a5OZi5xiJVfDoOiUyfK/BU1D4w+N6967F4=,2e41ca1e24a1ba5eedf980331527d6a5ad09b8ef653bbd040321572899eff8a2 +github.com/google/gofuzz,v1.0.0,h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=,752570262575bbcb5f0107dbd80a463abacaf51e94e15f96f5bc4166ff2d33e1 +github.com/google/gopacket,v1.1.17,h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY=,008645038244e12a1bfbda2317372ec34a514250741139b8e4842de7f98639d4 +github.com/google/gxui,v0.0.0-20151028112939-f85e0a97b3a4,h1:OL2d27ueTKnlQJoqLW2fc9pWYulFnJYLWzomGV7HqZo=,be209ad45b16077b010faef4a7bcbf0723dfbe47869a6f4c0aacd534e7fcbfb1 +github.com/google/martian,v2.1.1-0.20190517191504-25dcb96d9e51+incompatible,h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE=,dfc5eac3877863c1f231457f96c54c915ea1c86f86c590710b7477f96e1ba0f3 +github.com/google/netstack,v0.0.0-20191031000057-4787376a6744,h1:wKeh74w+ydKcE1Eo44WDzIOcPHWmxxmtAzkAL0Mlspc=,dd74d0c9fadfb29db3bd09da657cb95300255d562ce596e88c865a71ee5d2519 +github.com/google/pprof,v0.0.0-20191028172815-5e965273ee43,h1:59gkLC5pLENSgzw9Gx73BQQho5i//80XwgIIYWxZjp4=,667012da0f67eb7822d16f532e850091a58c1efebeef5047df9a02e972112484 +github.com/google/readahead,v0.0.0-20161222183148-eaceba169032,h1:6Be3nkuJFyRfCgr6qTIzmRp8y9QwDIbqy/nYr9WDPos=,3a2435123538463dc3412a2eb1be033b7cf8105775c1ff3524351ec405fa1469 +github.com/google/renameio,v0.1.0,h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=,b8510bb34078691a20b8e4902d371afe0eb171b2daf953f67cb3960d1926ccf3 +github.com/google/rpmpack,v0.0.0-20191101142923-13d81472ccfe,h1:P1WflKHEgTAYe39btxYzeds84DhxQSLj4hfoNn0tCyQ=,5144bdeda051f10f407f1f798502ec0d7599f9c4a7e0a79c3711fe2b79f5cae4 +github.com/google/shlex,v0.0.0-20181106134648-c34317bd91bf,h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=,250fc48c105475c54cc8c9fe5c110e31986590433de2608740d6592d0dc0a4c6 +github.com/google/subcommands,v1.0.1,h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=,de4249d9823a0509df32ebad2787d5e54c9b53c1059592bd9a3bb0c4cf58034d +github.com/google/uuid,v1.1.1,h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=,2b0cbc45fb0e21c8bfebbae9b04babc196d9f06d9f3b9dec5e2adc8cfd0c1b81 +github.com/google/wire,v0.3.0,h1:imGQZGEVEHpje5056+K+cgdO72p0LQv2xIIFXNGUf60=,38eb402dbe84aee2f891df0e62623f9ff5615dfeb1e4f631eaac5cf1859c9ea6 +github.com/googleapis/gax-go,v2.0.2+incompatible,h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww=,36fe8c993c8f90067bffbba78f1325ff45ae60c8a85b778d798c56067e55c19e +github.com/googleapis/gax-go/v2,v2.0.5,h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=,846b017e21fc01f408774051d4a10bfccd7c294e10a1ad5d725278889d5f1d42 +github.com/googleapis/gnostic,v0.3.1,h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=,33277bd9aab84cf04d058a5e2e1dbb5f3c023ba30c6127b4cc8a6662a776de53 +github.com/gopackage/ddp,v0.0.0-20170117053602-652027933df4,h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo=,76b2493aae8a5513b707e4f6c529f57175cca6c834dd19072a51ed3974cd77bc +github.com/gophercloud/gophercloud,v0.6.0,h1:Xb2lcqZtml1XjgYZxbeayEemq7ASbeTp09m36gQFpEU=,f5be75a3b128c9de7385dd7e2a8ec9fba18fb46dcf57624d88249ae99e188ed2 +github.com/gophercloud/utils,v0.0.0-20190128072930-fbb6ab446f01,h1:OgCNGSnEalfkRpn//WGJHhpo7fkP+LhTpvEITZ7CkK4=,c98b6d529b47679302d175f04d7b635824c292edc8a5ede807f9ba8145517ce7 +github.com/gopherjs/gopherjs,v0.0.0-20190915194858-d3ddacdb130f,h1:TyqzGm2z1h3AGhjOoRYyeLcW4WlW81MDQkWa+rx/000=,ff395ad20350783713974a6b4d03254b811d83c0c0caa13bcb329462a7263f70 +github.com/gopherjs/jquery,v0.0.0-20180404123100-3ba2b901425e,h1:Tf0PnEo36tq56/JezxbbiFpEce0pmK6tY7hS6PNS7tI=,26fb481ef7f7010ec901990527d7ef7b06bc18c38cb617db77f8b61263b5b453 +github.com/gopherjs/jsbuiltin,v0.0.0-20180426082241-50091555e127,h1:atBEgNR1C5+LFkl8ipQtLee9RStheS8YeCSkiYqBhOg=,603151a77e4be25c8389014b06449520c2ad5856f0161590a5de5f01bee28912 +github.com/goreleaser/goreleaser,v0.120.5,h1:N3VirNAK9u30Wj7xulfE9/cCvptO0vl+CLhaMEVGbGs=,9c516d6e8db8c6800102ca68e3f674a62dd42877d7785607f56c22f6dc9b5a9e +github.com/goreleaser/nfpm,v1.1.2,h1:9+hnNm/h/ANQWLxZixNO562w4tIO/8VlgCwOKwwZTX4=,9781a05527458d352a744a524c94473d2a72694fd54bc559a5888158bb4fa1fb +github.com/gorhill/cronexpr,v0.0.0-20180427100037-88b0669f7d75,h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY=,742d8957d3f9fe773150fb3164868a755b2af5b705b38c72c45ca5386715c617 +github.com/gorilla/context,v1.1.1,h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=,4ec8e01fe741a931edeebdee9348ffb49b5cc565ca245551d0d20b67062e6f0b +github.com/gorilla/csrf,v1.6.0,h1:60oN1cFdncCE8tjwQ3QEkFND5k37lQPcRjnlvm7CIJ0=,6fa6b9d34ba1c2409e6575db396f57607c5283e397d38a271b6930c666f166b0 +github.com/gorilla/handlers,v1.4.2,h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=,9e47491112a46d32e372be827899e8678a881f6407f290564c63e8725b5e9a19 +github.com/gorilla/mux,v1.7.3,h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=,9ffc6c6c1194cb2b9f39237ff90b20eb4a55273404c97364ed9a6500e9571fe3 +github.com/gorilla/pat,v1.0.1,h1:OeSoj6sffw4/majibAY2BAUsXjNP7fEE+w30KickaL4=,e0dedacf6f405854b94932a59b410bbda64d4fff8111b674db987ce242bc9d57 +github.com/gorilla/rpc,v1.1.0,h1:marKfvVP0Gpd/jHlVBKCQ8RAoUPdX7K1Nuh6l1BNh7A=,0e83ae0cbc4164cdaf0b808413f97fed7a90e2096095c14f5495b6dbfaa34266 +github.com/gorilla/schema,v1.1.0,h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=,42a6d7dc873e8ba1822551b4e15304d5654a11f6da3cccdc270be847148bbfaf +github.com/gorilla/securecookie,v1.1.1,h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=,dd83a4230e11568159756bbea4d343c88df0cd1415bbbc7cd5badad6cd2ed903 +github.com/gorilla/sessions,v1.2.0,h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=,8753d00ae6cf8ea0e28c195d4b87875384e2ed79df7eba4cf210fdf9ab0294df +github.com/gorilla/websocket,v1.4.1,h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=,86eb427567de9e2dc84da52ee4f4315496c5ffc2152928df0e3ac4ce8a359ff7 +github.com/gosimple/slug,v1.9.0,h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs=,0f72d897e3decea434cdc68c7d0226afbda7d6b1908e955bf406333e7d6bb4a7 +github.com/gosuri/uitable,v0.0.3,h1:9ZY4qCODg6JL1Ui4dL9LqCF4ghWnAOSV2h7xG98SkHE=,1316f88b6b2689d941a4727889818705a289c72d7f1f4d2d9cf5cd06fecd0b7b +github.com/gotestyourself/gotestyourself,v2.2.0+incompatible,h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=,653f8ec3ed62f8d235ab67cfc56e7c814d4ac6f56f24000802b32728523c074c +github.com/gotnospirit/makeplural,v0.0.0-20180622080156-a5f48d94d976,h1:b70jEaX2iaJSPZULSUxKtm73LBfsCrMsIlYCUgNGSIs=,5750c916115b851f4881b76d90128802d090558958aa821c691d4fa378018093 +github.com/gotnospirit/messageformat,v0.0.0-20180622080451-0eab1176a3fb,h1:akgcoKcMcMOlzb6fdycEck1Vc3+y7ubUjO6hgAOyqC8=,7189231c806aa1988b50a82019c5f972a5f1b82e61c94776999728ec1894cd29 +github.com/graarh/golang-socketio,v0.0.0-20170510162725-2c44953b9b5f,h1:utzdm9zUvVWGRtIpkdE4+36n+Gv60kNb7mFvgGxLElY=,f41faefdf625d1c04113636d467a9fa47fe083148d7393fa65c0f08e3a4078c3 +github.com/grafana/globalconf,v0.0.0-20181214112547-7a1aae0695d9,h1:2/Bz5A5zR4TMGd9yvgGMal7nhQwHBt5/dfp0sbJFfes=,0393f4fa690096ea26c76373e99f9d9f3bfc9b34e5acd08d639b68f68af7b5e2 +github.com/grandcat/zeroconf,v0.0.0-20190424104450-85eadb44205c,h1:svzQzfVE9t7Y1CGULS5PsMWs4/H4Au/ZTJzU/0CKgqc=,2d364bea1939e3ec55b732cae452feb3182fc1d8ffa30f35aa42c0181709d138 +github.com/graph-gophers/graphql-go,v0.0.0-20190225005345-3e8838d4614c,h1:YyFUsspLqAt3noyPCLz7EFK/o1LpC1j/6MjU0bSVOQ4=,fad60e1061e15848aff79c6620f1cf55a9dd87d58ca2f57fea50c35322c817ac +github.com/graphql-go/graphql,v0.7.9-0.20190403165646-199d20bbfed7,h1:E45QFM7IqRdFnuyFk8GSamb42EckUSyJ55rtVB/w8VQ=,6e9d51c4dc431d2d7c1348fa2b3358ed8e57338a07750177698bde29c913e786 +github.com/gravitational/trace,v0.0.0-20190726142706-a535a178675f,h1:68WxnfBzJRYktZ30fmIjGQ74RsXYLoeH2/NITPktTMY=,6fb8317692ac3aa8280cd4b4749970ec6652ecbe2c629cd43b52005f9a992197 +github.com/graymeta/stow,v0.2.4,h1:qDGstknYXqcnmBQ5TRJtxD9Qv1MuRbYRhLoSMeUDs7U=,67b4e728448b89c2233da14c22f18fe6c720e88a858dff2cd3c7405c7ea10493 +github.com/gregjones/httpcache,v0.0.0-20190611155906-901d90724c79,h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=,73d773791d582cad0d90942e7d92f52d82f13119dd78e849bbd77fae2acc0276 +github.com/grokify/html-strip-tags-go,v0.0.0-20190921062105-daaa06bf1aaf,h1:wIOAyJMMen0ELGiFzlmqxdcV1yGbkyHBAB6PolcNbLA=,0bb5eaff16e4119a9251bb0a26b4190a8e36cbacce8daee8c77df76022e1087c +github.com/grpc-ecosystem/go-grpc-middleware,v1.1.0,h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg=,def2c3ec1d07264489b79fa0e8e7a5c23545f16ba3c6e613f5cdba2ae8fe2768 +github.com/grpc-ecosystem/go-grpc-prometheus,v1.2.1-0.20191002090509-6af20e3a5340,h1:uGoIog/wiQHI9GAxXO5TJbT0wWKH3O9HhOJW1F9c3fY=,bca256c9eee3d43fe310c205866c69de454e71346f18ea2b05a32bd2f6018c84 +github.com/grpc-ecosystem/grpc-gateway,v1.11.3,h1:h8+NsYENhxNTuq+dobk3+ODoJtwY4Fu0WQXsxJfL8aM=,d96a88c820576b8b6989944cbe15f4f2d94d2884f29f2f683b975a03a5bdc5fc +github.com/grpc-ecosystem/grpc-opentracing,v0.0.0-20180507213350-8e809c8a8645,h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=,0606bde24e978e9cd91ae45ca9e5222ce695c21a07ae02e77546496bf23b1c62 +github.com/gucumber/gucumber,v0.0.0-20180127021336-7d5c79e832a2,h1:iR8wSrr/JCzL1Ul+dRVxtIOnP8DGg/m02nHZJ9PH6P0=,4feb5116e650552868f056ee74d179e91239bf166d365267f32e903ccc495dbb +github.com/guptarohit/asciigraph,v0.4.1,h1:YHmCMN8VH81BIUIgTg2Fs3B52QDxNZw2RQ6j5pGoSxo=,976279cdbc5425609c272b2116a92fb5871a40164ae64c51dedffea7b550d2d4 +github.com/guregu/null,v2.1.3-0.20151024101046-79c5bd36b615+incompatible,h1:SZmF1M6CdAm4MmTPYYTG+x9EC8D3FOxUq9S4D37irQg=,1adcbf87f6c55963b0d020ccbac0ebd07e8aca5e0ff22469ac708c6574d7333f +github.com/gxed/go-shellwords,v1.0.3,h1:2TP32H4TAklZUdz84oj95BJhVnIrRasyx2j1cqH5K38=,c63674c66949c0442402bceca8b7768684875a667140ea0b32afdd46fc094a7f +github.com/gxed/hashland/keccakpg,v0.0.1,h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU=,c77522ff0820feb7b5be4e1c74d7c64b3aa5afe3452e1dd2f54d1ffa067c6b2d +github.com/gxed/hashland/murmur3,v0.0.1,h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc=,4576d7ae9b5d2f4ebd238de84f3b52b9d4ae4d41822ac0eabd404d346eace067 +github.com/gxed/pubsub,v0.0.0-20180201040156-26ebdf44f824,h1:TF4mX7zXpeyz/xintezebSa7ZDxAGBnqDwcoobvaz2o=,718b183cca4e30a97d3fa06457060b4d3be66742838d98a39b02ea710693d9eb +github.com/h2non/filetype,v1.0.8,h1:le8gpf+FQA0/DlDABbtisA1KiTS0Xi+YSC/E8yY3Y14=,534a477c811032fceb0c8e1ad7a15f35ff95f1d038d41164bb4d265860cc42c3 +github.com/h2non/gock,v1.0.9,h1:17gCehSo8ZOgEsFKpQgqHiR7VLyjxdAG3lkhVvO9QZU=,ab5679329b0c26b523254dd728cad1b4e6e2e7bf11569df73a1dcaa468a46cd6 +github.com/h2non/parth,v0.0.0-20190131123155-b4df798d6542,h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=,3b7b7e4bb3c2d0e22075e13443af78d03fb2ed54b3eb5bb1fa6f528c7ebe3ac0 +github.com/hailocab/go-hostpool,v0.0.0-20160125115350-e80d13ce29ed,h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=,faf2b985681cda77ab928976b620b790585e364b6aff351483227d474db85e9a +github.com/hanwen/go-fuse,v1.0.0,h1:GxS9Zrn6c35/BnfiVsZVWmsG803xwE7eVRDvcf/BEVc=,4b94d038e80959f816a18b34cdcbb5244e87b73956b220aac213483999b54c84 +github.com/hashicorp/aws-sdk-go-base,v0.4.0,h1:zH9hNUdsS+2G0zJaU85ul8D59BGnZBaKM+KMNPAHGwk=,967c057aecede32de140c88b6527149d2441216569620b9d9350522d0f309bdc +github.com/hashicorp/consul,v1.6.1,h1:ISPgwOO8/vPYrCXQNyx63eJAYjPGRnmFsXK7aj2XICs=,0ca8c5046df99a7a6607ab68b6604340af58d1696c7901088adfd9618850629f +github.com/hashicorp/consul/api,v1.2.0,h1:oPsuzLp2uk7I7rojPKuncWbZ+m5TMoD4Ivs+2Rkeh4Y=,2833a78c39a4fa869a928e1218f3aa83130e4f5c03b4d4e355fb76b91fa75946 +github.com/hashicorp/consul/sdk,v0.2.0,h1:GWFYFmry/k4b1hEoy7kSkmU8e30GAyI4VZHk0fRxeL4=,3f0b677061f7e79191cc0d2f8184895c20051166959566a2e48e511b1fab222c +github.com/hashicorp/errwrap,v1.0.0,h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=,ccdf4c90f894d8a5fde4e79d5828c5d27a13e9f7ce3006dd72ce76e6e17cdeb2 +github.com/hashicorp/go-azure-helpers,v0.0.0-20190129193224-166dfd221bb2,h1:VBRx+yPYUZaobnn5ANBcOUf4hhWpTHSQgftG4TcDkhI=,dd17ed56e4b541cffa69679557074071372ab70682f695d8b61126c9393f92dc +github.com/hashicorp/go-bexpr,v0.1.2,h1:ijMXI4qERbzxbCnkxmfUtwMyjrrk3y+Vt0MxojNCbBs=,ac79086a2900ebf2f5414fe54b5799f24b3ddf953a28299f46831a11b10b1df0 +github.com/hashicorp/go-checkpoint,v0.5.0,h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=,1baf63010271d6c8abc0f4edc9e9d41483cb55218e4e399ca4c70ef225415f36 +github.com/hashicorp/go-cleanhttp,v0.5.1,h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=,e3cc9964b0bc80c6156d6fb064abcb62ff8c00df8be8009b6f6d3aefc2776a23 +github.com/hashicorp/go-discover,v0.0.0-20190403160810-22221edb15cd,h1:SynRxs8h2h7lLSA5py5a3WWkYpImhREtju0CuRd97wc=,c58ed5375890c98a836234f5166cf88b73ad7595899edaa43c775d650043b4b3 +github.com/hashicorp/go-gcp-common,v0.5.0,h1:kkIQTjNTopn4eXQ1+lCiHYZXUtgIZvbc6YtAQkMnTos=,a1fee55619b3579e5fe89b6f944dce87e190b8ea1526f24622ba5941d664b639 +github.com/hashicorp/go-getter,v1.4.0,h1:ENHNi8494porjD0ZhIrjlAHnveSFhY7hvOJrV/fsKkw=,cbae7b8a5f018c78bb304c47840c390b3c3be98b712b90b33d16304f1b427eb1 +github.com/hashicorp/go-hclog,v0.9.2,h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=,e1a873d9fa828038b5b2c93e0f49f9e8187b4f5255d0a3d7989d3ac178807af4 +github.com/hashicorp/go-immutable-radix,v1.1.0,h1:vN9wG1D6KG6YHRTWr8512cxGOVgTMEfgEdSj/hr8MPc=,c23ca92f0fb7dce35b86d35ccf9cfa871db97379d2ca8a0fcc15fde32ff369bb +github.com/hashicorp/go-memdb,v1.0.4,h1:sIdJHAEtV3//iXcUb4LumSQeorYos5V0ptvqvQvFgDA=,c3eedd68e60f3db16499dff27fe4d4e874978c250bab152044965a475cb47c72 +github.com/hashicorp/go-msgpack,v0.5.5,h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=,fb47605669b0ddd75292aac788208475fecd54e0ea3e9a282d8a98ae8c60d1f5 +github.com/hashicorp/go-multierror,v1.0.0,h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=,a66a1b9dff26a9a7fcaa5aa5e658c13f94c0daeb572536b1ecc7ebe51f4d0be7 +github.com/hashicorp/go-oracle-terraform,v0.0.0-20181016190316-007121241b79,h1:RKu7yAXZTaQsxj1K9GDsh+QVw0+Wu1SWHxtbFN0n+hE=,5b3ab30e1aef56e38d750a5dc344f1ab996859408a6b76a9f48f5f75747fd712 +github.com/hashicorp/go-plugin,v1.0.1,h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE=,0853effcccdb7bfac1c122f72cd3a1241b4e0934609541c409e9f59b441ae01e +github.com/hashicorp/go-raftchunking,v0.6.2,h1:imj6CVkwXj6VzgXZQvzS+fSrkbFCzlJ2t00F3PacnuU=,f5c55a3679c8a8f63d798d2b67552bfcd198dc5b9473d81c3ce1b353a055bc5c +github.com/hashicorp/go-retryablehttp,v0.6.3,h1:tuulM+WnToeqa05z83YLmKabZxrySOmJAd4mJ+s2Nfg=,69cb67f4821e97ca8f04b0cb710c61a5acfaa948dda59b949b40fd6fae8e7dec +github.com/hashicorp/go-rootcerts,v1.0.1,h1:DMo4fmknnz0E0evoNYnV48RjWndOsmd6OW+09R3cEP8=,3f558b1a436ed6fb15872383545109227f9552bf5daa95583e9402bbd3a24fff +github.com/hashicorp/go-safetemp,v1.0.0,h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=,6843a6b60d650ae9be836add0ab5ac1b1719a101bf12fe4ca6678fcd87baa19a +github.com/hashicorp/go-slug,v0.4.0,h1:YSz3afoEZZJVVB46NITf0+opd2cHpaYJ1XSojOyP0x8=,b6a027a2d69ae8786a6830239a79ceac487463237b49e03250a9b1e116f0a5ac +github.com/hashicorp/go-sockaddr,v1.0.2,h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=,50c1b60863b0cd31d03b26d3975f76cab55466666c067cd1823481a61f19af33 +github.com/hashicorp/go-syslog,v1.0.0,h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE=,a0ca8b61ea365e9ecdca513b94f200aef3ff68b4c95d9dabc88ca25fcb33bce6 +github.com/hashicorp/go-tfe,v0.3.25,h1:4rPk/9rSYuRoujKk5FsxSvtC/AjJCQphLS/57yr6wUM=,5ade1d16517697c7bd04b556f852264eef33906c52d32bd6702c47838c1c1c04 +github.com/hashicorp/go-uuid,v1.0.1,h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=,a05417b988b047d55fca8ad4fec6bde56c3907f679fece48f97d608e61e82a5c +github.com/hashicorp/go-version,v1.2.0,h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=,a3231adb6bf029750970de2955e82e41e4c062b94eb73683e9111aa0c0841008 +github.com/hashicorp/go.net,v0.0.1,h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw=,71564aa3cb6e2820ee31e4d9e264e4ed889c7916f958b2f54c6f3004d4fcd8d2 +github.com/hashicorp/golang-lru,v0.5.3,h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=,ac6e8bdc76a1275e3496f1ab2484e28ab4be2c81e2da78b8cdd1c2d269b931e4 +github.com/hashicorp/hcl,v1.0.0,h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=,54149a2e5121b3e81f961c79210e63d6798eb63de28d2599ee59ade1fa76c82b +github.com/hashicorp/hcl/v2,v2.0.0,h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8=,6275e2af8b3247c6de72baab13b3be531431f695e001e4d36c920e412a715032 +github.com/hashicorp/hcl2,v0.0.0-20191002203319-fb75b3253c80,h1:PFfGModn55JA0oBsvFghhj0v93me+Ctr3uHC/UmFAls=,42811f77c4da1d31371c51076cbcecc99042fc7a74c6e2622b11bea96043a777 +github.com/hashicorp/hil,v0.0.0-20190212112733-ab17b08d6590,h1:2yzhWGdgQUWZUCNK+AoO35V+HTsgEmcM4J9IkArh7PI=,cb2b110c86a312b7c60094c9b11853ae288945c34fa5861b67ff2d97edaab292 +github.com/hashicorp/logutils,v1.0.0,h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=,0e88424578d1d6b7793b63d30c180a353ce8041701d25dc7c3bcd9841c36db5b +github.com/hashicorp/mdns,v1.0.1,h1:XFSOubp8KWB+Jd2PDyaX5xUd5bhSP/+pTDZVDMzZJM8=,0f4b33961638b1273ace80b64c6fc7e54a1064484b2a1e182ab3d38a35dbc94f +github.com/hashicorp/memberlist,v0.1.5,h1:AYBsgJOW9gab/toO5tEB8lWetVgDKZycqkebJ8xxpqM=,51054573cad1655b1b349553a8d455eedc15b49f0277edd2e693bc5d0503af62 +github.com/hashicorp/net-rpc-msgpackrpc,v0.0.0-20151116020338-a14192a58a69,h1:lc3c72qGlIMDqQpQH82Y4vaglRMMFdJbziYWriR4UcE=,b0c3a5ec955b0dfb85b39a6aa1d10fe0e810dd78493c0a14ea5760bac1cadd32 +github.com/hashicorp/nomad/api,v0.0.0-20190412184103-1c38ced33adf,h1:U/40PQvWkaXCDdK9QHKf1pVDVcA+NIDVbzzonFGkgIA=,b9e994cd47eed80531b93d9f64be426cbdc6fc6e58323f6b26ae53b1fd692bbd +github.com/hashicorp/packer,v1.4.4,h1:ee+jewbEfTKV77+YtRR0m2Q8suTiXnr010bBFt5vJSA=,d2fc7c22b3528a4acb321fda24575cf2f88df8f5085b3b5da559e44d8b12295a +github.com/hashicorp/raft,v1.1.1,h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs=,b6a10aa04b5f45486a6111d4a50cb65ee179b091f04a047e316b85f38ebbf873 +github.com/hashicorp/raft-boltdb,v0.0.0-20191021154308-4207f1bf0617,h1:CJDRE/2tBNFOrcoexD2nvTRbQEox3FDxl4NxIezp1b8=,e2008570aed06ba72cd783d6bc729b67b7e0cecd2219a8420dd24dcef82e64f8 +github.com/hashicorp/raft-snapshot,v1.0.1,h1:cx002JsTEAfAP0pIuANlDtTXg/pi2Db6YbRRmLQTQKw=,3d40d03f6793fe87464359f28b136b920daf7aa8544a98270470d04cef132a77 +github.com/hashicorp/serf,v0.8.5,h1:ZynDUIQiA8usmRgPdGPHFdPnb1wgGI9tK3mO9hcAJjc=,88623d0f1a155bb2fe254210f68f1603b42162f031fbf51256f1465b36bc7769 +github.com/hashicorp/terraform,v0.12.13,h1:LACXUTZvAGf8W/6wehHjOgi6YEMN7ejDUpnpll2qbJ0=,4dbe6d0c15f4d934fd583fc20bec55326ffc79cf0d5b7fd28978ba14d178fe8d +github.com/hashicorp/terraform-config-inspect,v0.0.0-20190821133035-82a99dc22ef4,h1:fTkL0YwjohGyN7AqsDhz6bwcGBpT+xBqi3Qhpw58Juw=,1261dc9b65805f9be029f6a42d9e0ddccc89c4d0c50e5fa2895b1b53198195c3 +github.com/hashicorp/terraform-svchost,v0.0.0-20191011084731-65d371908596,h1:hjyO2JsNZUKT1ym+FAdlBEkGPevazYsmVgIMw7dVELg=,8055e9f82b0484eb70594ca682bcf4401d2286c2021ffc72c6c3b6ad9ac9a024 +github.com/hashicorp/vault,v1.2.0-rc1,h1:GFYP6ck5f0EaJsGMD4PARIX5HaHREUxMbTaVPy+dFEg=,89c84474c97b1400ca858fe1b6e0eb3bd91dac17a4aff4336bd95104381e8b2b +github.com/hashicorp/vault-plugin-auth-alicloud,v0.5.2-0.20190725165955-db428c1b0976,h1:f+r1gXVvQJ0+2pfxgBDP1zZUC6lUmPNM0xp7AKupyBg=,3bc95606713215c3ae25f9be06ed2186f8f2e5e9ad8e025fafd332d97045ed09 +github.com/hashicorp/vault-plugin-auth-azure,v0.5.2-0.20190725170003-0fc4bd518aa2,h1:Ua6AFhJYkdNGC5s4uDL7EGVBD/jPUOcnubDkPsaG7K8=,bfa988cf4a3e33e7db3caf2ecad55c2f7c2e3f39088243767927ac8ed8d2556e +github.com/hashicorp/vault-plugin-auth-centrify,v0.5.2-0.20190725170023-9d8d5e0b03e6,h1:UXM3yxzNaruvgaccRjFXKcKnsTTHzp213MJ045wto6A=,165cf5f7daa0e4c286bad12f09eeac648062554399f18890bf35789b6b16e9c7 +github.com/hashicorp/vault-plugin-auth-gcp,v0.5.2-0.20190725170032-0aa7d1c92039,h1:uqYbah1dntV8OccHCbY3bBzYX/zLtjmG0ZIZPV+x6EM=,e9f9ccc7ca02c40291bb27012f2dd1fead86d2de2ab85a6d07b0aa7d98533f49 +github.com/hashicorp/vault-plugin-auth-jwt,v0.5.2-0.20190725170041-1cfee03e8d3a,h1:zdhacnLMH4P47PdSPJo0omNh+IkSvPj0LbiHLQu0aVk=,2b04c80c6d2000558b63ced2c9ba60a4a2ffe4c76d2d58d5fe121f714a3cf291 +github.com/hashicorp/vault-plugin-auth-kubernetes,v0.5.2-0.20190725170047-354505be0ecf,h1:il4UUQC9zfsSRNR2EAQVqC+DzrvzZpFmJReQ7p6/bKw=,d95794ab78e644a95799a3505a83af58a83c6bf775e69832b3660ca47c042d5a +github.com/hashicorp/vault-plugin-auth-oci,v0.0.0-20190904175623-97c0c0187c5c,h1:z6LQZvs1OtoVy2XgbgNhiDgp0U62Xbstn7/cgNZvh6g=,b23f2afa7fab5368d83a01be865e2dddf7ba6c7e8804ac205ccc1701a9239d51 +github.com/hashicorp/vault-plugin-auth-pcf,v0.0.0-20190725170053-826a135618c1,h1:mPyQ1+jB/ztcqebEdmNhSuYq4XVOpB5TUyyi0118T40=,c444159df670a1aba7e59029bf928989091886fa45970f751fe644d243d43744 +github.com/hashicorp/vault-plugin-database-elasticsearch,v0.0.0-20190725170059-5c0d558eb59d,h1:VUD1T3aI5GL8uoSSDhHncHP8ksgepZsvSLhsRG8MJ3s=,b151c27f632b8e05686473b4936b480cec694498c1e446dc5208b4db05c559f1 +github.com/hashicorp/vault-plugin-secrets-ad,v0.5.3-0.20190725170108-e1b17ad0c772,h1:N219G3MUxPRhtOBMFVdsSQWU47MrvivSHLmTAPpHcs4=,c8801ee5f030fa6cb36045f1e321d964224f9a2b4a17100140cafca7a6d8daf5 +github.com/hashicorp/vault-plugin-secrets-alicloud,v0.5.2-0.20190725170114-7d66a3fa0600,h1:kyHR0JOKFDAaC4sjQ3iD1lTH6uaIfmTk4rQ+JOGW5Zo=,f816c029601c9e7235f798e9591246ac935d3b1e330abfb23af59afa6bc08e0d +github.com/hashicorp/vault-plugin-secrets-azure,v0.5.2-0.20190725170121-541440395211,h1:hZ21h0DWWKkoeMW7zkYaPVLxGZtKfYyIcE9G8xug4YQ=,5d71ad3ef26fd40b3afaf852913f38e5be0a1db8844bf21cb787e204cdbc48e4 +github.com/hashicorp/vault-plugin-secrets-gcp,v0.5.3-0.20190725170127-aa49df112140,h1:gSvWU9aYAsHxqKU0ohJD9njlNQ1/qLFPRs85u+xJFv4=,9b209e3ef7b8d7c41e823705cc190699540bbd2076f82344a83c106fa7e4ac98 +github.com/hashicorp/vault-plugin-secrets-gcpkms,v0.5.2-0.20190725170135-aaf270943731,h1:zP2vqetYhON59Mf5FTV9KmyKSnY1cLFzdNW0YYnNKbo=,5d3bc6de4bdad4725c4348a0d6861bce3e80a9eb13d4b05179cd663b47f46545 +github.com/hashicorp/vault-plugin-secrets-kv,v0.5.2-0.20190725170141-1c4dac87f383,h1:4IqT7JQt/GyYKr0HGemkUlYpF45ZALHSN9rHy7Sipos=,10f03c6d8a51714692b43ab69c2cb5f041ac611210aa9804237a9345e930f018 +github.com/hashicorp/vault/api,v1.0.4,h1:j08Or/wryXT4AcHj1oCbMd7IijXcKzYUGw59LGu9onU=,a885d16e067a5586e55914cd8e40f250a28fe94b3b864de47d495ad1f71c4251 +github.com/hashicorp/vault/sdk,v0.1.14-0.20190909201848-e0fbf9b652e2,h1:b65cSyZqljnCPzzsUXvR4P0eXypo1xahQyG809+IySk=,0aca8708570b724605514cab6dbbc9cc7bce5d27786a4b2da87553c437c42463 +github.com/hashicorp/vic,v1.5.1-0.20190403131502-bbfe86ec9443,h1:O/pT5C1Q3mVXMyuqg7yuAWUg/jMZR1/0QTzTRdNR6Uw=,9c09a35b14d797812e6714073471b3472c16f9cb4deb430f9e2dd15fa8d25e32 +github.com/hashicorp/yamux,v0.0.0-20190923154419-df201c70410d,h1:W+SIwDdl3+jXWeidYySAgzytE3piq6GumXeBjFBG67c=,d8a888d6a4ecbc09f2f3663cb47aa2d064298eeb1491f4761a43ae95e93ba035 +github.com/herenow/go-crate,v0.0.0-20190617151714-6f2215a33eca,h1:kk1qCxy+FS5McLJ69dSpB6Y6kHCMa23UwHyglIzJ/bk=,aa618858b9c03e47962afb2a4098ad6cca8ecd09904cdbc5eb62c5a1d74befca +github.com/hetznercloud/hcloud-go,v1.15.1,h1:G8Q+xyAqQ5IUY7yq4HKZgkabFa0S/VXJXq3TGCeT8JM=,028402928c1bc1db686cab5738e6fb91a61252c1236258e2d911dd8da21f8af5 +github.com/hinshun/vt10x,v0.0.0-20180616224451-1954e6464174,h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=,4afc77bd4950db746c68d23e6ed681d31cd952559d712c1400da476084567cf6 +github.com/hjfreyer/taglib-go,v0.0.0-20151027170453-0ef8bba9c41b,h1:Q4OOFmH18aIjnDJlvYm4BXmpHKXk1zTJP0QZ0otNwPs=,e7735f2cdbb7441dbe6bbc303cff9b9a20d9845dc901e31f6e29e3ef83613390 +github.com/howeyc/fsnotify,v0.9.0,h1:0gtV5JmOKH4A8SsFxG2BczSeXWWPvcMT0euZt5gDAxY=,a72f2f092433c8b53e095d6db3d3e18517db1a5a9814a78ed97194239145740f +github.com/howeyc/gopass,v0.0.0-20190910152052-7cb4b85ec19c,h1:aY2hhxLhjEAbfXOx2nRJxCXezC6CO2V/yN+OCr1srtk=,83560b6c9a6220bcbb4ad2f043e5a190ab11a013b77c1bbff9a3a67ed74d4b37 +github.com/hpcloud/tail,v1.0.0,h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=,3cba484748e2e2919d72663599b8cc6454058976fbca96f9ac78d84f195b922a +github.com/huandu/xstrings,v1.2.0,h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0=,fe7011ad569e464d6ff81bdb1d80c4ebdb5baac5c89d17c1644a23cac0c48828 +github.com/huin/goupnp,v1.0.0,h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo=,9685536729d9860766846ad4e56fb961b246d5afa209e4058ee0d021aec37827 +github.com/huin/goutil,v0.0.0-20170803182201-1ca381bf3150,h1:vlNjIqmUZ9CMAWsbURYl3a6wZbw7q5RHVvlXTNS/Bs8=,d887199bd2f388075ff7aaf1d3061b13b92c20e01ccd6337c864fd409fe78831 +github.com/hybridgroup/go-ardrone,v0.0.0-20140402002621-b9750d8d7b78,h1:7of6LJZ4LF9AvF4bTiMr2I72KxodBf1BXrSD9Tz0lWU=,997e0efef1b73cc1930ad67cd649268ff864393fa85dedf32672ecca78647021 +github.com/hybridgroup/mjpeg,v0.0.0-20140228234708-4680f319790e,h1:xCcwD5FOXul+j1dn8xD16nbrhJkkum/Cn+jTd/u1LhY=,d9134203da596f895c55c3a9fd0aea32ad26501ca88e646cbe9f82136f592c0f +github.com/hyperledger/fabric,v1.4.3,h1:6MmYhcDbxhd0TvpvHLR3c5m3fVjaX97690H8TRjpJNA=,067d2bd69094dc9f693d9b00c8bea810f61f6a8a3d0ac640830b468934e22023 +github.com/hyperonecom/h1-client-go,v0.0.0-20190122232013-cf38e8387775,h1:MIteIoIQ5nFoOmwEHPDsqng8d0dtKj3lCnQCwGvtxXc=,135625f81c1c6c62b296269829a74f1266928600545fedec0825cb97284264f6 +github.com/iancoleman/strcase,v0.0.0-20190422225806-e506e3ef7365,h1:ECW73yc9MY7935nNYXUkK7Dz17YuSUI9yqRqYS8aBww=,f93e74faf2e05699180c40ef21204629a1c6bd382658f1059c80631c377c5246 +github.com/ianlancetaylor/demangle,v0.0.0-20181102032728-5e5cf60278f6,h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=,73ae40ed96af2703f85cd4c552cf6b14551ceb782348be8185b730f44c842ab9 +github.com/iij/doapi,v0.0.0-20190504054126-0bbf12d6d7df,h1:MZf03xP9WdakyXhOWuAD5uPK3wHh96wCsqe3hCMKh8E=,7e33155961c2cba072047deb34d19a7d863a713e502abe8bdc31ab91424bd226 +github.com/ijc/Gotty,v0.0.0-20170406111628-a8b993ba6abd,h1:anPrsicrIi2ColgWTVPk+TrN42hJIWlfPHSBP9S0ZkM=,b8b9a99b3632feb3449d1fb8950d292333f8a7f494b182320ecdb0479d78442f +github.com/imdario/mergo,v0.3.8,h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=,579cad1ed913cfcb424deb97e7016749abcc9d585bad07d14f19550df052cec5 +github.com/imkira/go-interpol,v1.1.0,h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=,de5111f7694700ea056beeb7c1ca1a827075d423422f251076ee17bd869477d9 +github.com/improbable-eng/grpc-web,v0.9.1,h1:tenDg9Lg+zYXeS/ojbKyfwVO5TVYh5FFGsrXNAblF1o=,3a287ae758b41feea9f26ec1b8757628d4742b87376fa40b29d878ee651bfe62 +github.com/imroc/req,v0.2.3,h1:ElMCifcqg/1GonGloyyTUrj6D6IITL6EiNEKHUl4xZM=,951172f0969fa0bad31ebbe9b17699ea3909b09eaf8df39ccd78e48097682c78 +github.com/inconshreveable/go-update,v0.0.0-20160112193335-8152e7eb6ccf,h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=,adf856fb49e7c5059b2edb42a31daf4a536dc698fe0728835b018150a884b678 +github.com/inconshreveable/log15,v0.0.0-20180818164646-67afb5ed74ec,h1:CGkYB1Q7DSsH/ku+to+foV4agt2F2miquaLUgF6L178=,31875747bcd198c39714d38747ac77e585620f2f37d1b1e1a03b164af6762995 +github.com/inconshreveable/mousetrap,v1.0.0,h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=,c3fa0813e78f5cef10dc0e9912c43e68e06ff970a98e98c4050fe14dbbfd18c7 +github.com/influxdata/changelog,v1.1.0,h1:HXhmLZDrbuC+Ca5YX7g8B8cH5DmJpaOjd844d9Y7aTQ=,19e60d9b658aaecca4e075126c996c1abd5e369003c14bbe575edc4ba2b9c182 +github.com/influxdata/flux,v0.52.0,h1:R91uUXbHzoiyYF7Xhm+wP3a0iSnl43iYJrN93nBhuP0=,e0121889c46cc4ad22f1662e68df7dbdfbb361c3da6809add4d1409cef764be9 +github.com/influxdata/influxdb,v1.7.9,h1:uSeBTNO4rBkbp1Be5FKRsAmglM9nlx25TzVQRQt1An4=,b49a72374a14f726229e71152e74e8a132c2913137c4457f31bae8c7735e812c +github.com/influxdata/influxdb1-client,v0.0.0-20190809212627-fc22c7df067e,h1:txQltCyjXAqVVSZDArPEhUTg35hKwVIuXwtQo7eAMNQ=,fc41ea93bf2b06b231823b116dc11b0ed89badf1ce6a4c848a33c77dcf2c123a +github.com/influxdata/influxql,v1.0.1,h1:6PGG0SunRmptIMIreNRolhQ38Sq4qDfi2dS3BS1YD8Y=,2a697984d1cd82656f69901bfe1771676493411c1370d77271bde3ab3c917a1e +github.com/influxdata/line-protocol,v0.0.0-20180522152040-32c6aa80de5e,h1:/o3vQtpWJhvnIbXley4/jwzzqNeigJK9z+LZcJZ9zfM=,6111b5e459106f7003477186aa2e34423dbe0c53983944a07d8b835ff8c7757c +github.com/influxdata/promql/v2,v2.12.0,h1:kXn3p0D7zPw16rOtfDR+wo6aaiH8tSMfhPwONTxrlEc=,b928626f2eb81eed0046ef23a83a77a28dd140d369a0d2538c94e85d1055877f +github.com/influxdata/tdigest,v0.0.0-20181121200506-bf2b5ad3c0a9,h1:MHTrDWmQpHq/hkq+7cw9oYAt2PqUw52TZazRA0N7PGE=,5d6b056d98d1e7e9cd884aea4e73934cc8ea89218eb43ee1d5140d3ccb34ed52 +github.com/influxdb/influxdb,v1.7.9,h1:KMBwwvyJyBppIwrg5t0662p+Yei/ucnIkqUl8txiQdQ=,ad251d4cc00aec767465dc60d6b702a3635b68402123a4ee5d1ee2b5006310b3 +github.com/iotexproject/go-pkgs,v0.1.1,h1:AyWJf8jqOg4aMSrxi+MInFFBZhTvSm0LCu1o08heijk=,c5099edde7450b4f8b9a0f49c42697f5e9bcb92d2bf58395aa0681f3ef6b583d +github.com/iotexproject/iotex-address,v0.2.1,h1:ZJH2ajx5OBrbaRJ0ZWlWUo685zr5kjWijVjtmUrm42E=,53c7ce4d7fbc55ee79e92e9e0b31ee3b3ba0e6e5d3e24cd43e0a58c766568c9d +github.com/iotexproject/iotex-proto,v0.2.5,h1:SYdl9Lqb0LYfFf3sfw92fN8GY3bthfCvGmltz+2uvDQ=,546cb070e92286601aee16d03383712172061c8fe78e53cf04498a9358470a78 +github.com/ipfs/bbloom,v0.0.4,h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=,92993c175552cc626ef6b1ab6cf887f0f640311748c47e7615df29a966c1b774 +github.com/ipfs/go-bitswap,v0.1.3,h1:jAl9Z/TYObpGeGATUemnOZ7RYb0F/kzNVlhcYZesz+0=,ee26d57b2765f808ebebca8aa18695bfa02b738f47b4b5db5efce5c91f28fbcd +github.com/ipfs/go-block-format,v0.0.2,h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE=,02ad9fa29f97073ece45a5da7a92e59e6c6b856e9a03bd853361b8107296c020 +github.com/ipfs/go-blockservice,v0.1.2,h1:fqFeeu1EG0lGVrqUo+BVJv7LZV31I4ZsyNthCOMAJRc=,31c5ff02d71ee454bebea3944d7e06c2ffd6f1c4cfdddf71c5122e982f261c7d +github.com/ipfs/go-cid,v0.0.3,h1:UIAh32wymBpStoe83YCzwVQQ5Oy/H0FdxvUS6DJDzms=,f8bd60f8bbd79ed1fa5c8c113f6e17addb12257b0d925d3327ee7c25a7733591 +github.com/ipfs/go-datastore,v0.1.1,h1:F4k0TkTAZGLFzBOrVKDAvch6JZtuN4NHkfdcEZL50aI=,be724f5e3a459cf6ae9e68d2fa14e27cc92c53ae775979f2412b4f5b3f2b0336 +github.com/ipfs/go-detect-race,v0.0.1,h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk=,c00c97cacb355cb0569bee75775eff6b656d95dd7d0855ed97c2ee44666b72cd +github.com/ipfs/go-ds-badger,v0.0.7,h1:NMyh88Q50HG6/S2YD58DLkq0c0/ZQPMbSojONH+PRf4=,26a453fc19eb26fe6077f12310ff1ad7230fe31b31a0c17fb47abba75379ee61 +github.com/ipfs/go-ds-leveldb,v0.1.0,h1:OsCuIIh1LMTk4WIQ1UJH7e3j01qlOP+KWVhNS6lBDZY=,43085f79b999edef0b8b49dea1ed35d47cc1c453ef401634825c0be5b62ac6d9 +github.com/ipfs/go-hamt-ipld,v0.0.13,h1:Jbt5ALTYnrzbcOBka11kAkgn3auvkQBGkKWjGRsQrio=,e16acbc3f203616ccd9119415b9db28a6f18c72f053259842f7db50aa1193cf8 +github.com/ipfs/go-ipfs-blockstore,v0.1.0,h1:V1GZorHFUIB6YgTJQdq7mcaIpUfCM3fCyVi+MTo9O88=,19a45734b2615632b180b59032d39c04c50fc735c7f9fd27c5547b0facb4ef8f +github.com/ipfs/go-ipfs-blocksutil,v0.0.1,h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ=,3fcf4221d4d59af5807040f209ff0d28d81f6974d61ac279b43a44b2f46d8182 +github.com/ipfs/go-ipfs-chunker,v0.0.1,h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw=,02a0e4766162345a5bea8962c315b4bab8f2550aa1b760dcece96794b3ba22ef +github.com/ipfs/go-ipfs-config,v0.0.11,h1:5/4nas2CQXiKr2/MLxU24GDGTBvtstQIQezuk7ltOQQ=,e26bdd6db98c4ccf932440aa22a1aa2d550903a0f6f9da82f1ff5902ebbe260e +github.com/ipfs/go-ipfs-delay,v0.0.1,h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ=,bc3a4494d27cd7fabdeb7036e2edadd27f0edbd2b7d3cf49d14e3402c17c3ab6 +github.com/ipfs/go-ipfs-ds-help,v0.0.1,h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU=,52d0d886ebb65366abb35f19b76c4f6f349464eaedf092da95c661a451b2bf06 +github.com/ipfs/go-ipfs-exchange-interface,v0.0.1,h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM=,0a593df65586ff592255eb69923a43d413b24ad56454e14e94f5e722756fb102 +github.com/ipfs/go-ipfs-exchange-offline,v0.0.1,h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew=,04b69dc6dd34a2c5c2d1f0df8777fcaa8590aa528b960cc26178af6f609e29cf +github.com/ipfs/go-ipfs-files,v0.0.6,h1:sMRtPiSmDrTA2FEiFTtk1vWgO2Dkg7bxXKJ+s8/cDAc=,442fa790aba0beff3a79503064a35dceab2a29dc4ab8edcca690c7f61ef6c6c0 +github.com/ipfs/go-ipfs-flags,v0.0.1,h1:OH5cEkJYL0QgA+bvD55TNG9ud8HA2Nqaav47b2c/UJk=,61ac13bc74f89286ac30db2ce79b26adfba63a0676cbc430ad750df2d516565a +github.com/ipfs/go-ipfs-posinfo,v0.0.1,h1:Esoxj+1JgSjX0+ylc0hUmJCOv6V2vFoZiETLR6OtpRs=,149f52f33d8ffd4f82056b4ea1dae2f25024a2e8df0ff555789c549468d998e7 +github.com/ipfs/go-ipfs-pq,v0.0.1,h1:zgUotX8dcAB/w/HidJh1zzc1yFq6Vm8J7T2F4itj/RU=,4eda59f4f898933265b82d381cc1ea5a3d3c75752618f46496a2d150c09aeb2d +github.com/ipfs/go-ipfs-routing,v0.1.0,h1:gAJTT1cEeeLj6/DlLX6t+NxD9fQe2ymTO6qWRDI/HQQ=,e2281e568eed0ee5621886d28802eefd8a9d0806cbd1db80c01550ad59ec54c7 +github.com/ipfs/go-ipfs-util,v0.0.1,h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50=,6d3af4d6dcb95047b64fc74972cdcd84f199c6bad467a7de3543c3eaa0d4ee49 +github.com/ipfs/go-ipld-cbor,v0.0.3,h1:ENsxvybwkmke7Z/QJOmeJfoguj6GH3Y0YOaGrfy9Q0I=,4087b9930a8e2899c3540e61bd8e7f04c8bdd8670f68ddbfcf10f45a0e619cef +github.com/ipfs/go-ipld-format,v0.0.2,h1:OVAGlyYT6JPZ0pEfGntFPS40lfrDmaDbQwNHEY2G9Zs=,3da08ede588080b6ec81c5ad8fbfb1c9ea306a038be41dc06b1f3a1a101ebe50 +github.com/ipfs/go-log,v0.0.1,h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc=,9165a91716b11b432f8bf303d59fc019bf91872f1b9ca7e12d666c11ba6e6676 +github.com/ipfs/go-merkledag,v0.2.4,h1:ZSHQSe9BENfixUjT+MaLeHEeZGxrZQfgo3KT3SLosF8=,ed269e045c613cc7b9bba3593797fe09cdf84c906726bef9261c74bd8c470404 +github.com/ipfs/go-metrics-interface,v0.0.1,h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=,e83f0c01b084000492db0c0e1a28ff900c3f6d11eea8defdbe8bdd1a04c33fd0 +github.com/ipfs/go-mfs,v0.1.1,h1:tjYEWFIl0W6vRFuM/EnySHaaYzPmDcQWwTjtYWMGQ1A=,1db35113aff60e645544cc64cbbddbf0608332b1f2208615744098af59b97fee +github.com/ipfs/go-path,v0.0.7,h1:H06hKMquQ0aYtHiHryOMLpQC1qC3QwXwkahcEVD51Ho=,96c607c0253c24ed0cb37016007f34420a3a83c37cdd68b6d4391126418835c4 +github.com/ipfs/go-peertaskqueue,v0.1.1,h1:+gPjbI+V3NktXZOqJA1kzbms2pYmhjgQQal0MzZrOAY=,5fa92b0302d8e72e8c4d74517a68fad04c1d89d90f0a6314a5e30662dda5d359 +github.com/ipfs/go-unixfs,v0.2.2,h1:eTkDT9F0dn4qHmBMVRMZbziwyqLRcogjtPYqMgZYmQs=,77f7f6b2de604b592018dd914a6606084069d22efa70ea95e0dd623a04e4453c +github.com/ipfs/go-verifcid,v0.0.1,h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E=,1f808a29fcd38406325435c7a6a02b253aee28832704f0032600c2b41ef3b8f1 +github.com/ipfs/interface-go-ipfs-core,v0.2.4,h1:oQiJ3Mj3rqVJohdi316K3+VSyiADto3Z35ukj7z+UGg=,e1030de5fc1ee1868a87386708be313fc0fcbbe137d5a71d71f28621393f70a2 +github.com/ipfs/iptb,v1.4.0,h1:YFYTrCkLMRwk/35IMyC6+yjoQSHTEcNcefBStLJzgvo=,0b00d0279c700ad687cfbba073f504cc4c8a17ff731550c3784fcb3e24b0c6d5 +github.com/iris-contrib/blackfriday,v2.0.0+incompatible,h1:o5sHQHHm0ToHUlAJSTjW9UWicjJSDDauOOQ2AHuIVp4=,936679f49251da75fde84b8f38884dbce89747b96f8206f7a4675bfcc7dd165d +github.com/iris-contrib/formBinder,v5.0.0+incompatible,h1:jL+H+cCSEV8yzLwVbBI+tLRN/PpVatZtUZGK9ldi3bU=,6f1fef9e533a1f57a8b033f8c0a135ed038524d7535dd16ba22e9494e3096e3b +github.com/iris-contrib/go.uuid,v2.0.0+incompatible,h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE=,c6bae86643c2d6047c68c25226a1e75c5331c03466532ee6c943705743949bd9 +github.com/issue9/assert,v1.3.2,h1:IaTa37u4m1fUuTH9K9ldO5IONKVDXjLiUO1T9vj0OF0=,f4349cbd5af134fce10b399717aa4b455b5c73df6c20c1057c6e45973f24a06d +github.com/issue9/identicon,v0.0.0-20160320065130-d36b54562f4c,h1:A/PDn117UYld5mlxe58EpMguqpkeTMw5/FCo0ZPS/Ko=,5a837560a10469ab524b185a092edf67be85aff5ed794e1fcaaa084cf4540336 +github.com/itchio/arkive,v0.0.0-20190702114012-1bb6c7241ec3,h1:UcZnU7qzWTmZf8v7F3mC79H98I0b77pZz+99vqHFwtI=,dad4e3a988e6834d4ce1c3fb650a8dbb9aedd116ba8b3556c8f8babecdd17ead +github.com/itchio/dskompress,v0.0.0-20190702113811-5e6f499be697,h1:u3Q2WkrIPYlGEw4fjcImSOrkivWd6SVb0BF0Ehoih9c=,d8379b7e4219f001b61e5c2b3b34b2a6b69f8a55dc1acde2919be3050a7c84f5 +github.com/itchio/go-brotli,v0.0.0-20190702114328-3f28d645a45c,h1:Jf20xV/yR/O6eSUqLTuXhka/+54YR59sGwN7b3MkxYk=,6bab2adfb10a8ae7132e02ed10823df2e91c42dd08a1f3e1835679390ea69927 +github.com/itchio/headway,v0.0.0-20190702175331-a4c65c5306de,h1:RQW9xPqYtvjdHHRZR95XsaEA9B4URCuNHK78IuJcc+Y=,54e63fd6f25217e272e196f6213915515196a5b17a1923a666c05b4f49c82ef3 +github.com/itchio/httpkit,v0.0.0-20190702184704-639fe5edf1f1,h1:mViP/A8hAP04YWbbZR7Kcm7rTkUeT2HLcn3BBiK+CwM=,e56bf70a53a305f6866631d1272a3f3543abd45a68c50d202ddc80796b58c461 +github.com/itchio/kompress,v0.0.0-20190702090658-5e2558a00102,h1:QXEwRXrrx+7CxU+Y+G4GpDk4mUeHbP7grMXHhydk8qU=,cadec4996aed4026c0e0321f90b5bb11d9b8d1de3665752b2e862c6ddbfa229d +github.com/itchio/ox,v0.0.0-20190925154941-b613e528fc7d,h1:EcmVffUYduCSFCEM12YpSXoVXvyeq8Ro4Q+rwc60TIo=,81c3dfe8e91eb13815bf5b7f159f24a3cb1bd7028a395f691e9cefc1c3a71d01 +github.com/itchio/randsource,v0.0.0-20190702184213-a7635a4cb94b,h1:fG+9RlMeggMG/C2FH80HTfJmm+eOjAve2pFSv6Uio8A=,2375b07785c2738527c864dfb1bee0082b1f89c51e200157165bcd36f5c2933f +github.com/itchio/savior,v0.0.0-20190925162935-b92976a0b402,h1:a51wRxkLoJWu5NqnVDkI6cE50S0mDpJfOXkCp4ltvr8=,1454524a51fa6492ee593fb7d648dc037fec7c32d90e2d21c149b6e724a74838 +github.com/iwind/TeaGo,v0.0.0-20191007090339-daba0bb6607e,h1:bxD34HpyJWx6bnGdahZo6uN6XnuOvMa8LrzfC+eZqes=,bec78c179e2676d51bb1a07122896661d4ae7727d325e9fa91682361e0321161 +github.com/jackc/chunkreader,v1.0.0,h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=,e204c917e2652ffe047f5c8b031192757321f568654e3df8408bf04178df1408 +github.com/jackc/chunkreader/v2,v2.0.0,h1:DUwgMQuuPnS0rhMXenUtZpqZqrR/30NWY+qQvTpSvEs=,cae1df6cc4f52abdf31d9c7c9869714f5c2e2dddc8047eb6d335409489e76031 +github.com/jackc/fake,v0.0.0-20150926172116-812a484cc733,h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=,bf8b5b51ae03f572a70a0582dc663c5733bba9aca785d39bb0367797148e6d64 +github.com/jackc/pgconn,v1.0.1,h1:ZANo4pIkeHKIVD1cQMcxu8fwrwIICLblzi9HCjooZeQ=,4b7e033c80207f032275845f7d366b51b46e3434cafebd13599a351f01f68b86 +github.com/jackc/pgio,v1.0.0,h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=,1a83c03d53f6a40339364cafcbbabb44238203c79ca0c9b98bf582d0df0e0468 +github.com/jackc/pgmock,v0.0.0-20190831213851-13a1b77aafa2,h1:JVX6jT/XfzNqIjye4717ITLaNwV9mWbJx0dLCpcRzdA=,5d8117d8fb79d3a41998bec8dca93d450eba9edf3cf0b8c36881e0ea6140b406 +github.com/jackc/pgpassfile,v1.0.0,h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=,1cc79fb0b80f54b568afd3f4648dd1c349f746ad7c379df8d7f9e0eb1cac938b +github.com/jackc/pgproto3,v1.1.0,h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=,e3766bee50ed74e49a067b2c4797a2c69015cf104bf3f3624cd483a9e940b4ee +github.com/jackc/pgproto3/v2,v2.0.0,h1:FApgMJ/GtaXfI0s8Lvd0kaLaRwMOhs4VH92pwkwQQvU=,22635755552d1363817a9c9f192cf464034dfc31593e4975982a85de8295dcf4 +github.com/jackc/pgtype,v0.0.0-20190828014616-a8802b16cc59,h1:xOamcCJ9MFJTxR5bvw3ZXmiP8evQMohdt2VJ57C0W8Q=,30822259b27010e41850fde5f75166abc90028b9c57e2a77976cab119e01295f +github.com/jackc/pgx,v3.6.0+incompatible,h1:bJeo4JdVbDAW8KB2m8XkFeo8CPipREoG37BwEoKGz+Q=,07a0cc87069e38acac988cc48e5a6cfd1bfd02b4b843d0e8931e48bb8c25d821 +github.com/jackc/pgx/v4,v4.0.0-pre1.0.20190824185557-6972a5742186,h1:ZQM8qLT/E/CGD6XX0E6q9FAwxJYmWpJufzmLMaFuzgQ=,1782863d2118cd0e63cc50cca24bd79cbea5674bac3b798bf12148400590128d +github.com/jackc/puddle,v0.0.0-20190608224051-11cab39313c9,h1:KLBBPU++1T3DHtm1B1QaIHy80Vhu0wNMErIFCNgAL8Y=,a780306bb3ad76174eca1d83a6d925fb3f7a13981cda6249e51be64476c76f15 +github.com/jackmordaunt/icns,v0.0.0-20181231085925-4f16af745526,h1:NfuKjkj/Xc2z1xZIj+EmNCm5p1nKJPyw3F4E20usXvg=,06f511df7637fd1424b6f099d7ce7ecf7378e62adc9d13133ce7df419e51faf0 +github.com/jackpal/gateway,v1.0.5,h1:qzXWUJfuMdlLMtt0a3Dgt+xkWQiA5itDEITVJtuSwMc=,adab846630d73763e5a3b984c8264d6503c8cb0b2914df559dacd41f6380e4ef +github.com/jackpal/go-nat-pmp,v1.0.1,h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=,d7f2409f72895a01e0d11b457eac015dbcd94c2657f95d508e53867ca6b07db1 +github.com/jacobsa/crypto,v0.0.0-20190317225127-9f44e2d11115,h1:YuDUUFNM21CAbyPOpOP8BicaTD/0klJEKt5p8yuw+uY=,ec4d2a1fc28e1d99c68557e38cd77527df5a9f5090aa12876ab4aa6f9137a3d5 +github.com/jacobsa/oglematchers,v0.0.0-20150720000706-141901ea67cd,h1:9GCSedGjMcLZCrusBZuo4tyKLpKUPenUUqi34AkuFmA=,bcd70357107c45c3177c913b718624376b692d39672c157708fe2cd9aa78fcb5 +github.com/jacobsa/oglemock,v0.0.0-20150831005832-e94d794d06ff,h1:2xRHTvkpJ5zJmglXLRqHiZQNjUoOkhUyhTAhEQvPAWw=,5159f5f22d0e130b1fbfdbc96eb9d4653b32bd463439cb0f3c98e179de5daf80 +github.com/jacobsa/ogletest,v0.0.0-20170503003838-80d50a735a11,h1:BMb8s3ENQLt5ulwVIHVDWFHp8eIXmbfSExkvdn9qMXI=,69d96e3ea6e055d68ed46c0c1044a5dfa18064c9d45bc68d5946aa55e048af6b +github.com/jacobsa/reqtrace,v0.0.0-20150505043853-245c9e0234cb,h1:uSWBjJdMf47kQlXMwWEfmc864bA1wAC+Kl3ApryuG9Y=,a7efb54142e39f4acab39d22db692d5734f818723783646f6727269228deea83 +github.com/jaegertracing/jaeger,v1.14.0,h1:C0En+gfcxf3NsAriMAvQ6LcSFrQ5VQGXddqfty1EpTI=,5f6245d1b0c986c44cc37c7c950f3cf9c2cfd1e0d540905cd4fab9a164684ecd +github.com/jarcoal/httpmock,v1.0.4,h1:jp+dy/+nonJE4g4xbVtl9QdrUNbn6/3hDT5R4nDIZnA=,5c7d051f237633573a168713760758005724c268242484d982cb0c76dc3f3ee7 +github.com/jaytaylor/html2text,v0.0.0-20190408195923-01ec452cbe43,h1:jTkyeF7NZ5oIr0ESmcrpiDgAfoidCBF4F5kJhjtaRwE=,2369830967f1c18c382cbee77a510431b42275f1f368e3b5cbbdaa782ae24c0d +github.com/jbenet/go-base58,v0.0.0-20150317085156-6237cf65f3a6,h1:4zOlv2my+vf98jT1nQt4bT/yKWUImevYPJ2H344CloE=,e686d369d490d6728f6e63b1680db3b567c9e884545f8c47ca656f0d944299b7 +github.com/jbenet/go-cienv,v0.1.0,h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc=,3de5dadf2add50bf7fbdf88db4e6d008ba1848516585f7f9dfbf53cb6dc1705c +github.com/jbenet/go-context,v0.0.0-20150711004518-d14ea06fba99,h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=,4cd0955abeea43dc4b5a08b8769e696109e0376f2a113a9b8eff13cc90cac1c7 +github.com/jbenet/go-temp-err-catcher,v0.0.0-20150120210811-aac704a3f4f2,h1:vhC1OXXiT9R2pczegwz6moDvuRpggaroAXhPIseh57A=,9299671a264400f8f0e145da442aa3216394f324c50f045ef2ed2b898b3945c9 +github.com/jbenet/goprocess,v0.1.3,h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10=,026bb36c2d4316ad327f8b2e623f172c01140f699d57ec8609f702df5cdf021d +github.com/jcmturner/gofork,v1.0.0,h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8=,5e015dd9b038f1dded0b2ded77e529d2f6ba0bed228a98831af5a3610eefcb52 +github.com/jdcloud-api/jdcloud-sdk-go,v1.9.1-0.20190605102154-3d81a50ca961,h1:a2/K4HRhg31A5vafiz5yYiGMjaCxwRpyjJStfVquKds=,93754c3fe6c00591fcd499cf73ad7f66e4ed864619579ff726872a2f50b53dfa +github.com/jdkato/prose,v1.1.0,h1:LpvmDGwbKGTgdCH3a8VJL56sr7p/wOFPw/R4lM4PfFg=,4e07b4f2012b46465fcc262d907b1cb81699bc61e6fb7a59ee47ea262e4986d1 +github.com/jeffchao/backoff,v0.0.0-20140404060208-9d7fd7aa17f2,h1:mex1izRBCD+7WjieGgRdy7e651vD/lvB1bD9vNE/3K4=,e6daeed2ffbf793cbdab5e21e9ba47ced708e7c594d4155e1964109903bd199f +github.com/jefferai/isbadcipher,v0.0.0-20190226160619-51d2077c035f,h1:E87tDTVS5W65euzixn7clSzK66puSt1H4I5SC0EmHH4=,c438b15316e4af2487ba2c818288aa15ba19e39b3bf2f83651dcc9d451af6c5b +github.com/jefferai/jsonx,v1.0.0,h1:Xoz0ZbmkpBvED5W9W1B5B/zc3Oiq7oXqiW7iRV3B6EI=,e8ccf27ffc8d4560e7db02f8a1663fd4605c5996a025f90721f8157fde332be7 +github.com/jellevandenhooff/dkim,v0.0.0-20150330215556-f50fe3d243e1,h1:ujPKutqRlJtcfWk6toYVYagwra7HQHbXOaS171b4Tg8=,8a3ba94d93fb61070bee24ffca5043eb32b4a6aafa9b84e4950a5f8f34328659 +github.com/jessevdk/go-flags,v1.4.0,h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=,a26e72c3f4c220df8b65ac6eb3d358a8ad2efc300b212318582893ea882726f9 +github.com/jfrazelle/go,v1.5.1-1,h1:EJWkn/L/VOoena+VQryO7xEkxz7J6lHvPXAe+Z3Q6Gc=,ff67181f47086da85e0d0896aeffb52142f6f45bd3bbf75b94cd7546365bf140 +github.com/jfrog/gofrog,v1.0.5,h1:pEJmKZ9XgvQH2a8WCqAEeUDSXBCKBMN90QzOiOhBTIs=,bb6267655de882922977dca0860020c4c781bf7b3d6aba3fddc206a21c13784c +github.com/jfrog/jfrog-client-go,v0.5.5,h1:dYoajyMXcmc13YpZ/NLye0KL7r+QfpP9l8+WriZNZbE=,3d62cf613d821eb41b8b62ff01e09d8d4eed781f4deb52d3dd96e5a636967732 +github.com/jhump/protoreflect,v1.5.0,h1:NgpVT+dX71c8hZnxHof2M7QDK7QtohIJ7DYycjnkyfc=,a6f0926d31ed98d63d04f2aa60a5579cca471e7544cb701202ba5a5fd3134256 +github.com/jimstudt/http-authentication,v0.0.0-20140401203705-3eca13d6893a,h1:BcF8coBl0QFVhe8vAMMlD+CV8EISiu9MGKLoj6ZEyJA=,0bcf35e1ca69658b70fe05050f436b18ae141a08863cf6011afb39edef5c4013 +github.com/jinzhu/copier,v0.0.0-20190924061706-b57f9002281a,h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=,c05742c031370bace7c0d5b4101d437e59ad4613bb707fda49c365b3e6af8ad2 +github.com/jinzhu/gorm,v1.9.11,h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE=,87f36225e1108c93f299d9b7e4cda23c2f9469ce3db0de59df90691c1e740565 +github.com/jinzhu/inflection,v1.0.0,h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=,cf1087a6f6653ed5f366f85cf0110bbbf581d4e9bc8a4d1a9b56765d94b546c3 +github.com/jinzhu/now,v1.0.1,h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=,5900b34a1d8daa959798e342e684c4237f60ffaebd1aa4201e29a7d3a98d32b7 +github.com/jlaffaye/ftp,v0.0.0-20190126081051-8019e6774408,h1:9AeqmB6KVEJ7GQU985MGQc7Mtxz1+C+JZkgqBnUWqMU=,b1b8b0e10084219eaf1a829778c1b53c049eeb77249a5660b62291cc3b454e6b +github.com/jmcvetta/neoism,v1.3.1,h1:GCFSl/90OYwEQH5LML/Vy6UlwK4SZ2OIO278UI4K7DE=,93e9ce5946ab71d9d0970e3709716a2b9cc96b4d03cfc708dfba8f062e870885 +github.com/jmcvetta/randutil,v0.0.0-20150817122601-2bb1b664bcff,h1:6NvhExg4omUC9NfA+l4Oq3ibNNeJUdiAF3iBVB0PlDk=,742cb157c8eb74da05a7972de646034cf0ddaba7c89d8aac625ed73027e778c1 +github.com/jmespath/go-jmespath,v0.0.0-20180206201540-c2b33e8439af,h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=,5c18f15c2bcfbbdb4fd15c0598ea5d3a373991a7b46a8f2405d00ac8b6121629 +github.com/jmhodges/clock,v0.0.0-20160418191101-880ee4c33548,h1:dYTbLf4m0a5u0KLmPfB6mgxbcV7588bOCx79hxa5Sr4=,f66a541ce3f97b4696d65282a332e8d08dee3f15271b7c2066050aeb5b7334b7 +github.com/jmhodges/levigo,v1.0.0,h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U=,7f43feb409c9650336152a959d7dc4d8e5a260c92e0212b1d2e0f0a7d3de6d87 +github.com/jmoiron/sqlx,v1.2.0,h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=,c8000fe80e86eea575e0d3dd0737f6399c1880a420ce2a9d833ca0e0cfc9c875 +github.com/joefitzgerald/rainbow-reporter,v0.1.0,h1:AuMG652zjdzI0YCCnXAqATtRBpGXMcAnrajcaTrSeuo=,889ea7a751c043bd0ea0ee31734011938be19ecbf08e652d53fc41f3eade9435 +github.com/joeshaw/multierror,v0.0.0-20140124173710-69b34d4ec901,h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4=,e31f735c5f42ac65aef51a70ba1a32b5ac34067a7ba0624192dd41e5ea03aa1e +github.com/joho/godotenv,v1.3.0,h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=,acef5a394fbd1193f52d0d19690b0bfe82728d18dd3bf67730dc5031c22d563f +github.com/jonas-p/go-shp,v0.1.1,h1:LY81nN67DBCz6VNFn2kS64CjmnDo9IP8rmSkTvhO9jE=,ac1706c486b7ea7e83eecd1f773259098569d2fe3ad2a53cc32ff89a68915a8f +github.com/jonboulle/clockwork,v0.1.0,h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=,930d355d1ced60a668bcbca6154bb5671120ba11a34119505d1c0677f7bbbf97 +github.com/joncalhoun/qson,v0.0.0-20170526102502-8a9cab3a62b1,h1:lnrOS18wZBYrzdDmnUeg1OVk+kQ3rxG8mZWU89DpMIA=,062b14a6986be3fb833eb9dd907acb7e563d5b6cfcaee1a04120a9b1fcc2d451 +github.com/josephspurrier/goversioninfo,v0.0.0-20190124120936-8611f5a5ff3f,h1:wBb8/KQrr2tWYffdugrpxOdWyOPSBRNzAR76aF9Nn3Y=,50be4b48f9fb8fbe79a013a791c015c13d7294c5de8f9bee586eaadd6f479459 +github.com/joyent/triton-go,v0.0.0-20190112182421-51ffac552869,h1:BvV6PYcRz0yGnWXNZrd5wginNT1GfFfPvvWpPbjfFL8=,5e875a04efd7f844211b68657d21313ae16b479cb01dc7161811c2c39ac19b18 +github.com/jpillora/backoff,v1.0.0,h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=,f856692c725143c49b9cceabfbca8bc93d3dbde84a0aaa53fb26ed3774c220cc +github.com/jrick/logrotate,v1.0.0,h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=,b87ee434f9e2cfda719b639cd5bd0a52523f920f64d23336f88070e9d3765d54 +github.com/jsimonetti/rtnetlink,v0.0.0-20190606172950-9527aa82566a,h1:84IpUNXj4mCR9CuCEvSiCArMbzr/TMbuPIadKDwypkI=,97d995d4ca858da8955aefcead01425d12a91188d6f9b36b5cb63aa35a4ea674 +github.com/json-iterator/go,v1.1.8,h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=,0de8f316729fb05ba608361323b178aa32944154e77aa208ad2818848b0628e2 +github.com/jstemmer/go-junit-report,v0.0.0-20190106144839-af01ea7f8024,h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc=,b623acfae0dcc440f81ae14f3c5bc3ca40b1a674660ad549127980f892ab165e +github.com/jteeuwen/go-bindata,v3.0.7+incompatible,h1:91Uy4d9SYVr1kyTJ15wJsog+esAZZl7JmEfTkwmhJts=,03f794b47c49da98a4eab6c3a7cc49d286f012d64ab832f783b76b9fcd3bd8b2 +github.com/jtolds/gls,v4.20.0+incompatible,h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=,2f51f8cb610e846dc4bd9b3c0fbf6bebab24bb06d866db7804e123a61b0bd9ec +github.com/jtolds/go-luar,v0.0.0-20170419063437-0786921db8c0,h1:UyVaeqfY1fLPMt1iUTaWsxUNxYAzZVyK+7G+a3sRfhk=,1ed97930b5dfc7f89c84ff3c5ea5a7de9964ccca970f45853d42a13a138b644e +github.com/jtolds/monkit-hw,v0.0.0-20190108155550-0f753668cf20,h1:XK96humQhnPbQ24uKtSHKbdShDgrKYqlWBNKJTcIKbg=,5d84e6f3f559b67e00b08a5e93e1017866695a4590b97ccb23a82e3ce792ad04 +github.com/juju/ansiterm,v0.0.0-20180109212912-720a0952cc2a,h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=,17d1e05fd6f1c8fdce7ba7495af54f4dac1e155febff56bd6450593b016655c2 +github.com/juju/clock,v0.0.0-20190205081909-9c5c9712527c,h1:3UvYABOQRhJAApj9MdCN+Ydv841ETSoy6xLzdmmr/9A=,f57579c0c104add5228b279c4673f592d5756033d33b085185ef72a3d2f83bfe +github.com/juju/cmd,v0.0.0-20190815094254-0c5c82a8dfc6,h1:rPqkdymtMRLcCSYKOeIxuw5mmd8dWx8jSq+t9EGBgtA=,c603f2311cf6524a74535eb9d416a83959c03e6ad52ab4ec081cbc7343734af6 +github.com/juju/collections,v0.0.0-20180717171555-9be91dc79b7c,h1:m/Uo8B7nrH3K6nvk66Y67T7cbHcyY101rW24vGuMON8=,18275066d75835f37845565980c0ac818f9c29145f756b1eeacb6496dac3ebd3 +github.com/juju/errors,v0.0.0-20190930114154-d42613fe1ab9,h1:hJix6idebFclqlfZCHE7EUX7uqLCyb70nHNHH1XKGBg=,2519c885f89cfba663da3bd9a1ff2532e3ae948bdea3e44b42603d8f91cc0796 +github.com/juju/gnuflag,v0.0.0-20171113085948-2ce1bb71843d,h1:c93kUJDtVAXFEhsCh5jSxyOJmFHuzcihnslQiX8Urwo=,47cdfb1bf94a2719e97e03caf4e0dc1cb89ba27c35ed7ce7020701fe8ee2c353 +github.com/juju/gojsonpointer,v0.0.0-20150204194629-afe8b77aa08f,h1:QzpKmMsaP06HVZnYNlcy1CLIXPytsj2NuzfCHitxuus=,0e75303c5dc230f30a629963589376030c3c2a1152a40b9e2075a084224eb173 +github.com/juju/gojsonreference,v0.0.0-20150204194633-f0d24ac5ee33,h1:huRsqE0iXmVPTML75YvFBOiaNj4ZiCZgKVnkRQ06d3w=,d1648b2f71dfbb02acc4a18c55711c721e0f6b50a5280d852cd9c0a639e8ebe6 +github.com/juju/gojsonschema,v0.0.0-20150312170016-e1ad140384f2,h1:VqIDC6dRE0C7wEtTdT6zx2zP5omaoJiZXp2g/dBHRcE=,a9f736e7cb462ccf3b2cb03aa8a133db13dc8d938a2753329a7a1274bdca2656 +github.com/juju/httpprof,v0.0.0-20141217160036-14bf14c30767,h1:COsaGcfAONDdIDnGS8yFdxOyReP7zKQEr7jFzCHKDkM=,9a8c77f887765536c312c89d73d7568126393c7d38c473a50addbec30f8c80ec +github.com/juju/httprequest,v2.0.0+incompatible,h1:+WtiSbRkEwdqKRBi+4JH8PTdNxBa/h8U8RIzdYaMENI=,0d2ae765c01f7956da6896b7c7d8bb1ad4065e960b93c09a644e2e61a0acaa52 +github.com/juju/jsonschema,v0.0.0-20161102181919-a0ef8b74ebcf,h1:SGTxyCG74uh2dYdBJCUJOo2FSx0fRHP7nMRH7s5JVeQ=,a5681c88d87b34d10dcf701b10d149303fa6d152ee224dc1bd7bd7680da80bfa +github.com/juju/loggo,v0.0.0-20190526231331-6e530bcce5d8,h1:UUHMLvzt/31azWTN/ifGWef4WUqvXk0iRqdhdy/2uzI=,3db058c07ced25b8689f5d3e462d344ffb965c6f371eabc0396ce94d927e6206 +github.com/juju/lru,v0.0.0-20190314140547-92a0afabdc41,h1:/ucixsNZ+l94agL5LZioJ4ECyOz7kOYY+DKb/0NN6ME=,8f41907249beb66ba4dee5df1f53c37f387506e21568cc89db4b72493b970e85 +github.com/juju/os,v0.0.0-20191022170002-da411304426c,h1:iJZl5krsl2AqkgU7IiJ2/jNAchctLFa3BiKdyOUvK+g=,b236cb3d90b3fae0f83e767feef3a17b472ab0fe238ac08810c4f9c1d683c14d +github.com/juju/proxy,v0.0.0-20180523025733-5f8741c297b4,h1:y2eoq0Uof/dWLAXRyKKGOJuF0TEkauPscQI7Q1XQqvM=,443cd58a22392e66576d883b9d04c17faebafa37a406a346b671f7e994436c34 +github.com/juju/pubsub,v0.0.0-20190419131051-c1f7536b9cc6,h1:2aARJxmMC2IF9GqVtt5PYcIy4jyuAcR44byqwXKTK0o=,b908f7985f6250270708c2c46ca0ccfc17a3705fea4a27da6f1277a9f6b5404c +github.com/juju/qthttptest,v0.0.1,h1:pR8nTl6Uo/iI6/ynQf5Cxy9FEICXzaa83NtrBdGMCVQ=,4ba292a46e27af468c181118214f7eb1bfc015f289e90841d7746b954f20ba49 +github.com/juju/ratelimit,v1.0.1,h1:+7AIFJVQ0EQgq/K9+0Krm7m530Du7tIz0METWzN0RgY=,c9af5c6719ce3b6912579a029cb2a651707aa25daa1921488f9cae9c4f8ed334 +github.com/juju/retry,v0.0.0-20180821225755-9058e192b216,h1:/eQL7EJQKFHByJe3DeE8Z36yqManj9UY5zppDoQi4FU=,c5b2437ff128cf13f2d6f3cc3b7e226f2c0119e22caed286946245150b9428e7 +github.com/juju/schema,v1.0.0,h1:sZvJ7iQXHhMw/lJ4YfUmq+fe7R2ZSUzZzd/eSokaB3M=,746bcab557bed4e05456419e5012573dc8481dc8740309100e4bd901ff282a39 +github.com/juju/testing,v0.0.0-20191001232224-ce9dec17d28b,h1:Rrp0ByJXEjhREMPGTt3aWYjoIsUGCbt21ekbeJcTWv0=,317de254f343f9aff6e1226b4ea225cab92fee84667db8e72d541667715ea610 +github.com/juju/txn,v0.0.0-20190612234757-afeb83d59782,h1:FcaMWAFKHuxS7UAaB/GuLWrqI9L7f20m6aXaxg+t5lY=,4656c1c5f0e3dac641999feba77879c7206aff1d606513d7bdb3be7d17a6635c +github.com/juju/utils,v0.0.0-20180820210520-bf9cc5bdd62d,h1:irPlN9z5VCe6BTsqVsxheCZH99OFSmqSVyTigW4mEoY=,8edd8a74c692eb717156a2bb689e1e24a446656677760dc7dc06b761ee451df5 +github.com/juju/version,v0.0.0-20180108022336-b64dbd566305,h1:lQxPJ1URr2fjsKnJRt/BxiIxjLt9IKGvS+0injMHbag=,73312c50c8b4f6f8644aaccc09b71a2235c8083cfc6c99425540f3c0a3c29e64 +github.com/juju/webbrowser,v1.0.0,h1:JLdmbFtCGY6Qf2jmS6bVaenJFGIFkdF1/BjUm76af78=,7b38f053656e4a883bc122589994e4ec34eae3f833e899450650752d5b72eec8 +github.com/juliangruber/go-intersect,v1.0.0,h1:0XNPNaEoPd7PZljVNZLk4qrRkR153Sjk2ZL1426zFQ0=,e7f539e6b13470da34009d3ab44c6ba84a6b9bb9f6e92d315551919287a25e3c +github.com/julienschmidt/httprouter,v1.3.0,h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=,e457dccd7015f340664e3b8cfd41997471382da2f4a743ee55be539abc6ca1f9 +github.com/jung-kurt/gofpdf,v1.0.3-0.20190309125859-24315acbbda5,h1:PJr+ZMXIecYc1Ey2zucXdR73SMBtgjPgwa31099IMv0=,f0fa70ade137185bbff2f016831a2a456eaadc8d14bc7bf24f0229211820c078 +github.com/justinas/alice,v0.0.0-20171023064455-03f45bd4b7da,h1:5y58+OCjoHCYB8182mpf/dEsq0vwTKPOo4zGfH0xW9A=,3d6623831901bb973db882bbaffcff3f55849724100ee72c5bf8d0fdfa927ae4 +github.com/jzelinskie/whirlpool,v0.0.0-20170603002051-c19460b8caa6,h1:RyOL4+OIUc6u5ac2LclitlZvFES6k+sg18fBMfxFUUs=,ca0115fcfaaa03f1973f65d05c6d6aefdbdeca6507cdda4359fdf55fd0be2c48 +github.com/k0kubun/colorstring,v0.0.0-20150214042306-9440f1994b88,h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=,32a2eac0ffb69c6882b32ccfcdd76968cb9dfee9d9dc3d469fc405775399167c +github.com/k0kubun/pp,v3.0.1+incompatible,h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40=,2b91f559df17a49554094e4befd7e1c7d32ba4519417b1b36796d9b49d7328c5 +github.com/kami-zh/go-capturer,v0.0.0-20171211120116-e492ea43421d,h1:cVtBfNW5XTHiKQe7jDaDBSh/EVM4XLPutLAGboIXuM0=,fb1ef7d18f4cec39e9115fb200fbf7d5cff65674afe6ecc63ad57d413f503830 +github.com/kamilsk/retry/v4,v4.3.1,h1:hNQmK1xAgybAVsadNAGvCNutFLS2h+Ycpw317u4d+i0=,74181d82f9bba5b7c313c6b338f127668fffbede70f5495a4a2ef8fddaa6c20f +github.com/kardianos/osext,v0.0.0-20190222173326-2bc1f35cddc0,h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=,10976c39b58f218a6e29687d19763845e7650d04ac86096cd67ace58f4e56346 +github.com/karrick/godirwalk,v1.13.0,h1:GJq8GHQEAPsjwqfGhLNXBO5P0dS2HYdDRVWe+P4E/EQ=,9652ac9eb85bf13594ba9c41a86864ec5236e429a65f6bbb19c6897d1e335092 +github.com/kataras/golog,v0.0.9,h1:J7Dl82843nbKQDrQM/abbNJZvQjS6PfmkkffhOTXEpM=,bb4d1476d5cbe33088190116a5af7b355fd62858127a8ea9d30d77701279350e +github.com/kataras/iris,v11.1.1+incompatible,h1:c2iRKvKLpTYMXKdVB8YP/+A67NtZFt9kFFy+ZwBhWD0=,9aba6b1128d42ee2b63a9319e28c1b665b7e82dde1b10763ee7510bcc6427a25 +github.com/kataras/pio,v0.0.0-20190103105442-ea782b38602d,h1:V5Rs9ztEWdp58oayPq/ulmlqJJZeJP6pP79uP3qjcao=,70a50855f07ff59d96db9633a0cf729280a8b9f7af72b936fe8a28e48406432f +github.com/kavu/go_reuseport,v1.4.0,h1:YIp/96RZ3sJfn0LN+FFkkXIq3H3dfVOdRUtNejhDcxc=,b08d4f774766e1136fd256484f2584d42cd568b5edc7dbc7b19e1259b5dbb75c +github.com/kballard/go-shellquote,v0.0.0-20180428030007-95032a82bc51,h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=,ae4cb7b097dc4eb0c248dff00ed3bbf0f36984c4162ad1d615266084e58bd6cc +github.com/kellydunn/golang-geo,v0.7.0,h1:A5j0/BvNgGwY6Yb6inXQxzYwlPHc6WVZR+MrarZYNNg=,4f4699636a450e20bd107fb81894fcdcc8ceeddbac7062e9457c67326c1fb036 +github.com/kelseyhightower/envconfig,v1.4.0,h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=,af674112c38290862e5f59fc2867b81f7b0e623ec2fd1465cd3812e538b351d3 +github.com/kennygrant/sanitize,v1.2.4,h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=,733211913a22ff6eb5843455345fde8c0c3cff25cc5e8e8225c330fb4c6a72df +github.com/kevinburke/ssh_config,v0.0.0-20190725054713-01f96b0aa0cd,h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=,ebd98d4bfd0deb1825d9a54689560b42a17d87385222971117ad72e7ad2f36fa +github.com/keybase/go-crypto,v0.0.0-20190403132359-d65b6b94177f,h1:Gsc9mVHLRqBjMgdQCghN9NObCcRncDqxJvBvEaIIQEo=,a839bacd8eb0a61a72f84678d568d8df899b512510a326e06db0f191e8c1c5a1 +github.com/kisielk/errcheck,v1.2.0,h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E=,709eeca978804f41720a94bc69ee3cfa8277f7d15016478a3ebda86606a286c5 +github.com/kisielk/gotool,v1.0.0,h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=,089dbba6e3aa09944fdb40d72acc86694e8bdde01cfc0f40fe0248309eb80a3f +github.com/kisielk/sqlstruct,v0.0.0-20150923205031-648daed35d49,h1:o/c0aWEP/m6n61xlYW2QP4t9424qlJOsxugn5Zds2Rg=,dbff9241f676de69e88bc006004da6087576433457b306f53cb952d0313ccb78 +github.com/kisom/goutils,v1.1.0,h1:z4HEOgAnFq+e1+O4QdVsyDPatJDu5Ei/7w7DRbYjsIA=,a0b58731f8e1144c013107294885891c44b7fd3235da0ec20776f4d644b4eaa4 +github.com/kkdai/bstream,v1.0.0,h1:Se5gHwgp2VT2uHfDrkbbgbgEvV9cimLELwrPJctSjg8=,dc1d546e0df6ef040963bc9d483834d6e56c77e0e4f6c48e574ac360e7723121 +github.com/klauspost/compress,v1.8.2,h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs=,4dc2632696a9cd93cc32c1564e1a6aa4aecfcb5c995a077d45c6f92116e1711d +github.com/klauspost/cpuid,v1.2.1,h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=,8367d6c97e74f88b149ba9de708ff321273e0114aeb71a45e62e5ac296412420 +github.com/klauspost/crc32,v0.0.0-20161016154125-cb6bfca970f6,h1:KAZ1BW2TCmT6PRihDPpocIy1QTtsAsrx6TneU/4+CMg=,6b632853a19f039138f251f94dbbdfdb72809adc3a02da08e4301d3d48275b06 +github.com/klauspost/pgzip,v1.2.1,h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=,a482336aa4b0e4e9368b15d75629ae741b44ef290b7d16430ba05ce561846213 +github.com/klauspost/reedsolomon,v1.9.2,h1:E9CMS2Pqbv+C7tsrYad4YC9MfhnMVWhMRsTi7U0UB18=,ea8a4d6d994088dae0308843fd6bddb7541cf36306463a696fd4a29097496705 +github.com/knative/pkg,v0.0.0-20191031171713-d4ce00139499,h1:ha5eqzJaPg1CZroomqWxHqspOqpqpRMO3fDtgF1fvIM=,a8d19fc2196a1aec7869ca45df44ba9c5de5b81b6094f0579d25989eb7967660 +github.com/kniren/gota,v0.9.0,h1:ywFrdNxkBD5Xypk5BxjCaKiH507oQVXIf31pTvRhC4I=,062182a345c456c9c0fd7ce9644900708f7f9c08707d64fe2438b9d295dad6dd +github.com/knq/sysutil,v0.0.0-20191005231841-15668db23d08,h1:V0an7KRw92wmJysvFvtqtKMAPmvS5O0jtB0nYo6t+gs=,81ec4ac93dba6a6161264a0575f20235d8932abab0cd6b9777b4be936f5c2af5 +github.com/knqyf263/berkeleydb,v0.0.0-20190501065933-fafe01fb9662,h1:UGS0RbPHwXJkq8tcba8OD0nvVUWLf2h7uUJznuHPPB0=,1e575b5fdc170e0318ab06841873ae6d115978fbaffc3779290d7ba3aadbdf0e +github.com/knqyf263/go-deb-version,v0.0.0-20190517075300-09fca494f03d,h1:X4cedH4Kn3JPupAwwWuo4AzYp16P0OyLO9d7OnMZc/c=,4a09d0533768cf6f9d929858aa2e79b6942685569c2db00b8d4688590a89ba3d +github.com/knqyf263/go-rpmdb,v0.0.0-20190501070121-10a1c42a10dc,h1:pumO9pqmRAjvic6oove22RGh9wDZQnj96XQjJSbSEPs=,33a3568289d22672dfcb0ba7c5b8aa7f9223d5303003368e7dbe8c9718a803b4 +github.com/knqyf263/nested,v0.0.1,h1:Sv26CegUMhjt19zqbBKntjwESdxe5hxVPSk0+AKjdUc=,c0e123844a174b1e9929d4368d8a8bb2f5ecef578ee9dee692c5971a47a633ff +github.com/koki/structurederrors,v0.0.0-20180506174113-6b997eb5e2ca,h1:KmXUVzyPjXzd3kY0feNFsWOGVDYFT4MjjgG8QJx0m6k=,1efa717c181722fd1c6807919571dc559b48d17120f5eeb4638a322fb882411a +github.com/kolo/xmlrpc,v0.0.0-20190717152603-07c4ee3fd181,h1:TrxPzApUukas24OMMVDUMlCs1XCExJtnGaDEiIAR4oQ=,9d37c94f50784536aa8ef9a7623ec7bcac9e5bc67b18f7a801efc7cbbe6b1ab0 +github.com/konsorten/go-windows-terminal-sequences,v1.0.2,h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=,4d00d71b8de60bcaf454f8f867210ebcd05e75c0a7c2725904f71aa2f20fb08e +github.com/koron/go-ssdp,v0.0.0-20180514024734-4a0ed625a78b,h1:wxtKgYHEncAU00muMD06dzLiahtGM1eouRNOzVV7tdQ=,3a99f050b7a668291942cada4e38213965fa0ae3794469bb29ad0d6d9677db23 +github.com/kr/fs,v0.1.0,h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=,d376bd98e81aea34585fc3b04bab76363e9e87cde69383964e57e9779f2af81e +github.com/kr/logfmt,v0.0.0-20140226030751-b84e30acd515,h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=,ebd95653aaca6182184a1b9b309a65d55eb4c7c833c5e790aee11efd73d4722c +github.com/kr/pretty,v0.1.0,h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=,06063d21457e06dc2aba4a5bd09771147ec3d8ab40b224f26e55c5a76089ca43 +github.com/kr/pty,v1.1.8,h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI=,d66e6fbc65e772289a7ff8c58ab2cdfb886253053b0cea11ba3ca1738b2d6bc6 +github.com/kr/text,v0.1.0,h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=,9363a4c8f1f3387a36014de51b477b831a13981fc59a5665f9d21609bea9e77c +github.com/kshvakov/clickhouse,v1.3.4,h1:p/yqvOmeDRH+KyCH6NtwExelr4rimLBBfKW2a/wBN94=,01a0d1a90e0545da94350319a52c051257fee64c838e2632ec40ef8d89a2f153 +github.com/kylelemons/go-gypsy,v0.0.0-20160905020020-08cad365cd28,h1:mkl3tvPHIuPaWsLtmHTybJeoVEW7cbePK73Ir8VtruA=,321087246482a680bd3f06de64075fb843430da544596ad216a4a63d5b8dafa3 +github.com/kylelemons/godebug,v1.1.0,h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=,dbbd0ce8c2f4932bb03704d73026b21af12bd68d5b8f4798dbf10a487a2b6d13 +github.com/kyokomi/emoji,v2.1.0+incompatible,h1:+DYU2RgpI6OHG4oQkM5KlqD3Wd3UPEsX8jamTo1Mp6o=,0721a2fc643e49e002bd8a3e604b5d2f0f3e242cc279d14d76f90a55f8aeebf7 +github.com/labbsr0x/bindman-dns-webhook,v1.0.2,h1:I7ITbmQPAVwrDdhd6dHKi+MYJTJqPCK0jE6YNBAevnk=,d1a327ab22f62486250f50f98990c0d9e1a5fdece6a496fbbb85d4e123df3244 +github.com/labbsr0x/goh,v1.0.1,h1:97aBJkDjpyBZGPbQuOK5/gHcSFbcr5aRsq3RSRJFpPk=,84c91135623961c7c400bf8b646da76c0ce2941fe8706d5aef5650be9a5e37dd +github.com/labstack/echo,v3.3.10+incompatible,h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=,29634743cf44c47079b74812ecf5aa7074630507886c4ff40b60c397c45af524 +github.com/labstack/gommon,v0.3.0,h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0=,2783ed1c24d09a5539bc35954f71f41d270d78dc656be256c98a8ede2cbbe451 +github.com/lafriks/xormstore,v1.0.0,h1:P/IJzNSIpjXl/Up3o2Td5ZU/x4v6DEKLMaPQJGtmJCk=,0e347e24ab91f62e1b69bab5d78cbba77569f087b483569ef37761e1f93a3f46 +github.com/lann/builder,v0.0.0-20180802200727-47ae307949d0,h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=,1fe7a88079ff2bbe90fb4724fb5c353ecb6af4cd7e011440354c804f678895ee +github.com/lann/ps,v0.0.0-20150810152359-62de8c46ede0,h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=,76756d46634f44edd3facdb01e7271ddf23a1b51a8423de55d3a2bf685ff032a +github.com/leanovate/gopter,v0.2.4,h1:U4YLBggDFhJdqQsG4Na2zX7joVTky9vHaj/AGEwSuXU=,99b27788411d478764bf7c51e4f6e84e5ccd60f3959a88a03e96b2a1d519a45d +github.com/leodido/go-urn,v1.2.0,h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=,8a854d784171000a69b79babb2cd3da9b8fccb1e1b6bb102c7a6d2b52380d08a +github.com/lestrrat-go/jspointer,v0.0.0-20181205001929-82fadba7561c,h1:pGh5EFIfczeDHwgMHgfwjhZzL+8/E3uZF6T7vER/W8c=,a64de11dd2840c3251906c5fe5f61719713af52a41287411007434684745af39 +github.com/lestrrat-go/jsref,v0.0.0-20181205001954-1b590508f37d,h1:1eeFdKL5ySmmYevvKv7iECIc4dTATeKTtBqP4/nXxDk=,1acee9b59501460f5063a82bc2c05f1a11cd24077198fc08ba100ee642d3db72 +github.com/lestrrat-go/jsschema,v0.0.0-20181205002244-5c81c58ffcc3,h1:TSKrrGm89gmmVlrG34ZzCIOMNVk5kkSV1P88Dt38DiE=,1b7552a5ecd193bdd07995226f58fe48de0aadedbcb42f3a5b135fd7b3538ea4 +github.com/lestrrat-go/jsval,v0.0.0-20181205002323-20277e9befc0,h1:w4rIjeCV/gQpxtn3i1voyF6Hd7v1mRGIB63F7RZOk1U=,f060af1b36e0f156546436dcc9b1569600871185d69e9daf214f24e0e2934784 +github.com/lestrrat-go/pdebug,v0.0.0-20180220043849-39f9a71bcabe,h1:S7XSBlgc/eI2v47LkPPVa+infH3FuTS4tPJbqCtJovo=,17690c72219264e0a195dac69ae6ed12bbadf309242dbaa21609339dfa74b3a5 +github.com/lestrrat-go/structinfo,v0.0.0-20190212233437-acd51874663b,h1:YUFRoeHK/mvRjBR0bBRDC7ZGygYchoQ8j1xMENlObro=,8dd77f51595dea974553558e0d249059b9047a39354548b5bbd88b32cf3df75a +github.com/lestrrat/go-jsschema,v0.0.0-20181205002244-5c81c58ffcc3,h1:UaOmzcaCH2ziMcSbQFBq/3Iuz/E/Jr/GOGtV80jpFII=,ce0f1e04d70eadcc75f96d70703b53231e1c5be7d9fd832c144e0135bfd5afb4 +github.com/lib/pq,v1.2.0,h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=,cb1028c395747cacafb6c3c6ad5fa244563ce641aae45cf7742f98b6764b1fde +github.com/libp2p/go-addr-util,v0.0.1,h1:TpTQm9cXVRVSKsYbgQ7GKc3KbbHVTnbostgGaDEP+88=,d49a37e15540c8b95f845dde6cdf802e7af490bc13fd88fec3da318d08464f7b +github.com/libp2p/go-buffer-pool,v0.0.2,h1:QNK2iAFa8gjAe1SPz6mHSMuCcjs+X1wlHzeOSqcmlfs=,fef932705b72198df3d50befd9d2aa157aea1b5f3d23712b09d627d02cfe841e +github.com/libp2p/go-conn-security,v0.0.1,h1:4kMMrqrt9EUNCNjX1xagSJC+bq16uqjMe9lk1KBMVNs=,e7b58f887c8a8a2ed0178d2f0d6b4ad36bdd7b8cf52ca4d66bafc108b80d095c +github.com/libp2p/go-conn-security-multistream,v0.1.0,h1:aqGmto+ttL/uJgX0JtQI0tD21CIEy5eYd1Hlp0juHY0=,597b249bd51de097142815318b13c339752532f15131887492d9d3e3407ab92e +github.com/libp2p/go-eventbus,v0.1.0,h1:mlawomSAjjkk97QnYiEmHsLu7E136+2oCWSHRUvMfzQ=,1b02c8340d2740f99d67078a8c8823c6b9212b92dd9ca7eaf2a38adf2bfd6b56 +github.com/libp2p/go-flow-metrics,v0.0.1,h1:0gxuFd2GuK7IIP5pKljLwps6TvcuYgvG7Atqi3INF5s=,f783542a7fce8382de9cea6940049b106cc35f9714126a1e3d61925c29db8617 +github.com/libp2p/go-libp2p-autonat,v0.1.0,h1:aCWAu43Ri4nU0ZPO7NyLzUvvfqd0nE3dX0R/ZGYVgOU=,11e86ef0b36125a7cd6aa447ffe488f7f3ab00e441bdf8cf30a832a41da4342c +github.com/libp2p/go-libp2p-blankhost,v0.1.4,h1:I96SWjR4rK9irDHcHq3XHN6hawCRTPUADzkJacgZLvk=,9cd5abe8ad2f137c13309a9dbdd213376bbec03f9685cf8cde7fbfe2e5783e7d +github.com/libp2p/go-libp2p-circuit,v0.1.0,h1:eniLL3Y9aq/sryfyV1IAHj5rlvuyj3b7iz8tSiZpdhY=,24ee6c7851f4f0072922ae497c230718a0f44beab890d0403261b38a2946a866 +github.com/libp2p/go-libp2p-core,v0.2.4,h1:Et6ykkTwI6PU44tr8qUF9k43vP0aduMNniShAbUJJw8=,d521cc1bffba8afc8b8057901cf22c2f6ffd88faec0274426e13c4e7c12c756c +github.com/libp2p/go-libp2p-crypto,v0.1.0,h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ=,14ef1867bd8b0ef8fc528f5069ef267270dd0de8cf89a235beb9fbd79e4bed8d +github.com/libp2p/go-libp2p-discovery,v0.2.0,h1:1p3YSOq7VsgaL+xVHPi8XAmtGyas6D2J6rWBEfz/aiY=,d1c0800b601cbe6833522727b249567379422e9f324b7d0a0866bd86c74fb930 +github.com/libp2p/go-libp2p-host,v0.1.0,h1:OZwENiFm6JOK3YR5PZJxkXlJE8a5u8g4YvAUrEV2MjM=,d26bf1db299917f080a13ace37ef4363c08c2407c126cee59e642b1372d2b211 +github.com/libp2p/go-libp2p-interface-connmgr,v0.0.5,h1:KG/KNYL2tYzXAfMvQN5K1aAGTYSYUMJ1prgYa2/JI1E=,fe1e74365cc5c155161e5500671a8e9a85a90efdad9f5630bdfdc15bdfc52fe5 +github.com/libp2p/go-libp2p-interface-pnet,v0.0.1,h1:7GnzRrBTJHEsofi1ahFdPN9Si6skwXQE9UqR2S+Pkh8=,9767f78f87f54bdf3fb1f0f9b5f67e907463b445a00a566402bacca85749c8fe +github.com/libp2p/go-libp2p-loggables,v0.1.0,h1:h3w8QFfCt2UJl/0/NW4K829HX/0S4KD31PQ7m8UXXO8=,351c87c02c2b147193fac5c441d8767d2b247cd3f3c420fa205da2ccd1c3f00f +github.com/libp2p/go-libp2p-metrics,v0.1.0,h1:v7YMUTHNobFaQeqaMfJJMbnK3EPlZeb6/KFm4gE9dks=,a86fe0ae6cda820fd6a0e576bcd94a22360439819f344a9121086b31c651caaf +github.com/libp2p/go-libp2p-mplex,v0.2.1,h1:E1xaJBQnbSiTHGI1gaBKmKhu1TUKkErKJnE8iGvirYI=,f11961ef5114e57eb176740a066e1535132c8c238bd444ed53d94fad36ba7708 +github.com/libp2p/go-libp2p-nat,v0.0.4,h1:+KXK324yaY701On8a0aGjTnw8467kW3ExKcqW2wwmyw=,4c3db4e0f7f714439364ca0853f63d426bba67924da6fd050fd0184abdfec2df +github.com/libp2p/go-libp2p-net,v0.1.0,h1:3t23V5cR4GXcNoFriNoZKFdUZEUDZgUkvfwkD2INvQE=,4140afd418393c2a4ecccca97d80b4752d20da6f34fac15fbdc4f0566f7b8cea +github.com/libp2p/go-libp2p-netutil,v0.1.0,h1:zscYDNVEcGxyUpMd0JReUZTrpMfia8PmLKcKF72EAMQ=,c98ad0a3ffab37b6a0bc80aefba4e4cb442b09c01277a7dcc0086c4a004e649a +github.com/libp2p/go-libp2p-peer,v0.2.0,h1:EQ8kMjaCUwt/Y5uLgjT8iY2qg0mGUT0N1zUjer50DsY=,5b400d6b6337cc759846d7ddf50ec2d761148e1447a86982696687ef1e792c1a +github.com/libp2p/go-libp2p-peerstore,v0.1.4,h1:d23fvq5oYMJ/lkkbO4oTwBp/JP+I/1m5gZJobNXCE/k=,1606c0bb56c31d0249980b8a0c0e5dda9212687b1994ef47cfd42039d4cf1847 +github.com/libp2p/go-libp2p-protocol,v0.1.0,h1:HdqhEyhg0ToCaxgMhnOmUO8snQtt/kQlcjVk3UoJU3c=,4560018136a73817e03eed49af46d97dd561b3eeffb1ff00559152acf9a74627 +github.com/libp2p/go-libp2p-pubsub,v0.2.0,h1:4UXcjpQdpam/RsGhfWyT/4u5f6F42ods/WgDAaocYxA=,bde7bb50d950b8ea7902c523a696eff4ad7b5d0daac808356358ff6d53aecb14 +github.com/libp2p/go-libp2p-record,v0.1.1,h1:ZJK2bHXYUBqObHX+rHLSNrM3M8fmJUlUHrodDPPATmY=,27a3e94e144b893cbb5ceaddfa7a4e456052e173f807db52945e06920f62d0b3 +github.com/libp2p/go-libp2p-routing,v0.1.0,h1:hFnj3WR3E2tOcKaGpyzfP4gvFZ3t8JkQmbapN0Ct+oU=,4241980dadf216e937a42a572a9c5b5eb28ff62458380ad37892c5b5095de270 +github.com/libp2p/go-libp2p-secio,v0.2.0,h1:ywzZBsWEEz2KNTn5RtzauEDq5RFEefPsttXYwAWqHng=,979a82829f3188d4ca8d20d194923c5620ff12a161d13c945c1630b7b9d050ff +github.com/libp2p/go-libp2p-swarm,v0.2.2,h1:T4hUpgEs2r371PweU3DuH7EOmBIdTBCwWs+FLcgx3bQ=,b920f69fbfaa8805047b958c6d45d944a195181dd6dddab36bead5fe68f2f1e4 +github.com/libp2p/go-libp2p-testing,v0.1.0,h1:WaFRj/t3HdMZGNZqnU2pS7pDRBmMeoDx7/HDNpeyT9U=,e1c7fa467d88b33f2fc519542cc19aa48bcade304f579f10ab402a19c38d0aa6 +github.com/libp2p/go-libp2p-transport,v0.0.5,h1:pV6+UlRxyDpASSGD+60vMvdifSCby6JkJDfi+yUMHac=,df7bc96a5d76c351fd3a6ee29995f4974013d9709904edd9608b86f4fa089ad2 +github.com/libp2p/go-libp2p-transport-upgrader,v0.1.1,h1:PZMS9lhjK9VytzMCW3tWHAXtKXmlURSc3ZdvwEcKCzw=,60ea73fa42536178798c3d4a36c5f9cffb185b6c1629c23c3faff5919f9e9cad +github.com/libp2p/go-libp2p-yamux,v0.2.1,h1:Q3XYNiKCC2vIxrvUJL+Jg1kiyeEaIDNKLjgEjo3VQdI=,849f0097fd7203b5c6d590463b7fb17573af8d12136413768706188a39b34b21 +github.com/libp2p/go-maddr-filter,v0.0.5,h1:CW3AgbMO6vUvT4kf87y4N+0P8KUl2aqLYhrGyDUbLSg=,19c76e021879aab85a8858b53d706220e9e3277a96dead161db152f5a1d17219 +github.com/libp2p/go-mplex,v0.1.0,h1:/nBTy5+1yRyY82YaO6HXQRnO5IAGsXTjEJaR3LdTPc0=,3340a423ea89310360810973a77a97c217fe7b35e1c18189a3628e35fe1275e0 +github.com/libp2p/go-msgio,v0.0.4,h1:agEFehY3zWJFUHK6SEMR7UYmk2z6kC3oeCM7ybLhguA=,ec22f703203a2a443c57896b2082c02fe9c54d372aad091cdca144709d244721 +github.com/libp2p/go-nat,v0.0.3,h1:l6fKV+p0Xa354EqQOQP+d8CivdLM4kl5GxC1hSc/UeI=,d642c9dd697176ec69c4a5faeff1fc3b5472ef9f32c2c40e21c42f81ceef86b9 +github.com/libp2p/go-openssl,v0.0.3,h1:wjlG7HvQkt4Fq4cfH33Ivpwp0omaElYEi9z26qaIkIk=,f2eb05d710fe960ba12d5f640cefe7d31d24f1fab0d9a52faf5f2923a19c6f13 +github.com/libp2p/go-reuseport,v0.0.1,h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw=,274ade934c7f26ffae86d3f4d34352371c3eca7ead080392f6f35698ec5f0a3f +github.com/libp2p/go-reuseport-transport,v0.0.2,h1:WglMwyXyBu61CMkjCCtnmqNqnjib0GIEjMiHTwR/KN4=,866f45bfa6c2e65d563955a28050bcfbc6ed11df6ded7c551e92ff98ba98a2d8 +github.com/libp2p/go-stream-muxer,v0.1.0,h1:3ToDXUzx8pDC6RfuOzGsUYP5roMDthbUKRdMRRhqAqY=,d42dab9fb102b3e56cc555eb9aacb742e4230120dd356078cc723f8817200d43 +github.com/libp2p/go-stream-muxer-multistream,v0.2.0,h1:714bRJ4Zy9mdhyTLJ+ZKiROmAFwUHpeRidG+q7LTQOg=,a4ca5d0422d55ee7b4e74b040ca85799365b05684b7b6687adfa79a345049a9d +github.com/libp2p/go-tcp-transport,v0.1.1,h1:yGlqURmqgNA2fvzjSgZNlHcsd/IulAnKM8Ncu+vlqnw=,147dc8d50aab944666c1a7a371ba3e351480506313be298ebf8dcdb9dc51b1b4 +github.com/libp2p/go-testutil,v0.1.0,h1:4QhjaWGO89udplblLVpgGDOQjzFlRavZOjuEnz2rLMc=,9fa6fa5741f541a6309e8a5fa6031c51f97fcd3086fe3a3b371b74f9d8e9a4b8 +github.com/libp2p/go-ws-transport,v0.1.0,h1:F+0OvvdmPTDsVc4AjPHjV7L7Pk1B7D5QwtDcKE2oag4=,30cfd8011bb8de03c23680d2249120ea9ba29879e855ca5c35311f8fa874d094 +github.com/libp2p/go-yamux,v1.2.3,h1:xX8A36vpXb59frIzWFdEgptLMsOANMFq2K7fPRlunYI=,97947a07c9430184c3be45e87580abcdea18c9b7435adb8048b08aebce0fea50 +github.com/liggitt/tabwriter,v0.0.0-20181228230101-89fcab3d43de,h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=,41b6869255915ffdfd32575ba14d52732d62d34b47d904df4890e165489ec77d +github.com/linkedin/goavro,v2.1.0+incompatible,h1:DV2aUlj2xZiuxQyvag8Dy7zjY69ENjS66bWkSfdpddY=,25d4ccde4ece770196fbf6f09ca4184df581944224be5d64a263eb2c7f9a24fc +github.com/linode/linodego,v0.10.0,h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM=,4c4e8829c0290c473e36bacdce8b490833d1f6247b1a4290062db30ba2b21568 +github.com/liquidweb/liquidweb-go,v1.6.0,h1:vIj1I/Wf97fUnyirD+bi6Y63c0GiXk9nKI1+sFFl3G0=,19e08fe2aa62655eb3cb209b37d532a267dd3078e5d262c4c45e7e09134b079c +github.com/lithammer/dedent,v1.1.0,h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=,4ec56a3fef0d7dd1536046e540827e60419a935dde49d87d21f5856174cadba2 +github.com/logrusorgru/aurora,v0.0.0-20180419164547-d694e6f975a9,h1:KQdwUNlTDGyS6e+2rjAxfHSpBFIOHXqgDceNDqb55+4=,3b9d5caeede8553ead48405de57cd25bf6276b12531dae582c3ee089474aaf95 +github.com/loov/hrtime,v0.0.0-20181214195526-37a208e8344e,h1:UC+nLCm+w3WL+ibAW/wsWbQC3KAz7LLawR2hgX0eR9s=,f077796a9f39c579d356ac8f99831c56b3b2c52b70526f97730eccdc5ce558b2 +github.com/loov/plot,v0.0.0-20180510142208-e59891ae1271,h1:51ToN6N0TDtCruf681gufYuEhO9qFHQzM3RFTS/n6XE=,eb57dc24113d92cda1d0eecd6280603a2f1a98eececde895db4b060a7208659a +github.com/lovoo/gcloud-opentracing,v0.3.0,h1:nAeKG70rIsog0TelcEtt6KU0Y1s5qXtsDLnHp0urPLU=,7bead4937d23976e07caf4bf7a7f302724cda9155aa8ac4de7baa2e10976eacc +github.com/lsegal/gucumber,v0.0.0-20180127021336-7d5c79e832a2,h1:Gg0dt1q5bB+3R3qu+BucR+1f5ZhKm3OzPPo53dZ3Hxs=,2e5cd235f8c80ae078b3115b41fb765682c796d62fa54ecbb2096b159b0294bd +github.com/lucas-clemente/aes12,v0.0.0-20171027163421-cd47fb39b79f,h1:sSeNEkJrs+0F9TUau0CgWTTNEwF23HST3Eq0A+QIx+A=,074a3c40044c8f07dbe93129fe30bfd4a12f6283f393e7300664d59924a8af2b +github.com/lucas-clemente/quic-clients,v0.1.0,h1:/P9n0nICT/GnQJkZovtBqridjxU0ao34m7DpMts79qY=,b916edbd87d45fd375b0f81f905453102eb4e7e724ca0fc8ac5be323fe5958b8 +github.com/lucas-clemente/quic-go,v0.12.1,h1:BPITli+6KnKogtTxBk2aS4okr5dUHz2LtIDAP1b8UL4=,144443ffb6231cabbe6da1496c5851eb73f03fff33d7bd94aa394f8d1e3c73b3 +github.com/lucas-clemente/quic-go-certificates,v0.0.0-20160823095156-d2f86524cced,h1:zqEC1GJZFbGZA0tRyNZqRjep92K5fujFtFsu5ZW7Aug=,d9eff929a62711fc36f9655008e144863cd816ad2b59d25eb00a248c96178ce5 +github.com/lucasb-eyer/go-colorful,v1.0.2,h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4=,c0e388db91f217be87f8d508ac9f495adc5a33ffda78849e2d0a89a8e8dae28c +github.com/lunixbochs/struc,v0.0.0-20190916212049-a5c72983bc42,h1:PzBD7QuxXSgSu61TKXxRwVGzWO5d9QZ0HxFFpndZMCg=,8a7db31161ec3a3bcc7b52e25975d0299b9c0bb465f076014d303f112b5cb9e1 +github.com/lunixbochs/vtclean,v1.0.0,h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8=,4d73f9678abde21c67dd8cb4ed8d7f63bcdd9413b6093b53cec4d26ce1be5b88 +github.com/lunny/dingtalk_webhook,v0.0.0-20171025031554-e3534c89ef96,h1:uNwtsDp7ci48vBTTxDuwcoTXz4lwtDTe7TjCQ0noaWY=,b94d4c7cacca0c289b3fbbeae6cc9e66f2eec4a3210fbbfd208316337ff2f1e3 +github.com/lunny/levelqueue,v0.0.0-20190217115915-02b525a4418e,h1:GSprKUrG9wNgwQgROvjPGXmcZrg4OLslOuZGB0uJjx8=,8f62ece23811c3c2be0d1c8d10057ab564641b2f73dc5a9910dd5f8462954f19 +github.com/lunny/log,v0.0.0-20160921050905-7887c61bf0de,h1:nyxwRdWHAVxpFcDThedEgQ07DbcRc5xgNObtbTp76fk=,0d551b83dcb0c4a3e0f97febf74e8f69b58a419791e217a7d2fd3d79a1e5877b +github.com/lunny/nodb,v0.0.0-20160621015157-fc1ef06ad4af,h1:UaWHNBdukWrSG3DRvHFR/hyfg681fceqQDYVTBncKfQ=,a0f6632294f1eec60e2651fa2d4b3590f3a1a8e2f7692dcc77251b945906a701 +github.com/lusis/go-artifactory,v0.0.0-20160115162124-7e4ce345df82,h1:wnfcqULT+N2seWf6y4yHzmi7GD2kNx4Ute0qArktD48=,487d2ef1720bd49c5a36efc8893fdb0a76bd5f8b064c2a98974a78b3e35f5763 +github.com/lusis/go-slackbot,v0.0.0-20180109053408-401027ccfef5,h1:AsEBgzv3DhuYHI/GiQh2HxvTP71HCCE9E/tzGUzGdtU=,0bb7feaeb5a4e83486234c1c8fbe2f73b94213f511aaf6b8ef1f0fc96dd7b4fa +github.com/lusis/outputter,v0.0.0-20171130132426-5a3b464a163f,h1:JY0YSH+YvMGmq83g5qILMAkJDFv7qIiHalhlQXal9V0=,e3b54ad36707730681b10a3838d89c346bf2d2c52cb61a241b178bcb0fc96e0f +github.com/lusis/slack-test,v0.0.0-20190426140909-c40012f20018,h1:MNApn+Z+fIT4NPZopPfCc1obT6aY3SVM6DOctz1A9ZU=,019aa5a65d7fc369730c089a8af985f8d4760297a0058dd0c352fb662e8a0cfc +github.com/lyft/protoc-gen-star,v0.4.11,h1:zW6fJQBtCtVeSiO/Kbpzv32GO0J/Z8egSLeohES202w=,673c0c53ce301a5589d4aab2b389c6ab52c8312193bae9b491e75e4938475277 +github.com/lyft/protoc-gen-validate,v0.1.0,h1:NytKd9K7UW7Szxn+9PYNsaJ/98TL/WsDq4ro4ZVuh5o=,2e452d4298aa5f2be8d4eda3e55522a4c020d0f23dac6b33ecf9942be09bf082 +github.com/magefile/mage,v1.4.0,h1:RI7B1CgnPAuu2O9lWszwya61RLmfL0KCdo+QyyI/Bhk=,55862155e89367536d665080ac028decc98ce68c5651ccc4238d7e34ddf1cbc2 +github.com/magiconair/properties,v1.8.1,h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=,c0f0378f5949db2e7976d6822a0dfac1786acd34190e83ab253d6505542d0128 +github.com/mailgun/mailgun-go,v0.0.0-20171127222028-17e8bd11e87c,h1:5huPh/MfWW65cx8KWNVD4mCCnwIrNiX4bFJR5OeONg0=,33250edd00795e387f2de671003b8ef8f2d940d24b12a9ce90c6b49dd6094231 +github.com/mailgun/minheap,v0.0.0-20170619185613-3dbe6c6bf55f,h1:aOqSQstfwSx9+tcM/xiKTio3IVjs7ZL2vU8kI9bI6bM=,26930b2a6dc2f2b442e28ecc5dcbb22c2e7da3d151b3388d0bc604370bd9df77 +github.com/mailgun/multibuf,v0.0.0-20150714184110-565402cd71fb,h1:m2FGM8K2LC9Zyt/7zbQNn5Uvf/YV7vFWKtoMcC7hHU8=,7dbb280e8bc981732510ee72e124e931991d06c317531de709fd7922e38a5339 +github.com/mailgun/timetools,v0.0.0-20170619190023-f3a7b8ffff47,h1:jlyJPTyctWqANbaxi/nXRrxX4WeeAGMPaHPj9XlO0Rw=,a4d961cefbfbe858f4ba5a5824d91ad8713a736707f5c259cf0d7307a07ac83e +github.com/mailgun/ttlmap,v0.0.0-20170619185759-c1c17f74874f,h1:ZZYhg16XocqSKPGNQAe0aeweNtFxuedbwwb4fSlg7h4=,35308e95ed02635049d1804b85f16407f3109fc60c38df541f0401dbba66dc8d +github.com/mailru/easyjson,v0.7.0,h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=,c36c8ab36aab9ba2ca776d1c71cbd9c30fce7c4e8e62be6611f4c2d1e98e86ae +github.com/manucorporat/sse,v0.0.0-20160126180136-ee05b128a739,h1:ykXz+pRRTibcSjG1yRhpdSHInF8yZY/mfn+Rz2Nd1rE=,cd90f350cca3a6536432afb4cd2355ff25124ef89fc23a52392e5189733b0359 +github.com/manveru/faker,v0.0.0-20171103152722-9fbc68a78c4d,h1:Zj+PHjnhRYWBK6RqCDBcAhLXoi3TzC27Zad/Vn+gnVQ=,80bc3e8ca50e89d3a6139d1709fbf4680c26231079d297d237902d3c23f4c1e8 +github.com/manveru/gobdd,v0.0.0-20131210092515-f1a17fdd710b,h1:3E44bLeN8uKYdfQqVQycPnaVviZdBLbizFhU49mtbe4=,39811c3d6c7de66195a29a78b235dead57fb866e61082301fe68d51cf04a5200 +github.com/markbates/deplist,v1.3.0,h1:uPgoloPraPBPYtNSxj2UwZBh2EHW9TmMvQCP2FBiRlU=,e0b1903fb33c324721565076e2061d7f54e29ba098afb80af4fe2ccdd02ed178 +github.com/markbates/going,v1.0.3,h1:mY45T5TvW+Xz5A6jY7lf4+NLg9D8+iuStIHyR7M8qsE=,61efe687a56d3141284be7bdb83bb5ae86e1df694ababa5937c4d3e30f3b60f1 +github.com/markbates/goth,v1.49.0,h1:qQ4Ti4WaqAxNAggOC+4s5M85sMVfMJwQn/Xkp73wfgI=,39a0244d07f47d7b91215590900a7754c4700e875c0866b1e65568133471478a +github.com/markbates/grift,v1.1.0,h1:DsljFKUSK1ELpU22ZE+Gi93jiQI3cYD/RQ+vHM/PpY8=,29aa2fa782f9d8730bde2df024c40ba749f1812dd3bbab489b4197a1faa78627 +github.com/markbates/hmax,v1.1.0,h1:MswE0ks4Iv1UAQNlvAyFpsyFQSBHolckas95gRUkka4=,8c7557798a88c74594f27137be859e99195427e2e04f0835f48781b0bde5c73a +github.com/markbates/inflect,v1.0.4,h1:5fh1gzTFhfae06u3hzHYO9xe3l3v3nW5Pwt3naLTP5g=,0da6e75f6cd27672255a41f5dfab418d2746897239ad601e5d8d78d6354b5665 +github.com/markbates/oncer,v1.0.0,h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=,9a774885bfa4c9a96c438fdb51768833e1c7003f35cd27961137ff4096b1a764 +github.com/markbates/refresh,v1.8.0,h1:ELMS9kKyO/H6cJrqFo6qCyE0cRx2JeHWC9yusDkVeM8=,7ac81390a898cfd1cdc097ffb1e05321c415183165b7341749de41160c47e504 +github.com/markbates/safe,v1.0.1,h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=,d5a98e8242318d4e88844ddbbfebe91f67f41e5aa1f6a96a58fa2fa94e0ae9ef +github.com/markbates/sigtx,v1.0.0,h1:y/xtkBvNPRjD4KeEplf4w9rJVSc23/xl+jXYGowTwy0=,e3b591a1a2b4dcec7b86d59e504b0bbf87ec3663efad818cd9b00471a33a0345 +github.com/markbates/willie,v1.0.9,h1:394PpHImWjScL9X2VRCDXJAcc77sHsSr3w3sOnL/DVc=,a6c3eda44d765eeb1370b0ddeb739df86e900b78eb365688da143f1c0c0e9bc0 +github.com/marstr/guid,v1.1.0,h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI=,7db3cd8020c72ba260d1a20183bf5a030c696d6442eccaff2b31f72b194fc571 +github.com/marten-seemann/qpack,v0.1.0,h1:/0M7lkda/6mus9B8u34Asqm8ZhHAAt9Ho0vniNuVSVg=,46c42087e554edae4e19f79b785722d27316e23278889bf78a0c8f43fc387f2e +github.com/marten-seemann/qtls,v0.3.2,h1:O7awy4bHEzSX/K3h+fZig3/Vo03s/RxlxgsAk9sYamI=,ff5245b3d5a1e65754d4a740e09ff02c738e9043c6e2bc02c59d5851c1fc1e2d +github.com/martini-contrib/render,v0.0.0-20150707142108-ec18f8345a11,h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw=,2edd7f64b2f1f053f86a51856cd0f02b1f762af61a458a2e282dab76ad093d70 +github.com/martinlindhe/unit,v0.0.0-20190604142932-3b6be53d49af,h1:4bEyeobv/dO+lT1Qp1hr+/DcNjy6Ob8BDaSrxX6nQsQ=,ee5001e908fb9997e5918c909dcb0cc078f1a91719f4df3d62243d5e88dc07c6 +github.com/martinusso/go-docs,v0.0.0-20161215163720-81905d575a58,h1:VmcrkkMjTdCGOsuuMnn7P2X9dGh3meUNASx6kHIpe7A=,70ad43a3172287882f904657184af77133a578c6d1ec968c5ce3e27259100a06 +github.com/maruel/panicparse,v0.0.0-20171209025017-c0182c169410,h1:1ROIrlLvFoHKX+i48KdRauq21irSOXPyfQw4T/PrINY=,5fd98b2b0a8346ffcba1858775e93db0582ead6b3329b974595d5ab448c95f28 +github.com/maruel/ut,v1.0.0,h1:Tg5f5waOijrohsOwnMlr1bZmv+wHEbuMEacNBE8kQ7k=,a7c90a5020071c66efe2ccae7f3859c60f17840d4ae2972ee9c9a38ae071fb3e +github.com/masterzen/azure-sdk-for-go,v0.0.0-20161014135628-ee4f0065d00c,h1:FMUOnVGy8nWk1cvlMCAoftRItQGMxI0vzJ3dQjeZTCE=,de40198aee773ecaf502d59b8f29fe5d1564fb9a68900b6bfed2369e169e193a +github.com/masterzen/simplexml,v0.0.0-20190410153822-31eea3082786,h1:2ZKn+w/BJeL43sCxI2jhPLRv73oVVOjEKZjKkflyqxg=,a9e4548a5c7e098c89273c470e4e9d18cb0beb530629f2e512f6f105fd9cbc88 +github.com/masterzen/winrm,v0.0.0-20190223112901-5e5c9a7fe54b,h1:/1RFh2SLCJ+tEnT73+Fh5R2AO89sQqs8ba7o+hx1G0Y=,28f8e69baadf7f220842a5cd4269ccebdb175a835c0b43819a6b15670ae5403c +github.com/matryer/moq,v0.0.0-20190312154309-6cfb0558e1bd,h1:HvFwW+cm9bCbZ/+vuGNq7CRWXql8c0y8nGeYpqmpvmk=,b9fb2bc3d0894dfaa3cc4298f49c97346ccb66f2f0e6911f4f224ffc9acc3972 +github.com/matryer/try,v0.0.0-20161228173917-9ac251b645a2,h1:JAEbJn3j/FrhdWA9jW8B5ajsLIjeuEHLi8xE4fk997o=,f1afa36a4bd0bf09a1290f3afef954058e334d6b275aae6a591d8dad276f5e2f +github.com/mattbaird/elastigo,v0.0.0-20170123220020-2fe47fd29e4b,h1:v29yPGHhOqw7VHEnTeQFAth3SsBrmwc8JfuhNY0G34k=,f6a94deccbe4d008d265bb4b5cbaee7893e5994a82bc49b44438675a0ca8d8f3 +github.com/mattbaird/jsonpatch,v0.0.0-20171005235357-81af80346b1a,h1:+J2gw7Bw77w/fbK7wnNJJDKmw1IbWft2Ul5BzrG1Qm8=,55abaf4d26d8ad7f81c230f38a6e482b6b416d9b5777a6c3b1a5c140465a5235 +github.com/mattermost/mattermost-server,v5.11.1+incompatible,h1:LPzKY0+2Tic/ik67qIg6VrydRCgxNXZQXOeaiJ2rMBY=,1f601d79e647a248f9e711891e015b1709f3af37e6a45d5e97827f074c40398e +github.com/mattn/go-colorable,v0.1.4,h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=,02ad42bc54adf7c52030b6ab903277af8fb7163aad4f7f8d8703ecfdc62597de +github.com/mattn/go-ieproxy,v0.0.0-20190805055040-f9202b1cfdeb,h1:hXqqXzQtJbENrsb+rsIqkVqcg4FUJL0SQFGw08Dgivw=,5914c18852b0be63008f7ccaf1bd3a8214a82fae78f8afe2e7d774ff96a410ff +github.com/mattn/go-isatty,v0.0.10,h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=,dca893515dccb58e21f9b08837470c5512e0ecd1275767ed996912bb46933c91 +github.com/mattn/go-mastodon,v0.0.5-0.20190517015615-8f6192e26b66,h1:TbnaLJhq+sFuqZ1wxdfF5Uk7A2J41iOobCCFnLI+RPE=,b290b77b6e5556bba70cf18ac815c13ed9a80ffa4cb03627d73187e99cd15d42 +github.com/mattn/go-oci8,v0.0.0-20190320171441-14ba190cf52d,h1:m+dSK37rFf2fqppZhg15yI2IwC9BtucBiRwSDm9VL8g=,eb3bd1fa93c8a341ad43176cb6e4d8540d7a91d3edd7eb98c1388cf2f4c3515c +github.com/mattn/go-runewidth,v0.0.5,h1:jrGtp51JOKTWgvLFzfG6OtZOJcK2sEnzc/U+zw7TtbA=,3b34033634b059bfa31ac552d2150d8c0d6e530dd1c0ead2ce0806e1d7cc754a +github.com/mattn/go-shellwords,v1.0.6,h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI=,374285b205f0659ab4be3f8ce346cfd3291cd42f47b12bda15174c42c462b1a6 +github.com/mattn/go-sqlite3,v1.11.0,h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=,7fec79c50206f5faa759d1b64500fb0d082e22ef23f10e2d4cbce24e4fc2d5c1 +github.com/mattn/go-tty,v0.0.0-20190424173100-523744f04859,h1:smQbSzmT3EHl4EUwtFwFGmGIpiYgIiiPeVv1uguIQEE=,76f28f59927667d2d750fa6ffdefeb3f0c41034cb593e4545a206995c76c619f +github.com/mattn/go-xmpp,v0.0.0-20190124093244-6093f50721ed,h1:A1hEQg5M0b3Wg06pm3q/B0wdZsPjVQ/a2IgauQ8wCZo=,2c39b78184ea27890be56f593353c8fe6b3d6efa53db20e800ff8793bc665199 +github.com/mattn/go-zglob,v0.0.1,h1:xsEx/XUoVlI6yXjqBK062zYhRTZltCNmYPx6v+8DNaY=,8decd6c1916188ab4fa1001e3da3f22d7c9fb6218215fd25053c901979930feb +github.com/mattn/goveralls,v0.0.2,h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc=,3df5b7ebfb61edd9a098895aae7009a927a2fe91f73f38f48467a7b9e6c006f7 +github.com/matttproud/golang_protobuf_extensions,v1.0.1,h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=,e64dc58023f4b8c4472d05a44f2719b84d6c2cc364cc682820c9f72b233c9cdc +github.com/maxbrunsfeld/counterfeiter/v6,v6.2.2,h1:g+4J5sZg6osfvEfkRZxJ1em0VT95/UOZgi/l7zi1/oE=,c185793a7e749ff2557f4557628f5b5d8d9edbf72ca6bd2cb94503f4817c01d2 +github.com/mcuadros/go-version,v0.0.0-20190830083331-035f6764e8d2,h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg=,ff2364bda8605ad94051c576ffa601e1a9aedabc8a1fda588eb04c3371a845ea +github.com/mdlayher/dhcp6,v0.0.0-20190311162359-2a67805d7d0b,h1:r12blE3QRYlW1WBiBEe007O6NrTb/P54OjR5d4WLEGk=,fba7b2f01311e2d41bb4ebe15409d4e0a605a79d2f05156bb0f4adbc20f557bc +github.com/mdlayher/netlink,v0.0.0-20191009155606-de872b0d824b,h1:W3er9pI7mt2gOqOWzwvx20iJ8Akiqz1mUMTxU6wdvl8=,9be201b393fe866f855e5ebb20ef33e86a0e6a99b6b76209531b93615fcbac7c +github.com/mesos/mesos-go,v0.0.10,h1:+M/7Zlkvw4MolkLvXHfj6hkDsLLHOOU54CmOkOUaNBc=,f18d5601dc6a5234b9c2d65cb96b8d30ab877e3117dd52dd47e31a353ed887d1 +github.com/mgutz/ansi,v0.0.0-20170206155736-9520e82c474b,h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=,d7c0ff88c53dfca384bb82108a6e5fdc9e11b358d68b67144ff6a285be20a16a +github.com/mgutz/logxi,v0.0.0-20161027140823-aebf8a7d67ab,h1:n8cgpHzJ5+EDyDri2s/GC7a9+qK3/YEGnBsd0uS/8PY=,0a7837d5246591fe1fd341e48a72786c0b61fff8d3ebfea0e9c789176c3e75d5 +github.com/mgutz/str,v1.2.0,h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw=,bf640c2048957f183e72664ff08745ae3d016f64072a5967f5269ccb5fc4b318 +github.com/mholt/archiver,v3.1.1+incompatible,h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU=,6cbad83ecd8a2bcb013fb1ac163a6551e6f948b103df9b258788612c72551184 +github.com/mholt/certmagic,v0.7.5,h1:1ZGHwUI4+zg1S17tPUj5Xxb9Q1ghTjLcUZE5G4yV5SM=,a85c14ecbb135636c8e4701a25b8d2884f091d948269c0a3187918af83e11db3 +github.com/michaelklishin/rabbit-hole,v1.5.0,h1:Bex27BiFDsijCM9D0ezSHqyy0kehpYHuNKaPqq/a4RM=,1fdb62e985c4b1be24632875668720ed687455ece54cb2c77079488784e06e69 +github.com/micro-plat/gmq,v1.0.1,h1:ai1PiCEfgBmiqzmZ4iWE3l2Vuz7rOTWOakqRWqi/Hgo=,63c4a02b87b31c0f5cfcdfee5df2fa05e77eeaa2aab93b0ef217c57f6b37b38a +github.com/micro-plat/lib4go,v0.2.1,h1:NBTIq0DvpRzTChnYShBagPmsYM4k1NgvkE8OYhgMDt8=,ae1056cc76eee3fccb14b0d8723b6444d8f31d2575a0caa1d3723bc54b91496b +github.com/micro/cli,v0.2.0,h1:ut3rV5JWqZjsXIa2MvGF+qMUP8DAUTvHX9Br5gO4afA=,09e532e4616aa7827d1a1f249bc80ebb01fe8c63978f4b14605246c6be596b82 +github.com/micro/go-log,v0.1.0,h1:szYSR+yyTsomZM2jyinJC5562DlqffSjHmTZFaeZ2vY=,5ec9ba1cfb781edd3695dc9c28afb520cced5e1cf7eabb5faafd4bd8db6953ea +github.com/micro/go-micro,v1.14.0,h1:lptn9DBbsNCB3RC3PMwxTJGqCUgU8Rf23nAMaRuOcOA=,2278cfa86f7bf97df81ea79535127cf87bf03aba29e7603f2feeb48b2d1a3334 +github.com/micro/go-rcache,v0.2.0,h1:g51QJW+lj+dAOXwRlYNZPQQ8ueHLptgoUzZE3iRwJMg=,fa96add40dac8fb14cf08f7a8c96d05c902da40b27b2c4e586cf3304e4ef6533 +github.com/micro/h2c,v1.0.0,h1:ejw6MS5+WaUoMHRtqkVCCrrVzLMzOFEH52rEyd8Fl2I=,6fea0303cbaa2bc6c45098ce5ad0ae2aa7f9c54ce2ff90160549756f8c7a2b07 +github.com/micro/mdns,v0.3.0,h1:bYycYe+98AXR3s8Nq5qvt6C573uFTDPIYzJemWON0QE=,a40ecbd32a2170698f0f49f8961b39e88e7c3e958546a401a59653231b51f1b2 +github.com/micro/micro,v1.14.0,h1:Uol1+Yg5frzneACpzoHEDsyNTN+/+yLrlGMuxR3RVRQ=,0fd330788ad610cc2cb3eb2224f1ca403d9888ad40e78628f250c885373d739c +github.com/micro/util,v0.2.0,h1:6u0cPj1TeixEk5cAR9jbcVRUWDQsmCaZvDBiM3zFZuA=,3e61d5232a3a91d521ade483ab64b53a7b8760d0635978d72b4920eba52f8f79 +github.com/microcosm-cc/bluemonday,v1.0.2,h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s=,9cfac37098da75ab1c278740e8f0f7741891d8843e14afb256574596ad786f83 +github.com/miekg/dns,v1.1.22,h1:Jm64b3bO9kP43ddLjL2EY3Io6bmy1qGb9Xxz6TqS6rc=,54f1f62de314150df163bbe1de91acc922cdce70c5c8a43dfeb7f4af24711d38 +github.com/miekg/mmark,v1.3.6,h1:t47x5vThdwgLJzofNsbsAl7gmIiJ7kbDQN5BxwBmwvY=,8d1b05ee1c0a28093c678af2ed9d0aac9dfc30dce728ccd21fe1506762b54cee +github.com/mindprince/gonvml,v0.0.0-20190828220739-9ebdce4bb989,h1:PS1dLCGtD8bb9RPKJrc8bS7qHL6JnW1CZvwzH9dPoUs=,6702f94187c4e2994ffbdc318c94a04d4bc67081a402e968a2c362a74c81263f +github.com/minio/blake2b-simd,v0.0.0-20160723061019-3f5f724cb5b1,h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=,ab10edfe994b513e2d03cdd8122b352f31a1eb246fe884617b3f2f6195a3ca0c +github.com/minio/cli,v1.22.0,h1:VTQm7lmXm3quxO917X3p+el1l0Ca5X3S4PM2ruUYO68=,33533a4e0a2b1a698d0f899cb5b84d9fc199e7723b971d1408e4b5ee797c9a50 +github.com/minio/dsync,v0.0.0-20180124070302-439a0961af70,h1:pRHQdPOlUhelWqNUF3icFrBSC6VYH1hvF6HigVfgMoI=,850e5b400afc4301a1860debf934c5e8e67565d4937ac45f9a37132b31a09941 +github.com/minio/highwayhash,v0.0.0-20180501080913-85fc8a2dacad,h1:L+8skVz2lusCbtlalLXmJp+TK8XaGAsZ3utSC3k5Jc0=,7393dfe736668f9ab98fcf2d264f9bd20bbf4f98538f02ff15df9604f747cdb1 +github.com/minio/lsync,v0.0.0-20180328070428-f332c3883f63,h1:utJHim4C0K4CmD+Qgod/tgHvo7QNOlH6HN5O8QUvPEI=,417c4bdd4fc5d50da2d81e8890b03af4b80ce9fbd5e4c196731a3d76a09913c1 +github.com/minio/mc,v0.0.0-20180926130011-a215fbb71884,h1:co3kRW9cEI65yolYtcLcNxp2a9yk5T/eEt7gw14tJVs=,37300de5179e1085559c6f317b331d261cc4508ba0e4febbd93cbbfef42d7fc9 +github.com/minio/minio,v0.0.0-20180508161510-54cd29b51c38,h1:F7p0ZU9AQuxlA6SWwhXr0H/rYrA9fOiBk2OzOj7GtfM=,6421e5cf72b35a2948e5edd2b189f37ad1896b8637d5b9bcf7cd40b7ab63dfd4 +github.com/minio/minio-go,v6.0.14+incompatible,h1:fnV+GD28LeqdN6vT2XdGKW8Qe/IfjJDswNVuni6km9o=,3bc396d5e1c0c6f3497743140eaf16ebb97c5f1ca815ba12c4f431e804fb737d +github.com/minio/minio-go/v6,v6.0.27-0.20190529152532-de69c0e465ed,h1:g3DRJpu22jEjs14fSeJ7Crn9vdreiRsn4RtrEsXH/6A=,34d85b6b915ef5876f9c262f260583fabec147c37dcb82e1f42374dd088b9096 +github.com/minio/sha256-simd,v0.1.1,h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU=,0ecfa6532265e139d5d9406c0a803c7ef45b1d8d0f0c1b1d55f7b81969294bfc +github.com/minio/sio,v0.0.0-20180327104954-6a41828a60f0,h1:ys4bbOlPvaUBlA0byjm6TqydsXZu614ZIUTfF+4MRY0=,6c46bc4a68353d7b41f6e91eb276c9b21560cad4f75419baaee01764927fb7e8 +github.com/mistifyio/go-zfs,v2.1.1+incompatible,h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=,545764e34ed40473380ea1b08af9f0aea1715d15a0a56fc937e6c3b1bda0d9a3 +github.com/mitchellh/cli,v1.0.0,h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y=,74199f2c2e1735a45e9f5c2ca049d352b0cc73d945823540e54ca9975ce35752 +github.com/mitchellh/colorstring,v0.0.0-20190213212951-d06e56a500db,h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=,d0733284b20567055e374b420373f5508fa47e95204e59e4b8a66834e7e3964d +github.com/mitchellh/copystructure,v1.0.0,h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=,4a2c9eb367a7781864e8edbd3b11781897766bcf6120f77a717d54a575392eee +github.com/mitchellh/go-fs,v0.0.0-20180402234041-7b48fa161ea7,h1:PXPMDtfqV+rZJshQHOiwUFqlqErXaAcuWy+/ZmyRfNc=,21c34fee3df3dc1ddad5e774ddf9e05998061177420709fb68a958c6c113a90b +github.com/mitchellh/go-homedir,v1.1.0,h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=,fffec361fc7e776bb71433560c285ee2982d2c140b8f5bfba0db6033c0ade184 +github.com/mitchellh/go-linereader,v0.0.0-20190213213312-1b945b3263eb,h1:GRiLv4rgyqjqzxbhJke65IYUf4NCOOvrPOJbV/sPxkM=,7b83ef857c71fe8d4937b57923923176dd43c7b1b7632a9779bac411924e87e1 +github.com/mitchellh/go-ps,v0.0.0-20190716172923-621e5597135b,h1:9+ke9YJ9KGWw5ANXK6ozjoK47uI3uNbXv4YVINBnGm8=,06090b6c22dedf800259eb5d9b5f35bfb7b38e22888c0345631dc54366b21f89 +github.com/mitchellh/go-testing-interface,v1.0.0,h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=,255871a399420cd3513b12f50738d290e251637deb23e21a4332192584ecf9c7 +github.com/mitchellh/go-vnc,v0.0.0-20150629162542-723ed9867aed,h1:FI2NIv6fpef6BQl2u3IZX/Cj20tfypRF4yd+uaHOMtI=,2d65ac584e1a17421265fe97f83bd1cbff447ca6a911fa8d91414fa2115e3e74 +github.com/mitchellh/go-wordwrap,v1.0.0,h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=,9ea185f97dfe616da351b63b229a5a212b14ac0e23bd3f943e39590eadb38031 +github.com/mitchellh/gox,v1.0.1,h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI=,30a69e17ba5cafe6f1ac436bcc99368a5a34f0a0763926d2c6780a781f8e9e95 +github.com/mitchellh/hashstructure,v1.0.0,h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y=,3b79b07860631d05645ea3f54830b7e1997dbcf477e84a8adfe4979be3abdfde +github.com/mitchellh/iochan,v1.0.0,h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=,f3eede01adb24c22945bf71b4f84ae25e3744a12b9d8bd7c016705adc0d778b8 +github.com/mitchellh/mapstructure,v1.1.2,h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=,cd86d8586cbc333de28f6a46989069487877fae437df4c2cc417668d203c7305 +github.com/mitchellh/panicwrap,v0.0.0-20190213213626-17011010aaa4,h1:jw9tsdJ1FQmUkyTXdIF/nByTX+mMnnp16glnvGZMsC4=,b9ab07bbacf733cc24f9f7f53eec19f9bf999cbb35180ad0b615fe437640de6e +github.com/mitchellh/pointerstructure,v0.0.0-20190430161007-f252a8fd71c8,h1:1CO5wil3HuiVLrUQ2ovSTO+6AfNOA5EMkHHVyHE9IwA=,658a3e14e4983f3c8a04c8da4a56d4d8a86e2b4fcaa6b1eefab150efcd742848 +github.com/mitchellh/prefixedio,v0.0.0-20190213213902-5733675afd51,h1:eD92Am0Qf3rqhsOeA1zwBHSfRkoHrt4o6uORamdmJP8=,d3209d88b3b5b05ecd48f469bc16811666f786685c49273664a5496d5dd69018 +github.com/mitchellh/reflectwalk,v1.0.1,h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=,bf1d4540bf05ea244e65fca3e9f859d8129c381adaeebe7f22703959aadc4210 +github.com/mjibson/esc,v0.2.0,h1:k96hdaR9Z+nMcnDwNrOvhdBqtjyMrbVyxLpsRCdP2mA=,9f090786bd43dddb5c0d798b449d5e8aede4cb7d106f56dcac0aebd8fd1929cc +github.com/mndrix/ps,v0.0.0-20131111202200-33ddf69629c1,h1:kCroTjOY+wyp+iHA2lZOV5aJ6WfBVjGnW8bCYmXmLPo=,30b12b7a2467d4a1aa64aa31c715cb45d570d36e31ae70719101d686363d2685 +github.com/mndrix/tap-go,v0.0.0-20171203230836-629fa407e90b,h1:Ga1nclDSe8gOw37MVLMhfu2QKWtD6gvtQ298zsKVh8g=,c6f65bd8d977e53fa083d9d0309cffb0dbfaaae69a5a64a352fb2f7d079ce73d +github.com/modern-go/concurrent,v0.0.0-20180306012644-bacd9c7ef1dd,h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=,91ef49599bec459869d94ff3dec128871ab66bd2dfa61041f1e1169f9b4a8073 +github.com/modern-go/reflect2,v1.0.1,h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=,6af8268206d037428a4197bd421bbe5399c19450ef53ae8309a083f34fb7ac05 +github.com/mohae/deepcopy,v0.0.0-20170929034955-c48cc78d4826,h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=,41ba726508a213f4af89e7d58937263ff778e352d591edd422d3a3dc3272585c +github.com/mongodb/grip,v0.0.0-20191008181606-ee248dc03622,h1:pPoJByX3B56ydhWGUMard1QQ2skLNTw/s1W5VuLLAtA=,08fcfea928382f428dc1fceeada1c264e7f6dc7256dbe05c5c0ba41dca16a42c +github.com/monoculum/formam,v0.0.0-20190830100315-7ff9597b1407,h1:ZU5O9BawmEx9Mu1lxn9NLIwO9DrqRfjE+HWKU+e9GKQ=,5a04e3907fb1008c1e6640e8a0e9394c752aab4ebf7e3be01cd3ee55c2659121 +github.com/montanaflynn/stats,v0.5.0,h1:2EkzeTSqBB4V4bJwWrt5gIIrZmpJBcoIRGS2kWLgzmk=,05527945351f54f4e8c48666bce277fbace34026eed22ac7d88a50a6730767f1 +github.com/morikuni/aec,v1.0.0,h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=,c14eeff6945b854edd8b91a83ac760fbd95068f33dc17d102c18f2e8e86bcced +github.com/moul/anonuuid,v0.0.0-20160222162117-609b752a95ef,h1:E/seV1Rtsnr2juBw1Dfz4iDPT3/5s1H/BATx+ePmSyo=,ec103e75b93231b5b858a2fc9985da39d6b7c35644a689a20e60f3a6ad6b1396 +github.com/moul/gotty-client,v0.0.0-20180327180212-b26a57ebc215,h1:y6FZWUBBt1iPmJyGbGza3ncvVBMKzgd32oFChRZR7Do=,265c4cbad4789e267f283b9012ad174c89e378e59ad9c64ac28729402eb60afe +github.com/moul/http2curl,v0.0.0-20161031194548-4e24498b31db,h1:eZgFHVkk9uOTaOQLC6tgjkzdp7Ays8eEVecBcfHZlJQ=,2ff4e19b14d84f6d181afc79f28668c6171d6dea79c43a1918c0428a265137c1 +github.com/mozilla-services/heka,v0.10.0,h1:w+y6RPJkU6ZKeNbG1VvK9aSqJm0sru5TYcwOj6ejv8U=,f325891304f9acc654944d9a2297b8816a0a86440b2f035c4996ec38fcfa0eed +github.com/mozillazg/go-cos,v0.12.0,h1:b9hUd5HjrDe10BUfkyiLYI1+z4M2kAgKasktszx9pO4=,5376eaf13e10fed6d73b713fbabc4a159d204239579120c410ea74de33dd6d71 +github.com/mozillazg/go-httpheader,v0.2.1,h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=,50b7a36360fc1ec1a85fd40fe45f8db02fc734fc2af0514a60a068f0a2708122 +github.com/mozillazg/go-unidecode,v0.1.1,h1:uiRy1s4TUqLbcROUrnCN/V85Jlli2AmDF6EeAXOeMHE=,812d3bc9f03cb6a8552bfadd9e0d1b44a57807a3af2e8667a42861510bb2b20c +github.com/mpvl/unique,v0.0.0-20150818121801-cbe035fff7de,h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto=,af2bcc8a61a6881e0703afee2217dd1e75c8b34f4e49947c0d7f6e87af574e0e +github.com/mr-tron/base58,v1.1.2,h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=,c2b362db55d8266ce02a161b7f73cad646432d2dae98511385b88481380c4e86 +github.com/mreiferson/go-httpclient,v0.0.0-20160630210159-31f0106b4474,h1:oKIteTqeSpenyTrOVj5zkiyCaflLa8B+CD0324otT+o=,e94cbe43c052831323c59ff186c830ea2e271065f7f8b2794ade7aaf88a37a85 +github.com/mrjones/oauth,v0.0.0-20180629183705-f4e24b6d100c,h1:3wkDRdxK92dF+c1ke2dtj7ZzemFWBHB9plnJOtlwdFA=,4c1fef02b34241008ba6bc33fb5d01b4cfb3b7e7544fb7f70823fe74b9b21362 +github.com/mrunalp/fileutils,v0.0.0-20171103030105-7d4729fb3618,h1:7InQ7/zrOh6SlFjaXFubv0xX0HsuC9qJsdqm7bNQpYM=,c32d691ce15012ba21fbe69db3558df0c97326426c14ef747b8a1e02652ca7b3 +github.com/mschoch/smat,v0.0.0-20160514031455-90eadee771ae,h1:VeRdUYdCw49yizlSbMEn2SZ+gT+3IUKx8BqxyQdz+BY=,488e193897c7d8e3b3758cbeb8a5bc1b58b9619f3f14288a2ea9e0baa5ed9b3e +github.com/msteinert/pam,v0.0.0-20151204160544-02ccfbfaf0cc,h1:z1PgdCCmYYVL0BoJTUgmAq1p7ca8fzYIPsNyfsN3xAU=,315d911c41d88a22bf8831b174bbd15310bc403626507095f98b9780ddcf9174 +github.com/muesli/smartcrop,v0.0.0-20180228075044-f6ebaa786a12,h1:l0X/8IDy2UoK+oXcQFMRSIOcyuYb5iEPytPGplnM41Y=,5857e4d0ed238d8c6f8f41294b98771f1c21874a80ea5f2e75b4a49cbcf1d3e0 +github.com/multiformats/go-base32,v0.0.3,h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=,658875e4980370db6180f99835b3a48158a697eef69e7c3eb86b0b4f5c1c19ed +github.com/multiformats/go-multiaddr,v0.1.1,h1:rVAztJYMhCQ7vEFr8FvxW3mS+HF2eY/oPbOMeS0ZDnE=,ba4849fc68453c3e812e850f40e6d5acef671060ed79f203c2d179d395d20fc5 +github.com/multiformats/go-multiaddr-dns,v0.0.2,h1:/Bbsgsy3R6e3jf2qBahzNHzww6usYaZ0NhNH3sqdFS8=,219f855f485aa198d36305f2f43012a73bd40f15caa3e606324cee9f117e5b89 +github.com/multiformats/go-multiaddr-fmt,v0.1.0,h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=,d83537dc1f83185dfb60b190ea4b3c7b05c552a75ad7cfaddd0b987c00ff0cff +github.com/multiformats/go-multiaddr-net,v0.1.1,h1:jFFKUuXTXv+3ARyHZi3XUqQO+YWMKgBdhEvuGRfnL6s=,241c47d621bcb9a40d33284f407a7fdf458cb3f87ef02db68735cc6b9002afed +github.com/multiformats/go-multibase,v0.0.1,h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=,ed39145efcf5e8c99deaa183071aed246239730f5781b291bad7de5d1fc12d81 +github.com/multiformats/go-multihash,v0.0.8,h1:wrYcW5yxSi3dU07n5jnuS5PrNwyHy0zRHGVoUugWvXg=,44fae6e8771331f54f267d9440a9d520e7daeb91817ff61e26b8494099ae046a +github.com/multiformats/go-multistream,v0.1.0,h1:UpO6jrsjqs46mqAK3n6wKRYFhugss9ArzbyUzU+4wkQ=,f720be6e29845f0a41c1241a24f19c08adf762f9e7e972b4096416776c603b15 +github.com/munnerz/goautoneg,v0.0.0-20191010083416-a7dc8b61c822,h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=,3d7ce17916779890be02ea6b3dd6345c3c30c1df502ad9d8b5b9b310e636afd9 +github.com/mwitkow/go-conntrack,v0.0.0-20190716064945-2f068394615f,h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=,d6fc513490d5c73e3f64ede3cf18ba973a4f8ef4c39c9816cc6080e39c8c480a +github.com/mwitkow/go-grpc-middleware,v1.0.0,h1:XraEe8LhUuB33YeV4NWfLh2KUZicskSZ2lMhVRnDvTQ=,074f46f92d7a0043c5b283f1af224123cc48e21f96b259e62f77b6da72240812 +github.com/mxk/go-flowrate,v0.0.0-20140419014527-cca7078d478f,h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=,bd0701ef9115469a661c07a3e9c2e572114126eb2d098b01eda34ebf62548492 +github.com/myesui/uuid,v1.0.0,h1:xCBmH4l5KuvLYc5L7AS7SZg9/jKdIFubM7OVoLqaQUI=,3055c4b167daeb9984ccd7c8eeba154e3d84afa6fdf06a3151280ef120d1633d +github.com/myitcv/gobin,v0.0.8,h1:hQORun03Mlnm8yp/OgKX8UYSIVZQ8ebTWf3aahY1u+s=,015311e9db646cb9e5f63a0586c466c9eb5bc5f45661282644f8a5b549607e72 +github.com/myitcv/vbash,v0.0.2,h1:8R+91eSlfcgoRjEbnUgvbXYOmfh+p0+7i5klFOM5VMA=,08dcf62b94843e7fd115cd0605158d948fb361ca8c958db1958c5d2feef9c2d1 +github.com/namedotcom/go,v0.0.0-20180403034216-08470befbe04,h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g=,0c6ea2c994e982c25e44ccba2ead1a9655cd2f253986eedb73253c30ad21b42f +github.com/naoina/go-stringutil,v0.1.0,h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=,4cfea6f0ebfecb5e6297f8a6eee0e9ef9fe254883eb75dd6179133995a219c58 +github.com/naoina/toml,v0.1.1,h1:PT/lllxVVN0gzzSqSlHEmP8MJB4MY2U7STGxiouV4X8=,8e34d510563d9e8b3f2dbdf0927bf5108b669144bdbe2fda4fcb44e7e2e55268 +github.com/natefinch/lumberjack,v2.0.0+incompatible,h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=,1f6e7c9e0b915c45151d8780a8711426b19d16d04c9cf0e7995b29035d6b500f +github.com/nats-io/gnatsd,v1.3.0,h1:+5d80klu3QaJgNbdavVBjWJP7cHd11U2CLnRTFM9ICI=,85fa90b3eaef17698734d398a9939b8bb94df1b9f35bc92c8d31cb7a349c1e97 +github.com/nats-io/go-nats,v1.6.0,h1:FznPwMfrVwGnSCh7JTXyJDRW0TIkD4Tr+M1LPJt9T70=,8c63be6f10479802a40c66c0999f724e492bcb9863d5517038c6472e585a76aa +github.com/nats-io/go-nats-streaming,v0.4.2,h1:e7Fs4yxvFTs8N5xKFoJyw0sVW2heJwYvrUWfdf9VQlE=,62dd1d6ba18f3b7686766116e3beaaf9f62b89b58a6efb0b8f1ad04d3ddfb026 +github.com/nats-io/jwt,v0.3.0,h1:xdnzwFETV++jNc4W1mw//qFyJGb2ABOombmZJQS4+Qo=,e131314c7cf6a714ec10ca3b6f95f8af6a41f5cdaf72a364f7c71b33e97314db +github.com/nats-io/nats,v1.6.0,h1:U5b2apHOTZlUou+NGfCRWG4ZEeivbt2hpsZO4kHKIVU=,12cc70ed3477472d110d4b4bc109fbe20218e8199629669ad5f617c199fbf9d2 +github.com/nats-io/nats-server/v2,v2.1.0,h1:Yi0+ZhRPtPAGeIxFn5erIeJIV9wXA+JznfSxK621Fbk=,a5897b8f5302ae38894de2c240f31d33ab7b2f3d4e88a2c212fc9b31f2d4f444 +github.com/nats-io/nats-streaming-server,v0.12.2,h1:EpyLfUBZgwu5c0mdSSytQsapm615AyitPssq7jgafdw=,48605f61f74903ba1322f11aa17806b57f71cebf2557b7dd8620d4193abc868d +github.com/nats-io/nats.go,v1.9.1,h1:ik3HbLhZ0YABLto7iX80pZLPw/6dx3T+++MZJwLnMrQ=,34a735d158d70685faad1fc3153f08da0ddc21c0ae42f6a0cb09430d638364b2 +github.com/nats-io/nkeys,v0.1.0,h1:qMd4+pRHgdr1nAClu+2h/2a5F2TmKcCzjCDazVgRoX4=,dbc82abacf752e532ffd67db230a97f52a5f92070b04b4028cb79534d2ab0ef6 +github.com/nats-io/nuid,v1.0.1,h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=,809d144fbd16f91651a433e28d2008d339e19dafc450c5995e2ed92f1c17c1f3 +github.com/nats-io/stan.go,v0.5.0,h1:ZaSPMb6jnDXsSlOACynJrUiB3Evleg3ZyyX+rnf3TlQ=,1dcb14e2ef8ad30dd1ee61a63b0a3bfbaa48e9c3d13f69458a149956a14bbab7 +github.com/nbio/st,v0.0.0-20140626010706-e9e8d9816f32,h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=,e6cd27bd360be27d0f7efd3c4c41c4e14e659e60086b0bc4f09fb09cfd02a50d +github.com/ncw/swift,v1.0.49,h1:eQaKIjSt/PXLKfYgzg01nevmO+CMXfXGRhB1gOhDs7E=,b2be24cad8923c9171835547df2d621d2aa2029ceb9fa770d6ecf3bf70c2c029 +github.com/neelance/astrewrite,v0.0.0-20160511093645-99348263ae86,h1:D6paGObi5Wud7xg83MaEFyjxQB1W5bz5d0IFppr+ymk=,815811c2140669e55e99d59d4bdd2fcf4c810610a9d278fd25cc2c3480c002d4 +github.com/neelance/sourcemap,v0.0.0-20151028013722-8c68805598ab,h1:eFXv9Nu1lGbrNbj619aWwZfVF5HBrm9Plte8aNptuTI=,ce5499f29779a604233bb76f36925c3326a8a8f270533df8d3dff1107b7aa066 +github.com/neurosnap/sentences,v1.0.6,h1:iBVUivNtlwGkYsJblWV8GGVFmXzZzak907Ci8aA0VTE=,9dbe86e291937eba92847454650d1c65338527ff89dec5daccb99aaf7e03865b +github.com/newrelic/go-agent,v2.15.0+incompatible,h1:IB0Fy+dClpBq9aEoIrLyQXzU34JyI1xVTanPLB/+jvU=,4c541c5f7b10055c37cf22843edbb9b0fcb06ad3504e8d6eae3d9c37ff3c64c6 +github.com/nf/cr2,v0.0.0-20140528043846-05d46fef4f2f,h1:nyKdx+jcykIdxGNrbgo/TGjdGi99EY9FKBCjYAUS4bU=,665afbe7830424dd9815cae42aa7762b657484686d671f88704257ea7c9736be +github.com/nfnt/resize,v0.0.0-20180221191011-83c6a9932646,h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=,b8e97cb14e5e5ef29d762d2dff890f6279a125990ddf9cb7ae5c4d2a015b109c +github.com/ngaut/pools,v0.0.0-20180318154953-b7bc8c42aac7,h1:7KAv7KMGTTqSmYZtNdcNTgsos+vFzULLwyElndwn+5c=,26342833d7a5b91a52f8451e8e34bc9ffc5069d342666ab0b478628c41a86d44 +github.com/ngaut/sync2,v0.0.0-20141008032647-7a24ed77b2ef,h1:K0Fn+DoFqNqktdZtdV3bPQ/0cuYh2H4rkg0tytX/07k=,2635d6120b6172c190f84b57b5fc878f9158b768b4bd6bd4468bfa98a73061a4 +github.com/nicksnyder/go-i18n,v2.0.2+incompatible,h1:Xt6dluut3s2zBUha8/3sj6atWMQbFioi9OMqUGH9khg=,687be9dc953545d390761e5464e07c38f313d19c1f695f7d7702d954afcf6b66 +github.com/nicolai86/scaleway-sdk,v1.10.2-0.20180628010248-798f60e20bb2,h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s=,a2e992324edd4396f24e0b6a165c4d1057eeefdecdc9f7472b0de8a30f3be729 +github.com/niklasfasching/go-org,v0.1.6,h1:F521WcqRNl8OJumlgAnekZgERaTA2HpfOYYfVEKOeI8=,c938afb1ad7f567524686395c9de66da75220eaa60fe8917c02b97aa1e2cbbb1 +github.com/nkovacs/streamquote,v0.0.0-20170412213628-49af9bddb229,h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg=,679a789b4b1409ea81054cb12e5f8441199f5fb17d4a2d3510c51f3aa5f3f0cc +github.com/nlopes/slack,v0.6.0,h1:jt0jxVQGhssx1Ib7naAOZEZcGdtIhTzkP0nopK0AsRA=,048ddfddd4a66407f26b069a65d4d8f3d6d0368adcd52fd5a0dc6d86fe012f47 +github.com/nrdcg/auroradns,v1.0.0,h1:b+NpSqNG6HzMqX2ohGQe4Q/G0WQq8pduWCiZ19vdLY8=,81e3564b38ca27024b6e981a03ae70afcf435d5f8d35a2113321dfd3a220f00b +github.com/nrdcg/goinwx,v0.6.1,h1:AJnjoWPELyCtofhGcmzzcEMFd9YdF2JB/LgutWsWt/s=,8e1e3ea7d38f5b9b21603350d97a583c9108d380f5cc08bf93a4c69d6968dc8a +github.com/nrdcg/namesilo,v0.2.1,h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg=,e20a47d9257fcf7ce95254b14bb84ba290b5f4867e4d63027b669f5a55aaab6c +github.com/nsf/jsondiff,v0.0.0-20160203110537-7de28ed2b6e3,h1:OqFSgO6CJ8heZRAbXLpT+ojX+jnnGij4qZwUz/SJJ9I=,9652618358184592fb7a4657e2c51748cbe0bf5bbf97150a2c6e95ecf65b126b +github.com/nsf/termbox-go,v0.0.0-20190817171036-93860e161317,h1:hhGN4SFXgXo61Q4Sjj/X9sBjyeSa2kdpaOzCO+8EVQw=,a64e374836a25ab74ece4eb5314d79617d8b828bd6d13c654d95bed920c82784 +github.com/nsqio/go-nsq,v1.0.7,h1:O0pIZJYTf+x7cZBA0UMY8WxFG79lYTURmWzAAh48ljY=,5acb7902bf31355fa7d77f507ed42847368834eb378fbf407d82ae3e4211e248 +github.com/nu7hatch/gouuid,v0.0.0-20131221200532-179d4d0c4d8d,h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ=,0889a0ac13cfa9f32f986a88a82bb24380070932299131ae7d7180a389d08ca7 +github.com/nullstyle/go-xdr,v0.0.0-20180726165426-f4c839f75077,h1:A804awGqaW7i61y8KnbtHmh3scqbNuTJqcycq3u5ZAU=,0ab4f958f0420027d40b53c98bcb8f3cbe1e106dfb49d3e91415cb1c512a552c +github.com/nutmegdevelopment/sumologic,v0.0.0-20160817160817-42ed9b372fa3,h1:xOEJG5C3e8CvgAYsnkgoSBzCr0No+m++aB6v7A2WScY=,a33916e02e1159304145b621ffdf284120e50f618c684f38776a8bab7ae7b3fe +github.com/nwaples/rardecode,v0.0.0-20171029023500-e06696f847ae,h1:UF9xsJn7AeQ72TCus3eRO1lh08Id3AoF37vl+qigL/w=,5598a02308af3b04418b15854ff940be49cf31ce7238ce23c10409110364d40f +github.com/ogier/pflag,v0.0.1,h1:RW6JSWSu/RkSatfcLtogGfFgpim5p7ARQ10ECk5O750=,c4db0ecff32deb3205c705d72a616bce01e1f6a1948c851d30b52deeec3fbf91 +github.com/oklog/run,v1.0.0,h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=,108d409b7d235d61b82cfb6e1df139501123fcd8fa68fe94ddb024b53335cb48 +github.com/oklog/ulid,v1.3.1,h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=,40e502c064a922d5eb7f2bc2cda9c6a2a929ec0fc76c9aae4db54fb7b6b611ae +github.com/olekukonko/tablewriter,v0.0.1,h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=,7e5cc8a9b5a51126a0cb46ac96b274d92a8b1cc24b2321832c38d60c0ea4cc9c +github.com/oliamb/cutter,v0.2.2,h1:Lfwkya0HHNU1YLnGv2hTkzHfasrSMkgv4Dn+5rmlk3k=,9174c2374109a7d3aeb2c59b5f4b744ec5f65752aab797f0d50beb26cfc7d857 +github.com/olivere/elastic,v6.2.25+incompatible,h1:X34sPAlSpZVlnuSjOYwbMbiCMU+WKK7YUxrunuNSdG8=,bf3b4cc7ea89a716e91002a31b33f55ec3168ce5ab36ffe5c02ff68d94b9aad5 +github.com/olivere/env,v1.1.0,h1:owp/uwMwhru5668JjMDp8UTG3JGT27GTCk4ufYQfaTw=,f486deab73b3d7866e762e1ad34fe63c88e9ac38f41d811414361fb6490bbb2c +github.com/onsi/ginkgo,v1.10.3,h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY=,088314495acb90d1e520519b243f4dbdd17b43469e6fb83bd45d600796856e63 +github.com/onsi/gomega,v1.7.1,h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=,0a245e719f17cc2bc399aa7c2005cca84f1cfba5373b0c96f5c64673f758a712 +github.com/op/go-logging,v0.0.0-20160315200505-970db520ece7,h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=,c506eace74028656eb28677a4c162f9c023ce2f9c0207354ba80cca89f11b461 +github.com/openconfig/gnmi,v0.0.0-20190823184014-89b2bf29312c,h1:a380JP+B7xlMbEQOlha1buKhzBPXFqgFXplyWCEIGEY=,f52967c7b194daa57252042f6ccf9d26f8c599a7e13aca26043f948d5139b91a +github.com/openconfig/reference,v0.0.0-20190727015836-8dfd928c9696,h1:yHCGAHg2zMaW8olLrqEt3SAHGcEx2aJPEQWMRCyravY=,040cf32cee7256a08716313dd7ea4f8c44f1d644ae872ecf2dd381c35b12125c +github.com/opencontainers/go-digest,v1.0.0-rc1,h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=,25fd455029e8a1bbe15ed2eeafc67222372c6f305a47b4ec157d8a1a2849c15c +github.com/opencontainers/image-spec,v1.0.1,h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=,ebb2dca711a137fbfb717158b0368792f834000f4308d9ea259d06c6804c677c +github.com/opencontainers/runc,v0.1.1,h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=,aa212163f009190d0f4f3dbe64f71fcda06d7896b67863d7f7b185fee6a68ea6 +github.com/opencontainers/runtime-spec,v1.0.1,h1:wY4pOY8fBdSIvs9+IDHC55thBuEulhzfSgKeC1yFvzQ=,1958458b00ce912425f5c7d2ee836431b296a3f9320d565512d8c96b107fffbf +github.com/opencontainers/runtime-tools,v0.9.0,h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=,53c720dbb7452cfb2fd3945e37c26b5a0140cb1012d35a2b72a5e035f28a32c4 +github.com/opencontainers/selinux,v1.3.0,h1:xsI95WzPZu5exzA6JzkLSfdr/DilzOhCJOqGe5TgR0g=,88286825b32cd46a0469e578f378a185032da2d5b03893623861ef3af59359d8 +github.com/openshift/api,v3.9.0+incompatible,h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs=,fc087ac9809ce58bdd15614e04c13f8ecc4a17e71addbe6eb6b777c377b01243 +github.com/openshift/client-go,v3.9.0+incompatible,h1:13k3Ok0B7TA2hA3bQW2aFqn6y04JaJWdk7ITTyg+Ek0=,661b7f28b4905f1936dd58e373374513d54663ec85aecafede1c7d9c260e9369 +github.com/openshift/library-go,v0.0.0-20191101161407-e7c97b468b83,h1:wwR+laNaFKVGiizoIDL/cAKIZVoKXJ9jbjUoUlq2p5I=,c74f8134013f978ef154d6accf9b4b0c5126941f2d45e6eb223db7098f7ab2a4 +github.com/opentracing-contrib/go-observer,v0.0.0-20170622124052-a52f23424492,h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=,50023eee1ef04412410f43d8b5dcf3ef481c0fc39067add27799654705fa84b2 +github.com/opentracing-contrib/go-stdlib,v0.0.0-20190519235532-cf7a6c988dc9,h1:QsgXACQhd9QJhEmRumbsMQQvBtmdS0mafoVEBplWXEg=,966cdf6d869ff62c35edf1ea00113465cc9b90f34838c6a6990a1f776e7d1152 +github.com/opentracing/basictracer-go,v1.0.0,h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo=,a908957c8e55b7b036b4761fb64c643806fcb9b59d4e7c6fcd03fca1105a9156 +github.com/opentracing/opentracing-go,v1.1.0,h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=,3e0f42d035019fa037991d340da9677a802f8182792770c38e87906d33e06629 +github.com/openzipkin-contrib/zipkin-go-opentracing,v0.4.4,h1:bzTJRoOZEN7uI1gq594S5HhMYNSud4FKUEwd4aFbsEI=,8a4688f80cd67140aa4edb91506d440ecea4d8ec01634caab5c95991af011c5d +github.com/openzipkin/zipkin-go,v0.2.2,h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI=,dfc610dc52d9299df49172a9e61fcc772d85450b6b6f82e8f43cf23562232a4c +github.com/oracle/oci-go-sdk,v7.0.0+incompatible,h1:oj5ESjXwwkFRdhZSnPlShvLWYdt/IZ65RQxveYM3maA=,941cd26813b22873477f1c6bb86fed929bdc85379d435bd9707d923f57d070dc +github.com/orcaman/concurrent-map,v0.0.0-20190826125027-8c72a8bb44f6,h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw=,ec80830c751199283290a8d398ebf28ca5169e866a70347b39856d2c1178f2cb +github.com/ory/dockertest,v3.3.4+incompatible,h1:VrpM6Gqg7CrPm3bL4Wm1skO+zFWLbh7/Xb5kGEbJRh8=,cbcc7ba21c846d38229aa06a2d7cf35b99ac219eb2694bd9a1ceeac89667e475 +github.com/ory/herodot,v0.6.2,h1:zOb5MsuMn7AH9/Ewc/EK83yqcNViK1m1l3C2UuP3RcA=,caf465ffb73c7537212ba4fd58a4c2c41fe7ca69737404a28e84ceff90c340ea +github.com/otiai10/copy,v0.0.0-20180813032824-7e9a647135a1,h1:A7kMXwDPBTfIVRv2l6XV3U6Su3SzLUzZjxnDDQVZDIY=,67d0e4f6ba369653e30257882fbbb20c28b560bc837e1847a42c48e868f1c81c +github.com/otiai10/curr,v0.0.0-20150429015615-9b4961190c95,h1:+OLn68pqasWca0z5ryit9KGfp3sUsW4Lqg32iRMJyzs=,7cf2143067d9bb3e7d54d2906766bb24c11d76f1bb0b0c5069574e9a0d8ae93d +github.com/otiai10/mint,v1.2.3,h1:PsrRBmrxR68kyNu6YlqYHbNlItc5vOkuS6LBEsNttVA=,0b82a05ca43810c9aa8299ddae1663feeb178d699aeb5242c3bdeb61cb5a54fb +github.com/outscale/osc-go,v0.0.1,h1:hvBtORyu7sWSKW1norGlfIP8C7c2aegI2Vkq75SRPCE=,2a988384c564fdba8b8c496024aafc212140e4b996654be7a92a3b0c7a962632 +github.com/ovh/go-ovh,v0.0.0-20181109152953-ba5adb4cf014,h1:37VE5TYj2m/FLA9SNr4z0+A0JefvTmR60Zwf8XSEV7c=,0fa35e8026a9b3aebd804739f31ffe07e553b84e2b8ea145b2f2ebaa0dd7c08f +github.com/oxtoacart/bpool,v0.0.0-20190530202638-03653db5a59c,h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=,6816ec3a6f197cbee0ba6ddb9ec70958bc28870e59864b24e43da0c858079a1b +github.com/packer-community/winrmcp,v0.0.0-20180921204643-0fd363d6159a,h1:A3QMuteviunoaY/8ex+RKFqwhcZJ/Cf3fCW3IwL2wx4=,4a48fa503853d129e7e32ca81f069b9e09a9e3249739781f61fae70bb02d098b +github.com/packethost/packngo,v0.1.1-0.20180711074735-b9cb5096f54c,h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE=,6dac4e55c104df58ace636ef31d5dd6173a36747c4fd79299252ba8826127491 +github.com/parnurzeal/gorequest,v0.2.16,h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ=,cc7b7d56e2e4c3fa0709e0e547875807746ac067b2a5c4b740b3088c1fdf941d +github.com/pascaldekloe/goe,v0.1.0,h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=,37b73886f1eec9b093143e7b03f547b90ab55d8d5c9aa3966e90f9df2d07353c +github.com/patrickmn/go-cache,v2.1.0+incompatible,h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=,d5d1c13e3c9cfeb04a943f656333ec68627dd6ce136af67e2aa5881ad7353c55 +github.com/pborman/uuid,v1.2.0,h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=,b888ff5d33651a1f5f6b8094acc434dd6dc284e2fe5052754a7993cebd539437 +github.com/pelletier/go-buffruneio,v0.2.0,h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA=,70593688607f4d48192776fe257ab9298689267ebcdd7b155bfe40d893735f38 +github.com/pelletier/go-toml,v1.6.0,h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=,cc6dce19df6c6c30abd67594d17ea6015d1210aa6dd8c6096c6429eec06fdab4 +github.com/peterbourgon/diskv,v2.0.1+incompatible,h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=,1eeff260bd1ad71cd1611078995db99e1c7eba28628e7d6f24c79039536ea1cb +github.com/peterbourgon/g2s,v0.0.0-20170223122336-d4e7ad98afea,h1:sKwxy1H95npauwu8vtF95vG/syrL0p8fSZo/XlDg5gk=,41526f42b4fe3019581ab3745afea18271d7f037eb55a6e9fb3e32fd09ff9b8d +github.com/petergtz/pegomock,v2.7.0+incompatible,h1:42rJ5wIOBAg9OGdkLaPW9PlF/RtqDc5aGl6PcTCXl3o=,dc93e4483e8de4eb429e007aad17348822197ea7a3adde283b7752bc4544dfbb +github.com/peterh/liner,v1.1.0,h1:f+aAedNJA6uk7+6rXsYBnhdo4Xux7ESLe+kcuVUF5os=,5cdc45c19901db8d8295c139bb382d7eea150e8fd96bd26de10384685728a461 +github.com/peterhellberg/link,v1.0.0,h1:mUWkiegowUXEcmlb+ybF75Q/8D2Y0BjZtR8cxoKhaQo=,d320f4204fbe886e1cefc0b677af2bfaba855e9e6556a6e92e43bcd80c3bb7a5 +github.com/petermattis/goid,v0.0.0-20180202154549-b0b1615b78e5,h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=,5134a176e306f9b973ff670a33c7536b59bf4114d83fd94f74c736ff0cc10ef0 +github.com/phayes/freeport,v0.0.0-20180830031419-95f893ade6f2,h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=,4ac97358de55a9b1ac60f13fdb223c5309a129fb3fb7bf731062f9c095a0796c +github.com/philhofer/fwd,v1.0.0,h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=,b4e79b1f5fdfe8c44bf6dae3dd593c62862930114411a30968f304084de1d0b3 +github.com/pierrec/lz4,v2.3.0+incompatible,h1:CZzRn4Ut9GbUkHlQ7jqBXeZQV41ZSKWFc302ZU6lUTk=,775487f2be5ddf23034b59bc862cb0d5767155c5e08d1186665d117092ceb50f +github.com/pingcap/check,v0.0.0-20190102082844-67f458068fc8,h1:USx2/E1bX46VG32FIw034Au6seQ2fY9NEILmNh/UlQg=,b8eeddacc35915d8c40b42e9af4db468ed309a506412a767ba6bb03bb7ce4627 +github.com/pingcap/errors,v0.11.4,h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=,df62e548162429501a88d936a3e8330f2379ddfcd4d23c22b78bc1b157e05b97 +github.com/pingcap/gofail,v0.0.0-20181217135706-6a951c1e42c3,h1:04yuCf5NMvLU8rB2m4Qs3rynH7EYpMno3lHkewIOdMo=,444866a53b7429e80a8a16791e39555de8103c7514cd322fe191c902b8071360 +github.com/pingcap/goleveldb,v0.0.0-20171020122428-b9ff6c35079e,h1:P73/4dPCL96rGrobssy1nVy2VaVpNCuLpCbr+FEaTA8=,08ec0ffe5d0d74bdc543695f975316af6a63c17e36644ae56d42e30b0d1f8777 +github.com/pingcap/kvproto,v0.0.0-20191101062931-76b56d6eb466,h1:C5nV9osqA+R/R2fxYxVfqAUlCi3Oo5yJ/JSKDeHSAOk=,0d834c10c217c5de2c9ef79049891a69e73e102c4dbcd130173c3650e96da570 +github.com/pingcap/log,v0.0.0-20191012051959-b742a5d432e9,h1:AJD9pZYm72vMgPcQDww9rkZ1DnWfl0pXV3BOWlkYIjA=,eaece6f27792a39ccff08152050d4eb7905c250bf36877cacdd7e74c79d80472 +github.com/pingcap/parser,v0.0.0-20191101070347-94a5ef60f10b,h1:TLljHrSTC9MCTiUA6nMhV68my/D/FI3VNkUs94Wo3DE=,94e6857f4d2bf653edf4c2881cb8fb6b3abdf9efaec7d1f49159deec77580df2 +github.com/pingcap/pd,v2.1.17+incompatible,h1:mpfJYffRC14jeAfiq0jbHkqXVc8ZGNV0Lr2xG1sJslw=,b75266cd20abe6b1ccbb777a2f71d74dfcf231a06276b602df08bf27a9ea36f1 +github.com/pingcap/tidb-tools,v2.1.4+incompatible,h1:dkB4FMJcSk9GYRB2ICupU/lsTLf4mHLfkBE6fAsLdJ4=,c5c8e2b5c69c21bba2050c75d3a4582eda26308a355557036f058365d4583e5f +github.com/pingcap/tipb,v0.0.0-20191030045153-07a0962bbc64,h1:wUSHIp4dura5/YAepdgDBEdf2zz20MHXyNtMi1TcaDE=,8ac8e775e3d5fd255b7a8f07460f3b19bebb04cb50a3c0f5d6f64cc2fd585177 +github.com/pkg/browser,v0.0.0-20180916011732-0a3d74bf9ce4,h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98=,b845f84fbf08bba75401a4eff94c01c9e2c668fa1b43016e835bd60c6a8b4e87 +github.com/pkg/errors,v0.8.1,h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=,4e47d021340b7396a7dee454f527552faf7360a9fc34038b1dc32ba3b5a951d8 +github.com/pkg/profile,v1.3.0,h1:OQIvuDgm00gWVWGTf4m4mCt6W1/0YqU7Ntg0mySWgaI=,5f20c007ac81019900f06cf1e4d451ce8e1d981460e39e04794fbcc60639f851 +github.com/pkg/sftp,v1.10.1,h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc=,4e30f0455865434be7b83d4010ab97667217dafd0017caa651faafa2cc6aed64 +github.com/pkg/term,v0.0.0-20180730021639-bffc007b7fd5,h1:tFwafIEMf0B7NlcxV/zJ6leBIa81D3hgGSgsE5hCkOQ=,165bb00eeab26fe65c64e0e13bc29abc7ea18ac28d288e2218c137cd0bd91d9b +github.com/plaid/plaid-go,v0.0.0-20161222051224-02b6af68061b,h1:Don6I/E8nLCT6gdBi1sKB9hYxkx/24YD7XWwSly8IEo=,bd900ff0acd2968150f60770ab4e870d9f6b92c129a49eac0c9620a8043f901e +github.com/pmezard/go-difflib,v1.0.0,h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=,de04cecc1a4b8d53e4357051026794bcbc54f2e6a260cfac508ce69d5d6457a0 +github.com/polydawn/refmt,v0.0.0-20190408063855-01bf1e26dd14,h1:2m16U/rLwVaRdz7ANkHtHTodP3zTP3N451MADg64x5k=,a92440a944006fd3e0b6f1717fce4c2ea490cf2c4af93b56675216204f138c3a +github.com/portworx/kvdb,v0.0.0-20190911174000-a0108bddd091,h1:DqGiNhvCpvhWW/HJ1naJa0DudtlckvzQ9hEXSsOyv8Y=,d6fa957e1469a1b47ccbebc805034bafc5ed24798a1bef8675f751f9c4ed961e +github.com/portworx/sched-ops,v0.0.0-20191101005636-ded833c86f1e,h1:emQnaLwLEYN3Hner2ekVuZfrcChdN3H3J4Lxu5mPe64=,43ff366e97ff640a34a566c81dd7d63537c2864da85d33b49d5261417cd8d4b0 +github.com/posener/complete,v1.2.1,h1:LrvDIY//XNo65Lq84G/akBuMGlawHvGBABv8f/ZN6DI=,a97f73829e0b71ae7a8f17a4884d5dcbb2c3499d8d3a077c2a8d7c2596f68d37 +github.com/pquerna/cachecontrol,v0.0.0-20180517163645-1555304b9b35,h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU=,0e5185ab4dab1bb2241e9e23e36ebde5713f3fb1e47767c3eb44001b7e17644f +github.com/pquerna/ffjson,v0.0.0-20190930134022-aa0246cd15f7,h1:xoIK0ctDddBMnc74udxJYBqlo9Ylnsp1waqjLsnef20=,377b4667540f620eae19722b5346f6f1efdea5688f9eedda97f2c659dad131f9 +github.com/pquerna/otp,v1.1.0,h1:q2gMsMuMl3JzneUaAX1MRGxLvOG6bzXV51hivBaStf0=,d46d289853f801387dfc514fd50133de30b684a6af34031b27caa877cbb7f687 +github.com/profitbricks/profitbricks-sdk-go,v4.0.2+incompatible,h1:ZoVHH6voxW9Onzo6z2yLtocVoN6mBocyDoqoyAMHokE=,b0baf185752eb96f8890f3e9adf856b13f5c43b5346387b659e2b1deb1d087c7 +github.com/project-flogo/core,v0.9.3,h1:uZXHR9j1Byqt+x3faNnOqB8NlEfwE2gpCh40iQ+44oA=,d1c43e3bc517bb438a9d313d976e327ba219232418064d439fb20671341832a2 +github.com/projectcalico/libcalico-go,v1.7.3,h1:qcbxAhsq/5zqZqpHE24VqMHfmoBVdXZV0Kf82+5rbqU=,4f638d56eb47ff8e1763f65131050294f7d2c828139276fe86127a803245ae8c +github.com/prometheus/alertmanager,v0.18.0,h1:sPppYFge7kdf9O96KIh3fd093D1xN8JxIp03wW6yAEE=,45e122e7c2ac69577d63844313798060673a28b2e86ec8a0197f330c584b379b +github.com/prometheus/client_golang,v1.2.1,h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI=,174c921fe3e154adddd8e0dc572323dd04901bcad0965de614174241981da57c +github.com/prometheus/client_model,v0.0.0-20190812154241-14fe0d1b01d4,h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=,5d4719be47f4f69ab5bf36a04c75eb078a0f69b43a335f400c2d688ac9e61795 +github.com/prometheus/common,v0.7.0,h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY=,f2640a94b18b115552df41ee33effa013e10536aca51e09a971d1503a20e186a +github.com/prometheus/procfs,v0.0.5,h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=,f45b90c72f8c2e4c84e5314092ee1ccf7d6ace1cc14b2f483c82f7c1e6d0d0d4 +github.com/prometheus/prom2json,v1.1.0,h1:/fEL2DK7EEyHVeGMG4TV+gSS9Sw53yYKt//QRL0IIYE=,166f5f98c62d0b90139947d1464ee747f8143772b9e926c7b51c53a4420380ff +github.com/prometheus/prometheus,v2.5.0+incompatible,h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg=,ede73f6ccabd60365549986a6c7ae152c1952129006c8ae521c86ff45c4aadcc +github.com/prometheus/tsdb,v0.10.0,h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=,34e98f0e9ba55e7290774ee40569737745b395e32811e5940d2ed124a20f927c +github.com/pyinx/gorocket,v0.0.0-20170810024322-78ae1353729f,h1:N1r6pSlez3lLsqaNHbtrHW9ZuzrilETIabr9jPNj3Zs=,dcd920b789a98157bbe1ed7fff249255c1dd4d2fd80f7edc39b3a49fc08db13a +github.com/qor/admin,v0.0.0-20191021122103-f3db8244d2d2,h1:IWw22+hlihdss/qI93QH48jTBUEOD/fsBqj+0z61z/Y=,722e243550878791adcdb3bcea66ab8e7a185637c8a7ad0a752713951aef2a91 +github.com/qor/assetfs,v0.0.0-20170713023933-ff57fdc13a14,h1:JRpyNNSRAkwNHd4WgyPcalTAhxOCh3eFNMoQkxWhjSw=,7fe36875e7e59afd9154f827babbffaa7f67ac54b7790df5a4a4a376c78b2282 +github.com/qor/middlewares,v0.0.0-20170822143614-781378b69454,h1:+WCc1IigwWpWBxMFsmLUsIF230TakGHstDajd8aKDAc=,4c2ed9a2f7b24dfa64464091b2c01ce9fc947524bb834d77aeb9ceaf8610e5fc +github.com/qor/qor,v0.0.0-20191022064424-b3deff729f68,h1:MSbP9P4HnmEyH+uGQAW+V0HoTzlZ9SRq7kdCaRiZEmU=,9053796b8a7afe21483262affaf5b35bac8bf3387e24531448a4833d7b758978 +github.com/qor/render,v1.1.1,h1:DaGaKlf0OzpOB+hJUEiOTbZ40mg+n+LlSJx20/KUfes=,8f957a13173ef1a22d0caeea1cc6d198b064d242676444e00e2f597c405928c9 +github.com/qor/responder,v0.0.0-20171031032654-b6def473574f,h1:sKELSAyL+z5BRHFe97Bx71z197cBEobVJ6rASKTMSqU=,b69784649ec65ec2580d7640af25ec66973d59d82ec5391498cfe4c3076e5f6f +github.com/qor/roles,v0.0.0-20171127035124-d6375609fe3e,h1:F0BNcPJKfubM/+IIILu/GbrH9v2vPZWQ5/StSRKUfK4=,1a35a5480c7169e86025eb19dbcddc13fd00472e6b4ade7574e62c290cf09100 +github.com/qor/session,v0.0.0-20170907035918-8206b0adab70,h1:8l21EEdlZ9R0AA3FbeUAANc5NAx8Y3tn1VKbyAgjYlI=,7c759bc736c4936a602ca1f0ebad9a324d8332ffd342e1e3acd80355180fc858 +github.com/qor/validations,v0.0.0-20171228122639-f364bca61b46,h1:dRlsVUhwD1pwrasuVbNooGQITYjKzmXK5eYoEEvBGQI=,b29360c4a4e9cc8d0ff682d8bf1f446a5d61d5a4f8d3cf2fc6d8cc077e5d810f +github.com/racker/perigee,v0.1.0,h1:8RjBm1YGJKVVjUfO02Uok+npegz8lSSEVqjimDqlFYc=,d43613102ed67445c9fc81b621959b58f827c187189b09cec236c3bac5ce1ccb +github.com/raff/goble,v0.0.0-20190909174656-72afc67d6a99,h1:JtoVdxWJ3tgyqtnPq3r4hJ9aULcIDDnPXBWxZsdmqWU=,ef5dde1af55d451c37ddf13e17ae339d299903cb7e67567fc6d1e69688a789e1 +github.com/rai-project/config,v0.0.0-20190926180509-3bd01e698aad,h1:o0056EwcQBeyaVb2my+T0TvMR5FpEY0CGNgWkbj/xEo=,27c2311ad1fdc185e08f2e1703893482b7d26caf64854ed371bf38f3a9303f92 +github.com/rai-project/godotenv,v0.0.0-20180619160704-a501614c3b8d,h1:reVy+ViZcrx1ILo+L8wa3dGf6hSd4qlY62VqxZxEgWs=,f4d9ecb56f20667fbb09bd5256d0c6b81b9e8cbca8f6476240c5d1800ffb07ed +github.com/rai-project/logger,v0.0.0-20190701163301-49978a80bf96,h1:GeXSVSRfXOBN5XHNA+wq5G+sfq99mhpwn6U5kcGwSeg=,53d7677e7d7dab6b1f83591ec10491301289752e337641403f8413c0749b84d8 +github.com/rai-project/utils,v0.0.0-20180619204045-c582bb171808,h1:cHOS6oMEt8wi93zm5V7cHVnWgOhaAUCpjRDEZHBsckg=,6d43ccc901ad2f19744696f6c3d04ee28b4496cef7fe72ce7eccb89af0d8bfac +github.com/rai-project/vipertags,v0.0.0-20190404224953-d63b0a674aa9,h1:3o86f/tK0DBZdPcUBjzFu1mEZsRCzjSgi5PNHope4AQ=,9aa8cdd1a3369382d28bad0f4581250fbecae51602aa8566cbe68dfadc8f7785 +github.com/raintank/schema,v1.0.0,h1:tK0zKHceZd5nkCUI5Soip1pA2BAvoc4qzloVEsK0y+Q=,9ffc30e882b1cfed3152bab9c8c95e00c984dc0d8895426c95d96a184e09ffe3 +github.com/rainycape/memcache,v0.0.0-20150622160815-1031fa0ce2f2,h1:dq90+d51/hQRaHEqRAsQ1rE/pC1GUS4sc2rCbbFsAIY=,2d42bb018c6b0531f93e2dc862c87374966c64c9a88863612ab5e676a32661fa +github.com/rainycape/unidecode,v0.0.0-20150907023854-cb7f23ec59be,h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ=,0ab56010a3ef93c20bb6d8c486e3b447b4004052053e280ea6eabf2a5138bdce +github.com/rakyll/statik,v0.1.6,h1:uICcfUXpgqtw2VopbIncslhAmE5hwc4g20TEyEENBNs=,58cc0c07f8e9dd17ad5c4e0f89c03d8a3ed420aac0e76b79adf7ebd1d48c5893 +github.com/rcrowley/go-metrics,v0.0.0-20190826022208-cac0b30c2563,h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ=,22e944d960aec1a1e62e8cc2daaa70abefbbe989dd9c233060ab533de5f6e724 +github.com/remyoudompheng/bigfft,v0.0.0-20190512091148-babf20351dd7,h1:FUL3b97ZY2EPqg2NbXKuMHs5pXJB9hjj1fDHnF2vl28=,73f78c7e36c32822221f9f676b65ebe7ccb92ab6ff221035ace35c184e165c0d +github.com/renier/xmlrpc,v0.0.0-20170708154548-ce4a1a486c03,h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o=,f9c07652c6de1aecf5baaa3b93c1e6c23379458e30553400d5f96ac8b3ea85c4 +github.com/renstrom/fuzzysearch,v0.0.0-20160331204855-2d205ac6ec17,h1:4qPms2txLWMLXKzqlnYSulKRS4cS9aYgPtAEpUelQok=,01782a5d1682a72614126da402171253030c0de60485bc18a3e63b07d977c094 +github.com/retr0h/go-gilt,v0.0.0-20190206215556-f73826b37af2,h1:vZ42M1tDiMLtirFA1K5k2QVFhWRqR4BjdSw0IMclzH4=,e7956b01b3ccea41395f1f641a0f9045f214c1075d7ecc25553b72383009274e +github.com/revel/config,v0.21.0,h1:Bw4iXLGAuD/Di2HEhPSOyDywrTlFIXUMbds91lXTtTU=,22842698f6c646b9b89649b432d0f24deae1c5a3779c49819ec99c5db6e4b5a0 +github.com/revel/log15,v2.11.20+incompatible,h1:JkA4tbwIo/UGEMumY50zndKq816RQW3LQ0wIpRc+32U=,28e4263b0320a07dd2ae71ba09aef1f9b4af44258a8c0f1dfb1d63300f93c401 +github.com/revel/pathtree,v0.0.0-20140121041023-41257a1839e9,h1:/d6kfjzjyx19ieWqMOXHSTLFuRxLOH15ZubtcAXExKw=,de658b8de908c9c090343447e66e6bbdfe99656fcfa5889997486b0594c2a719 +github.com/revel/revel,v0.21.0,h1:E6kDJmpJSDb0F8XwbyG5h4ayzpZ+8Wcw2IiPZW/2qSc=,c66570c338f37e95626646909af1086f0bf31d8432fe982d24c415d14bc1dc9c +github.com/rivo/tview,v0.0.0-20191018125527-685bf6da76c2,h1:GVXSfgXOMAeLvFH7IrpY3yYM8H3YekZEFcZ14q9gQXM=,000538d9517bd5f28cfe377e63183f7093043acf8bb913eb493adb29518eb6b8 +github.com/rivo/uniseg,v0.1.0,h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=,cb701df81f36acfbb2627a78662fdcaa150ee1ac00d0796a7f3eafbdb6218128 +github.com/rjeczalik/notify,v0.9.2,h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8=,e8b9b93870f7ed17f30c617acb55f5fa78e7931518c88999c3d1b5b048f51482 +github.com/rkt/rkt,v1.30.0,h1:ZI5RQtSibfjicSttV/HLiHuWreYClEJA2Or5XKAdJb0=,ca2e00335dbeae7e0fbe2c45535d2bb8fce72c2bb6045b0bdf25bc6b8b59179e +github.com/robertkrimen/otto,v0.0.0-20180617131154-15f95af6e78d,h1:1VUlQbCfkoSGv7qP7Y+ro3ap1P1pPZxgdGVqiTVy5C4=,7adbe73b0db5319bae0421a0ed7fc5619002d6e9a2be87dc8c673c8541dfd949 +github.com/robfig/cron,v1.2.0,h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=,0811a1a5a4e1f45824ac520deb2002326a659dbb4918cdfea47d80560a23211d +github.com/robfig/cron/v3,v3.0.0,h1:kQ6Cb7aHOHTSzNVNEhmp8EcWKLb4CbiMW9h9VyIhO4E=,5e29b4f7f4ba62293420b918fb2309823523a583c2adaf6eddb059f525f05496 +github.com/rogpeppe/fastuuid,v1.2.0,h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s=,f9b8293f5e20270e26fb4214ca7afec864de92c73d03ff62b5ee29d1db4e72a1 +github.com/rogpeppe/go-charset,v0.0.0-20180617210344-2471d30d28b4,h1:BN/Nyn2nWMoqGRA7G7paDNDqTXE30mXGqzzybrfo05w=,a28b06534aa71873d08578d69b08512dab54caa0ffd9e2943b3479166049eddd +github.com/rogpeppe/go-internal,v1.4.0,h1:LUa41nrWTQNGhzdsZ5lTnkwbNjj6rXTdazA1cSdjkOY=,fb7d843253301d3ea9793f90e6bea16a8f2970a01b361f490ee66b36f81e03a5 +github.com/rpcx-ecosystem/quic-conn,v0.0.0-20190920095804-3967ef162525,h1:Awv5A28rrxuHf1+9+N08cnBa6JuKbhHswmNdfj65Bzo=,b40886ad7129eff9e517187b527467330db3705207349cdaa8f35c0dc8445c08 +github.com/rs/cors,v1.7.0,h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=,67815316761fddc4acfaad852965cf04ec88674abe3a05c6c332519556c55855 +github.com/rs/xhandler,v0.0.0-20160618193221-ed27b6fd6521,h1:3hxavr+IHMsQBrYUPQM5v0CgENFktkkbg1sfpgM3h20=,665ae95533e1a046cf470c7341c59e64b3e2a795cdaaf307368f69a0ba547f2c +github.com/rs/xid,v1.2.1,h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=,4abdedc4de69adcb9a4575f99c59d8ab542191e1800b6a91e12a4e9ea8da0026 +github.com/rs/zerolog,v1.16.0,h1:AaELmZdcJHT8m6oZ5py4213cdFK8XGXkB3dFdAQ+P7Q=,64e248c1fa3c62e2d904868b49acf906d0cb04a00a323d2562ea9ce7c6f154e1 +github.com/rubenv/sql-migrate,v0.0.0-20191025130928-9355dd04f4b3,h1:lwDYefgiwhjuAuVnMVUYknoF+Yg9CBUykYGvYoPCNnQ=,4d4e9e2c7387542b26a1cd9fbfcbdab7b75dce807877d5a0a501180b584c60f2 +github.com/rubyist/circuitbreaker,v2.2.1+incompatible,h1:KUKd/pV8Geg77+8LNDwdow6rVCAYOp8+kHUyFvL6Mhk=,fc1125d9260a471d349c94a251340c437f98743b42324706482596f303c28b11 +github.com/russross/blackfriday,v2.0.0+incompatible,h1:cBXrhZNUf9C+La9/YpS+UHpUT8YD6Td9ZMSU9APFcsk=,836047aa9cbd223efba85b892e6897cf7a3b5ee3f2e6ad36b189d40842f703df +github.com/russross/blackfriday/v2,v2.0.1,h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=,496079bbc8c4831cd0507213e059a925d2c22bd1ea9ada4dd85815d51b485228 +github.com/rwcarlsen/goexif,v0.0.0-20190401172101-9e8deecbddbd,h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc=,98e8ce7bf484716bdf272f31ee01354599f4ec4b4ece7c04156c15b264d8f6ec +github.com/ryanuber/columnize,v2.1.0+incompatible,h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s=,ff687e133db2e470640e511c90cf474154941537a94cd97bb0cf7a28a7d00dc7 +github.com/ryanuber/go-glob,v1.0.0,h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=,2084f36ead38a505489fdb46329502fb627f568224dcc22ef11ec173b61fc2cf +github.com/ryszard/goskiplist,v0.0.0-20150312221310-2dfbae5fcf46,h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8=,12c65729fc31d5a9bf246eb387bd4c268d0d68bf33b913cccd81bebd47d6f80d +github.com/sacloud/libsacloud,v1.26.1,h1:td3Kd7lvpSAxxHEVpnaZ9goHmmhi0D/RfP0Rqqf/kek=,4f0e24194ce3566707df5862177cb0f697debe3d5b799decb2685ee8d07dbe11 +github.com/saintfish/chardet,v0.0.0-20120816061221-3af4cd4741ca,h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=,d9cb0e35c88fbf91a409db0626f2e8ae9db305cf95dc3469dc7d089a8432c9c3 +github.com/samuel/go-zookeeper,v0.0.0-20190923202752-2cc03de413da,h1:p3Vo3i64TCLY7gIfzeQaUJ+kppEO5WQG3cL8iE8tGHU=,499f8144de8a6839b2d70c8869d88f294604188ec501e928ca17446043147d40 +github.com/sanity-io/litter,v1.1.0,h1:BllcKWa3VbZmOZbDCoszYLk7zCsKHz5Beossi8SUcTc=,c4bbddbf1bd7bb4ef74a3c2cac98f4a78a2a3a5a6b8dd140bd31a5d38c459217 +github.com/santhosh-tekuri/jsonschema,v1.2.4,h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis=,1c946415ee3395181090664a37779c296b540ca7eec58844ad0283fef11fec00 +github.com/sasha-s/go-deadlock,v0.2.0,h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y=,6c3f90c7947da1090f545438f4b3fd461cfeec79ee1c6e5e83a0eed7258622b1 +github.com/sassoftware/go-rpmutils,v0.0.0-20190420191620-a8f1baeba37b,h1:+gCnWOZV8Z/8jehJ2CdqB47Z3S+SREmQcuXkRFLNsiI=,88264dbd268c88bc8a57e4b4a261f22058fa6e03eb2883b0a82375f854e15188 +github.com/satori/go.uuid,v1.2.0,h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=,4f741306a0cbe97581e34a638531bcafe3c2848150539a2ec2ba12c5e3e6cbdd +github.com/satori/uuid,v1.2.0,h1:6TFY4nxn5XwBx0gDfzbEMCNT6k4N/4FNIuN8RACZ0KI=,bfd4d3d619e3ad4dd915e05fec5bf10949d8af9bc5c19b840db35ec0f21172ad +github.com/scaleway/scaleway-cli,v0.0.0-20180921094345-7b12c9699d70,h1:DaqC32ZwOuO4ctgg9qAdKnlQxwFPkKmCOEqwSNwYy7c=,05566d6711de08738803132b8522f7051fccd3b3bf2c739dde421fffdfa75eaf +github.com/sclevine/agouti,v3.0.0+incompatible,h1:8IBJS6PWz3uTlMP3YBIR5f+KAldcGuOeFkFbUWfBgK4=,b20c8a6a2c1fda0ae6a9cd6d319e78a7a5afea4bc90810cd46b99246d8219d23 +github.com/sclevine/spec,v1.2.0,h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA=,582017cd824cf3cdf6803ec7db2250304f66efea705feb69cbabab416928b8f4 +github.com/sean-/conswriter,v0.0.0-20180208195008-f5ae3917a627,h1:Tn2Iev07a4oOcAuFna8AJxDOF/M+6OkNbpEZLX30D6M=,0637d2fc0eb4627827e4b73dbe3a72479708641df8fc71a06e7bc481f6a7f39b +github.com/sean-/pager,v0.0.0-20180208200047-666be9bf53b5,h1:D07EBYJLI26GmLRKNtrs47p8vs/5QqpUX3VcwsAPkEo=,a4288f9116ea01c34efd65b7dce4357ba6f9c02ad984ca758fea0d0aebb605c9 +github.com/sean-/seed,v0.0.0-20170313163322-e2103e2c3529,h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=,0bc8e6e0a07e554674b0bb92ef4eb7de1650056b50878eed8d5d631aec9b6362 +github.com/sebest/xff,v0.0.0-20150611211316-7a36e3a787b5,h1:MqIPVG2sHTgcQxFwZ+iHZSQ869PVP42SgEEeI1+X4Y8=,8cbe518a78ab7998550c509bd9fadc95a1aef8e86b1022cb3d265348ad370cde +github.com/seccomp/libseccomp-golang,v0.9.1,h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo=,5989692d87ef4c377fbc60d441795a90d9453b9e357d019e44d9033ab39ca888 +github.com/segmentio/go-loggly,v0.5.1-0.20171222203950-eb91657e62b2,h1:S4OC0+OBKz6mJnzuHioeEat74PuQ4Sgvbf8eus695sc=,5e071d0b6923a0fa78895bf7e673f5a4e482d39d4603b7dabd4056a506923ca7 +github.com/segmentio/go-prompt,v1.2.1-0.20161017233205-f0d19b6901ad,h1:EqOdoSJGI7CsBQczPcIgmpm3hJE7X8Hj3jrgI002whs=,b86fcda4b8afd5a3893ea333431368e60ea5ebee302a3014aee6d2020233bf31 +github.com/segmentio/kafka-go,v0.1.0,h1:IXCHG+sXPNiIR5pC/vTEItZduPKu4cnpr85YgxpxlW0=,e0b749b974d3277438d09dd6178928c3ad6c3760313f7ad45ec5cd88d8eb14b9 +github.com/serenize/snaker,v0.0.0-20171204205717-a683aaf2d516,h1:ofR1ZdrNSkiWcMsRrubK9tb2/SlZVWttAfqUjJi6QYc=,67272dde9cf92af80704869dea59346be1c37098373200dd8eea6e0e034079b4 +github.com/sergi/go-diff,v1.0.0,h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=,287218ffcd136dbb28ce99a2f162048d8dfa6f97b524c17797964aacde2f8f52 +github.com/serialx/hashring,v0.0.0-20180504054112-49a4782e9908,h1:RRpyb4kheanCQVyYfOhkZoD/cwClvn12RzHex2ZmHxw=,4184e14faf8e39222109eb2b7fa3aee2e0a544b66785ad0b7058318483ff76bb +github.com/sethgrid/pester,v0.0.0-20190127155807-68a33a018ad0,h1:X9XMOYjxEfAYSy3xK1DzO5dMkkWhs9E9UCcS1IERx2k=,ddcaf31e63aaf1ac003af97e667bedaa0fc89956e19aeb032c5658629da29800 +github.com/shiena/ansicolor,v0.0.0-20151119151921-a422bbe96644,h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=,60da6dc53662eb72063784f3bf609edb7aa317c552f81651164bc657754902a6 +github.com/shirou/gopsutil,v2.19.10+incompatible,h1:lA4Pi29JEVIQIgATSeftHSY0rMGI9CLrl2ZvDLiahto=,e5afa6f0b690ecc3ff12458663c6337920a759f27c3d9692a0836644337e4e85 +github.com/shirou/w32,v0.0.0-20160930032740-bb4de0191aa4,h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U=,3ed6741a7e1470feffb50031ecf9919f30b5f573f993683b6574488756ef65c1 +github.com/shopspring/decimal,v0.0.0-20191009025716-f1972eb1d1f5,h1:Gojs/hac/DoYEM7WEICT45+hNWczIeuL5D21e5/HPAw=,91a0ee539fb6f3de1550cdf93c73434fc8a16bab37be693997b20317510331a9 +github.com/shurcooL/component,v0.0.0-20170202220835-f88ec8f54cc4,h1:Fth6mevc5rX7glNLpbAMJnqKlfIkcTjZCSHEeqvKbcI=,2dd1cfac518def9fc8c6ac69022a85b0413269caf93d9532f77dca7375e1d645 +github.com/shurcooL/events,v0.0.0-20181021180414-410e4ca65f48,h1:vabduItPAIz9px5iryD5peyx7O3Ya8TBThapgXim98o=,1dcade8d00ba3945f5d1bc56c09a84e2d51fa20d20ef4fa6f867e5e4cd918e9d +github.com/shurcooL/github_flavored_markdown,v0.0.0-20181002035957-2122de532470,h1:qb9IthCFBmROJ6YBS31BEMeSYjOscSiG+EO+JVNTz64=,d984dc45e823f4c99e89841d675e34d2d35d3b334f1b3690fde05de30a66929f +github.com/shurcooL/githubv4,v0.0.0-20191006152017-6d1ea27df521,h1:ARaYJO1zp2afVv0s28fq7uxgee4WLop35FWrOoSZyak=,7f5c88b38760c5090bffe582a40abe7dc17a789f9041549e5c17e3d71df2d75d +github.com/shurcooL/go,v0.0.0-20180423040247-9e1955d9fb6e,h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM=,350e4c547dbeb657bb3b2eab428f1c29a80808e8096ff87324fd84744f914766 +github.com/shurcooL/go-goon,v0.0.0-20170922171312-37c2f522c041,h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc=,31cb3f736521597c56f962b9d7d21073620fbb1da845305aba743960f09e4115 +github.com/shurcooL/gofontwoff,v0.0.0-20180329035133-29b52fc0a18d,h1:Yoy/IzG4lULT6qZg62sVC+qyBL8DQkmD2zv6i7OImrc=,685dedb79602bb41403a7b5198f5c9d0ffbc99a68d7f99160ecf08a71475e5f4 +github.com/shurcooL/gopherjslib,v0.0.0-20160914041154-feb6d3990c2c,h1:UOk+nlt1BJtTcH15CT7iNO7YVWTfTv/DNwEAQHLIaDQ=,ea6c396c92724a8028793bde957dbe9a1c594b8af085035e652d4335e6aa30e1 +github.com/shurcooL/graphql,v0.0.0-20181231061246-d48a9a75455f,h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk=,eb1b45dc90aed0edcfc4cacffdc2645121dda8155702440eada1bcafefddcbba +github.com/shurcooL/highlight_diff,v0.0.0-20170515013008-09bb4053de1b,h1:vYEG87HxbU6dXj5npkeulCS96Dtz5xg3jcfCgpcvbIw=,b4bcb7f3e50a99623d5f39c4e054964fc60d5e4b34543408582a0a984a67b630 +github.com/shurcooL/highlight_go,v0.0.0-20181028180052-98c3abbbae20,h1:7pDq9pAMCQgRohFmd25X8hIH8VxmT3TaDm+r9LHxgBk=,9f879b051c8eadb6dc063ca3ff6856d0e64cd30b5ad545e580b77b4f8ef9ddd7 +github.com/shurcooL/home,v0.0.0-20181020052607-80b7ffcb30f9,h1:MPblCbqA5+z6XARjScMfz1TqtJC7TuTRj0U9VqIBs6k=,0042d859afa3221fd4b4049b350a2d6ffcc674e4c4177bb0c232dc120b410ee6 +github.com/shurcooL/htmlg,v0.0.0-20190503024804-b6326af49ef6,h1:kXXs9Xnfv5gU7KLKiOE3AQgaRUUXchcXnO2rP3fZ5Ao=,52485f17bba8920b37a70124b90eea9d43037a9764a785c97a7e531ca09ed5a5 +github.com/shurcooL/httperror,v0.0.0-20190506043526-2e76094aa70e,h1:QTph/PpT1aDtFHk0sVJoVG/Vfox0YZkq70sW/tvXJM0=,7807129d1577611bdf803b7a4dd3253f45e4b63a77c1a73bed48a0c838c463c6 +github.com/shurcooL/httpfs,v0.0.0-20190707220628-8d4bc4ba7749,h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=,a2079dbd8c236262ecbb22312467265fbbddd9b5ee789531c5f7f24fbdda174b +github.com/shurcooL/httpgzip,v0.0.0-20190720172056-320755c1c1b0,h1:mj/nMDAwTBiaCqMEs4cYCqF7pO6Np7vhy1D1wcQGz+E=,70ef73fce2f89d622f828cb439fd6c7b48a7fe63600410a8c0a936042c0e4631 +github.com/shurcooL/issues,v0.0.0-20190705005435-6a96395fbb66,h1:kls/E9JqtKEj8tWx2PwKCWqEWmwzsX7cnj9QkaEhUpM=,dd1ace2ad69b6c130a9294c3eb4032090e73c3b7dace098a5a7e1ad154f8e911 +github.com/shurcooL/issuesapp,v0.0.0-20180602232740-048589ce2241,h1:Y+TeIabU8sJD10Qwd/zMty2/LEaT9GNDaA6nyZf+jgo=,ac947684d3f13beef9433724deddc2c7ddb6d19921d6902f4789dd4ce1af5f3c +github.com/shurcooL/notifications,v0.0.0-20181111060504-bcc2b3082a7a,h1:bQX0+HfDylIQCtf1tzyrxQ+BqIV08ZjkjgspFWiIYhc=,c1c77700f490d0211cec00fd5fd0ee80debf66e0e41de1dc68b24dc726db5409 +github.com/shurcooL/octicon,v0.0.0-20190930024621-43309dfb482e,h1:C2+alklsN4yRHXaOX3v9TuCGlTSwZQjSnN88nLGVhg8=,88953a9951a14e24afd2d1040e9de0b4fbe194805fdc7ec9d9d9bbcd8c2f3448 +github.com/shurcooL/reactions,v0.0.0-20181222204718-145cd5e7f3d1,h1:hHIhW4KrmPQ/hJ7AuKNNvVPVE2k/LVE5NTFsQ68taBw=,fd5f9a0c6e7e292bdfa81fcad767f61c95dc84f18bf4f9f02a4fe02f75327d37 +github.com/shurcooL/sanitized_anchor_name,v1.0.0,h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=,0af034323e0627a9e94367f87aa50ce29e5b165d54c8da2926cbaffd5834f757 +github.com/shurcooL/users,v0.0.0-20180125191416-49c67e49c537,h1:YGaxtkYjb8mnTvtufv2LKLwCQu2/C7qFB7UtrOlTWOY=,3f17089e996438a88a478d38807ce4f3c045a91114830946a1bdc760eb2b7c58 +github.com/shurcooL/vfsgen,v0.0.0-20181202132449-6a9ea43bcacd,h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=,8a093681b21159514a1742b1a49e88fa2cf562673a5a0055e9abeb7ff590ee19 +github.com/shurcooL/webdavfs,v0.0.0-20170829043945-18c3829fa133,h1:JtcyT0rk/9PKOdnKQzuDR+FSjh7SGtJwpgVpfZBRKlQ=,bb70104152800cbb490c480bead0d2ef24176be9e1304e6701ab161115484863 +github.com/siddontang/go,v0.0.0-20180604090527-bdc77568d726,h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM=,ef97fabc8a96a758fac273b01dff6be7957ed44c4b6c6a8316f43741329a0049 +github.com/siddontang/go-snappy,v0.0.0-20140704025258-d8f7bb82a96d,h1:qQWKKOvHN7Q9c6GdmUteCef2F9ubxMpxY1IKwpIKz68=,faf83d6459d06f5f4a9acd09e23e284e11792d14de331bd7b87852b18f9cf5c3 +github.com/siddontang/ledisdb,v0.0.0-20190202134119-8ceb77e66a92,h1:qvsJwGToa8rxb42cDRhkbKeX2H5N8BH+s2aUikGt8mI=,dab81c0bdfc62063a340f61dfab19c065d2d10b1245cd56cc04832130a6bbea5 +github.com/siddontang/rdb,v0.0.0-20150307021120-fc89ed2e418d,h1:NVwnfyR3rENtlz62bcrkXME3INVUa4lcdGt+opvxExs=,93bf89960d84b8732e648cb413dced692c1d3d9000997e99826538a5f20b1d82 +github.com/sigurn/crc8,v0.0.0-20160107002456-e55481d6f45c,h1:hk0Jigjfq59yDMgd6bzi22Das5tyxU0CtOkh7a9io84=,12916a0da94e747b99653138a25112e24b082db53bc0d5cffe62214ce3fb884d +github.com/sigurn/utils,v0.0.0-20190728110027-e1fefb11a144,h1:ccb8W1+mYuZvlpn/mJUMAbsFHTMCpcJBS78AsBQxNcY=,694bb4cbe9dd17447c1e0054ef327eebd9bed8682aa39f5f4d282fb9b1717299 +github.com/sirupsen/logrus,v1.4.2,h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=,9a8e55830261a4b1c9350d7c45db029c8586c0b2d934d1224cde469425031edd +github.com/skratchdot/open-golang,v0.0.0-20190402232053-79abb63cd66e,h1:VAzdS5Nw68fbf5RZ8RDVlUvPXNU6Z3jtPCK/qvm4FoQ=,242db3338b172ecb58bdf3406b4cafecfa738cfb7b8cd71698d23831aedd94b0 +github.com/skyrings/skyring-common,v0.0.0-20160929130248-d1c0bb1cbd5e,h1:jrZSSgPUDtBeJbGXqgGUeupQH8I+ZvGXfhpIahye2Bc=,d5010d4900d7417c05d4863399e5509e82dfaca9c09c31ac9e5ebdcaf109e833 +github.com/smallnest/libkv-etcdv3-store,v0.0.0-20191101045330-f92940446965,h1:YQtdLz+7JQdKn7f5cG+xSrSbI7X4jObx0Jy6ZzffGew=,b9fb22d7d67e16cd3a1d7c7a5b2faf6c35c690ae1c3bcf70dbf77813db7dc563 +github.com/smallnest/rpcx,v0.0.0-20191101045608-2a801682117a,h1:Fzp1HLqyYg8koEELgwfSEUgkE6QPvrN9qCkHZ8tikFY=,0d2255c9ffc429e32936dbb9e51c79bbf2b76a7dec95c5d9dc1668053d5642bc +github.com/smallnest/valkeyrie,v0.0.0-20191030064635-54a884e4b303,h1:NDOAHb1sE8pYWd0Dge8W6bGQ63FHfa0/QjClXG2hrgw=,b846d492aaf7053115b2e143b7c7696299b852ec670d261bd78b5cd996eacde3 +github.com/smartystreets/assertions,v1.0.1,h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=,2e3d9f61f68cdf7b48653582640ef88744c1a3bdd4257ac68f621579a2f807dd +github.com/smartystreets/go-aws-auth,v0.0.0-20180515143844-0c1422d1fdb9,h1:hp2CYQUINdZMHdvTdXtPOY2ainKl4IoMcpAXEf2xj3Q=,d9441cfbef2c680269ced67f8e1d99af9cf649e11a7f133a5b0685be0277ca7d +github.com/smartystreets/goconvey,v0.0.0-20190731233626-505e41936337,h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=,fd90be078397b45806e4dfaca367235aef6d6133871c8a6cc6d3d579280d8d03 +github.com/smartystreets/gunit,v1.0.0,h1:RyPDUFcJbvtXlhJPk7v+wnxZRY2EUokhEYl2EJOPToI=,36cf43529cfadeb297ce1537c7d0fca8373a95936806121ce7ce0bf653e959ee +github.com/smola/gocompat,v0.2.0,h1:6b1oIMlUXIpz//VKEDzPVBK8KG7beVwmHIUEBIs/Pns=,7812934f407beeab20aa289b0056234ae6637b30b301ebf97a5d7a9fd8e665fc +github.com/snikch/goodman,v0.0.0-20171125024755-10e37e294daa,h1:YJfZp12Z3AFhSBeXOlv4BO55RMwPn2NoQeDsrdWnBtY=,ab939c56cb7afcff213aef4568f40c9ddeae30166e34a2fa7f5718a47227c2e1 +github.com/softlayer/softlayer-go,v0.0.0-20180806151055-260589d94c7d,h1:bVQRCxQvfjNUeRqaY/uT0tFuvuFY0ulgnczuR684Xic=,63ad57bc2d4c27db3dcab7cf545a075bb4d7ea66aba57c284c07a2c938220f8c +github.com/soheilhy/cmux,v0.1.4,h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=,6d6cadade0e186f84b5f8e7ddf8f4256601b21e49b0ca49fd003a7e570ae1885 +github.com/songtianyi/rrframework,v0.0.0-20180901111106-4caefe307b3f,h1:o3QHyJEW1U+8oyEZeaXFcYqdhhiZjrs25/8AZmsWjiU=,b1cf04474a48de1ed7ae535ae4a2d5b17a0df4ce0d3b953c5268f42ee34cb17d +github.com/soniakeys/unit,v1.0.0,h1:UMIgu6dxDQaK6tYaQV6dJn5oovB6035KRxCS0O7Jiec=,565c64fe777e1140d82422e9b8d29ce8de82d7916e50dac2f7591d2c6f2d79e7 +github.com/sony/gobreaker,v0.4.1,h1:oMnRNZXX5j85zso6xCPRNPtmAycat+WcoKbklScLDgQ=,eab9bf8f98b16b051d7d13c4f5c70d6d1039347e380e0a12cb9ff6e33200d784 +github.com/sourcegraph/annotate,v0.0.0-20160123013949-f4cad6c6324d,h1:yKm7XZV6j9Ev6lojP2XaIshpT4ymkqhMeSghO5Ps00E=,2a58cbf2485b2e97e49d7c3e83e81385d1418bfbab2b846dabec041a3d402b3e +github.com/sourcegraph/syntaxhighlight,v0.0.0-20170531221838-bd320f5d308e,h1:qpG93cPwA5f7s/ZPBJnGOYQNK/vKsaDaseuKT5Asee8=,c0e6323ed7a5dcddcdd7686f2d7c68dff44a8ecbfd6818db3bdb33a7af422792 +github.com/spacemonkeygo/errors,v0.0.0-20171212215202-9064522e9fd1,h1:xHQewZjohU9/wUsyC99navCjQDNHtTgUOM/J1jAbzfw=,b360a46f9534dd46d2b2c27c84ba8bbe3942832e74aa4ceb16acaa6ba30620be +github.com/spacemonkeygo/monotime,v0.0.0-20180824235756-e3f48a95f98a,h1:8+cCjxhToanKmxLIbuyBNe2EnpgwhiivsIaRJstDRFA=,4a55e556811ab93b23b46907b354e53fc553eb93314cf0b524933f37ac1437f8 +github.com/spacemonkeygo/openssl,v0.0.0-20181017203307-c2dcc5cca94a,h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek=,23031c8d37bbaa5aace338eed65af68c7d72bf134d7d0e09c963ed4974c56e58 +github.com/spacemonkeygo/spacelog,v0.0.0-20180420211403-2296661a0572,h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=,91eb98e80c44d42e6f3ff7ddf84f825d20eb55669452d752fb8ed3adeb723be7 +github.com/spaolacci/murmur3,v1.1.0,h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=,60bd43ada88cc70823b31fd678a8b906d48631b47145300544d45219ee6a17bc +github.com/spf13/afero,v1.2.2,h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=,81d51799397212c9adb2cea6cf3a96a2b50f1baff8aff7bd410128a84f2a9e73 +github.com/spf13/cast,v1.3.0,h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=,001ed519a3ec007e76e639f72bd9560be70497d499acbf1a32ccf32dc4647d91 +github.com/spf13/cobra,v0.0.5,h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=,6c6739f11d69fa1e5b60ba1e04529f355f8a30e1aa2b137ba26260de8fa7a647 +github.com/spf13/fsync,v0.9.0,h1:f9CEt3DOB2mnHxZaftmEOFWjABEvKM/xpf3cUwJrGOY=,d470c73c6e821d6c8f47ce05be3360f4d686d9079dd5af1585420c73e4725c56 +github.com/spf13/jwalterweatherman,v1.1.0,h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=,43cc5f056caf66dc8225dca36637bfc18509521b103a69ca76fbc2b6519194a3 +github.com/spf13/pflag,v1.0.5,h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=,fc6e704f2f6a84ddcdce6de0404e5340fa20c8676181bf5d381b17888107ba84 +github.com/spf13/viper,v1.5.0,h1:GpsTwfsQ27oS/Aha/6d1oD7tpKIqWnOA6tgOX9HHkt4=,7f3513d0a1186b765937c788f0ac751076067b7a0abc82420171b6f262787ac5 +github.com/src-d/envconfig,v1.0.0,h1:/AJi6DtjFhZKNx3OB2qMsq7y4yT5//AeSZIe7rk+PX8=,c694b1440b6969dfd4ebcba669faea8a05bdc7791ac78dcfbe29f153b0a8f0cd +github.com/src-d/gcfg,v1.4.0,h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4=,2aa52404cbeec89c0a976d333448d1a4a6e113f03e000a715ce9006c84eb2e32 +github.com/srwiley/oksvg,v0.0.0-20190829233741-58e08c8fe40e,h1:LJUrNHytcMXWKxnULIHPe5SCb1jDpO9o672VB1x2EuQ=,e29e85accb2169d2f0f4dc90c22c446c24d244d68e0bbe038ba9df63381916c5 +github.com/srwiley/rasterx,v0.0.0-20181219215540-696f7edb7a7e,h1:FFotfUvew9Eg02LYRl8YybAnm0HCwjjfY5JlOI1oB00=,8a4b0686258a3e1b4f8b3e5f25efbaaefe7919d4e47e89eb36a6779504f8b116 +github.com/ssdb/gossdb,v0.0.0-20180723034631-88f6b59b84ec,h1:q6XVwXmKvCRHRqesF3cSv6lNqqHi0QWOvgDlSohg8UA=,2c20531d93416fa34ee9039308166c869c72c16fff715c73c05a3977157fdc2d +github.com/ssor/bom,v0.0.0-20170718123548-6386211fdfcf,h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=,7622ce25bbc5d5376ccb113f267f3d68bf2363963b02d04c053dfbc252f62c4a +github.com/steakknife/bloomfilter,v0.0.0-20180922174646-6819c0d2a570,h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE=,fb001f6df1197d462e7dfdbeded863aebd85bb904da5075117174a027a1b8cb1 +github.com/steakknife/hamming,v0.0.0-20180906055917-c99c65617cd3,h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=,e42bd1bc7073772613c2b4879110dd5330fded46a8cdf9269ff03cb6a82d1108 +github.com/stellar/go,v0.0.0-20191031165136-ed88b67b723d,h1:0pucQZ9fngYUl/tIGO/H96N3F5NL5ySjM3fuz+XEFSY=,d9d23bd5fc8cae6e65d4bb0d87e3cb582bc684eac1a519ca787b187a175999a5 +github.com/stellar/go-xdr,v0.0.0-20180917104419-0bc96f33a18e,h1:n/hfey8pO+RYMoGXyvyzuw5pdO8IFDoyAL/g5OiCesY=,5122e57a861bd0c38a3a3607f13576a150face8cacf9cafaf24e21e38a104b87 +github.com/stellar/throttled,v2.2.3-0.20190823235211-89d75816f59d+incompatible,h1:jMXXAcz6xTarGDQ4VtVbtERogcmDQw4RaE85Cr9CgoQ=,a89e929d8d8ba24e621c479708378263714861d8fce137085108da9f0cc8805a +github.com/steveyen/gtreap,v0.0.0-20150807155958-0abe01ef9be2,h1:JNEGSiWg6D3lcBCMCBqN3ELniXujt+0QNHLhNnO0w3s=,64b6a1f094784f1a843a6787bd159a103b9bebd2e85cc09a7e8445cc9e3ffc03 +github.com/streadway/amqp,v0.0.0-20190827072141-edfb9018d271,h1:WhxRHzgeVGETMlmVfqhRn8RIeeNoPr2Czh33I4Zdccw=,66bd109504bf565a4a777c20a8cf6a1c5d05cd87b59baa50da8b6f2b0da4c494 +github.com/stretchr/objx,v0.2.0,h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=,5517d43cfb7e628b9c2c64010b934e346cd24726e3d6eaf02b7f86e10752e968 +github.com/stretchr/testify,v1.4.0,h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=,0400c42ab95389bb4f4577bc09917a040a97f0f4251db2a54a7f6f5e65065b73 +github.com/stripe/stripe-go,v66.1.1+incompatible,h1:D8qUD1rxv+RdXi2qo+IdDELkDevxYUQDfje20bGQPiw=,471de64dbc99da2b83fc1822ff9b4627b1b0738a8e3ee9ffb038510ce84e4baf +github.com/struCoder/pidusage,v0.1.2,h1:fFPTThlcWFQyizv3xKs5Lyq1lpG5lZ36arEGNhWz2Vs=,6ae03cd6cab9014ca7c0326fc233b27d942556c9753d2da87a93dd0fecbb9986 +github.com/stumble/gorocksdb,v0.0.3,h1:9UU+QA1pqFYJuf9+5p7z1IqdE5k0mma4UAeu2wmX8kA=,8bf18874189196133dabeb8fb7444633a0961e8983f8b2d8588d522d6aa679de +github.com/subosito/gotenv,v1.2.0,h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=,21474df92536f36de6f91dfbf466995289445cc4e5a5900d9c40ae8776b8b0cf +github.com/svanharmelen/jsonapi,v0.0.0-20180618144545-0c0828c3f16d,h1:Z4EH+5EffvBEhh37F0C0DnpklTMh00JOkjW5zK3ofBI=,482b13f426a15f3cb64ae5cb1a5fd2f27ca142465a174e24a2cc356812a3ed28 +github.com/swaggo/files,v0.0.0-20190704085106-630677cd5c14,h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=,e1fe1ffca3a181bede3787e75797345bc69a583a67d8bb10b934f7a140516162 +github.com/swaggo/gin-swagger,v1.2.0,h1:YskZXEiv51fjOMTsXrOetAjrMDfFaXD79PEoQBOe2W0=,7ba6476ca79affa95429821a187b7cb3458305737ac2d1b86340814c3f276f71 +github.com/swaggo/swag,v1.6.3,h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI=,1adbe98538a3f1b5e64fdf08f86cea4502a2c0d0cf1b047a27af6acf764f8c17 +github.com/syndtr/gocapability,v0.0.0-20180916011248-d98352740cb2,h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=,ece41bcca6ca06202649ccee0d2ab62667217ceb70f3a84794c3751c16b75cee +github.com/syndtr/goleveldb,v1.0.1-0.20190318030020-c3a204f8e965,h1:1oFLiOyVl+W7bnBzGhf7BbIv9loSFQcieWWYIjLqcAw=,b0dbd1bdec73ea70eb1db85322046d202bcbfe901bc821d6a50ffc182c276306 +github.com/tarm/serial,v0.0.0-20180830185346-98f6abe2eb07,h1:UyzmZLoiDWMRywV4DUYb9Fbt8uiOSooupjTq10vpvnU=,cd962b3b9ef46158abad455c95ed92f2632cdb9217df2b7690171cc3db507add +github.com/tatsushid/go-fastping,v0.0.0-20160109021039-d7bb493dee3e,h1:nt2877sKfojlHCTOBXbpWjBkuWKritFaGIfgQwbQUls=,1c25333d4ca05ca13828835e07876c0efdd90a1c32a715527aa722b3c63c2d48 +github.com/tchap/go-patricia,v2.3.0+incompatible,h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=,19db63cf16ba944ea853c18397e4336342f1e95e4b2cb12127405bb64c67cf73 +github.com/tdewolff/minify,v2.3.6+incompatible,h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo=,8cabb8163bd65e43b42c5842b700d55e2daeae60c82b019007aceb1ae63638d5 +github.com/tdewolff/minify/v2,v2.5.2,h1:If/q1brvT+91oWiWnIMEGuFcwWtpB6AtLTxba78tvMs=,0af37ec252d094917a1ff4178659fe9f4539fdc3dca108bbeb9c0c2f86499eb9 +github.com/tdewolff/parse,v2.3.4+incompatible,h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=,f290dda8150ebdc2b9586f509770a6c82093ac9027329aeb9f3004a0b26de8e9 +github.com/tdewolff/parse/v2,v2.3.9,h1:d8/K6XOLy5JVpLTG9Kx+SxA72rlm5OowFmVSVgtOlmM=,5f517cbecd071b97ed822e8f88f96ba7d8b5a8accc49fc515298210ac088e7ef +github.com/tdewolff/test,v1.0.4,h1:ih38SXuQJ32Hng5EtSW32xqEsVeMnPp6nNNRPhBBDE8=,807205136d8f39bb7533d10b72932a183f15b45c385cd5464ae9d06e4af43337 +github.com/tealeg/xlsx,v1.0.5,h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=,ff32f4336aed03df7c9cb7a4df9f1f42a1c64fe5d17c34566159511943d24bde +github.com/tecbot/gorocksdb,v0.0.0-20181010114359-8752a9433481,h1:HOxvxvnntLiPn123Fk+twfUhCQdMDaqmb0cclArW0T0=,26c0e94162340c7b4d1da3ee4c71ca03f9d6638711cf440d6835e1a8f07e4fb4 +github.com/technoweenie/multipartstreamer,v1.0.1,h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=,5a9aff85522275b125767b746869d24f4e2f776d5031631bf6e29641d99344dc +github.com/tedsuo/ifrit,v0.0.0-20191009134036-9a97d0632f00,h1:mujcChM89zOHwgZBBNr5WZ77mBXP1yR+gLThGCYZgAg=,1c502a5584dfbce25ff99c1a5689e2d106a138989e4a03249221ca4818674098 +github.com/tedsuo/rata,v1.0.0,h1:Sf9aZrYy6ElSTncjnGkyC2yuVvz5YJetBIUKJ4CmeKE=,f6745fd8ef8ee098410b31b1219def2c4e86c337ba6ff1319f086419b928f134 +github.com/temoto/robotstxt,v1.1.1,h1:Gh8RCs8ouX3hRSxxK7B1mO5RFByQ4CmJZDwgom++JaA=,c37f16f826a27512b7ae683ed32be5124a0252d1c7a8c4a00fd4e27d01c563d4 +github.com/templexxx/cpufeat,v0.0.0-20180724012125-cef66df7f161,h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=,c29bd644943d69b238da1936593421373d2db675a0fce54090d1c8b7eab7397b +github.com/templexxx/xor,v0.0.0-20181023030647-4e92f724b73b,h1:mnG1fcsIB1d/3vbkBak2MM0u+vhGhlQwpeimUi7QncM=,578ab42785a74d1a5dd3e65bf0979138b3a98bf877de4767b8eae5701a2342e1 +github.com/tencentcloud/tencentcloud-sdk-go,v3.0.71+incompatible,h1:9sIWfe6ZC7xoSlshYWNGicPqomK7N+CsHMa1YFWBCWU=,33a9526ee0244844270e532358a22616d821cc7f8f0638e33c60f722f84c5e42 +github.com/tendermint/btcd,v0.1.1,h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s=,1967aa3cbabfb9e9780c0371a5359cc21ed77e5673b64e7dd5b234e838c82e62 +github.com/tendermint/crypto,v0.0.0-20180820045704-3764759f34a5,h1:u8i49c+BxloX3XQ55cvzFNXplizZP/q00i+IlttUjAU=,49ad334d452402d59757d3a415602f57bd7b66962d6115262f5c7413112d61bb +github.com/tendermint/ed25519,v0.0.0-20171027050219-d8387025d2b9,h1:zccWau0P8FELSb4HTDJ88hRo+WVNMbIbg27rFqDrhCE=,7c4a6e57c787df7c6e990c35bb31df3f4a5aa89f45c3b3df4a25dfb70c01f7e3 +github.com/tendermint/go-amino,v0.15.1,h1:D2uk35eT4iTsvJd9jWIetzthE5C0/k2QmMFkCN+4JgQ=,e91cde0d10d5a8ea6ab726fbab02ef737ba52f47e207cf675440f625153d3205 +github.com/tendermint/iavl,v0.12.2,h1:Ls5p5VINCM1HRT9g5Vvs2zmDOCU/CCIvIHzd/pZ8P0E=,a56011434929c4003fd735cbef8147e8aca3d241983c5fa7a006f5753e123020 +github.com/tendermint/tendermint,v0.32.7,h1:Szu5Fm1L3pvn3t4uQxPAcP+7ndZEQKgLie/yokM56rU=,495a31dc762d79a689ce00cdd52f66b6b4071fc2b738ce4b3d1c2a9447389ecc +github.com/tendermint/tm-db,v0.2.0,h1:rJxgdqn6fIiVJZy4zLpY1qVlyD0TU6vhkT4kEf71TQQ=,99b7c1a00ee483b97e73126a25327b75da9a5bc6e34bf9fb1ecd6b83832fe13e +github.com/tent/http-link-go,v0.0.0-20130702225549-ac974c61c2f9,h1:/Bsw4C+DEdqPjt8vAqaC9LAqpAQnaCQQqmolqq3S1T4=,a4fe19fdbf8fbc30fe866e2cbb8761ee179f4a83bda63a0a6d30a651f3700ec2 +github.com/terraform-providers/terraform-provider-openstack,v1.15.0,h1:adpjqej+F8BAX9dHmuPF47sUIkgifeqBu6p7iCsyj0Y=,9c7419845747d0c4e3a9432f50788d8adec7ed6fca93ec9ffbf99e8c8b1cf0c3 +github.com/testcontainers/testcontainers-go,v0.0.8,h1:71E+jJpE9dSgydCfn5aWESVM7+l8giw/DBWaTy35TTU=,bceec8989a3beb9f14802c13c496c9158509f6b4cee6f855c0fb06b01e7da150 +github.com/tevino/abool,v0.0.0-20170917061928-9b9efcf221b5,h1:hNna6Fi0eP1f2sMBe/rJicDmaHmoXGe1Ta84FPYHLuE=,924168edd97fe37d4af80990d69c1d11d06b8e9236ebae65b9b68ba0261baaf1 +github.com/tgulacsi/picago,v0.0.0-20171229130838-9e1ac2306c70,h1:elvpffAnrLcWnsunBkvTwxr+Q79bPSNT1+2/pOFkCj0=,68e0cb434718215eae670723ce9327ec16d462a6403007ca22b6af71346445c5 +github.com/thanos-io/thanos,v0.3.2,h1:gNWga6sqv5kZp6ltaA7oUIFj+tTG2ohq4W9SQ4YU6ds=,99491658e5ed421ba1563818dd7c01034803fa1e0c4e5d7c28b06f3d3ed2a570 +github.com/theplant/cldr,v0.0.0-20190423050709-9f76f7ce4ee8,h1:di0cR5qqo2DllBMwmP75kZpUX6dAXhsn1O2dshQfMaA=,214ea2cc1e66f278928d0b5b1b40a3e12358b7a71e0fa6d6ea606c4d687e8eef +github.com/theupdateframework/notary,v0.6.1,h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=,f921dfb3d54538118367d9018d9abacc3c0c026951442140d669443977180b66 +github.com/thoj/go-ircevent,v0.0.0-20180816043103-14f3614f28c3,h1:389FrrKIAlxqQMTscCQ7VH3JAVuxb/pe53v2LBiA7z8=,32edd7a9e219bdff36d2aac0c6c5f3ac982c2daf4869e6e0718e917efb23b3de +github.com/tiancaiamao/appdash,v0.0.0-20181126055449-889f96f722a2,h1:mbAskLJ0oJfDRtkanvQPiooDH8HvJ2FBh+iKT/OmiQQ=,a9961e6079339aec983f97fdb39d5d7258bf8d2031da68482e58e17b27a93a78 +github.com/tidwall/gjson,v1.3.3,h1:wM/XREVc9c0LbRLcNMgVcGpI16r0pbbTJpltR4jJjh0=,17da724ffc86cfb3132bd9c7ac3eb860ca43a2748be519a59aa50b436c147bc6 +github.com/tidwall/match,v1.0.1,h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=,a1b9d52b9a4c7574f46068665279522f2084be26bac71594630786f6ee9a70f2 +github.com/tidwall/pretty,v1.0.0,h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=,3b25a1a0fe7688989326aaa1ca1c74c972b30152ef2a756fbf2d217a827fc07d +github.com/tidwall/sjson,v1.0.4,h1:UcdIRXff12Lpnu3OLtZvnc03g4vH2suXDXhBwBqmzYg=,cb47595016d45d72e6ee0f5585a86247aaeb93d9efa74e07676d32f60e8a7398 +github.com/tildeleb/cuckoo,v0.0.0-20190627040100-71059d5a2b62,h1:rXSNik45VDd1hfRLUAZwDLCY0FWvn2KlCeXjbd1yAI0=,f81f44544ec771ab630ddd5d65f4735ba2acc7619e41ccbc4bfad2473c21dc2f +github.com/timewasted/linode,v0.0.0-20160829202747-37e84520dcf7,h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8=,9a3190b3751964a3d47449265d48e2d3a76b23c66a7cb402cc9bdf3d732d82b4 +github.com/tinylib/msgp,v1.1.0,h1:9fQd+ICuRIu/ue4vxJZu6/LzxN0HwMds2nq/0cFvxHU=,61bd58489c555b30abffbe1175565b6f8460583349118e9ee12025fd17b67ea4 +github.com/tj/assert,v0.0.0-20171129193455-018094318fb0,h1:Rw8kxzWo1mr6FSaYXjQELRe88y2KdfynXdnK72rdjtA=,59a81d1883aac9635ac15d8a6a6e0630cf0a4122328116f921289dab840374b7 +github.com/tj/cobra,v0.0.0-20160702192511-5e2db986a612,h1:eiUtRvCN5HSnOg9AyX5z5od5VWy/ukyJ2oTboInm9MM=,493ac2ac61730652fcdd0b9b4c1e0c63855666df7fcaa02821b63982a5a7ccdf +github.com/tj/go-elastic,v0.0.0-20171221160941-36157cbbebc2,h1:eGaGNxrtoZf/mBURsnNQKDR7u50Klgcf2eFDQEnc8Bc=,a0df933432e9c7ec276cbc0edbb941375726cf5a39c663aafe0e945f9ba3079f +github.com/tj/go-kinesis,v0.0.0-20171128231115-08b17f58cb1b,h1:m74UWYy+HBs+jMFR9mdZU6shPewugMyH5+GV6LNgW8w=,0885f4631d33a20b5447ebbe12a0d23eb5ea3394de4bbc849cfe54ad19cadb2a +github.com/tj/go-spin,v1.1.0,h1:lhdWZsvImxvZ3q1C5OIB7d72DuOwP4O2NdBg9PyzNds=,060d09c35b1db5992747cde71ccbdaefe596ada06a6fe146e0ef10dc67d817dd +github.com/tj/pflag,v0.0.0-20160702191705-e367e44eec04,h1:RAPJe7XUQhTjVUKvYegzhXnWkJd/1daXdoiXjvkSURU=,2156357bb17b30ccb893b8f7013168c85c1eb265b7156aca845d06fb35805257 +github.com/tjfoc/gmsm,v1.0.1,h1:R11HlqhXkDospckjZEihx9SW/2VW0RgdwrykyWMFOQU=,f8fe3c4d02f0dc90fd873278957d57c4c45f1c53b1fee3969216b67844efabb1 +github.com/tmc/grpc-websocket-proxy,v0.0.0-20190109142713-0ad062ec5ee5,h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=,dadf62266d259ffb6aa1d707892b97fa36c3f39df5cae99f54d3ef7682995376 +github.com/tomnomnom/linkheader,v0.0.0-20180905144013-02ca5825eb80,h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y=,558504ea96d4312be0fe5faa6de13fb6abd8f1b2ac154123c67b623a5f219cdb +github.com/toqueteos/webbrowser,v1.2.0,h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=,1227d3ebeab16d8232a304a10b087984a96ad30f7439b6687bab2f5747d308cf +github.com/transip/gotransip,v0.0.0-20190812104329-6d8d9179b66f,h1:clyOmELPZd2LuFEyuo1mP6RXpbAW75PwD+RfDj4kBm0=,38b593cbdeb59e64d042533c1ce6196d89662de3282373de0d3c0749fe4c4856 +github.com/trivago/tgo,v1.0.5,h1:ihzy8zFF/LPsd8oxsjYOE8CmyOTNViyFCy0EaFreUIk=,06dc60662735374365cd525e2f4f4d1580f348125546e1f3e0d92d2deca4fa9a +github.com/tstranex/u2f,v1.0.0,h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=,325e3db32035ce38a5981bfaa35fb6d9b5cb4b960cfa0285b92448d21d29f379 +github.com/tsuru/config,v0.0.0-20180418191556-87403ee7da02,h1:mHuZ6JOixltE9fJmS+W1xLi4t/uDuR6Nl7w/e4uj0+I=,0255268934770d67b9d101a030ed7ed578938e346a279a273ab3983b0eee53fb +github.com/ttacon/chalk,v0.0.0-20160626202418-22c06c80ed31,h1:OXcKh35JaYsGMRzpvFkLv/MEyPuL49CThT1pZ8aSml4=,325521131515e4840e0083bc62cd9553da0b8d2480820f7e92ca89ae324f4c23 +github.com/tus/tusd,v1.0.1,h1:jb0SDf8zCUvlWv5SuHalOuRn684aW6WIvhfWRHC/XB8=,9a91d59123262b9bb1c43d39588a26d7560513b9e3c18254cd321890e8975083 +github.com/tv42/httpunix,v0.0.0-20150427012821-b75d8614f926,h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=,8246ebc82e0d9d3142f5aeb50d4fcd67f3f435fb5464120c356a4e5d57ef4aa0 +github.com/twinj/uuid,v1.0.0,h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk=,842c314d6d2ef9cb95b0f3f1b4cf998715680e836cfab8c2a7f75e351765a345 +github.com/twitchtv/twirp,v5.8.0+incompatible,h1:DTfGS9u/jHbo34cBB+qhzVHRaAq+tRois71j8pvjQ5M=,a4137792083eedd9ac04e88918d8952a841120b11e71161d2d444065b8e65d79 +github.com/tyler-smith/go-bip39,v1.0.2,h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=,6173ded455fa17cddd889bf3bc123be2343a09aeb60f83e2b63823dd9ce94e09 +github.com/tylerb/graceful,v1.2.15,h1:B0x01Y8fsJpogzZTkDg6BDi6eMf03s01lEKGdrv83oA=,770bd36defb9463ebe8b190f508e47c37bbb6bedf23a32c675066f8edbd7aa8d +github.com/u-root/dhcp4,v0.0.0-20190206235119-03363dc71ec8,h1:F9cRXeXZ95CzG7352mm+yfgloHFrjpr1L+CQFiCH/iU=,1db09816d65071cfc5dbf25d5dbf11b2b48c3442495d30777cc0714bb4cf4163 +github.com/u-root/u-root,v6.0.0+incompatible,h1:YqPGmRoRyYmeg17KIWFRSyVq6LX5T6GSzawyA6wG6EE=,f3ec29d4b285e50d7b3116e121caca0d722535346a0ddf189d4c7d8e7e0a07d3 +github.com/uber-go/atomic,v1.4.0,h1:yOuPqEq4ovnhEjpHmfFwsqBXDYbQeT6Nb0bwD6XnD5o=,f380292d46ebec89bf53939e4d7d19d617327cbcdf2978e30e6c39bc77df5e73 +github.com/uber/jaeger-client-go,v2.19.0+incompatible,h1:pbwbYfHUoaase0oPQOdZ1GcaUjImYGimUXSQ/+8+Z8Q=,d4928d51ce4440c825df67b4a54f851ead075701e67ece4b07fbc5c5857c091c +github.com/uber/jaeger-lib,v2.2.0+incompatible,h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=,496f63f6df32c28ceb6574959c70969da2b609abc8f9f3b3a709466f862054bf +github.com/uber/tchannel-go,v1.16.0,h1:B7dirDs15/vJJYDeoHpv3xaEUjuRZ38Rvt1qq9g7pSo=,64a37a5e89dd111ab943d94a1670f9addc0d2d41d34d630c95b0a756df916e01 +github.com/ucloud/ucloud-sdk-go,v0.8.7,h1:BmXOb5RivI0Uu4oZRpjI6SQ9/y7n/H9wxTGR1txIE8o=,d94766624c6f676880de354d4ed5c62c9ee7755c3d59cdf106ac0f5a070c0ece +github.com/ugorji/go,v1.1.7,h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=,d02959e71c59b273d5b099697c058426941a862feef66c191c63e2934db7a2ff +github.com/ugorji/go/codec,v1.1.7,h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=,8d482061c55b4c4fbf78de9fbf98a8d1b295f5904769679c73a2dc0b06a1a102 +github.com/ulikunitz/xz,v0.5.6,h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=,19ebb331e7ae7a542ed58597d13ab703fc423acf93a1e3c4db86476b0322049a +github.com/unixpickle/anyvec,v0.0.0-20170908190750-59aa66ba0472,h1:eVBSKiY98Zth6cEYVzeu0CYagakYqbSWgpWqjZFiUvI=,4159f95762f7a99ee540397e78c7a60da788e6775ad9eca7fc1bd07d332a88f1 +github.com/unixpickle/autofunc,v0.0.0-20170112172612-f27a3f82164a,h1:ZUrHljv3rPkFyTYzUmBH8gBFjDwCIHc4a2DdPCWRjl0=,b39c092ab522c2ca3e8889dfbff281223628c08590b361242e72cc29015da9df +github.com/unixpickle/essentials,v0.0.0-20180916162721-ae02bc395f1d,h1:mRwAxGRBEFcoKSWDoX5CROMJo6xmXBh4rNqOmyhpRi0=,7aa26b2cbcbac91669e88903f1e05b7696b32a6d8194d66c0fe7d93c613c2f5f +github.com/unixpickle/num-analysis,v0.0.0-20161229165253-c45203c63047,h1:gipJz9DZGU3fgBjoaiNg+5CG9UdE7MmlBvSwNp1ulnY=,c1dac9bfeb72d39bb0b445f0f0b2af61753e5b11ff66e69bc196886189b7d50a +github.com/unixpickle/serializer,v0.0.0-20170723202158-c6c092dc55bb,h1:kdurEYFZ2P58xnfWtmxKWkVtFPyK80BMIaJ2zW5uskY=,2cbf6cce1b2a57307c2c675a283ce9b46adcb9d18c3a9317d3ee20772175ae40 +github.com/unknwon/com,v1.0.1,h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=,f6264780f210f130a0edeafe4ffb0753c64b5168771f2d6cd1613999a7b79cd1 +github.com/unrolled/render,v1.0.1,h1:VDDnQQVfBMsOsp3VaCJszSO0nkBIVEYoPWeRThk9spY=,5b0ace5c3798f8989322a32b75c3eeabce7f6568533f808065cacf92425dd867 +github.com/unrolled/secure,v0.0.0-20190103195806-76e6d4e9b90c,h1:ZY4dowVsuIAQtXXwKJ9ezfonDQ2YT7pcXRpPF2iAy3Y=,1aba4f13fe4199198f9b59bbfd337773d049bad06f68360483a5f4c5431bdce4 +github.com/urfave/cli,v1.22.1,h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=,116fc1fba7db091617cd47c2b83c78d22489deeaf8390a6d3509da7fc9217d57 +github.com/urfave/cli/v2,v2.0.0-alpha.2,h1:2OVOKijPPhkA1cJA5SABACE8TT3Cwx9T0N6VtI8LJSI=,57250f97530fcb6fef7abc87cde3fbaf11ea45830adf98e3f1c986e2674e3b5f +github.com/urfave/negroni,v1.0.0,h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=,7b50615961d34d748866565b8885edd7013e33812acdbaed47502d7cc73a4bbd +github.com/valyala/bytebufferpool,v1.0.0,h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=,7f59f32c568539afee9a21a665a4156962b019beaac8404e26ba37af056b4f1e +github.com/valyala/fasthttp,v1.6.0,h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY=,b15a953ed5395599871097c94977d21c026205e6ca7ad6e340cd595096d5840e +github.com/valyala/fastrand,v1.0.0,h1:LUKT9aKer2dVQNUi3waewTbKV+7H17kvWFNKs2ObdkI=,ed2166483141b4f3d59ee07975a5d91990e4c17f36c919565b8063c0cb02f7ed +github.com/valyala/fasttemplate,v1.0.1,h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8=,b4d9f77c6c15a0404952925ad59b759102c0ff48426b6fc88d6bfd347fe243b8 +github.com/valyala/tcplisten,v0.0.0-20161114210144-ceec8f93295a,h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=,07066d5b879a94d6bc1feed20ad4003c62865975dd1f4c062673178be406206a +github.com/vbatts/tar-split,v0.11.1,h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=,73136db95ff35c2547c49be43727aa3f67da2d8837e1475954db910b41b1fa18 +github.com/veandco/go-sdl2,v0.3.3,h1:4/TirgB2MQ7oww3pM3Yfgf1YbChMlAQAmiCPe5koK0I=,d19e162daa2a6cc72569eb052adfd3d757fd069ee461a64803e9e8f2e9bb87a7 +github.com/vektah/dataloaden,v0.2.1-0.20190515034641-a19b9a6e7c9e,h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg=,92fe72fa4962bb2f375fae83f7a44a804e398ec08818f7d018724e0a23394ae3 +github.com/vektah/gqlparser,v1.1.2,h1:ZsyLGn7/7jDNI+y4SEhI4yAxRChlv15pUHMjijT+e68=,cdd0119855b98641e7af60dce5b2848b31f8ef03dfcf097c06912309b86fc97c +github.com/viant/assertly,v0.4.8,h1:5x1GzBaRteIwTr5RAGFVG14uNeRFxVNbXPWrK2qAgpc=,253a5e53bb09bf94be7131d5034a6ba19c6eb1f9b8c7fa66182d577bd7b2d6cd +github.com/viant/toolbox,v0.24.0,h1:6TteTDQ68CjgcCe8wH3D3ZhUQQOJXMTbj/D9rkk2a1k=,d6773a06b59de043eff2003bb97567056a1910eb0fd514f5503873b8f23309f4 +github.com/vimeo/go-util,v1.2.0,h1:YHzwOnM+V2tc6r67K9fXpYqUiRwXp0TgFKuyj+A5bsg=,85e52371bcf8299d47d8242546bc06e9e0c9c555b719008096889cd081a69173 +github.com/vincent-petithory/dataurl,v0.0.0-20160330182126-9a301d65acbb,h1:lyL3z7vYwTWXf4/bI+A01+cCSnfhKIBhy+SQ46Z/ml8=,5d5fa46ce0f88ba0734f52d0b0bcaa8a427770ef13cd1bfd7995e4d2a8439abb +github.com/vishvananda/netlink,v1.0.0,h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM=,6fb7184280eb1321e1857171862bdb624eae29876496f1cb56932fbc0064020f +github.com/vishvananda/netns,v0.0.0-20190625233234-7109fa855b0f,h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I=,a99a67e03a35e1d02d1a17900185a1c38c513a79b2b325ad826553dc078a90de +github.com/vivint/infectious,v0.0.0-20190108171102-2455b059135b,h1:dLkqBELopfQNhe8S9ucnSf+HhiUCgK/hPIjVG0f9GlY=,f5d948bf34ac58786ad20df4fd6e99f990f72458dd2825558bf2e3c871f3f37a +github.com/vmihailenco/msgpack,v4.0.4+incompatible,h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=,918f7dd7883105b9c55728c704a3bc54c80568b2b09583890b51508c03391356 +github.com/vmware/govmomi,v0.21.0,h1:jc8uMuxpcV2xMAA/cnEDlnsIjvqcMra5Y8onh/U3VuY=,75ca40f34da851e95d7e63685adbaf1ec5c7f659fb0b47096c85da44f098c4a3 +github.com/vmware/vic,v1.5.4,h1:y546pkye0aes2j2h2n6fWz++v8WxMZTLFl1mLOMzqYQ=,2a6f0c20be8acb3b467c78d3de18009ccd0ab2429a997266089d14341e43115c +github.com/vmware/vmw-guestinfo,v0.0.0-20170707015358-25eff159a728,h1:sH9mEk+flyDxiUa5BuPiuhDETMbzrt9A20I2wktMvRQ=,29c73ba44ac315461640797d6ebfda2d906c28dbe21c20656c6e5fa1f515f220 +github.com/vulcand/oxy,v1.0.0,h1:7vL5/pjDFzHGbtBEhmlHITUi6KLH4xXTDF33/wrdRKw=,148843b55ed01813f8920aab70a799aa10cfdccc0bbd55e270cde78e1ad23b88 +github.com/vulcand/predicate,v1.1.0,h1:Gq/uWopa4rx/tnZu2opOSBqHK63Yqlou/SzrbwdJiNg=,3dd716f2436651429ce7f5fdd59fa1a9944ab4d57fdbae5fef00ef01baf7c4be +github.com/vultr/govultr,v0.1.4,h1:UnNMixYFVO0p80itc8PcweoVENyo1PasfvwKhoasR9U=,7281fa718c076b84610b155fb0dec34503ea1ae5f2930cc714ed7772e475bb08 +github.com/warpfork/go-wish,v0.0.0-20190328234359-8b3e70f8e830,h1:8kxMKmKzXXL4Ru1nyhvdms/JjWt+3YLpvRb/bAjO/y0=,77a9eefa3edf38cb90eba443f282bd73ffcb6f1b87aebe8f891d8c8b38124d95 +github.com/weaveworks/common,v0.0.0-20190917143411-a2b2a6303c33,h1:UAh7j96ZXQID3shhQsrtfJsrQ2uO3tyRxCuXvh+kipw=,e1ceacd5b24c6414ae664f4b09e295dc25e48d3a1dcd5100d8c98dd405a0d162 +github.com/weaveworks/mesh,v0.0.0-20191031093817-8e3db2fe8f47,h1:RUdrWPah1Xu+efIGqN0YGTv7gQeyR5qwBq9uL4HloKw=,05f5d769f7ff6af1c098f0e42983227d6a86f5d8d1f8453cb0566450cad49358 +github.com/wellington/go-libsass,v0.9.3-0.20181113175235-c63644206701,h1:9vG9vvVNVupO4Y7uwFkRgIMNe9rdaJMCINDe8vhAhLo=,2ae95ed360950fab28eff3bedf1c1a6f5f81b73078000d3a0bd67443d38df87f +github.com/wendal/errors,v0.0.0-20130201093226-f66c77a7882b,h1:0Ve0/CCjiAiyKddUMUn3RwIGlq2iTW4GuVzyoKBYO/8=,f7722558c5c450fa02e800ce7bf4d0bc1d2a0e1696d3fc50ff1489bcd02ff3b3 +github.com/weppos/publicsuffix-go,v0.5.0,h1:rutRtjBJViU/YjcI5d80t4JAVvDltS6bciJg2K1HrLU=,bd8365c8501b307a1fbd62501bc3332ff97721bef51921a99e67a3f8b96318fc +github.com/whyrusleeping/cbor-gen,v0.0.0-20190910031516-c1cbffdb01bb,h1:8yBVx6dgk1GfkiWOQ+RbeDDBLCOZxOtmZ949O2uj5H4=,9d5ab8362eaffa07bc2700d9a9e967c1ecf394e3233a6e7141efb48970bfd4e5 +github.com/whyrusleeping/chunker,v0.0.0-20181014151217-fe64bd25879f,h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=,b28fdb03b69be216c423967e9dee2481aa10c3e39c71d3bfc8911940dadb26a9 +github.com/whyrusleeping/go-keyspace,v0.0.0-20160322163242-5b898ac5add1,h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=,9416f8227e6c516294b9b938fcf2347bebe2cdab4377454150ba60dcd86c2990 +github.com/whyrusleeping/go-logging,v0.0.0-20170515211332-0457bb6b88fc,h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo=,125b1a836936436354791583be42ae19f7c04a636b5c0c96135645d52aaa72ea +github.com/whyrusleeping/go-notifier,v0.0.0-20170827234753-097c5d47330f,h1:M/lL30eFZTKnomXY6huvM6G0+gVquFNf6mxghaWlFUg=,08dddb594554c3b35791893207e66dd3c04e4da24d0e0df001bb185f97dec6cc +github.com/whyrusleeping/go-smux-multiplex,v3.0.16+incompatible,h1:iqksILj8STw03EJQe7Laj4ubnw+ojOyik18cd5vPL1o=,e16e3da58e283e71955b21725c384d180a2999bc2a50cb0490b5e2f7a74b5fc6 +github.com/whyrusleeping/go-smux-multistream,v2.0.2+incompatible,h1:BdYHctE9HJZLquG9tpTdwWcbG4FaX6tVKPGjCGgiVxo=,9a783c4a1b69f6002ac4e0af684f4d5c4d360b7107fbbdde48faf38f7e23e998 +github.com/whyrusleeping/go-smux-yamux,v2.0.9+incompatible,h1:nVkExQ7pYlN9e45LcqTCOiDD0904fjtm0flnHZGbXkw=,3f44f41fc7b133085bba08d52e7615e9a8eb92f55fde6a07d3cd7804117e9985 +github.com/whyrusleeping/mafmt,v1.2.8,h1:TCghSl5kkwEE0j+sU/gudyhVMRlpBin8fMBBHg59EbA=,e5d5783d2bc35f7c23f2034fd52c5750ad0590773115c10b4e15360575322c69 +github.com/whyrusleeping/mdns,v0.0.0-20180901202407-ef14215e6b30,h1:nMCC9Pwz1pxfC1Y6mYncdk+kq8d5aLx0Q+/gyZGE44M=,fc2e4d2365ba40d52d03126ea490e712762b4ad398c8d6adb2a1a08699a10eb1 +github.com/whyrusleeping/multiaddr-filter,v0.0.0-20160516205228-e903e4adabd7,h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds=,14e8963464dab0f6277f596985be5ea419bc3bae8bf4f4f139cce456e1815faf +github.com/whyrusleeping/timecache,v0.0.0-20160911033111-cfcb2f1abfee,h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow=,c33dfc5ac935582261bf5ddbab31bb07febc471a9c26eb3e1a895eddd574d3e8 +github.com/whyrusleeping/yamux,v1.1.5,h1:4CK3aUUJQu0qpKZv5gEWJjNOQtdbdDhVVS6PJ+HimdE=,658f9e704cbe1cac295ed34471bb096a4d2713f69ffbb8140fbf50b8ff6420e0 +github.com/willf/bitset,v1.1.9,h1:GBtFynGY9ZWZmEC9sWuu41/7VBXPFCOAbCbqTflOg9c=,ddd687772ccfd6774e55e7e9d9e71dab86d85a64b98ce1d864d9661f5b0767e4 +github.com/x-cray/logrus-prefixed-formatter,v0.5.2,h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=,00719eeb4f9eadb9431dd9f763fa4013dc52b37a8803a973c6d0c1ce8281e14b +github.com/xanzy/go-cloudstack,v0.0.0-20190526095453-42f262b63ed0,h1:NJrcIkdzq0C3I8ypAZwFE9RHtGbfp+mJvqIcoFATZuk=,34b46eae351e4916015ce2a43ed501403937e4079cf69dae98a9544bfeec8092 +github.com/xanzy/go-gitlab,v0.21.0,h1:Ru55sR4TBoDNsAKwCOpzeaGtbiWj7xTksVmzBJbLu6c=,12ae6fa35c19fffc31d1fa2891f386875caac8077d19f3f09f49b5e2e51b1755 +github.com/xanzy/ssh-agent,v0.2.1,h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=,7011c1771f8ad9b65795f8a85113e4518c9a2c7493029c4c988bc802b63d9e28 +github.com/xdg/scram,v0.0.0-20180814205039-7eeb5667e42c,h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=,33884d438b686676ceaa2a439634a108f7fe763ce974342d2aa811c22b34112c +github.com/xdg/stringprep,v1.0.0,h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=,2b262e4e8e9655100c98e2b7e75b517e3e83e2155818174c63ea09d3cce22721 +github.com/xeipuuv/gojsonpointer,v0.0.0-20180127040702-4e3ac2762d5f,h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=,5b1a4bcc8e003f214c92b3fa52959d9eb0e3af1c0c529efa55815db951146e48 +github.com/xeipuuv/gojsonreference,v0.0.0-20180127040603-bd5ef7bd5415,h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=,7ec98f4df894413f4dc58c8df330ca8b24ff425b05a8e1074c3028c99f7e45e7 +github.com/xeipuuv/gojsonschema,v1.2.0,h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=,55c8ce068257aa0d263aad7470113dafcd50f955ee754fc853c2fdcd31ad096f +github.com/xenolf/lego,v2.7.2+incompatible,h1:aGxxYqhnQLQ71HsvEAjJVw6ao14APwPpRk0mpFroPXk=,25c2495e4fc2f5fea8c70b442add86c049f2f8810235e1ee94f29d8e0267ad2c +github.com/xeonx/timeago,v1.0.0-rc4,h1:9rRzv48GlJC0vm+iBpLcWAr8YbETyN9Vij+7h2ammz4=,b06f4ede554b35387394827ca0350b628a72228a8002653817826991867e1fdd +github.com/xi2/xz,v0.0.0-20171230120015-48954b6210f8,h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=,1ffe8f24af5118966084d41eca2c9bee7a831a07deb4356e4d707d208da22e8e +github.com/xiang90/probing,v0.0.0-20190116061207-43a291ad63a2,h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=,437bdc666239fda4581b592b068001f08269c68c70699a721bff9334412d4181 +github.com/xlab/treeprint,v0.0.0-20181112141820-a009c3971eca,h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=,d14ebea967caa835f25e4c3980c60719e07f0e36375b74dc48928613fca5b2ff +github.com/xo/dburl,v0.0.0-20191005012637-293c3298d6c0,h1:6DtWz8hNS4qbq0OCRPhdBMG9E2qKTSDKlwnP3dmZvuA=,1fb150cf2144a4b7a571360af52d9b22dfe53e2ba9ab3e56584fdb0eb282d315 +github.com/xordataexchange/crypt,v0.0.3-0.20170626215501-b2862e3d0a77,h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=,46dc29ef77d77a2bc3e7bd70c94dbaeec0062dd3bd6fcacbaab785c15dcd625b +github.com/xtaci/kcp-go,v5.4.5+incompatible,h1:CdPonwNu3RKu7HcXSno5r0GXfTViDY2iFV2RDOao/4U=,98e77493d94b33bfec990bd5791d15a09add1a0ba2f3281f26bdc98c1815d9a7 +github.com/xtaci/lossyconn,v0.0.0-20190602105132-8df528c0c9ae,h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=,75cc8c3e14cf812dcc56a1e8cecafd8affd9b2843d39540ab67929f7ce3d1abc +github.com/xtgo/set,v1.0.0,h1:6BCNBRv3ORNDQ7fyoJXRv+tstJz3m1JVFQErfeZz2pY=,6b70026a5ea66bc0be7efb2247afa53ae970b9535c7a8541795750ef9b640217 +github.com/yalp/jsonpath,v0.0.0-20150812003900-31a79c7593bb,h1:06WAhQa+mYv7BiOk13B/ywyTlkoE/S7uu6TBKU6FHnE=,d2041be5f19a3dbcd4b384dbbf5782cdb96d80ad9c60c8c9b887f2c5170cb25f +github.com/yandex-cloud/go-genproto,v0.0.0-20190928220815-a36c849d0fc1,h1:GDyRNvsi/tOZj1ssPkk+kocO1djpbmLSpDKg4XeRPy4=,5502c680146902518514935af5ab5b554a80f5ebe2e79d491db3120911f5498d +github.com/yandex-cloud/go-sdk,v0.0.0-20190916101744-c781afa45829,h1:2FGwbx03GpP1Ulzg/L46tSoKh9t4yg8BhMKQl/Ff1x8=,4b375b871ce7501943a26ba02c348ad4fdf2cb112520513628566a15a98a4796 +github.com/yohcop/openid-go,v0.0.0-20160914080427-2c050d2dae53,h1:HsIQ6yAjfjQ3IxPGrTusxp6Qxn92gNVq2x5CbvQvx3w=,8c4f676193e3aa5ec012e0661d0e552a3e5d5d96086a73901dcfbf0bd4a6d2e9 +github.com/yookoala/realpath,v1.0.0,h1:7OA9pj4FZd+oZDsyvXWQvjn5oBdcHRTV44PpdMSuImQ=,9fe8b06f8efabb7df08608f18edc77d284e04ad06d490af9f55196e4184c339f +github.com/yosssi/ace,v0.0.5,h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA=,96157dbef72f2f69a900e09b3e58093ee24f7df341ac287bddfb15f8c3f530db +github.com/yosssi/gmq,v0.0.1,h1:GhlDVaAQoi3Mvjul/qJXXGfL4JBeE0GQwbWp3eIsja8=,d06bbe96ba0e8c3c79bfb0b9191a02a19d8d3d3c181eba62df6d94c0602c784e +github.com/youtube/vitess,v2.1.1+incompatible,h1:SE+P7DNX/jw5RHFs5CHRhZQjq402EJFCD33JhzQMdDw=,2eb3c516c8b24a72b8cb14f76f39562638acf0cd7fc3858002163d28047607f2 +github.com/yudai/gojsondiff,v0.0.0-20170107030110-7b1b7adf999d,h1:yJIizrfO599ot2kQ6Af1enICnwBD3XoxgX3MrMwot2M=,3f61230fe62a6fe2e93a75264d176bda3f62323063c1e9bfb87c0be31ac5d269 +github.com/yudai/golcs,v0.0.0-20150405163532-d1c525dea8ce,h1:888GrqRxabUce7lj4OaoShPxodm3kXOMpSa85wdYzfY=,ff1f3899e710574a08aaa51051a36c523ecf850180ad0564d55eec611c3cff72 +github.com/yudai/pp,v2.0.1+incompatible,h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=,ecfda4152182e295f2b21a7b2726e2865a9415fc135a955ce42e039db29e7a20 +github.com/yuin/gopher-lua,v0.0.0-20190514113301-1cd887cd7036,h1:1b6PAtenNyhsmo/NKXVe34h7JEZKva1YB/ne7K7mqKM=,fd157d5d26c336c44837eceef5c6fc4b442a56b25931d4afae3c4080932a7aa7 +github.com/zach-klippenstein/goregen,v0.0.0-20160303162051-795b5e3961ea,h1:CyhwejzVGvZ3Q2PSbQ4NRRYn+ZWv5eS1vlaEusT+bAI=,6f523a11fcb80dca31c3bae99c8c4a59b7e5a4176e36cad0e3f1e64e1b9a7b11 +github.com/zclconf/go-cty,v1.1.0,h1:uJwc9HiBOCpoKIObTQaLR+tsEXx1HBHnOsOOpcdhZgw=,024660decfe11e74a9fab80f1447b79c61e328baf6418629a15c74e183b95e95 +github.com/zclconf/go-cty-yaml,v1.0.1,h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8=,2502da37ac6d9105b07748c4252f970aa6a7ffc8929b92a0b85abb81b804e9b7 +github.com/zeebo/admission,v0.0.0-20180821192747-f24f2a94a40c,h1:WoYvMZp+keiJz+ZogLAhwsUZvWe81W+mCnpfdgEUOl4=,b62a80509cfa84e697b23dd6b1b314a264e6f68586661ecd84026625f7753cb1 +github.com/zeebo/assert,v1.0.0,h1:qw3LXzO7lbptWIQ6DsemJIUOoaqyKbgY3M8b8yvlaaY=,bb31d428cc59a322975ab6b5757832e62507655f3e2c467a88345b21d7431d98 +github.com/zeebo/errs,v1.2.2,h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g=,d2fa293e275c21bfb413e2968d79036931a55f503d8b62381563ed189b523cd2 +github.com/zeebo/float16,v0.1.0,h1:kRqxv5og6z1emEyz5FpW0/BVHe5VfxEAw6b1ljCZlUc=,ffc6b2a7bce5e37798bc3ac53448b6190039a77f2e7d589779680fbd3cb53a48 +github.com/zeebo/incenc,v0.0.0-20180505221441-0d92902eec54,h1:+cwNE5KJ3pika4HuzmDHkDlK5myo0G9Sv+eO7WWxnUQ=,141b997c5ece8f136f43644f5a2526305563128c4ecce280d9a54ce1ae506ba2 +github.com/zeebo/structs,v1.0.2,h1:kvcd7s2LqXuO9cdV5LqrGHCOAfCBXaZpKCA3jD9SJIc=,0495c69abfeb2ffa0911f4c44ba145d81b04ec76d2311e2eedfc2b3e2efd66c9 +github.com/zenazn/goji,v0.9.0,h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ=,0807a255d9d715d18427a6eedd8e4f5a22670b09e5f45fddd229c1ae38da25a9 +github.com/ziutek/mymysql,v1.5.4,h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=,1ea104186e0990a3d97a1e67fcd31177849c975de4abd9399270ab0a04c025de +github.com/zkfy/cron,v0.0.0-20170309132418-df38d32658d8,h1:jxPemXnLeekMXItoaw4jZtDfe8HmvFmviUm2L5tEBhE=,81a903448f6bc140e07bc4ff70762f0a46e750388f4b92f700d358331b1ca8d5 +github.com/zkfy/go-metrics,v0.0.0-20161128210544-1f30fe9094a5,h1:Rb2qQMbEon+BI3IXGh4eW3u/iTLPA3+Y6kNK+gHO32w=,07f9078cbc233559128dc4ae80d69505dd1a07d47d33135fc8f4969829fd6ee8 +github.com/zkfy/jwt-go,v3.0.0+incompatible,h1:5hZNIkrRRa0mrkRiXoPFdLJWpMDByIZ6VIbX9aWhwmk=,8306a4a65059e17be035dd47f45d83aac503c50c954716c83e481d0b6530aed6 +github.com/zkfy/log,v0.0.0-20180312054228-b2704c3ef896,h1:nktyhX5ycnu+WA489Ei7SUi00bF+LW8TF2N7se5gQ/o=,dd0acb5ccceb2225c89f0f50dc8eea9f1cae0971b731750ea7a1b186c194d9bc +github.com/zkfy/stompngo,v0.0.0-20170803022748-9378e70ca481,h1:dqbWcJVZJv06ZR7zK8yN9w8oNOHL23eylL4o9Xj9Zn0=,9e643fbfd166421cb186275742bafc663fc350da83e59e9d88c06feb12ec4462 +github.com/zmap/rc2,v0.0.0-20131011165748-24b9757f5521,h1:kKCF7VX/wTmdg2ZjEaqlq99Bjsoiz7vH6sFniF/vI4M=,fd70713ed40c95220e95c7c47f7e15051e8dc909d39253f403bb694f45fbe789 +github.com/zmap/zcertificate,v0.0.0-20180516150559-0e3d58b1bac4,h1:17HHAgFKlLcZsDOjBOUrd5hDihb1ggf+1a5dTbkgkIY=,7dc2c0bedccfdeb9c42ef41ef502f404befa9ef073c35db3b15c99cae6697b41 +github.com/zmap/zcrypto,v0.0.0-20190729165852-9051775e6a2e,h1:mvOa4+/DXStR4ZXOks/UsjeFdn5O5JpLUtzqk9U8xXw=,871979cf16453ddb4db7f153f449af4e346f68b51355c74b5eee832225618ff0 +github.com/zmap/zlint,v0.0.0-20190806154020-fd021b4cfbeb,h1:vxqkjztXSaPVDc8FQCdHTaejm2x747f6yPbnu1h2xkg=,e62f5cd5f434d84f53d336261e3a6e50c8902152ce8f2f5ce918270d6d201cab +github.com/zondax/hid,v0.9.0,h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=,9c72a6bdbf03d9465dfdf1ba876eabf5fa923d5bb9e726c9e4a994098dc9bd79 +github.com/zondax/ledger-go,v0.9.0,h1:oTrtFqPFA4VdCPRvqMaN45mQnJxkPc0JxoVZfCoUpjI=,6c6a7e036f9a621ce951939d7d13ae1f0c098f58829307c78f9312e02e78e438 +github.com/zquestz/grab,v0.0.0-20190224022517-abcee96e61b1,h1:1qKTeMTSIEvRIjvVYzgcRp0xVp0eoiRTTiHSncb5gD8=,4decd67f1252df4ee34968cb0cb4e7dc6010302b24ce8edd418f1c2520f1c351 +gitlab.com/NebulousLabs/errors,v0.0.0-20171229012116-7ead97ef90b8,h1:gZfMjx7Jr6N8b7iJO4eUjDsn6xJqoyXg8D+ogdoAfKY=,b355474f1a2ef2722ae450ef6df7209d223188ae413706be122b472fcc053c48 +gitlab.com/NebulousLabs/fastrand,v0.0.0-20181126182046-603482d69e40,h1:dizWJqTWjwyD8KGcMOwgrkqu1JIkofYgKkmDeNE7oAs=,a56acdda993c7a4795028fe38844d54de9b1877d22e8ae09f205e488ce2284bc +gitlab.com/yumeko/MumbleEmu,v0.0.0-20170923112213-54c9892f02e9,h1:QSaGLacCEAlWXhL/xGZyS3+2aDVvBZe5jcmrDWwXhqs=,51cc295a04dc3b9c39b341f21b95fc42765e3bb61fe30ec2a59fe867c1b5e5ed +go.bug.st/serial.v1,v0.0.0-20180827123349-5f7892a7bb45,h1:mACY1anK6HNCZtm/DK2Rf2ZPHggVqeB0+7rY9Gl6wyI=,f0ea4cd4c51228f1a3cf14c6b92888169944f267e1ee778909512a4c8ac4762f +go.cryptoscope.co/luigi,v0.3.4,h1:eDrtCoUL5Vl2Atr5ty2dq0uFbzFCc6Pz1HEqU1e7I1I=,949612e92dcb2fc919e506740f36d0cfe0797c1f85579a98763aad0135a4580a +go.dedis.ch/fixbuf,v1.0.3,h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=,dfa737543a5873b14cdfd0eec675c63044b16d3dbe481b2289c758ae4186ae95 +go.dedis.ch/kyber/v3,v3.0.8,h1:qnHzOBaxEO3+ZYuZAfwPTOPzX+F6QMmWGo8YJvENh68=,d69db17bd37bf14c4e508eb84974c3df9a82b8cb30b55ddc3ac0ee2784abcbac +go.dedis.ch/kyber/v4,v4.0.0-pre1,h1:1f5OPESkyxK6kPaCSV3J9BlpnoysIpbGLNujX9Ov8m4=,d082a41e2178f7e18c088e414e020928794245a9dae41d07da842ebb667a337e +go.dedis.ch/onet/v3,v3.0.26,h1:wQhVGB+SCdG7B0tbo6ZeZINQKWkU4u9TNMkGBH16EEM=,a41978897a3371f2eaaab5c84c354c95b4fdbd7b8207afa7c79f32b85f857d5d +go.elastic.co/apm,v1.5.0,h1:arba7i+CVc36Jptww3R1ttW+O10ydvnBtidyd85DLpg=,447a5954db3f7fc61575c83782be0b6d69e453f1e667b0534d3bf5336039238a +go.elastic.co/apm/module/apmhttp,v1.5.0,h1:sxntP97oENyWWi+6GAwXUo05oEpkwbiarZLqrzLRA4o=,1e6bc42b2e3ab10165036afd95a8a4d910acadce451c0b4e7c998cbb5c06da73 +go.elastic.co/apm/module/apmot,v1.5.0,h1:rPyHRI6Ooqjwny67au6e2eIxLZshqd7bJfAUpdgOw/4=,235fb0c1d0e107ffb7c5056e49226152063ac87ebc657428ea410d5170804d2e +go.elastic.co/fastjson,v1.0.0,h1:ooXV/ABvf+tBul26jcVViPT3sBir0PvXgibYB1IQQzg=,451e29b2854f9e09c58e3fe4c1b3a72d9b2ee293628ab4c4323e8192af015c6c +go.etcd.io/bbolt,v1.3.3,h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=,1ea076dbe18dabe78909e1fb7ec2954fc2d58cd72e7730ad69b35248a30049fd +go.etcd.io/etcd,v3.3.17+incompatible,h1:g8iRku1SID8QAW8cDlV0L/PkZlw63LSiYEHYHoE6j/s=,7bd292878f70e154a061ed6b85fc70502aa270fcf0072340cbde1a0cb35b0d2d +go.mongodb.org/mongo-driver,v1.1.2,h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=,6b3141ced32d7a41ebd0539df957b76331fc3efdca22eae68da54d41aad23fed +go.opencensus.io,v0.22.1,h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50=,b8d9a5fca5e714c4bf66f6497dd905992113cfd6aae948bb7fad5ce987a520ed +go.starlark.net,v0.0.0-20191021185836-28350e608555,h1:FhmD1D59MmncMfRVTRa889iERZG3jdaKj/1FtOQB1G0=,add124cd355e714f076a385eb3f2ddcfb8ce0c7c8e6611e2e03acc427a4c32bf +go.uber.org/atomic,v1.5.0,h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=,7e32f8f75b2029aa53399c2cd6e581398ac4e971c17a763980377279ede95c77 +go.uber.org/automaxprocs,v1.2.0,h1:+RUihKM+nmYUoB9w0D0Ov5TJ2PpFO2FgenTxMJiZBZA=,4c7bf41eab5dd7781c69130aa37011427531dee231ffbdc3c9ed4267c06aa93c +go.uber.org/multierr,v1.3.0,h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=,29b25df332dea2dbfaaa308013fc6d3673ecd3d9ee09c666c69df504533d0714 +go.uber.org/ratelimit,v0.1.0,h1:U2AruXqeTb4Eh9sYQSTrMhH8Cb7M0Ian2ibBOnBcnAw=,78f82854809625c784088b9dec5dfb4810fbbd09c24891b8aaf2c2679212dfd8 +go.uber.org/thriftrw,v1.20.2,h1:0JlCE7dOyWHEQdfDm0MWIbgTn6vXkiMA6LNIe8FQXjw=,148b93f97a6ab865e2dbe0eb09b9f9504248808efc437e20efc1bf9b7896de9a +go.uber.org/tools,v0.0.0-20190618225709-2cfd321de3ee,h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=,988dba9c5074080240d33d98e8ce511532f728698db7a9a4ac316c02c94030d6 +go.uber.org/zap,v1.12.0,h1:dySoUQPFBGj6xwjmBzageVL8jGi8uxc6bEmJQjA06bw=,d4b304046a3f9443e4abe217889b5b2a4ecef35d52f175bcacf2baff18646595 +go4.org,v0.0.0-20191010144846-132d2879e1e9,h1:zHLoVtbywceo2hE4Wqv8CmIufe7jDERQ2KJHZoSDfCU=,21811f50d48c55047df1d6bf68db778087afe9116f1f32faf79f8ca459d29d89 +gobot.io/x/gobot,v1.14.0,h1:IJv4A9f5/lUz4JQaS37UW8bRVl3lG+jCGUcNmJ2F0vE=,95ad64d1bf33ee46816b2c87edb10d7b3bfe118b6f7026bf4b5f762867d1e776 +gocloud.dev,v0.17.0,h1:UuDiCphYsiNhRNLtgHVL/eZheQeCt00hL3XjDfbt820=,0df8e26a2356735d596e8a3917ec4b69f61fb5e9f6f291b51f6145a51b646a9b +gocv.io/x/gocv,v0.21.0,h1:dVjagrupZrfCRY0qPEaYWgoNMRpBel6GYDH4mvQOK8Y=,9e1a70258d72b873d9605a2939b38f9e560650472d70b97f5dd0fc2657eaf35f +golang.org/x/arch,v0.0.0-20191101135251-a0d8588395bd,h1:e1iK2rWppIPlzzqtjXT/p6WR/+ritGZ8xkfL8uDZb0g=,daba41c9150ebf192ce54952d69ef12fe47c5c6250a33c01f0624befea35354e +golang.org/x/build,v0.0.0-20191031202223-0706ea4fce0c,h1:jjNoDZTS0vmbqBhqD5MPXauZW+kcGyflfDDFBNCPSVI=,a675f674bcee677f1dc9a15ca4d84bb2e842c29d745b165ba3e5423c09367d29 +golang.org/x/crypto,v0.0.0-20191029031824-8986dd9e96cf,h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss=,0a303100f9afba8628988bef45404b23c2e0c6aa73b5ad4ac9259af14a0e53ae +golang.org/x/exp,v0.0.0-20191030013958-a1ab85dbe136,h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw=,18ff05b39d29a3fd4c7f9071e7013264994ac18f7faa72f66b2f514fcdd141b0 +golang.org/x/image,v0.0.0-20191009234506-e7c1f5e7dbb8,h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=,aebca4c096dac7c20d9024b73bd0b4a87a85f4c6b50aae7615dec504c5f478c8 +golang.org/x/lint,v0.0.0-20190930215403-16217165b5de,h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=,91323fe1a77f13de722a0ce8efc5c5f2da4f26216d858acec64cb23c956fa163 +golang.org/x/mobile,v0.0.0-20191031020345-0945064e013a,h1:CrJ8+QyIm2tcw/zt9Rp/vGFsey+jndL1y5EnFwzgGOg=,5ee0c7eed83b64cc851d6ddb76346413d7c43213ea1241385b588c66e2169854 +golang.org/x/mod,v0.1.0,h1:sfUMP1Gu8qASkorDVjnMuvgJzwFbTZSeXFiGBYAVdl4=,e0d9b32f6f66103f777e8357b5b60f94a486330d46c6c8ea87789dab1a14cefa +golang.org/x/net,v0.0.0-20191101175033-0deb6923b6d9,h1:DPz9iiH3YoKiKhX/ijjoZvT0VFwK2c6CWYWQ7Zyr8TU=,b07094a5589a436fd98c6700cd5898f2094d9c02f8385f9331a7ace46305c7ae +golang.org/x/oauth2,v0.0.0-20190604053449-0f29369cfe45,h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=,f72b6c3c2b734ad053fadf5fa2adb2ad23024cfeacd567fec31a751526d1dfe0 +golang.org/x/perf,v0.0.0-20180704124530-6e6d33e29852,h1:xYq6+9AtI+xP3M4r0N1hCkHrInHDBohhquRgx9Kk6gI=,a2c7d02cc94c4ba767b6322f70ddcba4941cb5f60fed1bada3aa7a4d3a8128f1 +golang.org/x/sync,v0.0.0-20190911185100-cd5d95a43a6e,h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=,9c63fe51b0c533b258d3acc30d9319fe78679ce1a051109c9dea3105b93e2eef +golang.org/x/sys,v0.0.0-20191029155521-f43be2a4598c,h1:S/FtSvpNLtFBgjTqcKsRpsa6aVsI6iztaz1bQd9BJwE=,c5a8efb84e706e4ec1e1fa5cda44d1d571e8b3f46afe165d5e93b90e777a15fc +golang.org/x/text,v0.3.2,h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=,f755c0e7f4693f170e2f03c161f500b33f82accb8184a38dcfda63fed883f13c +golang.org/x/time,v0.0.0-20191024005414-555d28b269f0,h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=,e0ca5eceb4840bcc264237408ff8942044e19b503d6e8e5546ed9f7e1f4bf82e +golang.org/x/tools,v0.0.0-20191101200257-8dbcdeb83d3f,h1:+QO45yvqhfD79HVNFPAgvstYLFye8zA+rd0mHFsGV9s=,c3beb2acb726571e4cca3e922dd1eb037dcb6ef66ca562e9544716a53b6a1026 +golang.org/x/xerrors,v0.0.0-20191011141410-1b5146add898,h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=,5059c7b7e95f139b8c42d9001972fa5fa688b3581ef946c912c1dbc52415ff16 +gomodules.xyz/envconfig,v1.3.0,h1:w1laMNVtP05uOKqmRAY6Vx7HvfPL9yc388gcVtUiI/M=,ae5b4ee26eeb143c16bfb5316eb97e8ff4418bce379ae74e2a0bba367706d69c +gomodules.xyz/jsonpatch/v2,v2.0.1,h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=,3c97ac5b7cfa3388f3dc157e20e6ad7b7a5789a4df1d5257a39589cf66edd462 +gonum.org/v1/gonum,v0.6.0,h1:DJy6UzXbahnGUf1ujUNkh/NEtK14qMo2nvlBPs4U5yw=,98857b431471c87facf3cd779eadc5d33760c9edee4b56a8228af4b383b90aa2 +gonum.org/v1/netlib,v0.0.0-20190331212654-76723241ea4e,h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts=,ed4dca5026c9ab5410d23bbe21c089433ca58a19bd2902311c6a91791142a687 +gonum.org/v1/plot,v0.0.0-20191004082913-159cd04f920c,h1:Ssc2Jy4xun3/JMt2asledr/xSPAvX7ZZ7HimX2Gwz1w=,9246b6f7a9299061b31d99e50b2ac2685853dc478a6c2c730fada016c7268ea1 +google.golang.org/api,v0.13.0,h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA=,4c853034281c673829b7a7f3e39c62640d01895d20a666f003f855ad5f55ec30 +google.golang.org/appengine,v1.6.5,h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=,24ddb4adf72189738dc8340b28f9493a385515e680eb0bfbffe08951412b6655 +google.golang.org/genproto,v0.0.0-20191028173616-919d9bdd9fe6,h1:UXl+Zk3jqqcbEVV7ace5lrt4YdA4tXiz3f/KbmD29Vo=,cb4eec9cf94aa450efbb0d131cf1484f6334f1e8c1e1475b76c3ab2dea76c72a +google.golang.org/grpc,v1.24.0,h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s=,eb4433685a85e20f934c2a98e35d104db2d77abe438a242d75d5aae9f78898fb +google.golang.org/protobuf,v0.0.0-20191101204728-ef19a2a99470,h1:wSgCzfaFwg6Q4Eh+T7XknFfgswhFaeYkEs8t5endA/c=,73a49a6e5fd3330de7364564ab0954146e25ad8bbdff0ea6180f8ace153b0c1b +gopkg.in/Acconut/lockfile.v1,v1.1.0,h1:c5AMZOxgM1y+Zl8eSbaCENzVYp/LCaWosbQSXzb3FVI=,66e89c98908e2b9295de1a32cdd90f626a2468c256ce6182d6339e6659548e71 +gopkg.in/AlecAivazis/survey.v1,v1.8.7,h1:oBJqtgsyBLg9K5FK9twNUbcPnbCPoh+R9a+7nag3qJM=,c924df9f9d79f015cc619b1ecede52c92618c0ab8d020cd63e2c783f46b3907d +gopkg.in/DataDog/dd-trace-go.v1,v1.19.0,h1:aFSFd6oDMdvPYiToGqTv7/ERA6QrPhGaXSuueRCaM88=,f8eb14519d62c80eea88fca1daa69b274a0b492aa8b775890424b48d362c32b3 +gopkg.in/Shopify/sarama.v1,v1.18.0,h1:f9aTXuIEFEjVvLG9p+kMSk01dMfFumHsySRk1okTdqU=,beeb8546c4202289f282529630bc3db4452dc5f7eb69c3d8546196470c7d8be3 +gopkg.in/VividCortex/ewma.v1,v1.1.1,h1:tWHEKkKq802K/JT9RiqGCBU5fW3raAPnJGTE9ostZvg=,fe7800182ce944f2b28834d6cf60c620de0cbba1d691d9442f3473baf2a3d50d +gopkg.in/airbrake/gobrake.v2,v2.0.9,h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=,2db903664908e5a9afafefba94821b9579bbf271e2929c1f0b7b1fdd23f7bbcf +gopkg.in/alecthomas/gometalinter.v2,v2.0.12,h1:/xBWwtjmOmVxn8FXfIk9noV8m2E2Id9jFfUY/Mh9QAI=,7e6b56f4b985a08d11c1494f9dcc2b595676e787afe7a1caa9c522d41cab9487 +gopkg.in/alecthomas/kingpin.v2,v2.2.6,h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=,638080591aefe7d2642f2575b627d534c692606f02ea54ba89f42db112ba8839 +gopkg.in/alecthomas/kingpin.v3-unstable,v3.0.0-20180810215634-df19058c872c,h1:vTxShRUnK60yd8DZU+f95p1zSLj814+5CuEh7NjF2/Y=,0e35a5bb02770611e4c53c611529b95b96d0bc573f05d10bb43f7441abef2fde +gopkg.in/alexcesaro/quotedprintable.v3,v3.0.0-20150716171945-2caba252f4dc,h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=,1a310c5e55038937be3e69765276449601ca582f681129f7d9d47e052846cafc +gopkg.in/asn1-ber.v1,v1.0.0-20181015200546-f715ec2f112d,h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=,fee158570ba9cbfc11156afbe9b9ab0833ab00d0f1a2a2af29a6325984a79903 +gopkg.in/bblfsh/sdk.v1,v1.17.0,h1:Ez/4P0S0Zaq30iZKfiTlhOtqMx6dfQHMTYpqKFvnv4A=,172521b9f2bdd4180751ed5122971c9c37a8c0bca2e0710bc255bc0e5ff8c106 +gopkg.in/bblfsh/sdk.v2,v2.16.4,h1:Ta/kBVRGXf8UOBYDw/ih8mw13/8NND+AdR0JiXBQrOw=,eb7a8a7d08bd80cd0673a6b9c90fa524bda9db24242bd6ef82fb414941c4ef0f +gopkg.in/bsm/ratelimit.v1,v1.0.0-20160220154919-db14e161995a,h1:stTHdEoWg1pQ8riaP5ROrjS6zy6wewH/Q2iwnLCQUXY=,fea8af18591a0ac50d29c8db124d13a43da6bee7a624c411b7449a99ee87b489 +gopkg.in/bufio.v1,v1.0.0-20140618132640-567b2bfa514e,h1:wGA78yza6bu/mWcc4QfBuIEHEtc06xdiU0X8sY36yUU=,9d63fe986f79edba7fca9bcd3bee0c7dcff7787cd30b43b5f2ae8a59feae512c +gopkg.in/check.v1,v1.0.0-20190902080502-41f04d3bba15,h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=,004537cb19dbe45954ec1605f331705f6685ccc267eddd4289c1eb27513ab817 +gopkg.in/cheggaaa/pb.v1,v1.0.28,h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk=,39725f9f37aac44dd55bdc9ade65a2d066953a090456298d34203257fc7e8ee9 +gopkg.in/cheggaaa/pb.v2,v2.0.7,h1:beaAg8eacCdMQS9Y7obFEtkY7gQl0uZ6Zayb3ry41VY=,a6ba73f81893f0eca8c0a60c238a705a12bae499a44fe6217a4471687766ef02 +gopkg.in/clog.v1,v1.2.0,h1:BHfwHRNQy497iBNsRBassPixSAxRbn2z5KVkdBFbwxc=,51eb8901943d1cec850b55556a9989e21488a9636ac692d6f7575db057804f3d +gopkg.in/editorconfig/editorconfig-core-go.v1,v1.3.0,h1:oxOEwvhxLMpWpN+0pb2r9TWrM0DCFBHxbuIlS27tmFg=,b5371885f56b40c03da4fd05006c717fabdfb8ee9ea1ceef4cc5b7caeda35041 +gopkg.in/errgo.v1,v1.0.1,h1:oQFRXzZ7CkBGdm1XZm/EbQYaYNNEElNBOd09M6cqNso=,32f45f7cfacfc04ae9e7e8c9fc55a53812554799da7c2bd17b043068b5fd5171 +gopkg.in/errgo.v2,v2.1.0,h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=,6b8954819a20ec52982a206fd3eb94629ff53c5790aa77534e6d8daf7de01bee +gopkg.in/fatih/color.v1,v1.7.0,h1:bYGjb+HezBM6j/QmgBfgm1adxHpzzrss6bj4r9ROppk=,ed20c58de8c575144c2cc1c924121ee1a240e0621c77918231547b576d46d3ce +gopkg.in/fatih/set.v0,v0.2.1,h1:Xvyyp7LXu34P0ROhCyfXkmQCAoOUKb1E2JS9I7SE5CY=,d743141e21d20f6d5ae8e784dd4644c0947948103b63404a878b0298f14a9e62 +gopkg.in/fsnotify.v1,v1.4.7,h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=,ce003d540f42b3c0a3dec385deb387b255b536b25ea4438baa65b89458b28f75 +gopkg.in/fsnotify/fsnotify.v1,v1.4.7,h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo=,6f74f844c970ff3059d1639c8a850d9ba7029dd059b5d9a305f87bd307c05491 +gopkg.in/gavv/httpexpect.v1,v1.0.0-20170111145843-40724cf1e4a0,h1:r5ptJ1tBxVAeqw4CrYWhXIMr0SybY3CDHuIbCg5CFVw=,4fe4a5e78a26ac5b60fc16405d3a5918d83cd645d36bd9dc0d558824136930b6 +gopkg.in/gcfg.v1,v1.2.3,h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs=,06cdad29610507bafb35e2e73d64fd7aa6c5c2ce1e5feff30a622af5475bca3b +gopkg.in/gemnasium/logrus-airbrake-hook.v2,v2.1.2,h1:OAj3g0cR6Dx/R07QgQe8wkA9RNjB2u4i700xBkIT4e0=,ce35c69d2a1f49d8672447bced4833c02cc7af036aa9df94d5a6a0f5d871cccd +gopkg.in/go-playground/assert.v1,v1.2.1,h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=,11da2f608d82304df2384a2301e0155fe72e8414e1a17776f1966c3a4c403bc4 +gopkg.in/go-playground/validator.v8,v8.18.2,h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=,fea7482c7122c2573d964b7d294a78f2162fa206ccd4b808d0c82f3d87b4d159 +gopkg.in/go-playground/validator.v9,v9.30.0,h1:Wk0Z37oBmKj9/n+tPyBHZmeL19LaCoK3Qq48VwYENss=,f4769db84ddc2db880bc190a5420762ef45f80ebbce678b622c4fa82b422b890 +gopkg.in/gobwas/glob.v0,v0.2.3,h1:uLMy+ys6BqRCutdUNyWLlmEnd7VULqh1nsxxV1kj0qQ=,3a5fe045be1ff9b47c5e21a9f97bdefaada31463f365503d6b176b76e18a0257 +gopkg.in/gographics/imagick.v3,v3.2.0,h1:eUwlkCw2fa20OGu47G39Im8c50S9n/CVkh8PwtOKExA=,99695d22cf7d5609887609cc9dc63ca1031b5a3238c26f6b779f32e39d572a01 +gopkg.in/gomail.v2,v2.0.0-20160411212932-81ebce5c23df,h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=,08b3372836aef3a403b0a01e6867a3a2252a07f65c28e0d33fe9c4b1b3ac517a +gopkg.in/gorp.v1,v1.7.2,h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=,eaad3325e8b5358d5d54a1ca8b1e6aa19d16968a1f11f3dc45671588d914ef25 +gopkg.in/guregu/null.v3,v3.4.0,h1:AOpMtZ85uElRhQjEDsFx21BkXqFPwA7uoJukd4KErIs=,b38d62a816c5905933396a02eb11e23cbe2c17f8837563cc10794274e5af7e6e +gopkg.in/h2non/gentleman.v2,v2.0.3,h1:exsUPKJDFwNjJykboVj8+BKPWMNOxR/AmPL3f7Hutwo=,7a71dc2dd74e413832782e4478f85cc0617aed125e078e308b46207f34d6a500 +gopkg.in/h2non/gock.v1,v1.0.15,h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0=,c6a3d33e638b56ddd050c1dc6c1c6c8e9007c70cacfcc29e778fcf421f1fc029 +gopkg.in/httprequest.v1,v1.2.0,h1:YTGV1oXzaoKI6oPzQ0knoIPcrrVzeRG3amkoxoP7Xng=,3960019870090d0de3fca818633111186d46a908b4bcac6d87e5f08e7fb58770 +gopkg.in/inconshreveable/log15.v2,v2.0.0-20180818164646-67afb5ed74ec,h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A=,799307ed46ca30ca0ac2dc0332f3673814b8ff6cc1ee905a462ccfd438e8e695 +gopkg.in/inf.v0,v0.9.1,h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=,08abac18c95cc43b725d4925f63309398d618beab68b4669659b61255e5374a0 +gopkg.in/ini.v1,v1.49.0,h1:MW0aLMiezbm/Ray0gJJ+nQFE2uOC9EpK2p5zPN3NqpM=,579074067ceacbf11e938940d65647094da4f23f627645b5c58218bf05c060f0 +gopkg.in/jarcoal/httpmock.v1,v1.0.0-20181117152235-275e9df93516,h1:H6trpavCIuipdInWrab8l34Mf+GGVfphniHostMdMaQ=,5b896c9e5e44146260a066533409c1b86268458301a7155624ef27f784e5d94a +gopkg.in/jcmturner/aescts.v1,v1.0.1,h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=,8bfd83c7204032fb16946202d5d643bd9a7e618005bd39578f29030a7d51dcf9 +gopkg.in/jcmturner/dnsutils.v1,v1.0.1,h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=,4fb8b6a5471cb6dda1d0aabd1e01e4d54cb5ee83c395849916392b19153f5203 +gopkg.in/jcmturner/goidentity.v3,v3.0.0,h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI=,1be44bee93d9080ce89f40827c57e8a396b7c801e2d19a1f5446a4325afa755e +gopkg.in/jcmturner/gokrb5.v7,v7.2.3,h1:hHMV/yKPwMnJhPuPx7pH2Uw/3Qyf+thJYlisUc44010=,3eec5b25adb89633174beb9798d8092e91ff4eed146a4b4cb950dd02414bd75e +gopkg.in/jcmturner/rpc.v1,v1.1.0,h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU=,83d897b60ecb5a66d25232b775ed04c182ca8e02431f351b3768d4d2876d07ae +gopkg.in/jmcvetta/napping.v3,v3.2.0,h1:NpSZLAL6VgiyhdqaOkxwVtHXOLrQJZ6fFOMQgp7G8PQ=,887358529a8cd287b6a8232b43cc48636463fa266bac5ba48328cb0609d1dcb6 +gopkg.in/juju/charm.v6,v6.0.0-20191031115626-f595bfd8a049,h1:+isWLR3tDZyDacru13gHH0ooIuuDB28kuZJjSc8kOqU=,8d404b146f31d35148015de3f5bd4d25260f0a4b9f22a540a9167864d9e5d082 +gopkg.in/juju/charmrepo.v3,v3.0.1,h1:mm7/CwCczsO7JYHlYkw4iCUYR7X8upEOaY5bYj7eUkw=,8f673109a6d98e4abe4ef612f85dea26bdbd7de5c66b6722c546a08aefb548fc +gopkg.in/juju/environschema.v1,v1.0.0,h1:51vT1bzbP9fntQ0I9ECSlku2p19Szj/N2beZFeIH2kM=,46ae8efc5a450745fea959dc8532d2a013aa741ab7193d3cea8b0735f09c6e8a +gopkg.in/juju/names.v2,v2.0.0-20190813004204-e057c73bd1be,h1:xDxN+Fe8olIH8sTqvFJBMsuflBYzeHVeYC4Iz97+f5M=,72ac554c125260751aadf6d41eb82d85de22ef8bff1d59c6602e9e0f5b84a28c +gopkg.in/juju/worker.v1,v1.0.0-20191018043616-19a698a7150f,h1:UAHa7z4EdrOcMN+9p5P+ojJshcIC34vwi0hCmEL6Qf8=,2e0da8053029ca9da961f8e6f1037a9d7ba12623e5c16fc5f88bf1a724c5dd23 +gopkg.in/karalabe/cookiejar.v2,v2.0.0-20150724131613-8dcd6a7f4951,h1:DMTcQRFbEH62YPRWwOI647s2e5mHda3oBPMHfrLs2bw=,07aae15601f54a5806705d218e313794118d54d9dda7addc1bf4bda4332dfc16 +gopkg.in/kothar/go-backblaze.v0,v0.0.0-20190520213052-702d4e7eb465,h1:DKgyTtKkmpZZesLue2fz/LxEhzBDUWg4N8u/BVRJqlA=,215300ce3726c40f51ee43c41a27c204441e756c8cb4f4b76b1a4dd08f509eef +gopkg.in/ldap.v2,v2.5.1,h1:wiu0okdNfjlBzg6UWvd1Hn8Y+Ux17/u/4nlk4CQr6tU=,4fd426691e674164a701ef3ec3548596574f95447cde1fa331018f7d73f8399b +gopkg.in/ldap.v3,v3.0.2,h1:R6RBtabK6e1GO0eQKtkyOFbAHO73QesLzI2w2DZ6b9w=,f79d1cb87a0a6d571e671c2028409056d65e6bfa7d3d0563ded0edbe8ff0998e +gopkg.in/macaron.v1,v1.3.4,h1:HvIscOwxhFhx3swWM/979wh2QMYyuXrNmrF9l+j3HZs=,f9aca15b099dada4382e47898516d500876aae45d36895314cde86700636c05c +gopkg.in/macaroon-bakery.v2,v2.1.0,h1:9Jw/+9XHBSutkaeVpWhDx38IcSNLJwWUICkOK98DHls=,0a12f46df7290b131ee74ec6a4d4760170192920a091939aa2d7a39a4d0fb310 +gopkg.in/macaroon-bakery.v2-unstable,v2.0.0-20171026135619-38b77b89a624,h1:FIOL4YpoNbXH6K+LnOoAEMa/1ebliK7B9mj5NuJHmiA=,51476e40e03bd1f64fd3cdf936d1cde4b8c1395884af9376ff65755041c247aa +gopkg.in/macaroon.v2,v2.1.0,h1:HZcsjBCzq9t0eBPMKqTN/uSN6JOm78ZJ2INbqcBQOUI=,ae47a93d20ce5c053eafc9d6a76c01b2b06784f9886137dc73a99302928046eb +gopkg.in/macaroon.v2-unstable,v2.0.0-20180319203259-5c9beabe0e9e,h1:yPxshueS06kvTVlsymSbHvk6VQ1WhX1Ou3hCqqWBp/s=,e09a1f8268d65e3dc28da85c75e78f15f1f742d1dcd31cce427fd885b1962bc4 +gopkg.in/mail.v2,v2.0.0-20180731213649-a0242b2233b4,h1:a3llQg4+Czqaf+QH4diHuHiKv4j1abMwuRXwaRNHTPU=,d7d60701b95fd7f62d3f83bc026f42c0fa69c3f16cc445d2b20497c9dd182ff6 +gopkg.in/mattes/migrate.v1,v1.3.2,h1:tWus4MPMhDY/htX+NCvASiQVRU2pj4Jyj4T8AIv6vUw=,c50f590108871c25d55631addd6bc267f311830d4306ff4d36a6feaad0b23255 +gopkg.in/mattn/go-colorable.v0,v0.1.0,h1:WYuADWvfvYC07fm8ygYB3LMcsc5CunpxfMGKawHkAos=,337a25f7f87a87097e5fb853313c1fac3d3126ed0eb9bb88511d52ba9a0eb4e0 +gopkg.in/mattn/go-isatty.v0,v0.0.4,h1:NtS1rQGQr4IaFWBGz4Cz4BhB///gyys4gDVtKA7hIsc=,18500935e08e5b74487537b8b78a30778a5b2304a138f53aa8758b86266773ff +gopkg.in/mattn/go-runewidth.v0,v0.0.4,h1:r0P71TnzQDlNIcizCqvPSSANoFa3WVGtcNJf3TWurcY=,e0307a435e39658f761b7526dda9149e7664b7250958494c1a4eebd14884b82d +gopkg.in/mcuadros/go-syslog.v2,v2.2.1,h1:60g8zx1BijSVSgLTzLCW9UC4/+i1Ih9jJ1DR5Tgp9vE=,1f444e24504b6a21c0d204441a84336ab1240f77a1280b60e48f68ea1b99da7b +gopkg.in/mgo.v2,v2.0.0-20190816093944-a6b53ec6cb22,h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=,14edbec0d97107b0e0980b66166400f8a4c3844b03bd3240fc57be2b82734b16 +gopkg.in/natefinch/lumberjack.v2,v2.0.0,h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=,8c268e36660d6ce36af808d74b9be80207c05463679703e93d857e954c637aaa +gopkg.in/neurosnap/sentences.v1,v1.0.6,h1:v7ElyP020iEZQONyLld3fHILHWOPs+ntzuQTNPkul8E=,e3df38d6fc6097f9d1d76ee13e24fec69103c43248ca6a7f3ade2afec5e85bdd +gopkg.in/ns1/ns1-go.v2,v2.0.0-20190730140822-b51389932cbc,h1:GAcf+t0o8gdJAdSFYdE9wChu4bIyguMVqz0RHiFL5VY=,c51d0889ff5eb72df2f9e4adc28e9f3602e6eb567c3824bebb3c7d315a60710a +gopkg.in/olivere/elastic.v2,v2.0.61,h1:7cpl3MW8ysa4GYFBXklpo5mspe4NK0rpZTdyZ+QcD4U=,0a20d84f6003850343937ef79179cabe99feef9b038c281fd65ec32ec6c7e85c +gopkg.in/olivere/elastic.v5,v5.0.82,h1:QH7ere4lvOAWnnOd0VLJ54W8LzExZszoGIRijnb1h2Y=,3c66a7606b226d19f61651b3ad58aecda3155edc802029bd21cd4b8724bd0c9f +gopkg.in/ory-am/dockertest.v3,v3.3.4,h1:oen8RiwxVNxtQ1pRoV4e4jqh6UjNsOuIZ1NXns6jdcw=,73b01a1d025d30c8f11def182179b873410eae72f7b2fd9f9394b0fcf4683c93 +gopkg.in/redis.v2,v2.3.2,h1:GPVIIB/JnL1wvfULefy3qXmPu1nfNu2d0yA09FHgwfs=,abe2fa39afa36f8186ee287bcf82f9f4bc083aa35d17dd82a2ccbf5850ecdde8 +gopkg.in/redis.v3,v3.6.4,h1:u7XgPH1rWwsdZnR+azldXC6x9qDU2luydOIeU/l52fE=,749ef3e08eb4eda43969f88135040ae4517b450b27dbd48aefb9bf5e72465621 +gopkg.in/redis.v4,v4.2.4,h1:y3XbwQAiHwgNLUng56mgWYK39vsPqo8sT84XTEcxjr0=,6403d2b45edf2804bfd07b6d697184fc97377168589ad43ad19b2433e1dcee34 +gopkg.in/redis.v5,v5.2.9,h1:MNZYOLPomQzZMfpN3ZtD1uyJ2IDonTTlxYiV/pEApiw=,3c30e42670d1ef5f0b33876928b3bd5693ef3b5be1df6b2710d48c2667ca7133 +gopkg.in/resty.v1,v1.12.0,h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=,43487bb0bb40626d16502b1fe9e719cf751e7a5b4e4233276971873e7863d3cf +gopkg.in/robfig/cron.v2,v2.0.0-20150107220207-be2e0b0deed5,h1:E846t8CnR+lv5nE+VuiKTDG/v1U2stad0QzddfJC7kY=,b25da9b8747e664334044e581d1a8fb700237239e7f182fd226d6296e6180bc0 +gopkg.in/satori/go.uuid.v1,v1.2.0,h1:AH9uksa7bGe9rluapecRKBCpZvxaBEyu0RepitcD0Hw=,794cefc3062e09b17f4300eb6b02622ac348af9d368341ff71a655a15884547f +gopkg.in/sourcemap.v1,v1.0.5,h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=,05b5f382bfa60212f444c7207168e9eb0c722e26b57a688123cb8bbf234de692 +gopkg.in/spacemonkeygo/monkit.v2,v2.0.0-20190623001553-09813957f0a8,h1:nyw4hxw2zz4S0EHqr5nQfA3zGbMFJDRJlQPM4PCb7O4=,4a8e607c4f16b32bb9ee380627716979b19ac3df74ca2a4f80aefbaf0b411784 +gopkg.in/square/go-jose.v2,v2.4.0,h1:0kXPskUMGAXXWJlP05ktEMOV0vmzFQUWw6d+aZJQU8A=,d00c4af5a633ab9cf7645b68f6fa389c8f0d9ffebc486742c7a5292280cae84b +gopkg.in/src-d/go-billy.v4,v4.3.2,h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=,c49871e1d08bba07b2261626b929096b6dc5c839e781adfc24fcc410067cc2bf +gopkg.in/src-d/go-cli.v0,v0.0.0-20181105080154-d492247bbc0d,h1:mXa4inJUuWOoA4uEROxtJ3VMELMlVkIxIfcR0HBekAM=,86042ffc0c8492845917453682c5bdba46beb2f0c067b61e495a92b9a8621076 +gopkg.in/src-d/go-errors.v1,v1.0.0,h1:cooGdZnCjYbeS1zb1s6pVAAimTdKceRrpn7aKOnNIfc=,f7d9f00c057d4b49bc6e57167561a7fb508ebb113a1946cb2b6f71dac5b14cfb +gopkg.in/src-d/go-git-fixtures.v3,v3.5.0,h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg=,282dc6474c5ecf62c1169d04ad1f6d75e6058922897b4709a16a1007a5f22eb7 +gopkg.in/src-d/go-git.v4,v4.13.1,h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE=,13364fe60f2316a179e912fb4eb6c576e2aabd67e8d390651a155e85c69146d2 +gopkg.in/src-d/go-log.v1,v1.0.1,h1:heWvX7J6qbGWbeFS/aRmiy1eYaT+QMV6wNvHDyMjQV4=,48f6c8a7bdc5436d296f388cd5d40ffb9c749e1e4ab1e455984efc61008fd5d7 +gopkg.in/stack.v0,v0.0.0-20141108040640-9b43fcefddd0,h1:lMH45EKqD8Nf6LwoF+43YOKjOAEEHQRVgDyG8RCV4MU=,a88c4cb4af34bb5c4dd69d0c771829331be7416d2f18d58ff599126f7b291984 +gopkg.in/stretchr/testify.v1,v1.2.2,h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M=,0126e73e5f2ce5687dec597bb276e11dc4031dbdf199e68de735bc67bf808149 +gopkg.in/telegram-bot-api.v3,v3.0.0,h1:Y6QmqOMwRKv5NUdlvzEBtEZChjsrqdTS6O858cvuCww=,03c58e32567a5cc4ec631cc226ecc99dd1113a7a98bab4778b02cde073ab5ed4 +gopkg.in/telegram-bot-api.v4,v4.6.4,h1:hpHWhzn4jTCsAJZZ2loNKfy2QWyPDRJVl3aTFXeMW8g=,01a91b240fb416bf83bcaaa07133cafac28fd8eb8f0f251f6a616beec88c92ac +gopkg.in/testfixtures.v2,v2.5.0,h1:N08B7l2GzFQenyYbzqthDnKAA+cmb17iAZhhFxr7JHw=,05baac4af6e2855d296a5c045b27deb1b33d0a04cd0df96f029927f0742765a3 +gopkg.in/tomb.v1,v1.0.0-20141024135613-dd632973f1e7,h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=,34898dc0e38ba7a792ab74a3e0fa113116313fd9142ffb444b011fd392762186 +gopkg.in/tomb.v2,v2.0.0-20161208151619-d5d1b5820637,h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs=,15d93d96e1e8b2d8daf7b9e57a2a9193c0e676a2c6b63d9325bf34b53e93db00 +gopkg.in/tylerb/graceful.v1,v1.2.15,h1:1JmOyhKqAyX3BgTXMI84LwT6FOJ4tP2N9e2kwTCM0nQ=,0a8639cfe62508438ebf2cae721468b64d8cd2992fc0f80439c83c718f4608e0 +gopkg.in/urfave/cli.v1,v1.20.0,h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=,413704688402027dc0f51666bac42152eb1668a73fa0e33858c3d2123c0592e5 +gopkg.in/warnings.v0,v0.1.2,h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=,c412b1f704c1e8ba59b6cfdb1072f8be847c03f77d6507c692913d6d9454e51c +gopkg.in/yaml.v1,v1.0.0-20140924161607-9f9df34309c0,h1:POO/ycCATvegFmVuPpQzZFJ+pGZeX22Ufu6fibxDVjU=,7abff7973fdab7386de5a1e9e197d8dc50d41ded9d24ff914685900caa0eb742 +gopkg.in/yaml.v2,v2.2.4,h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=,815be785649ae218b51efd8e40b3b75de8f9b57dd43162386ffe3e76709f2a5d +gorgonia.org/tensor,v0.9.2,h1:bVTWB68apbLfdrAlz5Ev3daGhfOhKuPkVFacMSNzpHs=,17562e7c1c6477b8b530d6236ab9a61228edbabe01c1cfb9ba23286c2394ba4c +gorgonia.org/vecf32,v0.9.0,h1:PClazic1r+JVJ1dEzRXgeiVl4g1/Hf/w+wUSqnco1Xg=,618df2e604236a2d143958a3571f9939c8264ab2aaae7d8c71b897b728240a23 +gorgonia.org/vecf64,v0.9.0,h1:bgZDP5x0OzBF64PjMGC3EvTdOoMEcmfAh1VCUnZFm1A=,f57695832a12a6f1fbcc04cdaa267ed01fb6b8105f518590d64b2c63b9ac4c61 +gotest.tools,v2.2.0+incompatible,h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=,55fab831b2660201183b54d742602563d4e17e7125ee75788a309a4f6cb7285e +grpc.go4.org,v0.0.0-20170609214715-11d0a25b4919,h1:tmXTu+dfa+d9Evp8NpJdgOy6+rt8/x4yG7qPBrtNfLY=,58b5c3cccf3e765d0f42918d458cddcd03fc28ff5d701790783677513a8446e3 +h12.io/socks,v1.0.0,h1:oiFI7YXv4h/0kBNcmAb5EkkoFJgYsOF88EQjMBxjitc=,3bf83125284ccabf811aa238954b442e39f53e3e068d4ddb6bf679ba2be28bbe +honnef.co/go/js/dom,v0.0.0-20190526011328-ebc4cf92d81f,h1:b3Q9PqH+5NYHfIjNUEN+f8lYvBh9A25AX+kPh8dpYmc=,a65720d9c0339450c8818226693a85986549fb156ee4df65913682c350bd4d60 +honnef.co/go/js/util,v0.0.0-20150216223935-96b8dd9d1621,h1:QBApQyt1KyR3SvDWU8sHcIXeWTSCUamO7xQopvwuLWI=,db5638addc7638cc5cf2245cb9bcb19cf04a5912120330560149b54b4575ae50 +honnef.co/go/js/xhr,v0.0.0-20150307031022-00e3346113ae,h1:2dIKMawnBWvHzZrS8STyu/KdhYIOpnKQpp1WZm+K7TE=,d2a4a85c43fb4ccd9b5be6521450d272406a1722f7547f188f4a1d0cc65c4e13 +honnef.co/go/tools,v0.0.1-2019.2.3,h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=,539825114c487680f99df80f6107410e1e53bbfd5deb931b84d1faf2d221638e +howett.net/plist,v0.0.0-20181124034731-591f970eefbb,h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=,58c94cd949be714c0ee320d1be0cff3116fc829c412b9e7b816b03fb3c85f463 +istio.io/api,v0.0.0-20191029012234-9fe6a7da3673,h1:wxFykuQoScKAnEtKujAPqjwR8Aqo2LNtkoIvodxyCSs=,9ba545b9c5411725b709287b590082d140d3b29d924be351e38942f46c33ff55 +istio.io/gogo-genproto,v0.0.0-20190930162913-45029607206a,h1:w7zILua2dnYo9CxImhpNW4NE/8ZxEoc/wfBfHrhUhrE=,3b5a81f1807f48117d6691c8d007402a94b648f45f4446841a3f56229aa94aba +istio.io/pkg,v0.0.0-20191029184635-5c2f5ef63692,h1:MT7e5hpQ8cGtKCeWIjtdluEVkIhkN2tw4iVkAzhWHYA=,887882f7e721e6d00dee301f0b029792bd04bd38c455ab7e5cf4f2bc5bf309df +k8s.io/api,v0.0.0-20191031065753-b19d8caf39be,h1:X0MqzqUHuZj50SrMQFExejJfy67RKPf30Vt2nnpa4AA=,00a67ed9b84be18f621701796b42cee630c770c858582753fe0eb9c146ef93ff +k8s.io/apiextensions-apiserver,v0.0.0-20191028232452-c47e10e6d5a3,h1:XxkWdWvPKTParJ1sXpUIvHJsJ2iIIj5Ebjxxy5YU1Zo=,2cb12eb8b2b0f95fb5d69b1f80b754b32ae46ef1f9636333fe27c6b17b1a6e19 +k8s.io/apimachinery,v0.0.0-20191030190112-bb31b70367b7,h1:81UYA9Qq3JXPpZMmRBnq6T3qU+b71Dvnm6sV3NSQTVk=,4c16a440acf7559b0974d99650c876969ad4811ddc76f9f5b7aa43afc34f66ec +k8s.io/apiserver,v0.0.0-20191031110436-8cb875160ee0,h1:BGkQMPpKpx07hvq9AW64gifbf+zbAh/xUbB5OYXPvQ0=,baefad9177a1f8077c94a2d88b7e85deb7df79317d3d6d6afe8ca0be8261b1ae +k8s.io/cli-runtime,v0.0.0-20191025231729-08207da42a69,h1:05z+vSvn9yPr7GTAt3MXpVc9VeU4D80HHwvJU6jC3D4=,46264219a6e1c8263acd610841a156086bbbdd43436a836effcd7285c37b0e8a +k8s.io/client-go,v11.0.0+incompatible,h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o=,70925f536d409accf4f6ae3f20dafd81370ac096f848e99009141bea971103c2 +k8s.io/cloud-provider,v0.0.0-20191025232453-66dd06a864dd,h1:CxSfhPPmLwYFZquskmKvODMeEm82ZLc4eph47AdUp+o=,55623701c005f824ae847ecad409c6e61ef5fcfc6588b8dd2995a4a0991eeae8 +k8s.io/cluster-bootstrap,v0.0.0-20191025232351-410fafc3baf5,h1:P1mMVQngKW9pj1haVjyAtqViIBqkJmsITXsfuaHGRko=,ff50816340cdb73313e7233c3ff6df383c350102762b88ea0cc744910053c7bd +k8s.io/code-generator,v0.0.0-20191029223907-9f431a56fdbc,h1:klQ4aWfZ3uk4UiSLkZZt5qQDI+7DwSdvbvyL5QUBHsQ=,1f63d3191c255d8fcc47ad24b3bd979865a3c12eca678b39f278c194c2ae560a +k8s.io/component-base,v0.0.0-20191029070825-5e0e35147053,h1:W9/+uFw7olz+qQOCmSOG92c6j2YgIwagxqR9RWai/cE=,45bd9877048a57c3dfe7eb9c98bc1939775c73fdd6451afd055d7e4f7b9659bc +k8s.io/cri-api,v0.0.0-20191025232916-446748cffdda,h1:HVTA1bXCQek+NF0xTZkryScnkGYWHkoeYAQVEVs73r8=,7aea277309740df8d1fad1c620901d60633569d755d2d0715d97bc553988d7be +k8s.io/csi-api,v0.0.0-20190313123203-94ac839bf26c,h1:m3xih+9aI7l7Z/PvwzizV1J4vBvaUpkHrmagnGa5UNg=,0579fba2111dfd5b3cb62d7d234e52c54051176d9564ae3f0f2fdc69b31872b0 +k8s.io/gengo,v0.0.0-20191010091904-7fa3014cb28f,h1:eW/6wVuHNZgQJmFesyAxu0cvj0WAHHUuGaLbPcmNY3Q=,7fe69109e947204ee0b95705626e3c3b540faefb947d3426260f2991d1e4c036 +k8s.io/helm,v2.15.2+incompatible,h1:UjEb+c5BUZDGR9zU3dWG3OXASLIeqLeY0FCIx6ZyfTY=,377860d9db9fb1d45ffa90fe6ee79d7cfc4e91e5bc04183921480a823cf79ede +k8s.io/klog,v1.0.0,h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=,a564b06078ddf014c5b793a7d36643d6fda31fc131e36b95cdea94ff838b99be +k8s.io/kube-aggregator,v0.0.0-20191025230902-aa872b06629d,h1:ls0BmbSFkF5BhZN7grE+W5/X49QMU42RH6J9DWdP7UQ=,9a51f29a98f603acde33e3a10625e9ab603d7db29b3c2b2256d145adf7396393 +k8s.io/kube-controller-manager,v0.0.0-20191025232249-6de08162fd59,h1:bTAKwqwK2HvJVmpowb/ccyeV3wsxQZUtFQE1AqhMZ6I=,a1183bb172f19f6ae319da09c111a3f5dded663a9be85e18b9bceb131f03a342 +k8s.io/kube-openapi,v0.0.0-20190918143330-0270cf2f1c1d,h1:Xpe6sK+RY4ZgCTyZ3y273UmFmURhjtoJiwOMbQsXitY=,fb1dcd1508144991be0a243cea9a066944775ba4e9fa23c7ea038822e4e8e232 +k8s.io/kubelet,v0.0.0-20191025232041-e9c3b1e8a9ed,h1:ISiRMWhiLjmSsx24QQ6NJSgW1oKmAN59LCFzB7llrSk=,8c409ac5922dfb4cb0b8e6bb52823b2132e82faa3756dc3a94cdeabeaa3ff51e +k8s.io/kubernetes,v1.11.10,h1:wCo67+wmguioiYv0ipIiTaXbVPfFBBjOTgIngeGGG+A=,7c8ca4ca473e9f2b5c6586a714209e98d99f193af84cdb3e8536a3d1e26be4bf +k8s.io/metrics,v0.0.0-20191026071343-a166cc0bce8f,h1:D4AcfwGLY2gFDQaeK2QVyb8g4fy4Xzs0GopdwAgfSGc=,f4243455881a38d4962483ba5f2888220743a6ddece179c2b8f706815b75778f +k8s.io/node-api,v0.0.0-20191025232816-761e5a80fde0,h1:V3FaBxwSQWPjPScXd5ioFx9+aREXGU24yFl8Gm7ib8w=,cb8718b6e148a66097f8cae4e4544dc55c674748202f9c21d07a2139b6e83fd1 +k8s.io/sample-apiserver,v0.0.0-20191030110742-cbfc6c263d7e,h1:9bsKcUCncu1Qg3A4pB5ZySTM0JMEZW4qgybjVhmaS4A=,91d701af12da2ff6cde6f07d53547885faafa32c2eadfa8d4614b4d814a854b9 +k8s.io/sample-controller,v0.0.0-20191025231305-d7b8b8302943,h1:ZYb6if7+Qa5kXFidUsQRLFDyZjCjRyG1sFf6GpZaA70=,07c3e3a95d0fac07a247a98c38448a8fc4ab0069ad599ec06ac9405df88b470b +k8s.io/utils,v0.0.0-20191030222137-2b95a09bc58d,h1:1P0iBJsBzxRmR+dIFnM+Iu4aLxnoa7lBqozW/0uHbT8=,e21be6d971127d4650bd13525a2d2627b2a98dbb8589f168b734a45d50f3ea22 +launchpad.net/gocheck,v0.0.0-20140225173054-000000000087,h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=,1a1d9b10f2c69564e69993e4340d5299392a518d895ec06502e842e6c69f4857 +layeh.com/radius,v0.0.0-20190322222518-890bc1058917,h1:BDXFaFzUt5EIqe/4wrTc4AcYZWP6iC6Ult+jQWLh5eU=,5eb6b6a05a5f89bc114f37085deda268f895a46621aee2e36649b8d80061357e +leb.io/aeshash,v0.0.0-20190627052759-9e6b40329b3b,h1:MG17Tc0pA3XmFTsPwklMMEfcos3pTFnVYM4A0YfVSbU=,a78b48ac18e98ea68dacce16cd94c9074688a0b125f824f047313a33b264ea88 +leb.io/hashland,v0.0.0-20171003003232-07375b562dea,h1:s9IkzZTqYqw77voO6taUZHc0C1B096h4T/kQtujGApE=,0698177f24cbde0a7b45495e7fe976fe7623f2b9205995b7d91fd2e7b0f0e243 +leb.io/hrff,v0.0.0-20170927164517-757f8bd43e20,h1:9CHS8LIq9MDwUsAaCHUsbUq7zb5lSjLQYWlJ/AbMZKg=,538008712599401a903a7982714c0a9ae745221042d3dfb1437bc508d8fb9e96 +llvm.org/llvm,v0.0.0-20191022153947-000000375505,h1:cncItmsQ0kcXFrnkQZv2TGle2ELPCEDi3Q36Kf2T3yg=,3f48da9846fc0f69ccc447ead4480f8c7f2b44b0c24b98a793d36d8cb2a572c0 +modernc.org/cc,v1.0.0,h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ=,24711e9b28b0d79dd32438eeb7debd86b850350f5f7749b7af640422ecf6b93b +modernc.org/golex,v1.0.0,h1:wWpDlbK8ejRfSyi0frMyhilD3JBvtcx2AdGDnU+JtsE=,335133038991d7feaba5349ac2385db7b49601bba0904abf680803ee2d3c99df +modernc.org/mathutil,v1.0.0,h1:93vKjrJopTPrtTNpZ8XIovER7iCIH1QU7wNbOQXC60I=,766ad95195543fe1ac217ce9f54e1fb43119c25db2b89013b9ef5477ad2dd9d1 +modernc.org/strutil,v1.0.0,h1:XVFtQwFVwc02Wk+0L/Z/zDDXO81r5Lhe6iMKmGX3KhE=,4bbca362df97450c6f24b90b7dc80b97ecf19e5f0f5954655b26f335a0b8f378 +modernc.org/xc,v1.0.0,h1:7ccXrupWZIS3twbUGrtKmHS2DXY6xegFua+6O3xgAFU=,ef80e60acacc023cd294eef2555bd348f74c1bcd22c8cfbbd2472cb91e35900d +moul.io/http2curl,v1.0.0,h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8=,422e2b8833089b001da02c6d7235ecb4c0591bb585fee125cbd0d72b1371dba5 +mvdan.cc/sh,v2.6.0+incompatible,h1:BLDuJ+D75OCaBF7W70+2oALi8aKAjcAiDBNmmwR8BQA=,c5c335f4ae8f1c4228a01710b84ba8f847709b1920d2beeddc4648e62cdd25f7 +mvdan.cc/sh/v3,v3.0.0-alpha1,h1:ao/4li6H9nZe5HDXA14cynXoq90+DLZz0HmjZE/qjhA=,5da16556569786a039c24229b55eb0f76049c2293ac96a9b978cede87676962e +mvdan.cc/xurls/v2,v2.0.0,h1:r1zSOSNS/kqtpmATyMMMvaZ4/djsesbYz5kr0+qMRWc=,67e609a744e93b7ba05adee985d7e3471e6d414cea611ac73206e007a5e03082 +myitcv.io,v0.0.0-20190927111909-7837eed0ff8e,h1:aTqeLMcNZAhWxtvBgs0fbjTxg5BuNvHYnLo1lhSq9hE=,0d734b4e576c5c34dd9788481761864faef6cacdd735296d22f885b211fe9c70 +pack.ag/amqp,v0.11.2,h1:cuNDWLUTbKRtEZwhB0WQBXf9pGbm87pUBXQhvcFxBWg=,7cdc81d1aeef4ad24c4a49f6227aac060ee193587c95d48bfe4437beaf08310a +periph.io/x/periph,v3.6.2+incompatible,h1:B9vqhYVuhKtr6bXua8N9GeBEvD7yanczCvE0wU2LEqw=,aeb77a51a9e20e0414e7ea7c9a3a30302fcb5ffc5cf4dd41c3455ec0c3d7b1bc +perkeep.org,v0.0.0-20190926184543-d342b0e26632,h1:6ZKRr0VZtsfdHyYDJ/G9rCy7z8jGfrpmYANf0BR+vJM=,fd9e06dfc30d3bcb49399fd062094dfdf364a8344d409541896cb96d36465ade +rsc.io/binaryregexp,v0.2.0,h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=,b3e706aa278fa7f880d32fa1cc40ef8282d1fc7d6e00356579ed0db88f3b0047 +rsc.io/goversion,v1.2.0,h1:SPn+NLTiAG7w30IRK/DKp1BjvpWabYgxlLp/+kx5J8w=,f8426f6078b1d1b4e29a8c6223603680169c7c0a8789d2aee7e401a46ff6343f +rsc.io/pdf,v0.1.1,h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=,79bf310e399cf0e2d8aa61536750d2a6999c5ca884e7a27faf88d3701cd5ba8f +rsc.io/qr,v0.1.0,h1:M/sAxsU2J5mlQ4W84Bxga2EgdQqOaAliipcjPmMUM5Q=,fd09c124eb71d01dab3a0116eac47a6fce78f34bbdd84620b2dc01b90582b11c +sigs.k8s.io/cluster-api,v0.2.7,h1:WjhtuvyjnMgo62kKlVizhI/nYs4DJxHNf+ZMSk/uUsM=,1e3767e7d0f655b72a52eab40e122779ccd1f734c06b9c6488ea9615a3db7b24 +sigs.k8s.io/controller-runtime,v0.3.0,h1:ZtdgqJXVHsIytjdmDuk0QjagnzyLq9FjojXRqIp+dU4=,f37a21668e57315e7248169bec6d4a71f86bcf53d7528c9752e7b459ee74efe0 +sigs.k8s.io/kustomize,v2.0.3+incompatible,h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=,e0f6ad3aaaf7160abcb5e7b16f711c13aebe876833ae9e6ad6f858f31641bf62 +sigs.k8s.io/structured-merge-diff,v0.0.0-20191023203907-336d3378ca53,h1:WCMuuk4OLJ1WdEK3fx+hroiutCODdAGwDlL2Dj4mpa0=,b389a2eafcce0dcef4ca1052942980f26b62030da007b3a84a653de5c0f91668 +sigs.k8s.io/testing_frameworks,v0.1.2-0.20190130140139-57f07443c2d4,h1:GtDhkj3cF4A4IW+A9LScsuxvJqA9DE7G7PGH1f8B07U=,bfb65beb3dda386efc0c0ff9237a07877cec71922f4d3dc1f4a40d5fcaa090a9 +sigs.k8s.io/yaml,v1.1.0,h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=,a0d39252e8665a428a8cb9d4dfc9cbea07b7ae90ae62e7cf3651be719adf515a +sofastack.io/sofa-mosn,v0.0.0-20191101130505-becc7a6dc50c,h1:8IAozA6SkwfqCAF7fVyy8gu4FdyJvH5iBC12WhiocB8=,0ed9cc5b20e6233051bb4de2ffee5c7f3365704fe01d28e87237d9e8041a786d +sourcegraph.com/sourcegraph/appdash,v0.0.0-20190107175209-d9ea5c54f7dc,h1:lmf242UNy8ucQUSUse9oXtyxHb6kaF82XRLqeVDXXhA=,49e3fd73d6218c97f49266f0e32bbdab1b6352f2f40da8d1aa98ee8dfdeec072 +sourcegraph.com/sourcegraph/appdash-data,v0.0.0-20151005221446-73f23eafcf67,h1:e1sMhtVq9AfcEy8AXNb8eSg6gbzfdpYhoNqnPJa+GzI=,382adefecd62bb79172e2552bcfb7d45f47122f9bd22259b0566b26fb2627b87 +sourcegraph.com/sourcegraph/go-diff,v0.5.0,h1:eTiIR0CoWjGzJcnQ3OkhIl/b9GJovq4lSAVRt0ZFEG8=,2c5eaad1d3743b3d4bd6de70459a413e62d1753673d5b96402dda27508454b3b +sourcegraph.com/sqs/pbtypes,v0.0.0-20180604144634-d3ebe8f20ae4,h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c=,6750f8618ecbde1668de332800ec01d713debb145dee395c23fc9a373c207fe3 +storj.io/drpc,v0.0.7-0.20191021224058-08e7133752cd,h1:Oh7Nww1cgFA3fhrCOheDwQ0VcUKFcO1LsBSJEgiGgUQ=,51befd9e6e3aa6cfb9f5b56e47b3cd59715dbe656d0a12cfbb0282609b5456dd +storj.io/storj,v0.24.5,h1:dWqApMsdhPoUufrljPQC1gZWkYcSTjRr5AoZ7mrSjCw=,ce0628bdcce2b8f0241d27993431d343d212b2e55323510bf657928001c2fb26 +strk.kbt.io/projects/go/libravatar,v0.0.0-20160628055650-5eed7bff870a,h1:8q33ShxKXRwQ7JVd1ZnhIU3hZhwwn0Le+4fTeAackuM=,be48b3949775d6ba0dd3105d7d31d338fede9fbd1471b41fe861f1cfcabbf85c +v.io/x/lib,v0.1.4,h1:PCDfluqBeRbA7OgDIs9tIpT+z6ZNZ5VMeR+t7h/K2ig=,411c5ded56ba1b69269c37748d184954089c320f43ee76beb0c53f7c598baeaf +vbom.ml/util,v0.0.0-20180919145318-efcd4e0f9787,h1:O69FD9pJA4WUZlEwYatBEEkRWKQ5cKodWpdKTrCS/iQ=,abbc7a9ac1d820f336ccbe247404800d0f79859b4e4412f0d107aebbb564f920 +vitess.io/vitess,v2.1.1+incompatible,h1:nuuGHiWYWpudD3gOCLeGzol2EJ25e/u5Wer2wV1O130=,8f823ede6775b4f5b3f6cd4c04b3b6be453416e124362a8d68fa2e829429fa68 +xorm.io/builder,v0.3.6,h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8=,8f16bb96bf2f75b4813be77072a966d1f2248a38f2c7afff4132b666876310a7 +xorm.io/core,v0.7.2,h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=,24c93962a78b2a177ff5c66cd43921eb1e8b13290d0e8a4d87c6f075a81c4531 diff --git a/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go new file mode 100644 index 00000000000..331d634d102 --- /dev/null +++ b/libgo/go/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go @@ -0,0 +1,230 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package zip_sum_test tests that the module zip files produced by modfetch +// have consistent content sums. Ideally the zip files themselves are also +// stable over time, though this is not strictly necessary. +// +// This test loads a table from testdata/zip_sums.csv. The table has columns +// for module path, version, content sum, and zip file hash. The table +// includes a large number of real modules. The test downloads these modules +// in direct mode and verifies the zip files. +// +// This test is very slow, and it depends on outside modules that change +// frequently, so this is a manual test. To enable it, pass the -zipsum flag. +package zip_sum_test + +import ( + "crypto/sha256" + "encoding/csv" + "encoding/hex" + "flag" + "fmt" + "internal/testenv" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "testing" + + "cmd/go/internal/cfg" + "cmd/go/internal/modfetch" + "cmd/go/internal/modload" + + "golang.org/x/mod/module" +) + +var ( + updateTestData = flag.Bool("u", false, "when set, tests may update files in testdata instead of failing") + enableZipSum = flag.Bool("zipsum", false, "enable TestZipSums") + debugZipSum = flag.Bool("testwork", false, "when set, TestZipSums will preserve its test directory") + modCacheDir = flag.String("zipsumcache", "", "module cache to use instead of temp directory") + shardCount = flag.Int("zipsumshardcount", 1, "number of shards to divide TestZipSums into") + shardIndex = flag.Int("zipsumshard", 0, "index of TestZipSums shard to test (0 <= zipsumshard < zipsumshardcount)") +) + +const zipSumsPath = "testdata/zip_sums.csv" + +type zipSumTest struct { + m module.Version + wantSum, wantFileHash string +} + +func TestZipSums(t *testing.T) { + if !*enableZipSum { + // This test is very slow and heavily dependent on external repositories. + // Only run it explicitly. + t.Skip("TestZipSum not enabled with -zipsum") + } + if *shardCount < 1 { + t.Fatal("-zipsumshardcount must be a positive integer") + } + if *shardIndex < 0 || *shardCount <= *shardIndex { + t.Fatal("-zipsumshard must be between 0 and -zipsumshardcount") + } + + testenv.MustHaveGoBuild(t) + testenv.MustHaveExternalNetwork(t) + testenv.MustHaveExecPath(t, "bzr") + testenv.MustHaveExecPath(t, "git") + // TODO(jayconrod): add hg, svn, and fossil modules to testdata. + // Could not find any for now. + + tests, err := readZipSumTests() + if err != nil { + t.Fatal(err) + } + + if *modCacheDir != "" { + cfg.BuildContext.GOPATH = *modCacheDir + } else { + tmpDir, err := ioutil.TempDir("", "TestZipSums") + if err != nil { + t.Fatal(err) + } + if *debugZipSum { + fmt.Fprintf(os.Stderr, "TestZipSums: modCacheDir: %s\n", tmpDir) + } else { + defer os.RemoveAll(tmpDir) + } + cfg.BuildContext.GOPATH = tmpDir + } + + cfg.GOPROXY = "direct" + cfg.GOSUMDB = "off" + modload.Init() + + // Shard tests by downloading only every nth module when shard flags are set. + // This makes it easier to test small groups of modules quickly. We avoid + // testing similarly named modules together (the list is sorted by module + // path and version). + if *shardCount > 1 { + r := *shardIndex + w := 0 + for r < len(tests) { + tests[w] = tests[r] + w++ + r += *shardCount + } + tests = tests[:w] + } + + // Download modules with a rate limit. We may run out of file descriptors + // or cause timeouts without a limit. + needUpdate := false + for i := range tests { + test := &tests[i] + name := fmt.Sprintf("%s@%s", strings.ReplaceAll(test.m.Path, "/", "_"), test.m.Version) + t.Run(name, func(t *testing.T) { + t.Parallel() + zipPath, err := modfetch.DownloadZip(test.m) + if err != nil { + if *updateTestData { + t.Logf("%s: could not download module: %s (will remove from testdata)", test.m, err) + test.m.Path = "" // mark for deletion + needUpdate = true + } else { + t.Errorf("%s: could not download mdoule: %s", test.m, err) + } + return + } + + sum := modfetch.Sum(test.m) + if sum != test.wantSum { + if *updateTestData { + t.Logf("%s: updating content sum to %s", test.m, sum) + test.wantSum = sum + needUpdate = true + } else { + t.Errorf("%s: got content sum %s; want sum %s", test.m, sum, test.wantSum) + return + } + } + + h := sha256.New() + f, err := os.Open(zipPath) + if err != nil { + t.Errorf("%s: %v", test.m, err) + } + defer f.Close() + if _, err := io.Copy(h, f); err != nil { + t.Errorf("%s: %v", test.m, err) + } + zipHash := hex.EncodeToString(h.Sum(nil)) + if zipHash != test.wantFileHash { + if *updateTestData { + t.Logf("%s: updating zip file hash to %s", test.m, zipHash) + test.wantFileHash = zipHash + needUpdate = true + } else { + t.Errorf("%s: got zip file hash %s; want hash %s (but content sum matches)", test.m, zipHash, test.wantFileHash) + } + } + }) + } + + if needUpdate { + // Remove tests marked for deletion + r, w := 0, 0 + for r < len(tests) { + if tests[r].m.Path != "" { + tests[w] = tests[r] + w++ + } + r++ + } + tests = tests[:w] + + if err := writeZipSumTests(tests); err != nil { + t.Error(err) + } + } +} + +func readZipSumTests() ([]zipSumTest, error) { + f, err := os.Open(filepath.FromSlash(zipSumsPath)) + if err != nil { + return nil, err + } + defer f.Close() + r := csv.NewReader(f) + + var tests []zipSumTest + for { + line, err := r.Read() + if err == io.EOF { + break + } else if err != nil { + return nil, err + } else if len(line) != 4 { + return nil, fmt.Errorf("%s:%d: malformed line", f.Name(), len(tests)+1) + } + test := zipSumTest{m: module.Version{Path: line[0], Version: line[1]}, wantSum: line[2], wantFileHash: line[3]} + tests = append(tests, test) + } + return tests, nil +} + +func writeZipSumTests(tests []zipSumTest) (err error) { + f, err := os.Create(filepath.FromSlash(zipSumsPath)) + if err != nil { + return err + } + defer func() { + if cerr := f.Close(); err == nil && cerr != nil { + err = cerr + } + }() + w := csv.NewWriter(f) + line := make([]string, 0, 4) + for _, test := range tests { + line = append(line[:0], test.m.Path, test.m.Version, test.wantSum, test.wantFileHash) + if err := w.Write(line); err != nil { + return err + } + } + w.Flush() + return nil +} diff --git a/libgo/go/cmd/go/internal/modfile/gopkgin.go b/libgo/go/cmd/go/internal/modfile/gopkgin.go deleted file mode 100644 index c94b3848a0e..00000000000 --- a/libgo/go/cmd/go/internal/modfile/gopkgin.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// TODO: Figure out what gopkg.in should do. - -package modfile - -import "strings" - -// ParseGopkgIn splits gopkg.in import paths into their constituent parts -func ParseGopkgIn(path string) (root, repo, major, subdir string, ok bool) { - if !strings.HasPrefix(path, "gopkg.in/") { - return - } - f := strings.Split(path, "/") - if len(f) >= 2 { - if elem, v, ok := dotV(f[1]); ok { - root = strings.Join(f[:2], "/") - repo = "github.com/go-" + elem + "/" + elem - major = v - subdir = strings.Join(f[2:], "/") - return root, repo, major, subdir, true - } - } - if len(f) >= 3 { - if elem, v, ok := dotV(f[2]); ok { - root = strings.Join(f[:3], "/") - repo = "github.com/" + f[1] + "/" + elem - major = v - subdir = strings.Join(f[3:], "/") - return root, repo, major, subdir, true - } - } - return -} - -func dotV(name string) (elem, v string, ok bool) { - i := len(name) - 1 - for i >= 0 && '0' <= name[i] && name[i] <= '9' { - i-- - } - if i <= 2 || i+1 >= len(name) || name[i-1] != '.' || name[i] != 'v' || name[i+1] == '0' && len(name) != i+2 { - return "", "", false - } - return name[:i-1], name[i:], true -} diff --git a/libgo/go/cmd/go/internal/modfile/print.go b/libgo/go/cmd/go/internal/modfile/print.go deleted file mode 100644 index cefc43b141c..00000000000 --- a/libgo/go/cmd/go/internal/modfile/print.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Module file printer. - -package modfile - -import ( - "bytes" - "fmt" - "strings" -) - -func Format(f *FileSyntax) []byte { - pr := &printer{} - pr.file(f) - return pr.Bytes() -} - -// A printer collects the state during printing of a file or expression. -type printer struct { - bytes.Buffer // output buffer - comment []Comment // pending end-of-line comments - margin int // left margin (indent), a number of tabs -} - -// printf prints to the buffer. -func (p *printer) printf(format string, args ...interface{}) { - fmt.Fprintf(p, format, args...) -} - -// indent returns the position on the current line, in bytes, 0-indexed. -func (p *printer) indent() int { - b := p.Bytes() - n := 0 - for n < len(b) && b[len(b)-1-n] != '\n' { - n++ - } - return n -} - -// newline ends the current line, flushing end-of-line comments. -func (p *printer) newline() { - if len(p.comment) > 0 { - p.printf(" ") - for i, com := range p.comment { - if i > 0 { - p.trim() - p.printf("\n") - for i := 0; i < p.margin; i++ { - p.printf("\t") - } - } - p.printf("%s", strings.TrimSpace(com.Token)) - } - p.comment = p.comment[:0] - } - - p.trim() - p.printf("\n") - for i := 0; i < p.margin; i++ { - p.printf("\t") - } -} - -// trim removes trailing spaces and tabs from the current line. -func (p *printer) trim() { - // Remove trailing spaces and tabs from line we're about to end. - b := p.Bytes() - n := len(b) - for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') { - n-- - } - p.Truncate(n) -} - -// file formats the given file into the print buffer. -func (p *printer) file(f *FileSyntax) { - for _, com := range f.Before { - p.printf("%s", strings.TrimSpace(com.Token)) - p.newline() - } - - for i, stmt := range f.Stmt { - switch x := stmt.(type) { - case *CommentBlock: - // comments already handled - p.expr(x) - - default: - p.expr(x) - p.newline() - } - - for _, com := range stmt.Comment().After { - p.printf("%s", strings.TrimSpace(com.Token)) - p.newline() - } - - if i+1 < len(f.Stmt) { - p.newline() - } - } -} - -func (p *printer) expr(x Expr) { - // Emit line-comments preceding this expression. - if before := x.Comment().Before; len(before) > 0 { - // Want to print a line comment. - // Line comments must be at the current margin. - p.trim() - if p.indent() > 0 { - // There's other text on the line. Start a new line. - p.printf("\n") - } - // Re-indent to margin. - for i := 0; i < p.margin; i++ { - p.printf("\t") - } - for _, com := range before { - p.printf("%s", strings.TrimSpace(com.Token)) - p.newline() - } - } - - switch x := x.(type) { - default: - panic(fmt.Errorf("printer: unexpected type %T", x)) - - case *CommentBlock: - // done - - case *LParen: - p.printf("(") - case *RParen: - p.printf(")") - - case *Line: - sep := "" - for _, tok := range x.Token { - p.printf("%s%s", sep, tok) - sep = " " - } - - case *LineBlock: - for _, tok := range x.Token { - p.printf("%s ", tok) - } - p.expr(&x.LParen) - p.margin++ - for _, l := range x.Line { - p.newline() - p.expr(l) - } - p.margin-- - p.newline() - p.expr(&x.RParen) - } - - // Queue end-of-line comments for printing when we - // reach the end of the line. - p.comment = append(p.comment, x.Comment().Suffix...) -} diff --git a/libgo/go/cmd/go/internal/modfile/read.go b/libgo/go/cmd/go/internal/modfile/read.go deleted file mode 100644 index 1d81ff1ab7a..00000000000 --- a/libgo/go/cmd/go/internal/modfile/read.go +++ /dev/null @@ -1,869 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Module file parser. -// This is a simplified copy of Google's buildifier parser. - -package modfile - -import ( - "bytes" - "fmt" - "os" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -// A Position describes the position between two bytes of input. -type Position struct { - Line int // line in input (starting at 1) - LineRune int // rune in line (starting at 1) - Byte int // byte in input (starting at 0) -} - -// add returns the position at the end of s, assuming it starts at p. -func (p Position) add(s string) Position { - p.Byte += len(s) - if n := strings.Count(s, "\n"); n > 0 { - p.Line += n - s = s[strings.LastIndex(s, "\n")+1:] - p.LineRune = 1 - } - p.LineRune += utf8.RuneCountInString(s) - return p -} - -// An Expr represents an input element. -type Expr interface { - // Span returns the start and end position of the expression, - // excluding leading or trailing comments. - Span() (start, end Position) - - // Comment returns the comments attached to the expression. - // This method would normally be named 'Comments' but that - // would interfere with embedding a type of the same name. - Comment() *Comments -} - -// A Comment represents a single // comment. -type Comment struct { - Start Position - Token string // without trailing newline - Suffix bool // an end of line (not whole line) comment -} - -// Comments collects the comments associated with an expression. -type Comments struct { - Before []Comment // whole-line comments before this expression - Suffix []Comment // end-of-line comments after this expression - - // For top-level expressions only, After lists whole-line - // comments following the expression. - After []Comment -} - -// Comment returns the receiver. This isn't useful by itself, but -// a Comments struct is embedded into all the expression -// implementation types, and this gives each of those a Comment -// method to satisfy the Expr interface. -func (c *Comments) Comment() *Comments { - return c -} - -// A FileSyntax represents an entire go.mod file. -type FileSyntax struct { - Name string // file path - Comments - Stmt []Expr -} - -func (x *FileSyntax) Span() (start, end Position) { - if len(x.Stmt) == 0 { - return - } - start, _ = x.Stmt[0].Span() - _, end = x.Stmt[len(x.Stmt)-1].Span() - return start, end -} - -func (x *FileSyntax) addLine(hint Expr, tokens ...string) *Line { - if hint == nil { - // If no hint given, add to the last statement of the given type. - Loop: - for i := len(x.Stmt) - 1; i >= 0; i-- { - stmt := x.Stmt[i] - switch stmt := stmt.(type) { - case *Line: - if stmt.Token != nil && stmt.Token[0] == tokens[0] { - hint = stmt - break Loop - } - case *LineBlock: - if stmt.Token[0] == tokens[0] { - hint = stmt - break Loop - } - } - } - } - - if hint != nil { - for i, stmt := range x.Stmt { - switch stmt := stmt.(type) { - case *Line: - if stmt == hint { - // Convert line to line block. - stmt.InBlock = true - block := &LineBlock{Token: stmt.Token[:1], Line: []*Line{stmt}} - stmt.Token = stmt.Token[1:] - x.Stmt[i] = block - new := &Line{Token: tokens[1:], InBlock: true} - block.Line = append(block.Line, new) - return new - } - case *LineBlock: - if stmt == hint { - new := &Line{Token: tokens[1:], InBlock: true} - stmt.Line = append(stmt.Line, new) - return new - } - for j, line := range stmt.Line { - if line == hint { - // Add new line after hint. - stmt.Line = append(stmt.Line, nil) - copy(stmt.Line[j+2:], stmt.Line[j+1:]) - new := &Line{Token: tokens[1:], InBlock: true} - stmt.Line[j+1] = new - return new - } - } - } - } - } - - new := &Line{Token: tokens} - x.Stmt = append(x.Stmt, new) - return new -} - -func (x *FileSyntax) updateLine(line *Line, tokens ...string) { - if line.InBlock { - tokens = tokens[1:] - } - line.Token = tokens -} - -func (x *FileSyntax) removeLine(line *Line) { - line.Token = nil -} - -// Cleanup cleans up the file syntax x after any edit operations. -// To avoid quadratic behavior, removeLine marks the line as dead -// by setting line.Token = nil but does not remove it from the slice -// in which it appears. After edits have all been indicated, -// calling Cleanup cleans out the dead lines. -func (x *FileSyntax) Cleanup() { - w := 0 - for _, stmt := range x.Stmt { - switch stmt := stmt.(type) { - case *Line: - if stmt.Token == nil { - continue - } - case *LineBlock: - ww := 0 - for _, line := range stmt.Line { - if line.Token != nil { - stmt.Line[ww] = line - ww++ - } - } - if ww == 0 { - continue - } - if ww == 1 { - // Collapse block into single line. - line := &Line{ - Comments: Comments{ - Before: commentsAdd(stmt.Before, stmt.Line[0].Before), - Suffix: commentsAdd(stmt.Line[0].Suffix, stmt.Suffix), - After: commentsAdd(stmt.Line[0].After, stmt.After), - }, - Token: stringsAdd(stmt.Token, stmt.Line[0].Token), - } - x.Stmt[w] = line - w++ - continue - } - stmt.Line = stmt.Line[:ww] - } - x.Stmt[w] = stmt - w++ - } - x.Stmt = x.Stmt[:w] -} - -func commentsAdd(x, y []Comment) []Comment { - return append(x[:len(x):len(x)], y...) -} - -func stringsAdd(x, y []string) []string { - return append(x[:len(x):len(x)], y...) -} - -// A CommentBlock represents a top-level block of comments separate -// from any rule. -type CommentBlock struct { - Comments - Start Position -} - -func (x *CommentBlock) Span() (start, end Position) { - return x.Start, x.Start -} - -// A Line is a single line of tokens. -type Line struct { - Comments - Start Position - Token []string - InBlock bool - End Position -} - -func (x *Line) Span() (start, end Position) { - return x.Start, x.End -} - -// A LineBlock is a factored block of lines, like -// -// require ( -// "x" -// "y" -// ) -// -type LineBlock struct { - Comments - Start Position - LParen LParen - Token []string - Line []*Line - RParen RParen -} - -func (x *LineBlock) Span() (start, end Position) { - return x.Start, x.RParen.Pos.add(")") -} - -// An LParen represents the beginning of a parenthesized line block. -// It is a place to store suffix comments. -type LParen struct { - Comments - Pos Position -} - -func (x *LParen) Span() (start, end Position) { - return x.Pos, x.Pos.add(")") -} - -// An RParen represents the end of a parenthesized line block. -// It is a place to store whole-line (before) comments. -type RParen struct { - Comments - Pos Position -} - -func (x *RParen) Span() (start, end Position) { - return x.Pos, x.Pos.add(")") -} - -// An input represents a single input file being parsed. -type input struct { - // Lexing state. - filename string // name of input file, for errors - complete []byte // entire input - remaining []byte // remaining input - token []byte // token being scanned - lastToken string // most recently returned token, for error messages - pos Position // current input position - comments []Comment // accumulated comments - endRule int // position of end of current rule - - // Parser state. - file *FileSyntax // returned top-level syntax tree - parseError error // error encountered during parsing - - // Comment assignment state. - pre []Expr // all expressions, in preorder traversal - post []Expr // all expressions, in postorder traversal -} - -func newInput(filename string, data []byte) *input { - return &input{ - filename: filename, - complete: data, - remaining: data, - pos: Position{Line: 1, LineRune: 1, Byte: 0}, - } -} - -// parse parses the input file. -func parse(file string, data []byte) (f *FileSyntax, err error) { - in := newInput(file, data) - // The parser panics for both routine errors like syntax errors - // and for programmer bugs like array index errors. - // Turn both into error returns. Catching bug panics is - // especially important when processing many files. - defer func() { - if e := recover(); e != nil { - if e == in.parseError { - err = in.parseError - } else { - err = fmt.Errorf("%s:%d:%d: internal error: %v", in.filename, in.pos.Line, in.pos.LineRune, e) - } - } - }() - - // Invoke the parser. - in.parseFile() - if in.parseError != nil { - return nil, in.parseError - } - in.file.Name = in.filename - - // Assign comments to nearby syntax. - in.assignComments() - - return in.file, nil -} - -// Error is called to report an error. -// The reason s is often "syntax error". -// Error does not return: it panics. -func (in *input) Error(s string) { - if s == "syntax error" && in.lastToken != "" { - s += " near " + in.lastToken - } - in.parseError = fmt.Errorf("%s:%d:%d: %v", in.filename, in.pos.Line, in.pos.LineRune, s) - panic(in.parseError) -} - -// eof reports whether the input has reached end of file. -func (in *input) eof() bool { - return len(in.remaining) == 0 -} - -// peekRune returns the next rune in the input without consuming it. -func (in *input) peekRune() int { - if len(in.remaining) == 0 { - return 0 - } - r, _ := utf8.DecodeRune(in.remaining) - return int(r) -} - -// peekPrefix reports whether the remaining input begins with the given prefix. -func (in *input) peekPrefix(prefix string) bool { - // This is like bytes.HasPrefix(in.remaining, []byte(prefix)) - // but without the allocation of the []byte copy of prefix. - for i := 0; i < len(prefix); i++ { - if i >= len(in.remaining) || in.remaining[i] != prefix[i] { - return false - } - } - return true -} - -// readRune consumes and returns the next rune in the input. -func (in *input) readRune() int { - if len(in.remaining) == 0 { - in.Error("internal lexer error: readRune at EOF") - } - r, size := utf8.DecodeRune(in.remaining) - in.remaining = in.remaining[size:] - if r == '\n' { - in.pos.Line++ - in.pos.LineRune = 1 - } else { - in.pos.LineRune++ - } - in.pos.Byte += size - return int(r) -} - -type symType struct { - pos Position - endPos Position - text string -} - -// startToken marks the beginning of the next input token. -// It must be followed by a call to endToken, once the token has -// been consumed using readRune. -func (in *input) startToken(sym *symType) { - in.token = in.remaining - sym.text = "" - sym.pos = in.pos -} - -// endToken marks the end of an input token. -// It records the actual token string in sym.text if the caller -// has not done that already. -func (in *input) endToken(sym *symType) { - if sym.text == "" { - tok := string(in.token[:len(in.token)-len(in.remaining)]) - sym.text = tok - in.lastToken = sym.text - } - sym.endPos = in.pos -} - -// lex is called from the parser to obtain the next input token. -// It returns the token value (either a rune like '+' or a symbolic token _FOR) -// and sets val to the data associated with the token. -// For all our input tokens, the associated data is -// val.Pos (the position where the token begins) -// and val.Token (the input string corresponding to the token). -func (in *input) lex(sym *symType) int { - // Skip past spaces, stopping at non-space or EOF. - countNL := 0 // number of newlines we've skipped past - for !in.eof() { - // Skip over spaces. Count newlines so we can give the parser - // information about where top-level blank lines are, - // for top-level comment assignment. - c := in.peekRune() - if c == ' ' || c == '\t' || c == '\r' { - in.readRune() - continue - } - - // Comment runs to end of line. - if in.peekPrefix("//") { - in.startToken(sym) - - // Is this comment the only thing on its line? - // Find the last \n before this // and see if it's all - // spaces from there to here. - i := bytes.LastIndex(in.complete[:in.pos.Byte], []byte("\n")) - suffix := len(bytes.TrimSpace(in.complete[i+1:in.pos.Byte])) > 0 - in.readRune() - in.readRune() - - // Consume comment. - for len(in.remaining) > 0 && in.readRune() != '\n' { - } - in.endToken(sym) - - sym.text = strings.TrimRight(sym.text, "\n") - in.lastToken = "comment" - - // If we are at top level (not in a statement), hand the comment to - // the parser as a _COMMENT token. The grammar is written - // to handle top-level comments itself. - if !suffix { - // Not in a statement. Tell parser about top-level comment. - return _COMMENT - } - - // Otherwise, save comment for later attachment to syntax tree. - if countNL > 1 { - in.comments = append(in.comments, Comment{sym.pos, "", false}) - } - in.comments = append(in.comments, Comment{sym.pos, sym.text, suffix}) - countNL = 1 - return _EOL - } - - if in.peekPrefix("/*") { - in.Error(fmt.Sprintf("mod files must use // comments (not /* */ comments)")) - } - - // Found non-space non-comment. - break - } - - // Found the beginning of the next token. - in.startToken(sym) - defer in.endToken(sym) - - // End of file. - if in.eof() { - in.lastToken = "EOF" - return _EOF - } - - // Punctuation tokens. - switch c := in.peekRune(); c { - case '\n': - in.readRune() - return c - - case '(': - in.readRune() - return c - - case ')': - in.readRune() - return c - - case '"', '`': // quoted string - quote := c - in.readRune() - for { - if in.eof() { - in.pos = sym.pos - in.Error("unexpected EOF in string") - } - if in.peekRune() == '\n' { - in.Error("unexpected newline in string") - } - c := in.readRune() - if c == quote { - break - } - if c == '\\' && quote != '`' { - if in.eof() { - in.pos = sym.pos - in.Error("unexpected EOF in string") - } - in.readRune() - } - } - in.endToken(sym) - return _STRING - } - - // Checked all punctuation. Must be identifier token. - if c := in.peekRune(); !isIdent(c) { - in.Error(fmt.Sprintf("unexpected input character %#q", c)) - } - - // Scan over identifier. - for isIdent(in.peekRune()) { - if in.peekPrefix("//") { - break - } - if in.peekPrefix("/*") { - in.Error(fmt.Sprintf("mod files must use // comments (not /* */ comments)")) - } - in.readRune() - } - return _IDENT -} - -// isIdent reports whether c is an identifier rune. -// We treat nearly all runes as identifier runes. -func isIdent(c int) bool { - return c != 0 && !unicode.IsSpace(rune(c)) -} - -// Comment assignment. -// We build two lists of all subexpressions, preorder and postorder. -// The preorder list is ordered by start location, with outer expressions first. -// The postorder list is ordered by end location, with outer expressions last. -// We use the preorder list to assign each whole-line comment to the syntax -// immediately following it, and we use the postorder list to assign each -// end-of-line comment to the syntax immediately preceding it. - -// order walks the expression adding it and its subexpressions to the -// preorder and postorder lists. -func (in *input) order(x Expr) { - if x != nil { - in.pre = append(in.pre, x) - } - switch x := x.(type) { - default: - panic(fmt.Errorf("order: unexpected type %T", x)) - case nil: - // nothing - case *LParen, *RParen: - // nothing - case *CommentBlock: - // nothing - case *Line: - // nothing - case *FileSyntax: - for _, stmt := range x.Stmt { - in.order(stmt) - } - case *LineBlock: - in.order(&x.LParen) - for _, l := range x.Line { - in.order(l) - } - in.order(&x.RParen) - } - if x != nil { - in.post = append(in.post, x) - } -} - -// assignComments attaches comments to nearby syntax. -func (in *input) assignComments() { - const debug = false - - // Generate preorder and postorder lists. - in.order(in.file) - - // Split into whole-line comments and suffix comments. - var line, suffix []Comment - for _, com := range in.comments { - if com.Suffix { - suffix = append(suffix, com) - } else { - line = append(line, com) - } - } - - if debug { - for _, c := range line { - fmt.Fprintf(os.Stderr, "LINE %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte) - } - } - - // Assign line comments to syntax immediately following. - for _, x := range in.pre { - start, _ := x.Span() - if debug { - fmt.Printf("pre %T :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte) - } - xcom := x.Comment() - for len(line) > 0 && start.Byte >= line[0].Start.Byte { - if debug { - fmt.Fprintf(os.Stderr, "ASSIGN LINE %q #%d\n", line[0].Token, line[0].Start.Byte) - } - xcom.Before = append(xcom.Before, line[0]) - line = line[1:] - } - } - - // Remaining line comments go at end of file. - in.file.After = append(in.file.After, line...) - - if debug { - for _, c := range suffix { - fmt.Fprintf(os.Stderr, "SUFFIX %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte) - } - } - - // Assign suffix comments to syntax immediately before. - for i := len(in.post) - 1; i >= 0; i-- { - x := in.post[i] - - start, end := x.Span() - if debug { - fmt.Printf("post %T :%d:%d #%d :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte, end.Line, end.LineRune, end.Byte) - } - - // Do not assign suffix comments to end of line block or whole file. - // Instead assign them to the last element inside. - switch x.(type) { - case *FileSyntax: - continue - } - - // Do not assign suffix comments to something that starts - // on an earlier line, so that in - // - // x ( y - // z ) // comment - // - // we assign the comment to z and not to x ( ... ). - if start.Line != end.Line { - continue - } - xcom := x.Comment() - for len(suffix) > 0 && end.Byte <= suffix[len(suffix)-1].Start.Byte { - if debug { - fmt.Fprintf(os.Stderr, "ASSIGN SUFFIX %q #%d\n", suffix[len(suffix)-1].Token, suffix[len(suffix)-1].Start.Byte) - } - xcom.Suffix = append(xcom.Suffix, suffix[len(suffix)-1]) - suffix = suffix[:len(suffix)-1] - } - } - - // We assigned suffix comments in reverse. - // If multiple suffix comments were appended to the same - // expression node, they are now in reverse. Fix that. - for _, x := range in.post { - reverseComments(x.Comment().Suffix) - } - - // Remaining suffix comments go at beginning of file. - in.file.Before = append(in.file.Before, suffix...) -} - -// reverseComments reverses the []Comment list. -func reverseComments(list []Comment) { - for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 { - list[i], list[j] = list[j], list[i] - } -} - -func (in *input) parseFile() { - in.file = new(FileSyntax) - var sym symType - var cb *CommentBlock - for { - tok := in.lex(&sym) - switch tok { - case '\n': - if cb != nil { - in.file.Stmt = append(in.file.Stmt, cb) - cb = nil - } - case _COMMENT: - if cb == nil { - cb = &CommentBlock{Start: sym.pos} - } - com := cb.Comment() - com.Before = append(com.Before, Comment{Start: sym.pos, Token: sym.text}) - case _EOF: - if cb != nil { - in.file.Stmt = append(in.file.Stmt, cb) - } - return - default: - in.parseStmt(&sym) - if cb != nil { - in.file.Stmt[len(in.file.Stmt)-1].Comment().Before = cb.Before - cb = nil - } - } - } -} - -func (in *input) parseStmt(sym *symType) { - start := sym.pos - end := sym.endPos - token := []string{sym.text} - for { - tok := in.lex(sym) - switch tok { - case '\n', _EOF, _EOL: - in.file.Stmt = append(in.file.Stmt, &Line{ - Start: start, - Token: token, - End: end, - }) - return - case '(': - in.file.Stmt = append(in.file.Stmt, in.parseLineBlock(start, token, sym)) - return - default: - token = append(token, sym.text) - end = sym.endPos - } - } -} - -func (in *input) parseLineBlock(start Position, token []string, sym *symType) *LineBlock { - x := &LineBlock{ - Start: start, - Token: token, - LParen: LParen{Pos: sym.pos}, - } - var comments []Comment - for { - tok := in.lex(sym) - switch tok { - case _EOL: - // ignore - case '\n': - if len(comments) == 0 && len(x.Line) > 0 || len(comments) > 0 && comments[len(comments)-1].Token != "" { - comments = append(comments, Comment{}) - } - case _COMMENT: - comments = append(comments, Comment{Start: sym.pos, Token: sym.text}) - case _EOF: - in.Error(fmt.Sprintf("syntax error (unterminated block started at %s:%d:%d)", in.filename, x.Start.Line, x.Start.LineRune)) - case ')': - x.RParen.Before = comments - x.RParen.Pos = sym.pos - tok = in.lex(sym) - if tok != '\n' && tok != _EOF && tok != _EOL { - in.Error("syntax error (expected newline after closing paren)") - } - return x - default: - l := in.parseLine(sym) - x.Line = append(x.Line, l) - l.Comment().Before = comments - comments = nil - } - } -} - -func (in *input) parseLine(sym *symType) *Line { - start := sym.pos - end := sym.endPos - token := []string{sym.text} - for { - tok := in.lex(sym) - switch tok { - case '\n', _EOF, _EOL: - return &Line{ - Start: start, - Token: token, - End: end, - InBlock: true, - } - default: - token = append(token, sym.text) - end = sym.endPos - } - } -} - -const ( - _EOF = -(1 + iota) - _EOL - _IDENT - _STRING - _COMMENT -) - -var ( - slashSlash = []byte("//") - moduleStr = []byte("module") -) - -// ModulePath returns the module path from the gomod file text. -// If it cannot find a module path, it returns an empty string. -// It is tolerant of unrelated problems in the go.mod file. -func ModulePath(mod []byte) string { - for len(mod) > 0 { - line := mod - mod = nil - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, mod = line[:i], line[i+1:] - } - if i := bytes.Index(line, slashSlash); i >= 0 { - line = line[:i] - } - line = bytes.TrimSpace(line) - if !bytes.HasPrefix(line, moduleStr) { - continue - } - line = line[len(moduleStr):] - n := len(line) - line = bytes.TrimSpace(line) - if len(line) == n || len(line) == 0 { - continue - } - - if line[0] == '"' || line[0] == '`' { - p, err := strconv.Unquote(string(line)) - if err != nil { - return "" // malformed quoted string or multiline module path - } - return p - } - - return string(line) - } - return "" // missing module path -} diff --git a/libgo/go/cmd/go/internal/modfile/read_test.go b/libgo/go/cmd/go/internal/modfile/read_test.go deleted file mode 100644 index 8cb1a3908c5..00000000000 --- a/libgo/go/cmd/go/internal/modfile/read_test.go +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package modfile - -import ( - "bytes" - "fmt" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "reflect" - "strings" - "testing" -) - -// exists reports whether the named file exists. -func exists(name string) bool { - _, err := os.Stat(name) - return err == nil -} - -// Test that reading and then writing the golden files -// does not change their output. -func TestPrintGolden(t *testing.T) { - outs, err := filepath.Glob("testdata/*.golden") - if err != nil { - t.Fatal(err) - } - for _, out := range outs { - testPrint(t, out, out) - } -} - -// testPrint is a helper for testing the printer. -// It reads the file named in, reformats it, and compares -// the result to the file named out. -func testPrint(t *testing.T, in, out string) { - data, err := ioutil.ReadFile(in) - if err != nil { - t.Error(err) - return - } - - golden, err := ioutil.ReadFile(out) - if err != nil { - t.Error(err) - return - } - - base := "testdata/" + filepath.Base(in) - f, err := parse(in, data) - if err != nil { - t.Error(err) - return - } - - ndata := Format(f) - - if !bytes.Equal(ndata, golden) { - t.Errorf("formatted %s incorrectly: diff shows -golden, +ours", base) - tdiff(t, string(golden), string(ndata)) - return - } -} - -func TestParseLax(t *testing.T) { - badFile := []byte(`module m - surprise attack - x y ( - z - ) - exclude v1.2.3 - replace <-!!! - `) - _, err := ParseLax("file", badFile, nil) - if err != nil { - t.Fatalf("ParseLax did not ignore irrelevant errors: %v", err) - } -} - -// Test that when files in the testdata directory are parsed -// and printed and parsed again, we get the same parse tree -// both times. -func TestPrintParse(t *testing.T) { - outs, err := filepath.Glob("testdata/*") - if err != nil { - t.Fatal(err) - } - for _, out := range outs { - data, err := ioutil.ReadFile(out) - if err != nil { - t.Error(err) - continue - } - - base := "testdata/" + filepath.Base(out) - f, err := parse(base, data) - if err != nil { - t.Errorf("parsing original: %v", err) - continue - } - - ndata := Format(f) - f2, err := parse(base, ndata) - if err != nil { - t.Errorf("parsing reformatted: %v", err) - continue - } - - eq := eqchecker{file: base} - if err := eq.check(f, f2); err != nil { - t.Errorf("not equal (parse/Format/parse): %v", err) - } - - pf1, err := Parse(base, data, nil) - if err != nil { - switch base { - case "testdata/replace2.in", "testdata/gopkg.in.golden": - t.Errorf("should parse %v: %v", base, err) - } - } - if err == nil { - pf2, err := Parse(base, ndata, nil) - if err != nil { - t.Errorf("Parsing reformatted: %v", err) - continue - } - eq := eqchecker{file: base} - if err := eq.check(pf1, pf2); err != nil { - t.Errorf("not equal (parse/Format/Parse): %v", err) - } - - ndata2, err := pf1.Format() - if err != nil { - t.Errorf("reformat: %v", err) - } - pf3, err := Parse(base, ndata2, nil) - if err != nil { - t.Errorf("Parsing reformatted2: %v", err) - continue - } - eq = eqchecker{file: base} - if err := eq.check(pf1, pf3); err != nil { - t.Errorf("not equal (Parse/Format/Parse): %v", err) - } - ndata = ndata2 - } - - if strings.HasSuffix(out, ".in") { - golden, err := ioutil.ReadFile(strings.TrimSuffix(out, ".in") + ".golden") - if err != nil { - t.Error(err) - continue - } - if !bytes.Equal(ndata, golden) { - t.Errorf("formatted %s incorrectly: diff shows -golden, +ours", base) - tdiff(t, string(golden), string(ndata)) - return - } - } - } -} - -// An eqchecker holds state for checking the equality of two parse trees. -type eqchecker struct { - file string - pos Position -} - -// errorf returns an error described by the printf-style format and arguments, -// inserting the current file position before the error text. -func (eq *eqchecker) errorf(format string, args ...interface{}) error { - return fmt.Errorf("%s:%d: %s", eq.file, eq.pos.Line, - fmt.Sprintf(format, args...)) -} - -// check checks that v and w represent the same parse tree. -// If not, it returns an error describing the first difference. -func (eq *eqchecker) check(v, w interface{}) error { - return eq.checkValue(reflect.ValueOf(v), reflect.ValueOf(w)) -} - -var ( - posType = reflect.TypeOf(Position{}) - commentsType = reflect.TypeOf(Comments{}) -) - -// checkValue checks that v and w represent the same parse tree. -// If not, it returns an error describing the first difference. -func (eq *eqchecker) checkValue(v, w reflect.Value) error { - // inner returns the innermost expression for v. - // if v is a non-nil interface value, it returns the concrete - // value in the interface. - inner := func(v reflect.Value) reflect.Value { - for { - if v.Kind() == reflect.Interface && !v.IsNil() { - v = v.Elem() - continue - } - break - } - return v - } - - v = inner(v) - w = inner(w) - if v.Kind() == reflect.Invalid && w.Kind() == reflect.Invalid { - return nil - } - if v.Kind() == reflect.Invalid { - return eq.errorf("nil interface became %s", w.Type()) - } - if w.Kind() == reflect.Invalid { - return eq.errorf("%s became nil interface", v.Type()) - } - - if v.Type() != w.Type() { - return eq.errorf("%s became %s", v.Type(), w.Type()) - } - - if p, ok := v.Interface().(Expr); ok { - eq.pos, _ = p.Span() - } - - switch v.Kind() { - default: - return eq.errorf("unexpected type %s", v.Type()) - - case reflect.Bool, reflect.Int, reflect.String: - vi := v.Interface() - wi := w.Interface() - if vi != wi { - return eq.errorf("%v became %v", vi, wi) - } - - case reflect.Slice: - vl := v.Len() - wl := w.Len() - for i := 0; i < vl || i < wl; i++ { - if i >= vl { - return eq.errorf("unexpected %s", w.Index(i).Type()) - } - if i >= wl { - return eq.errorf("missing %s", v.Index(i).Type()) - } - if err := eq.checkValue(v.Index(i), w.Index(i)); err != nil { - return err - } - } - - case reflect.Struct: - // Fields in struct must match. - t := v.Type() - n := t.NumField() - for i := 0; i < n; i++ { - tf := t.Field(i) - switch { - default: - if err := eq.checkValue(v.Field(i), w.Field(i)); err != nil { - return err - } - - case tf.Type == posType: // ignore positions - case tf.Type == commentsType: // ignore comment assignment - } - } - - case reflect.Ptr, reflect.Interface: - if v.IsNil() != w.IsNil() { - if v.IsNil() { - return eq.errorf("unexpected %s", w.Elem().Type()) - } - return eq.errorf("missing %s", v.Elem().Type()) - } - if err := eq.checkValue(v.Elem(), w.Elem()); err != nil { - return err - } - } - return nil -} - -// diff returns the output of running diff on b1 and b2. -func diff(b1, b2 []byte) (data []byte, err error) { - f1, err := ioutil.TempFile("", "testdiff") - if err != nil { - return nil, err - } - defer os.Remove(f1.Name()) - defer f1.Close() - - f2, err := ioutil.TempFile("", "testdiff") - if err != nil { - return nil, err - } - defer os.Remove(f2.Name()) - defer f2.Close() - - f1.Write(b1) - f2.Write(b2) - - data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput() - if len(data) > 0 { - // diff exits with a non-zero status when the files don't match. - // Ignore that failure as long as we get output. - err = nil - } - return -} - -// tdiff logs the diff output to t.Error. -func tdiff(t *testing.T, a, b string) { - data, err := diff([]byte(a), []byte(b)) - if err != nil { - t.Error(err) - return - } - t.Error(string(data)) -} - -var modulePathTests = []struct { - input []byte - expected string -}{ - {input: []byte("module \"github.com/rsc/vgotest\""), expected: "github.com/rsc/vgotest"}, - {input: []byte("module github.com/rsc/vgotest"), expected: "github.com/rsc/vgotest"}, - {input: []byte("module \"github.com/rsc/vgotest\""), expected: "github.com/rsc/vgotest"}, - {input: []byte("module github.com/rsc/vgotest"), expected: "github.com/rsc/vgotest"}, - {input: []byte("module `github.com/rsc/vgotest`"), expected: "github.com/rsc/vgotest"}, - {input: []byte("module \"github.com/rsc/vgotest/v2\""), expected: "github.com/rsc/vgotest/v2"}, - {input: []byte("module github.com/rsc/vgotest/v2"), expected: "github.com/rsc/vgotest/v2"}, - {input: []byte("module \"gopkg.in/yaml.v2\""), expected: "gopkg.in/yaml.v2"}, - {input: []byte("module gopkg.in/yaml.v2"), expected: "gopkg.in/yaml.v2"}, - {input: []byte("module \"gopkg.in/check.v1\"\n"), expected: "gopkg.in/check.v1"}, - {input: []byte("module \"gopkg.in/check.v1\n\""), expected: ""}, - {input: []byte("module gopkg.in/check.v1\n"), expected: "gopkg.in/check.v1"}, - {input: []byte("module \"gopkg.in/check.v1\"\r\n"), expected: "gopkg.in/check.v1"}, - {input: []byte("module gopkg.in/check.v1\r\n"), expected: "gopkg.in/check.v1"}, - {input: []byte("module \"gopkg.in/check.v1\"\n\n"), expected: "gopkg.in/check.v1"}, - {input: []byte("module gopkg.in/check.v1\n\n"), expected: "gopkg.in/check.v1"}, - {input: []byte("module \n\"gopkg.in/check.v1\"\n\n"), expected: ""}, - {input: []byte("module \ngopkg.in/check.v1\n\n"), expected: ""}, - {input: []byte("module \"gopkg.in/check.v1\"asd"), expected: ""}, - {input: []byte("module \n\"gopkg.in/check.v1\"\n\n"), expected: ""}, - {input: []byte("module \ngopkg.in/check.v1\n\n"), expected: ""}, - {input: []byte("module \"gopkg.in/check.v1\"asd"), expected: ""}, - {input: []byte("module \nmodule a/b/c "), expected: "a/b/c"}, - {input: []byte("module \" \""), expected: " "}, - {input: []byte("module "), expected: ""}, - {input: []byte("module \" a/b/c \""), expected: " a/b/c "}, - {input: []byte("module \"github.com/rsc/vgotest1\" // with a comment"), expected: "github.com/rsc/vgotest1"}, -} - -func TestModulePath(t *testing.T) { - for _, test := range modulePathTests { - t.Run(string(test.input), func(t *testing.T) { - result := ModulePath(test.input) - if result != test.expected { - t.Fatalf("ModulePath(%q): %s, want %s", string(test.input), result, test.expected) - } - }) - } -} diff --git a/libgo/go/cmd/go/internal/modfile/rule.go b/libgo/go/cmd/go/internal/modfile/rule.go deleted file mode 100644 index 6e1a22f3caa..00000000000 --- a/libgo/go/cmd/go/internal/modfile/rule.go +++ /dev/null @@ -1,763 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package modfile - -import ( - "bytes" - "errors" - "fmt" - "internal/lazyregexp" - "path/filepath" - "sort" - "strconv" - "strings" - "unicode" - - "cmd/go/internal/module" -) - -// A File is the parsed, interpreted form of a go.mod file. -type File struct { - Module *Module - Go *Go - Require []*Require - Exclude []*Exclude - Replace []*Replace - - Syntax *FileSyntax -} - -// A Module is the module statement. -type Module struct { - Mod module.Version - Syntax *Line -} - -// A Go is the go statement. -type Go struct { - Version string // "1.23" - Syntax *Line -} - -// A Require is a single require statement. -type Require struct { - Mod module.Version - Indirect bool // has "// indirect" comment - Syntax *Line -} - -// An Exclude is a single exclude statement. -type Exclude struct { - Mod module.Version - Syntax *Line -} - -// A Replace is a single replace statement. -type Replace struct { - Old module.Version - New module.Version - Syntax *Line -} - -func (f *File) AddModuleStmt(path string) error { - if f.Syntax == nil { - f.Syntax = new(FileSyntax) - } - if f.Module == nil { - f.Module = &Module{ - Mod: module.Version{Path: path}, - Syntax: f.Syntax.addLine(nil, "module", AutoQuote(path)), - } - } else { - f.Module.Mod.Path = path - f.Syntax.updateLine(f.Module.Syntax, "module", AutoQuote(path)) - } - return nil -} - -func (f *File) AddComment(text string) { - if f.Syntax == nil { - f.Syntax = new(FileSyntax) - } - f.Syntax.Stmt = append(f.Syntax.Stmt, &CommentBlock{ - Comments: Comments{ - Before: []Comment{ - { - Token: text, - }, - }, - }, - }) -} - -type VersionFixer func(path, version string) (string, error) - -// Parse parses the data, reported in errors as being from file, -// into a File struct. It applies fix, if non-nil, to canonicalize all module versions found. -func Parse(file string, data []byte, fix VersionFixer) (*File, error) { - return parseToFile(file, data, fix, true) -} - -// ParseLax is like Parse but ignores unknown statements. -// It is used when parsing go.mod files other than the main module, -// under the theory that most statement types we add in the future will -// only apply in the main module, like exclude and replace, -// and so we get better gradual deployments if old go commands -// simply ignore those statements when found in go.mod files -// in dependencies. -func ParseLax(file string, data []byte, fix VersionFixer) (*File, error) { - return parseToFile(file, data, fix, false) -} - -func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File, error) { - fs, err := parse(file, data) - if err != nil { - return nil, err - } - f := &File{ - Syntax: fs, - } - - var errs bytes.Buffer - for _, x := range fs.Stmt { - switch x := x.(type) { - case *Line: - f.add(&errs, x, x.Token[0], x.Token[1:], fix, strict) - - case *LineBlock: - if len(x.Token) > 1 { - if strict { - fmt.Fprintf(&errs, "%s:%d: unknown block type: %s\n", file, x.Start.Line, strings.Join(x.Token, " ")) - } - continue - } - switch x.Token[0] { - default: - if strict { - fmt.Fprintf(&errs, "%s:%d: unknown block type: %s\n", file, x.Start.Line, strings.Join(x.Token, " ")) - } - continue - case "module", "require", "exclude", "replace": - for _, l := range x.Line { - f.add(&errs, l, x.Token[0], l.Token, fix, strict) - } - } - } - } - - if errs.Len() > 0 { - return nil, errors.New(strings.TrimRight(errs.String(), "\n")) - } - return f, nil -} - -var GoVersionRE = lazyregexp.New(`([1-9][0-9]*)\.(0|[1-9][0-9]*)`) - -func (f *File) add(errs *bytes.Buffer, line *Line, verb string, args []string, fix VersionFixer, strict bool) { - // If strict is false, this module is a dependency. - // We ignore all unknown directives as well as main-module-only - // directives like replace and exclude. It will work better for - // forward compatibility if we can depend on modules that have unknown - // statements (presumed relevant only when acting as the main module) - // and simply ignore those statements. - if !strict { - switch verb { - case "module", "require", "go": - // want these even for dependency go.mods - default: - return - } - } - - switch verb { - default: - fmt.Fprintf(errs, "%s:%d: unknown directive: %s\n", f.Syntax.Name, line.Start.Line, verb) - - case "go": - if f.Go != nil { - fmt.Fprintf(errs, "%s:%d: repeated go statement\n", f.Syntax.Name, line.Start.Line) - return - } - if len(args) != 1 || !GoVersionRE.MatchString(args[0]) { - fmt.Fprintf(errs, "%s:%d: usage: go 1.23\n", f.Syntax.Name, line.Start.Line) - return - } - f.Go = &Go{Syntax: line} - f.Go.Version = args[0] - case "module": - if f.Module != nil { - fmt.Fprintf(errs, "%s:%d: repeated module statement\n", f.Syntax.Name, line.Start.Line) - return - } - f.Module = &Module{Syntax: line} - if len(args) != 1 { - - fmt.Fprintf(errs, "%s:%d: usage: module module/path\n", f.Syntax.Name, line.Start.Line) - return - } - s, err := parseString(&args[0]) - if err != nil { - fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - f.Module.Mod = module.Version{Path: s} - case "require", "exclude": - if len(args) != 2 { - fmt.Fprintf(errs, "%s:%d: usage: %s module/path v1.2.3\n", f.Syntax.Name, line.Start.Line, verb) - return - } - s, err := parseString(&args[0]) - if err != nil { - fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - v, err := parseVersion(verb, s, &args[1], fix) - if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - pathMajor, err := modulePathMajor(s) - if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - if err := module.MatchPathMajor(v, pathMajor); err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, &Error{Verb: verb, ModPath: s, Err: err}) - return - } - if verb == "require" { - f.Require = append(f.Require, &Require{ - Mod: module.Version{Path: s, Version: v}, - Syntax: line, - Indirect: isIndirect(line), - }) - } else { - f.Exclude = append(f.Exclude, &Exclude{ - Mod: module.Version{Path: s, Version: v}, - Syntax: line, - }) - } - case "replace": - arrow := 2 - if len(args) >= 2 && args[1] == "=>" { - arrow = 1 - } - if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { - fmt.Fprintf(errs, "%s:%d: usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory\n", f.Syntax.Name, line.Start.Line, verb, verb) - return - } - s, err := parseString(&args[0]) - if err != nil { - fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - pathMajor, err := modulePathMajor(s) - if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - var v string - if arrow == 2 { - v, err = parseVersion(verb, s, &args[1], fix) - if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - if err := module.MatchPathMajor(v, pathMajor); err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, &Error{Verb: verb, ModPath: s, Err: err}) - return - } - } - ns, err := parseString(&args[arrow+1]) - if err != nil { - fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - nv := "" - if len(args) == arrow+2 { - if !IsDirectoryPath(ns) { - fmt.Fprintf(errs, "%s:%d: replacement module without version must be directory path (rooted or starting with ./ or ../)\n", f.Syntax.Name, line.Start.Line) - return - } - if filepath.Separator == '/' && strings.Contains(ns, `\`) { - fmt.Fprintf(errs, "%s:%d: replacement directory appears to be Windows path (on a non-windows system)\n", f.Syntax.Name, line.Start.Line) - return - } - } - if len(args) == arrow+3 { - nv, err = parseVersion(verb, ns, &args[arrow+2], fix) - if err != nil { - fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) - return - } - if IsDirectoryPath(ns) { - fmt.Fprintf(errs, "%s:%d: replacement module directory path %q cannot have version\n", f.Syntax.Name, line.Start.Line, ns) - return - } - } - f.Replace = append(f.Replace, &Replace{ - Old: module.Version{Path: s, Version: v}, - New: module.Version{Path: ns, Version: nv}, - Syntax: line, - }) - } -} - -// isIndirect reports whether line has a "// indirect" comment, -// meaning it is in go.mod only for its effect on indirect dependencies, -// so that it can be dropped entirely once the effective version of the -// indirect dependency reaches the given minimum version. -func isIndirect(line *Line) bool { - if len(line.Suffix) == 0 { - return false - } - f := strings.Fields(line.Suffix[0].Token) - return (len(f) == 2 && f[1] == "indirect" || len(f) > 2 && f[1] == "indirect;") && f[0] == "//" -} - -// setIndirect sets line to have (or not have) a "// indirect" comment. -func setIndirect(line *Line, indirect bool) { - if isIndirect(line) == indirect { - return - } - if indirect { - // Adding comment. - if len(line.Suffix) == 0 { - // New comment. - line.Suffix = []Comment{{Token: "// indirect", Suffix: true}} - return - } - // Insert at beginning of existing comment. - com := &line.Suffix[0] - space := " " - if len(com.Token) > 2 && com.Token[2] == ' ' || com.Token[2] == '\t' { - space = "" - } - com.Token = "// indirect;" + space + com.Token[2:] - return - } - - // Removing comment. - f := strings.Fields(line.Suffix[0].Token) - if len(f) == 2 { - // Remove whole comment. - line.Suffix = nil - return - } - - // Remove comment prefix. - com := &line.Suffix[0] - i := strings.Index(com.Token, "indirect;") - com.Token = "//" + com.Token[i+len("indirect;"):] -} - -// IsDirectoryPath reports whether the given path should be interpreted -// as a directory path. Just like on the go command line, relative paths -// and rooted paths are directory paths; the rest are module paths. -func IsDirectoryPath(ns string) bool { - // Because go.mod files can move from one system to another, - // we check all known path syntaxes, both Unix and Windows. - return strings.HasPrefix(ns, "./") || strings.HasPrefix(ns, "../") || strings.HasPrefix(ns, "/") || - strings.HasPrefix(ns, `.\`) || strings.HasPrefix(ns, `..\`) || strings.HasPrefix(ns, `\`) || - len(ns) >= 2 && ('A' <= ns[0] && ns[0] <= 'Z' || 'a' <= ns[0] && ns[0] <= 'z') && ns[1] == ':' -} - -// MustQuote reports whether s must be quoted in order to appear as -// a single token in a go.mod line. -func MustQuote(s string) bool { - for _, r := range s { - if !unicode.IsPrint(r) || r == ' ' || r == '"' || r == '\'' || r == '`' { - return true - } - } - return s == "" || strings.Contains(s, "//") || strings.Contains(s, "/*") -} - -// AutoQuote returns s or, if quoting is required for s to appear in a go.mod, -// the quotation of s. -func AutoQuote(s string) string { - if MustQuote(s) { - return strconv.Quote(s) - } - return s -} - -func parseString(s *string) (string, error) { - t := *s - if strings.HasPrefix(t, `"`) { - var err error - if t, err = strconv.Unquote(t); err != nil { - return "", err - } - } else if strings.ContainsAny(t, "\"'`") { - // Other quotes are reserved both for possible future expansion - // and to avoid confusion. For example if someone types 'x' - // we want that to be a syntax error and not a literal x in literal quotation marks. - return "", fmt.Errorf("unquoted string cannot contain quote") - } - *s = AutoQuote(t) - return t, nil -} - -type Error struct { - Verb string - ModPath string - Err error -} - -func (e *Error) Error() string { - return fmt.Sprintf("%s %s: %v", e.Verb, e.ModPath, e.Err) -} - -func (e *Error) Unwrap() error { return e.Err } - -func parseVersion(verb string, path string, s *string, fix VersionFixer) (string, error) { - t, err := parseString(s) - if err != nil { - return "", &Error{ - Verb: verb, - ModPath: path, - Err: &module.InvalidVersionError{ - Version: *s, - Err: err, - }, - } - } - if fix != nil { - var err error - t, err = fix(path, t) - if err != nil { - if err, ok := err.(*module.ModuleError); ok { - return "", &Error{ - Verb: verb, - ModPath: path, - Err: err.Err, - } - } - return "", err - } - } - if v := module.CanonicalVersion(t); v != "" { - *s = v - return *s, nil - } - return "", &Error{ - Verb: verb, - ModPath: path, - Err: &module.InvalidVersionError{ - Version: t, - Err: errors.New("must be of the form v1.2.3"), - }, - } -} - -func modulePathMajor(path string) (string, error) { - _, major, ok := module.SplitPathVersion(path) - if !ok { - return "", fmt.Errorf("invalid module path") - } - return major, nil -} - -func (f *File) Format() ([]byte, error) { - return Format(f.Syntax), nil -} - -// Cleanup cleans up the file f after any edit operations. -// To avoid quadratic behavior, modifications like DropRequire -// clear the entry but do not remove it from the slice. -// Cleanup cleans out all the cleared entries. -func (f *File) Cleanup() { - w := 0 - for _, r := range f.Require { - if r.Mod.Path != "" { - f.Require[w] = r - w++ - } - } - f.Require = f.Require[:w] - - w = 0 - for _, x := range f.Exclude { - if x.Mod.Path != "" { - f.Exclude[w] = x - w++ - } - } - f.Exclude = f.Exclude[:w] - - w = 0 - for _, r := range f.Replace { - if r.Old.Path != "" { - f.Replace[w] = r - w++ - } - } - f.Replace = f.Replace[:w] - - f.Syntax.Cleanup() -} - -func (f *File) AddGoStmt(version string) error { - if !GoVersionRE.MatchString(version) { - return fmt.Errorf("invalid language version string %q", version) - } - if f.Go == nil { - f.Go = &Go{ - Version: version, - Syntax: f.Syntax.addLine(nil, "go", version), - } - } else { - f.Go.Version = version - f.Syntax.updateLine(f.Go.Syntax, "go", version) - } - return nil -} - -func (f *File) AddRequire(path, vers string) error { - need := true - for _, r := range f.Require { - if r.Mod.Path == path { - if need { - r.Mod.Version = vers - f.Syntax.updateLine(r.Syntax, "require", AutoQuote(path), vers) - need = false - } else { - f.Syntax.removeLine(r.Syntax) - *r = Require{} - } - } - } - - if need { - f.AddNewRequire(path, vers, false) - } - return nil -} - -func (f *File) AddNewRequire(path, vers string, indirect bool) { - line := f.Syntax.addLine(nil, "require", AutoQuote(path), vers) - setIndirect(line, indirect) - f.Require = append(f.Require, &Require{module.Version{Path: path, Version: vers}, indirect, line}) -} - -func (f *File) SetRequire(req []*Require) { - need := make(map[string]string) - indirect := make(map[string]bool) - for _, r := range req { - need[r.Mod.Path] = r.Mod.Version - indirect[r.Mod.Path] = r.Indirect - } - - for _, r := range f.Require { - if v, ok := need[r.Mod.Path]; ok { - r.Mod.Version = v - r.Indirect = indirect[r.Mod.Path] - } - } - - var newStmts []Expr - for _, stmt := range f.Syntax.Stmt { - switch stmt := stmt.(type) { - case *LineBlock: - if len(stmt.Token) > 0 && stmt.Token[0] == "require" { - var newLines []*Line - for _, line := range stmt.Line { - if p, err := parseString(&line.Token[0]); err == nil && need[p] != "" { - line.Token[1] = need[p] - delete(need, p) - setIndirect(line, indirect[p]) - newLines = append(newLines, line) - } - } - if len(newLines) == 0 { - continue // drop stmt - } - stmt.Line = newLines - } - - case *Line: - if len(stmt.Token) > 0 && stmt.Token[0] == "require" { - if p, err := parseString(&stmt.Token[1]); err == nil && need[p] != "" { - stmt.Token[2] = need[p] - delete(need, p) - setIndirect(stmt, indirect[p]) - } else { - continue // drop stmt - } - } - } - newStmts = append(newStmts, stmt) - } - f.Syntax.Stmt = newStmts - - for path, vers := range need { - f.AddNewRequire(path, vers, indirect[path]) - } - f.SortBlocks() -} - -func (f *File) DropRequire(path string) error { - for _, r := range f.Require { - if r.Mod.Path == path { - f.Syntax.removeLine(r.Syntax) - *r = Require{} - } - } - return nil -} - -func (f *File) AddExclude(path, vers string) error { - var hint *Line - for _, x := range f.Exclude { - if x.Mod.Path == path && x.Mod.Version == vers { - return nil - } - if x.Mod.Path == path { - hint = x.Syntax - } - } - - f.Exclude = append(f.Exclude, &Exclude{Mod: module.Version{Path: path, Version: vers}, Syntax: f.Syntax.addLine(hint, "exclude", AutoQuote(path), vers)}) - return nil -} - -func (f *File) DropExclude(path, vers string) error { - for _, x := range f.Exclude { - if x.Mod.Path == path && x.Mod.Version == vers { - f.Syntax.removeLine(x.Syntax) - *x = Exclude{} - } - } - return nil -} - -func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { - need := true - old := module.Version{Path: oldPath, Version: oldVers} - new := module.Version{Path: newPath, Version: newVers} - tokens := []string{"replace", AutoQuote(oldPath)} - if oldVers != "" { - tokens = append(tokens, oldVers) - } - tokens = append(tokens, "=>", AutoQuote(newPath)) - if newVers != "" { - tokens = append(tokens, newVers) - } - - var hint *Line - for _, r := range f.Replace { - if r.Old.Path == oldPath && (oldVers == "" || r.Old.Version == oldVers) { - if need { - // Found replacement for old; update to use new. - r.New = new - f.Syntax.updateLine(r.Syntax, tokens...) - need = false - continue - } - // Already added; delete other replacements for same. - f.Syntax.removeLine(r.Syntax) - *r = Replace{} - } - if r.Old.Path == oldPath { - hint = r.Syntax - } - } - if need { - f.Replace = append(f.Replace, &Replace{Old: old, New: new, Syntax: f.Syntax.addLine(hint, tokens...)}) - } - return nil -} - -func (f *File) DropReplace(oldPath, oldVers string) error { - for _, r := range f.Replace { - if r.Old.Path == oldPath && r.Old.Version == oldVers { - f.Syntax.removeLine(r.Syntax) - *r = Replace{} - } - } - return nil -} - -func (f *File) SortBlocks() { - f.removeDups() // otherwise sorting is unsafe - - for _, stmt := range f.Syntax.Stmt { - block, ok := stmt.(*LineBlock) - if !ok { - continue - } - sort.Slice(block.Line, func(i, j int) bool { - li := block.Line[i] - lj := block.Line[j] - for k := 0; k < len(li.Token) && k < len(lj.Token); k++ { - if li.Token[k] != lj.Token[k] { - return li.Token[k] < lj.Token[k] - } - } - return len(li.Token) < len(lj.Token) - }) - } -} - -func (f *File) removeDups() { - have := make(map[module.Version]bool) - kill := make(map[*Line]bool) - for _, x := range f.Exclude { - if have[x.Mod] { - kill[x.Syntax] = true - continue - } - have[x.Mod] = true - } - var excl []*Exclude - for _, x := range f.Exclude { - if !kill[x.Syntax] { - excl = append(excl, x) - } - } - f.Exclude = excl - - have = make(map[module.Version]bool) - // Later replacements take priority over earlier ones. - for i := len(f.Replace) - 1; i >= 0; i-- { - x := f.Replace[i] - if have[x.Old] { - kill[x.Syntax] = true - continue - } - have[x.Old] = true - } - var repl []*Replace - for _, x := range f.Replace { - if !kill[x.Syntax] { - repl = append(repl, x) - } - } - f.Replace = repl - - var stmts []Expr - for _, stmt := range f.Syntax.Stmt { - switch stmt := stmt.(type) { - case *Line: - if kill[stmt] { - continue - } - case *LineBlock: - var lines []*Line - for _, line := range stmt.Line { - if !kill[line] { - lines = append(lines, line) - } - } - stmt.Line = lines - if len(lines) == 0 { - continue - } - } - stmts = append(stmts, stmt) - } - f.Syntax.Stmt = stmts -} diff --git a/libgo/go/cmd/go/internal/modfile/rule_test.go b/libgo/go/cmd/go/internal/modfile/rule_test.go deleted file mode 100644 index b88ad629168..00000000000 --- a/libgo/go/cmd/go/internal/modfile/rule_test.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package modfile - -import ( - "bytes" - "fmt" - "testing" -) - -var addRequireTests = []struct { - in string - path string - vers string - out string -}{ - { - ` - module m - require x.y/z v1.2.3 - `, - "x.y/z", "v1.5.6", - ` - module m - require x.y/z v1.5.6 - `, - }, - { - ` - module m - require x.y/z v1.2.3 - `, - "x.y/w", "v1.5.6", - ` - module m - require ( - x.y/z v1.2.3 - x.y/w v1.5.6 - ) - `, - }, - { - ` - module m - require x.y/z v1.2.3 - require x.y/q/v2 v2.3.4 - `, - "x.y/w", "v1.5.6", - ` - module m - require x.y/z v1.2.3 - require ( - x.y/q/v2 v2.3.4 - x.y/w v1.5.6 - ) - `, - }, -} - -func TestAddRequire(t *testing.T) { - for i, tt := range addRequireTests { - t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) { - f, err := Parse("in", []byte(tt.in), nil) - if err != nil { - t.Fatal(err) - } - g, err := Parse("out", []byte(tt.out), nil) - if err != nil { - t.Fatal(err) - } - golden, err := g.Format() - if err != nil { - t.Fatal(err) - } - - if err := f.AddRequire(tt.path, tt.vers); err != nil { - t.Fatal(err) - } - out, err := f.Format() - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(out, golden) { - t.Errorf("have:\n%s\nwant:\n%s", out, golden) - } - }) - } -} diff --git a/libgo/go/cmd/go/internal/modfile/testdata/block.golden b/libgo/go/cmd/go/internal/modfile/testdata/block.golden deleted file mode 100644 index 4aa2d634fc9..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/block.golden +++ /dev/null @@ -1,29 +0,0 @@ -// comment -x "y" z - -// block -block ( // block-eol - // x-before-line - - "x" ( y // x-eol - "x1" - "x2" - // line - "x3" - "x4" - - "x5" - - // y-line - "y" // y-eol - - "z" // z-eol -) // block-eol2 - -block2 ( - x - y - z -) - -// eof diff --git a/libgo/go/cmd/go/internal/modfile/testdata/block.in b/libgo/go/cmd/go/internal/modfile/testdata/block.in deleted file mode 100644 index 1dfae65f5c0..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/block.in +++ /dev/null @@ -1,29 +0,0 @@ -// comment -x "y" z - -// block -block ( // block-eol - // x-before-line - - "x" ( y // x-eol - "x1" - "x2" - // line - "x3" - "x4" - - "x5" - - // y-line - "y" // y-eol - - "z" // z-eol -) // block-eol2 - - -block2 (x - y - z -) - -// eof diff --git a/libgo/go/cmd/go/internal/modfile/testdata/comment.golden b/libgo/go/cmd/go/internal/modfile/testdata/comment.golden deleted file mode 100644 index 75f3b84478c..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/comment.golden +++ /dev/null @@ -1,10 +0,0 @@ -// comment -module "x" // eol - -// mid comment - -// comment 2 -// comment 2 line 2 -module "y" // eoy - -// comment 3 diff --git a/libgo/go/cmd/go/internal/modfile/testdata/comment.in b/libgo/go/cmd/go/internal/modfile/testdata/comment.in deleted file mode 100644 index bfc2492b264..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/comment.in +++ /dev/null @@ -1,8 +0,0 @@ -// comment -module "x" // eol -// mid comment - -// comment 2 -// comment 2 line 2 -module "y" // eoy -// comment 3 diff --git a/libgo/go/cmd/go/internal/modfile/testdata/empty.golden b/libgo/go/cmd/go/internal/modfile/testdata/empty.golden deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libgo/go/cmd/go/internal/modfile/testdata/empty.in b/libgo/go/cmd/go/internal/modfile/testdata/empty.in deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/libgo/go/cmd/go/internal/modfile/testdata/gopkg.in.golden b/libgo/go/cmd/go/internal/modfile/testdata/gopkg.in.golden deleted file mode 100644 index 41669b3a737..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/gopkg.in.golden +++ /dev/null @@ -1,6 +0,0 @@ -module x - -require ( - gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528 - gopkg.in/yaml.v2 v2.2.1 -) diff --git a/libgo/go/cmd/go/internal/modfile/testdata/module.golden b/libgo/go/cmd/go/internal/modfile/testdata/module.golden deleted file mode 100644 index 78ba94398c3..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/module.golden +++ /dev/null @@ -1 +0,0 @@ -module abc diff --git a/libgo/go/cmd/go/internal/modfile/testdata/module.in b/libgo/go/cmd/go/internal/modfile/testdata/module.in deleted file mode 100644 index 08f383623f9..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/module.in +++ /dev/null @@ -1 +0,0 @@ -module "abc" diff --git a/libgo/go/cmd/go/internal/modfile/testdata/replace.golden b/libgo/go/cmd/go/internal/modfile/testdata/replace.golden deleted file mode 100644 index 5d6abcfcdad..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/replace.golden +++ /dev/null @@ -1,5 +0,0 @@ -module abc - -replace xyz v1.2.3 => /tmp/z - -replace xyz v1.3.4 => my/xyz v1.3.4-me diff --git a/libgo/go/cmd/go/internal/modfile/testdata/replace.in b/libgo/go/cmd/go/internal/modfile/testdata/replace.in deleted file mode 100644 index 685249946a2..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/replace.in +++ /dev/null @@ -1,5 +0,0 @@ -module "abc" - -replace "xyz" v1.2.3 => "/tmp/z" - -replace "xyz" v1.3.4 => "my/xyz" v1.3.4-me diff --git a/libgo/go/cmd/go/internal/modfile/testdata/replace2.golden b/libgo/go/cmd/go/internal/modfile/testdata/replace2.golden deleted file mode 100644 index e1d9c728df4..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/replace2.golden +++ /dev/null @@ -1,10 +0,0 @@ -module abc - -replace ( - xyz v1.2.3 => /tmp/z - xyz v1.3.4 => my/xyz v1.3.4-me - xyz v1.4.5 => "/tmp/my dir" - xyz v1.5.6 => my/xyz v1.5.6 - - xyz => my/other/xyz v1.5.4 -) diff --git a/libgo/go/cmd/go/internal/modfile/testdata/replace2.in b/libgo/go/cmd/go/internal/modfile/testdata/replace2.in deleted file mode 100644 index 786469866f9..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/replace2.in +++ /dev/null @@ -1,10 +0,0 @@ -module "abc" - -replace ( - "xyz" v1.2.3 => "/tmp/z" - "xyz" v1.3.4 => "my/xyz" "v1.3.4-me" - xyz "v1.4.5" => "/tmp/my dir" - xyz v1.5.6 => my/xyz v1.5.6 - - xyz => my/other/xyz v1.5.4 -) diff --git a/libgo/go/cmd/go/internal/modfile/testdata/rule1.golden b/libgo/go/cmd/go/internal/modfile/testdata/rule1.golden deleted file mode 100644 index 8a5c7258948..00000000000 --- a/libgo/go/cmd/go/internal/modfile/testdata/rule1.golden +++ /dev/null @@ -1,7 +0,0 @@ -module "x" - -module "y" - -require "x" - -require x diff --git a/libgo/go/cmd/go/internal/modget/get.go b/libgo/go/cmd/go/internal/modget/get.go index 1cae311c4c1..2a0f6346581 100644 --- a/libgo/go/cmd/go/internal/modget/get.go +++ b/libgo/go/cmd/go/internal/modget/get.go @@ -6,25 +6,26 @@ package modget import ( + "errors" + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "sync" + "cmd/go/internal/base" - "cmd/go/internal/cfg" "cmd/go/internal/get" "cmd/go/internal/imports" "cmd/go/internal/load" "cmd/go/internal/modload" - "cmd/go/internal/module" "cmd/go/internal/mvs" "cmd/go/internal/par" "cmd/go/internal/search" - "cmd/go/internal/semver" "cmd/go/internal/work" - "errors" - "fmt" - "os" - "path/filepath" - "sort" - "strings" - "sync" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) var CmdGet = &base.Command{ @@ -199,7 +200,7 @@ func (v *upgradeFlag) Set(s string) error { func (v *upgradeFlag) String() string { return "" } func init() { - work.AddBuildFlags(CmdGet) + work.AddBuildFlags(CmdGet, work.OmitModFlag) CmdGet.Run = runGet // break init loop CmdGet.Flag.BoolVar(&get.Insecure, "insecure", get.Insecure, "") CmdGet.Flag.Var(&getU, "u", "") @@ -256,11 +257,6 @@ type query struct { } func runGet(cmd *base.Command, args []string) { - // -mod=readonly has no effect on "go get". - if cfg.BuildMod == "readonly" { - cfg.BuildMod = "" - } - switch getU { case "", "upgrade", "patch": // ok @@ -278,10 +274,6 @@ func runGet(cmd *base.Command, args []string) { } modload.LoadTests = *getT - if cfg.BuildMod == "vendor" { - base.Fatalf("go get: disabled by -mod=%s", cfg.BuildMod) - } - buildList := modload.LoadBuildList() buildList = buildList[:len(buildList):len(buildList)] // copy on append versionByPath := make(map[string]string) @@ -294,6 +286,10 @@ func runGet(cmd *base.Command, args []string) { // what was requested. modload.DisallowWriteGoMod() + // Allow looking up modules for import paths outside of a module. + // 'go get' is expected to do this, unlike other commands. + modload.AllowMissingModuleImports() + // Parse command-line arguments and report errors. The command-line // arguments are of the form path@version or simply path, with implicit // @upgrade. path@none is "downgrade away". @@ -364,6 +360,10 @@ func runGet(cmd *base.Command, args []string) { // upgrade golang.org/x/tools. case path == "all": + // If there is no main module, "all" is not meaningful. + if !modload.HasModRoot() { + base.Errorf(`go get %s: cannot match "all": working directory is not part of a module`, arg) + } // Don't query modules until we load packages. We'll automatically // look up any missing modules. @@ -372,13 +372,15 @@ func runGet(cmd *base.Command, args []string) { continue default: - // The argument is a package path. - if pkgs := modload.TargetPackages(path); len(pkgs) != 0 { - // The path is in the main module. Nothing to query. - if vers != "upgrade" && vers != "patch" { - base.Errorf("go get %s: can't request explicit version of path in main module", arg) + // The argument is a package or module path. + if modload.HasModRoot() { + if pkgs := modload.TargetPackages(path); len(pkgs) != 0 { + // The path is in the main module. Nothing to query. + if vers != "upgrade" && vers != "patch" { + base.Errorf("go get %s: can't request explicit version of path in main module", arg) + } + continue } - continue } first := path @@ -452,10 +454,13 @@ func runGet(cmd *base.Command, args []string) { // This includes explicitly requested modules that don't have a root package // and modules with a target version of "none". var wg sync.WaitGroup + var modOnlyMu sync.Mutex modOnly := make(map[string]*query) for _, q := range queries { if q.m.Version == "none" { + modOnlyMu.Lock() modOnly[q.m.Path] = q + modOnlyMu.Unlock() continue } if q.path == q.m.Path { @@ -464,7 +469,9 @@ func runGet(cmd *base.Command, args []string) { if hasPkg, err := modload.ModuleHasRootPackage(q.m); err != nil { base.Errorf("go get: %v", err) } else if !hasPkg { + modOnlyMu.Lock() modOnly[q.m.Path] = q + modOnlyMu.Unlock() } wg.Done() }(q) @@ -763,6 +770,9 @@ func getQuery(path, vers string, prevM module.Version, forceModulePath bool) (mo info, err := modload.Query(path, vers, prevM.Version, modload.Allowed) if err == nil { + if info.Version != vers && info.Version != prevM.Version { + logOncef("go: %s %s => %s", path, vers, info.Version) + } return module.Version{Path: path, Version: info.Version}, nil } @@ -791,6 +801,9 @@ func getQuery(path, vers string, prevM module.Version, forceModulePath bool) (mo if !strings.Contains(path, "...") { var modErr *modload.PackageNotInModuleError if errors.As(err, &modErr) && modErr.Mod.Path == path { + if modErr.Mod.Version != vers { + logOncef("go: %s %s => %s", path, vers, modErr.Mod.Version) + } return modErr.Mod, nil } } @@ -798,7 +811,13 @@ func getQuery(path, vers string, prevM module.Version, forceModulePath bool) (mo return module.Version{}, err } - return results[0].Mod, nil + m := results[0].Mod + if m.Path != path { + logOncef("go: found %s in %s %s", path, m.Path, m.Version) + } else if m.Version != vers { + logOncef("go: %s %s => %s", path, vers, m.Version) + } + return m, nil } // An upgrader adapts an underlying mvs.Reqs to apply an @@ -955,6 +974,9 @@ func (u *upgrader) Upgrade(m module.Version) (module.Version, error) { return m, nil } + if info.Version != m.Version { + logOncef("go: %s %s => %s", m.Path, getU, info.Version) + } return module.Version{Path: m.Path, Version: info.Version}, nil } @@ -983,3 +1005,12 @@ func (r *lostUpgradeReqs) Required(mod module.Version) ([]module.Version, error) } return r.Reqs.Required(mod) } + +var loggedLines sync.Map + +func logOncef(format string, args ...interface{}) { + msg := fmt.Sprintf(format, args...) + if _, dup := loggedLines.LoadOrStore(msg, true); !dup { + fmt.Fprintln(os.Stderr, msg) + } +} diff --git a/libgo/go/cmd/go/internal/modload/build.go b/libgo/go/cmd/go/internal/modload/build.go index 7cbdef1c36c..292fd45a4a6 100644 --- a/libgo/go/cmd/go/internal/modload/build.go +++ b/libgo/go/cmd/go/internal/modload/build.go @@ -6,13 +6,6 @@ package modload import ( "bytes" - "cmd/go/internal/base" - "cmd/go/internal/cfg" - "cmd/go/internal/modfetch" - "cmd/go/internal/modinfo" - "cmd/go/internal/module" - "cmd/go/internal/search" - "cmd/go/internal/semver" "encoding/hex" "fmt" "internal/goroot" @@ -20,6 +13,15 @@ import ( "path/filepath" "runtime/debug" "strings" + + "cmd/go/internal/base" + "cmd/go/internal/cfg" + "cmd/go/internal/modfetch" + "cmd/go/internal/modinfo" + "cmd/go/internal/search" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) var ( @@ -43,11 +45,19 @@ func findStandardImportPath(path string) string { return "" } +// PackageModuleInfo returns information about the module that provides +// a given package. If modules are not enabled or if the package is in the +// standard library or if the package was not successfully loaded with +// ImportPaths or a similar loading function, nil is returned. func PackageModuleInfo(pkgpath string) *modinfo.ModulePublic { if isStandardImportPath(pkgpath) || !Enabled() { return nil } - return moduleInfo(findModule(pkgpath, pkgpath), true) + m, ok := findModule(pkgpath) + if !ok { + return nil + } + return moduleInfo(m, true) } func ModuleInfo(path string) *modinfo.ModulePublic { @@ -119,13 +129,8 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { info.GoVersion = loaded.goVersion[m.Path] } - if cfg.BuildMod == "vendor" { - info.Dir = filepath.Join(ModRoot(), "vendor", m.Path) - return info - } - - // complete fills in the extra fields in m. - complete := func(m *modinfo.ModulePublic) { + // completeFromModCache fills in the extra fields in m using the module cache. + completeFromModCache := func(m *modinfo.ModulePublic) { if m.Version != "" { if q, err := Query(m.Path, m.Version, "", nil); err != nil { m.Error = &modinfo.ModuleError{Err: err.Error()} @@ -151,13 +156,21 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { } if !fromBuildList { - complete(info) + completeFromModCache(info) // Will set m.Error in vendor mode. return info } r := Replacement(m) if r.Path == "" { - complete(info) + if cfg.BuildMod == "vendor" { + // It's tempting to fill in the "Dir" field to point within the vendor + // directory, but that would be misleading: the vendor directory contains + // a flattened package tree, not complete modules, and it can even + // interleave packages from different modules if one module path is a + // prefix of the other. + } else { + completeFromModCache(info) + } return info } @@ -176,23 +189,29 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { } else { info.Replace.Dir = filepath.Join(ModRoot(), r.Path) } + info.Replace.GoMod = filepath.Join(info.Replace.Dir, "go.mod") + } + if cfg.BuildMod != "vendor" { + completeFromModCache(info.Replace) + info.Dir = info.Replace.Dir + info.GoMod = info.Replace.GoMod } - complete(info.Replace) - info.Dir = info.Replace.Dir - info.GoMod = filepath.Join(info.Dir, "go.mod") return info } +// PackageBuildInfo returns a string containing module version information +// for modules providing packages named by path and deps. path and deps must +// name packages that were resolved successfully with ImportPaths or one of +// the Load functions. func PackageBuildInfo(path string, deps []string) string { if isStandardImportPath(path) || !Enabled() { return "" } - - target := findModule(path, path) + target := mustFindModule(path, path) mdeps := make(map[module.Version]bool) for _, dep := range deps { if !isStandardImportPath(dep) { - mdeps[findModule(path, dep)] = true + mdeps[mustFindModule(path, dep)] = true } } var mods []module.Version @@ -227,9 +246,12 @@ func PackageBuildInfo(path string, deps []string) string { return buf.String() } -// findModule returns the module containing the package at path, -// needed to build the package at target. -func findModule(target, path string) module.Version { +// mustFindModule is like findModule, but it calls base.Fatalf if the +// module can't be found. +// +// TODO(jayconrod): remove this. Callers should use findModule and return +// errors instead of relying on base.Fatalf. +func mustFindModule(target, path string) module.Version { pkg, ok := loaded.pkgCache.Get(path).(*loadPkg) if ok { if pkg.err != nil { @@ -249,17 +271,49 @@ func findModule(target, path string) module.Version { panic("unreachable") } -func ModInfoProg(info string) []byte { +// findModule searches for the module that contains the package at path. +// If the package was loaded with ImportPaths or one of the other loading +// functions, its containing module and true are returned. Otherwise, +// module.Version{} and false are returend. +func findModule(path string) (module.Version, bool) { + if pkg, ok := loaded.pkgCache.Get(path).(*loadPkg); ok { + return pkg.mod, pkg.mod != module.Version{} + } + if path == "command-line-arguments" { + return Target, true + } + return module.Version{}, false +} + +func ModInfoProg(info string, isgccgo bool) []byte { // Inject a variable with the debug information as runtime.modinfo, // but compile it in package main so that it is specific to the binary. // The variable must be a literal so that it will have the correct value // before the initializer for package main runs. // - // The runtime startup code refers to the variable, which keeps it live in all binaries. - return []byte(fmt.Sprintf(`package main + // The runtime startup code refers to the variable, which keeps it live + // in all binaries. + // + // Note: we use an alternate recipe below for gccgo (based on an + // init function) due to the fact that gccgo does not support + // applying a "//go:linkname" directive to a variable. This has + // drawbacks in that other packages may want to look at the module + // info in their init functions (see issue 29628), which won't + // work for gccgo. See also issue 30344. + + if !isgccgo { + return []byte(fmt.Sprintf(`package main import _ "unsafe" //go:linkname __set_modinfo__ runtime.setmodinfo func __set_modinfo__(string) func init() { __set_modinfo__(%q) } `, string(infoStart)+info+string(infoEnd))) + } else { + return []byte(fmt.Sprintf(`package main +import _ "unsafe" +//go:linkname __set_debug_modinfo__ runtime.setmodinfo +func __set_debug_modinfo__(string) +func init() { __set_debug_modinfo__(%q) } + `, string(infoStart)+info+string(infoEnd))) + } } diff --git a/libgo/go/cmd/go/internal/modload/help.go b/libgo/go/cmd/go/internal/modload/help.go index 1927c1cff73..b47f3dedb37 100644 --- a/libgo/go/cmd/go/internal/modload/help.go +++ b/libgo/go/cmd/go/internal/modload/help.go @@ -179,6 +179,9 @@ If invoked with -mod=vendor, the go command assumes that the vendor directory holds the correct copies of dependencies and ignores the dependency descriptions in go.mod. +If invoked with -mod=mod, the go command loads modules from the module cache +even if there is a vendor directory present. + Pseudo-versions The go.mod file and the go command more generally use semantic versions as diff --git a/libgo/go/cmd/go/internal/modload/import.go b/libgo/go/cmd/go/internal/modload/import.go index 70add3507a2..9ae2900e469 100644 --- a/libgo/go/cmd/go/internal/modload/import.go +++ b/libgo/go/cmd/go/internal/modload/import.go @@ -5,7 +5,6 @@ package modload import ( - "bytes" "errors" "fmt" "go/build" @@ -17,31 +16,81 @@ import ( "time" "cmd/go/internal/cfg" + "cmd/go/internal/load" "cmd/go/internal/modfetch" - "cmd/go/internal/module" "cmd/go/internal/par" "cmd/go/internal/search" - "cmd/go/internal/semver" - "cmd/go/internal/str" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) type ImportMissingError struct { - ImportPath string - Module module.Version + Path string + Module module.Version + QueryErr error // newMissingVersion is set to a newer version of Module if one is present // in the build list. When set, we can't automatically upgrade. newMissingVersion string } +var _ load.ImportPathError = (*ImportMissingError)(nil) + func (e *ImportMissingError) Error() string { if e.Module.Path == "" { - if str.HasPathPrefix(e.ImportPath, "cmd") { - return fmt.Sprintf("package %s is not in GOROOT (%s)", e.ImportPath, filepath.Join(cfg.GOROOT, "src", e.ImportPath)) + if search.IsStandardImportPath(e.Path) { + return fmt.Sprintf("package %s is not in GOROOT (%s)", e.Path, filepath.Join(cfg.GOROOT, "src", e.Path)) + } + if e.QueryErr != nil { + return fmt.Sprintf("cannot find module providing package %s: %v", e.Path, e.QueryErr) + } + return "cannot find module providing package " + e.Path + } + return fmt.Sprintf("missing module for import: %s@%s provides %s", e.Module.Path, e.Module.Version, e.Path) +} + +func (e *ImportMissingError) Unwrap() error { + return e.QueryErr +} + +func (e *ImportMissingError) ImportPath() string { + return e.Path +} + +// An AmbiguousImportError indicates an import of a package found in multiple +// modules in the build list, or found in both the main module and its vendor +// directory. +type AmbiguousImportError struct { + ImportPath string + Dirs []string + Modules []module.Version // Either empty or 1:1 with Dirs. +} + +func (e *AmbiguousImportError) Error() string { + locType := "modules" + if len(e.Modules) == 0 { + locType = "directories" + } + + var buf strings.Builder + fmt.Fprintf(&buf, "ambiguous import: found package %s in multiple %s:", e.ImportPath, locType) + + for i, dir := range e.Dirs { + buf.WriteString("\n\t") + if i < len(e.Modules) { + m := e.Modules[i] + buf.WriteString(m.Path) + if m.Version != "" { + fmt.Fprintf(&buf, " %s", m.Version) + } + fmt.Fprintf(&buf, " (%s)", dir) + } else { + buf.WriteString(dir) } - return "cannot find module providing package " + e.ImportPath } - return "missing module for import: " + e.Module.Path + "@" + e.Module.Version + " provides " + e.ImportPath + + return buf.String() } // Import finds the module and directory in the build list @@ -68,8 +117,8 @@ func Import(path string) (m module.Version, dir string, err error) { } // Is the package in the standard library? - if search.IsStandardImportPath(path) && - goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) { + pathIsStd := search.IsStandardImportPath(path) + if pathIsStd && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) { if targetInGorootSrc { if dir, ok := dirInModule(path, targetPrefix, ModRoot(), true); ok { return Target, dir, nil @@ -78,9 +127,6 @@ func Import(path string) (m module.Version, dir string, err error) { dir := filepath.Join(cfg.GOROOT, "src", path) return module.Version{}, dir, nil } - if str.HasPathPrefix(path, "cmd") { - return module.Version{}, "", &ImportMissingError{ImportPath: path} - } // -mod=vendor is special. // Everything must be in the main module or the main module's vendor directory. @@ -88,7 +134,7 @@ func Import(path string) (m module.Version, dir string, err error) { mainDir, mainOK := dirInModule(path, targetPrefix, ModRoot(), true) vendorDir, vendorOK := dirInModule(path, "", filepath.Join(ModRoot(), "vendor"), false) if mainOK && vendorOK { - return module.Version{}, "", fmt.Errorf("ambiguous import: found %s in multiple directories:\n\t%s\n\t%s", path, mainDir, vendorDir) + return module.Version{}, "", &AmbiguousImportError{ImportPath: path, Dirs: []string{mainDir, vendorDir}} } // Prefer to return main directory if there is one, // Note that we're not checking that the package exists. @@ -97,7 +143,7 @@ func Import(path string) (m module.Version, dir string, err error) { return Target, mainDir, nil } readVendorList() - return vendorMap[path], vendorDir, nil + return vendorPkgModule[path], vendorDir, nil } // Check each module on the build list. @@ -128,22 +174,26 @@ func Import(path string) (m module.Version, dir string, err error) { return mods[0], dirs[0], nil } if len(mods) > 0 { - var buf bytes.Buffer - fmt.Fprintf(&buf, "ambiguous import: found %s in multiple modules:", path) - for i, m := range mods { - fmt.Fprintf(&buf, "\n\t%s", m.Path) - if m.Version != "" { - fmt.Fprintf(&buf, " %s", m.Version) - } - fmt.Fprintf(&buf, " (%s)", dirs[i]) - } - return module.Version{}, "", errors.New(buf.String()) + return module.Version{}, "", &AmbiguousImportError{ImportPath: path, Dirs: dirs, Modules: mods} } // Look up module containing the package, for addition to the build list. // Goal is to determine the module, download it to dir, and return m, dir, ErrMissing. if cfg.BuildMod == "readonly" { - return module.Version{}, "", fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod) + var queryErr error + if !pathIsStd { + if cfg.BuildModReason == "" { + queryErr = fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod) + } + queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason) + } + return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: queryErr} + } + if modRoot == "" && !allowMissingModuleImports { + return module.Version{}, "", &ImportMissingError{ + Path: path, + QueryErr: errors.New("working directory is not part of a module"), + } } // Not on build list. @@ -187,9 +237,31 @@ func Import(path string) (m module.Version, dir string, err error) { } _, ok := dirInModule(path, m.Path, root, isLocal) if ok { - return m, "", &ImportMissingError{ImportPath: path, Module: m} + return m, "", &ImportMissingError{Path: path, Module: m} } } + if len(mods) > 0 && module.CheckPath(path) != nil { + // The package path is not valid to fetch remotely, + // so it can only exist if in a replaced module, + // and we know from the above loop that it is not. + return module.Version{}, "", &PackageNotInModuleError{ + Mod: mods[0], + Query: "latest", + Pattern: path, + Replacement: Replacement(mods[0]), + } + } + } + + if pathIsStd { + // This package isn't in the standard library, isn't in any module already + // in the build list, and isn't in any other module that the user has + // shimmed in via a "replace" directive. + // Moreover, the import path is reserved for the standard library, so + // QueryPackage cannot possibly find a module containing this package. + // + // Instead of trying QueryPackage, report an ImportMissingError immediately. + return module.Version{}, "", &ImportMissingError{Path: path} } candidates, err := QueryPackage(path, "latest", Allowed) @@ -197,7 +269,7 @@ func Import(path string) (m module.Version, dir string, err error) { if errors.Is(err, os.ErrNotExist) { // Return "cannot find module providing package […]" instead of whatever // low-level error QueryPackage produced. - return module.Version{}, "", &ImportMissingError{ImportPath: path} + return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: err} } else { return module.Version{}, "", err } @@ -222,7 +294,7 @@ func Import(path string) (m module.Version, dir string, err error) { } } } - return m, "", &ImportMissingError{ImportPath: path, Module: m, newMissingVersion: newMissingVersion} + return m, "", &ImportMissingError{Path: path, Module: m, newMissingVersion: newMissingVersion} } // maybeInModule reports whether, syntactically, diff --git a/libgo/go/cmd/go/internal/modload/import_test.go b/libgo/go/cmd/go/internal/modload/import_test.go index c6ade5d17f4..accc60eecdf 100644 --- a/libgo/go/cmd/go/internal/modload/import_test.go +++ b/libgo/go/cmd/go/internal/modload/import_test.go @@ -21,7 +21,7 @@ var importTests = []struct { }, { path: "golang.org/x/net", - err: "module golang.org/x/net@.* found, but does not contain package golang.org/x/net", + err: `module golang.org/x/net@.* found \(v0.0.0-.*\), but does not contain package golang.org/x/net`, }, { path: "golang.org/x/text", @@ -44,6 +44,10 @@ var importTests = []struct { func TestImport(t *testing.T) { testenv.MustHaveExternalNetwork(t) testenv.MustHaveExecPath(t, "git") + defer func(old bool) { + allowMissingModuleImports = old + }(allowMissingModuleImports) + AllowMissingModuleImports() for _, tt := range importTests { t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) { diff --git a/libgo/go/cmd/go/internal/modload/init.go b/libgo/go/cmd/go/internal/modload/init.go index 807ce8d5dc5..61cbdf2c543 100644 --- a/libgo/go/cmd/go/internal/modload/init.go +++ b/libgo/go/cmd/go/internal/modload/init.go @@ -7,6 +7,7 @@ package modload import ( "bytes" "encoding/json" + "errors" "fmt" "go/build" "internal/lazyregexp" @@ -22,26 +23,24 @@ import ( "cmd/go/internal/cache" "cmd/go/internal/cfg" "cmd/go/internal/load" + "cmd/go/internal/lockedfile" "cmd/go/internal/modconv" "cmd/go/internal/modfetch" "cmd/go/internal/modfetch/codehost" - "cmd/go/internal/modfile" - "cmd/go/internal/module" "cmd/go/internal/mvs" - "cmd/go/internal/renameio" "cmd/go/internal/search" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) var ( - cwd string // TODO(bcmills): Is this redundant with base.Cwd? mustUseModules = false initialized bool - modRoot string - modFile *modfile.File - modFileData []byte - excluded map[module.Version]bool - Target module.Version + modRoot string + Target module.Version // targetPrefix is the path prefix for packages in Target, without a trailing // slash. For most modules, targetPrefix is just Target.Path, but the @@ -56,8 +55,31 @@ var ( CmdModInit bool // running 'go mod init' CmdModModule string // module argument for 'go mod init' + + allowMissingModuleImports bool ) +var modFile *modfile.File + +// A modFileIndex is an index of data corresponding to a modFile +// at a specific point in time. +type modFileIndex struct { + data []byte + dataNeedsFix bool // true if fixVersion applied a change while parsing data + module module.Version + goVersion string + require map[module.Version]requireMeta + replace map[module.Version]module.Version + exclude map[module.Version]bool +} + +// index is the index of the go.mod file as of when it was last read or written. +var index *modFileIndex + +type requireMeta struct { + indirect bool +} + // ModFile returns the parsed go.mod file. // // Note that after calling ImportPaths or LoadBuildList, @@ -89,6 +111,9 @@ func Init() { } initialized = true + // Keep in sync with WillBeEnabled. We perform extra validation here, and + // there are lots of diagnostics and side effects, so we can't use + // WillBeEnabled directly. env := cfg.Getenv("GO111MODULE") switch env { default: @@ -129,18 +154,15 @@ func Init() { os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no") } - var err error - cwd, err = os.Getwd() - if err != nil { - base.Fatalf("go: %v", err) - } - if CmdModInit { // Running 'go mod init': go.mod will be created in current directory. - modRoot = cwd + modRoot = base.Cwd } else { - modRoot = findModuleRoot(cwd) + modRoot = findModuleRoot(base.Cwd) if modRoot == "" { + if cfg.ModFile != "" { + base.Fatalf("go: cannot find main module, but -modfile was set.\n\t-modfile cannot be used to set the module root directory.") + } if !mustUseModules { // GO111MODULE is 'auto', and we can't find a module root. // Stay in GOPATH mode. @@ -156,6 +178,9 @@ func Init() { fmt.Fprintf(os.Stderr, "go: warning: ignoring go.mod in system temp root %v\n", os.TempDir()) } } + if cfg.ModFile != "" && !strings.HasSuffix(cfg.ModFile, ".mod") { + base.Fatalf("go: -modfile=%s: file does not have .mod extension", cfg.ModFile) + } // We're in module mode. Install the hooks to make it work. @@ -198,30 +223,23 @@ func Init() { if modRoot == "" { // We're in module mode, but not inside a module. // - // If the command is 'go get' or 'go list' and all of the args are in the - // same existing module, we could use that module's download directory in - // the module cache as the module root, applying any replacements and/or - // exclusions specified by that module. However, that would leave us in a - // strange state: we want 'go get' to be consistent with 'go list', and 'go - // list' should be able to operate on multiple modules. Moreover, the 'get' - // target might specify relative file paths (e.g. in the same repository) as - // replacements, and we would not be able to apply those anyway: we would - // need to either error out or ignore just those replacements, when a build - // from an empty module could proceed without error. + // Commands like 'go build', 'go run', 'go list' have no go.mod file to + // read or write. They would need to find and download the latest versions + // of a potentially large number of modules with no way to save version + // information. We can succeed slowly (but not reproducibly), but that's + // not usually a good experience. // - // Instead, we'll operate as though we're in some ephemeral external module, - // ignoring all replacements and exclusions uniformly. - - // Normally we check sums using the go.sum file from the main module, but - // without a main module we do not have an authoritative go.sum file. + // Instead, we forbid resolving import paths to modules other than std and + // cmd. Users may still build packages specified with .go files on the + // command line, but they'll see an error if those files import anything + // outside std. // - // TODO(bcmills): In Go 1.13, check sums when outside the main module. + // This can be overridden by calling AllowMissingModuleImports. + // For example, 'go get' does this, since it is expected to resolve paths. // - // One possible approach is to merge the go.sum files from all of the - // modules we download: that doesn't protect us against bad top-level - // modules, but it at least ensures consistency for transitive dependencies. + // See golang.org/issue/32027. } else { - modfetch.GoSumFile = filepath.Join(modRoot, "go.sum") + modfetch.GoSumFile = strings.TrimSuffix(ModFilePath(), ".mod") + ".sum" search.SetModRoot(modRoot) } } @@ -237,6 +255,54 @@ func init() { } } +// WillBeEnabled checks whether modules should be enabled but does not +// initialize modules by installing hooks. If Init has already been called, +// WillBeEnabled returns the same result as Enabled. +// +// This function is needed to break a cycle. The main package needs to know +// whether modules are enabled in order to install the module or GOPATH version +// of 'go get', but Init reads the -modfile flag in 'go get', so it shouldn't +// be called until the command is installed and flags are parsed. Instead of +// calling Init and Enabled, the main package can call this function. +func WillBeEnabled() bool { + if modRoot != "" || mustUseModules { + return true + } + if initialized { + return false + } + + // Keep in sync with Init. Init does extra validation and prints warnings or + // exits, so it can't call this function directly. + env := cfg.Getenv("GO111MODULE") + switch env { + case "on": + return true + case "auto", "": + break + default: + return false + } + + if CmdModInit { + // Running 'go mod init': go.mod will be created in current directory. + return true + } + if modRoot := findModuleRoot(base.Cwd); modRoot == "" { + // GO111MODULE is 'auto', and we can't find a module root. + // Stay in GOPATH mode. + return false + } else if search.InDir(modRoot, os.TempDir()) == "." { + // If you create /tmp/go.mod for experimenting, + // then any tests that create work directories under /tmp + // will find it and get modules when they're not expecting them. + // It's a bit of a peculiar thing to disallow but quite mysterious + // when it happens. See golang.org/issue/26708. + return false + } + return true +} + // Enabled reports whether modules are (or must be) enabled. // If modules are enabled but there is no main module, Enabled returns true // and then the first use of module information will call die @@ -263,6 +329,20 @@ func HasModRoot() bool { return modRoot != "" } +// ModFilePath returns the effective path of the go.mod file. Normally, this +// "go.mod" in the directory returned by ModRoot, but the -modfile flag may +// change its location. ModFilePath calls base.Fatalf if there is no main +// module, even if -modfile is set. +func ModFilePath() string { + if !HasModRoot() { + die() + } + if cfg.ModFile != "" { + return cfg.ModFile + } + return filepath.Join(modRoot, "go.mod") +} + // printStackInDie causes die to print a stack trace. // // It is enabled by the testgo tag, and helps to diagnose paths that @@ -276,24 +356,25 @@ func die() { if cfg.Getenv("GO111MODULE") == "off" { base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") } - if cwd != "" { - if dir, name := findAltConfig(cwd); dir != "" { - rel, err := filepath.Rel(cwd, dir) - if err != nil { - rel = dir - } - cdCmd := "" - if rel != "." { - cdCmd = fmt.Sprintf("cd %s && ", rel) - } - base.Fatalf("go: cannot find main module, but found %s in %s\n\tto create a module there, run:\n\t%sgo mod init", name, dir, cdCmd) + if dir, name := findAltConfig(base.Cwd); dir != "" { + rel, err := filepath.Rel(base.Cwd, dir) + if err != nil { + rel = dir } + cdCmd := "" + if rel != "." { + cdCmd = fmt.Sprintf("cd %s && ", rel) + } + base.Fatalf("go: cannot find main module, but found %s in %s\n\tto create a module there, run:\n\t%sgo mod init", name, dir, cdCmd) } base.Fatalf("go: cannot find main module; see 'go help modules'") } // InitMod sets Target and, if there is a main module, parses the initial build // list from its go.mod file, creating and populating that file if needed. +// +// As a side-effect, InitMod sets a default for cfg.BuildMod if it does not +// already have an explicit value. func InitMod() { if len(buildList) > 0 { return @@ -315,19 +396,20 @@ func InitMod() { return } - gomod := filepath.Join(modRoot, "go.mod") - data, err := renameio.ReadFile(gomod) + gomod := ModFilePath() + data, err := lockedfile.Read(gomod) if err != nil { base.Fatalf("go: %v", err) } - f, err := modfile.Parse(gomod, data, fixVersion) + var fixed bool + f, err := modfile.Parse(gomod, data, fixVersion(&fixed)) if err != nil { // Errors returned by modfile.Parse begin with file:line. base.Fatalf("go: errors parsing go.mod:\n%s\n", err) } modFile = f - modFileData = data + index = indexModFile(data, f, fixed) if len(f.Syntax.Stmt) == 0 || f.Module == nil { // Empty mod file. Must add module path. @@ -344,20 +426,77 @@ func InitMod() { legacyModInit() } - excluded = make(map[module.Version]bool) - for _, x := range f.Exclude { - excluded[x.Mod] = true - } modFileToBuildList() - stdVendorMode() - WriteGoMod() + setDefaultBuildMod() + if cfg.BuildMod == "vendor" { + readVendorList() + checkVendorConsistency() + } else { + // TODO(golang.org/issue/33326): if cfg.BuildMod != "readonly"? + WriteGoMod() + } +} + +// fixVersion returns a modfile.VersionFixer implemented using the Query function. +// +// It resolves commit hashes and branch names to versions, +// canonicalizes versions that appeared in early vgo drafts, +// and does nothing for versions that already appear to be canonical. +// +// The VersionFixer sets 'fixed' if it ever returns a non-canonical version. +func fixVersion(fixed *bool) modfile.VersionFixer { + return func(path, vers string) (resolved string, err error) { + defer func() { + if err == nil && resolved != vers { + *fixed = true + } + }() + + // Special case: remove the old -gopkgin- hack. + if strings.HasPrefix(path, "gopkg.in/") && strings.Contains(vers, "-gopkgin-") { + vers = vers[strings.Index(vers, "-gopkgin-")+len("-gopkgin-"):] + } + + // fixVersion is called speculatively on every + // module, version pair from every go.mod file. + // Avoid the query if it looks OK. + _, pathMajor, ok := module.SplitPathVersion(path) + if !ok { + return "", &module.ModuleError{ + Path: path, + Err: &module.InvalidVersionError{ + Version: vers, + Err: fmt.Errorf("malformed module path %q", path), + }, + } + } + if vers != "" && module.CanonicalVersion(vers) == vers { + if err := module.CheckPathMajor(vers, pathMajor); err == nil { + return vers, nil + } + } + + info, err := Query(path, vers, "", nil) + if err != nil { + return "", err + } + return info.Version, nil + } +} + +// AllowMissingModuleImports allows import paths to be resolved to modules +// when there is no module root. Normally, this is forbidden because it's slow +// and there's no way to make the result reproducible, but some commands +// like 'go get' are expected to do this. +func AllowMissingModuleImports() { + allowMissingModuleImports = true } // modFileToBuildList initializes buildList from the modFile. func modFileToBuildList() { Target = modFile.Module.Mod targetPrefix = Target.Path - if rel := search.InDir(cwd, cfg.GOROOTsrc); rel != "" { + if rel := search.InDir(base.Cwd, cfg.GOROOTsrc); rel != "" { targetInGorootSrc = true if Target.Path == "std" { targetPrefix = "" @@ -371,45 +510,144 @@ func modFileToBuildList() { buildList = list } -// stdVendorMode applies inside $GOROOT/src. -// It checks that the go.mod matches vendor/modules.txt -// and then sets -mod=vendor unless this is a command -// that has to do explicitly with modules. -func stdVendorMode() { - if !targetInGorootSrc { +// setDefaultBuildMod sets a default value for cfg.BuildMod +// if it is currently empty. +func setDefaultBuildMod() { + if cfg.BuildMod != "" { + // Don't override an explicit '-mod=' argument. return } + cfg.BuildMod = "mod" if cfg.CmdName == "get" || strings.HasPrefix(cfg.CmdName, "mod ") { + // Don't set -mod implicitly for commands whose purpose is to + // manipulate the build list. + return + } + if modRoot == "" { return } + if fi, err := os.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() { + modGo := "unspecified" + if index.goVersion != "" { + if semver.Compare("v"+index.goVersion, "v1.14") >= 0 { + // The Go version is at least 1.14, and a vendor directory exists. + // Set -mod=vendor by default. + cfg.BuildMod = "vendor" + cfg.BuildModReason = "Go version in go.mod is at least 1.14 and vendor directory exists." + return + } else { + modGo = index.goVersion + } + } + + // Since a vendor directory exists, we have a non-trivial reason for + // choosing -mod=mod, although it probably won't be used for anything. + // Record the reason anyway for consistency. + // It may be overridden if we switch to mod=readonly below. + cfg.BuildModReason = fmt.Sprintf("Go version in go.mod is %s.", modGo) + } + + p := ModFilePath() + if fi, err := os.Stat(p); err == nil && !hasWritePerm(p, fi) { + cfg.BuildMod = "readonly" + cfg.BuildModReason = "go.mod file is read-only." + } +} + +// checkVendorConsistency verifies that the vendor/modules.txt file matches (if +// go 1.14) or at least does not contradict (go 1.13 or earlier) the +// requirements and replacements listed in the main module's go.mod file. +func checkVendorConsistency() { readVendorList() -BuildList: - for _, m := range buildList { - if m.Path == "cmd" || m.Path == "std" { - continue + + pre114 := false + if modFile.Go == nil || semver.Compare("v"+modFile.Go.Version, "v1.14") < 0 { + // Go versions before 1.14 did not include enough information in + // vendor/modules.txt to check for consistency. + // If we know that we're on an earlier version, relax the consistency check. + pre114 = true + } + + vendErrors := new(strings.Builder) + vendErrorf := func(mod module.Version, format string, args ...interface{}) { + detail := fmt.Sprintf(format, args...) + if mod.Version == "" { + fmt.Fprintf(vendErrors, "\n\t%s: %s", mod.Path, detail) + } else { + fmt.Fprintf(vendErrors, "\n\t%s@%s: %s", mod.Path, mod.Version, detail) } - for _, v := range vendorList { - if m.Path == v.Path { - if m.Version != v.Version { - base.Fatalf("go: inconsistent vendoring in %s:\n"+ - "\tgo.mod requires %s %s but vendor/modules.txt has %s.\n"+ - "\trun 'go mod tidy; go mod vendor' to sync", - modRoot, m.Path, m.Version, v.Version) + } + + for _, r := range modFile.Require { + if !vendorMeta[r.Mod].Explicit { + if pre114 { + // Before 1.14, modules.txt did not indicate whether modules were listed + // explicitly in the main module's go.mod file. + // However, we can at least detect a version mismatch if packages were + // vendored from a non-matching version. + if vv, ok := vendorVersion[r.Mod.Path]; ok && vv != r.Mod.Version { + vendErrorf(r.Mod, fmt.Sprintf("is explicitly required in go.mod, but vendor/modules.txt indicates %s@%s", r.Mod.Path, vv)) } - continue BuildList + } else { + vendErrorf(r.Mod, "is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt") + } + } + } + + describe := func(m module.Version) string { + if m.Version == "" { + return m.Path + } + return m.Path + "@" + m.Version + } + + // We need to verify *all* replacements that occur in modfile: even if they + // don't directly apply to any module in the vendor list, the replacement + // go.mod file can affect the selected versions of other (transitive) + // dependencies + for _, r := range modFile.Replace { + vr := vendorMeta[r.Old].Replacement + if vr == (module.Version{}) { + if pre114 && (r.Old.Version == "" || vendorVersion[r.Old.Path] != r.Old.Version) { + // Before 1.14, modules.txt omitted wildcard replacements and + // replacements for modules that did not have any packages to vendor. + } else { + vendErrorf(r.Old, "is replaced in go.mod, but not marked as replaced in vendor/modules.txt") + } + } else if vr != r.New { + vendErrorf(r.Old, "is replaced by %s in go.mod, but marked as replaced by %s in vendor/modules.txt", describe(r.New), describe(vr)) + } + } + + for _, mod := range vendorList { + meta := vendorMeta[mod] + if meta.Explicit { + if _, inGoMod := index.require[mod]; !inGoMod { + vendErrorf(mod, "is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod") } } - base.Fatalf("go: inconsistent vendoring in %s:\n"+ - "\tgo.mod requires %s %s but vendor/modules.txt does not include it.\n"+ - "\trun 'go mod tidy; go mod vendor' to sync", modRoot, m.Path, m.Version) } - cfg.BuildMod = "vendor" + + for _, mod := range vendorReplaced { + r := Replacement(mod) + if r == (module.Version{}) { + vendErrorf(mod, "is marked as replaced in vendor/modules.txt, but not replaced in go.mod") + continue + } + if meta := vendorMeta[mod]; r != meta.Replacement { + vendErrorf(mod, "is marked as replaced by %s in vendor/modules.txt, but replaced by %s in go.mod", describe(meta.Replacement), describe(r)) + } + } + + if vendErrors.Len() > 0 { + base.Fatalf("go: inconsistent vendoring in %s:%s\n\nrun 'go mod vendor' to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory", modRoot, vendErrors) + } } // Allowed reports whether module m is allowed (not excluded) by the main module's go.mod. func Allowed(m module.Version) bool { - return !excluded[m] + return index == nil || !index.exclude[m] } func legacyModInit() { @@ -478,6 +716,9 @@ var altConfigs = []string{ } func findModuleRoot(dir string) (root string) { + if dir == "" { + panic("dir not set") + } dir = filepath.Clean(dir) // Look for enclosing go.mod. @@ -495,6 +736,9 @@ func findModuleRoot(dir string) (root string) { } func findAltConfig(dir string) (root, name string) { + if dir == "" { + panic("dir not set") + } dir = filepath.Clean(dir) for { for _, name := range altConfigs { @@ -625,16 +869,17 @@ func AllowWriteGoMod() { allowWriteGoMod = true } -// MinReqs returns a Reqs with minimal dependencies of Target, +// MinReqs returns a Reqs with minimal additional dependencies of Target, // as will be written to go.mod. func MinReqs() mvs.Reqs { - var direct []string + var retain []string for _, m := range buildList[1:] { - if loaded.direct[m.Path] { - direct = append(direct, m.Path) + _, explicit := index.require[m] + if explicit || loaded.direct[m.Path] { + retain = append(retain, m.Path) } } - min, err := mvs.Req(Target, buildList, direct, Reqs()) + min, err := mvs.Req(Target, retain, Reqs()) if err != nil { base.Fatalf("go: %v", err) } @@ -655,7 +900,9 @@ func WriteGoMod() { return } - addGoStmt() + if cfg.BuildMod != "readonly" { + addGoStmt() + } if loaded != nil { reqs := MinReqs() @@ -672,87 +919,177 @@ func WriteGoMod() { } modFile.SetRequire(list) } + modFile.Cleanup() - modFile.Cleanup() // clean file after edits - new, err := modFile.Format() - if err != nil { - base.Fatalf("go: %v", err) - } - - dirty := !bytes.Equal(new, modFileData) + dirty := index.modFileIsDirty(modFile) if dirty && cfg.BuildMod == "readonly" { // If we're about to fail due to -mod=readonly, // prefer to report a dirty go.mod over a dirty go.sum - base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly") + if cfg.BuildModReason != "" { + base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly\n\t(%s)", cfg.BuildModReason) + } else { + base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly") + } } // Always update go.sum, even if we didn't change go.mod: we may have // downloaded modules that we didn't have before. modfetch.WriteGoSum() - if !dirty { - // We don't need to modify go.mod from what we read previously. + if !dirty && cfg.CmdName != "mod tidy" { + // The go.mod file has the same semantic content that it had before + // (but not necessarily the same exact bytes). // Ignore any intervening edits. return } - unlock := modfetch.SideLock() - defer unlock() + new, err := modFile.Format() + if err != nil { + base.Fatalf("go: %v", err) + } + defer func() { + // At this point we have determined to make the go.mod file on disk equal to new. + index = indexModFile(new, modFile, false) + }() + + // Make a best-effort attempt to acquire the side lock, only to exclude + // previous versions of the 'go' command from making simultaneous edits. + if unlock, err := modfetch.SideLock(); err == nil { + defer unlock() + } - file := filepath.Join(modRoot, "go.mod") - old, err := renameio.ReadFile(file) - if !bytes.Equal(old, modFileData) { + errNoChange := errors.New("no update needed") + + err = lockedfile.Transform(ModFilePath(), func(old []byte) ([]byte, error) { if bytes.Equal(old, new) { - // Some other process wrote the same go.mod file that we were about to write. - modFileData = new - return + // The go.mod file is already equal to new, possibly as the result of some + // other process. + return nil, errNoChange } - if err != nil { - base.Fatalf("go: can't determine whether go.mod has changed: %v", err) + + if index != nil && !bytes.Equal(old, index.data) { + // The contents of the go.mod file have changed. In theory we could add all + // of the new modules to the build list, recompute, and check whether any + // module in *our* build list got bumped to a different version, but that's + // a lot of work for marginal benefit. Instead, fail the command: if users + // want to run concurrent commands, they need to start with a complete, + // consistent module definition. + return nil, fmt.Errorf("existing contents have changed since last read") } - // The contents of the go.mod file have changed. In theory we could add all - // of the new modules to the build list, recompute, and check whether any - // module in *our* build list got bumped to a different version, but that's - // a lot of work for marginal benefit. Instead, fail the command: if users - // want to run concurrent commands, they need to start with a complete, - // consistent module definition. - base.Fatalf("go: updates to go.mod needed, but contents have changed") + return new, nil + }) + + if err != nil && err != errNoChange { + base.Fatalf("go: updating go.mod: %v", err) + } +} + +// indexModFile rebuilds the index of modFile. +// If modFile has been changed since it was first read, +// modFile.Cleanup must be called before indexModFile. +func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileIndex { + i := new(modFileIndex) + i.data = data + i.dataNeedsFix = needsFix + + i.module = module.Version{} + if modFile.Module != nil { + i.module = modFile.Module.Mod + } + + i.goVersion = "" + if modFile.Go != nil { + i.goVersion = modFile.Go.Version + } + + i.require = make(map[module.Version]requireMeta, len(modFile.Require)) + for _, r := range modFile.Require { + i.require[r.Mod] = requireMeta{indirect: r.Indirect} + } + + i.replace = make(map[module.Version]module.Version, len(modFile.Replace)) + for _, r := range modFile.Replace { + if prev, dup := i.replace[r.Old]; dup && prev != r.New { + base.Fatalf("go: conflicting replacements for %v:\n\t%v\n\t%v", r.Old, prev, r.New) + } + i.replace[r.Old] = r.New } - if err := renameio.WriteFile(file, new, 0666); err != nil { - base.Fatalf("error writing go.mod: %v", err) + i.exclude = make(map[module.Version]bool, len(modFile.Exclude)) + for _, x := range modFile.Exclude { + i.exclude[x.Mod] = true } - modFileData = new + + return i } -func fixVersion(path, vers string) (string, error) { - // Special case: remove the old -gopkgin- hack. - if strings.HasPrefix(path, "gopkg.in/") && strings.Contains(vers, "-gopkgin-") { - vers = vers[strings.Index(vers, "-gopkgin-")+len("-gopkgin-"):] +// modFileIsDirty reports whether the go.mod file differs meaningfully +// from what was indexed. +// If modFile has been changed (even cosmetically) since it was first read, +// modFile.Cleanup must be called before modFileIsDirty. +func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool { + if i == nil { + return modFile != nil + } + + if i.dataNeedsFix { + return true } - // fixVersion is called speculatively on every - // module, version pair from every go.mod file. - // Avoid the query if it looks OK. - _, pathMajor, ok := module.SplitPathVersion(path) - if !ok { - return "", &module.ModuleError{ - Path: path, - Err: &module.InvalidVersionError{ - Version: vers, - Err: fmt.Errorf("malformed module path %q", path), - }, + if modFile.Module == nil { + if i.module != (module.Version{}) { + return true } + } else if modFile.Module.Mod != i.module { + return true } - if vers != "" && module.CanonicalVersion(vers) == vers { - if err := module.MatchPathMajor(vers, pathMajor); err == nil { - return vers, nil + + if modFile.Go == nil { + if i.goVersion != "" { + return true + } + } else if modFile.Go.Version != i.goVersion { + if i.goVersion == "" && cfg.BuildMod == "readonly" { + // go.mod files did not always require a 'go' version, so do not error out + // if one is missing — we may be inside an older module in the module + // cache, and should bias toward providing useful behavior. + } else { + return true } } - info, err := Query(path, vers, "", nil) - if err != nil { - return "", err + if len(modFile.Require) != len(i.require) || + len(modFile.Replace) != len(i.replace) || + len(modFile.Exclude) != len(i.exclude) { + return true + } + + for _, r := range modFile.Require { + if meta, ok := i.require[r.Mod]; !ok { + return true + } else if r.Indirect != meta.indirect { + if cfg.BuildMod == "readonly" { + // The module's requirements are consistent; only the "// indirect" + // comments that are wrong. But those are only guaranteed to be accurate + // after a "go mod tidy" — it's a good idea to run those before + // committing a change, but it's certainly not mandatory. + } else { + return true + } + } + } + + for _, r := range modFile.Replace { + if r.New != i.replace[r.Old] { + return true + } } - return info.Version, nil + + for _, x := range modFile.Exclude { + if !i.exclude[x.Mod] { + return true + } + } + + return false } diff --git a/libgo/go/cmd/go/internal/modload/list.go b/libgo/go/cmd/go/internal/modload/list.go index 35d0c28cde1..9400793bcb2 100644 --- a/libgo/go/cmd/go/internal/modload/list.go +++ b/libgo/go/cmd/go/internal/modload/list.go @@ -11,10 +11,12 @@ import ( "strings" "cmd/go/internal/base" + "cmd/go/internal/cfg" "cmd/go/internal/modinfo" - "cmd/go/internal/module" "cmd/go/internal/par" "cmd/go/internal/search" + + "golang.org/x/mod/module" ) func ListModules(args []string, listU, listVersions bool) []*modinfo.ModulePublic { @@ -55,6 +57,9 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic { if search.IsRelativePath(arg) { base.Fatalf("go: cannot use relative path %s to specify module", arg) } + if !HasModRoot() && (arg == "all" || strings.Contains(arg, "...")) { + base.Fatalf("go: cannot match %q: working directory is not part of a module", arg) + } if i := strings.Index(arg, "@"); i >= 0 { path := arg[:i] vers := arg[i+1:] @@ -121,10 +126,20 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic { } continue } - mods = append(mods, &modinfo.ModulePublic{ - Path: arg, - Error: modinfoError(arg, "", errors.New("not a known dependency")), - }) + if cfg.BuildMod == "vendor" { + // In vendor mode, we can't determine whether a missing module is “a + // known dependency” because the module graph is incomplete. + // Give a more explicit error message. + mods = append(mods, &modinfo.ModulePublic{ + Path: arg, + Error: modinfoError(arg, "", errors.New("can't resolve module using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)")), + }) + } else { + mods = append(mods, &modinfo.ModulePublic{ + Path: arg, + Error: modinfoError(arg, "", errors.New("not a known dependency")), + }) + } } else { fmt.Fprintf(os.Stderr, "warning: pattern %q matched no module dependencies\n", arg) } diff --git a/libgo/go/cmd/go/internal/modload/load.go b/libgo/go/cmd/go/internal/modload/load.go index d18723e7dcd..408c79022b4 100644 --- a/libgo/go/cmd/go/internal/modload/load.go +++ b/libgo/go/cmd/go/internal/modload/load.go @@ -22,13 +22,14 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/imports" "cmd/go/internal/modfetch" - "cmd/go/internal/modfile" - "cmd/go/internal/module" "cmd/go/internal/mvs" "cmd/go/internal/par" "cmd/go/internal/search" - "cmd/go/internal/semver" "cmd/go/internal/str" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) // buildList is the list of modules to use for building packages. @@ -93,11 +94,11 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { pkgs := m.Pkgs m.Pkgs = m.Pkgs[:0] for _, pkg := range pkgs { - dir := pkg - if !filepath.IsAbs(dir) { - dir = filepath.Join(cwd, pkg) + var dir string + if !filepath.IsAbs(pkg) { + dir = filepath.Join(base.Cwd, pkg) } else { - dir = filepath.Clean(dir) + dir = filepath.Clean(pkg) } // golang.org/issue/32917: We should resolve a relative path to a @@ -211,11 +212,17 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { // One last pass to finalize wildcards. updateMatches(matches, false) + checkMultiplePaths() + WriteGoMod() + + return matches +} - // A given module path may be used as itself or as a replacement for another - // module, but not both at the same time. Otherwise, the aliasing behavior is - // too subtle (see https://golang.org/issue/26607), and we don't want to - // commit to a specific behavior at this point. +// checkMultiplePaths verifies that a given module path is used as itself +// or as a replacement for another module, but not both at the same time. +// +// (See https://golang.org/issue/26607 and https://golang.org/issue/34650.) +func checkMultiplePaths() { firstPath := make(map[module.Version]string, len(buildList)) for _, mod := range buildList { src := mod @@ -229,9 +236,6 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { } } base.ExitIfErrors() - WriteGoMod() - - return matches } // pathInModuleCache returns the import path of the directory dir, @@ -318,7 +322,7 @@ func DirImportPath(dir string) string { } if !filepath.IsAbs(dir) { - dir = filepath.Join(cwd, dir) + dir = filepath.Join(base.Cwd, dir) } else { dir = filepath.Clean(dir) } @@ -383,6 +387,7 @@ func loadAll(testAll bool) []string { } all := TargetPackages("...") loaded.load(func() []string { return all }) + checkMultiplePaths() WriteGoMod() var paths []string @@ -401,6 +406,10 @@ func loadAll(testAll bool) []string { // matching pattern, which may be relative to the working directory, under all // build tag settings. func TargetPackages(pattern string) []string { + // TargetPackages is relative to the main module, so ensure that the main + // module is a thing that can contain packages. + ModRoot() + return matchPackages(pattern, imports.AnyTags(), false, []module.Version{Target}) } @@ -419,6 +428,37 @@ func SetBuildList(list []module.Version) { buildList = append([]module.Version{}, list...) } +// TidyBuildList trims the build list to the minimal requirements needed to +// retain the same versions of all packages from the preceding Load* or +// ImportPaths* call. +func TidyBuildList() { + used := map[module.Version]bool{Target: true} + for _, pkg := range loaded.pkgs { + used[pkg.mod] = true + } + + keep := []module.Version{Target} + var direct []string + for _, m := range buildList[1:] { + if used[m] { + keep = append(keep, m) + if loaded.direct[m.Path] { + direct = append(direct, m.Path) + } + } else if cfg.BuildV { + if _, ok := index.require[m]; ok { + fmt.Fprintf(os.Stderr, "unused %s\n", m.Path) + } + } + } + + min, err := mvs.Req(Target, direct, &mvsReqs{buildList: keep}) + if err != nil { + base.Fatalf("go: %v", err) + } + buildList = append([]module.Version{Target}, min...) +} + // ImportMap returns the actual package import path // for an import path found in source code. // If the given import path does not appear in the source code @@ -621,6 +661,7 @@ func (ld *loader) load(roots func() []string) { added[pkg.path] = true numAdded++ if !haveMod[err.Module] { + fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, err.Module.Path, err.Module.Version) haveMod[err.Module] = true modAddedBy[err.Module] = pkg buildList = append(buildList, err.Module) @@ -960,21 +1001,15 @@ func WhyDepth(path string) int { // If there is no replacement for mod, Replacement returns // a module.Version with Path == "". func Replacement(mod module.Version) module.Version { - if modFile == nil { - // Happens during testing and if invoking 'go get' or 'go list' outside a module. - return module.Version{} - } - - var found *modfile.Replace - for _, r := range modFile.Replace { - if r.Old.Path == mod.Path && (r.Old.Version == "" || r.Old.Version == mod.Version) { - found = r // keep going + if index != nil { + if r, ok := index.replace[mod]; ok { + return r + } + if r, ok := index.replace[module.Version{Path: mod.Path}]; ok { + return r } } - if found == nil { - return module.Version{} - } - return found.New + return module.Version{} } // mvsReqs implements mvs.Reqs for module semantic versions, @@ -1007,15 +1042,17 @@ func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) { return cached{nil, err} } for i, mv := range list { - for excluded[mv] { - mv1, err := r.next(mv) - if err != nil { - return cached{nil, err} - } - if mv1.Version == "none" { - return cached{nil, fmt.Errorf("%s(%s) depends on excluded %s(%s) with no newer version available", mod.Path, mod.Version, mv.Path, mv.Version)} + if index != nil { + for index.exclude[mv] { + mv1, err := r.next(mv) + if err != nil { + return cached{nil, err} + } + if mv1.Version == "none" { + return cached{nil, fmt.Errorf("%s(%s) depends on excluded %s(%s) with no newer version available", mod.Path, mod.Version, mv.Path, mv.Version)} + } + mv = mv1 } - mv = mv1 } list[i] = mv } @@ -1028,30 +1065,106 @@ func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) { var vendorOnce sync.Once +type vendorMetadata struct { + Explicit bool + Replacement module.Version +} + var ( - vendorList []module.Version - vendorMap map[string]module.Version + vendorList []module.Version // modules that contribute packages to the build, in order of appearance + vendorReplaced []module.Version // all replaced modules; may or may not also contribute packages + vendorVersion map[string]string // module path → selected version (if known) + vendorPkgModule map[string]module.Version // package → containing module + vendorMeta map[module.Version]vendorMetadata ) // readVendorList reads the list of vendored modules from vendor/modules.txt. func readVendorList() { vendorOnce.Do(func() { vendorList = nil - vendorMap = make(map[string]module.Version) - data, _ := ioutil.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt")) - var m module.Version + vendorPkgModule = make(map[string]module.Version) + vendorVersion = make(map[string]string) + vendorMeta = make(map[module.Version]vendorMetadata) + data, err := ioutil.ReadFile(filepath.Join(ModRoot(), "vendor/modules.txt")) + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + base.Fatalf("go: %s", err) + } + return + } + + var mod module.Version for _, line := range strings.Split(string(data), "\n") { if strings.HasPrefix(line, "# ") { f := strings.Fields(line) - m = module.Version{} - if len(f) == 3 && semver.IsValid(f[2]) { - m = module.Version{Path: f[1], Version: f[2]} - vendorList = append(vendorList, m) + + if len(f) < 3 { + continue } - } else if m.Path != "" { - f := strings.Fields(line) - if len(f) == 1 { - vendorMap[f[0]] = m + if semver.IsValid(f[2]) { + // A module, but we don't yet know whether it is in the build list or + // only included to indicate a replacement. + mod = module.Version{Path: f[1], Version: f[2]} + f = f[3:] + } else if f[2] == "=>" { + // A wildcard replacement found in the main module's go.mod file. + mod = module.Version{Path: f[1]} + f = f[2:] + } else { + // Not a version or a wildcard replacement. + // We don't know how to interpret this module line, so ignore it. + mod = module.Version{} + continue + } + + if len(f) >= 2 && f[0] == "=>" { + meta := vendorMeta[mod] + if len(f) == 2 { + // File replacement. + meta.Replacement = module.Version{Path: f[1]} + vendorReplaced = append(vendorReplaced, mod) + } else if len(f) == 3 && semver.IsValid(f[2]) { + // Path and version replacement. + meta.Replacement = module.Version{Path: f[1], Version: f[2]} + vendorReplaced = append(vendorReplaced, mod) + } else { + // We don't understand this replacement. Ignore it. + } + vendorMeta[mod] = meta + } + continue + } + + // Not a module line. Must be a package within a module or a metadata + // directive, either of which requires a preceding module line. + if mod.Path == "" { + continue + } + + if strings.HasPrefix(line, "## ") { + // Metadata. Take the union of annotations across multiple lines, if present. + meta := vendorMeta[mod] + for _, entry := range strings.Split(strings.TrimPrefix(line, "## "), ";") { + entry = strings.TrimSpace(entry) + if entry == "explicit" { + meta.Explicit = true + } + // All other tokens are reserved for future use. + } + vendorMeta[mod] = meta + continue + } + + if f := strings.Fields(line); len(f) == 1 && module.CheckImportPath(f[0]) == nil { + // A package within the current module. + vendorPkgModule[f[0]] = mod + + // Since this module provides a package for the build, we know that it + // is in the build list and is the selected version of its path. + // If this information is new, record it. + if v, ok := vendorVersion[mod.Path]; !ok || semver.Compare(v, mod.Version) < 0 { + vendorList = append(vendorList, mod) + vendorVersion[mod.Path] = mod.Version } } } @@ -1082,19 +1195,6 @@ func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) { return append([]module.Version(nil), vendorList...), nil } - if targetInGorootSrc { - // When inside "std" or "cmd", only fetch and read go.mod files if we're - // explicitly running a command that can change the module graph. If we have - // to resolve a new dependency, we might pick the wrong version, but 'go mod - // tidy' will fix it — and new standard-library dependencies should be rare - // anyway. - // - // TODO(golang.org/issue/30240): Drop this special-case. - if cfg.CmdName != "get" && !strings.HasPrefix(cfg.CmdName, "mod ") { - return nil, nil - } - } - origPath := mod.Path if repl := Replacement(mod); repl.Path != "" { if repl.Version == "" { @@ -1209,6 +1309,11 @@ func (*mvsReqs) next(m module.Version) (module.Version, error) { return module.Version{Path: m.Path, Version: "none"}, nil } +// fetch downloads the given module (or its replacement) +// and returns its location. +// +// The isLocal return value reports whether the replacement, +// if any, is local to the filesystem. func fetch(mod module.Version) (dir string, isLocal bool, err error) { if mod == Target { return ModRoot(), true, nil diff --git a/libgo/go/cmd/go/internal/modload/query.go b/libgo/go/cmd/go/internal/modload/query.go index 602bf47275d..53278b91002 100644 --- a/libgo/go/cmd/go/internal/modload/query.go +++ b/libgo/go/cmd/go/internal/modload/query.go @@ -9,15 +9,18 @@ import ( "fmt" "os" pathpkg "path" + "path/filepath" "strings" "sync" + "cmd/go/internal/cfg" "cmd/go/internal/imports" "cmd/go/internal/modfetch" - "cmd/go/internal/module" "cmd/go/internal/search" - "cmd/go/internal/semver" "cmd/go/internal/str" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) // Query looks up a revision of a given module given a version query string. @@ -61,10 +64,24 @@ func Query(path, query, current string, allowed func(module.Version) bool) (*mod return info, err } +var errQueryDisabled error = queryDisabledError{} + +type queryDisabledError struct{} + +func (queryDisabledError) Error() string { + if cfg.BuildModReason == "" { + return fmt.Sprintf("cannot query module due to -mod=%s", cfg.BuildMod) + } + return fmt.Sprintf("cannot query module due to -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason) +} + func queryProxy(proxy, path, query, current string, allowed func(module.Version) bool) (*modfetch.RevInfo, error) { if current != "" && !semver.IsValid(current) { return nil, fmt.Errorf("invalid previous version %q", current) } + if cfg.BuildMod != "" && cfg.BuildMod != "mod" { + return nil, errQueryDisabled + } if allowed == nil { allowed = func(module.Version) bool { return true } } @@ -74,10 +91,20 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) badVersion := func(v string) (*modfetch.RevInfo, error) { return nil, fmt.Errorf("invalid semantic version %q in range %q", v, query) } - var ok func(module.Version) bool - var prefix string - var preferOlder bool - var mayUseLatest bool + matchesMajor := func(v string) bool { + _, pathMajor, ok := module.SplitPathVersion(path) + if !ok { + return false + } + return module.CheckPathMajor(v, pathMajor) == nil + } + var ( + ok func(module.Version) bool + prefix string + preferOlder bool + mayUseLatest bool + preferIncompatible bool = strings.HasSuffix(current, "+incompatible") + ) switch { case query == "latest": ok = allowed @@ -110,6 +137,9 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) ok = func(m module.Version) bool { return semver.Compare(m.Version, v) <= 0 && allowed(m) } + if !matchesMajor(v) { + preferIncompatible = true + } case strings.HasPrefix(query, "<"): v := query[len("<"):] @@ -119,6 +149,9 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) ok = func(m module.Version) bool { return semver.Compare(m.Version, v) < 0 && allowed(m) } + if !matchesMajor(v) { + preferIncompatible = true + } case strings.HasPrefix(query, ">="): v := query[len(">="):] @@ -129,6 +162,9 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) return semver.Compare(m.Version, v) >= 0 && allowed(m) } preferOlder = true + if !matchesMajor(v) { + preferIncompatible = true + } case strings.HasPrefix(query, ">"): v := query[len(">"):] @@ -143,12 +179,18 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) return semver.Compare(m.Version, v) > 0 && allowed(m) } preferOlder = true + if !matchesMajor(v) { + preferIncompatible = true + } case semver.IsValid(query) && isSemverPrefix(query): ok = func(m module.Version) bool { return matchSemverPrefix(query, m.Version) && allowed(m) } prefix = query + "." + if !matchesMajor(query) { + preferIncompatible = true + } default: // Direct lookup of semantic version or commit identifier. @@ -201,6 +243,10 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) if err != nil { return nil, err } + releases, prereleases, err := filterVersions(path, versions, ok, preferIncompatible) + if err != nil { + return nil, err + } lookup := func(v string) (*modfetch.RevInfo, error) { rev, err := repo.Stat(v) @@ -221,28 +267,18 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) } if preferOlder { - for _, v := range versions { - if semver.Prerelease(v) == "" && ok(module.Version{Path: path, Version: v}) { - return lookup(v) - } + if len(releases) > 0 { + return lookup(releases[0]) } - for _, v := range versions { - if semver.Prerelease(v) != "" && ok(module.Version{Path: path, Version: v}) { - return lookup(v) - } + if len(prereleases) > 0 { + return lookup(prereleases[0]) } } else { - for i := len(versions) - 1; i >= 0; i-- { - v := versions[i] - if semver.Prerelease(v) == "" && ok(module.Version{Path: path, Version: v}) { - return lookup(v) - } + if len(releases) > 0 { + return lookup(releases[len(releases)-1]) } - for i := len(versions) - 1; i >= 0; i-- { - v := versions[i] - if semver.Prerelease(v) != "" && ok(module.Version{Path: path, Version: v}) { - return lookup(v) - } + if len(prereleases) > 0 { + return lookup(prereleases[len(prereleases)-1]) } } @@ -286,6 +322,52 @@ func matchSemverPrefix(p, v string) bool { return len(v) > len(p) && v[len(p)] == '.' && v[:len(p)] == p && semver.Prerelease(v) == "" } +// filterVersions classifies versions into releases and pre-releases, filtering +// out: +// 1. versions that do not satisfy the 'ok' predicate, and +// 2. "+incompatible" versions, if a compatible one satisfies the predicate +// and the incompatible version is not preferred. +func filterVersions(path string, versions []string, ok func(module.Version) bool, preferIncompatible bool) (releases, prereleases []string, err error) { + var lastCompatible string + for _, v := range versions { + if !ok(module.Version{Path: path, Version: v}) { + continue + } + + if !preferIncompatible { + if !strings.HasSuffix(v, "+incompatible") { + lastCompatible = v + } else if lastCompatible != "" { + // If the latest compatible version is allowed and has a go.mod file, + // ignore any version with a higher (+incompatible) major version. (See + // https://golang.org/issue/34165.) Note that we even prefer a + // compatible pre-release over an incompatible release. + + ok, err := versionHasGoMod(module.Version{Path: path, Version: lastCompatible}) + if err != nil { + return nil, nil, err + } + if ok { + break + } + + // No acceptable compatible release has a go.mod file, so the versioning + // for the module might not be module-aware, and we should respect + // legacy major-version tags. + preferIncompatible = true + } + } + + if semver.Prerelease(v) != "" { + prereleases = append(prereleases, v) + } else { + releases = append(releases, v) + } + } + + return releases, prereleases, nil +} + type QueryResult struct { Mod module.Version Rev *modfetch.RevInfo @@ -381,9 +463,10 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q r.Packages = match(r.Mod, root, isLocal) if len(r.Packages) == 0 { return r, &PackageNotInModuleError{ - Mod: r.Mod, - Query: query, - Pattern: pattern, + Mod: r.Mod, + Replacement: Replacement(r.Mod), + Query: query, + Pattern: pattern, } } return r, nil @@ -471,7 +554,17 @@ func queryPrefixModules(candidateModules []string, queryModule func(path string) notExistErr = rErr } } else if err == nil { - err = r.err + if len(found) > 0 || noPackage != nil { + // golang.org/issue/34094: If we have already found a module that + // could potentially contain the target package, ignore unclassified + // errors for modules with shorter paths. + + // golang.org/issue/34383 is a special case of this: if we have + // already found example.com/foo/v2@v2.0.0 with a matching go.mod + // file, ignore the error from example.com/foo@v2.0.0. + } else { + err = r.err + } } } } @@ -526,21 +619,32 @@ func (e *NoMatchingVersionError) Error() string { // code for the versions it knows about, and thus did not have the opportunity // to return a non-400 status code to suppress fallback. type PackageNotInModuleError struct { - Mod module.Version - Query string - Pattern string + Mod module.Version + Replacement module.Version + Query string + Pattern string } func (e *PackageNotInModuleError) Error() string { found := "" - if e.Query != e.Mod.Version { + if r := e.Replacement; r.Path != "" { + replacement := r.Path + if r.Version != "" { + replacement = fmt.Sprintf("%s@%s", r.Path, r.Version) + } + if e.Query == e.Mod.Version { + found = fmt.Sprintf(" (replaced by %s)", replacement) + } else { + found = fmt.Sprintf(" (%s, replaced by %s)", e.Mod.Version, replacement) + } + } else if e.Query != e.Mod.Version { found = fmt.Sprintf(" (%s)", e.Mod.Version) } if strings.Contains(e.Pattern, "...") { - return fmt.Sprintf("module %s@%s%s found, but does not contain packages matching %s", e.Mod.Path, e.Query, found, e.Pattern) + return fmt.Sprintf("module %s@%s found%s, but does not contain packages matching %s", e.Mod.Path, e.Query, found, e.Pattern) } - return fmt.Sprintf("module %s@%s%s found, but does not contain package %s", e.Mod.Path, e.Query, found, e.Pattern) + return fmt.Sprintf("module %s@%s found%s, but does not contain package %s", e.Mod.Path, e.Query, found, e.Pattern) } // ModuleHasRootPackage returns whether module m contains a package m.Path. @@ -552,3 +656,12 @@ func ModuleHasRootPackage(m module.Version) (bool, error) { _, ok := dirInModule(m.Path, m.Path, root, isLocal) return ok, nil } + +func versionHasGoMod(m module.Version) (bool, error) { + root, _, err := fetch(m) + if err != nil { + return false, err + } + fi, err := os.Stat(filepath.Join(root, "go.mod")) + return err == nil && !fi.IsDir(), nil +} diff --git a/libgo/go/cmd/go/internal/modload/query_test.go b/libgo/go/cmd/go/internal/modload/query_test.go index b91cbb5a700..9c91c05e5f8 100644 --- a/libgo/go/cmd/go/internal/modload/query_test.go +++ b/libgo/go/cmd/go/internal/modload/query_test.go @@ -17,7 +17,8 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modfetch/codehost" - "cmd/go/internal/module" + + "golang.org/x/mod/module" ) func TestMain(m *testing.M) { diff --git a/libgo/go/cmd/go/internal/modload/search.go b/libgo/go/cmd/go/internal/modload/search.go index d82386eca30..a303f51858a 100644 --- a/libgo/go/cmd/go/internal/modload/search.go +++ b/libgo/go/cmd/go/internal/modload/search.go @@ -13,8 +13,9 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/imports" - "cmd/go/internal/module" "cmd/go/internal/search" + + "golang.org/x/mod/module" ) // matchPackages returns a list of packages in the list of modules @@ -48,16 +49,20 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules [] return nil } - // Don't use GOROOT/src but do walk down into it. - if path == root && importPathRoot == "" { - return nil - } - want := true - // Avoid .foo, _foo, and testdata directory trees. - _, elem := filepath.Split(path) - if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" { - want = false + elem := "" + + // Don't use GOROOT/src but do walk down into it. + if path == root { + if importPathRoot == "" { + return nil + } + } else { + // Avoid .foo, _foo, and testdata subdirectory trees. + _, elem = filepath.Split(path) + if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" { + want = false + } } name := importPathRoot + filepath.ToSlash(path[len(root):]) diff --git a/libgo/go/cmd/go/internal/modload/stat_openfile.go b/libgo/go/cmd/go/internal/modload/stat_openfile.go new file mode 100644 index 00000000000..931aaf1577b --- /dev/null +++ b/libgo/go/cmd/go/internal/modload/stat_openfile.go @@ -0,0 +1,27 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix js,wasm plan9 + +// On plan9, per http://9p.io/magic/man2html/2/access: “Since file permissions +// are checked by the server and group information is not known to the client, +// access must open the file to check permissions.” +// +// aix and js,wasm are similar, in that they do not define syscall.Access. + +package modload + +import ( + "os" +) + +// hasWritePerm reports whether the current user has permission to write to the +// file with the given info. +func hasWritePerm(path string, _ os.FileInfo) bool { + if f, err := os.OpenFile(path, os.O_WRONLY, 0); err == nil { + f.Close() + return true + } + return false +} diff --git a/libgo/go/cmd/go/internal/modload/stat_unix.go b/libgo/go/cmd/go/internal/modload/stat_unix.go new file mode 100644 index 00000000000..a53d17e93a8 --- /dev/null +++ b/libgo/go/cmd/go/internal/modload/stat_unix.go @@ -0,0 +1,31 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd hurd linux netbsd openbsd solaris + +package modload + +import ( + "os" + "syscall" +) + +// hasWritePerm reports whether the current user has permission to write to the +// file with the given info. +// +// Although the root user on most Unix systems can write to files even without +// permission, hasWritePerm reports false if no appropriate permission bit is +// set even if the current user is root. +func hasWritePerm(path string, fi os.FileInfo) bool { + if os.Getuid() == 0 { + // The root user can access any file, but we still want to default to + // read-only mode if the go.mod file is marked as globally non-writable. + // (If the user really intends not to be in readonly mode, they can + // pass -mod=mod explicitly.) + return fi.Mode()&0222 != 0 + } + + const W_OK = 0x2 + return syscall.Access(path, W_OK) == nil +} diff --git a/libgo/go/cmd/go/internal/modload/stat_windows.go b/libgo/go/cmd/go/internal/modload/stat_windows.go new file mode 100644 index 00000000000..d7826cfc6b8 --- /dev/null +++ b/libgo/go/cmd/go/internal/modload/stat_windows.go @@ -0,0 +1,23 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows + +package modload + +import ( + "os" +) + +// hasWritePerm reports whether the current user has permission to write to the +// file with the given info. +func hasWritePerm(_ string, fi os.FileInfo) bool { + // Windows has a read-only attribute independent of ACLs, so use that to + // determine whether the file is intended to be overwritten. + // + // Per https://golang.org/pkg/os/#Chmod: + // “On Windows, only the 0200 bit (owner writable) of mode is used; it + // controls whether the file's read-only attribute is set or cleared.” + return fi.Mode()&0200 != 0 +} diff --git a/libgo/go/cmd/go/internal/modload/testgo.go b/libgo/go/cmd/go/internal/modload/testgo.go index 663b24a68d7..6b34f5be393 100644 --- a/libgo/go/cmd/go/internal/modload/testgo.go +++ b/libgo/go/cmd/go/internal/modload/testgo.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build testgo +// +build testgo package modload diff --git a/libgo/go/cmd/go/internal/module/module.go b/libgo/go/cmd/go/internal/module/module.go deleted file mode 100644 index 3e0baba15b3..00000000000 --- a/libgo/go/cmd/go/internal/module/module.go +++ /dev/null @@ -1,632 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package module defines the module.Version type -// along with support code. -package module - -// IMPORTANT NOTE -// -// This file essentially defines the set of valid import paths for the go command. -// There are many subtle considerations, including Unicode ambiguity, -// security, network, and file system representations. -// -// This file also defines the set of valid module path and version combinations, -// another topic with many subtle considerations. -// -// Changes to the semantics in this file require approval from rsc. - -import ( - "errors" - "fmt" - "sort" - "strings" - "unicode" - "unicode/utf8" - - "cmd/go/internal/semver" -) - -// A Version is defined by a module path and version pair. -type Version struct { - Path string - - // Version is usually a semantic version in canonical form. - // There are two exceptions to this general rule. - // First, the top-level target of a build has no specific version - // and uses Version = "". - // Second, during MVS calculations the version "none" is used - // to represent the decision to take no version of a given module. - Version string `json:",omitempty"` -} - -// A ModuleError indicates an error specific to a module. -type ModuleError struct { - Path string - Version string - Err error -} - -// VersionError returns a ModuleError derived from a Version and error. -func VersionError(v Version, err error) error { - return &ModuleError{ - Path: v.Path, - Version: v.Version, - Err: err, - } -} - -func (e *ModuleError) Error() string { - if v, ok := e.Err.(*InvalidVersionError); ok { - return fmt.Sprintf("%s@%s: invalid %s: %v", e.Path, v.Version, v.noun(), v.Err) - } - if e.Version != "" { - return fmt.Sprintf("%s@%s: %v", e.Path, e.Version, e.Err) - } - return fmt.Sprintf("module %s: %v", e.Path, e.Err) -} - -func (e *ModuleError) Unwrap() error { return e.Err } - -// An InvalidVersionError indicates an error specific to a version, with the -// module path unknown or specified externally. -// -// A ModuleError may wrap an InvalidVersionError, but an InvalidVersionError -// must not wrap a ModuleError. -type InvalidVersionError struct { - Version string - Pseudo bool - Err error -} - -// noun returns either "version" or "pseudo-version", depending on whether -// e.Version is a pseudo-version. -func (e *InvalidVersionError) noun() string { - if e.Pseudo { - return "pseudo-version" - } - return "version" -} - -func (e *InvalidVersionError) Error() string { - return fmt.Sprintf("%s %q invalid: %s", e.noun(), e.Version, e.Err) -} - -func (e *InvalidVersionError) Unwrap() error { return e.Err } - -// Check checks that a given module path, version pair is valid. -// In addition to the path being a valid module path -// and the version being a valid semantic version, -// the two must correspond. -// For example, the path "yaml/v2" only corresponds to -// semantic versions beginning with "v2.". -func Check(path, version string) error { - if err := CheckPath(path); err != nil { - return err - } - if !semver.IsValid(version) { - return &ModuleError{ - Path: path, - Err: &InvalidVersionError{Version: version, Err: errors.New("not a semantic version")}, - } - } - _, pathMajor, _ := SplitPathVersion(path) - if err := MatchPathMajor(version, pathMajor); err != nil { - return &ModuleError{Path: path, Err: err} - } - return nil -} - -// firstPathOK reports whether r can appear in the first element of a module path. -// The first element of the path must be an LDH domain name, at least for now. -// To avoid case ambiguity, the domain name must be entirely lower case. -func firstPathOK(r rune) bool { - return r == '-' || r == '.' || - '0' <= r && r <= '9' || - 'a' <= r && r <= 'z' -} - -// pathOK reports whether r can appear in an import path element. -// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: + - . _ and ~. -// This matches what "go get" has historically recognized in import paths. -// TODO(rsc): We would like to allow Unicode letters, but that requires additional -// care in the safe encoding (see note below). -func pathOK(r rune) bool { - if r < utf8.RuneSelf { - return r == '+' || r == '-' || r == '.' || r == '_' || r == '~' || - '0' <= r && r <= '9' || - 'A' <= r && r <= 'Z' || - 'a' <= r && r <= 'z' - } - return false -} - -// fileNameOK reports whether r can appear in a file name. -// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters. -// If we expand the set of allowed characters here, we have to -// work harder at detecting potential case-folding and normalization collisions. -// See note about "safe encoding" below. -func fileNameOK(r rune) bool { - if r < utf8.RuneSelf { - // Entire set of ASCII punctuation, from which we remove characters: - // ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ - // We disallow some shell special characters: " ' * < > ? ` | - // (Note that some of those are disallowed by the Windows file system as well.) - // We also disallow path separators / : and \ (fileNameOK is only called on path element characters). - // We allow spaces (U+0020) in file names. - const allowed = "!#$%&()+,-.=@[]^_{}~ " - if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' { - return true - } - for i := 0; i < len(allowed); i++ { - if rune(allowed[i]) == r { - return true - } - } - return false - } - // It may be OK to add more ASCII punctuation here, but only carefully. - // For example Windows disallows < > \, and macOS disallows :, so we must not allow those. - return unicode.IsLetter(r) -} - -// CheckPath checks that a module path is valid. -func CheckPath(path string) error { - if err := checkPath(path, false); err != nil { - return fmt.Errorf("malformed module path %q: %v", path, err) - } - i := strings.Index(path, "/") - if i < 0 { - i = len(path) - } - if i == 0 { - return fmt.Errorf("malformed module path %q: leading slash", path) - } - if !strings.Contains(path[:i], ".") { - return fmt.Errorf("malformed module path %q: missing dot in first path element", path) - } - if path[0] == '-' { - return fmt.Errorf("malformed module path %q: leading dash in first path element", path) - } - for _, r := range path[:i] { - if !firstPathOK(r) { - return fmt.Errorf("malformed module path %q: invalid char %q in first path element", path, r) - } - } - if _, _, ok := SplitPathVersion(path); !ok { - return fmt.Errorf("malformed module path %q: invalid version", path) - } - return nil -} - -// CheckImportPath checks that an import path is valid. -func CheckImportPath(path string) error { - if err := checkPath(path, false); err != nil { - return fmt.Errorf("malformed import path %q: %v", path, err) - } - return nil -} - -// checkPath checks that a general path is valid. -// It returns an error describing why but not mentioning path. -// Because these checks apply to both module paths and import paths, -// the caller is expected to add the "malformed ___ path %q: " prefix. -// fileName indicates whether the final element of the path is a file name -// (as opposed to a directory name). -func checkPath(path string, fileName bool) error { - if !utf8.ValidString(path) { - return fmt.Errorf("invalid UTF-8") - } - if path == "" { - return fmt.Errorf("empty string") - } - if path[0] == '-' { - return fmt.Errorf("leading dash") - } - if strings.Contains(path, "..") { - return fmt.Errorf("double dot") - } - if strings.Contains(path, "//") { - return fmt.Errorf("double slash") - } - if path[len(path)-1] == '/' { - return fmt.Errorf("trailing slash") - } - elemStart := 0 - for i, r := range path { - if r == '/' { - if err := checkElem(path[elemStart:i], fileName); err != nil { - return err - } - elemStart = i + 1 - } - } - if err := checkElem(path[elemStart:], fileName); err != nil { - return err - } - return nil -} - -// checkElem checks whether an individual path element is valid. -// fileName indicates whether the element is a file name (not a directory name). -func checkElem(elem string, fileName bool) error { - if elem == "" { - return fmt.Errorf("empty path element") - } - if strings.Count(elem, ".") == len(elem) { - return fmt.Errorf("invalid path element %q", elem) - } - if elem[0] == '.' && !fileName { - return fmt.Errorf("leading dot in path element") - } - if elem[len(elem)-1] == '.' { - return fmt.Errorf("trailing dot in path element") - } - charOK := pathOK - if fileName { - charOK = fileNameOK - } - for _, r := range elem { - if !charOK(r) { - return fmt.Errorf("invalid char %q", r) - } - } - - // Windows disallows a bunch of path elements, sadly. - // See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file - short := elem - if i := strings.Index(short, "."); i >= 0 { - short = short[:i] - } - for _, bad := range badWindowsNames { - if strings.EqualFold(bad, short) { - return fmt.Errorf("%q disallowed as path element component on Windows", short) - } - } - return nil -} - -// CheckFilePath checks whether a slash-separated file path is valid. -func CheckFilePath(path string) error { - if err := checkPath(path, true); err != nil { - return fmt.Errorf("malformed file path %q: %v", path, err) - } - return nil -} - -// badWindowsNames are the reserved file path elements on Windows. -// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file -var badWindowsNames = []string{ - "CON", - "PRN", - "AUX", - "NUL", - "COM1", - "COM2", - "COM3", - "COM4", - "COM5", - "COM6", - "COM7", - "COM8", - "COM9", - "LPT1", - "LPT2", - "LPT3", - "LPT4", - "LPT5", - "LPT6", - "LPT7", - "LPT8", - "LPT9", -} - -// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path -// and version is either empty or "/vN" for N >= 2. -// As a special case, gopkg.in paths are recognized directly; -// they require ".vN" instead of "/vN", and for all N, not just N >= 2. -func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) { - if strings.HasPrefix(path, "gopkg.in/") { - return splitGopkgIn(path) - } - - i := len(path) - dot := false - for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') { - if path[i-1] == '.' { - dot = true - } - i-- - } - if i <= 1 || i == len(path) || path[i-1] != 'v' || path[i-2] != '/' { - return path, "", true - } - prefix, pathMajor = path[:i-2], path[i-2:] - if dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == "/v1" { - return path, "", false - } - return prefix, pathMajor, true -} - -// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths. -func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) { - if !strings.HasPrefix(path, "gopkg.in/") { - return path, "", false - } - i := len(path) - if strings.HasSuffix(path, "-unstable") { - i -= len("-unstable") - } - for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') { - i-- - } - if i <= 1 || path[i-1] != 'v' || path[i-2] != '.' { - // All gopkg.in paths must end in vN for some N. - return path, "", false - } - prefix, pathMajor = path[:i-2], path[i-2:] - if len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != ".v0" { - return path, "", false - } - return prefix, pathMajor, true -} - -// MatchPathMajor returns a non-nil error if the semantic version v -// does not match the path major version pathMajor. -func MatchPathMajor(v, pathMajor string) error { - if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { - pathMajor = strings.TrimSuffix(pathMajor, "-unstable") - } - if strings.HasPrefix(v, "v0.0.0-") && pathMajor == ".v1" { - // Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1. - // For example, gopkg.in/yaml.v2@v2.2.1's go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405. - return nil - } - m := semver.Major(v) - if pathMajor == "" { - if m == "v0" || m == "v1" || semver.Build(v) == "+incompatible" { - return nil - } - pathMajor = "v0 or v1" - } else if pathMajor[0] == '/' || pathMajor[0] == '.' { - if m == pathMajor[1:] { - return nil - } - pathMajor = pathMajor[1:] - } - return &InvalidVersionError{ - Version: v, - Err: fmt.Errorf("should be %s, not %s", pathMajor, semver.Major(v)), - } -} - -// PathMajorPrefix returns the major-version tag prefix implied by pathMajor. -// An empty PathMajorPrefix allows either v0 or v1. -// -// Note that MatchPathMajor may accept some versions that do not actually begin -// with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1' -// pathMajor, even though that pathMajor implies 'v1' tagging. -func PathMajorPrefix(pathMajor string) string { - if pathMajor == "" { - return "" - } - if pathMajor[0] != '/' && pathMajor[0] != '.' { - panic("pathMajor suffix " + pathMajor + " passed to PathMajorPrefix lacks separator") - } - if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { - pathMajor = strings.TrimSuffix(pathMajor, "-unstable") - } - m := pathMajor[1:] - if m != semver.Major(m) { - panic("pathMajor suffix " + pathMajor + "passed to PathMajorPrefix is not a valid major version") - } - return m -} - -// CanonicalVersion returns the canonical form of the version string v. -// It is the same as semver.Canonical(v) except that it preserves the special build suffix "+incompatible". -func CanonicalVersion(v string) string { - cv := semver.Canonical(v) - if semver.Build(v) == "+incompatible" { - cv += "+incompatible" - } - return cv -} - -// Sort sorts the list by Path, breaking ties by comparing Versions. -func Sort(list []Version) { - sort.Slice(list, func(i, j int) bool { - mi := list[i] - mj := list[j] - if mi.Path != mj.Path { - return mi.Path < mj.Path - } - // To help go.sum formatting, allow version/file. - // Compare semver prefix by semver rules, - // file by string order. - vi := mi.Version - vj := mj.Version - var fi, fj string - if k := strings.Index(vi, "/"); k >= 0 { - vi, fi = vi[:k], vi[k:] - } - if k := strings.Index(vj, "/"); k >= 0 { - vj, fj = vj[:k], vj[k:] - } - if vi != vj { - return semver.Compare(vi, vj) < 0 - } - return fi < fj - }) -} - -// Safe encodings -// -// Module paths appear as substrings of file system paths -// (in the download cache) and of web server URLs in the proxy protocol. -// In general we cannot rely on file systems to be case-sensitive, -// nor can we rely on web servers, since they read from file systems. -// That is, we cannot rely on the file system to keep rsc.io/QUOTE -// and rsc.io/quote separate. Windows and macOS don't. -// Instead, we must never require two different casings of a file path. -// Because we want the download cache to match the proxy protocol, -// and because we want the proxy protocol to be possible to serve -// from a tree of static files (which might be stored on a case-insensitive -// file system), the proxy protocol must never require two different casings -// of a URL path either. -// -// One possibility would be to make the safe encoding be the lowercase -// hexadecimal encoding of the actual path bytes. This would avoid ever -// needing different casings of a file path, but it would be fairly illegible -// to most programmers when those paths appeared in the file system -// (including in file paths in compiler errors and stack traces) -// in web server logs, and so on. Instead, we want a safe encoding that -// leaves most paths unaltered. -// -// The safe encoding is this: -// replace every uppercase letter with an exclamation mark -// followed by the letter's lowercase equivalent. -// -// For example, -// github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go. -// github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy -// github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus. -// -// Import paths that avoid upper-case letters are left unchanged. -// Note that because import paths are ASCII-only and avoid various -// problematic punctuation (like : < and >), the safe encoding is also ASCII-only -// and avoids the same problematic punctuation. -// -// Import paths have never allowed exclamation marks, so there is no -// need to define how to encode a literal !. -// -// Although paths are disallowed from using Unicode (see pathOK above), -// the eventual plan is to allow Unicode letters as well, to assume that -// file systems and URLs are Unicode-safe (storing UTF-8), and apply -// the !-for-uppercase convention. Note however that not all runes that -// are different but case-fold equivalent are an upper/lower pair. -// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin) -// are considered to case-fold to each other. When we do add Unicode -// letters, we must not assume that upper/lower are the only case-equivalent pairs. -// Perhaps the Kelvin symbol would be disallowed entirely, for example. -// Or perhaps it would encode as "!!k", or perhaps as "(212A)". -// -// Also, it would be nice to allow Unicode marks as well as letters, -// but marks include combining marks, and then we must deal not -// only with case folding but also normalization: both U+00E9 ('é') -// and U+0065 U+0301 ('e' followed by combining acute accent) -// look the same on the page and are treated by some file systems -// as the same path. If we do allow Unicode marks in paths, there -// must be some kind of normalization to allow only one canonical -// encoding of any character used in an import path. - -// EncodePath returns the safe encoding of the given module path. -// It fails if the module path is invalid. -func EncodePath(path string) (encoding string, err error) { - if err := CheckPath(path); err != nil { - return "", err - } - - return encodeString(path) -} - -// EncodeVersion returns the safe encoding of the given module version. -// Versions are allowed to be in non-semver form but must be valid file names -// and not contain exclamation marks. -func EncodeVersion(v string) (encoding string, err error) { - if err := checkElem(v, true); err != nil || strings.Contains(v, "!") { - return "", &InvalidVersionError{ - Version: v, - Err: fmt.Errorf("disallowed version string"), - } - } - return encodeString(v) -} - -func encodeString(s string) (encoding string, err error) { - haveUpper := false - for _, r := range s { - if r == '!' || r >= utf8.RuneSelf { - // This should be disallowed by CheckPath, but diagnose anyway. - // The correctness of the encoding loop below depends on it. - return "", fmt.Errorf("internal error: inconsistency in EncodePath") - } - if 'A' <= r && r <= 'Z' { - haveUpper = true - } - } - - if !haveUpper { - return s, nil - } - - var buf []byte - for _, r := range s { - if 'A' <= r && r <= 'Z' { - buf = append(buf, '!', byte(r+'a'-'A')) - } else { - buf = append(buf, byte(r)) - } - } - return string(buf), nil -} - -// DecodePath returns the module path of the given safe encoding. -// It fails if the encoding is invalid or encodes an invalid path. -func DecodePath(encoding string) (path string, err error) { - path, ok := decodeString(encoding) - if !ok { - return "", fmt.Errorf("invalid module path encoding %q", encoding) - } - if err := CheckPath(path); err != nil { - return "", fmt.Errorf("invalid module path encoding %q: %v", encoding, err) - } - return path, nil -} - -// DecodeVersion returns the version string for the given safe encoding. -// It fails if the encoding is invalid or encodes an invalid version. -// Versions are allowed to be in non-semver form but must be valid file names -// and not contain exclamation marks. -func DecodeVersion(encoding string) (v string, err error) { - v, ok := decodeString(encoding) - if !ok { - return "", fmt.Errorf("invalid version encoding %q", encoding) - } - if err := checkElem(v, true); err != nil { - return "", fmt.Errorf("disallowed version string %q", v) - } - return v, nil -} - -func decodeString(encoding string) (string, bool) { - var buf []byte - - bang := false - for _, r := range encoding { - if r >= utf8.RuneSelf { - return "", false - } - if bang { - bang = false - if r < 'a' || 'z' < r { - return "", false - } - buf = append(buf, byte(r+'A'-'a')) - continue - } - if r == '!' { - bang = true - continue - } - if 'A' <= r && r <= 'Z' { - return "", false - } - buf = append(buf, byte(r)) - } - if bang { - return "", false - } - return string(buf), true -} diff --git a/libgo/go/cmd/go/internal/module/module_test.go b/libgo/go/cmd/go/internal/module/module_test.go deleted file mode 100644 index b9f07bf57d5..00000000000 --- a/libgo/go/cmd/go/internal/module/module_test.go +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package module - -import "testing" - -var checkTests = []struct { - path string - version string - ok bool -}{ - {"rsc.io/quote", "0.1.0", false}, - {"rsc io/quote", "v1.0.0", false}, - - {"github.com/go-yaml/yaml", "v0.8.0", true}, - {"github.com/go-yaml/yaml", "v1.0.0", true}, - {"github.com/go-yaml/yaml", "v2.0.0", false}, - {"github.com/go-yaml/yaml", "v2.1.5", false}, - {"github.com/go-yaml/yaml", "v3.0.0", false}, - - {"github.com/go-yaml/yaml/v2", "v1.0.0", false}, - {"github.com/go-yaml/yaml/v2", "v2.0.0", true}, - {"github.com/go-yaml/yaml/v2", "v2.1.5", true}, - {"github.com/go-yaml/yaml/v2", "v3.0.0", false}, - - {"gopkg.in/yaml.v0", "v0.8.0", true}, - {"gopkg.in/yaml.v0", "v1.0.0", false}, - {"gopkg.in/yaml.v0", "v2.0.0", false}, - {"gopkg.in/yaml.v0", "v2.1.5", false}, - {"gopkg.in/yaml.v0", "v3.0.0", false}, - - {"gopkg.in/yaml.v1", "v0.8.0", false}, - {"gopkg.in/yaml.v1", "v1.0.0", true}, - {"gopkg.in/yaml.v1", "v2.0.0", false}, - {"gopkg.in/yaml.v1", "v2.1.5", false}, - {"gopkg.in/yaml.v1", "v3.0.0", false}, - - // For gopkg.in, .v1 means v1 only (not v0). - // But early versions of vgo still generated v0 pseudo-versions for it. - // Even though now we'd generate those as v1 pseudo-versions, - // we accept the old pseudo-versions to avoid breaking existing go.mod files. - // For example gopkg.in/yaml.v2@v2.2.1's go.mod requires check.v1 at a v0 pseudo-version. - {"gopkg.in/check.v1", "v0.0.0", false}, - {"gopkg.in/check.v1", "v0.0.0-20160102150405-abcdef123456", true}, - - {"gopkg.in/yaml.v2", "v1.0.0", false}, - {"gopkg.in/yaml.v2", "v2.0.0", true}, - {"gopkg.in/yaml.v2", "v2.1.5", true}, - {"gopkg.in/yaml.v2", "v3.0.0", false}, - - {"rsc.io/quote", "v17.0.0", false}, - {"rsc.io/quote", "v17.0.0+incompatible", true}, -} - -func TestCheck(t *testing.T) { - for _, tt := range checkTests { - err := Check(tt.path, tt.version) - if tt.ok && err != nil { - t.Errorf("Check(%q, %q) = %v, wanted nil error", tt.path, tt.version, err) - } else if !tt.ok && err == nil { - t.Errorf("Check(%q, %q) succeeded, wanted error", tt.path, tt.version) - } - } -} - -var checkPathTests = []struct { - path string - ok bool - importOK bool - fileOK bool -}{ - {"x.y/z", true, true, true}, - {"x.y", true, true, true}, - - {"", false, false, false}, - {"x.y/\xFFz", false, false, false}, - {"/x.y/z", false, false, false}, - {"x./z", false, false, false}, - {".x/z", false, false, true}, - {"-x/z", false, false, false}, - {"x..y/z", false, false, false}, - {"x.y/z/../../w", false, false, false}, - {"x.y//z", false, false, false}, - {"x.y/z//w", false, false, false}, - {"x.y/z/", false, false, false}, - - {"x.y/z/v0", false, true, true}, - {"x.y/z/v1", false, true, true}, - {"x.y/z/v2", true, true, true}, - {"x.y/z/v2.0", false, true, true}, - {"X.y/z", false, true, true}, - - {"!x.y/z", false, false, true}, - {"_x.y/z", false, true, true}, - {"x.y!/z", false, false, true}, - {"x.y\"/z", false, false, false}, - {"x.y#/z", false, false, true}, - {"x.y$/z", false, false, true}, - {"x.y%/z", false, false, true}, - {"x.y&/z", false, false, true}, - {"x.y'/z", false, false, false}, - {"x.y(/z", false, false, true}, - {"x.y)/z", false, false, true}, - {"x.y*/z", false, false, false}, - {"x.y+/z", false, true, true}, - {"x.y,/z", false, false, true}, - {"x.y-/z", true, true, true}, - {"x.y./zt", false, false, false}, - {"x.y:/z", false, false, false}, - {"x.y;/z", false, false, false}, - {"x.y/z", false, false, false}, - {"x.y?/z", false, false, false}, - {"x.y@/z", false, false, true}, - {"x.y[/z", false, false, true}, - {"x.y\\/z", false, false, false}, - {"x.y]/z", false, false, true}, - {"x.y^/z", false, false, true}, - {"x.y_/z", false, true, true}, - {"x.y`/z", false, false, false}, - {"x.y{/z", false, false, true}, - {"x.y}/z", false, false, true}, - {"x.y~/z", false, true, true}, - {"x.y/z!", false, false, true}, - {"x.y/z\"", false, false, false}, - {"x.y/z#", false, false, true}, - {"x.y/z$", false, false, true}, - {"x.y/z%", false, false, true}, - {"x.y/z&", false, false, true}, - {"x.y/z'", false, false, false}, - {"x.y/z(", false, false, true}, - {"x.y/z)", false, false, true}, - {"x.y/z*", false, false, false}, - {"x.y/z+", true, true, true}, - {"x.y/z,", false, false, true}, - {"x.y/z-", true, true, true}, - {"x.y/z.t", true, true, true}, - {"x.y/z/t", true, true, true}, - {"x.y/z:", false, false, false}, - {"x.y/z;", false, false, false}, - {"x.y/z<", false, false, false}, - {"x.y/z=", false, false, true}, - {"x.y/z>", false, false, false}, - {"x.y/z?", false, false, false}, - {"x.y/z@", false, false, true}, - {"x.y/z[", false, false, true}, - {"x.y/z\\", false, false, false}, - {"x.y/z]", false, false, true}, - {"x.y/z^", false, false, true}, - {"x.y/z_", true, true, true}, - {"x.y/z`", false, false, false}, - {"x.y/z{", false, false, true}, - {"x.y/z}", false, false, true}, - {"x.y/z~", true, true, true}, - {"x.y/x.foo", true, true, true}, - {"x.y/aux.foo", false, false, false}, - {"x.y/prn", false, false, false}, - {"x.y/prn2", true, true, true}, - {"x.y/com", true, true, true}, - {"x.y/com1", false, false, false}, - {"x.y/com1.txt", false, false, false}, - {"x.y/calm1", true, true, true}, - {"github.com/!123/logrus", false, false, true}, - - // TODO: CL 41822 allowed Unicode letters in old "go get" - // without due consideration of the implications, and only on github.com (!). - // For now, we disallow non-ASCII characters in module mode, - // in both module paths and general import paths, - // until we can get the implications right. - // When we do, we'll enable them everywhere, not just for GitHub. - {"github.com/user/unicode/испытание", false, false, true}, - - {"../x", false, false, false}, - {"./y", false, false, false}, - {"x:y", false, false, false}, - {`\temp\foo`, false, false, false}, - {".gitignore", false, false, true}, - {".github/ISSUE_TEMPLATE", false, false, true}, - {"x☺y", false, false, false}, -} - -func TestCheckPath(t *testing.T) { - for _, tt := range checkPathTests { - err := CheckPath(tt.path) - if tt.ok && err != nil { - t.Errorf("CheckPath(%q) = %v, wanted nil error", tt.path, err) - } else if !tt.ok && err == nil { - t.Errorf("CheckPath(%q) succeeded, wanted error", tt.path) - } - - err = CheckImportPath(tt.path) - if tt.importOK && err != nil { - t.Errorf("CheckImportPath(%q) = %v, wanted nil error", tt.path, err) - } else if !tt.importOK && err == nil { - t.Errorf("CheckImportPath(%q) succeeded, wanted error", tt.path) - } - - err = CheckFilePath(tt.path) - if tt.fileOK && err != nil { - t.Errorf("CheckFilePath(%q) = %v, wanted nil error", tt.path, err) - } else if !tt.fileOK && err == nil { - t.Errorf("CheckFilePath(%q) succeeded, wanted error", tt.path) - } - } -} - -var splitPathVersionTests = []struct { - pathPrefix string - version string -}{ - {"x.y/z", ""}, - {"x.y/z", "/v2"}, - {"x.y/z", "/v3"}, - {"x.y/v", ""}, - {"gopkg.in/yaml", ".v0"}, - {"gopkg.in/yaml", ".v1"}, - {"gopkg.in/yaml", ".v2"}, - {"gopkg.in/yaml", ".v3"}, -} - -func TestSplitPathVersion(t *testing.T) { - for _, tt := range splitPathVersionTests { - pathPrefix, version, ok := SplitPathVersion(tt.pathPrefix + tt.version) - if pathPrefix != tt.pathPrefix || version != tt.version || !ok { - t.Errorf("SplitPathVersion(%q) = %q, %q, %v, want %q, %q, true", tt.pathPrefix+tt.version, pathPrefix, version, ok, tt.pathPrefix, tt.version) - } - } - - for _, tt := range checkPathTests { - pathPrefix, version, ok := SplitPathVersion(tt.path) - if pathPrefix+version != tt.path { - t.Errorf("SplitPathVersion(%q) = %q, %q, %v, doesn't add to input", tt.path, pathPrefix, version, ok) - } - } -} - -var encodeTests = []struct { - path string - enc string // empty means same as path -}{ - {path: "ascii.com/abcdefghijklmnopqrstuvwxyz.-+/~_0123456789"}, - {path: "github.com/GoogleCloudPlatform/omega", enc: "github.com/!google!cloud!platform/omega"}, -} - -func TestEncodePath(t *testing.T) { - // Check invalid paths. - for _, tt := range checkPathTests { - if !tt.ok { - _, err := EncodePath(tt.path) - if err == nil { - t.Errorf("EncodePath(%q): succeeded, want error (invalid path)", tt.path) - } - } - } - - // Check encodings. - for _, tt := range encodeTests { - enc, err := EncodePath(tt.path) - if err != nil { - t.Errorf("EncodePath(%q): unexpected error: %v", tt.path, err) - continue - } - want := tt.enc - if want == "" { - want = tt.path - } - if enc != want { - t.Errorf("EncodePath(%q) = %q, want %q", tt.path, enc, want) - } - } -} - -var badDecode = []string{ - "github.com/GoogleCloudPlatform/omega", - "github.com/!google!cloud!platform!/omega", - "github.com/!0google!cloud!platform/omega", - "github.com/!_google!cloud!platform/omega", - "github.com/!!google!cloud!platform/omega", - "", -} - -func TestDecodePath(t *testing.T) { - // Check invalid decodings. - for _, bad := range badDecode { - _, err := DecodePath(bad) - if err == nil { - t.Errorf("DecodePath(%q): succeeded, want error (invalid decoding)", bad) - } - } - - // Check invalid paths (or maybe decodings). - for _, tt := range checkPathTests { - if !tt.ok { - path, err := DecodePath(tt.path) - if err == nil { - t.Errorf("DecodePath(%q) = %q, want error (invalid path)", tt.path, path) - } - } - } - - // Check encodings. - for _, tt := range encodeTests { - enc := tt.enc - if enc == "" { - enc = tt.path - } - path, err := DecodePath(enc) - if err != nil { - t.Errorf("DecodePath(%q): unexpected error: %v", enc, err) - continue - } - if path != tt.path { - t.Errorf("DecodePath(%q) = %q, want %q", enc, path, tt.path) - } - } -} diff --git a/libgo/go/cmd/go/internal/mvs/mvs.go b/libgo/go/cmd/go/internal/mvs/mvs.go index 4e7a828c24f..dd3b3ccb865 100644 --- a/libgo/go/cmd/go/internal/mvs/mvs.go +++ b/libgo/go/cmd/go/internal/mvs/mvs.go @@ -13,8 +13,9 @@ import ( "sync" "sync/atomic" - "cmd/go/internal/module" "cmd/go/internal/par" + + "golang.org/x/mod/module" ) // A Reqs is the requirement graph on which Minimal Version Selection (MVS) operates. @@ -250,10 +251,15 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m return list, nil } -// Req returns the minimal requirement list for the target module -// that results in the given build list, with the constraint that all -// module paths listed in base must appear in the returned list. -func Req(target module.Version, list []module.Version, base []string, reqs Reqs) ([]module.Version, error) { +// Req returns the minimal requirement list for the target module, +// with the constraint that all module paths listed in base must +// appear in the returned list. +func Req(target module.Version, base []string, reqs Reqs) ([]module.Version, error) { + list, err := BuildList(target, reqs) + if err != nil { + return nil, err + } + // Note: Not running in parallel because we assume // that list came from a previous operation that paged // in all the requirements, so there's no I/O to overlap now. diff --git a/libgo/go/cmd/go/internal/mvs/mvs_test.go b/libgo/go/cmd/go/internal/mvs/mvs_test.go index 72d3ea95b79..9a30a8c3ac0 100644 --- a/libgo/go/cmd/go/internal/mvs/mvs_test.go +++ b/libgo/go/cmd/go/internal/mvs/mvs_test.go @@ -10,7 +10,7 @@ import ( "strings" "testing" - "cmd/go/internal/module" + "golang.org/x/mod/module" ) var tests = ` @@ -280,6 +280,20 @@ D2: build A: A B1 C1 D1 upgrade* A: A B2 C2 D2 +# Cycles with multiple possible solutions. +# (golang.org/issue/34086) +name: cycle3 +M: A1 C2 +A1: B1 +B1: C1 +B2: C2 +C1: +C2: B2 +build M: M A1 B2 C2 +req M: A1 B2 +req M A: A1 B2 +req M C: A1 C2 + # Requirement minimization. name: req1 @@ -390,7 +404,15 @@ func Test(t *testing.T) { fns = append(fns, func(t *testing.T) { list, err := Upgrade(m(kf[1]), reqs, ms(kf[2:])...) if err == nil { - list, err = Req(m(kf[1]), list, nil, reqs) + // Copy the reqs map, but substitute the upgraded requirements in + // place of the target's original requirements. + upReqs := make(reqsMap, len(reqs)) + for m, r := range reqs { + upReqs[m] = r + } + upReqs[m(kf[1])] = list + + list, err = Req(m(kf[1]), nil, upReqs) } checkList(t, key, list, err, val) }) @@ -418,11 +440,7 @@ func Test(t *testing.T) { t.Fatalf("req takes at least one argument: %q", line) } fns = append(fns, func(t *testing.T) { - list, err := BuildList(m(kf[1]), reqs) - if err != nil { - t.Fatal(err) - } - list, err = Req(m(kf[1]), list, kf[2:], reqs) + list, err := Req(m(kf[1]), kf[2:], reqs) checkList(t, key, list, err, val) }) continue diff --git a/libgo/go/cmd/go/internal/note/example_test.go b/libgo/go/cmd/go/internal/note/example_test.go deleted file mode 100644 index 53554b4c23f..00000000000 --- a/libgo/go/cmd/go/internal/note/example_test.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package note_test - -import ( - "fmt" - "io" - "os" - - "cmd/go/internal/note" -) - -func ExampleSign() { - skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz" - text := "If you think cryptography is the answer to your problem,\n" + - "then you don't know what your problem is.\n" - - signer, err := note.NewSigner(skey) - if err != nil { - fmt.Println(err) - return - } - - msg, err := note.Sign(¬e.Note{Text: text}, signer) - if err != nil { - fmt.Println(err) - return - } - os.Stdout.Write(msg) - - // Output: - // If you think cryptography is the answer to your problem, - // then you don't know what your problem is. - // - // — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM= -} - -func ExampleOpen() { - vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW" - msg := []byte("If you think cryptography is the answer to your problem,\n" + - "then you don't know what your problem is.\n" + - "\n" + - "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n") - - verifier, err := note.NewVerifier(vkey) - if err != nil { - fmt.Println(err) - return - } - verifiers := note.VerifierList(verifier) - - n, err := note.Open(msg, verifiers) - if err != nil { - fmt.Println(err) - return - } - fmt.Printf("%s (%08x):\n%s", n.Sigs[0].Name, n.Sigs[0].Hash, n.Text) - - // Output: - // PeterNeumann (c74f20a3): - // If you think cryptography is the answer to your problem, - // then you don't know what your problem is. -} - -var rand = struct { - Reader io.Reader -}{ - zeroReader{}, -} - -type zeroReader struct{} - -func (zeroReader) Read(buf []byte) (int, error) { - for i := range buf { - buf[i] = 0 - } - return len(buf), nil -} - -func ExampleSign_add_signatures() { - vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW" - msg := []byte("If you think cryptography is the answer to your problem,\n" + - "then you don't know what your problem is.\n" + - "\n" + - "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n") - - verifier, err := note.NewVerifier(vkey) - if err != nil { - fmt.Println(err) - return - } - verifiers := note.VerifierList(verifier) - - n, err := note.Open([]byte(msg), verifiers) - if err != nil { - fmt.Println(err) - return - } - - skey, vkey, err := note.GenerateKey(rand.Reader, "EnochRoot") - if err != nil { - fmt.Println(err) - return - } - _ = vkey // give to verifiers - - me, err := note.NewSigner(skey) - if err != nil { - fmt.Println(err) - return - } - - msg, err = note.Sign(n, me) - if err != nil { - fmt.Println(err) - return - } - os.Stdout.Write(msg) - - // Output: - // If you think cryptography is the answer to your problem, - // then you don't know what your problem is. - // - // — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM= - // — EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ= -} diff --git a/libgo/go/cmd/go/internal/note/note.go b/libgo/go/cmd/go/internal/note/note.go deleted file mode 100644 index f770da24b37..00000000000 --- a/libgo/go/cmd/go/internal/note/note.go +++ /dev/null @@ -1,683 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package note defines the notes signed by the Go module database server. -// -// This package is part of a DRAFT of what the Go module database server will look like. -// Do not assume the details here are final! -// -// A note is text signed by one or more server keys. -// The text should be ignored unless the note is signed by -// a trusted server key and the signature has been verified -// using the server's public key. -// -// A server's public key is identified by a name, typically the "host[/path]" -// giving the base URL of the server's transparency log. -// The syntactic restrictions on a name are that it be non-empty, -// well-formed UTF-8 containing neither Unicode spaces nor plus (U+002B). -// -// A Go module database server signs texts using public key cryptography. -// A given server may have multiple public keys, each -// identified by the first 32 bits of the SHA-256 hash of -// the concatenation of the server name, a newline, and -// the encoded public key. -// -// Verifying Notes -// -// A Verifier allows verification of signatures by one server public key. -// It can report the name of the server and the uint32 hash of the key, -// and it can verify a purported signature by that key. -// -// The standard implementation of a Verifier is constructed -// by NewVerifier starting from a verifier key, which is a -// plain text string of the form "++". -// -// A Verifiers allows looking up a Verifier by the combination -// of server name and key hash. -// -// The standard implementation of a Verifiers is constructed -// by VerifierList from a list of known verifiers. -// -// A Note represents a text with one or more signatures. -// An implementation can reject a note with too many signatures -// (for example, more than 100 signatures). -// -// A Signature represents a signature on a note, verified or not. -// -// The Open function takes as input a signed message -// and a set of known verifiers. It decodes and verifies -// the message signatures and returns a Note structure -// containing the message text and (verified or unverified) signatures. -// -// Signing Notes -// -// A Signer allows signing a text with a given key. -// It can report the name of the server and the hash of the key -// and can sign a raw text using that key. -// -// The standard implementation of a Signer is constructed -// by NewSigner starting from an encoded signer key, which is a -// plain text string of the form "PRIVATE+KEY+++". -// Anyone with an encoded signer key can sign messages using that key, -// so it must be kept secret. The encoding begins with the literal text -// "PRIVATE+KEY" to avoid confusion with the public server key. -// -// The Sign function takes as input a Note and a list of Signers -// and returns an encoded, signed message. -// -// Signed Note Format -// -// A signed note consists of a text ending in newline (U+000A), -// followed by a blank line (only a newline), -// followed by one or more signature lines of this form: -// em dash (U+2014), space (U+0020), -// server name, space, base64-encoded signature, newline. -// -// Signed notes must be valid UTF-8 and must not contain any -// ASCII control characters (those below U+0020) other than newline. -// -// A signature is a base64 encoding of 4+n bytes. -// -// The first four bytes in the signature are the uint32 key hash -// stored in big-endian order, which is to say they are the first -// four bytes of the truncated SHA-256 used to derive the key hash -// in the first place. -// -// The remaining n bytes are the result of using the specified key -// to sign the note text (including the final newline but not the -// separating blank line). -// -// Generating Keys -// -// There is only one key type, Ed25519 with algorithm identifier 1. -// New key types may be introduced in the future as needed, -// although doing so will require deploying the new algorithms to all clients -// before starting to depend on them for signatures. -// -// The GenerateKey function generates and returns a new signer -// and corresponding verifier. -// -// Example -// -// Here is a well-formed signed note: -// -// If you think cryptography is the answer to your problem, -// then you don't know what your problem is. -// -// — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM= -// -// It can be constructed and displayed using: -// -// skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz" -// text := "If you think cryptography is the answer to your problem,\n" + -// "then you don't know what your problem is.\n" -// -// signer, err := note.NewSigner(skey) -// if err != nil { -// log.Fatal(err) -// } -// -// msg, err := note.Sign(¬e.Note{Text: text}, signer) -// if err != nil { -// log.Fatal(err) -// } -// os.Stdout.Write(msg) -// -// The note's text is two lines, including the final newline, -// and the text is purportedly signed by a server named -// "PeterNeumann". (Although server names are canonically -// base URLs, the only syntactic requirement is that they -// not contain spaces or newlines). -// -// If Open is given access to a Verifiers including the -// Verifier for this key, then it will succeed at verifiying -// the encoded message and returning the parsed Note: -// -// vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW" -// msg := []byte("If you think cryptography is the answer to your problem,\n" + -// "then you don't know what your problem is.\n" + -// "\n" + -// "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n") -// -// verifier, err := note.NewVerifier(vkey) -// if err != nil { -// log.Fatal(err) -// } -// verifiers := note.VerifierList(verifier) -// -// n, err := note.Open([]byte(msg), verifiers) -// if err != nil { -// log.Fatal(err) -// } -// fmt.Printf("%s (%08x):\n%s", n.Sigs[0].Name, n.Sigs[0].Hash, n.Text) -// -// You can add your own signature to this message by re-signing the note: -// -// skey, vkey, err := note.GenerateKey(rand.Reader, "EnochRoot") -// if err != nil { -// log.Fatal(err) -// } -// _ = vkey // give to verifiers -// -// me, err := note.NewSigner(skey) -// if err != nil { -// log.Fatal(err) -// } -// -// msg, err := note.Sign(n, me) -// if err != nil { -// log.Fatal(err) -// } -// os.Stdout.Write(msg) -// -// This will print a doubly-signed message, like: -// -// If you think cryptography is the answer to your problem, -// then you don't know what your problem is. -// -// — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM= -// — EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ= -// -package note - -import ( - "bytes" - "crypto/ed25519" - "crypto/sha256" - "encoding/base64" - "encoding/binary" - "errors" - "fmt" - "io" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -// A Verifier verifies messages signed with a specific key. -type Verifier interface { - // Name returns the server name associated with the key. - Name() string - - // KeyHash returns the key hash. - KeyHash() uint32 - - // Verify reports whether sig is a valid signature of msg. - Verify(msg, sig []byte) bool -} - -// A Signer signs messages using a specific key. -type Signer interface { - // Name returns the server name associated with the key. - Name() string - - // KeyHash returns the key hash. - KeyHash() uint32 - - // Sign returns a signature for the given message. - Sign(msg []byte) ([]byte, error) -} - -// keyHash computes the key hash for the given server name and encoded public key. -func keyHash(name string, key []byte) uint32 { - h := sha256.New() - h.Write([]byte(name)) - h.Write([]byte("\n")) - h.Write(key) - sum := h.Sum(nil) - return binary.BigEndian.Uint32(sum) -} - -var ( - errVerifierID = errors.New("malformed verifier id") - errVerifierAlg = errors.New("unknown verifier algorithm") - errVerifierHash = errors.New("invalid verifier hash") -) - -const ( - algEd25519 = 1 -) - -// isValidName reports whether name is valid. -// It must be non-empty and not have any Unicode spaces or pluses. -func isValidName(name string) bool { - return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+") -} - -// NewVerifier construct a new Verifier from an encoded verifier key. -func NewVerifier(vkey string) (Verifier, error) { - name, vkey := chop(vkey, "+") - hash16, key64 := chop(vkey, "+") - hash, err1 := strconv.ParseUint(hash16, 16, 32) - key, err2 := base64.StdEncoding.DecodeString(key64) - if len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 { - return nil, errVerifierID - } - if uint32(hash) != keyHash(name, key) { - return nil, errVerifierHash - } - - v := &verifier{ - name: name, - hash: uint32(hash), - } - - alg, key := key[0], key[1:] - switch alg { - default: - return nil, errVerifierAlg - - case algEd25519: - if len(key) != 32 { - return nil, errVerifierID - } - v.verify = func(msg, sig []byte) bool { - return ed25519.Verify(key, msg, sig) - } - } - - return v, nil -} - -// chop chops s at the first instance of sep, if any, -// and returns the text before and after sep. -// If sep is not present, chop returns before is s and after is empty. -func chop(s, sep string) (before, after string) { - i := strings.Index(s, sep) - if i < 0 { - return s, "" - } - return s[:i], s[i+len(sep):] -} - -// verifier is a trivial Verifier implementation. -type verifier struct { - name string - hash uint32 - verify func([]byte, []byte) bool -} - -func (v *verifier) Name() string { return v.name } -func (v *verifier) KeyHash() uint32 { return v.hash } -func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) } - -// NewSigner constructs a new Signer from an encoded signer key. -func NewSigner(skey string) (Signer, error) { - priv1, skey := chop(skey, "+") - priv2, skey := chop(skey, "+") - name, skey := chop(skey, "+") - hash16, key64 := chop(skey, "+") - hash, err1 := strconv.ParseUint(hash16, 16, 32) - key, err2 := base64.StdEncoding.DecodeString(key64) - if priv1 != "PRIVATE" || priv2 != "KEY" || len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 { - return nil, errSignerID - } - - // Note: hash is the hash of the public key and we have the private key. - // Must verify hash after deriving public key. - - s := &signer{ - name: name, - hash: uint32(hash), - } - - var pubkey []byte - - alg, key := key[0], key[1:] - switch alg { - default: - return nil, errSignerAlg - - case algEd25519: - if len(key) != 32 { - return nil, errSignerID - } - key = ed25519.NewKeyFromSeed(key) - pubkey = append([]byte{algEd25519}, key[32:]...) - s.sign = func(msg []byte) ([]byte, error) { - return ed25519.Sign(key, msg), nil - } - } - - if uint32(hash) != keyHash(name, pubkey) { - return nil, errSignerHash - } - - return s, nil -} - -var ( - errSignerID = errors.New("malformed verifier id") - errSignerAlg = errors.New("unknown verifier algorithm") - errSignerHash = errors.New("invalid verifier hash") -) - -// signer is a trivial Signer implementation. -type signer struct { - name string - hash uint32 - sign func([]byte) ([]byte, error) -} - -func (s *signer) Name() string { return s.name } -func (s *signer) KeyHash() uint32 { return s.hash } -func (s *signer) Sign(msg []byte) ([]byte, error) { return s.sign(msg) } - -// GenerateKey generates a signer and verifier key pair for a named server. -// The signer key skey is private and must be kept secret. -func GenerateKey(rand io.Reader, name string) (skey, vkey string, err error) { - pub, priv, err := ed25519.GenerateKey(rand) - if err != nil { - return "", "", err - } - pubkey := append([]byte{algEd25519}, pub...) - privkey := append([]byte{algEd25519}, priv.Seed()...) - h := keyHash(name, pubkey) - - skey = fmt.Sprintf("PRIVATE+KEY+%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(privkey)) - vkey = fmt.Sprintf("%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(pubkey)) - return skey, vkey, nil -} - -// NewEd25519VerifierKey returns an encoded verifier key using the given name -// and Ed25519 public key. -func NewEd25519VerifierKey(name string, key ed25519.PublicKey) (string, error) { - if len(key) != ed25519.PublicKeySize { - return "", fmt.Errorf("invalid public key size %d, expected %d", len(key), ed25519.PublicKeySize) - } - - pubkey := append([]byte{algEd25519}, key...) - hash := keyHash(name, pubkey) - - b64Key := base64.StdEncoding.EncodeToString(pubkey) - return fmt.Sprintf("%s+%08x+%s", name, hash, b64Key), nil -} - -// A Verifiers is a collection of known verifier keys. -type Verifiers interface { - // Verifier returns the Verifier associated with the key - // identified by the name and hash. - // If the name, hash pair is unknown, Verifier should return - // an UnknownVerifierError. - Verifier(name string, hash uint32) (Verifier, error) -} - -// An UnknownVerifierError indicates that the given key is not known. -// The Open function records signatures without associated verifiers as -// unverified signatures. -type UnknownVerifierError struct { - Name string - KeyHash uint32 -} - -func (e *UnknownVerifierError) Error() string { - return fmt.Sprintf("unknown key %s+%08x", e.Name, e.KeyHash) -} - -// An ambiguousVerifierError indicates that the given name and hash -// match multiple keys passed to VerifierList. -// (If this happens, some malicious actor has taken control of the -// verifier list, at which point we may as well give up entirely, -// but we diagnose the problem instead.) -type ambiguousVerifierError struct { - name string - hash uint32 -} - -func (e *ambiguousVerifierError) Error() string { - return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash) -} - -// VerifierList returns a Verifiers implementation that uses the given list of verifiers. -func VerifierList(list ...Verifier) Verifiers { - m := make(verifierMap) - for _, v := range list { - k := nameHash{v.Name(), v.KeyHash()} - m[k] = append(m[k], v) - } - return m -} - -type nameHash struct { - name string - hash uint32 -} - -type verifierMap map[nameHash][]Verifier - -func (m verifierMap) Verifier(name string, hash uint32) (Verifier, error) { - v, ok := m[nameHash{name, hash}] - if !ok { - return nil, &UnknownVerifierError{name, hash} - } - if len(v) > 1 { - return nil, &ambiguousVerifierError{name, hash} - } - return v[0], nil -} - -// A Note is a text and signatures. -type Note struct { - Text string // text of note - Sigs []Signature // verified signatures - UnverifiedSigs []Signature // unverified signatures -} - -// A Signature is a single signature found in a note. -type Signature struct { - // Name and Hash give the name and key hash - // for the key that generated the signature. - Name string - Hash uint32 - - // Base64 records the base64-encoded signature bytes. - Base64 string -} - -// An UnverifiedNoteError indicates that the note -// successfully parsed but had no verifiable signatures. -type UnverifiedNoteError struct { - Note *Note -} - -func (e *UnverifiedNoteError) Error() string { - return "note has no verifiable signatures" -} - -// An InvalidSignatureError indicates that the given key was known -// and the associated Verifier rejected the signature. -type InvalidSignatureError struct { - Name string - Hash uint32 -} - -func (e *InvalidSignatureError) Error() string { - return fmt.Sprintf("invalid signature for key %s+%08x", e.Name, e.Hash) -} - -var ( - errMalformedNote = errors.New("malformed note") - errInvalidSigner = errors.New("invalid signer") - - sigSplit = []byte("\n\n") - sigPrefix = []byte("— ") -) - -// Open opens and parses the message msg, checking signatures from the known verifiers. -// -// For each signature in the message, Open calls known.Verifier to find a verifier. -// If known.Verifier returns a verifier and the verifier accepts the signature, -// Open records the signature in the returned note's Sigs field. -// If known.Verifier returns a verifier but the verifier rejects the signature, -// Open returns an InvalidSignatureError. -// If known.Verifier returns an UnknownVerifierError, -// Open records the signature in the returned note's UnverifiedSigs field. -// If known.Verifier returns any other error, Open returns that error. -// -// If no known verifier has signed an otherwise valid note, -// Open returns an UnverifiedNoteError. -// In this case, the unverified note can be fetched from inside the error. -func Open(msg []byte, known Verifiers) (*Note, error) { - if known == nil { - // Treat nil Verifiers as empty list, to produce useful error instead of crash. - known = VerifierList() - } - - // Must have valid UTF-8 with no non-newline ASCII control characters. - for i := 0; i < len(msg); { - r, size := utf8.DecodeRune(msg[i:]) - if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 { - return nil, errMalformedNote - } - i += size - } - - // Must end with signature block preceded by blank line. - split := bytes.LastIndex(msg, sigSplit) - if split < 0 { - return nil, errMalformedNote - } - text, sigs := msg[:split+1], msg[split+2:] - if len(sigs) == 0 || sigs[len(sigs)-1] != '\n' { - return nil, errMalformedNote - } - - n := &Note{ - Text: string(text), - } - - var buf bytes.Buffer - buf.Write(text) - - // Parse and verify signatures. - // Ignore duplicate signatures. - seen := make(map[nameHash]bool) - seenUnverified := make(map[string]bool) - numSig := 0 - for len(sigs) > 0 { - // Pull out next signature line. - // We know sigs[len(sigs)-1] == '\n', so IndexByte always finds one. - i := bytes.IndexByte(sigs, '\n') - line := sigs[:i] - sigs = sigs[i+1:] - - if !bytes.HasPrefix(line, sigPrefix) { - return nil, errMalformedNote - } - line = line[len(sigPrefix):] - name, b64 := chop(string(line), " ") - sig, err := base64.StdEncoding.DecodeString(b64) - if err != nil || !isValidName(name) || b64 == "" || len(sig) < 5 { - return nil, errMalformedNote - } - hash := binary.BigEndian.Uint32(sig[0:4]) - sig = sig[4:] - - if numSig++; numSig > 100 { - // Avoid spending forever parsing a note with many signatures. - return nil, errMalformedNote - } - - v, err := known.Verifier(name, hash) - if _, ok := err.(*UnknownVerifierError); ok { - // Drop repeated identical unverified signatures. - if seenUnverified[string(line)] { - continue - } - seenUnverified[string(line)] = true - n.UnverifiedSigs = append(n.UnverifiedSigs, Signature{Name: name, Hash: hash, Base64: b64}) - continue - } - if err != nil { - return nil, err - } - - // Drop repeated signatures by a single verifier. - if seen[nameHash{name, hash}] { - continue - } - seen[nameHash{name, hash}] = true - - ok := v.Verify(text, sig) - if !ok { - return nil, &InvalidSignatureError{name, hash} - } - - n.Sigs = append(n.Sigs, Signature{Name: name, Hash: hash, Base64: b64}) - } - - // Parsed and verified all the signatures. - if len(n.Sigs) == 0 { - return nil, &UnverifiedNoteError{n} - } - return n, nil -} - -// Sign signs the note with the given signers and returns the encoded message. -// The new signatures from signers are listed in the encoded message after -// the existing signatures already present in n.Sigs. -// If any signer uses the same key as an existing signature, -// the existing signature is elided from the output. -func Sign(n *Note, signers ...Signer) ([]byte, error) { - var buf bytes.Buffer - if !strings.HasSuffix(n.Text, "\n") { - return nil, errMalformedNote - } - buf.WriteString(n.Text) - - // Prepare signatures. - var sigs bytes.Buffer - have := make(map[nameHash]bool) - for _, s := range signers { - name := s.Name() - hash := s.KeyHash() - have[nameHash{name, hash}] = true - if !isValidName(name) { - return nil, errInvalidSigner - } - - sig, err := s.Sign(buf.Bytes()) // buf holds n.Text - if err != nil { - return nil, err - } - - var hbuf [4]byte - binary.BigEndian.PutUint32(hbuf[:], hash) - b64 := base64.StdEncoding.EncodeToString(append(hbuf[:], sig...)) - sigs.WriteString("— ") - sigs.WriteString(name) - sigs.WriteString(" ") - sigs.WriteString(b64) - sigs.WriteString("\n") - } - - buf.WriteString("\n") - - // Emit existing signatures not replaced by new ones. - for _, list := range [][]Signature{n.Sigs, n.UnverifiedSigs} { - for _, sig := range list { - name, hash := sig.Name, sig.Hash - if !isValidName(name) { - return nil, errMalformedNote - } - if have[nameHash{name, hash}] { - continue - } - // Double-check hash against base64. - raw, err := base64.StdEncoding.DecodeString(sig.Base64) - if err != nil || len(raw) < 4 || binary.BigEndian.Uint32(raw) != hash { - return nil, errMalformedNote - } - buf.WriteString("— ") - buf.WriteString(sig.Name) - buf.WriteString(" ") - buf.WriteString(sig.Base64) - buf.WriteString("\n") - } - } - buf.Write(sigs.Bytes()) - - return buf.Bytes(), nil -} diff --git a/libgo/go/cmd/go/internal/note/note_test.go b/libgo/go/cmd/go/internal/note/note_test.go deleted file mode 100644 index 729324647e7..00000000000 --- a/libgo/go/cmd/go/internal/note/note_test.go +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package note - -import ( - "crypto/ed25519" - "crypto/rand" - "errors" - "strings" - "testing" - "testing/iotest" -) - -func TestNewVerifier(t *testing.T) { - vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW" - _, err := NewVerifier(vkey) - if err != nil { - t.Fatal(err) - } - - // Check various manglings are not accepted. - badKey := func(k string) { - _, err := NewVerifier(k) - if err == nil { - t.Errorf("NewVerifier(%q) succeeded, should have failed", k) - } - } - - b := []byte(vkey) - for i := 0; i <= len(b); i++ { - for j := i + 1; j <= len(b); j++ { - if i != 0 || j != len(b) { - badKey(string(b[i:j])) - } - } - } - for i := 0; i < len(b); i++ { - b[i]++ - badKey(string(b)) - b[i]-- - } - - badKey("PeterNeumann+cc469956+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TWBADKEY==") // wrong length key, with adjusted key hash - badKey("PeterNeumann+173116ae+ZRpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW") // unknown algorithm, with adjusted key hash -} - -func TestNewSigner(t *testing.T) { - skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz" - _, err := NewSigner(skey) - if err != nil { - t.Fatal(err) - } - - // Check various manglings are not accepted. - b := []byte(skey) - for i := 0; i <= len(b); i++ { - for j := i + 1; j <= len(b); j++ { - if i == 0 && j == len(b) { - continue - } - _, err := NewSigner(string(b[i:j])) - if err == nil { - t.Errorf("NewSigner(%q) succeeded, should have failed", b[i:j]) - } - } - } - for i := 0; i < len(b); i++ { - b[i]++ - _, err := NewSigner(string(b)) - if err == nil { - t.Errorf("NewSigner(%q) succeeded, should have failed", b) - } - b[i]-- - } -} - -func testSignerAndVerifier(t *testing.T, Name string, signer Signer, verifier Verifier) { - if name := signer.Name(); name != Name { - t.Errorf("signer.Name() = %q, want %q", name, Name) - } - if name := verifier.Name(); name != Name { - t.Errorf("verifier.Name() = %q, want %q", name, Name) - } - shash := signer.KeyHash() - vhash := verifier.KeyHash() - if shash != vhash { - t.Errorf("signer.KeyHash() = %#08x != verifier.KeyHash() = %#08x", shash, vhash) - } - - msg := []byte("hi") - sig, err := signer.Sign(msg) - if err != nil { - t.Fatalf("signer.Sign: %v", err) - } - if !verifier.Verify(msg, sig) { - t.Fatalf("verifier.Verify failed on signature returned by signer.Sign") - } - sig[0]++ - if verifier.Verify(msg, sig) { - t.Fatalf("verifier.Verify succceeded on corrupt signature") - } - sig[0]-- - msg[0]++ - if verifier.Verify(msg, sig) { - t.Fatalf("verifier.Verify succceeded on corrupt message") - } -} - -func TestGenerateKey(t *testing.T) { - // Generate key pair, make sure it is all self-consistent. - const Name = "EnochRoot" - - skey, vkey, err := GenerateKey(rand.Reader, Name) - if err != nil { - t.Fatalf("GenerateKey: %v", err) - } - signer, err := NewSigner(skey) - if err != nil { - t.Fatalf("NewSigner: %v", err) - } - verifier, err := NewVerifier(vkey) - if err != nil { - t.Fatalf("NewVerifier: %v", err) - } - - testSignerAndVerifier(t, Name, signer, verifier) - - // Check that GenerateKey returns error from rand reader. - _, _, err = GenerateKey(iotest.TimeoutReader(iotest.OneByteReader(rand.Reader)), Name) - if err == nil { - t.Fatalf("GenerateKey succeeded with error-returning rand reader") - } -} - -func TestFromEd25519(t *testing.T) { - const Name = "EnochRoot" - - pub, priv, err := ed25519.GenerateKey(rand.Reader) - if err != nil { - t.Fatalf("GenerateKey: %v", err) - } - signer, err := newSignerFromEd25519Seed(Name, priv.Seed()) - if err != nil { - t.Fatalf("newSignerFromEd25519Seed: %v", err) - } - vkey, err := NewEd25519VerifierKey(Name, pub) - if err != nil { - t.Fatalf("NewEd25519VerifierKey: %v", err) - } - verifier, err := NewVerifier(vkey) - if err != nil { - t.Fatalf("NewVerifier: %v", err) - } - - testSignerAndVerifier(t, Name, signer, verifier) - - // Check that wrong key sizes return errors. - _, err = NewEd25519VerifierKey(Name, pub[:len(pub)-1]) - if err == nil { - t.Errorf("NewEd25519VerifierKey succeeded with a seed of the wrong size") - } -} - -// newSignerFromEd25519Seed constructs a new signer from a verifier name and a -// crypto/ed25519 private key seed. -func newSignerFromEd25519Seed(name string, seed []byte) (Signer, error) { - if len(seed) != ed25519.SeedSize { - return nil, errors.New("invalid seed size") - } - priv := ed25519.NewKeyFromSeed(seed) - pub := priv[32:] - - pubkey := append([]byte{algEd25519}, pub...) - hash := keyHash(name, pubkey) - - s := &signer{ - name: name, - hash: uint32(hash), - sign: func(msg []byte) ([]byte, error) { - return ed25519.Sign(priv, msg), nil - }, - } - return s, nil -} - -func TestSign(t *testing.T) { - skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz" - text := "If you think cryptography is the answer to your problem,\n" + - "then you don't know what your problem is.\n" - - signer, err := NewSigner(skey) - if err != nil { - t.Fatal(err) - } - - msg, err := Sign(&Note{Text: text}, signer) - if err != nil { - t.Fatal(err) - } - - want := `If you think cryptography is the answer to your problem, -then you don't know what your problem is. - -— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM= -` - if string(msg) != want { - t.Errorf("Sign: wrong output\nhave:\n%s\nwant:\n%s", msg, want) - } - - // Check that existing signature is replaced by new one. - msg, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "PeterNeumann", Hash: 0xc74f20a3, Base64: "BADSIGN="}}}, signer) - if err != nil { - t.Fatal(err) - } - if string(msg) != want { - t.Errorf("Sign replacing signature: wrong output\nhave:\n%s\nwant:\n%s", msg, want) - } - - // Check various bad inputs. - _, err = Sign(&Note{Text: "abc"}, signer) - if err == nil || err.Error() != "malformed note" { - t.Fatalf("Sign with short text: %v, want malformed note error", err) - } - - _, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "a+b", Base64: "ABCD"}}}) - if err == nil || err.Error() != "malformed note" { - t.Fatalf("Sign with bad name: %v, want malformed note error", err) - } - - _, err = Sign(&Note{Text: text, Sigs: []Signature{{Name: "PeterNeumann", Hash: 0xc74f20a3, Base64: "BADHASH="}}}) - if err == nil || err.Error() != "malformed note" { - t.Fatalf("Sign with bad pre-filled signature: %v, want malformed note error", err) - } - - _, err = Sign(&Note{Text: text}, &badSigner{signer}) - if err == nil || err.Error() != "invalid signer" { - t.Fatalf("Sign with bad signer: %v, want invalid signer error", err) - } - - _, err = Sign(&Note{Text: text}, &errSigner{signer}) - if err != errSurprise { - t.Fatalf("Sign with failing signer: %v, want errSurprise", err) - } -} - -func TestVerifierList(t *testing.T) { - peterKey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW" - peterVerifier, err := NewVerifier(peterKey) - if err != nil { - t.Fatal(err) - } - - enochKey := "EnochRoot+af0cfe78+ATtqJ7zOtqQtYqOo0CpvDXNlMhV3HeJDpjrASKGLWdop" - enochVerifier, err := NewVerifier(enochKey) - if err != nil { - t.Fatal(err) - } - - list := VerifierList(peterVerifier, enochVerifier, enochVerifier) - v, err := list.Verifier("PeterNeumann", 0xc74f20a3) - if v != peterVerifier || err != nil { - t.Fatalf("list.Verifier(peter) = %v, %v, want %v, nil", v, err, peterVerifier) - } - v, err = list.Verifier("PeterNeumann", 0xc74f20a4) - if v != nil || err == nil || err.Error() != "unknown key PeterNeumann+c74f20a4" { - t.Fatalf("list.Verifier(peter bad hash) = %v, %v, want nil, unknown key error", v, err) - } - - v, err = list.Verifier("PeterNeuman", 0xc74f20a3) - if v != nil || err == nil || err.Error() != "unknown key PeterNeuman+c74f20a3" { - t.Fatalf("list.Verifier(peter bad name) = %v, %v, want nil, unknown key error", v, err) - } - v, err = list.Verifier("EnochRoot", 0xaf0cfe78) - if v != nil || err == nil || err.Error() != "ambiguous key EnochRoot+af0cfe78" { - t.Fatalf("list.Verifier(enoch) = %v, %v, want nil, ambiguous key error", v, err) - } -} - -type badSigner struct { - Signer -} - -func (b *badSigner) Name() string { - return "bad name" -} - -var errSurprise = errors.New("surprise!") - -type errSigner struct { - Signer -} - -func (e *errSigner) Sign([]byte) ([]byte, error) { - return nil, errSurprise -} - -func TestOpen(t *testing.T) { - peterKey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW" - peterVerifier, err := NewVerifier(peterKey) - if err != nil { - t.Fatal(err) - } - - enochKey := "EnochRoot+af0cfe78+ATtqJ7zOtqQtYqOo0CpvDXNlMhV3HeJDpjrASKGLWdop" - enochVerifier, err := NewVerifier(enochKey) - if err != nil { - t.Fatal(err) - } - - text := `If you think cryptography is the answer to your problem, -then you don't know what your problem is. -` - peterSig := "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n" - enochSig := "— EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ=\n" - - peter := Signature{"PeterNeumann", 0xc74f20a3, "x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM="} - enoch := Signature{"EnochRoot", 0xaf0cfe78, "rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ="} - - // Check one signature verified, one not. - n, err := Open([]byte(text+"\n"+peterSig+enochSig), VerifierList(peterVerifier)) - if err != nil { - t.Fatal(err) - } - if n.Text != text { - t.Errorf("n.Text = %q, want %q", n.Text, text) - } - if len(n.Sigs) != 1 || n.Sigs[0] != peter { - t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter}) - } - if len(n.UnverifiedSigs) != 1 || n.UnverifiedSigs[0] != enoch { - t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter}) - } - - // Check both verified. - n, err = Open([]byte(text+"\n"+peterSig+enochSig), VerifierList(peterVerifier, enochVerifier)) - if err != nil { - t.Fatal(err) - } - if len(n.Sigs) != 2 || n.Sigs[0] != peter || n.Sigs[1] != enoch { - t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter, enoch}) - } - if len(n.UnverifiedSigs) != 0 { - t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{}) - } - - // Check both unverified. - n, err = Open([]byte(text+"\n"+peterSig+enochSig), VerifierList()) - if n != nil || err == nil { - t.Fatalf("Open unverified = %v, %v, want nil, error", n, err) - } - e, ok := err.(*UnverifiedNoteError) - if !ok { - t.Fatalf("Open unverified: err is %T, want *UnverifiedNoteError", err) - } - if err.Error() != "note has no verifiable signatures" { - t.Fatalf("Open unverified: err.Error() = %q, want %q", err.Error(), "note has no verifiable signatures") - } - - n = e.Note - if n == nil { - t.Fatalf("Open unverified: missing note in UnverifiedNoteError") - } - if len(n.Sigs) != 0 { - t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{}) - } - if len(n.UnverifiedSigs) != 2 || n.UnverifiedSigs[0] != peter || n.UnverifiedSigs[1] != enoch { - t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter, enoch}) - } - - // Check duplicated verifier. - _, err = Open([]byte(text+"\n"+enochSig), VerifierList(enochVerifier, peterVerifier, enochVerifier)) - if err == nil || err.Error() != "ambiguous key EnochRoot+af0cfe78" { - t.Fatalf("Open with duplicated verifier: err=%v, want ambiguous key", err) - } - - // Check unused duplicated verifier. - _, err = Open([]byte(text+"\n"+peterSig), VerifierList(enochVerifier, peterVerifier, enochVerifier)) - if err != nil { - t.Fatal(err) - } - - // Check too many signatures. - n, err = Open([]byte(text+"\n"+strings.Repeat(peterSig, 101)), VerifierList(peterVerifier)) - if n != nil || err == nil || err.Error() != "malformed note" { - t.Fatalf("Open too many verified signatures = %v, %v, want nil, malformed note error", n, err) - } - n, err = Open([]byte(text+"\n"+strings.Repeat(peterSig, 101)), VerifierList()) - if n != nil || err == nil || err.Error() != "malformed note" { - t.Fatalf("Open too many verified signatures = %v, %v, want nil, malformed note error", n, err) - } - - // Invalid signature. - n, err = Open([]byte(text+"\n"+peterSig[:60]+"ABCD"+peterSig[60:]), VerifierList(peterVerifier)) - if n != nil || err == nil || err.Error() != "invalid signature for key PeterNeumann+c74f20a3" { - t.Fatalf("Open too many verified signatures = %v, %v, want nil, invalid signature error", n, err) - } - - // Duplicated verified and unverified signatures. - enochABCD := Signature{"EnochRoot", 0xaf0cfe78, "rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n" + "ABCD" + "2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ="} - n, err = Open([]byte(text+"\n"+peterSig+peterSig+enochSig+enochSig+enochSig[:60]+"ABCD"+enochSig[60:]), VerifierList(peterVerifier)) - if err != nil { - t.Fatal(err) - } - if len(n.Sigs) != 1 || n.Sigs[0] != peter { - t.Errorf("n.Sigs:\nhave %v\nwant %v", n.Sigs, []Signature{peter}) - } - if len(n.UnverifiedSigs) != 2 || n.UnverifiedSigs[0] != enoch || n.UnverifiedSigs[1] != enochABCD { - t.Errorf("n.UnverifiedSigs:\nhave %v\nwant %v", n.UnverifiedSigs, []Signature{enoch, enochABCD}) - } - - // Invalid encoded message syntax. - badMsgs := []string{ - text, - text + "\n", - text + "\n" + peterSig[:len(peterSig)-1], - "\x01" + text + "\n" + peterSig, - "\xff" + text + "\n" + peterSig, - text + "\n" + "— Bad Name x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=", - text + "\n" + peterSig + "Unexpected line.\n", - } - for _, msg := range badMsgs { - n, err := Open([]byte(msg), VerifierList(peterVerifier)) - if n != nil || err == nil || err.Error() != "malformed note" { - t.Fatalf("Open bad msg = %v, %v, want nil, malformed note error\nmsg:\n%s", n, err, msg) - } - } -} - -func BenchmarkOpen(b *testing.B) { - vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW" - msg := []byte("If you think cryptography is the answer to your problem,\n" + - "then you don't know what your problem is.\n" + - "\n" + - "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n") - - verifier, err := NewVerifier(vkey) - if err != nil { - b.Fatal(err) - } - verifiers := VerifierList(verifier) - verifiers0 := VerifierList() - - // Try with 0 signatures and 1 signature so we can tell how much each signature adds. - - b.Run("Sig0", func(b *testing.B) { - for i := 0; i < b.N; i++ { - _, err := Open(msg, verifiers0) - e, ok := err.(*UnverifiedNoteError) - if !ok { - b.Fatal("expected UnverifiedNoteError") - } - n := e.Note - if len(n.Sigs) != 0 || len(n.UnverifiedSigs) != 1 { - b.Fatal("wrong signature count") - } - } - }) - - b.Run("Sig1", func(b *testing.B) { - for i := 0; i < b.N; i++ { - n, err := Open(msg, verifiers) - if err != nil { - b.Fatal(err) - } - if len(n.Sigs) != 1 || len(n.UnverifiedSigs) != 0 { - b.Fatal("wrong signature count") - } - } - }) -} diff --git a/libgo/go/cmd/go/internal/renameio/renameio_test.go b/libgo/go/cmd/go/internal/renameio/renameio_test.go index 81dba6d5451..ee2f3ba1bb8 100644 --- a/libgo/go/cmd/go/internal/renameio/renameio_test.go +++ b/libgo/go/cmd/go/internal/renameio/renameio_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build !plan9 +// +build !plan9 package renameio @@ -131,10 +131,18 @@ func TestConcurrentReadsAndWrites(t *testing.T) { } var minReadSuccesses int64 = attempts - if runtime.GOOS == "windows" { + + switch runtime.GOOS { + case "windows": // Windows produces frequent "Access is denied" errors under heavy rename load. - // As long as those are the only errors and *some* of the writes succeed, we're happy. + // As long as those are the only errors and *some* of the reads succeed, we're happy. minReadSuccesses = attempts / 4 + + case "darwin": + // The filesystem on macOS 10.14 occasionally fails with "no such file or + // directory" errors. See https://golang.org/issue/33041. The flake rate is + // fairly low, so ensure that at least 75% of attempts succeed. + minReadSuccesses = attempts - (attempts / 4) } if readSuccesses < minReadSuccesses { diff --git a/libgo/go/cmd/go/internal/renameio/umask_test.go b/libgo/go/cmd/go/internal/renameio/umask_test.go index 1a471c9e4e6..d75d67c9a93 100644 --- a/libgo/go/cmd/go/internal/renameio/umask_test.go +++ b/libgo/go/cmd/go/internal/renameio/umask_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build !nacl,!plan9,!windows,!js +// +build !plan9,!windows,!js package renameio @@ -19,6 +19,7 @@ func TestWriteFileModeAppliesUmask(t *testing.T) { if err != nil { t.Fatalf("Failed to create temporary directory: %v", err) } + defer os.RemoveAll(dir) const mode = 0644 const umask = 0007 @@ -29,7 +30,6 @@ func TestWriteFileModeAppliesUmask(t *testing.T) { if err != nil { t.Fatalf("Failed to write file: %v", err) } - defer os.RemoveAll(dir) fi, err := os.Stat(file) if err != nil { diff --git a/libgo/go/cmd/go/internal/robustio/robustio_darwin.go b/libgo/go/cmd/go/internal/robustio/robustio_darwin.go new file mode 100644 index 00000000000..99fd8ebc2ff --- /dev/null +++ b/libgo/go/cmd/go/internal/robustio/robustio_darwin.go @@ -0,0 +1,21 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package robustio + +import ( + "errors" + "syscall" +) + +const errFileNotFound = syscall.ENOENT + +// isEphemeralError returns true if err may be resolved by waiting. +func isEphemeralError(err error) bool { + var errno syscall.Errno + if errors.As(err, &errno) { + return errno == errFileNotFound + } + return false +} diff --git a/libgo/go/cmd/go/internal/robustio/robustio_flaky.go b/libgo/go/cmd/go/internal/robustio/robustio_flaky.go new file mode 100644 index 00000000000..e57c8c74c4c --- /dev/null +++ b/libgo/go/cmd/go/internal/robustio/robustio_flaky.go @@ -0,0 +1,92 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build windows darwin + +package robustio + +import ( + "errors" + "io/ioutil" + "math/rand" + "os" + "syscall" + "time" +) + +const arbitraryTimeout = 500 * time.Millisecond + +// retry retries ephemeral errors from f up to an arbitrary timeout +// to work around filesystem flakiness on Windows and Darwin. +func retry(f func() (err error, mayRetry bool)) error { + var ( + bestErr error + lowestErrno syscall.Errno + start time.Time + nextSleep time.Duration = 1 * time.Millisecond + ) + for { + err, mayRetry := f() + if err == nil || !mayRetry { + return err + } + + var errno syscall.Errno + if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) { + bestErr = err + lowestErrno = errno + } else if bestErr == nil { + bestErr = err + } + + if start.IsZero() { + start = time.Now() + } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout { + break + } + time.Sleep(nextSleep) + nextSleep += time.Duration(rand.Int63n(int64(nextSleep))) + } + + return bestErr +} + +// rename is like os.Rename, but retries ephemeral errors. +// +// On Windows it wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with +// MOVEFILE_REPLACE_EXISTING. +// +// Windows also provides a different system call, ReplaceFile, +// that provides similar semantics, but perhaps preserves more metadata. (The +// documentation on the differences between the two is very sparse.) +// +// Empirical error rates with MoveFileEx are lower under modest concurrency, so +// for now we're sticking with what the os package already provides. +func rename(oldpath, newpath string) (err error) { + return retry(func() (err error, mayRetry bool) { + err = os.Rename(oldpath, newpath) + return err, isEphemeralError(err) + }) +} + +// readFile is like ioutil.ReadFile, but retries ephemeral errors. +func readFile(filename string) ([]byte, error) { + var b []byte + err := retry(func() (err error, mayRetry bool) { + b, err = ioutil.ReadFile(filename) + + // Unlike in rename, we do not retry errFileNotFound here: it can occur + // as a spurious error, but the file may also genuinely not exist, so the + // increase in robustness is probably not worth the extra latency. + return err, isEphemeralError(err) && !errors.Is(err, errFileNotFound) + }) + return b, err +} + +func removeAll(path string) error { + return retry(func() (err error, mayRetry bool) { + err = os.RemoveAll(path) + return err, isEphemeralError(err) + }) +} diff --git a/libgo/go/cmd/go/internal/robustio/robustio_other.go b/libgo/go/cmd/go/internal/robustio/robustio_other.go index 91ca56cb82c..907b5568587 100644 --- a/libgo/go/cmd/go/internal/robustio/robustio_other.go +++ b/libgo/go/cmd/go/internal/robustio/robustio_other.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build !windows +// +build !windows,!darwin package robustio diff --git a/libgo/go/cmd/go/internal/robustio/robustio_windows.go b/libgo/go/cmd/go/internal/robustio/robustio_windows.go index a3d94e566fe..687dcb66f83 100644 --- a/libgo/go/cmd/go/internal/robustio/robustio_windows.go +++ b/libgo/go/cmd/go/internal/robustio/robustio_windows.go @@ -7,88 +7,10 @@ package robustio import ( "errors" "internal/syscall/windows" - "io/ioutil" - "math/rand" - "os" "syscall" - "time" ) -const arbitraryTimeout = 500 * time.Millisecond - -// retry retries ephemeral errors from f up to an arbitrary timeout -// to work around spurious filesystem errors on Windows -func retry(f func() (err error, mayRetry bool)) error { - var ( - bestErr error - lowestErrno syscall.Errno - start time.Time - nextSleep time.Duration = 1 * time.Millisecond - ) - for { - err, mayRetry := f() - if err == nil || !mayRetry { - return err - } - - var errno syscall.Errno - if errors.As(err, &errno) && (lowestErrno == 0 || errno < lowestErrno) { - bestErr = err - lowestErrno = errno - } else if bestErr == nil { - bestErr = err - } - - if start.IsZero() { - start = time.Now() - } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout { - break - } - time.Sleep(nextSleep) - nextSleep += time.Duration(rand.Int63n(int64(nextSleep))) - } - - return bestErr -} - -// rename is like os.Rename, but retries ephemeral errors. -// -// It wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with -// MOVEFILE_REPLACE_EXISTING. -// -// Windows also provides a different system call, ReplaceFile, -// that provides similar semantics, but perhaps preserves more metadata. (The -// documentation on the differences between the two is very sparse.) -// -// Empirical error rates with MoveFileEx are lower under modest concurrency, so -// for now we're sticking with what the os package already provides. -func rename(oldpath, newpath string) (err error) { - return retry(func() (err error, mayRetry bool) { - err = os.Rename(oldpath, newpath) - return err, isEphemeralError(err) - }) -} - -// readFile is like ioutil.ReadFile, but retries ephemeral errors. -func readFile(filename string) ([]byte, error) { - var b []byte - err := retry(func() (err error, mayRetry bool) { - b, err = ioutil.ReadFile(filename) - - // Unlike in rename, we do not retry ERROR_FILE_NOT_FOUND here: it can occur - // as a spurious error, but the file may also genuinely not exist, so the - // increase in robustness is probably not worth the extra latency. - return err, isEphemeralError(err) && !errors.Is(err, syscall.ERROR_FILE_NOT_FOUND) - }) - return b, err -} - -func removeAll(path string) error { - return retry(func() (err error, mayRetry bool) { - err = os.RemoveAll(path) - return err, isEphemeralError(err) - }) -} +const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND // isEphemeralError returns true if err may be resolved by waiting. func isEphemeralError(err error) bool { diff --git a/libgo/go/cmd/go/internal/run/run.go b/libgo/go/cmd/go/internal/run/run.go index 71da5adc934..2edae38ccaa 100644 --- a/libgo/go/cmd/go/internal/run/run.go +++ b/libgo/go/cmd/go/internal/run/run.go @@ -33,7 +33,7 @@ If the -exec flag is given, 'go run' invokes the binary using xprog: If the -exec flag is not given, GOOS or GOARCH is different from the system default, and a program named go_$GOOS_$GOARCH_exec can be found on the current search path, 'go run' invokes the binary using that program, -for example 'go_nacl_386_exec a.out arguments...'. This allows execution of +for example 'go_js_wasm_exec a.out arguments...'. This allows execution of cross-compiled programs when a simulator or other execution method is available. @@ -49,7 +49,7 @@ See also: go build. func init() { CmdRun.Run = runRun // break init loop - work.AddBuildFlags(CmdRun) + work.AddBuildFlags(CmdRun, work.DefaultBuildFlags) CmdRun.Flag.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "") } diff --git a/libgo/go/cmd/go/internal/search/search.go b/libgo/go/cmd/go/internal/search/search.go index 0167c8d7550..ad33e60af14 100644 --- a/libgo/go/cmd/go/internal/search/search.go +++ b/libgo/go/cmd/go/internal/search/search.go @@ -125,32 +125,43 @@ func SetModRoot(dir string) { modRoot = dir } -// MatchPackagesInFS is like allPackages but is passed a pattern -// beginning ./ or ../, meaning it should scan the tree rooted -// at the given directory. There are ... in the pattern too. -// (See go help packages for pattern syntax.) +// MatchPackagesInFS is like MatchPackages but is passed a pattern that +// begins with an absolute path or "./" or "../". On Windows, the pattern may +// use slash or backslash separators or a mix of both. +// +// MatchPackagesInFS scans the tree rooted at the directory that contains the +// first "..." wildcard and returns a match with packages that func MatchPackagesInFS(pattern string) *Match { m := &Match{ Pattern: pattern, Literal: false, } + // Clean the path and create a matching predicate. + // filepath.Clean removes "./" prefixes (and ".\" on Windows). We need to + // preserve these, since they are meaningful in MatchPattern and in + // returned import paths. + cleanPattern := filepath.Clean(pattern) + isLocal := strings.HasPrefix(pattern, "./") || (os.PathSeparator == '\\' && strings.HasPrefix(pattern, `.\`)) + prefix := "" + if cleanPattern != "." && isLocal { + prefix = "./" + cleanPattern = "." + string(os.PathSeparator) + cleanPattern + } + slashPattern := filepath.ToSlash(cleanPattern) + match := MatchPattern(slashPattern) + // Find directory to begin the scan. // Could be smarter but this one optimization // is enough for now, since ... is usually at the // end of a path. - i := strings.Index(pattern, "...") - dir, _ := path.Split(pattern[:i]) + i := strings.Index(cleanPattern, "...") + dir, _ := filepath.Split(cleanPattern[:i]) // pattern begins with ./ or ../. // path.Clean will discard the ./ but not the ../. // We need to preserve the ./ for pattern matching // and in the returned import paths. - prefix := "" - if strings.HasPrefix(pattern, "./") { - prefix = "./" - } - match := MatchPattern(pattern) if modRoot != "" { abs, err := filepath.Abs(dir) @@ -241,7 +252,7 @@ func TreeCanMatchPattern(pattern string) func(name string) bool { // // First, /... at the end of the pattern can match an empty string, // so that net/... matches both net and packages in its subdirectories, like net/http. -// Second, any slash-separted pattern element containing a wildcard never +// Second, any slash-separated pattern element containing a wildcard never // participates in a match of the "vendor" element in the path of a vendored // package, so that ./... does not match packages in subdirectories of // ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do. @@ -361,32 +372,49 @@ func ImportPathsQuiet(patterns []string) []*Match { return out } -// CleanPatterns returns the patterns to use for the given -// command line. It canonicalizes the patterns but does not -// evaluate any matches. +// CleanPatterns returns the patterns to use for the given command line. It +// canonicalizes the patterns but does not evaluate any matches. For patterns +// that are not local or absolute paths, it preserves text after '@' to avoid +// modifying version queries. func CleanPatterns(patterns []string) []string { if len(patterns) == 0 { return []string{"."} } var out []string for _, a := range patterns { - // Arguments are supposed to be import paths, but - // as a courtesy to Windows developers, rewrite \ to / - // in command-line arguments. Handles .\... and so on. - if filepath.Separator == '\\' { - a = strings.ReplaceAll(a, `\`, `/`) + var p, v string + if build.IsLocalImport(a) || filepath.IsAbs(a) { + p = a + } else if i := strings.IndexByte(a, '@'); i < 0 { + p = a + } else { + p = a[:i] + v = a[i:] } - // Put argument in canonical form, but preserve leading ./. - if strings.HasPrefix(a, "./") { - a = "./" + path.Clean(a) - if a == "./." { - a = "." - } + // Arguments may be either file paths or import paths. + // As a courtesy to Windows developers, rewrite \ to / + // in arguments that look like import paths. + // Don't replace slashes in absolute paths. + if filepath.IsAbs(p) { + p = filepath.Clean(p) } else { - a = path.Clean(a) + if filepath.Separator == '\\' { + p = strings.ReplaceAll(p, `\`, `/`) + } + + // Put argument in canonical form, but preserve leading ./. + if strings.HasPrefix(p, "./") { + p = "./" + path.Clean(p) + if p == "./." { + p = "." + } + } else { + p = path.Clean(p) + } } - out = append(out, a) + + out = append(out, p+v) } return out } diff --git a/libgo/go/cmd/go/internal/search/search_test.go b/libgo/go/cmd/go/internal/search/search_test.go index 0bef765fa45..5f27daf3fb8 100644 --- a/libgo/go/cmd/go/internal/search/search_test.go +++ b/libgo/go/cmd/go/internal/search/search_test.go @@ -33,7 +33,7 @@ var matchPatternTests = ` match net net/http not not/http not/net/http netchan - # Second, any slash-separted pattern element containing a wildcard never + # Second, any slash-separated pattern element containing a wildcard never # participates in a match of the "vendor" element in the path of a vendored # package, so that ./... does not match packages in subdirectories of # ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do. diff --git a/libgo/go/cmd/go/internal/semver/semver.go b/libgo/go/cmd/go/internal/semver/semver.go deleted file mode 100644 index 122e612dd4b..00000000000 --- a/libgo/go/cmd/go/internal/semver/semver.go +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package semver implements comparison of semantic version strings. -// In this package, semantic version strings must begin with a leading "v", -// as in "v1.0.0". -// -// The general form of a semantic version string accepted by this package is -// -// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] -// -// where square brackets indicate optional parts of the syntax; -// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; -// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers -// using only alphanumeric characters and hyphens; and -// all-numeric PRERELEASE identifiers must not have leading zeros. -// -// This package follows Semantic Versioning 2.0.0 (see semver.org) -// with two exceptions. First, it requires the "v" prefix. Second, it recognizes -// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) -// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. -package semver - -// parsed returns the parsed form of a semantic version string. -type parsed struct { - major string - minor string - patch string - short string - prerelease string - build string - err string -} - -// IsValid reports whether v is a valid semantic version string. -func IsValid(v string) bool { - _, ok := parse(v) - return ok -} - -// Canonical returns the canonical formatting of the semantic version v. -// It fills in any missing .MINOR or .PATCH and discards build metadata. -// Two semantic versions compare equal only if their canonical formattings -// are identical strings. -// The canonical invalid semantic version is the empty string. -func Canonical(v string) string { - p, ok := parse(v) - if !ok { - return "" - } - if p.build != "" { - return v[:len(v)-len(p.build)] - } - if p.short != "" { - return v + p.short - } - return v -} - -// Major returns the major version prefix of the semantic version v. -// For example, Major("v2.1.0") == "v2". -// If v is an invalid semantic version string, Major returns the empty string. -func Major(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return v[:1+len(pv.major)] -} - -// MajorMinor returns the major.minor version prefix of the semantic version v. -// For example, MajorMinor("v2.1.0") == "v2.1". -// If v is an invalid semantic version string, MajorMinor returns the empty string. -func MajorMinor(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - i := 1 + len(pv.major) - if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { - return v[:j] - } - return v[:i] + "." + pv.minor -} - -// Prerelease returns the prerelease suffix of the semantic version v. -// For example, Prerelease("v2.1.0-pre+meta") == "-pre". -// If v is an invalid semantic version string, Prerelease returns the empty string. -func Prerelease(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return pv.prerelease -} - -// Build returns the build suffix of the semantic version v. -// For example, Build("v2.1.0+meta") == "+meta". -// If v is an invalid semantic version string, Build returns the empty string. -func Build(v string) string { - pv, ok := parse(v) - if !ok { - return "" - } - return pv.build -} - -// Compare returns an integer comparing two versions according to -// according to semantic version precedence. -// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. -// -// An invalid semantic version string is considered less than a valid one. -// All invalid semantic version strings compare equal to each other. -func Compare(v, w string) int { - pv, ok1 := parse(v) - pw, ok2 := parse(w) - if !ok1 && !ok2 { - return 0 - } - if !ok1 { - return -1 - } - if !ok2 { - return +1 - } - if c := compareInt(pv.major, pw.major); c != 0 { - return c - } - if c := compareInt(pv.minor, pw.minor); c != 0 { - return c - } - if c := compareInt(pv.patch, pw.patch); c != 0 { - return c - } - return comparePrerelease(pv.prerelease, pw.prerelease) -} - -// Max canonicalizes its arguments and then returns the version string -// that compares greater. -func Max(v, w string) string { - v = Canonical(v) - w = Canonical(w) - if Compare(v, w) > 0 { - return v - } - return w -} - -func parse(v string) (p parsed, ok bool) { - if v == "" || v[0] != 'v' { - p.err = "missing v prefix" - return - } - p.major, v, ok = parseInt(v[1:]) - if !ok { - p.err = "bad major version" - return - } - if v == "" { - p.minor = "0" - p.patch = "0" - p.short = ".0.0" - return - } - if v[0] != '.' { - p.err = "bad minor prefix" - ok = false - return - } - p.minor, v, ok = parseInt(v[1:]) - if !ok { - p.err = "bad minor version" - return - } - if v == "" { - p.patch = "0" - p.short = ".0" - return - } - if v[0] != '.' { - p.err = "bad patch prefix" - ok = false - return - } - p.patch, v, ok = parseInt(v[1:]) - if !ok { - p.err = "bad patch version" - return - } - if len(v) > 0 && v[0] == '-' { - p.prerelease, v, ok = parsePrerelease(v) - if !ok { - p.err = "bad prerelease" - return - } - } - if len(v) > 0 && v[0] == '+' { - p.build, v, ok = parseBuild(v) - if !ok { - p.err = "bad build" - return - } - } - if v != "" { - p.err = "junk on end" - ok = false - return - } - ok = true - return -} - -func parseInt(v string) (t, rest string, ok bool) { - if v == "" { - return - } - if v[0] < '0' || '9' < v[0] { - return - } - i := 1 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - if v[0] == '0' && i != 1 { - return - } - return v[:i], v[i:], true -} - -func parsePrerelease(v string) (t, rest string, ok bool) { - // "A pre-release version MAY be denoted by appending a hyphen and - // a series of dot separated identifiers immediately following the patch version. - // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. - // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." - if v == "" || v[0] != '-' { - return - } - i := 1 - start := 1 - for i < len(v) && v[i] != '+' { - if !isIdentChar(v[i]) && v[i] != '.' { - return - } - if v[i] == '.' { - if start == i || isBadNum(v[start:i]) { - return - } - start = i + 1 - } - i++ - } - if start == i || isBadNum(v[start:i]) { - return - } - return v[:i], v[i:], true -} - -func parseBuild(v string) (t, rest string, ok bool) { - if v == "" || v[0] != '+' { - return - } - i := 1 - start := 1 - for i < len(v) { - if !isIdentChar(v[i]) && v[i] != '.' { - return - } - if v[i] == '.' { - if start == i { - return - } - start = i + 1 - } - i++ - } - if start == i { - return - } - return v[:i], v[i:], true -} - -func isIdentChar(c byte) bool { - return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' -} - -func isBadNum(v string) bool { - i := 0 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - return i == len(v) && i > 1 && v[0] == '0' -} - -func isNum(v string) bool { - i := 0 - for i < len(v) && '0' <= v[i] && v[i] <= '9' { - i++ - } - return i == len(v) -} - -func compareInt(x, y string) int { - if x == y { - return 0 - } - if len(x) < len(y) { - return -1 - } - if len(x) > len(y) { - return +1 - } - if x < y { - return -1 - } else { - return +1 - } -} - -func comparePrerelease(x, y string) int { - // "When major, minor, and patch are equal, a pre-release version has - // lower precedence than a normal version. - // Example: 1.0.0-alpha < 1.0.0. - // Precedence for two pre-release versions with the same major, minor, - // and patch version MUST be determined by comparing each dot separated - // identifier from left to right until a difference is found as follows: - // identifiers consisting of only digits are compared numerically and - // identifiers with letters or hyphens are compared lexically in ASCII - // sort order. Numeric identifiers always have lower precedence than - // non-numeric identifiers. A larger set of pre-release fields has a - // higher precedence than a smaller set, if all of the preceding - // identifiers are equal. - // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < - // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." - if x == y { - return 0 - } - if x == "" { - return +1 - } - if y == "" { - return -1 - } - for x != "" && y != "" { - x = x[1:] // skip - or . - y = y[1:] // skip - or . - var dx, dy string - dx, x = nextIdent(x) - dy, y = nextIdent(y) - if dx != dy { - ix := isNum(dx) - iy := isNum(dy) - if ix != iy { - if ix { - return -1 - } else { - return +1 - } - } - if ix { - if len(dx) < len(dy) { - return -1 - } - if len(dx) > len(dy) { - return +1 - } - } - if dx < dy { - return -1 - } else { - return +1 - } - } - } - if x == "" { - return -1 - } else { - return +1 - } -} - -func nextIdent(x string) (dx, rest string) { - i := 0 - for i < len(x) && x[i] != '.' { - i++ - } - return x[:i], x[i:] -} diff --git a/libgo/go/cmd/go/internal/semver/semver_test.go b/libgo/go/cmd/go/internal/semver/semver_test.go deleted file mode 100644 index 77025a44abd..00000000000 --- a/libgo/go/cmd/go/internal/semver/semver_test.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package semver - -import ( - "strings" - "testing" -) - -var tests = []struct { - in string - out string -}{ - {"bad", ""}, - {"v1-alpha.beta.gamma", ""}, - {"v1-pre", ""}, - {"v1+meta", ""}, - {"v1-pre+meta", ""}, - {"v1.2-pre", ""}, - {"v1.2+meta", ""}, - {"v1.2-pre+meta", ""}, - {"v1.0.0-alpha", "v1.0.0-alpha"}, - {"v1.0.0-alpha.1", "v1.0.0-alpha.1"}, - {"v1.0.0-alpha.beta", "v1.0.0-alpha.beta"}, - {"v1.0.0-beta", "v1.0.0-beta"}, - {"v1.0.0-beta.2", "v1.0.0-beta.2"}, - {"v1.0.0-beta.11", "v1.0.0-beta.11"}, - {"v1.0.0-rc.1", "v1.0.0-rc.1"}, - {"v1", "v1.0.0"}, - {"v1.0", "v1.0.0"}, - {"v1.0.0", "v1.0.0"}, - {"v1.2", "v1.2.0"}, - {"v1.2.0", "v1.2.0"}, - {"v1.2.3-456", "v1.2.3-456"}, - {"v1.2.3-456.789", "v1.2.3-456.789"}, - {"v1.2.3-456-789", "v1.2.3-456-789"}, - {"v1.2.3-456a", "v1.2.3-456a"}, - {"v1.2.3-pre", "v1.2.3-pre"}, - {"v1.2.3-pre+meta", "v1.2.3-pre"}, - {"v1.2.3-pre.1", "v1.2.3-pre.1"}, - {"v1.2.3-zzz", "v1.2.3-zzz"}, - {"v1.2.3", "v1.2.3"}, - {"v1.2.3+meta", "v1.2.3"}, - {"v1.2.3+meta-pre", "v1.2.3"}, - {"v1.2.3+meta-pre.sha.256a", "v1.2.3"}, -} - -func TestIsValid(t *testing.T) { - for _, tt := range tests { - ok := IsValid(tt.in) - if ok != (tt.out != "") { - t.Errorf("IsValid(%q) = %v, want %v", tt.in, ok, !ok) - } - } -} - -func TestCanonical(t *testing.T) { - for _, tt := range tests { - out := Canonical(tt.in) - if out != tt.out { - t.Errorf("Canonical(%q) = %q, want %q", tt.in, out, tt.out) - } - } -} - -func TestMajor(t *testing.T) { - for _, tt := range tests { - out := Major(tt.in) - want := "" - if i := strings.Index(tt.out, "."); i >= 0 { - want = tt.out[:i] - } - if out != want { - t.Errorf("Major(%q) = %q, want %q", tt.in, out, want) - } - } -} - -func TestMajorMinor(t *testing.T) { - for _, tt := range tests { - out := MajorMinor(tt.in) - var want string - if tt.out != "" { - want = tt.in - if i := strings.Index(want, "+"); i >= 0 { - want = want[:i] - } - if i := strings.Index(want, "-"); i >= 0 { - want = want[:i] - } - switch strings.Count(want, ".") { - case 0: - want += ".0" - case 1: - // ok - case 2: - want = want[:strings.LastIndex(want, ".")] - } - } - if out != want { - t.Errorf("MajorMinor(%q) = %q, want %q", tt.in, out, want) - } - } -} - -func TestPrerelease(t *testing.T) { - for _, tt := range tests { - pre := Prerelease(tt.in) - var want string - if tt.out != "" { - if i := strings.Index(tt.out, "-"); i >= 0 { - want = tt.out[i:] - } - } - if pre != want { - t.Errorf("Prerelease(%q) = %q, want %q", tt.in, pre, want) - } - } -} - -func TestBuild(t *testing.T) { - for _, tt := range tests { - build := Build(tt.in) - var want string - if tt.out != "" { - if i := strings.Index(tt.in, "+"); i >= 0 { - want = tt.in[i:] - } - } - if build != want { - t.Errorf("Build(%q) = %q, want %q", tt.in, build, want) - } - } -} - -func TestCompare(t *testing.T) { - for i, ti := range tests { - for j, tj := range tests { - cmp := Compare(ti.in, tj.in) - var want int - if ti.out == tj.out { - want = 0 - } else if i < j { - want = -1 - } else { - want = +1 - } - if cmp != want { - t.Errorf("Compare(%q, %q) = %d, want %d", ti.in, tj.in, cmp, want) - } - } - } -} - -func TestMax(t *testing.T) { - for i, ti := range tests { - for j, tj := range tests { - max := Max(ti.in, tj.in) - want := Canonical(ti.in) - if i < j { - want = Canonical(tj.in) - } - if max != want { - t.Errorf("Max(%q, %q) = %q, want %q", ti.in, tj.in, max, want) - } - } - } -} - -var ( - v1 = "v1.0.0+metadata-dash" - v2 = "v1.0.0+metadata-dash1" -) - -func BenchmarkCompare(b *testing.B) { - for i := 0; i < b.N; i++ { - if Compare(v1, v2) != 0 { - b.Fatalf("bad compare") - } - } -} diff --git a/libgo/go/cmd/go/internal/sumweb/cache.go b/libgo/go/cmd/go/internal/sumweb/cache.go deleted file mode 100644 index a8117a71b78..00000000000 --- a/libgo/go/cmd/go/internal/sumweb/cache.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Parallel cache. -// This file is copied from cmd/go/internal/par. - -package sumweb - -import ( - "sync" - "sync/atomic" -) - -// parCache runs an action once per key and caches the result. -type parCache struct { - m sync.Map -} - -type cacheEntry struct { - done uint32 - mu sync.Mutex - result interface{} -} - -// Do calls the function f if and only if Do is being called for the first time with this key. -// No call to Do with a given key returns until the one call to f returns. -// Do returns the value returned by the one call to f. -func (c *parCache) Do(key interface{}, f func() interface{}) interface{} { - entryIface, ok := c.m.Load(key) - if !ok { - entryIface, _ = c.m.LoadOrStore(key, new(cacheEntry)) - } - e := entryIface.(*cacheEntry) - if atomic.LoadUint32(&e.done) == 0 { - e.mu.Lock() - if atomic.LoadUint32(&e.done) == 0 { - e.result = f() - atomic.StoreUint32(&e.done, 1) - } - e.mu.Unlock() - } - return e.result -} - -// Get returns the cached result associated with key. -// It returns nil if there is no such result. -// If the result for key is being computed, Get does not wait for the computation to finish. -func (c *parCache) Get(key interface{}) interface{} { - entryIface, ok := c.m.Load(key) - if !ok { - return nil - } - e := entryIface.(*cacheEntry) - if atomic.LoadUint32(&e.done) == 0 { - return nil - } - return e.result -} diff --git a/libgo/go/cmd/go/internal/sumweb/client.go b/libgo/go/cmd/go/internal/sumweb/client.go deleted file mode 100644 index 6973e5ac179..00000000000 --- a/libgo/go/cmd/go/internal/sumweb/client.go +++ /dev/null @@ -1,619 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sumweb - -import ( - "bytes" - "errors" - "fmt" - "strings" - "sync" - "sync/atomic" - - "cmd/go/internal/note" - "cmd/go/internal/str" - "cmd/go/internal/tlog" -) - -// A Client provides the external operations -// (file caching, HTTP fetches, and so on) -// needed to implement the HTTP client Conn. -// The methods must be safe for concurrent use by multiple goroutines. -type Client interface { - // ReadRemote reads and returns the content served at the given path - // on the remote database server. The path begins with "/lookup" or "/tile/". - // It is the implementation's responsibility to turn that path into a full URL - // and make the HTTP request. ReadRemote should return an error for - // any non-200 HTTP response status. - ReadRemote(path string) ([]byte, error) - - // ReadConfig reads and returns the content of the named configuration file. - // There are only a fixed set of configuration files. - // - // "key" returns a file containing the verifier key for the server. - // - // serverName + "/latest" returns a file containing the latest known - // signed tree from the server. It is read and written (using WriteConfig). - // To signal that the client wishes to start with an "empty" signed tree, - // ReadConfig can return a successful empty result (0 bytes of data). - ReadConfig(file string) ([]byte, error) - - // WriteConfig updates the content of the named configuration file, - // changing it from the old []byte to the new []byte. - // If the old []byte does not match the stored configuration, - // WriteConfig must return ErrWriteConflict. - // Otherwise, WriteConfig should atomically replace old with new. - WriteConfig(file string, old, new []byte) error - - // ReadCache reads and returns the content of the named cache file. - // Any returned error will be treated as equivalent to the file not existing. - // There can be arbitrarily many cache files, such as: - // serverName/lookup/pkg@version - // serverName/tile/8/1/x123/456 - ReadCache(file string) ([]byte, error) - - // WriteCache writes the named cache file. - WriteCache(file string, data []byte) - - // Log prints the given log message (such as with log.Print) - Log(msg string) - - // SecurityError prints the given security error log message. - // The Conn returns ErrSecurity from any operation that invokes SecurityError, - // but the return value is mainly for testing. In a real program, - // SecurityError should typically print the message and call log.Fatal or os.Exit. - SecurityError(msg string) -} - -// ErrWriteConflict signals a write conflict during Client.WriteConfig. -var ErrWriteConflict = errors.New("write conflict") - -// ErrSecurity is returned by Conn operations that invoke Client.SecurityError. -var ErrSecurity = errors.New("security error: misbehaving server") - -// A Conn is a client connection to a go.sum database. -// All the methods are safe for simultaneous use by multiple goroutines. -type Conn struct { - client Client // client-provided external world - - didLookup uint32 - - // one-time initialized data - initOnce sync.Once - initErr error // init error, if any - name string // name of accepted verifier - verifiers note.Verifiers // accepted verifiers (just one, but Verifiers for note.Open) - tileReader tileReader - tileHeight int - nosumdb string - - record parCache // cache of record lookup, keyed by path@vers - tileCache parCache // cache of c.readTile, keyed by tile - - latestMu sync.Mutex - latest tlog.Tree // latest known tree head - latestMsg []byte // encoded signed note for latest - - tileSavedMu sync.Mutex - tileSaved map[tlog.Tile]bool // which tiles have been saved using c.client.WriteCache already -} - -// NewConn returns a new Conn using the given Client. -func NewConn(client Client) *Conn { - return &Conn{ - client: client, - } -} - -// init initiailzes the conn (if not already initialized) -// and returns any initialization error. -func (c *Conn) init() error { - c.initOnce.Do(c.initWork) - return c.initErr -} - -// initWork does the actual initialization work. -func (c *Conn) initWork() { - defer func() { - if c.initErr != nil { - c.initErr = fmt.Errorf("initializing sumweb.Conn: %v", c.initErr) - } - }() - - c.tileReader.c = c - if c.tileHeight == 0 { - c.tileHeight = 8 - } - c.tileSaved = make(map[tlog.Tile]bool) - - vkey, err := c.client.ReadConfig("key") - if err != nil { - c.initErr = err - return - } - verifier, err := note.NewVerifier(strings.TrimSpace(string(vkey))) - if err != nil { - c.initErr = err - return - } - c.verifiers = note.VerifierList(verifier) - c.name = verifier.Name() - - data, err := c.client.ReadConfig(c.name + "/latest") - if err != nil { - c.initErr = err - return - } - if err := c.mergeLatest(data); err != nil { - c.initErr = err - return - } -} - -// SetTileHeight sets the tile height for the Conn. -// Any call to SetTileHeight must happen before the first call to Lookup. -// If SetTileHeight is not called, the Conn defaults to tile height 8. -func (c *Conn) SetTileHeight(height int) { - if atomic.LoadUint32(&c.didLookup) != 0 { - panic("SetTileHeight used after Lookup") - } - if c.tileHeight != 0 { - panic("multiple calls to SetTileHeight") - } - c.tileHeight = height -} - -// SetGONOSUMDB sets the list of comma-separated GONOSUMDB patterns for the Conn. -// For any module path matching one of the patterns, -// Lookup will return ErrGONOSUMDB. -// Any call to SetGONOSUMDB must happen before the first call to Lookup. -func (c *Conn) SetGONOSUMDB(list string) { - if atomic.LoadUint32(&c.didLookup) != 0 { - panic("SetGONOSUMDB used after Lookup") - } - if c.nosumdb != "" { - panic("multiple calls to SetGONOSUMDB") - } - c.nosumdb = list -} - -// ErrGONOSUMDB is returned by Lookup for paths that match -// a pattern listed in the GONOSUMDB list (set by SetGONOSUMDB, -// usually from the environment variable). -var ErrGONOSUMDB = errors.New("skipped (listed in GONOSUMDB)") - -func (c *Conn) skip(target string) bool { - return str.GlobsMatchPath(c.nosumdb, target) -} - -// Lookup returns the go.sum lines for the given module path and version. -// The version may end in a /go.mod suffix, in which case Lookup returns -// the go.sum lines for the module's go.mod-only hash. -func (c *Conn) Lookup(path, vers string) (lines []string, err error) { - atomic.StoreUint32(&c.didLookup, 1) - - if c.skip(path) { - return nil, ErrGONOSUMDB - } - - defer func() { - if err != nil { - err = fmt.Errorf("%s@%s: %v", path, vers, err) - } - }() - - if err := c.init(); err != nil { - return nil, err - } - - // Prepare encoded cache filename / URL. - epath, err := encodePath(path) - if err != nil { - return nil, err - } - evers, err := encodeVersion(strings.TrimSuffix(vers, "/go.mod")) - if err != nil { - return nil, err - } - file := c.name + "/lookup/" + epath + "@" + evers - remotePath := "/lookup/" + epath + "@" + evers - - // Fetch the data. - // The lookupCache avoids redundant ReadCache/GetURL operations - // (especially since go.sum lines tend to come in pairs for a given - // path and version) and also avoids having multiple of the same - // request in flight at once. - type cached struct { - data []byte - err error - } - result := c.record.Do(file, func() interface{} { - // Try the on-disk cache, or else get from web. - writeCache := false - data, err := c.client.ReadCache(file) - if err != nil { - data, err = c.client.ReadRemote(remotePath) - if err != nil { - return cached{nil, err} - } - writeCache = true - } - - // Validate the record before using it for anything. - id, text, treeMsg, err := tlog.ParseRecord(data) - if err != nil { - return cached{nil, err} - } - if err := c.mergeLatest(treeMsg); err != nil { - return cached{nil, err} - } - if err := c.checkRecord(id, text); err != nil { - return cached{nil, err} - } - - // Now that we've validated the record, - // save it to the on-disk cache (unless that's where it came from). - if writeCache { - c.client.WriteCache(file, data) - } - - return cached{data, nil} - }).(cached) - if result.err != nil { - return nil, result.err - } - - // Extract the lines for the specific version we want - // (with or without /go.mod). - prefix := path + " " + vers + " " - var hashes []string - for _, line := range strings.Split(string(result.data), "\n") { - if strings.HasPrefix(line, prefix) { - hashes = append(hashes, line) - } - } - return hashes, nil -} - -// mergeLatest merges the tree head in msg -// with the Conn's current latest tree head, -// ensuring the result is a consistent timeline. -// If the result is inconsistent, mergeLatest calls c.client.SecurityError -// with a detailed security error message and then -// (only if c.client.SecurityError does not exit the program) returns ErrSecurity. -// If the Conn's current latest tree head moves forward, -// mergeLatest updates the underlying configuration file as well, -// taking care to merge any independent updates to that configuration. -func (c *Conn) mergeLatest(msg []byte) error { - // Merge msg into our in-memory copy of the latest tree head. - when, err := c.mergeLatestMem(msg) - if err != nil { - return err - } - if when != msgFuture { - // msg matched our present or was in the past. - // No change to our present, so no update of config file. - return nil - } - - // Flush our extended timeline back out to the configuration file. - // If the configuration file has been updated in the interim, - // we need to merge any updates made there as well. - // Note that writeConfig is an atomic compare-and-swap. - for { - msg, err := c.client.ReadConfig(c.name + "/latest") - if err != nil { - return err - } - when, err := c.mergeLatestMem(msg) - if err != nil { - return err - } - if when != msgPast { - // msg matched our present or was from the future, - // and now our in-memory copy matches. - return nil - } - - // msg (== config) is in the past, so we need to update it. - c.latestMu.Lock() - latestMsg := c.latestMsg - c.latestMu.Unlock() - if err := c.client.WriteConfig(c.name+"/latest", msg, latestMsg); err != ErrWriteConflict { - // Success or a non-write-conflict error. - return err - } - } -} - -const ( - msgPast = 1 + iota - msgNow - msgFuture -) - -// mergeLatestMem is like mergeLatest but is only concerned with -// updating the in-memory copy of the latest tree head (c.latest) -// not the configuration file. -// The when result explains when msg happened relative to our -// previous idea of c.latest: -// msgPast means msg was from before c.latest, -// msgNow means msg was exactly c.latest, and -// msgFuture means msg was from after c.latest, which has now been updated. -func (c *Conn) mergeLatestMem(msg []byte) (when int, err error) { - if len(msg) == 0 { - // Accept empty msg as the unsigned, empty timeline. - c.latestMu.Lock() - latest := c.latest - c.latestMu.Unlock() - if latest.N == 0 { - return msgNow, nil - } - return msgPast, nil - } - - note, err := note.Open(msg, c.verifiers) - if err != nil { - return 0, fmt.Errorf("reading tree note: %v\nnote:\n%s", err, msg) - } - tree, err := tlog.ParseTree([]byte(note.Text)) - if err != nil { - return 0, fmt.Errorf("reading tree: %v\ntree:\n%s", err, note.Text) - } - - // Other lookups may be calling mergeLatest with other heads, - // so c.latest is changing underfoot. We don't want to hold the - // c.mu lock during tile fetches, so loop trying to update c.latest. - c.latestMu.Lock() - latest := c.latest - latestMsg := c.latestMsg - c.latestMu.Unlock() - - for { - // If the tree head looks old, check that it is on our timeline. - if tree.N <= latest.N { - if err := c.checkTrees(tree, msg, latest, latestMsg); err != nil { - return 0, err - } - if tree.N < latest.N { - return msgPast, nil - } - return msgNow, nil - } - - // The tree head looks new. Check that we are on its timeline and try to move our timeline forward. - if err := c.checkTrees(latest, latestMsg, tree, msg); err != nil { - return 0, err - } - - // Install our msg if possible. - // Otherwise we will go around again. - c.latestMu.Lock() - installed := false - if c.latest == latest { - installed = true - c.latest = tree - c.latestMsg = msg - } else { - latest = c.latest - latestMsg = c.latestMsg - } - c.latestMu.Unlock() - - if installed { - return msgFuture, nil - } - } -} - -// checkTrees checks that older (from olderNote) is contained in newer (from newerNote). -// If an error occurs, such as malformed data or a network problem, checkTrees returns that error. -// If on the other hand checkTrees finds evidence of misbehavior, it prepares a detailed -// message and calls log.Fatal. -func (c *Conn) checkTrees(older tlog.Tree, olderNote []byte, newer tlog.Tree, newerNote []byte) error { - thr := tlog.TileHashReader(newer, &c.tileReader) - h, err := tlog.TreeHash(older.N, thr) - if err != nil { - if older.N == newer.N { - return fmt.Errorf("checking tree#%d: %v", older.N, err) - } - return fmt.Errorf("checking tree#%d against tree#%d: %v", older.N, newer.N, err) - } - if h == older.Hash { - return nil - } - - // Detected a fork in the tree timeline. - // Start by reporting the inconsistent signed tree notes. - var buf bytes.Buffer - fmt.Fprintf(&buf, "SECURITY ERROR\n") - fmt.Fprintf(&buf, "go.sum database server misbehavior detected!\n\n") - indent := func(b []byte) []byte { - return bytes.Replace(b, []byte("\n"), []byte("\n\t"), -1) - } - fmt.Fprintf(&buf, "old database:\n\t%s\n", indent(olderNote)) - fmt.Fprintf(&buf, "new database:\n\t%s\n", indent(newerNote)) - - // The notes alone are not enough to prove the inconsistency. - // We also need to show that the newer note's tree hash for older.N - // does not match older.Hash. The consumer of this report could - // of course consult the server to try to verify the inconsistency, - // but we are holding all the bits we need to prove it right now, - // so we might as well print them and make the report not depend - // on the continued availability of the misbehaving server. - // Preparing this data only reuses the tiled hashes needed for - // tlog.TreeHash(older.N, thr) above, so assuming thr is caching tiles, - // there are no new access to the server here, and these operations cannot fail. - fmt.Fprintf(&buf, "proof of misbehavior:\n\t%v", h) - if p, err := tlog.ProveTree(newer.N, older.N, thr); err != nil { - fmt.Fprintf(&buf, "\tinternal error: %v\n", err) - } else if err := tlog.CheckTree(p, newer.N, newer.Hash, older.N, h); err != nil { - fmt.Fprintf(&buf, "\tinternal error: generated inconsistent proof\n") - } else { - for _, h := range p { - fmt.Fprintf(&buf, "\n\t%v", h) - } - } - c.client.SecurityError(buf.String()) - return ErrSecurity -} - -// checkRecord checks that record #id's hash matches data. -func (c *Conn) checkRecord(id int64, data []byte) error { - c.latestMu.Lock() - latest := c.latest - c.latestMu.Unlock() - - if id >= latest.N { - return fmt.Errorf("cannot validate record %d in tree of size %d", id, latest.N) - } - hashes, err := tlog.TileHashReader(latest, &c.tileReader).ReadHashes([]int64{tlog.StoredHashIndex(0, id)}) - if err != nil { - return err - } - if hashes[0] == tlog.RecordHash(data) { - return nil - } - return fmt.Errorf("cannot authenticate record data in server response") -} - -// tileReader is a *Conn wrapper that implements tlog.TileReader. -// The separate type avoids exposing the ReadTiles and SaveTiles -// methods on Conn itself. -type tileReader struct { - c *Conn -} - -func (r *tileReader) Height() int { - return r.c.tileHeight -} - -// ReadTiles reads and returns the requested tiles, -// either from the on-disk cache or the server. -func (r *tileReader) ReadTiles(tiles []tlog.Tile) ([][]byte, error) { - // Read all the tiles in parallel. - data := make([][]byte, len(tiles)) - errs := make([]error, len(tiles)) - var wg sync.WaitGroup - for i, tile := range tiles { - wg.Add(1) - go func(i int, tile tlog.Tile) { - defer wg.Done() - data[i], errs[i] = r.c.readTile(tile) - }(i, tile) - } - wg.Wait() - - for _, err := range errs { - if err != nil { - return nil, err - } - } - - return data, nil -} - -// tileCacheKey returns the cache key for the tile. -func (c *Conn) tileCacheKey(tile tlog.Tile) string { - return c.name + "/" + tile.Path() -} - -// tileRemotePath returns the remote path for the tile. -func (c *Conn) tileRemotePath(tile tlog.Tile) string { - return "/" + tile.Path() -} - -// readTile reads a single tile, either from the on-disk cache or the server. -func (c *Conn) readTile(tile tlog.Tile) ([]byte, error) { - type cached struct { - data []byte - err error - } - - result := c.tileCache.Do(tile, func() interface{} { - // Try the requested tile in on-disk cache. - data, err := c.client.ReadCache(c.tileCacheKey(tile)) - if err == nil { - c.markTileSaved(tile) - return cached{data, nil} - } - - // Try the full tile in on-disk cache (if requested tile not already full). - // We only save authenticated tiles to the on-disk cache, - // so the recreated prefix is equally authenticated. - full := tile - full.W = 1 << tile.H - if tile != full { - data, err := c.client.ReadCache(c.tileCacheKey(full)) - if err == nil { - c.markTileSaved(tile) // don't save tile later; we already have full - return cached{data[:len(data)/full.W*tile.W], nil} - } - } - - // Try requested tile from server. - data, err = c.client.ReadRemote(c.tileRemotePath(tile)) - if err == nil { - return cached{data, nil} - } - - // Try full tile on server. - // If the partial tile does not exist, it should be because - // the tile has been completed and only the complete one - // is available. - if tile != full { - data, err := c.client.ReadRemote(c.tileRemotePath(full)) - if err == nil { - // Note: We could save the full tile in the on-disk cache here, - // but we don't know if it is valid yet, and we will only find out - // about the partial data, not the full data. So let SaveTiles - // save the partial tile, and we'll just refetch the full tile later - // once we can validate more (or all) of it. - return cached{data[:len(data)/full.W*tile.W], nil} - } - } - - // Nothing worked. - // Return the error from the server fetch for the requested (not full) tile. - return cached{nil, err} - }).(cached) - - return result.data, result.err -} - -// markTileSaved records that tile is already present in the on-disk cache, -// so that a future SaveTiles for that tile can be ignored. -func (c *Conn) markTileSaved(tile tlog.Tile) { - c.tileSavedMu.Lock() - c.tileSaved[tile] = true - c.tileSavedMu.Unlock() -} - -// SaveTiles saves the now validated tiles. -func (r *tileReader) SaveTiles(tiles []tlog.Tile, data [][]byte) { - c := r.c - - // Determine which tiles need saving. - // (Tiles that came from the cache need not be saved back.) - save := make([]bool, len(tiles)) - c.tileSavedMu.Lock() - for i, tile := range tiles { - if !c.tileSaved[tile] { - save[i] = true - c.tileSaved[tile] = true - } - } - c.tileSavedMu.Unlock() - - for i, tile := range tiles { - if save[i] { - // If WriteCache fails here (out of disk space? i/o error?), - // c.tileSaved[tile] is still true and we will not try to write it again. - // Next time we run maybe we'll redownload it again and be - // more successful. - c.client.WriteCache(c.name+"/"+tile.Path(), data[i]) - } - } -} diff --git a/libgo/go/cmd/go/internal/sumweb/client_test.go b/libgo/go/cmd/go/internal/sumweb/client_test.go deleted file mode 100644 index 83a182adc55..00000000000 --- a/libgo/go/cmd/go/internal/sumweb/client_test.go +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sumweb - -import ( - "bytes" - "fmt" - "strings" - "sync" - "testing" - - "cmd/go/internal/note" - "cmd/go/internal/tlog" -) - -const ( - testName = "localhost.localdev/sumdb" - testVerifierKey = "localhost.localdev/sumdb+00000c67+AcTrnkbUA+TU4heY3hkjiSES/DSQniBqIeQ/YppAUtK6" - testSignerKey = "PRIVATE+KEY+localhost.localdev/sumdb+00000c67+AXu6+oaVaOYuQOFrf1V59JK1owcFlJcHwwXHDfDGxSPk" -) - -func TestConnLookup(t *testing.T) { - tc := newTestClient(t) - tc.mustHaveLatest(1) - - // Basic lookup. - tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=") - tc.mustHaveLatest(3) - - // Everything should now be cached, both for the original package and its /go.mod. - tc.getOK = false - tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=") - tc.mustLookup("rsc.io/sampler", "v1.3.0/go.mod", "rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=") - tc.mustHaveLatest(3) - tc.getOK = true - tc.getTileOK = false // the cache has what we need - - // Lookup with multiple returned lines. - tc.mustLookup("rsc.io/quote", "v1.5.2", "rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=\nrsc.io/quote v1.5.2 h2:xyzzy") - tc.mustHaveLatest(3) - - // Lookup with need for !-encoding. - // rsc.io/Quote is the only record written after rsc.io/samper, - // so it is the only one that should need more tiles. - tc.getTileOK = true - tc.mustLookup("rsc.io/Quote", "v1.5.2", "rsc.io/Quote v1.5.2 h1:uppercase!=") - tc.mustHaveLatest(4) -} - -func TestConnBadTiles(t *testing.T) { - tc := newTestClient(t) - - flipBits := func() { - for url, data := range tc.remote { - if strings.Contains(url, "/tile/") { - for i := range data { - data[i] ^= 0x80 - } - } - } - } - - // Bad tiles in initial download. - tc.mustHaveLatest(1) - flipBits() - _, err := tc.conn.Lookup("rsc.io/sampler", "v1.3.0") - tc.mustError(err, "rsc.io/sampler@v1.3.0: initializing sumweb.Conn: checking tree#1: downloaded inconsistent tile") - flipBits() - tc.newConn() - tc.mustLookup("rsc.io/sampler", "v1.3.0", "rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=") - - // Bad tiles after initial download. - flipBits() - _, err = tc.conn.Lookup("rsc.io/Quote", "v1.5.2") - tc.mustError(err, "rsc.io/Quote@v1.5.2: checking tree#3 against tree#4: downloaded inconsistent tile") - flipBits() - tc.newConn() - tc.mustLookup("rsc.io/Quote", "v1.5.2", "rsc.io/Quote v1.5.2 h1:uppercase!=") - - // Bad starting tree hash looks like bad tiles. - tc.newConn() - text := tlog.FormatTree(tlog.Tree{N: 1, Hash: tlog.Hash{}}) - data, err := note.Sign(¬e.Note{Text: string(text)}, tc.signer) - if err != nil { - tc.t.Fatal(err) - } - tc.config[testName+"/latest"] = data - _, err = tc.conn.Lookup("rsc.io/sampler", "v1.3.0") - tc.mustError(err, "rsc.io/sampler@v1.3.0: initializing sumweb.Conn: checking tree#1: downloaded inconsistent tile") -} - -func TestConnFork(t *testing.T) { - tc := newTestClient(t) - tc2 := tc.fork() - - tc.addRecord("rsc.io/pkg1@v1.5.2", `rsc.io/pkg1 v1.5.2 h1:hash!= -`) - tc.addRecord("rsc.io/pkg1@v1.5.4", `rsc.io/pkg1 v1.5.4 h1:hash!= -`) - tc.mustLookup("rsc.io/pkg1", "v1.5.2", "rsc.io/pkg1 v1.5.2 h1:hash!=") - - tc2.addRecord("rsc.io/pkg1@v1.5.3", `rsc.io/pkg1 v1.5.3 h1:hash!= -`) - tc2.addRecord("rsc.io/pkg1@v1.5.4", `rsc.io/pkg1 v1.5.4 h1:hash!= -`) - tc2.mustLookup("rsc.io/pkg1", "v1.5.4", "rsc.io/pkg1 v1.5.4 h1:hash!=") - - key := "/lookup/rsc.io/pkg1@v1.5.2" - tc2.remote[key] = tc.remote[key] - _, err := tc2.conn.Lookup("rsc.io/pkg1", "v1.5.2") - tc2.mustError(err, ErrSecurity.Error()) - - /* - SECURITY ERROR - go.sum database server misbehavior detected! - - old database: - go.sum database tree! - 5 - nWzN20+pwMt62p7jbv1/NlN95ePTlHijabv5zO/s36w= - - — localhost.localdev/sumdb AAAMZ5/2FVAdMH58kmnz/0h299pwyskEbzDzoa2/YaPdhvLya4YWDFQQxu2TQb5GpwAH4NdWnTwuhILafisyf3CNbgg= - - new database: - go.sum database tree - 6 - wc4SkQt52o5W2nQ8To2ARs+mWuUJjss+sdleoiqxMmM= - - — localhost.localdev/sumdb AAAMZ6oRNswlEZ6ZZhxrCvgl1MBy+nusq4JU+TG6Fe2NihWLqOzb+y2c2kzRLoCr4tvw9o36ucQEnhc20e4nA4Qc/wc= - - proof of misbehavior: - T7i+H/8ER4nXOiw4Bj0koZOkGjkxoNvlI34GpvhHhQg= - Nsuejv72de9hYNM5bqFv8rv3gm3zJQwv/DT/WNbLDLA= - mOmqqZ1aI/lzS94oq/JSbj7pD8Rv9S+xDyi12BtVSHo= - /7Aw5jVSMM9sFjQhaMg+iiDYPMk6decH7QLOGrL9Lx0= - */ - - wants := []string{ - "SECURITY ERROR", - "go.sum database server misbehavior detected!", - "old database:\n\tgo.sum database tree\n\t5\n", - "— localhost.localdev/sumdb AAAMZ5/2FVAd", - "new database:\n\tgo.sum database tree\n\t6\n", - "— localhost.localdev/sumdb AAAMZ6oRNswl", - "proof of misbehavior:\n\tT7i+H/8ER4nXOiw4Bj0k", - } - text := tc2.security.String() - for _, want := range wants { - if !strings.Contains(text, want) { - t.Fatalf("cannot find %q in security text:\n%s", want, text) - } - } -} - -func TestConnGONOSUMDB(t *testing.T) { - tc := newTestClient(t) - tc.conn.SetGONOSUMDB("p,*/q") - tc.conn.Lookup("rsc.io/sampler", "v1.3.0") // initialize before we turn off network - tc.getOK = false - - ok := []string{ - "abc", - "a/p", - "pq", - "q", - "n/o/p/q", - } - skip := []string{ - "p", - "p/x", - "x/q", - "x/q/z", - } - - for _, path := range ok { - _, err := tc.conn.Lookup(path, "v1.0.0") - if err == ErrGONOSUMDB { - t.Errorf("Lookup(%q): ErrGONOSUMDB, wanted failed actual lookup", path) - } - } - for _, path := range skip { - _, err := tc.conn.Lookup(path, "v1.0.0") - if err != ErrGONOSUMDB { - t.Errorf("Lookup(%q): %v, wanted ErrGONOSUMDB", path, err) - } - } -} - -// A testClient is a self-contained client-side testing environment. -type testClient struct { - t *testing.T // active test - conn *Conn // conn being tested - tileHeight int // tile height to use (default 2) - getOK bool // should tc.GetURL succeed? - getTileOK bool // should tc.GetURL of tiles succeed? - treeSize int64 - hashes []tlog.Hash - remote map[string][]byte - signer note.Signer - - // mu protects config, cache, log, security - // during concurrent use of the exported methods - // by the conn itself (testClient is the Conn's Client, - // and the Client methods can both read and write these fields). - // Unexported methods invoked directly by the test - // (for example, addRecord) need not hold the mutex: - // for proper test execution those methods should only - // be called when the Conn is idle and not using its Client. - // Not holding the mutex in those methods ensures - // that if a mistake is made, go test -race will report it. - // (Holding the mutex would eliminate the race report but - // not the underlying problem.) - // Similarly, the get map is not protected by the mutex, - // because the Client methods only read it. - mu sync.Mutex // prot - config map[string][]byte - cache map[string][]byte - security bytes.Buffer -} - -// newTestClient returns a new testClient that will call t.Fatal on error -// and has a few records already available on the remote server. -func newTestClient(t *testing.T) *testClient { - tc := &testClient{ - t: t, - tileHeight: 2, - getOK: true, - getTileOK: true, - config: make(map[string][]byte), - cache: make(map[string][]byte), - remote: make(map[string][]byte), - } - - tc.config["key"] = []byte(testVerifierKey + "\n") - var err error - tc.signer, err = note.NewSigner(testSignerKey) - if err != nil { - t.Fatal(err) - } - - tc.newConn() - - tc.addRecord("rsc.io/quote@v1.5.2", `rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= -rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= -rsc.io/quote v1.5.2 h2:xyzzy -`) - - tc.addRecord("golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c", `golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -`) - tc.addRecord("rsc.io/sampler@v1.3.0", `rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -`) - tc.config[testName+"/latest"] = tc.signTree(1) - - tc.addRecord("rsc.io/!quote@v1.5.2", `rsc.io/Quote v1.5.2 h1:uppercase!= -`) - return tc -} - -// newConn resets the Conn associated with tc. -// This clears any in-memory cache from the Conn -// but not tc's on-disk cache. -func (tc *testClient) newConn() { - tc.conn = NewConn(tc) - tc.conn.SetTileHeight(tc.tileHeight) -} - -// mustLookup does a lookup for path@vers and checks that the lines that come back match want. -func (tc *testClient) mustLookup(path, vers, want string) { - tc.t.Helper() - lines, err := tc.conn.Lookup(path, vers) - if err != nil { - tc.t.Fatal(err) - } - if strings.Join(lines, "\n") != want { - tc.t.Fatalf("Lookup(%q, %q):\n\t%s\nwant:\n\t%s", path, vers, strings.Join(lines, "\n\t"), strings.Replace(want, "\n", "\n\t", -1)) - } -} - -// mustHaveLatest checks that the on-disk configuration -// for latest is a tree of size n. -func (tc *testClient) mustHaveLatest(n int64) { - tc.t.Helper() - - latest := tc.config[testName+"/latest"] - lines := strings.Split(string(latest), "\n") - if len(lines) < 2 || lines[1] != fmt.Sprint(n) { - tc.t.Fatalf("/latest should have tree %d, but has:\n%s", n, latest) - } -} - -// mustError checks that err's error string contains the text. -func (tc *testClient) mustError(err error, text string) { - tc.t.Helper() - if err == nil || !strings.Contains(err.Error(), text) { - tc.t.Fatalf("err = %v, want %q", err, text) - } -} - -// fork returns a copy of tc. -// Changes made to the new copy or to tc are not reflected in the other. -func (tc *testClient) fork() *testClient { - tc2 := &testClient{ - t: tc.t, - getOK: tc.getOK, - getTileOK: tc.getTileOK, - tileHeight: tc.tileHeight, - treeSize: tc.treeSize, - hashes: append([]tlog.Hash{}, tc.hashes...), - signer: tc.signer, - config: copyMap(tc.config), - cache: copyMap(tc.cache), - remote: copyMap(tc.remote), - } - tc2.newConn() - return tc2 -} - -func copyMap(m map[string][]byte) map[string][]byte { - m2 := make(map[string][]byte) - for k, v := range m { - m2[k] = v - } - return m2 -} - -// ReadHashes is tc's implementation of tlog.HashReader, for use with -// tlog.TreeHash and so on. -func (tc *testClient) ReadHashes(indexes []int64) ([]tlog.Hash, error) { - var list []tlog.Hash - for _, id := range indexes { - list = append(list, tc.hashes[id]) - } - return list, nil -} - -// addRecord adds a log record using the given (!-encoded) key and data. -func (tc *testClient) addRecord(key, data string) { - tc.t.Helper() - - // Create record, add hashes to log tree. - id := tc.treeSize - tc.treeSize++ - rec, err := tlog.FormatRecord(id, []byte(data)) - if err != nil { - tc.t.Fatal(err) - } - hashes, err := tlog.StoredHashesForRecordHash(id, tlog.RecordHash([]byte(data)), tc) - if err != nil { - tc.t.Fatal(err) - } - tc.hashes = append(tc.hashes, hashes...) - - // Create lookup result. - tc.remote["/lookup/"+key] = append(rec, tc.signTree(tc.treeSize)...) - - // Create new tiles. - tiles := tlog.NewTiles(tc.tileHeight, id, tc.treeSize) - for _, tile := range tiles { - data, err := tlog.ReadTileData(tile, tc) - if err != nil { - tc.t.Fatal(err) - } - tc.remote["/"+tile.Path()] = data - // TODO delete old partial tiles - } -} - -// signTree returns the signed head for the tree of the given size. -func (tc *testClient) signTree(size int64) []byte { - h, err := tlog.TreeHash(size, tc) - if err != nil { - tc.t.Fatal(err) - } - text := tlog.FormatTree(tlog.Tree{N: size, Hash: h}) - data, err := note.Sign(¬e.Note{Text: string(text)}, tc.signer) - if err != nil { - tc.t.Fatal(err) - } - return data -} - -// ReadRemote is for tc's implementation of Client. -func (tc *testClient) ReadRemote(path string) ([]byte, error) { - // No mutex here because only the Client should be running - // and the Client cannot change tc.get. - if !tc.getOK { - return nil, fmt.Errorf("disallowed remote read %s", path) - } - if strings.Contains(path, "/tile/") && !tc.getTileOK { - return nil, fmt.Errorf("disallowed remote tile read %s", path) - } - - data, ok := tc.remote[path] - if !ok { - return nil, fmt.Errorf("no remote path %s", path) - } - return data, nil -} - -// ReadConfig is for tc's implementation of Client. -func (tc *testClient) ReadConfig(file string) ([]byte, error) { - tc.mu.Lock() - defer tc.mu.Unlock() - - data, ok := tc.config[file] - if !ok { - return nil, fmt.Errorf("no config %s", file) - } - return data, nil -} - -// WriteConfig is for tc's implementation of Client. -func (tc *testClient) WriteConfig(file string, old, new []byte) error { - tc.mu.Lock() - defer tc.mu.Unlock() - - data := tc.config[file] - if !bytes.Equal(old, data) { - return ErrWriteConflict - } - tc.config[file] = new - return nil -} - -// ReadCache is for tc's implementation of Client. -func (tc *testClient) ReadCache(file string) ([]byte, error) { - tc.mu.Lock() - defer tc.mu.Unlock() - - data, ok := tc.cache[file] - if !ok { - return nil, fmt.Errorf("no cache %s", file) - } - return data, nil -} - -// WriteCache is for tc's implementation of Client. -func (tc *testClient) WriteCache(file string, data []byte) { - tc.mu.Lock() - defer tc.mu.Unlock() - - tc.cache[file] = data -} - -// Log is for tc's implementation of Client. -func (tc *testClient) Log(msg string) { - tc.t.Log(msg) -} - -// SecurityError is for tc's implementation of Client. -func (tc *testClient) SecurityError(msg string) { - tc.mu.Lock() - defer tc.mu.Unlock() - - fmt.Fprintf(&tc.security, "%s\n", strings.TrimRight(msg, "\n")) -} diff --git a/libgo/go/cmd/go/internal/sumweb/encode.go b/libgo/go/cmd/go/internal/sumweb/encode.go deleted file mode 100644 index d044a84f3a8..00000000000 --- a/libgo/go/cmd/go/internal/sumweb/encode.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// FS-safe encoding of module paths and versions. -// Copied from cmd/go/internal/module and unexported. - -package sumweb - -import ( - "fmt" - "unicode/utf8" -) - -// Safe encodings -// -// Module paths appear as substrings of file system paths -// (in the download cache) and of web server URLs in the proxy protocol. -// In general we cannot rely on file systems to be case-sensitive, -// nor can we rely on web servers, since they read from file systems. -// That is, we cannot rely on the file system to keep rsc.io/QUOTE -// and rsc.io/quote separate. Windows and macOS don't. -// Instead, we must never require two different casings of a file path. -// Because we want the download cache to match the proxy protocol, -// and because we want the proxy protocol to be possible to serve -// from a tree of static files (which might be stored on a case-insensitive -// file system), the proxy protocol must never require two different casings -// of a URL path either. -// -// One possibility would be to make the safe encoding be the lowercase -// hexadecimal encoding of the actual path bytes. This would avoid ever -// needing different casings of a file path, but it would be fairly illegible -// to most programmers when those paths appeared in the file system -// (including in file paths in compiler errors and stack traces) -// in web server logs, and so on. Instead, we want a safe encoding that -// leaves most paths unaltered. -// -// The safe encoding is this: -// replace every uppercase letter with an exclamation mark -// followed by the letter's lowercase equivalent. -// -// For example, -// github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go. -// github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy -// github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus. -// -// Import paths that avoid upper-case letters are left unchanged. -// Note that because import paths are ASCII-only and avoid various -// problematic punctuation (like : < and >), the safe encoding is also ASCII-only -// and avoids the same problematic punctuation. -// -// Import paths have never allowed exclamation marks, so there is no -// need to define how to encode a literal !. -// -// Although paths are disallowed from using Unicode (see pathOK above), -// the eventual plan is to allow Unicode letters as well, to assume that -// file systems and URLs are Unicode-safe (storing UTF-8), and apply -// the !-for-uppercase convention. Note however that not all runes that -// are different but case-fold equivalent are an upper/lower pair. -// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin) -// are considered to case-fold to each other. When we do add Unicode -// letters, we must not assume that upper/lower are the only case-equivalent pairs. -// Perhaps the Kelvin symbol would be disallowed entirely, for example. -// Or perhaps it would encode as "!!k", or perhaps as "(212A)". -// -// Also, it would be nice to allow Unicode marks as well as letters, -// but marks include combining marks, and then we must deal not -// only with case folding but also normalization: both U+00E9 ('é') -// and U+0065 U+0301 ('e' followed by combining acute accent) -// look the same on the page and are treated by some file systems -// as the same path. If we do allow Unicode marks in paths, there -// must be some kind of normalization to allow only one canonical -// encoding of any character used in an import path. - -// encodePath returns the safe encoding of the given module path. -// It fails if the module path is invalid. -func encodePath(path string) (encoding string, err error) { - return encodeString(path) -} - -// encodeVersion returns the safe encoding of the given module version. -// Versions are allowed to be in non-semver form but must be valid file names -// and not contain exclamation marks. -func encodeVersion(v string) (encoding string, err error) { - return encodeString(v) -} - -func encodeString(s string) (encoding string, err error) { - haveUpper := false - for _, r := range s { - if r == '!' || r >= utf8.RuneSelf { - // This should be disallowed by CheckPath, but diagnose anyway. - // The correctness of the encoding loop below depends on it. - return "", fmt.Errorf("internal error: inconsistency in EncodePath") - } - if 'A' <= r && r <= 'Z' { - haveUpper = true - } - } - - if !haveUpper { - return s, nil - } - - var buf []byte - for _, r := range s { - if 'A' <= r && r <= 'Z' { - buf = append(buf, '!', byte(r+'a'-'A')) - } else { - buf = append(buf, byte(r)) - } - } - return string(buf), nil -} - -// decodePath returns the module path of the given safe encoding. -// It fails if the encoding is invalid or encodes an invalid path. -func decodePath(encoding string) (path string, err error) { - path, ok := decodeString(encoding) - if !ok { - return "", fmt.Errorf("invalid module path encoding %q", encoding) - } - return path, nil -} - -// decodeVersion returns the version string for the given safe encoding. -// It fails if the encoding is invalid or encodes an invalid version. -// Versions are allowed to be in non-semver form but must be valid file names -// and not contain exclamation marks. -func decodeVersion(encoding string) (v string, err error) { - v, ok := decodeString(encoding) - if !ok { - return "", fmt.Errorf("invalid version encoding %q", encoding) - } - return v, nil -} - -func decodeString(encoding string) (string, bool) { - var buf []byte - - bang := false - for _, r := range encoding { - if r >= utf8.RuneSelf { - return "", false - } - if bang { - bang = false - if r < 'a' || 'z' < r { - return "", false - } - buf = append(buf, byte(r+'A'-'a')) - continue - } - if r == '!' { - bang = true - continue - } - if 'A' <= r && r <= 'Z' { - return "", false - } - buf = append(buf, byte(r)) - } - if bang { - return "", false - } - return string(buf), true -} diff --git a/libgo/go/cmd/go/internal/sumweb/encode_test.go b/libgo/go/cmd/go/internal/sumweb/encode_test.go deleted file mode 100644 index 9ed5e4a9a04..00000000000 --- a/libgo/go/cmd/go/internal/sumweb/encode_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sumweb - -import "testing" - -var encodeTests = []struct { - path string - enc string // empty means same as path -}{ - {path: "ascii.com/abcdefghijklmnopqrstuvwxyz.-+/~_0123456789"}, - {path: "github.com/GoogleCloudPlatform/omega", enc: "github.com/!google!cloud!platform/omega"}, -} - -func TestEncodePath(t *testing.T) { - // Check encodings. - for _, tt := range encodeTests { - enc, err := encodePath(tt.path) - if err != nil { - t.Errorf("encodePath(%q): unexpected error: %v", tt.path, err) - continue - } - want := tt.enc - if want == "" { - want = tt.path - } - if enc != want { - t.Errorf("encodePath(%q) = %q, want %q", tt.path, enc, want) - } - } -} - -var badDecode = []string{ - "github.com/GoogleCloudPlatform/omega", - "github.com/!google!cloud!platform!/omega", - "github.com/!0google!cloud!platform/omega", - "github.com/!_google!cloud!platform/omega", - "github.com/!!google!cloud!platform/omega", -} - -func TestDecodePath(t *testing.T) { - // Check invalid decodings. - for _, bad := range badDecode { - _, err := decodePath(bad) - if err == nil { - t.Errorf("DecodePath(%q): succeeded, want error (invalid decoding)", bad) - } - } - - // Check encodings. - for _, tt := range encodeTests { - enc := tt.enc - if enc == "" { - enc = tt.path - } - path, err := decodePath(enc) - if err != nil { - t.Errorf("decodePath(%q): unexpected error: %v", enc, err) - continue - } - if path != tt.path { - t.Errorf("decodePath(%q) = %q, want %q", enc, path, tt.path) - } - } -} diff --git a/libgo/go/cmd/go/internal/sumweb/server.go b/libgo/go/cmd/go/internal/sumweb/server.go deleted file mode 100644 index 5050805f873..00000000000 --- a/libgo/go/cmd/go/internal/sumweb/server.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package sumweb implements the HTTP protocols for serving or accessing a go.sum database. -package sumweb - -import ( - "context" - "internal/lazyregexp" - "net/http" - "os" - "strings" - - "cmd/go/internal/tlog" -) - -// A Server provides the external operations -// (underlying database access and so on) -// needed to implement the HTTP server Handler. -type Server interface { - // NewContext returns the context to use for the request r. - NewContext(r *http.Request) (context.Context, error) - - // Signed returns the signed hash of the latest tree. - Signed(ctx context.Context) ([]byte, error) - - // ReadRecords returns the content for the n records id through id+n-1. - ReadRecords(ctx context.Context, id, n int64) ([][]byte, error) - - // Lookup looks up a record by its associated key ("module@version"), - // returning the record ID. - Lookup(ctx context.Context, key string) (int64, error) - - // ReadTileData reads the content of tile t. - // It is only invoked for hash tiles (t.L ≥ 0). - ReadTileData(ctx context.Context, t tlog.Tile) ([]byte, error) -} - -// A Handler is the go.sum database server handler, -// which should be invoked to serve the paths listed in Paths. -// The calling code is responsible for initializing Server. -type Handler struct { - Server Server -} - -// Paths are the URL paths for which Handler should be invoked. -// -// Typically a server will do: -// -// handler := &sumweb.Handler{Server: srv} -// for _, path := range sumweb.Paths { -// http.HandleFunc(path, handler) -// } -// -var Paths = []string{ - "/lookup/", - "/latest", - "/tile/", -} - -var modVerRE = lazyregexp.New(`^[^@]+@v[0-9]+\.[0-9]+\.[0-9]+(-[^@]*)?(\+incompatible)?$`) - -func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - ctx, err := h.Server.NewContext(r) - if err != nil { - http.Error(w, err.Error(), 500) - return - } - - switch { - default: - http.NotFound(w, r) - - case strings.HasPrefix(r.URL.Path, "/lookup/"): - mod := strings.TrimPrefix(r.URL.Path, "/lookup/") - if !modVerRE.MatchString(mod) { - http.Error(w, "invalid module@version syntax", http.StatusBadRequest) - return - } - i := strings.Index(mod, "@") - encPath, encVers := mod[:i], mod[i+1:] - path, err := decodePath(encPath) - if err != nil { - reportError(w, r, err) - return - } - vers, err := decodeVersion(encVers) - if err != nil { - reportError(w, r, err) - return - } - id, err := h.Server.Lookup(ctx, path+"@"+vers) - if err != nil { - reportError(w, r, err) - return - } - records, err := h.Server.ReadRecords(ctx, id, 1) - if err != nil { - // This should never happen - the lookup says the record exists. - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - if len(records) != 1 { - http.Error(w, "invalid record count returned by ReadRecords", http.StatusInternalServerError) - return - } - msg, err := tlog.FormatRecord(id, records[0]) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - signed, err := h.Server.Signed(ctx) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "text/plain; charset=UTF-8") - w.Write(msg) - w.Write(signed) - - case r.URL.Path == "/latest": - data, err := h.Server.Signed(ctx) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.Header().Set("Content-Type", "text/plain; charset=UTF-8") - w.Write(data) - - case strings.HasPrefix(r.URL.Path, "/tile/"): - t, err := tlog.ParseTilePath(r.URL.Path[1:]) - if err != nil { - http.Error(w, "invalid tile syntax", http.StatusBadRequest) - return - } - if t.L == -1 { - // Record data. - start := t.N << uint(t.H) - records, err := h.Server.ReadRecords(ctx, start, int64(t.W)) - if err != nil { - reportError(w, r, err) - return - } - if len(records) != t.W { - http.Error(w, "invalid record count returned by ReadRecords", http.StatusInternalServerError) - return - } - var data []byte - for i, text := range records { - msg, err := tlog.FormatRecord(start+int64(i), text) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } - data = append(data, msg...) - } - w.Header().Set("Content-Type", "text/plain; charset=UTF-8") - w.Write(data) - return - } - - data, err := h.Server.ReadTileData(ctx, t) - if err != nil { - reportError(w, r, err) - return - } - w.Header().Set("Content-Type", "application/octet-stream") - w.Write(data) - } -} - -// reportError reports err to w. -// If it's a not-found, the reported error is 404. -// Otherwise it is an internal server error. -// The caller must only call reportError in contexts where -// a not-found err should be reported as 404. -func reportError(w http.ResponseWriter, r *http.Request, err error) { - if os.IsNotExist(err) { - http.Error(w, err.Error(), http.StatusNotFound) - return - } - http.Error(w, err.Error(), http.StatusInternalServerError) -} diff --git a/libgo/go/cmd/go/internal/sumweb/test.go b/libgo/go/cmd/go/internal/sumweb/test.go deleted file mode 100644 index cce86e7e9af..00000000000 --- a/libgo/go/cmd/go/internal/sumweb/test.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sumweb - -import ( - "context" - "fmt" - "net/http" - "strings" - "sync" - - "cmd/go/internal/note" - "cmd/go/internal/tlog" -) - -// NewTestServer constructs a new TestServer -// that will sign its tree with the given signer key -// (see cmd/go/internal/note) -// and fetch new records as needed by calling gosum. -func NewTestServer(signer string, gosum func(path, vers string) ([]byte, error)) *TestServer { - return &TestServer{signer: signer, gosum: gosum} -} - -// A TestServer is an in-memory implementation of Server for testing. -type TestServer struct { - signer string - gosum func(path, vers string) ([]byte, error) - - mu sync.Mutex - hashes testHashes - records [][]byte - lookup map[string]int64 -} - -// testHashes implements tlog.HashReader, reading from a slice. -type testHashes []tlog.Hash - -func (h testHashes) ReadHashes(indexes []int64) ([]tlog.Hash, error) { - var list []tlog.Hash - for _, id := range indexes { - list = append(list, h[id]) - } - return list, nil -} - -func (s *TestServer) NewContext(r *http.Request) (context.Context, error) { - return nil, nil -} - -func (s *TestServer) Signed(ctx context.Context) ([]byte, error) { - s.mu.Lock() - defer s.mu.Unlock() - - size := int64(len(s.records)) - h, err := tlog.TreeHash(size, s.hashes) - if err != nil { - return nil, err - } - text := tlog.FormatTree(tlog.Tree{N: size, Hash: h}) - signer, err := note.NewSigner(s.signer) - if err != nil { - return nil, err - } - return note.Sign(¬e.Note{Text: string(text)}, signer) -} - -func (s *TestServer) ReadRecords(ctx context.Context, id, n int64) ([][]byte, error) { - s.mu.Lock() - defer s.mu.Unlock() - - var list [][]byte - for i := int64(0); i < n; i++ { - if id+i >= int64(len(s.records)) { - return nil, fmt.Errorf("missing records") - } - list = append(list, s.records[id+i]) - } - return list, nil -} - -func (s *TestServer) Lookup(ctx context.Context, key string) (int64, error) { - s.mu.Lock() - id, ok := s.lookup[key] - s.mu.Unlock() - if ok { - return id, nil - } - - // Look up module and compute go.sum lines. - i := strings.Index(key, "@") - if i < 0 { - return 0, fmt.Errorf("invalid lookup key %q", key) - } - path, vers := key[:i], key[i+1:] - data, err := s.gosum(path, vers) - if err != nil { - return 0, err - } - - s.mu.Lock() - defer s.mu.Unlock() - - // We ran the fetch without the lock. - // If another fetch happened and committed, use it instead. - id, ok = s.lookup[key] - if ok { - return id, nil - } - - // Add record. - id = int64(len(s.records)) - s.records = append(s.records, data) - if s.lookup == nil { - s.lookup = make(map[string]int64) - } - s.lookup[key] = id - hashes, err := tlog.StoredHashesForRecordHash(id, tlog.RecordHash([]byte(data)), s.hashes) - if err != nil { - panic(err) - } - s.hashes = append(s.hashes, hashes...) - - return id, nil -} - -func (s *TestServer) ReadTileData(ctx context.Context, t tlog.Tile) ([]byte, error) { - s.mu.Lock() - defer s.mu.Unlock() - - return tlog.ReadTileData(t, s.hashes) -} diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go index 95000011d83..fb011d4c03f 100644 --- a/libgo/go/cmd/go/internal/test/test.go +++ b/libgo/go/cmd/go/internal/test/test.go @@ -572,8 +572,9 @@ func runTest(cmd *base.Command, args []string) { } // Pass timeout to tests if it exists. + // Prepend rather than appending so that it appears before positional arguments. if testActualTimeout > 0 { - testArgs = append(testArgs, "-test.timeout="+testActualTimeout.String()) + testArgs = append([]string{"-test.timeout=" + testActualTimeout.String()}, testArgs...) } // show passing test output (after buffering) with -v flag. @@ -828,7 +829,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin if p.ImportPath == "command-line-arguments" { elem = p.Name } else { - elem = load.DefaultExecName(p.ImportPath) + elem = p.DefaultExecName() } testBinary := elem + ".test" diff --git a/libgo/go/cmd/go/internal/test/testflag.go b/libgo/go/cmd/go/internal/test/testflag.go index 138e1f9d2a2..e214b1532bd 100644 --- a/libgo/go/cmd/go/internal/test/testflag.go +++ b/libgo/go/cmd/go/internal/test/testflag.go @@ -65,7 +65,7 @@ var testFlagDefn = []*cmdflag.Defn{ func init() { cmdflag.AddKnownFlags("test", testFlagDefn) var cmd base.Command - work.AddBuildFlags(&cmd) + work.AddBuildFlags(&cmd, work.DefaultBuildFlags) cmd.Flag.VisitAll(func(f *flag.Flag) { if f.Name == "v" { // test overrides the build -v flag @@ -88,7 +88,8 @@ func init() { // go test fmt -custom-flag-for-fmt-test // go test -x math func testFlags(usage func(), args []string) (packageNames, passToTest []string) { - args = str.StringList(cmdflag.FindGOFLAGS(testFlagDefn), args) + goflags := cmdflag.FindGOFLAGS(testFlagDefn) + args = str.StringList(goflags, args) inPkg := false var explicitArgs []string for i := 0; i < len(args); i++ { @@ -127,6 +128,9 @@ func testFlags(usage func(), args []string) (packageNames, passToTest []string) passToTest = append(passToTest, args[i]) continue } + if i < len(goflags) { + f.Present = false // Not actually present on the command line. + } if f.Value != nil { if err := f.Value.Set(value); err != nil { base.Fatalf("invalid flag argument for -%s: %v", f.Name, err) diff --git a/libgo/go/cmd/go/internal/tlog/ct_test.go b/libgo/go/cmd/go/internal/tlog/ct_test.go deleted file mode 100644 index c2d9aebe79a..00000000000 --- a/libgo/go/cmd/go/internal/tlog/ct_test.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tlog - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "os" - "testing" -) - -func TestCertificateTransparency(t *testing.T) { - // Test that we can verify actual Certificate Transparency proofs. - // (The other tests check that we can verify our own proofs; - // this is a test that the two are compatible.) - - if testing.Short() { - t.Skip("skipping in -short mode") - } - - var root ctTree - httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-sth", &root) - - var leaf ctEntries - httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-entries?start=10000&end=10000", &leaf) - hash := RecordHash(leaf.Entries[0].Data) - - var rp ctRecordProof - httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-proof-by-hash?tree_size="+fmt.Sprint(root.Size)+"&hash="+url.QueryEscape(hash.String()), &rp) - - err := CheckRecord(rp.Proof, root.Size, root.Hash, 10000, hash) - if err != nil { - t.Fatal(err) - } - - var tp ctTreeProof - httpGET(t, "http://ct.googleapis.com/logs/argon2020/ct/v1/get-sth-consistency?first=3654490&second="+fmt.Sprint(root.Size), &tp) - - oh, _ := ParseHash("AuIZ5V6sDUj1vn3Y1K85oOaQ7y+FJJKtyRTl1edIKBQ=") - err = CheckTree(tp.Proof, root.Size, root.Hash, 3654490, oh) - if err != nil { - t.Fatal(err) - } -} - -type ctTree struct { - Size int64 `json:"tree_size"` - Hash Hash `json:"sha256_root_hash"` -} - -type ctEntries struct { - Entries []*ctEntry -} - -type ctEntry struct { - Data []byte `json:"leaf_input"` -} - -type ctRecordProof struct { - Index int64 `json:"leaf_index"` - Proof RecordProof `json:"audit_path"` -} - -type ctTreeProof struct { - Proof TreeProof `json:"consistency"` -} - -func httpGET(t *testing.T, url string, targ interface{}) { - if testing.Verbose() { - println() - println(url) - } - resp, err := http.Get(url) - if err != nil { - t.Fatal(err) - } - defer resp.Body.Close() - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - t.Fatal(err) - } - if testing.Verbose() { - os.Stdout.Write(data) - } - err = json.Unmarshal(data, targ) - if err != nil { - println(url) - os.Stdout.Write(data) - t.Fatal(err) - } -} diff --git a/libgo/go/cmd/go/internal/tlog/note.go b/libgo/go/cmd/go/internal/tlog/note.go deleted file mode 100644 index 65c71644baf..00000000000 --- a/libgo/go/cmd/go/internal/tlog/note.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tlog - -import ( - "bytes" - "encoding/base64" - "errors" - "fmt" - "strconv" - "strings" - "unicode/utf8" -) - -// A Tree is a tree description, to be signed by a go.sum database server. -type Tree struct { - N int64 - Hash Hash -} - -// FormatTree formats a tree description for inclusion in a note. -// -// The encoded form is three lines, each ending in a newline (U+000A): -// -// go.sum database tree -// N -// Hash -// -// where N is in decimal and Hash is in base64. -// -// A future backwards-compatible encoding may add additional lines, -// which the parser can ignore. -// A future backwards-incompatible encoding would use a different -// first line (for example, "go.sum database tree v2"). -func FormatTree(tree Tree) []byte { - return []byte(fmt.Sprintf("go.sum database tree\n%d\n%s\n", tree.N, tree.Hash)) -} - -var errMalformedTree = errors.New("malformed tree note") -var treePrefix = []byte("go.sum database tree\n") - -// ParseTree parses a tree root description. -func ParseTree(text []byte) (tree Tree, err error) { - // The message looks like: - // - // go.sum database tree - // 2 - // nND/nri/U0xuHUrYSy0HtMeal2vzD9V4k/BO79C+QeI= - // - // For forwards compatibility, extra text lines after the encoding are ignored. - if !bytes.HasPrefix(text, treePrefix) || bytes.Count(text, []byte("\n")) < 3 || len(text) > 1e6 { - return Tree{}, errMalformedTree - } - - lines := strings.SplitN(string(text), "\n", 4) - n, err := strconv.ParseInt(lines[1], 10, 64) - if err != nil || n < 0 || lines[1] != strconv.FormatInt(n, 10) { - return Tree{}, errMalformedTree - } - - h, err := base64.StdEncoding.DecodeString(lines[2]) - if err != nil || len(h) != HashSize { - return Tree{}, errMalformedTree - } - - var hash Hash - copy(hash[:], h) - return Tree{n, hash}, nil -} - -var errMalformedRecord = errors.New("malformed record data") - -// FormatRecord formats a record for serving to a client -// in a lookup response or data tile. -// -// The encoded form is the record ID as a single number, -// then the text of the record, and then a terminating blank line. -// Record text must be valid UTF-8 and must not contain any ASCII control -// characters (those below U+0020) other than newline (U+000A). -// It must end in a terminating newline and not contain any blank lines. -func FormatRecord(id int64, text []byte) (msg []byte, err error) { - if !isValidRecordText(text) { - return nil, errMalformedRecord - } - msg = []byte(fmt.Sprintf("%d\n", id)) - msg = append(msg, text...) - msg = append(msg, '\n') - return msg, nil -} - -// isValidRecordText reports whether text is syntactically valid record text. -func isValidRecordText(text []byte) bool { - var last rune - for i := 0; i < len(text); { - r, size := utf8.DecodeRune(text[i:]) - if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 || last == '\n' && r == '\n' { - return false - } - i += size - last = r - } - if last != '\n' { - return false - } - return true -} - -// ParseRecord parses a record description at the start of text, -// stopping immediately after the terminating blank line. -// It returns the record id, the record text, and the remainder of text. -func ParseRecord(msg []byte) (id int64, text, rest []byte, err error) { - // Leading record id. - i := bytes.IndexByte(msg, '\n') - if i < 0 { - return 0, nil, nil, errMalformedRecord - } - id, err = strconv.ParseInt(string(msg[:i]), 10, 64) - if err != nil { - return 0, nil, nil, errMalformedRecord - } - msg = msg[i+1:] - - // Record text. - i = bytes.Index(msg, []byte("\n\n")) - if i < 0 { - return 0, nil, nil, errMalformedRecord - } - text, rest = msg[:i+1], msg[i+2:] - if !isValidRecordText(text) { - return 0, nil, nil, errMalformedRecord - } - return id, text, rest, nil -} diff --git a/libgo/go/cmd/go/internal/tlog/note_test.go b/libgo/go/cmd/go/internal/tlog/note_test.go deleted file mode 100644 index a32d6d21436..00000000000 --- a/libgo/go/cmd/go/internal/tlog/note_test.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tlog - -import ( - "strings" - "testing" -) - -func TestFormatTree(t *testing.T) { - n := int64(123456789012) - h := RecordHash([]byte("hello world")) - golden := "go.sum database tree\n123456789012\nTszzRgjTG6xce+z2AG31kAXYKBgQVtCSCE40HmuwBb0=\n" - b := FormatTree(Tree{n, h}) - if string(b) != golden { - t.Errorf("FormatTree(...) = %q, want %q", b, golden) - } -} - -func TestParseTree(t *testing.T) { - in := "go.sum database tree\n123456789012\nTszzRgjTG6xce+z2AG31kAXYKBgQVtCSCE40HmuwBb0=\n" - goldH := RecordHash([]byte("hello world")) - goldN := int64(123456789012) - tree, err := ParseTree([]byte(in)) - if tree.N != goldN || tree.Hash != goldH || err != nil { - t.Fatalf("ParseTree(...) = Tree{%d, %v}, %v, want Tree{%d, %v}, nil", tree.N, tree.Hash, err, goldN, goldH) - } - - // Check invalid trees. - var badTrees = []string{ - "not-" + in, - "go.sum database tree\n0xabcdef\nTszzRgjTG6xce+z2AG31kAXYKBgQVtCSCE40HmuwBb0=\n", - "go.sum database tree\n123456789012\nTszzRgjTG6xce+z2AG31kAXYKBgQVtCSCE40HmuwBTOOBIG=\n", - } - for _, bad := range badTrees { - _, err := ParseTree([]byte(bad)) - if err == nil { - t.Fatalf("ParseTree(%q) succeeded, want failure", in) - } - } - - // Check junk on end is ignored. - var goodTrees = []string{ - in + "JOE", - in + "JOE\n", - in + strings.Repeat("JOE\n", 1000), - } - for _, good := range goodTrees { - _, err := ParseTree([]byte(good)) - if tree.N != goldN || tree.Hash != goldH || err != nil { - t.Fatalf("ParseTree(...+%q) = Tree{%d, %v}, %v, want Tree{%d, %v}, nil", good[len(in):], tree.N, tree.Hash, err, goldN, goldH) - } - } -} - -func TestFormatRecord(t *testing.T) { - id := int64(123456789012) - text := "hello, world\n" - golden := "123456789012\nhello, world\n\n" - msg, err := FormatRecord(id, []byte(text)) - if err != nil { - t.Fatalf("FormatRecord: %v", err) - } - if string(msg) != golden { - t.Fatalf("FormatRecord(...) = %q, want %q", msg, golden) - } - - var badTexts = []string{ - "", - "hello\nworld", - "hello\n\nworld\n", - "hello\x01world\n", - } - for _, bad := range badTexts { - msg, err := FormatRecord(id, []byte(bad)) - if err == nil { - t.Errorf("FormatRecord(id, %q) = %q, want error", bad, msg) - } - } -} - -func TestParseRecord(t *testing.T) { - in := "123456789012\nhello, world\n\njunk on end\x01\xff" - goldID := int64(123456789012) - goldText := "hello, world\n" - goldRest := "junk on end\x01\xff" - id, text, rest, err := ParseRecord([]byte(in)) - if id != goldID || string(text) != goldText || string(rest) != goldRest || err != nil { - t.Fatalf("ParseRecord(%q) = %d, %q, %q, %v, want %d, %q, %q, nil", in, id, text, rest, err, goldID, goldText, goldRest) - } - - in = "123456789012\nhello, world\n\n" - id, text, rest, err = ParseRecord([]byte(in)) - if id != goldID || string(text) != goldText || len(rest) != 0 || err != nil { - t.Fatalf("ParseRecord(%q) = %d, %q, %q, %v, want %d, %q, %q, nil", in, id, text, rest, err, goldID, goldText, "") - } - if rest == nil { - t.Fatalf("ParseRecord(%q): rest = []byte(nil), want []byte{}", in) - } - - // Check invalid records. - var badRecords = []string{ - "not-" + in, - "123\nhello\x01world\n\n", - "123\nhello\xffworld\n\n", - "123\nhello world\n", - "0x123\nhello world\n\n", - } - for _, bad := range badRecords { - id, text, rest, err := ParseRecord([]byte(bad)) - if err == nil { - t.Fatalf("ParseRecord(%q) = %d, %q, %q, nil, want error", in, id, text, rest) - } - } -} diff --git a/libgo/go/cmd/go/internal/tlog/tile.go b/libgo/go/cmd/go/internal/tlog/tile.go deleted file mode 100644 index 694d89cdf26..00000000000 --- a/libgo/go/cmd/go/internal/tlog/tile.go +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tlog - -import ( - "fmt" - "strconv" - "strings" -) - -// A Tile is a description of a transparency log tile. -// A tile of height H at level L offset N lists W consecutive hashes -// at level H*L of the tree starting at offset N*(2**H). -// A complete tile lists 2**H hashes; a partial tile lists fewer. -// Note that a tile represents the entire subtree of height H -// with those hashes as the leaves. The levels above H*L -// can be reconstructed by hashing the leaves. -// -// Each Tile can be encoded as a “tile coordinate path” -// of the form tile/H/L/NNN[.p/W]. -// The .p/W suffix is present only for partial tiles, meaning W < 2**H. -// The NNN element is an encoding of N into 3-digit path elements. -// All but the last path element begins with an "x". -// For example, -// Tile{H: 3, L: 4, N: 1234067, W: 1}'s path -// is tile/3/4/x001/x234/067.p/1, and -// Tile{H: 3, L: 4, N: 1234067, W: 8}'s path -// is tile/3/4/x001/x234/067. -// See Tile's Path method and the ParseTilePath function. -// -// The special level L=-1 holds raw record data instead of hashes. -// In this case, the level encodes into a tile path as the path element -// "data" instead of "-1". -type Tile struct { - H int // height of tile (1 ≤ H ≤ 30) - L int // level in tiling (-1 ≤ L ≤ 63) - N int64 // number within level (0 ≤ N, unbounded) - W int // width of tile (1 ≤ W ≤ 2**H; 2**H is complete tile) -} - -// TileForIndex returns the tile of height h ≥ 1 -// and least width storing the given hash storage index. -func TileForIndex(h int, index int64) Tile { - if h < 1 { - panic("TileForIndex: invalid height") - } - t, _, _ := tileForIndex(h, index) - return t -} - -// tileForIndex returns the tile of height h ≥ 1 -// storing the given hash index, which can be -// reconstructed using tileHash(data[start:end]). -func tileForIndex(h int, index int64) (t Tile, start, end int) { - level, n := SplitStoredHashIndex(index) - t.H = h - t.L = level / h - level -= t.L * h // now level within tile - t.N = n << uint(level) >> uint(t.H) - n -= t.N << uint(t.H) >> uint(level) // now n within tile at level - t.W = int((n + 1) << uint(level)) - return t, int(n< 30 || t.L < 0 || t.L >= 64 || t.W < 1 || t.W > 1<>(H*level) > 0; level++ { - oldN := oldTreeSize >> (H * level) - newN := newTreeSize >> (H * level) - for n := oldN >> H; n < newN>>H; n++ { - tiles = append(tiles, Tile{H: h, L: int(level), N: n, W: 1 << H}) - } - n := newN >> H - maxW := int(newN - n< n<= pathBase { - n /= pathBase - nStr = fmt.Sprintf("x%03d/%s", n%pathBase, nStr) - } - pStr := "" - if t.W != 1< 30 { - return Tile{}, &badPathError{path} - } - w := 1 << uint(h) - if dotP := f[len(f)-2]; strings.HasSuffix(dotP, ".p") { - ww, err := strconv.Atoi(f[len(f)-1]) - if err != nil || ww <= 0 || ww >= w { - return Tile{}, &badPathError{path} - } - w = ww - f[len(f)-2] = dotP[:len(dotP)-len(".p")] - f = f[:len(f)-1] - } - f = f[3:] - n := int64(0) - for _, s := range f { - nn, err := strconv.Atoi(strings.TrimPrefix(s, "x")) - if err != nil || nn < 0 || nn >= pathBase { - return Tile{}, &badPathError{path} - } - n = n*pathBase + int64(nn) - } - if isData { - l = -1 - } - t := Tile{H: h, L: l, N: n, W: w} - if path != t.Path() { - return Tile{}, &badPathError{path} - } - return t, nil -} - -type badPathError struct { - path string -} - -func (e *badPathError) Error() string { - return fmt.Sprintf("malformed tile path %q", e.path) -} - -// A TileReader reads tiles from a go.sum database log. -type TileReader interface { - // Height returns the height of the available tiles. - Height() int - - // ReadTiles returns the data for each requested tile. - // If ReadTiles returns err == nil, it must also return - // a data record for each tile (len(data) == len(tiles)) - // and each data record must be the correct length - // (len(data[i]) == tiles[i].W*HashSize). - ReadTiles(tiles []Tile) (data [][]byte, err error) - - // SaveTiles informs the TileReader that the tile data - // returned by ReadTiles has been confirmed as valid - // and can be saved in persistent storage (on disk). - SaveTiles(tiles []Tile, data [][]byte) -} - -// TileHashReader returns a HashReader that satisfies requests -// by loading tiles of the given tree. -// -// The returned HashReader checks that loaded tiles are -// valid for the given tree. Therefore, any hashes returned -// by the HashReader are already proven to be in the tree. -func TileHashReader(tree Tree, tr TileReader) HashReader { - return &tileHashReader{tree: tree, tr: tr} -} - -type tileHashReader struct { - tree Tree - tr TileReader -} - -// tileParent returns t's k'th tile parent in the tiles for a tree of size n. -// If there is no such parent, tileParent returns Tile{}. -func tileParent(t Tile, k int, n int64) Tile { - t.L += k - t.N >>= uint(k * t.H) - t.W = 1 << uint(t.H) - if max := n >> uint(t.L*t.H); t.N<= max { - if t.N<= max { - return Tile{} - } - t.W = int(max - t.N<= StoredHashIndex(0, r.tree.N) { - return nil, fmt.Errorf("indexes not in tree") - } - - tile, _, _ := tileForIndex(h, x) - - // Walk up parent tiles until we find one we've requested. - // That one will be authenticated. - k := 0 - for ; ; k++ { - p := tileParent(tile, k, r.tree.N) - if j, ok := tileOrder[p]; ok { - if k == 0 { - indexTileOrder[i] = j - } - break - } - } - - // Walk back down recording child tiles after parents. - // This loop ends by revisiting the tile for this index - // (tileParent(tile, 0, r.tree.N)) unless k == 0, in which - // case the previous loop did it. - for k--; k >= 0; k-- { - p := tileParent(tile, k, r.tree.N) - if p.W != 1<= 0; i-- { - h, err := HashFromTile(tiles[stxTileOrder[i]], data[stxTileOrder[i]], stx[i]) - if err != nil { - return nil, err - } - th = NodeHash(h, th) - } - if th != r.tree.Hash { - // The tiles do not support the tree hash. - // We know at least one is wrong, but not which one. - return nil, fmt.Errorf("downloaded inconsistent tile") - } - - // Authenticate full tiles against their parents. - for i := len(stx); i < len(tiles); i++ { - tile := tiles[i] - p := tileParent(tile, 1, r.tree.N) - j, ok := tileOrder[p] - if !ok { - return nil, fmt.Errorf("bad math in tileHashReader %d %v: lost parent of %v", r.tree.N, indexes, tile) - } - h, err := HashFromTile(p, data[j], StoredHashIndex(p.L*p.H, tile.N)) - if err != nil { - return nil, fmt.Errorf("bad math in tileHashReader %d %v: lost hash of %v: %v", r.tree.N, indexes, tile, err) - } - if h != tileHash(data[i]) { - return nil, fmt.Errorf("downloaded inconsistent tile") - } - } - - // Now we have all the tiles needed for the requested hashes, - // and we've authenticated the full tile set against the trusted tree hash. - r.tr.SaveTiles(tiles, data) - - // Pull out the requested hashes. - hashes := make([]Hash, len(indexes)) - for i, x := range indexes { - j := indexTileOrder[i] - h, err := HashFromTile(tiles[j], data[j], x) - if err != nil { - return nil, fmt.Errorf("bad math in tileHashReader %d %v: lost hash %v: %v", r.tree.N, indexes, x, err) - } - hashes[i] = h - } - - return hashes, nil -} diff --git a/libgo/go/cmd/go/internal/tlog/tlog.go b/libgo/go/cmd/go/internal/tlog/tlog.go deleted file mode 100644 index 6703656b19f..00000000000 --- a/libgo/go/cmd/go/internal/tlog/tlog.go +++ /dev/null @@ -1,601 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package tlog implements a tamper-evident log -// used in the Go module go.sum database server. -// -// This package is part of a DRAFT of what the go.sum database server will look like. -// Do not assume the details here are final! -// -// This package follows the design of Certificate Transparency (RFC 6962) -// and its proofs are compatible with that system. -// See TestCertificateTransparency. -// -package tlog - -import ( - "crypto/sha256" - "encoding/base64" - "errors" - "fmt" - "math/bits" -) - -// A Hash is a hash identifying a log record or tree root. -type Hash [HashSize]byte - -// HashSize is the size of a Hash in bytes. -const HashSize = 32 - -// String returns a base64 representation of the hash for printing. -func (h Hash) String() string { - return base64.StdEncoding.EncodeToString(h[:]) -} - -// MarshalJSON marshals the hash as a JSON string containing the base64-encoded hash. -func (h Hash) MarshalJSON() ([]byte, error) { - return []byte(`"` + h.String() + `"`), nil -} - -// UnmarshalJSON unmarshals a hash from JSON string containing the a base64-encoded hash. -func (h *Hash) UnmarshalJSON(data []byte) error { - if len(data) != 1+44+1 || data[0] != '"' || data[len(data)-2] != '=' || data[len(data)-1] != '"' { - return errors.New("cannot decode hash") - } - - // As of Go 1.12, base64.StdEncoding.Decode insists on - // slicing into target[33:] even when it only writes 32 bytes. - // Since we already checked that the hash ends in = above, - // we can use base64.RawStdEncoding with the = removed; - // RawStdEncoding does not exhibit the same bug. - // We decode into a temporary to avoid writing anything to *h - // unless the entire input is well-formed. - var tmp Hash - n, err := base64.RawStdEncoding.Decode(tmp[:], data[1:len(data)-2]) - if err != nil || n != HashSize { - return errors.New("cannot decode hash") - } - *h = tmp - return nil -} - -// ParseHash parses the base64-encoded string form of a hash. -func ParseHash(s string) (Hash, error) { - data, err := base64.StdEncoding.DecodeString(s) - if err != nil || len(data) != HashSize { - return Hash{}, fmt.Errorf("malformed hash") - } - var h Hash - copy(h[:], data) - return h, nil -} - -// maxpow2 returns k, the maximum power of 2 smaller than n, -// as well as l = log₂ k (so k = 1< 0; l-- { - n = 2*n + 1 - } - - // Level 0's n'th hash is written at n+n/2+n/4+... (eventually n/2ⁱ hits zero). - i := int64(0) - for ; n > 0; n >>= 1 { - i += n - } - - return i + int64(level) -} - -// SplitStoredHashIndex is the inverse of StoredHashIndex. -// That is, SplitStoredHashIndex(StoredHashIndex(level, n)) == level, n. -func SplitStoredHashIndex(index int64) (level int, n int64) { - // Determine level 0 record before index. - // StoredHashIndex(0, n) < 2*n, - // so the n we want is in [index/2, index/2+log₂(index)]. - n = index / 2 - indexN := StoredHashIndex(0, n) - if indexN > index { - panic("bad math") - } - for { - // Each new record n adds 1 + trailingZeros(n) hashes. - x := indexN + 1 + int64(bits.TrailingZeros64(uint64(n+1))) - if x > index { - break - } - n++ - indexN = x - } - // The hash we want was commited with record n, - // meaning it is one of (0, n), (1, n/2), (2, n/4), ... - level = int(index - indexN) - return level, n >> uint(level) -} - -// StoredHashCount returns the number of stored hashes -// that are expected for a tree with n records. -func StoredHashCount(n int64) int64 { - if n == 0 { - return 0 - } - // The tree will have the hashes up to the last leaf hash. - numHash := StoredHashIndex(0, n-1) + 1 - // And it will have any hashes for subtrees completed by that leaf. - for i := uint64(n - 1); i&1 != 0; i >>= 1 { - numHash++ - } - return numHash -} - -// StoredHashes returns the hashes that must be stored when writing -// record n with the given data. The hashes should be stored starting -// at StoredHashIndex(0, n). The result will have at most 1 + log₂ n hashes, -// but it will average just under two per call for a sequence of calls for n=1..k. -// -// StoredHashes may read up to log n earlier hashes from r -// in order to compute hashes for completed subtrees. -func StoredHashes(n int64, data []byte, r HashReader) ([]Hash, error) { - return StoredHashesForRecordHash(n, RecordHash(data), r) -} - -// StoredHashesForRecordHash is like StoredHashes but takes -// as its second argument RecordHash(data) instead of data itself. -func StoredHashesForRecordHash(n int64, h Hash, r HashReader) ([]Hash, error) { - // Start with the record hash. - hashes := []Hash{h} - - // Build list of indexes needed for hashes for completed subtrees. - // Each trailing 1 bit in the binary representation of n completes a subtree - // and consumes a hash from an adjacent subtree. - m := int(bits.TrailingZeros64(uint64(n + 1))) - indexes := make([]int64, m) - for i := 0; i < m; i++ { - // We arrange indexes in sorted order. - // Note that n>>i is always odd. - indexes[m-1-i] = StoredHashIndex(i, n>>uint(i)-1) - } - - // Fetch hashes. - old, err := r.ReadHashes(indexes) - if err != nil { - return nil, err - } - if len(old) != len(indexes) { - return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(old)) - } - - // Build new hashes. - for i := 0; i < m; i++ { - h = NodeHash(old[m-1-i], h) - hashes = append(hashes, h) - } - return hashes, nil -} - -// A HashReader can read hashes for nodes in the log's tree structure. -type HashReader interface { - // ReadHashes returns the hashes with the given stored hash indexes - // (see StoredHashIndex and SplitStoredHashIndex). - // ReadHashes must return a slice of hashes the same length as indexes, - // or else it must return a non-nil error. - // ReadHashes may run faster if indexes is sorted in increasing order. - ReadHashes(indexes []int64) ([]Hash, error) -} - -// A HashReaderFunc is a function implementing HashReader. -type HashReaderFunc func([]int64) ([]Hash, error) - -func (f HashReaderFunc) ReadHashes(indexes []int64) ([]Hash, error) { - return f(indexes) -} - -// TreeHash computes the hash for the root of the tree with n records, -// using the HashReader to obtain previously stored hashes -// (those returned by StoredHashes during the writes of those n records). -// TreeHash makes a single call to ReadHash requesting at most 1 + log₂ n hashes. -// The tree of size zero is defined to have an all-zero Hash. -func TreeHash(n int64, r HashReader) (Hash, error) { - if n == 0 { - return Hash{}, nil - } - indexes := subTreeIndex(0, n, nil) - hashes, err := r.ReadHashes(indexes) - if err != nil { - return Hash{}, err - } - if len(hashes) != len(indexes) { - return Hash{}, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes)) - } - hash, hashes := subTreeHash(0, n, hashes) - if len(hashes) != 0 { - panic("tlog: bad index math in TreeHash") - } - return hash, nil -} - -// subTreeIndex returns the storage indexes needed to compute -// the hash for the subtree containing records [lo, hi), -// appending them to need and returning the result. -// See https://tools.ietf.org/html/rfc6962#section-2.1 -func subTreeIndex(lo, hi int64, need []int64) []int64 { - // See subTreeHash below for commentary. - for lo < hi { - k, level := maxpow2(hi - lo + 1) - if lo&(k-1) != 0 { - panic("tlog: bad math in subTreeIndex") - } - need = append(need, StoredHashIndex(level, lo>>uint(level))) - lo += k - } - return need -} - -// subTreeHash computes the hash for the subtree containing records [lo, hi), -// assuming that hashes are the hashes corresponding to the indexes -// returned by subTreeIndex(lo, hi). -// It returns any leftover hashes. -func subTreeHash(lo, hi int64, hashes []Hash) (Hash, []Hash) { - // Repeatedly partition the tree into a left side with 2^level nodes, - // for as large a level as possible, and a right side with the fringe. - // The left hash is stored directly and can be read from storage. - // The right side needs further computation. - numTree := 0 - for lo < hi { - k, _ := maxpow2(hi - lo + 1) - if lo&(k-1) != 0 || lo >= hi { - panic("tlog: bad math in subTreeHash") - } - numTree++ - lo += k - } - - if len(hashes) < numTree { - panic("tlog: bad index math in subTreeHash") - } - - // Reconstruct hash. - h := hashes[numTree-1] - for i := numTree - 2; i >= 0; i-- { - h = NodeHash(hashes[i], h) - } - return h, hashes[numTree:] -} - -// A RecordProof is a verifiable proof that a particular log root contains a particular record. -// RFC 6962 calls this a “Merkle audit path.” -type RecordProof []Hash - -// ProveRecord returns the proof that the tree of size t contains the record with index n. -func ProveRecord(t, n int64, r HashReader) (RecordProof, error) { - if t < 0 || n < 0 || n >= t { - return nil, fmt.Errorf("tlog: invalid inputs in ProveRecord") - } - indexes := leafProofIndex(0, t, n, nil) - if len(indexes) == 0 { - return RecordProof{}, nil - } - hashes, err := r.ReadHashes(indexes) - if err != nil { - return nil, err - } - if len(hashes) != len(indexes) { - return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes)) - } - - p, hashes := leafProof(0, t, n, hashes) - if len(hashes) != 0 { - panic("tlog: bad index math in ProveRecord") - } - return p, nil -} - -// leafProofIndex builds the list of indexes needed to construct the proof -// that leaf n is contained in the subtree with leaves [lo, hi). -// It appends those indexes to need and returns the result. -// See https://tools.ietf.org/html/rfc6962#section-2.1.1 -func leafProofIndex(lo, hi, n int64, need []int64) []int64 { - // See leafProof below for commentary. - if !(lo <= n && n < hi) { - panic("tlog: bad math in leafProofIndex") - } - if lo+1 == hi { - return need - } - if k, _ := maxpow2(hi - lo); n < lo+k { - need = leafProofIndex(lo, lo+k, n, need) - need = subTreeIndex(lo+k, hi, need) - } else { - need = subTreeIndex(lo, lo+k, need) - need = leafProofIndex(lo+k, hi, n, need) - } - return need -} - -// leafProof constructs the proof that leaf n is contained in the subtree with leaves [lo, hi). -// It returns any leftover hashes as well. -// See https://tools.ietf.org/html/rfc6962#section-2.1.1 -func leafProof(lo, hi, n int64, hashes []Hash) (RecordProof, []Hash) { - // We must have lo <= n < hi or else the code here has a bug. - if !(lo <= n && n < hi) { - panic("tlog: bad math in leafProof") - } - - if lo+1 == hi { // n == lo - // Reached the leaf node. - // The verifier knows what the leaf hash is, so we don't need to send it. - return RecordProof{}, hashes - } - - // Walk down the tree toward n. - // Record the hash of the path not taken (needed for verifying the proof). - var p RecordProof - var th Hash - if k, _ := maxpow2(hi - lo); n < lo+k { - // n is on left side - p, hashes = leafProof(lo, lo+k, n, hashes) - th, hashes = subTreeHash(lo+k, hi, hashes) - } else { - // n is on right side - th, hashes = subTreeHash(lo, lo+k, hashes) - p, hashes = leafProof(lo+k, hi, n, hashes) - } - return append(p, th), hashes -} - -var errProofFailed = errors.New("invalid transparency proof") - -// CheckRecord verifies that p is a valid proof that the tree of size t -// with hash th has an n'th record with hash h. -func CheckRecord(p RecordProof, t int64, th Hash, n int64, h Hash) error { - if t < 0 || n < 0 || n >= t { - return fmt.Errorf("tlog: invalid inputs in CheckRecord") - } - th2, err := runRecordProof(p, 0, t, n, h) - if err != nil { - return err - } - if th2 == th { - return nil - } - return errProofFailed -} - -// runRecordProof runs the proof p that leaf n is contained in the subtree with leaves [lo, hi). -// Running the proof means constructing and returning the implied hash of that -// subtree. -func runRecordProof(p RecordProof, lo, hi, n int64, leafHash Hash) (Hash, error) { - // We must have lo <= n < hi or else the code here has a bug. - if !(lo <= n && n < hi) { - panic("tlog: bad math in runRecordProof") - } - - if lo+1 == hi { // m == lo - // Reached the leaf node. - // The proof must not have any unnecessary hashes. - if len(p) != 0 { - return Hash{}, errProofFailed - } - return leafHash, nil - } - - if len(p) == 0 { - return Hash{}, errProofFailed - } - - k, _ := maxpow2(hi - lo) - if n < lo+k { - th, err := runRecordProof(p[:len(p)-1], lo, lo+k, n, leafHash) - if err != nil { - return Hash{}, err - } - return NodeHash(th, p[len(p)-1]), nil - } else { - th, err := runRecordProof(p[:len(p)-1], lo+k, hi, n, leafHash) - if err != nil { - return Hash{}, err - } - return NodeHash(p[len(p)-1], th), nil - } -} - -// A TreeProof is a verifiable proof that a particular log tree contains -// as a prefix all records present in an earlier tree. -// RFC 6962 calls this a “Merkle consistency proof.” -type TreeProof []Hash - -// ProveTree returns the proof that the tree of size t contains -// as a prefix all the records from the tree of smaller size n. -func ProveTree(t, n int64, h HashReader) (TreeProof, error) { - if t < 1 || n < 1 || n > t { - return nil, fmt.Errorf("tlog: invalid inputs in ProveTree") - } - indexes := treeProofIndex(0, t, n, nil) - if len(indexes) == 0 { - return TreeProof{}, nil - } - hashes, err := h.ReadHashes(indexes) - if err != nil { - return nil, err - } - if len(hashes) != len(indexes) { - return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes)) - } - - p, hashes := treeProof(0, t, n, hashes) - if len(hashes) != 0 { - panic("tlog: bad index math in ProveTree") - } - return p, nil -} - -// treeProofIndex builds the list of indexes needed to construct -// the sub-proof related to the subtree containing records [lo, hi). -// See https://tools.ietf.org/html/rfc6962#section-2.1.2. -func treeProofIndex(lo, hi, n int64, need []int64) []int64 { - // See treeProof below for commentary. - if !(lo < n && n <= hi) { - panic("tlog: bad math in treeProofIndex") - } - - if n == hi { - if lo == 0 { - return need - } - return subTreeIndex(lo, hi, need) - } - - if k, _ := maxpow2(hi - lo); n <= lo+k { - need = treeProofIndex(lo, lo+k, n, need) - need = subTreeIndex(lo+k, hi, need) - } else { - need = subTreeIndex(lo, lo+k, need) - need = treeProofIndex(lo+k, hi, n, need) - } - return need -} - -// treeProof constructs the sub-proof related to the subtree containing records [lo, hi). -// It returns any leftover hashes as well. -// See https://tools.ietf.org/html/rfc6962#section-2.1.2. -func treeProof(lo, hi, n int64, hashes []Hash) (TreeProof, []Hash) { - // We must have lo < n <= hi or else the code here has a bug. - if !(lo < n && n <= hi) { - panic("tlog: bad math in treeProof") - } - - // Reached common ground. - if n == hi { - if lo == 0 { - // This subtree corresponds exactly to the old tree. - // The verifier knows that hash, so we don't need to send it. - return TreeProof{}, hashes - } - th, hashes := subTreeHash(lo, hi, hashes) - return TreeProof{th}, hashes - } - - // Interior node for the proof. - // Decide whether to walk down the left or right side. - var p TreeProof - var th Hash - if k, _ := maxpow2(hi - lo); n <= lo+k { - // m is on left side - p, hashes = treeProof(lo, lo+k, n, hashes) - th, hashes = subTreeHash(lo+k, hi, hashes) - } else { - // m is on right side - th, hashes = subTreeHash(lo, lo+k, hashes) - p, hashes = treeProof(lo+k, hi, n, hashes) - } - return append(p, th), hashes -} - -// CheckTree verifies that p is a valid proof that the tree of size t with hash th -// contains as a prefix the tree of size n with hash h. -func CheckTree(p TreeProof, t int64, th Hash, n int64, h Hash) error { - if t < 1 || n < 1 || n > t { - return fmt.Errorf("tlog: invalid inputs in CheckTree") - } - h2, th2, err := runTreeProof(p, 0, t, n, h) - if err != nil { - return err - } - if th2 == th && h2 == h { - return nil - } - return errProofFailed -} - -// runTreeProof runs the sub-proof p related to the subtree containing records [lo, hi), -// where old is the hash of the old tree with n records. -// Running the proof means constructing and returning the implied hashes of that -// subtree in both the old and new tree. -func runTreeProof(p TreeProof, lo, hi, n int64, old Hash) (Hash, Hash, error) { - // We must have lo < n <= hi or else the code here has a bug. - if !(lo < n && n <= hi) { - panic("tlog: bad math in runTreeProof") - } - - // Reached common ground. - if n == hi { - if lo == 0 { - if len(p) != 0 { - return Hash{}, Hash{}, errProofFailed - } - return old, old, nil - } - if len(p) != 1 { - return Hash{}, Hash{}, errProofFailed - } - return p[0], p[0], nil - } - - if len(p) == 0 { - return Hash{}, Hash{}, errProofFailed - } - - // Interior node for the proof. - k, _ := maxpow2(hi - lo) - if n <= lo+k { - oh, th, err := runTreeProof(p[:len(p)-1], lo, lo+k, n, old) - if err != nil { - return Hash{}, Hash{}, err - } - return oh, NodeHash(th, p[len(p)-1]), nil - } else { - oh, th, err := runTreeProof(p[:len(p)-1], lo+k, hi, n, old) - if err != nil { - return Hash{}, Hash{}, err - } - return NodeHash(p[len(p)-1], oh), NodeHash(p[len(p)-1], th), nil - } -} diff --git a/libgo/go/cmd/go/internal/tlog/tlog_test.go b/libgo/go/cmd/go/internal/tlog/tlog_test.go deleted file mode 100644 index 584e728c1bb..00000000000 --- a/libgo/go/cmd/go/internal/tlog/tlog_test.go +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tlog - -import ( - "bytes" - "fmt" - "testing" -) - -type testHashStorage []Hash - -func (t testHashStorage) ReadHash(level int, n int64) (Hash, error) { - return t[StoredHashIndex(level, n)], nil -} - -func (t testHashStorage) ReadHashes(index []int64) ([]Hash, error) { - // It's not required by HashReader that indexes be in increasing order, - // but check that the functions we are testing only ever ask for - // indexes in increasing order. - for i := 1; i < len(index); i++ { - if index[i-1] >= index[i] { - panic("indexes out of order") - } - } - - out := make([]Hash, len(index)) - for i, x := range index { - out[i] = t[x] - } - return out, nil -} - -type testTilesStorage struct { - unsaved int - m map[Tile][]byte -} - -func (t testTilesStorage) Height() int { - return 2 -} - -func (t *testTilesStorage) SaveTiles(tiles []Tile, data [][]byte) { - t.unsaved -= len(tiles) -} - -func (t *testTilesStorage) ReadTiles(tiles []Tile) ([][]byte, error) { - out := make([][]byte, len(tiles)) - for i, tile := range tiles { - out[i] = t.m[tile] - } - t.unsaved += len(tiles) - return out, nil -} - -func TestTree(t *testing.T) { - var trees []Hash - var leafhashes []Hash - var storage testHashStorage - tiles := make(map[Tile][]byte) - const testH = 2 - for i := int64(0); i < 100; i++ { - data := []byte(fmt.Sprintf("leaf %d", i)) - hashes, err := StoredHashes(i, data, storage) - if err != nil { - t.Fatal(err) - } - leafhashes = append(leafhashes, RecordHash(data)) - oldStorage := len(storage) - storage = append(storage, hashes...) - if count := StoredHashCount(i + 1); count != int64(len(storage)) { - t.Errorf("StoredHashCount(%d) = %d, have %d StoredHashes", i+1, count, len(storage)) - } - th, err := TreeHash(i+1, storage) - if err != nil { - t.Fatal(err) - } - - for _, tile := range NewTiles(testH, i, i+1) { - data, err := ReadTileData(tile, storage) - if err != nil { - t.Fatal(err) - } - old := Tile{H: tile.H, L: tile.L, N: tile.N, W: tile.W - 1} - oldData := tiles[old] - if len(oldData) != len(data)-HashSize || !bytes.Equal(oldData, data[:len(oldData)]) { - t.Fatalf("tile %v not extending earlier tile %v", tile.Path(), old.Path()) - } - tiles[tile] = data - } - for _, tile := range NewTiles(testH, 0, i+1) { - data, err := ReadTileData(tile, storage) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(tiles[tile], data) { - t.Fatalf("mismatch at %+v", tile) - } - } - for _, tile := range NewTiles(testH, i/2, i+1) { - data, err := ReadTileData(tile, storage) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(tiles[tile], data) { - t.Fatalf("mismatch at %+v", tile) - } - } - - // Check that all the new hashes are readable from their tiles. - for j := oldStorage; j < len(storage); j++ { - tile := TileForIndex(testH, int64(j)) - data, ok := tiles[tile] - if !ok { - t.Log(NewTiles(testH, 0, i+1)) - t.Fatalf("TileForIndex(%d, %d) = %v, not yet stored (i=%d, stored %d)", testH, j, tile.Path(), i, len(storage)) - continue - } - h, err := HashFromTile(tile, data, int64(j)) - if err != nil { - t.Fatal(err) - } - if h != storage[j] { - t.Errorf("HashFromTile(%v, %d) = %v, want %v", tile.Path(), int64(j), h, storage[j]) - } - } - - trees = append(trees, th) - - // Check that leaf proofs work, for all trees and leaves so far. - for j := int64(0); j <= i; j++ { - p, err := ProveRecord(i+1, j, storage) - if err != nil { - t.Fatalf("ProveRecord(%d, %d): %v", i+1, j, err) - } - if err := CheckRecord(p, i+1, th, j, leafhashes[j]); err != nil { - t.Fatalf("CheckRecord(%d, %d): %v", i+1, j, err) - } - for k := range p { - p[k][0] ^= 1 - if err := CheckRecord(p, i+1, th, j, leafhashes[j]); err == nil { - t.Fatalf("CheckRecord(%d, %d) succeeded with corrupt proof hash #%d!", i+1, j, k) - } - p[k][0] ^= 1 - } - } - - // Check that leaf proofs work using TileReader. - // To prove a leaf that way, all you have to do is read and verify its hash. - storage := &testTilesStorage{m: tiles} - thr := TileHashReader(Tree{i + 1, th}, storage) - for j := int64(0); j <= i; j++ { - h, err := thr.ReadHashes([]int64{StoredHashIndex(0, j)}) - if err != nil { - t.Fatalf("TileHashReader(%d).ReadHashes(%d): %v", i+1, j, err) - } - if h[0] != leafhashes[j] { - t.Fatalf("TileHashReader(%d).ReadHashes(%d) returned wrong hash", i+1, j) - } - - // Even though reading the hash suffices, - // check we can generate the proof too. - p, err := ProveRecord(i+1, j, thr) - if err != nil { - t.Fatalf("ProveRecord(%d, %d, TileHashReader(%d)): %v", i+1, j, i+1, err) - } - if err := CheckRecord(p, i+1, th, j, leafhashes[j]); err != nil { - t.Fatalf("CheckRecord(%d, %d, TileHashReader(%d)): %v", i+1, j, i+1, err) - } - } - if storage.unsaved != 0 { - t.Fatalf("TileHashReader(%d) did not save %d tiles", i+1, storage.unsaved) - } - - // Check that ReadHashes will give an error if the index is not in the tree. - if _, err := thr.ReadHashes([]int64{(i + 1) * 2}); err == nil { - t.Fatalf("TileHashReader(%d).ReadHashes(%d) for index not in tree , want err", i, i+1) - } - if storage.unsaved != 0 { - t.Fatalf("TileHashReader(%d) did not save %d tiles", i+1, storage.unsaved) - } - - // Check that tree proofs work, for all trees so far, using TileReader. - // To prove a tree that way, all you have to do is compute and verify its hash. - for j := int64(0); j <= i; j++ { - h, err := TreeHash(j+1, thr) - if err != nil { - t.Fatalf("TreeHash(%d, TileHashReader(%d)): %v", j, i+1, err) - } - if h != trees[j] { - t.Fatalf("TreeHash(%d, TileHashReader(%d)) = %x, want %x (%v)", j, i+1, h[:], trees[j][:], trees[j]) - } - - // Even though computing the subtree hash suffices, - // check that we can generate the proof too. - p, err := ProveTree(i+1, j+1, thr) - if err != nil { - t.Fatalf("ProveTree(%d, %d): %v", i+1, j+1, err) - } - if err := CheckTree(p, i+1, th, j+1, trees[j]); err != nil { - t.Fatalf("CheckTree(%d, %d): %v [%v]", i+1, j+1, err, p) - } - for k := range p { - p[k][0] ^= 1 - if err := CheckTree(p, i+1, th, j+1, trees[j]); err == nil { - t.Fatalf("CheckTree(%d, %d) succeeded with corrupt proof hash #%d!", i+1, j+1, k) - } - p[k][0] ^= 1 - } - } - if storage.unsaved != 0 { - t.Fatalf("TileHashReader(%d) did not save %d tiles", i+1, storage.unsaved) - } - } -} - -func TestSplitStoredHashIndex(t *testing.T) { - for l := 0; l < 10; l++ { - for n := int64(0); n < 100; n++ { - x := StoredHashIndex(l, n) - l1, n1 := SplitStoredHashIndex(x) - if l1 != l || n1 != n { - t.Fatalf("StoredHashIndex(%d, %d) = %d, but SplitStoredHashIndex(%d) = %d, %d", l, n, x, x, l1, n1) - } - } - } -} - -// TODO(rsc): Test invalid paths too, like "tile/3/5/123/456/078". -var tilePaths = []struct { - path string - tile Tile -}{ - {"tile/4/0/001", Tile{4, 0, 1, 16}}, - {"tile/4/0/001.p/5", Tile{4, 0, 1, 5}}, - {"tile/3/5/x123/x456/078", Tile{3, 5, 123456078, 8}}, - {"tile/3/5/x123/x456/078.p/2", Tile{3, 5, 123456078, 2}}, - {"tile/1/0/x003/x057/500", Tile{1, 0, 3057500, 2}}, - {"tile/3/5/123/456/078", Tile{}}, - {"tile/3/-1/123/456/078", Tile{}}, - {"tile/1/data/x003/x057/500", Tile{1, -1, 3057500, 2}}, -} - -func TestTilePath(t *testing.T) { - for _, tt := range tilePaths { - if tt.tile.H > 0 { - p := tt.tile.Path() - if p != tt.path { - t.Errorf("%+v.Path() = %q, want %q", tt.tile, p, tt.path) - } - } - tile, err := ParseTilePath(tt.path) - if err != nil { - if tt.tile.H == 0 { - // Expected error. - continue - } - t.Errorf("ParseTilePath(%q): %v", tt.path, err) - } else if tile != tt.tile { - if tt.tile.H == 0 { - t.Errorf("ParseTilePath(%q): expected error, got %+v", tt.path, tt.tile) - continue - } - t.Errorf("ParseTilePath(%q) = %+v, want %+v", tt.path, tile, tt.tile) - } - } -} diff --git a/libgo/go/cmd/go/internal/vet/vet.go b/libgo/go/cmd/go/internal/vet/vet.go index 327b761c3cd..660a739fbbd 100644 --- a/libgo/go/cmd/go/internal/vet/vet.go +++ b/libgo/go/cmd/go/internal/vet/vet.go @@ -51,6 +51,7 @@ func runVet(cmd *base.Command, args []string) { work.BuildInit() work.VetFlags = vetFlags + work.VetExplicit = true if vetTool != "" { var err error work.VetTool, err = filepath.Abs(vetTool) diff --git a/libgo/go/cmd/go/internal/vet/vetflag.go b/libgo/go/cmd/go/internal/vet/vetflag.go index cbe7f8ce08c..e3de48bbffa 100644 --- a/libgo/go/cmd/go/internal/vet/vetflag.go +++ b/libgo/go/cmd/go/internal/vet/vetflag.go @@ -114,7 +114,7 @@ func vetFlags(usage func(), args []string) (passToVet, packageNames []string) { // Add build flags to vetFlagDefn. var cmd base.Command - work.AddBuildFlags(&cmd) + work.AddBuildFlags(&cmd, work.DefaultBuildFlags) // This flag declaration is a placeholder: // -vettool is actually parsed by the init function above. cmd.Flag.StringVar(new(string), "vettool", "", "path to vet tool binary") @@ -126,7 +126,8 @@ func vetFlags(usage func(), args []string) (passToVet, packageNames []string) { }) // Process args. - args = str.StringList(cmdflag.FindGOFLAGS(vetFlagDefn), args) + goflags := cmdflag.FindGOFLAGS(vetFlagDefn) + args = str.StringList(goflags, args) for i := 0; i < len(args); i++ { if !strings.HasPrefix(args[i], "-") { return args[:i], args[i:] @@ -139,6 +140,9 @@ func vetFlags(usage func(), args []string) (passToVet, packageNames []string) { base.SetExitStatus(2) base.Exit() } + if i < len(goflags) { + f.Present = false // Not actually present on the command line. + } if f.Value != nil { if err := f.Value.Set(value); err != nil { base.Fatalf("invalid flag argument for -%s: %v", f.Name, err) diff --git a/libgo/go/cmd/go/internal/web/api.go b/libgo/go/cmd/go/internal/web/api.go index cd0e19d3ffd..ad99eb2f8c3 100644 --- a/libgo/go/cmd/go/internal/web/api.go +++ b/libgo/go/cmd/go/internal/web/api.go @@ -10,12 +10,15 @@ package web import ( + "bytes" "fmt" "io" "io/ioutil" "net/url" "os" "strings" + "unicode" + "unicode/utf8" ) // SecurityMode specifies whether a function should make network @@ -34,9 +37,32 @@ type HTTPError struct { URL string // redacted Status string StatusCode int + Err error // underlying error, if known + Detail string // limited to maxErrorDetailLines and maxErrorDetailBytes } +const ( + maxErrorDetailLines = 8 + maxErrorDetailBytes = maxErrorDetailLines * 81 +) + func (e *HTTPError) Error() string { + if e.Detail != "" { + detailSep := " " + if strings.ContainsRune(e.Detail, '\n') { + detailSep = "\n\t" + } + return fmt.Sprintf("reading %s: %v\n\tserver response:%s%s", e.URL, e.Status, detailSep, e.Detail) + } + + if err := e.Err; err != nil { + if pErr, ok := e.Err.(*os.PathError); ok && strings.HasSuffix(e.URL, pErr.Path) { + // Remove the redundant copy of the path. + err = pErr.Err + } + return fmt.Sprintf("reading %s: %v", e.URL, err) + } + return fmt.Sprintf("reading %s: %v", e.URL, e.Status) } @@ -44,6 +70,10 @@ func (e *HTTPError) Is(target error) bool { return target == os.ErrNotExist && (e.StatusCode == 404 || e.StatusCode == 410) } +func (e *HTTPError) Unwrap() error { + return e.Err +} + // GetBytes returns the body of the requested resource, or an error if the // response status was not http.StatusOK. // @@ -69,16 +99,69 @@ type Response struct { Status string StatusCode int Header map[string][]string - Body io.ReadCloser + Body io.ReadCloser // Either the original body or &errorDetail. + + fileErr error + errorDetail errorDetailBuffer } // Err returns an *HTTPError corresponding to the response r. -// It returns nil if the response r has StatusCode 200 or 0 (unset). +// If the response r has StatusCode 200 or 0 (unset), Err returns nil. +// Otherwise, Err may read from r.Body in order to extract relevant error detail. func (r *Response) Err() error { if r.StatusCode == 200 || r.StatusCode == 0 { return nil } - return &HTTPError{URL: r.URL, Status: r.Status, StatusCode: r.StatusCode} + + return &HTTPError{ + URL: r.URL, + Status: r.Status, + StatusCode: r.StatusCode, + Err: r.fileErr, + Detail: r.formatErrorDetail(), + } +} + +// formatErrorDetail converts r.errorDetail (a prefix of the output of r.Body) +// into a short, tab-indented summary. +func (r *Response) formatErrorDetail() string { + if r.Body != &r.errorDetail { + return "" // Error detail collection not enabled. + } + + // Ensure that r.errorDetail has been populated. + _, _ = io.Copy(ioutil.Discard, r.Body) + + s := r.errorDetail.buf.String() + if !utf8.ValidString(s) { + return "" // Don't try to recover non-UTF-8 error messages. + } + for _, r := range s { + if !unicode.IsGraphic(r) && !unicode.IsSpace(r) { + return "" // Don't let the server do any funny business with the user's terminal. + } + } + + var detail strings.Builder + for i, line := range strings.Split(s, "\n") { + if strings.TrimSpace(line) == "" { + break // Stop at the first blank line. + } + if i > 0 { + detail.WriteString("\n\t") + } + if i >= maxErrorDetailLines { + detail.WriteString("[Truncated: too many lines.]") + break + } + if detail.Len()+len(line) > maxErrorDetailBytes { + detail.WriteString("[Truncated: too long.]") + break + } + detail.WriteString(line) + } + + return detail.String() } // Get returns the body of the HTTP or HTTPS resource specified at the given URL. @@ -131,3 +214,39 @@ func Join(u *url.URL, path string) *url.URL { j.RawPath = strings.TrimSuffix(u.RawPath, "/") + "/" + strings.TrimPrefix(path, "/") return &j } + +// An errorDetailBuffer is an io.ReadCloser that copies up to +// maxErrorDetailLines into a buffer for later inspection. +type errorDetailBuffer struct { + r io.ReadCloser + buf strings.Builder + bufLines int +} + +func (b *errorDetailBuffer) Close() error { + return b.r.Close() +} + +func (b *errorDetailBuffer) Read(p []byte) (n int, err error) { + n, err = b.r.Read(p) + + // Copy the first maxErrorDetailLines+1 lines into b.buf, + // discarding any further lines. + // + // Note that the read may begin or end in the middle of a UTF-8 character, + // so don't try to do anything fancy with characters that encode to larger + // than one byte. + if b.bufLines <= maxErrorDetailLines { + for _, line := range bytes.SplitAfterN(p[:n], []byte("\n"), maxErrorDetailLines-b.bufLines) { + b.buf.Write(line) + if len(line) > 0 && line[len(line)-1] == '\n' { + b.bufLines++ + if b.bufLines > maxErrorDetailLines { + break + } + } + } + } + + return n, err +} diff --git a/libgo/go/cmd/go/internal/web/file_test.go b/libgo/go/cmd/go/internal/web/file_test.go index e31ad71d4d9..63394690453 100644 --- a/libgo/go/cmd/go/internal/web/file_test.go +++ b/libgo/go/cmd/go/internal/web/file_test.go @@ -19,6 +19,8 @@ func TestGetFileURL(t *testing.T) { if err != nil { t.Fatal(err) } + defer os.Remove(f.Name()) + if _, err := f.WriteString(content); err != nil { t.Error(err) } diff --git a/libgo/go/cmd/go/internal/web/http.go b/libgo/go/cmd/go/internal/web/http.go index b790fe9916e..5e4319b00e9 100644 --- a/libgo/go/cmd/go/internal/web/http.go +++ b/libgo/go/cmd/go/internal/web/http.go @@ -14,7 +14,7 @@ package web import ( "crypto/tls" "fmt" - "io/ioutil" + "mime" "net/http" urlpkg "net/url" "os" @@ -64,7 +64,7 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { Status: "404 testing", StatusCode: 404, Header: make(map[string][]string), - Body: ioutil.NopCloser(strings.NewReader("")), + Body: http.NoBody, } if cfg.BuildX { fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", Redacted(url), res.Status, time.Since(start).Seconds()) @@ -111,7 +111,7 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { fetched, res, err = fetch(secure) if err != nil { if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: %v\n", Redacted(url), err) + fmt.Fprintf(os.Stderr, "# get %s: %v\n", Redacted(secure), err) } if security != Insecure || url.Scheme == "https" { // HTTPS failed, and we can't fall back to plain HTTP. @@ -146,7 +146,7 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { insecure.Scheme = "http" if insecure.User != nil && security != Insecure { if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: insecure credentials\n", Redacted(url)) + fmt.Fprintf(os.Stderr, "# get %s: insecure credentials\n", Redacted(insecure)) } return nil, fmt.Errorf("refusing to pass credentials to insecure URL: %s", Redacted(insecure)) } @@ -154,7 +154,7 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { fetched, res, err = fetch(insecure) if err != nil { if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: %v\n", Redacted(url), err) + fmt.Fprintf(os.Stderr, "# get %s: %v\n", Redacted(insecure), err) } // HTTP failed, and we already tried HTTPS if applicable. // Report the error from the HTTP attempt. @@ -165,8 +165,9 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { // Note: accepting a non-200 OK here, so people can serve a // meta import in their http 404 page. if cfg.BuildX { - fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", Redacted(url), res.Status, time.Since(start).Seconds()) + fmt.Fprintf(os.Stderr, "# get %s: %v (%.3fs)\n", Redacted(fetched), res.Status, time.Since(start).Seconds()) } + r := &Response{ URL: Redacted(fetched), Status: res.Status, @@ -174,6 +175,20 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { Header: map[string][]string(res.Header), Body: res.Body, } + + if res.StatusCode != http.StatusOK { + contentType := res.Header.Get("Content-Type") + if mediaType, params, _ := mime.ParseMediaType(contentType); mediaType == "text/plain" { + switch charset := strings.ToLower(params["charset"]); charset { + case "us-ascii", "utf-8", "": + // Body claims to be plain text in UTF-8 or a subset thereof. + // Try to extract a useful error message from it. + r.errorDetail.r = res.Body + r.Body = &r.errorDetail + } + } + } + return r, nil } @@ -190,6 +205,7 @@ func getFile(u *urlpkg.URL) (*Response, error) { Status: http.StatusText(http.StatusNotFound), StatusCode: http.StatusNotFound, Body: http.NoBody, + fileErr: err, }, nil } @@ -199,6 +215,7 @@ func getFile(u *urlpkg.URL) (*Response, error) { Status: http.StatusText(http.StatusForbidden), StatusCode: http.StatusForbidden, Body: http.NoBody, + fileErr: err, }, nil } diff --git a/libgo/go/cmd/go/internal/web/url_other.go b/libgo/go/cmd/go/internal/web/url_other.go index bd243e591a9..2641ee62bfa 100644 --- a/libgo/go/cmd/go/internal/web/url_other.go +++ b/libgo/go/cmd/go/internal/web/url_other.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build !windows +// +build !windows package web diff --git a/libgo/go/cmd/go/internal/web/url_other_test.go b/libgo/go/cmd/go/internal/web/url_other_test.go index b4a74d94b93..aa5663355ef 100644 --- a/libgo/go/cmd/go/internal/web/url_other_test.go +++ b/libgo/go/cmd/go/internal/web/url_other_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build !windows +// +build !windows package web diff --git a/libgo/go/cmd/go/internal/work/action.go b/libgo/go/cmd/go/internal/work/action.go index eabac6bd14e..db422fd9935 100644 --- a/libgo/go/cmd/go/internal/work/action.go +++ b/libgo/go/cmd/go/internal/work/action.go @@ -291,11 +291,12 @@ func (b *Builder) Init() { } } - if _, ok := cfg.OSArchSupportsCgo[cfg.Goos+"/"+cfg.Goarch]; !ok && cfg.BuildContext.Compiler == "gc" { - fmt.Fprintf(os.Stderr, "cmd/go: unsupported GOOS/GOARCH pair %s/%s\n", cfg.Goos, cfg.Goarch) + if err := CheckGOOSARCHPair(cfg.Goos, cfg.Goarch); err != nil { + fmt.Fprintf(os.Stderr, "cmd/go: %v\n", err) base.SetExitStatus(2) base.Exit() } + for _, tag := range cfg.BuildContext.BuildTags { if strings.Contains(tag, ",") { fmt.Fprintf(os.Stderr, "cmd/go: -tags space-separated list contains comma\n") @@ -305,6 +306,13 @@ func (b *Builder) Init() { } } +func CheckGOOSARCHPair(goos, goarch string) error { + if _, ok := cfg.OSArchSupportsCgo[goos+"/"+goarch]; !ok && cfg.BuildContext.Compiler == "gc" { + return fmt.Errorf("unsupported GOOS/GOARCH pair %s/%s", goos, goarch) + } + return nil +} + // NewObjdir returns the name of a fresh object directory under b.WorkDir. // It is up to the caller to call b.Mkdir on the result at an appropriate time. // The result ends in a slash, so that file names in that directory @@ -707,7 +715,7 @@ func (b *Builder) addInstallHeaderAction(a *Action) { } // buildmodeShared takes the "go build" action a1 into the building of a shared library of a1.Deps. -// That is, the input a1 represents "go build pkgs" and the result represents "go build -buidmode=shared pkgs". +// That is, the input a1 represents "go build pkgs" and the result represents "go build -buildmode=shared pkgs". func (b *Builder) buildmodeShared(mode, depMode BuildMode, args []string, pkgs []*load.Package, a1 *Action) *Action { name, err := libname(args, pkgs) if err != nil { diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go index 9305b2d859c..e3b25c937c3 100644 --- a/libgo/go/cmd/go/internal/work/build.go +++ b/libgo/go/cmd/go/internal/work/build.go @@ -62,11 +62,13 @@ and test commands: The default is the number of CPUs available. -race enable data race detection. - Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64. + Supported only on linux/amd64, freebsd/amd64, darwin/amd64, windows/amd64, + linux/ppc64le and linux/arm64 (only for 48-bit VMA). -msan enable interoperation with memory sanitizer. Supported only on linux/amd64, linux/arm64 and only with Clang/LLVM as the host C compiler. + On linux/arm64, pie build mode will be used. -v print the names of packages as they are compiled. -work @@ -95,11 +97,21 @@ and test commands: -ldflags '[pattern=]arg list' arguments to pass on each go tool link invocation. -linkshared - link against shared libraries previously created with - -buildmode=shared. + build code that will be linked against shared libraries previously + created with -buildmode=shared. -mod mode - module download mode to use: readonly or vendor. + module download mode to use: readonly, vendor, or mod. See 'go help modules' for more. + -modcacherw + leave newly-created directories in the module cache read-write + instead of making them read-only. + -modfile file + in module aware mode, read (and possibly write) an alternate go.mod + file instead of the one in the module root directory. A file named + "go.mod" must still be present in order to determine the module root + directory, but it is not accessed. When -modfile is specified, an + alternate go.sum file is also used: its path is derived from the + -modfile flag by trimming the ".mod" extension and appending ".sum". -pkgdir dir install and load all packages from dir instead of the usual locations. For example, when building with a non-standard configuration, @@ -165,8 +177,8 @@ func init() { CmdInstall.Flag.BoolVar(&cfg.BuildI, "i", false, "") - AddBuildFlags(CmdBuild) - AddBuildFlags(CmdInstall) + AddBuildFlags(CmdBuild, DefaultBuildFlags) + AddBuildFlags(CmdInstall, DefaultBuildFlags) } // Note that flags consulted by other parts of the code @@ -214,9 +226,17 @@ func init() { } } -// addBuildFlags adds the flags common to the build, clean, get, +type BuildFlagMask int + +const ( + DefaultBuildFlags BuildFlagMask = 0 + OmitModFlag BuildFlagMask = 1 << iota + OmitModCommonFlags +) + +// AddBuildFlags adds the flags common to the build, clean, get, // install, list, run, and test commands. -func AddBuildFlags(cmd *base.Command) { +func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "") cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "") cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "") @@ -228,7 +248,12 @@ func AddBuildFlags(cmd *base.Command) { cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "") cmd.Flag.Var(&load.BuildGcflags, "gcflags", "") cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "") - cmd.Flag.StringVar(&cfg.BuildMod, "mod", "", "") + if mask&OmitModFlag == 0 { + cmd.Flag.StringVar(&cfg.BuildMod, "mod", "", "") + } + if mask&OmitModCommonFlags == 0 { + AddModCommonFlags(cmd) + } cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "") cmd.Flag.Var(&load.BuildLdflags, "ldflags", "") cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "") @@ -244,6 +269,13 @@ func AddBuildFlags(cmd *base.Command) { cmd.Flag.StringVar(&cfg.DebugActiongraph, "debug-actiongraph", "", "") } +// AddModCommonFlags adds the module-related flags common to build commands +// and 'go mod' subcommands. +func AddModCommonFlags(cmd *base.Command) { + cmd.Flag.BoolVar(&cfg.ModCacheRW, "modcacherw", false, "") + cmd.Flag.StringVar(&cfg.ModFile, "modfile", "", "") +} + // tagsFlag is the implementation of the -tags flag. type tagsFlag []string @@ -318,7 +350,7 @@ func runBuild(cmd *base.Command, args []string) { explicitO := len(cfg.BuildO) > 0 if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" { - cfg.BuildO = load.DefaultExecName(pkgs[0].ImportPath) + cfg.BuildO = pkgs[0].DefaultExecName() cfg.BuildO += cfg.ExeSuffix } @@ -362,7 +394,8 @@ func runBuild(cmd *base.Command, args []string) { if p.Name != "main" { continue } - p.Target = filepath.Join(cfg.BuildO, load.DefaultExecName(p.ImportPath)) + + p.Target = filepath.Join(cfg.BuildO, p.DefaultExecName()) p.Target += cfg.ExeSuffix p.Stale = true p.StaleReason = "build -o flag in use" @@ -584,7 +617,7 @@ func InstallPackages(patterns []string, pkgs []*load.Package) { if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" { // Compute file 'go build' would have created. // If it exists and is an executable file, remove it. - targ := load.DefaultExecName(pkgs[0].ImportPath) + targ := pkgs[0].DefaultExecName() targ += cfg.ExeSuffix if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory fi, err := os.Stat(targ) diff --git a/libgo/go/cmd/go/internal/work/build_test.go b/libgo/go/cmd/go/internal/work/build_test.go index 55e1eea25ba..b60f4e27c04 100644 --- a/libgo/go/cmd/go/internal/work/build_test.go +++ b/libgo/go/cmd/go/internal/work/build_test.go @@ -221,8 +221,6 @@ func pkgImportPath(pkgpath string) *load.Package { // See https://golang.org/issue/18878. func TestRespectSetgidDir(t *testing.T) { switch runtime.GOOS { - case "nacl": - t.Skip("can't set SetGID bit with chmod on nacl") case "darwin": if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { t.Skip("can't set SetGID bit with chmod on iOS") diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index 27bde8c6151..7558a3091aa 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -15,7 +15,6 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cache" "cmd/go/internal/cfg" - "cmd/go/internal/load" "cmd/go/internal/str" "cmd/internal/buildid" ) @@ -421,7 +420,7 @@ func (b *Builder) fileHash(file string) string { // during a's work. The caller should defer b.flushOutput(a), to make sure // that flushOutput is eventually called regardless of whether the action // succeeds. The flushOutput call must happen after updateBuildID. -func (b *Builder) useCache(a *Action, p *load.Package, actionHash cache.ActionID, target string) bool { +func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string) bool { // The second half of the build ID here is a placeholder for the content hash. // It's important that the overall buildID be unlikely verging on impossible // to appear in the output by chance, but that should be taken care of by diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index c666026213b..ba81543fdf7 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -54,8 +54,9 @@ func actionList(root *Action) []*Action { // do runs the action graph rooted at root. func (b *Builder) Do(root *Action) { - if c := cache.Default(); c != nil && !b.IsCmdList { + if !b.IsCmdList { // If we're doing real work, take time at the end to trim the cache. + c := cache.Default() defer c.Trim() } @@ -200,13 +201,17 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { // same compiler settings and can reuse each other's results. // If not, the reason is already recorded in buildGcflags. fmt.Fprintf(h, "compile\n") + // Only include the package directory if it may affect the output. + // We trim workspace paths for all packages when -trimpath is set. // The compiler hides the exact value of $GOROOT - // when building things in GOROOT, - // but it does not hide the exact value of $GOPATH. - // Include the full dir in that case. + // when building things in GOROOT. // Assume b.WorkDir is being trimmed properly. - if !p.Goroot && !strings.HasPrefix(p.Dir, b.WorkDir) { + // When -trimpath is used with a package built from the module cache, + // use the module path and version instead of the directory. + if !p.Goroot && !cfg.BuildTrimpath && !strings.HasPrefix(p.Dir, b.WorkDir) { fmt.Fprintf(h, "dir %s\n", p.Dir) + } else if cfg.BuildTrimpath && p.Module != nil { + fmt.Fprintf(h, "module %s@%s\n", p.Module.Path, p.Module.Version) } fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch) fmt.Fprintf(h, "import %q\n", p.ImportPath) @@ -394,7 +399,7 @@ func (b *Builder) build(a *Action) (err error) { bit(needCompiledGoFiles, b.NeedCompiledGoFiles) if !p.BinaryOnly { - if b.useCache(a, p, b.buildActionID(a), p.Target) { + if b.useCache(a, b.buildActionID(a), p.Target) { // We found the main output in the cache. // If we don't need any other outputs, we can stop. // Otherwise, we need to write files to a.Objdir (needVet, needCgoHdr). @@ -406,15 +411,19 @@ func (b *Builder) build(a *Action) (err error) { if b.NeedExport { p.Export = a.built } - if need&needCompiledGoFiles != 0 && b.loadCachedSrcFiles(a) { - need &^= needCompiledGoFiles + if need&needCompiledGoFiles != 0 { + if err := b.loadCachedSrcFiles(a); err == nil { + need &^= needCompiledGoFiles + } } } // Source files might be cached, even if the full action is not // (e.g., go list -compiled -find). - if !cachedBuild && need&needCompiledGoFiles != 0 && b.loadCachedSrcFiles(a) { - need &^= needCompiledGoFiles + if !cachedBuild && need&needCompiledGoFiles != 0 { + if err := b.loadCachedSrcFiles(a); err == nil { + need &^= needCompiledGoFiles + } } if need == 0 { @@ -428,7 +437,7 @@ func (b *Builder) build(a *Action) (err error) { err = fmt.Errorf("go build %s: %v", a.Package.ImportPath, err) } if err != nil && b.IsCmdList && b.NeedError && p.Error == nil { - p.Error = &load.PackageError{Err: err.Error()} + p.Error = &load.PackageError{Err: err} } }() if cfg.BuildN { @@ -459,16 +468,20 @@ func (b *Builder) build(a *Action) (err error) { objdir := a.Objdir // Load cached cgo header, but only if we're skipping the main build (cachedBuild==true). - if cachedBuild && need&needCgoHdr != 0 && b.loadCachedCgoHdr(a) { - need &^= needCgoHdr + if cachedBuild && need&needCgoHdr != 0 { + if err := b.loadCachedCgoHdr(a); err == nil { + need &^= needCgoHdr + } } // Load cached vet config, but only if that's all we have left // (need == needVet, not testing just the one bit). // If we are going to do a full build anyway, // we're going to regenerate the files below anyway. - if need == needVet && b.loadCachedVet(a) { - need &^= needVet + if need == needVet { + if err := b.loadCachedVet(a); err == nil { + need &^= needVet + } } if need == 0 { return nil @@ -615,8 +628,8 @@ func (b *Builder) build(a *Action) (err error) { need &^= needVet } if need&needCompiledGoFiles != 0 { - if !b.loadCachedSrcFiles(a) { - return fmt.Errorf("failed to cache compiled Go files") + if err := b.loadCachedSrcFiles(a); err != nil { + return fmt.Errorf("loading compiled Go files from cache: %w", err) } need &^= needCompiledGoFiles } @@ -656,7 +669,7 @@ func (b *Builder) build(a *Action) (err error) { } if p.Internal.BuildInfo != "" && cfg.ModulesEnabled { - if err := b.writeFile(objdir+"_gomod_.go", load.ModInfoProg(p.Internal.BuildInfo)); err != nil { + if err := b.writeFile(objdir+"_gomod_.go", load.ModInfoProg(p.Internal.BuildInfo, cfg.BuildToolchainName == "gccgo")); err != nil { return err } gofiles = append(gofiles, objdir+"_gomod_.go") @@ -790,7 +803,7 @@ func (b *Builder) cacheObjdirFile(a *Action, c *cache.Cache, name string) error func (b *Builder) findCachedObjdirFile(a *Action, c *cache.Cache, name string) (string, error) { file, _, err := c.GetFile(cache.Subkey(a.actionID, name)) if err != nil { - return "", err + return "", fmt.Errorf("loading cached file %s: %w", name, err) } return file, nil } @@ -805,26 +818,16 @@ func (b *Builder) loadCachedObjdirFile(a *Action, c *cache.Cache, name string) e func (b *Builder) cacheCgoHdr(a *Action) { c := cache.Default() - if c == nil { - return - } b.cacheObjdirFile(a, c, "_cgo_install.h") } -func (b *Builder) loadCachedCgoHdr(a *Action) bool { +func (b *Builder) loadCachedCgoHdr(a *Action) error { c := cache.Default() - if c == nil { - return false - } - err := b.loadCachedObjdirFile(a, c, "_cgo_install.h") - return err == nil + return b.loadCachedObjdirFile(a, c, "_cgo_install.h") } func (b *Builder) cacheSrcFiles(a *Action, srcfiles []string) { c := cache.Default() - if c == nil { - return - } var buf bytes.Buffer for _, file := range srcfiles { if !strings.HasPrefix(file, a.Objdir) { @@ -844,14 +847,11 @@ func (b *Builder) cacheSrcFiles(a *Action, srcfiles []string) { c.PutBytes(cache.Subkey(a.actionID, "srcfiles"), buf.Bytes()) } -func (b *Builder) loadCachedVet(a *Action) bool { +func (b *Builder) loadCachedVet(a *Action) error { c := cache.Default() - if c == nil { - return false - } list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles")) if err != nil { - return false + return fmt.Errorf("reading srcfiles list: %w", err) } var srcfiles []string for _, name := range strings.Split(string(list), "\n") { @@ -863,22 +863,19 @@ func (b *Builder) loadCachedVet(a *Action) bool { continue } if err := b.loadCachedObjdirFile(a, c, name); err != nil { - return false + return err } srcfiles = append(srcfiles, a.Objdir+name) } buildVetConfig(a, srcfiles) - return true + return nil } -func (b *Builder) loadCachedSrcFiles(a *Action) bool { +func (b *Builder) loadCachedSrcFiles(a *Action) error { c := cache.Default() - if c == nil { - return false - } list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles")) if err != nil { - return false + return fmt.Errorf("reading srcfiles list: %w", err) } var files []string for _, name := range strings.Split(string(list), "\n") { @@ -891,12 +888,12 @@ func (b *Builder) loadCachedSrcFiles(a *Action) bool { } file, err := b.findCachedObjdirFile(a, c, name) if err != nil { - return false + return fmt.Errorf("finding %s: %w", name, err) } files = append(files, file) } a.Package.CompiledGoFiles = files - return true + return nil } // vetConfig is the configuration passed to vet describing a single package. @@ -1032,7 +1029,7 @@ func (b *Builder) vet(a *Action) error { // dependency tree turn on *more* analysis, as here. // (The unsafeptr check does not write any facts for use by // later vet runs.) - if a.Package.Goroot && !VetExplicit { + if a.Package.Goroot && !VetExplicit && VetTool == "" { // Note that $GOROOT/src/buildall.bash // does the same for the misc-compile trybots // and should be updated if these flags are @@ -1060,12 +1057,11 @@ func (b *Builder) vet(a *Action) error { } key := cache.ActionID(h.Sum()) - if vcfg.VetxOnly { - if c := cache.Default(); c != nil && !cfg.BuildA { - if file, _, err := c.GetFile(key); err == nil { - a.built = file - return nil - } + if vcfg.VetxOnly && !cfg.BuildA { + c := cache.Default() + if file, _, err := c.GetFile(key); err == nil { + a.built = file + return nil } } @@ -1093,9 +1089,7 @@ func (b *Builder) vet(a *Action) error { // If vet wrote export data, save it for input to future vets. if f, err := os.Open(vcfg.VetxOutput); err == nil { a.built = vcfg.VetxOutput - if c := cache.Default(); c != nil { - c.Put(key, f) - } + cache.Default().Put(key, f) f.Close() } @@ -1183,7 +1177,7 @@ func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) { // link is the action for linking a single command. // Note that any new influence on this logic must be reported in b.linkActionID above as well. func (b *Builder) link(a *Action) (err error) { - if b.useCache(a, a.Package, b.linkActionID(a), a.Package.Target) || b.IsCmdList { + if b.useCache(a, b.linkActionID(a), a.Package.Target) || b.IsCmdList { return nil } defer b.flushOutput(a) @@ -1416,7 +1410,7 @@ func (b *Builder) linkSharedActionID(a *Action) cache.ActionID { } func (b *Builder) linkShared(a *Action) (err error) { - if b.useCache(a, nil, b.linkSharedActionID(a), a.Target) || b.IsCmdList { + if b.useCache(a, b.linkSharedActionID(a), a.Target) || b.IsCmdList { return nil } defer b.flushOutput(a) @@ -1622,12 +1616,12 @@ func (b *Builder) copyFile(dst, src string, perm os.FileMode, force bool) error // Be careful about removing/overwriting dst. // Do not remove/overwrite if dst exists and is a directory - // or a non-object file. + // or a non-empty non-object file. if fi, err := os.Stat(dst); err == nil { if fi.IsDir() { return fmt.Errorf("build output %q already exists and is a directory", dst) } - if !force && fi.Mode().IsRegular() && !isObject(dst) { + if !force && fi.Mode().IsRegular() && fi.Size() != 0 && !isObject(dst) { return fmt.Errorf("build output %q already exists and is not an object file", dst) } } @@ -1652,7 +1646,7 @@ func (b *Builder) copyFile(dst, src string, perm os.FileMode, force bool) error df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) } if err != nil { - return err + return fmt.Errorf("copying %s: %w", src, err) // err should already refer to dst } _, err = io.Copy(df, sf) @@ -1782,6 +1776,11 @@ func (b *Builder) fmtcmd(dir string, format string, args ...interface{}) string } if b.WorkDir != "" { cmd = strings.ReplaceAll(cmd, b.WorkDir, "$WORK") + escaped := strconv.Quote(b.WorkDir) + escaped = escaped[1 : len(escaped)-1] // strip quote characters + if escaped != b.WorkDir { + cmd = strings.ReplaceAll(cmd, escaped, "$WORK") + } } return cmd } @@ -2408,7 +2407,7 @@ func (b *Builder) gccArchArgs() []string { switch cfg.Goarch { case "386": return []string{"-m32"} - case "amd64", "amd64p32": + case "amd64": return []string{"-m64"} case "arm": return []string{"-marm"} // not thumb diff --git a/libgo/go/cmd/go/internal/work/gc.go b/libgo/go/cmd/go/internal/work/gc.go index 86322946a61..57024694cf6 100644 --- a/libgo/go/cmd/go/internal/work/gc.go +++ b/libgo/go/cmd/go/internal/work/gc.go @@ -92,8 +92,7 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s if a.buildID != "" { gcargs = append(gcargs, "-buildid", a.buildID) } - platform := cfg.Goos + "/" + cfg.Goarch - if p.Internal.OmitDebug || platform == "nacl/amd64p32" || cfg.Goos == "plan9" || cfg.Goarch == "wasm" { + if p.Internal.OmitDebug || cfg.Goos == "plan9" || cfg.Goarch == "wasm" { gcargs = append(gcargs, "-dwarf=false") } if strings.HasPrefix(runtimeVersion, "go1") && !strings.Contains(os.Args[0], "go_bootstrap") { diff --git a/libgo/go/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go index 87b3f5facd9..f6fa17da85c 100644 --- a/libgo/go/cmd/go/internal/work/gccgo.go +++ b/libgo/go/cmd/go/internal/work/gccgo.go @@ -91,6 +91,10 @@ func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg args = append(args, "-I", root) } } + if cfg.BuildTrimpath && b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") { + args = append(args, "-ffile-prefix-map="+base.Cwd+"=.") + args = append(args, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build") + } args = append(args, a.Package.Internal.Gccgoflags...) for _, f := range gofiles { args = append(args, mkAbs(p.Dir, f)) @@ -354,7 +358,7 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string } if haveShlib[filepath.Base(a.Target)] { - // This is a shared library we want to link againt. + // This is a shared library we want to link against. if !addedShlib[a.Target] { shlibs = append(shlibs, a.Target) addedShlib[a.Target] = true @@ -560,7 +564,10 @@ func (tools gccgoToolchain) cc(b *Builder, a *Action, ofile, cfile string) error defs = append(defs, "-fsplit-stack") } defs = tools.maybePIC(defs) - if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") { + if b.gccSupportsFlag(compiler, "-ffile-prefix-map=a=b") { + defs = append(defs, "-ffile-prefix-map="+base.Cwd+"=.") + defs = append(defs, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build") + } else if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") { defs = append(defs, "-fdebug-prefix-map="+b.WorkDir+"=/tmp/go-build") } if b.gccSupportsFlag(compiler, "-gno-record-gcc-switches") { diff --git a/libgo/go/cmd/go/internal/work/init.go b/libgo/go/cmd/go/internal/work/init.go index 35d3a505cc7..9091f986368 100644 --- a/libgo/go/cmd/go/internal/work/init.go +++ b/libgo/go/cmd/go/internal/work/init.go @@ -60,6 +60,11 @@ func instrumentInit() { mode := "race" if cfg.BuildMSan { mode = "msan" + // MSAN does not support non-PIE binaries on ARM64. + // See issue #33712 for details. + if cfg.Goos == "linux" && cfg.Goarch == "arm64" && cfg.BuildBuildmode == "default" { + cfg.BuildBuildmode = "pie" + } } modeFlag := "-" + mode @@ -81,7 +86,11 @@ func instrumentInit() { func buildModeInit() { gccgo := cfg.BuildToolchainName == "gccgo" var codegenArg string - platform := cfg.Goos + "/" + cfg.Goarch + + // Configure the build mode first, then verify that it is supported. + // That way, if the flag is completely bogus we will prefer to error out with + // "-buildmode=%s not supported" instead of naming the specific platform. + switch cfg.BuildBuildmode { case "archive": pkgsFilter = pkgsNotMain @@ -90,20 +99,18 @@ func buildModeInit() { if gccgo { codegenArg = "-fPIC" } else { - switch platform { - case "darwin/arm", "darwin/arm64": - codegenArg = "-shared" - default: - switch cfg.Goos { - case "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris": - if platform == "linux/ppc64" { - base.Fatalf("-buildmode=c-archive not supported on %s\n", platform) - } - // Use -shared so that the result is - // suitable for inclusion in a PIE or - // shared library. + switch cfg.Goos { + case "darwin": + switch cfg.Goarch { + case "arm", "arm64": codegenArg = "-shared" } + + case "dragonfly", "freebsd", "illumos", "linux", "netbsd", "openbsd", "solaris": + // Use -shared so that the result is + // suitable for inclusion in a PIE or + // shared library. + codegenArg = "-shared" } } cfg.ExeSuffix = ".a" @@ -113,27 +120,25 @@ func buildModeInit() { if gccgo { codegenArg = "-fPIC" } else { - switch platform { - case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/s390x", - "android/amd64", "android/arm", "android/arm64", "android/386", - "freebsd/amd64": + switch cfg.Goos { + case "linux", "android", "freebsd": codegenArg = "-shared" - case "darwin/amd64", "darwin/386": - case "windows/amd64", "windows/386": + case "windows": // Do not add usual .exe suffix to the .dll file. cfg.ExeSuffix = "" - default: - base.Fatalf("-buildmode=c-shared not supported on %s\n", platform) } } ldBuildmode = "c-shared" case "default": - switch platform { - case "android/arm", "android/arm64", "android/amd64", "android/386": + switch cfg.Goos { + case "android": codegenArg = "-shared" ldBuildmode = "pie" - case "darwin/arm", "darwin/arm64": - codegenArg = "-shared" + case "darwin": + switch cfg.Goarch { + case "arm", "arm64": + codegenArg = "-shared" + } fallthrough default: ldBuildmode = "exe" @@ -156,18 +161,8 @@ func buildModeInit() { } if gccgo { codegenArg = "-fPIE" - } else { - switch platform { - case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", - "android/amd64", "android/arm", "android/arm64", "android/386", - "freebsd/amd64": - codegenArg = "-shared" - case "darwin/amd64": - codegenArg = "-shared" - case "aix/ppc64": - default: - base.Fatalf("-buildmode=pie not supported on %s\n", platform) - } + } else if cfg.Goos != "aix" { + codegenArg = "-shared" } ldBuildmode = "pie" case "shared": @@ -175,11 +170,6 @@ func buildModeInit() { if gccgo { codegenArg = "-fPIC" } else { - switch platform { - case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x": - default: - base.Fatalf("-buildmode=shared not supported on %s\n", platform) - } codegenArg = "-dynlink" } if cfg.BuildO != "" { @@ -191,15 +181,6 @@ func buildModeInit() { if gccgo { codegenArg = "-fPIC" } else { - switch platform { - case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", - "android/amd64", "android/arm", "android/arm64", "android/386": - case "darwin/amd64": - // Skip DWARF generation due to #21647 - forcedLdflags = append(forcedLdflags, "-w") - default: - base.Fatalf("-buildmode=plugin not supported on %s\n", platform) - } codegenArg = "-dynlink" } cfg.ExeSuffix = ".so" @@ -207,17 +188,21 @@ func buildModeInit() { default: base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode) } + + if !sys.BuildModeSupported(cfg.BuildToolchainName, cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) { + base.Fatalf("-buildmode=%s not supported on %s/%s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) + } + if cfg.BuildLinkshared { + if !sys.BuildModeSupported(cfg.BuildToolchainName, "shared", cfg.Goos, cfg.Goarch) { + base.Fatalf("-linkshared not supported on %s/%s\n", cfg.Goos, cfg.Goarch) + } if gccgo { codegenArg = "-fPIC" } else { - switch platform { - case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x": - forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1") - default: - base.Fatalf("-linkshared not supported on %s\n", platform) - } + forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1") codegenArg = "-dynlink" + forcedGcflags = append(forcedGcflags, "-linkshared") // TODO(mwhudson): remove -w when that gets fixed in linker. forcedLdflags = append(forcedLdflags, "-linkshared", "-w") } @@ -241,12 +226,20 @@ func buildModeInit() { switch cfg.BuildMod { case "": // ok - case "readonly", "vendor": - if load.ModLookup == nil && !inGOFLAGS("-mod") { + case "readonly", "vendor", "mod": + if !cfg.ModulesEnabled && !inGOFLAGS("-mod") { base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod) } default: - base.Fatalf("-mod=%s not supported (can be '', 'readonly', or 'vendor')", cfg.BuildMod) + base.Fatalf("-mod=%s not supported (can be '', 'mod', 'readonly', or 'vendor')", cfg.BuildMod) + } + if !cfg.ModulesEnabled { + if cfg.ModCacheRW && !inGOFLAGS("-modcacherw") { + base.Fatalf("build flag -modcacherw only valid when using modules") + } + if cfg.ModFile != "" && !inGOFLAGS("-mod") { + base.Fatalf("build flag -modfile only valid when using modules") + } } } diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go index 0d8da21ae38..0ce1664c16f 100644 --- a/libgo/go/cmd/go/internal/work/security.go +++ b/libgo/go/cmd/go/internal/work/security.go @@ -43,6 +43,7 @@ var re = lazyregexp.New var validCompilerFlags = []*lazyregexp.Regexp{ re(`-D([A-Za-z_].*)`), + re(`-U([A-Za-z_]*)`), re(`-F([^@\-].*)`), re(`-I([^@\-].*)`), re(`-O`), @@ -51,6 +52,7 @@ var validCompilerFlags = []*lazyregexp.Regexp{ re(`-W([^@,]+)`), // -Wall but not -Wa,-foo. re(`-Wa,-mbig-obj`), re(`-Wp,-D([A-Za-z_].*)`), + re(`-Wp,-U([A-Za-z_]*)`), re(`-ansi`), re(`-f(no-)?asynchronous-unwind-tables`), re(`-f(no-)?blocks`), @@ -127,6 +129,7 @@ var validCompilerFlags = []*lazyregexp.Regexp{ var validCompilerFlagsWithNextArg = []string{ "-arch", "-D", + "-U", "-I", "-framework", "-isysroot", @@ -280,6 +283,15 @@ Args: continue Args } + // Permit -I= /path, -I $SYSROOT. + if i+1 < len(list) && arg == "-I" { + if (strings.HasPrefix(list[i+1], "=") || strings.HasPrefix(list[i+1], "$SYSROOT")) && + load.SafeArg(list[i+1][1:]) { + i++ + continue Args + } + } + if i+1 < len(list) { return fmt.Errorf("invalid flag in %s: %s %s (see https://golang.org/s/invalidflag)", source, arg, list[i+1]) } diff --git a/libgo/go/cmd/go/internal/work/security_test.go b/libgo/go/cmd/go/internal/work/security_test.go index fd8caeab4ec..6b85c40b13b 100644 --- a/libgo/go/cmd/go/internal/work/security_test.go +++ b/libgo/go/cmd/go/internal/work/security_test.go @@ -12,6 +12,7 @@ import ( var goodCompilerFlags = [][]string{ {"-DFOO"}, {"-Dfoo=bar"}, + {"-Ufoo"}, {"-F/Qt"}, {"-I/"}, {"-I/etc/passwd"}, @@ -21,6 +22,8 @@ var goodCompilerFlags = [][]string{ {"-Osmall"}, {"-W"}, {"-Wall"}, + {"-Wp,-Dfoo=bar"}, + {"-Wp,-Ufoo"}, {"-fobjc-arc"}, {"-fno-objc-arc"}, {"-fomit-frame-pointer"}, @@ -56,6 +59,9 @@ var goodCompilerFlags = [][]string{ {"-I", "."}, {"-I", "/etc/passwd"}, {"-I", "世界"}, + {"-I", "=/usr/include/libxml2"}, + {"-I", "dir"}, + {"-I", "$SYSROOT/dir"}, {"-framework", "Chocolate"}, {"-x", "c"}, {"-v"}, @@ -64,6 +70,7 @@ var goodCompilerFlags = [][]string{ var badCompilerFlags = [][]string{ {"-D@X"}, {"-D-X"}, + {"-Ufoo=bar"}, {"-F@dir"}, {"-F-dir"}, {"-I@dir"}, @@ -83,6 +90,7 @@ var badCompilerFlags = [][]string{ {"-D", "-foo"}, {"-I", "@foo"}, {"-I", "-foo"}, + {"-I", "=@obj"}, {"-framework", "-Caffeine"}, {"-framework", "@Home"}, {"-x", "--c"}, @@ -143,6 +151,7 @@ var goodLinkerFlags = [][]string{ {"-L", "framework"}, {"-framework", "Chocolate"}, {"-v"}, + {"-Wl,-sectcreate,__TEXT,__info_plist,${SRCDIR}/Info.plist"}, {"-Wl,-framework", "-Wl,Chocolate"}, {"-Wl,-framework,Chocolate"}, {"-Wl,-unresolved-symbols=ignore-all"}, diff --git a/libgo/go/cmd/go/main.go b/libgo/go/cmd/go/main.go index 16bdb6209f1..bb442b5f8e4 100644 --- a/libgo/go/cmd/go/main.go +++ b/libgo/go/cmd/go/main.go @@ -91,7 +91,7 @@ func main() { } if args[0] == "get" || args[0] == "help" { - if modload.Init(); !modload.Enabled() { + if !modload.WillBeEnabled() { // Replace module-aware get with GOPATH get if appropriate. *modget.CmdGet = *get.CmdGet } diff --git a/libgo/go/cmd/go/proxy_test.go b/libgo/go/cmd/go/proxy_test.go index 6919d321847..8214488a59a 100644 --- a/libgo/go/cmd/go/proxy_test.go +++ b/libgo/go/cmd/go/proxy_test.go @@ -23,14 +23,15 @@ import ( "sync" "testing" - "cmd/go/internal/dirhash" "cmd/go/internal/modfetch" "cmd/go/internal/modfetch/codehost" - "cmd/go/internal/module" "cmd/go/internal/par" - "cmd/go/internal/semver" - "cmd/go/internal/sumweb" "cmd/go/internal/txtar" + + "golang.org/x/mod/module" + "golang.org/x/mod/semver" + "golang.org/x/mod/sumdb" + "golang.org/x/mod/sumdb/dirhash" ) var ( @@ -65,7 +66,7 @@ func StartProxy() { // Prepopulate main sumdb. for _, mod := range modList { - sumdbHandler.Server.Lookup(nil, mod.Path+"@"+mod.Version) + sumdbOps.Lookup(nil, mod) } }) } @@ -88,7 +89,7 @@ func readModList() { continue } encPath := strings.ReplaceAll(name[:i], "_", "/") - path, err := module.DecodePath(encPath) + path, err := module.UnescapePath(encPath) if err != nil { if encPath != "example.com/invalidpath/v1" { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) @@ -96,7 +97,7 @@ func readModList() { continue } encVers := name[i+1:] - vers, err := module.DecodeVersion(encVers) + vers, err := module.UnescapeVersion(encVers) if err != nil { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) continue @@ -113,8 +114,13 @@ const ( testSumDBSignerKey = "PRIVATE+KEY+localhost.localdev/sumdb+00000c67+AXu6+oaVaOYuQOFrf1V59JK1owcFlJcHwwXHDfDGxSPk" ) -var sumdbHandler = &sumweb.Handler{Server: sumweb.NewTestServer(testSumDBSignerKey, proxyGoSum)} -var sumdbWrongHandler = &sumweb.Handler{Server: sumweb.NewTestServer(testSumDBSignerKey, proxyGoSumWrong)} +var ( + sumdbOps = sumdb.NewTestServer(testSumDBSignerKey, proxyGoSum) + sumdbServer = sumdb.NewServer(sumdbOps) + + sumdbWrongOps = sumdb.NewTestServer(testSumDBSignerKey, proxyGoSumWrong) + sumdbWrongServer = sumdb.NewServer(sumdbWrongOps) +) // proxyHandler serves the Go module proxy protocol. // See the proxy section of https://research.swtch.com/vgo-module. @@ -155,7 +161,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { // (Client thinks it is talking directly to a sumdb.) if strings.HasPrefix(path, "sumdb-direct/") { r.URL.Path = path[len("sumdb-direct"):] - sumdbHandler.ServeHTTP(w, r) + sumdbServer.ServeHTTP(w, r) return } @@ -164,7 +170,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { // (Client thinks it is talking directly to a sumdb.) if strings.HasPrefix(path, "sumdb-wrong/") { r.URL.Path = path[len("sumdb-wrong"):] - sumdbWrongHandler.ServeHTTP(w, r) + sumdbWrongServer.ServeHTTP(w, r) return } @@ -178,7 +184,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { // Request for $GOPROXY/sumdb//... goes to sumdb. if sumdbPrefix := "sumdb/" + testSumDBName + "/"; strings.HasPrefix(path, sumdbPrefix) { r.URL.Path = path[len(sumdbPrefix)-1:] - sumdbHandler.ServeHTTP(w, r) + sumdbServer.ServeHTTP(w, r) return } @@ -187,7 +193,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { // latest version, including pseudo-versions. if i := strings.LastIndex(path, "/@latest"); i >= 0 { enc := path[:i] - modPath, err := module.DecodePath(enc) + modPath, err := module.UnescapePath(enc) if err != nil { if !quiet { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) @@ -225,7 +231,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { return } - encVers, err := module.EncodeVersion(latest) + encVers, err := module.EscapeVersion(latest) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -240,7 +246,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { return } enc, file := path[:i], path[i+len("/@v/"):] - path, err := module.DecodePath(enc) + path, err := module.UnescapePath(enc) if err != nil { if !quiet { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) @@ -276,7 +282,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { return } encVers, ext := file[:i], file[i+1:] - vers, err := module.DecodeVersion(encVers) + vers, err := module.UnescapeVersion(encVers) if err != nil { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) http.NotFound(w, r) @@ -397,11 +403,11 @@ var archiveCache par.Cache var cmdGoDir, _ = os.Getwd() func readArchive(path, vers string) (*txtar.Archive, error) { - enc, err := module.EncodePath(path) + enc, err := module.EscapePath(path) if err != nil { return nil, err } - encVers, err := module.EncodeVersion(vers) + encVers, err := module.EscapeVersion(vers) if err != nil { return nil, err } diff --git a/libgo/go/cmd/go/script_test.go b/libgo/go/cmd/go/script_test.go index 4dcb4b4e0d5..ec498bbcd76 100644 --- a/libgo/go/cmd/go/script_test.go +++ b/libgo/go/cmd/go/script_test.go @@ -30,6 +30,7 @@ import ( "cmd/go/internal/robustio" "cmd/go/internal/txtar" "cmd/go/internal/work" + "cmd/internal/sys" ) // TestScript runs the tests in testdata/script/*.txt. @@ -117,6 +118,7 @@ func (ts *testScript) setup() { "GOSUMDB=" + testSumDBVerifierKey, "GONOPROXY=", "GONOSUMDB=", + "PWD=" + ts.cd, tempEnvName() + "=" + filepath.Join(ts.workdir, "tmp"), "devnull=" + os.DevNull, "goversion=" + goVersion(ts), @@ -291,6 +293,22 @@ Script: }).(bool) break } + if strings.HasPrefix(cond.tag, "GODEBUG:") { + value := strings.TrimPrefix(cond.tag, "GODEBUG:") + parts := strings.Split(os.Getenv("GODEBUG"), ",") + for _, p := range parts { + if strings.TrimSpace(p) == value { + ok = true + break + } + } + break + } + if strings.HasPrefix(cond.tag, "buildmode:") { + value := strings.TrimPrefix(cond.tag, "buildmode:") + ok = sys.BuildModeSupported(runtime.Compiler, value, runtime.GOOS, runtime.GOARCH) + break + } if !imports.KnownArch[cond.tag] && !imports.KnownOS[cond.tag] && cond.tag != "gc" && cond.tag != "gccgo" { ts.fatalf("unknown condition %q", cond.tag) } @@ -414,6 +432,7 @@ func (ts *testScript) cmdCd(neg bool, args []string) { ts.fatalf("%s is not a directory", dir) } ts.cd = dir + ts.envMap["PWD"] = dir fmt.Fprintf(&ts.log, "%s\n", ts.cd) } @@ -429,7 +448,11 @@ func (ts *testScript) cmdChmod(neg bool, args []string) { if err != nil || perm&uint64(os.ModePerm) != perm { ts.fatalf("invalid mode: %s", args[0]) } - for _, path := range args[1:] { + for _, arg := range args[1:] { + path := arg + if !filepath.IsAbs(path) { + path = filepath.Join(ts.cd, arg) + } err := os.Chmod(path, os.FileMode(perm)) ts.check(err) } @@ -441,10 +464,15 @@ func (ts *testScript) cmdCmp(neg bool, args []string) { // It would be strange to say "this file can have any content except this precise byte sequence". ts.fatalf("unsupported: ! cmp") } + quiet := false + if len(args) > 0 && args[0] == "-q" { + quiet = true + args = args[1:] + } if len(args) != 2 { ts.fatalf("usage: cmp file1 file2") } - ts.doCmdCmp(args, false) + ts.doCmdCmp(args, false, quiet) } // cmpenv compares two files with environment variable substitution. @@ -452,13 +480,18 @@ func (ts *testScript) cmdCmpenv(neg bool, args []string) { if neg { ts.fatalf("unsupported: ! cmpenv") } + quiet := false + if len(args) > 0 && args[0] == "-q" { + quiet = true + args = args[1:] + } if len(args) != 2 { ts.fatalf("usage: cmpenv file1 file2") } - ts.doCmdCmp(args, true) + ts.doCmdCmp(args, true, quiet) } -func (ts *testScript) doCmdCmp(args []string, env bool) { +func (ts *testScript) doCmdCmp(args []string, env, quiet bool) { name1, name2 := args[0], args[1] var text1, text2 string if name1 == "stdout" { @@ -484,15 +517,14 @@ func (ts *testScript) doCmdCmp(args []string, env bool) { return } - fmt.Fprintf(&ts.log, "[diff -%s +%s]\n%s\n", name1, name2, diff(text1, text2)) + if !quiet { + fmt.Fprintf(&ts.log, "[diff -%s +%s]\n%s\n", name1, name2, diff(text1, text2)) + } ts.fatalf("%s and %s differ", name1, name2) } // cp copies files, maybe eventually directories. func (ts *testScript) cmdCp(neg bool, args []string) { - if neg { - ts.fatalf("unsupported: ! cp") - } if len(args) < 2 { ts.fatalf("usage: cp src... dst") } @@ -531,7 +563,14 @@ func (ts *testScript) cmdCp(neg bool, args []string) { if dstDir { targ = filepath.Join(dst, filepath.Base(src)) } - ts.check(ioutil.WriteFile(targ, data, mode)) + err := ioutil.WriteFile(targ, data, mode) + if neg { + if err == nil { + ts.fatalf("unexpected command success") + } + } else { + ts.check(err) + } } } @@ -547,26 +586,31 @@ func (ts *testScript) cmdEnv(neg bool, args []string) { args = args[1:] } + var out strings.Builder if len(args) == 0 { printed := make(map[string]bool) // env list can have duplicates; only print effective value (from envMap) once for _, kv := range ts.env { k := kv[:strings.Index(kv, "=")] if !printed[k] { - fmt.Fprintf(&ts.log, "%s=%s\n", k, ts.envMap[k]) + fmt.Fprintf(&out, "%s=%s\n", k, ts.envMap[k]) } } - return - } - for _, env := range args { - i := strings.Index(env, "=") - if i < 0 { - // Display value instead of setting it. - fmt.Fprintf(&ts.log, "%s=%s\n", env, ts.envMap[env]) - continue + } else { + for _, env := range args { + i := strings.Index(env, "=") + if i < 0 { + // Display value instead of setting it. + fmt.Fprintf(&out, "%s=%s\n", env, ts.envMap[env]) + continue + } + key, val := env[:i], conv(env[i+1:]) + ts.env = append(ts.env, key+"="+val) + ts.envMap[key] = val } - key, val := env[:i], conv(env[i+1:]) - ts.env = append(ts.env, key+"="+val) - ts.envMap[key] = val + } + if out.Len() > 0 || len(args) > 0 { + ts.stdout = out.String() + ts.log.WriteString(out.String()) } } diff --git a/libgo/go/cmd/go/testdata/dep_test.go b/libgo/go/cmd/go/testdata/dep_test.go deleted file mode 100644 index ac39a5bb1c2..00000000000 --- a/libgo/go/cmd/go/testdata/dep_test.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package deps - -import _ "testing" diff --git a/libgo/go/cmd/go/testdata/local/easy.go b/libgo/go/cmd/go/testdata/local/easy.go deleted file mode 100644 index 4eeb517da15..00000000000 --- a/libgo/go/cmd/go/testdata/local/easy.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "./easysub" - -func main() { - easysub.Hello() -} diff --git a/libgo/go/cmd/go/testdata/local/easysub/easysub.go b/libgo/go/cmd/go/testdata/local/easysub/easysub.go deleted file mode 100644 index 07040daee57..00000000000 --- a/libgo/go/cmd/go/testdata/local/easysub/easysub.go +++ /dev/null @@ -1,7 +0,0 @@ -package easysub - -import "fmt" - -func Hello() { - fmt.Println("easysub.Hello") -} diff --git a/libgo/go/cmd/go/testdata/local/easysub/main.go b/libgo/go/cmd/go/testdata/local/easysub/main.go deleted file mode 100644 index 6c30b52362e..00000000000 --- a/libgo/go/cmd/go/testdata/local/easysub/main.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build ignore - -package main - -import "." - -func main() { - easysub.Hello() -} diff --git a/libgo/go/cmd/go/testdata/local/hard.go b/libgo/go/cmd/go/testdata/local/hard.go deleted file mode 100644 index 2ffac3fd73b..00000000000 --- a/libgo/go/cmd/go/testdata/local/hard.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "./sub" - -func main() { - sub.Hello() -} diff --git a/libgo/go/cmd/go/testdata/local/sub/sub.go b/libgo/go/cmd/go/testdata/local/sub/sub.go deleted file mode 100644 index d5dbf6d5fa5..00000000000 --- a/libgo/go/cmd/go/testdata/local/sub/sub.go +++ /dev/null @@ -1,12 +0,0 @@ -package sub - -import ( - "fmt" - - subsub "./sub" -) - -func Hello() { - fmt.Println("sub.Hello") - subsub.Hello() -} diff --git a/libgo/go/cmd/go/testdata/local/sub/sub/subsub.go b/libgo/go/cmd/go/testdata/local/sub/sub/subsub.go deleted file mode 100644 index 4cc72233e13..00000000000 --- a/libgo/go/cmd/go/testdata/local/sub/sub/subsub.go +++ /dev/null @@ -1,7 +0,0 @@ -package subsub - -import "fmt" - -func Hello() { - fmt.Println("subsub.Hello") -} diff --git a/libgo/go/cmd/go/testdata/mod/example.com_dotgo.go_v1.0.0.txt b/libgo/go/cmd/go/testdata/mod/example.com_dotgo.go_v1.0.0.txt new file mode 100644 index 00000000000..4f7f4d7dd21 --- /dev/null +++ b/libgo/go/cmd/go/testdata/mod/example.com_dotgo.go_v1.0.0.txt @@ -0,0 +1,16 @@ +This module's path ends with ".go". +Based on github.com/nats-io/nats.go. +Used in regression tests for golang.org/issue/32483. + +-- .mod -- +module example.com/dotgo.go + +go 1.13 +-- .info -- +{"Version":"v1.0.0"} +-- go.mod -- +module example.com/dotgo.go + +go 1.13 +-- dotgo.go -- +package dotgo diff --git a/libgo/go/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt b/libgo/go/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt new file mode 100644 index 00000000000..787b7aedfa4 --- /dev/null +++ b/libgo/go/cmd/go/testdata/mod/example.com_stack_v1.0.0.txt @@ -0,0 +1,18 @@ +Module with a function that prints file name for the top stack frame. +Different versions of this module are identical, but they should return +different file names with -trimpath. +-- .mod -- +module example.com/stack + +go 1.14 +-- .info -- +{"Version":"v1.0.0"} +-- stack.go -- +package stack + +import "runtime" + +func TopFile() string { + _, file, _, _ := runtime.Caller(0) + return file +} diff --git a/libgo/go/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt b/libgo/go/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt new file mode 100644 index 00000000000..c715dd234f7 --- /dev/null +++ b/libgo/go/cmd/go/testdata/mod/example.com_stack_v1.0.1.txt @@ -0,0 +1,18 @@ +Module with a function that prints file name for the top stack frame. +Different versions of this module are identical, but they should return +different file names with -trimpath. +-- .mod -- +module example.com/stack + +go 1.14 +-- .info -- +{"Version":"v1.0.1"} +-- stack.go -- +package stack + +import "runtime" + +func TopFile() string { + _, file, _, _ := runtime.Caller(0) + return file +} diff --git a/libgo/go/cmd/go/testdata/mod/not-rsc.io_quote_v0.1.0-nomod.txt b/libgo/go/cmd/go/testdata/mod/not-rsc.io_quote_v0.1.0-nomod.txt new file mode 100644 index 00000000000..efff08826ad --- /dev/null +++ b/libgo/go/cmd/go/testdata/mod/not-rsc.io_quote_v0.1.0-nomod.txt @@ -0,0 +1,59 @@ +Constructed by hand. +(derived from rsc.io/quote@e7a685a342, but without an explicit go.mod file.) + +-- .mod -- +module "not-rsc.io/quote" +-- .info -- +{"Version":"v0.1.0-nomod","Time":"2018-02-14T00:51:33Z"} +-- quote.go -- +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package quote collects pithy sayings. +package quote // import "rsc.io/quote" + +// Hello returns a greeting. +func Hello() string { + return "Hello, world." +} + +// Glass returns a useful phrase for world travelers. +func Glass() string { + // See http://www.oocities.org/nodotus/hbglass.html. + return "I can eat glass and it doesn't hurt me." +} + +// Go returns a Go proverb. +func Go() string { + return "Don't communicate by sharing memory, share memory by communicating." +} +-- quote_test.go -- +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package quote + +import "testing" + +func TestHello(t *testing.T) { + hello := "Hello, world." + if out := Hello(); out != hello { + t.Errorf("Hello() = %q, want %q", out, hello) + } +} + +func TestGlass(t *testing.T) { + glass := "I can eat glass and it doesn't hurt me." + if out := Glass(); out != glass { + t.Errorf("Glass() = %q, want %q", out, glass) + } +} + +func TestGo(t *testing.T) { + go1 := "Don't communicate by sharing memory. Share memory by communicating." + if out := Go(); out != go1 { + t.Errorf("Go() = %q, want %q", out, go1) + } +} diff --git a/libgo/go/cmd/go/testdata/print_goroot.go b/libgo/go/cmd/go/testdata/print_goroot.go index 54772910609..91fbf7d8ec3 100644 --- a/libgo/go/cmd/go/testdata/print_goroot.go +++ b/libgo/go/cmd/go/testdata/print_goroot.go @@ -4,8 +4,11 @@ package main -import "runtime" +import ( + "fmt" + "runtime" +) func main() { - println(runtime.GOROOT()) + fmt.Println(runtime.GOROOT()) } diff --git a/libgo/go/cmd/go/testdata/script/README b/libgo/go/cmd/go/testdata/script/README index 66ab8515c33..2782a097079 100644 --- a/libgo/go/cmd/go/testdata/script/README +++ b/libgo/go/cmd/go/testdata/script/README @@ -38,6 +38,7 @@ Scripts also have access to these other environment variables: TMPDIR=$WORK/tmp devnull= goversion= + := The scripts supporting files are unpacked relative to $GOPATH/src (aka $WORK/gopath/src) and then the script begins execution in that directory as well. Thus the example above runs @@ -77,9 +78,13 @@ should only run when the condition is satisfied. The available conditions are: - [root] for os.Geteuid() == 0 - [symlink] for testenv.HasSymlink() - [exec:prog] for whether prog is available for execution (found by exec.LookPath) + - [GODEBUG:value] for whether value is one of the comma-separated entries in the GODEBUG variable + - [buildmode:value] for whether -buildmode=value is supported A condition can be negated: [!short] means to run the rest of the line -when testing.Short() is false. +when testing.Short() is false. Multiple conditions may be given for a single +command, for example, '[linux] [amd64] skip'. The command will run if all conditions +are satisfied. The commands are: @@ -105,13 +110,14 @@ The commands are: Like cmp, but environment variables are substituted in the file contents before the comparison. For example, $GOOS is replaced by the target GOOS. -- cp src... dst +- [!] cp src... dst Copy the listed files to the target file or existing directory. src can include "stdout" or "stderr" to use the standard output or standard error from the most recent exec or go command. - env [-r] [key=value...] - With no arguments, print the environment (useful for debugging). + With no arguments, print the environment to stdout + (useful for debugging and for verifying initial state). Otherwise add the listed key=value pairs to the environment. The -r flag causes the values to be escaped using regexp.QuoteMeta before being recorded. @@ -160,7 +166,7 @@ The commands are: - [!] stdout [-count=N] pattern Apply the grep command (see above) to the standard output - from the most recent exec, go, or wait command. + from the most recent exec, go, wait, or env command. - stop [message] Stop the test early (marking it as passing), including the message if given. diff --git a/libgo/go/cmd/go/testdata/script/bug.txt b/libgo/go/cmd/go/testdata/script/bug.txt index db3ac253672..f52250a1b0b 100644 --- a/libgo/go/cmd/go/testdata/script/bug.txt +++ b/libgo/go/cmd/go/testdata/script/bug.txt @@ -1,14 +1,15 @@ # Verify that go bug creates the appropriate URL issue body [!linux] skip +[gccgo] skip go install env BROWSER=$GOPATH/bin/browser go bug exists $TMPDIR/browser grep '^go version' $TMPDIR/browser -[!gccgo] grep '^GOROOT/bin/go version: go version' $TMPDIR/browser -[!gccgo] grep '^GOROOT/bin/go tool compile -V: compile version' $TMPDIR/browser +grep '^GOROOT/bin/go version: go version' $TMPDIR/browser +grep '^GOROOT/bin/go tool compile -V: compile version' $TMPDIR/browser grep '^uname -sr: Linux' $TMPDIR/browser -- go.mod -- diff --git a/libgo/go/cmd/go/testdata/script/build_cache_trimpath.txt b/libgo/go/cmd/go/testdata/script/build_cache_trimpath.txt index 39367ae3809..9a4b9d7b40c 100644 --- a/libgo/go/cmd/go/testdata/script/build_cache_trimpath.txt +++ b/libgo/go/cmd/go/testdata/script/build_cache_trimpath.txt @@ -1,3 +1,4 @@ +[short] skip env GO111MODULE=on # Set up fresh GOCACHE. @@ -12,9 +13,35 @@ go build -x -o a.out -trimpath stderr '(compile|gccgo)( |\.exe)' stderr 'link( |\.exe)' +# Two distinct versions of the same module with identical content should +# still be cached separately. +# Verifies golang.org/issue/35412. +go get -d example.com/stack@v1.0.0 +go run -trimpath printstack.go +stdout '^example.com/stack@v1.0.0/stack.go$' +go get -d example.com/stack@v1.0.1 +go run -trimpath printstack.go +stdout '^example.com/stack@v1.0.1/stack.go$' + -- $WORK/hello.go -- package main func main() { println("hello") } +-- $WORK/printstack.go -- +// +build ignore + +package main + +import ( + "fmt" + + "example.com/stack" +) + +func main() { + fmt.Println(stack.TopFile()) +} -- $WORK/go.mod -- module m + +go 1.14 diff --git a/libgo/go/cmd/go/testdata/script/build_gcflags.txt b/libgo/go/cmd/go/testdata/script/build_gcflags.txt new file mode 100644 index 00000000000..e0accb10d50 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/build_gcflags.txt @@ -0,0 +1,21 @@ +env GO111MODULE=off + +# Test that the user can override default code generation flags. + +[gccgo] skip # gccgo does not use -gcflags +[!cgo] skip +[!linux] skip # test only works if c-archive implies -shared +[short] skip + +go build -x -buildmode=c-archive -gcflags=all=-shared=false ./override.go +stderr '^.*/compile (.* )?-shared (.* )?-shared=false' + +-- override.go -- +package main + +import "C" + +//export GoFunc +func GoFunc() {} + +func main() {} diff --git a/libgo/go/cmd/go/testdata/script/build_i.txt b/libgo/go/cmd/go/testdata/script/build_i.txt new file mode 100644 index 00000000000..0e7ebed0f99 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/build_i.txt @@ -0,0 +1,41 @@ +env GO111MODULE=off + +# Test that 'go build -i' installs dependencies of the requested package. + +[short] skip + +# Since we are checking installation of dependencies, use a clean cache +# to ensure that multiple runs of the test do not interfere. +env GOCACHE=$WORK/cache + +# The initial 'go build -i' for bar should install its dependency foo. + +go build -v -i x/y/bar +stderr 'x/y/foo' # should be rebuilt +go build -v -i x/y/bar +! stderr 'x/y/foo' # should already be installed + +# After modifying the source files, both packages should be rebuild. + +cp x/y/foo/foo.go.next x/y/foo/foo.go +cp x/y/bar/bar.go.next x/y/bar/bar.go + +go build -v -i x/y/bar +stderr 'x/y/foo' # should be rebuilt +go build -v -i x/y/bar +! stderr 'x/y/foo' # should already be installed + +-- x/y/foo/foo.go -- +package foo +func F() {} +-- x/y/bar/bar.go -- +package bar +import "x/y/foo" +func F() { foo.F() } +-- x/y/foo/foo.go.next -- +package foo +func F() { F() } +-- x/y/bar/bar.go.next -- +package main +import "x/y/foo" +func main() { foo.F() } diff --git a/libgo/go/cmd/go/testdata/script/build_multi_main.txt b/libgo/go/cmd/go/testdata/script/build_multi_main.txt index 1d4926d9790..8afd8b8a2e1 100644 --- a/libgo/go/cmd/go/testdata/script/build_multi_main.txt +++ b/libgo/go/cmd/go/testdata/script/build_multi_main.txt @@ -10,6 +10,11 @@ stderr 'no main packages' ! go build ./cmd/c1 stderr 'already exists and is a directory' +# Verify build -o output correctly local packages +mkdir $WORK/local +go build -o $WORK/local ./exec.go +exists $WORK/local/exec$GOEXE + -- go.mod -- module exmod @@ -29,5 +34,10 @@ package pkg1 -- pkg2/pkg2.go -- package pkg2 +-- exec.go -- +package main + +func main() {} + -- c1$GOEXE/keep.txt -- Create c1 directory. diff --git a/libgo/go/cmd/go/testdata/script/build_trimpath.txt b/libgo/go/cmd/go/testdata/script/build_trimpath.txt index f785b0cb9ec..cfab80743ea 100644 --- a/libgo/go/cmd/go/testdata/script/build_trimpath.txt +++ b/libgo/go/cmd/go/testdata/script/build_trimpath.txt @@ -1,21 +1,132 @@ [short] skip -env -r GOROOT_REGEXP=$GOROOT -env -r WORK_REGEXP=$WORK -env GOROOT GOROOT_REGEXP WORK WORK_REGEXP +# Set up two identical directories that can be used as GOPATH. +env GO111MODULE=on +mkdir $WORK/a/src/paths $WORK/b/src/paths +cp paths.go $WORK/a/src/paths +cp paths.go $WORK/b/src/paths +cp go.mod $WORK/a/src/paths/ +cp go.mod $WORK/b/src/paths/ -go build -trimpath -o hello.exe hello.go -! grep -q $GOROOT_REGEXP hello.exe -! grep -q $WORK_REGEXP hello.exe -env GO111MODULE=on -go build -trimpath -o fortune.exe rsc.io/fortune -! grep -q $GOROOT_REGEXP fortune.exe -! grep -q $WORK_REGEXP fortune.exe +# A binary built without -trimpath should contain the module root dir +# and GOROOT for debugging and stack traces. +cd $WORK/a/src/paths +go build -o $WORK/paths-dbg.exe . +exec $WORK/paths-dbg.exe $WORK/paths-dbg.exe +stdout 'binary contains module root: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain the current workspace +# or GOROOT. +go build -trimpath -o $WORK/paths-a.exe . +exec $WORK/paths-a.exe $WORK/paths-a.exe +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' + +# A binary from an external module built with -trimpath should not contain +# the current workspace or GOROOT. +go get -trimpath rsc.io/fortune +exec $WORK/paths-a.exe $GOPATH/bin/fortune$GOEXE +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' +go mod edit -droprequire rsc.io/fortune + +# Two binaries built from identical packages in different directories +# should be identical. +cd $WORK/b/src/paths +go build -trimpath -o $WORK/paths-b.exe +cmp -q $WORK/paths-a.exe $WORK/paths-b.exe + + +# Same sequence of tests but in GOPATH mode. +# A binary built without -trimpath should contain GOPATH and GOROOT. +env GO111MODULE=off +cd $WORK +env GOPATH=$WORK/a +go build -o paths-dbg.exe paths +exec ./paths-dbg.exe paths-dbg.exe +stdout 'binary contains GOPATH: true' +stdout 'binary contains GOROOT: true' + +# A binary built with -trimpath should not contain GOPATH or GOROOT. +go build -trimpath -o paths-a.exe paths +exec ./paths-a.exe paths-a.exe +stdout 'binary contains GOPATH: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different GOPATH roots +# should be identical. +env GOPATH=$WORK/b +go build -trimpath -o paths-b.exe paths +cmp -q paths-a.exe paths-b.exe + --- hello.go -- +# Same sequence of tests but with gccgo. +# gccgo does not support builds in module mode. +[!exec:gccgo] stop +env GOPATH=$WORK/a + +# A binary built with gccgo without -trimpath should contain the current +# GOPATH and GOROOT. +go build -compiler=gccgo -o paths-dbg.exe paths +exec ./paths-dbg.exe paths-dbg.exe +stdout 'binary contains GOPATH: true' +stdout 'binary contains GOROOT: false' # gccgo doesn't load std from GOROOT. + +# A binary built with gccgo with -trimpath should not contain GOPATH or GOROOT. +go build -compiler=gccgo -trimpath -o paths-a.exe paths +exec ./paths-a.exe paths-a.exe +stdout 'binary contains GOPATH: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different directories +# should be identical. +env GOPATH=$WORK/b +go build -compiler=gccgo -trimpath -o paths-b.exe paths +cmp -q paths-a.exe paths-b.exe + +-- paths.go -- package main -func main() { println("hello") } + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "strings" +) + +func main() { + exe := os.Args[1] + data, err := ioutil.ReadFile(exe) + if err != nil { + log.Fatal(err) + } + + if os.Getenv("GO111MODULE") == "on" { + out, err := exec.Command("go", "env", "GOMOD").Output() + if err != nil { + log.Fatal(err) + } + modRoot := filepath.Dir(strings.TrimSpace(string(out))) + check(data, "module root", modRoot) + } else { + check(data, "GOPATH", os.Getenv("GOPATH")) + } + check(data, "GOROOT", os.Getenv("GOROOT")) +} + +func check(data []byte, desc, dir string) { + containsDir := bytes.Contains(data, []byte(dir)) + containsSlashDir := bytes.Contains(data, []byte(filepath.ToSlash(dir))) + fmt.Printf("binary contains %s: %v\n", desc, containsDir || containsSlashDir) +} -- go.mod -- -module m +module paths + +go 1.14 diff --git a/libgo/go/cmd/go/testdata/script/cache_vet.txt b/libgo/go/cmd/go/testdata/script/cache_vet.txt new file mode 100644 index 00000000000..928024e0340 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/cache_vet.txt @@ -0,0 +1,22 @@ +env GO111MODULE=off + +[short] skip +[GODEBUG:gocacheverify=1] skip +[gccgo] skip # gccgo has no standard packages + +# Start with a clean build cache: +# test failures may be masked if the cache has just the right entries already. +env GOCACHE=$WORK/cache + +# Run 'go vet os/user' once to warm up the cache. +go vet os/user + +# Check that second vet reuses cgo-derived inputs. +# The first command could be build instead of vet, +# except that if the cache is empty and there's a net.a +# in GOROOT/pkg, the build will not bother to regenerate +# and cache the cgo outputs, whereas vet always will. + +go vet -x os/user +! stderr '^(clang|gcc)' # should not have run compiler +! stderr '[\\/]cgo ' # should not have run cgo diff --git a/libgo/go/cmd/go/testdata/script/cmd_import_error.txt b/libgo/go/cmd/go/testdata/script/cmd_import_error.txt index ba94f9bd3eb..685c606a413 100644 --- a/libgo/go/cmd/go/testdata/script/cmd_import_error.txt +++ b/libgo/go/cmd/go/testdata/script/cmd_import_error.txt @@ -5,7 +5,7 @@ env GO111MODULE=on # a clear error in module mode. ! go list cmd/unknown -stderr '^can''t load package: package cmd/unknown: package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' +stderr '^can''t load package: package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' go list -f '{{range .DepsErrors}}{{.Err}}{{end}}' x.go stdout '^package cmd/unknown is not in GOROOT \('$GOROOT'[/\\]src[/\\]cmd[/\\]unknown\)$' diff --git a/libgo/go/cmd/go/testdata/script/cover_mod_empty.txt b/libgo/go/cmd/go/testdata/script/cover_mod_empty.txt new file mode 100644 index 00000000000..20c9199ae7d --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/cover_mod_empty.txt @@ -0,0 +1,11 @@ +[gccgo] skip + +go tool cover -func=cover.out +stdout total.*statements.*0.0% + +go mod init golang.org/issue/33855 + +go tool cover -func=cover.out +stdout total.*statements.*0.0% + +-- cover.out -- diff --git a/libgo/go/cmd/go/testdata/script/cover_modes.txt b/libgo/go/cmd/go/testdata/script/cover_modes.txt new file mode 100644 index 00000000000..f8a399d0e60 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/cover_modes.txt @@ -0,0 +1,25 @@ +env GO111MODULE=off + +# Coverage analysis should use 'set' mode by default, +# and should merge coverage profiles correctly. + +[short] skip +[gccgo] skip # gccgo has no cover tool + +go test -short -cover encoding/binary errors -coverprofile=$WORK/cover.out +! stderr '[^0-9]0\.0%' +! stdout '[^0-9]0\.0%' + +grep -count=1 '^mode: set$' $WORK/cover.out +grep 'errors\.go' $WORK/cover.out +grep 'binary\.go' $WORK/cover.out + +[!race] stop + +go test -short -race -cover encoding/binary errors -coverprofile=$WORK/cover.out +! stderr '[^0-9]0\.0%' +! stdout '[^0-9]0\.0%' + +grep -count=1 '^mode: atomic$' $WORK/cover.out +grep 'errors\.go' $WORK/cover.out +grep 'binary\.go' $WORK/cover.out diff --git a/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt b/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt index ab7cd66949d..f21cd8b3a8e 100644 --- a/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt +++ b/libgo/go/cmd/go/testdata/script/cover_pkgall_multiple_mains.txt @@ -1,29 +1,32 @@ # This test checks that multiple main packages can be tested # with -coverpkg=all without duplicate symbol errors. -# Verifies golang.org/issue/30374. - -env GO111MODULE=on +# Verifies golang.org/issue/30374, golang.org/issue/34114. [short] skip +cd $GOPATH/src/example.com/cov + +env GO111MODULE=on +go test -coverpkg=all ./... +env GO111MODULE=off go test -coverpkg=all ./... --- go.mod -- +-- $GOPATH/src/example.com/cov/go.mod -- module example.com/cov --- mainonly/mainonly.go -- +-- $GOPATH/src/example.com/cov/mainonly/mainonly.go -- package main func main() {} --- mainwithtest/mainwithtest.go -- +-- $GOPATH/src/example.com/cov/mainwithtest/mainwithtest.go -- package main func main() {} func Foo() {} --- mainwithtest/mainwithtest_test.go -- +-- $GOPATH/src/example.com/cov/mainwithtest/mainwithtest_test.go -- package main import "testing" @@ -32,10 +35,10 @@ func TestFoo(t *testing.T) { Foo() } --- xtest/x.go -- +-- $GOPATH/src/example.com/cov/xtest/x.go -- package x --- xtest/x_test.go -- +-- $GOPATH/src/example.com/cov/xtest/x_test.go -- package x_test import "testing" diff --git a/libgo/go/cmd/go/testdata/script/devnull.txt b/libgo/go/cmd/go/testdata/script/devnull.txt new file mode 100644 index 00000000000..ccb866aed1a --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/devnull.txt @@ -0,0 +1,26 @@ +env GO111MODULE=off + +# Issue 28035: go test -c -o NUL should work. +# Issue 28549: go test -c -o /dev/null should not overwrite /dev/null when run as root. +cd x +cmp $devnull $WORK/empty.txt +go test -o=$devnull -c +! exists x.test$GOEXE +cmp $devnull $WORK/empty.txt + +# Issue 12407: go build -o /dev/null should succeed. +cd .. +go build -o $devnull y +cmp $devnull $WORK/empty.txt + +-- x/x_test.go -- +package x_test +import ( + "testing" +) +func TestNUL(t *testing.T) { +} +-- y/y.go -- +package y +func main() {} +-- $WORK/empty.txt -- diff --git a/libgo/go/cmd/go/testdata/script/env_write.txt b/libgo/go/cmd/go/testdata/script/env_write.txt index 695cc83f3d7..1cc08466c96 100644 --- a/libgo/go/cmd/go/testdata/script/env_write.txt +++ b/libgo/go/cmd/go/testdata/script/env_write.txt @@ -85,3 +85,36 @@ stderr 'multiple values for key: GOOS' # go env -w rejects missing variables ! go env -w GOOS stderr 'arguments must be KEY=VALUE: invalid argument: GOOS' + +# go env -w rejects invalid GO111MODULE values, as otherwise cmd/go would break +! go env -w GO111MODULE=badvalue +stderr 'invalid GO111MODULE value "badvalue"' + +# go env -w rejects invalid GOPATH values +! go env -w GOPATH=~/go +stderr 'GOPATH entry cannot start with shell metacharacter' + +! go env -w GOPATH=./go +stderr 'GOPATH entry is relative; must be absolute path' + +# go env -w/-u checks validity of GOOS/ARCH combinations +[gccgo] skip +env GOOS= +env GOARCH= +# check -w doesn't allow invalid GOOS +! go env -w GOOS=linuxx +stderr 'unsupported GOOS/GOARCH pair linuxx' +# check -w doesn't allow invalid GOARCH +! go env -w GOARCH=amd644 +stderr 'unsupported GOOS/GOARCH.*/amd644$' +# check -w doesn't allow invalid GOOS with valid GOARCH +! go env -w GOOS=linuxx GOARCH=amd64 +stderr 'unsupported GOOS/GOARCH pair linuxx' +# check a valid GOOS and GOARCH values but an incompatible combinations +! go env -w GOOS=android GOARCH=s390x +stderr 'unsupported GOOS/GOARCH pair android/s390x' +# check that -u considers explicit envs +go env -w GOOS=linux GOARCH=mips +env GOOS=windows +! go env -u GOOS +stderr 'unsupported GOOS/GOARCH.*windows/mips$' diff --git a/libgo/go/cmd/go/testdata/script/fmt_load_errors.txt b/libgo/go/cmd/go/testdata/script/fmt_load_errors.txt new file mode 100644 index 00000000000..297ec0fe3c7 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/fmt_load_errors.txt @@ -0,0 +1,19 @@ +env GO111MODULE=off + +! go fmt does-not-exist + +go fmt -n exclude +stdout 'exclude[/\\]x\.go' +stdout 'exclude[/\\]x_linux\.go' + +-- exclude/empty/x.txt -- +-- exclude/ignore/_x.go -- +package x +-- exclude/x.go -- +// +build linux,!linux + +package x +-- exclude/x_linux.go -- +// +build windows + +package x diff --git a/libgo/go/cmd/go/testdata/script/gccgo_m.txt b/libgo/go/cmd/go/testdata/script/gccgo_m.txt new file mode 100644 index 00000000000..b63ba46ced0 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/gccgo_m.txt @@ -0,0 +1,19 @@ +# It's absurd, but builds with -compiler=gccgo used to fail to build module m. +# golang.org/issue/34358 + +env GO111MODULE=off + +[short] skip + +cd m +go build +exists m$GOEXE +rm m$GOEXE +[exec:gccgo] go build -compiler=gccgo +[exec:gccgo] exists m$GOEXE + +-- m/go.mod -- +module m +-- m/main.go -- +package main +func main() {} diff --git a/libgo/go/cmd/go/testdata/script/gccgo_mangle.txt b/libgo/go/cmd/go/testdata/script/gccgo_mangle.txt new file mode 100644 index 00000000000..7a09a8002ec --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/gccgo_mangle.txt @@ -0,0 +1,15 @@ +# Issue 33871. + +cd m/a.0 +go build + +-- m/go.mod -- +module m +-- m/a.0/a.go -- +package a + +type T int + +func (t T) M() int { + return int(t) +} diff --git a/libgo/go/cmd/go/testdata/script/get_insecure_redirect.txt b/libgo/go/cmd/go/testdata/script/get_insecure_redirect.txt index a83b17672d4..0478d1f75de 100644 --- a/libgo/go/cmd/go/testdata/script/get_insecure_redirect.txt +++ b/libgo/go/cmd/go/testdata/script/get_insecure_redirect.txt @@ -1,11 +1,10 @@ # golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure. +# golang.org/issue/34049: 'go get' would panic in case of an insecure redirect in GOPATH mode [!net] skip [!exec:git] skip -env GO111MODULE=on -env GOPROXY=direct -env GOSUMDB=off +env GO111MODULE=off ! go get -d vcs-test.golang.org/insecure/go/insecure stderr 'redirected .* to insecure URL' diff --git a/libgo/go/cmd/go/testdata/script/goflags.txt b/libgo/go/cmd/go/testdata/script/goflags.txt index fac6d807202..686d1138b83 100644 --- a/libgo/go/cmd/go/testdata/script/goflags.txt +++ b/libgo/go/cmd/go/testdata/script/goflags.txt @@ -49,3 +49,11 @@ stderr '^go: invalid boolean value \"asdf\" for flag -e \(from (\$GOFLAGS|%GOFLA go env stdout GOFLAGS +# Flags listed in GOFLAGS should be safe to duplicate on the command line. +env GOFLAGS=-tags=magic +go list -tags=magic +go test -tags=magic -c -o $devnull +go vet -tags=magic + +-- foo_test.go -- +package foo diff --git a/libgo/go/cmd/go/testdata/script/gopath_install.txt b/libgo/go/cmd/go/testdata/script/gopath_install.txt new file mode 100644 index 00000000000..4b42fc593f9 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/gopath_install.txt @@ -0,0 +1,53 @@ +# Regression test for 'go install' locations in GOPATH mode. +env GO111MODULE=off +[short] skip + +# Without $GOBIN set, binaries should be installed into the GOPATH bin directory. +env GOBIN= +rm $GOPATH/bin/go-cmd-test$GOEXE +go install go-cmd-test +exists $GOPATH/bin/go-cmd-test$GOEXE + +# With $GOBIN set, binaries should be installed to $GOBIN. +env GOBIN=$WORK/bin1 +mkdir -p $GOBIN +go install go-cmd-test +exists $GOBIN/go-cmd-test$GOEXE + +# Issue 11065: installing to the current directory should create an executable. +cd go-cmd-test +env GOBIN=$PWD +go install +exists ./go-cmd-test$GOEXE +cd .. + +# Without $GOBIN set, installing a program outside $GOPATH should fail +# (there is nowhere to install it). +env GOPATH= # reset to default ($HOME/go, which does not exist) +env GOBIN= +! go install go-cmd-test/helloworld.go +stderr '^go install: no install location for \.go files listed on command line \(GOBIN not set\)$' + +# With $GOBIN set, should install there. +env GOBIN=$WORK/bin1 +go install go-cmd-test/helloworld.go +exists $GOBIN/helloworld$GOEXE + +# We can't assume that we can write to GOROOT, because it may not be writable. +# However, we can check its install location using 'go list'. +# cmd/fix should be installed to GOROOT/pkg, not GOPATH/bin. +env GOPATH=$PWD +go list -f '{{.Target}}' cmd/fix +stdout $GOROOT'[/\\]pkg[/\\]tool[/\\]'$GOOS'_'$GOARCH'[/\\]fix'$GOEXE'$' + +# GOBIN should not affect toolchain install locations. +env GOBIN=$WORK/bin1 +go list -f '{{.Target}}' cmd/fix +stdout $GOROOT'[/\\]pkg[/\\]tool[/\\]'$GOOS'_'$GOARCH'[/\\]fix'$GOEXE'$' + +-- go-cmd-test/helloworld.go -- +package main + +func main() { + println("hello world") +} diff --git a/libgo/go/cmd/go/testdata/script/gopath_local.txt b/libgo/go/cmd/go/testdata/script/gopath_local.txt new file mode 100644 index 00000000000..7ee1f83471c --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/gopath_local.txt @@ -0,0 +1,117 @@ +env GO111MODULE=off # Relative imports only work in GOPATH mode. + +[short] skip + +# Imports should be resolved relative to the source file. +go build testdata/local/easy.go +exec ./easy$GOEXE +stdout '^easysub\.Hello' + +# Ignored files should be able to import the package built from +# non-ignored files in the same directory. +go build -o easysub$GOEXE testdata/local/easysub/main.go +exec ./easysub$GOEXE +stdout '^easysub\.Hello' + +# Files in relative-imported packages should be able to +# use relative imports themselves. +go build testdata/local/hard.go +exec ./hard$GOEXE +stdout '^sub\.Hello' + +# Explicit source files listed on the command line should not install without +# GOBIN set, since individual source files aren't part of the containing GOPATH. +! go install testdata/local/easy.go +stderr '^go install: no install location for \.go files listed on command line \(GOBIN not set\)$' + +[windows] stop # Windows does not allow the ridiculous directory name we're about to use. + +env BAD_DIR_NAME='#$%:, &()*;<=>?\^{}' + +mkdir -p testdata/$BAD_DIR_NAME/easysub +mkdir -p testdata/$BAD_DIR_NAME/sub/sub + +cp testdata/local/easy.go testdata/$BAD_DIR_NAME/easy.go +cp testdata/local/easysub/easysub.go testdata/$BAD_DIR_NAME/easysub/easysub.go +cp testdata/local/easysub/main.go testdata/$BAD_DIR_NAME/easysub/main.go +cp testdata/local/hard.go testdata/$BAD_DIR_NAME/hard.go +cp testdata/local/sub/sub.go testdata/$BAD_DIR_NAME/sub/sub.go +cp testdata/local/sub/sub/subsub.go testdata/$BAD_DIR_NAME/sub/sub/subsub.go + +# Imports should be resolved relative to the source file. +go build testdata/$BAD_DIR_NAME/easy.go +exec ./easy$GOEXE +stdout '^easysub\.Hello' + +# Ignored files should be able to import the package built from +# non-ignored files in the same directory. +go build -o easysub$GOEXE testdata/$BAD_DIR_NAME/easysub/main.go +exec ./easysub$GOEXE +stdout '^easysub\.Hello' + +# Files in relative-imported packages should be able to +# use relative imports themselves. +go build testdata/$BAD_DIR_NAME/hard.go +exec ./hard$GOEXE +stdout '^sub\.Hello' + +# Explicit source files listed on the command line should not install without +# GOBIN set, since individual source files aren't part of the containing GOPATH. +! go install testdata/$BAD_DIR_NAME/easy.go +stderr '^go install: no install location for \.go files listed on command line \(GOBIN not set\)$' + +-- testdata/local/easy.go -- +package main + +import "./easysub" + +func main() { + easysub.Hello() +} +-- testdata/local/easysub/easysub.go -- +package easysub + +import "fmt" + +func Hello() { + fmt.Println("easysub.Hello") +} +-- testdata/local/easysub/main.go -- +// +build ignore + +package main + +import "." + +func main() { + easysub.Hello() +} +-- testdata/local/hard.go -- +package main + +import "./sub" + +func main() { + sub.Hello() +} +-- testdata/local/sub/sub.go -- +package sub + +import ( + "fmt" + + subsub "./sub" +) + +func Hello() { + fmt.Println("sub.Hello") + subsub.Hello() +} +-- testdata/local/sub/sub/subsub.go -- +package subsub + +import "fmt" + +func Hello() { + fmt.Println("subsub.Hello") +} diff --git a/libgo/go/cmd/go/testdata/script/gopath_moved_repo.txt b/libgo/go/cmd/go/testdata/script/gopath_moved_repo.txt new file mode 100644 index 00000000000..869980da7c5 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/gopath_moved_repo.txt @@ -0,0 +1,68 @@ +env GO111MODULE=off + +# Test that 'go get -u' reports packages whose VCS configurations do not +# match their import paths. + +[!net] skip +[short] skip + +# We need to execute a custom Go program to break the config files. +# +# git will ask for a username and password when we run 'go get -d -f -u', +# so we also need to set GIT_ASKPASS. Conveniently, a single binary can +# perform both tasks! + +go build -o replace.exe replace +env GIT_ASKPASS=$PWD/replace.exe + + +# Test that 'go get -u' reports moved git packages. + +[exec:git] go get -d rsc.io/pdf +[exec:git] go get -d -u rsc.io/pdf +[exec:git] exec ./replace.exe pdf rsc.io/pdf/.git/config + +[exec:git] ! go get -d -u rsc.io/pdf +[exec:git] stderr 'is a custom import path for' +[exec:git] ! go get -d -f -u rsc.io/pdf +[exec:git] stderr 'validating server certificate|[nN]ot [fF]ound' + + +# Test that 'go get -u' reports moved Mercurial packages. + +[exec:hg] go get -d vcs-test.golang.org/go/custom-hg-hello +[exec:hg] go get -d -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] exec ./replace.exe custom-hg-hello vcs-test.golang.org/go/custom-hg-hello/.hg/hgrc + +[exec:hg] ! go get -d -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] stderr 'is a custom import path for' +[exec:hg] ! go get -d -f -u vcs-test.golang.org/go/custom-hg-hello +[exec:hg] stderr 'validating server certificate|[nN]ot [fF]ound' + + +-- replace/replace.go -- +package main + +import ( + "bytes" + "io/ioutil" + "log" + "os" +) + +func main() { + if len(os.Args) < 3 { + return + } + + base := []byte(os.Args[1]) + path := os.Args[2] + data, err := ioutil.ReadFile(path) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile(path, bytes.ReplaceAll(data, base, append(base, "XXX"...)), 0644) + if err != nil { + log.Fatal(err) + } +} diff --git a/libgo/go/cmd/go/testdata/script/gopath_paths.txt b/libgo/go/cmd/go/testdata/script/gopath_paths.txt new file mode 100644 index 00000000000..04265b176f5 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/gopath_paths.txt @@ -0,0 +1,43 @@ +# Regression test for GOPATH validation in GOPATH mode. +env GO111MODULE=off + +env ORIG_GOPATH=$GOPATH + +# The literal path '.' in GOPATH should be rejected. +env GOPATH=. +! go build go-cmd-test/helloworld.go +stderr 'GOPATH entry is relative' + +# It should still be rejected if the requested package can be +# found using another entry. +env GOPATH=${:}$ORIG_GOPATH${:}. +! go build go-cmd-test +stderr 'GOPATH entry is relative' + +# GOPATH cannot be a relative subdirectory of the working directory. +env ORIG_GOPATH +stdout 'ORIG_GOPATH='$WORK[/\\]gopath +cd $WORK +env GOPATH=gopath +! go build gopath/src/go-cmd-test/helloworld.go +stderr 'GOPATH entry is relative' + +# Blank paths in GOPATH should be rejected as relative (issue 21928). +env GOPATH=' '${:}$ORIG_GOPATH +! go build go-cmd-test +stderr 'GOPATH entry is relative' + +[short] stop + +# Empty paths in GOPATH should be ignored (issue 21928). +env GOPATH=${:}$ORIG_GOPATH +env GOPATH +go install go-cmd-test +exists $ORIG_GOPATH/bin/go-cmd-test$GOEXE + +-- go-cmd-test/helloworld.go -- +package main + +func main() { + println("hello world") +} diff --git a/libgo/go/cmd/go/testdata/script/import_main.txt b/libgo/go/cmd/go/testdata/script/import_main.txt new file mode 100644 index 00000000000..bc2cc4d3370 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/import_main.txt @@ -0,0 +1,114 @@ +env GO111MODULE=off + +# Test that you cannot import a main package. +# See golang.org/issue/4210 and golang.org/issue/17475. + +[short] skip +cd $WORK + +# Importing package main from that package main's test should work. +go build x +go test -c x + +# Importing package main from another package should fail. +! go build p1 +stderr 'import "x" is a program, not an importable package' + +# ... even in that package's test. +go build p2 +! go test -c p2 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package's test is an xtest. +go build p3 +! go test p3 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package is a package main +go build p4 +! go test -c p4 +stderr 'import "x" is a program, not an importable package' + +# ... even if that package is a package main using an xtest. +go build p5 +! go test -c p5 +stderr 'import "x" is a program, not an importable package' + +-- x/main.go -- +package main + +var X int + +func main() {} +-- x/main_test.go -- +package main_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p1/p.go -- +package p1 + +import xmain "x" + +var _ = xmain.X +-- p2/p.go -- +package p2 +-- p2/p_test.go -- +package p2 + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p3/p.go -- +package p +-- p3/p_test.go -- +package p_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p4/p.go -- +package main + +func main() {} +-- p4/p_test.go -- +package main + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} +-- p5/p.go -- +package main +func main() {} +-- p5/p_test.go -- +package main_test + +import ( + "testing" + xmain "x" +) + +var _ = xmain.X + +func TestFoo(t *testing.T) {} diff --git a/libgo/go/cmd/go/testdata/script/install_cmd_gobin.txt b/libgo/go/cmd/go/testdata/script/install_cmd_gobin.txt index 81649e234ff..4a5d8c8c627 100644 --- a/libgo/go/cmd/go/testdata/script/install_cmd_gobin.txt +++ b/libgo/go/cmd/go/testdata/script/install_cmd_gobin.txt @@ -1,6 +1,6 @@ # Check that commands in cmd are install to $GOROOT/bin, not $GOBIN. # Verifies golang.org/issue/32674. -[gccgo] stop +[gccgo] skip env GOBIN=gobin mkdir gobin go list -f '{{.Target}}' cmd/go diff --git a/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt b/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt index 60aeed689f3..14cf7222620 100644 --- a/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt +++ b/libgo/go/cmd/go/testdata/script/install_cross_gobin.txt @@ -1,11 +1,10 @@ env GO111MODULE=off [!short] skip # rebuilds std for alternate architecture +[gccgo] skip cd mycmd go build mycmd -[gccgo] stop - # cross-compile install with implicit GOBIN=$GOPATH/bin can make subdirectory env GOARCH=386 [386] env GOARCH=amd64 diff --git a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt new file mode 100644 index 00000000000..c2ca27acbf9 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt @@ -0,0 +1,43 @@ +# Test that we can use the external linker with a host syso file that is +# embedded in a package, that is referenced by a Go assembly function. +# See issue 33139. +[!gc] skip +[!exec:cc] skip + +# External linking is not supported on linux/ppc64. +# See: https://github.com/golang/go/issues/8912 +[linux] [ppc64] skip + +# External linking is not supported on darwin/386 (10.14+). +# See: https://github.com/golang/go/issues/31751 +[darwin] [386] skip + +cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c +go build -ldflags='-linkmode=external' ./cmd/main.go + +-- syso/objTest.s -- +#include "textflag.h" + +TEXT ·ObjTest(SB), NOSPLIT, $0 + // We do not actually execute this function in the test above, thus + // there is no stack frame setup here. + // We only care about Go build and/or link errors when referencing + // the objTestImpl symbol in the syso file. + JMP objTestImpl(SB) + +-- syso/pkg.go -- +package syso + +func ObjTest() + +-- syso/src/objTestImpl.c -- +void objTestImpl() { /* Empty */ } + +-- cmd/main.go -- +package main + +import "syso" + +func main() { + syso.ObjTest() +} diff --git a/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt b/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt new file mode 100644 index 00000000000..bdb7ffb077a --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/list_ambiguous_path.txt @@ -0,0 +1,38 @@ +# Ensures that we can correctly list package patterns ending in '.go'. +# See golang.org/issue/34653. + +# A single pattern for a package ending in '.go'. +go list ./foo.go +stdout '^test/foo.go$' + +# Multiple patterns for packages including one ending in '.go'. +go list ./bar ./foo.go +stdout '^test/bar$' +stdout '^test/foo.go$' + +# A single pattern for a Go file. +go list ./a.go +stdout '^command-line-arguments$' + +# A single typo-ed pattern for a Go file. This should +# treat the wrong pattern as if it were a package. +! go list ./foo.go/b.go +stderr 'package ./foo.go/b.go: cannot find package "."' + +# Multiple patterns for Go files with a typo. This should +# treat the wrong pattern as if it were a non-existint file. +! go list ./foo.go/a.go ./foo.go/b.go +[plan9] stderr 'stat ./foo.go/b.go: ''./foo.go/b.go'' does not exist' +[windows] stderr './foo.go/b.go: The system cannot find the file specified' +[!plan9] [!windows] stderr './foo.go/b.go: no such file or directory' + +-- a.go -- +package main +-- bar/a.go -- +package bar +-- foo.go/a.go -- +package foo.go +-- go.mod -- +module "test" + +go 1.13 diff --git a/libgo/go/cmd/go/testdata/script/list_constraints.txt b/libgo/go/cmd/go/testdata/script/list_constraints.txt new file mode 100644 index 00000000000..7115c365f05 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/list_constraints.txt @@ -0,0 +1,86 @@ +# Check that files and their imports are not included in 'go list' output +# when they are excluded by build constraints. + +# Linux and cgo files should be included when building in that configuration. +env GOOS=linux +env GOARCH=amd64 +env CGO_ENABLED=1 +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^cgotag.go empty.go suffix_linux.go tag.go $' +go list -f '{{range .CgoFiles}}{{.}} {{end}}' +stdout '^cgoimport.go $' +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^C cgoimport cgotag suffix tag $' + +# Disabling cgo should exclude cgo files and their imports. +env CGO_ENABLED=0 +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout 'empty.go suffix_linux.go tag.go' +go list -f '{{range .CgoFiles}}{{.}} {{end}}' +! stdout . +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^suffix tag $' + +# Changing OS should exclude linux sources. +env GOOS=darwin +go list -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^empty.go $' +go list -f '{{range .Imports}}{{.}} {{end}}' +stdout '^$' + +# Enabling a tag should include files that require it. +go list -tags=extra -f '{{range .GoFiles}}{{.}} {{end}}' +stdout '^empty.go extra.go $' +go list -tags=extra -f '{{range .Imports}}{{.}} {{end}}' +stdout '^extra $' + +# Packages that require a tag should not be listed unless the tag is on. +! go list ./tagonly +go list -tags=extra ./tagonly +stdout m/tagonly + +-- go.mod -- +module m + +go 1.13 + +-- empty.go -- +package p + +-- extra.go -- +// +build extra + +package p + +import _ "extra" + +-- suffix_linux.go -- +package p + +import _ "suffix" + +-- tag.go -- +// +build linux + +package p + +import _ "tag" + +-- cgotag.go -- +// +build cgo + +package p + +import _ "cgotag" + +-- cgoimport.go -- +package p + +import "C" + +import _ "cgoimport" + +-- tagonly/tagonly.go -- +// +build extra + +package tagonly diff --git a/libgo/go/cmd/go/testdata/script/list_linkshared.txt b/libgo/go/cmd/go/testdata/script/list_linkshared.txt new file mode 100644 index 00000000000..baae1e2be83 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/list_linkshared.txt @@ -0,0 +1,16 @@ +env GO111MODULE=on + +# golang.org/issue/35759: 'go list -linkshared' +# panicked if invoked on a test-only package. + +[!buildmode:shared] skip + +go list -f '{{.ImportPath}}: {{.Target}} {{.Shlib}}' -linkshared . +stdout '^example.com: $' + +-- go.mod -- +module example.com + +go 1.14 +-- x.go -- +package x diff --git a/libgo/go/cmd/go/testdata/script/list_parse_err.txt b/libgo/go/cmd/go/testdata/script/list_parse_err.txt new file mode 100644 index 00000000000..5aacaa88fae --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/list_parse_err.txt @@ -0,0 +1,17 @@ +# 'go list' should report imports, even if some files have parse errors +# before the import block. +go list -e -f '{{range .Imports}}{{.}} {{end}}' +stdout '^fmt ' + +-- go.mod -- +module m + +go 1.13 + +-- a.go -- +package a + +import "fmt" + +-- b.go -- +// no package statement diff --git a/libgo/go/cmd/go/testdata/script/list_split_main.txt b/libgo/go/cmd/go/testdata/script/list_split_main.txt new file mode 100644 index 00000000000..74e7d5d74c2 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/list_split_main.txt @@ -0,0 +1,25 @@ +# This test checks that a "main" package with an external test package +# is recompiled only once. +# Verifies golang.org/issue/34321. + +env GO111MODULE=off + +go list -e -test -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' pkg +cmp stdout want + +-- $GOPATH/src/pkg/pkg.go -- +package main + +func main() {} + +-- $GOPATH/src/pkg/pkg_test.go -- +package main + +import "testing" + +func Test(t *testing.T) {} + +-- want -- +pkg +pkg [pkg.test] +pkg.test diff --git a/libgo/go/cmd/go/testdata/script/list_tags.txt b/libgo/go/cmd/go/testdata/script/list_tags.txt deleted file mode 100644 index 49069bd2135..00000000000 --- a/libgo/go/cmd/go/testdata/script/list_tags.txt +++ /dev/null @@ -1,10 +0,0 @@ -env GO111MODULE=off - -# go list supports -tags -go list -tags=thetag ./my... -stdout mypkg - --- mypkg/x.go -- -// +build thetag - -package mypkg diff --git a/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt b/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt new file mode 100644 index 00000000000..61e632a29cc --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_ambiguous_import.txt @@ -0,0 +1,49 @@ +env GO111MODULE=on + +cd $WORK + +# An import provided by two different modules should be flagged as an error. +! go build ./importx +stderr '^importx[/\\]importx.go:2:8: ambiguous import: found package example.com/a/x in multiple modules:\n\texample.com/a v0.1.0 \('$WORK'[/\\]a[/\\]x\)\n\texample.com/a/x v0.1.0 \('$WORK'[/\\]ax\)$' + +# However, it should not be an error if that import is unused. +go build ./importy + +# An import provided by both the main module and the vendor directory +# should be flagged as an error only when -mod=vendor is set. +# TODO: This error message is a bit redundant. +mkdir vendor/example.com/m/importy +cp $WORK/importy/importy.go vendor/example.com/m/importy/importy.go +go build example.com/m/importy +! go build -mod=vendor example.com/m/importy +stderr '^can.t load package: package example.com/m/importy: ambiguous import: found package example.com/m/importy in multiple directories:\n\t'$WORK'[/\\]importy\n\t'$WORK'[/\\]vendor[/\\]example.com[/\\]m[/\\]importy$' + +-- $WORK/go.mod -- +module example.com/m +go 1.13 +require ( + example.com/a v0.1.0 + example.com/a/x v0.1.0 +) +replace ( + example.com/a v0.1.0 => ./a + example.com/a/x v0.1.0 => ./ax +) +-- $WORK/importx/importx.go -- +package importx +import _ "example.com/a/x" +-- $WORK/importy/importy.go -- +package importy +import _ "example.com/a/y" +-- $WORK/a/go.mod -- +module example.com/a +go 1.14 +-- $WORK/a/x/x.go -- +package x +-- $WORK/a/y/y.go -- +package y +-- $WORK/ax/go.mod -- +module example.com/a/x +go 1.14 +-- $WORK/ax/x.go -- +package x diff --git a/libgo/go/cmd/go/testdata/script/mod_auth.txt b/libgo/go/cmd/go/testdata/script/mod_auth.txt index fe1d65794af..5bcbcd1a188 100644 --- a/libgo/go/cmd/go/testdata/script/mod_auth.txt +++ b/libgo/go/cmd/go/testdata/script/mod_auth.txt @@ -8,6 +8,8 @@ env GOSUMDB=off # basic auth should fail. env NETRC=$WORK/empty ! go list all +stderr '^\tserver response: ACCESS DENIED, buddy$' +stderr '^\tserver response: File\? What file\?$' # With credentials from a netrc file, it should succeed. env NETRC=$WORK/netrc diff --git a/libgo/go/cmd/go/testdata/script/mod_bad_domain.txt b/libgo/go/cmd/go/testdata/script/mod_bad_domain.txt index c9fd044cdc8..ec0d474382e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_bad_domain.txt +++ b/libgo/go/cmd/go/testdata/script/mod_bad_domain.txt @@ -2,10 +2,16 @@ env GO111MODULE=on # explicit get should report errors about bad names ! go get appengine -stderr 'malformed module path "appengine": missing dot in first path element' +stderr '^go get appengine: package appengine is not in GOROOT \(.*\)$' ! go get x/y.z stderr 'malformed module path "x/y.z": missing dot in first path element' +# 'go list -m' should report errors about module names, never GOROOT. +! go list -m -versions appengine +stderr 'malformed module path "appengine": missing dot in first path element' +! go list -m -versions x/y.z +stderr 'malformed module path "x/y.z": missing dot in first path element' + # build should report all unsatisfied imports, # but should be more definitive about non-module import paths ! go build ./useappengine diff --git a/libgo/go/cmd/go/testdata/script/mod_build_info_err.txt b/libgo/go/cmd/go/testdata/script/mod_build_info_err.txt new file mode 100644 index 00000000000..87a099b219c --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_build_info_err.txt @@ -0,0 +1,22 @@ +# This test verifies that line numbers are included in module import errors. +# Verifies golang.org/issue/34393. + +go list -e -deps -f '{{with .Error}}{{.Pos}}: {{.Err}}{{end}}' ./main +stdout 'bad[/\\]bad.go:3:8: malformed module path "🐧.example.com/string": invalid char ''🐧''' + +-- go.mod -- +module m + +go 1.13 + +-- main/main.go -- +package main + +import _ "m/bad" + +func main() {} + +-- bad/bad.go -- +package bad + +import _ "🐧.example.com/string" diff --git a/libgo/go/cmd/go/testdata/script/mod_cache_rw.txt b/libgo/go/cmd/go/testdata/script/mod_cache_rw.txt new file mode 100644 index 00000000000..a5410764bc0 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_cache_rw.txt @@ -0,0 +1,49 @@ +# Regression test for golang.org/issue/31481. + +env GO111MODULE=on + +# golang.org/issue/31481: an explicit flag should make directories in the module +# cache writable in order to work around the historical inability of 'rm -rf' to +# forcibly remove files in unwritable directories. +go get -modcacherw -d rsc.io/quote@v1.5.2 +cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go + +# After adding an extraneous file, 'go mod verify' should fail. +! go mod verify + +# However, files within those directories should still be read-only to avoid +# accidental mutations. +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + +# If all 'go' commands ran with the flag, the system's 'rm' binary +# should be able to remove the module cache if the '-rf' flags are set. +[!windows] [exec:rm] exec rm -rf $GOPATH/pkg/mod +[!windows] [!exec:rm] go clean -modcache +[windows] [exec:cmd.exe] exec cmd.exe /c rmdir /s /q $GOPATH\pkg\mod +[windows] [!exec:cmd.exe] go clean -modcache +! exists $GOPATH/pkg/mod + +# The directories in the module cache should by default be unwritable, +# so that tests and tools will not accidentally add extraneous files to them. +# Windows does not respect FILE_ATTRIBUTE_READONLY on directories, according +# to MSDN, so there we disable testing whether the directory itself is +# unwritable. +go get -d rsc.io/quote@latest +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod +[!windows] [!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go +! exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go + + +# Repeat part of the test with 'go mod download' instead of 'go get' to verify +# -modcacherw is supported on 'go mod' subcommands. +go clean -modcache +go mod download -modcacherw rsc.io/quote +cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/extraneous_file.go +! go mod verify +[!root] ! cp $WORK/extraneous.txt $GOPATH/pkg/mod/rsc.io/quote@v1.5.2/go.mod + + +-- $WORK/extraneous.txt -- +module oops +-- go.mod -- +module golang.org/issue/31481 diff --git a/libgo/go/cmd/go/testdata/script/mod_convert_tsv_insecure.txt b/libgo/go/cmd/go/testdata/script/mod_convert_tsv_insecure.txt new file mode 100644 index 00000000000..ddb0c081996 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_convert_tsv_insecure.txt @@ -0,0 +1,27 @@ +env GO111MODULE=on + +[!net] skip +[!exec:git] skip + +# secure fetch should report insecure warning +cd $WORK/test +go mod init +stderr 'redirected .* to insecure URL' + +# insecure fetch should not +env GOINSECURE=*.golang.org +rm go.mod +go mod init +! stderr 'redirected .* to insecure URL' + +# insecure fetch invalid path should report insecure warning +env GOINSECURE=foo.golang.org +rm go.mod +go mod init +stderr 'redirected .* to insecure URL' + +-- $WORK/test/dependencies.tsv -- +vcs-test.golang.org/insecure/go/insecure git 6fecd21f7c0c 2019-09-04T18:39:48Z + +-- $WORK/test/x.go -- +package x // import "m" diff --git a/libgo/go/cmd/go/testdata/script/mod_convert_vendor_json.txt b/libgo/go/cmd/go/testdata/script/mod_convert_vendor_json.txt index 47d111d4c13..df6db36574f 100644 --- a/libgo/go/cmd/go/testdata/script/mod_convert_vendor_json.txt +++ b/libgo/go/cmd/go/testdata/script/mod_convert_vendor_json.txt @@ -10,7 +10,7 @@ stderr '\s*cd \.\. && go mod init' # The command we suggested should succeed. cd .. go mod init -go list -m all +go list -m stdout '^m$' -- $WORK/test/vendor/vendor.json -- diff --git a/libgo/go/cmd/go/testdata/script/mod_convert_vendor_manifest.txt b/libgo/go/cmd/go/testdata/script/mod_convert_vendor_manifest.txt index 68edb9dc292..8b6a1414be2 100644 --- a/libgo/go/cmd/go/testdata/script/mod_convert_vendor_manifest.txt +++ b/libgo/go/cmd/go/testdata/script/mod_convert_vendor_manifest.txt @@ -10,7 +10,7 @@ stderr '\s*cd \.\. && go mod init' # The command we suggested should succeed. cd .. go mod init -go list -m all +go list -m stdout '^m$' -- $WORK/test/vendor/manifest -- diff --git a/libgo/go/cmd/go/testdata/script/mod_doc.txt b/libgo/go/cmd/go/testdata/script/mod_doc.txt index d7aa553c1d3..aac3db00be1 100644 --- a/libgo/go/cmd/go/testdata/script/mod_doc.txt +++ b/libgo/go/cmd/go/testdata/script/mod_doc.txt @@ -36,6 +36,35 @@ go doc rsc.io/quote ! stdout 'Package quote is located in a GOPATH workspace.' stdout 'Package quote collects pithy sayings.' +# Check that a sensible error message is printed when a package is not found. +env GOPROXY=off +! go doc example.com/hello +stderr '^doc: cannot find module providing package example.com/hello: module lookup disabled by GOPROXY=off$' + +# When in a module with a vendor directory, doc should use the vendored copies +# of the packages. 'std' and 'cmd' are convenient examples of such modules. +# +# When in those modules, the "// import" comment should refer to the same import +# path used in source code, not to the absolute path relative to GOROOT. + +cd $GOROOT/src +go doc cryptobyte +stdout '// import "golang.org/x/crypto/cryptobyte"' + +cd $GOROOT/src/cmd/go +go doc modfile +stdout '// import "golang.org/x/mod/modfile"' + +# When outside of the 'std' module, its vendored packages +# remain accessible using the 'vendor/' prefix, but report +# the correct "// import" comment as used within std. +cd $GOPATH +go doc vendor/golang.org/x/crypto/cryptobyte +stdout '// import "vendor/golang.org/x/crypto/cryptobyte"' + +go doc cmd/vendor/golang.org/x/mod/modfile +stdout '// import "cmd/vendor/golang.org/x/mod/modfile"' + -- go.mod -- module x require rsc.io/quote v1.5.2 diff --git a/libgo/go/cmd/go/testdata/script/mod_download.txt b/libgo/go/cmd/go/testdata/script/mod_download.txt index 9eb3140c332..3573928a933 100644 --- a/libgo/go/cmd/go/testdata/script/mod_download.txt +++ b/libgo/go/cmd/go/testdata/script/mod_download.txt @@ -4,6 +4,7 @@ env GOPROXY=$GOPROXY/quiet # download with version should print nothing go mod download rsc.io/quote@v1.5.0 ! stdout . +! stderr . exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.info exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.mod @@ -17,7 +18,6 @@ stderr 'this.domain.is.invalid' stdout '"Error": ".*this.domain.is.invalid.*"' # download -json with version should print JSON -# and download the .info file for the 'latest' version. go mod download -json 'rsc.io/quote@<=v1.5.0' stdout '^\t"Path": "rsc.io/quote"' stdout '^\t"Version": "v1.5.0"' @@ -28,14 +28,13 @@ stdout '^\t"Sum": "h1:6fJa6E\+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE="' # hash of stdout '^\t"GoModSum": "h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe\+TKr0="' ! stdout '"Error"' -exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info - # download queries above should not have added to go.mod. go list -m all ! stdout rsc.io # add to go.mod so we can test non-query downloads go mod edit -require rsc.io/quote@v1.5.2 +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip @@ -95,6 +94,12 @@ stderr '^rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$' ! go mod download -json bad/path stdout '^\t"Error": "module bad/path: not a known dependency"' +# download main module returns an error +go mod download m +stderr '^go mod download: skipping argument m that resolves to the main module\n' +go mod download m@latest +stderr '^go mod download: skipping argument m@latest that resolves to the main module\n' + # allow go mod download without go.mod env GO111MODULE=auto rm go.mod @@ -102,5 +107,11 @@ rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.2.1.zip go mod download rsc.io/quote@v1.2.1 exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.2.1.zip +# download -x with version should print +# the underlying commands such as contacting GOPROXY. +go mod download -x rsc.io/quote@v1.0.0 +! stdout . +stderr 'get '$GOPROXY + -- go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/script/mod_download_json.txt b/libgo/go/cmd/go/testdata/script/mod_download_json.txt new file mode 100644 index 00000000000..01c35dd9937 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_download_json.txt @@ -0,0 +1,10 @@ +env GO111MODULE=on +env GOPROXY=$GOPROXY/quiet +env GOSUMDB=$sumdb' '$proxy/sumdb-wrong + +# download -json with version should print JSON on sumdb failure +! go mod download -json 'rsc.io/quote@<=v1.5.0' +stdout '"Error": ".*verifying module' + +-- go.mod -- +module m diff --git a/libgo/go/cmd/go/testdata/script/mod_download_latest.txt b/libgo/go/cmd/go/testdata/script/mod_download_latest.txt deleted file mode 100644 index 60d860e4da4..00000000000 --- a/libgo/go/cmd/go/testdata/script/mod_download_latest.txt +++ /dev/null @@ -1,20 +0,0 @@ -env GO111MODULE=on - -# If the module is the latest version of itself, -# the Latest field should be set. -go mod download -json rsc.io/quote@v1.5.2 -stdout '"Latest":\s*true' - -# If the module is older than latest, the field should be unset. -go mod download -json rsc.io/quote@v1.5.1 -! stdout '"Latest":' - -# If the module is newer than "latest", the field should be unset... -go mod download -json rsc.io/quote@v1.5.3-pre1 -! stdout '"Latest":' - -# ...even if that version is also what is required by the main module. -go mod init example.com -go mod edit -require rsc.io/quote@v1.5.3-pre1 -go mod download -json rsc.io/quote@v1.5.3-pre1 -! stdout '"Latest":' diff --git a/libgo/go/cmd/go/testdata/script/mod_download_replace_file.txt b/libgo/go/cmd/go/testdata/script/mod_download_replace_file.txt new file mode 100644 index 00000000000..f6ab4fe91f0 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_download_replace_file.txt @@ -0,0 +1,16 @@ +# This test checks that 'go mod download' produces no output for +# the main module (when specified implicitly) and for a module replaced +# with a file path. +# Verifies golang.org/issue/35505. +go mod download -json all +cmp stdout no-output + +-- go.mod -- +module example.com/a + +require example.com/b v1.0.0 + +replace example.com/b => ./local/b +-- local/b/go.mod -- +module example.com/b +-- no-output -- diff --git a/libgo/go/cmd/go/testdata/script/mod_edit.txt b/libgo/go/cmd/go/testdata/script/mod_edit.txt index 42007b13d09..898d8524acf 100644 --- a/libgo/go/cmd/go/testdata/script/mod_edit.txt +++ b/libgo/go/cmd/go/testdata/script/mod_edit.txt @@ -52,6 +52,12 @@ go mod init a.a/b/c go mod edit -module x.x/y/z cmpenv go.mod go.mod.edit +# golang.org/issue/30513: don't require go-gettable module paths. +cd $WORK/local +go mod init foo +go mod edit -module local-only -require=other-local@v1.0.0 -replace other-local@v1.0.0=./other +cmpenv go.mod go.mod.edit + -- x.go -- package x @@ -159,6 +165,14 @@ exclude x.1 v1.2.0 replace x.1 => y.1/v2 v2.3.6 require x.3 v1.99.0 +-- $WORK/local/go.mod.edit -- +module local-only + +go $goversion + +require other-local v1.0.0 + +replace other-local v1.0.0 => ./other -- $WORK/go.mod.badfmt -- module x.x/y/z diff --git a/libgo/go/cmd/go/testdata/script/mod_edit_go.txt b/libgo/go/cmd/go/testdata/script/mod_edit_go.txt index 428510293f0..0f4e093573e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_edit_go.txt +++ b/libgo/go/cmd/go/testdata/script/mod_edit_go.txt @@ -1,6 +1,6 @@ # Test support for go mod -edit to set language version. -[gccgo] stop +[gccgo] skip env GO111MODULE=on ! go build diff --git a/libgo/go/cmd/go/testdata/script/mod_empty_err.txt b/libgo/go/cmd/go/testdata/script/mod_empty_err.txt new file mode 100644 index 00000000000..729f848156d --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_empty_err.txt @@ -0,0 +1,36 @@ +# This test checks error messages for non-existant packages in module mode. +# Veries golang.org/issue/35414 +env GO111MODULE=on +cd $WORK + +go list -e -f {{.Error}} . +stdout 'package \.: no Go files in \$WORK' + +go list -e -f {{.Error}} ./empty +stdout 'package \./empty: no Go files in \$WORK[/\\]empty' + +go list -e -f {{.Error}} ./exclude +stdout 'package \./exclude: build constraints exclude all Go files in \$WORK[/\\]exclude' + +go list -e -f {{.Error}} ./missing +stdout 'package \./missing: cannot find package "." in:\s*\$WORK[/\\]missing' + +# use 'go build -n' because 'go list' reports no error. +! go build -n ./testonly +stderr 'example.com/m/testonly: no non-test Go files in \$WORK[/\\]testonly' + +-- $WORK/go.mod -- +module example.com/m + +go 1.14 + +-- $WORK/empty/empty.txt -- +-- $WORK/exclude/exclude.go -- +// +build exclude + +package exclude +-- $WORK/testonly/testonly_test.go -- +package testonly_test +-- $WORK/excluded-stdout -- +package ./excluded: cannot find package "." in: + $WORK/excluded diff --git a/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt b/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt index fd7de130024..4911fbb6138 100644 --- a/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt +++ b/libgo/go/cmd/go/testdata/script/mod_fs_patterns.txt @@ -1,7 +1,6 @@ -# File system pattern searches should skip sub-modules and vendor directories. - env GO111MODULE=on +# File system pattern searches should skip sub-modules and vendor directories. cd x # all packages @@ -40,6 +39,24 @@ stderr '^can.t load package: package ./nonexist: cannot find package "." in:\n\t ! stderr 'import lookup disabled' stderr 'can.t load package: package ./go.mod: cannot find package' + +# File system paths and patterns should allow the '@' character. +cd ../@at +go list $PWD +stdout '^at$' +go list $PWD/... +stdout '^at$' + +# The '@' character is not allowed in directory paths that are part of +# a package path. +cd ../badat/bad@ +! go list . +stderr 'directory . outside available modules' +! go list $PWD +stderr 'directory . outside available modules' +! go list $PWD/... +stderr 'directory . outside available modules' + -- x/go.mod -- module m @@ -64,3 +81,17 @@ package z -- x/y/z/w/w.go -- package w + +-- @at/go.mod -- +module at + +go 1.14 +-- @at/at.go -- +package at + +-- badat/go.mod -- +module badat + +go 1.14 +-- badat/bad@/bad.go -- +package bad diff --git a/libgo/go/cmd/go/testdata/script/mod_get_direct.txt b/libgo/go/cmd/go/testdata/script/mod_get_direct.txt new file mode 100644 index 00000000000..42ccbcd38a1 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_get_direct.txt @@ -0,0 +1,20 @@ +# Regression test for golang.org/issue/34092: with an empty module cache, +# 'GOPROXY=direct go get golang.org/x/tools/gopls@master' did not correctly +# resolve the pseudo-version for its dependency on golang.org/x/tools. + +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +go list -m cloud.google.com/go@master +! stdout 'v0.0.0-' + +-- go.mod -- +module example.com + +go 1.14 +-- go.sum -- diff --git a/libgo/go/cmd/go/testdata/script/mod_get_insecure_redirect.txt b/libgo/go/cmd/go/testdata/script/mod_get_insecure_redirect.txt new file mode 100644 index 00000000000..3755f176332 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_get_insecure_redirect.txt @@ -0,0 +1,34 @@ +# golang.org/issue/29591: 'go get' was following plain-HTTP redirects even without -insecure. + +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +! go get -d vcs-test.golang.org/insecure/go/insecure +stderr 'redirected .* to insecure URL' + +go get -d -insecure vcs-test.golang.org/insecure/go/insecure + +# insecure host +env GOINSECURE=vcs-test.golang.org +go clean -modcache +go get -d vcs-test.golang.org/insecure/go/insecure + +# insecure glob host +env GOINSECURE=*.golang.org +go clean -modcache +go get -d vcs-test.golang.org/insecure/go/insecure + +# insecure multiple host +env GOINSECURE=somewhere-else.com,*.golang.org +go clean -modcache +go get -d vcs-test.golang.org/insecure/go/insecure + +# different insecure host does not fetch +env GOINSECURE=somewhere-else.com +go clean -modcache +! go get -d vcs-test.golang.org/insecure/go/insecure +stderr 'redirected .* to insecure URL' diff --git a/libgo/go/cmd/go/testdata/script/mod_get_major.txt b/libgo/go/cmd/go/testdata/script/mod_get_major.txt new file mode 100644 index 00000000000..367ede9ded4 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_get_major.txt @@ -0,0 +1,23 @@ +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# golang.org/issue/34383: if a module path ends in a major-version suffix, +# ensure that 'direct' mode can resolve the package to a module. + +go get -d vcs-test.golang.org/git/v3pkg.git/v3@v3.0.0 + +go list -m vcs-test.golang.org/git/v3pkg.git/v3 +stdout '^vcs-test.golang.org/git/v3pkg.git/v3 v3.0.0$' + +go get -d vcs-test.golang.org/git/empty-v2-without-v1.git/v2@v2.0.0 + +go list -m vcs-test.golang.org/git/empty-v2-without-v1.git/v2 +stdout '^vcs-test.golang.org/git/empty-v2-without-v1.git/v2 v2.0.0$' + +-- go.mod -- +module example.com +go 1.13 diff --git a/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt b/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt index b1838f824a6..5c197bb0b82 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt @@ -11,6 +11,5 @@ go mod init m cmp stderr stderr-expected -- stderr-expected -- -go: finding example.com/newcycle v1.0.0 go get: inconsistent versions: example.com/newcycle/a@v1.0.0 requires example.com/newcycle/a@v1.0.1 (not example.com/newcycle/a@v1.0.0) diff --git a/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt b/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt index bfab70090cf..8adc4b0c065 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt @@ -10,11 +10,11 @@ grep 'require rsc.io/quote' go.mod cp go.mod.orig go.mod ! go get -d rsc.io/quote/x... -stderr 'go get rsc.io/quote/x...: module rsc.io/quote@upgrade \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x...' +stderr 'go get rsc.io/quote/x...: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x...' ! grep 'require rsc.io/quote' go.mod ! go get -d rsc.io/quote/x/... -stderr 'go get rsc.io/quote/x/...: module rsc.io/quote@upgrade \(v1.5.2\) found, but does not contain packages matching rsc.io/quote/x/...' +stderr 'go get rsc.io/quote/x/...: module rsc.io/quote@upgrade found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x/...' ! grep 'require rsc.io/quote' go.mod # If a pattern matches no packages within a module, the module should not diff --git a/libgo/go/cmd/go/testdata/script/mod_get_svn.txt b/libgo/go/cmd/go/testdata/script/mod_get_svn.txt index cd19d99dbcc..3817fce9b61 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_svn.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_svn.txt @@ -1,17 +1,27 @@ [!net] skip [!exec:svn] skip +# 'go get' will fall back to svn+ssh once svn fails over protocols like https. +# If vcs-test.golang.org isn't in the user's known_hosts file, this will result +# in an ssh prompt, which will stop 'go test' entirely +# +# Unfortunately, there isn't a way to globally disable host checking for ssh, +# without modifying the real system's or user's configs. Changing $HOME won't +# affect ssh either, as it ignores the environment variable entirely. +# +# However, a useful trick is pointing SVN_SSH to a program that doesn't exist, +# resulting in svn skipping ssh entirely. Alternatives like +# SVN_SSH="ssh -o StrictHostKeyChecking=no" didn't avoid the prompt. +env SVN_SSH="svn_do_not_use_ssh" + env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off -# Attempting to get a module zip using svn should fail with a reasonable -# message instead of a panic. -# TODO(golang.org/issue/26092): Really, it shouldn't fail at all. -! go get -d vcs-test.golang.org/svn/hello.svn -stderr 'ReadZip not implemented for svn' -! go install . -stderr 'ReadZip not implemented for svn' +# Attempting to get a module zip using svn should succeed. +go get vcs-test.golang.org/svn/hello.svn@000000000001 +exists $GOPATH/pkg/mod/cache/download/vcs-test.golang.org/svn/hello.svn/@v/v0.0.0-20170922011245-000000000001.zip +exists $GOPATH/bin/hello.svn$GOEXE # Attempting to get a nonexistent module using svn should fail with a # reasonable message instead of a panic. @@ -21,7 +31,6 @@ stderr 'go get vcs-test.golang.org/svn/nonexistent.svn: no matching versions for -- go.mod -- module golang/go/issues/28943/main --- main.go -- -package main -import _ "vcs-test.golang.org/svn/hello.svn" -func main() {} +-- go.sum -- +vcs-test.golang.org/svn/hello.svn v0.0.0-20170922011245-000000000001 h1:rZjvboXMfQICKXdhx/QHqJ2Y/AQsJVrXnwGqwcTxQiw= +vcs-test.golang.org/svn/hello.svn v0.0.0-20170922011245-000000000001/go.mod h1:0memnh/BRLuxiK2zF4rvUgz6ts/fhhB28l3ULFWPusc= diff --git a/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt b/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt new file mode 100644 index 00000000000..7b5d90c50b5 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt @@ -0,0 +1,30 @@ +# go list should succeed to load a package ending with ".go" if the path does +# not correspond to an existing local file. Listing a pattern ending with +# ".go/" should try to list a package regardless of whether a file exists at the +# path without the suffixed "/" or not. +go list example.com/dotgo.go +stdout ^example.com/dotgo.go$ +go list example.com/dotgo.go/ +stdout ^example.com/dotgo.go$ + +# go get -d should succeed in either case, with or without a version. +# Arguments are interpreted as packages or package patterns with versions, +# not source files. +go get -d example.com/dotgo.go +go get -d example.com/dotgo.go/ +go get -d example.com/dotgo.go@v1.0.0 +go get -d example.com/dotgo.go/@v1.0.0 + +# go get (without -d) should also succeed in either case. +[short] skip +go get example.com/dotgo.go +go get example.com/dotgo.go/ +go get example.com/dotgo.go@v1.0.0 +go get example.com/dotgo.go/@v1.0.0 + +-- go.mod -- +module m + +go 1.13 + +require example.com/dotgo.go v1.0.0 diff --git a/libgo/go/cmd/go/testdata/script/mod_getmode_vendor.txt b/libgo/go/cmd/go/testdata/script/mod_getmode_vendor.txt index 7e1f6aa323e..d3df2078b07 100644 --- a/libgo/go/cmd/go/testdata/script/mod_getmode_vendor.txt +++ b/libgo/go/cmd/go/testdata/script/mod_getmode_vendor.txt @@ -6,14 +6,21 @@ env GOPATH=$WORK/empty env GOPROXY=file:///nonexist go list -mod=vendor -go list -mod=vendor -m -f '{{.Path}} {{.Version}} {{.Dir}}' all +go list -mod=vendor -f '{{with .Module}}{{.Path}} {{.Version}}{{end}} {{.Dir}}' all stdout '^rsc.io/quote v1.5.1 .*vendor[\\/]rsc.io[\\/]quote$' -stdout '^golang.org/x/text v0.0.0.* .*vendor[\\/]golang.org[\\/]x[\\/]text$' +stdout '^golang.org/x/text v0.0.0.* .*vendor[\\/]golang.org[\\/]x[\\/]text[\\/]language$' ! go list -mod=vendor -m rsc.io/quote@latest -stderr 'module lookup disabled by -mod=vendor' +stderr 'go list -m: rsc.io/quote@latest: cannot query module due to -mod=vendor' ! go get -mod=vendor -u -stderr 'go get: disabled by -mod=vendor' +stderr 'flag provided but not defined: -mod' + +# Since we don't have a complete module graph, 'go list -m' queries +# that require the complete graph should fail with a useful error. +! go list -mod=vendor -m all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' +! go list -mod=vendor -m ... +stderr 'go list -m: can''t match module patterns using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' -- go.mod -- module x diff --git a/libgo/go/cmd/go/testdata/script/mod_getx.txt b/libgo/go/cmd/go/testdata/script/mod_getx.txt new file mode 100644 index 00000000000..ccb8d1375aa --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_getx.txt @@ -0,0 +1,14 @@ +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# 'go get -x' should log URLs with an HTTP or HTTPS scheme. +# A bug had caused us to log schemeless URLs instead. +go get -x -d golang.org/x/text@v0.1.0 +stderr '^# get https://golang.org/x/text\?go-get=1$' +stderr '^# get https://golang.org/x/text\?go-get=1: 200 OK \([0-9.]+s\)$' +! stderr '^# get //.*' diff --git a/libgo/go/cmd/go/testdata/script/mod_go_version_mixed.txt b/libgo/go/cmd/go/testdata/script/mod_go_version_mixed.txt new file mode 100644 index 00000000000..d6216ae2443 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_go_version_mixed.txt @@ -0,0 +1,43 @@ +# Test that dependencies can use Go language features newer than the +# Go version specified by the main module. + +env GO111MODULE=on + +go build + +-- go.mod -- +module m +go 1.12 +require ( + sub.1 v1.0.0 +) +replace ( + sub.1 => ./sub +) + +-- x.go -- +package x + +import "sub.1" + +func F() { sub.F(0, 0) } + +var A sub.Alias +var D sub.Defined + +-- sub/go.mod -- +module m +go 1.14 + +-- sub/sub.go -- +package sub + +// signed shift counts added in Go 1.13 +func F(l, r int) int { return l << r } + +type m1 interface { M() } +type m2 interface { M() } + +// overlapping interfaces added in Go 1.14 +type Alias = interface { m1; m2; M() } +type Defined interface { m1; m2; M() } diff --git a/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt b/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt new file mode 100644 index 00000000000..2e08ae03aa3 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_goroot_errors.txt @@ -0,0 +1,55 @@ +env GO111MODULE=on + +[gccgo] skip + +# Regression test for https://golang.org/issue/34769. +# Missing standard-library imports should refer to GOROOT rather than +# complaining about a malformed module path. +# This is especially important when GOROOT is set incorrectly, +# since such an error will occur for every package in std. + +# Building a nonexistent std package directly should fail usefully. + +! go build -mod=readonly nonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^can''t load package: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +! go build nonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^can''t load package: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +# Building a nonexistent std package indirectly should also fail usefully. + +! go build -mod=readonly ./importnonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^importnonexist[/\\]x.go:2:8: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +! go build ./importnonexist +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr '^importnonexist[/\\]x.go:2:8: package nonexist is not in GOROOT \('$GOROOT'[/\\]src[/\\]nonexist\)$' + +# Building an *actual* std package should fail if GOROOT is set to something bogus. + +[!short] go build ./importjson # Prove that it works when GOROOT is valid. + +env GOROOT=$WORK/not-a-valid-goroot +! go build ./importjson +! stderr 'import lookup disabled' +! stderr 'missing dot' +stderr 'importjson[/\\]x.go:2:8: package encoding/json is not in GOROOT \('$WORK'[/\\]not-a-valid-goroot[/\\]src[/\\]encoding[/\\]json\)$' + +-- go.mod -- +module example.com +go 1.14 +-- importnonexist/x.go -- +package importnonexist +import _ "nonexist" +-- importjson/x.go -- +package importjson +import _ "encoding/json" +-- $WORK/not-a-valid-goroot/README -- +This directory is not a valid GOROOT. diff --git a/libgo/go/cmd/go/testdata/script/mod_in_testdata_dir.txt b/libgo/go/cmd/go/testdata/script/mod_in_testdata_dir.txt new file mode 100644 index 00000000000..f582569798b --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_in_testdata_dir.txt @@ -0,0 +1,45 @@ +# Regression test for golang.org/issue/28481: +# 'mod tidy' removed dependencies if the module root was +# within a directory named 'testdata' or '_foo'. + +env GO111MODULE=on + +# A module should be allowed in a directory named testdata. +cd $WORK/testdata +go mod init testdata.tld/foo + +# Building a package within that module should resolve its dependencies. +go build +grep 'rsc.io/quote' go.mod + +# Tidying the module should preserve those dependencies. +go mod tidy +grep 'rsc.io/quote' go.mod + +[short] stop + +# Vendoring the module's dependencies should work too. +go mod vendor +exists vendor/rsc.io/quote + +# The same should work in directories with names starting with underscores. +cd $WORK/_ignored +go mod init testdata.tld/foo + +go build +grep 'rsc.io/quote' go.mod + +go mod tidy +grep 'rsc.io/quote' go.mod + +go mod vendor +exists vendor/rsc.io/quote + +-- $WORK/testdata/main.go -- +package foo + +import _ "rsc.io/quote" +-- $WORK/_ignored/main.go -- +package foo + +import _ "rsc.io/quote" diff --git a/libgo/go/cmd/go/testdata/script/mod_internal.txt b/libgo/go/cmd/go/testdata/script/mod_internal.txt index 5a361a4f424..1193d528ece 100644 --- a/libgo/go/cmd/go/testdata/script/mod_internal.txt +++ b/libgo/go/cmd/go/testdata/script/mod_internal.txt @@ -2,8 +2,7 @@ env GO111MODULE=on [short] skip # golang.org/x/internal should be importable from other golang.org/x modules. -rm go.mod -go mod init golang.org/x/anything +go mod edit -module=golang.org/x/anything go build . # ...and their tests... @@ -20,8 +19,7 @@ stderr 'use of internal package golang.org/x/.* not allowed' stderr 'use of internal package internal/testenv not allowed' # Dependencies should be able to use their own internal modules... -rm go.mod -go mod init golang.org/notx +go mod edit -module=golang.org/notx go build ./throughdep # ... but other modules should not, even if they have transitive dependencies. @@ -34,8 +32,7 @@ stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' # Replacing an internal module should keep it internal to the same paths. -rm go.mod -go mod init golang.org/notx +go mod edit -module=golang.org/notx go mod edit -replace golang.org/x/internal=./replace/golang.org/notx/internal go build ./throughdep @@ -50,6 +47,9 @@ go build ./throughdep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' +-- go.mod -- +module TBD +go 1.12 -- useinternal.go -- package useinternal import _ "golang.org/x/internal/subtle" diff --git a/libgo/go/cmd/go/testdata/script/mod_issue35317.txt b/libgo/go/cmd/go/testdata/script/mod_issue35317.txt new file mode 100644 index 00000000000..92416a54e47 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_issue35317.txt @@ -0,0 +1,8 @@ +# Regression test for golang.org/issue/35317: +# 'go get' with multiple module-only arguments was racy. + +env GO111MODULE=on +[short] skip + +go mod init example.com +go get golang.org/x/text@v0.3.0 golang.org/x/internal@v0.1.0 golang.org/x/exp@none diff --git a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt index a8023cce9c5..f6994c1e666 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt @@ -12,10 +12,10 @@ stdout ^math$ go list -f '{{.ImportPath}}' . stdout ^x$ ! go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 -stderr '^can.t load package: package '$WORK'[/\\]gopath/pkg/mod/rsc.io/quote@v1.5.2: can only use path@version syntax with .go get.' +stderr '^can.t load package: package '$WORK'[/\\]gopath[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2: can only use path@version syntax with .go get.' go list -e -f '{{with .Error}}{{.}}{{end}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 -stdout '^package '$WORK'[/\\]gopath/pkg/mod/rsc.io/quote@v1.5.2: can only use path@version syntax with .go get.' +stdout '^package '$WORK'[/\\]gopath[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2: can only use path@version syntax with .go get.' go mod download rsc.io/quote@v1.5.2 go list -f '{{.ImportPath}}' $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 stdout '^rsc.io/quote$' diff --git a/libgo/go/cmd/go/testdata/script/mod_list_e_readonly.txt b/libgo/go/cmd/go/testdata/script/mod_list_e_readonly.txt new file mode 100644 index 00000000000..4969434e52b --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_list_e_readonly.txt @@ -0,0 +1,15 @@ +# 'go list -mod=readonly -e should attribute errors +# to individual missing packages. +# Verifies golang.org/issue/34829. +go list -mod=readonly -e -deps -f '{{if .Error}}{{.ImportPath}}: {{.Error}}{{end}}' . +stdout 'example.com/missing: use.go:3:8: cannot find module providing package example.com/missing: import lookup disabled by -mod=readonly' + +-- go.mod -- +module example.com/m + +go 1.14 + +-- use.go -- +package use + +import _ "example.com/missing" diff --git a/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt b/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt index f2d06490920..474df0dc269 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt @@ -1,28 +1,8 @@ env GO111MODULE=on -# If the current version is not latest, 'go list -u' should include its upgrade. go list -m -u all stdout 'rsc.io/quote v1.2.0 \[v1\.5\.2\]' -# If the current version is latest, 'go list -u' should omit the upgrade. -go get -d rsc.io/quote@v1.5.2 -go list -m -u all -stdout 'rsc.io/quote v1.5.2$' - -# If the current version is newer than latest, 'go list -u' should -# omit the upgrade. -go get -d rsc.io/quote@v1.5.3-pre1 -go list -m -u all -stdout 'rsc.io/quote v1.5.3-pre1$' - -# If the current build list has a higher version and the user asks about -# a lower one, -u should report the upgrade for the lower one -# but leave the build list unchanged. -go list -m -u rsc.io/quote@v1.5.1 -stdout 'rsc.io/quote v1.5.1 \[v1.5.2\]$' -go list -m -u rsc.io/quote -stdout 'rsc.io/quote v1.5.3-pre1$' - -- go.mod -- module x require rsc.io/quote v1.2.0 diff --git a/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt b/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt index b97a2e6eaba..2c532f1fda3 100644 --- a/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt +++ b/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt @@ -56,11 +56,13 @@ import ( func Test(t *testing.T) {} -- update-main-expected -- +go: example.com/badchain/c upgrade => v1.1.0 go get: example.com/badchain/c@v1.0.0 updating to example.com/badchain/c@v1.1.0: parsing go.mod: module declares its path as: badchain.example.com/c but was required as: example.com/badchain/c -- update-a-expected -- +go: example.com/badchain/a upgrade => v1.1.0 go get: example.com/badchain/a@v1.1.0 requires example.com/badchain/b@v1.1.0 requires example.com/badchain/c@v1.1.0: parsing go.mod: @@ -73,11 +75,13 @@ go: example.com/badchain/a@v1.1.0 requires module declares its path as: badchain.example.com/c but was required as: example.com/badchain/c -- list-missing-expected -- +go: found example.com/badchain/c in example.com/badchain/c v1.1.0 go: m/use imports example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: module declares its path as: badchain.example.com/c but was required as: example.com/badchain/c -- list-missing-test-expected -- +go: found example.com/badchain/c in example.com/badchain/c v1.1.0 go: m/testuse tested by m/testuse.test imports example.com/badchain/c: example.com/badchain/c@v1.1.0: parsing go.mod: diff --git a/libgo/go/cmd/go/testdata/script/mod_missing_repo.txt b/libgo/go/cmd/go/testdata/script/mod_missing_repo.txt new file mode 100644 index 00000000000..8dae85fa88d --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_missing_repo.txt @@ -0,0 +1,15 @@ +# Regression test for golang.org/issue/34094: modules hosted within gitlab.com +# subgroups could not be fetched because the server returned bogus go-import +# tags for prefixes of the module path. + +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +! go get -d vcs-test.golang.org/go/missingrepo/missingrepo-git +stderr 'vcs-test.golang.org/go/missingrepo/missingrepo-git: git ls-remote .*: exit status .*' + +go get -d vcs-test.golang.org/go/missingrepo/missingrepo-git/notmissing diff --git a/libgo/go/cmd/go/testdata/script/mod_missingpkg_prerelease.txt b/libgo/go/cmd/go/testdata/script/mod_missingpkg_prerelease.txt index 6203606c22d..319ff855872 100644 --- a/libgo/go/cmd/go/testdata/script/mod_missingpkg_prerelease.txt +++ b/libgo/go/cmd/go/testdata/script/mod_missingpkg_prerelease.txt @@ -3,6 +3,11 @@ env GO111MODULE=on ! go list use.go stderr 'example.com/missingpkg/deprecated: package provided by example.com/missingpkg at latest version v1.0.0 but not at required version v1.0.1-beta' +-- go.mod -- +module m + +go 1.14 + -- use.go -- package use diff --git a/libgo/go/cmd/go/testdata/script/mod_modinfo.txt b/libgo/go/cmd/go/testdata/script/mod_modinfo.txt index 1e7dd44a13d..731f53c6721 100644 --- a/libgo/go/cmd/go/testdata/script/mod_modinfo.txt +++ b/libgo/go/cmd/go/testdata/script/mod_modinfo.txt @@ -3,7 +3,8 @@ # when module is enabled. env GO111MODULE=on -[gccgo] stop +# gccgo doesn't support reading modinfo in init functions. +[gccgo] skip cd x go mod edit -require=rsc.io/quote@v1.5.2 diff --git a/libgo/go/cmd/go/testdata/script/mod_outside.txt b/libgo/go/cmd/go/testdata/script/mod_outside.txt index 4182e71dde1..03ef576168c 100644 --- a/libgo/go/cmd/go/testdata/script/mod_outside.txt +++ b/libgo/go/cmd/go/testdata/script/mod_outside.txt @@ -17,7 +17,7 @@ go list -m stdout '^command-line-arguments$' # 'go list' in the working directory should fail even if there is a a 'package # main' present: without a main module, we do not know its package path. -! go list ./foo +! go list ./needmod stderr 'cannot find main module' # 'go list all' lists the transitive import graph of the main module, @@ -25,8 +25,6 @@ stderr 'cannot find main module' go list all ! stdout . stderr 'warning: "all" matched no packages' -go list -m all -stderr 'warning: pattern "all" matched no module dependencies' # 'go list' on standard-library packages should work, since they do not depend # on the contents of any module. @@ -38,7 +36,7 @@ go list $GOROOT/src/fmt stdout '^fmt$' # 'go list' should work with file arguments. -go list ./foo/foo.go +go list ./needmod/needmod.go stdout 'command-line-arguments' # 'go list -m' with an explicit version should resolve that version. @@ -49,12 +47,22 @@ stdout 'example.com/version v1.1.0' go list -m -versions example.com/version stdout 'v1.0.0\s+v1.0.1\s+v1.1.0' -# 'go list -m all' does not include the dependencies of in the computation of 'all'. -go list -m example.com/printversion@v1.0.0 all -stdout 'example.com/printversion v1.0.0' -stderr 'warning: pattern "all" matched no module dependencies' +# 'go list -m all' should fail. "all" is not meaningful outside of a module. +! go list -m all +stderr 'go: cannot match "all": working directory is not part of a module' + +# 'go list -m all' should also fail. +! go list -m example.com/printversion@v1.0.0 all +stderr 'go: cannot match "all": working directory is not part of a module' ! stdout 'example.com/version' +# 'go list -m' with wildcards should fail. Wildcards match modules in the +# build list, so they aren't meaningful outside a module. +! go list -m ... +stderr 'go: cannot match "...": working directory is not part of a module' +! go list -m rsc.io/quote/... +stderr 'go: cannot match "rsc.io/quote/...": working directory is not part of a module' + # 'go clean' should skip the current directory if it isn't in a module. go clean -n @@ -66,10 +74,9 @@ go mod graph ! stdout . ! stderr . -# 'go mod why' should report that nothing is a dependency. -go mod why -m example.com/version -stdout 'does not need' - +# 'go mod why' should fail, since there is no main module to depend on anything. +! go mod why -m example.com/version +stderr 'cannot find main module' # 'go mod edit', 'go mod tidy', and 'go mod fmt' should fail: # there is no go.mod file to edit. @@ -81,21 +88,30 @@ stderr 'cannot find main module' stderr 'cannot find main module' +# 'go mod download' without arguments should report an error. +! go mod download +stderr 'no modules specified' + # 'go mod download' should download exactly the requested module without dependencies. rm -r $GOPATH/pkg/mod/cache/download/example.com go mod download example.com/printversion@v1.0.0 exists $GOPATH/pkg/mod/cache/download/example.com/printversion/@v/v1.0.0.zip ! exists $GOPATH/pkg/mod/cache/download/example.com/version/@v/v1.0.0.zip +# 'go mod download all' should fail. "all" is not meaningful outside of a module. +! go mod download all +stderr 'go: cannot match "all": working directory is not part of a module' + + # 'go mod vendor' should fail: it starts by clearing the existing vendor # directory, and we don't know where that is. ! go mod vendor stderr 'cannot find main module' -# 'go mod verify' should succeed: we have no modules to verify. -go mod verify -stdout 'all modules verified' -! stderr . + +# 'go mod verify' should fail: we have no modules to verify. +! go mod verify +stderr 'cannot find main module' # 'go get' without arguments implicitly operates on the main module, and thus @@ -104,14 +120,13 @@ stdout 'all modules verified' stderr 'cannot find main module' ! go get -u stderr 'cannot find main module' -! go get -u ./foo +! go get -u ./needmod stderr 'cannot find main module' # 'go get -u all' upgrades the transitive import graph of the main module, # which is empty. -go get -u all -! stdout . -stderr 'warning: "all" matched no packages' +! go get -u all +stderr 'go get all: cannot match "all": working directory is not part of a module' # 'go get' should check the proposed module graph for consistency, # even though we won't write it anywhere. @@ -126,35 +141,75 @@ exists $GOPATH/pkg/mod/example.com/version@v1.0.0 # 'go build' without arguments implicitly operates on the current directory, and should fail. -cd foo +cd needmod ! go build stderr 'cannot find main module' cd .. # 'go build' of a non-module directory should fail too. -! go build ./foo +! go build ./needmod stderr 'cannot find main module' -# However, 'go build' should succeed for standard-library packages. +# 'go build' of source files should fail if they import anything outside std. +! go build -n ./needmod/needmod.go +stderr 'needmod[/\\]needmod.go:10:2: cannot find module providing package example.com/version: working directory is not part of a module' + +# 'go build' of source files should succeed if they do not import anything outside std. +go build -n -o ignore ./stdonly/stdonly.go + +# 'go build' should succeed for standard-library packages. go build -n fmt -# TODO(golang.org/issue/28992): 'go doc' should document the latest version. -# For now it does not. +# 'go doc' without arguments implicitly operates on the current directory, and should fail. +# TODO(golang.org/issue/32027): currently, it succeeds. +cd needmod +go doc +cd .. + +# 'go doc' of a non-module directory should also succeed. +go doc ./needmod + +# 'go doc' should succeed for standard-library packages. +go doc fmt + +# 'go doc' should fail for a package path outside a module. ! go doc example.com/version -stderr 'no such package' +stderr 'doc: cannot find module providing package example.com/version: working directory is not part of a module' # 'go install' with a version should fail due to syntax. ! go install example.com/printversion@v1.0.0 stderr 'can only use path@version syntax with' +# 'go install' should fail if a package argument must be resolved to a module. +! go install example.com/printversion +stderr 'cannot find module providing package example.com/printversion: working directory is not part of a module' + +# 'go install' should fail if a source file imports a package that must be +# resolved to a module. +! go install ./needmod/needmod.go +stderr 'needmod[/\\]needmod.go:10:2: cannot find module providing package example.com/version: working directory is not part of a module' + + +# 'go run' with a verison should fail due to syntax. +! go run example.com/printversion@v1.0.0 +stderr 'can only use path@version syntax with' + +# 'go run' should fail if a package argument must be resolved to a module. +! go run example.com/printversion +stderr 'cannot find module providing package example.com/printversion: working directory is not part of a module' + +# 'go run' should fail if a source file imports a package that must be +# resolved to a module. +! go run ./needmod/needmod.go +stderr 'needmod[/\\]needmod.go:10:2: cannot find module providing package example.com/version: working directory is not part of a module' + # 'go fmt' should be able to format files outside of a module. -go fmt foo/foo.go +go fmt needmod/needmod.go # The remainder of the test checks dependencies by linking and running binaries. -[short] stop # 'go get' of a binary without a go.mod should install the requested version, # resolving outside dependencies to the latest available versions. @@ -180,39 +235,31 @@ stdout 'path is example.com/printversion' stdout 'main is example.com/printversion v1.0.0' stdout 'using example.com/version v1.0.1' -# 'go install' without a version should install the latest version -# using its minimal module requirements. -go install example.com/printversion -exec ../bin/printversion -stdout 'path is example.com/printversion' -stdout 'main is example.com/printversion v1.0.0' -stdout 'using example.com/version v1.0.0' - -# 'go run' should use 'main' as the effective module and import path. -go run ./foo/foo.go +# 'go run' should work with file arguments if they don't import anything +# outside std. +go run ./stdonly/stdonly.go stdout 'path is command-line-arguments$' stdout 'main is command-line-arguments \(devel\)' -stdout 'using example.com/version v1.1.0' # 'go generate' should work with file arguments. -[exec:touch] go generate ./foo/foo.go -[exec:touch] exists ./foo/gen.txt +[exec:touch] go generate ./needmod/needmod.go +[exec:touch] exists ./needmod/gen.txt # 'go install' should work with file arguments. -go install ./foo/foo.go +go install ./stdonly/stdonly.go # 'go test' should work with file arguments. -go test -v ./foo/foo_test.go -stdout 'foo was tested' +go test -v ./stdonly/stdonly_test.go +stdout 'stdonly was tested' # 'go vet' should work with file arguments. -go vet ./foo/foo.go +go vet ./stdonly/stdonly.go -- README.txt -- There is no go.mod file in the working directory. --- foo/foo.go -- +-- needmod/needmod.go -- //go:generate touch gen.txt package main @@ -237,7 +284,28 @@ func main() { } } --- foo/foo_test.go -- +-- stdonly/stdonly.go -- +package main + +import ( + "fmt" + "os" + "runtime/debug" +) + +func main() { + info, ok := debug.ReadBuildInfo() + if !ok { + panic("missing build info") + } + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + } +} + +-- stdonly/stdonly_test.go -- package main import ( @@ -245,6 +313,7 @@ import ( "testing" ) -func TestFoo(t *testing.T) { - fmt.Println("foo was tested") +func Test(t *testing.T) { + fmt.Println("stdonly was tested") } + diff --git a/libgo/go/cmd/go/testdata/script/mod_permissions.txt b/libgo/go/cmd/go/testdata/script/mod_permissions.txt new file mode 100644 index 00000000000..11fb4754f83 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_permissions.txt @@ -0,0 +1,57 @@ +# Regression test for golang.org/issue/34634: permissions for the go.sum and +# go.mod files should be preserved when overwriting them. + +env GO111MODULE=on +[short] skip + +# Skip platforms that do not have Unix-style file permissions. +[windows] skip +[plan9] skip + +chmod 0640 go.mod +chmod 0604 go.sum +go mod edit -module=golang.org/issue/34634 + +go build . +cmp go.mod go.mod.want +cmp go.sum go.sum.want + +go run . +stdout 'go.mod: 0640' +stdout 'go.sum: 0604' + +-- read_perm.go -- +package main + +import ( + "fmt" + "os" + _ "rsc.io/sampler" +) + +func main() { + for _, name := range []string{"go.mod", "go.sum"} { + fi, err := os.Stat(name) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", err) + continue + } + fmt.Printf("%s: 0%o\n", name, fi.Mode().Perm()) + } +} +-- go.mod -- +module TODO + +go 1.14 +-- go.sum -- +-- go.mod.want -- +module golang.org/issue/34634 + +go 1.14 + +require rsc.io/sampler v1.99.99 +-- go.sum.want -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:pvCbr/wm8HzDD3fVywevekufpn6tCGPY3spdHeZJEsw= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/sampler v1.99.99 h1:iMG9lbEG/8MdeR4lgL+Q8IcwbLNw7ijW7fTiK8Miqts= +rsc.io/sampler v1.99.99/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/libgo/go/cmd/go/testdata/script/mod_prefer_compatible.txt b/libgo/go/cmd/go/testdata/script/mod_prefer_compatible.txt new file mode 100644 index 00000000000..aa6260f63c8 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_prefer_compatible.txt @@ -0,0 +1,65 @@ +# Regression test for golang.org/issue/34189 and golang.org/issue/34165: +# @latest, @upgrade, and @patch should prefer compatible versions over +# +incompatible ones, even if offered by a proxy. + +[!net] skip + +env GO111MODULE=on +env GOPROXY= +env GOSUMDB= + +# github.com/russross/blackfriday v2.0.0+incompatible exists, +# and should be resolved if we ask for v2.0 explicitly. + +go list -m github.com/russross/blackfriday@v2.0 +stdout '^github.com/russross/blackfriday v2\.0\.0\+incompatible$' + +# blackfriday v1.5.2 has a go.mod file, so v1.5.2 should be preferred over +# v2.0.0+incompatible when resolving latest, upgrade, and patch. + +go list -m github.com/russross/blackfriday@latest +stdout '^github.com/russross/blackfriday v1\.' + +go list -m github.com/russross/blackfriday@upgrade +stdout '^github.com/russross/blackfriday v1\.' + +go list -m github.com/russross/blackfriday@patch +stdout '^github.com/russross/blackfriday v1\.' + +# If we're fetching directly from version control, ignored +incompatible +# versions should also be omitted by 'go list'. + +# (Note that they may still be included in results from a proxy: in proxy mode, +# we would need to fetch the whole zipfile for the latest compatible version in +# order to determine whether it contains a go.mod file, and part of the point of +# the proxy is to avoid fetching unnecessary data.) + +[!exec:git] stop +env GOPROXY=direct + +go list -versions -m github.com/russross/blackfriday github.com/russross/blackfriday +stdout '^github.com/russross/blackfriday v1\.5\.1 v1\.5\.2' # and possibly others +! stdout ' v2\.' + +# However, if the latest compatible version does not include a go.mod file, +# +incompatible versions should still be listed, as they may still reflect the +# intent of the module author. + +go list -versions -m github.com/rsc/legacytest +stdout '^github.com/rsc/legacytest v1\.0\.0 v1\.1\.0-pre v1\.2\.0 v2\.0\.0\+incompatible' + +# If we're fetching directly from version control, asking for a commit hash +# corresponding to a +incompatible version should continue to produce the +# +incompatible version tagged for that commit, even if it is no longer listed. + +go list -m github.com/russross/blackfriday@cadec560ec52 +stdout '^github.com/russross/blackfriday v2\.0\.0\+incompatible$' + +# Similarly, requesting an untagged commit should continue to produce a +incompatible +# pseudo-version. + +go list -m github.com/rsc/legacytest@7303f7796364 +stdout '^github.com/rsc/legacytest v2\.0\.1-0\.20180717164253-7303f7796364\+incompatible$' + +-- go.mod -- +module github.com/golang.org/issue/34165 diff --git a/libgo/go/cmd/go/testdata/script/mod_proxy_errors.txt b/libgo/go/cmd/go/testdata/script/mod_proxy_errors.txt new file mode 100644 index 00000000000..9cd1a824f08 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_proxy_errors.txt @@ -0,0 +1,19 @@ +[!net] skip + +env GO111MODULE=on +env GOSUMDB=off +env GOPROXY=direct + +# Server responses should be truncated to some reasonable number of lines. +# (For now, exactly eight.) +! go list -m vcs-test.golang.org/auth/ormanylines@latest +stderr '\tserver response:\n(.|\n)*\tline 8\n\t\[Truncated: too many lines.\]$' + +# Server responses should be truncated to some reasonable number of characters. +! go list -m vcs-test.golang.org/auth/oronelongline@latest +! stderr 'blah{40}' +stderr '\tserver response: \[Truncated: too long\.\]$' + +# Responses from servers using the 'mod' protocol should be propagated. +! go list -m vcs-test.golang.org/go/modauth404@latest +stderr '\tserver response: File\? What file\?' diff --git a/libgo/go/cmd/go/testdata/script/mod_readonly.txt b/libgo/go/cmd/go/testdata/script/mod_readonly.txt index ff25f4bfe2f..1d1771e9cc0 100644 --- a/libgo/go/cmd/go/testdata/script/mod_readonly.txt +++ b/libgo/go/cmd/go/testdata/script/mod_readonly.txt @@ -2,16 +2,22 @@ env GO111MODULE=on [short] skip # -mod=readonly must not resolve missing modules nor update go.mod -# -# TODO(bcmills): 'go list' should suffice, but today it does not fail due to -# unresolved imports. When that is fixed, use 'go list' instead of 'go list all'. env GOFLAGS=-mod=readonly go mod edit -fmt cp go.mod go.mod.empty ! go list all -stderr 'import lookup disabled by -mod=readonly' +stderr '^can''t load package: x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly' cmp go.mod go.mod.empty +# -mod=readonly should be set implicitly if the go.mod file is read-only +chmod 0400 go.mod +env GOFLAGS= +! go list all +stderr '^can''t load package: x.go:2:8: cannot find module providing package rsc\.io/quote: import lookup disabled by -mod=readonly\n\t\(go.mod file is read-only\.\)$' + +chmod 0600 go.mod +env GOFLAGS=-mod=readonly + # update go.mod - go get allowed go get rsc.io/quote grep rsc.io/quote go.mod @@ -19,13 +25,14 @@ grep rsc.io/quote go.mod # update go.mod - go mod tidy allowed cp go.mod.empty go.mod go mod tidy +cp go.mod go.mod.tidy # -mod=readonly must succeed once go.mod is up-to-date... -go list +go list all # ... even if it needs downloads go clean -modcache -go list +go list all # -mod=readonly should reject inconsistent go.mod files # (ones that would be rewritten). @@ -35,6 +42,19 @@ cp go.mod go.mod.inconsistent stderr 'go: updates to go.mod needed, disabled by -mod=readonly' cmp go.mod go.mod.inconsistent +# However, it should not reject files missing a 'go' directive, +# since that was not always required. +cp go.mod.nogo go.mod +go list all + +# Nor should it reject files with redundant (not incorrect) +# requirements. +cp go.mod.redundant go.mod +go list all + +cp go.mod.indirect go.mod +go list all + -- go.mod -- module m @@ -43,3 +63,30 @@ go 1.20 -- x.go -- package x import _ "rsc.io/quote" +-- go.mod.nogo -- +module m + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.redundant -- +module m + +go 1.20 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.indirect -- +module m + +go 1.20 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) diff --git a/libgo/go/cmd/go/testdata/script/mod_replace.txt b/libgo/go/cmd/go/testdata/script/mod_replace.txt index 35824b3a8a2..c21f1720021 100644 --- a/libgo/go/cmd/go/testdata/script/mod_replace.txt +++ b/libgo/go/cmd/go/testdata/script/mod_replace.txt @@ -38,6 +38,20 @@ grep 'not-rsc.io/quote/v3 v3.1.0' go.mod exec ./a5.exe stdout 'Concurrency is not parallelism.' +# Error messages for modules not found in replacements should +# indicate the replacement module. +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=./local/rsc.io/quote/v3 +! go get -d rsc.io/quote/v3/missing-package +stderr 'module rsc.io/quote/v3@upgrade found \(v3.0.0, replaced by ./local/rsc.io/quote/v3\), but does not contain package' + +# The reported Dir and GoMod for a replaced module should be accurate. +cp go.mod.orig go.mod +go mod edit -replace=rsc.io/quote/v3=not-rsc.io/quote@v0.1.0-nomod +go mod download +go list -m -f '{{.Path}} {{.Version}} {{.Dir}} {{.GoMod}}{{with .Replace}} => {{.Path}} {{.Version}} {{.Dir}} {{.GoMod}}{{end}}' rsc.io/quote/v3 +stdout '^rsc.io/quote/v3 v3.0.0 '$GOPATH'[/\\]pkg[/\\]mod[/\\]not-rsc.io[/\\]quote@v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]not-rsc.io[/\\]quote[/\\]@v[/\\]v0.1.0-nomod.mod => not-rsc.io/quote v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]not-rsc.io[/\\]quote@v0.1.0-nomod '$GOPATH'[/\\]pkg[/\\]mod[/\\]cache[/\\]download[/\\]not-rsc.io[/\\]quote[/\\]@v[/\\]v0.1.0-nomod.mod$' + -- go.mod -- module quoter diff --git a/libgo/go/cmd/go/testdata/script/mod_replace_gopkgin.txt b/libgo/go/cmd/go/testdata/script/mod_replace_gopkgin.txt new file mode 100644 index 00000000000..6608fb1b801 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_replace_gopkgin.txt @@ -0,0 +1,28 @@ +# Regression test for golang.org/issue/34254: +# a clone of gopkg.in/[…].vN should be replaceable by +# a fork hosted at corp.example.com/[…]/vN, +# even if there is an explicit go.mod file containing the +# gopkg.in path. + +[short] skip +[!net] skip +[!exec:git] skip + +env GO111MODULE=on +env GOPROXY=direct +env GOSUMDB=off + +# Replacing gopkg.in/[…].vN with a repository with a root go.mod file +# specifying […].vN and a compatible version should succeed, even if +# the replacement path is not a gopkg.in path. +cd dot-to-dot +go list gopkg.in/src-d/go-git.v4 + +-- dot-to-dot/go.mod -- +module golang.org/issue/34254 + +go 1.13 + +require gopkg.in/src-d/go-git.v4 v4.13.1 + +replace gopkg.in/src-d/go-git.v4 v4.13.1 => github.com/src-d/go-git/v4 v4.13.1 diff --git a/libgo/go/cmd/go/testdata/script/mod_replace_import.txt b/libgo/go/cmd/go/testdata/script/mod_replace_import.txt index 0da753a1a76..941ef61d355 100644 --- a/libgo/go/cmd/go/testdata/script/mod_replace_import.txt +++ b/libgo/go/cmd/go/testdata/script/mod_replace_import.txt @@ -23,6 +23,13 @@ stdout 'example.com/y v0.0.0-00010101000000-000000000000 => ./y' stdout 'example.com/x/v3 v3.0.0-00010101000000-000000000000 => ./v3' stdout 'example.com/v v1.12.0 => ./v12' +# The go command should print an informative error when the matched +# module does not contain a package. +cd fail +! go list all +stdout 'localhost.fail' +stderr '^can.t load package: m.go:3:8: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' + -- go.mod -- module example.com/m @@ -107,3 +114,16 @@ package v module v.localhost -- v/v.go -- package v + +-- fail/m.go -- +package main + +import _ "w" + +func main() {} + +-- fail/go.mod -- +module localhost.fail + +replace w => ../w + diff --git a/libgo/go/cmd/go/testdata/script/mod_retention.txt b/libgo/go/cmd/go/testdata/script/mod_retention.txt new file mode 100644 index 00000000000..bff4142ad83 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_retention.txt @@ -0,0 +1,135 @@ +# Regression test for golang.org/issue/34822: the 'go' command should prefer not +# to update the go.mod file if the changes only affect formatting, and should only +# remove redundant requirements in 'go mod tidy'. + +env GO111MODULE=on +[short] skip + +# Control case: verify that go.mod.tidy is actually tidy. +cp go.mod.tidy go.mod +go list all +cmp go.mod go.mod.tidy + + +# If the only difference in the go.mod file is the line endings, +# it should not be overwritten automatically. +cp go.mod.crlf go.mod +go list all +cmp go.mod go.mod.crlf + +# However, 'go mod tidy' should fix whitespace even if there are no other changes. +go mod tidy +cmp go.mod go.mod.tidy + + +# Out-of-order requirements should not be overwritten automatically... +cp go.mod.unsorted go.mod +go list all +cmp go.mod go.mod.unsorted + +# ...but 'go mod edit -fmt' should sort them. +go mod edit -fmt +cmp go.mod go.mod.tidy + + +# "// indirect" comments should be removed if direct dependencies are seen. +# changes. +cp go.mod.indirect go.mod +go list all +cmp go.mod go.mod.tidy + +# "// indirect" comments should be added if appropriate. +cp go.mod.toodirect go.mod +go list all +cmp go.mod go.mod.toodirect +go mod vendor # loads everything, so adds "// indirect" comments. +cmp go.mod go.mod.tidy +rm -r vendor + + +# Redundant requirements should be preserved... +cp go.mod.redundant go.mod +go list all +cmp go.mod go.mod.redundant +go mod vendor +cmp go.mod go.mod.redundant +rm -r vendor + +# ...except by 'go mod tidy'. +go mod tidy +cmp go.mod go.mod.tidy + + +# A missing "go" version directive should be added. +# However, that should not remove other redundant requirements. +cp go.mod.nogo go.mod +go list all +cmp go.mod go.mod.redundant + + +-- go.mod.tidy -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 // indirect +) +-- x.go -- +package x +import _ "rsc.io/quote" +-- go.mod.crlf -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.unsorted -- +module m + +go 1.14 + +require ( + rsc.io/testonly v1.0.0 // indirect + rsc.io/quote v1.5.2 +) +-- go.mod.indirect -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.toodirect -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/testonly v1.0.0 +) +-- go.mod.redundant -- +module m + +go 1.14 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) +-- go.mod.nogo -- +module m + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // indirect + rsc.io/testonly v1.0.0 // indirect +) diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb.txt index 641b9e73bcc..caf97e9699f 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb.txt @@ -9,7 +9,7 @@ env dbname=localhost.localdev/sumdb cp go.mod.orig go.mod env GOSUMDB=$sumdb' '$proxy/sumdb-wrong ! go get -d rsc.io/quote -stderr 'verifying rsc.io/quote@v1.5.2: checksum mismatch' +stderr 'go get rsc.io/quote: rsc.io/quote@v1.5.2: verifying module: checksum mismatch' stderr 'downloaded: h1:3fEy' stderr 'localhost.localdev/sumdb: h1:wrong' stderr 'SECURITY ERROR\nThis download does NOT match the one reported by the checksum server.' diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_cache.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_cache.txt index 486bdf5ecf6..2937b2e4dcd 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_cache.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_cache.txt @@ -37,7 +37,14 @@ env GOPROXY=$proxy/sumdb-504 ! go get -d rsc.io/quote@v1.5.2 stderr 504 +# GOINSECURE does not bypass checksum lookup +env GOINSECURE=rsc.io +env GOPROXY=$proxy/sumdb-504 +! go get -d rsc.io/quote@v1.5.2 +stderr 504 + # but -insecure bypasses the checksum lookup entirely +env GOINSECURE= go get -d -insecure rsc.io/quote@v1.5.2 # and then it is in go.sum again diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_file_path.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_file_path.txt index 47c8a3a0f3c..6108c0a5d36 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_file_path.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_file_path.txt @@ -7,10 +7,13 @@ env GOPATH=$WORK/gopath1 # With a file-based proxy with an empty checksum directory, # downloading a new module should fail, even if a subsequent # proxy contains a more complete mirror of the sum database. +# +# TODO(bcmills): The error message here is a bit redundant. +# It comes from the sumweb package, which isn't yet producing structured errors. [windows] env GOPROXY=file:///$WORK/sumproxy,https://proxy.golang.org [!windows] env GOPROXY=file://$WORK/sumproxy,https://proxy.golang.org ! go get -d golang.org/x/text@v0.3.2 -stderr '^verifying golang.org/x/text.*: Not Found' +stderr '^go get golang.org/x/text@v0.3.2: golang.org/x/text@v0.3.2: verifying module: golang.org/x/text@v0.3.2: reading file://.*/sumdb/sum.golang.org/lookup/golang.org/x/text@v0.3.2: (no such file or directory|.*cannot find the path specified.*)' # If the proxy does not claim to support the database, # checksum verification should fall through to the next proxy, diff --git a/libgo/go/cmd/go/testdata/script/mod_test_files.txt b/libgo/go/cmd/go/testdata/script/mod_test_files.txt index 87aecb44f67..6f520c7720d 100644 --- a/libgo/go/cmd/go/testdata/script/mod_test_files.txt +++ b/libgo/go/cmd/go/testdata/script/mod_test_files.txt @@ -20,6 +20,7 @@ stderr 'use of internal package' -- foo/go.mod -- module example.com/foo +go 1.12 require example.com/internal v0.0.0 replace example.com/internal => ../internal diff --git a/libgo/go/cmd/go/testdata/script/mod_tidy.txt b/libgo/go/cmd/go/testdata/script/mod_tidy.txt index de3b52e2c02..b1d9371217c 100644 --- a/libgo/go/cmd/go/testdata/script/mod_tidy.txt +++ b/libgo/go/cmd/go/testdata/script/mod_tidy.txt @@ -5,7 +5,6 @@ go mod tidy -v stderr '^unused y.1' ! stderr '^unused [^y]' -# tidy should not touch existing go line grep 'go 1.10' go.mod go list -m all diff --git a/libgo/go/cmd/go/testdata/script/mod_tidy_cycle.txt b/libgo/go/cmd/go/testdata/script/mod_tidy_cycle.txt new file mode 100644 index 00000000000..e46f37d7fa2 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_tidy_cycle.txt @@ -0,0 +1,75 @@ +# Regression test for https://golang.org/issue/34086: +# 'go mod tidy' produced different go.mod file from other +# subcommands when certain kinds of cycles were present +# in the build graph. + +env GO111MODULE=on + +cp go.mod go.mod.orig +go mod tidy +cmp go.mod go.mod.orig + +# If the go.mod file is already tidy, 'go mod graph' should not modify it. +go mod graph +cmp go.mod go.mod.orig + +-- go.mod -- +module root + +go 1.13 + +replace ( + a v0.1.0 => ./a1 + b v0.1.0 => ./b1 + b v0.2.0 => ./b2 + c v0.1.0 => ./c1 + c v0.2.0 => ./c2 +) + +require ( + a v0.1.0 + b v0.2.0 // indirect +) +-- main.go -- +package main + +import _ "a" + +func main() {} + +-- a1/go.mod -- +module a + +go 1.13 + +require b v0.1.0 +-- a1/a.go -- +package a + +import _ "c" +-- b1/go.mod -- +module b + +go 1.13 + +require c v0.1.0 +-- b2/go.mod -- +module b + +go 1.13 + +require c v0.2.0 +-- c1/go.mod -- +module c + +go 1.13 +-- c2/c.go -- +package c +-- c2/go.mod -- +module c + +go 1.13 + +require b v0.2.0 +-- c2/c.go -- +package c diff --git a/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt b/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt index 9bb8528cb0b..b6c24ceaf75 100644 --- a/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt +++ b/libgo/go/cmd/go/testdata/script/mod_tidy_error.txt @@ -4,12 +4,12 @@ env GO111MODULE=on # 'go mod tidy' and 'go mod vendor' should not hide loading errors. ! go mod tidy -stderr '^issue27063 imports\n\tnonexist: malformed module path "nonexist": missing dot in first path element' +stderr '^issue27063 imports\n\tnonexist: package nonexist is not in GOROOT \(.*\)' stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com' stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist' ! go mod vendor -stderr '^issue27063 imports\n\tnonexist: malformed module path "nonexist": missing dot in first path element' +stderr '^issue27063 imports\n\tnonexist: package nonexist is not in GOROOT \(.*\)' stderr '^issue27063 imports\n\tnonexist.example.com: cannot find module providing package nonexist.example.com' stderr '^issue27063 imports\n\tissue27063/other imports\n\tother.example.com/nonexist: cannot find module providing package other.example.com/nonexist' diff --git a/libgo/go/cmd/go/testdata/script/mod_tidy_replace.txt b/libgo/go/cmd/go/testdata/script/mod_tidy_replace.txt index d5c22530944..c3158f8610e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_tidy_replace.txt +++ b/libgo/go/cmd/go/testdata/script/mod_tidy_replace.txt @@ -47,6 +47,12 @@ grep 'rsc.io/sampler v1.2.0' go.mod cd outside go list -m all stdout 'rsc.io/sampler v1.3.0' +cd .. + +# The same module can't be used as two different paths. +cd multiple-paths +! go mod tidy +stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)' -- go.mod -- module example.com/tidy @@ -109,3 +115,23 @@ package b module golang.org/issue/30166/b require golang.org/issue/30166/a v0.0.0 +-- multiple-paths/main.go -- +package main + +import ( + "fmt" + "rsc.io/quote/v3" +) + +func main() { + fmt.Println(quote.GoV3()) +} +-- multiple-paths/go.mod -- +module quoter + +require ( + rsc.io/quote/v3 v3.0.0 + not-rsc.io/quote/v3 v3.0.0 +) + +replace not-rsc.io/quote/v3 => rsc.io/quote/v3 v3.0.0 diff --git a/libgo/go/cmd/go/testdata/script/mod_vendor.txt b/libgo/go/cmd/go/testdata/script/mod_vendor.txt index 5d872c3c80e..bb3e634b3a3 100644 --- a/libgo/go/cmd/go/testdata/script/mod_vendor.txt +++ b/libgo/go/cmd/go/testdata/script/mod_vendor.txt @@ -1,15 +1,15 @@ env GO111MODULE=on -go list -m all -stdout '^x v1.0.0 => ./x' -stdout '^w' - +# Without vendoring, a build should succeed unless -mod=vendor is set. [!short] go build [!short] ! go build -mod=vendor +# Without vendoring, 'go list' should report the replacement directory for +# a package in a replaced module. go list -f {{.Dir}} x stdout 'src[\\/]x' +# 'go mod vendor' should copy all replaced modules to the vendor directory. go mod vendor -v stderr '^# x v1.0.0 => ./x' stderr '^x' @@ -20,28 +20,47 @@ stderr '^z' ! stderr '^w' grep 'a/foo/bar/b\na/foo/bar/c' vendor/modules.txt # must be sorted -go list -f {{.Dir}} x +# An explicit '-mod=mod' should ignore the vendor directory. +go list -mod=mod -f {{.Dir}} x stdout 'src[\\/]x' -go list -f {{.Dir}} -m x +go list -mod=mod -f {{.Dir}} -m x stdout 'src[\\/]x' +# An explicit '-mod=vendor' should report package directories within +# the vendor directory. go list -mod=vendor -f {{.Dir}} x stdout 'src[\\/]vendor[\\/]x' -go list -mod=vendor -f {{.Dir}} -m x -stdout 'src[\\/]vendor[\\/]x' - -go list -f {{.Dir}} -m w +# 'go list -mod=vendor -m' should successfully list vendored modules, +# but should not provide a module directory because no directory contains +# the complete module. +go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m x +stdout '^v1.0.0 $' + +# 'go list -mod=vendor -m' on a transitive dependency that does not +# provide vendored packages should give a helpful error rather than +# 'not a known dependency'. +! go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m diamondright +stderr 'go list -m: module diamondright: can''t resolve module using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +# 'go list -mod=mod' should report packages outside the import graph, +# but 'go list -mod=vendor' should error out for them. +go list -mod=mod -f {{.Dir}} w stdout 'src[\\/]w' - ! go list -mod=vendor -f {{.Dir}} w stderr 'src[\\/]vendor[\\/]w' +go list -mod=mod -f {{.Dir}} diamondright +stdout 'src[\\/]diamondright' + +# Test dependencies should not be copied. ! exists vendor/x/testdata ! exists vendor/a/foo/bar/b/ignored.go ! exists vendor/a/foo/bar/b/main_test.go +# Licenses and other metadata for each module should be copied +# if any package within their module is copied. exists vendor/a/foo/AUTHORS.txt exists vendor/a/foo/CONTRIBUTORS exists vendor/a/foo/LICENSE @@ -59,14 +78,18 @@ exists vendor/mysite/myname/mypkg/LICENSE.txt [short] stop -go build +# 'go build' and 'go test' using vendored packages should succeed. +go build -mod=mod go build -mod=vendor go test -mod=vendor . ./subdir go test -mod=vendor ./... +go fmt -mod=vendor ./... -- go.mod -- module m +go 1.13 + require ( a v1.0.0 diamondroot v0.0.0 @@ -252,10 +275,11 @@ require ( -- diamondroot/x.go -- package diamondroot -import ( - _ "diamondleft" - _ "diamondright" -) +import _ "diamondleft" +-- diamondroot/unused/unused.go -- +package unused + +import _ "diamondright" -- diamondleft/go.mod -- module diamondleft diff --git a/libgo/go/cmd/go/testdata/script/mod_vendor_auto.txt b/libgo/go/cmd/go/testdata/script/mod_vendor_auto.txt new file mode 100644 index 00000000000..53120dcfa1f --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_vendor_auto.txt @@ -0,0 +1,256 @@ +# Integration test for golang.org/issue/33848: automatically check and use vendored packages. + +env GO111MODULE=on + +[short] skip + +cd $WORK/auto +cp go.mod go.mod.orig +cp $WORK/modules-1.13.txt $WORK/auto/modules.txt + +# An explicit -mod=vendor should force use of the vendor directory. +env GOFLAGS=-mod=vendor + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +! go list -m all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +! go list -m -f '{{.Dir}}' all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +# An explicit -mod=mod should force the vendor directory to be ignored. +env GOFLAGS=-mod=mod + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m all +stdout '^example.com/auto$' +stdout 'example.com/printversion v1.0.0' +stdout 'example.com/version v1.0.0' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# If the main module's "go" directive says 1.13, we should default to -mod=mod. +env GOFLAGS= +go mod edit -go=1.13 + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# A 'go 1.14' directive in the main module's go.mod file should enable +# -mod=vendor by default, along with stronger checks for consistency +# between the go.mod file and vendor/modules.txt. +# A 'go 1.13' vendor/modules.txt file is not usually sufficient +# to pass those checks. +go mod edit -go=1.14 + +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt' +stderr '^\texample.com/unused: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\texample.com/version@v1.2.0: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '\n\nrun .go mod vendor. to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory$' + +# Module-specific subcommands should continue to load the full module graph. +go mod graph +stdout '^example.com/printversion@v1.0.0 example.com/version@v1.0.0$' + +# An explicit -mod=mod should still force the vendor directory to be ignored. +env GOFLAGS=-mod=mod + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +go list -m all +stdout '^example.com/auto$' +stdout 'example.com/printversion v1.0.0' +stdout 'example.com/version v1.0.0' + +go list -m -f '{{.Dir}}' all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$GOPATH'[/\\]pkg[/\\]mod[/\\]example.com[/\\]printversion@v1.0.0$' +stdout '^'$WORK'[/\\]auto[/\\]replacement-version$' + +# 'go mod vendor' should repair vendor/modules.txt so that the implicit +# -mod=vendor works again. +env GOFLAGS= + +go mod edit -go=1.14 +go mod vendor + +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# ...but 'go list -m' should continue to fail, this time without +# referring to a -mod default that the user didn't set. +! go list -m all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + +! go list -m -f '{{.Dir}}' all +stderr 'go list -m: can''t compute ''all'' using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass.\)' + + +# 'go mod init' should work if there is already a GOPATH-mode vendor directory +# present. If there are no module dependencies, -mod=vendor should be used by +# default and should not fail the consistency check even though no module +# information is present. + +rm go.mod +rm vendor/modules.txt + +go mod init example.com/auto +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# If information about dependencies is added to a 1.14 go.mod file, subsequent +# list commands should error out if vendor/modules.txt is missing or incomplete. + +cp go.mod.orig go.mod +go mod edit -go=1.14 +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt' +stderr '^\texample.com/unused: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '^\texample.com/version@v1.2.0: is replaced in go.mod, but not marked as replaced in vendor/modules.txt' +stderr '\n\nrun .go mod vendor. to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory$' + +# If -mod=vendor is set, limited consistency checks should apply even when +# the go version is 1.13 or earlier. +# An incomplete or missing vendor/modules.txt should resolve the vendored packages... +go mod edit -go=1.13 +go list -mod=vendor -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# ...but a version mismatch for an explicit dependency should be noticed. +cp $WORK/modules-bad-1.13.txt vendor/modules.txt +! go list -mod=vendor -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$' +stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but vendor/modules.txt indicates example.com/printversion@v1.1.0$' +stderr '\n\nrun .go mod vendor. to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory$' + +# If the go version is still 1.13, 'go mod vendor' should write a +# matching vendor/modules.txt containing the corrected 1.13 data. +go mod vendor +cmp $WORK/modules-1.13.txt vendor/modules.txt + +go list -mod=vendor -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# When the version is upgraded to 1.14, 'go mod vendor' should write a +# vendor/modules.txt with the updated 1.14 annotations. +go mod edit -go=1.14 +go mod vendor +cmp $WORK/modules-1.14.txt vendor/modules.txt + +# Then, -mod=vendor should kick in automatically and succeed. +go list -f {{.Dir}} -tags tools all +stdout '^'$WORK'[/\\]auto$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]printversion$' +stdout '^'$WORK'[/\\]auto[/\\]vendor[/\\]example.com[/\\]version$' + +# 'go get' should update from the network or module cache, +# even if a vendor directory is present. +go get -u example.com/printversion +! go list -f {{.Dir}} -tags tools all +stderr '^go: inconsistent vendoring' + +-- $WORK/auto/go.mod -- +module example.com/auto + +go 1.13 + +require example.com/printversion v1.0.0 + +replace ( + example.com/unused => nonexistent.example.com/unused v1.0.0-whatever + example.com/version v1.0.0 => ./replacement-version + example.com/version v1.2.0 => nonexistent.example.com/version v1.2.0 +) +-- $WORK/auto/tools.go -- +// +build tools + +package auto + +import _ "example.com/printversion" +-- $WORK/auto/auto.go -- +package auto +-- $WORK/auto/replacement-version/go.mod -- +module example.com/version +-- $WORK/auto/replacement-version/version.go -- +package version + +const V = "v1.0.0-replaced" +-- $WORK/modules-1.14.txt -- +# example.com/printversion v1.0.0 +## explicit +example.com/printversion +# example.com/version v1.0.0 => ./replacement-version +example.com/version +# example.com/unused => nonexistent.example.com/unused v1.0.0-whatever +# example.com/version v1.2.0 => nonexistent.example.com/version v1.2.0 +-- $WORK/modules-1.13.txt -- +# example.com/printversion v1.0.0 +example.com/printversion +# example.com/version v1.0.0 => ./replacement-version +example.com/version +-- $WORK/modules-bad-1.13.txt -- +# example.com/printversion v1.1.0 +example.com/printversion +# example.com/version v1.1.0 +example.com/version +-- $WORK/auto/vendor/example.com/printversion/go.mod -- +module example.com/printversion + +require example.com/version v1.0.0 +replace example.com/version v1.0.0 => ../oops v0.0.0 +exclude example.com/version v1.0.1 +-- $WORK/auto/vendor/example.com/printversion/printversion.go -- +package main + +import ( + "fmt" + "os" + "runtime/debug" + + _ "example.com/version" +) + +func main() { + info, _ := debug.ReadBuildInfo() + fmt.Fprintf(os.Stdout, "path is %s\n", info.Path) + fmt.Fprintf(os.Stdout, "main is %s %s\n", info.Main.Path, info.Main.Version) + for _, m := range info.Deps { + fmt.Fprintf(os.Stdout, "using %s %s\n", m.Path, m.Version) + } +} +-- $WORK/auto/vendor/example.com/version/version.go -- +package version + +const V = "v1.0.0-replaced" diff --git a/libgo/go/cmd/go/testdata/script/mod_vendor_build.txt b/libgo/go/cmd/go/testdata/script/mod_vendor_build.txt index 24920a36b66..0c359cea6e9 100644 --- a/libgo/go/cmd/go/testdata/script/mod_vendor_build.txt +++ b/libgo/go/cmd/go/testdata/script/mod_vendor_build.txt @@ -32,7 +32,7 @@ stdout m -- go.mod -- module m - +go 1.12 -- x.go -- package x import _ "rsc.io/quote" diff --git a/libgo/go/cmd/go/testdata/script/mod_vendor_replace.txt b/libgo/go/cmd/go/testdata/script/mod_vendor_replace.txt index 6bc1c77ed3d..0c1c1d22f5b 100644 --- a/libgo/go/cmd/go/testdata/script/mod_vendor_replace.txt +++ b/libgo/go/cmd/go/testdata/script/mod_vendor_replace.txt @@ -1,7 +1,7 @@ env GO111MODULE=on # Before vendoring, we expect to see the original directory. -go list -f '{{.Version}} {{.Dir}}' -m rsc.io/quote/v3 +go list -f '{{with .Module}}{{.Version}}{{end}} {{.Dir}}' rsc.io/quote/v3 stdout 'v3.0.0' stdout '.*[/\\]not-rsc.io[/\\]quote[/\\]v3' @@ -15,12 +15,22 @@ go mod vendor # without attempting to look up the non-replaced version. cmp vendor/rsc.io/quote/v3/quote.go local/not-rsc.io/quote/v3/quote.go -go list -mod=vendor -f '{{.Version}} {{.Dir}}' -m rsc.io/quote/v3 +go list -mod=vendor -f '{{with .Module}}{{.Version}}{{end}} {{.Dir}}' rsc.io/quote/v3 stdout 'v3.0.0' stdout '.*[/\\]vendor[/\\]rsc.io[/\\]quote[/\\]v3' ! stderr 'finding' ! stderr 'lookup disabled' +# 'go list' should provide the original replacement directory as the module's +# replacement path. +go list -mod=vendor -f '{{with .Module}}{{with .Replace}}{{.Path}}{{end}}{{end}}' rsc.io/quote/v3 +stdout '.*[/\\]not-rsc.io[/\\]quote[/\\]v3' + +# The same module can't be used as two different paths. +cd multiple-paths +! go mod vendor +stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/quote/v3 and rsc.io/quote/v3\)' + -- go.mod -- module example.com/replace @@ -37,3 +47,20 @@ module not-rsc.io/quote/v3 -- local/not-rsc.io/quote/v3/quote.go -- package quote + +-- multiple-paths/main.go -- +package main +import ( + "fmt" + "rsc.io/quote/v3" +) +func main() { + fmt.Println(quote.GoV3()) +} +-- multiple-paths/go.mod -- +module quoter +require ( + rsc.io/quote/v3 v3.0.0 + not-rsc.io/quote/v3 v3.0.0 +) +replace not-rsc.io/quote/v3 => rsc.io/quote/v3 v3.0.0 diff --git a/libgo/go/cmd/go/testdata/script/mod_vendor_unused.txt b/libgo/go/cmd/go/testdata/script/mod_vendor_unused.txt new file mode 100644 index 00000000000..96251bb25ae --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/mod_vendor_unused.txt @@ -0,0 +1,67 @@ +# Auxiliary test for inclusion of otherwise-unused replacements in +# vendor/modules.txt for golang.org/issue/33848. +# We need metadata about replacements in order to verify that modules.txt +# remains in sync with the main module's go.mod file. + +env GO111MODULE=on + +go mod vendor +cmp go1.14-modules.txt vendor/modules.txt + +-- go.mod -- +module example.com/foo +go 1.14 + +require ( + example.com/a v0.1.0 +) + +replace ( + example.com/a v0.1.0 => ./a + example.com/b v0.1.0 => ./b1 + example.com/b v0.2.0-unused => ./b2 + example.com/c => ./c + example.com/d v0.1.0 => ./d1 + example.com/d v0.2.0 => ./d2 + example.com/e => example.com/e v0.1.0-unused +) +-- foo.go -- +package foo +import _ "example.com/a" +-- a/go.mod -- +module example.com/a +require ( + example.com/b v0.1.0 // indirect + example.com/c v0.1.0 // indirect +) +-- a/a.go -- +package a +import _ "example.com/d" +-- b1/go.mod -- +module example.com/b +require example.com/d v0.1.0 +-- b2/go.mod -- +module example.com/b +require example.com/c v0.2.0 +-- c/go.mod -- +module example.com/c +require example.com/d v0.2.0 +-- d1/go.mod -- +module example.com/d +-- d1/d1.go -- +package d +-- d2/go.mod -- +module example.com/d +-- d2/d2.go -- +package d +-- go1.14-modules.txt -- +# example.com/a v0.1.0 => ./a +## explicit +example.com/a +# example.com/d v0.2.0 => ./d2 +example.com/d +# example.com/b v0.1.0 => ./b1 +# example.com/b v0.2.0-unused => ./b2 +# example.com/c => ./c +# example.com/d v0.1.0 => ./d1 +# example.com/e => example.com/e v0.1.0-unused diff --git a/libgo/go/cmd/go/testdata/script/modfile_flag.txt b/libgo/go/cmd/go/testdata/script/modfile_flag.txt new file mode 100644 index 00000000000..1409be9599c --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/modfile_flag.txt @@ -0,0 +1,84 @@ +# Tests the behavior of the -modfile flag in commands that support it. +# The go.mod file exists but should not be read or written. +# Same with go.sum. + +env GOFLAGS=-modfile=go.alt.mod +cp go.mod go.mod.orig +cp go.sum go.sum.orig + + +# go mod init should create a new file, even though go.mod already exists. +go mod init example.com/m +grep example.com/m go.alt.mod + +# go mod edit should operate on the alternate file +go mod edit -require rsc.io/quote@v1.5.2 +grep rsc.io/quote go.alt.mod + +# other 'go mod' commands should work. 'go mod vendor' is tested later. +go mod download rsc.io/quote +go mod graph +stdout rsc.io/quote +go mod tidy +grep rsc.io/quote go.alt.sum +go mod verify +go mod why rsc.io/quote + + +# 'go list' and other commands with build flags should work. +# They should update the alternate go.mod when a dependency is missing. +go mod edit -droprequire rsc.io/quote +go list . +grep rsc.io/quote go.alt.mod +go build -n . +go test -n . +go get -d rsc.io/quote + + +# 'go mod vendor' should work. +go mod vendor +exists vendor + +# Automatic vendoring should be broken by editing an explicit requirement +# in the alternate go.mod file. +go mod edit -require rsc.io/quote@v1.5.1 +! go list . +go list -mod=mod +rm vendor + + +# 'go generate' should use the alternate file when resolving packages. +# Recursive go commands started with 'go generate' should not get an explicitly +# passed -modfile, but they should see arguments from GOFLAGS. +cp go.alt.mod go.gen.mod +env OLD_GOFLAGS=$GOFLAGS +env GOFLAGS=-modfile=go.gen.mod +go generate -modfile=go.alt.mod . +env GOFLAGS=$OLD_GOFLAGS +grep example.com/exclude go.gen.mod +! grep example.com/exclude go.alt.mod + + +# The original files should not have been modified. +cmp go.mod go.mod.orig +cmp go.sum go.sum.orig + + +# If the altnernate mod file does not have a ".mod" suffix, an error +# should be reported. +cp go.alt.mod goaltmod +! go mod tidy -modfile=goaltmod +stderr '-modfile=goaltmod: file does not have .mod extension' + +-- go.mod -- +ʕ◔ϖ◔ʔ +-- go.sum -- +ʕ◔ϖ◔ʔ +-- use.go -- +package main + +import _ "rsc.io/quote" +-- gen.go -- +//go:generate go mod edit -exclude example.com/exclude@v1.0.0 + +package main diff --git a/libgo/go/cmd/go/testdata/script/noncanonical_import.txt b/libgo/go/cmd/go/testdata/script/noncanonical_import.txt new file mode 100644 index 00000000000..7fdc0718ef1 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/noncanonical_import.txt @@ -0,0 +1,21 @@ +env GO111MODULE=off + +! go build canonical/d +stderr 'package canonical/d' +stderr 'imports canonical/b' +stderr 'imports canonical/a/: non-canonical' + +-- canonical/a/a.go -- +package a + +import _ "c" +-- canonical/b/b.go -- +package b + +import _ "canonical/a/" +-- canonical/a/vendor/c/c.go -- +package c +-- canonical/d/d.go -- +package d + +import _ "canonical/b" diff --git a/libgo/go/cmd/go/testdata/script/test_bad_example.txt b/libgo/go/cmd/go/testdata/script/test_bad_example.txt new file mode 100644 index 00000000000..1d147b663fe --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/test_bad_example.txt @@ -0,0 +1,13 @@ +# Tests that invalid examples are ignored. +# Verifies golang.org/issue/35284 +go test x_test.go + +-- x_test.go -- +package x + +import "fmt" + +func ExampleThisShouldNotHaveAParameter(thisShouldntExist int) { + fmt.Println("X") + // Output: +} \ No newline at end of file diff --git a/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt b/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt new file mode 100644 index 00000000000..46faca0f422 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt @@ -0,0 +1,230 @@ +env GO111MODULE=off + +# Test that cached test results are invalidated in response to +# changes to the external inputs to the test. + +[short] skip +[GODEBUG:gocacheverify=1] skip + +# We're testing cache behavior, so start with a clean GOCACHE. +env GOCACHE=$WORK/cache + +# Build a helper binary to invoke os.Chtimes. +go build -o mkold$GOEXE mkold.go + +# Make test input files appear to be a minute old. +exec ./mkold$GOEXE 1m testcache/file.txt +exec ./mkold$GOEXE 1m testcache/script.sh + +# If the test reads an environment variable, changes to that variable +# should invalidate cached test results. +env TESTKEY=x +go test testcache -run=TestLookupEnv +go test testcache -run=TestLookupEnv +stdout '\(cached\)' + +env TESTKEY=y +go test testcache -run=TestLookupEnv +! stdout '\(cached\)' +go test testcache -run=TestLookupEnv +stdout '\(cached\)' + +# If the test stats a file, changes to the file should invalidate the cache. +go test testcache -run=FileSize +go test testcache -run=FileSize +stdout '\(cached\)' + +cp 4x.txt testcache/file.txt +go test testcache -run=FileSize +! stdout '\(cached\)' +go test testcache -run=FileSize +stdout '\(cached\)' + +# Files should be tracked even if the test changes its working directory. +go test testcache -run=Chdir +go test testcache -run=Chdir +stdout '\(cached\)' +cp 6x.txt testcache/file.txt +go test testcache -run=Chdir +! stdout '\(cached\)' +go test testcache -run=Chdir +stdout '\(cached\)' + +# The content of files should affect caching, provided that the mtime also changes. +exec ./mkold$GOEXE 1m testcache/file.txt +go test testcache -run=FileContent +go test testcache -run=FileContent +stdout '\(cached\)' +cp 2y.txt testcache/file.txt +exec ./mkold$GOEXE 50s testcache/file.txt +go test testcache -run=FileContent +! stdout '\(cached\)' +go test testcache -run=FileContent +stdout '\(cached\)' + +# Directory contents read via os.ReadDirNames should affect caching. +go test testcache -run=DirList +go test testcache -run=DirList +stdout '\(cached\)' +rm testcache/file.txt +go test testcache -run=DirList +! stdout '\(cached\)' +go test testcache -run=DirList +stdout '\(cached\)' + +# Files outside GOROOT and GOPATH should not affect caching. +env TEST_EXTERNAL_FILE=$WORK/external.txt +go test testcache -run=ExternalFile +go test testcache -run=ExternalFile +stdout '\(cached\)' + +rm $WORK/external.txt +go test testcache -run=ExternalFile +stdout '\(cached\)' + +# Executables within GOROOT and GOPATH should affect caching, +# even if the test does not stat them explicitly. + +[!exec:/bin/sh] skip +chmod 0755 ./testcache/script.sh + +exec ./mkold$GOEXEC 1m testcache/script.sh +go test testcache -run=Exec +go test testcache -run=Exec +stdout '\(cached\)' + +exec ./mkold$GOEXE 50s testcache/script.sh +go test testcache -run=Exec +! stdout '\(cached\)' +go test testcache -run=Exec +stdout '\(cached\)' + +-- testcache/file.txt -- +xx +-- 4x.txt -- +xxxx +-- 6x.txt -- +xxxxxx +-- 2y.txt -- +yy +-- $WORK/external.txt -- +This file is outside of GOPATH. +-- testcache/script.sh -- +#!/bin/sh +exit 0 +-- testcache/testcache_test.go -- +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testcache + +import ( + "io/ioutil" + "os" + "testing" +) + +func TestChdir(t *testing.T) { + os.Chdir("..") + defer os.Chdir("testcache") + info, err := os.Stat("testcache/file.txt") + if err != nil { + t.Fatal(err) + } + if info.Size()%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddFileContent(t *testing.T) { + f, err := os.Open("file.txt") + if err != nil { + t.Fatal(err) + } + data, err := ioutil.ReadAll(f) + f.Close() + if err != nil { + t.Fatal(err) + } + if len(data)%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddFileSize(t *testing.T) { + info, err := os.Stat("file.txt") + if err != nil { + t.Fatal(err) + } + if info.Size()%2 != 1 { + t.Fatal("even file") + } +} + +func TestOddGetenv(t *testing.T) { + val := os.Getenv("TESTKEY") + if len(val)%2 != 1 { + t.Fatal("even env value") + } +} + +func TestLookupEnv(t *testing.T) { + _, ok := os.LookupEnv("TESTKEY") + if !ok { + t.Fatal("env missing") + } +} + +func TestDirList(t *testing.T) { + f, err := os.Open(".") + if err != nil { + t.Fatal(err) + } + f.Readdirnames(-1) + f.Close() +} + +func TestExec(t *testing.T) { + // Note: not using os/exec to make sure there is no unexpected stat. + p, err := os.StartProcess("./script.sh", []string{"script"}, new(os.ProcAttr)) + if err != nil { + t.Fatal(err) + } + ps, err := p.Wait() + if err != nil { + t.Fatal(err) + } + if !ps.Success() { + t.Fatalf("script failed: %v", err) + } +} + +func TestExternalFile(t *testing.T) { + os.Open(os.Getenv("TEST_EXTERNAL_FILE")) + _, err := os.Stat(os.Getenv("TEST_EXTERNAL_FILE")) + if err != nil { + t.Fatal(err) + } +} +-- mkold.go -- +package main + +import ( + "log" + "os" + "time" +) + +func main() { + d, err := time.ParseDuration(os.Args[1]) + if err != nil { + log.Fatal(err) + } + path := os.Args[2] + old := time.Now().Add(-d) + err = os.Chtimes(path, old, old) + if err != nil { + log.Fatal(err) + } +} diff --git a/libgo/go/cmd/go/testdata/script/test_compile_binary.txt b/libgo/go/cmd/go/testdata/script/test_compile_binary.txt index 6562f2453ff..63bb8ec3e78 100644 --- a/libgo/go/cmd/go/testdata/script/test_compile_binary.txt +++ b/libgo/go/cmd/go/testdata/script/test_compile_binary.txt @@ -4,5 +4,5 @@ env GO111MODULE=off stderr 'build comment' -- compile_binary/foo_test.go -- -//+build foo +// +build foo package foo diff --git a/libgo/go/cmd/go/testdata/script/test_compile_tempfile.txt b/libgo/go/cmd/go/testdata/script/test_compile_tempfile.txt new file mode 100644 index 00000000000..912410814f4 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/test_compile_tempfile.txt @@ -0,0 +1,11 @@ +[short] skip + +# Ensure that the target of 'go build -o' can be an existing, empty file so that +# its name can be reserved using ioutil.TempFile or the 'mktemp` command. + +go build -o empty-file$GOEXE main.go + +-- main.go -- +package main +func main() {} +-- empty-file$GOEXE -- diff --git a/libgo/go/cmd/go/testdata/script/test_devnull.txt b/libgo/go/cmd/go/testdata/script/test_devnull.txt deleted file mode 100644 index 33071679a29..00000000000 --- a/libgo/go/cmd/go/testdata/script/test_devnull.txt +++ /dev/null @@ -1,15 +0,0 @@ -env GO111MODULE=off - -# go test -c -o NUL -# should work (see golang.org/issue/28035). -cd x -go test -o=$devnull -c -! exists x.test$GOEXE - --- x/x_test.go -- -package x_test -import ( - "testing" -) -func TestNUL(t *testing.T) { -} diff --git a/libgo/go/cmd/go/testdata/script/test_main_archive.txt b/libgo/go/cmd/go/testdata/script/test_main_archive.txt new file mode 100644 index 00000000000..410d923d237 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/test_main_archive.txt @@ -0,0 +1,32 @@ +env GO111MODULE=off + +# Test that a main_test of 'package main' imports the package, +# not the installed binary. + +[short] skip + +env GOBIN=$WORK/bin +go test main_test +go install main_test + +go list -f '{{.Stale}}' main_test +stdout false + +go test main_test + +-- main_test/m.go -- +package main + +func F() {} +func main() {} +-- main_test/m_test.go -- +package main_test + +import ( + . "main_test" + "testing" +) + +func Test1(t *testing.T) { + F() +} diff --git a/libgo/go/cmd/go/testdata/script/test_rebuildall.txt b/libgo/go/cmd/go/testdata/script/test_rebuildall.txt new file mode 100644 index 00000000000..38233c18922 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/test_rebuildall.txt @@ -0,0 +1,14 @@ +env GO111MODULE=off + +# Regression test for golang.org/issue/6844: +# 'go test -a' should force dependencies in the standard library to be rebuilt. + +[short] skip + +go test -x -a -c testdata/dep_test.go +stderr '^.*[/\\]compile'$GOEXE'["]? (.* )?regexp .*[/\\]regexp\.go' + +-- testdata/dep_test.go -- +package deps + +import _ "testing" diff --git a/libgo/go/cmd/go/testdata/script/test_timeout.txt b/libgo/go/cmd/go/testdata/script/test_timeout.txt index 8dead0a439a..4de4df45082 100644 --- a/libgo/go/cmd/go/testdata/script/test_timeout.txt +++ b/libgo/go/cmd/go/testdata/script/test_timeout.txt @@ -2,12 +2,13 @@ env GO111MODULE=off cd a -# No timeout is passed via 'go test' command. -go test -v +# If no timeout is set explicitly, 'go test' should set +# -test.timeout to its internal deadline. +go test -v . -- stdout '10m0s' -# Timeout is passed via 'go test' command. -go test -v -timeout 30m +# An explicit -timeout argument should be propagated to -test.timeout. +go test -v -timeout 30m . -- stdout '30m0s' -- a/timeout_test.go -- @@ -19,4 +20,4 @@ import ( ) func TestTimeout(t *testing.T) { fmt.Println(flag.Lookup("test.timeout").Value.String()) -} \ No newline at end of file +} diff --git a/libgo/go/cmd/go/testdata/script/version.txt b/libgo/go/cmd/go/testdata/script/version.txt index 9086f047e4b..42526247f1e 100644 --- a/libgo/go/cmd/go/testdata/script/version.txt +++ b/libgo/go/cmd/go/testdata/script/version.txt @@ -1,6 +1,7 @@ env GO111MODULE=on [short] skip +# Check that 'go version' and 'go version -m' work on a binary built in module mode. go build -o fortune.exe rsc.io/fortune go version fortune.exe stdout '^fortune.exe: .+' @@ -8,6 +9,10 @@ go version -m fortune.exe stdout '^\tpath\trsc.io/fortune' stdout '^\tmod\trsc.io/fortune\tv1.0.0' +# Repeat the test with -buildmode=pie. +# TODO(golang.org/issue/27144): don't skip after -buildmode=pie is implemented +# on Windows. +[windows] skip # -buildmode=pie not supported go build -buildmode=pie -o external.exe rsc.io/fortune go version external.exe stdout '^external.exe: .+' diff --git a/libgo/go/cmd/go/testdata/script/vet_flags.txt b/libgo/go/cmd/go/testdata/script/vet_flags.txt new file mode 100644 index 00000000000..94bfd126c09 --- /dev/null +++ b/libgo/go/cmd/go/testdata/script/vet_flags.txt @@ -0,0 +1,37 @@ +env GO111MODULE=on + +# gccgo doesn't support vet on the standard library +[gccgo] skip + +# Regression test for issue 35837: "go vet - " +# did not apply the requested analyzer. +go vet -n -unreachable=false encoding/binary +stderr '-unreachable=false' +! stderr '-unsafeptr=false' + +[short] stop +env GOCACHE=$WORK/gocache +env GOTMPDIR=$WORK/tmp +go env GOTMPDIR +stdout '/tmp' + +# "go test" on a user package should by default enable an explicit whitelist of analyzers. +go test -x -run=none . +stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# "go test" on a standard package should by default disable an explicit blacklist. +go test -x -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +# Both should allow users to override via the -vet flag. +go test -x -vet=unreachable -run=none . +stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' +go test -x -vet=unreachable -run=none encoding/binary +stderr '[/\\]vet'$GOEXE'["]? -unreachable ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' + +-- go.mod -- +module example.com/x +-- x.go -- +package x +-- x_test.go -- +package x diff --git a/libgo/go/cmd/go/testdata/src/canonical/a/a.go b/libgo/go/cmd/go/testdata/src/canonical/a/a.go deleted file mode 100644 index 486cc4843fd..00000000000 --- a/libgo/go/cmd/go/testdata/src/canonical/a/a.go +++ /dev/null @@ -1,3 +0,0 @@ -package a - -import _ "c" diff --git a/libgo/go/cmd/go/testdata/src/canonical/a/vendor/c/c.go b/libgo/go/cmd/go/testdata/src/canonical/a/vendor/c/c.go deleted file mode 100644 index 7f96c221c2d..00000000000 --- a/libgo/go/cmd/go/testdata/src/canonical/a/vendor/c/c.go +++ /dev/null @@ -1 +0,0 @@ -package c diff --git a/libgo/go/cmd/go/testdata/src/canonical/b/b.go b/libgo/go/cmd/go/testdata/src/canonical/b/b.go deleted file mode 100644 index ce0f4ce3035..00000000000 --- a/libgo/go/cmd/go/testdata/src/canonical/b/b.go +++ /dev/null @@ -1,3 +0,0 @@ -package b - -import _ "canonical/a/" diff --git a/libgo/go/cmd/go/testdata/src/canonical/d/d.go b/libgo/go/cmd/go/testdata/src/canonical/d/d.go deleted file mode 100644 index ef7dd7dd461..00000000000 --- a/libgo/go/cmd/go/testdata/src/canonical/d/d.go +++ /dev/null @@ -1,3 +0,0 @@ -package d - -import _ "canonical/b" diff --git a/libgo/go/cmd/go/testdata/src/go-cmd-test/helloworld.go b/libgo/go/cmd/go/testdata/src/go-cmd-test/helloworld.go deleted file mode 100644 index 002a5c740c7..00000000000 --- a/libgo/go/cmd/go/testdata/src/go-cmd-test/helloworld.go +++ /dev/null @@ -1,5 +0,0 @@ -package main - -func main() { - println("hello world") -} diff --git a/libgo/go/cmd/go/testdata/src/main_test/m.go b/libgo/go/cmd/go/testdata/src/main_test/m.go deleted file mode 100644 index c682f030b4e..00000000000 --- a/libgo/go/cmd/go/testdata/src/main_test/m.go +++ /dev/null @@ -1,4 +0,0 @@ -package main - -func F() {} -func main() {} diff --git a/libgo/go/cmd/go/testdata/src/main_test/m_test.go b/libgo/go/cmd/go/testdata/src/main_test/m_test.go deleted file mode 100644 index f865b7734f0..00000000000 --- a/libgo/go/cmd/go/testdata/src/main_test/m_test.go +++ /dev/null @@ -1,10 +0,0 @@ -package main_test - -import ( - . "main_test" - "testing" -) - -func Test1(t *testing.T) { - F() -} diff --git a/libgo/go/cmd/go/testdata/src/testcache/testcache_test.go b/libgo/go/cmd/go/testdata/src/testcache/testcache_test.go deleted file mode 100644 index 9b2d1ea7824..00000000000 --- a/libgo/go/cmd/go/testdata/src/testcache/testcache_test.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package testcache - -import ( - "io/ioutil" - "os" - "runtime" - "testing" -) - -func TestChdir(t *testing.T) { - os.Chdir("..") - defer os.Chdir("testcache") - info, err := os.Stat("testcache/file.txt") - if err != nil { - t.Fatal(err) - } - if info.Size()%2 != 1 { - t.Fatal("even file") - } -} - -func TestOddFileContent(t *testing.T) { - f, err := os.Open("file.txt") - if err != nil { - t.Fatal(err) - } - data, err := ioutil.ReadAll(f) - f.Close() - if err != nil { - t.Fatal(err) - } - if len(data)%2 != 1 { - t.Fatal("even file") - } -} - -func TestOddFileSize(t *testing.T) { - info, err := os.Stat("file.txt") - if err != nil { - t.Fatal(err) - } - if info.Size()%2 != 1 { - t.Fatal("even file") - } -} - -func TestOddGetenv(t *testing.T) { - val := os.Getenv("TESTKEY") - if len(val)%2 != 1 { - t.Fatal("even env value") - } -} - -func TestLookupEnv(t *testing.T) { - _, ok := os.LookupEnv("TESTKEY") - if !ok { - t.Fatal("env missing") - } -} - -func TestDirList(t *testing.T) { - f, err := os.Open(".") - if err != nil { - t.Fatal(err) - } - f.Readdirnames(-1) - f.Close() -} - -func TestExec(t *testing.T) { - if runtime.GOOS == "plan9" || runtime.GOOS == "windows" || runtime.GOOS == "nacl" { - t.Skip("non-unix") - } - - // Note: not using os/exec to make sure there is no unexpected stat. - p, err := os.StartProcess("./script.sh", []string{"script"}, new(os.ProcAttr)) - if err != nil { - t.Fatal(err) - } - ps, err := p.Wait() - if err != nil { - t.Fatal(err) - } - if !ps.Success() { - t.Fatalf("script failed: %v", err) - } -} diff --git a/libgo/go/cmd/gofmt/gofmt.go b/libgo/go/cmd/gofmt/gofmt.go index d7a77a96823..9e472b2d51c 100644 --- a/libgo/go/cmd/gofmt/gofmt.go +++ b/libgo/go/cmd/gofmt/gofmt.go @@ -16,11 +16,12 @@ import ( "io" "io/ioutil" "os" - "os/exec" "path/filepath" "runtime" "runtime/pprof" "strings" + + "cmd/internal/diff" ) var ( @@ -141,7 +142,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error } } if *doDiff { - data, err := diff(src, res, filename) + data, err := diffWithReplaceTempFile(src, res, filename) if err != nil { return fmt.Errorf("computing diff: %s", err) } @@ -227,47 +228,12 @@ func gofmtMain() { } } -func writeTempFile(dir, prefix string, data []byte) (string, error) { - file, err := ioutil.TempFile(dir, prefix) - if err != nil { - return "", err - } - _, err = file.Write(data) - if err1 := file.Close(); err == nil { - err = err1 - } - if err != nil { - os.Remove(file.Name()) - return "", err - } - return file.Name(), nil -} - -func diff(b1, b2 []byte, filename string) (data []byte, err error) { - f1, err := writeTempFile("", "gofmt", b1) - if err != nil { - return - } - defer os.Remove(f1) - - f2, err := writeTempFile("", "gofmt", b2) - if err != nil { - return - } - defer os.Remove(f2) - - cmd := "diff" - if runtime.GOOS == "plan9" { - cmd = "/bin/ape/diff" - } - - data, err = exec.Command(cmd, "-u", f1, f2).CombinedOutput() +func diffWithReplaceTempFile(b1, b2 []byte, filename string) ([]byte, error) { + data, err := diff.Diff("gofmt", b1, b2) if len(data) > 0 { - // diff exits with a non-zero status when the files don't match. - // Ignore that failure as long as we get output. return replaceTempFilename(data, filename) } - return + return data, err } // replaceTempFilename replaces temporary filenames in diff with actual one. diff --git a/libgo/go/cmd/gofmt/gofmt_test.go b/libgo/go/cmd/gofmt/gofmt_test.go index 3008365cd23..98d3eb7eb27 100644 --- a/libgo/go/cmd/gofmt/gofmt_test.go +++ b/libgo/go/cmd/gofmt/gofmt_test.go @@ -112,7 +112,7 @@ func runTest(t *testing.T, in, out string) { } t.Errorf("(gofmt %s) != %s (see %s.gofmt)", in, out, in) - d, err := diff(expected, got, in) + d, err := diffWithReplaceTempFile(expected, got, in) if err == nil { t.Errorf("%s", d) } @@ -194,7 +194,7 @@ func TestDiff(t *testing.T) { in := []byte("first\nsecond\n") out := []byte("first\nthird\n") filename := "difftest.txt" - b, err := diff(in, out, filename) + b, err := diffWithReplaceTempFile(in, out, filename) if err != nil { t.Fatal(err) } diff --git a/libgo/go/cmd/gofmt/rewrite.go b/libgo/go/cmd/gofmt/rewrite.go index 79b7858a5af..bab22e04cda 100644 --- a/libgo/go/cmd/gofmt/rewrite.go +++ b/libgo/go/cmd/gofmt/rewrite.go @@ -271,6 +271,12 @@ func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value) // Otherwise copy. switch p := pattern; p.Kind() { case reflect.Slice: + if p.IsNil() { + // Do not turn nil slices into empty slices. go/ast + // guarantees that certain lists will be nil if not + // populated. + return reflect.Zero(p.Type()) + } v := reflect.MakeSlice(p.Type(), p.Len(), p.Len()) for i := 0; i < p.Len(); i++ { v.Index(i).Set(subst(m, p.Index(i), pos)) diff --git a/libgo/go/cmd/gofmt/testdata/import.golden b/libgo/go/cmd/gofmt/testdata/import.golden index 29bdc9baf4a..1125b70cb76 100644 --- a/libgo/go/cmd/gofmt/testdata/import.golden +++ b/libgo/go/cmd/gofmt/testdata/import.golden @@ -1,3 +1,4 @@ +// package comment package main import ( @@ -8,11 +9,6 @@ import ( "math" ) -import ( - "fmt" - "math" -) - import ( "fmt" @@ -25,6 +21,10 @@ import ( "io" ) +// We reset the line numbering to test that +// the formatting works independent of line directives +//line :19 + import ( "errors" "fmt" @@ -129,3 +129,66 @@ import ( "dedup_by_group" ) + +import ( + "fmt" // for Printf + /* comment */ io1 "io" + /* comment */ io2 "io" + /* comment */ "log" +) + +import ( + "fmt" + /* comment */ io1 "io" + /* comment */ io2 "io" // hello + "math" /* right side */ + // end +) + +import ( + "errors" // for New + "fmt" + /* comment */ io1 "io" /* before */ // after + io2 "io" // another + // end +) + +import ( + "errors" // for New + /* left */ "fmt" /* right */ + "log" // for Fatal + /* left */ "math" /* right */ +) + +import /* why */ /* comment here? */ ( + /* comment */ "fmt" + "math" +) + +// Reset it again +//line :100 + +// Dedup with different import styles +import ( + "path" + . "path" + _ "path" + pathpkg "path" +) + +/* comment */ +import ( + "fmt" + "math" // for Abs + // This is a new run + "errors" + "fmt" +) + +// End an import declaration in the same line +// as the last import. See golang.org/issue/33538. +// Note: Must be the last (or 2nd last) line of the file. +import ( + "fmt" + "math" +) diff --git a/libgo/go/cmd/gofmt/testdata/import.input b/libgo/go/cmd/gofmt/testdata/import.input index 78ab4f65443..040b8722d47 100644 --- a/libgo/go/cmd/gofmt/testdata/import.input +++ b/libgo/go/cmd/gofmt/testdata/import.input @@ -1,3 +1,4 @@ +// package comment package main import ( @@ -8,9 +9,6 @@ import ( "io" ) -import("fmt" -"math") - import ( "fmt" @@ -23,6 +21,10 @@ import ( "io" ) +// We reset the line numbering to test that +// the formatting works independent of line directives +//line :19 + import ( "fmt" "math" @@ -132,3 +134,66 @@ import ( "dedup_by_group" ) + +import ( + /* comment */ io1 "io" + "fmt" // for Printf + /* comment */ "log" + /* comment */ io2 "io" +) + +import ( + /* comment */ io2 "io" // hello + /* comment */ io1 "io" + "math" /* right side */ + "fmt" + // end +) + +import ( + /* comment */ io1 "io" /* before */ // after + "fmt" + "errors" // for New + io2 "io" // another + // end +) + +import ( + /* left */ "fmt" /* right */ + "errors" // for New + /* left */ "math" /* right */ + "log" // for Fatal +) + +import /* why */ /* comment here? */ ( + /* comment */ "fmt" + "math" +) + +// Reset it again +//line :100 + +// Dedup with different import styles +import ( + "path" + . "path" + _ "path" + "path" + pathpkg "path" +) + +/* comment */ +import ( + "math" // for Abs + "fmt" + // This is a new run + "errors" + "fmt" + "errors" +) + +// End an import declaration in the same line +// as the last import. See golang.org/issue/33538. +// Note: Must be the last (or 2nd last) line of the file. +import("fmt" +"math") \ No newline at end of file diff --git a/libgo/go/cmd/gofmt/testdata/issue28082.golden b/libgo/go/cmd/gofmt/testdata/issue28082.golden new file mode 100644 index 00000000000..5837fd52912 --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/issue28082.golden @@ -0,0 +1,13 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// testcase for issue #28082 + +func foo() {} + +func main() {} + +func bar() {} diff --git a/libgo/go/cmd/gofmt/testdata/issue28082.input b/libgo/go/cmd/gofmt/testdata/issue28082.input new file mode 100644 index 00000000000..ab7d2186cea --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/issue28082.input @@ -0,0 +1,13 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// testcase for issue #28082 + +func foo( ) {} + +func main( ) {} + +func bar() {} diff --git a/libgo/go/cmd/gofmt/testdata/rewrite10.golden b/libgo/go/cmd/gofmt/testdata/rewrite10.golden new file mode 100644 index 00000000000..1dd781fbb09 --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/rewrite10.golden @@ -0,0 +1,19 @@ +//gofmt -r=a->a + +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 33103, 33104, and 33105. + +package pkg + +func fn() { + _ = func() { + switch { + default: + } + } + _ = func() string {} + _ = func() { var ptr *string; println(ptr) } +} diff --git a/libgo/go/cmd/gofmt/testdata/rewrite10.input b/libgo/go/cmd/gofmt/testdata/rewrite10.input new file mode 100644 index 00000000000..1dd781fbb09 --- /dev/null +++ b/libgo/go/cmd/gofmt/testdata/rewrite10.input @@ -0,0 +1,19 @@ +//gofmt -r=a->a + +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 33103, 33104, and 33105. + +package pkg + +func fn() { + _ = func() { + switch { + default: + } + } + _ = func() string {} + _ = func() { var ptr *string; println(ptr) } +} diff --git a/libgo/go/cmd/internal/buildid/buildid_test.go b/libgo/go/cmd/internal/buildid/buildid_test.go index 15481dd7623..904c2c6f377 100644 --- a/libgo/go/cmd/internal/buildid/buildid_test.go +++ b/libgo/go/cmd/internal/buildid/buildid_test.go @@ -7,6 +7,7 @@ package buildid import ( "bytes" "crypto/sha256" + "internal/obscuretestdata" "io/ioutil" "os" "reflect" @@ -19,13 +20,6 @@ const ( ) func TestReadFile(t *testing.T) { - var files = []string{ - "p.a", - "a.elf", - "a.macho", - "a.pe", - } - f, err := ioutil.TempFile("", "buildid-test-") if err != nil { t.Fatal(err) @@ -34,26 +28,43 @@ func TestReadFile(t *testing.T) { defer os.Remove(tmp) f.Close() - for _, f := range files { - id, err := ReadFile("testdata/" + f) + // Use obscured files to prevent Apple’s notarization service from + // mistaking them as candidates for notarization and rejecting the entire + // toolchain. + // See golang.org/issue/34986 + var files = []string{ + "p.a.base64", + "a.elf.base64", + "a.macho.base64", + "a.pe.base64", + } + + for _, name := range files { + f, err := obscuretestdata.DecodeToTempFile("testdata/" + name) + if err != nil { + t.Errorf("obscuretestdata.DecodeToTempFile(testdata/%s): %v", name, err) + continue + } + defer os.Remove(f) + id, err := ReadFile(f) if id != expectedID || err != nil { t.Errorf("ReadFile(testdata/%s) = %q, %v, want %q, nil", f, id, err, expectedID) } old := readSize readSize = 2048 - id, err = ReadFile("testdata/" + f) + id, err = ReadFile(f) readSize = old if id != expectedID || err != nil { - t.Errorf("ReadFile(testdata/%s) [readSize=2k] = %q, %v, want %q, nil", f, id, err, expectedID) + t.Errorf("ReadFile(%s) [readSize=2k] = %q, %v, want %q, nil", f, id, err, expectedID) } - data, err := ioutil.ReadFile("testdata/" + f) + data, err := ioutil.ReadFile(f) if err != nil { t.Fatal(err) } m, _, err := FindAndHash(bytes.NewReader(data), expectedID, 1024) if err != nil { - t.Errorf("FindAndHash(testdata/%s): %v", f, err) + t.Errorf("FindAndHash(%s): %v", f, err) continue } if err := ioutil.WriteFile(tmp, data, 0666); err != nil { @@ -68,7 +79,7 @@ func TestReadFile(t *testing.T) { err = Rewrite(tf, m, newID) err2 := tf.Close() if err != nil { - t.Errorf("Rewrite(testdata/%s): %v", f, err) + t.Errorf("Rewrite(%s): %v", f, err) continue } if err2 != nil { @@ -77,7 +88,7 @@ func TestReadFile(t *testing.T) { id, err = ReadFile(tmp) if id != newID || err != nil { - t.Errorf("ReadFile(testdata/%s after Rewrite) = %q, %v, want %q, nil", f, id, err, newID) + t.Errorf("ReadFile(%s after Rewrite) = %q, %v, want %q, nil", f, id, err, newID) } } } diff --git a/libgo/go/cmd/internal/buildid/testdata/a.elf b/libgo/go/cmd/internal/buildid/testdata/a.elf deleted file mode 100644 index f63128921aa..00000000000 Binary files a/libgo/go/cmd/internal/buildid/testdata/a.elf and /dev/null differ diff --git a/libgo/go/cmd/internal/buildid/testdata/a.elf.base64 b/libgo/go/cmd/internal/buildid/testdata/a.elf.base64 new file mode 100644 index 00000000000..fa855217358 --- /dev/null +++ b/libgo/go/cmd/internal/buildid/testdata/a.elf.base64 @@ -0,0 +1 @@ +f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAABBAAAAAAABAAAAAAAAAAMgBAAAAAAAAAAAAAEAAOAAHAEAADQADAAYAAAAEAAAAQAAAAAAAAABAAEAAAAAAAEAAQAAAAAAAiAEAAAAAAACIAQAAAAAAAAAQAAAAAAAABAAAAAQAAACUDwAAAAAAAJQPQAAAAAAAlA9AAAAAAABsAAAAAAAAAGwAAAAAAAAABAAAAAAAAAABAAAABQAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAABAQAAAAAAAAEBAAAAAAAAAAEAAAAAAAAAEAAAAEAAAAACAAAAAAAAAAIEAAAAAAAAAgQAAAAAAAfgEAAAAAAAB+AQAAAAAAAAAQAAAAAAAAAQAAAAYAAAAAMAAAAAAAAAAwQAAAAAAAADBAAAAAAADgAQAAAAAAAOABAAAAAAAAABAAAAAAAABR5XRkBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAIAVBGUAKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAABgAAAAAAAAAAEEAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAABBAAAAAQAAAAIAAAAAAAAAACBAAAAAAAAAIAAAAAAAADgAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAcgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAQCAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAEkAAAABAAAAAgAAAAAAAAC8IEAAAAAAALwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAABTAAAAAQAAAAIAAAAAAAAAvCBAAAAAAAC8IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXQAAAAEAAAACAAAAAAAAALwgQAAAAAAAvCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAGcAAAABAAAAAgAAAAAAAADAIEAAAAAAAMAgAAAAAAAAvgAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAHAAAAAQAAAAMAAAAAAAAAADBAAAAAAAAAMAAAAAAAAOABAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAEgAAAAgAAAADAAAAAAAAAOAxQAAAAAAA4DEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAAAIAAAAAwAAAAAAAADgMUAAAAAAAOAxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdAAAACAAAAAMAAAAAAAAA4DFAAAAAAADgMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJwAAAAcAAAACAAAAAAAAAJQPQAAAAAAAlA8AAAAAAABsAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABbAAAABAAAAEdvAABhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei4xMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0AMPMzMzMzMzMzMzMzMzMzMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAEEAAAAAAAAAAAAAAAAAAAC50ZXh0AC5ub3B0cmRhdGEALmRhdGEALmJzcwAubm9wdHJic3MALm5vdGUuZ28uYnVpbGRpZAAuZWxmZGF0YQAucm9kYXRhAC50eXBlbGluawAuaXRhYmxpbmsALmdvc3ltdGFiAC5nb3BjbG50YWIALnNoc3RydGFiAAAAAAD7////AAABCAEAAAAAAAAAABBAAAAAAAAwAAAAAAAAAAEQQAAAAAAAgAAAAAAAAAAAEEAAAAAAAGgAAAAAAAAAZ0UjAXMAAAB2AAAAeQAAAAAAAAACAAAAACBAAAAAAAAAIEAAAAAAAG1haW4ubWFpbgAAAgEABAEABgEAAAAAAAIAAACIAAAAL1VzZXJzL3JzYy9nby9zcmMvY21kL2ludGVybmFsL2J1aWxkaWQvdGVzdGRhdGEvcC5nbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIDBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAIEAAAAAAAL4AAAAAAAAAvgAAAAAAAADQIEAAAAAAAAIAAAAAAAAAAgAAAAAAAABAIUAAAAAAAAIAAAAAAAAAAgAAAAAAAAAMIEAAAAAAAAAQQAAAAAAAARBAAAAAAAAAEEAAAAAAABAQQAAAAAAAADBAAAAAAADgMUAAAAAAAOAxQAAAAAAA4DFAAAAAAADgMUAAAAAAAOAxQAAAAAAA4DFAAAAAAADgMUAAAAAAAOAxQAAAAAAACSBAAAAAAAAIIEAAAAAAAAAgQAAAAAAAOCBAAAAAAAAgIEAAAAAAAAEAAAAAAAAAAQAAAAAAAAC8IEAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8IEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA diff --git a/libgo/go/cmd/internal/buildid/testdata/a.macho b/libgo/go/cmd/internal/buildid/testdata/a.macho deleted file mode 100644 index fbbd57c1fe3..00000000000 Binary files a/libgo/go/cmd/internal/buildid/testdata/a.macho and /dev/null differ diff --git a/libgo/go/cmd/internal/buildid/testdata/a.macho.base64 b/libgo/go/cmd/internal/buildid/testdata/a.macho.base64 new file mode 100644 index 00000000000..2e9f6a7dff3 --- /dev/null +++ b/libgo/go/cmd/internal/buildid/testdata/a.macho.base64 @@ -0,0 +1 @@ +z/rt/gcAAAEDAAAAAgAAAAkAAAAwBgAAAQAAAAAAAAAZAAAASAAAAF9fUEFHRVpFUk8AAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAeAIAAF9fVEVYVAAAAAAAAAAAAAAAAAABAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAcAAAAFAAAABwAAAAAAAABfX3RleHQAAAAAAAAAAAAAX19URVhUAAAAAAAAAAAAAAAQAAEAAAAAgAAAAAAAAAAAEAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAF9fcm9kYXRhAAAAAAAAAABfX1RFWFQAAAAAAAAAAAAAgBAAAQAAAAA4AAAAAAAAAIAQAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX19zeW1ib2xfc3R1YjEAAF9fVEVYVAAAAAAAAAAAAAC4EAABAAAAAAAAAAAAAAAAuBAAAAAAAAAAAAAAAAAAAAgEAIAAAAAABgAAAAAAAABfX3R5cGVsaW5rAAAAAAAAX19URVhUAAAAAAAAAAAAALgQAAEAAAAAAAAAAAAAAAC4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9faXRhYmxpbmsAAAAAAABfX1RFWFQAAAAAAAAAAAAAuBAAAQAAAAAAAAAAAAAAALgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX19nb3N5bXRhYgAAAAAAAF9fVEVYVAAAAAAAAAAAAAC4EAABAAAAAAAAAAAAAAAAuBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2dvcGNsbnRhYgAAAAAAX19URVhUAAAAAAAAAAAAAMAQAAEAAAAABgEAAAAAAADAEAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkAAADYAQAAX19EQVRBAAAAAAAAAAAAAAAgAAEAAAAA4AEAAAAAAAAAIAAAAAAAAOABAAAAAAAAAwAAAAMAAAAFAAAAAAAAAF9fbmxfc3ltYm9sX3B0cgBfX0RBVEEAAAAAAAAAAAAAACAAAQAAAAAAAAAAAAAAAAAgAAACAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAX19ub3B0cmRhdGEAAAAAAF9fREFUQQAAAAAAAAAAAAAAIAABAAAAAOABAAAAAAAAACAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2RhdGEAAAAAAAAAAAAAX19EQVRBAAAAAAAAAAAAAOAhAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAF9fYnNzAAAAAAAAAAAAAABfX0RBVEEAAAAAAAAAAAAA4CEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAX19ub3B0cmJzcwAAAAAAAF9fREFUQQAAAAAAAAAAAADgIQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAZAAAASAAAAF9fTElOS0VESVQAAAAAAAAAMAABAAAAAKAEAAAAAAAAADAAAAAAAACgBAAAAAAAAAcAAAADAAAAAAAAAAAAAAAFAAAAuAAAAAQAAAAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwEAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAABgAAAAAMAAAJQAAAFAyAABQAgAACwAAAFAAAAAAAAAAJQAAACUAAAAAAAAAJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAIAAAAAwAAAAvdXNyL2xpYi9keWxkAAAAAAAAACQAAAAQAAAAAAcKAAAHCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8gR28gYnVpbGQgSUQ6ICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei4xMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0Igog/8zDzMzMzMzMzMzMzMzMzMzMAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAABAAAQAAAAAAAAAAAAAAAPv///8AAAEIAgAAAAAAAAAAEAABAAAAAEAAAAAAAAAAcBAAAQAAAAB4AAAAAAAAAHEQAAEAAAAAyAAAAAAAAAAAEAABAAAAAGgAAAAAAAAAZ0UjAQAAAAAAAAAAAAAAAAAAAAAAAAAAZ28uYnVpbGRpZAAAAAAAAHAQAAEAAAAAsAAAAAAAAABnRSMBuwAAAL4AAADBAAAAAAAAAAIAAACAEAABAAAAAIAQAAEAAAAAbWFpbi5tYWluAAACAQAEAQAGAQAAAAAAAgAAANAAAAAvVXNlcnMvcnNjL2dvL3NyYy9jbWQvaW50ZXJuYWwvYnVpbGRpZC90ZXN0ZGF0YS9wLmdvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAQAAEAAAAABgEAAAAAAAAGAQAAAAAAANAQAAEAAAAAAwAAAAAAAAADAAAAAAAAAIgRAAEAAAAAAgAAAAAAAAACAAAAAAAAAIwQAAEAAAAAABAAAQAAAABxEAABAAAAAAAQAAEAAAAAgBAAAQAAAAAAIAABAAAAAOAhAAEAAAAA4CEAAQAAAADgIQABAAAAAOAhAAEAAAAA4CEAAQAAAADgIQABAAAAAOAhAAEAAAAA4CEAAQAAAACJEAABAAAAAIgQAAEAAAAAgBAAAQAAAAC4EAABAAAAAKAQAAEAAAAAAQAAAAAAAAABAAAAAAAAALgQAAEAAAAAAAAAAAAAAAAAAAAAAAAAALgQAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAA4BAAAAEAABAAAAAA0AAAAOAgAAgBAAAQAAAAAXAAAADgIAAIAQAAEAAAAAIwAAAA4BAABwEAABAAAAAC0AAAAOCwAA4CEAAQAAAAA5AAAADgoAAOAhAAEAAAAARgAAAA4LAADgIQABAAAAAFMAAAAOCgAA4CEAAQAAAABhAAAADgIAAIkQAAEAAAAAcAAAAA4CAACKEAABAAAAAIAAAAAOBQAAuBAAAQAAAACSAAAADgwAAOAhAAEAAAAAngAAAA4MAADgIQABAAAAALAAAAAOCQAA4CEAAQAAAADDAAAADgcAAMYRAAEAAAAA1AAAAA4CAAC4EAABAAAAAOQAAAAOBgAAuBAAAQAAAAD0AAAADgEAAIAQAAEAAAAAAgEAAA4CAAC4EAABAAAAABEBAAAOAgAAjBAAAQAAAAAlAQAADgkAACAgAAEAAAAAPQEAAA4CAACKEAABAAAAAFoBAAAOAgAAiBAAAQAAAABrAQAADgIAAIgQAAEAAAAAeQEAAA4CAACJEAABAAAAAIgBAAAOBQAAuBAAAQAAAACZAQAADgkAAAAgAAEAAAAAsQEAAA4MAADgIQABAAAAAMIBAAAOCQAAACAAAQAAAADUAQAADgcAAMAQAAEAAAAA5AEAAA4CAACAEAABAAAAAPMBAAAOBgAAuBAAAQAAAAACAgAADgEAAAAQAAEAAAAADwIAAA4CAACgEAABAAAAACYCAAAOBAAAuBAAAQAAAAA3AgAADgIAAIAQAAEAAAAARQIAAA4CAACAEAABAAAAACAAZ28uYnVpbGRpZABnby5mdW5jLioAZ28uc3RyaW5nLioAbWFpbi5tYWluAHJ1bnRpbWUuYnNzAHJ1bnRpbWUuZGF0YQBydW50aW1lLmVic3MAcnVudGltZS5lZGF0YQBydW50aW1lLmVnY2JzcwBydW50aW1lLmVnY2RhdGEAcnVudGltZS5laXRhYmxpbmsAcnVudGltZS5lbmQAcnVudGltZS5lbm9wdHJic3MAcnVudGltZS5lbm9wdHJkYXRhAHJ1bnRpbWUuZXBjbG50YWIAcnVudGltZS5lcm9kYXRhAHJ1bnRpbWUuZXN5bXRhYgBydW50aW1lLmV0ZXh0AHJ1bnRpbWUuZXR5cGVzAHJ1bnRpbWUuZmluZGZ1bmN0YWIAcnVudGltZS5maXJzdG1vZHVsZWRhdGEAcnVudGltZS5mcmFtZXBvaW50ZXJfZW5hYmxlZABydW50aW1lLmdjYml0cy4qAHJ1bnRpbWUuZ2Nic3MAcnVudGltZS5nY2RhdGEAcnVudGltZS5pdGFibGluawBydW50aW1lLmxhc3Rtb2R1bGVkYXRhcABydW50aW1lLm5vcHRyYnNzAHJ1bnRpbWUubm9wdHJkYXRhAHJ1bnRpbWUucGNsbnRhYgBydW50aW1lLnJvZGF0YQBydW50aW1lLnN5bXRhYgBydW50aW1lLnRleHQAcnVudGltZS50ZXh0c2VjdGlvbm1hcABydW50aW1lLnR5cGVsaW5rAHJ1bnRpbWUudHlwZXMAdHlwZS4qAAAAAAA= diff --git a/libgo/go/cmd/internal/buildid/testdata/a.pe b/libgo/go/cmd/internal/buildid/testdata/a.pe deleted file mode 100644 index 91202728c3f..00000000000 Binary files a/libgo/go/cmd/internal/buildid/testdata/a.pe and /dev/null differ diff --git a/libgo/go/cmd/internal/buildid/testdata/a.pe.base64 b/libgo/go/cmd/internal/buildid/testdata/a.pe.base64 new file mode 100644 index 00000000000..d3a31a3a627 --- /dev/null +++ b/libgo/go/cmd/internal/buildid/testdata/a.pe.base64 @@ -0,0 +1 @@ +TVqQAAMABAAAAAAA//8AAIsAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAAZIYEAAAAAAAADAAAAAAAAPAAIwILAgMAAAIAAAACAAAAAAAAcBAAAAAQAAAAAEAAAAAAAAAQAAAAAgAABAAAAAEAAAAEAAAAAAAAAABQAAAABgAAAAAAAAMAAAAAACAAAAAAAADgHwAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAMAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAudGV4dAAAAMYBAAAAEAAAAAIAAAAGAAAAAAAAAAAAAAAAAABgAABgLmRhdGEAAADgAQAAACAAAAACAAAACAAAAAAAAAAAAAAAAAAAQAAAwC5pZGF0YQAAFAAAAAAwAAAAAgAAAAoAAAAAAAAAAAAAAAAAAEAAAMAuc3ltdGFiAAQAAAAAQAAAAAIAAAAMAAAAAAAAAAAAAAAAAAAAAABCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/yBHbyBidWlsZCBJRDogImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6LjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQiCiD/zMPMzMzMzMzMzMzMzMzMzMwBAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAEEAAAAAAAAAAAAAAAAAA+////wAAAQgCAAAAAAAAAAAQQAAAAAAAQAAAAAAAAABwEEAAAAAAAHgAAAAAAAAAcRBAAAAAAADIAAAAAAAAAAAQQAAAAAAAaAAAAAAAAABnRSMBAAAAAAAAAAAAAAAAAAAAAAAAAABnby5idWlsZGlkAAAAAAAAcBBAAAAAAACwAAAAAAAAAGdFIwG7AAAAvgAAAMEAAAAAAAAAAgAAAIAQQAAAAAAAgBBAAAAAAABtYWluLm1haW4AAAIBAAQBAAYBAAAAAAACAAAA0AAAAC9Vc2Vycy9yc2MvZ28vc3JjL2NtZC9pbnRlcm5hbC9idWlsZGlkL3Rlc3RkYXRhL3AuZ28AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAQQAAAAAAABgEAAAAAAAAGAQAAAAAAANAQQAAAAAAAAwAAAAAAAAADAAAAAAAAAIgRQAAAAAAAAgAAAAAAAAACAAAAAAAAAIwQQAAAAAAAABBAAAAAAABxEEAAAAAAAAAQQAAAAAAAgBBAAAAAAAAAIEAAAAAAAOAhQAAAAAAA4CFAAAAAAADgIUAAAAAAAOAhQAAAAAAA4CFAAAAAAADgIUAAAAAAAOAhQAAAAAAA4CFAAAAAAACJEEAAAAAAAIgQQAAAAAAAgBBAAAAAAAC4EEAAAAAAAKAQQAAAAAAAAQAAAAAAAAABAAAAAAAAALgQQAAAAAAAAAAAAAAAAAAAAAAAAAAAALgQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= diff --git a/libgo/go/cmd/internal/buildid/testdata/p.a b/libgo/go/cmd/internal/buildid/testdata/p.a deleted file mode 100644 index dcc3e76ef8b..00000000000 Binary files a/libgo/go/cmd/internal/buildid/testdata/p.a and /dev/null differ diff --git a/libgo/go/cmd/internal/buildid/testdata/p.a.base64 b/libgo/go/cmd/internal/buildid/testdata/p.a.base64 new file mode 100644 index 00000000000..ba96c10ca50 --- /dev/null +++ b/libgo/go/cmd/internal/buildid/testdata/p.a.base64 @@ -0,0 +1 @@ +ITxhcmNoPgpfXy5QS0dERUYgICAgICAgMCAgICAgICAgICAgMCAgICAgMCAgICAgNjQ0ICAgICAzMzAgICAgICAgYApnbyBvYmplY3QgZGFyd2luIGFtZDY0IGRldmVsICszYjMzYWY1ZDY4IFRodSBPY3QgNSAxNjo1OTowMCAyMDE3IC0wNDAwIFg6ZnJhbWVwb2ludGVyCmJ1aWxkIGlkICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei4xMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0IgotLS0tCgpidWlsZCBpZCAiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXouMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNCIKCiQkQgp2ZXJzaW9uIDUKCgACAQFwAAsACwABAAokJApfZ29fLm8gICAgICAgICAgMCAgICAgICAgICAgMCAgICAgMCAgICAgNjQ0ICAgICAyMjMgICAgICAgYApnbyBvYmplY3QgZGFyd2luIGFtZDY0IGRldmVsICszYjMzYWY1ZDY4IFRodSBPY3QgNSAxNjo1OTowMCAyMDE3IC0wNDAwIFg6ZnJhbWVwb2ludGVyCmJ1aWxkIGlkICJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei4xMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0IgotLS0tCgoKIQoAAGdvMTlsZAEA/wAAAAAAAP//Z28xOWxkAA== diff --git a/libgo/go/cmd/internal/diff/diff.go b/libgo/go/cmd/internal/diff/diff.go new file mode 100644 index 00000000000..e9d2c237800 --- /dev/null +++ b/libgo/go/cmd/internal/diff/diff.go @@ -0,0 +1,58 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package diff implements a Diff function that compare two inputs +// using the 'diff' tool. +package diff + +import ( + "io/ioutil" + "os" + "os/exec" + "runtime" +) + +// Returns diff of two arrays of bytes in diff tool format. +func Diff(prefix string, b1, b2 []byte) ([]byte, error) { + f1, err := writeTempFile(prefix, b1) + if err != nil { + return nil, err + } + defer os.Remove(f1) + + f2, err := writeTempFile(prefix, b2) + if err != nil { + return nil, err + } + defer os.Remove(f2) + + cmd := "diff" + if runtime.GOOS == "plan9" { + cmd = "/bin/ape/diff" + } + + data, err := exec.Command(cmd, "-u", f1, f2).CombinedOutput() + if len(data) > 0 { + // diff exits with a non-zero status when the files don't match. + // Ignore that failure as long as we get output. + err = nil + } + return data, err +} + +func writeTempFile(prefix string, data []byte) (string, error) { + file, err := ioutil.TempFile("", prefix) + if err != nil { + return "", err + } + _, err = file.Write(data) + if err1 := file.Close(); err == nil { + err = err1 + } + if err != nil { + os.Remove(file.Name()) + return "", err + } + return file.Name(), nil +} diff --git a/libgo/go/cmd/internal/objabi/doc.go b/libgo/go/cmd/internal/objabi/doc.go index 03dc9fb88bc..08e922b11fb 100644 --- a/libgo/go/cmd/internal/objabi/doc.go +++ b/libgo/go/cmd/internal/objabi/doc.go @@ -22,10 +22,12 @@ // // The file format is: // -// - magic header: "\x00go112ld" +// - magic header: "\x00go114ld" // - byte 1 - version number // - sequence of strings giving dependencies (imported packages) // - empty string (marks end of sequence) +// - number of entries in the following sequence +// - sequence of filename strings to generate debug information // - sequence of symbol references used by the defined symbols // - byte 0xff (marks end of sequence) // - sequence of integer lengths: @@ -38,7 +40,7 @@ // - data, the content of the defined symbols // - sequence of defined symbols // - byte 0xff (marks end of sequence) -// - magic footer: "\xffgo112ld" +// - magic footer: "\xffgo114ld" // // All integers are stored in a zigzag varint format. // See golang.org/s/go12symtab for a definition. diff --git a/libgo/go/cmd/internal/objabi/funcdata.go b/libgo/go/cmd/internal/objabi/funcdata.go index addbd2ac88b..08b75eb9fed 100644 --- a/libgo/go/cmd/internal/objabi/funcdata.go +++ b/libgo/go/cmd/internal/objabi/funcdata.go @@ -15,11 +15,12 @@ const ( PCDATA_StackMapIndex = 1 PCDATA_InlTreeIndex = 2 - FUNCDATA_ArgsPointerMaps = 0 - FUNCDATA_LocalsPointerMaps = 1 - FUNCDATA_RegPointerMaps = 2 - FUNCDATA_StackObjects = 3 - FUNCDATA_InlTree = 4 + FUNCDATA_ArgsPointerMaps = 0 + FUNCDATA_LocalsPointerMaps = 1 + FUNCDATA_RegPointerMaps = 2 + FUNCDATA_StackObjects = 3 + FUNCDATA_InlTree = 4 + FUNCDATA_OpenCodedDeferInfo = 5 // ArgsSizeUnknown is set in Func.argsize to mark all functions // whose argument size is unknown (C vararg functions, and diff --git a/libgo/go/cmd/internal/objabi/funcid.go b/libgo/go/cmd/internal/objabi/funcid.go index a30bc3fa05a..0fda1db1789 100644 --- a/libgo/go/cmd/internal/objabi/funcid.go +++ b/libgo/go/cmd/internal/objabi/funcid.go @@ -37,6 +37,8 @@ const ( FuncID_debugCallV1 FuncID_gopanic FuncID_panicwrap + FuncID_handleAsyncEvent + FuncID_asyncPreempt FuncID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.) ) @@ -82,6 +84,19 @@ func GetFuncID(name, file string) FuncID { return FuncID_gopanic case "runtime.panicwrap": return FuncID_panicwrap + case "runtime.handleAsyncEvent": + return FuncID_handleAsyncEvent + case "runtime.asyncPreempt": + return FuncID_asyncPreempt + case "runtime.deferreturn": + // Don't show in the call stack (used when invoking defer functions) + return FuncID_wrapper + case "runtime.runOpenDeferFrame": + // Don't show in the call stack (used when invoking defer functions) + return FuncID_wrapper + case "runtime.reflectcallSave": + // Don't show in the call stack (used when invoking defer functions) + return FuncID_wrapper } if file == "" { return FuncID_wrapper diff --git a/libgo/go/cmd/internal/objabi/head.go b/libgo/go/cmd/internal/objabi/head.go index 0a542282284..6836c338c93 100644 --- a/libgo/go/cmd/internal/objabi/head.go +++ b/libgo/go/cmd/internal/objabi/head.go @@ -42,7 +42,6 @@ const ( Hfreebsd Hjs Hlinux - Hnacl Hnetbsd Hopenbsd Hplan9 @@ -65,8 +64,6 @@ func (h *HeadType) Set(s string) error { *h = Hjs case "linux", "android": *h = Hlinux - case "nacl": - *h = Hnacl case "netbsd": *h = Hnetbsd case "openbsd": @@ -97,8 +94,6 @@ func (h *HeadType) String() string { return "js" case Hlinux: return "linux" - case Hnacl: - return "nacl" case Hnetbsd: return "netbsd" case Hopenbsd: diff --git a/libgo/go/cmd/internal/objabi/reloctype.go b/libgo/go/cmd/internal/objabi/reloctype.go index 5dc9356fe17..dc6482802af 100644 --- a/libgo/go/cmd/internal/objabi/reloctype.go +++ b/libgo/go/cmd/internal/objabi/reloctype.go @@ -64,6 +64,8 @@ const ( // R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address // of a CALL (JAL) instruction, by encoding the address into the instruction. R_CALLMIPS + // R_CALLRISCV marks RISC-V CALLs for stack checking. + R_CALLRISCV R_CONST R_PCREL // R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the @@ -200,6 +202,16 @@ const ( // relocated symbol rather than the symbol's address. R_ADDRPOWER_TOCREL_DS + // RISC-V. + + // R_RISCV_PCREL_ITYPE resolves a 32-bit PC-relative address using an + // AUIPC + I-type instruction pair. + R_RISCV_PCREL_ITYPE + + // R_RISCV_PCREL_STYPE resolves a 32-bit PC-relative address using an + // AUIPC + S-type instruction pair. + R_RISCV_PCREL_STYPE + // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. // TODO(mundaym): remove once variants can be serialized - see issue 14218. R_PCRELDBL @@ -210,6 +222,7 @@ const ( // R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS // address (offset from thread pointer), by encoding it into the instruction. R_ADDRMIPSTLS + // R_ADDRCUOFF resolves to a pointer-sized offset from the start of the // symbol's DWARF compile unit. R_ADDRCUOFF @@ -223,16 +236,34 @@ const ( R_XCOFFREF ) +// IsDirectCall reports whether r is a relocation for a direct call. +// A direct call is a CALL instruction that takes the target address +// as an immediate. The address is embedded into the instruction, possibly +// with limited width. An indirect call is a CALL instruction that takes +// the target address in register or memory. +func (r RelocType) IsDirectCall() bool { + switch r { + case R_CALL, R_CALLARM, R_CALLARM64, R_CALLMIPS, R_CALLPOWER, R_CALLRISCV: + return true + } + return false +} + // IsDirectJump reports whether r is a relocation for a direct jump. -// A direct jump is a CALL or JMP instruction that takes the target address -// as immediate. The address is embedded into the instruction, possibly -// with limited width. -// An indirect jump is a CALL or JMP instruction that takes the target address -// in register or memory. +// A direct jump is a JMP instruction that takes the target address +// as an immediate. The address is embedded into the instruction, possibly +// with limited width. An indirect jump is a JMP instruction that takes +// the target address in register or memory. func (r RelocType) IsDirectJump() bool { switch r { - case R_CALL, R_CALLARM, R_CALLARM64, R_CALLPOWER, R_CALLMIPS, R_JMPMIPS: + case R_JMPMIPS: return true } return false } + +// IsDirectCallOrJump reports whether r is a relocation for a direct +// call or a direct jump. +func (r RelocType) IsDirectCallOrJump() bool { + return r.IsDirectCall() || r.IsDirectJump() +} diff --git a/libgo/go/cmd/internal/objabi/reloctype_string.go b/libgo/go/cmd/internal/objabi/reloctype_string.go index a1c4c1aa518..83dfe71e071 100644 --- a/libgo/go/cmd/internal/objabi/reloctype_string.go +++ b/libgo/go/cmd/internal/objabi/reloctype_string.go @@ -4,9 +4,9 @@ package objabi import "strconv" -const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" +const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" -var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 129, 136, 144, 152, 160, 166, 172, 178, 188, 197, 208, 219, 229, 238, 251, 265, 279, 293, 309, 320, 333, 346, 360, 374, 389, 403, 417, 428, 442, 457, 474, 492, 513, 523, 534, 547, 558, 570, 580} +var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 219, 230, 240, 249, 262, 276, 290, 304, 320, 331, 344, 357, 371, 385, 400, 414, 428, 439, 453, 468, 485, 503, 524, 543, 562, 572, 583, 596, 607, 619, 629} func (i RelocType) String() string { i -= 1 diff --git a/libgo/go/cmd/internal/objabi/stack.go b/libgo/go/cmd/internal/objabi/stack.go index 62ab0398a66..7320dbf365f 100644 --- a/libgo/go/cmd/internal/objabi/stack.go +++ b/libgo/go/cmd/internal/objabi/stack.go @@ -18,7 +18,7 @@ const ( ) // Initialize StackGuard and StackLimit according to target system. -var StackGuard = 880*stackGuardMultiplier() + StackSystem +var StackGuard = 896*stackGuardMultiplier() + StackSystem var StackLimit = StackGuard - StackSystem - StackSmall // stackGuardMultiplier returns a multiplier to apply to the default diff --git a/libgo/go/cmd/internal/objabi/symkind.go b/libgo/go/cmd/internal/objabi/symkind.go index 16b4c535ed8..69f15286cde 100644 --- a/libgo/go/cmd/internal/objabi/symkind.go +++ b/libgo/go/cmd/internal/objabi/symkind.go @@ -59,7 +59,7 @@ const ( SDWARFINFO SDWARFRANGE SDWARFLOC - SDWARFMISC + SDWARFLINES // ABI alias. An ABI alias symbol is an empty symbol with a // single relocation with 0 size that references the native // function implementation symbol. @@ -67,6 +67,8 @@ const ( // TODO(austin): Remove this and all uses once the compiler // generates real ABI wrappers rather than symbol aliases. SABIALIAS + // Coverage instrumentation counter for libfuzzer. + SLIBFUZZER_EXTRA_COUNTER // Update cmd/link/internal/sym/AbiSymKindToSymKind for new SymKind values. ) diff --git a/libgo/go/cmd/internal/objabi/util.go b/libgo/go/cmd/internal/objabi/util.go index bf71b6b0c02..0e7693ee564 100644 --- a/libgo/go/cmd/internal/objabi/util.go +++ b/libgo/go/cmd/internal/objabi/util.go @@ -127,7 +127,7 @@ func init() { } func Framepointer_enabled(goos, goarch string) bool { - return framepointer_enabled != 0 && (goarch == "amd64" && goos != "nacl" || goarch == "arm64" && goos == "linux") + return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && goos == "linux") } func addexp(s string) { diff --git a/libgo/go/cmd/internal/sys/arch.go b/libgo/go/cmd/internal/sys/arch.go index 487c9260e85..e8687363def 100644 --- a/libgo/go/cmd/internal/sys/arch.go +++ b/libgo/go/cmd/internal/sys/arch.go @@ -7,8 +7,7 @@ package sys import "encoding/binary" // ArchFamily represents a family of one or more related architectures. -// For example, amd64 and amd64p32 are both members of the AMD64 family, -// and ppc64 and ppc64le are both members of the PPC64 family. +// For example, ppc64 and ppc64le are both members of the PPC64 family. type ArchFamily byte const ( @@ -20,6 +19,7 @@ const ( MIPS MIPS64 PPC64 + RISCV64 S390X Wasm ) @@ -71,15 +71,6 @@ var ArchAMD64 = &Arch{ MinLC: 1, } -var ArchAMD64P32 = &Arch{ - Name: "amd64p32", - Family: AMD64, - ByteOrder: binary.LittleEndian, - PtrSize: 4, - RegSize: 8, - MinLC: 1, -} - var ArchARM = &Arch{ Name: "arm", Family: ARM, @@ -152,6 +143,15 @@ var ArchPPC64LE = &Arch{ MinLC: 4, } +var ArchRISCV64 = &Arch{ + Name: "riscv64", + Family: RISCV64, + ByteOrder: binary.LittleEndian, + PtrSize: 8, + RegSize: 8, + MinLC: 4, +} + var ArchS390X = &Arch{ Name: "s390x", Family: S390X, @@ -173,7 +173,6 @@ var ArchWasm = &Arch{ var Archs = [...]*Arch{ Arch386, ArchAMD64, - ArchAMD64P32, ArchARM, ArchARM64, ArchMIPS, @@ -182,6 +181,7 @@ var Archs = [...]*Arch{ ArchMIPS64LE, ArchPPC64, ArchPPC64LE, + ArchRISCV64, ArchS390X, ArchWasm, } diff --git a/libgo/go/cmd/internal/sys/supported.go b/libgo/go/cmd/internal/sys/supported.go index 4162858ac1b..02f833e945e 100644 --- a/libgo/go/cmd/internal/sys/supported.go +++ b/libgo/go/cmd/internal/sys/supported.go @@ -43,3 +43,71 @@ func MustLinkExternal(goos, goarch string) bool { } return false } + +// BuildModeSupported reports whether goos/goarch supports the given build mode +// using the given compiler. +func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { + if compiler == "gccgo" { + return true + } + + platform := goos + "/" + goarch + + switch buildmode { + case "archive": + return true + + case "c-archive": + // TODO(bcmills): This seems dubious. + // Do we really support c-archive mode on js/wasm‽ + return platform != "linux/ppc64" + + case "c-shared": + switch platform { + case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/s390x", + "android/amd64", "android/arm", "android/arm64", "android/386", + "freebsd/amd64", + "darwin/amd64", "darwin/386", + "windows/amd64", "windows/386": + return true + } + return false + + case "default": + return true + + case "exe": + return true + + case "pie": + switch platform { + case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", + "android/amd64", "android/arm", "android/arm64", "android/386", + "freebsd/amd64", + "darwin/amd64", + "aix/ppc64": + return true + } + return false + + case "shared": + switch platform { + case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x": + return true + } + return false + + case "plugin": + switch platform { + case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le", + "android/amd64", "android/arm", "android/arm64", "android/386", + "darwin/amd64", + "freebsd/amd64": + return true + } + return false + + default: + return false + } +} diff --git a/libgo/go/cmd/vet/testdata/asm/asm.go b/libgo/go/cmd/vet/testdata/asm/asm.go index 72ff452aae8..1e60d8bf941 100644 --- a/libgo/go/cmd/vet/testdata/asm/asm.go +++ b/libgo/go/cmd/vet/testdata/asm/asm.go @@ -7,3 +7,5 @@ package testdata func arg1(x int8, y uint8) + +func cpx(x complex64, y complex128) diff --git a/libgo/go/cmd/vet/testdata/asm/asm1.s b/libgo/go/cmd/vet/testdata/asm/asm1.s new file mode 100644 index 00000000000..a5bb6dd0af8 --- /dev/null +++ b/libgo/go/cmd/vet/testdata/asm/asm1.s @@ -0,0 +1,23 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64 + +TEXT ·arg1(SB),0,$0-2 + MOVW x+0(FP), AX // ERROR "\[amd64\] arg1: invalid MOVW of x\+0\(FP\); int8 is 1-byte value" + +TEXT ·cpx(SB),0,$0-24 + // These are ok + MOVSS x_real+0(FP), X0 + MOVSS x_imag+4(FP), X0 + MOVSD y_real+8(FP), X0 + MOVSD y_imag+16(FP), X0 + // Loading both parts of a complex is ok: see issue 35264. + MOVSD x+0(FP), X0 + MOVO y+8(FP), X0 + MOVOU y+8(FP), X0 + + // These are not ok. + MOVO x+0(FP), X0 // ERROR "\[amd64\] cpx: invalid MOVO of x\+0\(FP\); complex64 is 8-byte value containing x_real\+0\(FP\) and x_imag\+4\(FP\)" + MOVSD y+8(FP), X0 // ERROR "\[amd64\] cpx: invalid MOVSD of y\+8\(FP\); complex128 is 16-byte value containing y_real\+8\(FP\) and y_imag\+16\(FP\)" diff --git a/libgo/go/cmd/vet/testdata/print/print.go b/libgo/go/cmd/vet/testdata/print/print.go index 7a4783aee4f..fca594925f7 100644 --- a/libgo/go/cmd/vet/testdata/print/print.go +++ b/libgo/go/cmd/vet/testdata/print/print.go @@ -81,8 +81,8 @@ func PrintfTests() { fmt.Printf("%T %T", 3, i) fmt.Printf("%U %U", 3, i) fmt.Printf("%v %v", 3, i) - fmt.Printf("%x %x %x %x", 3, i, "hi", s) - fmt.Printf("%X %X %X %X", 3, i, "hi", s) + fmt.Printf("%x %x %x %x %x %x %x", 3, i, "hi", s, x, c, fslice) + fmt.Printf("%X %X %X %X %X %X %X", 3, i, "hi", s, x, c, fslice) fmt.Printf("%.*s %d %g", 3, "hi", 23, 2.3) fmt.Printf("%s", &stringerv) fmt.Printf("%v", &stringerv) @@ -125,7 +125,6 @@ func PrintfTests() { fmt.Printf("%t", 23) // ERROR "Printf format %t has arg 23 of wrong type int" fmt.Printf("%U", x) // ERROR "Printf format %U has arg x of wrong type float64" fmt.Printf("%x", nil) // ERROR "Printf format %x has arg nil of wrong type untyped nil" - fmt.Printf("%X", 2.3) // ERROR "Printf format %X has arg 2.3 of wrong type float64" fmt.Printf("%s", stringerv) // ERROR "Printf format %s has arg stringerv of wrong type .*print.ptrStringer" fmt.Printf("%t", stringerv) // ERROR "Printf format %t has arg stringerv of wrong type .*print.ptrStringer" fmt.Printf("%s", embeddedStringerv) // ERROR "Printf format %s has arg embeddedStringerv of wrong type .*print.embeddedStringer" diff --git a/libgo/go/cmd/vet/testdata/src/asm/asm1.s b/libgo/go/cmd/vet/testdata/src/asm/asm1.s deleted file mode 100644 index c3ba986fb8b..00000000000 --- a/libgo/go/cmd/vet/testdata/src/asm/asm1.s +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build amd64 - -TEXT ·arg1(SB),0,$0-2 - MOVW x+0(FP), AX // ERROR "\[amd64\] arg1: invalid MOVW of x\+0\(FP\); int8 is 1-byte value" diff --git a/libgo/go/compress/flate/deflate.go b/libgo/go/compress/flate/deflate.go index 8b92f1586db..550032176d7 100644 --- a/libgo/go/compress/flate/deflate.go +++ b/libgo/go/compress/flate/deflate.go @@ -465,17 +465,20 @@ Loop: } else { newIndex = d.index + prevLength - 1 } - for d.index++; d.index < newIndex; d.index++ { - if d.index < d.maxInsertIndex { - d.hash = hash4(d.window[d.index : d.index+minMatchLength]) + index := d.index + for index++; index < newIndex; index++ { + if index < d.maxInsertIndex { + d.hash = hash4(d.window[index : index+minMatchLength]) // Get previous value with the same hash. // Our chain should point to the previous value. hh := &d.hashHead[d.hash&hashMask] - d.hashPrev[d.index&windowMask] = *hh + d.hashPrev[index&windowMask] = *hh // Set the head of the hash chain to us. - *hh = uint32(d.index + d.hashOffset) + *hh = uint32(index + d.hashOffset) } } + d.index = index + if d.fastSkipHashing == skipNever { d.byteAvailable = false d.length = minMatchLength - 1 diff --git a/libgo/go/compress/gzip/gunzip_test.go b/libgo/go/compress/gzip/gunzip_test.go index fdea0c5d5ff..1b014041692 100644 --- a/libgo/go/compress/gzip/gunzip_test.go +++ b/libgo/go/compress/gzip/gunzip_test.go @@ -7,6 +7,7 @@ package gzip import ( "bytes" "compress/flate" + "encoding/base64" "io" "io/ioutil" "os" @@ -413,11 +414,16 @@ func TestDecompressor(t *testing.T) { } func TestIssue6550(t *testing.T) { - f, err := os.Open("testdata/issue6550.gz") + // Apple’s notarization service will recursively attempt to decompress + // files in order to find binaries to notarize. Since the service is + // unable to decompress this file, it may reject the entire toolchain. Use a + // base64-encoded version to avoid this. + // See golang.org/issue/34986 + f, err := os.Open("testdata/issue6550.gz.base64") if err != nil { t.Fatal(err) } - gzip, err := NewReader(f) + gzip, err := NewReader(base64.NewDecoder(base64.StdEncoding, f)) if err != nil { t.Fatalf("NewReader(testdata/issue6550.gz): %v", err) } diff --git a/libgo/go/compress/gzip/testdata/issue6550.gz b/libgo/go/compress/gzip/testdata/issue6550.gz deleted file mode 100644 index 82b4af10263..00000000000 Binary files a/libgo/go/compress/gzip/testdata/issue6550.gz and /dev/null differ diff --git a/libgo/go/compress/gzip/testdata/issue6550.gz.base64 b/libgo/go/compress/gzip/testdata/issue6550.gz.base64 new file mode 100644 index 00000000000..f2509ff5d19 --- /dev/null +++ b/libgo/go/compress/gzip/testdata/issue6550.gz.base64 @@ -0,0 +1 @@ +H4sIpAAAAABRD4Ln88wy94RQV16rm+R8Pqb4w4SMwwfplXWDm+1O+yzZDgz6MI/ICLMlE3SLc8kJX169kFWdNmxRkbZNNdfxpFYvUH6tUEwlFNWxFbXwfymbmzj2n7i/HZcjfnwpVSdQseIGHWN5p1KAwFXnWtaoayRH3TphLm7sgU9cSmZRvn+fx5WwYqLmf32Hmh9vcKNzs9PudbrDxWp8EkUrcZpM5rPmxARH95wDrtt0PVIvU/gyp+OWOrfo1iqH5RxLVZ96F53+xXbB/Mpq/vEdao7R1btSVc10JKXwYj7XRkaFOi4WYk1bZCuiANhdQmzrcdDxsme5nsvYs16w+fM7yEDV/1Rqzk5V8xQFQjaFUdTsynGlRIu1vE7dYsF2NQjIqVm36hWzYhCAjHuqmldU87V2/PKOSOqLHqSTiYDez3qD3nK8HIRp1JyACxzpcqZNjOiW4+IQNp5/CsDrBYLhXF08ms0sH5eNUevZOMFkveavrXDiGo8gdvyh9LLTJU5MYO+CBjEzgIYwIpEW1W5I9rxRPs74rlm+VitbOde2asT3svVaza7L4NgQSTti57wbnl0Md2LES+wAv1jN2X1mh+H9FuDIr6byPv3usNtdXh5asyKcIhmRDg5jkWWA30bpL2BLfuDzuMMSwlwfB7RVcNXpXijjaQm+urTl/TUlfNqcs8Mw632pjGgSUuEo6j9e3O0B7A7aMZ3MSRhNyZ1soZ7PZVySz+g5rVzKOFbWseyaTVw8RGvaJsUot3/e2T30eIllp+sd4PdXc1ArZnQepDorcVK+ddo+ba0CkDQvIAYJDQf39uB0ncckNrtLzj1LMxjBncB1kzu18lYH70Wqg/eKk/K/qRC0abaQJ9+WPl6nROtLasZravIlvaiVjDJzKyatZ9x6uVwyHLdaqmTcapm6TiZ1vK7du73jvOOlKfmUSklcrP3gSrrw2UEqB9TptFvJ2PkWX25VCMW7EQJ7YmKdkTj5j/VaiTdvsJ6jEpJiSeLaDxJCnsBwvV+l4eDHmwcHn3wMGkRkzMPxfLJ+f71UsAQDydIci3OzDlEHxFMMHD3m43D0rp563cR5/dsdAdzs/ublWDVqMLDeQgwx0cRUjLUZIRC5xUsFPBbg/E8G55iwEczH5CbujZWPSgNeOj+QHKP6k/vJ6Qelx/aBsok4Pg+NAPV0cPA3lhuVNS0mBEymhpFck+jFcs4q02wp42YrtGZed284h4X6UaGoHRbyWfidKd5Iike3cZQ3bIet27vvQx9eZtI9Sd8gvt5stv3Y/fSSyTXmXlW/Q306nUba1MDDNRqZTQv53I18MZ8vHOeyuVytns3kK/laLl81nGrGNvI1vUyWBPVut8775+3hxe6W20ucO1N2kD/YlrK/vkFOGrSiXOlToo3IdKppkybRQAd1vHckCQ7pQ1AkUEH9+Pgc7mjEwfGHz6JcTspG4xVEIg+2IdLsQXr/wOnNfhuwXqe33CALfMCrq9o8nE7kWKt4ePjWj1e/4BKCeEIAL7b5ngURkml7rrEXIl1FV1YDvdaDbUf27gfpu204udFtt9dj1isukDExZkGojR3XwqM18CG4J3mB40FD3NVRx7iiDEiPbNZbn2ZfRTLB/0UPtmM6RLLfkcrcqKg15oQ+1oyRFGNjrM0rWatkldyy7pay2TweXLXdWjmr1VzGqUtt12VqTNdunXd6O4HrZYYYkxbozoPtMSe0/0rD6hpeoIKgMK1I0IgRGY5j5ABpyxMB9r5gNzB3hv2Ri46weJhxb23sihsBE9lCk6ttwG80zT+g6PnKDK+6bg0QJ9mMDG0cTkKNTMc3rjecE082HMHqFYcbi3KAbAhc2x8PPojN1bjd3Ub4UoOASaj9LQ+SXf1rI4yY/PXpTqol/jaWqBXRq0KLFo4h2muWCsJyfDfrSUd3WJXLkgGBkWZ5so7FcQYI1kk8y9lOAH7wJAb4jUtSEgP8rQ+2U1Gf2/CPnZu9AZiu5S2LFAHN0IjGEMzhsv56fOMePLvkPjBGIpo9CeyGX3e9PTONiQG+tHx9RrFTm1qC9uxeuilsYbtiLUmToOuEBT7Fc2E4yYSqgSONZhC3EQdimWJ7xofovvtBglffu94r+yCN9do3B20U5LNlU0KYIkK7Y1gVJy+5beboDTBQVFQ9E60ViJEwfblx+Kx3O71faKvT80kg66e3yPjFxyZjukEGyRYqxaJxXC2VMsViIVuuGnlewP2mGU647VhPcvrsSYhIePHeB9vptD+EZx87SFXzO/1ha9BfnhUJDWM8m8f9R2JKxNxlLp6Hxl2G1LMcadsARQi1IdKjvI4Xw+j+LR1P5+rnD+xAJn8Az2ap8GFwOhwkyERlw4yEWgj4CifKsNsl3uftIK7CYAjTB/FX3v4h+KfSAj3b4csRcqlD8Gl4Be8PMHfx/s0ZmZE7WiFfzlArl8lJ17cxpYmj/J6z2OyErUeqQJ2et887uyHWE2c2z9dZqE/AS1c2etoyH1W2A8ahNfBeQVghCYkmNN2YTo1m/CWHcEpK15WeLR0R2Nixo1m0XoWgztYprzFjc5FN2gtefi1PqGjIL+/QEPbR9L3JeMqsC18uzyCl6NDExHFdjn7O48LD2Thw4TgXC19y6jHuWBW2x3U8tWLM5x5spzvQK/5AKgRJecCprgEdEGXLadOYj43psVXQLFOvOTWCC7goZa5t6HYd1N41LfhMvf1LQJ/OGe8/2KEjqPw/kl4Cqij6eDpr6tNJfNGJzGe65tmaxSvHNmN4a4DjCW/P8eO93jgTi6d/n1ENI+HFv9lhrd7wUQWNLIk47Q87yyll/PFPRTQRQm9Gzblxy3OFz714zprD6+PlAebRwKM5XD9yDdQnVVBSp8yuuicwQSP/x4PtpMMLQMZcUfPhzdNuu9XuxIvD8H80n6iEBEY4JZ6WdYs2MSy36jgmcfNOwXU1ptk1lj8uFuFXHkm46PTSVZjV+YfnrhKb/+GO2By94renqzCKB0yxYmyEIXEbFCdP/EbAcI2KjxtUpFfDuQ0R/3rYhoX9HnDySCrGK+dx/aPbZuqbP6rsuV8cSYHvBz+6Zc04JDNDGCQiU83Qp9rIdq28Ay6bgpmqumikuOlJbJrEY1Q+ZSRd3VOXT145L5sQgo6ismGo0KF8JJWXXTiPhZkS4P2iKR4wbWqGmAstS47z7PhG3TkyAVQZOcNwdOvYcHNOldeyTtEyUmbqdve8M9zpOK5U3mMf3RYsdCbfm6riq45j+f6TaN6cibEWTScoRF48xATBX0M0GnhMpIESJpYHpR8ytHgVx7EWLH+HYM0+qkCrmB/dXqvVby8dx4iMjCgaRdIIQbiiKCRSu2EXdWK6NcMx6NGxcXhUNw7zJbNeKR5eN7M6KaZGHi5297VtCdajb6qvzRWapmRPUqCYsPRR9aW5WmR6xwbBdklNJ5OIaPOwEbgnwclJQ/gnfhw/YVEvbpGEyFzGibj9+2CG+4Lyxxh6Hx38/8pqUIXB/wAAH4sIBAAAAAAA/wYAQkMCAFRTvL0JkCRpVh6YVZWVV5zu4eH+u/v/+3+4R3ZIXV0b9yFxlEdGd8UADcxMCVoIxDHssNyCGWAwroqYQITQ7sJMV3d1VbMSEqzESmCABCuQFphhBAIhBAIJ07KYLUgItBzCtDKZ0M4as+95hEe4x1FZmdm1WVlHR890+efv+t773//eh/f29vLw823f+epN/eMeVq/tvbrnLz77t9/x6s33fexjH3vxHe+o1RqNVut2p9tt9xqdvdr1vT0jDMdhOBtrcjobj8lQK7q5fDHDmHQ1lxOHlRmjnNueSxiljLnUtaxXau+69kr9XXsvDz+r2d57x93PWv6398KX31X51JfftfdO+P3lt7/r4165F/65wds/6875X3s/vnjgz0UQNoLYi0B8bPEFf9yL/6LG7Wa322+0mxGI+ZOTYXUaGkrqxrDIfVcqGShbU3bgVzhnfsFypO04Ist5qbS/T5MgGvdqYT0JpLEHIK7HDz8479lf2vtI8uEjCbxzL1h8dgM+G8cSqHW6jdvtWqdTq3f27mx5+LHBfVlRKqj4gaoEFSl5EACWQAgRBB78roJAJp++s3xy/I/vFMG5KEAGMYzJFhg+fPbNMYx6p9O83WzVau16LYIRamM5k2Q0rBqDwXA6mIwo1Tx73y9lbZ/YPvUOfQ6IlE1tpQVESEU43w4D/+NX0KQ7e/948cjfhTCuPaxe3/ueJYyfhc9ejlUJ/qb27UYbfq23934TNO4L4d9ETz+ozrSJMlR1NguHpGxqhDjO9ZNMyTg+LOapnqFm9uh4/7iok/3jXE4/BAj11t16LWwlcbQRxzVUJsBxDXBcAxwvPy2O2CS+B3HsoTjGkUmY8PPNwmceJU2ie7vZ6LV7gANNIpiq6ZgoOdBn06ExmBp3LJNLz1NKSuULYXjKpSSg1CMkT0uu9LLMfKV29tENm+4igr2FJPbg6d/xlPb8ocXD/y18eIYP/66lENgHXr35OH540Nr67W6t12+1epEuDaojfPeyOhuGw2o4DIZgBPDcKvCl9AIiXVmxA+G53LLFqTJ8x/Dswiu197i3Nuyhnnp8EEDl6SHc2ftHi+f9u4BBiwTwgQgDCuAdv9DZ31th6HRv9zqNRr0VQUi9+8FwNCRFkxKbcGlJRziyLMAAclwoqYRwuMeVRz3wSe/5XGcdQueyEljpzz9Y6s/nR/qDrvWHPvgZ2aT+tG43+r1GrdOfu9TEk8sq/EEIX/lceEowP+BKeI4ljMDNauW863P7kJODfdCfv7k9Jmw8/fnOaO/Di4f/ED58Fh/+e5ZB7RNAf7478fCd2/U+qD/4Inz4SGWm4USfjYeDcDic3NEEtR3TOTYtwiw9n80W9PyNXF67WcyflA4yB0fZm/Dgjdrd5lkrrN9rJgF0EEAWAOwDgCxoUPbpTXhvfG3lddATJR0qeqe/n3CoK0+EGrRAEA5VGI4mYagMAwLaaUCFFJKrSuXU9107OPUrKlBEVRRnshI71JNXws/q33q+CxbV7NW7t5qdl2/V/2y9duv5JsgYQS0+6tx6vlHv9Zrt1f+ofuv5eqPR7zZb3eVn7VvPtxu9ThNeyOKjFnzS7fbqzVp98Un71gvdHgTlTrsX/9+6t17otDutRq1eX/2XXuj3251mq9eOP7r1QqPTqLXqvfihNsPB0o3uJdzoU4eDOKr93NIMwkgI6D9/4Od/d29pBvA39YBZ1Jv9/jw4L2UwABmMQAbwlk3FlAQbqIDx8oyQBwe2XpRctwq+qW6AOdsgBHcR1er9sBv2klB6sT1cT9jDU8TmO3u/tYDxrxfBORnV+mAQ04RDrQHLa7U7/TlBMuDfLNVITQdSH4VTzaEG9RhwIw5uiQuiKBfMZfCL9EzLdy2/WFzo0zXQJ9CBuXy7Szm9cvYuP23w+FcjQGshK+uioTuW1W8jyGo6anwigPzmVNRoQdDodeaySkIbVOVkMgZPKySEjEAJCb9KR1ZI4DPuK7AjJv1KEMQA97cHDm0BQwMY1YvA+PXFI598ICZSKxhfDZ/91ZSs6q0GaEZjHjm0qg5kYzyYDqfTEUS+qUTCBxgC+PLh21cV3+J+xae2r0jJEbZfTsip3rj1fK/WBx1u7jCoKwspjivOB56Gqrca3W69PXfNK1RqOhkoNRC8pGRJ40ERxCdMswJKWLnpSAsC5n7W8a6d6DcTLLHRDtthczdVv4CGIQfRK/NkKRYNcpV3J6h6mpcMRyPghjoBfmIoeFw10YhTzhRu5rh1aNp5WSqVhGtzxzSoKyRzHYc6zk6qnqImyHHZZQyl/4FNqo4e4hsTMFbeAGHggxtIrAwI8uFkQELHPbGNa4Y6BfWSyLUg65CRycjAt+En/GEnjJQqXZiq/34ios+j/DuXUR4j/+clUte1KC+Romgj4IgkkFNDF9wFaisPBRBd6foC/izAHfu+IXwjgH90uViguA520mjcegHCUKvVakIoaqOdNCAWQTQEJ91sLT7aTHKXfGAvwQeeVvl+PeHK5u5tpXzo8iYp5Uu6tzWRgbfLMmm7jHoO0DJql6UtAbE0bE8KeAXcczziJPxCAu9uv5DyetZFvd5HEh4urkMECU/4NSmdTHq9UQhskwzlRJ9q4BoC3Si5BjUtoZSXkYKrAnBO4MqQBnAOUrY55x59RjoZM89vSDjvWCd/O+m8QRuat9vwTnudVqST4XQAdDkEDzEIZTgKQwEAgDb7vgjAfwuwJAivitsSmHRJmb4nCd9ZTrlKErz307FL+0BMen44ksUJ/Pys//SXDpKpS+82+IZ6t9uPZKGlvsbVUMtohq7rmmGUdJ0da96R53nFoucxxoSZLYuC47iAwnul/p5/fw1h1BNZcC3Bea7tyGBexO8Xh8M7dwZh4uPBUhS//YHNytY3JDVqQxTjiRzPhkNjDHm8MSNjSAFy9lGR2DkXMi6PBzYIhgGH9nzuQ24JzsLbXdl6S0RR/CBkkWtk4Bvhs+9I8M/G7Xa33+stsshQGwOAsZyGWjibSUnKEjybL4DyA/uUEqiADLgfVIAUQIIsK6by2c6iyu7a0NOgiI278cFYFCv6+QZ89lcSlKZxu9mDwNnsRjCITsBxaRoJiS618Ww2dZhrcrAEwQVm9pjbc6lsoGtCiLJtQ+SsXKLEdf5XuITxjg9uMrMJfPbOhF30b9drmAzU55W66WwMzAz5GXwNZoYmgZEp/HaCgAduxav4kvicWIwfBlRRy5diFwxItHfAuPtJd89BMXxpqVOfl9Cp2DD+BXz2aio7bkAS1p1XfBOPrxF9NFBFgQbAAUCA0V95XlCWLv6Doxzbgczgup8E0UyXSjsxjGsXlEZ455OXKL5xiWIVMNBaviqRHqcsYzSQGhi1bozJRM0G09E4y07KbrFMLUo5c6knSqxEIQg6oGiUcWZxYT1jyxhvUal/D599e6pK1GzU+93OXKU0Au5JjrSZqk6rw5kRziSDGKHgGyi/52OKAtaBv566NlAaNBVzp0p1d8EIzwXxYqL4+8HN6I3W8gOr6L1mGWuiGJJZtuy4pJAvOdwtWrrUs4xJp8CZFEXhQQiH0OFe3DIuJI0PbJHG/wOf/fcJbwsho9OpdeoLA19KYTrE4tFsxjFx9GwTvC0rulx5RWlJ1/N4jmd0cMeeEDtIyFVq2OFLoxeXMN744Ca/Rxf8dakThaS7XYhgOJLVGZnNAAerVPAMAeh9pVIBJyt9yCKjZBLdVwAhJfCeibu9s/dPFo/841ukkX311Ztfm87n632k4/OoMZ1Oo8cfTzSdzMbVGTy2q8T82dE9AQDITCoQEGVFyeuKP8f3kzBqd1t3axvs1l7UXuyLQHnb8M7eTy0e+xc/GCeOc0ZlwU/7O773WrqM1O6AanXnUCIAYRUBacBIyGjsupbl2MRjHnVAn/Y9F/5AXQ7Oy8VPIAsmOxWrl0ocLyKNDyUihLZGpzCSfHkq20pEjfXnrwpX95yCQYlncw/crKuxMmUOfLvgfSHtBYQ72VTnKmzqIwnPuu6m0AN/bcJNpb3tSJvO9InUycQgZGZUp4RQmzHwRo7wmGSYYmByISwkg/DPnDNjt5va6W2fShQfSbikdRjout6bOmpLuqnl04NEhnI8NGY051lZ0yoUSP6Q5LQDo5w7KFBy6NiQRVkmhXRptzZd7agtJuj/7wc3c6XPB/v+tr3kEUOr2W3X+4uj53UURaC0vvSByoKRYxAEcQRYu/PARWHkk97uXOlKR88fSTikdSf1tfDZ/7AEUa93b3cgx2gsTm+XD2/MlKwOdWMiFGR5oEMyQBwKD60U1k8gia0EDPQLVGu7LPA//pao1ArGSqXQ/357uriQ8LWbMPbBF9ku91yH+RYWFjj+hCgOtB0MhhfPrWzZl4XxM4tH/m9eXSUasUo9ejURwCOVane7nUa7Nz/1NIaz0Ww0hQA4qM6G2ui+ZeaF5x1RnyrfY35Q9ox80dSyh7nsYSGT1fOFVHWxe7cebqrVpSIGAPm5xUPXX93MmF5L2kbkqfDstt2cVxpXOCZVyP3gz2WGtR7hUaa4B9957tm5Y0sxaWXyGWnq15mRRFK7W2/cbWy4q0tCWenWn9mC5Yfgs0epckKz1+v22nMs09kIOJUCcRiz4XhUnY4gvLngX/HwQZQFJBwsJ8ENM07LmbJXVDohJzu9bu9KJvIPFo/88a/GMfxJlet6EzSgN68nzJUKhTEdGRPIBe/zQASeBNfEHTB2K2JTlYqrY52q4l4LBJVrbGSjbv20x1hng9GSSb20xUl9P3w2S1UR6nX0UvOCb/LdQwo7nSkPHloVFQ2wPlqQRBX1imlyx5WmTdSNwk33UEtqU++sebe5kTBdWZk+dQuUn4bPHqaYFPjaerM+57YrGHI6UkY4JeCRQIWES3lQEaYXEXapypRIJkslpyhKhd0UvXclRxXHvs98dTP2fXjNUbWBibS6rVo3UqbJbDib6WQ4kUMSTqrV8A7nEPi4h9FPBEK5Ek+uXA+TQAlpH3xq74x97bci9r2yRRa/Cp/9tbRh1+v1WnPOQ1JiUJMpHlAHBNuTon4lz5Ke8h0mFARzCsnHc5ACih3VqSsb9o8uHvkvLg27+MTusSakr51F91gKw1SBLATV/IKguhkE4lDyMgdzsf2A+7pvBZzZu3lIZNZ7iyd/8cWzcx887lX6/Fc3K5xIqr4+1buXJFCR/ozm+hOOBoEqnhjHrlukZV3jGdPlnBK3VC4LH4isf+hBtiGStYN6/W6juZVDXbSUk9Sj92wJEGgMX5WwaYjaYA0ggbkeLR7fUNNhoMZSEeITQRk8vcYYMPADfrxP3ZKhlW4a1M4fOsxiO4og+B9/SzjU127hUMir3rMUxzoVjHRnIAfV4WBQ1XU5VsWcm5VuEft9IGuVgtmQV9iUSw4RwgNCyNmOktSVqWAc5973dOZQByZYW/QKGEEaheCHhnmQ5YQ62GQCXlZ4ZUfLOUBlPU85GLoTKFr3mrVLxzl89H8a53Lw6BpLtzn83qupo/NOB1hsvd/vrrocVkqkq+lYjkKXesAspDykkKlaivOIwXokTzxRguxVHHiF+PG39TN0omSVLQTBLnpMG2fc7391s077x8lQB68KOHkLJDHnGxtAhFBcMN8WwoGgLSFK8MAHSgi/eR4X0g2IvtMt1d+K84tvQ2XS0hL5Lfjsm1LpURtiRL9W2/sQcCtsSZnD0BcwdH0ysQRjGetgn5nMPjkq+fZNUx6wIjXMo4OTk9JhRlhl9E+Ns3p7wyS0hX/ClgztIs2UsWUj817vR/yvSTZeR71qtzqNXr+1OL+YS0BOxgNjMp7KKY9OXyqY31XKwrRVRfnPOdynnqycQpCTLi/tdFBXU6h/nIQR9V68bT+ZVOytweg2W80kjCHAmMQwHIRBwGiMin1801Y6BOyioaid9SFWl6TFkzSw3rzXDeutDSxxN5N9ERxfk8Sx97C6t/ete+fj0DVlDFRVGRNVHaqhCia5k6xGrhva4f51diNzeDN3csIOD938ceHm/kGRHt28mdNSD5zSg7XCKmZqX5+qHyWzsk09AMfiuB5TvkANkJACCN+pwO/Sx3+KOieeXD+6NPmMHcujLY7l6MGrNz+wlzwAavc6yLDQsaxjmN7HHgkJDiU6qlZ4VC3x+SX8LlyOjee7+c7OUt7ZudRnsNTlRwlRxBgw+39vivskM/0FiMEKRDZDPcctgd4qrvybrh14kN1wwCQoZz6QoORRXL11r1HbmuhfnPucLVXqb2/h0H+CKrWXKnL34as3V6mVFGbVqRyOq2N47WUfXj1k9gx4tBEYjuc7yq84luVkfCHK7rUnF14uTRr+eSKbnDcYrrgPZp3vS53GxRkmht2otSsBZApABsZx0c7k80Y+f+QV7aP8TVqEKKBlb+QOWKnkGaJkKGst9Daad+v1rYnmJTjpyuf/wNLnryLXb8Bnn7qXPLNu99vNdmdeEVuTysAYO5SCSHJlBtaRVeLEsnU3V5YnIBBleIwaNi08+RDl0j4/hvFDW1wWFmS+KOGy0sWXKhmQ0WgyGxgjfWbIkTaVrvIUdhHCt1QVoKUVtHYWiECqIErWdrusq+Row2W+/MNb8uUiuKzxXqqw12wCG6rPmznWZEHuCLzGgL2QkcMCFD5zsWMtKFuc8JLtPMFnXSFDGCxl8eEtssDc5zsSRpLOc5YPP5xo+sSQY832QQBZ4QWnPrC4wIMgAv4Kz3h9/KNUpSecWV8tz/nwBoxV2vmZa643XbvYgFEsSep5LnM16TDJXUiQuedE6uX4ikvqit1HQZevXZytDhd/ekuyhrWlL07IYq2ONBpMI3MYSa0qB0QjWvkwf3RSPCqUMtQwNN106UnJyR4fn5g2KRsnruvlkmlO2LjX2GzsvnRJ7BcSJZf15u6Pf5A4gog8VbdTr/d6tWXas9SomdKnxgxUxyme4PlV3uSay1VG5CVIQsiiEsQr6y7Iq6A/Ke254rHvR9bgJCWDlaYvSHusRFVpE4rmGfKQUGE60nMhdTuR0mK2KfEehPCoW7K93Yd0V6sqxQTlNxbx43rC2DGm/L30tb5F/Bgid40a6WQImjWRVW00UcqQGuXX969V1TVhguHbGaMimX0tkHlP2HYZXTB4MoRwVm/crW+Kgy20Kw4gT5f7nA2WJxG/tcjgkk4Ls7r3p6oacQY3b0eP5DBREznQiKHGug4R4tiQ6shVVHHrSCphz6kuBBGJ/Y4qxbTa9yCP627N464n8rinlsnPLp77d7aQrRFYyrcmLKUGltLpxo3PIIhwNKmiIMaDqiaxDx2iXhAwDHrY7SzR6SIY5Z+6ARBipcqpBOiskTxTmfeZXrJitvLB/9eWeHgMSAap2kCj2+/2GvN4uLCMhUSMaVgULrx3JX3hCbyqBWQeMxCOpWMIk6WAphtV3rriQKxav7cs16xUC0s4iZ7fVbkm5oyIQ2oJHOTIck9PK66jrh1eswLPDDyfB5IH0d0ngXHelwt/1TurwY9Ga2ux5saFzQQISlw1+09PdTrUARZfB4IaFfSTGGYkHICfgvwDu+oiMQQq4BUI6pwFPg089GMseSRfO2vuPh367Le/fK4YYof7X7ZYBdaZgr1kGR+7yvuLdoK1B69in2lAiO9ijUlFthBQA1xTxQuQn4jnIB/c2Xp9aYf7SS+NRi8tTWIFY3X2+3VgEn8zZRKtbrfdaM9vvG7AuG/lgZW71LPzHqVZ7mU4NtZknQIVRfvwoGC4R8/AJM5WsvjjLcEPgf1GKvglZbF0TNpsPDXUbDYr28QrOq4l8swET6tM4UnHsTH4eZSIYsF7QiPdJWUBmfvduy8tKwx//Opms9D7k+xqvXS5geK+njWolTso2czJCoiCjDlAGRn1IGfPediDs5shXlYUZy+OVt2+/3WZAL6aqjJ9fYIhpot+2shQoQJ1qi6sYnaiH2Y1enxwYNzUi7RMWeaoVCoUTJajmmE7OdshBFPYsH2vHnbDRMxLFv32L+iYBsPB2d6vLB75owjjpYfVGwnr/pxkzJvfy693er16b++HwH9p8G/uw891G8fexqiGiVMGpOSYe2A/uQi4XzmNbv8Iseym+7Qz0KyXt3YNXSTyfT5+fd7nDRdCjjnvn2ypN2Ap5dvS/SqLskkcO9YBTWf7WZMV7KzI2VRYninNXEHijU0hDI5fBUqdJ3Leq5VPfnHx6NcexHBWQnr3g1S7B5DFRrfdry2iB0JaB2OMMR0PfIV1/qCCjZpg+rICX0hSXN9TpX1zHc5aw2PjSvwkZr/7D2IHsMpJ3vsg0WMeVUo7kK8viFbSgc1m46ExotEVd+BZPuOQiTBP+Hi2B183KPXMHLHyqfaVzt3+1la7S+GIHdnRg01HhqXHr0x1PSZKpQkUI0Rh3CeamXM4yXMhKZ50UxzIgbzE51wBRkGfUddjHBiPH2zm68gffzLljJNcMaVU4XA8KhLDdHSbuky4Ocfy8Mvl6Isp5RTyXPcJIK7EFWMQxS0gsCj0Lel6b6IAlJLCWAtUsVTUMplClmezvECIzfKMO8IDECVKqavbJntGc2pir/VnH2xm6t/3IH2bp3kb89pmbXVAOZppoRFKQxsa1dHMMEYhKbmuzcskVya2S42sXrBKJXJc1rOmSfN54yRbzO32Wldu4IyN4+MebJ4j/NiDRP/HXCa1GgTJRd8EgNARzWA6G4fDadH1MfnD/A9+2HiJAdg6OC+k7z6VgvqXqck9xaiIOMp//IPNmtyvJg/tU8WTqOV/XRpjpR9VT91T33eU64K7xXq8tGUlcAMGFhOwkrrE9J2XnkYUMYzRg03eiNnuN6SuTyYz24QUINDPxrPqPuVlcLqCGlivFr5Lhe3ihVhOOREeByPf3b9Ze0tqP5/+YDMV+UH4bJIwkPbtRr3W6yxOKNMQJpPpkM8v77N5V5ePP+gp5CBCeafw7VVsYweMeGrElS+Kfc4WaXw0KY0U54q6abH7lExm1eoQIog2qA5zGWKx41KxyI6YkSuXLKdQBjLCDNdlOqeEuhdp0H7p6cvVK3f17gebJAuZytenbCNmJTHJSsMIJ7OwnD1wmXQdkY8u60nuSMJ9IFmS440+ZPVPJllXKyzGIeTLH2zWTH7tQfpubhuk0m3VFwliGsZgVr0Pjw3+CXQJzxECJfGGLrbdYRUO/BZe231y3fpSh7cvvW3pc796i8/9xQfJhgr0ufUeiGRe6x2GZIyNIaQ6NaqT2XR0X+B1aB8Ng0WP70ePj4e3WNgKXE2qi/vcl148x+kOR8umkPcuMax8LhLGL08doyfI4TqEmVIUJMArysNpZxKE4Qdg7X4luqOEU898cc4p+pXV6esebJ5AY6r+F9M5bqLekNSk2XA2qd5nXlnRUmBQ7PTC8QOQYSmi+FwsChnjs6BVq+Fz73uw2dnym/DZ/b1k612912h1a4thI2uSgKxQOVKTFcWYK/EwilE8jToFJfMAjXEjsI/tJx9JXfqUM5bFwwebtZ/rryVvYUSm3ekCr5oTq+psXK0CuR1oEAg1Qw+FxcuO40Ko44VCtkCKzC5ht53LWF7TtbJ3VCw8A9NOsMPvW7rblVkgY/yqVNSI2eHyDD0GEEz16XAIDEvLCklOK/LUJ/BTgF6ZquJLL6pNQyYVyNVB51vNDs9eXLbVRnDO6SNs3+70+v1Gr7MoAhlaqIWBPgrB8Y60sKgx2/UMAfHB8jSgur5pcjfPfFt5jmMLICXsCTJJtNWe++CDVUvGD26J3khMkpMM0yQk/f51OZswYhDPs4seydgENKlMXYjYDhWO65YxdjtPuKx3FRKyar37sS2pKzL2L0hnTCt2ro9G89euKTILJjK8c2w4mpPxokoIdz1pMZYjFDImp8Qcy83QVHNwO2z0t8aKq/QG/+IWFBgD359CkYh38PJHyjAGVTnEgTvDUNCjQiFzM58vU82VlmEzcLfeyVGuxLhrlVzI/ZJpX6N5r15/y2H8csJBLc9owUF9Z6rAg7eju425n40kMFQTYzCRg2CoTyaGQ48Mj5t6TqfcJNK1s9zPE8asE9M4yOWdItUunmY8lU7F96t+dUu4GLyWTmC7YBqtRmdxGBjLohrJQlWrYU7guZklWc6u5GxFbEtJj5YKmp0/cm/oh2Apx0l59O+ljKMbB4xrlwkYsa/9l1sy8U94LXVm3unfxtu49WZ9mYmvS2RKQHtwGprr5ZUASBxYFJVcK+XtAmceJx5bDkTb3ip8tYvrcfz7V1uoLcJJUtvO7Xq32ewtpmqlxFIFsWBLH8QH4LaBwDs+8A1IRIHQnOnjnRJWIk+uU102/sXK9WtbSjzI2ZMDW9L8PAgHaXEUtbyesw8Nx+bZrK2oYAHF3mcRFa6l8tIDW+ph827aZy0D+WUu78XG/utbjP3tr6XGl4JyNXv9eqM27y1Z0ypSBeN2PZsLl5YjWfCszexy2ZUuVbzIXeLKwg5SFSvVlS9T/uaDuINhFQeRL95PtSvF3PBH4N9+5zVQLE0NlDZUEnhipFhjXT/OHB0eHR1ljvmhfnRYPHRuHNKsRo0yKZOjvFP2rOgWQP2sdbfe3MoOL3E2u5LHf95SVfgikMdre8kDzk6r0YvbdsMxuNuJInoVtEavTnQlMWGiAY7OkaaMxspWsN9SkpwfiBJQXXvHaOIrd5TE3QtIaNcTDiS+70nbR4LkgsZPdF1TkC9VZWioSdE0T5jjGPArl4Ej/LwjbgjbItT3fMg+lJmqtzXu1TthfTvTvYyBxEnsn3ltdToQI/ne19K335q3m7V6rT/3VrpBBmSo60oLQZ/GkggLUiYbjwWUz7HDpyxylkfNQpHlCzjMpWTvZobNq3irZeHwtc3CIUb5v5QespGI6OFUTkMJhmFEA4FAqY59RvYDixd91y+WaaUSTSAnvl+et1vqnBSfQUQfJGB8whYY//JBqv6ZCIRRS3taEpDymfDiRdmXvu4bGatS8StRa4/0MZH1A4gp9u5k/CoB8Gzpq1YwVrHjX63FjnQATMLACw1KHOePSscFJ5sxrJPDgDJHWF7pIHtUcH2XnXhlluaJrXudcHPq7yVM49M+8zPevjw4Qza17nR/dS0JXDGsFvzbYlTkWWiWplUJapY8yJ5k88ZRNnd086auWUcuK+6bh9px4SR3dKwfFsFKTIyAnXvts3ptK8G6eNvYnVV/5du36BXGxXen9CoZA7GhMnp0HWQiqxNjzK9JesOW11RQIFLPZs2Kr1fABYP7jQZ7wx+SetU6a5wl+iuTcfASzmq4FMlfeG2TXP0wfPa+hLfCDrhWvRm39qxQTMdkYIyK4Fo5dlnNB9rjtAoReGLfly4CKftCJGvSjUZYbyRV6yqHmUtT/6LXNvNaDI1fmuotSYXBuRwQgTGSM200tF3X9MxyoUAYLxplk3tAT0w/w7kF2XhOMI8+q8bKuK7wxa89zf3EDuTn7UVzyQaKogvcFjlt4GI3A1ZBOR6aR53sge/h7binu657kff/na9t0sLM68njsnknZa3WXVz1mGlaOJwq+HWsaQRCuWHhOEs83uAcXjzD1Q4Uz8twywOydOL4O2jIE++HnnvxJpFrPNhiDgcA40HKHOD1t+rd+WT4dRDqDk4lU2XDJ8Iv2zae/5VyAQOjxoZWGrgHorTz/e+8AzU8/8RsadPf+9qqBB2DQFaS7GFPMRANnl3hs49mcjZTmlFU0UwpCdnRsdjH6wSOwNlY0UwHvJkPNp3s1rvXvdfobGUh687pC971rs//vL/45++8+Gnn69QPvLZZ+My9njgwm69vabVa7WbMCSHNmE3IbCI14OfDatHyXOoy+D7KUcvl+aMbdq4IoaSQLZ5YeSObyye72BvdsPuWlUdinfrBLTrlvL5ev4WI1+ktTveTKCSgMIoc7AA3Iygfr6REgwkr85ZW3ITCA0l333W90jiEWKd+eAsHwdgxS+hUOk4kMISIQb9fkqaRzeMZbJnlfUcAKweLOHEl3kIW0sunut4ajbO3ME7EhcMffW1z5ih9PTGTMKp/tmvtXmseudOC0GfVESWYcgfRQGiFnUhKYj3ac08tzylSYUpr98zRq5U/Y8v4R69tJn0uoHh/AkXvdr3fbfbqc36+hmEwG3OBR33IYnEok6pQqk59zs1Tj526FrdODe94J4yrRbsYxh8gjHY6aAQA4y+kKm7tTqMJJj6/vzUj0wkk3rPJTJuCGRvSUpRqlFJgsDgjQVCTOpwQRu0sMYlr2zbZcQ0tpoPFBIz2ZYL2HzxV0K43Wr1uv784oFmDIdwiGDcNHNfxTFvmfVArFmUa3KEWBwf2hGG8lw7af7h88ETtAN7/d6ULhb16u7vIj2bj2UhNJrNZdUzCMNQGBK8L4FUtrHvCj8p86A8PLLfkl1xP2tTbPeOkv2vke/g0QTvOjzBAr/smDORflvJNqaCNmjMFTm5AbqSR2ez+Qa6YowakEpbnUepljqgosFzmsMwO3ILmum6qfap+t9E6620N3Bdj44Oz4d3VHbrM65t5BRKr1anGOokCAYTaWAsnACNqLpz6AfOieTN43g0aBFwQqHmQ+PJ3zOB9Eol66bwRvHcSAS/3+mYtB2P5N6eONZJxewPF/euW5ThlzvNU849ODk1bgHV7QARdbKHC2UC7D4+v0M52tgShvR7bxtcvZYGf7e0l29la7Va91YyvBqUgwI+iYPLIYxXDcbhrudSywTYqwVwa0aTRIHnGVLu75agyHhO+nGs5PA/D3dUwgQhENEzgR58CBFDYQTTjnEyHQ4LDUou2dXzoHZ0YRgHyonKpUDKzpus4RUaPy47DwNVaqQeO356zxSSRB6XLeUnOA4YoSfTmRvADKMOdvFYmxFOew+fDmPEnJJZBNBlKeZw/k2uUCffovr6ZU2Lk/abUNcpklE1Jf2roUyNbNkoZ48ggjm1DNgC5F0Qrjzvc8xy76Lqc+ecMNr3yZT2kN+vDpJEGfW3qyDdBedYlEYaZnK7l9jO2l/c8xsuMcTxZdPHg1NWKhsNckU3J4l5tK+m5OHMbrMSBzGDOFlbeEUPv/5yqHiXZQgrEqDqtVoUMTr1KxfcFVYEHxBPreVJ6qiIxkiGni1PMm09mC8UEW/iUlz/97aNP+9RPetsTotbeTy4e+b9FGHo6HfjI64mulKia1wTLaC4G+Uwmw6qsDjQ1kWpSHY4mRfDo1OZURAP3IPbyLBUuE8KFf+FqeIotX6m9h+e3n2Ul17/pW7YP7ELwY4unfffr8fa3ty0RvDvpVeajueq9Tm1++F4NBhN9KvWqgu/pcCYhRwYTwKMrgQmNjNJ+P1pORHwaHc1hbfizt7v2y2zfe8/as+N4lXOffWKMyCTUdKM606VORtOiVaLOiZtlpqFnc07eBKeeye9nMtlsNq/ZzL6paamnjSuGyKrWK5/Ivr4wXYleMK24/WXjvQ1LOaOQ9TKWbebz1CszWWYKggyqAsRKzjiPSlT3dh/HXnr3Xzzu+RsQSi4dGL8h+Qbnc2LqjWatPSeNc6U1BuGsGkzUxFATXrXkKRbVlVupSOoCb+S+cCOqwoPFrca5GWa2d7jFMHJPHRbvDPfGSQh7KI0ffQoI8QG5Zkwmmq7huoBQI4amjfevy4KFhqgDRWecMI9pIA+PMeE5QCNd5rooidTD/97iL/wWfAgj7Qf+3euJuZXzFjugrM3Fctr1t4ilJpys6+M9UOFIH0fVEIVGBY6BwxulXlx5xQ0/9VvPtyHWt/u13mKbT+fWC3Xw+3X4u3o7F/yk9jIZoDbGBWJp/Mo/sHzlX7Ma67zGRLq4AqdRW4zYjl45fFUVGc1XrxghmZ0cHx9YfL9YOCpYN/ePjq5p88Yv9Nx4wiSNIk++8sht/8LGQ/z4UzzEsgltpKpqUFWBMcalPGMZHh2fZA6Ps5njo2w2c3Kk5Yyck8mxkg0ZBNUKJgPiAu/9MNEY0QvryTs89YQaX7+YK7sT7avER/+7iUgSwzEfJgpLEbtr9LvtXnNxSjfTDTIa6FLpAKUKXKWs8rhDiOBwCrxO6VfgT/JQHrhUgcvjnr7s5bqBKtQDHep04AX1aomtht1Gu9uo1eNFh9FqpVq93Wku/1c72rhjtdIXoejpFmXcDZfv4Pu3vAPtYXr6K3C0Jp7xLY5iQIDTKbwBGVTDwZjgzT+urEAqWxVcLh1cQqrKBRlY4NBdHHvuLVPYtXdQ33wH3Y130O3vfAe9y76DSA/iXWE/jDHNSL+DfwaffcJesqbV7/fajcU45bQOjLUZl7h5FQ9o8fipomz/FOeOn4qK4lgeOq1IL+FJmreebzQhWtV6jdXWynq/38IssvXktZWX8yTD4d4fLaD9ryjy43TVqPgw0SUejWNq9prwdPMWxpS0Md0nlmC4BcWmHC+ERIubGPhrF1ueGDXLZoHjZejri11huPCz32wDQ263EztAG91Wv9Fozt9BY+E676aobyO16gkgH1/E0v8kwQ/nWr5Kp5BH3k+dACc541Kys/HIMHRjeF8ruFY2e0wczymwPDXK5VyZAmpISWyXsUSFI1LyPi40beJq0ngbHKj28612t9Zv1Zcf1W690Kg32tgs+uQFcZdU8mXd9p8tdXxFoFDvfzqVxCR0fC5oYxyGcjiaTSGIGEx3CLGLRcemHsWEjGUs5jqQzzoOJdTg0aWTg1fqZ9/9ZNXdW6juO56OeNzZ+4nFE/8aytFJn2h84sN0Kxve7O3Wa9358V4SwWw6UENhCY6DU12pu4EnHFc5eecmkI/rN52y5RwcHhUOoxP8u2sn+FEYdxbxxgEETnz0fX6tbe8fJgHszcmfn/gsSZ+7txsd9A7NDQCj6UAOhecqypgMmBsoT9hqfqkBL58IUSIu5Vjaec/PHmw/HFsn/0+zxv29a0+P5ZDzn14b6NPq1JByaOhDg0zlnWOp55hRdh3meVoGt0yUPc2jRoG5rODYYE5W6nFjsf+7JdVbmS/Sv/d9LHWbIkH1ZrOBnM6GyhhMR1UJHEiUXM018x4WKO2y43iCOR7WheE3x3aYY0f7RV5+MntLKe5TvLiYq/4eAuin9fZTHiZW7M4XZvfqnVZ9TpgXwq4OkTNP1DAQJpN4387nLvdsYlNKjh3paAVOs26+cJIjJ2YiwnRxETM4oF4/diyvQIRp9Pq9ZrPf2OlrovzQSESY/gV8zR8skP1+Au1yEiag/eJVetCt38bejvri3khaVsFgIB3IBzxMyrmEUKM8VpYUKKomCsDUTffYNIncCjeOLwm4OzhUfEH/knBX/cJ/tExOV3hHgPcbUni7nW6v017d3F1HPJ0ajqeXPMFdpiTLOr60HepQKkj2gOQzZT1jZZfTg3bPG7jyfZk/en3zvPXdDxMrGebX2pv1Vn9xr30Dyn0RXYTDI1fsQsCWFhWNqBak6JmeKNupOUhv4b32WCb/+fXNoQlocYnRmTjCDW84NFdDE9YEQqoD6dkIw5TB/EgAdDBLpMMlEwXdNFlF7j/hNvVbNjDs8OHm8OovfJi+ioWjX5r1Xjdq+sLmryUIpVflAPM8omlUp1R36Illm9hB6B5mda1oaMfu0ZFBjw8PDuLJmf17zQ2qvd5a/xSdX3dTOJBnzrnnqgaJfPT9CRqS5p6jcDIFbh3l65oGfiL0FOW+D8SaB5wD5UaK7WO2jktyokGzEdfOvFJ/z+9c2yAijXV/fiFCGdejMEWKCeVyacbr6ZGm6bRpGMuhqqRmjKZDcpw3M7nczYOjkyPdyOh5LXd8nC0c7+eOStctzcqZWg5DElk2iTQ6956w+v1ixcg7e7+UyHgRSrK0hpnxez6WvFkWZ8HL0tocDKQ9GkEwY5krnpyc5A+PSSaX0TXtoJgtHuSccq7ouPkjup8lmoNwDBDL/3J9oWTpsbnrRzYXhhR7sD/9cLPx5TseppdHdXFhUa9dm18WiBQLkvvRKNRldTCq3rEYbh1jlukApbIYI9RjnstOWMHwgLdYJ8XdA9Cucod0Wa7HiDmPoitTwcj6MDXFJhlFUQrD6VRT+jSYANdVhsDJ6AZ1Ar8oXVXBGVzw5cpoPh0Tgovdw1nTwbGSCI7nj2K+M1zC6CZkEcN4/WGiCSkaPtCAQN3p9xZzTVMYwioBMuB4LsdZdBaGEhP4O1MmLnx1NGblHEF2X2662vCB+Iz847eo1GP47FtSDK7V6bebi/pbAoMeVkfj2X2L5YuQKTLIPwzL1IskwzN2IZ87olktW85qh/mD1F2zu62ws0HOLtteH9sGpkvzFOqdKQ7/NWkunUih0rIYzyZF98QITnxBHSH9QHAJFhFAvMcaiC+jrqpzbiY7C3HEadTTHi7/fIJdrc/PRNryrSnbiBlX7LMARKikEc4QhFadBCRXdEs0EDftrHlNUs6ORUb4eaG4JHhxnJhyOR2wc9Y8a53V+1v51qWmA/7zBC1Zn6SA9OXbUq23MVWJwazkMY6gjI3StWzO0jIlfpA5ybo3iQ6MuXwDbEZaNIu7B4E3r4/Hrp3VNzdrX3ow0keSiPppHcMU6BtTDQzJdAfAyKE+npGZ1GcqnGl3zGOXYsehhCxNSuUKxYhkWGMVjvA9nMOeaihpbq6eMRI4Yt91984nf/Lbzp5Yc1jCePvDVze6xH7mYWLHxnz8S73erDXmq85jC1lIRINgIiA75xJ7fOYNCwpnwCgX+As4YxeyObXzatDuWxzn7wG6M1jOD7u31K/vWW52+ImH6cW14LpqtVa7tqLCKWmEhiZlqVw8NG3qFqleLgm6b+SNG8cGhawanFfJKh4XMhubT5pnqenrV+kHXd11urfFF//kw/QNIUhQuq0WvMP5nAt9tgAziMAAoS/kXTvjFlyWp57nMbB+YhxIZnpazrYML+PlU7eX6/D9llzoiJDEpv+5K9EsNezn10TTxTX0bZxUt7xpulSvgTKqmpxqRVO3C9ywrANKjiyPnpSPgVTqunl8kM1Yx8VDK7+epTRqa6s3rjYTLbaZL9wS7n/6YWIW+7xZotvvNLuLkUkLBVNyMNZJqGs6dh9mS65hO4aZNVn2wKXl4wNqeKxwcJIpHGiannlGDaL/OAFDY2nyhTnY/RS/X+RbEQp9HYVt7+eBYbneqS9PK9KnNqsIJvG2qT+/tpkaKd84a56fb11YHO9eimNVOcNA+UWpwncyl5frOO5o1MnptiM1x7f93HHRC0SB+pQpXHCrpORmqrXvrLlpJ9vU6lM+83wYsQv7qw83s/nfSR5ZzLkwth102okDZ31qDA1tNNPJZDqe6rNoBrMWUN8vl33quyyrB+KY84p16vrMZRl6uL/uwlrh5s7nbXjCTzq/x2/ZxILZSGHNhRlvvHrzb6foZKfZW85nTuIwpkWLeUWbWpZDbS+ae+jhFlWbeydlruU4OTJyOynYlcbVfTiBYL1JEfOur081jSZzrE0QkpdwOYwIyoHvqmi3bbQ0Bq+bKmxSe0KT4hVyrNU0j9cTIGK9woTlmxM8Mp2chKExG8tZdURCOQq16WgsT233OQG27cPjYx+vDDDBqkQVI5/j0OPdOdZVkpPVJbTHW2SBCcs4vesvkZysQMwiEFpR58IBnmKUpV/Zpy7eo/OPFcXhSQKyxPJJim/hPtjW1tzkwtFjuNrb8yNbqlxoFcm2/Obtdr3ZB10QyOjhX6AI9FlVmwARDgeT2UiS0klOJ4eFnOPccHP5wr5OczcKxeJx5vjYNE/2c9kidnZ1wtbd3tqd8uaV7pTHBOUnVvJYMi4kLckd3CvGFfXlD8akOtMMo1qdjrVZGOqmaTCF+y6z3pGnTtWpC862UlG+i7O4lGmktyjh8sXWW0e1Yiv/yS2alUKyQbWmKIlwLgmNTA1NMMvhgU/LHt618eZz97AqXPJ9KxCuKBWdJ9eCr3ob+0NbePwvwme1VfTAUfKNbqe9aAtfxyA1nBuIz+/7Uf9sNOYfU1/hcwqSqfjgvHa26V++ov3i6JOXJYif3uKskKd8S7oPNUGt1lAEmu5Jx1IcOxP8U+kyHRVK4doeHNcsCmp9N1c9bG0lVxdUqhfPzs5Wbfo/kyAlyxEYDxMDwDfyquo0aRqaJolwIPEoc1tgM7BU2L6HpS1feJxG0dBhu+dRXm3eTUxKfn5JSlby+Nw1K1+R9zhvR4HoS7XStbGePZYOSEPfL3q+gsRWURSPlCbOzFbY2rm68LggJd17je5bx93jDZm/8HDe6JxkWS+8kTiljFhWs9Fs9VctZmty0aqhxMURaB+4xg6tBGRSURXu4+XZQHjBc0ycf4x15ctRv7hFy9AT/HJ6gUTC6jeQEGJ4pgcUy3UcTnBhpuspiifsuPDGE7Z38IQbzVc5x1odZP3OluoQ0uH3p8vAC+oba5kWPb6haWQ40CaaDEc3yoRrpMipZ7u+nuM8U7RNUlaayYTmOSAj91kOM4+l8n9vyQ+/AnTsr6/54ma/3lr03GnadCiJ1A1jitfmRzPXRbbLJaUeWAjwR3DDnshKwiXjlDhcN3duTruiVOJ2GmQl6/khspdvSh2aLJhKlB+SkTYcYtMrtkIHYzmhFnOx35yCHw7KTFKIj4pzRwnJcOIE/NhRGUrylEud9P5kAkVhLbojr//z6YtGcRaygeE+tYDgcorts/MDUl8gCBwzLxwhy+nVPc8gC3kOEOiNdB71xhuJUfLzSmMTuw3ntS0yVpoa6aQajo1hOCZEmLi/Fye3clsywXH9G/UhtzXJScFx3Dz8fDKIXAJE4wIg/mnCx2prJo6++BtTJr7wu7GFz5VoSkAiRBtPpFYtH9NstsDKmiwzQqXNGU63khwol2CuAL/1TNcVxA7r41EkrTSJ/+431vcoNXqtervXX4WRSBZK06fTsRHqE6PqmLbjlMp5U5h5iIMgBluZynR14eDiZWowizwRTpRbFRJwWpeZY/4yCqeydpYIn31hQsMat5s4PLu7SHNjBAoMxpBDzNWZjb2RnuUwyg2PudyjuuPSopvXTkql48xOBUsdV1cuZuhLp4sYFouW95e3yd5Itx+1kam0esArfvMacPy9JZAxAJmS0JhEQFwcg8po2YWQccIZlZwYOmXFfCF/5N7MFjAVaZ917zXvpe6eR8RRW+RVF1y1nIax1piyDqNzu1vr1Hqt9qYshigLsG+/jGSdC9+LptmZ0aBmJdgNz2c+dVNFue697lMVs85HsaK/997YTEc+9EZiTmJEf1v1Tr3en18A0Ya4VHBSHU/HAyM0BhoBgxA+i9pRZAW3eGAXoMdlRWjSLzlY0L7EscJTCGMljc94YzOS/2/w2V/ZS3bYtLq9Rrs232i/gWJg2GAJGhclzRF2wStL1xTSZp5e5sWTEqPU0ss7I3lUIbWuCuNztkjjp9LuCm8W1Xvw4harXGPD1oZSm1YDMpY+8BOBc1ZwVRrEcUE8l+ZJJQhccepoJjd23BmObxVdEsaqkvUVb2wmh8i1Pn+N7SZ4VSSBSTjTNGM6HGtDXbHTaOi6X1EksDDZjS7aCl9AEhIR+d2VrCvxqtUq1/sIo5P2tn+YtI3IUzV6/U59cfV5+fTId3UyqwqL4ZxNSMw5pB+GT8BVSZzE6ZWo7vJMRpfx3LT97fdetQUK9FOdJYrwXJWKyeF3JMihn/Bd35WgVamQEepTbRzK2WSC85p1ohcpPSnTMo73EMoLcH2zPy/F+QEQLkjZo0k+N1+pn33v/OygsTVoxF00F7iothTFG0tqtUKBdOvL04e4CWoVvf5oTrMcy3A2kEXfUzY8trSoiDQJyz6BH/3E3ebgi2O7OHkytcpdkFrF0fu7UBTtdMj46Bvrq4H7PVCnebv1GgLduIMbKPFCmB9ElzvwT2o+VD4aIiMDlbrxuolh243Xp8Hwy4vn/esoCCtNqHKPEhvZ57kGeJJed0WolrpkGEOlyeF4TLLC5hr3yrZOsxo7zGplq3R8M3+4r2sH+dKJnTvAS8j7gOQz40PC+r3avcQUmWSHVtx0Zl2kQysmid+9JIkrd4XEMb2SJCaJMeddYSLTOSbX8fbBOZ1a+O0GngfREPdaWSAssBssNcYu6+B8kli4KEmMS3M/+MZyD+p+0uKTDQ8rgjXfbk6megRhqkGCW5V3HBesuxxI0w+UPn905Cd+pGquwvOQ5KyDsHuWHhm1dF3rW1Df+eL5QD6cBLJ2XrgOZI1iLWURA3FtjXOLZ7J4p1N6Xt5jnudZ1MFx+U4Bl6k9m97f/z3BQtZjIbKVr0vvSUwwE2NESKhhODTkVJ8SOQFlUhYNsE+uXMHGDcf3K14R/qCcQJZQKvGNfbzg1L71Qq/da/Vrje6uZvM0X7EuyldicD/1xmZZ63PSlrPGV5aSGZCwGk6IHDqmlbFcyzLAXkp5s0iLxJGulcVUOC84M/iyrJUC19zZSZ9mMRcEt9qN86Et4JAuf1WqMpykxutyM4ambVG3dJMYBtMt01aU49U8IS1heUJkBCTCz6oyHF+A+AWMOv00p6w9Sl5Nxjk0zUavvhhvmRROqE2lNoOIw/DkEPTMkxhxpKK4mj7qH1AcCP9yAS/ef3jl1vP1VguPRevLO5W1Wy80651mr93tbBdbPLDm0hcgPrbA9n+g2LppvJ1HqeN53Mrdgb+yNTe4FVBNG+jh1ED+jEM7hYiYAmQ0OC6vXKlYqsI0aj0HrCEu6kX36+q3nu/1a/1WrdlcoOvdeqHdrtd63V5rdcfwBRym1+90dlyqjM1ST1yv617moOwPl8R1xZbuJzV3g7gukRNZnej6bHQ/F0HnvrQlvgvIJXDMrwo8P1qDhle8njywRUsobucSbOmjS7a08v7IoNJ79BJsafXw4yEZVo2x4Dr3eFExxamvAoYkHAQp8N5SNKOOe+aTi2mXnCa29+sJZoRsKen8kUF9Zboyu2BL0Q2DxbMrSCWQYIwNFliVE64qWYcWTkuBhIzuCLjePi4KExUszAY84R9bYHztVrvbrnd2eP/169rWgjc9JbhV7YAAOs2ejw4JEp/tpTxLv9Oo1ebbkcYjXWraCDhtVRuOwOCGQrmuckTAGReuw7HOnL/BwS1qVr5Y4lq57CaHx2OfWO2steE0YgpoX8Ra3puEsZgici6M8TCGQADCRM0mxLFOcrbDiZaxdZ2Uy7mTUuYom8kdaAc3MuWjzI1DM/W8sZWePopXVKzSyzcfJYa9zyd7NlvNuPl58bcCxRmS0dAItTuWwK3uhEHSz8kRDXDPjG+7Ls/xHDFympbfPUryKmX7ZZcERpJ5dEmUi99I3oZciy74+OHi8YehroyAHNmFQNrlI09Kh4qyKwNX4LE2tnR5nnDsVE9XL0wcNyajxnp37VMpQXx+ihECo0ay7I2R5P0pmhZHjeX5qTTC6TQcasYQm9QGZGocC1AFZgHZtE8UgedXgghdMCalRxj8M1vve06tR0/GgBjQhWJADOgTH212c77xKHUPEAC12/12t7Eai5LCMhvMhlrey5qcAlkhuTyXpiVI9lC3maXLUknqx9cD4mx0qdXvNjcAXaod504iS9sG6PseJdpToyyt3mrX+7WdgKZDzWF2Gc9LBafUcACXxUybq3zJca5x15fEuvbERShXvMMR12XCR5t7hxHOt+8lS331Xr3TXjR7rQOZUoaVVbB8l0vLBirGS+US5Dimxy3hZS3bMXcXLK+2ziU+tBs+WjVJxT7sp+Cz/ynhw7q3u+1uF2TyoWt7kdONDV/ORtPZECfTWY5bcA6Os1TXGA44OMJErWwUMtQtnuwXspmTfHQN/izVzbl1wc5F6/if+miz5Pp3HiXu0kSXADuNTr9dW0xAmj95dRiSkTYajwaGh7OubCSMPq4Zr+AFwIrypY8tdz7FvHn3ENmdLD98mmEEH0qYtsbStaXM43QwwbGZgGOxfUpqMtTHCnKWqRwYE3Vf4NVFH2Kw53MkF76T93HqENdwlEgGl5g9uQHycrEkXF7+e+PRZg8LWv23pnxw7LJiH6xrmm5oRJfjKRkYcqSq+zS7T0F1TnnOvCZKlh9klSmwQhZEA5Ydw7fWLLxx1jtrbHdal2ipXzHxNx+t7gbFYsG4/6UJEruK8Qi6GJWRdU2vJhDdL13zvDL1rsssaJiIdi7CT5yq7vsMJy77Am8G3K2Hje0x/sIrEl5arV78G0uisjKRP4TP3p0wkdZtCPD9en+e5WvJh5/pcjjmkEUpqQcEkgdUM0HlqSr5tFzxeNlSnkWs3Q0Gb83qxe99tHlipz1Ol/Pr0RjLxqJvO2Eds7EyRqQoJKYQ0bJeH49X/IiFQ14MuWKWMmBju9sH61c4W1mGje97tLmRFEPJ16YqLomwsYaAkAnHIoTgDARAKhLiH0E0xAkErqsIFC5EeUZh4yMJFOtFMbT096YqrnEs3w7Du8Zw+KMq+9zGsY+Wwp22OXterYyqFTtnFb9F9zD/zqPNChHGk3EivUvHDkChpVBoZe2EaOSGsCxG3PKJxSmzjk3hMkYJZdRmXmpYdOes0d8aPa50UebHtlh443FiykLUzdlpNvv93vzALoEg0LSpRiSXPFpeJohhz7ekgxCY0p2y5/muZdicmTstvL3LwgcXCYI/9WjzrAsZyrtS1wAWbCQKgsPxeDyTeqiRUJsYM3KHOrkCcynYgWu5RDl40OUzF7cQOxb3y+oJTURXCIIrL/VLW7zUx615KYgYLUhFuvVFE+fi4UdTLdSmaooFDvxSduCDt2Jg3kHZl26AK6FpECUhT84Kr9oJ9StbQLQep5sjmrcbtXaj12os7ryDCo3G01kIsXxQHej3seKkHAcRoLtFv+QpXA6rBcRw4A/m7uXPO0Gcv3njxSWIX3u06imIQbQfp4/rOrchVoBxLyaRpyHM9CJe3KfYbwO/Uuq5lLmel9HLlssyrkPLdv6cdvOrXtz/Px9tNkZ8+uPkDhTMzxu1ZqfRXIzUi9VIVscSjGM2sPBuvhdNdmXKN+e1Uc9X1PQMv8DALOjRJVa5XESh/u0Whao8Tjc+NXHkar1Wby5uvKdBGMCXZFS5jO6Q4GH2YqW4j/Td83hQeEZWEcfuP1ySwVW4QG71OL2mcMGjfgiyJZTSHEMYYQBSNTJmR8XCcf4kU8hkbOvgOJ8llp11WdbK57SSa9wsO8zCNYX1xr365i2Mi+VLb9vUqP+4JWH6tKRZzGN3t9vrd+catZKBhGRPD8cDGURdTtE1ZBnNT68oVQkqkDWB6wKfqyrPKnbHMP7LFsP4BIDxJSnDaLe7NXC1cxhrGAwSGYbEmYpCMEmBBqoAMygHYrl9yFwhCvozMowYxkdXMJa3ez77cbpNvnYbB/91a4vm3zUQ+shxcDWsYNG1BfjJIZCXudTQaXFmE+YYO+sIbxGTimBo6Wvh22C0On14cXtYR9xbQFEIZTxBKNVZ2aFGLo9Qynks8nMw+2PhZHNAr2SxlHFPjvXoglLYu9sIextALtkVuFUee7uBdFr9Zm/hb59OHjaXZchcQR5ACJ3ss5JHDGPv8aaRf8nj9F3w3m3IaRq9Rn0xlnOA4x8gNistHAdjIIR48UJxvDaiQTA3sLSAQ+Mc6gpVhnhYKmV3EsKrTaqKy1NYAZkTwtUZ0htr6XeqKjLTtXAQoBC0CVFjYyq0zFExU8i7pWMj5zoFltUxkDusqJl20fEATLQS9m79XitsbC9PXeL63vIESXu82QOBiWzyKG8taR1oiedXclLMiuPyzZsFRguuSXGIG2QaDmVlD3DYtuc6yx4IPEDq3Xq+3qi3Wt1eaz5Gej4LtXXWrG3NZq9d/Ix9tQVgi5qNHycmiUWNgo0GOK9Fc8Skqo0GikAqOApHQ6LhLAi87IrDXkR0Ugk0xWd+AOrHdN/zg0pF+s+iUXD4tiU7qWwREjKW70pVeZLsZCEaQw6nxjQcayGuMWM41dUmHBL0wPaEwA5O7ByM5mGzJzSqXJ6dnN3Z+9eLB/5Tjzcp1puP09vyOrfbvU4PIuK8vp6GoJE7ltItrIe4OKaO4vB0h2PTo50p4/JbjR3YCU1r1G+90ALVbdX75wycvWQvx97PJXLZdeaFOe8XfSx5WzHObzG0YIiRoQxjNSPadDoe53NHuXz+8ODEODYzJzfL9OaRVTCPWfm4lHOobhLDJPGZwVm9G9Y3N2dcel9prGytLcqG+dY3ppQtmVutbCUCMZbiyMzhbkzuGVaRe+xQcJajusfAKbNCAeIPfRbKlgDRfrwqAC0HPz1KH+6nc6uEmo1GhOh6USrBos4EHi3OA0rJ/HmTqq8YOAH3CYOfrmD3q61CH7dFEr+05pvTqXpKCpIE2n3TME+4yZiEwE6caJWMxzwcX11wmaNT5wmrwq4kieVa5cebpTjkxq+n11QlePA6hvGIRveUcKxQtNnHwWQdB4tArqWcaB+5uMSaqqdAsSKQLz3ePIj6e/DZ/7iX7K3t9dtdeG1YY0esiCIcj6vSCPDCz0S7b3m0aGp5lnFwxF4mV+S8mNnP5CxIs3JWJl8qYG9wDxcq32uEzbubI9HQvm9e0L6Ta64/7fFmTfE/Ji1jI71CY9AmITEgPxnMxpoWuq5HmcelJznBQae4V0LiXMoo3VVKCpc+IwIZTx349C1qhbWIL0upVbLusNCmcEQmRhXvAWigVT4VeKHPkUFFQBzHa7wQ2fG3eQN6auxW616jvlWzrjR14M8BkuIaR/nI40TH86KBs7toclmThRFqeBvDkbbPwRA49swHQblSCaRTCSjSFUPKneJ4i5YzfvZKHMv86qOP0rf60mkimPVSEEONqOmESvkcSKMiy6eqUKkgs8LsvSKjSQTCx9PPZ6RV/yQJQzsfxjxNjGEMDJKEoRyf6V4l4xN1UqmwCAa2ZyMMlrdAq5Kr7Hv3mumTwVWiuN7bfFmJ7O2GkkwUt0hE8Wq0v16eKgOD4P9/Eomt4797vFkk/TePE1sno/wEj3Hi/CQJYDQZaLJo4bVppXwcMaKEC6QdHZVp267DTM/TTrj2bA7V4taSL3m8ea0dM+Dk8IRVthsfPMfmPamOglkgdU1m8sUj48jizHGJUS5amVwhc2DnHZOUSLlk5lzXecIt0StnvfEK0697HG873HvS3vF+AxLfxVTNFYbpaKpNpneAwHOO04wdVQHmXlHiuVNx6leYrFQ8CB8+3906mVphevYUg6himxhviX2YIt5PHG6m08HkM4fDAZkRHJLLiUlLZZkRnBOIdTy6mQ94GLZ80mc2JSGG8a2PN2tAP/E4vQm3A7wwSqXmpcU1EKMxsR1aztGyS4nlsnIB77mSvGUYNEssK2to2ePczuLJ1WDElOovb4HxHx4n9ltEga/eqPWa/TkMTeqj4Swk1aExlLPxdKa5DO+6EU/mOVNcopkzl1gM0lxDL5qeVaT7ydPNsNHfCH5X7hz7y0vzXkXw33+c6ICPXG2z3ui2W4mBbVInaTB2tJxbRBfffK6wL1yHHJ0qL1DKqHhK2nS3eV/Z5cadfY+XcFZyOX7z1ZsfTKgXUKtGo9ZprhrhYhCjUBvrU2OgG4RrxYN82TWy5SzJ66WCRvIFpp+Yh0U7Uzo8LB4WN+Y0tresvboyw3pzSx6F1YgvSyWDycrDwkgM3Po7CodS3jnOlgyezxtlveDldM3DdRqQRnGXMU4dV8+J3f6qc5UYEoP4G4/nl8iS5ZPimwmaGJUa6xBDWouMNo0g1MI7wjeVD+yEU+CFNiRP3LcDZTmC2DiZjkq6vD+2/fB5292xs3OPPFee64e2mPzvwmeflea6vW63s5gVBghQlzQDUkJ9KsezKiQfHsPJRx5WgMu4hFNyHUQAXpji8HLb23nl5YrXqD+USPzW+wAwQfzq1NWBRTI4r2StgRBgysrF6eRFIFQWXnoNTCtKnYDFl11TnjdM5LJ9ALHT+tFFEE9a+a/AZ5+YcloQCFvN+mqPx0KTQk2rDiChnegzw2XOScEUEAQtyQUv4iAn0CxplUE4nPrOajP8bqeVHPoQXEQkcW/fP9zitG69mehPjFplcEJjs7YaLpuSiayOZ2MLLdo2GIQP17Vc0yUu23eLhp0taxa7mTu8sbkCo3FWu5ua/Nu4Um9fbCw/saVgGryZmDkwP1zoAWdcqFlaMmRE7gisjig89PSj82jfj3aoYj3Fw2Q9TeAb/bPtYycv7n6HyzD/E1sSEWQwyU28abayAWMYCHF6ehpEuxsVTnHz8UAXyDyW4wOwlSA1AQJwbOcrlwoj8VWEjywT9RV7xOT9Kz+WbB9dJeprGIB8FQ2jqFtl5kiREdSVpudIi0vXJtzluFzOspPcsdE8S1xHvvLA8ngj788s6XvxCfQdWHC7uVjLtQlECB+nUkEI8fHuGqjUaVQv8f+04JC5+8Dhk0DqZ+l50hGDv7Z4+NHdt50zbuBsyU3QQ+lBuoUXPdmHU1lt7LVWV6mXTx5de9InJwVW9kqHJVwlC/ksIMAmvyDIEbAYWsShuVgXxZV+x/FSzuQV5KTfusTcgdWpyL/ZUqjGnPcLP5Y8f0vmt6QaRheEqnIcGnIYjoqgTbgKBgWAv+FAOtxK4EffuCRXisSpSL116/lWrdNu1ZfL+s5Jey96KhLf3v3dLZaPDOBvpQ0mEe0X0iGGNjCGxjjUDewQeE7RkpQ+d3xTVLD8gBUI7IbHeQTBcqkHguvceh5L+u1mo3G5q8nnzZpfeuff35JLYiLwvpQmxqQ/une9Bm084nZRUUpEXto2DuMyVCQvYSoOHE16ee4az6i+EvcMYcKlrVUfP+PNVBKGFa8muILFwpKV4hmaHBkzPdoVJaIRiLgQtuJHHctoU+AbpP8cTtt7xnW7/7BF01AYX5PStFQqqVW1NIxrHBeQXQvKpwHoF6lEw4Y4KJsv0EFgm2AyVtbO2mc7kslLRP3hsrCNmdY6FMzIviI1aDPOviK9Go/GajicYB6JE+tmwNGcgAvviFonEC8dG+UCmTHAUP6fUrjsIxUu67VkV//V0q7hqr8Rs5N5xrJKu/5GMl5uZCy6HI6CcAgGEoZkOtTC+waxNY+5+knWA16fKQrmMU/zXKJRMBzbs9ju46tUxnLBkWhLEMGbm7kjMpqvS4FIkbD5o49nkOAPDaJp9y3pQF5iM8emvufT6PQKIqfNOWT5AugyPwfEVffD/ek3NwsUI/gsTBh5/Xan1Wk2klfbUihmE2MGWQrXAt8qlj3iCbNSkW6xjHYeGAeOPIZMbNWPtnvo3iUnHK9c760tJoL8/0s/lmyLj7n+fBjXGhIDYuVp1McvsPlBFnDHGt6yivyYCrDY7e2sfzV2wXjp/GLkymmN3tyMICipn0pNQoylEjWnwIMTEg61sTELQzWZzixBbcpt59iJ5gHnM5J7fgHrYAVdM5nuJcYgIhHrhbWws1UiV0pVXn7z1Y0+m+9/M733qoEF7k6jsTiNC8dTIyTaaGpopDqajqXENAXn5gJtwRHNQGcqAfcrlUpwCj74OTAce2cYudooi59NwFi/M/kjbybuTEaHip1arRtPG1lDgfkjJ8KWypMkK3DhDZi7ze2Cq9tcZjRqH+ZT8w+bYe1s81DxMgI5S+rWp765uaXz77+ZKkni4JRat9mrNVc1vFmkXDoolzYez0a67lLqetz2iJvTLGEekazKFi1Dl5njjG14J9k8JahXYb1xt39Wv9tNBsR+XKfYXzuvvjsanQPm7oqhfMZSKK+mysRfkz6TWzGUhXkA2QcEhpyOQsu1PWBYkHbhjW+uOGSMOCYFbN8TwoaQQndPSXlrGlC/5M154pI8x/oXa8l8HVB0ut3+vKsmfvgqkBOQCZndt1xuYfXL9lzuuJxQ+JUVXafguHYxr9909rFN/nA1zryeKEskt/tev3jGsgyI3/zmZlXiB+Gzd+4lO+WbvVar0W8t1i/A42vT8YxEpcjx6A5uhcHCBJYkfJw1j2eJ+AN/obgAS+4MiG9Je9BkC4iPvZkYzBwNMOkAde/25tO/1yAMSBEHy2Nbih81/cMj+1icAGpFKUYP7jjZnSCusrdn6XT/2pubxdTidyVKXpHT7dQgCPbnI/LhsfHoZzyshrNwIGeKONTDAxRBLbByMAbJONbuDMlNanJbc01n/xk53RjG928Jg+iIk2tJ1mLH6vlBJmMQiyFJiQnXdiVXNrOU5EypqLvZwz2KHmVPMPCrwfhwwgb+v6E3FEF5ZS3qYi2kfOHUItEioiTRpNgo4QGMF2AGF5MRFpSXl5eWlxETkpcH7euWAy33lwFtCAXfOEiTNZpIpdTm2bB9eoiWFagqQerUIlUb4MVBLiheaBQUkpdjk1WUFJJWVZFWVJERFpZXAR0gpqIiIgnsJ4Jai6hXxBiFGBtjrTTIugoKVmlsmY25jRWUqODbWNFrctT01AE6E19WUVUe3LoVAx8OqgrelQtaCKwCWR+EeikflkVnZDd0D0BdvHs2onMOS1NWwBy+EKWsNbUEDedAxoZQYkKiRbFBAbzTXhl62RDoaCUl8GGO4KNOQcfoKpGxy42wF1wZAEYrOkpX/wAAH4sIBAAAAAAA/wYAQkMCAGhStb0JuCTZVR74qqvelntERkbcWG7cuDciX+eA9Mg98wGCF/myq7Jbaq0laMQiCYkBhAVoQSAJicokEYGxWNTY8iC61XtLA5Y1jPk+5gOE0M5my4xlPDazMB5jPsw39oz9zQdm0ZwTmZF5I5da3qvK7npVHdLXHX+ee875z7ln+fTOzk4Bfv36hx7dVb/2g7VLO0/vBPNn7i88uvtj8PsDr3xlvV7vdk+OO91GvV1v7Zzet7MTCaJMx+PpOIoUhUcDMrUt6nrM8DzKGPe4IB7XmevpVqngVTS9yHSTP1J/w6VHGm/YeXj4mlZ355XXXrP4l++ED7+h+tKH37DzKvj94Ve84WsfuR6+evCK15zexmfnt+av/BmEUUUYb9jx589eDjA+lsBoNtuN416nVW+2+zt1gJGGMCa85NmcCy48zn34CDdwXfhdZ8zxmWto1DB1GUVngQL/3YhiR0JBbx/Fzu/OX/h35rK4T5JFG0D8PUkW3eNOv9Hs9loxCG0HgcgoiELUolmirmXbrl70DMKcfMZidknLlUzT1RXTLalaLkHyyNkb/DQa/I/cFZn884VMXrWQyZvg2Q9++ctfXsqk0+r2eifNGM5YUcmURyNlooyVMR/zki583/N9K4AffuCBZFA48FBwHgju+MK7fZkEdyCTBMSXF/rx6ALEBJ69XgLROe72Ou1evxuDqJGxopBopGqT6ZCrRCupaoG5Qri67TDGLJu6xLQF8xiA8oQDemNsBdG5gCgWIA7hEKnHae14Lzz7oKQdreNuq9Xr9RsxCPn91Yk2mdzwBHzroB2BgF+BZ7t+wODtfe6BSITBVW+7JFoI4lACcXwHID49f+HSLySSeNVCOx4HSXxPIol6t9c87tZb9f5JPbZUfFQbDhQ+Dmvwp5qqKKMrAbHcIpyeivBFwKt4mKoBdwXjVAT48dxtlqrXvJBWfHb+ygrAUNjM4C4OFDx7NCWLZvuk35mJQhLDYDLminZqMMvlwmWW75vUp7SQ94qK2HUKqpovlRRb0bISiGbzeqNxvb4mjz1Ach8gMQEJuwN5fE7yEqvyQG/y7qU8VjxHLAgSC2IUKmQ8GHtHNre8ypHnX3HKoODlKih1gH+ZQcBE4HlC9hyN+lmzs9F5XDqPSH5XsrEzu7tEgrb47RKSpd1Fmxs7kKmiRFpNG4y0Kfwaj4SpmYLqzC9YRwWj6FGS4WXuMJPrOkChgaeQ8j20u5+cv/pX4wlbMVm/BnBeK5ms1nHnpF3vdmbKDpIYBuMR/tImQquVdDufOyiaTt4oFlzuMtcpuyKgwmccLBk+2G6xWhexWImyfx2KpDezWIlIInj25pQrbJ70Gs3+SXy4ViCo0ZAXAuI73Bao655jCxv0JfDBvZcCzXNK1PErW2lJLApVQtG7bRRXT3c+I1EQlaZFgVTllSkXKNOSkabO3j4c1sLhdKiVDvJKJXt4UPTsciFjGfm8RnN0n7gOc0quAy4li8788iONt1n3AYz29VZ9oxdEFdkBIFUA8srbFMen5u/8rYsjtRTHF+DZTyXiaHS7bdB1gNGNpVGDNx9MtdEwDElUGw/FlFU9QakHdtYXtgAjbLsVZjHDdQue6zrmgepsMb34777AmQoXh+oH5tKQ+dWX4NmPplGctHudenfni5d2dt6Oxy5+/SFg0UbTIByPFINRz6aa4lCPlouWQYiuFZzdilrYLajZTD6XL+Tn+t08WYNB5zDonCU+jDAGtyGM35y/8nsQRgaF8YoYBn7e+psfjX9P/kvd41av1W/VZ7qxfP1ROOBD4FhlB9zdUQmJblACkyt8U4jArwrXqgo0wZyzuTT0NWnEupGZw8jciYlKJPHeBSFZ6gWSlO9OmSiZkNSGw+E0HEaD4VQTWhgNgMTmXavguprJqOsCS694FvU8m1EfwhAhqJfYKAsQdEJJFDIlQbU4vENKkljaycKXLxku+vc3p2BIvjxMY1C5x4D+Qczke57jgysEShW4wK9cD/7g+Q4DfjVH0dxsaffmcti7Qzf+t5JVnVnaRxdKgdb30ZTzky1tGkFtMJgULEIq1gHRmca4Qh3uGcwrAquivAzslqhAfecoLj8Svqb5gheenJx0Gycn9Re0ug+/oPE1zcYLXtg46XRP+t3u/FEX/k8NYHLAHuZPbmGk1Tsy0qdLI/0FyV8m3wAavLcm38CqcVPmn2igRVGocEUta9oBKRPbODQMxVCI4eq5iu0B3ae2bVPbcVIOs34mCVI2b6s05uUvf/nwVS991atfMXjZy0YveeDBjTj+j/k7//bCvC2NtPnYo7tvk+xC87jTq/dO4JtrI6WWwCgQOUbRGNBg1It2wWXB7FMt3Xclu3+lVHScw5LN94DygxQ7ILJ2p9dpgJmJJdSMJdToXG9cq581rrWv9WSMzcT27a7avtPTN8Dnjd/2ra9//ete+9pv/ZZV6Q2vPrQwHF9aONQlVUOz/p60rOYmPBYWWLtRNFWAdda4MlQmnAKpPPK9+6tHVaeK1g6DSTAY8BP/iQtHsJt7olUTjqI6u/rArY9cAuNfLrjzUlRfDaL68ZQJb7Q6nXpvDmN52CaKFhKhMWDH3Am4Br8JFlRFFV8/8I8gTmOACYjOdoe6lWmeXbsNzUniysuPJdJYxjLfBc/eJ8UyveMGHJJ+Z5awgDM2DZVoSsYhHLlabXRqeLMvn1nw3k4BPFEgFPwjtYoHvsldqm2lmr1twji9OrwliM9KKpJwtEBSpfdLR2qpNjP9V+HNh1ptPOHRCHRGLZKDfTWj5rLFSkHVMmreqOxapqsSAz4usR3VlPW/E0ocTdaNS6s4bkcan5UOkLpix/CgvVMCsnKouELCAYRj4ymEMqoW1RyzqJGyYeiMENs6ZA6xwXjZ4FTZgeXYhBmMpMQR1jceqzuPx0av3vmV+Ut//WNJ4qgUH6svzz870rGCSP+k3u/3ZhGMMtUgMI5ICOeKjyZkVBKgG3B6dAjvIVoB6smAFUBIWQ28alD1jxjfnq5oxkmj+ZtfPbvVm58t1Polj60nU38enr1Filr6x21wpv1GYxYSz794Ph0rmgYuhYO7AHrJSsxjTHB8dQi3GOiI59o6M9meaZtbo5b+hQLIT0kqPHMkS1qDqv4uidYs1RrjYS/WCqIqZCiU8VANw6nKS/f5NODsQAtczhwGrAY4zX2esJDZ+B5n8AOV4Xqjdb3R3qjX9636imunt7Kyi/zEdy/0emljPwXPfjjlDhvNRrvR78xdxSQFQK2BK/QYBxdoOq4QVS/jZ5gvLOpDROkDXa6KSlHOT/SvNzY7vVXFHj549dbySI7VDz+27i0+Ac++Y3mses3jVuekX++1ZxQt0EgIZjQajGtaqBCicOHZ6NWRUAZA7wETr4LD8wNTUHDxIuD+vch8DR9cwIg2aMdfPCZlvuAA9447zX7/pNmbCUQCQMbKQOEQ9IIgPBqAckAsaVqgFx6IiNuOZbtuxXPN8lbt6F1IOxLr9DO3ZZ0a4C+A4c7S2ikIRBvdoLZqe7bngyUCP10FKVSqAVomsE/wBCzVbVqn23nxxFv/Q0khErUuP/7o7mM78h1JsweB4zyVnXppvFy4UfZtwVXqc9PnmCyF75y5ENI7FYMyogVlS9w8H7/RW2/ktfJntDhEP//YetYRze5PS+FK2sSuYogiYEdg/gMKRrXKfcuzWKwLSJ6A9vpIebffV53XxF576CUPv3gRc3xI0oVEFhWQxS+kZVFvnrQa9dkhGiuRonEVrBNRJkoU3TAgtnBKec2htGzrlQOWwUxRoWy4mYLq7mUz2dU0cHNNHOb5cqcLcTy5Qaf3AcdPSEa2ddzogzCa/dn14RxEFIOIxoKTOHqHWMmC31yDGBZlOnWpoeuWruuEGMTZSmQvkm083fmnEoxSM84MXUlgHKzA6B93+u0530CftwQyjoFMAAi8OIR6ubKr2tlMTrVoxc5WKmVlL2Nlr5Ddw/0rK/nfZuMMk9oyon4ilyQ53zxPhuWZDd6PA6IPp5NE3V4dWNTM2MoqEqmCTMAKcfALgc+Rg3DfAW5uzzLAIgBtgQDjFhHGJm0f3A6nTVLzv/TY+pXo3uOSE5+pe6fdO2k2FqJJw9AIn2AEbrsHZYVhuOG6JcV1Pc80eaVse8DQSzYp3TQ1v5DKhZgVeu3VPOqX4NlXpzx5p9NsnMw84AKAgkZMGUIAGAjweCAJkAv+gL+r8AFPAmZL1CzP87car+2O/IFbCmUwWAQan9gQaCBH+VDqJk7mI5GqrsBwbcelrme5CgcmqAhmM8ZcTsCbHFIQELUsS4LRPms1NgJZNV63kUhdKsknNyjJX8Oz10hK0jtun/Ta/e4MyJo4xkjNQRNAG8AxYvSKssB70RyEGq5jHDmm2Kok2wPY24GRyONTGyJYZL/TVAQrM12BTHc8nqGAgHzC9x3iQpx32THtomHbmrZfyVdAa5wSAWalOIZlG/D6vWvNs+ZZo3mtGzZvN7tz888DVwcL9fjSY+uZODxsn0sdLFk9FEUbQtyhqgGZ1pRwNHJsE7whhejJhajDE/AXNWOdh5PFXU6pbd0Lniudqn+9wbd//eNScicuGWi0OxCIzy594oMEZygEuqtpwVQB304qFYvSHLLakgXenLkFGt/EuYeHtOyUZcvb7F/vyq69c/4wPFzQxf9TijoSGF+GZ1+foiiNeqN9ctKeUZQFhCmEtYPxuASqHUC0BwwLqzd8zMpjXhtiDeYHDCJzj9+cLp7T4i5U40838JPR49KVT3xJ3Tip93rN+V1JCgGpRRPb1p0cHCNfcIg0PEEEs8BCGY5l2p5jc6ui2TKK9jXZVF3ojjpcAPl/F6qxPFSPAJAoFXV0eifd1pyiLCCIaKIpyrhkMPB4Aus4MEMobN/xfTfjg0xcA1iWnVNK8plqXG9ea9TTkccKM7kTiSRh+V9sIPAYGb5ZIvDpKHApCYRBaqGCL+9XsQQInB5HkwuhOIa0gQjQK3ppAt/oX5PCcjkQvGORXHtotLBWf71IkyytFXqU5ySzu/Qe/+nSzs51xDrDEs6xkOGopB5qyp5DTNvUdUoPPGrrRcfKgQmwrF3HckzXiBPrZ43ORudx6Y5s7kvS8viy5Mx9SfV/K3VFLas5BFSTKOIQ0iqTqaKAVuzlHdOqFDUwVcUKy/llX8DZsg2XCdQZlzvp249G/VqztVHXz3OyErt76fF1Xf8O2e7GXLHXbjXb7VlBCgKZSkBqNRvjEMYhpGKcgppz7plcF0hOHOow+MvW7lH27Z9J9Ha1GuWXZG+eorxJNQpIRJGBDIa2ZlKRv3QkuBk4XtVh3LaCgJnwU6clsMI25SuUt30NYpGTjbT3HIK5tpDM/uPrOo8h1w9KmrISJabFMhiOIODg9pGPlwU+d31Rje+oXVd43AcCRqQb6zuIEofhLWEMdn5fighnUeKrrmyDkUSJiVzG0SqQy5cPDvySwvN5w+VqBdwJt3ip6ArX0nlAU0Dmcqlfb1xr3bUgcUnkyxs05gPw7CmJ/3aOu61mq92dp0glINPJNOITwhwLdANi+F1iObZRpure4e6BpqpZ28oc5DKFdNlsKx3tXoCqSCURMZCVOhtMd70hZcRSqa0JcEd1DmQ8jcQNTVeK+ULZ2t/P5ip7yqFa3D88OABk+dwVNw/O3ihitvpa+6zRPettTGxdvlPyK9nhiqQjCQTMEr0xDUHKCKmxKHgiCjHx9ousWLQuVUzqm/4VvaQQr2I4QRlidcvSPbDFcloRTlXzerNx1+xwYsDMx9dj9p+EZ38/FVXhmWr224uYHbEESyxiAGGWapoOydpXCppBy6SczeT3aUnNqbqj6JXdfb2UX1GUE8ATttac5EZEt9b8pWuxH1/PwL8Vnr1rR75L6PbqrVb7ZJ66XiqJmPCBNnV9DyPFwK86uoWFAS6hqO7UMSvUdMrEVrdEJkl8tYkMD259j7Bkw+zx9Xj378Kz96eyda1+o9VpNmcltGkQ0UiwuDzTEma57NlFHlRt5ii2bwrVtkmxfLms5lPZusa19pol3njVeevPYCEP/vg69cKM1+tTV51Jdis5YohluMAyHAleLOWLlV3NubJrOIVKztasspbPGZ6TtckuBL9EsUh8rBpyhCVnt9ZuqG75OVtWnnz9Bp3H6PGdX5aLy+VIcSRqgxpEiwPBw0ltPKidMgdIvcM9v4qJiEsBLxY8Znq+r5NA+PBHX3aLjV7Y6N2lUHGpHqMN/h0jr/d8WS4FlqOs6VDBQkeITTQxjQbaaOC7EA/aAS9T6nJ8cYhRqjEsTHFBDAn+/h41kSQ3Ow89ntzs7NzkZqfV75z0m7ObnTUUN0DH8TqHMe8I7zshEhHC80RVVKvM8x3Td9Tbu9k5u2UFw/L7v/74eqj+y/DshvTi3eNGr9notGcvLr/zRAsnWlzfX/GAWOHtGpwcyhwwWJTZnuFZBcNyDsy0G085jgtc/C9hPLKBjvwMPPvmFIFv1TEYmdHENAh1SoDAM1tnLgMSRQVzsNiHCcXQqeXZnstdYmzP/1yQwH9SgqGsaDWG7z8kaXUqVF9D4Vnw3j6PmW1y+MGHw+94XQjK4acrlDobo/SL1F9/xwaNxvjqnakgRI6l+HBa40PCa+FkEvHRcKqaATaLaMI+grf3dQ7qHMSIvAD+FGO6+9dsMxifl3z0aqYaffn7UplR2W+rChyi2kSbjkIeahP4876p7BYMLV/JZit2ljgVojrUznoV2zOprlLdZano9nrzrLWeGz0nqVre3r4doShpHf8TePaBVDqu0272+vOSWXUVyQ2PYfrHw44qOELCJx5IxfOJr2DdrIdJoZun45S5QBRAYZ/jWP3ABh71JXg22ZFLANp9oCC92e3t8jhpyojDnxU4QAwjPtQM1zfKAAVOE68SbNkT9/v3M2fLdWFdooPJsbp6J7L4HYkzrdIP5FZvS8WzCY9KQsHhDIAmRBQOo6g2mOzn93IH2exutpwlldzBfmn34ECjB1lrP69aJUelVCdzZttoh43r8Nd6WHvOwGMplJ/coOvI4b8nlcdK+HpMbmeSqNUSIFMXZGFSanvYI+JYnmPbWE0ONgvic/DczAu2R+drQjlXF89PL4SyPFt/BM++d3m2eg0gIe16V+KEq0CmIccyJY5+m2M5RuD7QvGr1UAcqeIoqOk+z9z0qrC3Vudw/3kudX5mg1TQszybssCyMwQNH6uTaKqNoskUua5CeY3/N9jxAnbXZjYWOQASvDbEQgdOUDQprn69vdEGnys2T47XBzYAwXj926TjlU4ypHGMhsrEFc6BL/KCCgfvOgNe9aq+CITlxt1iAitgtx6vi7RQLu3vRx9fv9XRPizFTrNWHjhfzfnxik8TqY1HIqppkxqPTg28gcIyh7wtqG9pmm0RZlGRNfIkx4iWK5dvbn8v2gj6y4+vJ3uRPN6QqEmaKCpgsCa1CYCYkGkt0mqnu4clVSkVMjlSMvK0oIDxgljWtR3LoZatmPZNesMu0uC24Ff/5PHlJXoCwviw1LI+k0S/0e+157nRNIQBOkLgUdSLHSFHhg467+OVFPW57/iBe4sypvNhWLYifWoRaiyp7l/Bs29JUd1mt9Gpzx3h8u1BNcigFim2jW33HjvgTJRKFcqEQP+uUGbpHjWtimbeguqes2H9dJER/fQchpzqqX1YupWKdRs4Yg/NYmJzURcG0XgwRbs7FdEYLBH1HEuzi7t2pWId2rRMPdPe1bMZI6tZBS2bO1BWbW47XXrckfvc7hhQcqfzO3i2qmmC8sIPSxXts0i2g5HsLJBNiURVoxpaJIMIk3OrBKapGhSzgcOMqs3LDtW4d2Q79OaB7LnF8i8kSqVe/WDtssRPkHq9N3XHltCsGxDvKvD/+HicIplJROG1SRR/KqTMbEYYzTou5woFQWUcBZxJXHjpMebSBWl82RnAeXgj37pt7vv6173uda993bd8y2seeXV8Ddk76y3yJf+LpDWJ5r8SpPOhlOY3271WtzlT/RU002HJwHYrwUBZhOO6nssYmICK0C3BPXJYrhRLGfkWFOLc9QzpxmN2yzrx053/TaIl6v0frF2R5IP05QNSncOSqqDKlOYywt8TSDP5RMMwLB+ouWIFxLHnekYxy0lJ5/iBJ4x5rusCJQPZNF7VaD/ceLBZfzhWok2U5RZE8uUPDU9fDx/s0vmmb3z1HBbS0+4ZfFOtRTb7f11IaqlHfwPPznbk8rN2twcQZ5xyRU4aGcaVNZ6HHBKbW/wjPvsI4eaMPYMaTJFvFhonZ431HN25LcK/lGIs1Z7JKjlzGIt9b3qKxTzu+v6dmZyeuDQzdWAQoiUiTUxKFWW/mC3lS6WSU7KKRbPs5gilEFFWHIdZxLQ8A0QVy+nk4carNoZgl+chmCJLaXTt9KUv+YarLzsbvHj40hU0o1hIKCOIRxIy8J8RWSvtR4ugTV8naVPruAHRcbMxuzRZwgBuM1GFdooJCd9nnnDAoZqUQVTvGSC1gDJX9wyiWEl9/MHm9sXC3NYVAE5rLp8HX/LQrcrjFyD+EkHspE3CG1doWfe426jX23NalkYwmIanhmFaIAPDypmm52oZbnmlLCsVcm6hnFHNwkERc3ZXHmmcPbuZ0SQGG9urd+6gvTphA3+1yMsvKTIyhGdSXF9mA6sYRiPKHc0TR4YpmG1iFTNyfMvGtDDWcWIZDp+j+B9vzgbusEl8GYH9NcI4TLOBV4Ms3p1yns1us56kKFBFwmk4qAXA87ngw9pQm46xBQa7YAzLI2idhWczo2g6NrEoI3mP0Hx+DuXXNhZrnqzCObwTOJ+X7NVqWR3atd9IXTLINkysCkXLZg4Lud1yOVs6JIVSxVZL++SKQx0zZ5NSHigzSUZCnP0sJo/C+vVWe6MRu0+SzB3HYKjWM1VfGjFU/0+lGpVlVUcEQ0QQDIY8ILXpaaF4qB1mc4X9vFlwS0AxnYplly3bOSxTalmOk5pi07/e7G5U9sQYt84RvmC8tXpf8lE577IWg80O1GAYDNRwEg1rHLwhFqT5nu5xH0IxFwtmmeUBHfDR2eBAm3sTgyUUE0OV1fEcGNK8Ow1iGb6kxDCYqFMvS0n+UDOUUlY3d3XquXsacTCkZIxbYs/jNJ2RbLU3olgL6198Sw6zCMKQ5a+aLIwGfigV1SfMP86szgRQGyhiwsVEDEc5RVdMk2jlsk3sLGg3M4GS2bpgBgRnSSXE2+67tDmkP6e9GiyqBpDYKysKjgHAu9LXVkuyP/v6uVoT8HcwjLjmOHYuQ83KISP7igrUq6wJj3Km5Q1WYAxCMRfY8dves39zpn/HJjdhxK+UxJAcJmTJ35GuGpAYcRgJMRUTEIJQRlptGN7IWk7B3cV5Tpid9z0Xi2wgGsZhBDiCh8UztjKPNN72n++L+/XSkxQuMGDkbOcLkpuYuY7lcUJ38mMpUSSuI8moRrU0lEjNK2a24uqGyiui6hKRtT0c8BQnwDxvltUDeXzNfffAb3xCoh8zSrKUyV+uWKk0JVm+vzZQVZVDOG8YuhtYRd+CWMsz0EI5Adgu5FmC+RxEAzD++0t3l48kdvYHFgiWzPDffDhdbNo4brX6WFEzL/0dIjNX+VQMB2MSRTew9FfYWOyL9hbCEBPtq8Ud5guNAeN1MGy8Dxzfl24+ue22QQzOHnjg6tWFdk9Ru2MQr4+P1BX49cijTfxNGiF00mt3O915UfwgGNaUaPnhHvIoLz45TATLD4RVeZ3uUmojiH1QDeW+zdMpFig2IsCmsJe+7GUvf/krXvHwww+fPvCS04cffvGLF0b2JxZyeHChFfhsASGedtBqNk9aJ805A4m/fenDuEEpr+I4AJRQ3Guf+nAP0xEFwPCN960Z2vYtMAzOhlcfuHptNHrwwQcfgs+LZ5+Hru2MVzDct/Njt4EhIYWqMg4G02EQjIY1fMmJSpjNHNPJKaZeBoexq+fK+7pyeGhdOTykZHcvmykdyFFt/PL/NCEJ+BLZNDMtPSH1d8VnodU86TTay8mKUTSC73KkElUbTiZwtiObYIQAPgo+TAdvW2as7FaMCnVtx6lohB0kI6VKycVNb6X4OBWWZuFwZ5Mb/9tR0Z1Ls7f/gw8nY1uWiL7mCWlWZExOu81eu92YXQ9ow+EkCtVJLRQTbRROeEQYyRFiacx2NMAD8aehY6u/RdScmdUODSeb3Pnj2JZG/wUvbDYb7U6z05gP/GjDk5NOq1vvzR+0XvCVjWar3m/XG21pKEjrevpKdDG45dJ5BrckTOrfLNRjyaTQdP1QyvnJZmqqoMeo8eGUgLYPavy0XNw9dEkBAo4CfA++T0sK1W0F/njFBKPl8XiKkIiHz4WNzvX+Rjt13zmMbWKn/miDkv+RrCDNRqN33Ok1GifdmSRTQgzgDwL8tAEK7vkuLwW84ppmoIHXc8Df2cKugjOMWe1lsLZPpHUc/+W3tlNbIIxXIMg6vh3C4upNnZDRUPBBUBtzZQrM0FArOndLtjjwtHw+79I9fReYSCZTLBYcd6+070MkLul4/PJJuPb/fXh9utdbQCMelzQCguj6CYQHy5eIvz7wv9o0Gg7Q/46IXlErNKcqDqHEqlRydkbLWJqq7pm5ilPMZazDw6R7sxM2wlTDf//8dWHwff7N/LX3n0iOxM/GB3sPfr17702Xl9/nrC6s1+81Z7Wgo9F0SLRgGEw1oU4DMT2ljlsqscNs3uVmhVnZPQuOs0Ncy6EQtVUsK44RrsQZddDt5gte2Dtp1esnrRe0Oqi2nRe8ECjjSavXPpk/aXRBuVvAhlut5P8U590a8CWky0g7Kb24A53IXlra5pm9XtJBtOE/KNHBpb1O6CAZK8svYFBT1EHeUEv3VXxGeI5WORM4P9bmbjUAvY4vp23O5W8BQJ+0Ol2wXydz6wWPvrLdPmnUwYwubRwc5Va9t/g/JXcS8E2k+xTXw/fsnehXwgOMJ9ZvvN4Bz8ap89Cv907qs+g9/S2QSXSDmRxLu5CNBZ6FdWnwFQS8Wo2734H5l/ytYe+5L1Cvnr54kYJA5zRzWEuRohN7eyqbIjusMalNRDSZkGkUTQdaOB0LCElEnLwPjnzh+aJaFVVsfwWGUMW5tDe7Br7ARMfTZeXpNz2xXqP28SekSuDY1DXrrXYjsdbTMZlMa6oyGMfFm8oAG7EYZhywP9FnDk4yxq5eiFJs6vkeKbLSZhiJtb7wbfa3LWAsT9QnnpAKcUDsbZz61mo15pObotpgzLWaCg50Gmo8KmHu18O2PhwILJDl41gRDB0dx8fZb66z9UhdZKDjAsRrN4D4xSekio/Y/7e73Xp7Xmm3IggyxowPzqGBiCqITxT2VuN1cOCCrfCw68e9N+mg5KYEXdRqIgVd2benmkoStxVnIebvPo1qZDSB01WzFEuDqF2xCafE9QpVLnxXhzMVCBMiXj2f7o1pdM8aJxu91oWKst/xxHpiCy3Xj6SqmSUrFR8jgIBIRtiQUbIKKqWmi/fYgRX4ru8HOk4awHmOELmAcOTEVqNxlm4jO3cx89nVZeHNuzZo+PPw7OU7ch1RG5hwpzObM72CQiE1VSu4zHGZV3YhdufCdDXf9kq6bjia4trMrqSqUHtnzb7kNXrbM3S3c7ISebxHUo8EyJ+shAit40693enP26nJOFicqbGiTKYa88BpEixgxiEQ3IffAoglj3hwVPXhD2B1t/TDXXg2x6el7361fghl9PHUZaksDzKOJoQLEk2jcBgqoTJwBQfPIXRq+VbOCVxR5ryKlUOgL3g5ogcK2QxDlsaFLO4vLmAstQMN2AdSwYpsrFZBjEuqbeq5EssVgMj5hq25AfMpNib7ICVhglPZXnpzIWOVyOLjG2SBHnFRT7vm/SBshhB6qg0VTdFqypRElg9GCVt1qzMRiHgWFf7CCfPgToL08KO75P2uPXRtIYtPbJAFesT3SrJIez/p/ac8JGF0CkqsuK6gvu97Lk4DA0/uwqtjEY4QLrCr7dsiLuT9Esfx7zbYqa97Mj0apXcMsXkHCO1ML0aRqI0mkUZGJBoQPhrbjkEdsFOGsPN7nqAV6hUgTrhCVV0lrGQZeinVE966Js0QulAjtXyq/kQSRyAZr7enymllQzWNJgLM7Ri41WjKJ1pESqaiOJkKsR3Xxk5dalOHYkoDwh1aYQ5z3S0aftcM1d9usLff/WR6SHbnuH3SbnXbcxjxq6vTQRRFNW0caQOGs5dxsg7HrQpHviuO4hzd4ZFhg4qLkkWubIVxsULHz0lnaFXH8axNU8VD8rmKSDQeg/MjcSmXUptEnnB9nIWCIx6MgOl5K6dVq34JE/BIFX033aDfCZv1u3+uXvPkukB+48lUMVevCQJptvpzJPjuKq4eiWrROBorIuKAIa4G5shDAmxfwF4enDiALRnVgN2/tZrrIvNEzpae4/VPPrpWefoHT6Y3RnSPm/1evdufZ+NrClEh6gPBKGptGkae7pTcguPkbMehl13FoQWad65k8lqhUnSMfCmfV7ZaqwsVbX5aUoRVHUeFeWvqvlBWjhQAMVEFuWIaBYeAIuedPCi4YxNn1pZPCWi7TQhl23X8YsqRpBzf/+T6AKf/G55NJR1vHsN31p9P2qlFkTIeTJRxLRopYgr+w8XbAw/nBWHQWg0qvl914oEoOIgRWxlseyuKizT3LE/Ur244Ufc/9ejuz6ZOVKPZaHZb8w5dbRiNNQV5CMEaQZw+Z1oV3bbtrOPYbjHnqnbedQtFJc+4RVnBoJmbn6iLtij9xoYThRov3d6uaPcoUkLw4kBssV4zUiecuhbFShPhERejPSYYjyeEYWAOPz3b3dpLcpemBX1ug5HqPiVpdxz/tcH3tfqzTqulEMY1AWiUKYNwj+P9FBB0p2rOBlqD+0CKbmFmJGDbJ+hdrNPqtySDtFqagYbrzalLT9lIyQCUmlablsp6xuDc0XhGL2RpUAyKvl+MEwyi5HuGb3rWvTFSn5M0eXX+FGr8D6faxSTt1mqRBgo+UHG9kCpUTTULtlvK0z0Cn0Ju1zUsohOcHGLbBybVcOJZahL0tWYj7G/U8HN1iyWn6j8+uU4O3wKn6tmUneq2T7r9xuxUDaJwBCrOBe4YUjkPucE8R6eFQjZjm3aGMt32LKOs6cxgFc0gJaPgbklTJTDOfaqS8obqU+uGKnoqXerfgVNV77Xrs0T4ZKJGkxqoNwk1QcREOTU013FKQAXdA49S6oLrYArwQZo1WD7LTSXrpHIK4V3KKcgH6/6n1rUDjfD3pfsuJIMrAAYHGNocxuj0sk9wKL8XKI5t8MD2dz2QCHApM17N5cclAfJwh+71dKt3d+vJuo1W489KpmnV6n5O1vM1czWewnGa1Lg2BX4YcKBVeaJkytnDQ6LlNJIlOt1z8FJXtUmZOBqxsO5PgtK91lzPVl2YHA6eWp+F8Cw8e0+KHHbaJ51WY179I0EItdGoVuNlSgKcdRRw14xn0ATloFo1LIdZThY8S+1WQ5XPOfvv6gLGK59adx+/8lSa4zaArTdPGr35VrTF62NgDgxrxHHmcIBDuQMO4bfPZwwX2yy9uN14JQl617Ijy/Fmr3pq3V599ilpZsjMmTdbJ815LRYhkaYMp+DKo2k0GkMEBa7cdSjuIPEcTxjct3zw6GXhudyjVq5SOUjPbmpda2505xc6Vq/bII9PPCVd1cQ3V+0GJnpmZSeSIMZAebXhlCP5iOtMcHAL7tkLAt2PB0P7R4zYhTLd3jh9sR1iCYxv32B4/xiePZkyvEDXe636LFu1gmI6LRnMwS2UDlX3XTC8jB4qOnEJy+R5Jqce5Ap5eXZ6q36tfdfsbgLjLU+tx7LoGr853f8tuUE4TApufBqFRJsoyiiKbO4yYQvMqwurSn1R9XWOiU+/nCub8a7Q7VNwz+sGrz740EtGyz1DT60P//uP8OynJWngpLl6o92c1zmMR7gQIYrUaDodDSY3DByS7nGPCUEpTro2gsA0A9/XTCtHyrqnmFu51UWunBYEcbrhRP37FVfeBlHgTevMBa5imJR0vDfDySC+H7u8IL568oG1mxzOGY4mvrc3TtEGP44c5d2pKw6Zj6xAILVTjwYQscY1yMDTCSCJK+QCHRM98E/c2j7b4ULbQH9b8nKr3evoDX80PWV17vl+Dv7Xj18C+Y3g9dRaKLBMfwKkJCxlzXy2tFcmyt5lk5CDvUoZCJaj5lnOM6ntHVDDSgolrrexeb230f9dqHn9YxscR+np9P7i/nGr1Wh067O8wjh5fwLEndeG0xBsFE6DdvIKx3tZLiqEuy7jtss8y3YJMN5bNFKeOyJPYPzKBlqFrv1dqUsO2Y2P+IBPFWDsQp2Ohup0zE3L8B0Cvs5zi5wz5mNciyoPf9YZo45Dt4++vdglRwLjExtgoEf8kVTdhuz9llKojVQC3ETR8kapYmq27niu57BSPECSa4yZONHXdV2HbMmP3DXv99kNbgMZSnrVrMxGllKYEDImg/HE1xTPNVXfj1c8xGuLMe3pYwYUb5qxkuEepRaSZNUXnlovG/m/nko3ePWOe512/aQXG6uUHKY1wm94BiBgtq8II9DBmSu4t4Jyw9aJVtQqulrZS4++ra85jvOuGEhs7h9vsLlIT16bsrkyFcGvX4smU63GB2okIuWGyUyHFzRL8BJ1meM5qovX/LyM86FxHu5N5ulcyOZ+VvraV+/GUTxyA05KFPDlj6JaOJgQXpvUxmRYKuSzWTVzmC/ni8VDZa+QLRwcKpmCkjMKjm3ZzkEhdTd+cq3Rvr5ZGneeWXjpQhr/foM0piseMO3G06KYjkY3GOZ0QCPw9s/HCb7x0i9PBPH9nxekI9m76MYX2ZENJP0BcBrvTEcb/W4f/puzmxoZwDSqTTR8aS9ejhDwuMMgKOA/zAbr8Or93pF/r1KHn5RgrA6aQqr4ltShkmnhKgowrsCeHB8bhyDqcHi8Zx07ojCfgEBuIooL0cIEw/+zgdp+F4jiv5NsVAtEUe8nAwRWBeEZWGpEOaNYyAMW1nR9ptACFSqlRY/mSvbhVgwXWlac6MR/2UBt3/h0ejQTWKj2SaPb6s11Yq7VELpOIo78vAzuQsB37u55pXKFMS8b6CahbokbjmrnC2z7aKa7wgqRNK36vI89lV7nnSZS8NrTcThWtNpQGQltrJDa/Y7NA+r5R/FaiqAqvCpoRpX7BlDceGVWKtfWDBupGeM3Gzh86xyVpODO0+us8M3w7O0SKzw5brYb4MFb851+CGMYwwhHmqaqNgVXwSqcaizubCaceFgv6lLXdEsmNU2ruJWHbB1IOLw6HN5qR8UChrcBxpuelrZgxxfjzVavXm8nCek0iIgQk3qVUtmqKA51DNVwikVFL+YzJvwoZlRS3C9t2Zh11y7Gv3YDjH8Ez35uR65U6Jw0IQ6f9wrCi0fD6YCMalEICsLHuC6EOy5e5+se0FkTW4qwSdAlLtc9x7D0rRU8F1z8lcB44Ol1cosm+MfTrFD2GqMhn+JdU22iEiUimkpcHJjBcTOsjt04An7i0BZchsdwljUI6R55jcRavfTppfNbUJGn06unWse9Lvw151MLIZDxGGfJkdN4eZ+P9Z9BvM/B57gSz+cmx9VaPrf97XsdLnCmhgsQr9gA4rPw7B+kTG6n0eq0W7NAXJaCpoTT8AabIfARQYwkwCV4mPLkcQekTbcPAdpucm+5gOaBZe52g1784tOpCp5ZmNFCZhtnp9JyGJLIslyHGRwXnvB4sAkQWrzCxFEMwHENx7w3+07CwUIW159ed3+ffFqqe4kvN3qNeqvVmxV+rqG4YTDPhZePSQdOXIPfHMxVucJhfsVhlG53f+eN+QZnw+GCoL/u6XVK+Kl0HqFXPwZD2+l22vMqw8XrRwLMLTB1LHiZNdFC1Af+zprtZhKcBqLsXSkEdopNyaOR8V9/oQR0Io03Pr1O0JGgfG86XJLISArGcEK0U8fH6mfOYnoLhJbGnQPI2nHzlMAFhfeGjCSsEBngKrNFpvidqXkFEitcQTCaxJvUgZb7HiDRsI05sGbvj3l0D1totzPbC7HCRLvftIFQoUN/NFXVJjvvVQy1yPeqVX6EZSJHQdXHrQeYeMaV1VUsSKI4C/MeOO9rDy0vmN68AQbSq7+X7syWqBTY1iia8Kk24uMhMPVo6LPArZoQZAuu+NRHUuhVsbWWB8yL9y1692q286KleYOR+tjT0mzh2Ei1Gt1Ooz0fdpOCEGkTXGrvOi7xLV6xXM+nWHbE8GqDslzJMgslh5zDSD1w+0MX3olq0UqD+K/w7OkV193q12fT+1YQ1GqnBmYEcQ8WqLGtO6AQ1M/71CyJEnVKWdtWtjdtpAb23OkMj+Q8ffDp5dSh5Dz95UrC9gQznf2Ten0+DnJExqNIjIeD6Xg8VhWNz+Zzwi+8GsOOE62UE1Uj3t5p434pbtz8PJ0TxXI4zOMI4yvSvnv3mUd3/+5CFFgJ3aifNPut2WThSIsmNW0IYIjC+YhwYXg2xt1x1ZHBLNd3DMPxDVMzM24O4gvDzuzL1bfdsC/NvEuqoRUpWPqK8/DaX9yg4UhNpqvZzgUNSeQwnqiaOgaeHlEaV3birZgPHo/jDiYUDfIq5CNY73aPC6n+0QYYGHn8nfRiKSnKWEMB5BVtK3gNHaNWOFcWjzfDwoFDHPFYpXsSZSyZ7cc2+G80Xs+mSkVkQxUfKAUOFA9r2mhYm5SY63GO4/ooLp3waDz1Gdcke3jvJHz7JlmdC2TQzxYgPrkBBNLEt6ZAyJQweXdFJVzh0Ti6gZWQwsaKhHjseTBLnMfk0PfjfPo9AHH1weXWok9tiPeQJkoZkRVKuIohqlk67vmA4NUCLRAYshImcO0dB3quQyxoO9vpef2ueL7PSjASWWD49KYUIZRDpZkuKByBQBw+mZRKRcfVHGKhv3PdgDlu4NsB/HBBGMK7aePJhQhhAuILG0BgIPvGFCFMBa1pQXB+w2EFA4ShCnB1PoYV8O4u5px93ASNYdN2EHeFEf7Bhnjvz+HZi1I+o9Vr93Ddx6wGevn+0WQahsKgtudi66gdj6zyK/EodC+o+JYbBAVTK2ybfn7h3tEExv++AUYDXN8PpD14r9VerOCGMwRHqTbUVD5URrVwXKGW7TCiQ9THXeBSolLhiunluZYvWLrl0LJxjuTabcFIjtS/fTopAFuSqVc8kw5be8ddnEuyrC1MgZiU4oHOriNmTaQW1QwcHmFkaKZQsooHpQNlOyO8yO7XhSz+fIPTw2P26VRDlnyk4lOkhdpkSgjXRiOOPScMF6HHfSc04L6If8XUKk6N+N69aMiSYfzlghQuTe0H06Z2hRTOBIAFYBofjqYQLO3bpgGkybNMS2R9r6KVGQV/7nsFFwyUi8NjkhzCwc1JYeFOSWHCz//rgp8v3R5y9m9dsVILfi5JQRsCRRc3uC58Ezt3fQti7wpmEYKZ956t/5gN47rDgZq3hnC2WIJz3zPJ7InSTZbggNcDhzEbo5ECgPpxShUeOFdYDnsaWBVe3gmqHkO2bmNTkAEecDaN5A2ZDetLXnpnMyOSM4Tse8bIl6qALP0dKVWQGbl8ekAthjXcxccodwhmDbAWBG/FnLhXI54hFgti/vVf2awK8oaMO2LjX5y/cuWZ9e1p75EDi5jGNtt1nJi0GGMygzAECOEwVLXaaGKbJnWKLnfg687kKXWFsVdQvUoxWzh0me6QfHF1GX2jFcLf65tSL1yNTp5ZT6714Fm4s7zH6OKUupPuvMd9dpAGk0AbKspgGgFtwukCnqhamuCuqPqe5uCwQCxnKx5Rh6k2NbemQi7ScLKE0Xhm3diiM/zJtJWSHB8Kgk/FZBLVBiAf4CTABwNONU9kPMsOKq6Py8JFXHbrVyzkvP72e4yLOb4vSt/87IQtjS1K6DdTkzgSaSxm7QkyqNVqkyFKZjqYDrR8/qBilnYP1dxhLmNmDy8bZT2XcXKWk9eJxhyHLqEkJ6xzvdE5a20UzZ2esIde/IqrC2f+Nc+s3wf83DPS6NnZKKh6p9mZZwxTUhmA+brh+QxjjXgngD/7LTBM38arGc9iTGHb20/uSnf12QY1+cgz0gLb2R73brPZb847L2UAUW06GLkMKC1OYBaBw1yfWQEvOKpjaHaxVDRJztqtZO9R08bibuaZpL5w6QX/7UrwtyRWCLQEUIbDYJiAmEQhTmq9AgzxcrwIzmRMaL5jgBxwpxSIhmOc7sWjxRpnzd5GYnWOGUwLWXzPBln8h2ekVNusz6HR7re7J/PgD9x2CCxdTDiuFR4jsaqKAJyKMEHDeXAEmo49Wdw/ck0aHPHyPW/L+v4NevEHz0j9irMSkW6v1+nN4iZ1EBA8VoLUogHRROR5hul5logLQ4L4b4YFbRY3nAAvmgL7HpUOJ3Ol37MwWEu7i27yHanMTuISE4MlQaiJMcrjkmYx7viaGTiUVPO6hnd9vlGwObASCAhpYKxuRE7PB73IoqLhoqkpglcvrcRPf/WMdHcZH61W3AoUZ9tmEBSEUBvBj0meWrtahTg5zco5TlbfJUZlT8tcsTOZrFXYz+YO86nJ+G15zeuFO2iSs/Vzz6zH5GiHf0zS87TNnYlhhkGAokQ3DivFjLpbvJIv6Hla2LU8hzLFLZuma7m2RWjuJjH5hWzu70r2ddUZoh1+55flDoHE5iZnS6uJGuhIRKKpooVTMZ3kD4q5/UwulzUO8uVKRi8cahopO1nDtMsWKdKyuUSyfrYubHsTs/WZDWbLe/bR3fdKZ6uHky0a3f7MhYA4xDQk0Qh4lVpTyERjM6oLtouSIL5tch2cRgDWq4otBJ5wty+qvTvx4OefWU8xNJ9dHaXQPOk36u1ZHfF0Uhsq0XQ8EIoYKxEfEhK3hlcIsRzHKZWpUXEy1Dw0zGLWKGfsQm6/lLtH3eLJpfJvb5CGCzB+aEe+VO6cNHr9+fzWVRS1kHOM/PCmLxAujxt7bc6rrpuDIJH6ypWj9ASeprT/+MKXyovM1QZVR9fyw+lKQ8mNwHlS5+cpnJIRn9xQCHW4kimpprVrgEiskq171DVxUIdt2g7RZFXvyiORZEdynlLiRB5/9sx6z9+LQB5vSx+rzkk/2bOA4flkHIZRNFYjJVJJjZWxA6KMm31cbuoGTuUQum8fCdASQW3fNuUr2fa1VmPtYG0atTU4Hd5y5etCHv/hmfXUNDKWb5Ws1go7mU5IDUxSFCm1MRnzyZRYim2bFTvvMOpSG2urLMsyXMuyXUd3LMMR26cp3B128lcLT7h07Ogd35SCsfSEy5fnSijGw7HiCOEAM8dakapDKbPgQRm7nLhrAvWC6NfbfkG+FcTwwdHNEQyuLi/ID59dt1Xf+Wy646933IP/4MnJTBbS+xPOa5wPbZdik6LuVWwN7KvOyxVGiKF7RCcGt11Tpfequi3RDevZ5fjURMXf92w6Hdo5Bntb79V7O99/aSfmMyOFD1R1oqoDMQnEkEee4mTBzuZsWlZNTWd5q7Brslwukzs42L+SzeRzuRKqBW6zrF9rXm+uXRWgcly5NXN/YGXHzUIe7rPruoGGOEpd28hGV5kgBG0wmQ6nIZ+qJDJI3i+4h2B2LUY9xnXuEE8XxMMPcfHS/55c25yFC5bInp0tJ5Dl8aZnpdrPOA/XaHSw2PA/gTiGGMbzMR6nWm1YGwoyFrUbuksdHFZNHasCXIS5TsU4zCiF/Uwht1c63N+3MAXXPmt0rrVCuSM22SR8m+JYO1cJwfKeXSdYyFIm6e2ic0ayGOU60wsAMhqqJORRlMvr2WImm81q2YxpK9kDYht23nK0SkW1dOqYjK9mG9IE6wJqEi5PV1XS9kQsPwXPfjKlJr1GDzRlPucijWMYnhrMccDrGTYjnktInhGNwadYLJmunlMre8XUMJ5NSnLRxtjms+upLCRd6XE8MsFKVGMKRFHVwB1OqGGrh6xieyonrCqE4UBMK3RwiNV47ysYsnu1lDNZxPuihdFaHi508u9Pw5g79HaSahBkNB0FoqZFE3UA0brYz2bze/m9bPHKfm7XyeNYeSunVA5Le5eVTMHZpXsFLc41dMJWWD/rhM3rJxu9+t5FehkfeXadLuLZ+qYduR600QGv3pyX4E+Au9cm0+kk4jUQDjgWrNgDxujioEb427d8jvUY/MjzXQjdPXq0JU164UKMxJP8txtg/P6zqWH7WE/SPuklMYj0/mSijMKImEwEGhbwBabOmXYZl9A7quXvMkoLFWqVck4qMGxea20Eci7WmwD5zg1Kgt7+R1J5B9mzj0bBRB2DltfCiGtTbTzFUgytIgIncD3mCqdquSgWz81jmRLerqUqSjrXW3dxENqnJL+hrGyJQf/yqETfF74kzp2kxDEi4Y1djEMynGh+AJSX4LDluKGDxR1EOKNALtBdXTnU3MZ6bwdFwhbf9+z6rhtkLW9NFTIkDGVWGRNGtWhSGw81RRkqw1rp0LNANfz9A98m2HvNDUxouTSYJXw9m9+izeaiF7Y/tYEt/sWz0r66+A6h12n12v352BEZAG5BH9suXp4zi2J/LM9Z3OI6BO2UCctgLF86Ita9ukNYh7E0vGi+nk/VjMmmah2G5dqukaM4mtGLh2/5Bu61wZ2iHl7DUXpvStelI/VTkoYv+vnh2Q+kjlTKm6/CuOEKSqlO4yX0OF0di1mDeG0S5qmxj+4eFUsnsvjQhiN16bm0va0ft046II5kgpgWaoMxD7UIgJDpeGTZ2OxkGx5zQASm4MziJl65UThiniJARNvdxt2pU3psA7P6ODzrpAOQk5Nmd17is4biBi531TnWdvvCZaAkNlYpUeZmTSvrKErZ3l7dul0WV28Vly97IT6+4UAhsN9N2ygJxBhQRCMtmg4gtBUjJTxlaE29uMANHYTAO6l4xBPefoh7eKASEL++QRJX4EC9aUe+NGg0myf13nyTxvL1Qx4OVBz+gnfnuF0Xly7g/YGIc4mMU5tCuOu49+jS4PfmL/wJKZ5NtOKrnpOazuLy+2633Wp2O8uVPzMcUYwDh7MKkikXlYquls1ypbx7cDkLrPAwVy4cZg/2rEz2MLd/uJ/cbravNRrXmmeNa6kbztYFwqjTRV1GjKd6q7qMdreFW1bmHU9pmRCPUs50K6iyqu85cJaqYK8Y/GSBh0O9sVhmq1AWdRm3W1CSmKff3GCe+HNSwfcsydNtdk8688v/IQhgEow1TdU0XgsnnLiU2DhUC+cJlS2rbKiG5bjEUh2FsnyhkjfUc+Sqwtv4/hfVoBtYLQMYN9JWto/rAuf3NulvXygD5FBY2sO57ftBOe40Aw1nDo4AZYWqze/fPob8YlY2SSt8foNuV2UYszmNrX49qVFaSCJASWg1XgLO5LoES2SEwGpEX5QrnDPHZhZTLELtsoyicRI2NhfnnieATdIKv78hrYCBxw+mCEgSZCRphZQ0JooWafliybItw1IcUjHdQ6toZ1m5xPxsBXw65WXgKOrN7gTvUvH6P9+gJOFz6Smg7eMOLtOcJ60WugESATIVhorBXIr9sSazPIpTUhg1DnHBuWvqhOqOSbzt180XmauwhPGHG2C86LnV0K/T6zdaySLjNIZIjRzqcDeePICDWFm8d4ADDCCGtOK5JmVsi65fTBoDqapyAwwKMK5LJL1/3Gs3uo1Gd97coSlkXIuiMZDDcDjhkX2ggTjKwKgosBEXPzjZt3JoW7qtgnukRNlK0i+WXk9g/MWG+BUZ79tS9UrpWGMJIJrip0qy5aypBdgrG3BeBa/uVoMqdt/ECwVxhsedxxq3MLzhcPDAcAEDuewqjA+tqHqa3wIAbSRwdx9+BpoyDvzq/dWjo4ALE969ynwf+zpwLE/cS4QTELf3p9wdfnvluXVqiEzrH6Tu0FKsSpIDbh3QTrECg2M5ZYCtEDg3zMdZHSyuWEKmdZOmxvOzqsHyssN4bt0LvhCenaScebvTPWnPR+TOBTAM4QfRlMlwyhxORBl7anBJuXBNDxtMmYfcEH7kDDO7ZaT6hS+ePi0p8+qRQqX/pdSwC1nBVzBo07Gr338Eyn2EfU6zVRbAorAh0/ZmJfkQidxjBWfPrUfhyFNupDVD4iRrKEbErhhEAavqCpvhsDDchVQhZtwvxHywu/b2iQQX04wEBt8gDWSN705fA0oMcQ1FjXra0f1+lX1FNe7e94/ghzCxmRxLsESVp1cg3YvbzOoGBf+8LI01arUKYliCrzteN4BOD61SvKot/gu4OTZee/ekc2uZ8/xKScETEDfg2Q/upAvGsMq1Nx/TKCOYDskNO475gBziLjO77GmuTXEppeYT5Yp12VBM+UQ1+2EjbK9ZqvMVHS+3Ub1wg26g9fp8+opcslQpHHhVPqG5rKFSg2glx3GBUuFqEXh5x3IY/KW6BvPu1RV5AgND1tX1YBgK/h0JxjKMjZttVlFo1K76nJYs4YPn9n1HqwonVgqBXeQu7ra4RRf5ObOeS7refG69qv1X4dlHJUbVPW6060AM64toPCTBKByNNOxZCaOIh6GNU3mI45ouzwmGK7YMp1JSK55mKpp2WHSLpHgzun6XBgS+aIPF+sO16EPmuZI4sH+I8wEoyf0BXtQERxyvBLAhvorbX+LdjIG4WVP8XYo6wg0wMBKRh3mno45VENoIG8ir/hG7n4m48bdaPapCTIhjCuAJR8u7/XDdnahj8Nw6XX/yOWmZ4aw+9KRTT2aSLw+U0AaqxodjTKjbLnM9F2InigN5eLz9l7qYkK54nOjbZ4DenaK3l2/gVr/+nDzlN25g6XTr9f68kGT5/gJ+TBWC87pxsGEgYhKCQyK46zNs94f/qRg44p71ci3Kvzd4kH8lq/rMg9TbzcVyrcVhUvFHqNyIdx1h1ziIwBU8Hv0Eqk4F7ocgfsG6yYzcuzKt+IbkPRIQ6Bp/YqXgbekGp2M1CIcEgsCAD6ZTRb1BSOEwc5A9yDJiWcQ1HcM2VNNh4EDgY1qWs31D2EUqjRcH6h9u0Is/fU4qd4vpYbtfbzSaJ/PGfnjxiRaMSHyHScYj+KZjpfBmU6pMmoWoPINzWJnAu39KtrXd3DV6+OQGK4Uq/97UNays3jU+GI4neH+pRFo0HUXT+zm/n+NsQ7SruL0Jh08G+BPtbHxrc47G/tva2J7A+McLT75U7294/tHd30ileLodYA69+Szy5ftHo7EGbhBVoupgW5oPdkowFZfRK5wZnFm2UrIAYv7mxnaTJ3/g6q2BLO6S/4fnkrvkJYxXA4xfS1mpbrPZm/ORNRC4XnXWyI/NW77N8NuP14VxUcKG4KqT33KmEiN1bj6SCONXN5wp5CjfmBpUnPCRmB2OomE84V4JR7UB52FkY4iB09/j7WCMB2a8vgnzJGbsvm82LOLu8JBf30By0Y0sJ4CuuoxVEEOFObYeFMoB5dwIFHhn3PkJ7hA4IkTkaHy9LcNUbuYybjkGDWH85vyVP/Pceu0he17axTHbxwjxXw/HRl/a2fkv8L8ADD6DMR5Mh9No7BmOXbKcjFuybCd36JYzpVJu79DIZLO7u9nKwWG2gLWH3bCR2vCy0ItLd34/s8x8bnDeX/m8FDfF2t2s97ud+XprjUxDbTRWwHkDGwGvh4X33BMU4lcXLwaC+32hw0miriVUz+EWOPHtoxrbF2pxTPzev9rg914h68Wa88YjNIwUVRsRoIZTRTk1XKUM3s62qEMcpwKGynSoA0yK+a7jAMSbDIu4kPNOTNQfPbe+pO1Fz6eXtHWP++2TTmNWm7CCAJwHo0CfKI6twaE2LveF78atEGB/8dbMdG5SV3x3dPtPN5go9OjvTyV3ZO8tA4h1PAKzSqoOD47iGKOKE1lt3OI7Y4Y3N1EX8d7Xri0ivz/fEPmhv1gUTMbeu91vdfrzqh2M/FaBTDRc7EmZBv4hVhNkIoptqcTQCgVPdchB6ZJ908jv7pD0y8+vc6oyPGvtyPU7jX6rAdHfLGQaQ8DEQy0Mh9p4pJBoaufztAi+mxYVbrFCpZKjFaqrul62ILo1SYWQrTslL1i/k0gl+/y6VL77+dRtJpa2tVtAR5bxeBqGiBTFxusY1/Ac1zM5NXHyZDzcRtEdniVO2VC80r2SSrjMWpWfX9cVlNTvp246ZKmE4VSCgT5RHFVZ0T/yIZb1yxkGJNF292mVBWUjYJQRz0rpSqqxQ5bL6q3m2QO3HF28nP6EXm+1xg29449K9nfpCeP0mwQhVEIyulFQtAo1XE6YYTug44cMlycQLx7tbQiN2bcYr34+dnV1MRvtK59fZyV/KAdPa74QXn86f/1IC0dKpO7lsnulfOHKgaJSt1R0KwWjBFET7i+FM7frMNeWU2+9683mWWejPzzX5ILElaDbWN0IiO5F3giYciUzADxSp0QdjbEtW3ep5ZolZ889tHXVtTXHzBgOyZddyvYILije1vF/YVeSaPtgg7Z/4Pl031P/uN1s1zutZS3MeKhNIJwNx0GkCY0PFA56rjh5y3ErFi1RwzxwnKKt24qtGqpTJHsFc1/Zru13LdE+kGxwoiS//Hx63nrrGP9z9WZ/PtFqBYpnYK6He+VZEBIUfOpZVNXd/bxt7ZfsfKm8fXLPhYZBJTJ59UIm0hXUc1LpYcovJgUMC1FoKp+tYy1c4er9PA98xMGxexQjWe7OVqrj754U2d5tC3w22PmCBAfDwsuSomCo+EAqEpmHhYjmBrD4fwK/B9MlIqWmgIvZOywfwuEqauBKID5kgRVQS/eF6cQTsx3Po8Zir5DU2CwHh7dJ5V/2Klk0iTf5hufXuwowej9L2a8kUsdWqH+BzlFTNB5KOJRiyT68sq9kCkzfNcxDx9XIlbytk33TqaikwqjDjLj5pn7WOWs0Nsbqt7UcafTgZkX55g2K8sfw7COSojTALda7/cZM78FecVUJxWxRLomUGwZzTWpbWLFH8f6DudTGHTyua1sWMJaSvX3P712ZivHtG0B85vn0CIPuMZzjfq87azOXtCMak1FteMPwKN6oMea5wsZMQ0B91/WpzxXmU4fbB6mhGK3rDRnGuQuWziQYb9hAHNEGvzKVN2nXW/1ec5Y4SclhOplGUwMEARCY7YPxYo5mwx9d17JYmfJc1halTHbLRtYLZ3cTs/XdG8wWkskbKbOVEMfEbKXEMYpGCtdzOlYhHgVcq8abi6vxNfosL4e3neLemS2A8xvzV/+e59czDz8Bz05TGoJzJdqd/qLrUZbKKBqr5IaBVRkQWVHwJr7jV2ggmF7x2IFh7R/mrIy9v4vmqrWmHatc63bzDomt+r7n1/MOX1yJdTvxqirw7fMSgOWBglePRhBQ0QCnv2FFD+bh+NERXiPkeLaqaN6uAY4/lamuX0s59Ys0pC1t1U9sYL4onU+mpkkkkogPFRmN+LAW8VEUqhG4kJIbMN0LmBkEjPm+ixUZIvDjHabx70JsZ74bpXFbKMJwoeQ/jSCO09L42+elxeqz3tM+CGNeyZBGACHJAKfNYuU3iiNeyxpH7hxr4pyqz00kLDeP2Q8lrTg+T5D7gQ3hFJKu96fvzud8MT5UAwjRo6mCi5GUkTatjUXREgoudAqqXhVsr6h6OLvcg3/A/kDcT749mXV37s43wUAz/LEUJ5FN7joMcBNgmngAr1yNF1VVMU+Ng4C9eG+jCMS9Ho741PPrFweVj6zeC3Y77W6nNytWWr4+/mlA1Bru23JtjjfmgimX8XgZSA4rPFPRi6xQzha3HKq7lnL/6PNJAfsSxt5HpJTDbOxYr18H3zGLClEdIlQMjY/FGHwIw+5GTMIJcBX4C05WlaFMBD/iWNh3q7TcjiSNIIFxG/c4Czv1y9Kh8iXdkPcrpIOPpRTAo5NpqJZYEVW7DGYK/8YBujhcJd6KFjei3Wzr1gWCD6kmf4PX+DN49tLUkWp1seCqNd8aHQsgGiqcqBp48wgvceKL5gAJVTySGcsYcH00Dmiuwv96rybRJrL4zAZZIF384VTFlUwNExEoYx6GGpmOTuNu2bgAtDqrupiN3AxmY+BwU8Q9rrj64oZsyfc9n04xpD04vH44f/3REFiVquQrRlHL7uc0VmGagZey1HbijZ82c+yyplM3tVH9enO9ffl8HjxcSuN/Xij4kkuFoOA/I3GpznGj3eh3OvOh3/OjNJxOgVEpXCkZLlZXUQcvzNUyxEglqlKqq7abKxWZVbaK6lZpdFb1+zxNpn+84UhhGPVIiobIIdPy7ZWxohBl6AED9ALHc+APnj+fV578JlxctncLGnLRkOnPNhwpVPlfTk8FltQ7PkXw8oBBG0yHwXRkzd8db8lxHWAwg+B5zGaMGdieeY5rwdtAsYw1/nbOpuQ4HBnW96UneczZ1GJ0hDKsDQej4XQwwUGoykQoOdPRdbNALZa3HDS2gAEsro3xIPZMmCSp7SEbezxSrOrwTllVAucK6IKaTWfhvguevU8ih81j5FT9+VD8eLIrCmNY43wwHRPBB2rNoqZKDebZjGOzpg0OseK7RdPkjmvlrbLKKgWAcx/AMbe3rCSKsgNwsrc/bnd5yNB3q0H6kH1UjgTX/PkakqnpHJASZnUN3cibhNoGmCvLMVXFYbZzSDQWzyBCKC+5uT9HGNXzwMggjK9Ku8J3yOwqTvbgdPzmfEX8KoihwoRjC0qqQdWqxouX/aqpOGAGdG5UdNc1yaIUXN18cZuZw8gAjK86T18XEsLVnBUSx3QlQEIScQ/iF3FmTBCGwxmQAQIZTIv7eweHeh6cSSFX9qlTKNOKVbhSUHXTNEF9dsseDoxpnuHyxtZGlniOsZtLcZiI4zCdJvkKeNbeke/XWs1+u9mdlbSjhmtcRMNQq4XDYDgc4j5vHKjiMYYr0VwcDOVwJoTlGW6FWLmKiemeo3hwxFkzTE1cOElO1X3zU3V4e6cqPB2MluL4igWMZeiB0H4vPSpYgoFfvjYYDoaEC9zaM9R4wI44Z9gC7EBk7kDUYVZxHReO54sDwzhFYj/SeNvfXN58TyhrR4JjeO02xPE5yX+vRuXo578/3c8s+fQgHA60EALaUGhiPOBqae8+L+vR3Qz1+CFgyXuGZ2rGgWeyeBEX8Ebk7PsA46OXsF/wevt6evZbZ1Ukd6Doi0uplyyQLA/Wp+HZz6cob6PbaDZ782AwmmoqH9Q0iGOno4EiahWXeZ6pezruo3M8VrZ1vaKXdx1dy7K9sl3Zd/Zm5ursn8XpnrATrvvFcyJZJq1e+5FlQLjoJIJnP5JKWvUa9W6zOSdaKhlOFVVMJ5NxDfz8pISDCYDteljZEMRDj3GiB7J5EZdjgQ0DJO/dzE/OZ3Sv3hTA76Ui2viWs9U8aSb73TYBsH0aB+ABB1cogngtFC7fc+EvDKY2AmhfBEBSsPTGj6yH5J9fceX14y7oRavZnjuNEA7QqFZTgSRGHH/FyalZE50fb5HGlg9h+3YgmItVrwLjp+/cnOM5t99L2Mh3LdjI0kIhQ3lXuoF2zkYScpWSAfyaDl2TC6GYGECReIupwFL2oOrPzhF3vUUZe/HWbCQ7ZyO36f+W7R7vWLjxpf9D1/6W1J2N7MYXggB7NYDTNRjm1BKBjwkExIBPmeYObN2gFXCBNtbtkrK7hfKuuvHqHblxqZDhXRsO1r+GZz+atlIYzzZOkqvzFIjBwIv1FxOIsQTg+8djhuldETDb5PyynkwMPZjddjTXbFRhHgwWpDBq9OKHbuk6dn5//tI/Di+tNNJk9999JDUVEY5Xt9Xo1mWuy4cc6FWAA+bHI8EnlmVaZaDr1DM41W16aOp60SjsKYqVKR1ms8Tcy61cEzSRm6wdsJwU3TbOQ7B+GiVjpiXzNx+RUrtxTrRZBxM59x9zJGKGZAz8Cn059YQrTNfNiD1heI7qHeR8Tpli21cgYo+LGi6DK3zLpc1JUVnvzTvR++SE/WPE0U37wRd+9NHdJ3fkC4NG56Tfb8xN11BDaqKGIQlqU1WoIWF5YtgZxzwkumo55LCslPPlyuVyYS+bPTjQC/uHiVTiNRmtsLmWblDmAsFFGd3zJH/+p4+s3wuaH01PMmiBDe53cDFlfMSWGJQwnIbhDYNRV7gkruP1cKej68BPynCyxAGrmGoxfy8Scac7/z845CnKf/8AAB+LCAQAAAAAAP8GAEJDAgCmUbW9C5Ak21ke2HOnX/WuzMqqPJl5Tp48J7P61lpXs/Wu7kA2kzV11SVZAiGNsBBCICQwT0lISELCElNFClIsrMEXr2ClCFZejOG+H6OwHQYjJAFCIILA3l0twQZ2eJfwenEEsOslwvb67v9nVVZl1qOnp2um505PKy/Mza/+1/f/5///85t7e3tF+P3PfvmJA5V9snFt75173vzZK3/liYO/C38+/sY3Nputfr97o9c77bZ63b2bj+ztDVXfJ14jUKXi+4Hvh1MuPEZYVTpCEiklUV3XNeomkS5ntbIpuSiwtzTfee0trXfuvX701k73vLX3xvO3Lv76Pf/172Rf9/p3XnsT/Pn6b3gne8tt/83Db3jrzUt87f3G/KV/FYHUEcgTe+782bfCs8nLL78c/Zfa7W7rxqDV7Lfb/b0mABGepkyHoS+FppGRRgLHtjTKmeMIgwvX48KpudJ1XAeAcGkLKZiexNFboMC/G1HsAYo9QFG/PxR7vzl/4S8sQLxpIY3XwbPvXIBotQY3Wv1Wuz3oRdIYJyUx1ALS2LdrnNekEIaQdl3UJeARnvAcDzA5nuNK6SRQNP0kDvjrYxzX7h/Hzb3Pzl/6txdA9iJpvDz/2ovVCj6x9o32Wac/6DUjaazCUG460qt7jsNPTlzP89y6Kz3penXrUU/WQSIgFnurNNqRJO5DAl9Ye/EnFhJ4Fzz7SCyBZn/QvNFvdVud9swe1l7cpwa1CNFtW1KpgtYIVwghOXzuDndszixOzeSb9xdvjn/5Dnq0tIbf22INP5Cwhu6Ndqd91h60os9/YQVi7E8nGvHu6HluU4tbhsUdwUGnKBWmadoGpZQTqqsXWEN3F2uIZfFHC9+0lMVH4NlH09ZwOui3WmeRLJZvH0g1EA2pqZX9GreomdMdXjA926SGIxywZg7fmIPWHqM4TMsitoXiHEXpfmVxdm32yv8KYewhjJ+JYBzC71fXvu2RvYSLPb3R6rXbZ632zKj9SRKDDIJCOXNYOKSZci6bPcwYlYKWy5MjlqOUUE6JwqlKAMYRCuMt/ltPH3tlq9ts90/Pur3HOv3XP9b+mrfAo0671+p3zvrzR+3HXtFGWZ31BoP5o1b/sVd0ms1ep99sxo+aj72i3+x2Ot12O340eOwVrXar1zztx49QBXq32qdp134aq8Ejb5qZ4xsv8eH5w9Fr9744l/f/AR+e0kp7xB+HZz+SsMf2jX6n1W/2Z+aoKNPxUDSG6lQMG6OhooJLt/YrFrFkRXEtWa+C7wCvXhcWOEX48jwp5ipQABTd804raZBtxJCfO8Q8KEHrfpTg1+bv/BeoBCXE8ZqFQeKzpENs3eif9frts5lDTELQNOGpdxxGXO54GufUsxzuWoZDvZqo0hwzLcc4psRKqvL28FS6D2P8wSQA0OK9vY9fAkAjlI3GUIwbcjqeglGKss60R3K0rBBwfod5pVLMM8Kzx0fHeVU/LJcyx4qSet3fnv83/j/87xppJ/B34dl7YgWIrKfdhP+feUj0GyN//pFNxXQqFKWQUUv7h7lcRTeJfZBXiFYskBzbZxatggGZlmWThCtr3UJN3qrHBuiAcclP0L91Ptz79flrZ39l5s8e2fsfF1DeAc8+svgII3/WPGsNTgd7fw7u4zb8Gx8IV0OShlTmX6FucRveWKAD0wyI646wPVvAL7tiC0vaeW0fFaC15svYXAFilvX6jRC+8Rvf/k3f8s1vf9vb3vT2d3zzTAt+YwUC0sVYC94Pz/6bhBZ0bgDFAr7YjdR49fXDOw4VwKkM6bi24ykOREVXmlJSl7r4JUvFR0AYfy1CcLuVcCj4d6ccCqCob3Uqb3nrm77l7W/5tre9E7++/eu/brj3O/MXNhDEqz7ZuA4+JQbxT0Gl7iSCI4BonfbO2p29JvxbgW4c5IHKNEMx1gIF/ilXrmve8st1PWApQFyQZ7kz6pgkW53OGpj6HAwGyVcltepd0dc7vu3b3v4tb3vLCrahv/e7CbI+U6qlffyzZKRPEfh3zYEowWgGgIRjj4ReILJH6nEtlzss6Zae08wipaV8lRA7axV0UsmA/UKgvPVOF+2jd6vpt2/1bnc30vj9eyrYBjfzhSScftrfPwdwvjUBpwfB8uz0tDXjX3McUyJJ2EBXM+WgSJznPNsGT2lbjmXq3HI9YMEekZ6QoG18M//CvxxhKAnm0r8fdx9L5Q1zFUua+q/Ds5+J7WRGI5udfqt3GtmJhmrmT8k0nIahDOBHf6SpJmPAtRyHcanWhKvzrDCYXTaZQW2dOKTClEoMZS6dhN+P6WQ9AedV9wPnCwkvNTP7pVTQFfxYmonNPRdKZdoYAoPRfHDGwgd/7CtAHSEThETENuE75CVgKUKA94LvAowFfjubpbLNe10ORsJW3rdBKv8zwkhJZdDvRulVLBU1GGraSNEULRTqJBiPAmqBx+X4m1LdEJQL08pztSKIUzMc9UjXr7GHKJXYGaPjXSX5KJUPpP1YwhkvhDGeKg0yCsY3K+UcZQ7QfGCSTJiMQIJiAcE3TGbDHxAZt5P8zi4kPyZ4PziXyTWQSQziP8KzX05FlG73tNsE74kgZuIIluK4qdo1SEpMqutZO8MqYDTHRatQyuSKh6xwrB4fKdlkeG/77fZGP3zt/qWx4CmfWOBYFlL+Ap79REK32jdand4AtCsykZkERkJVBJZNgpGPSboUUfyA76RqGVW3WrPyTBwJ+YhiGyYtJ4C0+37b769xVSPBU65k7c8mRBJD0Z584uATKZ4CatXp9GZQhr4YCUnEmPhDTTRGE6GzGmcSlKkAGZbLBM9hAUXWgIyb1GQ0U7BqF1v7zk7rpQ0wzCcTEgFvD5rV63dbZzOnpQ1VMdUmgSaGajBWlZFKuKFyg3DLsqhqlXVTP2Z6zc4c68oRzVqKnlMKW0NJZycYsdP69YXTWvpeDC/vSVck5qEEHRYayVISmi9VEZJRKceqFlEgbhgVrSQMW6oe5Y5heS7zXFu6oHQPy2ndOt/7/PzVvwSvrqxI5b8CqQQJO4E8otsC/YqEkgIxUr2hD+rjcMu2bQcDI5brHCltXQhCdWaWVJ3q6tb6SmsnoXwlETVWhYLRJV0miiNJLBQBNjIBO5cjTyVkRIayut9wHMuzQAJCCmnpFOt2JqSkHvoAoPZrQmne6nQ3imXde73tda+5GM9wUXn8UxRLO+2GfRDLR1Pp3aDTBVI8qxeBzU8CPwDPNZ56vtYo68d5Q7N026pYRs0qqlWNZPZJ6TB/lMnqeVXL5EtJL3zeGvit9Rw16b3acyTj+5DMXywks+TD6Js/mCoYxH44lkwSCPFUqYhytqyXSqXDXP5wn6jlokIs3dQYF7bKVQtIJWXmimRO/fZmb3yFuHJz7x/PX/4vf+UypdRBu93q9gazlCsAVUpicThwXyDDHuc6xBaHUKfuOh53OdEtwyqXqXmcKtD7zbVi6rXLvvt4Gdv/48IDLxMtjPdvSRGUZGyPXpvMX1slY1m+fj1fE/RQF7ZTFFXHBDJMLOCOjisg3bIkd62kVrXO25tzrKvE9jiSYPCLccQ6hUHyQyn6mwyI+OpAGLVhYxKoYqxqURGYW9yrg2UD5+UcoqHApMQBxyvR+96L/u4cEM0NMF5KmsZaQFzBMPYlYVJntO66imnwumvXPUitIM1lsi5lHbi8xbbnVg8mIPInYwtfMq2fejKRW8F/qX+jB+n7aX+ZWyn+SIbEl9pEDLVA9TSVw+cumJB1+AMUSlrMdFyKdL7MAGaVk0ppe0DE/8g2OMPzS8CJPa/z5HpV6OPwLEzAAYcFatCDDxCTd0zik2IJfTkBxsVtZhDwvEa5bCgWIYX8UT53UDy8XikeHhzDT8elOYx29zwFpL3pBO6+U3fvyXUG/GPw7OPLyI51bojsg05zRhuTmuVDiI8SQjzlcTElBJOR8A1N3bZN5sm6bVs22xbaZ1W6K6tXTFCQjCgrVoKk5e8kAkiKoKSUSkjgKGXXqyjWiQ3qVIdgDpFF2JaoC5dJ6VgY0xcV54dFUF65wUg+/WSqANEfRGWhNsSp2EhWgEiQjOO5kjkuelsbKImwiAvRhAqPAAE7FCXPXGONTT9JUPqDHVzwzb0vJwApM0D7MaBPpQGBWAan3U6vtw2PGuGRhZrgiEeimlXA4B1JmUuACuvCsKyLU/fdxBPbSnuDrXwEnn1vylb6oGW9wUzLEkYCiaLw/RChgIE4YCPCis4Y60KYkGBR6Qm3Lhs5mz4kW4kDPDLEGWtcBnhkkj+aPnRfskZ1NBODRibgjMVockc1DvbNqqMBl68oXtXhjkkhUGJUBB8AzCV1Wt2+1fQ7rUuRxsvgiCsp735yvQjxb+DZJxMcq3ej3+udtU5nIWXs+0Jq46FQG+FQjLTGTR3TEVAszrGc7UGKAl+eDRzL0SpZg2VFZWslpbeDNPZ+a/7CH3gyLtItA8kfJ9P2JsbF9qDV6/TnLEWMAqnIMAA7GQbhdDKiFiQg3MaeAUBjUkvatQo5tJ0adZhWynBqV5PiaJ+3Okm16l+9l8NfWsdHFuJYcni0mL+/dMEr1pEQxDhsaCNNIaUC0UmmACmiMGscEEkOlg7oQKc4tx1mWg/FOvwFjB95cr0A8e/g2X+7lzz47Z0NOhDdZyWhSBb+TBa+r4x9Iinlpqlahk0Js0xOc6aVtQnJqLpRyjNSMI2tfGs3I49hfPzJ9eIvkpYfStDGJUFBGCsYvMkEZOA4VZsd21RyzlyHcCnqEjMTz3IMCPuivBVG++rF3wSMH9ugVEhZfjilVCl6klAnCCJjotZ0QgkkUTazMU83QKtM17HRXriNAZFaD0epbu79i/kr/+RcGtcTSvVXK0rVRRLfajVn5aA9gNKFP2YmHoQgkok3nQJtzJvHrHZsWZZqmbnK4VGmwgrHxn7+eJ9kyNGBmcmo+fjMB/L186bfP+/6Lb+TlM7i3Ofw/sjj+ehmggX/1AbpINFPHvMuSX0knSBIKJgIlKBQLtFSpkSyBlWprdUsZimUFGlBy5eoZtIK1ZPHvL3bneZGOn8lnhLTx08t6OMTC57yyifT5boFT4mOq5cAJuFkOpkqmlo1TdsyFYOJmmNJSRSIghw8MngtruSpbW7vH9qNn8Q51qefXK+irKBI0Me4irIOpVTSbaNqkirjTplLHdJDB6EIdMFc58w2rIvoVn+XzNdf8JQ/XuRYSxeG4fJDCTjL0BjDUYBnDcED+8E0HIVEG4fX6vXrhqKfSOC/nmuQAlbovOhbdJwFP4uIpbTgn7ONgfGR+02xzl87XvCUf/PkekEFuct3J/hWmqfg+4vF+4P13zENoPQutr1AQuLCNxG9Oz6AH1yg+vzB85RXv+bVC1P/dxvKEBgq35fq6EiGRUnGjWA8mYzCkIzDIAwblnTqdVfCb7cOKeKJhB/hByybRrVTSCRTKLob+pI2mvrjFyrUaPzGN79pAeQvN5D4dz/1xMEvJFwxSKM9wD6pWWBMgRiNxQR7OLD+IJjAY1Dg8pAtAkuR0j5xVQOgCZk68jk/SwLp7eSzYub4VxuA3AAg35QC0u33W73uPOedKVM4DqfBaEogQhYRA0EM2PEIeQnkuoABqxJR56ymV5IHPm2IJ901JFculqaQrHCVn1zRrWV03IzEKINOuViuozJq4pCW46giz8FMIK/ShdD5RUh262eOlSv/1Dp5fC88+/FUAj9oN88G3XnnG+rTyB+qJBQyCMRIsWzbgt+QiTiMGQ4kv8DiGXAvyoXtWDoxakk23zzf4ntXRfLmyxTk/yChSKuhBMX0j1IdHbFyxb53qGgamMjQm45Df6SQhpZVjrLlHDvOFWtaOa8WKmrukUObEzWvK1qhUNJsaawelfit09ut3kY1u9IJaRzkX/XU+iHWZ55K1Oyi45+zTu9s3iQsx40w0HxlOhn7mjb2JDGpBobBUByU8RoajiMMGwRj2rplVbVauia/3iS8c//Aq55amn0cTZ6AZx9OZL3dG+1mq3Xa7c/L8yswyg6Qd2x1cj1wW+B4XYyEwsMKHuAB1s/l1mjS3SXrjWn92zbYyeefWjusPm12+r3WPJooyiTUtKkiVKGQSajoDFuCpQX5CPguLjlQ+ponapawQUSWSVRDf0i1+ZhwvXNhJUsYX0prFATFQfus2+00F/UtQib+WKiKVJSQTLRGY0zB3CGc2EAVBaLB4AI/sDKpcqdakpWyemHD0APKGd/91Dqdx3D5jpTRJ0PjQhjDaRB42jCYGswglpIHN4U1rapNnWNqWtjvXIHf1OJgOhe3ce0M471PrVMVdMwfTtHgpBNeQ6FxW5QsGw9zGXZ2AOly3BpEROw+jorbQFa25oy7KddvJIw6loabMP4fT08DJAx9KERDGxMx8qfS94PRxNENnucKEncHomJ0Mg0v7xhgLdLlts3t2sMx9NhCPrXBQjJPr7bUtQFBszNYWEgKhNQkVkgNxiAiWhSioCCOxiGP15lGTV1nPF8jtXLtwgrwg2mp+/RT65zrt+DZ61LFodag2e6ezoYbRpOpNiLS08horIqhVDXOODpdYWvY9usYmlUWrGRYHFyZaVnAKVnl4uKQsetpyWeeWj8tQdX6oVQjRCISrkhjLEN+4oI2VZmh44APBe4oXBsUjFkQUzzhcne7gTwgYfyTDcK4Abr186miSmuAExqzk1H8+KeNiQyk6g8hooQ+JrXYzKhJKagpZQWpvGdQPFpUTeFxhdpbhbGLhSwLjp/f4K4wPq6cUydiYQoBhkTNpjUTQrq0PddkdWHarjezd/wHTd99aOfUcZ/8F5+KOx6WsxL4bG8v2YsCEHqD9mx4aQ2F44iqxUzqOIzojs31CmU1s+zp3CmJLDPzXN1P5Ye3m2uHCoshuCtMS0QQVqYltkNQfKDtWmOqKb6cAH+XZb2qZI1iIVPLldWj2iM5TSkUS4WDjJIv50tHWuY4p6Ze9w8SHmSVbKOnuZvKrWOvEpNt2RgKT5OTSSNQgE8o40YmUy0eZbP5XMZWtWy2Vskd5wsH1RojlVI1f2QapLJKI1qdWx0fNGCTi9mpHfFLG7T6nWkXk6BGs/pzShmmYcNlmiUV70Tmgdi59Yij1vFEFusFDrbtu9uD8G6UKNbqf7nQ6g8vYPzLpEpEFc4OaMTZYFZGTwLwtcZQlbTCeTXH+Ak7oY5lq3XhmMKUWM0RFnjMGtO2d1/0U+269wNhkoSwh9r12UtAiEPweOw3xkMgqKPhdDwSo4mWKx0WqkeZwnH+KKcf1wqZnKmYmWzBzFNLzROiFFWCWpV6+VgdvvrU+sRyC3z1DydeYgDU8qzfnJePVj/FacjFbCjTmZWK3Lp068CUbXFigHJ43qPyZLuv3qEX/TWjRaUCqcuqViPFSbd1xnRmrtVirE084g+FMgwnIqxYmnCz1olwTgBEDcmlJ4gbYZq1UaQiZ7tz3mpvDJ5XqLn4i0pF4en1ZPhD8OynEsSsfaNz2hmcxseOaRhj37Qgb8FxDcjnuZAcSSaIR5d2lTNiHHPqJNll6+y8td5pd+UyWAzEeHo9lXwrPHtXquTSbrX77ebcQhMY/LEmtCkAYSbDo2DHdllU26siHmI7VZtbwMiOk+d1g/PEoNnOvRKxbt14ej37Qorzt1NVsCSdCTRtMlTGUht5WkOB1D5ULMcuHheL1NC5oWnMVunhdWYwyioHwDup4chkTtxu+ulCS/fKSG4lOgjRsFenm9ABfDyBZGnscTwbRWBUbaRpJAIzydJ8rkxplhiMHBNuUSy80AOzSh0KiYBtcEePTrlund1qdTZa+1rh/tWXkEicgf31p9dLLV8Pz7oJPtC50W2f9pqD+XaCke8PJ8AMwpA0xiSUdxxXcC6lLaO+DxkNzoGBY7UFqafHLii17NJ5twDx9U+vp5EI7PfS7ZwJEPG7T0golGk4ImWDm6A80T8clMiGVIza8MtkJqRlIIoLhsp3AhHbxjcljDwG8RQ8+8EUM+v2W6enZ7MYtnz/ECLyRG04qmFULMoVRo0qU8BGNMe8/kiBFnMV87ic046VXMo0zpvJNolNTStXqXy9dUMEQRf26VRxIumuwmlDCacKaQQ+IFLklADtyQtUKEy1sHoXjcm5s1MU6Qis491/ceLW8BIwYl707U+v8yJ8liQVvRvtfr/TnMePNARNDENmV1TJnapVdrA1GIyjDuZBLNsQdtSX6nhbCnhxqej+edH5zb0PJCFEbP+zl4AwGimaPxXgl3wl1HxlIio8kyHHPHOYy2uabjH7+mGBalo1n7MMWqlY2Zqpp144VoHv2xCxfv/pdMtl/0a/2zltd+eOPvmxBeNwKi1eVLB8Y8GH5+SlU1N0Rxc4DGY6pAYWa7DtPQ1bW2AvocjLIsKHnl4vIiCreH+qZz/JIBpiAglTCM5RNkbDgPhcc03LlifSO4GQW3fxBKruzmpUqNTJ6Za1IkL7gRQRfuLpdWL6759OTBdG7dX9fqvTb8WKLINRww/IeDgWYSAaYx6djdclq8i6CdQegqyoiapwkQ9R1ZR1fTsx7Wwjpo+/+t4GufDyP78hVB0+k9gINO/p6zS7p/35vEHgTUk4VIOJDH0SqmWHYeMu5CYciwfMcaMmdz6LV9zDft6LF+nsWiz8zNPrxUIdQPxcisr1m4Nut9ddZCopEFowUhSLlm1KnSweDzgcOM+hrJlFljNMpVrjuq5YWvnCcvqD6dz/zAY7338mrVr9G73Ts16/MzvWXIdCHJOallI1dV4jrAoBV4V0S4FvkHHls9lCQd0+yrabnceq9VQiYsWqhfH4J1PtosnYm0IQTgm4I91yTAUPNGuyKjKey6Ves13igqJJ7Lw0ycWqdcWS58JZ/erCWS3N/GtBFv9wJQnudOZHAuORrwB/mEwUL8A0dDwkjmAsSj0dMatwck8ULAu3BdgWrR1Y16sPSRSfm7/xbydQLAgpoHgybeWtAYgikgR89oo6xuKQFzTCcRjedLgLZFS4Ljd1D1c6VMHX5hxBPdf0HKa5qc7dB2bktxaS+MoGSfiA4b9LOdzeaf8snrhNARgp/pSDDIhTdSRk/dJ2VWFh9wLl2I2hZjTreo2VLva3G0HcuoQkYtv+/Q00DuP6D6d6k5IxfKFH2EUS+BppmA6vg6s94fxECE2ANEwmheFxM6oECLd2AY3brlCXgREL43/ZUAV4NQjj7yWqAGDbrV6zPzvOSMkhGCtiaGEFwMDzMeyoBEpiQ5aALaIQOnTD0EyL5bbG8O0a5V8CReyhvrohO3h8JfiBMHog/96s9JySw2iiao4Ob07glV0po5Umnp0p2grlZW5pRWaWLZbZahe7GPdCo/79gogsk2YkJx9JzXkliYgfTFAAGqhKqElIPINSTj0sFjKF2lGuClQ0nzk4ZoVCtmgVS3kwjyxjhODb32qdY9Lsn24kIjutAvnzp9cPZd4AsvjRFLlt4b6hztm8AwY+fzGUQwLsUNMaYzAFVwdPSzFBdgUF89ZyNWEK12SGK5mkNWtrK+UDCnovb+BT7wUYT6RS//7g9OzsdBb0UAgChTAZBtiYL8uOMduRA4kax2kiz9uXoGAeMF6K26wMXn44WXMsCyQbq07qMysqlSYgsQQaPvweCjkdg2PV6EndPoFALe0TadW9E8nqwNZtJhkTQHXvUby+IorhQhaHz6xXMJDv/sDKvMqS266huHNcs6hSKGeZSmtE1crVGuRoliwbjl0GVwWJ0z2WRF5VFnGZMvfMul28Cp7d3kseVnabg0WPW0KV1IYXjoY+l0qlLgtM1AxpSBVXMpn7VVrLelrhQKlWtetFLbW3yG8/mOLezQRJ159ZH6JHpfquVAEjJumLJuNYEsFIUwMpp0OrxHOu4lYkM1nZLdUcu4YNlJAB2kLBIllVXLjZ4AF1Wfy1Z9YN/aeeSSTjUXNuu9U5a81H1GIAU6nKsNEgwZ1oLBjeONpL51Rtb9YXBhRRQEJlCVteoTl3eIns7/MJRVoN45+CZ9NUKaPXhDA+O2uLX30a+FKMR0PSIBCsKdUtxWJOhdbyOi3lKpXM0ZGez2mZ7FFRz2+Z4bywb+cyNaUvJFCsFsDRbJ5Ot4EmTGQdRo5kstl8qVAtqHklVzzKZgpKJVPMVUhZP3jkoJCv8u3NFbuc5y9nHr/2mXjmcQkD049vTnndeaqxOMxdBRJkcmrJKFZquZqm6/D2BYWqFVWvUk4ti5Z0jUuy3T52TjliNP4GNEjhvydFS+Z0fYFmFYzMFYu5fC6bL+dKFS1TJMZxKZ81DMIIU9WsoqpMuxjNblPosbU//sx6LvvVlVCSZorTSThujFQJuayYhkMZONQRBhZco+ZvMHgXa/o4cIvbPzjHc92HwxRja3/1M+uFNyTy704NqyRI+4osGsOx4MytStzFgPXiOm7VxJQjbhHzHOuCwtsu8XC0sPav3xAQvwuevSoVEIEonnb6s5mbpBS8sDGdjKOMDxInLm1cZeCeYIeAPHHBj+H/ODnJ8e3kpPtAWqm+fiGMJTnBNP0bVzZYL1Ly0XAFxc1MLlMuVjKVMmPH5YOqYZdMw7R5tkqZZePhnZM6s/M77Y3sZJddGW/Y4HqRyX80lc4mWXtKnaZhQwMSb9RsU1dMonNecmrVcg2Yiq1yp+xotsOUi8bsdnNW8Tqvv/XMesXtyyu1hfaNVvfstNmblXnS+kTCxljXcirhlmmoRVOxrJy1f6wxquWZlitbh9creqGcGok4O29u2Mtw5f6ZLyVMYVUiqGtfTJ8GJ8xjPB2DFEbTYBKA0wrIWJhq6fjYKOR41SgxSmoms3Rj36wVqtlijdEqyxaTmtW93erf3jAVcWUssdd97wYCjwnW96dX3iWSqRmOcI6jEco75Vwuc1QsWlbZqpq8ZBftEq/hqmuLWdQsG7WHdQQZn3j90DPrGz/+9Jn0bgYwkTNI0AfdPVyM9blr2JKrKCkgIbwwj74E5w61HGlzy5KMC4aLCauEM1JFvTpdM4+L9sD+rfPtTGshhx99Zr1O8mfPrO6BbbebnV57NogW+sFUDaeNMJCBMlLD8I7uYPnT4ZjA4kkNlkqE7bnUFJxYgtH0udMl5XDvmtUCxE9tUCYk8T+cmqZLEvbk+0+DxigoG5aRr+A+KKcmucM827Gk4dmeIYGySxwf2K5MO039x1HjUxtCONLfj6U67ROEffnyRFGn4VQLLI9mDyR16hokH1VZz5TqsuYKBTtxPVPKOvPusS915xPALyKKlbOzR59NHHBEnaud0+Zpc9ZGTAgZNnxFAUcbyFCEYeBg+R93k3guruRl0mXRTl4h6h7H4UbX3DIusNt+0YRCfXGDVbzi2eQsCipUpz/o9gezFvU1GHeytqWbjKEvwhV3nB1ZJWYf8lq1WNP1I5Y7fEgKFZcXvryh1IPRMEnT05HPTwtC0SbsulI/wUr6CW5ZqXt1WZnNBUWNBQ73HJE8AGwlV9ol496VyguxNP54Qz7uP5uYoINPDHRqgIXQ+U67+P3HYTgMtGByx4lWxUdfaAw2thfgqj4rqrELcdF40y5VhQWd+tNn1gcaMX68J02n5rEi4iGJ958gnqEhabZRN/AaDdw85HpRnzr2pYN00DIccY/TgZ0t4882ZEsYQ9KrapPxYgVDOHFw1gEFgaUQXLA9AxCplIP/BqTxcPuf/t8NCvXtzyZWL0TmDY520OnPFCr5/mIcNkLQJ5SAxC6VWfMx0UV0EGhz+JO73sOYvk6C+KsNIL4DQPx0KnJDvMALJOYFtzFRSRiOGqGqhRAxyk50pwli8GYr2y3sGRKOG7WhYRvRdhA7SSJuRM4/Gzcif2A5l/VsouEmylt7Z/3OWXe5DcrXyEgR4zEu1pZEDQJx7eCI7Vfdw+IB3cf9oWQf13qUNNPD42S8MkevJBuRo5T1t5MvUceX+KeXeIm4oDH/DLWgESoaGauNxn5Fd3Bxv9HIKVnpGqWCJco8n8PhShsXn1lm8d4rqa7U2P25RKhVVk6MMJh9JDU4kgi/+N7ARCeNkQhxmJ345eJhVRZlqSALoAFSSi2DW73dGnyXpFpwgAnhjszzs9ut9nl3Y/C9fpXjolixMdCuuhjE8KEUm0sG30ZjiBCCCEJAfKWMyxhtIblXdx3qucyxcZU/fNkeljJ0130Iwfc1r126++6z6z1E3w/P3pZKO3unvbPeYBZ8QzUcEpxf9wNFIY2xmIInEQxM1IwM0hA1w6XSkFYdJ/VOqChXiLaVzm3dteNfpv4ay8J/dp1ZYzj+cEIW6dA7E4AyDaZEhqQRju9Q28SBAMOiBUpti9nMpMwkpgVJGnAjal3ArLeG3uHo3iBiWYyfXS8rfQae/Z29VNNN7+ysN9/6GUugMZmCTchpOEE6CsojZF1GTlOe4I4HoEZUQOw6cU8cZ/veo90qGfFVXN/w7GX2x0LYHXTOZr5yIYNpA1w+UYI74Aj5ictxe6nLPa9el3XH8dBMpGNioeyCqHWfV3EtD+u+fYMSYQh+X8qgk+E2+sjFhMCLhxMFW55USiyDWZZR5Lp97DrFKnWi4UJMFkAgjvWQ2HQM4js2gMAQ/N4U8UmG2/lnDvl9iDeNTNU7KjZLm9SWmNPYHnUsFq1qkfgl8G6uh1SwiEF8F4JQ0nnNHzyb2KQ+q0x2+81ue9ZNF4kBs+WJEAoRjckd/diwTDtTKtFD02THRdM8qh6rB9zWC5Wsls9cL2UwE2ien/kt/+x8vTCpzPsJFAChXD5ALEB8/8K1LmMcuttfTOU1SdeKUpiGZCaFQJkE5Ni4vm9nisVctVo5rBxbCi3vl1U7V2D5mpIhSt7UVQxytzpYANvsWK8U5L6Q8D+rtTz0U0H6HD7hk0CPRoBiPAxHCpA4Xw3z5SwxbPCpTCNMp9yieNODZtWQbHAdnKvcPlf/YBp+f/HZ9VPGrzybGH6e3erV7Z62TueX7AF7DoJG4CuYoTWmIbUhh8Q7Q1wb+4NcLllVCIFjRFj/khbn25fAP5iG3199dr1GXHguMUoA6dPZje5ps9Nuzjq3Zq8+giAxGocQtafCMk2O1s24BPvmxML29RoQD4h4epXqlkW23JOAf/k2GJdoeVom/L++AcZ1gPG3U3Gu2+p0mqfzlWUqCMOfBsEonAB3kpqCWxl4pWxVKDFqjFFCScHQa5qqG2Ymk1XLhXIqznVutzdq1U6r177y7HopDDXt7svJNvKEVi0AgI2HkWrJiPeDd63jeGjdU10vGgj0Zuv4o9G6B69V56/9m69dDKj8wcLZLnksOuAPpo+BEs52pksTZQIGHhl5+bpOpTBcUYOXlvlrrhUVV/FQsVJV8GcrmSq3Oreat9rrA9DKvFofe9z7DRt/8ux6OewNz6U7n7o3+q3moN2axb6FHCaCgKEI5U4t6oiALzDw2f1aeEOKF60pkxKL32xr7Ntp7UQM4t8+u54vPw4gfmQv2RHYgQB+1p1VLiIRqMo0bEwVAj9O7zi6nNWQZg2zjseikQQ36uQCfghoHm5HIJrzak0Pzf7nU2EjaeJhGDb8qZTqdIpAQCplzOkEo9UasWzLxpJL9CvaYhJ1mV5wq9Z2FI+P7lmxX8DIPLfOyL/vudX7mzrdfhsz7ihupDH4YQMHY/Fk2on2JUeFMLB2vCdXKjmrkqsL5+ShbJsYLmAUNkgDY8lPJmp66bixBiIsG9wxPRyliFQLz99Br+qzm36jBxdsldkaNy4BY+lui8+tB/GPJc07gnHWHHTmLYGg7g34AhjhSCPTKZlAGocrTFys5gkI5K5t4S6ZomUXWSVK8apb2q93RhELo/7c+mHcFJ7dSaAY3Gh1T7tdgIG7VEeY4EZCUNUGIZNhOITs1bKiUUbBhcMMA/cuOTVDV7mj81qtRo8eIcd2XL1JDmFvHie/b2L42AbT+HRaGBD7Br1Op9VuzidEJkJOJqHWAFqljIPpFN7c9SjaBpiI6tUNCSHQdCDbA8N3If9wTrYuFN+RUsXetv/curf9+efSPXSDG+2z0+ZgfiSXQqBqDXh9S+q4R9GBWEFxe30FnJQBoAyhO2XmmRcMHz2Qmv1ff269iPMLz6U3FPRu9DuDQTveJgMq5GvhuCHEcKqGYzItghlXwEEZkhlCmGX3xK1LiCN4qcCJJEIXTv7iM7mdFyY//tx66orRcJLqcEpGPoQgFhCC0HcMVi6aViar5DlhomJZWMixNUqxmIOT1/lk6np2u7059l2lISVWqTc8t14XRGaSbBlIsxDUokYwCRvjQI2S8DtiNmctsakJ1ypgaRhvbfGiOrG7cqX6A2MhtxayePMG8/7cc+mtz50b3U7rtH06S14XMohKIWQSNIBA4QYfx4V8CQck4a1Por74OhBdMHVB3S2Rb8emudcs51WfW09fMainr81KBnC8a5UMQwACKXjgT4DqVi1aNahjCI7b3AVuS+X4jeCeS9thjN3jdvWdI9/HnltPNDAafn8qgCci3+LlGyRoYOlcoS4XFcwzcGlHHQhI1DFXx7qUE21TvFr8vkyRNs77ps+t531/8VxiYmfmpvCW78F87HYFRDgl3GFWtswsplm0RiHz08vRxZE6JLDUtg+r1RQpbJ931hzVlfO+LySBrJyRYli/83KyjzwO4ZuAjKclxzZrQAXpiQkxD2y8jjSqyiJqheX/ew7C73xG+jMbYt+X4dk3pzKN7qDdOevMhhMm4XAiIU3SQtFQJtjb5AjLtaOhZ3xjxytAhmGVnWgnb3TSyx9KpvHqxUnSzz63Plf4l0k6FVWbW6etQXOWvC4koE5I1B90J5qGdHBm2HVYdB8mXosJdoEkF5eNyu1n7ldmIcPhaDkBvSHwITH54dTpRZKEpIQQhoLcrDGN2YXyMcsy087UGC3TLFiHWaV4uapVLF1QeH4gJOTTG1ztY2kftUIIU1KYKjhjSIhgTLdMATTd1k1H6AZnlqE7uqM4mk2NCxbR70YI40PWX1jQ8yUM5FcfT7U3xVzqF+Hf/g/YKxfg6S5IZKwEM4lki6WjfL5wjDvUiofZXDazr+4faQeqomf280ZBrxbL8TV+t7p+q72RT9338vakRH5pg7+99vwTBx9LUfRebzAAMjJzU0lh+I1hEJgWp5zXbMFUsBCbV/DWSGngrteqKW0qmL71fqwHVPV8fgMVsZ5PUJEo+KEtNs/mmUYSgTaUZO6McKegh8dHdcMVdSrrpluzKxVwvpakW5YM7pz3xdHvcxvsA1lWclN4mlGNFq+vBWDnQxLWsmr5OG9pOmPHaqZAamZFpxa37GPKbSS4TqqS3vLTbU5Xv5sQVyTF8vjyBm+FoeQfpmh6MmwoSQzYn3IzW86RnEpJlgqTqSRj2aptVVVswWSWRaiRugW6dZ6+x34nmh5fWPa7GDiUdB7+6POJOtvM0Lv9zll/0dExkpOpGPt42hqGY5UEE82q7ecrVkbPKRk1d3DkWEeZ7MHBQfmgoOUOS7mDQvb63M67t05vN328y76bHl9dXAF/eP/HTUu5/OEGO+k9nypW4TUHrbNOd37elJLJWAsbCpiJg1tQZ9YCaSzHsI5jujW3rOVEHR4+jLWFo9cs5PJHz61v0ngdwPj7KXPvNzudQae1EEwaBhDFsWWbFt7ypTAbbzKhwmaQjDtZ6phOjh5Uq0phcUn34iK58+5Gw78SW4zb4f+vDXJhAOjNqYJPG9dJtufXGU3G0wleNz5RxjjpPZpCKihxcwPS9Dq2LSvXICV0XI9KUzg2299P+a/WADdADdYo487t8H+2gTJ2AMt3pyjjoNkedHqzdviZPMbTEeDB2fsxFkKxJu3iPgpcQGHij3gpSKR0Fs3J7RX2B1Kc/osN5VCk9O9Oh/hEHhJJw/NjaeBxgYkTnydu3TWQH55AVoU5Vd2Ts3FpyNMfVgtzzHz/8rn18Z2fTWYhq8w3LYdGGJYty6yYDrBEw7Cl61ImOTUkcTnnpohukdxOGncJ7gtRIB1ZFQXSlmmKNCYpylIEk0kQNsZYwvIs14saA7HE7kIiZWNVGn2Xy7HSK7esMNqZosQ+S31+3Wd97PnEFoeoM689ODvttJbL9ENCyHiKt0qpDdAwtTEyTUsD4ssdHuVUkpgu3otn21QyxwKpyOU8VXy1au928t6fwS4zVculddbz62Tl+SRZWeNckSgUicYuA19VNWIY8OK8Zui1A0cXIgd+Km87DMsmDK8LcFhq3gIHeM4enPf9rYSnXUWCHvmp9NK6hPddA0KElfVUxoCjAPEtA4ZMhmPDm8NsYTuC25SmkHRvt1sbfe9OSJCcKEraVpDETNJua0ZYIjafxKAIMgqv62ZBN7klS2pJydmm0IR74lapcAuiJirohZNeq3mrc7vT2shU7v+Y9vzxRRTpPL/OIDGyfDLFIJNRJAkCB3sad9RCuVqE3MR1LGFZXjWqkWIPJR7T4rVlznbX9UCiSG+DYv1hurS4QrdWMQRT08iIqihSR6Gc1aStUwcyXEEdvN6PcsIf3vV+sSz+xvPrEf2Xnk+3WnVvdDp9+G925gcgqhKMcShMhuPG0Cd4vbCMrnfHKaSoL3uWcLkYCR2DsAuWCOx0Zh63HI6fj1sOyxe0HIJlNAfNmf9Nvn9jMlXDm8yhuOLkhLsm1toxU7QcA5sn8dIy6dbr20vu99lyuCyzv25D/EMC/L0pPxuT3Ygbpl97NMZ9WMA6DIG8kNdlTdRnbQsujsJ4s22EDym3janI7efXi3Cfez49qNC5cdZrd05nlD2NYByKm05UauOOYUe9FliVxptKiCZENRqE0bavWYvyWn1He/7YBlFgXP+BBBVZxvAoUEissgMXGU5lYxQ0wsajhJ+IRyVyEVyX62EHrjuTgMCVkFRuL+pun02/xFas5VHBdCmKxXWQf/p8YghpNk3V7nT73fm5TRrDeGjjykSJS7GYi1f21S3JH/VcrnsHnmB63dP49n0auxGqDSj2tqPotQDEBSjEDIUj8ZijHrUkuZR72A7t4ozeFlnsiGJZ1/2lDXEO/e0HUyeBSd/a0CYkDMfCD6RGxooI7yhmuWTYRtnkmoHXqAELNAjQJ2Izits06AUUfSff+kcJO15NM9Dek13RKdvG155Mw3EAghgREjZu5suUMM5Vm1Tg9W2d45whZTYFDIRRw1pguPYW/63tx17Zajebp6f9095jnd7rH2t/TcSqmrfa3Y1Wj6xKv090cbn3d1BEpZUq0AtAqvaS55yts36n21peW682AvBb08CfwjcRyiAoAyG8XtVMmlWKOTWXPcoeHh+QKstnD0vVfT2TL+axUbfVPu/7zdu92+vry0rzduMSICldpf7z+8+v1xneCFD+0V6yWal32u7iyNssl4pFNCbTxlgZE8E9jzpRBmthBPHqTr2GfT7UsFU3Z1QgJXnIV+P8yfPrVes3AIyfXcQSHA3qN7utTnN2ZIvj9jKYaJOwMdIa4XgS6AwIFBWkjGv9pYVzKF7OE8eUq57paY5btLdcYr3znTKx7f/vC0rymgUMfLaXgtFudgDIrCdjLgLQKtzvR8bjwHJdCIc2Y46NzYh2NLZXhSgvbYDhZaplO3WpTMtfH3O6wqUyy7G3CEQ09vbxS4CIrSNQA7yZIPTGwURMpdLwiVk80I0cOSpkjjJq5pGjytHhUSmbyZSq+YNMOXd0WMgnx96il49jwZ8+v37BMcaHD7+c7KNPRrTU5+iPA2FV8lamWmWHOmWWwVRGlehGLotRvFqAg/FuX9f9YCJaAsXedhTJiLaGwjAIx0FtnUYoQC1YzQIUnFDccc9xR8ZDQhG7yz/fYJxvfyGxSSJSiC58xbdmpxCMwkY41FXHFpatiYIhpamYFRci2WG+kCkUM8eZjHZ0ZKT2VTb97nlzTa93vuUnCSWOa/8Jnr0ywVlbNzrtfncwH1NagUJwo4SD03uC8dmFlMK1JTxgEJdrumNQ8/godenT+XrP8xUKHDhTtvAz/ylBW90EtH+R6t5OwkAHqYVDbTzBHaJAvrGSAYQbj71F1GfkRI1HWF92nRkbv8Ji3cfvOfl2a3E2dvDCeuj6zhfSmzchDYIc6HQwH2xIvL8MwykZCwhcnmvK6DZmXqaec51h1sa4jRt2Wen6tRRr7Zy3H1y1adFpuwHIB15IZNPx6TGuQp2trUyA0MaNoDFWZc5xJJPYKIzrgcv0RFYhwa6Dorkn0tTqD6m0PFzk05UXLpNPt85OTwHIvBMvhWGilS3pEo9TnGrFlQwu1mWjbQYcKwVAze0HNsK3TETFC+uJ6CdeSFczeuBlsdw3X7ASvzCZjiejiV+OFjBg9uZGEdf0onQOJcHd6B5NKba+99ZP//HX3PPylr3/LUE/kZImE1GkqT+SOiiOKWnE4xoBWSJQhT90eVnR3EdsqdnsxJWWqUrLqUuJY6FOFQ+ShJKg3K0mcO5Oq9vptAetxzr9mHP3b7XPNhLVawmiet/UaPTCesnpuRcS9zdF7S7dfn8waM+0S2qgXsOpNlVGwwnxw6GD+/EpyEjaUS83oAILKds29htCsg38yNgqpcGDKBe84YX1cgFS1+9LTbCnaOry9aUqpTKaGNThIo+jZMJ2bbwRpQ6u2PJwKZ+BxxmOfDhXHy4LUG98Yb2KiYnEN6UaJJNJwxoKxTJ1S7Eh2tkG3ryumEhTpMOqGnWYsG1mXdC182CShjdv8Lv/5IX0oEb7RrvdO2vOO6CFNmooAQmwnUVoYwU0zMMBfIH7JKLMJ1rPh196wWUmk8y16w/lHMlfkMS3vLBe9ng/PPsbqTjY7p925t2qK5Lwhw28cj26Wwfd1/zWOSHqVV2loGSOwZx0N9sDnO+LhfH2DaaBlOQ9KdNIkcQVDOGQUsJQMJqzX8qVj5nHbMvwdHRcAKAGuamzpQaVJIg76dS7EEYnzXWfgWffl8qn251O97R5Ft/RmsSgTidmBRvZopVpglZzjiEEJBwGU5zj64JQtWAVtoy+xqZRTMDoXOVs8jtfWL+hE/nWR9Ml5jm3ireGqGAWSmQWckoC0Wiox/sWyev56nUVG/RslSiEV/QCVvptBzIou7A8q5ifTQ5utQcPjmN9PmEQq5kUGs7n02eTSyNJgJBKOBxPxvDqwqrVcPrYMCERxK3/eBxp4x+6jTnh9nOX3Urm8S7qD2wQC7LHD7680mcYMcVYLEvNkoIEXqhNc8VCOVMmRqVSsFRFVXIV9Zjkq5Ryw1KpUSOZtSPj9HbaB3Nx+cc3OOA/fyHdpDfAmzr73fnA30IYjXEI6ZQCiKLA5zmu7lUtPEbaF3XqmKZXKTFZ4J7LxZb8dueV2rFufeKF9WKneCFdsU3xxzSGqQzKFZrjikarHAtQ1HWAQxpAeV28Sk/UmJNe0Nc+8zczyKu0tv1mwkvNPNfSAaM3+9n0VZ8Jz4XXY5OQaJqi+OMQcpKhvC5szXEpDi/icQbIpsI9O+ptmWWHRsyDj1c3qiV9F+IoJnzX45cB8tUEK1wtoCN7fP/LycboJFNcw3FTNUiBUNswqU0d1cFZAXBYFHJ0K6qgG1qy+NwaPPaKVnfQPu23WlHxufU19yCQ91t5XlwBvoF5IY1JjqakKctk4vvgy8KQhCNgJuOpZxIDJxo1DZgWbm0X0S2mDl7+qTvC5tTQHla/dOzHPr/wY0vDb7z4xEGYMPz+jdbgrNPpLQvoKRRiBEmvmA1cR7plqiKH6+cJnpsVJa/lWJ1krq1eAJ3eqb/boogYzu9tgNN8Md1ECRo3AGLfX1Y8U0iUIR5a4vy+heWUqLnNAu9F7Xr9sGDatjiyMirLXbhja7s/G53fh5L9W4TTTnOYmy8mJgNnTQqdXvesNzvUxJeXmpgG42CI9XRtSC0cXgb9cnD7IJ71I6VhHBe/RhfMMn37xoioSaGQgNG+H6n860QkKa/0V33Hi+nb1SDkN8+aZwuZpEE0vJGP80F4MCD0SsUmTHftomtrFss4eVLjGkTRfD7hCgaPvRK8/Gm732vGKXEsqZbfWWMEVzyJShQkNzgEDKvJnqt0CF2BKEZ+nltVUVMdqtuCEl0XVVYm4BTQ7zmMCJtdQGx2C6H/Zf7K/wFhqGkm8HUvJrZYReforX6705tfrkgao3DUmAa+P5JTDY9wqIn2gyQfx8o9RweuIOyq47oqELSyp+ki3rVyHSR1+tgrzvr9Tu+s140k1fqa1tljr+idDlrgrE/nj3qPvbJ11h70mqet+ZMtR/DxYjsVPgH18u1NSx/y8gvxCMnyE3jfi6kOZsypIfz2+stby1MfwKQhgrGI2lAcnbmuyTAXdRzL9Awcj+b2yYn0rH307ofwKbxz456+ZhLOHsDBQ6A3XlagvzZ/9f0XZ4dAeF+qm3iWLAaCQJu9M0gh5teMzLRxGIbqlIwCv2yzqKu07BLPU/SKZ0pWo9hBK5FyexaPCh2PAJL65grzAsXlEez94AoAvC313gBU4SlDJVRIoxE2Qvi6k89W81q+krNIJaMZ180o3pp2hVVNizFqMK6nXjeuc2VfXI5lL9Y9w7PhXrIrptPrnLZPZ11J6U9NG/tlcFdROdKxZ7svI36Md4vajum6taykyMLK8MGdbW6LuaL4F+kjxvLVPAVj/g+l98HO4/viQuxAGY/8sTYcSxEMFVBsyya8aPIqofDutlRtjROVaRnhMNMS3CklUq65Mp/dam+O8Fe6Pf4LCQnMattLTomS+uepfoakVHwtGGmTkTeVZCRA9qOyWXPyFdumlmELm1ZtSmrRjbZUh7iIt0qnmjJSaXBSLjGO+5jeXMiluUEuv5emjwmispBLSiY+fC8ULdWwLNOs2qRa4zjlLBluyJBYY2VYj6QrcgGu39kYN9bl8rp7A4rlgrRkRlWWSQvSl4+/nOqnTFCVmTA0/K5p/kgbD4XzKD05OfFOgDjWhYuTzvNfoo5nW1ganoPJXUxVCvdHVUZ7/3j+yj7CyN9z+2EHzGVOVhaigK8R4BiBsYOPx/49S0rPeQVeFQn5F/gBoyaZoKZC4otTC9GM8+322uHJtStkJBilZ5F7qVIYzYOXkx1wycid/OiHDRz8r5qGRjVgWZBxqa6hg2WUqlS6NuUq57xGzZI59/T7F4ffvXn4vXS8it3ut25wu3/4Yvp4oXOj3x50zvrNubeSmpyGoYLUt9EQ3h2H48KhaKzZjtyulES4hqMLrkNmQp3KPa4KuOJw9oJDfMeL8a7fJeP96ouJ60Bm5t3vtLqnyzwkjSJQGgKs21a4Q7OsWhOmLQ2jzIh0SoTklJrpmEamxO6dh+wlSOF9jZp/dgXOxVbRap2e4v1YEZxVKOCNbLy6weM42yGcOnfqEie1eZ0RJqlnOdtlct8Hil9IvHh5tZb9QvrKuDjziE5H1FUJOM5+xTZw/QVeVuQ51AHP5OCFcVWcUonmzJMFoRXnmsotrlye++4X18tzvwbPPrSXbHPrNE/Per15+8kKDN+H9Jxzx+WeIaMpJxx68hyryk2Ka7kIqxjbV8t2dirJx2r0nkupUac1GLQ6M2a9gkGdlrnt6rbHsJzoUcE9TmS9yiDcSVoogUWIbP7BqVFszu9bmPPStWKa8L2pilycEsTRevXdgRbmH83oNiNO1qnZxwZkdoojDFAhqWf4jHuYF5lzOiW4b3P+3PzVnwA4Ck33zvwJPHt3Qg5dXDLbPuvOL3OeTFVlpAIiZSjCSYAXLDm4R5NxiHKOBQ5Xt4TgvOpwynXdNGlMoQ4297Xm5yDKAILeh0i+lFD/1XQbzeQTqWP2pEkMpaqqDSkaQ0WEEPOEOM7ntVwxm88eK/lyWcmUi4e6WtIL+YpGOaVlRp3k8U7Pb7X9xFhm0i52Gsv80oaQd/jSEwdvSWU4/W67dXY2c69TqU6ESgJ/NFVJCD/ddHi5RHFXD2adblmyvBSZouRmLVczFVHN69uvfG3tEvJipfrDF5ebF2IQGMvfnyLmcdzGW4qeBz+golrNcCiIw795XMmr+5mjfD5/aBVNohk2VahNMxADrTKzDOrgXvhW73artTFsX7v/nQuLGa2vLgTxplSh6nvSrHwetqPKeyQABV7cDwHFSFWduiXoPgQ0Sek1T1SVqgVxwq4bpiAQTWqUHuM69WOQxGNRS/Gt9jodj9OL+87645OQ//XF9Qtyzl5K3Ms529APxticNTKhPYRTRQQaAeMY+QK7F6RjYtrqRUvJMW0l2Jyl2tWSxmqQMJE5kP968xnulWsXn0s4pZmjWnbHofP6e6kO/ISjWoEwmdU7GS6oc3Wc4WDMFphJOPObWfAqrLldFC92VPn7clTLpoD/vEES73kpUU6KTgpbHSxUzuppqlRUDxyumKJdhMGYC8ls2+AeJN1V4OJ1oOhc85hhSeM4f2RmVa2wNXTvttzttxPuCC3jesK60W39cqpPMXZRPzi37qgwpgTDEfElaaDPDUdBuZw/PKwcHmYPsgUll81XCoqaL2YLxwXVtlipdFy00cIhLbrV6iaWYicd1X0vxX718ngt/9J6fe8DLyXuIotObjoABMc6/gBgIJylNMYjMQqDiRLdwIlFPmAkQnqkrikFrVLNUyJp7tojLFPMZpZTvp21s5srOqslkMJL6y2w74BnH1wJ493TVns22zETQgOEEAyD8chXyjqjlHJFN2kui7vQ7KzFWRl8VUk5zudyuXI+lz7u7NxqrZnIFQPg3u/MX1pZSGSZLf00PPsHKYn0m93OGXx0DgDB/6sElNHIV4Ph0LRtswKpH8cSVQ28F1AtKllRO9SzIAxFz2QWEuncbvldf7NUrrRyPeaK6gYwPjx7417yzGbQHpye9ZebSRa61RiNxooY+R4wECy1Oa7LBIO0w87rUuolvXSQs7KqUjsu5I5jMG0A0zzv32qvFUTYfCzlyluIvJfWU49PwbP/PuG+Bjfa/X5r0J3vXh8FGiAQHhmKMYAKNEj5GB5vRo2LtqxLQ+IaRGxodE/wbqOq3D6RttuxRnyZMMY+ZYXBY4xcXHuXjIcxgY/fX4jRUA1CtTE9yrJsJp8t5nL542rWVGzJjJpZZQo3uDR1xoV1QbvGaly8bwIfE8abCaHElv/US+kaSfdG/xQi41k7vi8lAUObhnewZ1xEu2Icj5mz1nGB5XzKBcXJR/sqm7LvsVDw1aPlNbz+S+tkC43n2VTFMDaUqGt87A9VbSQa44kMBRj/1BVc1B91IiwSojv8UXc5Hj3hbkTsc7hgDd/ptsj46nvf+rK8nfPxl+Kk9sMLGPhsby+Zm7davWZnMO/WWAExGlNwvRDY94Fr7Vu4AmPfwEuFseiAZ+qEAk+5ODe/0nVOkySEaE7os5eAELssBZhWECpTj0yCiar4YgIx/ah4YGiFg1z24Dh/kDncz2b383omd1BS1aOjSqVMknNC0csvbmXe4Gh+9aXERWOzIABBuTsf4E19hKNpI4x2/3nY64K67DH89Op1kTvKu0IBuveow4wtn+OODRWPL1tZE0E5hvFRePY3U3Sv3QRX0JxVYVcwNEaS1BjhFq0o5cMqrZXo9cJRVj3O1ahey5JqtpzLFXIX872dG8K+bYM0PvdSYqRjdnHIaRdX6c03wHujYCzDqQyGjWA0GYccWTZRmUMgFsu6iK4yMmt4n5FiVIVXdpwt/dEXbYC/RC+rv3CU71jAWCYQSJt+YiWBWFKkpBzC0VgL7whma+A7sbkYeJ50jJqL8djCCZtKtH71Hst8N9XNzm/dA8fQX8QuzBaUlZ2GmFV878vJXsN5BrG4N24qJ0MZyUFKtTGUpFAsZnOFUv6gVFRq16/v58x9LZtVC2qhohxVC6BrnMxjVv8cL6TxO/769tUrE4pF5+RLT6xtaERK/oGXk41TMf2O4cQ6BVjIUCVyotVyJdUpV7JGwZBqTddyOc10ZJXkRMVxmGVT0764lrb16rJLwflCwrZXu6XRB3w2JZykvYNOTSG+BkJMG8pQm4SCak4V8js9T0xhOcwE/irNGlacpVnHe0TlQ9tGFcP46Q3BGGn529N3ocwpeJSmggzEmEy1xpioDSDgkts113FOZD1aueHiq3tC2q5kmHEDCs7vcRnKFaWxvAPsZzcQI+NuYoh6Zu/gXlr9+b2hKyCmd/B+CsezgZdiK77tSSHLJg7TaZS6QrfTBf9L2vtlZBHn2j+/IYTs3U1OQUUN+M1erz/fKoJKNAwmE7B3RTYa4yDUbY5XCUhBcYTalRnNKx3VKpXDyoFncUqvk6NUPbDtt/zWGlHdeUrzUy+tV2kxo/jOhHWks4cVJBppEKtACKcGbkygVQ2XRlOaMwh8NykDLIRvn5vdLXuIfdY/eGl9Qdh/finVFBXVBZv97nxZW1T5WOhUMPHxdppG0baZjQMFUjLNqOWdnOsYJmSsuKRcNS2rbFyxrfBScOKS1JMvrc+p1O4m9p1FfK8P+jWIU7okimk4nWJKF804Ak+tIx5H1E/kSd2D6M7qJ8Kpe1u2tu24HH5ZrH1qg5lU7yaSoNl591mvfzqYL2ac6xQukFbDRthomMwwKberXNcNWeDiwBVuRhi6sCmkQgaeAyQ7cCEmth7gurbfWEOyLK5hivf+FEtJpnNL65gjcSrFDLVzpGArtl2qMbBxBnqluUSYpmBS57x2hXTuEiAWt5ttMHXk9O9NR5AEf18oUyAgL52COGoaodKEOM4YkFyO2/q5pFzidm+kXg74gIe8rvhzG2AgGf5owmOlie8qCBEQo3pskKqWY5ZVUauUOibFTcxMqVINdIo9vBvzPjd/5S+/tD5J27+bXunUvdHuNvFUNDpRSgKQZCjvRK1ruErdibIqgcVO+AWBHQc08frs7bvhd9KoL87f9/9EURiI4QciUeDG1a98+qlrybR0cKPT7XXOmjM/JRtjX1WDoYeXGEpJZAM+9pzUbVVx93nOdfUKuGAc9ffw3gcpONNSmXWreRtM/HQtguzFgfAq0eM/LKLH0t0OQRbvTUWP9lm7eTpYrpcMhmKBAn/ytdm5RdRTa1lISyTFCce6bZveieNVuLGY6XgY0SOG858XcJZUEQNksHJINguGMYFfwSIViOu4iNyhimnWPFamLncEkYKJ6HKwiIVpDxFObPDIrFYJPDKwD6Yqg0m2NQb6PpVTFTISZSjUYDwmji0ENttR+MOjwq1TPkOB22WxFWlbpvvAxh1Ld9cT9vfcTe1gGDRvtHq9bmc+dh7LYQRGPw1G4bQxu/LBxCvzcFW055k4oo3XvZyIXE4IySpb16zvNAl8axHUqxuk8VQyFK4F9RmGSYxhGmJTQsU8EdewACSug7vC7QWgVaahOtFlPFaKwbc65+32gwvqsfdCQrU654jE6wdSDQoJkoW6NBqPIZiPcBdDY9o4zmWzxUzuaL+S1WmuXKqqetWyLGoVlKpJNJMoRrLZ5fR2e7054co44lMm4+46OcE065vSJZRESjUkCZ0CeQR3coWjokLznGeowrlV4zkja9uWXmEQGM0q0Pgkg2/eavudB3fKFFuIucFCBvDsa1N8EYLJaXOe4ka2nZDHeNbTj20WFkfzrut53anU8TIkD3dIP2o51vYC49ZdK5eSx+ICug0wfu5uorVwdhFBs3fanze+JCQRTFVNBhp34PXxXBx3f9ZFtCbwxMWZrTotulW7LjMPh70vK3NJGLFaffJuck8YzgZGRa35WMIajDJ2eLoux62lTnR9Dba/YNER68AmQHQKWxnK9uBx7zuR9v75/IVfcTeuzC1TkF+AZ59MyeKs2+6eLk+S0yBIMJ0QMGmVgSVYXLNMWi6VCa1ShVBmq7mDjHZEnUp0+romhp3vAezfXZ+YRe74vpR1J3kiWoHwG/7IbxDkuuV8tVKiWj5vZYpuOVNWHI87DsNFKxTXrdiOXUt521vtddve9TaIwd31dnq0999IhY3YtmNOAlhCIYZLLFq+xnReylWrtnArWVER5aIiiMqFjTvpyuCz1oqKvfP2Q9jgPby7noYgj/zp9N7rOWeM2ttiGCOiBYoYaTJHeEmzmFE6dgzDEjlp5I6FIatlhdmiigvUjNTe69PbG+4c2Hmn0uN319P0J+8mJkxnJaBBp4v13ihN10bqZDol/gTYvOYPvVDnhBIFh+Krlpa1qW6Sil4hVi2rq4c5LVPNlrIPqQQU9xu+dgOMu8lqQ7QArnPWaQ3a81uvZzpFImGo44miEc4cQk0O1l41aO0Rq6SDjeequVJOK5JioVy2ikmB9M5bzVspo2/vVJWLQ/q3bsDym/DsE+kC41m/05tX5SIpKMqoIcIpmY7Hkug2w432RMiqy5hwTFsvua5LC66XKeQY0Q/LyRU+7UHizpTk+pudCifv2BBEfutuYs9s1HPY7kAk7M+2pyVxTBDHHQtou2OI6D4LOZvPcl08O8bCO25gcejWILJLKFwYyHs2mDqy+Y+mmouTzH359lOcOJuqATV1TA1rOP6Doz8gAJMzrJ9g4Qcbix/aJYcxjE9u4IkY5L8vEUnSAX1KAvn/kHFEFn1FFY2biqLbZqZqHRPbZKRmM2YzE96dWmbNqlmmleKJwHf7G0P6VSJJDOPnNkgDYXxPirYn6ZUIwfUGU6SKgaJINQirWYNnyhWT6TZllFsqx02VnGmWVdWZRSE6bq//7FYcjbOPX7gbdx0u8yhkK9+dgjFnJvPF5EtBjKeTCeazzOZOHakhXnkdrSIy4XtdYvHBkTx9KpXcyJfkJ8ket8vhGC7j4JMb8kGMKD+UPkBIRI+FFBpEJWEwlSGziYxufxfUjbYUwJsDZZSzq70FtocmgbTb563OxgBy/3p1/vgCyd0NSDCovD+BJB1AUiDCEZAV6tjuiT47See4lg832/No8UK0rBzcVpK3t9rn7c7G8HH/SIZLE/nNDUgwpHwoXTFJhI9wLBthMAzCqTbU/GCsEIFXsQoczML3hkyqHm1ZR3ng6hhsD7vC7rR7L61MBI/f2uCwMKB8ONWwngweCzmIEbCs0US5Y9ulqmGbZplzanOb8SJ3bGo71MZbTU3TtLdX3XcKHjHx/b27692Gj342fUkgEN+zXmcAIOIUZIYiHMnReBQqYRhOTUw+LIjjlYx9dGBoatFg2Zqi1a5B8LhefeRIe6QQz4+2bzX9jt9ebZ9cNOceXCUh+f35y39lQ0rV/mx6IcnpjV6v3T8b7P0rwPMuxIO6FZKp5ofjCY59S6tk8gJThMayjxwV8nq2Ui2Ia/liIbevKMaRppJcKcbTutU6b573z/EMNNWKv2gQO1xBdGHvxnzf/8Jc/qcNCfsrAdFHEszxFFzYabMzv2lkaSYNbSoDAAYJu8TWSdcklqA22EndAtO3BRPuiWIQvJxna0TZ7aaRGA== diff --git a/libgo/go/compress/lzw/reader.go b/libgo/go/compress/lzw/reader.go index 1be52d55e4f..f08021190c2 100644 --- a/libgo/go/compress/lzw/reader.go +++ b/libgo/go/compress/lzw/reader.go @@ -63,8 +63,7 @@ type decoder struct { // // last is the most recently seen code, or decoderInvalidCode. // - // An invariant is that - // (hi < overflow) || (hi == overflow && last == decoderInvalidCode) + // An invariant is that hi < overflow. clear, eof, hi, overflow, last uint16 // Each code c in [lo, hi] expands to two or more bytes. For c != hi: @@ -200,15 +199,18 @@ loop: } d.last, d.hi = code, d.hi+1 if d.hi >= d.overflow { + if d.hi > d.overflow { + panic("unreachable") + } if d.width == maxWidth { d.last = decoderInvalidCode // Undo the d.hi++ a few lines above, so that (1) we maintain - // the invariant that d.hi <= d.overflow, and (2) d.hi does not + // the invariant that d.hi < d.overflow, and (2) d.hi does not // eventually overflow a uint16. d.hi-- } else { d.width++ - d.overflow <<= 1 + d.overflow = 1 << d.width } } if d.o >= flushBuffer { diff --git a/libgo/go/context/context.go b/libgo/go/context/context.go index 62590850a66..b561968f31c 100644 --- a/libgo/go/context/context.go +++ b/libgo/go/context/context.go @@ -51,6 +51,7 @@ import ( "errors" "internal/reflectlite" "sync" + "sync/atomic" "time" ) @@ -67,6 +68,8 @@ type Context interface { // Done returns a channel that's closed when work done on behalf of this // context should be canceled. Done may return nil if this context can // never be canceled. Successive calls to Done return the same value. + // The close of the Done channel may happen asynchronously, + // after the cancel function returns. // // WithCancel arranges for Done to be closed when cancel is called; // WithDeadline arranges for Done to be closed when the deadline @@ -237,11 +240,24 @@ func newCancelCtx(parent Context) cancelCtx { return cancelCtx{Context: parent} } +// goroutines counts the number of goroutines ever created; for testing. +var goroutines int32 + // propagateCancel arranges for child to be canceled when parent is. func propagateCancel(parent Context, child canceler) { - if parent.Done() == nil { + done := parent.Done() + if done == nil { return // parent is never canceled } + + select { + case <-done: + // parent is already canceled + child.cancel(false, parent.Err()) + return + default: + } + if p, ok := parentCancelCtx(parent); ok { p.mu.Lock() if p.err != nil { @@ -255,6 +271,7 @@ func propagateCancel(parent Context, child canceler) { } p.mu.Unlock() } else { + atomic.AddInt32(&goroutines, +1) go func() { select { case <-parent.Done(): @@ -265,22 +282,31 @@ func propagateCancel(parent Context, child canceler) { } } -// parentCancelCtx follows a chain of parent references until it finds a -// *cancelCtx. This function understands how each of the concrete types in this -// package represents its parent. +// &cancelCtxKey is the key that a cancelCtx returns itself for. +var cancelCtxKey int + +// parentCancelCtx returns the underlying *cancelCtx for parent. +// It does this by looking up parent.Value(&cancelCtxKey) to find +// the innermost enclosing *cancelCtx and then checking whether +// parent.Done() matches that *cancelCtx. (If not, the *cancelCtx +// has been wrapped in a custom implementation providing a +// different done channel, in which case we should not bypass it.) func parentCancelCtx(parent Context) (*cancelCtx, bool) { - for { - switch c := parent.(type) { - case *cancelCtx: - return c, true - case *timerCtx: - return &c.cancelCtx, true - case *valueCtx: - parent = c.Context - default: - return nil, false - } + done := parent.Done() + if done == closedchan || done == nil { + return nil, false + } + p, ok := parent.Value(&cancelCtxKey).(*cancelCtx) + if !ok { + return nil, false } + p.mu.Lock() + ok = p.done == done + p.mu.Unlock() + if !ok { + return nil, false + } + return p, true } // removeChild removes a context from its parent. @@ -321,6 +347,13 @@ type cancelCtx struct { err error // set to non-nil by the first cancel call } +func (c *cancelCtx) Value(key interface{}) interface{} { + if key == &cancelCtxKey { + return c + } + return c.Context.Value(key) +} + func (c *cancelCtx) Done() <-chan struct{} { c.mu.Lock() if c.done == nil { diff --git a/libgo/go/context/context_test.go b/libgo/go/context/context_test.go index b07a5cfce64..cff09fd322f 100644 --- a/libgo/go/context/context_test.go +++ b/libgo/go/context/context_test.go @@ -10,6 +10,7 @@ import ( "runtime" "strings" "sync" + "sync/atomic" "time" ) @@ -21,6 +22,7 @@ type testingT interface { Failed() bool Fatal(args ...interface{}) Fatalf(format string, args ...interface{}) + Helper() Log(args ...interface{}) Logf(format string, args ...interface{}) Name() string @@ -251,6 +253,7 @@ func XTestChildFinishesFirst(t testingT) { } func testDeadline(c Context, name string, failAfter time.Duration, t testingT) { + t.Helper() select { case <-time.After(failAfter): t.Fatalf("%s: context should have timed out", name) @@ -401,8 +404,8 @@ func XTestAllocs(t testingT, testingShort func() bool, testingAllocsPerRun func( c, _ := WithTimeout(bg, 15*time.Millisecond) <-c.Done() }, - limit: 8, - gccgoLimit: 18, + limit: 12, + gccgoLimit: 15, }, { desc: "WithCancel(bg)", @@ -648,3 +651,81 @@ func XTestDeadlineExceededSupportsTimeout(t testingT) { t.Fatal("wrong value for timeout") } } + +type myCtx struct { + Context +} + +type myDoneCtx struct { + Context +} + +func (d *myDoneCtx) Done() <-chan struct{} { + c := make(chan struct{}) + return c +} + +func XTestCustomContextGoroutines(t testingT) { + g := atomic.LoadInt32(&goroutines) + checkNoGoroutine := func() { + t.Helper() + now := atomic.LoadInt32(&goroutines) + if now != g { + t.Fatalf("%d goroutines created", now-g) + } + } + checkCreatedGoroutine := func() { + t.Helper() + now := atomic.LoadInt32(&goroutines) + if now != g+1 { + t.Fatalf("%d goroutines created, want 1", now-g) + } + g = now + } + + _, cancel0 := WithCancel(&myDoneCtx{Background()}) + cancel0() + checkCreatedGoroutine() + + _, cancel0 = WithTimeout(&myDoneCtx{Background()}, 1*time.Hour) + cancel0() + checkCreatedGoroutine() + + checkNoGoroutine() + defer checkNoGoroutine() + + ctx1, cancel1 := WithCancel(Background()) + defer cancel1() + checkNoGoroutine() + + ctx2 := &myCtx{ctx1} + ctx3, cancel3 := WithCancel(ctx2) + defer cancel3() + checkNoGoroutine() + + _, cancel3b := WithCancel(&myDoneCtx{ctx2}) + defer cancel3b() + checkCreatedGoroutine() // ctx1 is not providing Done, must not be used + + ctx4, cancel4 := WithTimeout(ctx3, 1*time.Hour) + defer cancel4() + checkNoGoroutine() + + ctx5, cancel5 := WithCancel(ctx4) + defer cancel5() + checkNoGoroutine() + + cancel5() + checkNoGoroutine() + + _, cancel6 := WithTimeout(ctx5, 1*time.Hour) + defer cancel6() + checkNoGoroutine() + + // Check applied to cancelled context. + cancel6() + cancel1() + _, cancel7 := WithCancel(ctx5) + defer cancel7() + checkNoGoroutine() +} diff --git a/libgo/go/context/x_test.go b/libgo/go/context/x_test.go index d14b6f1a32b..e85ef2d50e5 100644 --- a/libgo/go/context/x_test.go +++ b/libgo/go/context/x_test.go @@ -27,3 +27,4 @@ func TestCancelRemoves(t *testing.T) { XTestCancelRemoves(t) } func TestWithCancelCanceledParent(t *testing.T) { XTestWithCancelCanceledParent(t) } func TestWithValueChecksKey(t *testing.T) { XTestWithValueChecksKey(t) } func TestDeadlineExceededSupportsTimeout(t *testing.T) { XTestDeadlineExceededSupportsTimeout(t) } +func TestCustomContextGoroutines(t *testing.T) { XTestCustomContextGoroutines(t) } diff --git a/libgo/go/crypto/aes/gcm_ppc64le.go b/libgo/go/crypto/aes/gcm_ppc64le.go new file mode 100644 index 00000000000..707478c6d2e --- /dev/null +++ b/libgo/go/crypto/aes/gcm_ppc64le.go @@ -0,0 +1,258 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore +// +build ppc64le + +package aes + +import ( + "crypto/cipher" + "crypto/subtle" + "encoding/binary" + "errors" +) + +// This file implements GCM using an optimized GHASH function. + +//go:noescape +func gcmInit(productTable *[256]byte, h []byte) + +//go:noescape +func gcmHash(output []byte, productTable *[256]byte, inp []byte, len int) + +//go:noescape +func gcmMul(output []byte, productTable *[256]byte) + +const ( + gcmCounterSize = 16 + gcmBlockSize = 16 + gcmTagSize = 16 + gcmStandardNonceSize = 12 +) + +var errOpen = errors.New("cipher: message authentication failed") + +// Assert that aesCipherGCM implements the gcmAble interface. +var _ gcmAble = (*aesCipherAsm)(nil) + +type gcmAsm struct { + cipher *aesCipherAsm + // ks is the key schedule, the length of which depends on the size of + // the AES key. + ks []uint32 + // productTable contains pre-computed multiples of the binary-field + // element used in GHASH. + productTable [256]byte + // nonceSize contains the expected size of the nonce, in bytes. + nonceSize int + // tagSize contains the size of the tag, in bytes. + tagSize int +} + +// NewGCM returns the AES cipher wrapped in Galois Counter Mode. This is only +// called by crypto/cipher.NewGCM via the gcmAble interface. +func (c *aesCipherAsm) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) { + g := &gcmAsm{cipher: c, ks: c.enc, nonceSize: nonceSize, tagSize: tagSize} + + hle := make([]byte, gcmBlockSize) + c.Encrypt(hle, hle) + + // Reverse the bytes in each 8 byte chunk + // Load little endian, store big endian + h1 := binary.LittleEndian.Uint64(hle[:8]) + h2 := binary.LittleEndian.Uint64(hle[8:]) + binary.BigEndian.PutUint64(hle[:8], h1) + binary.BigEndian.PutUint64(hle[8:], h2) + gcmInit(&g.productTable, hle) + + return g, nil +} + +func (g *gcmAsm) NonceSize() int { + return g.nonceSize +} + +func (g *gcmAsm) Overhead() int { + return g.tagSize +} + +func sliceForAppend(in []byte, n int) (head, tail []byte) { + if total := len(in) + n; cap(in) >= total { + head = in[:total] + } else { + head = make([]byte, total) + copy(head, in) + } + tail = head[len(in):] + return +} + +// deriveCounter computes the initial GCM counter state from the given nonce. +func (g *gcmAsm) deriveCounter(counter *[gcmBlockSize]byte, nonce []byte) { + if len(nonce) == gcmStandardNonceSize { + copy(counter[:], nonce) + counter[gcmBlockSize-1] = 1 + } else { + var hash [16]byte + g.paddedGHASH(&hash, nonce) + lens := gcmLengths(0, uint64(len(nonce))*8) + g.paddedGHASH(&hash, lens[:]) + copy(counter[:], hash[:]) + } +} + +// counterCrypt encrypts in using AES in counter mode and places the result +// into out. counter is the initial count value and will be updated with the next +// count value. The length of out must be greater than or equal to the length +// of in. +func (g *gcmAsm) counterCrypt(out, in []byte, counter *[gcmBlockSize]byte) { + var mask [gcmBlockSize]byte + + for len(in) >= gcmBlockSize { + // Hint to avoid bounds check + _, _ = in[15], out[15] + g.cipher.Encrypt(mask[:], counter[:]) + gcmInc32(counter) + + // XOR 16 bytes each loop iteration in 8 byte chunks + in0 := binary.LittleEndian.Uint64(in[0:]) + in1 := binary.LittleEndian.Uint64(in[8:]) + m0 := binary.LittleEndian.Uint64(mask[:8]) + m1 := binary.LittleEndian.Uint64(mask[8:]) + binary.LittleEndian.PutUint64(out[:8], in0^m0) + binary.LittleEndian.PutUint64(out[8:], in1^m1) + out = out[16:] + in = in[16:] + } + + if len(in) > 0 { + g.cipher.Encrypt(mask[:], counter[:]) + gcmInc32(counter) + // XOR leftover bytes + for i, inb := range in { + out[i] = inb ^ mask[i] + } + } +} + +// increments the rightmost 32-bits of the count value by 1. +func gcmInc32(counterBlock *[16]byte) { + c := counterBlock[len(counterBlock)-4:] + x := binary.BigEndian.Uint32(c) + 1 + binary.BigEndian.PutUint32(c, x) +} + +// paddedGHASH pads data with zeroes until its length is a multiple of +// 16-bytes. It then calculates a new value for hash using the ghash +// algorithm. +func (g *gcmAsm) paddedGHASH(hash *[16]byte, data []byte) { + if siz := len(data) - (len(data) % gcmBlockSize); siz > 0 { + gcmHash(hash[:], &g.productTable, data[:], siz) + data = data[siz:] + } + if len(data) > 0 { + var s [16]byte + copy(s[:], data) + gcmHash(hash[:], &g.productTable, s[:], len(s)) + } +} + +// auth calculates GHASH(ciphertext, additionalData), masks the result with +// tagMask and writes the result to out. +func (g *gcmAsm) auth(out, ciphertext, aad []byte, tagMask *[gcmTagSize]byte) { + var hash [16]byte + g.paddedGHASH(&hash, aad) + g.paddedGHASH(&hash, ciphertext) + lens := gcmLengths(uint64(len(aad))*8, uint64(len(ciphertext))*8) + g.paddedGHASH(&hash, lens[:]) + + copy(out, hash[:]) + for i := range out { + out[i] ^= tagMask[i] + } +} + +// Seal encrypts and authenticates plaintext. See the cipher.AEAD interface for +// details. +func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte { + if len(nonce) != g.nonceSize { + panic("cipher: incorrect nonce length given to GCM") + } + if uint64(len(plaintext)) > ((1<<32)-2)*BlockSize { + panic("cipher: message too large for GCM") + } + + ret, out := sliceForAppend(dst, len(plaintext)+g.tagSize) + + var counter, tagMask [gcmBlockSize]byte + g.deriveCounter(&counter, nonce) + + g.cipher.Encrypt(tagMask[:], counter[:]) + gcmInc32(&counter) + + g.counterCrypt(out, plaintext, &counter) + g.auth(out[len(plaintext):], out[:len(plaintext)], data, &tagMask) + + return ret +} + +// Open authenticates and decrypts ciphertext. See the cipher.AEAD interface +// for details. +func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { + if len(nonce) != g.nonceSize { + panic("cipher: incorrect nonce length given to GCM") + } + if len(ciphertext) < g.tagSize { + return nil, errOpen + } + if uint64(len(ciphertext)) > ((1<<32)-2)*uint64(BlockSize)+uint64(g.tagSize) { + return nil, errOpen + } + + tag := ciphertext[len(ciphertext)-g.tagSize:] + ciphertext = ciphertext[:len(ciphertext)-g.tagSize] + + var counter, tagMask [gcmBlockSize]byte + g.deriveCounter(&counter, nonce) + + g.cipher.Encrypt(tagMask[:], counter[:]) + gcmInc32(&counter) + + var expectedTag [gcmTagSize]byte + g.auth(expectedTag[:], ciphertext, data, &tagMask) + + ret, out := sliceForAppend(dst, len(ciphertext)) + + if subtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 { + for i := range out { + out[i] = 0 + } + return nil, errOpen + } + + g.counterCrypt(out, ciphertext, &counter) + return ret, nil +} + +func gcmLengths(len0, len1 uint64) [16]byte { + return [16]byte{ + byte(len0 >> 56), + byte(len0 >> 48), + byte(len0 >> 40), + byte(len0 >> 32), + byte(len0 >> 24), + byte(len0 >> 16), + byte(len0 >> 8), + byte(len0), + byte(len1 >> 56), + byte(len1 >> 48), + byte(len1 >> 40), + byte(len1 >> 32), + byte(len1 >> 24), + byte(len1 >> 16), + byte(len1 >> 8), + byte(len1), + } +} diff --git a/libgo/go/crypto/dsa/dsa.go b/libgo/go/crypto/dsa/dsa.go index 575314b1b46..43826bcb559 100644 --- a/libgo/go/crypto/dsa/dsa.go +++ b/libgo/go/crypto/dsa/dsa.go @@ -202,7 +202,7 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err // FIPS 186-3, section 4.6 n := priv.Q.BitLen() - if priv.Q.Sign() <= 0 || priv.P.Sign() <= 0 || priv.G.Sign() <= 0 || priv.X.Sign() <= 0 || n&7 != 0 { + if priv.Q.Sign() <= 0 || priv.P.Sign() <= 0 || priv.G.Sign() <= 0 || priv.X.Sign() <= 0 || n%8 != 0 { err = ErrInvalidPublicKey return } @@ -279,9 +279,12 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { } w := new(big.Int).ModInverse(s, pub.Q) + if w == nil { + return false + } n := pub.Q.BitLen() - if n&7 != 0 { + if n%8 != 0 { return false } z := new(big.Int).SetBytes(hash) diff --git a/libgo/go/crypto/dsa/dsa_test.go b/libgo/go/crypto/dsa/dsa_test.go index 7fc246bc2bd..28ac00e6ce6 100644 --- a/libgo/go/crypto/dsa/dsa_test.go +++ b/libgo/go/crypto/dsa/dsa_test.go @@ -97,6 +97,21 @@ func TestSignAndVerify(t *testing.T) { testSignAndVerify(t, 0, &priv) } +func TestSignAndVerifyWithBadPublicKey(t *testing.T) { + pub := PublicKey{ + Parameters: Parameters{ + P: fromHex("A9B5B793FB4785793D246BAE77E8FF63CA52F442DA763C440259919FE1BC1D6065A9350637A04F75A2F039401D49F08E066C4D275A5A65DA5684BC563C14289D7AB8A67163BFBF79D85972619AD2CFF55AB0EE77A9002B0EF96293BDD0F42685EBB2C66C327079F6C98000FBCB79AACDE1BC6F9D5C7B1A97E3D9D54ED7951FEF"), + Q: fromHex("FA"), + G: fromHex("634364FC25248933D01D1993ECABD0657CC0CB2CEED7ED2E3E8AECDFCDC4A25C3B15E9E3B163ACA2984B5539181F3EFF1A5E8903D71D5B95DA4F27202B77D2C44B430BB53741A8D59A8F86887525C9F2A6A5980A195EAA7F2FF910064301DEF89D3AA213E1FAC7768D89365318E370AF54A112EFBA9246D9158386BA1B4EEFDA"), + }, + Y: fromHex("32969E5780CFE1C849A1C276D7AEB4F38A23B591739AA2FE197349AEEBD31366AEE5EB7E6C6DDB7C57D02432B30DB5AA66D9884299FAA72568944E4EEDC92EA3FBC6F39F53412FBCC563208F7C15B737AC8910DBC2D9C9B8C001E72FDC40EB694AB1F06A5A2DBD18D9E36C66F31F566742F11EC0A52E9F7B89355C02FB5D32D2"), + } + + if Verify(&pub, []byte("testing"), fromHex("2"), fromHex("4")) { + t.Errorf("Verify unexpected success with non-existent mod inverse of Q") + } +} + func TestSigningWithDegenerateKeys(t *testing.T) { // Signing with degenerate private keys should not cause an infinite // loop. diff --git a/libgo/go/crypto/ecdsa/ecdsa.go b/libgo/go/crypto/ecdsa/ecdsa.go index ddc3b35ba30..65911e737ac 100644 --- a/libgo/go/crypto/ecdsa/ecdsa.go +++ b/libgo/go/crypto/ecdsa/ecdsa.go @@ -5,13 +5,23 @@ // Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as // defined in FIPS 186-3. // -// This implementation derives the nonce from an AES-CTR CSPRNG keyed by -// ChopMD(256, SHA2-512(priv.D || entropy || hash)). The CSPRNG key is IRO by -// a result of Coron; the AES-CTR stream is IRO under standard assumptions. +// This implementation derives the nonce from an AES-CTR CSPRNG keyed by: +// +// SHA2-512(priv.D || entropy || hash)[:32] +// +// The CSPRNG key is indifferentiable from a random oracle as shown in +// [Coron], the AES-CTR stream is indifferentiable from a random oracle +// under standard cryptographic assumptions (see [Larsson] for examples). +// +// References: +// [Coron] +// https://cs.nyu.edu/~dodis/ps/merkle.pdf +// [Larsson] +// https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf package ecdsa -// References: -// [NSA]: Suite B implementer's guide to FIPS 186-3, +// Further references: +// [NSA]: Suite B implementer's guide to FIPS 186-3 // https://apps.nsa.gov/iaarchive/library/ia-guidance/ia-solutions-for-classified/algorithm-guidance/suite-b-implementers-guide-to-fips-186-3-ecdsa.cfm // [SECG]: SECG, SEC1 // http://www.secg.org/sec1-v2.pdf @@ -189,21 +199,14 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err // See [NSA] 3.4.1 c := priv.PublicKey.Curve - e := hashToInt(hash, c) - r, s, err = sign(priv, &csprng, c, e) - return -} - -func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, e *big.Int) (r, s *big.Int, err error) { N := c.Params().N if N.Sign() == 0 { return nil, nil, errZeroParam } - var k, kInv *big.Int for { for { - k, err = randFieldElement(c, *csprng) + k, err = randFieldElement(c, csprng) if err != nil { r = nil return @@ -221,6 +224,8 @@ func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve break } } + + e := hashToInt(hash, c) s = new(big.Int).Mul(priv.D, r) s.Add(s, e) s.Mul(s, kInv) @@ -229,6 +234,7 @@ func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve break } } + return } @@ -246,12 +252,8 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { return false } e := hashToInt(hash, c) - return verify(pub, c, e, r, s) -} -func verifyGeneric(pub *PublicKey, c elliptic.Curve, e, r, s *big.Int) bool { var w *big.Int - N := c.Params().N if in, ok := c.(invertible); ok { w = in.Inverse(s) } else { diff --git a/libgo/go/crypto/ecdsa/ecdsa_noasm.go b/libgo/go/crypto/ecdsa/ecdsa_noasm.go deleted file mode 100644 index d9f9cffd855..00000000000 --- a/libgo/go/crypto/ecdsa/ecdsa_noasm.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !s390x gccgo - -package ecdsa - -import ( - "crypto/cipher" - "crypto/elliptic" - "math/big" -) - -func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, e *big.Int) (r, s *big.Int, err error) { - r, s, err = signGeneric(priv, csprng, c, e) - return -} - -func verify(pub *PublicKey, c elliptic.Curve, e, r, s *big.Int) bool { - return verifyGeneric(pub, c, e, r, s) -} diff --git a/libgo/go/crypto/ecdsa/ecdsa_s390x.go b/libgo/go/crypto/ecdsa/ecdsa_s390x.go deleted file mode 100644 index f07c3bf50c2..00000000000 --- a/libgo/go/crypto/ecdsa/ecdsa_s390x.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build s390x,!gccgo - -package ecdsa - -import ( - "crypto/cipher" - "crypto/elliptic" - "internal/cpu" - "math/big" -) - -// s390x accelerated signatures -//go:noescape -func kdsaSig(fc uint64, block *[1720]byte) (errn uint64) - -type signverify int - -const ( - signing signverify = iota - verifying -) - -// bufferOffsets represents the offset of a particular parameter in -// the buffer passed to the KDSA instruction. -type bufferOffsets struct { - baseSize int - hashSize int - offsetHash int - offsetKey1 int - offsetRNorKey2 int - offsetR int - offsetS int - functionCode uint64 -} - -func canUseKDSA(sv signverify, c elliptic.Curve, bo *bufferOffsets) bool { - if !cpu.S390X.HasECDSA { - return false - } - - switch c.Params().Name { - case "P-256": - bo.baseSize = 32 - bo.hashSize = 32 - bo.offsetHash = 64 - bo.offsetKey1 = 96 - bo.offsetRNorKey2 = 128 - bo.offsetR = 0 - bo.offsetS = 32 - if sv == signing { - bo.functionCode = 137 - } else { - bo.functionCode = 1 - } - return true - case "P-384": - bo.baseSize = 48 - bo.hashSize = 48 - bo.offsetHash = 96 - bo.offsetKey1 = 144 - bo.offsetRNorKey2 = 192 - bo.offsetR = 0 - bo.offsetS = 48 - if sv == signing { - bo.functionCode = 138 - } else { - bo.functionCode = 2 - } - return true - case "P-521": - bo.baseSize = 66 - bo.hashSize = 80 - bo.offsetHash = 160 - bo.offsetKey1 = 254 - bo.offsetRNorKey2 = 334 - bo.offsetR = 14 - bo.offsetS = 94 - if sv == signing { - bo.functionCode = 139 - } else { - bo.functionCode = 3 - } - return true - } - return false -} - -// zeroExtendAndCopy pads src with leading zeros until it has the size given. -// It then copies the padded src into the dst. Bytes beyond size in dst are -// not modified. -func zeroExtendAndCopy(dst, src []byte, size int) { - nz := size - len(src) - if nz < 0 { - panic("src is too long") - } - // the compiler should replace this loop with a memclr call - z := dst[:nz] - for i := range z { - z[i] = 0 - } - copy(dst[nz:size], src[:size-nz]) - return -} - -func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, e *big.Int) (r, s *big.Int, err error) { - var bo bufferOffsets - if canUseKDSA(signing, c, &bo) && e.Sign() != 0 { - var buffer [1720]byte - for { - var k *big.Int - k, err = randFieldElement(c, csprng) - if err != nil { - return nil, nil, err - } - zeroExtendAndCopy(buffer[bo.offsetHash:], e.Bytes(), bo.hashSize) - zeroExtendAndCopy(buffer[bo.offsetKey1:], priv.D.Bytes(), bo.baseSize) - zeroExtendAndCopy(buffer[bo.offsetRNorKey2:], k.Bytes(), bo.baseSize) - errn := kdsaSig(bo.functionCode, &buffer) - if errn == 2 { - return nil, nil, errZeroParam - } - if errn == 0 { // success == 0 means successful signing - r = new(big.Int) - r.SetBytes(buffer[bo.offsetR : bo.offsetR+bo.baseSize]) - s = new(big.Int) - s.SetBytes(buffer[bo.offsetS : bo.offsetS+bo.baseSize]) - return - } - //at this point, it must be that errn == 1: retry - } - } - r, s, err = signGeneric(priv, csprng, c, e) - return -} - -func verify(pub *PublicKey, c elliptic.Curve, e, r, s *big.Int) bool { - var bo bufferOffsets - if canUseKDSA(verifying, c, &bo) && e.Sign() != 0 { - var buffer [1720]byte - zeroExtendAndCopy(buffer[bo.offsetR:], r.Bytes(), bo.baseSize) - zeroExtendAndCopy(buffer[bo.offsetS:], s.Bytes(), bo.baseSize) - zeroExtendAndCopy(buffer[bo.offsetHash:], e.Bytes(), bo.hashSize) - zeroExtendAndCopy(buffer[bo.offsetKey1:], pub.X.Bytes(), bo.baseSize) - zeroExtendAndCopy(buffer[bo.offsetRNorKey2:], pub.Y.Bytes(), bo.baseSize) - errn := kdsaSig(bo.functionCode, &buffer) - return errn == 0 - } - return verifyGeneric(pub, c, e, r, s) -} diff --git a/libgo/go/crypto/ecdsa/ecdsa_s390x_test.go b/libgo/go/crypto/ecdsa/ecdsa_s390x_test.go deleted file mode 100644 index 80babc9cb42..00000000000 --- a/libgo/go/crypto/ecdsa/ecdsa_s390x_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build s390x,!gccgo - -package ecdsa - -import ( - "crypto/elliptic" - "testing" -) - -func TestNoAsm(t *testing.T) { - curves := [...]elliptic.Curve{ - elliptic.P256(), - elliptic.P384(), - elliptic.P521(), - } - - for _, curve := range curves { - // override the name of the curve to stop the assembly path being taken - params := *curve.Params() - name := params.Name - params.Name = name + "_GENERIC_OVERRIDE" - - testKeyGeneration(t, ¶ms, name) - testSignAndVerify(t, ¶ms, name) - testNonceSafety(t, ¶ms, name) - testINDCCA(t, ¶ms, name) - testNegativeInputs(t, ¶ms, name) - } -} diff --git a/libgo/go/crypto/ed25519/ed25519.go b/libgo/go/crypto/ed25519/ed25519.go index dc47e5585d6..dcb4f9544f9 100644 --- a/libgo/go/crypto/ed25519/ed25519.go +++ b/libgo/go/crypto/ed25519/ed25519.go @@ -96,6 +96,13 @@ func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { // with RFC 8032. RFC 8032's private keys correspond to seeds in this // package. func NewKeyFromSeed(seed []byte) PrivateKey { + // Outline the function body so that the returned key can be stack-allocated. + privateKey := make([]byte, PrivateKeySize) + newKeyFromSeed(privateKey, seed) + return privateKey +} + +func newKeyFromSeed(privateKey, seed []byte) { if l := len(seed); l != SeedSize { panic("ed25519: bad seed length: " + strconv.Itoa(l)) } @@ -112,16 +119,21 @@ func NewKeyFromSeed(seed []byte) PrivateKey { var publicKeyBytes [32]byte A.ToBytes(&publicKeyBytes) - privateKey := make([]byte, PrivateKeySize) copy(privateKey, seed) copy(privateKey[32:], publicKeyBytes[:]) - - return privateKey } // Sign signs the message with privateKey and returns a signature. It will // panic if len(privateKey) is not PrivateKeySize. func Sign(privateKey PrivateKey, message []byte) []byte { + // Outline the function body so that the returned signature can be + // stack-allocated. + signature := make([]byte, SignatureSize) + sign(signature, privateKey, message) + return signature +} + +func sign(signature, privateKey, message []byte) { if l := len(privateKey); l != PrivateKeySize { panic("ed25519: bad private key length: " + strconv.Itoa(l)) } @@ -161,11 +173,8 @@ func Sign(privateKey PrivateKey, message []byte) []byte { var s [32]byte edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced) - signature := make([]byte, SignatureSize) copy(signature[:], encodedR[:]) copy(signature[32:], s[:]) - - return signature } // Verify reports whether sig is a valid signature of message by publicKey. It diff --git a/libgo/go/crypto/ed25519/ed25519_test.go b/libgo/go/crypto/ed25519/ed25519_test.go index 9c980fceff3..cacd281f1cc 100644 --- a/libgo/go/crypto/ed25519/ed25519_test.go +++ b/libgo/go/crypto/ed25519/ed25519_test.go @@ -191,6 +191,14 @@ func BenchmarkKeyGeneration(b *testing.B) { } } +func BenchmarkNewKeyFromSeed(b *testing.B) { + seed := make([]byte, SeedSize) + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = NewKeyFromSeed(seed) + } +} + func BenchmarkSigning(b *testing.B) { var zero zeroReader _, priv, err := GenerateKey(zero) @@ -198,6 +206,7 @@ func BenchmarkSigning(b *testing.B) { b.Fatal(err) } message := []byte("Hello, world!") + b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { Sign(priv, message) diff --git a/libgo/go/crypto/elliptic/fuzz_test.go b/libgo/go/crypto/elliptic/fuzz_test.go index eaeed0dacce..b9209a789bf 100644 --- a/libgo/go/crypto/elliptic/fuzz_test.go +++ b/libgo/go/crypto/elliptic/fuzz_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64 arm64 +// +build amd64 arm64 ppc64le package elliptic diff --git a/libgo/go/crypto/elliptic/p256.go b/libgo/go/crypto/elliptic/p256.go index 937d2a4afea..3ad8e729926 100644 --- a/libgo/go/crypto/elliptic/p256.go +++ b/libgo/go/crypto/elliptic/p256.go @@ -85,7 +85,7 @@ func (p256Curve) ScalarMult(bigX, bigY *big.Int, scalar []byte) (x, y *big.Int) // Field elements are represented as nine, unsigned 32-bit words. // -// The value of an field element is: +// The value of a field element is: // x[0] + (x[1] * 2**29) + (x[2] * 2**57) + ... + (x[8] * 2**228) // // That is, each limb is alternately 29 or 28-bits wide in little-endian @@ -307,7 +307,7 @@ func p256Diff(out, in, in2 *[p256Limbs]uint32) { } // p256ReduceDegree sets out = tmp/R mod p where tmp contains 64-bit words with -// the same 29,28,... bit positions as an field element. +// the same 29,28,... bit positions as a field element. // // The values in field elements are in Montgomery form: x*R mod p where R = // 2**257. Since we just multiplied two Montgomery values together, the result diff --git a/libgo/go/crypto/elliptic/p256_generic.go b/libgo/go/crypto/elliptic/p256_generic.go index 48954a2e9c9..8e1a4125ade 100644 --- a/libgo/go/crypto/elliptic/p256_generic.go +++ b/libgo/go/crypto/elliptic/p256_generic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// -build !amd64,!s390x,!arm64 +// -build !amd64,!s390x,!arm64,!ppc64le package elliptic diff --git a/libgo/go/crypto/elliptic/p256_ppc64le.go b/libgo/go/crypto/elliptic/p256_ppc64le.go new file mode 100644 index 00000000000..6f721b8fc76 --- /dev/null +++ b/libgo/go/crypto/elliptic/p256_ppc64le.go @@ -0,0 +1,522 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore +// +build ppc64le + +package elliptic + +import ( + "crypto/subtle" + "encoding/binary" + "math/big" +) + +// This was ported from the s390x implementation for ppc64le. +// Some hints are included here for changes that should be +// in the big endian ppc64 implementation, however more +// investigation and testing is needed for the ppc64 big +// endian version to work. +type p256CurveFast struct { + *CurveParams +} + +type p256Point struct { + x [32]byte + y [32]byte + z [32]byte +} + +var ( + p256 Curve + p256PreFast *[37][64]p256Point +) + +func initP256Arch() { + p256 = p256CurveFast{p256Params} + initTable() + return +} + +func (curve p256CurveFast) Params() *CurveParams { + return curve.CurveParams +} + +// Functions implemented in p256_asm_ppc64le.s +// Montgomery multiplication modulo P256 +// +//go:noescape +func p256MulAsm(res, in1, in2 []byte) + +// Montgomery square modulo P256 +// +func p256Sqr(res, in []byte) { + p256MulAsm(res, in, in) +} + +// Montgomery multiplication by 1 +// +//go:noescape +func p256FromMont(res, in []byte) + +// iff cond == 1 val <- -val +// +//go:noescape +func p256NegCond(val *p256Point, cond int) + +// if cond == 0 res <- b; else res <- a +// +//go:noescape +func p256MovCond(res, a, b *p256Point, cond int) + +// Constant time table access +// +//go:noescape +func p256Select(point *p256Point, table []p256Point, idx int) + +// +//go:noescape +func p256SelectBase(point *p256Point, table []p256Point, idx int) + +// Point add with P2 being affine point +// If sign == 1 -> P2 = -P2 +// If sel == 0 -> P3 = P1 +// if zero == 0 -> P3 = P2 +// +//go:noescape +func p256PointAddAffineAsm(res, in1, in2 *p256Point, sign, sel, zero int) + +// Point add +// +//go:noescape +func p256PointAddAsm(res, in1, in2 *p256Point) int + +// +//go:noescape +func p256PointDoubleAsm(res, in *p256Point) + +// The result should be a slice in LE order, but the slice +// from big.Bytes is in BE order. +// TODO: For big endian implementation, do not reverse bytes. +// +func fromBig(big *big.Int) []byte { + // This could be done a lot more efficiently... + res := big.Bytes() + t := make([]byte, 32) + if len(res) < 32 { + copy(t[32-len(res):], res) + } else if len(res) == 32 { + copy(t, res) + } else { + copy(t, res[len(res)-32:]) + } + p256ReverseBytes(t, t) + return t +} + +// p256GetMultiplier makes sure byte array will have 32 byte elements, If the scalar +// is equal or greater than the order of the group, it's reduced modulo that order. +func p256GetMultiplier(in []byte) []byte { + n := new(big.Int).SetBytes(in) + + if n.Cmp(p256Params.N) >= 0 { + n.Mod(n, p256Params.N) + } + return fromBig(n) +} + +// p256MulAsm operates in a Montgomery domain with R = 2^256 mod p, where p is the +// underlying field of the curve. (See initP256 for the value.) Thus rr here is +// R×R mod p. See comment in Inverse about how this is used. +// TODO: For big endian implementation, the bytes in these slices should be in reverse order, +// as found in the s390x implementation. +var rr = []byte{0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00} + +// (This is one, in the Montgomery domain.) +var one = []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00} + +func maybeReduceModP(in *big.Int) *big.Int { + if in.Cmp(p256Params.P) < 0 { + return in + } + return new(big.Int).Mod(in, p256Params.P) +} + +// p256ReverseBytes copies the first 32 bytes from in to res in reverse order. +func p256ReverseBytes(res, in []byte) { + // remove bounds check + in = in[:32] + res = res[:32] + + // Load in reverse order + a := binary.BigEndian.Uint64(in[0:]) + b := binary.BigEndian.Uint64(in[8:]) + c := binary.BigEndian.Uint64(in[16:]) + d := binary.BigEndian.Uint64(in[24:]) + + // Store in normal order + binary.LittleEndian.PutUint64(res[0:], d) + binary.LittleEndian.PutUint64(res[8:], c) + binary.LittleEndian.PutUint64(res[16:], b) + binary.LittleEndian.PutUint64(res[24:], a) +} + +func (curve p256CurveFast) CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int) { + var r1, r2 p256Point + + scalarReduced := p256GetMultiplier(baseScalar) + r1IsInfinity := scalarIsZero(scalarReduced) + r1.p256BaseMult(scalarReduced) + + copy(r2.x[:], fromBig(maybeReduceModP(bigX))) + copy(r2.y[:], fromBig(maybeReduceModP(bigY))) + copy(r2.z[:], one) + p256MulAsm(r2.x[:], r2.x[:], rr[:]) + p256MulAsm(r2.y[:], r2.y[:], rr[:]) + + scalarReduced = p256GetMultiplier(scalar) + r2IsInfinity := scalarIsZero(scalarReduced) + r2.p256ScalarMult(scalarReduced) + + var sum, double p256Point + pointsEqual := p256PointAddAsm(&sum, &r1, &r2) + p256PointDoubleAsm(&double, &r1) + p256MovCond(&sum, &double, &sum, pointsEqual) + p256MovCond(&sum, &r1, &sum, r2IsInfinity) + p256MovCond(&sum, &r2, &sum, r1IsInfinity) + return sum.p256PointToAffine() +} + +func (curve p256CurveFast) ScalarBaseMult(scalar []byte) (x, y *big.Int) { + var r p256Point + reducedScalar := p256GetMultiplier(scalar) + r.p256BaseMult(reducedScalar) + return r.p256PointToAffine() +} + +func (curve p256CurveFast) ScalarMult(bigX, bigY *big.Int, scalar []byte) (x, y *big.Int) { + scalarReduced := p256GetMultiplier(scalar) + var r p256Point + copy(r.x[:], fromBig(maybeReduceModP(bigX))) + copy(r.y[:], fromBig(maybeReduceModP(bigY))) + copy(r.z[:], one) + p256MulAsm(r.x[:], r.x[:], rr[:]) + p256MulAsm(r.y[:], r.y[:], rr[:]) + r.p256ScalarMult(scalarReduced) + return r.p256PointToAffine() +} + +func scalarIsZero(scalar []byte) int { + // If any byte is not zero, return 0. + // Check for -0.... since that appears to compare to 0. + b := byte(0) + for _, s := range scalar { + b |= s + } + return subtle.ConstantTimeByteEq(b, 0) +} + +func (p *p256Point) p256PointToAffine() (x, y *big.Int) { + zInv := make([]byte, 32) + zInvSq := make([]byte, 32) + + p256Inverse(zInv, p.z[:]) + p256Sqr(zInvSq, zInv) + p256MulAsm(zInv, zInv, zInvSq) + + p256MulAsm(zInvSq, p.x[:], zInvSq) + p256MulAsm(zInv, p.y[:], zInv) + + p256FromMont(zInvSq, zInvSq) + p256FromMont(zInv, zInv) + + // SetBytes expects a slice in big endian order, + // since ppc64le is little endian, reverse the bytes. + // TODO: For big endian, bytes don't need to be reversed. + p256ReverseBytes(zInvSq, zInvSq) + p256ReverseBytes(zInv, zInv) + rx := new(big.Int).SetBytes(zInvSq) + ry := new(big.Int).SetBytes(zInv) + return rx, ry +} + +// p256Inverse sets out to in^-1 mod p. +func p256Inverse(out, in []byte) { + var stack [6 * 32]byte + p2 := stack[32*0 : 32*0+32] + p4 := stack[32*1 : 32*1+32] + p8 := stack[32*2 : 32*2+32] + p16 := stack[32*3 : 32*3+32] + p32 := stack[32*4 : 32*4+32] + + p256Sqr(out, in) + p256MulAsm(p2, out, in) // 3*p + + p256Sqr(out, p2) + p256Sqr(out, out) + p256MulAsm(p4, out, p2) // f*p + + p256Sqr(out, p4) + p256Sqr(out, out) + p256Sqr(out, out) + p256Sqr(out, out) + p256MulAsm(p8, out, p4) // ff*p + + p256Sqr(out, p8) + + for i := 0; i < 7; i++ { + p256Sqr(out, out) + } + p256MulAsm(p16, out, p8) // ffff*p + + p256Sqr(out, p16) + for i := 0; i < 15; i++ { + p256Sqr(out, out) + } + p256MulAsm(p32, out, p16) // ffffffff*p + + p256Sqr(out, p32) + + for i := 0; i < 31; i++ { + p256Sqr(out, out) + } + p256MulAsm(out, out, in) + + for i := 0; i < 32*4; i++ { + p256Sqr(out, out) + } + p256MulAsm(out, out, p32) + + for i := 0; i < 32; i++ { + p256Sqr(out, out) + } + p256MulAsm(out, out, p32) + + for i := 0; i < 16; i++ { + p256Sqr(out, out) + } + p256MulAsm(out, out, p16) + + for i := 0; i < 8; i++ { + p256Sqr(out, out) + } + p256MulAsm(out, out, p8) + + p256Sqr(out, out) + p256Sqr(out, out) + p256Sqr(out, out) + p256Sqr(out, out) + p256MulAsm(out, out, p4) + + p256Sqr(out, out) + p256Sqr(out, out) + p256MulAsm(out, out, p2) + + p256Sqr(out, out) + p256Sqr(out, out) + p256MulAsm(out, out, in) +} + +func boothW5(in uint) (int, int) { + var s uint = ^((in >> 5) - 1) + var d uint = (1 << 6) - in - 1 + d = (d & s) | (in & (^s)) + d = (d >> 1) + (d & 1) + return int(d), int(s & 1) +} + +func boothW6(in uint) (int, int) { + var s uint = ^((in >> 6) - 1) + var d uint = (1 << 7) - in - 1 + d = (d & s) | (in & (^s)) + d = (d >> 1) + (d & 1) + return int(d), int(s & 1) +} + +func boothW7(in uint) (int, int) { + var s uint = ^((in >> 7) - 1) + var d uint = (1 << 8) - in - 1 + d = (d & s) | (in & (^s)) + d = (d >> 1) + (d & 1) + return int(d), int(s & 1) +} + +func initTable() { + + p256PreFast = new([37][64]p256Point) + + // TODO: For big endian, these slices should be in reverse byte order, + // as found in the s390x implementation. + basePoint := p256Point{ + x: [32]byte{0x3c, 0x14, 0xa9, 0x18, 0xd4, 0x30, 0xe7, 0x79, 0x01, 0xb6, 0xed, 0x5f, 0xfc, 0x95, 0xba, 0x75, + 0x10, 0x25, 0x62, 0x77, 0x2b, 0x73, 0xfb, 0x79, 0xc6, 0x55, 0x37, 0xa5, 0x76, 0x5f, 0x90, 0x18}, //(p256.x*2^256)%p + y: [32]byte{0x0a, 0x56, 0x95, 0xce, 0x57, 0x53, 0xf2, 0xdd, 0x5c, 0xe4, 0x19, 0xba, 0xe4, 0xb8, 0x4a, 0x8b, + 0x25, 0xf3, 0x21, 0xdd, 0x88, 0x86, 0xe8, 0xd2, 0x85, 0x5d, 0x88, 0x25, 0x18, 0xff, 0x71, 0x85}, //(p256.y*2^256)%p + z: [32]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, //(p256.z*2^256)%p + + } + + t1 := new(p256Point) + t2 := new(p256Point) + *t2 = basePoint + + zInv := make([]byte, 32) + zInvSq := make([]byte, 32) + for j := 0; j < 64; j++ { + *t1 = *t2 + for i := 0; i < 37; i++ { + // The window size is 7 so we need to double 7 times. + if i != 0 { + for k := 0; k < 7; k++ { + p256PointDoubleAsm(t1, t1) + } + } + // Convert the point to affine form. (Its values are + // still in Montgomery form however.) + p256Inverse(zInv, t1.z[:]) + p256Sqr(zInvSq, zInv) + p256MulAsm(zInv, zInv, zInvSq) + + p256MulAsm(t1.x[:], t1.x[:], zInvSq) + p256MulAsm(t1.y[:], t1.y[:], zInv) + + copy(t1.z[:], basePoint.z[:]) + // Update the table entry + copy(p256PreFast[i][j].x[:], t1.x[:]) + copy(p256PreFast[i][j].y[:], t1.y[:]) + } + if j == 0 { + p256PointDoubleAsm(t2, &basePoint) + } else { + p256PointAddAsm(t2, t2, &basePoint) + } + } +} + +func (p *p256Point) p256BaseMult(scalar []byte) { + // TODO: For big endian, the index should be 31 not 0. + wvalue := (uint(scalar[0]) << 1) & 0xff + sel, sign := boothW7(uint(wvalue)) + p256SelectBase(p, p256PreFast[0][:], sel) + p256NegCond(p, sign) + + copy(p.z[:], one[:]) + var t0 p256Point + + copy(t0.z[:], one[:]) + + index := uint(6) + zero := sel + for i := 1; i < 37; i++ { + // TODO: For big endian, use the same index values as found + // in the s390x implementation. + if index < 247 { + wvalue = ((uint(scalar[index/8]) >> (index % 8)) + (uint(scalar[index/8+1]) << (8 - (index % 8)))) & 0xff + } else { + wvalue = (uint(scalar[index/8]) >> (index % 8)) & 0xff + } + index += 7 + sel, sign = boothW7(uint(wvalue)) + p256SelectBase(&t0, p256PreFast[i][:], sel) + p256PointAddAffineAsm(p, p, &t0, sign, sel, zero) + zero |= sel + } +} + +func (p *p256Point) p256ScalarMult(scalar []byte) { + // precomp is a table of precomputed points that stores powers of p + // from p^1 to p^16. + var precomp [16]p256Point + var t0, t1, t2, t3 p256Point + + *&precomp[0] = *p + p256PointDoubleAsm(&t0, p) + p256PointDoubleAsm(&t1, &t0) + p256PointDoubleAsm(&t2, &t1) + p256PointDoubleAsm(&t3, &t2) + *&precomp[1] = t0 + *&precomp[3] = t1 + *&precomp[7] = t2 + *&precomp[15] = t3 + + p256PointAddAsm(&t0, &t0, p) + p256PointAddAsm(&t1, &t1, p) + p256PointAddAsm(&t2, &t2, p) + + *&precomp[2] = t0 + *&precomp[4] = t1 + *&precomp[8] = t2 + + p256PointDoubleAsm(&t0, &t0) + p256PointDoubleAsm(&t1, &t1) + *&precomp[5] = t0 + *&precomp[9] = t1 + + p256PointAddAsm(&t2, &t0, p) + p256PointAddAsm(&t1, &t1, p) + *&precomp[6] = t2 + *&precomp[10] = t1 + + p256PointDoubleAsm(&t0, &t0) + p256PointDoubleAsm(&t2, &t2) + *&precomp[11] = t0 + *&precomp[13] = t2 + + p256PointAddAsm(&t0, &t0, p) + p256PointAddAsm(&t2, &t2, p) + *&precomp[12] = t0 + *&precomp[14] = t2 + + // Start scanning the window from top bit + index := uint(254) + var sel, sign int + + // TODO: For big endian, use index found in s390x implementation. + wvalue := (uint(scalar[index/8]) >> (index % 8)) & 0x3f + sel, _ = boothW5(uint(wvalue)) + p256Select(p, precomp[:], sel) + zero := sel + + for index > 4 { + index -= 5 + p256PointDoubleAsm(p, p) + p256PointDoubleAsm(p, p) + p256PointDoubleAsm(p, p) + p256PointDoubleAsm(p, p) + p256PointDoubleAsm(p, p) + + // TODO: For big endian, use index values as found in s390x implementation. + if index < 247 { + wvalue = ((uint(scalar[index/8]) >> (index % 8)) + (uint(scalar[index/8+1]) << (8 - (index % 8)))) & 0x3f + } else { + wvalue = (uint(scalar[index/8]) >> (index % 8)) & 0x3f + } + + sel, sign = boothW5(uint(wvalue)) + + p256Select(&t0, precomp[:], sel) + p256NegCond(&t0, sign) + p256PointAddAsm(&t1, p, &t0) + p256MovCond(&t1, &t1, p, sel) + p256MovCond(p, &t1, &t0, zero) + zero |= sel + } + + p256PointDoubleAsm(p, p) + p256PointDoubleAsm(p, p) + p256PointDoubleAsm(p, p) + p256PointDoubleAsm(p, p) + p256PointDoubleAsm(p, p) + + // TODO: Use index for big endian as found in s390x implementation. + wvalue = (uint(scalar[0]) << 1) & 0x3f + sel, sign = boothW5(uint(wvalue)) + + p256Select(&t0, precomp[:], sel) + p256NegCond(&t0, sign) + p256PointAddAsm(&t1, p, &t0) + p256MovCond(&t1, &t1, p, sel) + p256MovCond(p, &t1, &t0, zero) +} diff --git a/libgo/go/crypto/md5/md5block_decl.go b/libgo/go/crypto/md5/md5block_decl.go index 761398f38e9..ccdae404536 100644 --- a/libgo/go/crypto/md5/md5block_decl.go +++ b/libgo/go/crypto/md5/md5block_decl.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build ignore -// +build amd64 amd64p32 386 arm ppc64le ppc64 s390x arm64 +// +build amd64 386 arm ppc64le ppc64 s390x arm64 package md5 diff --git a/libgo/go/crypto/md5/md5block_generic.go b/libgo/go/crypto/md5/md5block_generic.go index 69c4456a4bd..56520f1f002 100644 --- a/libgo/go/crypto/md5/md5block_generic.go +++ b/libgo/go/crypto/md5/md5block_generic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// -build !amd64,!amd64p32,!386,!arm,!ppc64le,!ppc64,!s390x,!arm64 +// -build !amd64,!386,!arm,!ppc64le,!ppc64,!s390x,!arm64 package md5 diff --git a/libgo/go/crypto/rand/eagain.go b/libgo/go/crypto/rand/eagain.go index 5377eadd48e..fbe7475edc1 100644 --- a/libgo/go/crypto/rand/eagain.go +++ b/libgo/go/crypto/rand/eagain.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris package rand diff --git a/libgo/go/crypto/rand/rand_unix.go b/libgo/go/crypto/rand/rand_unix.go index b5e6746a23b..9c7023af69d 100644 --- a/libgo/go/crypto/rand/rand_unix.go +++ b/libgo/go/crypto/rand/rand_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd plan9 solaris +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd plan9 solaris // Unix cryptographically secure pseudorandom number // generator. diff --git a/libgo/go/crypto/sha1/sha1block_decl.go b/libgo/go/crypto/sha1/sha1block_decl.go index bb18cbf7346..88074c0bffe 100644 --- a/libgo/go/crypto/sha1/sha1block_decl.go +++ b/libgo/go/crypto/sha1/sha1block_decl.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build ignore -// +build amd64p32 arm 386 s390x +// +build arm 386 s390x package sha1 diff --git a/libgo/go/crypto/sha1/sha1block_generic.go b/libgo/go/crypto/sha1/sha1block_generic.go index b14c42cae43..089b3c45ff0 100644 --- a/libgo/go/crypto/sha1/sha1block_generic.go +++ b/libgo/go/crypto/sha1/sha1block_generic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// -build !amd64,!amd64p32,!386,!arm,!s390x,!arm64 +// -build !amd64,!386,!arm,!s390x,!arm64 package sha1 diff --git a/libgo/go/crypto/tls/alert.go b/libgo/go/crypto/tls/alert.go index 24199a735a8..22b3eca92fa 100644 --- a/libgo/go/crypto/tls/alert.go +++ b/libgo/go/crypto/tls/alert.go @@ -40,6 +40,7 @@ const ( alertNoRenegotiation alert = 100 alertMissingExtension alert = 109 alertUnsupportedExtension alert = 110 + alertUnrecognizedName alert = 112 alertNoApplicationProtocol alert = 120 ) @@ -69,6 +70,7 @@ var alertText = map[alert]string{ alertNoRenegotiation: "no renegotiation", alertMissingExtension: "missing extension", alertUnsupportedExtension: "unsupported extension", + alertUnrecognizedName: "unrecognized name", alertNoApplicationProtocol: "no application protocol", } diff --git a/libgo/go/crypto/tls/auth.go b/libgo/go/crypto/tls/auth.go index c62c9af76b6..009f8d3d1ef 100644 --- a/libgo/go/crypto/tls/auth.go +++ b/libgo/go/crypto/tls/auth.go @@ -18,70 +18,6 @@ import ( "io" ) -// pickSignatureAlgorithm selects a signature algorithm that is compatible with -// the given public key and the list of algorithms from the peer and this side. -// The lists of signature algorithms (peerSigAlgs and ourSigAlgs) are ignored -// for tlsVersion < VersionTLS12. -// -// The returned SignatureScheme codepoint is only meaningful for TLS 1.2, -// previous TLS versions have a fixed hash function. -func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []SignatureScheme, tlsVersion uint16) (sigAlg SignatureScheme, sigType uint8, hashFunc crypto.Hash, err error) { - if tlsVersion < VersionTLS12 || len(peerSigAlgs) == 0 { - // For TLS 1.1 and before, the signature algorithm could not be - // negotiated and the hash is fixed based on the signature type. For TLS - // 1.2, if the client didn't send signature_algorithms extension then we - // can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1. - switch pubkey.(type) { - case *rsa.PublicKey: - if tlsVersion < VersionTLS12 { - return 0, signaturePKCS1v15, crypto.MD5SHA1, nil - } else { - return PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1, nil - } - case *ecdsa.PublicKey: - return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil - case ed25519.PublicKey: - if tlsVersion < VersionTLS12 { - // RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1, - // but it requires holding on to a handshake transcript to do a - // full signature, and not even OpenSSL bothers with the - // complexity, so we can't even test it properly. - return 0, 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2") - } - return Ed25519, signatureEd25519, directSigning, nil - default: - return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey) - } - } - for _, sigAlg := range peerSigAlgs { - if !isSupportedSignatureAlgorithm(sigAlg, ourSigAlgs) { - continue - } - hashAlg, err := hashFromSignatureScheme(sigAlg) - if err != nil { - panic("tls: supported signature algorithm has an unknown hash function") - } - sigType := signatureFromSignatureScheme(sigAlg) - switch pubkey.(type) { - case *rsa.PublicKey: - if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS { - return sigAlg, sigType, hashAlg, nil - } - case *ecdsa.PublicKey: - if sigType == signatureECDSA { - return sigAlg, sigType, hashAlg, nil - } - case ed25519.PublicKey: - if sigType == signatureEd25519 { - return sigAlg, sigType, hashAlg, nil - } - default: - return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey) - } - } - return 0, 0, 0, errors.New("tls: peer doesn't support any common signature algorithms") -} - // verifyHandshakeSignature verifies a signature against pre-hashed // (if required) handshake contents. func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error { @@ -89,30 +25,30 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c case signatureECDSA: pubKey, ok := pubkey.(*ecdsa.PublicKey) if !ok { - return errors.New("tls: ECDSA signing requires a ECDSA public key") + return fmt.Errorf("expected an ECDSA public key, got %T", pubkey) } ecdsaSig := new(ecdsaSignature) if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { return err } if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errors.New("tls: ECDSA signature contained zero or negative values") + return errors.New("ECDSA signature contained zero or negative values") } if !ecdsa.Verify(pubKey, signed, ecdsaSig.R, ecdsaSig.S) { - return errors.New("tls: ECDSA verification failure") + return errors.New("ECDSA verification failure") } case signatureEd25519: pubKey, ok := pubkey.(ed25519.PublicKey) if !ok { - return errors.New("tls: Ed25519 signing requires a Ed25519 public key") + return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey) } if !ed25519.Verify(pubKey, signed, sig) { - return errors.New("tls: Ed25519 verification failure") + return errors.New("Ed25519 verification failure") } case signaturePKCS1v15: pubKey, ok := pubkey.(*rsa.PublicKey) if !ok { - return errors.New("tls: RSA signing requires a RSA public key") + return fmt.Errorf("expected an RSA public key, got %T", pubkey) } if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil { return err @@ -120,14 +56,14 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c case signatureRSAPSS: pubKey, ok := pubkey.(*rsa.PublicKey) if !ok { - return errors.New("tls: RSA signing requires a RSA public key") + return fmt.Errorf("expected an RSA public key, got %T", pubkey) } signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash} if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil { return err } default: - return errors.New("tls: unknown signature algorithm") + return errors.New("internal error: unknown signature type") } return nil } @@ -165,59 +101,159 @@ func signedMessage(sigHash crypto.Hash, context string, transcript hash.Hash) [] return h.Sum(nil) } +// typeAndHashFromSignatureScheme returns the corresponding signature type and +// crypto.Hash for a given TLS SignatureScheme. +func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) { + switch signatureAlgorithm { + case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512: + sigType = signaturePKCS1v15 + case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512: + sigType = signatureRSAPSS + case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512: + sigType = signatureECDSA + case Ed25519: + sigType = signatureEd25519 + default: + return 0, 0, fmt.Errorf("unsupported signature algorithm: %#04x", signatureAlgorithm) + } + switch signatureAlgorithm { + case PKCS1WithSHA1, ECDSAWithSHA1: + hash = crypto.SHA1 + case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256: + hash = crypto.SHA256 + case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384: + hash = crypto.SHA384 + case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512: + hash = crypto.SHA512 + case Ed25519: + hash = directSigning + default: + return 0, 0, fmt.Errorf("unsupported signature algorithm: %#04x", signatureAlgorithm) + } + return sigType, hash, nil +} + +// legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for +// a given public key used with TLS 1.0 and 1.1, before the introduction of +// signature algorithm negotiation. +func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) { + switch pub.(type) { + case *rsa.PublicKey: + return signaturePKCS1v15, crypto.MD5SHA1, nil + case *ecdsa.PublicKey: + return signatureECDSA, crypto.SHA1, nil + case ed25519.PublicKey: + // RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1, + // but it requires holding on to a handshake transcript to do a + // full signature, and not even OpenSSL bothers with the + // complexity, so we can't even test it properly. + return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2") + default: + return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub) + } +} + +var rsaSignatureSchemes = []struct { + scheme SignatureScheme + minModulusBytes int + maxVersion uint16 +}{ + // RSA-PSS is used with PSSSaltLengthEqualsHash, and requires + // emLen >= hLen + sLen + 2 + {PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13}, + {PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13}, + {PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13}, + // PKCS#1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires + // emLen >= len(prefix) + hLen + 11 + // TLS 1.3 dropped support for PKCS#1 v1.5 in favor of RSA-PSS. + {PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12}, + {PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12}, + {PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12}, + {PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12}, +} + // signatureSchemesForCertificate returns the list of supported SignatureSchemes -// for a given certificate, based on the public key and the protocol version. +// for a given certificate, based on the public key and the protocol version, +// and optionally filtered by its explicit SupportedSignatureAlgorithms. // -// It does not support the crypto.Decrypter interface, so shouldn't be used for -// server certificates in TLS 1.2 and earlier, and it must be kept in sync with -// supportedSignatureAlgorithms. +// This function must be kept in sync with supportedSignatureAlgorithms. func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme { priv, ok := cert.PrivateKey.(crypto.Signer) if !ok { return nil } + var sigAlgs []SignatureScheme switch pub := priv.Public().(type) { case *ecdsa.PublicKey: if version != VersionTLS13 { // In TLS 1.2 and earlier, ECDSA algorithms are not // constrained to a single curve. - return []SignatureScheme{ + sigAlgs = []SignatureScheme{ ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, ECDSAWithSHA1, } + break } switch pub.Curve { case elliptic.P256(): - return []SignatureScheme{ECDSAWithP256AndSHA256} + sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256} case elliptic.P384(): - return []SignatureScheme{ECDSAWithP384AndSHA384} + sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384} case elliptic.P521(): - return []SignatureScheme{ECDSAWithP521AndSHA512} + sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512} default: return nil } case *rsa.PublicKey: - if version != VersionTLS13 { - return []SignatureScheme{ - PKCS1WithSHA256, - PKCS1WithSHA384, - PKCS1WithSHA512, - PKCS1WithSHA1, + size := pub.Size() + sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes)) + for _, candidate := range rsaSignatureSchemes { + if size >= candidate.minModulusBytes && version <= candidate.maxVersion { + sigAlgs = append(sigAlgs, candidate.scheme) } } - return []SignatureScheme{ - PSSWithSHA256, - PSSWithSHA384, - PSSWithSHA512, - } case ed25519.PublicKey: - return []SignatureScheme{Ed25519} + sigAlgs = []SignatureScheme{Ed25519} default: return nil } + + if cert.SupportedSignatureAlgorithms != nil { + var filteredSigAlgs []SignatureScheme + for _, sigAlg := range sigAlgs { + if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) { + filteredSigAlgs = append(filteredSigAlgs, sigAlg) + } + } + return filteredSigAlgs + } + return sigAlgs +} + +// selectSignatureScheme picks a SignatureScheme from the peer's preference list +// that works with the selected certificate. It's only called for protocol +// versions that support signature algorithms, so TLS 1.2 and 1.3. +func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) { + supportedAlgs := signatureSchemesForCertificate(vers, c) + if len(supportedAlgs) == 0 { + return 0, unsupportedCertificateError(c) + } + if len(peerAlgs) == 0 && vers == VersionTLS12 { + // For TLS 1.2, if the client didn't send signature_algorithms then we + // can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1. + peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1} + } + // Pick signature scheme in the peer's preference order, as our + // preference order is not configurable. + for _, preferredAlg := range peerAlgs { + if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { + return preferredAlg, nil + } + } + return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms") } // unsupportedCertificateError returns a helpful error for certificates with @@ -247,10 +283,15 @@ func unsupportedCertificateError(cert *Certificate) error { return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name) } case *rsa.PublicKey: + return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms") case ed25519.PublicKey: default: return fmt.Errorf("tls: unsupported certificate key (%T)", pub) } + if cert.SupportedSignatureAlgorithms != nil { + return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms") + } + return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey) } diff --git a/libgo/go/crypto/tls/auth_test.go b/libgo/go/crypto/tls/auth_test.go index 1d958cf1410..c8d8c8fe4e0 100644 --- a/libgo/go/crypto/tls/auth_test.go +++ b/libgo/go/crypto/tls/auth_test.go @@ -6,72 +6,68 @@ package tls import ( "crypto" - "crypto/ed25519" "testing" ) func TestSignatureSelection(t *testing.T) { - rsaCert := &testRSAPrivateKey.PublicKey - ecdsaCert := &testECDSAPrivateKey.PublicKey - ed25519Cert := testEd25519PrivateKey.Public().(ed25519.PublicKey) - sigsPKCS1WithSHA := []SignatureScheme{PKCS1WithSHA256, PKCS1WithSHA1} - sigsPSSWithSHA := []SignatureScheme{PSSWithSHA256, PSSWithSHA384} - sigsECDSAWithSHA := []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1} + rsaCert := &Certificate{ + Certificate: [][]byte{testRSACertificate}, + PrivateKey: testRSAPrivateKey, + } + pkcs1Cert := &Certificate{ + Certificate: [][]byte{testRSACertificate}, + PrivateKey: testRSAPrivateKey, + SupportedSignatureAlgorithms: []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256}, + } + ecdsaCert := &Certificate{ + Certificate: [][]byte{testP256Certificate}, + PrivateKey: testP256PrivateKey, + } + ed25519Cert := &Certificate{ + Certificate: [][]byte{testEd25519Certificate}, + PrivateKey: testEd25519PrivateKey, + } tests := []struct { - pubkey crypto.PublicKey + cert *Certificate peerSigAlgs []SignatureScheme - ourSigAlgs []SignatureScheme tlsVersion uint16 - expectedSigAlg SignatureScheme // if tlsVersion == VersionTLS12 + expectedSigAlg SignatureScheme expectedSigType uint8 expectedHash crypto.Hash }{ - // Hash is fixed for RSA in TLS 1.1 and before. - // https://tools.ietf.org/html/rfc4346#page-44 - {rsaCert, nil, nil, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1}, - {rsaCert, nil, nil, VersionTLS10, 0, signaturePKCS1v15, crypto.MD5SHA1}, - {rsaCert, nil, nil, VersionSSL30, 0, signaturePKCS1v15, crypto.MD5SHA1}, - - // Before TLS 1.2, there is no signature_algorithms extension - // nor field in CertificateRequest and digitally-signed and thus - // it should be ignored. - {rsaCert, sigsPKCS1WithSHA, nil, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1}, - {rsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS11, 0, signaturePKCS1v15, crypto.MD5SHA1}, - // Use SHA-1 for TLS 1.0 and 1.1 with ECDSA, see https://tools.ietf.org/html/rfc4492#page-20 - {ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS11, 0, signatureECDSA, crypto.SHA1}, - {ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS10, 0, signatureECDSA, crypto.SHA1}, + {rsaCert, []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256}, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1}, + {rsaCert, []SignatureScheme{PKCS1WithSHA512, PKCS1WithSHA1}, VersionTLS12, PKCS1WithSHA512, signaturePKCS1v15, crypto.SHA512}, + {rsaCert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS12, PSSWithSHA256, signatureRSAPSS, crypto.SHA256}, + {pkcs1Cert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS12, PKCS1WithSHA256, signaturePKCS1v15, crypto.SHA256}, + {rsaCert, []SignatureScheme{PSSWithSHA384, PKCS1WithSHA1}, VersionTLS13, PSSWithSHA384, signatureRSAPSS, crypto.SHA384}, + {ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1}, + {ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, VersionTLS12, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256}, + {ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, VersionTLS13, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256}, + {ed25519Cert, []SignatureScheme{Ed25519}, VersionTLS12, Ed25519, signatureEd25519, directSigning}, + {ed25519Cert, []SignatureScheme{Ed25519}, VersionTLS13, Ed25519, signatureEd25519, directSigning}, // TLS 1.2 without signature_algorithms extension - // https://tools.ietf.org/html/rfc5246#page-47 - {rsaCert, nil, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1}, - {ecdsaCert, nil, sigsPKCS1WithSHA, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1}, - - {rsaCert, []SignatureScheme{PKCS1WithSHA1}, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1}, - {rsaCert, []SignatureScheme{PKCS1WithSHA256}, sigsPKCS1WithSHA, VersionTLS12, PKCS1WithSHA256, signaturePKCS1v15, crypto.SHA256}, - // "sha_hash" may denote hashes other than SHA-1 - // https://tools.ietf.org/html/draft-ietf-tls-rfc4492bis-17#page-17 - {ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, sigsECDSAWithSHA, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1}, - {ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, sigsECDSAWithSHA, VersionTLS12, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256}, + {rsaCert, nil, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1}, + {ecdsaCert, nil, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1}, - // RSASSA-PSS is defined in TLS 1.3 for TLS 1.2 - // https://tools.ietf.org/html/draft-ietf-tls-tls13-21#page-45 - {rsaCert, []SignatureScheme{PSSWithSHA256}, sigsPSSWithSHA, VersionTLS12, PSSWithSHA256, signatureRSAPSS, crypto.SHA256}, - - // All results are fixed for Ed25519. RFC 8422, Section 5.10. - {ed25519Cert, []SignatureScheme{Ed25519}, []SignatureScheme{ECDSAWithSHA1, Ed25519}, VersionTLS12, Ed25519, signatureEd25519, directSigning}, - {ed25519Cert, nil, nil, VersionTLS12, Ed25519, signatureEd25519, directSigning}, + // TLS 1.2 does not restrict the ECDSA curve (our ecdsaCert is P-256) + {ecdsaCert, []SignatureScheme{ECDSAWithP384AndSHA384}, VersionTLS12, ECDSAWithP384AndSHA384, signatureECDSA, crypto.SHA384}, } for testNo, test := range tests { - sigAlg, sigType, hashFunc, err := pickSignatureAlgorithm(test.pubkey, test.peerSigAlgs, test.ourSigAlgs, test.tlsVersion) + sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs) if err != nil { - t.Errorf("test[%d]: unexpected error: %v", testNo, err) + t.Errorf("test[%d]: unexpected selectSignatureScheme error: %v", testNo, err) } - if test.tlsVersion == VersionTLS12 && test.expectedSigAlg != sigAlg { + if test.expectedSigAlg != sigAlg { t.Errorf("test[%d]: expected signature scheme %#x, got %#x", testNo, test.expectedSigAlg, sigAlg) } + sigType, hashFunc, err := typeAndHashFromSignatureScheme(sigAlg) + if err != nil { + t.Errorf("test[%d]: unexpected typeAndHashFromSignatureScheme error: %v", testNo, err) + } if test.expectedSigType != sigType { t.Errorf("test[%d]: expected signature algorithm %#x, got %#x", testNo, test.expectedSigType, sigType) } @@ -80,34 +76,93 @@ func TestSignatureSelection(t *testing.T) { } } + brokenCert := &Certificate{ + Certificate: [][]byte{testRSACertificate}, + PrivateKey: testRSAPrivateKey, + SupportedSignatureAlgorithms: []SignatureScheme{Ed25519}, + } + badTests := []struct { - pubkey crypto.PublicKey + cert *Certificate peerSigAlgs []SignatureScheme - ourSigAlgs []SignatureScheme tlsVersion uint16 }{ - {rsaCert, sigsECDSAWithSHA, sigsPKCS1WithSHA, VersionTLS12}, - {ecdsaCert, sigsPKCS1WithSHA, sigsPKCS1WithSHA, VersionTLS12}, - {ecdsaCert, sigsECDSAWithSHA, sigsPKCS1WithSHA, VersionTLS12}, - {rsaCert, []SignatureScheme{0}, sigsPKCS1WithSHA, VersionTLS12}, - {ed25519Cert, sigsECDSAWithSHA, sigsECDSAWithSHA, VersionTLS12}, - {ed25519Cert, []SignatureScheme{Ed25519}, sigsECDSAWithSHA, VersionTLS12}, - {ecdsaCert, []SignatureScheme{Ed25519}, []SignatureScheme{Ed25519}, VersionTLS12}, - {ed25519Cert, nil, nil, VersionTLS11}, - {ed25519Cert, nil, nil, VersionTLS10}, - {ed25519Cert, nil, nil, VersionSSL30}, - - // ECDSA is unspecified for SSL 3.0 in RFC 4492. - // TODO a SSL 3.0 client cannot advertise signature_algorithms, - // but if an application feeds an ECDSA certificate anyway, it - // will be accepted rather than trigger a handshake failure. Ok? - //{ecdsaCert, nil, nil, VersionSSL30}, + {rsaCert, []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}, VersionTLS12}, + {ecdsaCert, []SignatureScheme{PKCS1WithSHA256, PKCS1WithSHA1}, VersionTLS12}, + {rsaCert, []SignatureScheme{0}, VersionTLS12}, + {ed25519Cert, []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}, VersionTLS12}, + {ecdsaCert, []SignatureScheme{Ed25519}, VersionTLS12}, + {brokenCert, []SignatureScheme{Ed25519}, VersionTLS12}, + {brokenCert, []SignatureScheme{PKCS1WithSHA256}, VersionTLS12}, + // RFC 5246, Section 7.4.1.4.1, says to only consider {sha1,ecdsa} as + // default when the extension is missing, and RFC 8422 does not update + // it. Anyway, if a stack supports Ed25519 it better support sigalgs. + {ed25519Cert, nil, VersionTLS12}, + // TLS 1.3 has no default signature_algorithms. + {rsaCert, nil, VersionTLS13}, + {ecdsaCert, nil, VersionTLS13}, + {ed25519Cert, nil, VersionTLS13}, + // Wrong curve, which TLS 1.3 checks + {ecdsaCert, []SignatureScheme{ECDSAWithP384AndSHA384}, VersionTLS13}, + // TLS 1.3 does not support PKCS1v1.5 or SHA-1. + {rsaCert, []SignatureScheme{PKCS1WithSHA256}, VersionTLS13}, + {pkcs1Cert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS13}, + {ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, VersionTLS13}, + // The key can be too small for the hash. + {rsaCert, []SignatureScheme{PSSWithSHA512}, VersionTLS12}, } for testNo, test := range badTests { - sigAlg, sigType, hashFunc, err := pickSignatureAlgorithm(test.pubkey, test.peerSigAlgs, test.ourSigAlgs, test.tlsVersion) + sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs) if err == nil { - t.Errorf("test[%d]: unexpected success, got %#x %#x %#x", testNo, sigAlg, sigType, hashFunc) + t.Errorf("test[%d]: unexpected success, got %#x", testNo, sigAlg) + } + } +} + +func TestLegacyTypeAndHash(t *testing.T) { + sigType, hashFunc, err := legacyTypeAndHashFromPublicKey(testRSAPrivateKey.Public()) + if err != nil { + t.Errorf("RSA: unexpected error: %v", err) + } + if expectedSigType := signaturePKCS1v15; expectedSigType != sigType { + t.Errorf("RSA: expected signature type %#x, got %#x", expectedSigType, sigType) + } + if expectedHashFunc := crypto.MD5SHA1; expectedHashFunc != hashFunc { + t.Errorf("RSA: expected hash %#x, got %#x", expectedHashFunc, sigType) + } + + sigType, hashFunc, err = legacyTypeAndHashFromPublicKey(testECDSAPrivateKey.Public()) + if err != nil { + t.Errorf("ECDSA: unexpected error: %v", err) + } + if expectedSigType := signatureECDSA; expectedSigType != sigType { + t.Errorf("ECDSA: expected signature type %#x, got %#x", expectedSigType, sigType) + } + if expectedHashFunc := crypto.SHA1; expectedHashFunc != hashFunc { + t.Errorf("ECDSA: expected hash %#x, got %#x", expectedHashFunc, sigType) + } + + // Ed25519 is not supported by TLS 1.0 and 1.1. + _, _, err = legacyTypeAndHashFromPublicKey(testEd25519PrivateKey.Public()) + if err == nil { + t.Errorf("Ed25519: unexpected success") + } +} + +// TestSupportedSignatureAlgorithms checks that all supportedSignatureAlgorithms +// have valid type and hash information. +func TestSupportedSignatureAlgorithms(t *testing.T) { + for _, sigAlg := range supportedSignatureAlgorithms { + sigType, hash, err := typeAndHashFromSignatureScheme(sigAlg) + if err != nil { + t.Errorf("%#04x: unexpected error: %v", sigAlg, err) + } + if sigType == 0 { + t.Errorf("%#04x: missing signature type", sigAlg) + } + if hash == 0 && sigAlg != Ed25519 { + t.Errorf("%#04x: missing hash", sigAlg) } } } diff --git a/libgo/go/crypto/tls/cipher_suites.go b/libgo/go/crypto/tls/cipher_suites.go index 61bbc9f9099..ea16ef95bf0 100644 --- a/libgo/go/crypto/tls/cipher_suites.go +++ b/libgo/go/crypto/tls/cipher_suites.go @@ -14,10 +14,100 @@ import ( "crypto/sha1" "crypto/sha256" "crypto/x509" - "golang.org/x/crypto/chacha20poly1305" + "fmt" "hash" + + "golang.org/x/crypto/chacha20poly1305" ) +// CipherSuite is a TLS cipher suite. Note that most functions in this package +// accept and expose cipher suite IDs instead of this type. +type CipherSuite struct { + ID uint16 + Name string + + // Supported versions is the list of TLS protocol versions that can + // negotiate this cipher suite. + SupportedVersions []uint16 + + // Insecure is true if the cipher suite has known security issues + // due to its primitives, design, or implementation. + Insecure bool +} + +var ( + supportedUpToTLS12 = []uint16{VersionTLS10, VersionTLS11, VersionTLS12} + supportedOnlyTLS12 = []uint16{VersionTLS12} + supportedOnlyTLS13 = []uint16{VersionTLS13} +) + +// CipherSuites returns a list of cipher suites currently implemented by this +// package, excluding those with security issues, which are returned by +// InsecureCipherSuites. +// +// The list is sorted by ID. Note that the default cipher suites selected by +// this package might depend on logic that can't be captured by a static list. +func CipherSuites() []*CipherSuite { + return []*CipherSuite{ + {TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, false}, + {TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, + {TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, + {TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, + {TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, + + {TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false}, + {TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false}, + {TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false}, + + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, + {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, false}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, + {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, + {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, + {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, + {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, + {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false}, + {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false}, + } +} + +// InsecureCipherSuites returns a list of cipher suites currently implemented by +// this package and which have security issues. +// +// Most applications should not use the cipher suites in this list, and should +// only use those returned by CipherSuites. +func InsecureCipherSuites() []*CipherSuite { + // RC4 suites are broken because RC4 is. + // CBC-SHA256 suites have no Lucky13 countermeasures. + return []*CipherSuite{ + {TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, + {TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, + {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, + {TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, + } +} + +// CipherSuiteName returns the standard name for the passed cipher suite ID +// (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation +// of the ID value if the cipher suite is not implemented by this package. +func CipherSuiteName(id uint16) string { + for _, c := range CipherSuites() { + if c.ID == id { + return c.Name + } + } + for _, c := range InsecureCipherSuites() { + if c.ID == id { + return c.Name + } + } + return fmt.Sprintf("0x%04X", id) +} + // a keyAgreement implements the client and server side of a TLS key agreement // protocol by generating and processing key exchange messages. type keyAgreement interface { @@ -38,7 +128,7 @@ type keyAgreement interface { } const ( - // suiteECDH indicates that the cipher suite involves elliptic curve + // suiteECDHE indicates that the cipher suite involves elliptic curve // Diffie-Hellman. This means that it should only be selected when the // client indicates that it supports ECC with a curve and point format // that we're happy with. @@ -103,6 +193,24 @@ var cipherSuites = []*cipherSuite{ {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteDefaultOff, cipherRC4, macSHA1, nil}, } +// selectCipherSuite returns the first cipher suite from ids which is also in +// supportedIDs and passes the ok filter. +func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite { + for _, id := range ids { + candidate := cipherSuiteByID(id) + if candidate == nil || !ok(candidate) { + continue + } + + for _, suppID := range supportedIDs { + if id == suppID { + return candidate + } + } + } + return nil +} + // A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash // algorithm to be used with HKDF. See RFC 8446, Appendix B.4. type cipherSuiteTLS13 struct { @@ -141,14 +249,6 @@ func cipherAES(key, iv []byte, isRead bool) interface{} { // macSHA1 returns a macFunction for the given protocol version. func macSHA1(version uint16, key []byte) macFunction { - if version == VersionSSL30 { - mac := ssl30MAC{ - h: sha1.New(), - key: make([]byte, len(key)), - } - copy(mac.key, key) - return mac - } return tls10MAC{h: hmac.New(newConstantTimeHash(sha1.New), key)} } @@ -288,46 +388,6 @@ func aeadChaCha20Poly1305(key, nonceMask []byte) aead { return ret } -// ssl30MAC implements the SSLv3 MAC function, as defined in -// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1 -type ssl30MAC struct { - h hash.Hash - key []byte - buf []byte -} - -func (s ssl30MAC) Size() int { - return s.h.Size() -} - -var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36} - -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} - -// MAC does not offer constant timing guarantees for SSL v3.0, since it's deemed -// useless considering the similar, protocol-level POODLE vulnerability. -func (s ssl30MAC) MAC(seq, header, data, extra []byte) []byte { - padLength := 48 - if s.h.Size() == 20 { - padLength = 40 - } - - s.h.Reset() - s.h.Write(s.key) - s.h.Write(ssl30Pad1[:padLength]) - s.h.Write(seq) - s.h.Write(header[:1]) - s.h.Write(header[3:5]) - s.h.Write(data) - s.buf = s.h.Sum(s.buf[:0]) - - s.h.Reset() - s.h.Write(s.key) - s.h.Write(ssl30Pad2[:padLength]) - s.h.Write(s.buf) - return s.h.Sum(s.buf[:0]) -} - type constantTimeHash interface { hash.Hash ConstantTimeSum(b []byte) []byte @@ -435,31 +495,31 @@ func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 { // A list of cipher suite IDs that are, or have been, implemented by this // package. // -// Taken from https://www.iana.org/assignments/tls-parameters/tls-parameters.xml +// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml const ( // TLS 1.0 - 1.2 cipher suites. - TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 - TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a - TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f - TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 - TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c - TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c - TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a - TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca8 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 uint16 = 0xcca9 + TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 + TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a + TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f + TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 + TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c + TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c + TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a + TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8 + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9 // TLS 1.3 cipher suites. TLS_AES_128_GCM_SHA256 uint16 = 0x1301 @@ -469,4 +529,9 @@ const ( // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator // that the client is doing version fallback. See RFC 7507. TLS_FALLBACK_SCSV uint16 = 0x5600 + + // Legacy names for the corresponding cipher suites with the correct _SHA256 + // suffix, retained for backward compatibility. + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 ) diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go index ef0b3858487..c3de0b3deed 100644 --- a/libgo/go/crypto/tls/common.go +++ b/libgo/go/crypto/tls/common.go @@ -5,9 +5,14 @@ package tls import ( + "bytes" "container/list" "crypto" + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" "crypto/rand" + "crypto/rsa" "crypto/sha512" "crypto/x509" "errors" @@ -16,7 +21,6 @@ import ( "io" "math/big" "net" - "os" "strings" "sync" "time" @@ -28,8 +32,8 @@ const ( VersionTLS12 = 0x0303 VersionTLS13 = 0x0304 - // Deprecated: SSLv3 is cryptographically broken, and will be - // removed in Go 1.14. See golang.org/issue/32716. + // Deprecated: SSLv3 is cryptographically broken, and is no longer + // supported by this package. See golang.org/issue/32716. VersionSSL30 = 0x0300 ) @@ -96,7 +100,6 @@ const ( extensionCertificateAuthorities uint16 = 47 extensionSignatureAlgorithmsCert uint16 = 50 extensionKeyShare uint16 = 51 - extensionNextProtoNeg uint16 = 13172 // not IANA assigned extensionRenegotiationInfo uint16 = 0xff01 ) @@ -188,21 +191,6 @@ var supportedSignatureAlgorithms = []SignatureScheme{ ECDSAWithSHA1, } -// supportedSignatureAlgorithmsTLS12 contains the signature and hash algorithms -// that are supported in TLS 1.2, where it is possible to distinguish the -// protocol version. This is temporary, see Issue 32425. -var supportedSignatureAlgorithmsTLS12 = []SignatureScheme{ - PKCS1WithSHA256, - ECDSAWithP256AndSHA256, - Ed25519, - PKCS1WithSHA384, - PKCS1WithSHA512, - ECDSAWithP384AndSHA384, - ECDSAWithP521AndSHA512, - PKCS1WithSHA1, - ECDSAWithSHA1, -} - // helloRetryRequestRandom is set as the Random value of a ServerHello // to signal that the message is actually a HelloRetryRequest. var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3. @@ -281,7 +269,7 @@ func requiresClientCert(c ClientAuthType) bool { // sessions. type ClientSessionState struct { sessionTicket []uint8 // Encrypted ticket used for session resumption with server - vers uint16 // SSL/TLS version negotiated for the session + vers uint16 // TLS version negotiated for the session cipherSuite uint16 // Ciphersuite negotiated for the session masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret serverCertificates []*x509.Certificate // Certificate chain presented by the server @@ -341,7 +329,7 @@ const ( ) // ClientHelloInfo contains information from a ClientHello message in order to -// guide certificate selection in the GetCertificate callback. +// guide application logic in the GetCertificate and GetConfigForClient callbacks. type ClientHelloInfo struct { // CipherSuites lists the CipherSuites supported by the client (e.g. // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256). @@ -385,6 +373,10 @@ type ClientHelloInfo struct { // from, or write to, this connection; that will cause the TLS // connection to fail. Conn net.Conn + + // config is embedded by the GetCertificate or GetConfigForClient caller, + // for use with SupportsCertificate. + config *Config } // CertificateRequestInfo contains information from a server's @@ -400,6 +392,9 @@ type CertificateRequestInfo struct { // SignatureSchemes lists the signature schemes that the server is // willing to verify. SignatureSchemes []SignatureScheme + + // Version is the TLS version that was negotiated for this connection. + Version uint16 } // RenegotiationSupport enumerates the different levels of support for TLS @@ -446,19 +441,26 @@ type Config struct { // If Time is nil, TLS uses time.Now. Time func() time.Time - // Certificates contains one or more certificate chains to present to - // the other side of the connection. Server configurations must include - // at least one certificate or else set GetCertificate. Clients doing - // client-authentication may set either Certificates or - // GetClientCertificate. + // Certificates contains one or more certificate chains to present to the + // other side of the connection. The first certificate compatible with the + // peer's requirements is selected automatically. + // + // Server configurations must set one of Certificates, GetCertificate or + // GetConfigForClient. Clients doing client-authentication may set either + // Certificates or GetClientCertificate. + // + // Note: if there are multiple Certificates, and they don't have the + // optional field Leaf set, certificate selection will incur a significant + // per-handshake performance cost. Certificates []Certificate // NameToCertificate maps from a certificate name to an element of // Certificates. Note that a certificate name can be of the form // '*.example.com' and so doesn't have to be a domain name as such. - // See Config.BuildNameToCertificate - // The nil value causes the first element of Certificates to be used - // for all connections. + // + // Deprecated: NameToCertificate only allows associating a single + // certificate with a given name. Leave this field nil to let the library + // select the first compatible chain from Certificates. NameToCertificate map[string]*Certificate // GetCertificate returns a Certificate based on the given @@ -467,7 +469,7 @@ type Config struct { // // If GetCertificate is nil or returns nil, then the certificate is // retrieved from NameToCertificate. If NameToCertificate is nil, the - // first element of Certificates will be used. + // best element of Certificates will be used. GetCertificate func(*ClientHelloInfo) (*Certificate, error) // GetClientCertificate, if not nil, is called when a server requests a @@ -582,12 +584,12 @@ type Config struct { // session resumption. It is only used by clients. ClientSessionCache ClientSessionCache - // MinVersion contains the minimum SSL/TLS version that is acceptable. - // If zero, then TLS 1.0 is taken as the minimum. + // MinVersion contains the minimum TLS version that is acceptable. + // If zero, TLS 1.0 is currently taken as the minimum. MinVersion uint16 - // MaxVersion contains the maximum SSL/TLS version that is acceptable. - // If zero, then the maximum version supported by this package is used, + // MaxVersion contains the maximum TLS version that is acceptable. + // If zero, the maximum version supported by this package is used, // which is currently TLS 1.3. MaxVersion uint16 @@ -788,75 +790,24 @@ var supportedVersions = []uint16{ VersionTLS12, VersionTLS11, VersionTLS10, - VersionSSL30, } -func (c *Config) supportedVersions(isClient bool) []uint16 { +func (c *Config) supportedVersions() []uint16 { versions := make([]uint16, 0, len(supportedVersions)) for _, v := range supportedVersions { - // TLS 1.0 is the default minimum version. - if (c == nil || c.MinVersion == 0) && v < VersionTLS10 { - continue - } if c != nil && c.MinVersion != 0 && v < c.MinVersion { continue } if c != nil && c.MaxVersion != 0 && v > c.MaxVersion { continue } - // TLS 1.0 is the minimum version supported as a client. - if isClient && v < VersionTLS10 { - continue - } - // TLS 1.3 is opt-out in Go 1.13. - if v == VersionTLS13 && !isTLS13Supported() { - continue - } versions = append(versions, v) } return versions } -// tls13Support caches the result for isTLS13Supported. -var tls13Support struct { - sync.Once - cached bool -} - -// isTLS13Supported returns whether the program enabled TLS 1.3 by not opting -// out with GODEBUG=tls13=0. It's cached after the first execution. -func isTLS13Supported() bool { - tls13Support.Do(func() { - tls13Support.cached = goDebugString("tls13") != "0" - }) - return tls13Support.cached -} - -// goDebugString returns the value of the named GODEBUG key. -// GODEBUG is of the form "key=val,key2=val2". -func goDebugString(key string) string { - s := os.Getenv("GODEBUG") - for i := 0; i < len(s)-len(key)-1; i++ { - if i > 0 && s[i-1] != ',' { - continue - } - afterKey := s[i+len(key):] - if afterKey[0] != '=' || s[i:i+len(key)] != key { - continue - } - val := afterKey[1:] - for i, b := range val { - if b == ',' { - return val[:i] - } - } - return val - } - return "" -} - -func (c *Config) maxSupportedVersion(isClient bool) uint16 { - supportedVersions := c.supportedVersions(isClient) +func (c *Config) maxSupportedVersion() uint16 { + supportedVersions := c.supportedVersions() if len(supportedVersions) == 0 { return 0 } @@ -886,10 +837,19 @@ func (c *Config) curvePreferences() []CurveID { return c.CurvePreferences } +func (c *Config) supportsCurve(curve CurveID) bool { + for _, cc := range c.curvePreferences() { + if cc == curve { + return true + } + } + return false +} + // mutualVersion returns the protocol version to use given the advertised // versions of the peer. Priority is given to the peer preference order. -func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bool) { - supportedVersions := c.supportedVersions(isClient) +func (c *Config) mutualVersion(peerVersions []uint16) (uint16, bool) { + supportedVersions := c.supportedVersions() for _, peerVersion := range peerVersions { for _, v := range supportedVersions { if v == peerVersion { @@ -900,6 +860,8 @@ func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bo return 0, false } +var errNoCertificates = errors.New("tls: no certificates configured") + // getCertificate returns the best certificate for the given ClientHelloInfo, // defaulting to the first element of c.Certificates. func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) { @@ -912,31 +874,32 @@ func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, err } if len(c.Certificates) == 0 { - return nil, errors.New("tls: no certificates configured") + return nil, errNoCertificates } - if len(c.Certificates) == 1 || c.NameToCertificate == nil { + if len(c.Certificates) == 1 { // There's only one choice, so no point doing any work. return &c.Certificates[0], nil } - name := strings.ToLower(clientHello.ServerName) - for len(name) > 0 && name[len(name)-1] == '.' { - name = name[:len(name)-1] - } - - if cert, ok := c.NameToCertificate[name]; ok { - return cert, nil + if c.NameToCertificate != nil { + name := strings.ToLower(clientHello.ServerName) + if cert, ok := c.NameToCertificate[name]; ok { + return cert, nil + } + if len(name) > 0 { + labels := strings.Split(name, ".") + labels[0] = "*" + wildcardName := strings.Join(labels, ".") + if cert, ok := c.NameToCertificate[wildcardName]; ok { + return cert, nil + } + } } - // try replacing labels in the name with wildcards until we get a - // match. - labels := strings.Split(name, ".") - for i := range labels { - labels[i] = "*" - candidate := strings.Join(labels, ".") - if cert, ok := c.NameToCertificate[candidate]; ok { - return cert, nil + for _, cert := range c.Certificates { + if err := clientHello.SupportsCertificate(&cert); err == nil { + return &cert, nil } } @@ -944,20 +907,213 @@ func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, err return &c.Certificates[0], nil } +// SupportsCertificate returns nil if the provided certificate is supported by +// the client that sent the ClientHello. Otherwise, it returns an error +// describing the reason for the incompatibility. +// +// If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate +// callback, this method will take into account the associated Config. Note that +// if GetConfigForClient returns a different Config, the change can't be +// accounted for by this method. +// +// This function will call x509.ParseCertificate unless c.Leaf is set, which can +// incur a significant performance cost. +func (chi *ClientHelloInfo) SupportsCertificate(c *Certificate) error { + // Note we don't currently support certificate_authorities nor + // signature_algorithms_cert, and don't check the algorithms of the + // signatures on the chain (which anyway are a SHOULD, see RFC 8446, + // Section 4.4.2.2). + + config := chi.config + if config == nil { + config = &Config{} + } + vers, ok := config.mutualVersion(chi.SupportedVersions) + if !ok { + return errors.New("no mutually supported protocol versions") + } + + // If the client specified the name they are trying to connect to, the + // certificate needs to be valid for it. + if chi.ServerName != "" { + x509Cert, err := c.leaf() + if err != nil { + return fmt.Errorf("failed to parse certificate: %w", err) + } + if err := x509Cert.VerifyHostname(chi.ServerName); err != nil { + return fmt.Errorf("certificate is not valid for requested server name: %w", err) + } + } + + // supportsRSAFallback returns nil if the certificate and connection support + // the static RSA key exchange, and unsupported otherwise. The logic for + // supporting static RSA is completely disjoint from the logic for + // supporting signed key exchanges, so we just check it as a fallback. + supportsRSAFallback := func(unsupported error) error { + // TLS 1.3 dropped support for the static RSA key exchange. + if vers == VersionTLS13 { + return unsupported + } + // The static RSA key exchange works by decrypting a challenge with the + // RSA private key, not by signing, so check the PrivateKey implements + // crypto.Decrypter, like *rsa.PrivateKey does. + if priv, ok := c.PrivateKey.(crypto.Decrypter); ok { + if _, ok := priv.Public().(*rsa.PublicKey); !ok { + return unsupported + } + } else { + return unsupported + } + // Finally, there needs to be a mutual cipher suite that uses the static + // RSA key exchange instead of ECDHE. + rsaCipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool { + if c.flags&suiteECDHE != 0 { + return false + } + if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { + return false + } + return true + }) + if rsaCipherSuite == nil { + return unsupported + } + return nil + } + + // If the client sent the signature_algorithms extension, ensure it supports + // schemes we can use with this certificate and TLS version. + if len(chi.SignatureSchemes) > 0 { + if _, err := selectSignatureScheme(vers, c, chi.SignatureSchemes); err != nil { + return supportsRSAFallback(err) + } + } + + // In TLS 1.3 we are done because supported_groups is only relevant to the + // ECDHE computation, point format negotiation is removed, cipher suites are + // only relevant to the AEAD choice, and static RSA does not exist. + if vers == VersionTLS13 { + return nil + } + + // The only signed key exchange we support is ECDHE. + if !supportsECDHE(config, chi.SupportedCurves, chi.SupportedPoints) { + return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange")) + } + + var ecdsaCipherSuite bool + if priv, ok := c.PrivateKey.(crypto.Signer); ok { + switch pub := priv.Public().(type) { + case *ecdsa.PublicKey: + var curve CurveID + switch pub.Curve { + case elliptic.P256(): + curve = CurveP256 + case elliptic.P384(): + curve = CurveP384 + case elliptic.P521(): + curve = CurveP521 + default: + return supportsRSAFallback(unsupportedCertificateError(c)) + } + var curveOk bool + for _, c := range chi.SupportedCurves { + if c == curve && config.supportsCurve(c) { + curveOk = true + break + } + } + if !curveOk { + return errors.New("client doesn't support certificate curve") + } + ecdsaCipherSuite = true + case ed25519.PublicKey: + if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 { + return errors.New("connection doesn't support Ed25519") + } + ecdsaCipherSuite = true + case *rsa.PublicKey: + default: + return supportsRSAFallback(unsupportedCertificateError(c)) + } + } else { + return supportsRSAFallback(unsupportedCertificateError(c)) + } + + // Make sure that there is a mutually supported cipher suite that works with + // this certificate. Cipher suite selection will then apply the logic in + // reverse to pick it. See also serverHandshakeState.cipherSuiteOk. + cipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool { + if c.flags&suiteECDHE == 0 { + return false + } + if c.flags&suiteECSign != 0 { + if !ecdsaCipherSuite { + return false + } + } else { + if ecdsaCipherSuite { + return false + } + } + if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { + return false + } + return true + }) + if cipherSuite == nil { + return supportsRSAFallback(errors.New("client doesn't support any cipher suites compatible with the certificate")) + } + + return nil +} + +// SupportsCertificate returns nil if the provided certificate is supported by +// the server that sent the CertificateRequest. Otherwise, it returns an error +// describing the reason for the incompatibility. +func (cri *CertificateRequestInfo) SupportsCertificate(c *Certificate) error { + if _, err := selectSignatureScheme(cri.Version, c, cri.SignatureSchemes); err != nil { + return err + } + + if len(cri.AcceptableCAs) == 0 { + return nil + } + + for j, cert := range c.Certificate { + x509Cert := c.Leaf + // Parse the certificate if this isn't the leaf node, or if + // chain.Leaf was nil. + if j != 0 || x509Cert == nil { + var err error + if x509Cert, err = x509.ParseCertificate(cert); err != nil { + return fmt.Errorf("failed to parse certificate #%d in the chain: %w", j, err) + } + } + + for _, ca := range cri.AcceptableCAs { + if bytes.Equal(x509Cert.RawIssuer, ca) { + return nil + } + } + } + return errors.New("chain is not signed by an acceptable CA") +} + // BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate // from the CommonName and SubjectAlternateName fields of each of the leaf // certificates. +// +// Deprecated: NameToCertificate only allows associating a single certificate +// with a given name. Leave that field nil to let the library select the first +// compatible chain from Certificates. func (c *Config) BuildNameToCertificate() { c.NameToCertificate = make(map[string]*Certificate) for i := range c.Certificates { cert := &c.Certificates[i] - x509Cert := cert.Leaf - if x509Cert == nil { - var err error - x509Cert, err = x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - continue - } + x509Cert, err := cert.leaf() + if err != nil { + continue } if len(x509Cert.Subject.CommonName) > 0 { c.NameToCertificate[x509Cert.Subject.CommonName] = cert @@ -1002,19 +1158,30 @@ type Certificate struct { // For a server up to TLS 1.2, it can also implement crypto.Decrypter with // an RSA PublicKey. PrivateKey crypto.PrivateKey + // SupportedSignatureAlgorithms is an optional list restricting what + // signature algorithms the PrivateKey can be used for. + SupportedSignatureAlgorithms []SignatureScheme // OCSPStaple contains an optional OCSP response which will be served // to clients that request it. OCSPStaple []byte // SignedCertificateTimestamps contains an optional list of Signed // Certificate Timestamps which will be served to clients that request it. SignedCertificateTimestamps [][]byte - // Leaf is the parsed form of the leaf certificate, which may be - // initialized using x509.ParseCertificate to reduce per-handshake - // processing for TLS clients doing client authentication. If nil, the - // leaf certificate will be parsed as needed. + // Leaf is the parsed form of the leaf certificate, which may be initialized + // using x509.ParseCertificate to reduce per-handshake processing. If nil, + // the leaf certificate will be parsed as needed. Leaf *x509.Certificate } +// leaf returns the parsed leaf certificate, either from c.Leaf or by parsing +// the corresponding c.Certificate[0]. +func (c *Certificate) leaf() (*x509.Certificate, error) { + if c.Leaf != nil { + return c.Leaf, nil + } + return x509.ParseCertificate(c.Certificate[0]) +} + type handshakeMessage interface { marshal() []byte unmarshal([]byte) bool @@ -1203,20 +1370,3 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg } return false } - -// signatureFromSignatureScheme maps a signature algorithm to the underlying -// signature method (without hash function). -func signatureFromSignatureScheme(signatureAlgorithm SignatureScheme) uint8 { - switch signatureAlgorithm { - case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512: - return signaturePKCS1v15 - case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512: - return signatureRSAPSS - case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512: - return signatureECDSA - case Ed25519: - return signatureEd25519 - default: - return 0 - } -} diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go index 0c7952f7b84..fac4b914734 100644 --- a/libgo/go/crypto/tls/conn.go +++ b/libgo/go/crypto/tls/conn.go @@ -289,22 +289,6 @@ func extractPadding(payload []byte) (toRemove int, good byte) { return } -// extractPaddingSSL30 is a replacement for extractPadding in the case that the -// protocol version is SSLv3. In this version, the contents of the padding -// are random and cannot be checked. -func extractPaddingSSL30(payload []byte) (toRemove int, good byte) { - if len(payload) < 1 { - return 0, 0 - } - - paddingLen := int(payload[len(payload)-1]) + 1 - if paddingLen > len(payload) { - return 0, 0 - } - - return paddingLen, 255 -} - func roundUp(a, b int) int { return a + (b-a%b)%b } @@ -382,11 +366,7 @@ func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) { // computing the digest. This makes the MAC roughly constant time as // long as the digest computation is constant time and does not // affect the subsequent write, modulo cache effects. - if hc.version == VersionSSL30 { - paddingLen, paddingGood = extractPaddingSSL30(payload) - } else { - paddingLen, paddingGood = extractPadding(payload) - } + paddingLen, paddingGood = extractPadding(payload) default: panic("unknown cipher type") } @@ -1047,8 +1027,6 @@ func (c *Conn) readHandshake() (interface{}, error) { m = &certificateVerifyMsg{ hasSignatureAlgorithm: c.vers >= VersionTLS12, } - case typeNextProtocol: - m = new(nextProtoMsg) case typeFinished: m = new(finishedMsg) case typeEncryptedExtensions: @@ -1086,10 +1064,10 @@ func (c *Conn) Write(b []byte) (int, error) { return 0, errClosed } if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) { - defer atomic.AddInt32(&c.activeCall, -2) break } } + defer atomic.AddInt32(&c.activeCall, -2) if err := c.Handshake(); err != nil { return 0, err @@ -1110,7 +1088,7 @@ func (c *Conn) Write(b []byte) (int, error) { return 0, errShutdown } - // SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext + // TLS 1.0 is susceptible to a chosen-plaintext // attack when using block mode ciphers due to predictable IVs. // This can be prevented by splitting each Application Data // record into two records, effectively randomizing the IV. @@ -1120,7 +1098,7 @@ func (c *Conn) Write(b []byte) (int, error) { // https://www.imperialviolet.org/2012/01/15/beastfollowup.html var m int - if len(b) > 1 && c.vers <= VersionTLS10 { + if len(b) > 1 && c.vers == VersionTLS10 { if _, ok := c.out.cipher.(cipher.BlockMode); ok { n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1]) if err != nil { @@ -1366,7 +1344,7 @@ func (c *Conn) Handshake() error { if c.handshakeErr == nil { c.handshakes++ } else { - // If an error occurred during the hadshake try to flush the + // If an error occurred during the handshake try to flush the // alert that might be left in the buffer. c.flush() } diff --git a/libgo/go/crypto/tls/conn_test.go b/libgo/go/crypto/tls/conn_test.go index 57f61050e5f..78935b1234b 100644 --- a/libgo/go/crypto/tls/conn_test.go +++ b/libgo/go/crypto/tls/conn_test.go @@ -72,8 +72,6 @@ var certWildcardExampleCom = `308201743082011ea003020102021100a7aa6297c9416a4633 var certFooExampleCom = `308201753082011fa00302010202101bbdb6070b0aeffc49008cde74deef29300d06092a864886f70d01010b050030123110300e060355040a130741636d6520436f301e170d3136303831373231343234345a170d3137303831373231343234345a30123110300e060355040a130741636d6520436f305c300d06092a864886f70d0101010500034b003048024100f00ac69d8ca2829f26216c7b50f1d4bbabad58d447706476cd89a2f3e1859943748aa42c15eedc93ac7c49e40d3b05ed645cb6b81c4efba60d961f44211a54eb0203010001a351304f300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff04023000301a0603551d1104133011820f666f6f2e6578616d706c652e636f6d300d06092a864886f70d01010b0500034100a0957fca6d1e0f1ef4b247348c7a8ca092c29c9c0ecc1898ea6b8065d23af6d922a410dd2335a0ea15edd1394cef9f62c9e876a21e35250a0b4fe1ddceba0f36` -var certDoubleWildcardExampleCom = `308201753082011fa003020102021039d262d8538db8ffba30d204e02ddeb5300d06092a864886f70d01010b050030123110300e060355040a130741636d6520436f301e170d3136303831373231343331335a170d3137303831373231343331335a30123110300e060355040a130741636d6520436f305c300d06092a864886f70d0101010500034b003048024100abb6bd84b8b9be3fb9415d00f22b4ddcaec7c99855b9d818c09003e084578430e5cfd2e35faa3561f036d496aa43a9ca6e6cf23c72a763c04ae324004f6cbdbb0203010001a351304f300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff04023000301a0603551d1104133011820f2a2e2a2e6578616d706c652e636f6d300d06092a864886f70d01010b05000341004837521004a5b6bc7ad5d6c0dae60bb7ee0fa5e4825be35e2bb6ef07ee29396ca30ceb289431bcfd363888ba2207139933ac7c6369fa8810c819b2e2966abb4b` - func TestCertificateSelection(t *testing.T) { config := Config{ Certificates: []Certificate{ @@ -86,9 +84,6 @@ func TestCertificateSelection(t *testing.T) { { Certificate: [][]byte{fromHex(certFooExampleCom)}, }, - { - Certificate: [][]byte{fromHex(certDoubleWildcardExampleCom)}, - }, }, } @@ -124,11 +119,8 @@ func TestCertificateSelection(t *testing.T) { if n := pointerToIndex(certificateForName("foo.example.com")); n != 2 { t.Errorf("foo.example.com returned certificate %d, not 2", n) } - if n := pointerToIndex(certificateForName("foo.bar.example.com")); n != 3 { - t.Errorf("foo.bar.example.com returned certificate %d, not 3", n) - } - if n := pointerToIndex(certificateForName("foo.bar.baz.example.com")); n != 0 { - t.Errorf("foo.bar.baz.example.com returned certificate %d, not 0", n) + if n := pointerToIndex(certificateForName("foo.bar.example.com")); n != 0 { + t.Errorf("foo.bar.example.com returned certificate %d, not 0", n) } } diff --git a/libgo/go/crypto/tls/example_test.go b/libgo/go/crypto/tls/example_test.go new file mode 100644 index 00000000000..c88f8add090 --- /dev/null +++ b/libgo/go/crypto/tls/example_test.go @@ -0,0 +1,238 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tls_test + +import ( + "crypto/tls" + "crypto/x509" + "errors" + "log" + "net/http" + "net/http/httptest" + "os" + "time" +) + +// zeroSource is an io.Reader that returns an unlimited number of zero bytes. +type zeroSource struct{} + +func (zeroSource) Read(b []byte) (n int, err error) { + for i := range b { + b[i] = 0 + } + + return len(b), nil +} + +func ExampleDial() { + // Connecting with a custom root-certificate set. + + const rootPEM = ` +-----BEGIN CERTIFICATE----- +MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG +EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy +bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP +VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv +h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE +ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ +EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC +DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7 +qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD +VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g +K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI +KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n +ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB +BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY +/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/ +zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza +HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto +WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6 +yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx +-----END CERTIFICATE-----` + + // First, create the set of root certificates. For this example we only + // have one. It's also possible to omit this in order to use the + // default root set of the current operating system. + roots := x509.NewCertPool() + ok := roots.AppendCertsFromPEM([]byte(rootPEM)) + if !ok { + panic("failed to parse root certificate") + } + + conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{ + RootCAs: roots, + }) + if err != nil { + panic("failed to connect: " + err.Error()) + } + conn.Close() +} + +func ExampleConfig_keyLogWriter() { + // Debugging TLS applications by decrypting a network traffic capture. + + // WARNING: Use of KeyLogWriter compromises security and should only be + // used for debugging. + + // Dummy test HTTP server for the example with insecure random so output is + // reproducible. + server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) + server.TLS = &tls.Config{ + Rand: zeroSource{}, // for example only; don't do this. + } + server.StartTLS() + defer server.Close() + + // Typically the log would go to an open file: + // w, err := os.OpenFile("tls-secrets.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + w := os.Stdout + + client := &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + KeyLogWriter: w, + + Rand: zeroSource{}, // for reproducible output; don't do this. + InsecureSkipVerify: true, // test server certificate is not trusted. + }, + }, + } + resp, err := client.Get(server.URL) + if err != nil { + log.Fatalf("Failed to get URL: %v", err) + } + resp.Body.Close() + + // The resulting file can be used with Wireshark to decrypt the TLS + // connection by setting (Pre)-Master-Secret log filename in SSL Protocol + // preferences. +} + +func ExampleLoadX509KeyPair() { + cert, err := tls.LoadX509KeyPair("testdata/example-cert.pem", "testdata/example-key.pem") + if err != nil { + log.Fatal(err) + } + cfg := &tls.Config{Certificates: []tls.Certificate{cert}} + listener, err := tls.Listen("tcp", ":2000", cfg) + if err != nil { + log.Fatal(err) + } + _ = listener +} + +func ExampleX509KeyPair() { + certPem := []byte(`-----BEGIN CERTIFICATE----- +MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw +DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow +EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d +7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B +5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr +BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1 +NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l +Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc +6MF9+Yw1Yy0t +-----END CERTIFICATE-----`) + keyPem := []byte(`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49 +AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q +EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== +-----END EC PRIVATE KEY-----`) + cert, err := tls.X509KeyPair(certPem, keyPem) + if err != nil { + log.Fatal(err) + } + cfg := &tls.Config{Certificates: []tls.Certificate{cert}} + listener, err := tls.Listen("tcp", ":2000", cfg) + if err != nil { + log.Fatal(err) + } + _ = listener +} + +func ExampleX509KeyPair_httpServer() { + certPem := []byte(`-----BEGIN CERTIFICATE----- +MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw +DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow +EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d +7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B +5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr +BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1 +NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l +Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc +6MF9+Yw1Yy0t +-----END CERTIFICATE-----`) + keyPem := []byte(`-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49 +AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q +EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== +-----END EC PRIVATE KEY-----`) + cert, err := tls.X509KeyPair(certPem, keyPem) + if err != nil { + log.Fatal(err) + } + cfg := &tls.Config{Certificates: []tls.Certificate{cert}} + srv := &http.Server{ + TLSConfig: cfg, + ReadTimeout: time.Minute, + WriteTimeout: time.Minute, + } + log.Fatal(srv.ListenAndServeTLS("", "")) +} + +func ExampleConfig_verifyPeerCertificate() { + // VerifyPeerCertificate can be used to replace and customize certificate + // verification. This example shows a VerifyPeerCertificate implementation + // that will be approximately equivalent to what crypto/tls does normally. + + config := &tls.Config{ + // Set InsecureSkipVerify to skip the default validation we are + // replacing. This will not disable VerifyPeerCertificate. + InsecureSkipVerify: true, + + // While packages like net/http will implicitly set ServerName, the + // VerifyPeerCertificate callback can't access that value, so it has to be set + // explicitly here or in VerifyPeerCertificate on the client side. If in + // an http.Transport DialTLS callback, this can be obtained by passing + // the addr argument to net.SplitHostPort. + ServerName: "example.com", + + // On the server side, set ClientAuth to require client certificates (or + // VerifyPeerCertificate will run anyway and panic accessing certs[0]) + // but not verify them with the default verifier. + // ClientAuth: tls.RequireAnyClientCert, + } + + config.VerifyPeerCertificate = func(certificates [][]byte, _ [][]*x509.Certificate) error { + certs := make([]*x509.Certificate, len(certificates)) + for i, asn1Data := range certificates { + cert, err := x509.ParseCertificate(asn1Data) + if err != nil { + return errors.New("tls: failed to parse certificate from server: " + err.Error()) + } + certs[i] = cert + } + + opts := x509.VerifyOptions{ + Roots: config.RootCAs, // On the server side, use config.ClientCAs. + DNSName: config.ServerName, + Intermediates: x509.NewCertPool(), + // On the server side, set KeyUsages to ExtKeyUsageClientAuth. The + // default value is appropriate for clients side verification. + // KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, + } + for _, cert := range certs[1:] { + opts.Intermediates.AddCert(cert) + } + _, err := certs[0].Verify(opts) + return err + } + + // Note that when InsecureSkipVerify and VerifyPeerCertificate are in use, + // ConnectionState.VerifiedChains will be nil. +} diff --git a/libgo/go/crypto/tls/generate_cert.go b/libgo/go/crypto/tls/generate_cert.go index 7329d97a9d0..f1d69c401ab 100644 --- a/libgo/go/crypto/tls/generate_cert.go +++ b/libgo/go/crypto/tls/generate_cert.go @@ -78,7 +78,7 @@ func main() { log.Fatalf("Unrecognized elliptic curve: %q", *ecdsaCurve) } if err != nil { - log.Fatalf("Failed to generate private key: %s", err) + log.Fatalf("Failed to generate private key: %v", err) } var notBefore time.Time @@ -87,7 +87,7 @@ func main() { } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) if err != nil { - log.Fatalf("Failed to parse creation date: %s", err) + log.Fatalf("Failed to parse creation date: %v", err) } } @@ -96,7 +96,7 @@ func main() { serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { - log.Fatalf("Failed to generate serial number: %s", err) + log.Fatalf("Failed to generate serial number: %v", err) } template := x509.Certificate{ @@ -128,24 +128,24 @@ func main() { derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) if err != nil { - log.Fatalf("Failed to create certificate: %s", err) + log.Fatalf("Failed to create certificate: %v", err) } certOut, err := os.Create("cert.pem") if err != nil { - log.Fatalf("Failed to open cert.pem for writing: %s", err) + log.Fatalf("Failed to open cert.pem for writing: %v", err) } if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { - log.Fatalf("Failed to write data to cert.pem: %s", err) + log.Fatalf("Failed to write data to cert.pem: %v", err) } if err := certOut.Close(); err != nil { - log.Fatalf("Error closing cert.pem: %s", err) + log.Fatalf("Error closing cert.pem: %v", err) } log.Print("wrote cert.pem\n") keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { - log.Fatalf("Failed to open key.pem for writing:", err) + log.Fatalf("Failed to open key.pem for writing: %v", err) return } privBytes, err := x509.MarshalPKCS8PrivateKey(priv) @@ -153,10 +153,10 @@ func main() { log.Fatalf("Unable to marshal private key: %v", err) } if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil { - log.Fatalf("Failed to write data to key.pem: %s", err) + log.Fatalf("Failed to write data to key.pem: %v", err) } if err := keyOut.Close(); err != nil { - log.Fatalf("Error closing key.pem: %s", err) + log.Fatalf("Error closing key.pem: %v", err) } log.Print("wrote key.pem\n") } diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go index ed000eb6192..4fb528cc9bf 100644 --- a/libgo/go/crypto/tls/handshake_client.go +++ b/libgo/go/crypto/tls/handshake_client.go @@ -16,7 +16,6 @@ import ( "fmt" "io" "net" - "strconv" "strings" "sync/atomic" "time" @@ -50,7 +49,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) { return nil, nil, errors.New("tls: NextProtos values too large") } - supportedVersions := config.supportedVersions(true) + supportedVersions := config.supportedVersions() if len(supportedVersions) == 0 { return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion") } @@ -73,7 +72,6 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) { serverName: hostnameInSNI(config.ServerName), supportedCurves: config.curvePreferences(), supportedPoints: []uint8{pointFormatUncompressed}, - nextProtoNeg: len(config.NextProtos) > 0, secureRenegotiationSupported: true, alpnProtocols: config.NextProtos, supportedVersions: supportedVersions, @@ -340,7 +338,7 @@ func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error { peerVersion = serverHello.supportedVersion } - vers, ok := c.config.mutualVersion(true, []uint16{peerVersion}) + vers, ok := c.config.mutualVersion([]uint16{peerVersion}) if !ok { c.sendAlert(alertProtocolVersion) return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion) @@ -519,7 +517,7 @@ func (hs *clientHandshakeState) doFullHandshake() error { certRequested = true hs.finishedHash.Write(certReq.marshal()) - cri := certificateRequestInfoFromMsg(certReq) + cri := certificateRequestInfoFromMsg(c.vers, certReq) if chainToSend, err = c.getClientCertificate(cri); err != nil { c.sendAlert(alertInternalError) return err @@ -563,9 +561,7 @@ func (hs *clientHandshakeState) doFullHandshake() error { } if chainToSend != nil && len(chainToSend.Certificate) > 0 { - certVerify := &certificateVerifyMsg{ - hasSignatureAlgorithm: c.vers >= VersionTLS12, - } + certVerify := &certificateVerifyMsg{} key, ok := chainToSend.PrivateKey.(crypto.Signer) if !ok { @@ -573,23 +569,32 @@ func (hs *clientHandshakeState) doFullHandshake() error { return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey) } - signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(key.Public(), certReq.supportedSignatureAlgorithms, supportedSignatureAlgorithmsTLS12, c.vers) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - // SignatureAndHashAlgorithm was introduced in TLS 1.2. - if certVerify.hasSignatureAlgorithm { + var sigType uint8 + var sigHash crypto.Hash + if c.vers >= VersionTLS12 { + signatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms) + if err != nil { + c.sendAlert(alertIllegalParameter) + return err + } + sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) + if err != nil { + return c.sendAlert(alertInternalError) + } + certVerify.hasSignatureAlgorithm = true certVerify.signatureAlgorithm = signatureAlgorithm + } else { + sigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public()) + if err != nil { + c.sendAlert(alertIllegalParameter) + return err + } } - signed, err := hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - signOpts := crypto.SignerOpts(hashFunc) + + signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret) + signOpts := crypto.SignerOpts(sigHash) if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc} + signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} } certVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts) if err != nil { @@ -673,26 +678,14 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) { } } - clientDidNPN := hs.hello.nextProtoNeg clientDidALPN := len(hs.hello.alpnProtocols) > 0 - serverHasNPN := hs.serverHello.nextProtoNeg serverHasALPN := len(hs.serverHello.alpnProtocol) > 0 - if !clientDidNPN && serverHasNPN { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: server advertised unrequested NPN extension") - } - if !clientDidALPN && serverHasALPN { c.sendAlert(alertHandshakeFailure) return false, errors.New("tls: server advertised unrequested ALPN extension") } - if serverHasNPN && serverHasALPN { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: server advertised both NPN and ALPN extensions") - } - if serverHasALPN { c.clientProtocol = hs.serverHello.alpnProtocol c.clientProtocolFallback = false @@ -784,18 +777,6 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error { if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { return err } - if hs.serverHello.nextProtoNeg { - nextProto := new(nextProtoMsg) - proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos) - nextProto.proto = proto - c.clientProtocol = proto - c.clientProtocolFallback = fallback - - hs.finishedHash.Write(nextProto.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, nextProto.marshal()); err != nil { - return err - } - } finished := new(finishedMsg) finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) @@ -868,7 +849,12 @@ var ( // certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS // <= 1.2 CertificateRequest, making an effort to fill in missing information. -func certificateRequestInfoFromMsg(certReq *certificateRequestMsg) *CertificateRequestInfo { +func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo { + cri := &CertificateRequestInfo{ + AcceptableCAs: certReq.certificateAuthorities, + Version: vers, + } + var rsaAvail, ecAvail bool for _, certType := range certReq.certificateTypes { switch certType { @@ -879,10 +865,6 @@ func certificateRequestInfoFromMsg(certReq *certificateRequestMsg) *CertificateR } } - cri := &CertificateRequestInfo{ - AcceptableCAs: certReq.certificateAuthorities, - } - if !certReq.hasSignatureAlgorithm { // Prior to TLS 1.2, the signature schemes were not // included in the certificate request message. In this @@ -903,7 +885,11 @@ func certificateRequestInfoFromMsg(certReq *certificateRequestMsg) *CertificateR // See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated"). cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms)) for _, sigScheme := range certReq.supportedSignatureAlgorithms { - switch signatureFromSignatureScheme(sigScheme) { + sigType, _, err := typeAndHashFromSignatureScheme(sigScheme) + if err != nil { + continue + } + switch sigType { case signatureECDSA, signatureEd25519: if ecAvail { cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme) @@ -923,43 +909,11 @@ func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, return c.config.GetClientCertificate(cri) } - // We need to search our list of client certs for one - // where SignatureAlgorithm is acceptable to the server and the - // Issuer is in AcceptableCAs. - for i, chain := range c.config.Certificates { - sigOK := false - for _, alg := range signatureSchemesForCertificate(c.vers, &chain) { - if isSupportedSignatureAlgorithm(alg, cri.SignatureSchemes) { - sigOK = true - break - } - } - if !sigOK { + for _, chain := range c.config.Certificates { + if err := cri.SupportsCertificate(&chain); err != nil { continue } - - if len(cri.AcceptableCAs) == 0 { - return &chain, nil - } - - for j, cert := range chain.Certificate { - x509Cert := chain.Leaf - // Parse the certificate if this isn't the leaf node, or if - // chain.Leaf was nil. - if j != 0 || x509Cert == nil { - var err error - if x509Cert, err = x509.ParseCertificate(cert); err != nil { - c.sendAlert(alertInternalError) - return nil, errors.New("tls: failed to parse configured certificate chain #" + strconv.Itoa(i) + ": " + err.Error()) - } - } - - for _, ca := range cri.AcceptableCAs { - if bytes.Equal(x509Cert.RawIssuer, ca) { - return &chain, nil - } - } - } + return &chain, nil } // No acceptable certificate found. Don't send a certificate. @@ -991,7 +945,7 @@ func mutualProtocol(protos, preferenceProtos []string) (string, bool) { return protos[0], true } -// hostnameInSNI converts name into an approriate hostname for SNI. +// hostnameInSNI converts name into an appropriate hostname for SNI. // Literal IP addresses and absolute FQDNs are not permitted as SNI values. // See RFC 6066, Section 3. func hostnameInSNI(name string) string { diff --git a/libgo/go/crypto/tls/handshake_client_test.go b/libgo/go/crypto/tls/handshake_client_test.go index 1b6b9a1074d..6bd3c374ce2 100644 --- a/libgo/go/crypto/tls/handshake_client_test.go +++ b/libgo/go/crypto/tls/handshake_client_test.go @@ -499,21 +499,15 @@ func peekError(conn net.Conn) error { } func runClientTestForVersion(t *testing.T, template *clientTest, version, option string) { - t.Run(version, func(t *testing.T) { - // Make a deep copy of the template before going parallel. - test := *template - if template.config != nil { - test.config = template.config.Clone() - } - - if !*update { - t.Parallel() - } + // Make a deep copy of the template before going parallel. + test := *template + if template.config != nil { + test.config = template.config.Clone() + } + test.name = version + "-" + test.name + test.args = append([]string{option}, test.args...) - test.name = version + "-" + test.name - test.args = append([]string{option}, test.args...) - test.run(t, *update) - }) + runTestAndUpdateIfNeeded(t, version, test.run, false) } func runClientTestTLS10(t *testing.T, template *clientTest) { @@ -843,19 +837,8 @@ func TestHandshakeClientCertRSAPSS(t *testing.T) { cert: testRSAPSSCertificate, key: testRSAPrivateKey, } - runClientTestTLS13(t, test) - - // In our TLS 1.2 client, RSA-PSS is only supported for server certificates. - // See Issue 32425. - test = &clientTest{ - name: "ClientCert-RSA-RSAPSS", - args: []string{"-cipher", "AES128", "-Verify", "1", "-client_sigalgs", - "rsa_pkcs1_sha256", "-sigalgs", "rsa_pss_rsae_sha256"}, - config: config, - cert: testRSAPSSCertificate, - key: testRSAPrivateKey, - } runClientTestTLS12(t, test) + runClientTestTLS13(t, test) } func TestHandshakeClientCertRSAPKCS1v15(t *testing.T) { diff --git a/libgo/go/crypto/tls/handshake_client_tls13.go b/libgo/go/crypto/tls/handshake_client_tls13.go index 82207eb646d..8994591ee42 100644 --- a/libgo/go/crypto/tls/handshake_client_tls13.go +++ b/libgo/go/crypto/tls/handshake_client_tls13.go @@ -123,9 +123,7 @@ func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error { return errors.New("tls: server sent an incorrect legacy version") } - if hs.serverHello.nextProtoNeg || - len(hs.serverHello.nextProtos) != 0 || - hs.serverHello.ocspStapling || + if hs.serverHello.ocspStapling || hs.serverHello.ticketSupported || hs.serverHello.secureRenegotiationSupported || len(hs.serverHello.secureRenegotiation) != 0 || @@ -450,23 +448,21 @@ func (hs *clientHandshakeStateTLS13) readServerCertificate() error { // See RFC 8446, Section 4.4.3. if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid certificate signature algorithm") + return errors.New("tls: certificate used with invalid signature algorithm") } - sigType := signatureFromSignatureScheme(certVerify.signatureAlgorithm) - sigHash, err := hashFromSignatureScheme(certVerify.signatureAlgorithm) - if sigType == 0 || err != nil { - c.sendAlert(alertInternalError) - return err + sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) + if err != nil { + return c.sendAlert(alertInternalError) } if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid certificate signature algorithm") + return errors.New("tls: certificate used with invalid signature algorithm") } signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, sigHash, signed, certVerify.signature); err != nil { c.sendAlert(alertDecryptError) - return errors.New("tls: invalid certificate signature") + return errors.New("tls: invalid signature by the server certificate: " + err.Error()) } hs.transcript.Write(certVerify.marshal()) @@ -530,6 +526,7 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { cert, err := c.getClientCertificate(&CertificateRequestInfo{ AcceptableCAs: hs.certReq.certificateAuthorities, SignatureSchemes: hs.certReq.supportedSignatureAlgorithms, + Version: c.vers, }) if err != nil { return err @@ -554,29 +551,16 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { certVerifyMsg := new(certificateVerifyMsg) certVerifyMsg.hasSignatureAlgorithm = true - supportedAlgs := signatureSchemesForCertificate(c.vers, cert) - if supportedAlgs == nil { - c.sendAlert(alertInternalError) - return unsupportedCertificateError(cert) - } - // Pick signature scheme in server preference order, as the client - // preference order is not configurable. - for _, preferredAlg := range hs.certReq.supportedSignatureAlgorithms { - if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { - certVerifyMsg.signatureAlgorithm = preferredAlg - break - } - } - if certVerifyMsg.signatureAlgorithm == 0 { + certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms) + if err != nil { // getClientCertificate returned a certificate incompatible with the // CertificateRequestInfo supported signature algorithms. c.sendAlert(alertHandshakeFailure) - return errors.New("tls: server doesn't support selected certificate") + return err } - sigType := signatureFromSignatureScheme(certVerifyMsg.signatureAlgorithm) - sigHash, err := hashFromSignatureScheme(certVerifyMsg.signatureAlgorithm) - if sigType == 0 || err != nil { + sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm) + if err != nil { return c.sendAlert(alertInternalError) } diff --git a/libgo/go/crypto/tls/handshake_messages.go b/libgo/go/crypto/tls/handshake_messages.go index 2d21377737c..b5f81e44366 100644 --- a/libgo/go/crypto/tls/handshake_messages.go +++ b/libgo/go/crypto/tls/handshake_messages.go @@ -6,8 +6,9 @@ package tls import ( "fmt" - "golang.org/x/crypto/cryptobyte" "strings" + + "golang.org/x/crypto/cryptobyte" ) // The marshalingFunction type is an adapter to allow the use of ordinary @@ -72,7 +73,6 @@ type clientHelloMsg struct { sessionId []byte cipherSuites []uint16 compressionMethods []uint8 - nextProtoNeg bool serverName string ocspStapling bool supportedCurves []CurveID @@ -121,11 +121,6 @@ func (m *clientHelloMsg) marshal() []byte { bWithoutExtensions := *b b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if m.nextProtoNeg { - // draft-agl-tls-nextprotoneg-04 - b.AddUint16(extensionNextProtoNeg) - b.AddUint16(0) // empty extension_data - } if len(m.serverName) > 0 { // RFC 6066, Section 3 b.AddUint16(extensionServerName) @@ -426,9 +421,6 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool { return false } } - case extensionNextProtoNeg: - // draft-agl-tls-nextprotoneg-04 - m.nextProtoNeg = true case extensionStatusRequest: // RFC 4366, Section 3.6 var statusType uint8 @@ -604,8 +596,6 @@ type serverHelloMsg struct { sessionId []byte cipherSuite uint16 compressionMethod uint8 - nextProtoNeg bool - nextProtos []string ocspStapling bool ticketSupported bool secureRenegotiationSupported bool @@ -616,6 +606,7 @@ type serverHelloMsg struct { serverShare keyShare selectedIdentityPresent bool selectedIdentity uint16 + supportedPoints []uint8 // HelloRetryRequest extensions cookie []byte @@ -643,16 +634,6 @@ func (m *serverHelloMsg) marshal() []byte { bWithoutExtensions := *b b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if m.nextProtoNeg { - b.AddUint16(extensionNextProtoNeg) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, proto := range m.nextProtos { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(proto)) - }) - } - }) - } if m.ocspStapling { b.AddUint16(extensionStatusRequest) b.AddUint16(0) // empty extension_data @@ -727,6 +708,14 @@ func (m *serverHelloMsg) marshal() []byte { b.AddUint16(uint16(m.selectedGroup)) }) } + if len(m.supportedPoints) > 0 { + b.AddUint16(extensionSupportedPoints) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes(m.supportedPoints) + }) + }) + } extensionsPresent = len(b.BytesOrPanic()) > 2 }) @@ -771,16 +760,6 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool { } switch extension { - case extensionNextProtoNeg: - m.nextProtoNeg = true - for !extData.Empty() { - var proto cryptobyte.String - if !extData.ReadUint8LengthPrefixed(&proto) || - proto.Empty() { - return false - } - m.nextProtos = append(m.nextProtos, string(proto)) - } case extensionStatusRequest: m.ocspStapling = true case extensionSessionTicket: @@ -841,6 +820,12 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool { if !extData.ReadUint16(&m.selectedIdentity) { return false } + case extensionSupportedPoints: + // RFC 4492, Section 5.1.2 + if !readUint8LengthPrefixed(&extData, &m.supportedPoints) || + len(m.supportedPoints) == 0 { + return false + } default: // Ignore unknown extensions. continue @@ -1579,66 +1564,6 @@ func (m *finishedMsg) unmarshal(data []byte) bool { s.Empty() } -type nextProtoMsg struct { - raw []byte - proto string -} - -func (m *nextProtoMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - l := len(m.proto) - if l > 255 { - l = 255 - } - - padding := 32 - (l+2)%32 - length := l + padding + 2 - x := make([]byte, length+4) - x[0] = typeNextProtocol - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - y := x[4:] - y[0] = byte(l) - copy(y[1:], []byte(m.proto[0:l])) - y = y[1+l:] - y[0] = byte(padding) - - m.raw = x - - return x -} - -func (m *nextProtoMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 5 { - return false - } - data = data[4:] - protoLen := int(data[0]) - data = data[1:] - if len(data) < protoLen { - return false - } - m.proto = string(data[0:protoLen]) - data = data[protoLen:] - - if len(data) < 1 { - return false - } - paddingLen := int(data[0]) - data = data[1:] - if len(data) != paddingLen { - return false - } - - return true -} - type certificateRequestMsg struct { raw []byte // hasSignatureAlgorithm indicates whether this message includes a list of diff --git a/libgo/go/crypto/tls/handshake_messages_test.go b/libgo/go/crypto/tls/handshake_messages_test.go index 21beb8ef2de..bef75705129 100644 --- a/libgo/go/crypto/tls/handshake_messages_test.go +++ b/libgo/go/crypto/tls/handshake_messages_test.go @@ -26,7 +26,6 @@ var tests = []interface{}{ }, &certificateStatusMsg{}, &clientKeyExchangeMsg{}, - &nextProtoMsg{}, &newSessionTicketMsg{}, &sessionState{}, &sessionStateTLS13{}, @@ -127,9 +126,6 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { m.cipherSuites[i] = cs } m.compressionMethods = randomBytes(rand.Intn(63)+1, rand) - if rand.Intn(10) > 5 { - m.nextProtoNeg = true - } if rand.Intn(10) > 5 { m.serverName = randomString(rand.Intn(255), rand) for strings.HasSuffix(m.serverName, ".") { @@ -205,13 +201,7 @@ func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value { m.sessionId = randomBytes(rand.Intn(32), rand) m.cipherSuite = uint16(rand.Int31()) m.compressionMethod = uint8(rand.Intn(256)) - - if rand.Intn(10) > 5 { - m.nextProtoNeg = true - for i := 0; i < rand.Intn(10); i++ { - m.nextProtos = append(m.nextProtos, randomString(20, rand)) - } - } + m.supportedPoints = randomBytes(rand.Intn(5)+1, rand) if rand.Intn(10) > 5 { m.ocspStapling = true @@ -308,12 +298,6 @@ func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value { return reflect.ValueOf(m) } -func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value { - m := &nextProtoMsg{} - m.proto = randomString(rand.Intn(255), rand) - return reflect.ValueOf(m) -} - func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value { m := &newSessionTicketMsg{} m.ticket = randomBytes(rand.Intn(4), rand) diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go index a3d8848caf9..b16415a03c2 100644 --- a/libgo/go/crypto/tls/handshake_server.go +++ b/libgo/go/crypto/tls/handshake_server.go @@ -24,7 +24,7 @@ type serverHandshakeState struct { clientHello *clientHelloMsg hello *serverHelloMsg suite *cipherSuite - ecdhOk bool + ecdheOk bool ecSignOk bool rsaDecryptOk bool rsaSignOk bool @@ -157,7 +157,7 @@ func (c *Conn) readClientHello() (*clientHelloMsg, error) { if len(clientHello.supportedVersions) == 0 { clientVersions = supportedVersionsFromMax(clientHello.vers) } - c.vers, ok = c.config.mutualVersion(false, clientVersions) + c.vers, ok = c.config.mutualVersion(clientVersions) if !ok { c.sendAlert(alertProtocolVersion) return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions) @@ -175,27 +175,6 @@ func (hs *serverHandshakeState) processClientHello() error { hs.hello = new(serverHelloMsg) hs.hello.vers = c.vers - supportedCurve := false - preferredCurves := c.config.curvePreferences() -Curves: - for _, curve := range hs.clientHello.supportedCurves { - for _, supported := range preferredCurves { - if supported == curve { - supportedCurve = true - break Curves - } - } - } - - supportedPointFormat := false - for _, pointFormat := range hs.clientHello.supportedPoints { - if pointFormat == pointFormatUncompressed { - supportedPointFormat = true - break - } - } - hs.ecdhOk = supportedCurve && supportedPointFormat - foundCompression := false // We only support null compression, so check that the client offered it. for _, compression := range hs.clientHello.compressionMethods { @@ -213,7 +192,7 @@ Curves: hs.hello.random = make([]byte, 32) serverRandom := hs.hello.random // Downgrade protection canaries. See RFC 8446, Section 4.1.3. - maxVers := c.config.maxSupportedVersion(false) + maxVers := c.config.maxSupportedVersion() if maxVers >= VersionTLS12 && c.vers < maxVers { if c.vers == VersionTLS12 { copy(serverRandom[24:], downgradeCanaryTLS12) @@ -244,26 +223,32 @@ Curves: hs.hello.alpnProtocol = selectedProto c.clientProtocol = selectedProto } - } else { - // Although sending an empty NPN extension is reasonable, Firefox has - // had a bug around this. Best to send nothing at all if - // c.config.NextProtos is empty. See - // https://golang.org/issue/5445. - if hs.clientHello.nextProtoNeg && len(c.config.NextProtos) > 0 { - hs.hello.nextProtoNeg = true - hs.hello.nextProtos = c.config.NextProtos - } } hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello)) if err != nil { - c.sendAlert(alertInternalError) + if err == errNoCertificates { + c.sendAlert(alertUnrecognizedName) + } else { + c.sendAlert(alertInternalError) + } return err } if hs.clientHello.scts { hs.hello.scts = hs.cert.SignedCertificateTimestamps } + hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints) + + if hs.ecdheOk { + // Although omitting the ec_point_formats extension is permitted, some + // old OpenSSL version will refuse to handshake if not present. + // + // Per RFC 4492, section 5.1.2, implementations MUST support the + // uncompressed point format. See golang.org/issue/31943. + hs.hello.supportedPoints = []uint8{pointFormatUncompressed} + } + if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok { switch priv.Public().(type) { case *ecdsa.PublicKey: @@ -290,6 +275,28 @@ Curves: return nil } +// supportsECDHE returns whether ECDHE key exchanges can be used with this +// pre-TLS 1.3 client. +func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool { + supportsCurve := false + for _, curve := range supportedCurves { + if c.supportsCurve(curve) { + supportsCurve = true + break + } + } + + supportsPointFormat := false + for _, pointFormat := range supportedPoints { + if pointFormat == pointFormatUncompressed { + supportsPointFormat = true + break + } + } + + return supportsCurve && supportsPointFormat +} + func (hs *serverHandshakeState) pickCipherSuite() error { c := hs.c @@ -302,12 +309,7 @@ func (hs *serverHandshakeState) pickCipherSuite() error { supportedList = c.config.cipherSuites() } - for _, id := range preferenceList { - if hs.setCipherSuite(id, supportedList, c.vers) { - break - } - } - + hs.suite = selectCipherSuite(preferenceList, supportedList, hs.cipherSuiteOk) if hs.suite == nil { c.sendAlert(alertHandshakeFailure) return errors.New("tls: no cipher suite supported by both client and server") @@ -316,7 +318,7 @@ func (hs *serverHandshakeState) pickCipherSuite() error { for _, id := range hs.clientHello.cipherSuites { if id == TLS_FALLBACK_SCSV { // The client is doing a fallback connection. See RFC 7507. - if hs.clientHello.vers < c.config.maxSupportedVersion(false) { + if hs.clientHello.vers < c.config.maxSupportedVersion() { c.sendAlert(alertInappropriateFallback) return errors.New("tls: client using inappropriate protocol fallback") } @@ -327,6 +329,27 @@ func (hs *serverHandshakeState) pickCipherSuite() error { return nil } +func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool { + if c.flags&suiteECDHE != 0 { + if !hs.ecdheOk { + return false + } + if c.flags&suiteECSign != 0 { + if !hs.ecSignOk { + return false + } + } else if !hs.rsaSignOk { + return false + } + } else if !hs.rsaDecryptOk { + return false + } + if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { + return false + } + return true +} + // checkForResumption reports whether we should perform resumption on this connection. func (hs *serverHandshakeState) checkForResumption() bool { c := hs.c @@ -363,7 +386,9 @@ func (hs *serverHandshakeState) checkForResumption() bool { } // Check that we also support the ciphersuite from the session. - if !hs.setCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers) { + hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite}, + c.config.cipherSuites(), hs.cipherSuiteOk) + if hs.suite == nil { return false } @@ -467,7 +492,7 @@ func (hs *serverHandshakeState) doFullHandshake() error { } if c.vers >= VersionTLS12 { certReq.hasSignatureAlgorithm = true - certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithmsTLS12 + certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms } // An empty list of certificateAuthorities signals to @@ -562,20 +587,29 @@ func (hs *serverHandshakeState) doFullHandshake() error { return unexpectedMessageError(certVerify, msg) } - // Determine the signature type. - _, sigType, hashFunc, err := pickSignatureAlgorithm(pub, []SignatureScheme{certVerify.signatureAlgorithm}, certReq.supportedSignatureAlgorithms, c.vers) - if err != nil { - c.sendAlert(alertIllegalParameter) - return err + var sigType uint8 + var sigHash crypto.Hash + if c.vers >= VersionTLS12 { + if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) { + c.sendAlert(alertIllegalParameter) + return errors.New("tls: client certificate used with invalid signature algorithm") + } + sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) + if err != nil { + return c.sendAlert(alertInternalError) + } + } else { + sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub) + if err != nil { + c.sendAlert(alertIllegalParameter) + return err + } } - signed, err := hs.finishedHash.hashForClientCertificate(sigType, hashFunc, hs.masterSecret) - if err == nil { - err = verifyHandshakeSignature(sigType, pub, hashFunc, signed, certVerify.signature) - } - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("tls: could not validate signature of connection nonces: " + err.Error()) + signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret) + if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil { + c.sendAlert(alertDecryptError) + return errors.New("tls: invalid signature by the client certificate: " + err.Error()) } hs.finishedHash.Write(certVerify.marshal()) @@ -618,20 +652,6 @@ func (hs *serverHandshakeState) readFinished(out []byte) error { return err } - if hs.hello.nextProtoNeg { - msg, err := c.readHandshake() - if err != nil { - return err - } - nextProto, ok := msg.(*nextProtoMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(nextProto, msg) - } - hs.finishedHash.Write(nextProto.marshal()) - c.clientProtocol = nextProto.proto - } - msg, err := c.readHandshake() if err != nil { return err @@ -740,7 +760,7 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error { chains, err := certs[0].Verify(opts) if err != nil { c.sendAlert(alertBadCertificate) - return errors.New("tls: failed to verify client's certificate: " + err.Error()) + return errors.New("tls: failed to verify client certificate: " + err.Error()) } c.verifiedChains = chains @@ -761,7 +781,7 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error { case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey: default: c.sendAlert(alertUnsupportedCertificate) - return fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey) + return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey) } c.peerCertificates = certs @@ -770,43 +790,6 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error { return nil } -// setCipherSuite sets a cipherSuite with the given id as the serverHandshakeState -// suite if that cipher suite is acceptable to use. -// It returns a bool indicating if the suite was set. -func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16) bool { - for _, supported := range supportedCipherSuites { - if id != supported { - continue - } - candidate := cipherSuiteByID(id) - if candidate == nil { - continue - } - // Don't select a ciphersuite which we can't - // support for this client. - if candidate.flags&suiteECDHE != 0 { - if !hs.ecdhOk { - continue - } - if candidate.flags&suiteECSign != 0 { - if !hs.ecSignOk { - continue - } - } else if !hs.rsaSignOk { - continue - } - } else if !hs.rsaDecryptOk { - continue - } - if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { - continue - } - hs.suite = candidate - return true - } - return false -} - func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { supportedVersions := clientHello.supportedVersions if len(clientHello.supportedVersions) == 0 { @@ -822,5 +805,6 @@ func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { SupportedProtos: clientHello.alpnProtocols, SupportedVersions: supportedVersions, Conn: c.conn, + config: c.config, } } diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go index a9c1c08cbc4..1e5da1e12e1 100644 --- a/libgo/go/crypto/tls/handshake_server_test.go +++ b/libgo/go/crypto/tls/handshake_server_test.go @@ -8,6 +8,7 @@ import ( "bytes" "crypto" "crypto/elliptic" + "crypto/x509" "encoding/pem" "errors" "fmt" @@ -61,32 +62,20 @@ func TestSimpleError(t *testing.T) { testClientHelloFailure(t, testConfig, &serverHelloDoneMsg{}, "unexpected handshake message") } -var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205} +var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205, VersionSSL30} func TestRejectBadProtocolVersion(t *testing.T) { + config := testConfig.Clone() + config.MinVersion = VersionSSL30 for _, v := range badProtocolVersions { - testClientHelloFailure(t, testConfig, &clientHelloMsg{ + testClientHelloFailure(t, config, &clientHelloMsg{ vers: v, random: make([]byte, 32), }, "unsupported versions") } - testClientHelloFailure(t, testConfig, &clientHelloMsg{ - vers: VersionTLS12, - supportedVersions: badProtocolVersions, - random: make([]byte, 32), - }, "unsupported versions") -} - -func TestSSLv3OptIn(t *testing.T) { - config := testConfig.Clone() - config.MinVersion = 0 - testClientHelloFailure(t, config, &clientHelloMsg{ - vers: VersionSSL30, - random: make([]byte, 32), - }, "unsupported versions") testClientHelloFailure(t, config, &clientHelloMsg{ vers: VersionTLS12, - supportedVersions: []uint16{VersionSSL30}, + supportedVersions: badProtocolVersions, random: make([]byte, 32), }, "unsupported versions") } @@ -284,6 +273,79 @@ func TestTLS12OnlyCipherSuites(t *testing.T) { } } +func TestTLSPointFormats(t *testing.T) { + // Test that a Server returns the ec_point_format extension when ECC is + // negotiated, and not returned on RSA handshake. + tests := []struct { + name string + cipherSuites []uint16 + supportedCurves []CurveID + supportedPoints []uint8 + wantSupportedPoints bool + }{ + {"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{compressionNone}, true}, + {"RSA", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, nil, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + clientHello := &clientHelloMsg{ + vers: VersionTLS12, + random: make([]byte, 32), + cipherSuites: tt.cipherSuites, + compressionMethods: []uint8{compressionNone}, + supportedCurves: tt.supportedCurves, + supportedPoints: tt.supportedPoints, + } + + c, s := localPipe(t) + replyChan := make(chan interface{}) + go func() { + cli := Client(c, testConfig) + cli.vers = clientHello.vers + cli.writeRecord(recordTypeHandshake, clientHello.marshal()) + reply, err := cli.readHandshake() + c.Close() + if err != nil { + replyChan <- err + } else { + replyChan <- reply + } + }() + config := testConfig.Clone() + config.CipherSuites = clientHello.cipherSuites + Server(s, config).Handshake() + s.Close() + reply := <-replyChan + if err, ok := reply.(error); ok { + t.Fatal(err) + } + serverHello, ok := reply.(*serverHelloMsg) + if !ok { + t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply) + } + if tt.wantSupportedPoints { + if len(serverHello.supportedPoints) < 1 { + t.Fatal("missing ec_point_format extension from server") + } + found := false + for _, p := range serverHello.supportedPoints { + if p == pointFormatUncompressed { + found = true + break + } + } + if !found { + t.Fatal("missing uncompressed format in ec_point_format extension from server") + } + } else { + if len(serverHello.supportedPoints) != 0 { + t.Fatalf("unexcpected ec_point_format extension from server: %v", serverHello.supportedPoints) + } + } + }) + } +} + func TestAlertForwarding(t *testing.T) { c, s := localPipe(t) go func() { @@ -668,29 +730,19 @@ func (test *serverTest) run(t *testing.T, write bool) { } func runServerTestForVersion(t *testing.T, template *serverTest, version, option string) { - t.Run(version, func(t *testing.T) { - // Make a deep copy of the template before going parallel. - test := *template - if template.config != nil { - test.config = template.config.Clone() - } - - if !*update && !template.wait { - t.Parallel() - } - - test.name = version + "-" + test.name - if len(test.command) == 0 { - test.command = defaultClientCommand - } - test.command = append([]string(nil), test.command...) - test.command = append(test.command, option) - test.run(t, *update) - }) -} + // Make a deep copy of the template before going parallel. + test := *template + if template.config != nil { + test.config = template.config.Clone() + } + test.name = version + "-" + test.name + if len(test.command) == 0 { + test.command = defaultClientCommand + } + test.command = append([]string(nil), test.command...) + test.command = append(test.command, option) -func runServerTestSSLv3(t *testing.T, template *serverTest) { - runServerTestForVersion(t, template, "SSLv3", "-ssl3") + runTestAndUpdateIfNeeded(t, version, test.run, test.wait) } func runServerTestTLS10(t *testing.T, template *serverTest) { @@ -714,7 +766,6 @@ func TestHandshakeServerRSARC4(t *testing.T) { name: "RSA-RC4", command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"}, } - runServerTestSSLv3(t, test) runServerTestTLS10(t, test) runServerTestTLS11(t, test) runServerTestTLS12(t, test) @@ -725,7 +776,6 @@ func TestHandshakeServerRSA3DES(t *testing.T) { name: "RSA-3DES", command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "DES-CBC3-SHA"}, } - runServerTestSSLv3(t, test) runServerTestTLS10(t, test) runServerTestTLS12(t, test) } @@ -735,7 +785,6 @@ func TestHandshakeServerRSAAES(t *testing.T) { name: "RSA-AES", command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA"}, } - runServerTestSSLv3(t, test) runServerTestTLS10(t, test) runServerTestTLS12(t, test) } @@ -1131,16 +1180,20 @@ func TestHandshakeServerRSAPKCS1v15(t *testing.T) { } func TestHandshakeServerRSAPSS(t *testing.T) { + // We send rsa_pss_rsae_sha512 first, as the test key won't fit, and we + // verify the server implementation will disregard the client preference in + // that case. See Issue 29793. test := &serverTest{ - name: "RSA-RSAPSS", - command: []string{"openssl", "s_client", "-no_ticket", "-sigalgs", "rsa_pss_rsae_sha256"}, - expectHandshakeErrorIncluding: "peer doesn't support any common signature algorithms", // See Issue 32425. + name: "RSA-RSAPSS", + command: []string{"openssl", "s_client", "-no_ticket", "-sigalgs", "rsa_pss_rsae_sha512:rsa_pss_rsae_sha256"}, } runServerTestTLS12(t, test) + runServerTestTLS13(t, test) test = &serverTest{ - name: "RSA-RSAPSS", - command: []string{"openssl", "s_client", "-no_ticket", "-sigalgs", "rsa_pss_rsae_sha256"}, + name: "RSA-RSAPSS-TooSmall", + command: []string{"openssl", "s_client", "-no_ticket", "-sigalgs", "rsa_pss_rsae_sha512"}, + expectHandshakeErrorIncluding: "peer doesn't support any of the certificate's signature algorithms", } runServerTestTLS13(t, test) } @@ -1300,14 +1353,6 @@ func TestClientAuth(t *testing.T) { runServerTestTLS12(t, test) runServerTestTLS13(t, test) - test = &serverTest{ - name: "ClientAuthRequestedAndGiven", - command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", - "-cert", certPath, "-key", keyPath, "-client_sigalgs", "rsa_pss_rsae_sha256"}, - config: config, - expectedPeerCerts: []string{}, // See Issue 32425. - } - runServerTestTLS12(t, test) test = &serverTest{ name: "ClientAuthRequestedAndGiven", command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", @@ -1315,6 +1360,7 @@ func TestClientAuth(t *testing.T) { config: config, expectedPeerCerts: []string{clientCertificatePEM}, } + runServerTestTLS12(t, test) runServerTestTLS13(t, test) test = &serverTest{ @@ -1601,16 +1647,33 @@ T+E0J8wlH24pgwQHzy7Ko2qLwn1b5PW8ecrlvP1g config.MinVersion = VersionTLS13 server := Server(serverConn, config) err := server.Handshake() - expectError(t, err, "key size too small for PSS signature") + expectError(t, err, "key size too small") close(done) }() err = client.Handshake() expectError(t, err, "handshake failure") <-done +} + +func TestMultipleCertificates(t *testing.T) { + clientConfig := testConfig.Clone() + clientConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256} + clientConfig.MaxVersion = VersionTLS12 - // In TLS 1.2 RSA-PSS is not used, so this should succeed. See Issue 32425. serverConfig := testConfig.Clone() - serverConfig.Certificates = []Certificate{cert} - serverConfig.MaxVersion = VersionTLS12 - testHandshake(t, testConfig, serverConfig) + serverConfig.Certificates = []Certificate{{ + Certificate: [][]byte{testECDSACertificate}, + PrivateKey: testECDSAPrivateKey, + }, { + Certificate: [][]byte{testRSACertificate}, + PrivateKey: testRSAPrivateKey, + }} + + _, clientState, err := testHandshake(t, clientConfig, serverConfig) + if err != nil { + t.Fatal(err) + } + if got := clientState.PeerCertificates[0].PublicKeyAlgorithm; got != x509.RSA { + t.Errorf("expected RSA certificate, got %v", got) + } } diff --git a/libgo/go/crypto/tls/handshake_server_tls13.go b/libgo/go/crypto/tls/handshake_server_tls13.go index 74f430cf8ad..5432145de46 100644 --- a/libgo/go/crypto/tls/handshake_server_tls13.go +++ b/libgo/go/crypto/tls/handshake_server_tls13.go @@ -108,7 +108,7 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error { if id == TLS_FALLBACK_SCSV { // Use c.vers instead of max(supported_versions) because an attacker // could defeat this by adding an arbitrary high version otherwise. - if c.vers < c.config.maxSupportedVersion(false) { + if c.vers < c.config.maxSupportedVersion() { c.sendAlert(alertInappropriateFallback) return errors.New("tls: client using inappropriate protocol fallback") } @@ -356,36 +356,26 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error { return nil } - // This implements a very simplistic certificate selection strategy for now: - // getCertificate delegates to the application Config.GetCertificate, or - // selects based on the server_name only. If the selected certificate's - // public key does not match the client signature_algorithms, the handshake - // is aborted. No attention is given to signature_algorithms_cert, and it is - // not passed to the application Config.GetCertificate. This will need to - // improve according to RFC 8446, sections 4.4.2.2 and 4.2.3. + // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3. + if len(hs.clientHello.supportedSignatureAlgorithms) == 0 { + return c.sendAlert(alertMissingExtension) + } + certificate, err := c.config.getCertificate(clientHelloInfo(c, hs.clientHello)) if err != nil { - c.sendAlert(alertInternalError) - return err - } - supportedAlgs := signatureSchemesForCertificate(c.vers, certificate) - if supportedAlgs == nil { - c.sendAlert(alertInternalError) - return unsupportedCertificateError(certificate) - } - // Pick signature scheme in client preference order, as the server - // preference order is not configurable. - for _, preferredAlg := range hs.clientHello.supportedSignatureAlgorithms { - if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { - hs.sigAlg = preferredAlg - break + if err == errNoCertificates { + c.sendAlert(alertUnrecognizedName) + } else { + c.sendAlert(alertInternalError) } + return err } - if hs.sigAlg == 0 { - // getCertificate returned a certificate incompatible with the - // ClientHello supported signature algorithms. + hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms) + if err != nil { + // getCertificate returned a certificate that is unsupported or + // incompatible with the client's signature algorithms. c.sendAlert(alertHandshakeFailure) - return errors.New("tls: client doesn't support selected certificate") + return err } hs.cert = certificate @@ -510,7 +500,6 @@ func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool { !bytes.Equal(ch.random, ch1.random) || !bytes.Equal(ch.sessionId, ch1.sessionId) || !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) || - ch.nextProtoNeg != ch1.nextProtoNeg || ch.serverName != ch1.serverName || ch.ocspStapling != ch1.ocspStapling || !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) || @@ -621,9 +610,8 @@ func (hs *serverHandshakeStateTLS13) sendServerCertificate() error { certVerifyMsg.hasSignatureAlgorithm = true certVerifyMsg.signatureAlgorithm = hs.sigAlg - sigType := signatureFromSignatureScheme(hs.sigAlg) - sigHash, err := hashFromSignatureScheme(hs.sigAlg) - if sigType == 0 || err != nil { + sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg) + if err != nil { return c.sendAlert(alertInternalError) } @@ -802,23 +790,21 @@ func (hs *serverHandshakeStateTLS13) readClientCertificate() error { // See RFC 8446, Section 4.4.3. if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid certificate signature algorithm") + return errors.New("tls: client certificate used with invalid signature algorithm") } - sigType := signatureFromSignatureScheme(certVerify.signatureAlgorithm) - sigHash, err := hashFromSignatureScheme(certVerify.signatureAlgorithm) - if sigType == 0 || err != nil { - c.sendAlert(alertInternalError) - return err + sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) + if err != nil { + return c.sendAlert(alertInternalError) } if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid certificate signature algorithm") + return errors.New("tls: client certificate used with invalid signature algorithm") } signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, sigHash, signed, certVerify.signature); err != nil { c.sendAlert(alertDecryptError) - return errors.New("tls: invalid certificate signature") + return errors.New("tls: invalid signature by the client certificate: " + err.Error()) } hs.transcript.Write(certVerify.marshal()) diff --git a/libgo/go/crypto/tls/handshake_test.go b/libgo/go/crypto/tls/handshake_test.go index cfd92908a96..f55cd16ca81 100644 --- a/libgo/go/crypto/tls/handshake_test.go +++ b/libgo/go/crypto/tls/handshake_test.go @@ -17,6 +17,7 @@ import ( "net" "os" "os/exec" + "runtime" "strconv" "strings" "sync" @@ -36,17 +37,31 @@ import ( // implementation. // // Tests can be updated by running them with the -update flag. This will cause -// the test files to be regenerated. Generally one should combine the -update -// flag with -test.run to updated a specific test. Since the reference -// implementation will always generate fresh random numbers, large parts of -// the reference connection will always change. +// the test files for failing tests to be regenerated. Since the reference +// implementation will always generate fresh random numbers, large parts of the +// reference connection will always change. var ( - update = flag.Bool("update", false, "update golden files on disk") + update = flag.Bool("update", false, "update golden files on failure") fast = flag.Bool("fast", false, "impose a quick, possibly flaky timeout on recorded tests") keyFile = flag.String("keylog", "", "destination file for KeyLogWriter") ) +func runTestAndUpdateIfNeeded(t *testing.T, name string, run func(t *testing.T, update bool), wait bool) { + success := t.Run(name, func(t *testing.T) { + if !*update && !wait { + t.Parallel() + } + run(t, false) + }) + + if !success && *update { + t.Run(name+"#update", func(t *testing.T) { + run(t, true) + }) + } +} + // checkOpenSSLVersion ensures that the version of OpenSSL looks reasonable // before updating the test data. func checkOpenSSLVersion() error { @@ -71,7 +86,7 @@ func checkOpenSSLVersion() error { println("to update the test data.") println("") println("Configure it with:") - println("./Configure enable-weak-ssl-ciphers enable-ssl3 enable-ssl3-method") + println("./Configure enable-weak-ssl-ciphers") println("and then add the apps/ directory at the front of your PATH.") println("***********************************************") @@ -243,19 +258,29 @@ func localServer(l net.Listener) { } } +var isConnRefused = func(err error) bool { return false } + func localPipe(t testing.TB) (net.Conn, net.Conn) { localListener.mu.Lock() defer localListener.mu.Unlock() addr := localListener.addr + var err error Dialing: // We expect a rare mismatch, but probably not 5 in a row. for i := 0; i < 5; i++ { tooSlow := time.NewTimer(1 * time.Second) defer tooSlow.Stop() - c1, err := net.Dial(addr.Network(), addr.String()) + var c1 net.Conn + c1, err = net.Dial(addr.Network(), addr.String()) if err != nil { + if runtime.GOOS == "dragonfly" && (isConnRefused(err) || os.IsTimeout(err)) { + // golang.org/issue/29583: Dragonfly sometimes returns a spurious + // ECONNREFUSED or ETIMEDOUT. + <-tooSlow.C + continue + } t.Fatalf("localPipe: %v", err) } if localFlakes == 2 && i == 0 { @@ -279,7 +304,7 @@ Dialing: } } - t.Fatalf("localPipe: failed to connect") + t.Fatalf("localPipe: failed to connect: %v", err) panic("unreachable") } @@ -345,8 +370,6 @@ func runMain(m *testing.M) int { Rand: zeroSource{}, Certificates: make([]Certificate, 2), InsecureSkipVerify: true, - MinVersion: VersionSSL30, - MaxVersion: VersionTLS13, CipherSuites: allCipherSuites(), } testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate} diff --git a/libgo/go/crypto/tls/handshake_unix_test.go b/libgo/go/crypto/tls/handshake_unix_test.go new file mode 100644 index 00000000000..72718544ae6 --- /dev/null +++ b/libgo/go/crypto/tls/handshake_unix_test.go @@ -0,0 +1,18 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris + +package tls + +import ( + "errors" + "syscall" +) + +func init() { + isConnRefused = func(err error) bool { + return errors.Is(err, syscall.ECONNREFUSED) + } +} diff --git a/libgo/go/crypto/tls/key_agreement.go b/libgo/go/crypto/tls/key_agreement.go index 2922017cc4d..03aa861a1d8 100644 --- a/libgo/go/crypto/tls/key_agreement.go +++ b/libgo/go/crypto/tls/key_agreement.go @@ -11,6 +11,7 @@ import ( "crypto/sha1" "crypto/x509" "errors" + "fmt" "io" ) @@ -29,15 +30,12 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certifi if len(ckx.ciphertext) < 2 { return nil, errClientKeyExchange } - - ciphertext := ckx.ciphertext - if version != VersionSSL30 { - ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) - if ciphertextLen != len(ckx.ciphertext)-2 { - return nil, errClientKeyExchange - } - ciphertext = ckx.ciphertext[2:] + ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) + if ciphertextLen != len(ckx.ciphertext)-2 { + return nil, errClientKeyExchange } + ciphertext := ckx.ciphertext[2:] + priv, ok := cert.PrivateKey.(crypto.Decrypter) if !ok { return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter") @@ -145,16 +143,11 @@ type ecdheKeyAgreement struct { } func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - preferredCurves := config.curvePreferences() - var curveID CurveID -NextCandidate: - for _, candidate := range preferredCurves { - for _, c := range clientHello.supportedCurves { - if candidate == c { - curveID = c - break NextCandidate - } + for _, c := range clientHello.supportedCurves { + if config.supportsCurve(c) { + curveID = c + break } } @@ -173,31 +166,45 @@ NextCandidate: // See RFC 4492, Section 5.4. ecdhePublic := params.PublicKey() - serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic)) - serverECDHParams[0] = 3 // named curve - serverECDHParams[1] = byte(curveID >> 8) - serverECDHParams[2] = byte(curveID) - serverECDHParams[3] = byte(len(ecdhePublic)) - copy(serverECDHParams[4:], ecdhePublic) + serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic)) + serverECDHEParams[0] = 3 // named curve + serverECDHEParams[1] = byte(curveID >> 8) + serverECDHEParams[2] = byte(curveID) + serverECDHEParams[3] = byte(len(ecdhePublic)) + copy(serverECDHEParams[4:], ecdhePublic) priv, ok := cert.PrivateKey.(crypto.Signer) if !ok { - return nil, errors.New("tls: certificate private key does not implement crypto.Signer") + return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey) } - signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(priv.Public(), clientHello.supportedSignatureAlgorithms, supportedSignatureAlgorithmsTLS12, ka.version) - if err != nil { - return nil, err + var signatureAlgorithm SignatureScheme + var sigType uint8 + var sigHash crypto.Hash + if ka.version >= VersionTLS12 { + signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms) + if err != nil { + return nil, err + } + sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) + if err != nil { + return nil, err + } + } else { + sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public()) + if err != nil { + return nil, err + } } if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { return nil, errors.New("tls: certificate cannot be used with the selected cipher suite") } - signed := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, hello.random, serverECDHParams) + signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams) - signOpts := crypto.SignerOpts(hashFunc) + signOpts := crypto.SignerOpts(sigHash) if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc} + signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} } sig, err := priv.Sign(config.rand(), signed, signOpts) if err != nil { @@ -209,9 +216,9 @@ NextCandidate: if ka.version >= VersionTLS12 { sigAndHashLen = 2 } - skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig)) - copy(skx.key, serverECDHParams) - k := skx.key[len(serverECDHParams):] + skx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig)) + copy(skx.key, serverECDHEParams) + k := skx.key[len(serverECDHEParams):] if ka.version >= VersionTLS12 { k[0] = byte(signatureAlgorithm >> 8) k[1] = byte(signatureAlgorithm) @@ -250,8 +257,8 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell if publicLen+4 > len(skx.key) { return errServerKeyExchange } - serverECDHParams := skx.key[:4+publicLen] - publicKey := serverECDHParams[4:] + serverECDHEParams := skx.key[:4+publicLen] + publicKey := serverECDHEParams[4:] sig := skx.key[4+publicLen:] if len(sig) < 2 { @@ -279,18 +286,27 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell ka.ckx.ciphertext[0] = byte(len(ourPublicKey)) copy(ka.ckx.ciphertext[1:], ourPublicKey) - var signatureAlgorithm SignatureScheme + var sigType uint8 + var sigHash crypto.Hash if ka.version >= VersionTLS12 { - // handle SignatureAndHashAlgorithm - signatureAlgorithm = SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1]) + signatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1]) sig = sig[2:] if len(sig) < 2 { return errServerKeyExchange } - } - _, sigType, hashFunc, err := pickSignatureAlgorithm(cert.PublicKey, []SignatureScheme{signatureAlgorithm}, clientHello.supportedSignatureAlgorithms, ka.version) - if err != nil { - return err + + if !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) { + return errors.New("tls: certificate used with invalid signature algorithm") + } + sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) + if err != nil { + return err + } + } else { + sigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey) + if err != nil { + return err + } } if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { return errServerKeyExchange @@ -302,8 +318,11 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell } sig = sig[2:] - signed := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, serverHello.random, serverECDHParams) - return verifyHandshakeSignature(sigType, cert.PublicKey, hashFunc, signed, sig) + signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams) + if err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil { + return errors.New("tls: invalid signature by the server certificate: " + err.Error()) + } + return nil } func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { diff --git a/libgo/go/crypto/tls/key_schedule.go b/libgo/go/crypto/tls/key_schedule.go index 83e5480fc5e..2aab323202f 100644 --- a/libgo/go/crypto/tls/key_schedule.go +++ b/libgo/go/crypto/tls/key_schedule.go @@ -7,14 +7,14 @@ package tls import ( "crypto/elliptic" "crypto/hmac" - "crypto/subtle" "errors" - "golang.org/x/crypto/cryptobyte" - "golang.org/x/crypto/curve25519" - "golang.org/x/crypto/hkdf" "hash" "io" "math/big" + + "golang.org/x/crypto/cryptobyte" + "golang.org/x/crypto/curve25519" + "golang.org/x/crypto/hkdf" ) // This file contains the functions necessary to compute the TLS 1.3 key @@ -111,12 +111,15 @@ type ecdheParameters interface { func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) { if curveID == X25519 { - p := &x25519Parameters{} - if _, err := io.ReadFull(rand, p.privateKey[:]); err != nil { + privateKey := make([]byte, curve25519.ScalarSize) + if _, err := io.ReadFull(rand, privateKey); err != nil { + return nil, err + } + publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint) + if err != nil { return nil, err } - curve25519.ScalarBaseMult(&p.publicKey, &p.privateKey) - return p, nil + return &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil } curve, ok := curveForCurveID(curveID) @@ -178,8 +181,8 @@ func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte { } type x25519Parameters struct { - privateKey [32]byte - publicKey [32]byte + privateKey []byte + publicKey []byte } func (p *x25519Parameters) CurveID() CurveID { @@ -191,19 +194,9 @@ func (p *x25519Parameters) PublicKey() []byte { } func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte { - if len(peerPublicKey) != 32 { - return nil - } - - var theirPublicKey, sharedKey [32]byte - copy(theirPublicKey[:], peerPublicKey) - curve25519.ScalarMult(&sharedKey, &p.privateKey, &theirPublicKey) - - // Check for low-order inputs. See RFC 8422, Section 5.11. - var allZeroes [32]byte - if subtle.ConstantTimeCompare(allZeroes[:], sharedKey[:]) == 1 { + sharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey) + if err != nil { return nil } - - return sharedKey[:] + return sharedKey } diff --git a/libgo/go/crypto/tls/prf.go b/libgo/go/crypto/tls/prf.go index 5e97726e792..13bfa009ca4 100644 --- a/libgo/go/crypto/tls/prf.go +++ b/libgo/go/crypto/tls/prf.go @@ -74,39 +74,6 @@ func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { } } -// prf30 implements the SSL 3.0 pseudo-random function, as defined in -// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6. -func prf30(result, secret, label, seed []byte) { - hashSHA1 := sha1.New() - hashMD5 := md5.New() - - done := 0 - i := 0 - // RFC 5246 section 6.3 says that the largest PRF output needed is 128 - // bytes. Since no more ciphersuites will be added to SSLv3, this will - // remain true. Each iteration gives us 16 bytes so 10 iterations will - // be sufficient. - var b [11]byte - for done < len(result) { - for j := 0; j <= i; j++ { - b[j] = 'A' + byte(i) - } - - hashSHA1.Reset() - hashSHA1.Write(b[:i+1]) - hashSHA1.Write(secret) - hashSHA1.Write(seed) - digest := hashSHA1.Sum(nil) - - hashMD5.Reset() - hashMD5.Write(secret) - hashMD5.Write(digest) - - done += copy(result[done:], hashMD5.Sum(nil)) - i++ - } -} - const ( masterSecretLength = 48 // Length of a master secret in TLS 1.1. finishedVerifyLength = 12 // Length of verify_data in a Finished message. @@ -119,8 +86,6 @@ var serverFinishedLabel = []byte("server finished") func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) { switch version { - case VersionSSL30: - return prf30, crypto.Hash(0) case VersionTLS10, VersionTLS11: return prf10, crypto.Hash(0) case VersionTLS12: @@ -175,28 +140,9 @@ func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clie return } -// hashFromSignatureScheme returns the corresponding crypto.Hash for a given -// hash from a TLS SignatureScheme. -func hashFromSignatureScheme(signatureAlgorithm SignatureScheme) (crypto.Hash, error) { - switch signatureAlgorithm { - case PKCS1WithSHA1, ECDSAWithSHA1: - return crypto.SHA1, nil - case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256: - return crypto.SHA256, nil - case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384: - return crypto.SHA384, nil - case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512: - return crypto.SHA512, nil - case Ed25519: - return directSigning, nil - default: - return 0, fmt.Errorf("tls: unsupported signature algorithm: %#04x", signatureAlgorithm) - } -} - func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash { var buffer []byte - if version == VersionSSL30 || version >= VersionTLS12 { + if version >= VersionTLS12 { buffer = []byte{} } @@ -251,48 +197,9 @@ func (h finishedHash) Sum() []byte { return h.client.Sum(out) } -// finishedSum30 calculates the contents of the verify_data member of a SSLv3 -// Finished message given the MD5 and SHA1 hashes of a set of handshake -// messages. -func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic []byte) []byte { - md5.Write(magic) - md5.Write(masterSecret) - md5.Write(ssl30Pad1[:]) - md5Digest := md5.Sum(nil) - - md5.Reset() - md5.Write(masterSecret) - md5.Write(ssl30Pad2[:]) - md5.Write(md5Digest) - md5Digest = md5.Sum(nil) - - sha1.Write(magic) - sha1.Write(masterSecret) - sha1.Write(ssl30Pad1[:40]) - sha1Digest := sha1.Sum(nil) - - sha1.Reset() - sha1.Write(masterSecret) - sha1.Write(ssl30Pad2[:40]) - sha1.Write(sha1Digest) - sha1Digest = sha1.Sum(nil) - - ret := make([]byte, len(md5Digest)+len(sha1Digest)) - copy(ret, md5Digest) - copy(ret[len(md5Digest):], sha1Digest) - return ret -} - -var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54} -var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52} - // clientSum returns the contents of the verify_data member of a client's // Finished message. func (h finishedHash) clientSum(masterSecret []byte) []byte { - if h.version == VersionSSL30 { - return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic[:]) - } - out := make([]byte, finishedVerifyLength) h.prf(out, masterSecret, clientFinishedLabel, h.Sum()) return out @@ -301,10 +208,6 @@ func (h finishedHash) clientSum(masterSecret []byte) []byte { // serverSum returns the contents of the verify_data member of a server's // Finished message. func (h finishedHash) serverSum(masterSecret []byte) []byte { - if h.version == VersionSSL30 { - return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic[:]) - } - out := make([]byte, finishedVerifyLength) h.prf(out, masterSecret, serverFinishedLabel, h.Sum()) return out @@ -312,38 +215,26 @@ func (h finishedHash) serverSum(masterSecret []byte) []byte { // hashForClientCertificate returns the handshake messages so far, pre-hashed if // necessary, suitable for signing by a TLS client certificate. -func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) ([]byte, error) { - if (h.version == VersionSSL30 || h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil { +func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) []byte { + if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil { panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer") } - if h.version == VersionSSL30 { - if sigType != signaturePKCS1v15 { - return nil, errors.New("tls: unsupported signature type for client certificate") - } - - md5Hash := md5.New() - md5Hash.Write(h.buffer) - sha1Hash := sha1.New() - sha1Hash.Write(h.buffer) - return finishedSum30(md5Hash, sha1Hash, masterSecret, nil), nil - } - if sigType == signatureEd25519 { - return h.buffer, nil + return h.buffer } if h.version >= VersionTLS12 { hash := hashAlg.New() hash.Write(h.buffer) - return hash.Sum(nil), nil + return hash.Sum(nil) } if sigType == signatureECDSA { - return h.server.Sum(nil), nil + return h.server.Sum(nil) } - return h.Sum(), nil + return h.Sum() } // discardHandshakeBuffer is called when there is no more need to @@ -353,7 +244,7 @@ func (h *finishedHash) discardHandshakeBuffer() { } // noExportedKeyingMaterial is used as a value of -// ConnectionState.ekm when renegotation is enabled and thus +// ConnectionState.ekm when renegotiation is enabled and thus // we wish to fail all key-material export requests. func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) { return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled") diff --git a/libgo/go/crypto/tls/prf_test.go b/libgo/go/crypto/tls/prf_test.go index ec54aac12e4..8233985a62b 100644 --- a/libgo/go/crypto/tls/prf_test.go +++ b/libgo/go/crypto/tls/prf_test.go @@ -137,20 +137,4 @@ var testKeysFromTests = []testKeysFromTest{ "678b0d43f607de35241dc7e9d1a7388a52c35033a1a0336d4d740060a6638fe2", "f3b4ac743f015ef21d79978297a53da3e579ee047133f38c234d829c0f907dab", }, - { - VersionSSL30, - cipherSuiteByID(TLS_RSA_WITH_RC4_128_SHA), - "832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1", - "4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e", - "4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e", - "a614863e56299dcffeea2938f22c2ba023768dbe4b3f6877bc9c346c6ae529b51d9cb87ff9695ea4d01f2205584405b2", - "2c450d5b6f6e2013ac6bea6a0b32200d4e1ffb94", - "7a7a7438769536f2fb1ae49a61f0703b79b2dc53", - "f8f6b26c10f12855c9aafb1e0e839ccf", - "2b9d4b4a60cb7f396780ebff50650419", - 20, - 16, - "d230d8fc4f695be60368635e5268c414ca3ae0995dd93aba9f877272049f35bf", - "6b5e9646e04df8e99482a9b22dbfbe42ddd4725e4b041d02d11e4ef44ad13120", - }, } diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN b/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN index 2708b262b6b..358b211fc19 100644 --- a/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN +++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-ALPN @@ -1,5 +1,5 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 12 01 00 01 0e 03 03 00 00 00 00 00 |................| +00000000 16 03 01 01 0e 01 00 01 0a 03 03 00 00 00 00 00 |................| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 |........... ....| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| @@ -7,22 +7,22 @@ 00000050 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#| 00000060 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5| 00000070 c0 12 00 0a 00 05 c0 11 c0 07 13 01 13 03 13 02 |................| -00000080 01 00 00 93 33 74 00 00 00 05 00 05 01 00 00 00 |....3t..........| -00000090 00 00 0a 00 0a 00 08 00 1d 00 17 00 18 00 19 00 |................| -000000a0 0b 00 02 01 00 00 0d 00 1a 00 18 08 04 04 03 08 |................| -000000b0 07 08 05 08 06 04 01 05 01 06 01 05 03 06 03 02 |................| -000000c0 01 02 03 ff 01 00 01 00 00 10 00 10 00 0e 06 70 |...............p| -000000d0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 12 00 00 |roto2.proto1....| -000000e0 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 33 00 |.+............3.| -000000f0 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 43 15 |&.$... /.}.G.bC.| -00000100 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| -00000110 90 99 5f 58 cb 3b 74 |.._X.;t| +00000080 01 00 00 8f 00 05 00 05 01 00 00 00 00 00 0a 00 |................| +00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................| +000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................| +000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................| +000000c0 01 00 01 00 00 10 00 10 00 0e 06 70 72 6f 74 6f |...........proto| +000000d0 32 06 70 72 6f 74 6f 31 00 12 00 00 00 2b 00 09 |2.proto1.....+..| +000000e0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.| +000000f0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._| +00000100 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X| +00000110 cb 3b 74 |.;t| >>> Flow 2 (server to client) -00000000 16 03 03 00 66 02 00 00 62 03 03 0e b3 00 4c e5 |....f...b.....L.| -00000010 e4 08 c5 3d c2 9c 19 a1 de ae 43 24 9a 4d 81 99 |...=......C$.M..| -00000020 df 60 cf a5 be ae c1 e8 e8 b9 a8 20 14 e6 e1 91 |.`......... ....| -00000030 7a ab 9f 7b 3c dc c5 71 4b 28 80 5e fa 56 c9 b7 |z..{<..qK(.^.V..| -00000040 d4 2f 0e 80 49 df 81 93 df 5d 34 49 cc a8 00 00 |./..I....]4I....| +00000000 16 03 03 00 66 02 00 00 62 03 03 95 14 55 52 0b |....f...b....UR.| +00000010 e7 c1 15 6b dc 19 3b 17 9e bb 6a b7 61 82 dc 59 |...k..;...j.a..Y| +00000020 d3 a4 7c e1 c3 83 cc e2 e5 56 e0 20 3c 82 0d 54 |..|......V. <..T| +00000030 2b 78 fe 50 cb 4e c1 69 d7 6f b3 9f ac 2e 27 c8 |+x.P.N.i.o....'.| +00000040 c6 7a 70 27 1e 14 67 43 4c f1 7d d7 cc a8 00 00 |.zp'..gCL.}.....| 00000050 1a ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 10 |................| 00000060 00 09 00 07 06 70 72 6f 74 6f 31 16 03 03 02 59 |.....proto1....Y| 00000070 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 |...U..R..O0..K0.| @@ -63,31 +63,31 @@ 000002a0 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 |.....@.a.Lr+...F| 000002b0 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 |..M...>...B...=.| 000002c0 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 |`.\!.;..........| -000002d0 00 a8 03 00 1d 20 18 37 3a d3 0a 4f 9b 95 c7 f0 |..... .7:..O....| -000002e0 a2 00 43 5f df 2e a8 16 a9 9f 2a 0e 51 cf c9 b9 |..C_......*.Q...| -000002f0 14 62 a7 ab 4b 6a 08 04 00 80 1a b2 78 e7 cd b6 |.b..Kj......x...| -00000300 18 65 31 19 f9 91 9f a6 cb 77 97 69 86 27 ef 06 |.e1......w.i.'..| -00000310 b5 bc f4 8f 75 96 01 72 64 2c d4 e4 67 0a d5 58 |....u..rd,..g..X| -00000320 e0 e1 05 82 a6 58 f6 e0 06 c2 15 03 69 ba 5a a0 |.....X......i.Z.| -00000330 2b af 6f b1 cd 16 84 1d 89 9c d0 c7 d2 c7 83 e8 |+.o.............| -00000340 43 b7 4f e8 ca 97 c0 e2 57 d0 10 48 0c 26 cf 58 |C.O.....W..H.&.X| -00000350 50 69 d8 86 b6 f5 aa 02 b8 f6 41 c4 15 52 99 52 |Pi........A..R.R| -00000360 05 05 5b 42 80 6d 8a bf 7a e6 f3 60 c5 67 23 dc |..[B.m..z..`.g#.| -00000370 39 4b e6 74 0e 0e 47 a7 57 02 16 03 03 00 04 0e |9K.t..G.W.......| +000002d0 00 a8 03 00 1d 20 c3 e3 43 9c 5d 0f 09 61 ae 18 |..... ..C.]..a..| +000002e0 66 05 b1 7d c1 9f e5 26 9c a7 97 d6 1f 9a 7c ff |f..}...&......|.| +000002f0 8c 34 a1 32 a2 35 08 04 00 80 6c 50 a1 80 d9 20 |.4.2.5....lP... | +00000300 56 08 da d9 5b 77 4d ad 43 66 71 15 ec fe db 02 |V...[wM.Cfq.....| +00000310 fb 40 d8 8d 67 22 e2 1b ec 8d b9 4e ba 65 01 8b |.@..g".....N.e..| +00000320 70 e0 83 bc 06 1b 14 8f 07 cf a6 08 58 c3 77 94 |p...........X.w.| +00000330 0f 94 53 62 54 6c 1f 92 22 9d ae f8 5a ad d5 f3 |..SbTl.."...Z...| +00000340 8a f7 e6 93 8c 0e 48 1b 23 89 d8 bd e9 5c 50 cd |......H.#....\P.| +00000350 07 3d 7e 8e b0 d6 65 44 58 62 03 a1 d9 94 72 f0 |.=~...eDXb....r.| +00000360 25 a9 e0 c1 be ac 32 05 59 f7 7f 6e 13 23 70 5a |%.....2.Y..n.#pZ| +00000370 65 ba a2 d7 da 3c a2 9e 6b 13 16 03 03 00 04 0e |e....<..k.......| 00000380 00 00 00 |...| >>> Flow 3 (client to server) 00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.| 00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....| 00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......| -00000030 16 03 03 00 20 0d 3c cf 6f 13 e3 73 d2 c5 05 06 |.... .<.o..s....| -00000040 85 8d 41 e0 46 3b 25 e7 0a ae b9 00 1e c3 3f 61 |..A.F;%.......?a| -00000050 82 2d e1 19 a4 |.-...| +00000030 16 03 03 00 20 5e 91 45 7d ab 7c b7 6f 57 a6 d0 |.... ^.E}.|.oW..| +00000040 17 83 cb 40 1b 76 6b 5e 80 39 03 2f 6d 2f 10 8e |...@.vk^.9./m/..| +00000050 74 33 12 54 8d |t3.T.| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 20 43 1a 5d c1 dc |.......... C.]..| -00000010 42 10 81 bc af 2d 40 82 fa 27 41 81 cc e5 97 99 |B....-@..'A.....| -00000020 80 27 3a b5 db f5 8e 2a 6d 72 86 |.':....*mr.| +00000000 14 03 03 00 01 01 16 03 03 00 20 f1 3c 7a 28 eb |.......... .>> Flow 5 (client to server) -00000000 17 03 03 00 16 f1 0a 98 3b 2a 06 98 ad 46 f5 f7 |........;*...F..| -00000010 42 cf 89 c0 d4 a7 08 df bb dc 4d 15 03 03 00 12 |B.........M.....| -00000020 9c d4 d2 a1 fb 38 98 31 7d ce 39 50 0b 58 d8 a8 |.....8.1}.9P.X..| -00000030 3e 19 |>.| +00000000 17 03 03 00 16 dc f6 18 54 22 e0 9c 08 bf db a8 |........T"......| +00000010 62 2a 64 9e 06 43 0f 22 18 0e 34 15 03 03 00 12 |b*d..C."..4.....| +00000020 20 2f f4 76 cd dc 82 eb 30 f9 e0 42 6b 29 16 ed | /.v....0..Bk)..| +00000030 7c f0 ||.| diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384 b/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384 index 22115d55651..3975b072c95 100644 --- a/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384 +++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384 @@ -16,11 +16,11 @@ 000000e0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0| 000000f0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |.........._X.;t| >>> Flow 2 (server to client) -00000000 16 03 03 00 59 02 00 00 55 03 03 41 6b 69 65 47 |....Y...U..AkieG| -00000010 8c 15 2f d5 6d 1a 3d 0c ff 56 ad 42 31 6c 1f 86 |../.m.=..V.B1l..| -00000020 06 62 e3 e4 18 9c 5c 47 9e 8c 66 20 af ba 7c 62 |.b....\G..f ..|b| -00000030 c2 32 f4 49 f1 8d f4 ba 7a 51 23 32 46 96 7e b8 |.2.I....zQ#2F.~.| -00000040 f0 2c ae 0a d4 04 49 16 4a 64 79 c8 c0 30 00 00 |.,....I.Jdy..0..| +00000000 16 03 03 00 59 02 00 00 55 03 03 d4 20 b3 4c 6a |....Y...U... .Lj| +00000010 69 44 3f f7 ab 15 35 85 ca 71 02 b0 70 18 8e d6 |iD?...5..q..p...| +00000020 61 d5 34 08 42 de cf a1 57 32 96 20 8c b4 72 dd |a.4.B...W2. ..r.| +00000030 63 93 e6 13 9d 4a ec 75 d9 a1 a6 9e 5e 02 f5 63 |c....J.u....^..c| +00000040 29 1a 78 9f 94 9f 6c 58 b5 91 ae 63 c0 30 00 00 |).x...lX...c.0..| 00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| 00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..| 00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............| @@ -60,17 +60,17 @@ 00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.| 000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..| 000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......| -000002c0 ac 0c 00 00 a8 03 00 1d 20 9e 80 b0 95 af 3b 4c |........ .....;L| -000002d0 e7 fb 97 65 d0 36 8f 97 88 0d 3b 5d a0 21 a8 78 |...e.6....;].!.x| -000002e0 81 39 4c 80 5c 58 52 6e 68 08 04 00 80 41 c6 e7 |.9L.\XRnh....A..| -000002f0 c9 48 c1 be 17 a6 a3 3c 3a de c8 c8 86 6e 70 37 |.H.....<:....np7| -00000300 2f d3 ed 8a dd 3a 73 5c b5 23 49 a8 4a fe e9 2b |/....:s\.#I.J..+| -00000310 4e 99 43 b8 e8 05 f9 fe 90 bf 74 be 92 3d d8 a3 |N.C.......t..=..| -00000320 c2 b2 38 80 1c 82 1f 35 e1 2e 04 bf a6 0a ec 3f |..8....5.......?| -00000330 81 4c a2 2b 19 8f 91 4c 51 b5 0d 52 1e 69 84 0a |.L.+...LQ..R.i..| -00000340 b0 cb de 41 1a bd a6 3d 50 9a ca d2 c0 26 11 3f |...A...=P....&.?| -00000350 cd 80 b4 2d 6e 03 f2 c5 2b cd 9c b6 a4 d8 e6 cf |...-n...+.......| -00000360 ec 1d 7a a9 17 59 6c 89 17 2f 64 0a 7c 16 03 03 |..z..Yl../d.|...| +000002c0 ac 0c 00 00 a8 03 00 1d 20 a2 bd 95 3e 0c 9f ad |........ ...>...| +000002d0 11 59 e0 6a c1 21 0c 6c 86 cc f1 ce bd a0 30 5d |.Y.j.!.l......0]| +000002e0 53 1e 75 f9 55 af 49 7b 31 08 04 00 80 d4 8b 11 |S.u.U.I{1.......| +000002f0 ca 22 14 79 a3 e8 b6 c7 d0 d6 1b 17 42 93 47 30 |.".y........B.G0| +00000300 ab 50 0e c9 0c 92 88 96 b4 63 4e 4e ac 7f dd c8 |.P.......cNN....| +00000310 8f 85 07 5b 95 c5 0a c0 4e 6d 4f 51 ba d8 d7 db |...[....NmOQ....| +00000320 14 70 80 4f 68 d9 b4 39 e7 48 27 21 76 4c 79 a4 |.p.Oh..9.H'!vLy.| +00000330 60 91 d7 2f 75 69 04 1a da 71 ff b8 4d 78 d8 e7 |`../ui...q..Mx..| +00000340 ca f2 f2 1e 71 21 b3 a0 44 a7 6c 99 16 a1 c9 f8 |....q!..D.l.....| +00000350 f0 de e8 99 12 7b 3d a2 e3 15 fa 63 62 e9 1b 72 |.....{=....cb..r| +00000360 c8 bb 27 38 4a 48 66 1d dd fb ef 6f d1 16 03 03 |..'8JHf....o....| 00000370 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......| 00000380 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| 00000390 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................| @@ -112,26 +112,26 @@ 00000200 e5 35 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.| 00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...| 00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 |......._X.;t....| -00000230 88 0f 00 00 84 04 01 00 80 29 22 23 51 c5 71 4a |.........)"#Q.qJ| -00000240 32 eb 72 6b f2 c8 46 99 df fe d5 a7 0c 55 3c 40 |2.rk..F......U<@| -00000250 e1 1e 09 4c 40 83 8a 0d 67 27 63 21 d2 36 66 8f |...L@...g'c!.6f.| -00000260 cb 97 4b 87 8a ed 9a 44 81 97 34 4b 9b 12 27 f5 |..K....D..4K..'.| -00000270 d8 63 9b 1f cf d7 b4 2b 54 99 86 2d cd 36 9f 3e |.c.....+T..-.6.>| -00000280 92 af 5a a6 0c 8a e0 e3 d3 b9 9b 47 ea 67 61 69 |..Z........G.gai| -00000290 d8 c1 86 1d fd 43 d4 1f 5c f5 48 d8 4a 97 a7 0f |.....C..\.H.J...| -000002a0 57 59 b0 5f e8 24 3f 9e 1d 96 3d 4b be 9c fa e3 |WY._.$?...=K....| -000002b0 3b 34 7e aa 67 d7 cc ea 78 14 03 03 00 01 01 16 |;4~.g...x.......| -000002c0 03 03 00 28 00 00 00 00 00 00 00 00 33 b3 7b c9 |...(........3.{.| -000002d0 3f e8 7d 08 3d 65 a3 22 fa e3 04 79 d9 9f 54 a3 |?.}.=e."...y..T.| -000002e0 45 e7 64 b2 5d 95 cf dd 88 cc ba 0b |E.d.].......| +00000230 88 0f 00 00 84 08 04 00 80 2e bf 05 22 82 a7 d6 |............"...| +00000240 e9 08 ff 9b 10 d3 4a 6c c4 73 5c 78 88 05 0c 15 |......Jl.s\x....| +00000250 b7 8c 78 49 64 2d 58 67 ef 8f db c0 67 fa 32 6e |..xId-Xg....g.2n| +00000260 65 45 90 a0 69 5c fb ba e0 16 1c d4 81 1d 24 89 |eE..i\........$.| +00000270 35 27 14 15 19 0b 86 ee 6a f2 b4 a5 27 61 5f 1f |5'......j...'a_.| +00000280 cc 47 7c 01 ed a9 ff ed 61 45 3f 53 1c 82 c8 cd |.G|.....aE?S....| +00000290 48 e4 89 82 12 d7 d2 ff fa 32 b3 e6 9d ce 75 75 |H........2....uu| +000002a0 d1 cd b2 a8 56 a6 a6 63 da 8d ed 27 13 01 9a 56 |....V..c...'...V| +000002b0 a2 26 b4 6c af 27 f6 4f 1b 14 03 03 00 01 01 16 |.&.l.'.O........| +000002c0 03 03 00 28 00 00 00 00 00 00 00 00 f0 e8 32 33 |...(..........23| +000002d0 50 df 73 17 3c 58 f2 c9 30 2e 5d e9 00 4f 4b 33 |P.s..6.X| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 28 7e 38 ab 82 0c |..........(~8...| -00000010 fd fa b9 83 3e 77 ed 22 b5 9d d3 c1 ca cd 18 c5 |....>w."........| -00000020 1c 01 a0 b8 8b 96 20 92 7b bd 0a 33 ee fe be 75 |...... .{..3...u| -00000030 95 6e 0c |.n.| +00000000 14 03 03 00 01 01 16 03 03 00 28 14 ce b1 86 0e |..........(.....| +00000010 9f ce 73 25 44 b7 3e a9 25 db a8 93 d9 39 33 75 |..s%D.>.%....93u| +00000020 2f a9 7f 97 6a 76 28 fe e2 84 5f 1e 84 66 b4 c8 |/...jv(..._..f..| +00000030 45 e7 64 |E.d| >>> Flow 5 (client to server) -00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 9d f0 cd |................| -00000010 53 8d 1a 45 ae 4a e4 01 97 dd ac f1 00 d3 aa b6 |S..E.J..........| -00000020 bf c9 bc 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................| -00000030 aa 1b 41 d5 f5 68 41 b8 32 94 9b 23 f8 60 7b 60 |..A..hA.2..#.`{`| -00000040 2c 8a |,.| +00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 3b 17 73 |.............;.s| +00000010 78 d6 3a b4 6d 3a 61 52 f6 a5 8c dd 18 3e ff 04 |x.:.m:aR.....>..| +00000020 d9 3f 22 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.?".............| +00000030 32 8d 5d 07 14 a9 d2 1c dd 1e 2f 3d 89 a9 8f 1d |2.]......./=....| +00000040 08 0f |..| diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA b/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA index db82b3837ea..2d608a78245 100644 --- a/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA +++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA @@ -16,11 +16,11 @@ 000000e0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0| 000000f0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |.........._X.;t| >>> Flow 2 (server to client) -00000000 16 03 03 00 59 02 00 00 55 03 03 59 e6 a5 3d 5a |....Y...U..Y..=Z| -00000010 bf 25 a3 16 e7 e3 da cb ac b7 11 09 0a 1a 8a c5 |.%..............| -00000020 33 a2 a6 58 12 27 cd 52 15 28 c9 20 23 9a f5 d3 |3..X.'.R.(. #...| -00000030 d4 df 49 1d 01 87 12 36 03 c6 36 17 39 d0 db 62 |..I....6..6.9..b| -00000040 22 48 7e 57 20 ab a3 7c b0 53 7e f1 c0 09 00 00 |"H~W ..|.S~.....| +00000000 16 03 03 00 59 02 00 00 55 03 03 3c ba b1 d8 8d |....Y...U..<....| +00000010 f5 52 f4 a4 70 fc 12 54 20 85 eb 23 bc b8 0b e0 |.R..p..T ..#....| +00000020 80 b6 ab 9b c5 34 84 57 bc ae 95 20 e3 51 8d 40 |.....4.W... .Q.@| +00000030 93 cc 9f e4 fd 77 82 c8 12 54 6a 23 08 db ff e5 |.....w...Tj#....| +00000040 87 8d 72 41 60 51 6a 11 5f 0a 9a d2 c0 09 00 00 |..rA`Qj._.......| 00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| 00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..| 00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....| @@ -55,23 +55,23 @@ 00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....| 00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.| 00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....| -00000270 2a 16 03 03 00 b6 0c 00 00 b2 03 00 1d 20 a7 6b |*............ .k| -00000280 75 97 e7 04 a7 19 99 af c7 73 72 82 59 7d 16 46 |u........sr.Y}.F| -00000290 de 80 c2 d3 36 c7 e8 42 89 ca 8d db 11 39 04 03 |....6..B.....9..| -000002a0 00 8a 30 81 87 02 41 73 4f fe e2 00 9d bf 60 0a |..0...AsO.....`.| -000002b0 36 0b 97 8a fc 3e 8c 1d ac ff a2 0b 7a dc 8d 2f |6....>......z../| -000002c0 d7 90 da 18 a0 14 8a 7c 51 4c a6 ae ec 13 ee 5e |.......|QL.....^| -000002d0 1a 60 aa 2f 5a d2 05 48 fb bb bb 3a 1a dc fa 21 |.`./Z..H...:...!| -000002e0 df 7b 6d 83 23 d6 62 0f 02 42 01 7f 5a 36 6d f4 |.{m.#.b..B..Z6m.| -000002f0 0d f5 d0 6f d9 71 52 f8 eb e3 ed 7c 40 fd 64 14 |...o.qR....|@.d.| -00000300 c1 31 4d 4b 78 70 5d 9f 61 18 3b 87 01 10 94 e5 |.1MKxp].a.;.....| -00000310 7b 83 34 2d cd 90 50 db 10 62 8d 36 40 45 20 c0 |{.4-..P..b.6@E .| -00000320 db ce de 5e b3 63 de 60 db bb fe be 16 03 03 00 |...^.c.`........| -00000330 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 06 |:...6...@.......| -00000340 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 |................| -00000350 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 |................| -00000360 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 04 |................| -00000370 0e 00 00 00 |....| +00000270 2a 16 03 03 00 b7 0c 00 00 b3 03 00 1d 20 86 f3 |*............ ..| +00000280 1e c5 fb 1f 91 44 0e e5 e4 3e 0a cd 75 a2 fb 4c |.....D...>..u..L| +00000290 a2 b9 07 f7 33 ce cc cd 61 a5 8c ba 6a 35 04 03 |....3...a...j5..| +000002a0 00 8b 30 81 88 02 42 01 f4 8d 4f 3e c8 73 b5 b4 |..0...B...O>.s..| +000002b0 b5 2b ac 2a 27 68 56 a1 45 ce b6 1d c6 37 ce de |.+.*'hV.E....7..| +000002c0 bd 96 90 5e e2 1c c8 84 b2 84 57 25 81 d4 c3 7a |...^......W%...z| +000002d0 db b2 3d 24 2b 17 3a 4a 7e 92 1a bb 0c fb b6 05 |..=$+.:J~.......| +000002e0 cd 0e 85 4c 3d 4b 24 2a 2a 02 42 00 f6 91 d6 82 |...L=K$**.B.....| +000002f0 9e 81 98 5f 64 59 ce 16 85 fc 65 19 0c 50 ca ea |..._dY....e..P..| +00000300 8a ba 1e 61 a8 71 cf 2c eb 94 24 ac 34 75 6e 5c |...a.q.,..$.4un\| +00000310 dc 92 ba b8 bd 42 75 ef 6d 67 5f 06 5c e3 6c c2 |.....Bu.mg_.\.l.| +00000320 aa 5e 29 25 66 00 68 c8 5d 9c 6f bb e0 16 03 03 |.^)%f.h.].o.....| +00000330 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......| +00000340 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| +00000350 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................| +00000360 03 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 |................| +00000370 04 0e 00 00 00 |.....| >>> Flow 3 (client to server) 00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0| 00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.| @@ -108,31 +108,31 @@ 00000200 e5 35 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.| 00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...| 00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 |......._X.;t....| -00000230 88 0f 00 00 84 04 01 00 80 88 59 ec 09 a4 c9 5e |..........Y....^| -00000240 37 b4 e3 04 71 52 1a 5a 6d d6 9b f6 09 14 01 c2 |7...qR.Zm.......| -00000250 3e 07 19 2f ec 15 d9 5b 12 6a 6e de 78 a3 ac 58 |>../...[.jn.x..X| -00000260 40 44 f2 66 0a 12 a5 62 37 8b af 5a 3a 20 be f2 |@D.f...b7..Z: ..| -00000270 6f 43 c8 00 69 21 c8 fd b0 cf 00 74 c3 96 a0 8b |oC..i!.....t....| -00000280 6f ce c1 09 e6 90 1d 8e 53 40 b8 44 83 b9 46 9c |o.......S@.D..F.| -00000290 78 3b c1 0a 36 68 a5 04 e8 b5 ed 6d 7d 09 21 8c |x;..6h.....m}.!.| -000002a0 0e 00 0c 5e d0 2b 47 c9 f6 31 f6 8f 7b b6 2d 8d |...^.+G..1..{.-.| -000002b0 ec 4e c2 0d 08 c5 1b 26 b6 14 03 03 00 01 01 16 |.N.....&........| +00000230 88 0f 00 00 84 08 04 00 80 53 85 ea dc a6 86 2d |.........S.....-| +00000240 e7 8c 0b 68 f9 57 7f f5 77 d8 fe 35 28 91 e7 2f |...h.W..w..5(../| +00000250 8a 2c 36 cf d7 8c 9f 3d f2 e2 99 41 11 b2 3c a2 |.,6....=...A..<.| +00000260 5e f3 68 1f b5 d4 f8 90 8a e2 5e 02 48 00 2b eb |^.h.......^.H.+.| +00000270 f0 e6 8c 28 af 11 80 82 ea 35 06 fd 0a 5f d7 1a |...(.....5..._..| +00000280 e9 63 29 08 8c aa 18 1e 7c 08 81 21 c8 aa 86 b1 |.c).....|..!....| +00000290 cf 94 db f6 8d 15 dc cc ae cf 41 2c 32 b1 3f 0c |..........A,2.?.| +000002a0 96 0e 5c ed 82 74 cc fc 35 f4 38 80 29 00 c1 3a |..\..t..5.8.)..:| +000002b0 70 d4 07 07 9c 49 9e 7b 91 14 03 03 00 01 01 16 |p....I.{........| 000002c0 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 00 |...@............| -000002d0 00 00 00 00 e7 64 7d 04 bb bf dd 2a ac fd 96 81 |.....d}....*....| -000002e0 25 d8 3e 6c 1d 53 c7 79 31 4d 13 c3 71 d3 da c0 |%.>l.S.y1M..q...| -000002f0 f8 74 11 bb 6b 9d 62 66 ed f0 97 ab 43 fe 12 cb |.t..k.bf....C...| -00000300 da 8d c2 4b |...K| +000002d0 00 00 00 00 f3 da dc d7 12 d6 f6 19 75 a8 02 68 |............u..h| +000002e0 57 0e e1 90 75 d1 fc b8 32 a3 34 16 d6 8d 2a f5 |W...u...2.4...*.| +000002f0 65 f2 a7 67 2c 2c a4 73 6a b6 f2 ad 2d 7f 8a ce |e..g,,.sj...-...| +00000300 a7 12 16 97 |....| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 40 35 ee 36 65 9a |..........@5.6e.| -00000010 e5 ac c7 30 18 b6 ff f9 fd fa 66 88 a7 73 be ba |...0......f..s..| -00000020 d5 89 59 26 cf 2d 8d 31 48 f0 fb 09 c1 66 ef eb |..Y&.-.1H....f..| -00000030 94 30 b7 47 71 a1 cb 03 34 37 14 f5 76 14 13 a9 |.0.Gq...47..v...| -00000040 6f d7 4d 59 c1 63 f8 db 8b 74 36 |o.MY.c...t6| +00000000 14 03 03 00 01 01 16 03 03 00 40 dc 11 a1 a2 fb |..........@.....| +00000010 55 0c 9e e0 e2 55 1a ca cd 5b df 1f 39 9e 08 51 |U....U...[..9..Q| +00000020 bd 6b 72 40 93 f8 23 7a 32 9d 85 18 20 b7 39 b0 |.kr@..#z2... .9.| +00000030 03 d3 10 6a 8e 66 6d e6 d5 38 03 c6 e5 b8 dc d7 |...j.fm..8......| +00000040 3c 27 1d d2 a9 59 f9 18 7d 15 90 |<'...Y..}..| >>> Flow 5 (client to server) 00000000 17 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -00000010 00 00 00 00 00 19 16 39 bc a3 30 b5 1d ae e5 a9 |.......9..0.....| -00000020 74 89 1e d1 77 86 8f 85 55 fa af cb 0a 94 45 f4 |t...w...U.....E.| -00000030 a9 fa 21 c5 54 15 03 03 00 30 00 00 00 00 00 00 |..!.T....0......| -00000040 00 00 00 00 00 00 00 00 00 00 40 17 27 41 8c ae |..........@.'A..| -00000050 74 59 34 f0 2e 72 34 4e 98 6e d8 da 17 07 b3 14 |tY4..r4N.n......| -00000060 d8 c8 2c ad b6 3e 44 5a 3e d7 |..,..>DZ>.| +00000010 00 00 00 00 00 c2 92 ee 96 31 60 90 d5 ee a6 1c |.........1`.....| +00000020 ed 3c 03 40 8c e7 0c db 7f b0 11 dc 7e 58 e1 aa |.<.@........~X..| +00000030 4c d7 68 2a 91 15 03 03 00 30 00 00 00 00 00 00 |L.h*.....0......| +00000040 00 00 00 00 00 00 00 00 00 00 b6 61 51 ac 66 a5 |...........aQ.f.| +00000050 d1 ef d3 ee c8 d3 48 72 d5 e0 ef 7d ca 6a ec b2 |......Hr...}.j..| +00000060 77 ff 2d a8 32 6d be 6e a7 42 |w.-.2m.n.B| diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA b/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA index 02b11a69337..cdc71041fbb 100644 --- a/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA +++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA @@ -16,11 +16,11 @@ 000000e0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0| 000000f0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |.........._X.;t| >>> Flow 2 (server to client) -00000000 16 03 03 00 59 02 00 00 55 03 03 43 a0 10 ae 54 |....Y...U..C...T| -00000010 09 23 be 14 d7 1d b3 64 66 5e 39 4e 42 ed 58 3a |.#.....df^9NB.X:| -00000020 1b de 35 eb ee 9b 86 44 fe 2b a8 20 e7 f1 4a 47 |..5....D.+. ..JG| -00000030 b1 6b f0 fb d7 ed 3c 33 4a 52 bc 9b 39 c0 16 d3 |.k....<3JR..9...| -00000040 f4 0a 7c 38 7e b3 95 31 7a c7 c8 f4 c0 2f 00 00 |..|8~..1z..../..| +00000000 16 03 03 00 59 02 00 00 55 03 03 f3 28 ca c9 ac |....Y...U...(...| +00000010 29 bb 15 80 56 d2 37 09 fa 7d 23 04 d4 79 e7 1d |)...V.7..}#..y..| +00000020 bb 4e c5 60 c8 44 39 02 6a e9 e0 20 b5 ae 39 87 |.N.`.D9.j.. ..9.| +00000030 4e 24 2f 33 02 fe 72 d6 2a 4d 0c 8c da 36 7b 28 |N$/3..r.*M...6{(| +00000040 3c 06 aa b2 60 68 91 7a ae d8 7b e2 c0 2f 00 00 |<...`h.z..{../..| 00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| 00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..| 00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............| @@ -60,17 +60,17 @@ 00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.| 000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..| 000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......| -000002c0 ac 0c 00 00 a8 03 00 1d 20 e7 c6 c3 84 0a b7 55 |........ ......U| -000002d0 ff fb ae 43 10 da 03 0d 7d 91 77 90 cd 05 6a ab |...C....}.w...j.| -000002e0 08 35 5a 38 23 79 45 9f 54 08 04 00 80 d8 b8 a1 |.5Z8#yE.T.......| -000002f0 67 15 39 93 cc d0 ac e7 55 85 3e 62 f3 a6 d8 35 |g.9.....U.>b...5| -00000300 5e bb 60 4e 33 70 05 47 b8 9e 8c e6 85 65 09 e2 |^.`N3p.G.....e..| -00000310 95 4f 8a d9 4b cb 60 62 3c ef 57 81 ed b4 20 cf |.O..K.`b<.W... .| -00000320 b1 71 d9 62 57 60 fa 07 89 12 a1 90 8f 8f 06 4a |.q.bW`.........J| -00000330 56 c3 81 e0 b6 11 9e ce 33 fe 0f 4e b2 84 cc 4b |V.......3..N...K| -00000340 dc d4 71 e4 43 04 61 11 a9 a6 8a 20 43 a7 0e b6 |..q.C.a.... C...| -00000350 a8 97 43 1b e0 a9 b1 0f e8 19 68 0a 5d 38 d9 69 |..C.......h.]8.i| -00000360 22 65 16 aa 05 16 11 cd 66 4a 4f be 90 16 03 03 |"e......fJO.....| +000002c0 ac 0c 00 00 a8 03 00 1d 20 d4 df 5d 10 ee ba a6 |........ ..]....| +000002d0 51 d7 1b fb bf ed bc d6 b9 34 44 e7 af 23 0e 9b |Q........4D..#..| +000002e0 45 af ba 7a 89 63 03 a9 4c 08 04 00 80 30 2c 0f |E..z.c..L....0,.| +000002f0 2e d9 e4 1d c2 90 01 1c cc cf d4 fe 06 6d c3 aa |.............m..| +00000300 59 d9 d9 bc 16 2f 2c b1 be 90 a3 93 a7 be bc 4d |Y..../,........M| +00000310 d8 f4 ac 21 36 59 a8 21 94 ef d3 c4 53 14 34 18 |...!6Y.!....S.4.| +00000320 c9 10 d5 77 fd 1e ad 15 0f 23 d7 73 90 7a c0 7b |...w.....#.s.z.{| +00000330 b3 b2 e2 df 15 42 35 ce 38 05 52 02 77 b7 b2 2b |.....B5.8.R.w..+| +00000340 6b 88 6a ce d4 20 99 9d e4 fe e8 38 1e 01 b7 78 |k.j.. .....8...x| +00000350 3c ea ac 8e ef 2f 7e e8 22 08 78 42 b7 db 84 80 |<..../~.".xB....| +00000360 8c 61 8a c5 cc d7 1f 6a 8d 5c 1d 2d 0d 16 03 03 |.a.....j.\.-....| 00000370 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......| 00000380 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| 00000390 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................| @@ -112,26 +112,26 @@ 00000200 e5 35 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.| 00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...| 00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 |......._X.;t....| -00000230 88 0f 00 00 84 04 01 00 80 2e af 25 b4 ff 00 08 |...........%....| -00000240 c8 dc 24 49 d5 9b d0 fe b5 81 8d 4e 15 d4 63 bf |..$I.......N..c.| -00000250 8e 4c a4 7d 96 58 a2 4b f4 25 a8 e3 39 fc df 2d |.L.}.X.K.%..9..-| -00000260 7c a0 20 61 86 35 8e 7e ba a5 2c f3 07 ad 84 36 ||. a.5.~..,....6| -00000270 df ef 66 e9 78 d8 5f b3 17 45 31 d4 4a 38 5c 6c |..f.x._..E1.J8\l| -00000280 03 73 3b 74 60 c9 00 d1 64 59 c9 a5 39 00 fc bf |.s;t`...dY..9...| -00000290 9c 3a 99 46 4b 71 90 64 8a 24 2e 37 cf 8a 42 c2 |.:.FKq.d.$.7..B.| -000002a0 56 a6 94 97 60 c5 56 ba de 71 78 6c f2 be ce 16 |V...`.V..qxl....| -000002b0 47 ca 0d 95 3c cc b8 6f b2 14 03 03 00 01 01 16 |G...<..o........| -000002c0 03 03 00 28 00 00 00 00 00 00 00 00 8e 0e 3b 43 |...(..........;C| -000002d0 63 52 24 16 91 bc 50 85 ef 34 ad b9 f0 45 e7 4c |cR$...P..4...E.L| -000002e0 9a 07 1d 46 53 2c 89 79 0f 27 dc 9d |...FS,.y.'..| +00000230 88 0f 00 00 84 08 04 00 80 b8 96 b3 c8 66 a9 fb |.............f..| +00000240 da 1b 82 65 9d 57 e5 e5 e5 60 c9 43 df 6e 99 53 |...e.W...`.C.n.S| +00000250 45 95 b8 58 d1 19 05 50 e1 a7 3c e8 07 ad 57 09 |E..X...P..<...W.| +00000260 9c 95 13 ea 80 24 53 56 b1 13 2d 59 9d e9 60 0f |.....$SV..-Y..`.| +00000270 75 97 d3 4f 82 3a b5 41 3e 90 75 ea 28 97 00 e7 |u..O.:.A>.u.(...| +00000280 74 c9 04 1d d0 16 ba 40 75 9c ae a0 bd 00 b1 a9 |t......@u.......| +00000290 86 d5 1a f2 30 45 72 99 ea b2 eb 61 b1 63 72 c5 |....0Er....a.cr.| +000002a0 ad b1 60 a8 fa bd 95 95 17 03 4c 8e 87 4b 44 e5 |..`.......L..KD.| +000002b0 ec f3 e0 48 33 b8 a9 74 78 14 03 03 00 01 01 16 |...H3..tx.......| +000002c0 03 03 00 28 00 00 00 00 00 00 00 00 e6 a6 db ee |...(............| +000002d0 7d fb 48 9f 81 a6 78 6a db a1 9a bb c8 da 7b b2 |}.H...xj......{.| +000002e0 6a 01 66 fb 85 a7 2f 35 40 77 b6 b2 |j.f.../5@w..| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 28 2f 40 03 cf 5a |..........(/@..Z| -00000010 76 6c 87 87 8d 99 4c e8 76 73 6a 62 1d a5 31 bc |vl....L.vsjb..1.| -00000020 2e 7e 23 8c 50 bf 07 b9 13 53 4a 59 a0 9b 74 b7 |.~#.P....SJY..t.| -00000030 53 21 2d |S!-| +00000000 14 03 03 00 01 01 16 03 03 00 28 b3 9c 30 b6 a2 |..........(..0..| +00000010 cb cf 75 38 10 e7 80 39 0e 87 39 9c d9 da 2c 53 |..u8...9..9...,S| +00000020 1a 64 2d 33 ff 21 25 e9 3c f2 ec 6d a4 59 f4 30 |.d-3.!%.<..m.Y.0| +00000030 ea 41 24 |.A$| >>> Flow 5 (client to server) -00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 83 69 b1 |..............i.| -00000010 20 19 eb db d4 58 e7 f1 5a 95 b0 d3 9d 3b 74 ad | ....X..Z....;t.| -00000020 bc 94 c4 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................| -00000030 7d 89 89 25 40 be 0d fc 24 d0 ff 5a 0f 24 5d f2 |}..%@...$..Z.$].| -00000040 a3 ab |..| +00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 65 72 8f |.............er.| +00000010 4a 5f 08 c1 f9 37 5d 30 bc c6 e6 5f a8 23 35 69 |J_...7]0..._.#5i| +00000020 d3 3c 7a 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.>> Flow 2 (server to client) -00000000 16 03 03 00 59 02 00 00 55 03 03 be 63 44 bb 7e |....Y...U...cD.~| -00000010 0d 88 88 15 b1 ed 7e 75 03 57 25 1a 0c 52 42 31 |......~u.W%..RB1| -00000020 f8 e1 46 e3 11 27 ff 05 5e 26 2e 20 e6 31 d0 a6 |..F..'..^&. .1..| -00000030 d9 7c 69 a6 57 09 ee 50 c5 3c 5e 1d a0 a7 2b 7a |.|i.W..P.<^...+z| -00000040 7c dd 04 b4 38 45 c9 90 a0 98 33 68 c0 2f 00 00 ||...8E....3h./..| +00000000 16 03 03 00 59 02 00 00 55 03 03 29 bc e2 fe ae |....Y...U..)....| +00000010 0a db 37 e6 39 d5 48 24 3d 0f e5 d7 6b a3 69 dd |..7.9.H$=...k.i.| +00000020 ce 09 fd 28 03 c2 7e 38 db c9 ec 20 d2 5e 3f 94 |...(..~8... .^?.| +00000030 b0 2c 5e 4c 77 c2 94 c3 f2 a9 d0 91 4f 96 45 0e |.,^Lw.......O.E.| +00000040 d3 34 fc 9f e0 a5 e6 fc 1e 8a c1 00 c0 2f 00 00 |.4.........../..| 00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| 00000060 03 02 66 0b 00 02 62 00 02 5f 00 02 5c 30 82 02 |..f...b.._..\0..| 00000070 58 30 82 01 8d a0 03 02 01 02 02 11 00 f2 99 26 |X0.............&| @@ -61,18 +61,18 @@ 000002a0 11 89 66 79 d1 8e 88 0e 0b a0 9e 30 2a c0 67 ef |..fy.......0*.g.| 000002b0 ca 46 02 88 e9 53 81 22 69 22 97 ad 80 93 d4 f7 |.F...S."i"......| 000002c0 dd 70 14 24 d7 70 0a 46 a1 16 03 03 00 ac 0c 00 |.p.$.p.F........| -000002d0 00 a8 03 00 1d 20 60 8e 8a 17 8a fc b4 4f 01 ad |..... `......O..| -000002e0 f8 ef 44 f3 fc af 2a 90 57 7d ba 1d dd a6 17 cc |..D...*.W}......| -000002f0 c6 4a 5f a2 fb 47 08 04 00 80 46 d8 62 04 19 4a |.J_..G....F.b..J| -00000300 29 9b cc 3c 2c 0d 7e 67 3d 97 c0 32 65 90 28 e2 |)..<,.~g=..2e.(.| -00000310 e9 df 7d 9b e1 62 82 a9 0b 22 99 a0 ae b9 7a 31 |..}..b..."....z1| -00000320 75 c2 6e 61 e7 a5 64 b9 72 ce b8 04 b2 ca 14 78 |u.na..d.r......x| -00000330 d4 b4 c2 b4 57 b4 a4 70 f9 d1 bf d0 77 e3 f5 66 |....W..p....w..f| -00000340 c0 3f dd b2 40 30 3d d5 e9 a6 d1 49 79 ac ea b9 |.?..@0=....Iy...| -00000350 38 43 52 3c a0 1c be 0d 18 a2 fc c0 a6 43 80 91 |8CR<.........C..| -00000360 3f c5 c2 3a 43 31 92 ff 58 a8 40 52 b3 99 0f c4 |?..:C1..X.@R....| -00000370 c6 00 89 0b b9 f4 9e 28 cd bf 16 03 03 00 0c 0d |.......(........| -00000380 00 00 08 01 01 00 02 04 01 00 00 16 03 03 00 04 |................| +000002d0 00 a8 03 00 1d 20 9e e4 39 3a b3 d5 f9 51 16 d4 |..... ..9:...Q..| +000002e0 a8 e1 0a 6d ad 3c ca 01 97 d6 a1 ce 03 2a 67 4a |...m.<.......*gJ| +000002f0 49 06 eb ed c6 24 08 04 00 80 b3 b7 9e fd 97 9b |I....$..........| +00000300 b0 d6 35 89 21 53 ff a8 4b 59 59 26 37 ac 2f 36 |..5.!S..KYY&7./6| +00000310 27 3d 5a 04 3f 50 ed 36 e0 5f 1a d7 1b 36 47 94 |'=Z.?P.6._...6G.| +00000320 45 ec 8c 0b 8f 0f fc df ec 3c 56 f0 d0 28 45 94 |E........>> Flow 3 (client to server) 00000000 16 03 03 02 66 0b 00 02 62 00 02 5f 00 02 5c 30 |....f...b.._..\0| @@ -116,27 +116,27 @@ 00000260 d4 f7 dd 70 14 24 d7 70 0a 46 a1 16 03 03 00 25 |...p.$.p.F.....%| 00000270 10 00 00 21 20 2f e5 7d a3 47 cd 62 43 15 28 da |...! /.}.G.bC.(.| 00000280 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........| -00000290 5f 58 cb 3b 74 16 03 03 00 88 0f 00 00 84 04 01 |_X.;t...........| -000002a0 00 80 d5 bf 41 e0 65 7b 32 16 bb a3 92 48 f6 0e |....A.e{2....H..| -000002b0 31 eb ca a2 b7 1c b3 3a b4 8f 91 0e 44 e8 9e ad |1......:....D...| -000002c0 f7 71 4c 71 20 da 59 29 09 4f 0b 1e fb 92 c5 ce |.qLq .Y).O......| -000002d0 7b a3 26 de 89 be f5 cc b6 be dc af 09 6a f9 a2 |{.&..........j..| -000002e0 f0 65 5c 39 2d ad 2c 46 ce df 26 09 2e 99 5d 9e |.e\9-.,F..&...].| -000002f0 58 2b cf 1f ed b5 1a 4b 21 0b d8 ec 14 fb bb f2 |X+.....K!.......| -00000300 eb 41 9d 1c 6a 06 d8 38 b9 68 fc 1d 90 ad ff 9c |.A..j..8.h......| -00000310 91 c1 4a ff b0 49 59 8a 0b 25 26 eb 28 b1 a5 f8 |..J..IY..%&.(...| -00000320 0d 8e 14 03 03 00 01 01 16 03 03 00 28 00 00 00 |............(...| -00000330 00 00 00 00 00 cd a4 31 83 38 57 c8 91 98 4c 6c |.......1.8W...Ll| -00000340 76 c7 e1 d8 af f9 47 ee 45 75 f4 51 6c e5 7e da |v.....G.Eu.Ql.~.| -00000350 00 0f da 44 49 |...DI| +00000290 5f 58 cb 3b 74 16 03 03 00 88 0f 00 00 84 08 04 |_X.;t...........| +000002a0 00 80 a6 6b 99 15 5e 97 33 4f a8 0e 59 af 15 22 |...k..^.3O..Y.."| +000002b0 f3 6e be 02 6e e4 20 d5 81 c0 b4 74 5a e2 20 32 |.n..n. ....tZ. 2| +000002c0 2b 7f 9c e6 94 32 4d 30 bf 93 86 9b 75 4d f1 9f |+....2M0....uM..| +000002d0 e4 48 28 00 27 fa 7c 45 2e fe d7 0b dc 03 c4 6b |.H(.'.|E.......k| +000002e0 42 ad a2 32 d7 9d ea d6 52 05 3f ed 87 fd b9 9d |B..2....R.?.....| +000002f0 58 fd d6 9f 28 6d 45 07 de 5b 4a 8e f4 4d 19 0b |X...(mE..[J..M..| +00000300 cf 4e 64 75 73 ae cd e9 ae f9 af 27 d0 b9 eb 4c |.Ndus......'...L| +00000310 98 ad 66 6d 4e bf 2c 39 87 f3 72 3e 4e bc a1 8f |..fmN.,9..r>N...| +00000320 a8 1e 14 03 03 00 01 01 16 03 03 00 28 00 00 00 |............(...| +00000330 00 00 00 00 00 04 3c cc ae cd 19 52 6b 1e 0e cc |......<....Rk...| +00000340 dd a9 ac 2f 2a c6 94 4c 09 f3 ee 2f b5 5a 13 1e |.../*..L.../.Z..| +00000350 4f 54 a0 ae c2 |OT...| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 28 7f 1d 85 46 4c |..........(...FL| -00000010 7f 93 d7 e3 c1 3f a7 71 69 16 90 9a a6 f8 9a 22 |.....?.qi......"| -00000020 a5 8b 0e 6d 6a f2 08 7e 40 6d ba 87 74 e4 e6 1d |...mj..~@m..t...| -00000030 ba 5e ff |.^.| +00000000 14 03 03 00 01 01 16 03 03 00 28 6d 44 cb 35 8b |..........(mD.5.| +00000010 15 5c f9 f8 1e ae 4f 8c 8c d9 90 9e 6c cf 13 f6 |.\....O.....l...| +00000020 12 29 f5 f7 d6 ff da e2 48 7d 68 ec ad 1a 6c 39 |.)......H}h...l9| +00000030 c5 77 6c |.wl| >>> Flow 5 (client to server) -00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 2a 5a a1 |.............*Z.| -00000010 d5 31 ba 8b 9d 3f f1 54 e0 53 cf 84 70 3b f5 bf |.1...?.T.S..p;..| -00000020 11 3c ad 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.<..............| -00000030 1b ad 23 3d 37 69 87 9d b5 60 f1 8a 13 d6 09 ab |..#=7i...`......| -00000040 a4 9b |..| +00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 2a ce da |.............*..| +00000010 11 1c 7d 49 0d aa 44 d4 d6 d4 7f 64 2b 49 47 20 |..}I..D....d+IG | +00000020 5a 21 bb 15 03 03 00 1a 00 00 00 00 00 00 00 02 |Z!..............| +00000030 fc 10 75 a7 22 f9 74 1c 3a d2 b2 a8 04 2d 37 5f |..u.".t.:....-7_| +00000040 c2 76 |.v| diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce index 96f7b000734..48a99eda155 100644 --- a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce +++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce @@ -16,11 +16,11 @@ 000000e0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0| 000000f0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |.........._X.;t| >>> Flow 2 (server to client) -00000000 16 03 03 00 59 02 00 00 55 03 03 1c 04 37 7b 4d |....Y...U....7{M| -00000010 49 2a 45 1d e8 db 60 7e 7d be 7b 2d ff a2 dc aa |I*E...`~}.{-....| -00000020 b7 5e 66 f9 67 bf 58 f7 f1 0a 7b 20 f2 72 71 31 |.^f.g.X...{ .rq1| -00000030 2a 6e 5e 2b e4 29 ef bc 3a 56 45 26 53 b4 9f 98 |*n^+.)..:VE&S...| -00000040 fb 07 d5 2f b3 f3 f0 3b 02 1f 00 9b cc a8 00 00 |.../...;........| +00000000 16 03 03 00 59 02 00 00 55 03 03 f1 d8 72 0c 79 |....Y...U....r.y| +00000010 e2 ca 92 11 1c 30 cc 45 00 9b ea 3d a3 ed 23 d5 |.....0.E...=..#.| +00000020 22 f0 da 9c 03 32 7b c3 13 d3 df 20 8f 7a 61 43 |"....2{.... .zaC| +00000030 cb 72 46 5e c1 39 78 42 32 97 cc 2b 90 2e 53 59 |.rF^.9xB2..+..SY| +00000040 31 38 ec 7b 2b 8a f3 80 e0 03 f0 0e cc a8 00 00 |18.{+...........| 00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| 00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..| 00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............| @@ -60,185 +60,185 @@ 00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.| 000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..| 000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......| -000002c0 ac 0c 00 00 a8 03 00 1d 20 6f fe 48 78 c0 68 41 |........ o.Hx.hA| -000002d0 fa 5a 33 f5 9b e0 b2 ae 93 e9 0c 5a 78 60 32 67 |.Z3........Zx`2g| -000002e0 de cf 17 26 20 88 3a f5 5e 08 04 00 80 58 d9 c5 |...& .:.^....X..| -000002f0 f0 c3 9e f5 4d a5 20 3e ed da a2 7d b9 2a 9b 95 |....M. >...}.*..| -00000300 ec 1c 2a c1 28 22 3e 36 4f 5a fe eb 2a 6a 9e 9e |..*.(">6OZ..*j..| -00000310 01 83 31 93 d1 bd 0f 6f ff 9d e8 4e 7a cb 9d 8f |..1....o...Nz...| -00000320 63 92 bc f2 0e 37 1f e0 8a 1e 22 2c eb 53 e8 25 |c....7....",.S.%| -00000330 15 20 97 1f 0c 75 5a 9d 6a aa e6 a6 86 d9 5d 4d |. ...uZ.j.....]M| -00000340 b8 58 d1 03 63 d4 8d cb 0b 4d 97 2e eb 50 13 39 |.X..c....M...P.9| -00000350 07 5c d9 a8 bf cf eb 05 47 0a 48 30 5b 71 c0 ea |.\......G.H0[q..| -00000360 cb 4f 22 27 1a d2 58 02 ca 07 bd 03 f1 16 03 03 |.O"'..X.........| +000002c0 ac 0c 00 00 a8 03 00 1d 20 96 cb 1d cd f6 2f ff |........ ...../.| +000002d0 fe 32 ef d6 18 a2 6b 57 66 cd 3d 50 42 56 dc a4 |.2....kWf.=PBV..| +000002e0 5f fe e4 91 ce d1 17 34 3c 08 04 00 80 b1 47 de |_......4<.....G.| +000002f0 b3 19 b0 fd 02 35 eb 3c a1 04 d3 6b 53 84 20 c7 |.....5.<...kS. .| +00000300 08 4b 96 12 23 ae bf ca a8 83 1d 90 16 ae d3 7c |.K..#..........|| +00000310 fa 1b b4 f0 bb bb 4e 3f 70 13 2f 40 6c d4 76 61 |......N?p./@l.va| +00000320 5b 23 85 3f e7 37 ef e1 55 47 8d 01 e1 24 22 7f |[#.?.7..UG...$".| +00000330 a4 2c 6f 97 47 5f d6 69 bf b4 db 4b b8 a1 ad 66 |.,o.G_.i...K...f| +00000340 5f d5 5d b6 06 ac 93 ed d7 06 cb b5 a4 d4 4b a7 |_.]...........K.| +00000350 7b de f7 73 60 af ad 23 f4 6a f1 bf 2a ee 5b 4e |{..s`..#.j..*.[N| +00000360 83 94 d7 95 3b e5 5e a5 3d 1a 0a 7a 9e 16 03 03 |....;.^.=..z....| 00000370 00 04 0e 00 00 00 |......| >>> Flow 3 (client to server) 00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.| 00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....| 00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......| -00000030 16 03 03 00 20 f9 b0 26 8b 30 54 a5 80 7e 5b 47 |.... ..&.0T..~[G| -00000040 2e b1 28 07 ef 12 93 33 5a 8d 5e de 8d 56 d5 c3 |..(....3Z.^..V..| -00000050 3c 05 a8 f1 5e |<...^| +00000030 16 03 03 00 20 f2 6f 2e 79 5c db 90 b8 2e cf 59 |.... .o.y\.....Y| +00000040 0a 56 69 86 f1 71 0c ff a9 7c 0b a0 e7 c9 8d 17 |.Vi..q...|......| +00000050 65 ad a5 6c 82 |e..l.| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 20 c1 77 25 ba a7 |.......... .w%..| -00000010 08 ba 0d 1e 8b e2 eb 11 77 d8 c7 e2 20 e0 60 da |........w... .`.| -00000020 97 f5 42 f4 12 bb 94 35 b7 ee c8 |..B....5...| +00000000 14 03 03 00 01 01 16 03 03 00 20 d5 90 08 84 71 |.......... ....q| +00000010 bc 09 48 be ad 59 11 76 c6 39 bb 94 8c 60 80 29 |..H..Y.v.9...`.)| +00000020 44 1a 0d fe 5c 00 4c bc 47 3c 1e |D...\.L.G<.| >>> Flow 5 (client to server) -00000000 17 03 03 00 16 6f f6 5b 37 2f 21 25 ae e9 30 be |.....o.[7/!%..0.| -00000010 ce b4 66 f7 fd 9a 5a 02 9d 43 e8 |..f...Z..C.| +00000000 17 03 03 00 16 42 cd 1c e5 91 35 b0 c1 4d df e4 |.....B....5..M..| +00000010 b0 ca f3 8a 7a 41 85 31 7a 7d 59 |....zA.1z}Y| >>> Flow 6 (server to client) -00000000 16 03 03 00 14 8f be 53 56 e9 19 ec 85 79 d0 cc |.......SV....y..| -00000010 8d ab 43 3c b2 7b a3 55 57 |..C<.{.UW| +00000000 16 03 03 00 14 3b 0f 40 64 9f ff 8f b9 85 18 af |.....;.@d.......| +00000010 b4 bc e7 33 8a 9b 03 de ed |...3.....| >>> Flow 7 (client to server) -00000000 16 03 03 01 16 ab 36 6a 25 3d 93 3c 71 b6 5b 91 |......6j%=.k../.]....| +00000000 16 03 03 01 16 17 a7 61 5b 22 97 6e eb dd 43 84 |.......a[".n..C.| +00000010 b9 ac 15 c2 76 7d 1f c0 e3 46 11 af c0 59 7d cc |....v}...F...Y}.| +00000020 d4 5d 02 90 28 bb b3 7c 85 76 46 34 7c bf 2b bf |.]..(..|.vF4|.+.| +00000030 c4 e9 e1 46 b0 15 7e af c1 03 4a 17 b3 7a 03 cd |...F..~...J..z..| +00000040 e0 90 b1 1b 59 ac 1f 33 b0 41 c3 47 ee 58 af 5b |....Y..3.A.G.X.[| +00000050 5b c4 7a 92 02 e2 34 8d cd 70 20 c4 59 5e 25 f2 |[.z...4..p .Y^%.| +00000060 28 b1 f2 a5 e0 c4 f9 d0 ae cc 2b 1e ea d4 5a fe |(.........+...Z.| +00000070 62 97 bc d7 57 94 5c b8 ce 4c 62 1a e5 29 02 1e |b...W.\..Lb..)..| +00000080 0e 68 1d 8a 17 f9 47 55 ac 65 cf 13 88 d3 95 0d |.h....GU.e......| +00000090 d7 e0 d8 03 f8 f6 6f 9c 5b de 5c 80 c3 34 7e 82 |......o.[.\..4~.| +000000a0 5c 8b c4 a3 99 c8 1e f0 f2 e5 6e 73 40 62 31 8e |\.........ns@b1.| +000000b0 3b 08 62 ba a8 b9 18 c4 84 a0 b4 9f 68 81 2f ae |;.b.........h./.| +000000c0 8d 7c cc 54 ba 4a ec 26 a5 8a 9b a7 bd 36 17 2c |.|.T.J.&.....6.,| +000000d0 52 69 4c 57 81 64 e6 34 88 27 81 d2 32 eb d2 8d |RiLW.d.4.'..2...| +000000e0 4d 8d c1 8b 14 b3 07 19 63 f8 d6 4a 9a 7d 3f c1 |M.......c..J.}?.| +000000f0 af 18 72 f7 2d c8 7e 82 52 28 51 80 59 0c 9b 9f |..r.-.~.R(Q.Y...| +00000100 ac 40 69 25 0e 6d d7 4a 72 b5 18 f8 78 b9 52 c3 |.@i%.m.Jr...x.R.| +00000110 d6 32 6c 7d 29 70 a8 33 18 d0 4b |.2l})p.3..K| >>> Flow 8 (server to client) -00000000 16 03 03 00 81 21 a2 14 95 1e 02 74 1b aa c5 ec |.....!.....t....| -00000010 3f 9f 1a 88 67 00 8b 16 68 54 52 bb df f7 4c 75 |?...g...hTR...Lu| -00000020 57 49 e3 00 1e b2 6f 61 67 eb ac 1e 77 31 bc e1 |WI....oag...w1..| -00000030 66 a9 db 13 8b 43 d3 73 f9 57 97 1d 75 bd fc 78 |f....C.s.W..u..x| -00000040 1b 0c 92 a4 66 95 d6 89 3d 86 63 a6 e8 15 5d d2 |....f...=.c...].| -00000050 65 4c b5 2b f7 3d be 81 17 e6 23 64 65 26 68 b8 |eL.+.=....#de&h.| -00000060 14 6b 68 24 78 19 84 a4 a1 82 d2 b6 6f d1 58 68 |.kh$x.......o.Xh| -00000070 43 db 14 90 af 15 3c 8d 0c 5d b3 26 f3 14 7f cf |C.....<..].&....| -00000080 09 05 2a 2a 5d 21 16 03 03 02 69 f3 b0 da 24 57 |..**]!....i...$W| -00000090 c9 6b 11 b6 67 20 2c 5f 64 53 ca a5 71 26 95 89 |.k..g ,_dS..q&..| -000000a0 47 be 7d 27 dd a9 6e 8e af 45 de 5d bd 37 8c 2b |G.}'..n..E.].7.+| -000000b0 b0 d8 d0 49 7e f1 cf 1c 47 a9 0f 5f fa 99 56 46 |...I~...G.._..VF| -000000c0 a2 41 f7 f6 08 5f 97 6b 14 64 01 aa b2 f6 55 34 |.A..._.k.d....U4| -000000d0 25 76 f3 ef 29 a3 cc 99 f5 06 ac 30 d1 00 db 36 |%v..)......0...6| -000000e0 9b 41 c0 45 2e d4 bc b9 02 87 0f 0a 0e 2d 9d 56 |.A.E.........-.V| -000000f0 df b8 94 8e 54 a8 6d 0a 8d b8 71 3c c0 76 0a 94 |....T.m...q<.v..| -00000100 6d dc c6 5b 24 7e c5 48 25 67 15 44 2b 48 d0 cd |m..[$~.H%g.D+H..| -00000110 82 d8 c8 5e 0c 20 32 95 a9 f8 d5 31 cd f7 44 da |...^. 2....1..D.| -00000120 05 c4 cb e9 04 48 72 ac ca 7b 26 e6 76 d2 01 18 |.....Hr..{&.v...| -00000130 c0 34 88 29 7c 8c dc 35 e3 25 c9 11 f0 2b 1f 44 |.4.)|..5.%...+.D| -00000140 d8 7d ea 1d 6a 57 b2 2c 52 8e 89 50 e3 e4 1c 51 |.}..jW.,R..P...Q| -00000150 91 0c 6d fd 8d ad 91 77 b1 34 02 83 96 7e 39 5f |..m....w.4...~9_| -00000160 bc ed b1 05 3b f0 d3 f0 b3 05 54 e8 47 36 32 b1 |....;.....T.G62.| -00000170 88 c9 31 7e d8 41 12 3b 55 25 b3 bc e3 9f a5 17 |..1~.A.;U%......| -00000180 a8 45 21 68 e6 12 83 0e 80 13 d5 80 4d 89 0d fb |.E!h........M...| -00000190 9f 06 84 35 04 e8 0e bc 8c e7 17 83 7a 0f 68 34 |...5........z.h4| -000001a0 ee db 10 78 31 85 34 e0 d8 f4 d2 3d fa 1c 18 49 |...x1.4....=...I| -000001b0 25 c9 b9 53 ee b1 62 ff 13 77 36 8e 59 73 f7 9b |%..S..b..w6.Ys..| -000001c0 5f 4d 01 2d 41 dc 9e 2e f7 f4 4c f7 27 eb e3 35 |_M.-A.....L.'..5| -000001d0 91 41 b5 7f 28 eb 04 2c f6 db 80 aa 3d 4e ac 2b |.A..(..,....=N.+| -000001e0 9d 95 c8 97 cf 35 f5 49 0d c7 b1 4f bf 41 eb 4a |.....5.I...O.A.J| -000001f0 9a a6 56 b8 8a 75 53 17 dc d4 ad ab 82 25 e8 0a |..V..uS......%..| -00000200 ae 8b c0 a3 8e 67 4b d1 96 04 45 1d c8 12 32 3f |.....gK...E...2?| -00000210 7e 4c 48 95 9f 24 8c 01 cf c3 78 10 d6 12 63 37 |~LH..$....x...c7| -00000220 38 58 d3 31 97 25 9d 43 29 29 86 fb 9a 47 b5 c1 |8X.1.%.C))...G..| -00000230 81 dc ab 4b be 57 bf 9f 0c 0b 28 fc 13 15 4e 2d |...K.W....(...N-| -00000240 58 97 78 3e 7f eb bf a1 cf a1 8d ab fe 3a 47 77 |X.x>.........:Gw| -00000250 c1 fb b7 b8 82 42 37 95 60 20 be 91 26 ca 2c 48 |.....B7.` ..&.,H| -00000260 44 57 6c 75 24 22 93 32 cf 83 f8 0c 75 b5 4a f1 |DWlu$".2....u.J.| -00000270 88 d0 8e 1d 4e c7 93 1b ba ea 14 04 38 f6 7a c2 |....N.......8.z.| -00000280 d2 4b 7c 9c 1b 8b 31 6c d8 09 88 6a 6d a1 61 d6 |.K|...1l...jm.a.| -00000290 ee 80 ea 76 c0 d9 5a 49 31 3b dd 0f b5 5a a1 29 |...v..ZI1;...Z.)| -000002a0 d4 ff db 68 48 96 26 e7 a7 82 10 e9 6e 5c c4 66 |...hH.&.....n\.f| -000002b0 d5 e0 87 c3 66 d8 7c 4e bf a5 31 0f fa 6e f6 21 |....f.|N..1..n.!| -000002c0 4d fe ea f0 36 91 9e 18 81 c0 21 4f 77 eb 65 c0 |M...6.....!Ow.e.| -000002d0 fe 84 45 22 dd 28 03 eb e5 ce 15 62 e1 b8 9f 0e |..E".(.....b....| -000002e0 aa 9d bc 5c 38 41 01 74 17 d0 92 a5 80 e4 4b 58 |...\8A.t......KX| -000002f0 42 bb 42 5d 16 03 03 00 bc 09 fb 78 c1 36 2e 27 |B.B].......x.6.'| -00000300 b2 44 17 1a a8 2b f5 cd 98 78 a4 c1 1c f2 e7 53 |.D...+...x.....S| -00000310 92 ef c1 88 83 78 37 23 08 f5 7f 5d 9f d1 c4 32 |.....x7#...]...2| -00000320 df 01 c6 9c 3e a8 11 31 f4 77 69 94 d7 67 bc 62 |....>..1.wi..g.b| -00000330 8e 18 57 0a cd d8 ba db cd 2b e8 f9 37 77 16 13 |..W......+..7w..| -00000340 be 18 53 2a 50 0b 0a d7 9a f0 7d 10 d3 13 bb 82 |..S*P.....}.....| -00000350 36 5c aa d1 17 ad 83 69 47 7f 81 5c 36 53 81 e3 |6\.....iG..\6S..| -00000360 1d 65 9f ac b2 3e 76 77 5a 6a 39 e5 df 92 55 e6 |.e...>vwZj9...U.| -00000370 90 96 9c b9 54 ac 09 17 ce f5 43 9f 3e 1e 3a b6 |....T.....C.>.:.| -00000380 cb 61 da 1a 3e e0 b4 51 30 3e 22 09 0b 05 a7 6e |.a..>..Q0>"....n| -00000390 5a df 82 d2 ab b9 d8 d2 37 a7 d7 b5 7f a9 ea 49 |Z.......7......I| -000003a0 2f 64 57 33 5a 19 7f a3 2f 6a 7e 40 18 19 4a 61 |/dW3Z.../j~@..Ja| -000003b0 05 92 35 8b 50 16 03 03 00 4a 50 1e e6 f4 47 dd |..5.P....JP...G.| -000003c0 fb 02 b4 22 71 e7 1e b1 51 28 9f 2d 40 64 2c 85 |..."q...Q(.-@d,.| -000003d0 47 33 69 3e b0 e4 c7 eb a6 31 13 76 45 39 e7 50 |G3i>.....1.vE9.P| -000003e0 94 86 2e dd e1 58 f2 83 60 86 07 94 29 ce 69 12 |.....X..`...).i.| -000003f0 0f 89 e3 89 2f 00 50 2b 56 ed 1d fe 25 55 9f 33 |..../.P+V...%U.3| -00000400 3d 30 93 3c 16 03 03 00 14 0e 3f df b0 79 70 a7 |=0.<......?..yp.| -00000410 08 bb 01 ff 08 44 69 65 49 81 9f e5 3a |.....DieI...:| +00000000 16 03 03 00 81 8b e2 a1 f5 15 55 13 f6 f2 fa 95 |..........U.....| +00000010 3b bb 0f 3d 3e 9b 3c b1 60 cb 69 7f 63 62 2d 9b |;..=>.<.`.i.cb-.| +00000020 20 47 3a 7d 5e d0 98 38 49 c3 94 f8 1d 56 1d 69 | G:}^..8I....V.i| +00000030 27 65 bc ca 63 22 65 61 60 67 49 35 f0 eb 83 1b |'e..c"ea`gI5....| +00000040 44 c4 f0 91 64 5a 81 b5 06 4b 3e 3a ef 3b 5c b0 |D...dZ...K>:.;\.| +00000050 81 b4 36 df f3 0d a3 0a 1c 40 03 fa 81 48 42 70 |..6......@...HBp| +00000060 bf 4c b3 6b 67 19 7b 83 05 a1 31 a3 1c 79 49 2c |.L.kg.{...1..yI,| +00000070 1f 58 bc 7d 98 4e 5b 64 44 3d 3c 43 fb 77 c7 7c |.X.}.N[dD=l.c[.| +000003c0 f0 c6 3a 58 e0 6c 6b 70 46 d0 be 6f 13 34 7a 30 |..:X.lkpF..o.4z0| +000003d0 e6 e4 b2 fd 39 ee 79 b1 7e 73 5e 9b 2d d9 3f 4f |....9.y.~s^.-.?O| +000003e0 61 d5 53 37 79 57 15 a3 3a 7c b7 02 cc 76 25 1d |a.S7yW..:|...v%.| +000003f0 96 8b dd 9e 32 8b 1a 9e 37 b1 1a b8 f2 4f ef 3c |....2...7....O.<| +00000400 78 e1 b9 07 16 03 03 00 14 bf da c1 d4 16 fd 48 |x..............H| +00000410 a9 ad 59 6d 8c dc e1 6c fd 73 ca 9c 1b |..Ym...l.s...| >>> Flow 9 (client to server) -00000000 16 03 03 02 69 b8 47 2d 3a 7a e4 d0 2b 45 b2 38 |....i.G-:z..+E.8| -00000010 1e 6f 8d 3d e1 26 91 92 d7 1f e9 a4 2c d8 30 2c |.o.=.&......,.0,| -00000020 ce 68 50 e7 80 77 63 e1 bd c7 c8 1b 6f ca b0 bf |.hP..wc.....o...| -00000030 82 1d 75 85 2c 5d b2 f6 9a f2 b6 9b c4 24 54 86 |..u.,].......$T.| -00000040 b8 fb dc ae 09 25 c4 42 fc 4d f2 18 5b a3 92 31 |.....%.B.M..[..1| -00000050 8a 78 1f 1a 74 d4 43 0b 24 2f 14 2b 0e 05 3a 8d |.x..t.C.$/.+..:.| -00000060 7a 1c 21 2f cd 7b 9d 6c 32 b1 f6 14 fa 9d f5 be |z.!/.{.l2.......| -00000070 9c f1 8e 75 b9 27 82 ba e7 fc 14 39 2a 6f 3e 59 |...u.'.....9*o>Y| -00000080 d6 bc 6c 3f f1 33 5e fa bb 07 bc e4 0b 7e 4a 5d |..l?.3^......~J]| -00000090 2b e8 9b d5 00 d2 cc 8f 94 01 82 0e bb 28 f9 d2 |+............(..| -000000a0 1f ee 0c ff 9c 4d 37 5b 23 5b 23 a5 39 fe cd 2b |.....M7[#[#.9..+| -000000b0 ef 30 46 b7 c1 0e a3 fc fd f6 1b d3 78 fb d9 93 |.0F.........x...| -000000c0 3a 52 fe 91 dc 42 63 85 09 64 63 3a 9d 9f 21 74 |:R...Bc..dc:..!t| -000000d0 c6 d9 e4 b5 cc ef 94 96 0f c1 d0 45 f6 e6 b9 32 |...........E...2| -000000e0 01 74 88 24 bb d9 d6 25 23 14 de 25 f4 7e 9c 77 |.t.$...%#..%.~.w| -000000f0 82 83 7e 59 dc c3 f7 d9 e4 b1 95 e0 bb 6e 66 e4 |..~Y.........nf.| -00000100 bd cb a2 72 a0 63 d4 39 9f 57 a7 d1 88 7a 59 64 |...r.c.9.W...zYd| -00000110 38 45 bb fc 5a 02 81 4c 2e e5 e4 1c 7d e9 e8 f0 |8E..Z..L....}...| -00000120 e1 b7 88 f5 a6 ee d0 b7 e5 2f 9e 15 d5 76 8d f7 |........./...v..| -00000130 68 0f 7b 6a 48 e7 19 3a bc ef f5 fc 72 a4 62 ce |h.{jH..:....r.b.| -00000140 a6 66 e5 e8 74 03 c0 4d b4 14 e4 0c 36 fd 99 0b |.f..t..M....6...| -00000150 0e 4f b6 5e 4c db dc 51 fe ae e9 07 37 92 6c 35 |.O.^L..Q....7.l5| -00000160 f7 99 6c b9 36 c2 b9 7c 5e ef 72 c1 1f ba fb 18 |..l.6..|^.r.....| -00000170 57 24 f2 d4 21 cf 46 bd 71 3d 62 63 ba 1c 0f 8b |W$..!.F.q=bc....| -00000180 f4 a6 fc ea 27 de 48 b8 ed e3 6e 4b 30 66 fa 1e |....'.H...nK0f..| -00000190 22 7b 49 e2 03 96 8a 6a 3c 6a 1a 62 81 cc 06 dd |"{I....jL| -000001d0 e7 b9 9f 90 aa 1f 39 13 e2 4b 8c ff b5 13 d1 d2 |......9..K......| -000001e0 cd ac ce 8c 2b bc b3 b3 fc f7 37 db 61 8f 6b 90 |....+.....7.a.k.| -000001f0 c2 bc 6e e3 8e fa d9 16 ab 62 c7 3f d7 e1 0b a8 |..n......b.?....| -00000200 2b 8a 0d b6 2c 90 dc 6e b4 44 e0 13 32 fb 80 23 |+...,..n.D..2..#| -00000210 a9 e4 18 ea 8d c7 8a 14 0a 82 8d 3b 21 88 bf bf |...........;!...| -00000220 ff 10 3c 08 6b 65 70 4c b5 88 7d 9c 92 43 15 55 |..<.kepL..}..C.U| -00000230 18 e9 cf 15 5d 55 3a f0 a1 46 ca d4 9e f3 c0 16 |....]U:..F......| -00000240 4b ee f6 17 95 e0 af 1e 85 54 62 dd 56 88 6b e1 |K........Tb.V.k.| -00000250 29 ac f9 4f dc 5c 89 16 19 6b 21 c9 6c c8 1e 1d |)..O.\...k!.l...| -00000260 89 7c cc a4 9b 1f c8 ce 67 c6 83 79 6a d6 16 03 |.|......g..yj...| -00000270 03 00 35 6f 33 7d 96 3c 8d 66 a5 d1 7a 8b bc fa |..5o3}.<.f..z...| -00000280 ca f0 89 9d 2b 37 0c f5 aa 14 07 f2 58 be d1 d3 |....+7......X...| -00000290 ec 73 dd b6 33 e2 df 46 1a d3 ee e8 26 d9 be 2b |.s..3..F....&..+| -000002a0 43 25 3b e2 78 72 10 43 16 03 03 00 98 18 03 96 |C%;.xr.C........| -000002b0 9c eb 31 50 72 15 0e 9b ff c7 6b b0 60 32 08 c6 |..1Pr.....k.`2..| -000002c0 ef 70 f9 0c 22 4a a2 0f 77 31 b3 ea d0 12 65 af |.p.."J..w1....e.| -000002d0 c9 28 0f f9 5b b7 f3 75 9c 5a 6e df a1 6a e6 d5 |.(..[..u.Zn..j..| -000002e0 82 0b 18 05 94 aa dd 93 e5 1d 60 06 47 f5 3e b1 |..........`.G.>.| -000002f0 d5 e8 e7 b7 9f 43 bf 4b 8a 5e 48 3b f1 42 f6 c0 |.....C.K.^H;.B..| -00000300 c3 65 86 e2 bc 7a 75 1d 93 cf 7f 3d 11 d3 85 c3 |.e...zu....=....| -00000310 c3 90 90 0b 77 e1 d7 64 da 71 3c 55 de 7c b9 71 |....w..d.q...| -00000370 f8 7e fd 4d bd 3b 0e bc 9b 74 27 09 33 c3 27 2a |.~.M.;...t'.3.'*| +00000000 16 03 03 02 69 11 1e 53 9b b7 57 6d ea 89 bb 37 |....i..S..Wm...7| +00000010 1b c6 01 bd 27 db fa 17 cc 5d 20 be ee 5b a9 64 |....'....] ..[.d| +00000020 48 4e 4a 4c 82 65 8e 3d 42 d6 ce 5c a8 50 d4 fa |HNJL.e.=B..\.P..| +00000030 0f 02 b2 19 90 b5 4e ae 6c e9 d6 b7 b8 64 ca 0e |......N.l....d..| +00000040 09 2d a9 7b ab 0f b8 83 97 b6 e0 eb bf 03 5a 1c |.-.{..........Z.| +00000050 e7 16 31 67 30 46 60 26 df 19 cf 5f fa 40 36 43 |..1g0F`&..._.@6C| +00000060 91 d5 7c 2f 5f 29 74 03 e0 90 cd 55 25 e5 1e fe |..|/_)t....U%...| +00000070 6b 13 ec 58 29 b0 f4 a3 b2 8d ba 4e 3b f1 11 d8 |k..X)......N;...| +00000080 85 49 50 b9 e0 03 89 a1 0f da ce 57 83 aa 4a 8c |.IP........W..J.| +00000090 3b 15 d5 10 47 01 22 32 4f 78 87 69 4c bf a6 6e |;...G."2Ox.iL..n| +000000a0 d4 e6 a5 1e fa 5b ff b0 38 a5 fa 83 1d 45 c5 18 |.....[..8....E..| +000000b0 72 65 91 6c 41 d2 21 be 5b 1d e9 f5 19 eb d0 5a |re.lA.!.[......Z| +000000c0 7e 0d 81 c9 ca f0 97 9e cc 9b 5c 77 6b 9c 15 d3 |~.........\wk...| +000000d0 bd 43 4d 42 e5 f9 82 a9 d6 f2 44 93 ae 74 a3 fd |.CMB......D..t..| +000000e0 c5 1f 15 13 a0 ea d2 f3 4c 4c ea 2d fe 3b 6e 7b |........LL.-.;n{| +000000f0 f4 11 f7 2e 7d 45 26 a0 d9 29 4e 4d ec 90 e2 3e |....}E&..)NM...>| +00000100 51 52 dd 6e e1 b5 77 b1 a2 f5 17 b5 34 7f e8 8f |QR.n..w.....4...| +00000110 38 9c d6 1c b5 6c 2d 99 00 a1 41 95 15 c5 e5 bf |8....l-...A.....| +00000120 c1 67 fb ea 53 6c a8 85 8c c4 a6 74 e3 dc f7 90 |.g..Sl.....t....| +00000130 b8 cc 99 39 1a a1 c6 51 db 65 e9 b8 ad 2b 1f 35 |...9...Q.e...+.5| +00000140 b5 90 ae f7 af c2 d0 a9 92 eb 63 21 24 4f 5e 62 |..........c!$O^b| +00000150 ba 69 ce 1a c8 41 79 db c0 6c ef bc cf 19 4a 2c |.i...Ay..l....J,| +00000160 e0 66 6e 72 97 2d 75 e5 ee 14 82 e8 26 98 fe c4 |.fnr.-u.....&...| +00000170 8a 17 c4 fb 48 2a d7 7e d9 3e 5b f9 d4 7d 0e da |....H*.~.>[..}..| +00000180 56 44 5e 33 9d 5f 97 ab d1 60 a8 ee 3d 16 6a 2a |VD^3._...`..=.j*| +00000190 33 b1 7d e2 e6 86 cd 88 ac e1 48 49 4e 19 a2 b0 |3.}.......HIN...| +000001a0 16 53 ec ff b8 a4 f7 35 2d a7 7a 04 86 66 42 52 |.S.....5-.z..fBR| +000001b0 51 3d 21 62 c5 35 9c e5 cb f9 bf 7b d1 12 b0 18 |Q=!b.5.....{....| +000001c0 7b 6f 88 d9 ef d2 1a 45 3e 51 ac 3e c8 87 8c 47 |{o.....E>Q.>...G| +000001d0 08 d0 90 b5 66 f6 4e c3 75 74 68 c8 7d 14 3a 2b |....f.N.uth.}.:+| +000001e0 83 7d 12 78 37 9e 11 02 3d 63 ba 78 b6 ba 6d 26 |.}.x7...=c.x..m&| +000001f0 30 b0 bf a9 23 1e 83 aa 3d a8 02 5b 77 5f 2a 95 |0...#...=..[w_*.| +00000200 d0 b9 c8 22 a3 a9 fe b0 32 99 8a 46 67 10 b3 d9 |..."....2..Fg...| +00000210 3e 84 02 ec a2 68 7e 69 db 51 99 37 ee 49 66 0b |>....h~i.Q.7.If.| +00000220 af e1 cd b0 25 74 dc ce 29 ed 70 1c 3a bb f2 99 |....%t..).p.:...| +00000230 03 86 6d af 3f 78 4a 86 70 b8 85 15 02 91 be f6 |..m.?xJ.p.......| +00000240 4f f2 73 98 00 c6 76 20 c2 19 c6 e9 6c d0 e5 09 |O.s...v ....l...| +00000250 5c 12 c8 1c a1 3d b7 41 18 26 cb ea d0 92 61 53 |\....=.A.&....aS| +00000260 06 7c f8 5e a8 27 de 76 4e 83 49 2a ab 82 16 03 |.|.^.'.vN.I*....| +00000270 03 00 35 4f b7 51 7c c8 51 25 a4 58 de 8b 4a e2 |..5O.Q|.Q%.X..J.| +00000280 97 cc 48 d0 4d be 9b 8a 44 3b 22 43 b9 82 a4 a5 |..H.M...D;"C....| +00000290 76 38 0b ae 91 d3 20 75 18 50 f3 1b eb 11 fd 86 |v8.... u.P......| +000002a0 4a 1a f1 e8 2a f8 e0 60 16 03 03 00 98 ae e6 1b |J...*..`........| +000002b0 b1 00 f9 14 93 55 be 63 ea 5b 5e d4 18 37 6b 14 |.....U.c.[^..7k.| +000002c0 5c 8e fb 82 51 e1 57 24 b7 4a 8b 55 74 79 70 55 |\...Q.W$.J.UtypU| +000002d0 de 33 82 14 0a 39 0d 91 92 9a 11 c0 4a dd 12 49 |.3...9......J..I| +000002e0 ea 1a 41 df fd f2 4a 79 c3 0a d5 93 5c ea 82 ff |..A...Jy....\...| +000002f0 16 4a 20 91 25 34 5d 72 9d ea 0e 40 dd 6d 86 fd |.J .%4]r...@.m..| +00000300 e9 d1 d9 db 61 e6 62 17 6b 09 47 c4 a7 32 1c 22 |....a.b.k.G..2."| +00000310 f6 e4 41 2a 3e 2b d0 c3 92 56 c5 b8 5f 6d 25 44 |..A*>+...V.._m%D| +00000320 81 e7 1a ed 70 6a a6 94 89 d1 ad 8d d1 c0 df a2 |....pj..........| +00000330 26 6f 20 0b 0e 51 15 dd 05 86 36 88 72 3f e1 5d |&o ..Q....6.r?.]| +00000340 da 9d d3 76 e4 14 03 03 00 11 52 70 cd 84 39 32 |...v......Rp..92| +00000350 7c c0 58 53 9b 32 00 96 14 b6 57 16 03 03 00 20 ||.XS.2....W.... | +00000360 98 94 aa 9f 77 71 42 3e 48 e8 74 8e 27 60 54 c2 |....wqB>H.t.'`T.| +00000370 55 ac 52 99 37 21 f3 1e 30 93 5f 71 06 19 e5 1c |U.R.7!..0._q....| >>> Flow 10 (server to client) -00000000 14 03 03 00 11 3d 29 da dc b6 5a 09 66 34 6e 00 |.....=)...Z.f4n.| -00000010 65 8c 29 d2 18 bd 16 03 03 00 20 63 55 d1 84 7d |e.)....... cU..}| -00000020 3e cc 2d f5 d3 48 c2 5c 72 d8 6b cf 69 b4 ed 5f |>.-..H.\r.k.i.._| -00000030 07 96 53 13 1e 53 59 18 c1 bb c7 17 03 03 00 19 |..S..SY.........| -00000040 30 5b 6d d2 26 db ef c1 a9 00 e6 ce 87 86 9b 71 |0[m.&..........q| -00000050 dd fb aa 79 aa b6 39 1e 70 |...y..9.p| +00000000 14 03 03 00 11 45 8e f9 74 04 d0 44 c6 94 80 60 |.....E..t..D...`| +00000010 c1 50 7d b2 64 76 16 03 03 00 20 d5 65 8a b9 26 |.P}.dv.... .e..&| +00000020 54 70 26 de c6 8a 8f 61 a3 b1 9e 8b 49 40 f7 24 |Tp&....a....I@.$| +00000030 4f 75 e0 94 e6 e7 68 51 38 8a 37 17 03 03 00 19 |Ou....hQ8.7.....| +00000040 42 7e 5a e2 46 7b ba 7d 0d 07 20 2a c0 56 fe aa |B~Z.F{.}.. *.V..| +00000050 01 eb ca d2 29 1d ff 85 10 |....)....| >>> Flow 11 (client to server) -00000000 15 03 03 00 12 32 8f cd ef b8 3e 96 01 07 ca 0b |.....2....>.....| -00000010 83 21 83 97 78 25 64 |.!..x%d| +00000000 15 03 03 00 12 1d 01 c7 d5 d5 d1 ce 8c 52 15 8f |.............R..| +00000010 75 1e 97 fa 38 5c 65 |u...8\e| diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice index 983174f5ec8..006e2d7cef8 100644 --- a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice +++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice @@ -16,11 +16,11 @@ 000000e0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0| 000000f0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |.........._X.;t| >>> Flow 2 (server to client) -00000000 16 03 03 00 59 02 00 00 55 03 03 34 8b db 6b 9e |....Y...U..4..k.| -00000010 68 c3 92 09 72 4f 02 6c b9 7a ac 74 72 0b 32 01 |h...rO.l.z.tr.2.| -00000020 f4 86 9e b5 53 db da 96 c2 65 2a 20 8f 89 24 79 |....S....e* ..$y| -00000030 8a a5 38 7a 52 68 7a a9 cc d0 5a 04 4d ce 87 0e |..8zRhz...Z.M...| -00000040 64 48 51 e0 00 cb 60 f0 b4 e9 99 27 cc a8 00 00 |dHQ...`....'....| +00000000 16 03 03 00 59 02 00 00 55 03 03 47 d0 f5 d9 f0 |....Y...U..G....| +00000010 59 d1 bf 28 d0 39 36 c0 bc d1 25 fd 5a 63 18 06 |Y..(.96...%.Zc..| +00000020 1e 8a 5c a6 6f d0 f9 b4 02 23 e1 20 df a0 2a 74 |..\.o....#. ..*t| +00000030 1a 52 8b d9 90 01 c2 86 69 12 b8 13 58 aa 59 b0 |.R......i...X.Y.| +00000040 66 79 ff 01 9b 9a 72 1c a6 83 e6 91 cc a8 00 00 |fy....r.........| 00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| 00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..| 00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............| @@ -60,284 +60,284 @@ 00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.| 000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..| 000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......| -000002c0 ac 0c 00 00 a8 03 00 1d 20 63 06 67 5c 4e da 3f |........ c.g\N.?| -000002d0 0a 02 78 46 92 fe 8f ed 41 ac 1a d5 04 e6 ca 4a |..xF....A......J| -000002e0 7e 9c d0 32 e8 ee f3 9c 5d 08 04 00 80 c0 51 ba |~..2....].....Q.| -000002f0 71 28 00 53 c6 40 63 20 d4 bd 52 60 d2 f6 e2 57 |q(.S.@c ..R`...W| -00000300 ba 6f a8 bf 42 2a 11 b5 9a eb 9f b6 53 77 87 72 |.o..B*......Sw.r| -00000310 ea 7d bf f8 f4 cf 1d 76 6c 03 75 9d df 88 b1 13 |.}.....vl.u.....| -00000320 66 5c 43 41 1e 97 52 32 86 d0 22 3c f6 ca 90 a5 |f\CA..R2.."<....| -00000330 ba cf 75 94 1f 22 93 c0 0c c9 82 a5 eb d2 07 85 |..u.."..........| -00000340 a0 39 9e 5d fa 88 1f 62 25 09 c3 97 c1 1d 4e a2 |.9.]...b%.....N.| -00000350 fe 98 96 b8 c0 eb b9 18 07 2d e1 cf 9b fd 25 ba |.........-....%.| -00000360 93 fb 73 e5 7e 36 27 b3 11 00 58 95 f8 16 03 03 |..s.~6'...X.....| +000002c0 ac 0c 00 00 a8 03 00 1d 20 20 97 bd 85 2f cb 85 |........ .../..| +000002d0 be a8 9c e3 ae 6b 23 a5 5b 18 65 5c f5 cc 24 2b |.....k#.[.e\..$+| +000002e0 34 2c 5f c8 4d e9 86 35 0b 08 04 00 80 d2 b6 ee |4,_.M..5........| +000002f0 86 76 aa 1d 9c 1c ee ef 0e 59 63 1d ec f1 cf a1 |.v.......Yc.....| +00000300 f3 5b 6d da 99 9c 40 07 bf 28 ad 72 cd 80 6c 9d |.[m...@..(.r..l.| +00000310 bf a2 20 33 2d d0 67 ef 90 28 88 2b d0 8e c6 9d |.. 3-.g..(.+....| +00000320 87 7a 18 8f 80 ce 25 92 13 8d ef 38 0a 14 f9 67 |.z....%....8...g| +00000330 88 94 ef af 97 d2 21 90 9e 24 2f af 1e bb fa 10 |......!..$/.....| +00000340 4c a7 9f f5 27 63 e6 d8 1a 86 53 c6 3c 15 a8 6c |L...'c....S.<..l| +00000350 b9 bc 8f c4 38 1a 4b 34 36 ec af b2 1e d0 bf 58 |....8.K46......X| +00000360 74 36 ad fb e4 f0 fd 9d 6d 01 cf 51 6c 16 03 03 |t6......m..Ql...| 00000370 00 04 0e 00 00 00 |......| >>> Flow 3 (client to server) 00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.| 00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....| 00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......| -00000030 16 03 03 00 20 02 50 f6 74 83 31 96 36 c1 22 99 |.... .P.t.1.6.".| -00000040 1d d7 99 b2 8c 2b 04 3a bd 3e 19 e5 ef 71 dc 72 |.....+.:.>...q.r| -00000050 b2 0d c8 d1 3f |....?| +00000030 16 03 03 00 20 e8 d5 df da 49 9a 94 10 30 90 81 |.... ....I...0..| +00000040 c6 19 54 d4 0d e2 0d e0 d9 a3 c0 21 7f a6 d1 cc |..T........!....| +00000050 ea 75 2e 17 01 |.u...| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 20 9b a3 02 3e 55 |.......... ...>U| -00000010 4a e6 4c 7f 9a a6 a2 65 bd 74 ff ad c5 ce 43 21 |J.L....e.t....C!| -00000020 d3 b1 d1 89 0c 15 7d 7d a7 d8 4c |......}}..L| +00000000 14 03 03 00 01 01 16 03 03 00 20 f3 92 03 fb 7b |.......... ....{| +00000010 0f 32 0b 5b dd 9e eb c3 26 2c 92 4d 58 35 a8 96 |.2.[....&,.MX5..| +00000020 74 d6 d8 0f 61 b2 7d b6 8d ec e6 |t...a.}....| >>> Flow 5 (client to server) -00000000 17 03 03 00 16 4c 5e 0a 69 e1 e8 fc 52 f0 3d ea |.....L^.i...R.=.| -00000010 33 f5 02 6b 47 49 cd a5 b5 94 4e |3..kGI....N| +00000000 17 03 03 00 16 ab 69 44 d0 fe 95 93 ae f9 1b d7 |......iD........| +00000010 33 6c 59 a5 41 cc d2 1b ca 2c 63 |3lY.A....,c| >>> Flow 6 (server to client) -00000000 16 03 03 00 14 6a 8d 46 e1 33 c6 63 9d 27 3e e8 |.....j.F.3.c.'>.| -00000010 7f 31 74 7f 4f 60 b3 f7 aa |.1t.O`...| +00000000 16 03 03 00 14 99 96 92 c4 82 c8 27 77 a6 f4 ca |...........'w...| +00000010 e5 5b ff 78 bc 54 b6 d7 cd |.[.x.T...| >>> Flow 7 (client to server) -00000000 16 03 03 01 16 6f 4d 64 ff 20 fa 1c 19 26 bc 99 |.....oMd. ...&..| -00000010 ec 09 be e7 6d 88 73 1e 4f c6 74 35 f7 5c b3 e5 |....m.s.O.t5.\..| -00000020 f6 d1 2a 90 7f c3 34 dc 83 6b a9 f1 32 01 a1 84 |..*...4..k..2...| -00000030 0c 4c 06 db 88 d4 19 31 d2 46 1f 2c 3d 13 75 5b |.L.....1.F.,=.u[| -00000040 f3 e5 d0 b7 a8 4f 2c b2 89 35 78 82 78 b7 f5 c6 |.....O,..5x.x...| -00000050 ea a2 1d f3 24 9d e2 01 25 e2 96 a1 06 57 5c 50 |....$...%....W\P| -00000060 d6 5b 56 24 18 6e b4 ce 6a 2e c7 01 65 99 3f 35 |.[V$.n..j...e.?5| -00000070 c1 07 48 75 ad 0b 1a b3 58 df 83 42 f8 78 eb 92 |..Hu....X..B.x..| -00000080 e8 70 c9 34 af db e8 d6 b0 c8 37 ac b2 d7 18 ba |.p.4......7.....| -00000090 a3 1d 35 09 2e 2f 82 e0 3a 68 fd 7f ba 4d 5c 5c |..5../..:h...M\\| -000000a0 6c 6d ac 24 60 bf e0 37 a9 17 8d 6d 8a 69 96 23 |lm.$`..7...m.i.#| -000000b0 4f c7 53 a0 48 65 58 cc 01 03 df 33 36 5a 8a 7e |O.S.HeX....36Z.~| -000000c0 3f 84 33 26 3f 02 66 48 82 22 22 b7 7d 62 7e 56 |?.3&?.fH."".}b~V| -000000d0 94 df 43 df 08 fc 70 f6 bb 1a dd 19 b1 ea ea a2 |..C...p.........| -000000e0 6f 36 ab b0 d2 77 e6 c8 f6 70 a6 a6 a3 0d ab c8 |o6...w...p......| -000000f0 dc d1 9b a2 05 43 44 0c 17 8d 47 86 55 77 56 34 |.....CD...G.UwV4| -00000100 d7 71 2c 75 9a d4 70 e4 77 5e 1a b7 b1 13 ae 14 |.q,u..p.w^......| -00000110 d0 99 a0 9e 50 9c 35 94 4d 34 e5 |....P.5.M4.| +00000000 16 03 03 01 16 d9 6a 26 33 e5 d8 df 32 d1 f5 84 |......j&3...2...| +00000010 1f 37 7f 07 6a ae be 20 84 20 dc 28 31 8e 46 32 |.7..j.. . .(1.F2| +00000020 0b 96 c8 22 28 fb 98 d9 8e 6f 6d 97 66 55 e2 1e |..."(....om.fU..| +00000030 b5 b8 e4 9b 52 25 28 c2 72 cb 9e 14 4c ba 58 6c |....R%(.r...L.Xl| +00000040 3b 33 da 56 db fe 14 d3 4c b4 ce a9 57 64 ae 4e |;3.V....L...Wd.N| +00000050 5f c5 a7 e6 f4 01 51 d7 81 f4 1d ca fa 3f 86 e7 |_.....Q......?..| +00000060 9f 64 28 6e 3f e4 ef 79 77 20 64 45 ed a2 16 e1 |.d(n?..yw dE....| +00000070 b4 63 99 9f 62 6d b7 6d f4 ad 1f fe d9 de 00 84 |.c..bm.m........| +00000080 4b bb 0c bc c8 82 a8 1d 8a ac f6 10 2d 5d d4 c7 |K...........-]..| +00000090 37 f8 fc 89 24 ea c4 b8 87 f4 f4 f0 4b cd db e2 |7...$.......K...| +000000a0 15 03 95 1e c1 10 7c e8 6d 99 6c e0 bc e1 0a a5 |......|.m.l.....| +000000b0 d8 36 eb 59 93 6d 1c 96 1c 61 1b 11 36 04 58 6b |.6.Y.m...a..6.Xk| +000000c0 c5 b0 fb 8e 9f 21 4a 25 a1 59 ee 5d 1b e3 e3 98 |.....!J%.Y.]....| +000000d0 71 0a d8 3f 18 f2 b2 1c 6f ec 6d 87 13 b9 d3 25 |q..?....o.m....%| +000000e0 53 c1 00 78 be 99 82 f6 27 05 24 01 10 1c 59 19 |S..x....'.$...Y.| +000000f0 94 6a af 7e e5 ae c5 03 14 04 e2 fe 5e 59 e8 e0 |.j.~........^Y..| +00000100 45 3d af c0 40 ea 84 0a 13 9c d3 0f d4 69 3f 3e |E=..@........i?>| +00000110 97 83 ac b5 b9 07 56 9a 19 44 ca |......V..D.| >>> Flow 8 (server to client) -00000000 16 03 03 00 81 28 ba 2e 7a 2b 59 83 ae aa ba c7 |.....(..z+Y.....| -00000010 d7 49 a5 ca c0 fc 8b 49 f5 10 77 ac e7 ae 12 de |.I.....I..w.....| -00000020 0d ad 0e 2c d9 ee 99 c4 95 7b 09 b2 91 27 44 6a |...,.....{...'Dj| -00000030 7c 08 ce bb 98 4a 1c 8c 47 30 21 c7 5d 1e 86 39 ||....J..G0!.]..9| -00000040 79 07 48 2a ac 90 7b 26 46 6a a5 b1 7c df fa ae |y.H*..{&Fj..|...| -00000050 0f 20 c8 f0 b5 65 57 2b d5 1f 14 cc bc 7e 94 42 |. ...eW+.....~.B| -00000060 b6 30 c1 d7 eb 8d 39 0f 65 7a b7 d0 38 21 eb b0 |.0....9.ez..8!..| -00000070 2d 04 5a 8b 9c 8b 24 91 fe de ac 1f f5 4f aa 74 |-.Z...$......O.t| -00000080 71 e1 98 8b df 2f 16 03 03 02 69 fb 1f be be 41 |q..../....i....A| -00000090 51 00 c5 48 bc a3 18 78 2c dc e3 59 d2 0d 23 c7 |Q..H...x,..Y..#.| -000000a0 2b 03 f3 ce 08 81 62 8a e9 59 52 06 2a cd 7f fe |+.....b..YR.*...| -000000b0 f4 58 5a a4 6c d1 fa f2 1e 31 7e c5 14 39 dc 37 |.XZ.l....1~..9.7| -000000c0 27 4f 70 ef 79 7e b1 d1 32 1b 3c cf 08 e2 8a 44 |'Op.y~..2.<....D| -000000d0 56 48 ea 85 8b 86 1d 77 ea 75 f2 c6 8b 14 9d 57 |VH.....w.u.....W| -000000e0 17 87 29 64 e1 ef 1a 46 25 ed e1 d3 e6 90 63 8d |..)d...F%.....c.| -000000f0 30 b6 4d 3c 98 68 45 95 78 11 2c c5 4e 2c 2b 3a |0.M<.hE.x.,.N,+:| -00000100 a8 8b 02 1c b9 15 09 ea 59 30 c7 a8 d5 28 f3 45 |........Y0...(.E| -00000110 77 eb bc bc 4a d9 82 4a 7d 8b 5e e1 36 17 ba 95 |w...J..J}.^.6...| -00000120 34 ea 7e d7 b8 0d 8c 63 07 30 d9 07 49 df b0 ea |4.~....c.0..I...| -00000130 aa 5e 95 7f 90 ab 09 79 31 88 27 00 9e bd 84 5b |.^.....y1.'....[| -00000140 ab f6 be 18 10 42 11 49 bd ce 42 dc 2b ae 8f 00 |.....B.I..B.+...| -00000150 a1 74 5a d1 e3 0b ba 62 57 5f 0e 65 e4 13 ce 78 |.tZ....bW_.e...x| -00000160 b1 da 89 03 f6 42 cd 1b fe 03 0c f4 89 77 07 bd |.....B.......w..| -00000170 fa 07 5a 4a 86 1f 47 15 2a 18 ec 26 36 e9 c7 04 |..ZJ..G.*..&6...| -00000180 75 bb 66 e1 32 97 65 e2 e8 2c b1 bc 39 14 3a d6 |u.f.2.e..,..9.:.| -00000190 77 d0 15 32 e5 58 eb 49 52 15 c6 d6 9c 4e 2d 97 |w..2.X.IR....N-.| -000001a0 5c 59 5a 51 11 71 1e 3b 1e 25 b8 20 ef 16 d0 27 |\YZQ.q.;.%. ...'| -000001b0 f9 ad 01 61 96 8c 50 a2 60 86 99 8c b3 cf 04 07 |...a..P.`.......| -000001c0 de 8a b3 85 53 95 28 e7 6c db 26 42 b2 6c 51 3c |....S.(.l.&B.lQ<| -000001d0 b7 54 98 ff 78 48 b2 8e 11 b9 3b 59 b9 38 0b 48 |.T..xH....;Y.8.H| -000001e0 ac 11 b3 0c b2 f7 98 58 64 ce 16 ae 78 9f 39 ce |.......Xd...x.9.| -000001f0 20 2b c3 14 74 54 17 54 8e a1 b7 ed 48 77 37 a0 | +..tT.T....Hw7.| -00000200 12 18 77 b2 ab 51 d2 e3 fc 6a af b3 a2 4b 60 87 |..w..Q...j...K`.| -00000210 fb f9 0c e8 33 84 e1 6b 95 f0 af 04 c3 c7 b7 0d |....3..k........| -00000220 bd f2 a6 26 f4 b2 15 c0 9e 90 1b cf 66 3f f8 1e |...&........f?..| -00000230 64 bf 91 30 b9 2f 31 5b 76 99 67 50 6e b3 fa 00 |d..0./1[v.gPn...| -00000240 1f 1f 50 1d 52 ea f9 98 7d 59 3a 1d 10 b5 cf 00 |..P.R...}Y:.....| -00000250 49 a6 72 78 2c e8 2a b2 64 38 34 55 25 b1 4f f7 |I.rx,.*.d84U%.O.| -00000260 3d 5d 18 d8 63 c4 34 b9 78 15 19 c8 6c d8 03 e9 |=]..c.4.x...l...| -00000270 0b cb bd 0c b1 32 9c 32 57 ad 7f bd cd db 99 77 |.....2.2W......w| -00000280 7f 2a 01 60 c6 ce 99 a9 a0 17 ae 02 0c 72 67 b2 |.*.`.........rg.| -00000290 0e d3 24 c4 88 96 7f ab c2 46 fb fe 47 b0 72 a0 |..$......F..G.r.| -000002a0 87 6b 22 00 ee 97 ce 13 eb ab 5b 41 2e 60 79 a1 |.k".......[A.`y.| -000002b0 4b d1 8f d2 d0 5b 02 77 9c 29 1e ea 3e 30 a9 8f |K....[.w.)..>0..| -000002c0 07 b7 22 2a d7 64 50 cf 0a 34 6b db b8 8d e4 f6 |.."*.dP..4k.....| -000002d0 50 71 65 54 0f e0 87 93 ca 3e 1b 68 29 2f d9 dd |PqeT.....>.h)/..| -000002e0 15 76 f0 c3 1c a4 ca e9 5f 17 29 87 bb 0a 5b 74 |.v......_.)...[t| -000002f0 6c 2d 13 63 16 03 03 00 bc a6 81 fa a1 7b 6e 54 |l-.c.........{nT| -00000300 0b 47 30 a5 e9 ca e6 86 db f9 af 19 5e fe ae a6 |.G0.........^...| -00000310 91 c8 e9 c0 c5 17 b4 a6 2b cd 40 ee 9e fc 2d ef |........+.@...-.| -00000320 8c 68 6c ce 05 66 b1 80 7d 6f 07 91 6e 9f 23 ab |.hl..f..}o..n.#.| -00000330 f2 a7 d1 99 d1 5f ed 58 b1 aa 7f 31 f4 7f 2a ea |....._.X...1..*.| -00000340 3e 21 a0 4e 1c 49 d9 ab 1e 43 84 dc 42 cf f5 75 |>!.N.I...C..B..u| -00000350 ae fc 97 a3 e7 b8 51 1b 68 1b f5 83 2b 2d b0 a5 |......Q.h...+-..| -00000360 7c f9 f2 21 c1 68 d9 e2 4f bf f5 1e e6 90 7b 54 ||..!.h..O.....{T| -00000370 2c 45 d2 35 a1 5c da 57 be ce 90 a7 56 90 f2 55 |,E.5.\.W....V..U| -00000380 08 9e b1 52 09 12 b9 f1 8b fd fb 1a f2 9f 39 bf |...R..........9.| -00000390 73 c2 9c dc 6c 0f 19 9b 37 ec 91 86 27 ec 1a e8 |s...l...7...'...| -000003a0 92 f8 a2 05 71 12 e6 8b 04 0c f3 b4 4d 93 d4 b4 |....q.......M...| -000003b0 69 7b c3 9c 22 16 03 03 00 4a ba fe c0 02 30 02 |i{.."....J....0.| -000003c0 33 02 67 87 19 20 13 90 48 80 a1 93 97 cc a6 26 |3.g.. ..H......&| -000003d0 51 14 4d 2b 60 3d da 72 f0 99 51 2a 8b b4 54 ff |Q.M+`=.r..Q*..T.| -000003e0 47 6b 6c b4 6a 92 a9 9c 3c c0 ee ae 79 25 de 17 |Gkl.j...<...y%..| -000003f0 61 cf 06 37 6f 84 e8 b8 4c 7b 9a c1 a1 ff 6e c5 |a..7o...L{....n.| -00000400 f3 0b 7d 8d 16 03 03 00 14 a9 38 b9 f0 df 71 c5 |..}.......8...q.| -00000410 1f fa 77 04 1e b4 4c 2b 64 01 e6 59 cb |..w...L+d..Y.| +00000000 16 03 03 00 81 4b d8 09 ef 6a 5b a2 c2 e0 2c b3 |.....K...j[...,.| +00000010 fa e9 21 b3 64 c7 51 8d d4 14 14 ba 7b 2f f8 1a |..!.d.Q.....{/..| +00000020 e9 f8 7a 69 8b 0b b4 5f 26 c5 b6 2e dd c9 90 04 |..zi..._&.......| +00000030 7d af fd 56 f7 9a 0d 56 09 6c 74 48 49 74 90 71 |}..V...V.ltHIt.q| +00000040 e1 ee 66 4c 1a da 66 43 50 fa 94 2c 84 21 10 f0 |..fL..fCP..,.!..| +00000050 00 85 a7 c2 ea 73 19 52 b7 f2 2a e8 17 17 23 67 |.....s.R..*...#g| +00000060 b6 80 d6 3f e0 a1 ed 81 66 89 0a 0d 48 9f 7f dc |...?....f...H...| +00000070 79 c4 27 9b c0 b8 68 ef 2a 5b ab df 8f 82 d6 ff |y.'...h.*[......| +00000080 84 38 f8 a4 f2 98 16 03 03 02 69 1f c6 1c dc 85 |.8........i.....| +00000090 f1 66 8d 7f 7f aa 36 cd c6 d4 cc 38 c8 8d 98 75 |.f....6....8...u| +000000a0 92 d2 db b4 49 0c 09 cc af e6 5b 07 64 76 34 c8 |....I.....[.dv4.| +000000b0 41 49 85 5e b4 68 ac 35 04 72 00 70 33 f7 5f a7 |AI.^.h.5.r.p3._.| +000000c0 84 40 34 03 2f 89 25 06 a1 50 dc ea d7 c4 29 57 |.@4./.%..P....)W| +000000d0 f9 5b 57 63 14 02 1e 74 db 5d 02 cf c4 f1 89 f6 |.[Wc...t.]......| +000000e0 6a 77 ce 87 5c 3a 61 b8 7d 02 f0 0e 6e 85 2a 51 |jw..\:a.}...n.*Q| +000000f0 d8 ad 4a 9f 65 04 4c 00 d0 35 76 01 dc 03 cf ca |..J.e.L..5v.....| +00000100 6b 11 83 9e 70 33 82 f6 cb eb 4c da 44 76 89 ab |k...p3....L.Dv..| +00000110 d4 65 01 e6 08 7b 2a 3d 49 02 39 85 e8 ff 53 fd |.e...{*=I.9...S.| +00000120 d0 ce 2a f0 11 3c 02 8f bd b8 2f ea 81 a1 64 10 |..*..<..../...d.| +00000130 7b c2 8b 72 f3 32 7b 36 80 13 17 8b 83 dc ce 3a |{..r.2{6.......:| +00000140 29 44 06 66 c9 c3 83 cc 28 38 c5 02 7c 3d b6 30 |)D.f....(8..|=.0| +00000150 55 07 a0 08 bb b3 e1 1e a8 a5 74 60 51 be ee dd |U.........t`Q...| +00000160 aa 83 09 e9 f3 c7 a5 1e 20 fc 6d d5 82 af f5 b6 |........ .m.....| +00000170 5b 23 dd 81 ce 78 5a 3c 92 c3 96 e1 aa e5 ad 24 |[#...xZ<.......$| +00000180 da 89 41 44 8b 0b 42 df e5 28 11 8e 9a e0 06 51 |..AD..B..(.....Q| +00000190 80 93 15 31 ec 8c 3e 60 92 ab a5 ec 25 5c c5 10 |...1..>`....%\..| +000001a0 ac 0f 01 1b c4 36 d5 f0 52 c7 0b f7 9b 40 9b c0 |.....6..R....@..| +000001b0 18 ad 1c eb 49 ed 8e 27 b6 35 b4 20 e0 e6 df 04 |....I..'.5. ....| +000001c0 69 d6 b5 56 04 30 d4 3d b0 9f e6 21 66 e7 97 cb |i..V.0.=...!f...| +000001d0 2f bd b2 b2 c1 be 4b 4f 6e 88 60 a1 cb eb b4 86 |/.....KOn.`.....| +000001e0 92 07 da 3c fa 8b 1a de 1c e7 6b c0 53 70 e7 ee |...<......k.Sp..| +000001f0 2f 70 4f e0 2a a3 b4 dc af 64 4f 5a 44 f9 ff fc |/pO.*....dOZD...| +00000200 7f 2f 7e 22 13 47 ed f4 ec 0c fa 01 21 e3 c1 d6 |./~".G......!...| +00000210 c7 53 f4 de 6c 91 c5 85 bd 3c a7 f3 d6 e7 f3 31 |.S..l....<.....1| +00000220 13 59 b7 ee 0b f7 6a 88 76 94 ab 45 41 9e ab d7 |.Y....j.v..EA...| +00000230 71 59 7e 45 ed 4d a0 12 4a 81 6a 15 05 a9 21 94 |qY~E.M..J.j...!.| +00000240 40 f0 1d aa 7e b3 d4 6d a6 ff 46 94 e6 d0 16 46 |@...~..m..F....F| +00000250 60 ac c5 15 94 d5 f7 76 1e 8b 90 e6 17 ff 5c 21 |`......v......\!| +00000260 d0 f9 98 25 0f 98 8b 6c 0f 2c 2a 92 0a f0 90 3d |...%...l.,*....=| +00000270 ef 9a 40 67 21 83 f7 5c 95 24 97 f6 45 51 81 4c |..@g!..\.$..EQ.L| +00000280 4b e1 64 0a f5 dd 02 fd 8d 21 d1 ef f8 96 70 4b |K.d......!....pK| +00000290 58 aa 3c f9 b1 f1 e9 fd 31 ea fc 68 4b c9 fa 79 |X.<.....1..hK..y| +000002a0 6d 2e 54 d7 1c 9d 5d 62 fc 43 2f cb 6a 48 4d 2e |m.T...]b.C/.jHM.| +000002b0 07 71 7b f2 b3 e6 08 8b 13 ca f0 e9 c1 d2 cc 7a |.q{............z| +000002c0 9a 49 e9 7b aa e8 bb d2 cf 97 73 b8 9a 3f 8b 01 |.I.{......s..?..| +000002d0 b9 cf c6 81 fd 99 fc c9 43 08 35 2c a0 fb 38 32 |........C.5,..82| +000002e0 8b d8 5b d4 20 41 a0 57 e6 34 c1 d8 66 6e 16 e7 |..[. A.W.4..fn..| +000002f0 78 4f e8 58 16 03 03 00 bc d3 91 f3 88 2f ec 1c |xO.X........./..| +00000300 da 94 cb b0 69 70 a2 41 4c fd 40 0d a0 97 01 34 |....ip.AL.@....4| +00000310 35 83 e6 3f a8 b0 c9 26 8d f1 8a c1 f6 a6 ab a4 |5..?...&........| +00000320 63 65 5a 10 38 d2 87 a7 8d ae ca 9e c6 23 7e c6 |ceZ.8........#~.| +00000330 c8 45 37 e8 7c 4b 40 5a 5b 68 19 bb 36 83 81 41 |.E7.|K@Z[h..6..A| +00000340 b2 fe 7c 39 7e 9f 95 3a 45 2e 9f 96 35 26 81 73 |..|9~..:E...5&.s| +00000350 4d 0f c3 09 61 32 eb 64 4b 46 76 c1 0e ca cf 02 |M...a2.dKFv.....| +00000360 6a f3 75 f3 bf aa b0 f8 43 e3 6b d1 c4 27 3e fe |j.u.....C.k..'>.| +00000370 06 a2 49 e4 bb 56 c5 c0 5d 36 81 06 97 ed ff a2 |..I..V..]6......| +00000380 99 78 43 0a c5 20 df a3 ac b7 8f 61 a2 ff 48 66 |.xC.. .....a..Hf| +00000390 ea c1 b6 57 38 fc 36 7c dd 30 b5 ce 58 b1 18 82 |...W8.6|.0..X...| +000003a0 e5 2a 54 d8 4d da f1 fc 98 06 97 43 d5 dc d9 3e |.*T.M......C...>| +000003b0 d4 f8 a3 76 9c 16 03 03 00 4a 78 c0 f2 02 60 a4 |...v.....Jx...`.| +000003c0 8e 9a cd 31 30 e9 16 df ce 98 bb 95 50 a0 05 48 |...10.......P..H| +000003d0 6c c2 ce c5 e2 77 f2 4a d0 45 80 97 98 d4 38 d1 |l....w.J.E....8.| +000003e0 90 04 91 48 cb 52 40 d3 a4 cb 8d 68 dc 64 9c 07 |...H.R@....h.d..| +000003f0 cb 8c b9 3b f8 44 fe 47 69 67 fb 2d ab 44 db d0 |...;.D.Gig.-.D..| +00000400 58 55 83 81 16 03 03 00 14 51 82 e0 57 8e cb 4a |XU.......Q..W..J| +00000410 d4 59 6e 58 f7 6d 44 3f f5 83 64 52 51 |.YnX.mD?..dRQ| >>> Flow 9 (client to server) -00000000 16 03 03 02 69 fb 20 8a eb 44 f8 0a 95 61 0a 01 |....i. ..D...a..| -00000010 48 6c ef 59 52 6f 99 7d 6e ce 7e 00 5e 67 f4 cd |Hl.YRo.}n.~.^g..| -00000020 19 08 39 12 a0 43 44 59 0f 9c 21 34 06 fe 09 6f |..9..CDY..!4...o| -00000030 3d de 99 a3 f8 96 03 12 78 eb 76 a7 ee 09 b4 49 |=.......x.v....I| -00000040 50 42 48 09 f1 7b 54 aa e9 45 73 29 e8 41 47 9a |PBH..{T..Es).AG.| -00000050 d5 8c fa bc f8 54 96 23 30 cb 36 ac cd 75 a4 16 |.....T.#0.6..u..| -00000060 ee 88 cc 74 25 5d 2e e2 88 d9 9d dc 87 bd 77 8b |...t%]........w.| -00000070 ac 98 20 34 cb c7 1c 71 44 b1 3c a6 42 11 bd 20 |.. 4...qD.<.B.. | -00000080 65 74 c3 36 c9 e3 6d ae 7e 37 9a b7 33 d8 6c 11 |et.6..m.~7..3.l.| -00000090 93 49 a4 e8 14 11 27 72 9c c8 44 75 21 5d 82 1e |.I....'r..Du!]..| -000000a0 71 ca 7d 46 95 5f 2e c4 80 be 90 2f 5a 13 92 28 |q.}F._...../Z..(| -000000b0 dc 54 5b e6 a0 9c c7 f8 bd 97 bd e5 6c 05 d2 68 |.T[.........l..h| -000000c0 c3 f3 54 1c 9e bc a3 20 c1 de f1 e7 3a 7e 5a fd |..T.... ....:~Z.| -000000d0 4f 22 f7 d4 e7 19 fb 94 6f fd bd 15 39 bf 9e 4b |O"......o...9..K| -000000e0 63 35 19 0b 59 28 47 f3 56 ae 4c 13 50 30 b5 d1 |c5..Y(G.V.L.P0..| -000000f0 d1 a9 a2 32 dc 23 5e 47 e9 dd 8c d5 32 12 d9 0d |...2.#^G....2...| -00000100 78 04 bc ae f9 81 5c e3 05 88 c9 89 72 c6 7d 86 |x.....\.....r.}.| -00000110 c6 55 aa 39 cd 9e 9e 5e ce 00 ce 51 fa 54 ee ba |.U.9...^...Q.T..| -00000120 64 a6 9c a8 88 00 a8 ed 6a 7a 63 cc d8 60 a4 52 |d.......jzc..`.R| -00000130 a9 2f 23 c5 ca 96 12 d5 ec 11 46 84 1f d3 43 74 |./#.......F...Ct| -00000140 db 87 13 42 18 71 b9 ff 18 d4 3b b5 c5 87 c8 c0 |...B.q....;.....| -00000150 91 fb 8c 7e c8 39 77 0e e0 52 bb 58 18 fa d8 5a |...~.9w..R.X...Z| -00000160 e0 e5 ab 4b 08 36 be 1d 6a ae a3 44 af 54 90 2f |...K.6..j..D.T./| -00000170 4f fb bc a5 d4 be c2 74 4e a1 22 61 10 09 5e 35 |O......tN."a..^5| -00000180 1c ab 1c 73 de 20 37 38 d0 5f 6c 24 f8 8d 79 22 |...s. 78._l$..y"| -00000190 0a b0 53 86 04 1e 73 36 57 dc c0 fb 98 15 ea 5e |..S...s6W......^| -000001a0 85 1d 8f 7f 7a 59 27 8d ce 5d df 29 c8 4d 10 d2 |....zY'..].).M..| -000001b0 87 79 9b 60 ff 17 a1 24 41 0d 12 99 dc ad ad 76 |.y.`...$A......v| -000001c0 00 74 a3 5a 73 9e 0c f4 90 0e bb 5a 11 5a 89 c7 |.t.Zs......Z.Z..| -000001d0 71 79 1a 72 f9 6f 19 6d eb 29 32 39 4d da 69 e4 |qy.r.o.m.)29M.i.| -000001e0 e9 f8 3a b0 b8 10 76 c0 21 3b 95 76 ec 01 7d f2 |..:...v.!;.v..}.| -000001f0 10 15 5f 1d 94 b1 13 e8 ca c4 07 c4 aa d1 50 65 |.._...........Pe| -00000200 5b 1f e9 ec 50 52 f6 33 38 e7 16 e4 e5 78 29 a1 |[...PR.38....x).| -00000210 41 6c 4f dc 07 bb 28 59 7f 1d cb 61 4d 2d 1e 43 |AlO...(Y...aM-.C| -00000220 b5 d5 8f b8 84 ec 4d 1c c7 5c 62 b7 21 71 83 74 |......M..\b.!q.t| -00000230 58 3b 70 92 c8 c8 af 7d f6 da 75 9d 30 99 cf 33 |X;p....}..u.0..3| -00000240 4e f0 8f 5e 44 1b 0d 35 83 80 b9 8c 80 23 a6 29 |N..^D..5.....#.)| -00000250 34 0c 88 8f 55 da 85 f8 92 89 4c 34 6a 73 98 bd |4...U.....L4js..| -00000260 86 70 11 7e a3 b7 04 0a 24 07 34 6c 06 64 16 03 |.p.~....$.4l.d..| -00000270 03 00 35 08 d2 96 51 e2 6f 68 ae 19 04 9c 59 e4 |..5...Q.oh....Y.| -00000280 09 72 da 6a 8e ee 4f 87 b3 b3 1e 89 0b a5 45 32 |.r.j..O.......E2| -00000290 98 a4 f3 af 64 d7 71 37 2a a5 d4 53 5a 0a 03 05 |....d.q7*..SZ...| -000002a0 d6 33 c2 ff 5f 2d 6d 94 16 03 03 00 98 49 3c 15 |.3.._-m......I<.| -000002b0 0a e5 ac 39 54 97 f5 2a dd 05 02 87 16 1c 6c ae |...9T..*......l.| -000002c0 4e 62 1e 27 81 54 66 13 9a d1 1d d2 2c 5b 17 20 |Nb.'.Tf.....,[. | -000002d0 a4 69 b5 69 ec 3a 59 bd 8b d2 5d f3 84 c7 65 a2 |.i.i.:Y...]...e.| -000002e0 ad 02 57 bf 3f 72 c5 ce 61 24 09 7e e4 f4 2a a6 |..W.?r..a$.~..*.| -000002f0 81 29 d0 9c 0f c5 d5 67 7a b0 e4 42 2f a5 5f 00 |.).....gz..B/._.| -00000300 42 ea ef 8b c8 55 c6 c4 27 26 e5 f7 57 2e 35 f8 |B....U..'&..W.5.| -00000310 e2 cc 41 6a 29 e2 66 b3 44 fe 2b f9 de 7d 32 96 |..Aj).f.D.+..}2.| -00000320 96 e6 cf 57 2c b8 73 bc e2 c2 89 20 8a 71 d3 03 |...W,.s.... .q..| -00000330 02 7e 95 ef 94 f6 68 b5 94 4b b4 ec a4 e0 10 42 |.~....h..K.....B| -00000340 c4 9e f2 28 dd 14 03 03 00 11 96 52 4d c7 17 35 |...(.......RM..5| -00000350 cf 9a 66 5f 73 c3 f5 40 60 12 11 16 03 03 00 20 |..f_s..@`...... | -00000360 67 eb 03 bf 5c 0f b8 d5 7d e4 14 0a 81 32 50 2a |g...\...}....2P*| -00000370 6b 02 53 f6 37 00 ef ef 8a 5f ee 3a bf 5b 84 b9 |k.S.7...._.:.[..| +00000000 16 03 03 02 69 96 85 13 d5 b1 07 ec bb 1c c1 be |....i...........| +00000010 a3 42 10 c8 e0 ec f8 f1 67 29 d5 52 ef bb 32 e8 |.B......g).R..2.| +00000020 7b e5 a7 3f ab 71 2d 74 20 f7 8a a7 1f bf 7c 4b |{..?.q-t .....|K| +00000030 8b 95 db 07 3c ad 86 5e b3 98 32 e9 5a ce 96 08 |....<..^..2.Z...| +00000040 c5 64 44 27 fb bc 44 29 49 44 32 3f 64 e8 86 1b |.dD'..D)ID2?d...| +00000050 54 63 74 3d a1 99 4d 4a 3e 5a 76 71 39 81 de df |Tct=..MJ>Zvq9...| +00000060 90 e4 f6 ac 96 15 0b 70 ad 7e 8a 1d 69 86 65 6e |.......p.~..i.en| +00000070 63 bf fb f2 6f 21 d5 66 ad f1 b1 09 05 04 f9 09 |c...o!.f........| +00000080 0e 0c 12 74 c1 cd f1 5e fa f1 1b cd 3b 2b 13 8f |...t...^....;+..| +00000090 fb f6 fd b0 ca ea 73 1b 38 ad db 6b fd 29 34 db |......s.8..k.)4.| +000000a0 51 4a 44 97 a7 2f 2a 98 d6 cc d5 c4 b9 17 23 ab |QJD../*.......#.| +000000b0 09 27 15 a5 35 3b 2b 7e b2 3b fd 12 1b 11 90 4d |.'..5;+~.;.....M| +000000c0 81 1b 84 bb fd 72 09 31 5e 78 0e f6 b6 60 44 bb |.....r.1^x...`D.| +000000d0 6c 06 72 0b ba ba 60 f6 c1 cb 7e 45 a9 25 44 3d |l.r...`...~E.%D=| +000000e0 ba da 71 99 bb 79 b3 73 ef eb c2 cc 07 87 76 f5 |..q..y.s......v.| +000000f0 e9 7c d9 47 8c fc 7d b7 a0 70 72 04 1e 3d 9b 2f |.|.G..}..pr..=./| +00000100 85 9f c8 2f d9 20 4e 00 97 d6 dd dc ae a1 04 96 |.../. N.........| +00000110 83 e1 4f f3 0d ad 9c ce 5f e7 7b 88 7a b7 d2 ce |..O....._.{.z...| +00000120 0a 61 95 d2 78 e3 45 a8 10 5e d9 ae d2 e1 22 bf |.a..x.E..^....".| +00000130 59 9c 4a 2c 28 fb c1 b6 89 3b 65 8c 94 a9 f0 7c |Y.J,(....;e....|| +00000140 86 98 8f 22 c4 18 47 e4 f0 b9 42 dd 34 ab 2a 8e |..."..G...B.4.*.| +00000150 fc 8f ce 09 ec 6f 57 6b d1 ab 32 fd 84 e2 9f 7e |.....oWk..2....~| +00000160 f5 b7 5d 26 aa 37 da e9 f3 18 6f 56 74 03 ff 1e |..]&.7....oVt...| +00000170 87 95 fb 93 57 2e 32 fb b3 cf d2 0d 42 02 4f 6a |....W.2.....B.Oj| +00000180 9e de ee 6a e6 7e e5 d2 ba cb 00 5d ff b4 6d 7f |...j.~.....]..m.| +00000190 23 5e 93 be e9 3a c1 b4 78 30 53 90 07 e4 a7 af |#^...:..x0S.....| +000001a0 da e1 29 7d 50 a5 76 ec a8 5e 96 50 45 26 c4 9d |..)}P.v..^.PE&..| +000001b0 c1 99 98 c6 1a bf 93 c1 63 b3 0a 2d af c8 29 7d |........c..-..)}| +000001c0 ef b2 d3 8f aa 93 fb be 39 c0 a1 65 51 e8 6e c4 |........9..eQ.n.| +000001d0 45 cb 2a 52 b7 ec e0 48 c0 b2 cc c7 72 12 18 e0 |E.*R...H....r...| +000001e0 c7 9f fa 09 97 95 16 9f f4 5d 70 c5 d6 7f 23 d5 |.........]p...#.| +000001f0 53 98 d0 80 50 9b 52 46 11 d4 97 ea 47 26 f5 6f |S...P.RF....G&.o| +00000200 66 7b 8a cc f8 8d 70 c7 ec fa 72 de ba ac d4 b2 |f{....p...r.....| +00000210 be 7d d8 78 44 dd de 66 53 26 f4 c0 8a 67 61 cb |.}.xD..fS&...ga.| +00000220 46 34 3d 6f 9e 9b dc ee 4a b9 5c 67 2b d9 87 2a |F4=o....J.\g+..*| +00000230 35 42 1c 3e b8 08 c9 32 13 a6 6f fc 4d cc be dd |5B.>...2..o.M...| +00000240 ad 76 19 1c 2d b3 6e 04 a1 17 05 93 b9 69 27 42 |.v..-.n......i'B| +00000250 23 13 7b c0 f1 53 9c b5 1d 8e 5c f6 40 7e 5a e9 |#.{..S....\.@~Z.| +00000260 20 dd 18 7a 0c f2 7b 5a ec 3d 4e 3b 29 b2 16 03 | ..z..{Z.=N;)...| +00000270 03 00 35 15 15 54 38 4e 87 f1 c1 9a 90 b2 74 df |..5..T8N......t.| +00000280 72 34 aa 0b 41 f3 df b4 c5 fd 50 00 2a 36 a8 d5 |r4..A.....P.*6..| +00000290 c4 49 ac b8 58 3e 89 48 cb a9 4e b1 a9 0f ee 51 |.I..X>.H..N....Q| +000002a0 37 d3 60 ca 23 76 68 0b 16 03 03 00 98 53 3c 0e |7.`.#vh......S<.| +000002b0 d5 3b d3 78 9f 47 5d 9e 1b b6 04 5f d4 04 66 55 |.;.x.G]...._..fU| +000002c0 68 bd d7 ab 54 b7 e5 9a 12 9b 0c 1d 75 7b c7 35 |h...T.......u{.5| +000002d0 e3 9e 9d a0 8f 61 7a 32 d1 a7 23 2a b6 ba 48 7c |.....az2..#*..H|| +000002e0 1a 62 66 61 b4 3d e8 e3 a9 4e 85 7a 8d 5b f3 69 |.bfa.=...N.z.[.i| +000002f0 c8 bc 0a 8a c7 e4 df 78 9b a8 cf 1d 37 14 90 a5 |.......x....7...| +00000300 a8 ce f7 1f e7 a3 e5 d8 97 be 95 fd d3 c0 d0 81 |................| +00000310 bf a6 e1 b3 6b 29 ee c6 16 3c 4c 68 6e b4 42 72 |....k)...>> Flow 10 (server to client) -00000000 14 03 03 00 11 ab e7 45 c8 02 30 54 0f 5a ea 63 |.......E..0T.Z.c| -00000010 42 ea 39 9b 46 ba 16 03 03 00 20 60 56 50 ad d0 |B.9.F..... `VP..| -00000020 fe 7d 56 a2 e1 d9 87 76 96 3b b3 27 3b 7f be e4 |.}V....v.;.';...| -00000030 98 d0 7a 6a a2 e3 37 1c f5 a9 a1 17 03 03 00 19 |..zj..7.........| -00000040 67 ee fd 6d 58 de bd b8 df aa 4d 36 e4 93 83 7b |g..mX.....M6...{| -00000050 e5 bd d1 ba 5c f3 2f aa a8 16 03 03 00 14 73 29 |....\./.......s)| -00000060 15 c9 16 62 a2 97 81 f8 44 94 86 c1 94 37 9f 19 |...b....D....7..| -00000070 1d c2 |..| +00000000 14 03 03 00 11 1b a8 a8 a9 c6 a8 85 60 bc 14 0d |............`...| +00000010 86 ce a5 0f 45 17 16 03 03 00 20 cb 3a 73 db 55 |....E..... .:s.U| +00000020 05 7e 3e 4b 6d d0 eb ca 68 39 bf 71 ba 6c e5 0c |.~>Km...h9.q.l..| +00000030 a7 90 d6 c1 b8 55 87 c6 20 40 35 17 03 03 00 19 |.....U.. @5.....| +00000040 28 50 71 7c f0 7c 1e 61 fb de 5d d1 bb 77 f6 c8 |(Pq|.|.a..]..w..| +00000050 a4 76 8d ab d4 c2 fe 27 96 16 03 03 00 14 e4 7e |.v.....'.......~| +00000060 51 bb 26 a8 9c 0c b0 25 7a 57 b9 98 c2 20 5a 50 |Q.&....%zW... ZP| +00000070 07 ca |..| >>> Flow 11 (client to server) -00000000 16 03 03 01 16 bb 29 a6 76 e4 5a ec 09 4e a7 6a |......).v.Z..N.j| -00000010 66 d7 6e 39 fc 5a dd be 9f 34 1e cb 3a b3 3f 1e |f.n9.Z...4..:.?.| -00000020 48 ad 0b e0 0e 43 b1 3e 57 f3 4a d1 c7 c6 1a f0 |H....C.>W.J.....| -00000030 a8 3e d1 37 de 95 ad 0f 92 85 ee b2 2b 1c 30 2f |.>.7........+.0/| -00000040 f5 70 ca 42 28 0c c2 e4 06 73 d5 eb 31 d2 86 f7 |.p.B(....s..1...| -00000050 d6 42 5d e0 b0 a6 c0 94 2c 52 0b 18 2c 95 9c 2a |.B].....,R..,..*| -00000060 56 4d a4 17 fb 51 49 be 3a 37 27 87 c7 d5 94 56 |VM...QI.:7'....V| -00000070 88 c5 94 a6 ff a1 dd cf 2b 70 e1 6c a9 39 1b e7 |........+p.l.9..| -00000080 69 c3 0e ef 08 d2 fb 6d 54 8a 80 64 99 6a b3 e4 |i......mT..d.j..| -00000090 2e 44 62 ce 1c 4d 7a 0a 45 cd ba 52 23 47 6d 05 |.Db..Mz.E..R#Gm.| -000000a0 97 03 c6 c4 c7 5a ca bf 38 73 b4 8c e5 a5 14 1b |.....Z..8s......| -000000b0 10 ea 29 17 af f6 37 bd 7f 56 88 b2 63 92 9f b9 |..)...7..V..c...| -000000c0 6c 18 9b 1b ad ce ac f0 97 45 3e 72 e0 10 8e 64 |l........E>r...d| -000000d0 80 dc cd a1 f9 10 d1 cd 46 2a 98 cd 40 94 5b dc |........F*..@.[.| -000000e0 f5 07 05 96 f3 74 db 91 3c 45 f1 6e b7 f9 52 e8 |.....t..n.| +000000d0 1d 3e 93 c6 23 f4 eb bf ad 62 21 1a da 53 e1 13 |.>..#....b!..S..| +000000e0 0a 3a 9c 57 48 d5 ee d3 72 af c3 74 fc 74 67 7d |.:.WH...r..t.tg}| +000000f0 b4 76 fc 21 55 67 49 92 fc 71 5d 42 69 d6 01 b5 |.v.!UgI..q]Bi...| +00000100 83 4e b8 cd f9 ed 28 41 ae 95 2f d6 69 b0 d3 b8 |.N....(A../.i...| +00000110 bd 06 d6 00 74 44 c9 47 aa 8e 1d |....tD.G...| >>> Flow 12 (server to client) -00000000 16 03 03 00 81 47 d2 a4 b9 04 d0 39 aa 1f d3 7a |.....G.....9...z| -00000010 f2 c3 a5 03 8a 35 6c 6b bf 18 02 62 d3 ab 8a 0f |.....5lk...b....| -00000020 99 69 f3 84 45 7a 09 28 09 68 3a 67 8a ee 94 b1 |.i..Ez.(.h:g....| -00000030 d3 2a e6 37 b7 f1 88 df c0 18 42 96 78 4e cf 3b |.*.7......B.xN.;| -00000040 e9 35 50 af ee 96 52 e9 1c 58 47 79 87 97 ce d9 |.5P...R..XGy....| -00000050 71 9b 4a 47 bc 60 8f 95 ea 75 4e c8 3e ca 79 0f |q.JG.`...uN.>.y.| -00000060 22 b2 37 19 12 d6 08 4d 01 93 d9 86 ed 4c 9e 42 |".7....M.....L.B| -00000070 fb 9b 37 26 98 33 74 cf 84 f4 e1 23 81 6f b6 b2 |..7&.3t....#.o..| -00000080 a9 27 e7 88 50 77 16 03 03 02 69 6b 78 db e3 0e |.'..Pw....ikx...| -00000090 cc 07 a4 96 1f 75 13 6d fe cd 3d 36 8c b0 44 e9 |.....u.m..=6..D.| -000000a0 4a 3a 41 26 c9 8c 2f 25 28 9d a8 7b dd df 28 6a |J:A&../%(..{..(j| -000000b0 fc ef 87 d4 06 dd 4e 05 ff 40 e3 6c 49 94 ad 1c |......N..@.lI...| -000000c0 c2 30 cc 41 35 39 a2 70 95 db de a7 c0 aa 05 c0 |.0.A59.p........| -000000d0 a2 a7 18 8e ba 70 ee 4b 0d 8d de 98 c7 8a 58 9c |.....p.K......X.| -000000e0 8b 51 f7 8f bb 7c 8f f7 60 53 9e 11 7e 5c e6 25 |.Q...|..`S..~\.%| -000000f0 be 22 aa 0a 3d 35 1c ac 2b 7d 98 fc 01 3a a9 9d |."..=5..+}...:..| -00000100 bf b5 d1 ae 10 52 ae 17 f6 df fc 24 38 0b f2 64 |.....R.....$8..d| -00000110 a8 9a 5c ff cb 42 bd 9d af 41 4d 6b 22 67 94 ac |..\..B...AMk"g..| -00000120 6b 95 2e 43 41 5d 5e c9 67 29 5f f8 8e 13 9d 18 |k..CA]^.g)_.....| -00000130 3c d4 ff 20 66 ff a6 d1 84 1a 33 31 27 5d 28 b5 |<.. f.....31'](.| -00000140 24 57 43 c1 83 6a e7 8c 35 0c a7 6f 5e 78 e8 84 |$WC..j..5..o^x..| -00000150 7c ee 9a 94 dc fd f7 a4 10 3d bb 66 0a 17 14 e7 ||........=.f....| -00000160 d7 29 47 f7 70 76 d6 ec b2 3c e2 a0 22 e6 c5 c3 |.)G.pv...<.."...| -00000170 bf a6 94 72 8b 70 eb 2b b8 4f c9 7d 72 22 75 ce |...r.p.+.O.}r"u.| -00000180 b9 c2 34 08 ac 87 d3 a8 35 81 f7 5e 20 02 0c e8 |..4.....5..^ ...| -00000190 0a 47 4e 37 4a 03 6d b1 c5 8f 29 77 80 c7 6c 5c |.GN7J.m...)w..l\| -000001a0 c3 3e 6f 3d 02 ee 5e f2 fb 20 a2 ad c1 5b 2c 02 |.>o=..^.. ...[,.| -000001b0 ef dd 81 e7 ea af f0 01 4f 0b eb f8 a1 82 3d ee |........O.....=.| -000001c0 be b5 09 df f2 34 49 f0 e8 f3 bc 7e e7 6a 14 0d |.....4I....~.j..| -000001d0 e4 aa e5 38 8a 2c 15 01 52 48 83 46 50 13 2b 71 |...8.,..RH.FP.+q| -000001e0 f4 48 1a 3d 3f 14 dc 3c ba fc a8 68 57 44 5d f1 |.H.=?..<...hWD].| -000001f0 f4 7f 23 8d ca f1 75 99 8c 36 99 38 b9 06 85 d0 |..#...u..6.8....| -00000200 a6 76 8b ae 7e 2a 26 cb cc 9e 8c 7c 98 e6 00 86 |.v..~*&....|....| -00000210 a9 d4 cb 42 8c 04 dc 6b 37 1e 8b e2 98 90 0f b3 |...B...k7.......| -00000220 c0 ea 07 1c 92 45 39 65 12 90 41 23 93 55 59 13 |.....E9e..A#.UY.| -00000230 22 e1 68 05 cc 5d ef a2 40 85 fb 61 d5 53 cb 77 |".h..]..@..a.S.w| -00000240 63 7b 16 bf c6 17 57 fb 58 1e d2 86 1a 4a 79 a2 |c{....W.X....Jy.| -00000250 1f da 2c 64 65 1c 7c 13 21 1b 33 22 36 0e 03 41 |..,de.|.!.3"6..A| -00000260 8e 6a 78 98 ae 29 71 3e 5c be 5f 83 55 f4 80 2d |.jx..)q>\._.U..-| -00000270 b8 2a b8 84 bd 97 7c 60 03 ae 67 77 44 47 70 c2 |.*....|`..gwDGp.| -00000280 09 0d 1b ed a8 17 8e 84 97 1a b4 75 c2 48 86 bd |...........u.H..| -00000290 b1 3c 1f 7c 1a 5b 60 10 a0 66 aa 8e f7 ba 9b e8 |.<.|.[`..f......| -000002a0 35 6c 46 f0 67 3f f1 8b 5f a0 be 31 2e 45 22 80 |5lF.g?.._..1.E".| -000002b0 ba d1 ff 88 f0 c8 bd 31 84 64 6a 07 02 75 bd 99 |.......1.dj..u..| -000002c0 f1 aa 3c 9d 0e b8 f4 76 b3 24 4f 68 f0 83 b1 da |..<....v.$Oh....| -000002d0 eb 70 1e 27 f4 17 90 a4 bc e5 1f d8 8b ee a1 e4 |.p.'............| -000002e0 1e c5 f4 a2 5b c3 0c 6d 2e c8 0e 67 89 4b d9 fe |....[..m...g.K..| -000002f0 9b a0 15 97 16 03 03 00 bc 2c e6 a2 fe 1b d7 1e |.........,......| -00000300 38 85 ef 39 d1 d6 df ae c4 7f af b2 ff c2 92 0b |8..9............| -00000310 37 e3 5c a9 6c 2c 9e f7 0e a3 88 ee 09 14 6b eb |7.\.l,........k.| -00000320 46 81 74 4a a7 f8 39 82 7d a0 16 69 e4 17 52 f0 |F.tJ..9.}..i..R.| -00000330 16 5f f7 2a a1 a0 a2 bb 41 4c 0c f9 9c e3 af 5e |._.*....AL.....^| -00000340 bd 43 47 2d 6d 4a 88 60 95 52 29 94 3d ec 75 d4 |.CG-mJ.`.R).=.u.| -00000350 dc f5 01 4a 57 fd 7b 96 13 75 5b ed a8 9d 29 5f |...JW.{..u[...)_| -00000360 5f 28 dc 04 3a 91 0f 6b d6 7d 32 fe 75 cd 61 49 |_(..:..k.}2.u.aI| -00000370 1b 6d b3 c6 41 87 6b 2d 09 e1 3d 8e f5 fb 9b b7 |.m..A.k-..=.....| -00000380 04 9a 01 ab 82 e5 2b 17 4f 93 d7 ef 31 79 10 b0 |......+.O...1y..| -00000390 1c cb 17 5b 8a 7a e9 22 ea 83 68 93 68 f6 85 34 |...[.z."..h.h..4| -000003a0 d1 4d 75 5a b3 69 46 42 92 04 09 47 b1 8e 67 ad |.MuZ.iFB...G..g.| -000003b0 47 4e 2c 02 48 16 03 03 00 14 b0 40 bb eb e1 a6 |GN,.H......@....| -000003c0 94 fd d0 8a e1 91 a7 c9 d2 4b f8 95 95 c7 |.........K....| +00000000 16 03 03 00 81 d3 99 6f 14 2b a1 f4 d7 45 c9 94 |.......o.+...E..| +00000010 69 0b b3 72 f4 2c 2e 5c 80 96 09 20 2f 63 a1 e4 |i..r.,.\... /c..| +00000020 8b df d7 22 11 71 bd 17 db da 2d c6 78 e8 9a 95 |...".q....-.x...| +00000030 6b 39 34 a2 13 7f 39 77 8b e5 1b 6c 4b 20 79 40 |k94...9w...lK y@| +00000040 a1 d9 69 89 b1 e2 60 8a 75 88 ae 83 b9 4f 42 a4 |..i...`.u....OB.| +00000050 c9 c7 44 ac 0d 3f 1c ca 49 f9 a7 05 e2 c7 05 cd |..D..?..I.......| +00000060 30 30 d2 f9 c2 87 60 33 3b 25 d0 e0 5e c2 bd 98 |00....`3;%..^...| +00000070 9c 51 d8 38 c9 ef 04 f4 39 30 50 b6 35 53 f6 95 |.Q.8....90P.5S..| +00000080 eb 5d 67 05 62 9a 16 03 03 02 69 39 94 a1 8d 01 |.]g.b.....i9....| +00000090 37 64 c6 be bb 9c 22 9d 56 e8 68 ab 0f 7a 3a e7 |7d....".V.h..z:.| +000000a0 2d 26 b7 ba 3e 54 38 b3 32 9d 7b d7 43 c4 d2 b3 |-&..>T8.2.{.C...| +000000b0 9a 84 62 73 03 7a f2 68 ec 3e 41 d2 68 c9 22 1a |..bs.z.h.>A.h.".| +000000c0 e9 4d 9c e8 80 6a a9 9e 6a bd 67 5d 77 97 8b f7 |.M...j..j.g]w...| +000000d0 32 cb 3a cb c2 c0 a1 40 7e 63 81 5f 19 a5 71 20 |2.:....@~c._..q | +000000e0 c3 76 88 ae 5c d4 bd 54 08 e7 7e e7 77 7e 3d 91 |.v..\..T..~.w~=.| +000000f0 b5 40 f7 7e 95 d5 e3 f2 e5 4a 57 f6 d9 94 df 07 |.@.~.....JW.....| +00000100 56 45 09 c4 bc 65 05 04 57 f4 00 c5 91 4c dc 4d |VE...e..W....L.M| +00000110 a0 1e c6 e2 37 35 d0 5a e9 79 ce f5 91 6d 3e 39 |....75.Z.y...m>9| +00000120 c3 68 6a 76 6d f3 29 1d e0 ef b2 20 3e 2a ac 11 |.hjvm.).... >*..| +00000130 7e 11 2d a3 84 60 94 b5 8e 3a e6 4b 34 70 aa f8 |~.-..`...:.K4p..| +00000140 e3 f9 0f 2c a4 bf 5b 27 7e c9 5e 6f c0 11 b4 ff |...,..['~.^o....| +00000150 53 6b 98 ee 20 77 87 87 fc 8e 30 1b 8f 74 29 af |Sk.. w....0..t).| +00000160 a2 c7 e8 c1 da e5 d7 0f 70 ec 27 23 46 3f 16 b1 |........p.'#F?..| +00000170 59 bd 43 76 09 1d 8c f4 eb 17 10 a5 c1 1a e0 c6 |Y.Cv............| +00000180 45 e2 d2 dc 6d f4 9a 87 36 ef 71 18 5c 1d e7 7c |E...m...6.q.\..|| +00000190 40 d6 4c 16 ee 58 75 d7 56 9f 2e 17 80 1d 74 1c |@.L..Xu.V.....t.| +000001a0 fd 86 7c 2b 05 ac ef 07 18 a3 98 73 fa 9c 16 6c |..|+.......s...l| +000001b0 14 95 37 91 1e a2 c7 47 a8 87 11 35 30 d8 ed 60 |..7....G...50..`| +000001c0 ba 65 ee 66 2b 1f db 67 c2 d0 71 26 3d ae 17 94 |.e.f+..g..q&=...| +000001d0 f0 f6 65 01 bb 1d 85 7e b3 d8 2c f1 96 c5 d5 e0 |..e....~..,.....| +000001e0 97 a4 3e df 97 ff 8f 4b e3 72 49 c4 5b 87 4e 06 |..>....K.rI.[.N.| +000001f0 93 11 75 04 7b 80 9d 1c a7 85 a3 2c f1 16 8a b9 |..u.{......,....| +00000200 78 6b 27 1e 9a e3 86 eb f9 42 95 10 02 d5 b6 01 |xk'......B......| +00000210 b3 94 04 63 49 50 9e 11 71 07 aa a1 d6 9d d1 db |...cIP..q.......| +00000220 f4 ea 2e bb fa ca 1e 00 53 75 70 de 0a 72 eb 55 |........Sup..r.U| +00000230 ab b7 ff 30 ad 5e 7e 13 90 75 42 5d 07 07 21 0f |...0.^~..uB]..!.| +00000240 db a6 f4 61 9c bf 31 34 e4 98 bb c4 ac 41 2d 76 |...a..14.....A-v| +00000250 fb 6c 30 b0 e2 98 5f ed d9 a8 42 d7 75 a1 bc 36 |.l0..._...B.u..6| +00000260 f2 3e c5 ac 50 ae c7 2e 42 35 6c 1a 47 aa 1f 0a |.>..P...B5l.G...| +00000270 2f ff 6e 0a a5 c4 b5 a5 92 3f 54 d0 4e 62 6e 3e |/.n......?T.Nbn>| +00000280 cb 07 2d 4d 1a fb 94 5b f8 d0 5b 26 34 2b 1b 26 |..-M...[..[&4+.&| +00000290 8c dd 91 a7 66 21 89 d0 11 24 a5 5f 99 ae 62 84 |....f!...$._..b.| +000002a0 34 9c d2 45 71 74 8c 68 db 8b ad 6f df 08 35 38 |4..Eqt.h...o..58| +000002b0 ed 5c 3b 3e 55 a1 c3 16 b6 61 f4 4d 6d d0 2a 5d |.\;>U....a.Mm.*]| +000002c0 10 fb 64 c9 6f 87 6f 3d ff d1 a0 97 64 b4 12 f9 |..d.o.o=....d...| +000002d0 2a a8 46 59 1b e4 6b d8 c9 3e ac 14 00 4f 1a e6 |*.FY..k..>...O..| +000002e0 26 9b 86 32 a3 9b 37 eb c1 cf 9a 70 16 2e 4a b0 |&..2..7....p..J.| +000002f0 6e e5 fc c2 16 03 03 00 bc bf c4 ea e0 dc be fe |n...............| +00000300 33 7f ef 2b d9 50 f7 87 d5 30 2b 09 bb 63 1e 4c |3..+.P...0+..c.L| +00000310 9c 3c a9 10 4e 04 e1 85 29 44 f9 ea 32 61 12 6e |.<..N...)D..2a.n| +00000320 63 0f d9 e7 e9 c8 81 a0 eb 4e fe 90 bf f4 f4 af |c........N......| +00000330 22 66 21 86 dc 2c f6 ed b1 be eb b1 ac 14 f5 ce |"f!..,..........| +00000340 6c b9 a8 45 e4 3f 09 d1 b1 f3 69 f7 df c4 f0 6c |l..E.?....i....l| +00000350 48 f6 15 80 8a b8 b0 39 0e e9 22 9a 5c 72 f9 fa |H......9..".\r..| +00000360 95 01 9d ca e4 68 ef 72 e2 34 28 a5 04 5d d2 30 |.....h.r.4(..].0| +00000370 c6 33 80 a8 f1 8f fb 6c ec 15 c3 7c 68 7c a2 2e |.3.....l...|h|..| +00000380 4d ba 64 af fb f5 b8 f7 6b 6b 8c 5c 56 dc dd 69 |M.d.....kk.\V..i| +00000390 39 d8 73 75 e3 be 17 09 3f 80 ed cc 12 5b ca d9 |9.su....?....[..| +000003a0 e6 e2 50 88 41 0b 39 8e 84 6f fb 6a c3 8e 4f fc |..P.A.9..o.j..O.| +000003b0 dc 18 ca 02 18 16 03 03 00 14 5e ac 52 4d 0b 89 |..........^.RM..| +000003c0 33 7d fe 1c d9 b5 1d 1c 2b 6d d4 4f 12 33 |3}......+m.O.3| >>> Flow 13 (client to server) -00000000 16 03 03 00 35 25 1e 49 ad bf 9c 37 e2 d0 2b aa |....5%.I...7..+.| -00000010 44 91 d5 61 e7 a5 16 b2 cb 93 43 d7 a0 2b b7 19 |D..a......C..+..| -00000020 f2 41 d8 36 65 95 4a bb 68 1b 65 7b de 89 a5 af |.A.6e.J.h.e{....| -00000030 1a aa ec bf b4 66 97 fc 76 d0 14 03 03 00 11 94 |.....f..v.......| -00000040 b0 9b 4d 47 6e 63 e3 3d c4 a7 36 94 3f d2 04 a3 |..MGnc.=..6.?...| -00000050 16 03 03 00 20 34 f5 58 f2 80 c9 19 41 07 d8 6c |.... 4.X....A..l| -00000060 6f 64 e7 e9 76 65 cf a8 61 97 27 29 28 f8 0c 7a |od..ve..a.')(..z| -00000070 2c 5e 05 c6 53 |,^..S| +00000000 16 03 03 00 35 a4 b8 43 07 6e 71 c9 b4 fa e1 9c |....5..C.nq.....| +00000010 a7 9d 0b 47 d8 ea 8b bd ea c2 f5 bf 36 fa 88 95 |...G........6...| +00000020 3b 98 b3 7e 19 21 9b 0f 58 76 e8 de 5b 24 d3 b5 |;..~.!..Xv..[$..| +00000030 81 bd 11 ce 86 02 b0 d1 3b ac 14 03 03 00 11 3f |........;......?| +00000040 4e a4 96 06 71 44 5f 57 30 5e 1a bc 22 8d 42 97 |N...qD_W0^..".B.| +00000050 16 03 03 00 20 23 e7 90 a5 0a 32 b4 69 06 d7 77 |.... #....2.i..w| +00000060 df ef f6 2f b8 d8 22 39 08 4f 39 02 e0 7f 62 93 |.../.."9.O9...b.| +00000070 02 b9 8e a5 b6 |.....| >>> Flow 14 (server to client) -00000000 14 03 03 00 11 c3 73 b6 63 12 88 86 2b cb a8 94 |......s.c...+...| -00000010 9b c4 10 9f 98 cb 16 03 03 00 20 1e 06 97 84 3f |.......... ....?| -00000020 7f 2e 8d 1a 81 1d da d1 f5 53 5d a4 89 9e 90 22 |.........S]...."| -00000030 fd 14 58 d1 f7 b2 cd eb 42 2f e8 17 03 03 00 19 |..X.....B/......| -00000040 1f e3 dc 74 9d 6b 81 43 cb 31 6b 48 31 50 15 e8 |...t.k.C.1kH1P..| -00000050 80 f0 60 c4 43 f6 50 9a 3c |..`.C.P.<| +00000000 14 03 03 00 11 0e 2d 1e 73 95 29 15 86 03 a2 da |......-.s.).....| +00000010 6c f4 d2 02 2c 57 16 03 03 00 20 cd a2 f5 b6 da |l...,W.... .....| +00000020 0c 35 45 96 54 c3 96 5d d8 e6 03 49 7b 5c d4 6f |.5E.T..]...I{\.o| +00000030 02 da 27 9e 2f a7 09 57 1b de 7b 17 03 03 00 19 |..'./..W..{.....| +00000040 18 06 7d aa 5c 93 a9 b3 d3 14 0b 76 78 a2 57 73 |..}.\......vx.Ws| +00000050 2f a3 4f 66 c4 b3 ee 21 95 |/.Of...!.| >>> Flow 15 (client to server) -00000000 15 03 03 00 12 33 e5 90 b6 f4 60 f4 da 3f f5 c4 |.....3....`..?..| -00000010 5c a1 a1 75 01 04 8a |\..u...| +00000000 15 03 03 00 12 55 f7 2f b2 a2 e7 59 6c f6 a9 2d |.....U./...Yl..-| +00000010 d1 17 88 01 49 c6 f2 |....I..| diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected index f9a7a113744..441fa0fd2aa 100644 --- a/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected +++ b/libgo/go/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected @@ -16,11 +16,11 @@ 000000e0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0| 000000f0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |.........._X.;t| >>> Flow 2 (server to client) -00000000 16 03 03 00 59 02 00 00 55 03 03 52 6a c1 e9 3d |....Y...U..Rj..=| -00000010 5e 12 f4 95 42 33 5e 56 98 6b e5 b9 c0 e2 b4 02 |^...B3^V.k......| -00000020 3e 99 0c 26 52 66 69 35 ef 4a 66 20 bb ee b5 86 |>..&Rfi5.Jf ....| -00000030 ec 40 54 e7 ef 93 8e cd e4 bd c2 57 e7 2b d3 86 |.@T........W.+..| -00000040 44 93 8f 4f 3a e3 4d eb 53 88 b0 43 cc a8 00 00 |D..O:.M.S..C....| +00000000 16 03 03 00 59 02 00 00 55 03 03 bb ec 39 c5 f2 |....Y...U....9..| +00000010 dd a8 26 56 80 09 60 f5 d8 0a 93 6d 08 c4 30 c2 |..&V..`....m..0.| +00000020 cf 0c 44 86 49 a3 19 84 20 38 98 20 0d 8b 81 b5 |..D.I... 8. ....| +00000030 a7 42 37 27 1b 9c be 36 8f 9b 49 31 4f 73 67 a7 |.B7'...6..I1Osg.| +00000040 78 9f 46 e5 9e 3b 45 ff e9 16 11 ca cc a8 00 00 |x.F..;E.........| 00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................| 00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..| 00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............| @@ -60,188 +60,188 @@ 00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.| 000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..| 000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......| -000002c0 ac 0c 00 00 a8 03 00 1d 20 dc 94 bc ee 1b 36 ac |........ .....6.| -000002d0 13 5f 6a b8 12 89 3b 05 8f 76 cf 1e 9c 20 2e 75 |._j...;..v... .u| -000002e0 7c a4 f4 23 7f 74 72 97 74 08 04 00 80 b9 22 bb ||..#.tr.t.....".| -000002f0 8e 21 42 cd 1e 68 2c 47 f0 b1 7f 2d 26 ac 7b a6 |.!B..h,G...-&.{.| -00000300 10 b0 a7 72 31 99 ce be 5e e3 a5 c0 18 a6 18 50 |...r1...^......P| -00000310 d8 98 9c 0a f5 15 0f db be 76 50 4b 09 8d f0 94 |.........vPK....| -00000320 a3 48 23 7b d0 13 5e 2c 71 c1 8b e4 56 2b 69 88 |.H#{..^,q...V+i.| -00000330 88 78 b4 b7 7c 0f 29 6c 73 21 b3 e5 26 a5 10 04 |.x..|.)ls!..&...| -00000340 23 93 77 06 81 ff 23 df 06 be 82 4e ac 42 80 10 |#.w...#....N.B..| -00000350 ea db 84 f9 96 98 8e bb bf ab b4 b6 fc 21 88 02 |.............!..| -00000360 49 cb a3 4c 89 ee 19 cb 4d 71 6f fc 37 16 03 03 |I..L....Mqo.7...| +000002c0 ac 0c 00 00 a8 03 00 1d 20 2f ad 87 a5 c9 9e c7 |........ /......| +000002d0 f6 f1 05 9a 44 97 57 34 6b 3a 30 54 4c 0e 47 5e |....D.W4k:0TL.G^| +000002e0 16 d3 c9 c2 25 a8 47 e5 63 08 04 00 80 9f 54 b4 |....%.G.c.....T.| +000002f0 c1 aa bb 15 07 5c b1 52 ef bd 26 fa ec ce 70 31 |.....\.R..&...p1| +00000300 90 fb f5 4d d2 26 0c 64 6f b3 9f 7f 27 c7 a5 b2 |...M.&.do...'...| +00000310 d1 6d cf 0e 9c 91 e3 c4 20 f7 e3 ae 95 ff 6d ce |.m...... .....m.| +00000320 80 b5 30 89 6c a2 dd 31 26 5b 24 19 7a 30 f7 43 |..0.l..1&[$.z0.C| +00000330 71 a8 e9 1a 27 ee 46 86 44 56 b1 f3 2e e1 bd d5 |q...'.F.DV......| +00000340 79 99 34 0c 9b 01 e6 bb 0f ad 96 4a 68 0f 10 79 |y.4........Jh..y| +00000350 e9 91 7f 06 e6 02 32 ba 8c b6 a2 0c 4b 6d 09 f6 |......2.....Km..| +00000360 28 8f 94 e8 10 e1 ca 48 6c de 56 c2 5c 16 03 03 |(......Hl.V.\...| 00000370 00 04 0e 00 00 00 |......| >>> Flow 3 (client to server) 00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.| 00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....| 00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......| -00000030 16 03 03 00 20 6e 65 ea 6e 03 fb f9 4e 00 8f d1 |.... ne.n...N...| -00000040 99 24 83 3a 38 ef 28 7b 16 43 70 b5 af 0d de 37 |.$.:8.({.Cp....7| -00000050 cd bf ac 83 09 |.....| +00000030 16 03 03 00 20 d5 77 86 8e 32 60 6b 0f 0f 36 33 |.... .w..2`k..63| +00000040 89 fe 51 b8 69 3a 1f 37 b3 d1 eb 43 ab e0 f6 db |..Q.i:.7...C....| +00000050 8b 9d 3c 0d 9a |..<..| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 20 ef 39 04 ca 70 |.......... .9..p| -00000010 71 ee f8 1b 72 10 b7 6a 89 cd 85 ee a4 81 a4 87 |q...r..j........| -00000020 88 1b c7 5b 18 d9 95 fe 31 d9 c8 |...[....1..| +00000000 14 03 03 00 01 01 16 03 03 00 20 ed 78 35 a3 71 |.......... .x5.q| +00000010 34 a9 40 b2 be 15 dc a9 10 86 e0 de 94 23 e9 51 |4.@..........#.Q| +00000020 2c 01 1e 34 19 07 53 20 59 ac f9 |,..4..S Y..| >>> Flow 5 (client to server) -00000000 17 03 03 00 16 58 8c 23 1b 8d 7f 44 92 a4 5d 88 |.....X.#...D..].| -00000010 3e ee 7c 98 90 14 b4 61 e9 5c ea |>.|....a.\.| +00000000 17 03 03 00 16 f3 a2 5f da 1c 09 70 76 af 14 83 |......._...pv...| +00000010 e5 7f 6f c9 9a 61 7f d9 e6 86 3c |..o..a....<| >>> Flow 6 (server to client) -00000000 16 03 03 00 14 32 2b 55 14 4a 65 21 51 b0 72 e0 |.....2+U.Je!Q.r.| -00000010 4c 57 b0 b1 78 0b e3 30 de |LW..x..0.| +00000000 16 03 03 00 14 71 23 15 46 93 87 94 38 01 d0 1b |.....q#.F...8...| +00000010 1a 34 db 58 17 d0 ac 62 87 |.4.X...b.| >>> Flow 7 (client to server) -00000000 16 03 03 01 16 ff 7a 5b 80 e0 cd 83 55 3d b5 97 |......z[....U=..| -00000010 60 d2 51 1e 75 d2 5d b9 ea 2a 5f 67 43 03 7c 50 |`.Q.u.]..*_gC.|P| -00000020 25 5d a2 81 5f fa 0f be 08 9d 80 ac 73 16 bc 64 |%].._.......s..d| -00000030 51 54 33 09 cc 05 90 24 c0 ee 99 a9 d1 8f 1b 3e |QT3....$.......>| -00000040 9f 6a e8 b6 83 b0 30 fe e6 6b 6e 37 dd 95 95 30 |.j....0..kn7...0| -00000050 64 46 c7 fc 15 54 84 ef 3d 1a 28 2d ee 3b aa 19 |dF...T..=.(-.;..| -00000060 60 21 f9 d1 98 04 b4 0f 08 79 34 1f aa 12 2e 60 |`!.......y4....`| -00000070 93 ff 87 16 56 55 24 c7 96 00 3b c2 72 7f 9d 96 |....VU$...;.r...| -00000080 8b b7 2b 50 8f 99 df f5 4c 6a 42 0a cc 2f 27 f2 |..+P....LjB../'.| -00000090 88 6d 42 e3 20 c8 1f 01 2b fb e9 b3 aa f3 2f 02 |.mB. ...+...../.| -000000a0 fa 78 34 38 00 0f 1d f9 c7 5a 08 ae 56 19 c2 6c |.x48.....Z..V..l| -000000b0 0b b0 d1 40 0d 0e 57 d2 00 be 3d 65 9c c1 86 00 |...@..W...=e....| -000000c0 4c a5 1b a6 67 4d 39 cd ba fe 96 3c c5 25 dd 43 |L...gM9....<.%.C| -000000d0 7b 49 f0 b5 8a 66 46 d4 65 6b 2d da 55 13 14 48 |{I...fF.ek-.U..H| -000000e0 76 c8 2c 3d a4 4d 7a 14 1e 70 32 06 b3 96 cd 4e |v.,=.Mz..p2....N| -000000f0 bd 4f 06 a8 83 ae 30 83 b6 6b 61 2e 08 73 0e 14 |.O....0..ka..s..| -00000100 08 13 3d f0 7c ec cf 78 ff b4 25 21 15 5e 80 14 |..=.|..x..%!.^..| -00000110 80 4f af c7 9e 44 04 33 da cb 27 |.O...D.3..'| +00000000 16 03 03 01 16 46 70 b5 5f 98 fc af a8 cb d6 7c |.....Fp._......|| +00000010 8c 1e 60 c3 68 25 20 7b 95 9a 0c 04 b3 2c 52 b2 |..`.h% {.....,R.| +00000020 30 f9 db cf 64 48 0a 46 9b 7a 11 76 11 5c 22 0c |0...dH.F.z.v.\".| +00000030 ef fa e6 6e a1 90 29 b3 64 aa ff 4d cb 7d 4d 91 |...n..).d..M.}M.| +00000040 c0 05 99 a0 3d 25 b2 1e 7c c4 d2 94 6b bf f0 f7 |....=%..|...k...| +00000050 0f 6a 3b 4c 66 c7 8a 26 9e 4f 79 68 50 5c f9 92 |.j;Lf..&.OyhP\..| +00000060 97 e1 a5 86 aa f2 e9 d5 8a a1 96 a7 37 82 71 7d |............7.q}| +00000070 7d 7e b6 77 a3 3d 84 40 58 0d 66 cd 52 6c 9b 18 |}~.w.=.@X.f.Rl..| +00000080 e2 c4 f0 dc 3d 9e 0e b8 49 ca 64 f3 71 c5 24 34 |....=...I.d.q.$4| +00000090 e7 ca c3 87 f6 b9 2c 6a 95 12 4d 9d 4a 4d fe 8a |......,j..M.JM..| +000000a0 51 16 6e c9 00 64 c0 d1 da ae e6 14 66 d2 a8 80 |Q.n..d......f...| +000000b0 35 ae 86 f6 64 f8 56 87 8a 40 46 43 ae d1 d1 fb |5...d.V..@FC....| +000000c0 64 1d 00 a1 3d e9 d9 7a b5 fb 71 2a db 76 5a 74 |d...=..z..q*.vZt| +000000d0 03 c3 79 df e6 90 e9 7e de f9 0e 70 7a 65 3c 68 |..y....~...pze| +00000100 cc f9 8d a6 56 37 0d ff 92 8f 1b 36 b3 3d 0b f5 |....V7.....6.=..| +00000110 5b fb fb 1e 4d c8 cb 84 39 5b 87 |[...M...9[.| >>> Flow 8 (server to client) -00000000 16 03 03 00 81 f5 0b a1 9d 19 be 84 54 fd 42 47 |............T.BG| -00000010 d9 4e f8 35 02 91 06 7e 53 5c ea 64 8b c4 34 ac |.N.5...~S\.d..4.| -00000020 f9 93 54 36 5d 13 d0 0d 75 9f 8f 22 20 70 17 45 |..T6]...u.." p.E| -00000030 37 a9 ed c2 34 23 8b bc c8 87 5f a2 ff 9c 54 48 |7...4#...._...TH| -00000040 1b d4 85 60 39 4b 53 75 6f 65 d0 33 a7 b6 90 7d |...`9KSuoe.3...}| -00000050 4f 84 28 cc 59 ab af bd 85 4b 40 ed 72 ff 30 c6 |O.(.Y....K@.r.0.| -00000060 a5 01 8b fa 03 52 7e 0d a8 5d 86 89 9b 4e c4 05 |.....R~..]...N..| -00000070 83 fb d4 aa f9 13 8b 06 b1 2b 89 82 12 d2 a3 e2 |.........+......| -00000080 79 d6 6a 07 ef a0 16 03 03 02 69 65 b4 cc 90 43 |y.j.......ie...C| -00000090 f7 6f 92 59 1b 47 32 e4 51 be 16 8c bb 7b ef 68 |.o.Y.G2.Q....{.h| -000000a0 60 38 9c 5f 5a f6 04 da 78 1d 4e 89 a7 e9 5b e0 |`8._Z...x.N...[.| -000000b0 27 7d 82 fa 6f 44 df 5d 59 b3 5b 4c 01 76 3e bd |'}..oD.]Y.[L.v>.| -000000c0 d7 b5 0b 9a 9d be d4 ec 03 9d e5 a5 e0 e2 f2 a3 |................| -000000d0 7f b2 87 ed 09 46 b2 e1 6a e2 39 e9 82 0d fb 62 |.....F..j.9....b| -000000e0 a4 ef 1e 29 75 96 68 da f9 8d 75 86 df 0c 57 9c |...)u.h...u...W.| -000000f0 48 e9 3e de 16 ab 22 b2 6d 37 38 d6 33 44 bd 38 |H.>...".m78.3D.8| -00000100 16 2c 49 1c 2c 17 1a 28 05 45 eb 65 44 4e 1a 02 |.,I.,..(.E.eDN..| -00000110 fc 2f 5c c9 e8 d8 16 e6 4f 5f f4 bd b4 d7 ec 73 |./\.....O_.....s| -00000120 2f d1 f5 5b 68 69 b6 6a 59 8e 0b 24 2d 7c 69 96 |/..[hi.jY..$-|i.| -00000130 a6 99 66 3e 38 25 82 30 ba 1a b5 b9 66 23 ea 60 |..f>8%.0....f#.`| -00000140 b6 30 5e f5 29 80 8a 75 fc 96 f0 af 3d d2 8e 83 |.0^.)..u....=...| -00000150 5e 00 fc 76 1c 69 cc 2b e8 d2 70 21 95 65 da 2c |^..v.i.+..p!.e.,| -00000160 ed c3 fd a4 31 de 00 e5 3a b1 81 38 fc 68 da 0f |....1...:..8.h..| -00000170 b0 8c 32 f4 67 08 ed 31 0d fc e1 9b 20 8c 79 99 |..2.g..1.... .y.| -00000180 bd 52 e6 eb 27 04 a5 94 1c e9 a0 5a 18 bf 7b 59 |.R..'......Z..{Y| -00000190 22 e6 5c 63 84 2f 0a f6 ef b8 c9 c0 cf 82 0d 07 |".\c./..........| -000001a0 42 66 65 0b d5 5e ea 27 0d f9 de 7e 13 a9 c2 b5 |Bfe..^.'...~....| -000001b0 ea e2 22 4f a0 13 dc 12 69 9a ec ed d4 44 b2 bc |.."O....i....D..| -000001c0 88 65 09 ea 50 ca d6 48 c2 f2 12 9e b3 ab 29 c5 |.e..P..H......).| -000001d0 61 72 3d 0e 77 bd 96 d9 ff 24 4d 7f 4d 22 e0 67 |ar=.w....$M.M".g| -000001e0 54 02 18 42 e7 78 0c 18 28 89 24 a8 4a a1 cc 70 |T..B.x..(.$.J..p| -000001f0 a2 a1 4f ee a0 b6 1f 7e cb 9b 20 95 1f 10 63 60 |..O....~.. ...c`| -00000200 df fe ce 37 9e 9e ce ff fa 49 4f 4c 5b c0 f6 35 |...7.....IOL[..5| -00000210 b7 eb e1 ac 85 64 11 6e 83 61 6f da d9 e9 09 a6 |.....d.n.ao.....| -00000220 10 eb c2 da 62 9c ac e0 2e 0a ff 21 2e f7 94 6d |....b......!...m| -00000230 a6 56 f9 1c 39 52 f3 c7 29 a9 d6 b2 8c a9 4f bf |.V..9R..).....O.| -00000240 62 c8 74 cb 80 3d 3e 4d d1 25 4c 29 14 21 cd 13 |b.t..=>M.%L).!..| -00000250 b0 92 5a ca 9b 10 f6 4c 91 6e f7 c3 55 5e 0e f0 |..Z....L.n..U^..| -00000260 e2 8f 2f 65 f9 b8 c2 43 0c 38 45 86 22 15 ed 8f |../e...C.8E."...| -00000270 6b 49 ff 45 e5 59 b7 54 f8 c9 d3 b0 f6 71 82 7b |kI.E.Y.T.....q.{| -00000280 7d 52 be 6c 33 f2 27 5c f8 33 96 05 64 fa b2 b9 |}R.l3.'\.3..d...| -00000290 ae 74 23 91 46 6f 9b 42 5b 96 1c c4 1c f4 5e b0 |.t#.Fo.B[.....^.| -000002a0 c7 78 0f f3 da d3 01 ae 25 6c c1 10 31 47 e9 0d |.x......%l..1G..| -000002b0 84 27 5d 5a 23 35 07 3c 2d ea e8 dc cd d3 c6 85 |.']Z#5.<-.......| -000002c0 86 ff 48 07 b8 97 d5 c5 10 f4 47 46 af 87 d9 03 |..H.......GF....| -000002d0 24 3d b0 80 33 46 2a 4d 15 77 5c 21 3c a4 13 99 |$=..3F*M.w\!<...| -000002e0 6c 9e ce 69 81 2e 90 c9 ba 9a 95 91 30 cc 8d 9b |l..i........0...| -000002f0 6c 55 c4 09 16 03 03 00 bc 30 d3 15 d7 3b 42 a9 |lU.......0...;B.| -00000300 9b a2 1f c8 ff 90 43 4c 0f 9c 4e 59 98 23 a2 9e |......CL..NY.#..| -00000310 17 e0 ea 06 ae 8f 23 e6 85 f9 ca 80 39 34 78 a3 |......#.....94x.| -00000320 7b 7e 61 88 86 35 e3 8e a3 61 2d f9 24 6e e4 b1 |{~a..5...a-.$n..| -00000330 c2 7d 56 bc 9d e0 12 3d e5 90 10 b9 39 d5 64 6b |.}V....=....9.dk| -00000340 a8 91 75 d7 95 e7 e6 ce 8f 11 b0 66 87 f5 48 5d |..u........f..H]| -00000350 c9 a1 56 b1 71 e9 74 5f 48 a6 06 32 dc 66 7b 0b |..V.q.t_H..2.f{.| -00000360 85 66 36 e9 d3 13 2d d8 60 8c b2 89 c5 2a de b7 |.f6...-.`....*..| -00000370 48 63 e0 8e 27 65 3a 01 6f be 75 45 ec 2a 61 c4 |Hc..'e:.o.uE.*a.| -00000380 a8 0b cf 95 93 a2 d6 27 fa 71 82 92 3a 95 39 a7 |.......'.q..:.9.| -00000390 fc e5 33 e3 f2 0e a4 94 94 bb e6 65 25 3a 6f 6e |..3........e%:on| -000003a0 da a0 6d fc 57 2b 46 f8 ab 55 0e 5a 1e 56 92 68 |..m.W+F..U.Z.V.h| -000003b0 7e 88 f4 d0 b2 16 03 03 00 4a 08 e0 60 21 59 5d |~........J..`!Y]| -000003c0 29 3e ba b9 1d 13 3a a0 e3 b2 76 39 29 00 92 d0 |)>....:...v9)...| -000003d0 24 a6 d9 fd e2 2b c8 5d 6b 78 ea 75 ce 68 93 1b |$....+.]kx.u.h..| -000003e0 3b b8 59 e4 6b 60 5b 4a 28 7a e9 1d 04 72 a8 e0 |;.Y.k`[J(z...r..| -000003f0 64 31 e4 86 da a9 f2 00 36 55 bd 56 02 d4 b3 48 |d1......6U.V...H| -00000400 a7 21 69 11 16 03 03 00 14 44 1c 39 61 56 3d 7e |.!i......D.9aV=~| -00000410 ca dd cb 34 06 10 4f 5f 32 45 63 c1 98 |...4..O_2Ec..| +00000000 16 03 03 00 81 25 44 f6 91 ed d5 01 fa 88 d6 74 |.....%D........t| +00000010 f7 cd 6d ba 85 76 1d bd ef 7b 31 51 db b4 42 a3 |..m..v...{1Q..B.| +00000020 0a 89 3f 47 dc ca 18 39 84 5d 5a 4e d2 cd ba 75 |..?G...9.]ZN...u| +00000030 b9 75 53 28 8c 85 6e 84 02 39 0a d2 59 ee ac 2f |.uS(..n..9..Y../| +00000040 fe a3 e4 fb 8c a1 72 e3 9f 28 8b 13 92 a8 5b 70 |......r..(....[p| +00000050 24 f0 1b 6d 19 aa f1 b2 bf 8a 1f e2 3a 3e 3f e2 |$..m........:>?.| +00000060 57 16 12 9e e8 21 11 66 b9 96 71 36 46 e1 2e fc |W....!.f..q6F...| +00000070 1e 40 a2 e2 6a 4d 4b 91 7a 50 0b d0 87 d1 04 16 |.@..jMK.zP......| +00000080 2f 47 4d f2 c9 68 16 03 03 02 69 9a 28 7b f7 fc |/GM..h....i.({..| +00000090 8b e7 2b 40 88 1c 30 c1 5a f6 1d 51 a9 a8 5e 70 |..+@..0.Z..Q..^p| +000000a0 73 1c 43 a7 3c 11 7e d5 92 78 b1 4f fd 5d 55 c6 |s.C.<.~..x.O.]U.| +000000b0 5a ef 83 88 b2 e2 33 2a 27 cd 2e e8 d2 f4 2b d4 |Z.....3*'.....+.| +000000c0 d5 b0 35 54 f6 a1 9c 07 75 10 8b 5d b9 dc bb 83 |..5T....u..]....| +000000d0 76 43 f6 7e 70 2f 7c fe 8e 64 ca 00 65 df a4 e1 |vC.~p/|..d..e...| +000000e0 a9 ad 71 79 d6 83 21 f6 9c 1b 88 d4 bb 51 3c 8a |..qy..!......Q<.| +000000f0 8c e5 c2 13 30 bd 6b 60 29 01 3e a0 cc 19 69 54 |....0.k`).>...iT| +00000100 f0 2d dd a9 a1 24 a3 cc 13 9b 9a 8b f5 06 88 a9 |.-...$..........| +00000110 9d ec c1 6f 0c b2 dd b3 60 be 23 ee 67 26 2d 65 |...o....`.#.g&-e| +00000120 b1 99 9a 5b 92 c5 06 79 47 c6 4d 39 36 83 3b 4b |...[...yG.M96.;K| +00000130 96 f0 03 41 5c f9 fa 7c 3e d5 bf 67 1c a3 cf 6f |...A\..|>..g...o| +00000140 26 98 e0 2a 2d 64 60 c2 71 b1 b3 35 ba 8a 38 00 |&..*-d`.q..5..8.| +00000150 88 cf 5a a5 2b 89 83 f3 04 ad 24 97 fa 34 69 fd |..Z.+.....$..4i.| +00000160 d7 70 00 09 ce 0f 60 f7 84 7d e3 5e 19 a9 1b dd |.p....`..}.^....| +00000170 45 3f 34 ae d4 c5 5c 1f 32 81 69 ea 22 44 1d c6 |E?4...\.2.i."D..| +00000180 a3 ca 99 c5 44 09 76 cb e2 ed 2e fd 23 09 d4 ea |....D.v.....#...| +00000190 62 cf cb 93 88 02 ca 8c 90 05 c9 0e 8d ff 8f e1 |b...............| +000001a0 2d ef 52 1c ed 01 53 ef a6 ee 11 11 b7 2b c8 b4 |-.R...S......+..| +000001b0 6e 32 8c 54 7a 2b 19 e1 32 3e d0 92 87 81 76 04 |n2.Tz+..2>....v.| +000001c0 c0 fd 99 3b 04 00 fb 76 d7 ed b0 81 e3 81 8c 1f |...;...v........| +000001d0 2b a0 59 d6 41 cd 8d 7d b6 62 9d ab 60 33 24 f5 |+.Y.A..}.b..`3$.| +000001e0 ec 70 8b b2 46 60 8f 53 c8 a3 f1 47 df e0 e8 b0 |.p..F`.S...G....| +000001f0 9a cf 61 d4 d0 f5 0b b6 cd 85 47 1b b2 26 7d f2 |..a.......G..&}.| +00000200 0a 32 af 5c 25 2a cc d2 66 9a 36 a1 68 95 34 18 |.2.\%*..f.6.h.4.| +00000210 2d 9a 5a 62 a7 39 be 00 70 59 63 38 6a f9 53 b7 |-.Zb.9..pYc8j.S.| +00000220 6d dd d4 cd c4 d2 12 b0 67 06 b5 d3 28 06 e4 43 |m.......g...(..C| +00000230 98 b5 13 9f 1a d5 5e 07 70 f9 96 3c 66 a0 60 d6 |......^.p.....Z| +00000350 71 82 05 10 8e be 0b 83 39 44 28 45 c6 e1 4a 85 |q.......9D(E..J.| +00000360 c0 bf 3f 80 9b 61 97 82 d1 54 37 5f bc b2 f7 1f |..?..a...T7_....| +00000370 a1 ef 0f c5 be 74 96 3b e8 89 30 3f d7 06 18 77 |.....t.;..0?...w| +00000380 ed 3b aa 6e df 0c 15 e1 3e b1 36 ae 85 23 7d 9a |.;.n....>.6..#}.| +00000390 17 c3 f4 91 3a ac b1 64 03 a9 59 19 89 c2 d9 ad |....:..d..Y.....| +000003a0 82 d7 8e 85 36 cb 81 61 0d 3a 24 a1 84 55 37 bb |....6..a.:$..U7.| +000003b0 13 80 61 38 ef 16 03 03 00 4a 88 8d 13 b9 32 18 |..a8.....J....2.| +000003c0 3c e2 72 b5 5c 0b 81 87 a0 ef 87 53 89 b1 f4 8b |<.r.\......S....| +000003d0 6a 87 68 c4 7d 59 2c 44 46 bb b1 40 8e 0a 45 4e |j.h.}Y,DF..@..EN| +000003e0 b8 a1 ba 72 bb 71 f9 52 55 c7 44 cd b3 56 82 68 |...r.q.RU.D..V.h| +000003f0 8c 57 39 58 0b 40 12 4f 5d a2 91 3a ab 68 55 19 |.W9X.@.O]..:.hU.| +00000400 26 dc ed 30 16 03 03 00 14 52 f8 53 d9 fc a6 a3 |&..0.....R.S....| +00000410 89 c4 5a 2d 66 46 17 16 c3 bb f9 3c ca |..Z-fF.....<.| >>> Flow 9 (client to server) -00000000 16 03 03 02 69 68 d9 de 2a 4d 03 fe 05 cc b8 d3 |....ih..*M......| -00000010 c8 f0 3d df 1c 73 f1 bd 55 08 45 c4 2a 6b a1 c8 |..=..s..U.E.*k..| -00000020 35 7d 56 b7 b9 15 63 ba 09 31 59 8b f8 ce a0 f8 |5}V...c..1Y.....| -00000030 1b 3b 5f 5e 1c 3d bb 26 43 cb 7b f3 ba 3b a2 38 |.;_^.=.&C.{..;.8| -00000040 a3 d5 bd 0b 65 16 7c e3 79 cc ed 17 04 34 60 e7 |....e.|.y....4`.| -00000050 1e 60 52 72 13 e4 6b ef 32 99 86 94 49 30 47 df |.`Rr..k.2...I0G.| -00000060 e2 6c 6d 3f 6c 19 e4 4e b9 df 42 e3 c8 47 2c d0 |.lm?l..N..B..G,.| -00000070 be 2c 94 3b 1d 3e 3a b3 06 67 c3 25 9b 24 4e 8e |.,.;.>:..g.%.$N.| -00000080 dc c7 50 ab 72 bd b4 d1 ff f7 3f 6d 13 89 55 8c |..P.r.....?m..U.| -00000090 14 a1 ae fe ad a0 bb 8f fe 51 ac 5b eb 23 3d d0 |.........Q.[.#=.| -000000a0 9e b8 5e 34 8c dd 47 79 9c 73 f5 6b 47 ff 10 7d |..^4..Gy.s.kG..}| -000000b0 ac 1d a7 54 5e b5 0f 75 86 67 13 70 d5 66 da 55 |...T^..u.g.p.f.U| -000000c0 0b 48 a0 88 ae f9 81 92 33 0b 29 79 42 f7 c2 98 |.H......3.)yB...| -000000d0 2c 2f 32 c7 df 35 ff 4a 44 10 fa 9f 66 ce 4b 9a |,/2..5.JD...f.K.| -000000e0 3c 5b b3 7d ac 3b 9a 68 bb 40 3d 36 6b 72 98 c5 |<[.}.;.h.@=6kr..| -000000f0 85 3c b0 75 1c d6 45 0f f9 4d 26 2d ec 67 90 ed |.<.u..E..M&-.g..| -00000100 88 33 92 7d 99 22 c4 08 90 64 17 1e 06 03 d5 a3 |.3.}."...d......| -00000110 72 a6 92 99 d3 c8 46 9f e7 f9 15 bb dd ba e5 f7 |r.....F.........| -00000120 d9 06 af 5c 1c a0 03 c7 fe 51 b5 41 0c 8f 6d ad |...\.....Q.A..m.| -00000130 f2 41 23 a5 44 38 8a bb b3 d9 3c e8 5e 99 98 23 |.A#.D8....<.^..#| -00000140 9c 87 3d f8 10 df 58 c2 dd b9 2c 7e 56 a1 75 84 |..=...X...,~V.u.| -00000150 a2 e5 66 20 58 ed fe f7 04 ff 93 e0 6e 9f 1e f3 |..f X.......n...| -00000160 a9 8a 9a 37 38 d2 7c 4d 74 88 f5 bd 2b 5a 05 bc |...78.|Mt...+Z..| -00000170 53 a1 48 ab 98 ca 91 bb fa f3 62 a9 0a fa 89 e6 |S.H.......b.....| -00000180 22 06 1d 59 72 32 51 d6 f6 de e8 89 b6 eb 96 f2 |"..Yr2Q.........| -00000190 4d e0 82 0d b8 ec a7 09 84 79 18 70 3e 09 ba 9a |M........y.p>...| -000001a0 98 27 13 e8 e6 e5 9d 7c df 4d 42 a8 41 be 62 e0 |.'.....|.MB.A.b.| -000001b0 1d 48 24 5d 35 e5 a5 ff f5 67 85 cf b8 53 e1 5e |.H$]5....g...S.^| -000001c0 dd 82 40 9e d3 94 fd 7b 1b b3 13 d8 98 a8 1f 21 |..@....{.......!| -000001d0 1a 04 5a df 3c 8f 3a c0 dc 86 8b e1 39 0a 03 8e |..Z.<.:.....9...| -000001e0 8c 9a 4c d5 15 32 2d 1c 0f ad 43 25 e6 5a 77 f9 |..L..2-...C%.Zw.| -000001f0 2d e5 a0 a0 b2 32 43 0f 11 55 bb c2 e1 c6 45 2a |-....2C..U....E*| -00000200 da a0 6c 14 49 0f a7 d7 40 b1 1a c8 72 2a a8 26 |..l.I...@...r*.&| -00000210 45 f4 66 9a e0 42 aa 25 ac 28 ec 8c a2 df 48 cc |E.f..B.%.(....H.| -00000220 c3 a9 9e 9e af 38 88 82 43 8f 99 02 79 90 3e d9 |.....8..C...y.>.| -00000230 9e d0 75 a5 95 83 ec 44 2b 13 1c d8 eb 3f 2c 5d |..u....D+....?,]| -00000240 1b 7e e2 fe 47 89 08 5b 58 dc 3d ea 32 5e a1 af |.~..G..[X.=.2^..| -00000250 c5 e8 90 b8 28 4b 58 55 34 46 ef 2a d6 a0 9b 0b |....(KXU4F.*....| -00000260 73 b9 8b b4 38 63 08 92 03 4c 8c 12 be a8 16 03 |s...8c...L......| -00000270 03 00 35 f5 3c 22 cc bc cf c3 ad 84 1d dc f4 b6 |..5.<"..........| -00000280 e0 4a 1c b9 e5 d8 a6 b7 a2 8c fb 40 11 12 40 5c |.J.........@..@\| -00000290 e2 f4 ce ac 83 93 69 71 19 85 43 19 9e 30 ee 97 |......iq..C..0..| -000002a0 02 8e 69 8f 4d 1d 2c 0f 16 03 03 00 98 94 e4 82 |..i.M.,.........| -000002b0 1d 6b d2 ce 76 6d 68 55 db bb 91 73 6e e9 73 05 |.k..vmhU...sn.s.| -000002c0 6a d3 eb 48 f1 d7 f6 52 ba 49 6a f2 f7 74 c8 56 |j..H...R.Ij..t.V| -000002d0 ba f5 e5 97 cb a0 b7 ab 37 2c ff 7a a6 42 e6 78 |........7,.z.B.x| -000002e0 51 8a 9c bf fa 05 b7 66 04 6d 83 d1 0d e8 18 d0 |Q......f.m......| -000002f0 f2 b3 4d 4d 2d c0 f7 ac d1 55 b8 03 d7 dc d7 c2 |..MM-....U......| -00000300 73 72 54 c9 29 e4 98 29 a3 95 11 7e 56 52 87 09 |srT.)..)...~VR..| -00000310 05 fe 74 e2 f1 74 c7 f6 f2 28 4f 2c 24 92 ac ae |..t..t...(O,$...| -00000320 1c df 4e f9 db ce 3c db 48 60 6b 4d 12 9c f7 de |..N...<.H`kM....| -00000330 26 73 25 d2 e7 d1 2e fd b5 5e c4 66 2a 60 4a 04 |&s%......^.f*`J.| -00000340 2d b9 6c b1 d2 14 03 03 00 11 58 08 81 e4 4d c4 |-.l.......X...M.| -00000350 93 47 e2 45 e2 44 73 36 3a fe ba 16 03 03 00 20 |.G.E.Ds6:...... | -00000360 25 2d 76 2c 22 34 e9 ed 11 a5 84 ee d3 63 df 17 |%-v,"4.......c..| -00000370 88 be 86 7c 51 35 fb 7e aa a6 b9 a2 02 59 f7 00 |...|Q5.~.....Y..| +00000000 16 03 03 02 69 fe 0d 45 cb 57 12 fa 9e 10 d7 b3 |....i..E.W......| +00000010 a5 dd 33 0e 39 41 77 63 8e 99 e0 5b b9 5e 94 0a |..3.9Awc...[.^..| +00000020 48 b2 6b e9 61 ab f2 74 6b 5e a3 f9 3f 9c 29 0b |H.k.a..tk^..?.).| +00000030 6b 34 29 92 d8 c8 2c 61 84 f2 3b 0f c2 5c e5 19 |k4)...,a..;..\..| +00000040 6a f0 e2 03 e3 93 a6 1e 4e 87 79 6b 07 dc 18 d2 |j.......N.yk....| +00000050 9a 25 be f3 d6 ab 2a be f8 68 65 68 92 8a 80 04 |.%....*..heh....| +00000060 26 eb 62 ae 6b bc 81 27 82 76 25 e0 6b ac 04 e9 |&.b.k..'.v%.k...| +00000070 67 68 13 f6 7b 7e 24 c2 75 27 8a c9 3a 7a 2f aa |gh..{~$.u'..:z/.| +00000080 a2 37 d9 73 97 bc 4b 09 ba 1b 2c ba 08 85 c6 82 |.7.s..K...,.....| +00000090 50 a3 e0 00 6e a8 7c 14 ab 38 ae c4 82 ee 05 4b |P...n.|..8.....K| +000000a0 9a c0 19 62 1e de ef 7f 8c a4 a0 0e 29 0f b4 09 |...b........)...| +000000b0 f1 b9 39 ae 09 1b 6e 6f ee 3d 31 72 70 09 51 44 |..9...no.=1rp.QD| +000000c0 1c 33 64 6d ae 8d da a5 e0 7b a3 49 19 2c 3f dd |.3dm.....{.I.,?.| +000000d0 6b 1e d1 a7 bb 8a 13 8c e9 aa 5f b3 fd 88 89 5a |k........._....Z| +000000e0 4a 30 dd d0 1e 6a 8c 8a 0d 35 82 01 64 c1 42 ff |J0...j...5..d.B.| +000000f0 60 ac 3d 62 bf 31 3e ab 42 7e b0 da 4a cc 9c d8 |`.=b.1>.B~..J...| +00000100 0e 92 97 a2 40 48 48 ce 66 49 bd 1b 8a ee ed 46 |....@HH.fI.....F| +00000110 18 98 b9 43 b8 76 e8 93 07 3c 38 6e c2 cd 9c ce |...C.v...<8n....| +00000120 e2 38 f0 d7 ee ad c7 4a c4 ed 3b fd 2e f2 9b 43 |.8.....J..;....C| +00000130 6c fe 75 d7 4d 61 2a c5 16 e2 3d af 98 5b 76 f5 |l.u.Ma*...=..[v.| +00000140 3e 96 b9 81 b3 cb 0c 91 89 44 6e d6 66 c4 f2 dd |>........Dn.f...| +00000150 c9 21 09 91 95 f2 99 29 62 54 44 03 b0 fe 84 bb |.!.....)bTD.....| +00000160 96 86 c4 ca 6e 7f c9 f9 1a 80 38 42 7d 54 b3 6f |....n.....8B}T.o| +00000170 2a 2d c3 19 54 60 3f fb 00 95 65 6a 85 4b a2 8f |*-..T`?...ej.K..| +00000180 6a 3d 38 61 e9 36 c2 25 92 3b 53 f2 ea bb 60 42 |j=8a.6.%.;S...`B| +00000190 ab 83 83 c0 2e 95 6d 5a 19 61 9f b3 29 ee b2 52 |......mZ.a..)..R| +000001a0 5f 27 16 46 d9 ad 62 45 d5 81 9a 93 ef a1 4f e7 |_'.F..bE......O.| +000001b0 0e e0 71 bf cd 49 68 e7 13 f1 71 59 8c f5 2d 05 |..q..Ih...qY..-.| +000001c0 5d 65 c4 6e 2c 91 c5 d3 40 c4 2f df c8 f6 59 55 |]e.n,...@./...YU| +000001d0 05 6b c1 b7 59 15 8e b8 85 1b 75 dd 44 9e b7 f3 |.k..Y.....u.D...| +000001e0 00 73 bf c6 93 d4 43 27 bd 60 79 1a 28 93 2d 64 |.s....C'.`y.(.-d| +000001f0 fb 2f 77 a6 79 22 54 f3 c3 3c 3f cd 4d ea 79 3b |./w.y"T..>> Flow 10 (server to client) -00000000 14 03 03 00 11 bb 91 ed b9 75 be 6c 2c b8 7c 57 |.........u.l,.|W| -00000010 0b 44 2e 6d 68 4a 16 03 03 00 20 49 17 51 ce 23 |.D.mhJ.... I.Q.#| -00000020 ff 71 ad f5 45 75 01 43 4d d2 f8 08 d8 e5 4d d7 |.q..Eu.CM.....M.| -00000030 1c 35 5e 8b 18 54 e5 f6 0c b5 2e 17 03 03 00 19 |.5^..T..........| -00000040 ec 43 1a 6d 9e fb 53 cd 55 1a 72 2e da d1 ea 58 |.C.m..S.U.r....X| -00000050 66 17 a9 1c be fc d9 72 dd 16 03 03 00 14 c2 98 |f......r........| -00000060 a4 ac d5 0c a2 10 61 8b 55 3a 69 b6 26 33 4f fe |......a.U:i.&3O.| -00000070 2d 42 |-B| +00000000 14 03 03 00 11 00 e4 ef 62 c1 c0 72 f3 98 4d 5a |........b..r..MZ| +00000010 6a c8 7e 29 92 b8 16 03 03 00 20 ff 7e fc cb b5 |j.~)...... .~...| +00000020 07 5f ea 8a 89 2a 46 1b c6 33 41 fe f9 f4 1e 3a |._...*F..3A....:| +00000030 9d 8b 1d 8f 9b 7b 89 07 b4 e8 59 17 03 03 00 19 |.....{....Y.....| +00000040 a3 ba 0c 9b 54 cd 59 6a e1 db 33 80 38 a9 95 a1 |....T.Yj..3.8...| +00000050 95 5b a5 5f ad 3c d0 52 f7 16 03 03 00 14 e6 22 |.[._.<.R......."| +00000060 84 a7 02 10 1e ee 58 88 a5 b8 e8 bf 0a 9b 61 46 |......X.......aF| +00000070 0c ae |..| >>> Flow 11 (client to server) -00000000 15 03 03 00 12 d4 c8 e4 36 30 00 40 d1 d5 9a 9d |........60.@....| -00000010 3c 2d eb 4f e0 6e a3 15 03 03 00 12 4d b6 67 e4 |<-.O.n......M.g.| -00000020 02 d0 89 50 ef 4b 8a 1f 49 f2 f0 14 b6 7e |...P.K..I....~| +00000000 15 03 03 00 12 7f 90 91 7b 93 4e 24 25 5e cb 35 |........{.N$%^.5| +00000010 2c eb ee 29 6a b3 a3 15 03 03 00 12 3d b7 30 fe |,..)j.......=.0.| +00000020 63 90 c3 2d 17 a0 e1 ed 8d bb a4 f6 f6 17 |c..-..........| diff --git a/libgo/go/crypto/tls/testdata/Client-TLSv13-ALPN b/libgo/go/crypto/tls/testdata/Client-TLSv13-ALPN index f2ca5acfbd2..0ac9b36933c 100644 --- a/libgo/go/crypto/tls/testdata/Client-TLSv13-ALPN +++ b/libgo/go/crypto/tls/testdata/Client-TLSv13-ALPN @@ -1,5 +1,5 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 12 01 00 01 0e 03 03 00 00 00 00 00 |................| +00000000 16 03 01 01 0e 01 00 01 0a 03 03 00 00 00 00 00 |................| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 |........... ....| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| @@ -7,87 +7,87 @@ 00000050 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#| 00000060 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5| 00000070 c0 12 00 0a 00 05 c0 11 c0 07 13 01 13 03 13 02 |................| -00000080 01 00 00 93 33 74 00 00 00 05 00 05 01 00 00 00 |....3t..........| -00000090 00 00 0a 00 0a 00 08 00 1d 00 17 00 18 00 19 00 |................| -000000a0 0b 00 02 01 00 00 0d 00 1a 00 18 08 04 04 03 08 |................| -000000b0 07 08 05 08 06 04 01 05 01 06 01 05 03 06 03 02 |................| -000000c0 01 02 03 ff 01 00 01 00 00 10 00 10 00 0e 06 70 |...............p| -000000d0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 12 00 00 |roto2.proto1....| -000000e0 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 33 00 |.+............3.| -000000f0 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 43 15 |&.$... /.}.G.bC.| -00000100 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| -00000110 90 99 5f 58 cb 3b 74 |.._X.;t| +00000080 01 00 00 8f 00 05 00 05 01 00 00 00 00 00 0a 00 |................| +00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................| +000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................| +000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................| +000000c0 01 00 01 00 00 10 00 10 00 0e 06 70 72 6f 74 6f |...........proto| +000000d0 32 06 70 72 6f 74 6f 31 00 12 00 00 00 2b 00 09 |2.proto1.....+..| +000000e0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.| +000000f0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._| +00000100 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X| +00000110 cb 3b 74 |.;t| >>> Flow 2 (server to client) -00000000 16 03 03 00 7a 02 00 00 76 03 03 9a f4 f5 6b ec |....z...v.....k.| -00000010 37 69 ea a2 43 05 46 fe dd 55 27 2e 78 cb f6 cc |7i..C.F..U'.x...| -00000020 96 ea fd 68 98 bb 3e 9d 75 ad 6e 20 00 00 00 00 |...h..>.u.n ....| +00000000 16 03 03 00 7a 02 00 00 76 03 03 23 c5 c4 0c 4a |....z...v..#...J| +00000010 d2 5f 0b f6 ea 21 7a d1 a0 7d 21 26 b5 a3 94 ca |._...!z..}!&....| +00000020 91 6c 13 58 60 4f 39 cc 1a f7 c0 20 00 00 00 00 |.l.X`O9.... ....| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 01 00 00 |................| -00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 04 |..+.....3.$... .| -00000060 67 13 de c7 ca 6c 02 d8 ee c4 80 d8 43 c2 ef 3e |g....l......C..>| -00000070 94 e1 51 d6 bf c7 1f 0c 4a b0 af 7f 91 a5 61 14 |..Q.....J.....a.| -00000080 03 03 00 01 01 17 03 03 00 24 3f 87 40 f6 93 e3 |.........$?.@...| -00000090 c9 cb 6e 83 75 c5 2f e3 af 0f 84 9a 3b 88 ad cc |..n.u./.....;...| -000000a0 99 c9 1b a8 26 e0 14 d4 ab fe 50 5f ad 79 17 03 |....&.....P_.y..| -000000b0 03 02 6d 67 86 8e eb e3 15 65 21 e5 2f aa 8d c7 |..mg.....e!./...| -000000c0 d5 34 6a b6 d3 ab 5f 96 f6 b2 79 b0 bc 3e f7 9c |.4j..._...y..>..| -000000d0 5d 8d 62 50 91 35 e1 7d fe 61 9b 8c 9d e1 4a 7f |].bP.5.}.a....J.| -000000e0 54 4b ad c5 35 3d c9 05 d1 b0 6c 3f b2 c4 f7 75 |TK..5=....l?...u| -000000f0 57 84 50 62 8d 50 80 be b6 71 b8 59 02 52 5d 55 |W.Pb.P...q.Y.R]U| -00000100 70 5e 76 61 77 d9 d1 f6 20 d1 d9 bf e2 03 16 1e |p^vaw... .......| -00000110 eb 1c 55 85 48 8d 43 72 56 2a d2 16 fc a3 cc 94 |..U.H.CrV*......| -00000120 08 6d a8 73 55 9d a8 0c 36 da f4 02 c9 23 7b d5 |.m.sU...6....#{.| -00000130 06 e7 63 63 a1 fa 80 1c ca 77 d3 ee 4a f8 61 31 |..cc.....w..J.a1| -00000140 4b 1c d6 8c f3 86 d3 16 ba fe 1c ff 5a f6 fa fc |K...........Z...| -00000150 d6 c7 ab b6 5a db 51 f3 cc 42 f0 65 b6 8f f3 d7 |....Z.Q..B.e....| -00000160 44 5a e7 1e a9 d4 a7 bd cd 20 bf a1 13 f1 b5 29 |DZ....... .....)| -00000170 91 a4 28 78 f5 b6 c2 09 a5 95 e5 98 ab c9 f4 4b |..(x...........K| -00000180 10 da eb 07 ff 46 44 f9 85 f6 4f 78 5c b0 fa 2d |.....FD...Ox\..-| -00000190 0b 3b 79 3f 11 a2 eb 12 96 a3 01 ac 13 d3 65 cc |.;y?..........e.| -000001a0 98 e8 c9 8c c3 c6 c9 09 aa f6 af 01 1e e5 30 40 |..............0@| -000001b0 40 88 44 26 ee 49 91 68 18 56 b9 ce 22 f6 80 ff |@.D&.I.h.V.."...| -000001c0 32 d0 ee 15 e3 8a 96 c0 e5 47 51 c1 7f 70 e1 fc |2........GQ..p..| -000001d0 3a 44 1a 36 b9 e7 ee f0 9c 4e 62 1f 78 2f cc dd |:D.6.....Nb.x/..| -000001e0 62 a3 3b 9b ae d1 34 ea 7f d7 dc b4 c5 2c d7 96 |b.;...4......,..| -000001f0 61 59 0b ed de cc 70 68 06 2c 93 3d a9 9f 0a 9b |aY....ph.,.=....| -00000200 46 0d 39 fa b0 db 7f 9b c1 80 c8 55 35 bb 10 4c |F.9........U5..L| -00000210 2d 8f 88 ae 94 bf 4a 5f 3b f5 95 e7 7a 47 e2 0e |-.....J_;...zG..| -00000220 19 b2 e7 69 f5 bb c0 08 9d e8 5e 23 f0 85 12 c0 |...i......^#....| -00000230 01 cf 7a 87 19 b1 98 97 8d 5a 19 5c 37 52 0b a7 |..z......Z.\7R..| -00000240 45 e8 8f 9b 0c 76 5f a6 5b d9 45 87 5b 6e 0e db |E....v_.[.E.[n..| -00000250 6a 6a e2 b2 1d f9 e6 31 13 09 8c 32 93 43 46 17 |jj.....1...2.CF.| -00000260 15 45 c8 26 7f f2 23 7b b1 da c4 20 56 59 4b c9 |.E.&..#{... VYK.| -00000270 3e 90 a6 77 ea 28 ea 05 74 b8 04 55 68 7a 60 91 |>..w.(..t..Uhz`.| -00000280 b7 8e 7d 96 11 ac 2d af f2 26 c5 03 99 57 80 a7 |..}...-..&...W..| -00000290 80 1f 6f ce fd 0e 81 af 2e d6 b0 6b 7c 4c 71 02 |..o........k|Lq.| -000002a0 4c 56 fc e9 0a 58 56 5e 4d fd 2d ea e8 ae d5 b7 |LV...XV^M.-.....| -000002b0 cf aa 66 48 a9 42 76 59 81 52 18 cf c4 6d d8 8c |..fH.BvY.R...m..| -000002c0 90 e3 57 28 53 43 5e ae cd 33 ac 64 e2 ff 65 17 |..W(SC^..3.d..e.| -000002d0 11 e2 6a 07 aa 57 40 63 90 51 11 43 9f 9e 6d 56 |..j..W@c.Q.C..mV| -000002e0 69 c2 44 bb f9 83 84 79 bf 98 be 62 e8 20 6e cc |i.D....y...b. n.| -000002f0 69 a9 c4 33 de 40 d5 e9 95 12 87 d5 28 24 05 62 |i..3.@......($.b| -00000300 ca b8 c2 bd d9 96 dc 16 03 c8 7d 9c 7a 83 de 55 |..........}.z..U| -00000310 3b 4f 90 7b af 36 9a a7 80 46 c5 76 14 70 6c f4 |;O.{.6...F.v.pl.| -00000320 17 03 03 00 99 6e 39 2c 0d 81 12 85 c2 1c 42 56 |.....n9,......BV| -00000330 6a 3a e2 04 60 af 78 13 20 d2 b5 b2 58 9e 2f b9 |j:..`.x. ...X./.| -00000340 f8 11 4f 52 cd 31 c3 a1 ec 83 bd 2e ea 9a 53 6b |..OR.1........Sk| -00000350 55 99 a6 8a 25 1c f7 b6 83 4e 9f 1e 5d c5 b2 b2 |U...%....N..]...| -00000360 a5 6b ea 87 96 0e 29 5b a4 24 f2 16 4c ad e1 9b |.k....)[.$..L...| -00000370 24 d2 95 7e 74 37 44 1a d7 83 f5 4c 28 3f 3d 92 |$..~t7D....L(?=.| -00000380 a7 6f 6e 70 1c 27 93 19 64 ee 61 dc 81 35 67 c8 |.onp.'..d.a..5g.| -00000390 f3 e6 de b0 8f 32 6c df b1 66 97 6b b9 4a 81 f0 |.....2l..f.k.J..| -000003a0 cd 3a b4 56 14 e3 27 50 b0 f3 9b 63 05 a5 99 3a |.:.V..'P...c...:| -000003b0 26 d6 a5 3c e4 ea 8a 5a 04 5e fb de 86 bb 17 03 |&..<...Z.^......| -000003c0 03 00 35 eb 5f 0f df 9f e0 c7 4d b4 3d a6 c8 1a |..5._.....M.=...| -000003d0 df f1 f8 1e 36 ea ae 30 32 da 78 0e 00 fe d3 54 |....6..02.x....T| -000003e0 cc 90 08 1a cb 92 1c 5f f7 0a 3c f7 19 ed a3 3b |......._..<....;| -000003f0 cb fd 56 cb 4f 30 83 07 |..V.O0..| +00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 f9 |..+.....3.$... .| +00000060 64 7e 54 8f 64 ec 3d 7c 17 f1 96 3c 44 ca cd d7 |d~T.d.=|...>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 35 ec 05 98 86 f9 |..........5.....| -00000010 a1 e4 14 c1 e2 85 17 62 f9 ff 5f 1f 53 8f 00 14 |.......b.._.S...| -00000020 28 dd 31 bc 9a 7e 2d 54 53 c2 57 f0 24 0f e1 ca |(.1..~-TS.W.$...| -00000030 5e 17 07 bc 32 a5 72 3f 3e 90 dd be f1 a1 cc 6b |^...2.r?>......k| -00000040 17 03 03 00 17 93 58 dd 95 9a 88 82 3d 63 41 f7 |......X.....=cA.| -00000050 ba da 0e 24 3f f2 b1 e5 db 83 2d bd 17 03 03 00 |...$?.....-.....| -00000060 13 03 a4 42 58 3b d7 c5 c2 08 45 e5 c1 bc eb 47 |...BX;....E....G| -00000070 b5 20 ea ce |. ..| +00000000 14 03 03 00 01 01 17 03 03 00 35 3e e7 50 e1 d1 |..........5>.P..| +00000010 4d 9f 84 fe ca 83 c4 3b a6 86 45 c2 7e e7 af 00 |M......;..E.~...| +00000020 db e6 23 3c 06 b8 a3 1e 36 2e ab 45 7e d8 07 8c |..#<....6..E~...| +00000030 66 bf 5a 0f ff e6 3f 09 a4 d3 cf 74 1c d6 cf c7 |f.Z...?....t....| +00000040 17 03 03 00 17 4c db af a7 f3 73 b3 84 b9 a7 d1 |.....L....s.....| +00000050 1c 2f cb 27 d8 ba 2c c6 84 48 88 18 17 03 03 00 |./.'..,..H......| +00000060 13 a3 41 6f fb da f5 5a 4d 85 0c e0 ff 3a fb 91 |..Ao...ZM....:..| +00000070 e2 5e ab 96 |.^..| diff --git a/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-3DES b/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-3DES deleted file mode 100644 index 869b22bc554..00000000000 --- a/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-3DES +++ /dev/null @@ -1,76 +0,0 @@ ->>> Flow 1 (client to server) -00000000 16 03 00 00 2f 01 00 00 2b 03 00 6b 1d 6c 38 1a |..../...+..k.l8.| -00000010 50 71 9a 32 88 4f 4a fe 47 00 8f 2a 58 08 72 cf |Pq.2.OJ.G..*X.r.| -00000020 b5 f8 27 9d f9 17 76 32 8a 3b 29 00 00 04 00 0a |..'...v2.;).....| -00000030 00 ff 01 00 |....| ->>> Flow 2 (server to client) -00000000 16 03 00 00 31 02 00 00 2d 03 00 00 00 00 00 00 |....1...-.......| -00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 0a 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 00 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 00 00 04 0e 00 00 00 |;............| ->>> Flow 3 (client to server) -00000000 16 03 00 00 84 10 00 00 80 24 e4 7a 2a e8 1b 68 |.........$.z*..h| -00000010 c5 87 ac 26 72 70 76 c6 3a 2c 9d ed ff 63 3c 5b |...&rpv.:,...c<[| -00000020 97 17 3e d4 e9 ab 5b f1 30 ed 29 07 1a 6b 69 f6 |..>...[.0.)..ki.| -00000030 65 b1 c7 b9 15 9f b1 69 7d 74 c4 73 04 2a 45 77 |e......i}t.s.*Ew| -00000040 ba f7 8f 98 65 ed 19 2d a4 de 74 1e 4e 96 78 11 |....e..-..t.N.x.| -00000050 33 9f be a5 20 e4 bd a8 a4 1a 4d 02 e7 7a ac 01 |3... .....M..z..| -00000060 f4 12 01 8d 51 9a 52 26 ac a4 f6 52 fc cf 91 97 |....Q.R&...R....| -00000070 b5 d7 9f 25 92 b4 16 c4 33 46 bd 41 27 89 a2 72 |...%....3F.A'..r| -00000080 7b 50 d3 ed b3 29 17 aa ab 14 03 00 00 01 01 16 |{P...)..........| -00000090 03 00 00 40 ba 01 09 10 84 68 0c 97 25 b5 2d ef |...@.....h..%.-.| -000000a0 be c6 d9 21 85 fe bf ef d4 f3 24 2f 79 04 fd e6 |...!......$/y...| -000000b0 d3 c1 d2 1b a9 94 10 2e 1f dd dd 1f 97 de 63 e9 |..............c.| -000000c0 8f 8a c1 d0 ac e1 69 de 92 fa 16 10 2c 9e 5f 3a |......i.....,._:| -000000d0 45 7c 3f 88 |E|?.| ->>> Flow 4 (server to client) -00000000 14 03 00 00 01 01 16 03 00 00 40 3b 60 e6 62 bc |..........@;`.b.| -00000010 53 0f 95 32 d8 95 33 1b 29 78 49 fd 1f a9 bf 64 |S..2..3.)xI....d| -00000020 71 2d b5 3e 03 80 a0 06 7a ca cd f6 f3 45 e9 d9 |q-.>....z....E..| -00000030 c1 fc da 4f 5d 77 a3 07 82 89 3b 77 00 9a 99 a2 |...O]w....;w....| -00000040 ac bf 73 78 31 a9 8c bf eb d1 2c 17 03 00 00 18 |..sx1.....,.....| -00000050 e9 c8 b2 91 db fa 9f 3c d4 ed 7d 43 f6 b3 53 d2 |.......<..}C..S.| -00000060 46 12 d2 6c a5 50 bd e1 17 03 00 00 28 2e 6f 91 |F..l.P......(.o.| -00000070 21 18 89 7b 94 3d c0 6f 8a 4c b4 95 44 4c fe 1a |!..{.=.o.L..DL..| -00000080 78 f5 6a fd 8f d0 79 c0 12 2f 4c 12 c4 29 9a 88 |x.j...y../L..)..| -00000090 43 1c b7 93 3a 15 03 00 00 18 ae 35 00 1f 79 99 |C...:......5..y.| -000000a0 cd 9f b1 16 a8 0f d6 28 29 e2 0a 16 e2 c2 de b3 |.......().......| -000000b0 5c 41 |\A| diff --git a/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-AES b/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-AES deleted file mode 100644 index 5b09409ae76..00000000000 --- a/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-AES +++ /dev/null @@ -1,77 +0,0 @@ ->>> Flow 1 (client to server) -00000000 16 03 00 00 2f 01 00 00 2b 03 00 c0 74 e5 6f 1e |..../...+...t.o.| -00000010 3d 51 26 e2 34 31 68 10 ee 99 ca 45 0f 7d d6 7d |=Q&.41h....E.}.}| -00000020 29 82 15 23 3f af d1 48 36 1f ac 00 00 04 00 2f |)..#?..H6....../| -00000030 00 ff 01 00 |....| ->>> Flow 2 (server to client) -00000000 16 03 00 00 31 02 00 00 2d 03 00 00 00 00 00 00 |....1...-.......| -00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 00 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 00 00 04 0e 00 00 00 |;............| ->>> Flow 3 (client to server) -00000000 16 03 00 00 84 10 00 00 80 62 6a 6e 2e 83 74 fe |.........bjn..t.| -00000010 08 7b e3 38 de be 06 18 ed c3 aa e0 27 5e bb 5d |.{.8........'^.]| -00000020 a3 22 38 92 d4 94 ec 18 02 f1 fd 57 98 ac 84 3c |."8........W...<| -00000030 07 ef c9 e2 c4 05 03 9c 89 69 dd cb 47 7c 61 5c |.........i..G|a\| -00000040 7b c7 02 7b e4 4c 94 28 ea d7 34 ed 03 ef eb de |{..{.L.(..4.....| -00000050 c0 75 e3 75 46 24 8a ed 33 33 5c 19 65 a2 f8 0c |.u.uF$..33\.e...| -00000060 69 f9 ce 3e b6 88 e3 f4 2a ba 5c 0d 85 2f 64 88 |i..>....*.\../d.| -00000070 cb 0e af 03 58 1b 54 71 21 fb 4c 13 ff 67 dd e9 |....X.Tq!.L..g..| -00000080 1a 83 08 a9 ad 46 85 2b 95 14 03 00 00 01 01 16 |.....F.+........| -00000090 03 00 00 40 65 17 83 78 12 b1 50 a8 7e 91 ad cf |...@e..x..P.~...| -000000a0 ff da 1b c3 c2 62 d7 7b dc 85 6a 1e 64 65 2e fc |.....b.{..j.de..| -000000b0 71 ea bd 4b a6 61 e3 95 27 78 f5 93 e6 6e 4c 83 |q..K.a..'x...nL.| -000000c0 78 f4 a0 ac 3b 23 08 61 b5 b6 96 3f a5 fd 50 be |x...;#.a...?..P.| -000000d0 20 ef 8f af | ...| ->>> Flow 4 (server to client) -00000000 14 03 00 00 01 01 16 03 00 00 40 c1 63 5c 1e 81 |..........@.c\..| -00000010 ef 1c 55 e7 5b ee 19 2b 89 c9 19 7a 53 96 ae f6 |..U.[..+...zS...| -00000020 47 22 4b b2 b9 64 38 06 99 b1 58 39 bc c2 7f 1c |G"K..d8...X9....| -00000030 c4 8e 0a ec f2 3d 41 ac a9 a2 34 d9 a2 66 4e 35 |.....=A...4..fN5| -00000040 a1 a5 a5 ad 70 c2 62 67 f7 83 3f 17 03 00 00 20 |....p.bg..?.... | -00000050 bf 4b 66 00 de 5f 75 f1 57 a1 47 e3 35 cb 1a 1b |.Kf.._u.W.G.5...| -00000060 1e f4 3b f5 96 84 bc ed 36 74 8a 8b 62 46 94 fd |..;.....6t..bF..| -00000070 17 03 00 00 30 a2 a7 8c ac 1b 27 d7 1a 6a 2b 37 |....0.....'..j+7| -00000080 cc 76 03 e3 93 6e ee 3d 12 d5 cd d7 b2 fc 59 ae |.v...n.=......Y.| -00000090 a5 e5 d5 9d 61 86 0b bf 2c 61 de ef 38 95 de 0c |....a...,a..8...| -000000a0 01 80 15 04 71 15 03 00 00 20 85 70 23 62 cb 0a |....q.... .p#b..| -000000b0 e0 fd f4 36 a6 7d 1a 85 50 36 70 c1 77 85 0d 94 |...6.}..P6p.w...| -000000c0 fd 90 8a eb cd ce a4 b5 d8 fc |..........| diff --git a/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-RC4 b/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-RC4 deleted file mode 100644 index 6feee485acd..00000000000 --- a/libgo/go/crypto/tls/testdata/Server-SSLv3-RSA-RC4 +++ /dev/null @@ -1,72 +0,0 @@ ->>> Flow 1 (client to server) -00000000 16 03 00 00 2f 01 00 00 2b 03 00 d6 26 87 86 f3 |..../...+...&...| -00000010 3f e3 08 85 7a fc 3c fe 91 44 1a 68 9f c8 77 10 |?...z.<..D.h..w.| -00000020 5e af fa b9 e1 09 5f fb fa ad dd 00 00 04 00 05 |^....._.........| -00000030 00 ff 01 00 |....| ->>> Flow 2 (server to client) -00000000 16 03 00 00 31 02 00 00 2d 03 00 00 00 00 00 00 |....1...-.......| -00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 05 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 00 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 00 00 04 0e 00 00 00 |;............| ->>> Flow 3 (client to server) -00000000 16 03 00 00 84 10 00 00 80 d2 67 c1 73 bb 95 8d |..........g.s...| -00000010 b2 e7 30 ca 6c 53 eb f0 34 e5 26 11 0b 91 e9 0a |..0.lS..4.&.....| -00000020 cb 7d 9f d8 f9 01 38 06 01 83 29 a7 1d 69 b8 a1 |.}....8...)..i..| -00000030 1f aa bf 73 1e 26 82 ed 44 f5 82 ec 95 69 88 4b |...s.&..D....i.K| -00000040 b7 ce dd 52 c1 a6 3f be b8 02 23 a5 f3 0c 1e 36 |...R..?...#....6| -00000050 f9 c9 00 1f da e9 d5 38 48 b0 24 5e 25 c1 d4 cb |.......8H.$^%...| -00000060 64 c2 16 ff 94 d6 bd e2 e1 bf 7a 98 d9 77 09 a1 |d.........z..w..| -00000070 c4 f0 99 e6 57 89 02 c8 dd f0 d5 94 d8 44 34 0b |....W........D4.| -00000080 7a 08 52 95 75 20 02 0a 83 14 03 00 00 01 01 16 |z.R.u ..........| -00000090 03 00 00 3c e9 19 7a 94 45 9a b0 ec 3f 8f 1d 19 |...<..z.E...?...| -000000a0 64 65 45 6c e8 4e e3 c8 c8 c6 dc d3 a1 05 cf ea |deEl.N..........| -000000b0 fa cf 59 74 93 84 53 a3 bd 7b f0 07 64 92 ea a2 |..Yt..S..{..d...| -000000c0 f1 2a ea 29 4a 80 c6 99 76 3c 7e c3 f7 b0 e5 e2 |.*.)J...v<~.....| ->>> Flow 4 (server to client) -00000000 14 03 00 00 01 01 16 03 00 00 3c 14 6c 96 8a 5e |..........<.l..^| -00000010 ab 93 c2 65 9b 22 57 31 e6 f1 ce 6a a2 28 31 e8 |...e."W1...j.(1.| -00000020 b5 c3 e7 07 98 2f 0b 40 b7 65 ec 92 f5 60 61 c2 |...../.@.e...`a.| -00000030 25 40 91 2f fa a4 4e 4a ad 7b b3 2a 26 23 d3 04 |%@./..NJ.{.*&#..| -00000040 0f c2 2e 95 82 9d 4b 17 03 00 00 21 5e c6 1e 2c |......K....!^..,| -00000050 49 23 4d 14 b2 87 4b c2 f9 09 17 f0 1a 11 15 50 |I#M...K........P| -00000060 52 d3 85 7b 25 0e e5 2c 7b 74 4b 5e 9d 15 03 00 |R..{%..,{tK^....| -00000070 00 16 6b aa 31 b5 e4 ff 02 0a 39 bc d7 57 51 a1 |..k.1.....9..WQ.| -00000080 42 07 c9 ba 2b 35 26 b7 |B...+5&.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES b/libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES index c5494af7df6..1132b39f4a9 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES +++ b/libgo/go/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES @@ -1,79 +1,80 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 63 01 00 00 5f 03 01 c7 00 ca ac 5f |....c..._......_| -00000010 08 6c a0 aa e8 a0 55 6f fb 20 ae 5d 6c 07 fa 6b |.l....Uo. .]l..k| -00000020 f8 2b 16 e2 46 ce f7 e7 c1 ba 5c 00 00 04 c0 0a |.+..F.....\.....| +00000000 16 03 01 00 63 01 00 00 5f 03 01 38 de f5 d6 ae |....c..._..8....| +00000010 46 71 e8 02 f2 45 88 b8 64 fb 6e 68 67 d1 7f e8 |Fq...E..d.nhg...| +00000020 49 71 1e a9 ec 8e 54 06 bb 2b 16 00 00 04 c0 0a |Iq....T..+......| 00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| 00000060 00 16 00 00 00 17 00 00 |........| >>> Flow 2 (server to client) -00000000 16 03 01 00 31 02 00 00 2d 03 01 00 00 00 00 00 |....1...-.......| +00000000 16 03 01 00 37 02 00 00 33 03 01 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 c0 0a 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 01 02 0e 0b 00 02 0a 00 |................| -00000040 02 07 00 02 04 30 82 02 00 30 82 01 62 02 09 00 |.....0...0..b...| -00000050 b8 bf 2d 47 a0 d2 eb f4 30 09 06 07 2a 86 48 ce |..-G....0...*.H.| -00000060 3d 04 01 30 45 31 0b 30 09 06 03 55 04 06 13 02 |=..0E1.0...U....| -00000070 41 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d |AU1.0...U....Som| -00000080 65 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a |e-State1!0...U..| -00000090 13 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 |..Internet Widgi| -000000a0 74 73 20 50 74 79 20 4c 74 64 30 1e 17 0d 31 32 |ts Pty Ltd0...12| -000000b0 31 31 32 32 31 35 30 36 33 32 5a 17 0d 32 32 31 |1122150632Z..221| -000000c0 31 32 30 31 35 30 36 33 32 5a 30 45 31 0b 30 09 |120150632Z0E1.0.| -000000d0 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 55 |..U....AU1.0...U| -000000e0 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 21 |....Some-State1!| -000000f0 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e 65 |0...U....Interne| -00000100 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c 74 |t Widgits Pty Lt| -00000110 64 30 81 9b 30 10 06 07 2a 86 48 ce 3d 02 01 06 |d0..0...*.H.=...| -00000120 05 2b 81 04 00 23 03 81 86 00 04 00 c4 a1 ed be |.+...#..........| -00000130 98 f9 0b 48 73 36 7e c3 16 56 11 22 f2 3d 53 c3 |...Hs6~..V.".=S.| -00000140 3b 4d 21 3d cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc |;M!=.ku......&..| -00000150 b2 87 f0 72 32 7c b3 64 2f 1c 90 bc ea 68 23 10 |...r2|.d/....h#.| -00000160 7e fe e3 25 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 |~..%.H:i.(m.7...| -00000170 62 dd 0d a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 |b....pb....d1...| -00000180 31 bd 96 b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 |1...h..#.vd?.\..| -00000190 12 0e 58 58 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc |..XX._p.........| -000001a0 b9 b6 9f 30 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 |...0f[f. .'...;0| -000001b0 09 06 07 2a 86 48 ce 3d 04 01 03 81 8c 00 30 81 |...*.H.=......0.| -000001c0 88 02 42 01 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 |..B...O..E.H}...| -000001d0 ed 98 9d ae 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 |....Gp.^../...M.| -000001e0 61 40 d3 11 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b |a@......~.~.v..;| -000001f0 7e a5 3f ce fa 10 e2 59 ec 47 2d 7c ac da 4e 97 |~.?....Y.G-|..N.| -00000200 0e 15 a0 6f d0 02 42 01 4d fc be 67 13 9c 2d 05 |...o..B.M..g..-.| -00000210 0e bd 3f a3 8c 25 c1 33 13 83 0d 94 06 bb d4 37 |..?..%.3.......7| -00000220 7a f6 ec 7a c9 86 2e dd d7 11 69 7f 85 7c 56 de |z..z......i..|V.| -00000230 fb 31 78 2b e4 c7 78 0d ae cb be 9e 4e 36 24 31 |.1x+..x.....N6$1| -00000240 7b 6a 0f 39 95 12 07 8f 2a 16 03 01 00 b4 0c 00 |{j.9....*.......| -00000250 00 b0 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 |..... /.}.G.bC.(| -00000260 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 |.._.).0.........| -00000270 99 5f 58 cb 3b 74 00 8a 30 81 87 02 41 4f 15 dd |._X.;t..0...AO..| -00000280 a7 4a 1e 90 6f f5 4b 31 f7 8f c5 5f 26 60 0c d2 |.J..o.K1..._&`..| -00000290 ab 71 cf e4 3e 20 2e 83 9e 94 00 fc 92 4f 87 43 |.q..> .......O.C| -000002a0 e8 53 2f a3 ee 4a 4e 58 6e d5 5f 11 64 54 de cc |.S/..JNXn._.dT..| -000002b0 ae 83 b1 53 4a 16 1d 14 5c f0 fe 6b c1 7a 02 42 |...SJ...\..k.z.B| -000002c0 00 89 a0 e3 33 70 5f 20 c3 72 e7 93 1a fa b1 49 |....3p_ .r.....I| -000002d0 4a 46 83 f4 a3 88 24 c0 22 72 e6 09 ad a7 bd d1 |JF....$."r......| -000002e0 c8 c1 b3 7c 21 04 dc 67 58 8e 8e d4 bf 2d f3 d7 |...|!..gX....-..| -000002f0 c4 5a 06 d6 c1 65 84 dc 97 5c 0d 6f a4 64 d2 5f |.Z...e...\.o.d._| -00000300 47 99 16 03 01 00 04 0e 00 00 00 |G..........| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 01 02 |................| +00000040 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 00 30 |...........0...0| +00000050 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 30 09 |..b.....-G....0.| +00000060 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 09 06 |..*.H.=..0E1.0..| +00000070 03 55 04 06 13 02 41 55 31 13 30 11 06 03 55 04 |.U....AU1.0...U.| +00000080 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 |...Some-State1!0| +00000090 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 |...U....Internet| +000000a0 20 57 69 64 67 69 74 73 20 50 74 79 20 4c 74 64 | Widgits Pty Ltd| +000000b0 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 33 32 |0...121122150632| +000000c0 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 32 5a |Z..221120150632Z| +000000d0 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 |0E1.0...U....AU1| +000000e0 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 |.0...U....Some-S| +000000f0 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 |tate1!0...U....I| +00000100 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 |nternet Widgits | +00000110 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 2a 86 |Pty Ltd0..0...*.| +00000120 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....| +00000130 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 16 56 |.........Hs6~..V| +00000140 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 f6 b0 |.".=S.;M!=.ku...| +00000150 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 2f 1c |...&.....r2|.d/.| +00000160 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 e0 28 |...h#.~..%.H:i.(| +00000170 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 d8 81 |m.7...b....pb...| +00000180 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 de 76 |.d1...1...h..#.v| +00000190 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd 9b d8 |d?.\....XX._p...| +000001a0 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a 20 e2 |.........0f[f. .| +000001b0 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d 04 01 |'...;0...*.H.=..| +000001c0 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb e2 45 |....0...B...O..E| +000001d0 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e 1b b6 |.H}.......Gp.^..| +000001e0 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b 7e 92 |/...M.a@......~.| +000001f0 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 ec 47 |~.v..;~.?....Y.G| +00000200 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 4d fc |-|..N....o..B.M.| +00000210 be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 13 83 |.g..-...?..%.3..| +00000220 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd d7 11 |.....7z..z......| +00000230 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d ae cb |i..|V..1x+..x...| +00000240 be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f 2a 16 |..N6$1{j.9....*.| +00000250 03 01 00 b5 0c 00 00 b1 03 00 1d 20 2f e5 7d a3 |........... /.}.| +00000260 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...| +00000270 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 8b 30 81 |......._X.;t..0.| +00000280 88 02 42 01 ad 26 fd 16 9a 93 5f 87 ce 29 8c d2 |..B..&...._..)..| +00000290 56 a7 d2 59 56 bd d3 1f 90 54 bd af 91 81 25 ff |V..YV....T....%.| +000002a0 66 74 57 16 2f 31 f2 5a 48 97 03 b9 41 4c 8e bb |ftW./1.ZH...AL..| +000002b0 87 31 ed 71 84 37 63 78 9f 0a c7 9d 5e f3 5a 53 |.1.q.7cx....^.ZS| +000002c0 88 89 46 ba a7 02 42 00 92 74 15 1c 0e 1f 2f 95 |..F...B..t..../.| +000002d0 e5 79 d5 e9 90 ce d8 96 0d fd b8 42 55 00 94 08 |.y.........BU...| +000002e0 4e 47 a9 ea bd 67 0b 02 a6 9e 8b d3 09 e5 53 ea |NG...g........S.| +000002f0 03 22 2e 2d 78 2c 69 1d 28 ab 13 3d 0a 46 15 09 |.".-x,i.(..=.F..| +00000300 b6 0b 74 69 2d 5a 96 bf b6 16 03 01 00 04 0e 00 |..ti-Z..........| +00000310 00 00 |..| >>> Flow 3 (client to server) -00000000 16 03 01 00 25 10 00 00 21 20 91 71 e4 59 10 64 |....%...! .q.Y.d| -00000010 19 77 13 21 9c 60 ee 81 58 ba 41 10 39 61 e0 a7 |.w.!.`..X.A.9a..| -00000020 73 4d ec e8 cd cc b5 e0 cc 6d 14 03 01 00 01 01 |sM.......m......| -00000030 16 03 01 00 30 5c 35 d5 37 46 1e 28 52 32 ed 35 |....0\5.7F.(R2.5| -00000040 44 37 9c ca 83 4c 06 80 ff 17 7c cd 7d e5 22 14 |D7...L....|.}.".| -00000050 0e 70 12 01 f0 e5 ce 5a ca be 41 e2 ee 48 9d 95 |.p.....Z..A..H..| -00000060 c3 51 0c 15 bb |.Q...| +00000000 16 03 01 00 25 10 00 00 21 20 82 c0 dd 83 c2 45 |....%...! .....E| +00000010 a2 bc 3a 2a ec ab 60 8e 02 e0 db 7c 59 83 c1 62 |..:*..`....|Y..b| +00000020 c7 cc 61 1e de dc 40 e4 65 6c 14 03 01 00 01 01 |..a...@.el......| +00000030 16 03 01 00 30 3e 26 56 0b a2 10 47 00 55 27 21 |....0>&V...G.U'!| +00000040 63 33 f2 7d 4b ba 77 5f e7 a7 09 7a 1f 51 85 f2 |c3.}K.w_...z.Q..| +00000050 46 a5 af 80 79 1a c7 72 bb 3d f9 dd 1d 83 05 22 |F...y..r.=....."| +00000060 c9 6c dd 91 d9 |.l...| >>> Flow 4 (server to client) -00000000 14 03 01 00 01 01 16 03 01 00 30 ba 12 b3 9d e1 |..........0.....| -00000010 9a 4d 9d d4 74 50 d7 b0 db 05 68 53 ba 1f 4b 3a |.M..tP....hS..K:| -00000020 b5 c4 91 ee e6 ed d4 e9 07 c7 12 c5 90 42 f5 44 |.............B.D| -00000030 5a 34 59 07 9d fa 8c ec a4 7e 5f 17 03 01 00 20 |Z4Y......~_.... | -00000040 04 58 11 87 90 9b fe ae 63 39 15 07 ec 74 fd 9a |.X......c9...t..| -00000050 15 28 ec b0 75 c4 e8 7a c5 59 73 9c cf 85 75 af |.(..u..z.Ys...u.| -00000060 17 03 01 00 30 24 12 78 fc 37 d4 d8 ec 25 67 38 |....0$.x.7...%g8| -00000070 63 91 68 3a fc 97 26 ab 11 b9 4b 8f 20 8f 75 4f |c.h:..&...K. .uO| -00000080 ca 02 ef 2b 43 b1 4e 7a ed dd dc 36 93 ae 79 6f |...+C.Nz...6..yo| -00000090 c5 8c a2 39 d6 15 03 01 00 20 b0 a0 fb f1 40 b2 |...9..... ....@.| -000000a0 09 00 94 fd b3 f5 98 1e d6 fb e8 96 20 36 bb 4b |............ 6.K| -000000b0 4a 28 fb 51 0e 6e 7b fe 05 48 |J(.Q.n{..H| +00000000 14 03 01 00 01 01 16 03 01 00 30 38 fa fd 42 8f |..........08..B.| +00000010 80 5a 7c 33 d4 6c 72 f7 4e 2f 00 ab c2 86 58 9d |.Z|3.lr.N/....X.| +00000020 fc a5 43 fa ea 5b a1 ee a9 df df 9d 90 4c c0 e3 |..C..[.......L..| +00000030 10 09 c4 23 21 f9 e9 69 f5 f8 fa 17 03 01 00 20 |...#!..i....... | +00000040 1e 57 17 e4 96 06 32 d4 00 a3 98 ed bd 1c 61 78 |.W....2.......ax| +00000050 e7 0d 89 ec 84 c3 56 fa 75 73 87 6f 47 35 80 3f |......V.us.oG5.?| +00000060 17 03 01 00 30 4d 51 0a dd 70 6d b0 c2 d1 46 5c |....0MQ..pm...F\| +00000070 b5 03 87 de e6 65 d3 e2 83 e0 33 f8 a2 0a 29 7f |.....e....3...).| +00000080 6c 24 2b 1f 7b 2b 53 19 21 e9 62 6c 31 75 9c be |l$+.{+S.!.bl1u..| +00000090 5b b0 3d 5b 1a 15 03 01 00 20 19 51 64 4b 5a 9b |[.=[..... .QdKZ.| +000000a0 c8 2a 1c e7 9e 29 d9 df ad 1d 08 09 82 a3 b1 1d |.*...)..........| +000000b0 60 99 00 25 30 51 a1 72 b6 27 |`..%0Q.r.'| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial index 7e6b5bcd676..5f80cb35950 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial +++ b/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial @@ -1,93 +1,94 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 75 01 00 00 71 03 01 7c 54 5c c6 6c |....u...q..|T\.l| -00000010 e9 bc 40 7a 4b 4e 46 5d 0a 37 3b d9 8f d7 97 47 |..@zKNF].7;....G| -00000020 44 42 d4 23 db 0d d2 3b 60 83 c3 00 00 12 c0 0a |DB.#...;`.......| +00000000 16 03 01 00 75 01 00 00 71 03 01 a0 fd 51 a6 77 |....u...q....Q.w| +00000010 69 ee 39 14 8d 0f be a6 9c f7 95 aa 63 14 d2 90 |i.9.........c...| +00000020 1e 39 34 2c df d8 e4 92 2b a0 36 00 00 12 c0 0a |.94,....+.6.....| 00000030 c0 14 00 39 c0 09 c0 13 00 33 00 35 00 2f 00 ff |...9.....3.5./..| 00000040 01 00 00 36 00 00 00 0e 00 0c 00 00 09 31 32 37 |...6.........127| 00000050 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 00 0a |.0.0.1..........| 00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#| 00000070 00 00 00 16 00 00 00 17 00 00 |..........| >>> Flow 2 (server to client) -00000000 16 03 01 00 35 02 00 00 31 03 01 00 00 00 00 00 |....5...1.......| +00000000 16 03 01 00 3b 02 00 00 37 03 01 00 00 00 00 00 |....;...7.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 c0 14 00 00 |...DOWNGRD......| -00000030 09 00 23 00 00 ff 01 00 01 00 16 03 01 02 59 0b |..#...........Y.| -00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| -00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| -00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| -00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| -00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| -00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| -000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| -000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| -000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| -000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| -000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| -000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| -00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| -00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| -00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| -00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| -00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| -00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| -00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| -00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| -00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| -00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| -000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| -000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| -000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| -000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| -000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| -000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| -00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| -00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| -00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| -00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| -00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | -00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| -00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| -00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| -00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| -00000290 84 5c 21 d3 3b e9 fa e7 16 03 01 00 aa 0c 00 00 |.\!.;...........| -000002a0 a6 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 da |.... /.}.G.bC.(.| -000002b0 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........| -000002c0 5f 58 cb 3b 74 00 80 67 06 ef c8 04 2d a2 ae 6b |_X.;t..g....-..k| -000002d0 4f 9b d7 94 aa a4 db dc 37 65 ac c5 49 96 7e 48 |O.......7e..I.~H| -000002e0 0f ea 82 62 d9 74 c8 e2 b4 20 72 77 b9 c1 b3 72 |...b.t... rw...r| -000002f0 4c 67 78 4b c9 4d 98 63 6d b7 df 16 43 65 d1 37 |LgxK.M.cm...Ce.7| -00000300 41 48 a3 4e 75 59 83 b9 7a 10 78 d3 84 d9 21 54 |AH.NuY..z.x...!T| -00000310 c2 86 b3 45 22 e7 e1 35 b7 74 0b 96 fc 7e 81 fa |...E"..5.t...~..| -00000320 27 9e 44 8b a7 87 b3 cb 39 d9 7f d2 dc 7f 98 f1 |'.D.....9.......| -00000330 45 34 cb c1 73 6a 1d 3e 01 f6 0b 9a 26 cf 48 d7 |E4..sj.>....&.H.| -00000340 ef 56 f2 fb 75 c3 af 16 03 01 00 04 0e 00 00 00 |.V..u...........| +00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............| +00000040 16 03 01 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0| +00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............| +00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..| +00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.| +00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....| +00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010| +000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101| +000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U| +000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...| +000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...| +000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......| +000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.| +00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B| +00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.| +00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t| +00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l| +00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.| +00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....| +00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.| +00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U| +00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U| +00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......| +000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.| +000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...| +000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..| +000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...| +000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{| +000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa| +00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*| +00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0| +00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(| +00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C| +00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..| +00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.| +00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.| +00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr| +00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B| +00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| +000002a0 01 00 aa 0c 00 00 a6 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G| +000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....| +000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 80 00 9f b3 |......_X.;t.....| +000002d0 fa c1 71 14 e3 1a 6c 3f b6 61 15 e2 7b 99 c5 4c |..q...l?.a..{..L| +000002e0 39 e0 45 f8 9d d3 84 1a c4 fc 7c 51 32 3d 67 0b |9.E.......|Q2=g.| +000002f0 28 b8 8c 6d 66 7e ab 82 c9 f6 d0 49 62 96 2c af |(..mf~.....Ib.,.| +00000300 4f 0a d1 21 54 b8 3e ae 09 fd d8 85 10 cb da c4 |O..!T.>.........| +00000310 6f 42 16 cd 70 cd 33 b0 a5 e5 a1 c7 9a 35 41 3f |oB..p.3......5A?| +00000320 59 db a1 b3 f4 ae f6 72 9c a8 db f5 86 99 43 b3 |Y......r......C.| +00000330 8f bc 0f d9 0a 50 49 58 3b 17 fa 51 27 11 e9 95 |.....PIX;..Q'...| +00000340 8c bb 1a 31 11 bc a2 fa 2c 6b c2 6a 40 16 03 01 |...1....,k.j@...| +00000350 00 04 0e 00 00 00 |......| >>> Flow 3 (client to server) -00000000 16 03 01 00 25 10 00 00 21 20 67 7e 47 91 48 7e |....%...! g~G.H~| -00000010 09 88 9e e7 6c 17 a8 36 3a fb b8 bf f3 1d 51 01 |....l..6:.....Q.| -00000020 b1 b4 fb 16 a6 9c 19 74 a0 65 14 03 01 00 01 01 |.......t.e......| -00000030 16 03 01 00 30 f5 06 6c 15 ad 06 45 cc 5d 12 67 |....0..l...E.].g| -00000040 93 63 e8 50 b5 df f8 75 9d 67 e6 45 92 26 a4 60 |.c.P...u.g.E.&.`| -00000050 3a fe 2e 75 6f 8b a9 da de 12 7d 61 05 b7 50 32 |:..uo.....}a..P2| -00000060 e9 c9 ab 46 e9 |...F.| +00000000 16 03 01 00 25 10 00 00 21 20 bf 0c 33 f5 6a 06 |....%...! ..3.j.| +00000010 18 0a 74 ad 8b bd ef 9c 00 a3 c0 03 20 5b ea 69 |..t......... [.i| +00000020 09 18 b8 4a 30 13 c7 10 30 3a 14 03 01 00 01 01 |...J0...0:......| +00000030 16 03 01 00 30 04 6d f7 66 e9 7f 72 80 32 24 93 |....0.m.f..r.2$.| +00000040 2f 74 5e 34 c5 fb 19 a0 64 31 1e cb 63 03 fb 51 |/t^4....d1..c..Q| +00000050 5c d9 17 a8 b0 8a b6 74 e8 84 86 a5 33 d2 75 4a |\......t....3.uJ| +00000060 c0 bb 6a bb f3 |..j..| >>> Flow 4 (server to client) 00000000 16 03 01 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6d ec a4 83 61 7c 54 a3 1a 2d bb 5f f0 10 99 e1 |m...a|T..-._....| -00000040 34 de 77 7f ee 2f ff 04 6d d3 d3 ef 66 e2 2d d1 |4.w../..m...f.-.| -00000050 6b 50 30 3c e0 24 e6 22 e3 f2 26 f3 d1 d7 4d ae |kP0<.$."..&...M.| -00000060 d3 7e 7f fa 1a 33 94 ef bd 3f 22 57 45 75 6c 1f |.~...3...?"WEul.| -00000070 fe ca 44 27 c1 20 14 cb 42 92 2d db 34 38 dc 50 |..D'. ..B.-.48.P| -00000080 3f a0 52 a0 78 7f ca 14 03 01 00 01 01 16 03 01 |?.R.x...........| -00000090 00 30 fe 05 cc db 6f b4 2b 94 01 56 c0 5e 6e cf |.0....o.+..V.^n.| -000000a0 29 b0 4d dc 74 ec a7 f6 68 2c 33 d9 cb f5 92 8b |).M.t...h,3.....| -000000b0 35 d3 e4 21 a1 a8 dc 4b a7 a3 97 8d a8 3b 55 21 |5..!...K.....;U!| -000000c0 17 bd 17 03 01 00 20 15 02 68 3e 6a 6f b8 4d bf |...... ..h>jo.M.| -000000d0 1b ef b3 0f 52 a0 9d 07 8f ae 57 50 a0 94 06 9b |....R.....WP....| -000000e0 29 d7 c9 4c 5d ad 50 17 03 01 00 30 ab 31 2f 85 |)..L].P....0.1/.| -000000f0 32 54 67 03 49 3c 25 00 9d b0 17 1d 90 07 ca e2 |2Tg.I<%.........| -00000100 6c 7e b9 cf 5a ea 7c 10 e4 9a 0c cf 0e fc 7d 4a |l~..Z.|.......}J| -00000110 f6 17 0d dc 5b be 3f cb 78 90 9b 87 15 03 01 00 |....[.?.x.......| -00000120 20 ab 1d cf 80 17 58 01 98 e7 c1 39 81 9f f5 18 | .....X....9....| -00000130 3e 88 30 81 64 62 36 89 8b e9 06 55 2b d3 ee 85 |>.0.db6....U+...| -00000140 b9 |.| +00000030 6d ec a4 83 61 28 8e b8 1b 0e dd 7d 71 4a 36 c3 |m...a(.....}qJ6.| +00000040 6d cb c7 88 ed 19 c5 08 72 b9 25 fb 6c 29 b8 b2 |m.......r.%.l)..| +00000050 72 f8 27 c0 1e f2 86 16 54 0f 72 a9 6e 15 69 9e |r.'.....T.r.n.i.| +00000060 66 fe d1 05 20 33 94 32 40 82 bb e3 61 47 3a 8e |f... 3.2@...aG:.| +00000070 b7 45 92 8a 5c 84 64 eb 6c 1a 3c bb 2f be ce b2 |.E..\.d.l.<./...| +00000080 5f cb c9 be c4 ff d6 14 03 01 00 01 01 16 03 01 |_...............| +00000090 00 30 5e ff 91 82 d5 30 a4 fb cd 20 90 c1 2d 08 |.0^....0... ..-.| +000000a0 aa 19 d6 72 fa 74 07 95 df 14 eb 59 bb 0c 81 3f |...r.t.....Y...?| +000000b0 75 77 45 96 d8 3e 45 a7 42 1c f1 82 c0 04 4d 2e |uwE..>E.B.....M.| +000000c0 3f 07 17 03 01 00 20 54 90 60 76 16 5f 6b d0 3e |?..... T.`v._k.>| +000000d0 f6 bf f3 0a 5c b9 3b 19 cb df a6 94 28 04 24 ea |....\.;.....(.$.| +000000e0 73 1f 49 5e 23 f6 91 17 03 01 00 30 b5 97 eb 85 |s.I^#......0....| +000000f0 cc 17 86 b0 0d 24 bf 64 6d 4f 16 55 b0 f3 64 7c |.....$.dmO.U..d|| +00000100 75 3f e4 16 94 41 56 64 12 50 0e 7c 0c 1c e7 58 |u?...AVd.P.|...X| +00000110 4d 9c 82 d8 f5 5a 61 a3 d8 3c f5 04 15 03 01 00 |M....Za..<......| +00000120 20 59 6c e6 9e 4e 14 94 5d 61 94 b2 ba 0f eb 18 | Yl..N..]a......| +00000130 cf 10 5b f6 90 27 58 8e 10 54 36 d4 c7 52 37 2e |..[..'X..T6..R7.| +00000140 a0 |.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES b/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES index 10fade15333..502fd284a07 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES +++ b/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-3DES @@ -1,75 +1,76 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 63 01 00 00 5f 03 01 33 4b 5c 08 a3 |....c..._..3K\..| -00000010 64 52 8d 1f c9 55 bd 2e 03 e8 9d 88 f4 ff c0 35 |dR...U.........5| -00000020 33 ad d0 aa 7d f6 2d 42 0c c4 85 00 00 04 00 0a |3...}.-B........| +00000000 16 03 01 00 63 01 00 00 5f 03 01 25 03 63 bf 34 |....c..._..%.c.4| +00000010 89 c8 9e f6 e0 46 f8 30 5c e8 62 0a f7 db 68 c9 |.....F.0\.b...h.| +00000020 50 54 0e c2 15 f1 cb 07 66 06 3d 00 00 04 00 0a |PT......f.=.....| 00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| 00000060 00 16 00 00 00 17 00 00 |........| >>> Flow 2 (server to client) -00000000 16 03 01 00 31 02 00 00 2d 03 01 00 00 00 00 00 |....1...-.......| +00000000 16 03 01 00 37 02 00 00 33 03 01 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 0a 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 01 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 01 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 01 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 01 00 86 10 00 00 82 00 80 69 ea b8 fd 3a |...........i...:| -00000010 76 cb 76 4d b2 7a 0e 61 4d 9d 9e 26 13 02 07 aa |v.vM.z.aM..&....| -00000020 31 94 01 9f 57 00 80 f1 aa 75 06 09 65 42 c7 c8 |1...W....u..eB..| -00000030 6d ea 8c 75 4e 69 35 d2 84 71 89 5a 44 f6 15 91 |m..uNi5..q.ZD...| -00000040 b0 a9 e1 ff 65 0a 51 fe 06 a3 2d eb cb 33 6e 07 |....e.Q...-..3n.| -00000050 dd 2f 02 fe d3 ec 89 7c 87 48 27 eb d8 8c 4c 6d |./.....|.H'...Lm| -00000060 95 4c 6f 8a a8 a0 fe 59 d6 a4 b4 7a a5 48 aa f1 |.Lo....Y...z.H..| -00000070 37 95 1d 4d 18 ee b0 a7 aa ca a8 18 65 83 8e 26 |7..M........e..&| -00000080 05 9c d6 76 ff 9b 40 65 b7 2e 47 14 03 01 00 01 |...v..@e..G.....| -00000090 01 16 03 01 00 28 fa 03 ae d2 47 ef 75 4e 99 79 |.....(....G.uN.y| -000000a0 69 87 be 5e 61 1f 0f 09 65 56 31 08 09 38 34 1b |i..^a...eV1..84.| -000000b0 41 6a 9e 2c 3b a9 11 62 34 a8 58 bc 1d 92 |Aj.,;..b4.X...| +00000000 16 03 01 00 86 10 00 00 82 00 80 0f e9 83 ca 77 |...............w| +00000010 c8 26 16 24 00 b7 09 d2 73 aa c1 d9 77 f3 fc 38 |.&.$....s...w..8| +00000020 1c 2e c0 26 b4 a6 40 e1 1b 93 39 8f a2 1f f2 f9 |...&..@...9.....| +00000030 18 2a 7b 0e cd 9b 9b 9c 49 86 43 3d 48 fd 40 d7 |.*{.....I.C=H.@.| +00000040 af f9 2b 5e c6 cc c6 2d 8d 36 fe b1 75 c1 b5 a0 |..+^...-.6..u...| +00000050 57 97 0f 01 ee b4 6a af 0c fe f0 68 78 04 6a 3e |W.....j....hx.j>| +00000060 83 d0 72 34 80 d8 7d cd 8b 83 06 5b 36 50 10 8e |..r4..}....[6P..| +00000070 b4 27 3d 6a ae b7 7f 8b 2a b1 0b 51 49 05 b5 01 |.'=j....*..QI...| +00000080 3c 27 9a 59 e3 41 18 38 d6 8f 7a 14 03 01 00 01 |<'.Y.A.8..z.....| +00000090 01 16 03 01 00 28 c0 46 65 9f 7f d8 c3 c4 a7 33 |.....(.Fe......3| +000000a0 50 f9 07 41 95 12 a6 f3 ca 53 b9 96 f8 a8 a6 5f |P..A.....S....._| +000000b0 1e c8 20 e5 8b 87 4e 12 73 13 e0 e4 c6 89 |.. ...N.s.....| >>> Flow 4 (server to client) -00000000 14 03 01 00 01 01 16 03 01 00 28 a4 c5 9f 93 86 |..........(.....| -00000010 fe 08 22 16 05 20 81 e3 a3 38 74 5d 32 24 41 50 |..".. ...8t]2$AP| -00000020 f4 e4 6b dd 92 0b d6 77 86 44 32 f9 2d f0 52 0e |..k....w.D2.-.R.| -00000030 c4 98 02 17 03 01 00 18 20 ee 92 bf 46 ce 52 ed |........ ...F.R.| -00000040 ac 85 df cd 2a a7 c1 6c 82 be ed 55 9e 55 25 b2 |....*..l...U.U%.| -00000050 17 03 01 00 28 b0 45 3d 83 94 79 d1 a5 a3 b0 0a |....(.E=..y.....| -00000060 59 63 13 62 1e 66 c2 69 4d a4 8d e0 fb 87 cb dc |Yc.b.f.iM.......| -00000070 5e 51 49 05 82 4d d6 1e 40 78 f0 cd 4b 15 03 01 |^QI..M..@x..K...| -00000080 00 18 38 0e 60 43 55 25 82 d2 4c 97 cf cd a9 7a |..8.`CU%..L....z| -00000090 e8 8a 4a eb c1 8d 54 cb e6 92 |..J...T...| +00000000 14 03 01 00 01 01 16 03 01 00 28 e2 47 2b 57 fe |..........(.G+W.| +00000010 74 71 95 6a ee 68 2b f3 48 40 13 52 35 46 58 d4 |tq.j.h+.H@.R5FX.| +00000020 ee aa 4c a8 53 0f 3a 19 ed 18 37 2d e4 b9 1e e6 |..L.S.:...7-....| +00000030 28 42 a1 17 03 01 00 18 d8 7c 20 f2 03 6d a9 ed |(B.......| ..m..| +00000040 c9 73 50 d7 56 4f 0b d8 4b 44 f6 80 e4 c1 a9 f5 |.sP.VO..KD......| +00000050 17 03 01 00 28 f5 b2 11 6b a6 4b 22 30 42 3c cc |....(...k.K"0B<.| +00000060 07 0d ed 10 d0 c7 7b ec b3 60 0b 2b 3c fb ec 3a |......{..`.+<..:| +00000070 c0 be 44 e7 76 b6 9e db 17 36 92 df 88 15 03 01 |..D.v....6......| +00000080 00 18 7a d9 2f 46 2e 0f ec c5 ee 7b ef bd fb e5 |..z./F.....{....| +00000090 26 40 0a a2 4e eb 56 0e ca 03 |&@..N.V...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES b/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES index 10fc9f06238..74253765453 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES +++ b/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-AES @@ -1,78 +1,79 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 63 01 00 00 5f 03 01 a1 4c 20 79 0a |....c..._...L y.| -00000010 35 d6 8b 7d e7 f2 3e eb bd c2 72 73 a9 18 c2 9b |5..}..>...rs....| -00000020 8a a0 b6 ae 17 21 df 6f d0 b0 f8 00 00 04 00 2f |.....!.o......./| +00000000 16 03 01 00 63 01 00 00 5f 03 01 78 91 f6 ad 9e |....c..._..x....| +00000010 79 23 92 10 d9 c5 43 52 8f f6 f4 3f f4 eb ac 6b |y#....CR...?...k| +00000020 f3 ce a9 76 a2 bf c3 5b 9d bc 52 00 00 04 00 2f |...v...[..R..../| 00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| 00000060 00 16 00 00 00 17 00 00 |........| >>> Flow 2 (server to client) -00000000 16 03 01 00 31 02 00 00 2d 03 01 00 00 00 00 00 |....1...-.......| +00000000 16 03 01 00 37 02 00 00 33 03 01 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 01 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 01 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 01 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 01 00 86 10 00 00 82 00 80 95 ba 78 12 0e |.............x..| -00000010 c1 98 6b 93 f6 7d bd f4 8c 77 de 0a 0a 2a 6e 25 |..k..}...w...*n%| -00000020 18 a9 eb 41 c2 c0 63 26 82 7a ea 84 ad cc e8 e2 |...A..c&.z......| -00000030 d8 f1 20 e4 fb 39 87 b8 47 f3 8a 6c 9f b6 08 13 |.. ..9..G..l....| -00000040 b0 76 99 65 cf 68 87 c4 e7 54 ff 6d 5f 81 f2 9f |.v.e.h...T.m_...| -00000050 57 1d 21 e8 ed aa 50 17 e7 85 a5 74 6e 9c cc 84 |W.!...P....tn...| -00000060 bb 06 11 ec 67 8b dc cd 7a 31 4c 08 f4 16 5f d5 |....g...z1L..._.| -00000070 07 0d 17 aa 00 56 51 6a 4c f5 9d 81 40 27 77 45 |.....VQjL...@'wE| -00000080 78 4d 68 6d 96 f7 28 c8 bd 18 b1 14 03 01 00 01 |xMhm..(.........| -00000090 01 16 03 01 00 30 df 7f 74 cd e8 0f 09 06 dd a5 |.....0..t.......| -000000a0 84 46 db ad 71 85 1a 0d e5 f1 d2 f0 2a b2 ef bb |.F..q.......*...| -000000b0 0b 79 88 ab ad 39 6d 4b 16 ae 0e 07 9b 9c 3a ea |.y...9mK......:.| -000000c0 b9 4b 8a 4b 73 06 |.K.Ks.| +00000000 16 03 01 00 86 10 00 00 82 00 80 73 aa be d1 21 |...........s...!| +00000010 67 e9 9c 20 40 cf 0a 47 31 61 e9 2b ba 06 4f aa |g.. @..G1a.+..O.| +00000020 ce 15 6a b7 df 0d 0e b0 fe b5 f2 c0 26 81 39 6e |..j.........&.9n| +00000030 5b 96 3c 2f 42 4f 08 92 48 a3 95 c8 ad 0d 0e 8f |[....2.>....| +00000080 36 99 9f b7 53 ef 34 e8 d6 13 3b 14 03 01 00 01 |6...S.4...;.....| +00000090 01 16 03 01 00 30 c6 d2 a6 85 cf 2a e4 9e 9e e1 |.....0.....*....| +000000a0 d0 82 d0 2a f8 e5 bd f6 9a 67 0b c6 47 07 9c 14 |...*.....g..G...| +000000b0 7e 73 9e 4c 8b d2 55 4f b2 32 9a 16 16 a5 e8 25 |~s.L..UO.2.....%| +000000c0 62 e2 e9 88 b6 44 |b....D| >>> Flow 4 (server to client) -00000000 14 03 01 00 01 01 16 03 01 00 30 cd 95 e4 10 a8 |..........0.....| -00000010 1b dd 36 80 7c 9e 04 23 4c 23 57 0a 57 cf 9a 2e |..6.|..#L#W.W...| -00000020 07 6d 81 b0 27 f8 5c cc 3b a8 80 40 38 be e0 27 |.m..'.\.;..@8..'| -00000030 25 ed f2 7d b9 5e a0 76 68 f8 06 17 03 01 00 20 |%..}.^.vh...... | -00000040 9c 12 9d 3b a0 e5 04 8b 78 44 bc 80 68 22 2b 4c |...;....xD..h"+L| -00000050 64 f1 ca 5c 83 eb 27 e7 29 ad cc 7d d5 e6 ec 1d |d..\..'.)..}....| -00000060 17 03 01 00 30 6e 42 31 b0 3d 46 7d e6 08 8c 43 |....0nB1.=F}...C| -00000070 ea 48 53 34 29 b4 6e ac 2e c4 1f a3 fb fa 70 d5 |.HS4).n.......p.| -00000080 36 9b 94 4f 6f 3f 00 fa e3 f4 4b e6 b3 f2 0d e2 |6..Oo?....K.....| -00000090 0f 60 e4 34 4d 15 03 01 00 20 21 a1 22 a3 e1 71 |.`.4M.... !."..q| -000000a0 ab 28 89 7c 12 ed 12 f7 3e 8a 9a 0e c0 f5 2b 2e |.(.|....>.....+.| -000000b0 91 bd 3f 05 ff 48 1c 3c b5 af |..?..H.<..| +00000000 14 03 01 00 01 01 16 03 01 00 30 21 7a ee 62 6a |..........0!z.bj| +00000010 20 39 2a 39 d1 d3 f7 bd 53 05 4f 1a 36 71 3b b6 | 9*9....S.O.6q;.| +00000020 c5 5a b7 3b c3 0b 3f b9 2f ac 62 1c c2 2f fa 29 |.Z.;..?./.b../.)| +00000030 dd f3 bc ff 35 28 7f 86 b8 0f 33 17 03 01 00 20 |....5(....3.... | +00000040 3a 6c 47 23 37 5a 15 bd 03 c6 64 c5 59 2f 91 e8 |:lG#7Z....d.Y/..| +00000050 a6 1b d5 04 c2 a7 80 0e 94 6c 3c e4 70 2c ea 81 |.........l<.p,..| +00000060 17 03 01 00 30 60 14 bc 6b 84 16 9f 53 b6 ee c9 |....0`..k...S...| +00000070 43 cf f3 46 97 45 e1 2f 86 96 26 cc ef ea 09 72 |C..F.E./..&....r| +00000080 36 92 4e 9e 2a 8e a2 d7 9a cd 5f 38 a8 07 c4 54 |6.N.*....._8...T| +00000090 a1 4d 6e 7a 36 15 03 01 00 20 1e c2 df a3 3e 8e |.Mnz6.... ....>.| +000000a0 15 c4 c0 90 8f 7c 5a e0 68 d7 ea 86 76 8d d1 27 |.....|Z.h...v..'| +000000b0 c1 d9 32 55 f9 ce f5 92 e6 51 |..2U.....Q| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4 b/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4 index cbf41d5c3a1..8b1de03b0c0 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv10-RSA-RC4 @@ -1,72 +1,73 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 63 01 00 00 5f 03 01 79 6a d2 2d 89 |....c..._..yj.-.| -00000010 ce 1b 74 2f fd 6b ea e2 2d 21 56 0d e9 37 ce b9 |..t/.k..-!V..7..| -00000020 bc 96 ef 0c 71 66 7a 3b 13 3a 6b 00 00 04 00 05 |....qfz;.:k.....| +00000000 16 03 01 00 63 01 00 00 5f 03 01 55 31 1a ed 02 |....c..._..U1...| +00000010 35 fe 3c ea 62 08 52 96 93 bc 2a 1b 82 fe b9 8f |5.<.b.R...*.....| +00000020 7a 47 0e 6a 9b e8 86 ca 89 a0 e6 00 00 04 00 05 |zG.j............| 00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| 00000060 00 16 00 00 00 17 00 00 |........| >>> Flow 2 (server to client) -00000000 16 03 01 00 31 02 00 00 2d 03 01 00 00 00 00 00 |....1...-.......| +00000000 16 03 01 00 37 02 00 00 33 03 01 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 05 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 01 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 01 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 01 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 01 00 86 10 00 00 82 00 80 d4 da 80 53 5a |..............SZ| -00000010 4c fc 0b c3 91 a0 b4 91 24 5a 6b 59 01 fa 05 52 |L.......$ZkY...R| -00000020 cb 37 8c de 51 58 d7 ac 24 e2 d3 ac ad e6 00 0f |.7..QX..$.......| -00000030 72 50 a4 81 c3 18 ef f9 cb 0f 8b 6a cd e5 0e 46 |rP.........j...F| -00000040 9a f1 3c 61 ed 31 d4 c0 35 61 14 1e e8 b5 0c b2 |..>> Flow 4 (server to client) -00000000 14 03 01 00 01 01 16 03 01 00 24 0a 1c be 60 96 |..........$...`.| -00000010 78 67 15 22 ac 38 39 87 80 f5 69 2b 08 32 01 23 |xg.".89...i+.2.#| -00000020 e0 96 b3 89 8c 57 5f e4 27 33 66 90 b9 47 bc 17 |.....W_.'3f..G..| -00000030 03 01 00 21 fd 10 f3 e3 e6 14 bf b2 72 ab f0 bb |...!........r...| -00000040 11 04 54 da cd 93 03 14 78 2c 26 32 44 2c 0c e8 |..T.....x,&2D,..| -00000050 7e 56 25 83 0f 15 03 01 00 16 0c 26 07 14 19 aa |~V%........&....| -00000060 7e 78 bf 39 96 07 44 3d a9 c6 50 7d dc c9 de f5 |~x.9..D=..P}....| +00000000 14 03 01 00 01 01 16 03 01 00 24 57 fc eb dd 40 |..........$W...@| +00000010 83 1d 9a 9a 80 a3 62 a0 08 23 c3 97 fd d5 fb d7 |......b..#......| +00000020 98 f8 14 ae 61 c7 21 fb 8a 18 1e c8 15 05 e7 17 |....a.!.........| +00000030 03 01 00 21 7c 2b 2d 72 2f 63 56 3a 09 51 4e ab |...!|+-r/cV:.QN.| +00000040 31 25 c8 7e 34 5b a4 ab 30 87 50 07 ed 32 3f 79 |1%.~4[..0.P..2?y| +00000050 f1 db c0 17 f3 15 03 01 00 16 fc ce c9 0c b6 0c |................| +00000060 c5 2d d9 3f 2a 9e 9a 83 40 e1 a3 b9 5f 89 aa 75 |.-.?*...@..._..u| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4 b/libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4 index 22e2291c54b..dc70edf94b3 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv11-RSA-RC4 @@ -1,72 +1,73 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 63 01 00 00 5f 03 02 ea cf 4a b4 40 |....c..._....J.@| -00000010 33 f1 d3 b2 c1 2a f6 d6 bb 3f 48 8c 1a d2 40 0f |3....*...?H...@.| -00000020 4a 1e e8 07 8a 06 19 45 6a 02 cb 00 00 04 00 05 |J......Ej.......| +00000000 16 03 01 00 63 01 00 00 5f 03 02 2b b6 22 28 e3 |....c..._..+."(.| +00000010 1f 42 f4 2e d0 43 4b 9a ea 2b 36 44 ca 93 6c 71 |.B...CK..+6D..lq| +00000020 b9 4d 52 44 64 57 b2 05 9b 41 da 00 00 04 00 05 |.MRDdW...A......| 00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| 00000060 00 16 00 00 00 17 00 00 |........| >>> Flow 2 (server to client) -00000000 16 03 02 00 31 02 00 00 2d 03 02 00 00 00 00 00 |....1...-.......| +00000000 16 03 02 00 37 02 00 00 33 03 02 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 05 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 02 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 02 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 02 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 02 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 02 00 86 10 00 00 82 00 80 a2 98 fb e6 12 |................| -00000010 7d 1c 3c de 04 9c 01 11 41 69 a4 e3 74 62 88 36 |}.<.....Ai..tb.6| -00000020 97 b5 28 14 6a 6d 27 1b 7d 27 0f fd 5b 76 07 3f |..(.jm'.}'..[v.?| -00000030 3e 99 21 93 46 9d 2c a0 4c d9 54 25 70 11 b8 ac |>.!.F.,.L.T%p...| -00000040 8e 5c 29 31 2c b2 39 92 10 32 dc b0 60 af 2e d4 |.\)1,.9..2..`...| -00000050 b3 f7 ba 44 0a 6c e2 4b 38 18 4b 51 60 1b a5 0d |...D.l.K8.KQ`...| -00000060 bf ec 00 fb fd 53 1f 6e b5 eb cd 32 1b 15 e9 ea |.....S.n...2....| -00000070 5c 93 72 dc 67 94 39 ed 2d 1e 6f f9 10 da 79 50 |\.r.g.9.-.o...yP| -00000080 e1 d2 db 6f 34 38 d1 fb 2c 38 cb 14 03 02 00 01 |...o48..,8......| -00000090 01 16 03 02 00 24 b4 29 aa 9d 48 a3 59 07 f8 a8 |.....$.)..H.Y...| -000000a0 f0 aa aa 0f 63 dd 0e ca d6 20 45 6d 88 ba 52 e2 |....c.... Em..R.| -000000b0 f9 cd 2f 25 d3 88 b1 a6 cf 9d |../%......| +00000000 16 03 02 00 86 10 00 00 82 00 80 3d 47 85 0a ef |...........=G...| +00000010 47 7c c5 93 bb 6f 7c 57 dc 2b 3f f4 e7 da 4e fc |G|...o|W.+?...N.| +00000020 04 52 36 71 c5 63 1f 6f e6 43 91 06 bc 5c 14 b0 |.R6q.c.o.C...\..| +00000030 ee 83 ed 3d 7a d2 4e 2c d2 2c bb f0 0c b5 82 d5 |...=z.N,.,......| +00000040 9d c2 5a 03 12 b6 70 20 3c 89 84 af 1b 2c 2f b7 |..Z...p <....,/.| +00000050 9b fe dd 71 06 ac 46 30 a7 b5 9f 0b aa 6e 58 50 |...q..F0.....nXP| +00000060 9d da 6b ba 00 51 e9 2a e9 d2 e9 0f 83 62 73 19 |..k..Q.*.....bs.| +00000070 91 a4 46 bd 53 42 f7 15 ab ab 6b 8f f3 6f d1 07 |..F.SB....k..o..| +00000080 44 41 97 4c 7d 89 4b 33 55 30 30 14 03 02 00 01 |DA.L}.K3U00.....| +00000090 01 16 03 02 00 24 54 fe a0 7c 16 47 de 0b 8f 7d |.....$T..|.G...}| +000000a0 51 68 05 da 1e 6d 96 c9 e1 94 68 fa 79 46 02 db |Qh...m....h.yF..| +000000b0 03 4e 2e 70 9f 7e 14 85 fd 1d |.N.p.~....| >>> Flow 4 (server to client) -00000000 14 03 02 00 01 01 16 03 02 00 24 cc 9a e8 46 cc |..........$...F.| -00000010 e5 45 8c f6 aa 71 28 f7 1b 2a 51 f8 33 c3 08 a3 |.E...q(..*Q.3...| -00000020 cd 72 7d 38 a9 d1 6f b8 c6 ce ef ae 4f 3d 50 17 |.r}8..o.....O=P.| -00000030 03 02 00 21 e1 9b 1e f6 56 28 6d 78 53 96 a4 41 |...!....V(mxS..A| -00000040 7b a8 15 29 74 40 b5 f4 d3 ae b7 8b b2 01 53 dd |{..)t@........S.| -00000050 45 bf 3a 55 9d 15 03 02 00 16 cb a8 cb 98 ac 0d |E.:U............| -00000060 1c eb aa c4 2a 71 65 aa b4 c9 d7 90 f7 88 3b b0 |....*qe.......;.| +00000000 14 03 02 00 01 01 16 03 02 00 24 4b c5 cf 20 3f |..........$K.. ?| +00000010 0a 13 1f 55 25 26 9b 33 fd 14 61 0f 44 32 26 b3 |...U%&.3..a.D2&.| +00000020 ab 01 ee c2 1f d3 38 08 f0 af 76 6a 0d e1 b7 17 |......8...vj....| +00000030 03 02 00 21 97 16 df 99 06 81 f2 00 d3 fd b4 03 |...!............| +00000040 be 16 b6 aa 74 d4 c7 25 67 94 14 34 25 ec 0d 12 |....t..%g..4%...| +00000050 c7 43 2d a2 1d 15 03 02 00 16 94 58 af 6b 55 5f |.C-........X.kU_| +00000060 25 0c 80 28 99 2d 75 1a ce 24 cd 75 0d 7f b9 71 |%..(.-u..$.u...q| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN index 0d9f63b0066..f6ddb972f6d 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e3 01 00 00 df 03 03 24 c0 b7 bd da |...........$....| -00000010 2a 23 bd 6f a0 8f 94 be 7c 14 56 ad fd a8 87 3f |*#.o....|.V....?| -00000020 c1 97 38 14 7a d4 30 28 11 c4 b5 00 00 38 c0 2c |..8.z.0(.....8.,| +00000000 16 03 01 00 e3 01 00 00 df 03 03 e7 33 0d 6a 2d |............3.j-| +00000010 87 bc b4 a1 11 ee 1a 4e 91 f5 fb ad 29 70 d4 6d |.......N....)p.m| +00000020 05 be ec f3 e2 b1 0d 4e da a4 b5 00 00 38 c0 2c |.......N.....8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| @@ -15,82 +15,83 @@ 000000d0 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................| 000000e0 02 02 04 02 05 02 06 02 |........| >>> Flow 2 (server to client) -00000000 16 03 03 00 42 02 00 00 3e 03 03 00 00 00 00 00 |....B...>.......| +00000000 16 03 03 00 48 02 00 00 44 03 03 00 00 00 00 00 |....H...D.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 30 00 00 |...DOWNGRD...0..| -00000030 16 00 23 00 00 ff 01 00 01 00 00 10 00 09 00 07 |..#.............| -00000040 06 70 72 6f 74 6f 31 16 03 03 02 59 0b 00 02 55 |.proto1....Y...U| -00000050 00 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 |..R..O0..K0.....| -00000060 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d |.........?.[..0.| -00000070 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 |..*.H........0.1| -00000080 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e |.0...U....Go1.0.| -00000090 06 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e |..U....Go Root0.| -000000a0 17 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 |..160101000000Z.| -000000b0 0d 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a |.250101000000Z0.| -000000c0 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 |1.0...U....Go1.0| -000000d0 09 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 |...U....Go0..0..| -000000e0 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 |.*.H............| -000000f0 30 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 |0.......F}...'.H| -00000100 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a |..(!.~...]..RE.z| -00000110 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 |6G....B[.....y.@| -00000120 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e |.Om..+.....g....| -00000130 d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 |."8.J.ts+.4.....| -00000140 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b |.t{.X.la<..A..++| -00000150 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 |$#w[.;.u]. T..c.| -00000160 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 |..$....P....C...| -00000170 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 |ub...R.........0| -00000180 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 |..0...U.........| -00000190 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b |..0...U.%..0...+| -000001a0 06 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 |.........+......| -000001b0 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 |.0...U.......0.0| -000001c0 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 |...U..........CC| -000001d0 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d |>I..m....`0...U.| -000001e0 23 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb |#..0...H.IM.~.1.| -000001f0 a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 |.....n{0...U....| -00000200 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 |0...example.gola| -00000210 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 |ng0...*.H.......| -00000220 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba |......0.@+[P.a..| -00000230 e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac |.SX...(.X..8....| -00000240 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 |1Z..f=C.-...... | -00000250 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa |d8.$:....}.@ ._.| -00000260 d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 |..a..v......\...| -00000270 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 |..l..s..Cw......| -00000280 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 |.@.a.Lr+...F..M.| -00000290 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 |..>...B...=.`.\!| -000002a0 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 |.;..............| -000002b0 1d 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb |. /.}.G.bC.(.._.| -000002c0 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb |).0.........._X.| -000002d0 3b 74 04 01 00 80 8a b8 11 46 fc 88 8d f3 7d 22 |;t.......F....}"| -000002e0 e0 1e d6 ac 45 79 e7 4d fa 46 df 6d a2 b2 67 38 |....Ey.M.F.m..g8| -000002f0 73 73 d9 20 9e 7c a1 a0 01 0c e7 e3 08 b2 f9 db |ss. .|..........| -00000300 97 82 c9 1e 27 33 f6 69 5b 8d 3c ca a8 a3 34 d5 |....'3.i[.<...4.| -00000310 70 ac f6 62 6e 80 5d 5b 6e 1e bd 2d 27 d2 6d c3 |p..bn.][n..-'.m.| -00000320 ca 08 8c fc ea 94 d2 99 49 d8 5f 30 6a a2 d9 c4 |........I._0j...| -00000330 f2 17 d9 50 9e 82 9c 95 93 6d 7c b6 18 16 84 92 |...P.....m|.....| -00000340 31 29 bd a0 df ed 09 ab bf 32 ca c5 26 67 bb 28 |1).......2..&g.(| -00000350 78 1b c6 5b 7a 21 16 03 03 00 04 0e 00 00 00 |x..[z!.........| +00000030 1c 00 23 00 00 ff 01 00 01 00 00 10 00 09 00 07 |..#.............| +00000040 06 70 72 6f 74 6f 31 00 0b 00 02 01 00 16 03 03 |.proto1.........| +00000050 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b |.Y...U..R..O0..K| +00000060 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f |0..............?| +00000070 e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |.[..0...*.H.....| +00000080 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 |...0.1.0...U....| +00000090 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 |Go1.0...U....Go | +000000a0 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 |Root0...16010100| +000000b0 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 |0000Z..250101000| +000000c0 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 |000Z0.1.0...U...| +000000d0 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f |.Go1.0...U....Go| +000000e0 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 |0..0...*.H......| +000000f0 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d |......0.......F}| +00000100 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d |...'.H..(!.~...]| +00000110 fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 |..RE.z6G....B[..| +00000120 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 |...y.@.Om..+....| +00000130 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 |.g....."8.J.ts+.| +00000140 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 |4......t{.X.la<.| +00000150 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce |.A..++$#w[.;.u].| +00000160 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa | T..c...$....P..| +00000170 b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 |..C...ub...R....| +00000180 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 |.....0..0...U...| +00000190 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 |........0...U.%.| +000001a0 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b |.0...+.........+| +000001b0 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 |.......0...U....| +000001c0 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 |...0.0...U......| +000001d0 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 |....CC>I..m....`| +000001e0 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 |0...U.#..0...H.I| +000001f0 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 |M.~.1......n{0..| +00000200 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c |.U....0...exampl| +00000210 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 |e.golang0...*.H.| +00000220 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b |............0.@+| +00000230 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a |[P.a...SX...(.X.| +00000240 a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 |.8....1Z..f=C.-.| +00000250 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d |..... d8.$:....}| +00000260 b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc |.@ ._...a..v....| +00000270 e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 |..\.....l..s..Cw| +00000280 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae |.......@.a.Lr+..| +00000290 db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe |.F..M...>...B...| +000002a0 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac |=.`.\!.;........| +000002b0 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 |....... /.}.G.bC| +000002c0 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 |.(.._.).0.......| +000002d0 ed 90 99 5f 58 cb 3b 74 08 04 00 80 b6 a2 61 f9 |..._X.;t......a.| +000002e0 30 40 0b 5c 2c 92 b4 7b e3 42 79 00 11 4d 6b 85 |0@.\,..{.By..Mk.| +000002f0 df 2e 19 c2 fc a8 bc 16 0b c0 8d 02 55 99 a7 06 |............U...| +00000300 fa 4c 4d 4c 27 de 6d 3d 1e 7a 6f 2c fc eb 9e 15 |.LML'.m=.zo,....| +00000310 40 6f 0c 81 b3 e1 4d 78 b7 38 c6 50 8f 5b 63 ac |@o....Mx.8.P.[c.| +00000320 20 4f a6 06 aa 00 84 f5 01 f4 68 7a 5a 16 c5 da | O........hzZ...| +00000330 71 b2 4f 04 6e 59 88 14 8c 81 01 91 a8 e8 c1 18 |q.O.nY..........| +00000340 a8 07 e8 7a f4 dc b9 e7 7f c5 ce 2c 32 8d fe d6 |...z.......,2...| +00000350 1f 0e a5 f0 f4 c7 dd 39 13 a1 ca 6d 16 03 03 00 |.......9...m....| +00000360 04 0e 00 00 00 |.....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 69 44 46 d1 ad ea |....%...! iDF...| -00000010 ac b6 dc 35 6a b1 06 77 57 e8 94 58 49 15 4b 35 |...5j..wW..XI.K5| -00000020 7c c9 40 a0 75 37 f0 77 79 0c 14 03 03 00 01 01 ||.@.u7.wy.......| -00000030 16 03 03 00 28 2d 84 08 73 fc f7 b7 8d 07 63 4a |....(-..s.....cJ| -00000040 c4 42 37 b6 cd e1 87 9f 4f 3b 4e 8c a5 3f 95 67 |.B7.....O;N..?.g| -00000050 74 02 9a f1 d1 39 0c 7b 7b 8e 82 79 28 |t....9.{{..y(| +00000000 16 03 03 00 25 10 00 00 21 20 d7 fa 22 66 b4 c8 |....%...! .."f..| +00000010 67 2c 45 93 bf 38 3a 13 21 45 d5 29 95 5b 0d 5c |g,E..8:.!E.).[.\| +00000020 79 d2 d6 9b ef bd 7d eb a9 21 14 03 03 00 01 01 |y.....}..!......| +00000030 16 03 03 00 28 a2 81 84 32 29 01 69 28 f9 56 cc |....(...2).i(.V.| +00000040 c9 72 51 5c 22 38 51 12 e1 55 a1 d6 8c cf 66 75 |.rQ\"8Q..U....fu| +00000050 b4 bd 49 60 d0 e4 7e 9e fe 56 d1 62 36 |..I`..~..V.b6| >>> Flow 4 (server to client) 00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f ec 80 83 61 f2 44 31 c6 93 15 b9 27 68 bc ab |o...a.D1....'h..| -00000040 b1 7f 48 8d 99 54 9c 9c 2e 36 11 6f 38 e7 3f 79 |..H..T...6.o8.?y| -00000050 f9 f1 a5 5d 36 9a 1a 4c 7c f2 ad 84 f4 13 a7 be |...]6..L|.......| -00000060 e4 79 39 c6 31 33 94 81 cf d3 85 2e 29 02 44 a8 |.y9.13......).D.| -00000070 61 4d 70 c3 dd ed b4 a2 f2 4b 44 c0 d5 af 19 8b |aMp......KD.....| -00000080 3f e5 fa fa ba dd 2d 14 03 03 00 01 01 16 03 03 |?.....-.........| -00000090 00 28 00 00 00 00 00 00 00 00 f0 16 42 20 de 60 |.(..........B .`| -000000a0 a4 a7 12 85 e5 cb b6 53 eb 76 7f 89 62 76 e8 46 |.......S.v..bv.F| -000000b0 69 a6 bd 1e f5 5e 13 18 1d d3 17 03 03 00 25 00 |i....^........%.| -000000c0 00 00 00 00 00 00 01 47 51 00 3f dd 64 0c 6f 43 |.......GQ.?.d.oC| -000000d0 d1 cb 25 22 45 af ee 64 5f a7 6e cf 6c 7e 26 b3 |..%"E..d_.n.l~&.| -000000e0 7e cd f0 71 15 03 03 00 1a 00 00 00 00 00 00 00 |~..q............| -000000f0 02 01 f4 16 18 8e 29 27 34 58 c4 9a f8 a7 58 3a |......)'4X....X:| -00000100 2e 4a 32 |.J2| +00000030 6f ec 80 83 61 cf 87 48 45 0d 9d a5 bf 38 b4 9f |o...a..HE....8..| +00000040 19 a9 cd ca 63 79 2d c3 ae 70 74 56 44 99 fb cc |....cy-..ptVD...| +00000050 7d 31 c2 67 75 fe 57 1b fd 6b 2f cd df ec fa 5b |}1.gu.W..k/....[| +00000060 23 47 19 7e 84 33 94 d7 de e2 b9 ff 75 7d dc 80 |#G.~.3......u}..| +00000070 9e 55 94 8e 15 94 70 8f b5 21 0e 4e f7 4c e6 44 |.U....p..!.N.L.D| +00000080 01 a3 9d 67 5f 05 73 14 03 03 00 01 01 16 03 03 |...g_.s.........| +00000090 00 28 00 00 00 00 00 00 00 00 3a 49 dc e2 aa ce |.(........:I....| +000000a0 a8 43 27 08 a8 6b 7c ae 3f 07 18 e1 04 a9 e6 24 |.C'..k|.?......$| +000000b0 0e 9e 0a 0f af a4 c3 6e 90 2d 17 03 03 00 25 00 |.......n.-....%.| +000000c0 00 00 00 00 00 00 01 41 e1 9b 4c 8a 1a e8 10 bf |.......A..L.....| +000000d0 9f fd 76 e4 43 c2 cf 04 ee 68 6a 02 3c 97 fc ec |..v.C....hj.<...| +000000e0 c4 0a 74 1d 15 03 03 00 1a 00 00 00 00 00 00 00 |..t.............| +000000f0 02 1c 9b b1 b6 07 fa 33 a8 70 03 d9 27 29 ea 61 |.......3.p..').a| +00000100 96 c2 48 |..H| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch index ced69a2acf8..f8b88a63d78 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e3 01 00 00 df 03 03 c8 61 61 3d 4e |............aa=N| -00000010 9a 5e 9e 0c 59 3f 23 e0 d8 ac d9 28 27 41 6a a0 |.^..Y?#....('Aj.| -00000020 fb 7e d3 5f 20 aa 40 6c df cb 07 00 00 38 c0 2c |.~._ .@l.....8.,| +00000000 16 03 01 00 e3 01 00 00 df 03 03 ed dd 7f 68 1d |..............h.| +00000010 9e 83 bc 08 01 39 8e 97 76 91 cb cb 24 73 15 f5 |.....9..v...$s..| +00000020 17 17 db 78 69 ca e1 ed 0f fc bc 00 00 38 c0 2c |...xi........8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| @@ -15,82 +15,82 @@ 000000d0 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................| 000000e0 02 02 04 02 05 02 06 02 |........| >>> Flow 2 (server to client) -00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| +00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 30 00 00 |...DOWNGRD...0..| -00000030 09 00 23 00 00 ff 01 00 01 00 16 03 03 02 59 0b |..#...........Y.| -00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| -00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| -00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| -00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| -00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| -00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| -000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| -000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| -000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| -000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| -000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| -000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| -00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| -00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| -00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| -00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| -00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| -00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| -00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| -00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| -00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| -00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| -000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| -000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| -000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| -000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| -000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| -000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| -00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| -00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| -00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| -00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| -00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | -00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| -00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| -00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| -00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| -00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 00 |.\!.;...........| -000002a0 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 da |.... /.}.G.bC.(.| -000002b0 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........| -000002c0 5f 58 cb 3b 74 04 01 00 80 a6 d5 2b cf 48 32 3e |_X.;t......+.H2>| -000002d0 09 74 c1 e4 2a 69 49 d7 bc ce 5a b7 55 e5 e1 f4 |.t..*iI...Z.U...| -000002e0 cc 3f 64 90 8a 58 e6 86 58 8b d7 94 60 d4 4e a9 |.?d..X..X...`.N.| -000002f0 e4 e1 45 f1 7b 14 79 d0 9f 5c e3 17 79 61 f3 7a |..E.{.y..\..ya.z| -00000300 0e e6 cc 7c ff d8 61 29 51 eb 36 f6 f1 57 2e c0 |...|..a)Q.6..W..| -00000310 43 de 54 fd 92 c7 d7 7a 54 77 f3 3f cf 53 b1 1f |C.T....zTw.?.S..| -00000320 57 53 7c 6d a3 74 b5 de ae 0b 22 1f 2c 3e d0 41 |WS|m.t....".,>.A| -00000330 04 7f df d8 d8 44 8d 8e 97 27 71 bc ff 6c 7f b6 |.....D...'q..l..| -00000340 bd 05 17 2c 1f 84 c6 f1 64 16 03 03 00 04 0e 00 |...,....d.......| -00000350 00 00 |..| +00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............| +00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0| +00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............| +00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..| +00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.| +00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....| +00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010| +000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101| +000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U| +000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...| +000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...| +000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......| +000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.| +00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B| +00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.| +00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t| +00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l| +00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.| +00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....| +00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.| +00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U| +00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U| +00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......| +000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.| +000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...| +000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..| +000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...| +000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{| +000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa| +00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*| +00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0| +00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(| +00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C| +00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..| +00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.| +00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.| +00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr| +00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B| +00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| +000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G| +000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....| +000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 59 |......_X.;t....Y| +000002d0 85 20 dc b1 4c d2 17 4d 20 73 1a a7 f7 ab 40 52 |. ..L..M s....@R| +000002e0 73 e7 02 21 eb 55 e2 c9 73 c0 c2 8a ed a3 fd 07 |s..!.U..s.......| +000002f0 0b 5b 30 c2 1e 63 a1 c2 27 41 6c 5a ca 6e 12 d3 |.[0..c..'AlZ.n..| +00000300 4a 87 15 29 7f 44 06 3d 14 76 98 45 e5 27 84 09 |J..).D.=.v.E.'..| +00000310 44 be f3 c4 ce 79 31 e9 92 06 b6 d2 d9 19 d1 24 |D....y1........$| +00000320 7d 44 6a 57 ea 9d 12 e3 e7 a1 16 86 10 fc 7a 66 |}DjW..........zf| +00000330 00 3a f0 f0 ed e7 7c 20 82 0a 26 5d 92 79 8a 5b |.:....| ..&].y.[| +00000340 55 98 fc 1a c1 2f c0 07 ce b8 03 3a 01 da 62 16 |U..../.....:..b.| +00000350 03 03 00 04 0e 00 00 00 |........| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 c8 8e d1 4e a9 96 |....%...! ...N..| -00000010 d4 73 45 b8 11 6e db db 00 f8 c0 c3 0e 96 62 c3 |.sE..n........b.| -00000020 7c 04 3b 4a 40 d6 f6 81 e9 0d 14 03 03 00 01 01 ||.;J@...........| -00000030 16 03 03 00 28 69 f9 fd 75 0d 63 bd ff 62 27 7b |....(i..u.c..b'{| -00000040 b2 28 b6 dc 55 c4 4b 10 f5 34 64 0d 85 a4 58 10 |.(..U.K..4d...X.| -00000050 ee d6 93 77 00 da 6e ab 5e 9f f4 62 41 |...w..n.^..bA| +00000000 16 03 03 00 25 10 00 00 21 20 d9 f2 e4 c5 cf 38 |....%...! .....8| +00000010 23 30 2e b6 d9 0f 3b a2 d7 2f eb d5 74 a8 29 12 |#0....;../..t.).| +00000020 5f 27 bc 81 96 6b 12 5a bb 2f 14 03 03 00 01 01 |_'...k.Z./......| +00000030 16 03 03 00 28 4b a1 12 ce 11 2a 0f 79 7c 56 eb |....(K....*.y|V.| +00000040 bb 9f 7d 91 c7 53 25 d6 ae 0b 98 f1 b5 ea ef 51 |..}..S%........Q| +00000050 8b 3a fb d1 6c ae 3d bb b7 67 d9 ba 36 |.:..l.=..g..6| >>> Flow 4 (server to client) 00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f ec 80 83 61 8d 11 1d 31 eb f3 00 20 b3 0f 72 |o...a...1... ..r| -00000040 a0 7d 10 58 c8 5f da e2 cb 82 74 4d 99 0d bb 75 |.}.X._....tM...u| -00000050 f3 cb 1a 19 11 ba 70 90 82 9e ab 73 be a9 96 58 |......p....s...X| -00000060 96 b7 98 07 ba 33 94 81 e5 8e d1 39 08 10 01 df |.....3.....9....| -00000070 ba dd f7 b1 0c ce 71 96 f6 d2 8a 50 43 9a 56 b9 |......q....PC.V.| -00000080 2c 29 d7 05 5b 0d ea 14 03 03 00 01 01 16 03 03 |,)..[...........| -00000090 00 28 00 00 00 00 00 00 00 00 94 0f b0 0f 1a 43 |.(.............C| -000000a0 e1 77 b5 36 55 21 8a d5 7e ae 37 eb c5 7b dc aa |.w.6U!..~.7..{..| -000000b0 28 1b 00 2f 31 e2 5e ca 54 89 17 03 03 00 25 00 |(../1.^.T.....%.| -000000c0 00 00 00 00 00 00 01 eb 0e 33 bd 20 4f 18 db 26 |.........3. O..&| -000000d0 b3 48 21 a6 87 e2 a4 1f fe 84 ae 89 fe cf 41 20 |.H!...........A | -000000e0 f9 d4 41 67 15 03 03 00 1a 00 00 00 00 00 00 00 |..Ag............| -000000f0 02 f3 51 22 2e 4e 9e 87 4a 06 06 2f f6 88 0c cf |..Q".N..J../....| -00000100 6f 0f 9b |o..| +00000030 6f ec 80 83 61 40 f9 2b 9e a7 30 60 fb 46 36 c4 |o...a@.+..0`.F6.| +00000040 0e b3 2a c4 73 64 2e 12 6c 0d f5 b9 6f 05 ae 27 |..*.sd..l...o..'| +00000050 d7 a3 47 c5 67 31 3e 95 84 bf 42 e1 b9 0d 90 40 |..G.g1>...B....@| +00000060 01 50 0d 32 4b 33 94 5c a3 1d b9 db e5 c5 24 02 |.P.2K3.\......$.| +00000070 48 31 ad 70 8e c7 e9 60 a5 7e ea 91 7b 01 79 06 |H1.p...`.~..{.y.| +00000080 66 f9 c4 9d bd 65 a5 14 03 03 00 01 01 16 03 03 |f....e..........| +00000090 00 28 00 00 00 00 00 00 00 00 32 be b5 c5 4d 83 |.(........2...M.| +000000a0 41 97 f6 26 0f aa 06 35 d5 9e f8 12 1c 04 f7 b6 |A..&...5........| +000000b0 16 9f f9 a4 43 b8 56 ea 4a 82 17 03 03 00 25 00 |....C.V.J.....%.| +000000c0 00 00 00 00 00 00 01 1a 8e 6b 4a 69 02 56 46 eb |.........kJi.VF.| +000000d0 26 12 47 a3 9d 9a 8a 09 20 4a 6c b2 d0 6a 14 48 |&.G..... Jl..j.H| +000000e0 be d5 f0 48 15 03 03 00 1a 00 00 00 00 00 00 00 |...H............| +000000f0 02 0e 01 9d 60 90 01 60 99 a0 f5 df 6d 38 e5 76 |....`..`....m8.v| +00000100 4d d7 d7 |M..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA b/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA index ce790fc16f1..63e0edb6b98 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 cb 01 00 00 c7 03 03 44 af b1 f3 8d |...........D....| -00000010 81 78 a9 28 a4 31 99 bb 66 17 63 ed 70 88 b7 bb |.x.(.1..f.c.p...| -00000020 da ef 4d 1d a2 a6 9e 18 96 97 ec 00 00 38 c0 2c |..M..........8.,| +00000000 16 03 01 00 cb 01 00 00 c7 03 03 3f 5d 09 25 4e |...........?].%N| +00000010 82 83 13 89 ba 89 43 d5 43 4f f1 c3 2f 08 77 39 |......C.CO../.w9| +00000020 bf eb c7 1d 4b d6 85 c8 17 2f 83 00 00 38 c0 2c |....K..../...8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| @@ -13,75 +13,76 @@ 000000b0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................| 000000c0 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 0a 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 03 02 0e 0b 00 02 0a 00 |................| -00000040 02 07 00 02 04 30 82 02 00 30 82 01 62 02 09 00 |.....0...0..b...| -00000050 b8 bf 2d 47 a0 d2 eb f4 30 09 06 07 2a 86 48 ce |..-G....0...*.H.| -00000060 3d 04 01 30 45 31 0b 30 09 06 03 55 04 06 13 02 |=..0E1.0...U....| -00000070 41 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d |AU1.0...U....Som| -00000080 65 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a |e-State1!0...U..| -00000090 13 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 |..Internet Widgi| -000000a0 74 73 20 50 74 79 20 4c 74 64 30 1e 17 0d 31 32 |ts Pty Ltd0...12| -000000b0 31 31 32 32 31 35 30 36 33 32 5a 17 0d 32 32 31 |1122150632Z..221| -000000c0 31 32 30 31 35 30 36 33 32 5a 30 45 31 0b 30 09 |120150632Z0E1.0.| -000000d0 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 55 |..U....AU1.0...U| -000000e0 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 21 |....Some-State1!| -000000f0 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e 65 |0...U....Interne| -00000100 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c 74 |t Widgits Pty Lt| -00000110 64 30 81 9b 30 10 06 07 2a 86 48 ce 3d 02 01 06 |d0..0...*.H.=...| -00000120 05 2b 81 04 00 23 03 81 86 00 04 00 c4 a1 ed be |.+...#..........| -00000130 98 f9 0b 48 73 36 7e c3 16 56 11 22 f2 3d 53 c3 |...Hs6~..V.".=S.| -00000140 3b 4d 21 3d cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc |;M!=.ku......&..| -00000150 b2 87 f0 72 32 7c b3 64 2f 1c 90 bc ea 68 23 10 |...r2|.d/....h#.| -00000160 7e fe e3 25 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 |~..%.H:i.(m.7...| -00000170 62 dd 0d a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 |b....pb....d1...| -00000180 31 bd 96 b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 |1...h..#.vd?.\..| -00000190 12 0e 58 58 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc |..XX._p.........| -000001a0 b9 b6 9f 30 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 |...0f[f. .'...;0| -000001b0 09 06 07 2a 86 48 ce 3d 04 01 03 81 8c 00 30 81 |...*.H.=......0.| -000001c0 88 02 42 01 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 |..B...O..E.H}...| -000001d0 ed 98 9d ae 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 |....Gp.^../...M.| -000001e0 61 40 d3 11 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b |a@......~.~.v..;| -000001f0 7e a5 3f ce fa 10 e2 59 ec 47 2d 7c ac da 4e 97 |~.?....Y.G-|..N.| -00000200 0e 15 a0 6f d0 02 42 01 4d fc be 67 13 9c 2d 05 |...o..B.M..g..-.| -00000210 0e bd 3f a3 8c 25 c1 33 13 83 0d 94 06 bb d4 37 |..?..%.3.......7| -00000220 7a f6 ec 7a c9 86 2e dd d7 11 69 7f 85 7c 56 de |z..z......i..|V.| -00000230 fb 31 78 2b e4 c7 78 0d ae cb be 9e 4e 36 24 31 |.1x+..x.....N6$1| -00000240 7b 6a 0f 39 95 12 07 8f 2a 16 03 03 00 b6 0c 00 |{j.9....*.......| -00000250 00 b2 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 |..... /.}.G.bC.(| -00000260 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 |.._.).0.........| -00000270 99 5f 58 cb 3b 74 04 03 00 8a 30 81 87 02 42 01 |._X.;t....0...B.| -00000280 96 02 ab 3d 94 2b dc 27 07 6b 1b 59 21 f2 88 3b |...=.+.'.k.Y!..;| -00000290 de 7a ce 4e d6 a5 47 30 0d 79 ae a9 e0 cf 9c e7 |.z.N..G0.y......| -000002a0 0b 14 eb 44 bc a3 b9 5b cf 01 f0 2f be 63 3e 9f |...D...[.../.c>.| -000002b0 63 32 4e ce 4d 4c 70 86 dd 16 09 70 f7 3e 3b f6 |c2N.MLp....p.>;.| -000002c0 34 02 41 0a 0f a9 75 dd a8 21 40 8f 05 82 2f e0 |4.A...u..!@.../.| -000002d0 09 37 08 0a b6 a4 8a 1c fd 3e 4d 1b e3 19 e1 4d |.7.......>M....M| -000002e0 15 90 65 00 2f e0 15 bf 2b 23 b6 2b 44 7a 3f 1a |..e./...+#.+Dz?.| -000002f0 4c 82 3a 95 b9 ff 37 0a 1e f2 63 e3 b1 71 81 36 |L.:...7...c..q.6| -00000300 6d 23 3e 53 16 03 03 00 04 0e 00 00 00 |m#>S.........| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 00 30 |...........0...0| +00000050 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 30 09 |..b.....-G....0.| +00000060 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 09 06 |..*.H.=..0E1.0..| +00000070 03 55 04 06 13 02 41 55 31 13 30 11 06 03 55 04 |.U....AU1.0...U.| +00000080 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 |...Some-State1!0| +00000090 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 |...U....Internet| +000000a0 20 57 69 64 67 69 74 73 20 50 74 79 20 4c 74 64 | Widgits Pty Ltd| +000000b0 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 33 32 |0...121122150632| +000000c0 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 32 5a |Z..221120150632Z| +000000d0 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 |0E1.0...U....AU1| +000000e0 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 |.0...U....Some-S| +000000f0 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 |tate1!0...U....I| +00000100 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 |nternet Widgits | +00000110 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 2a 86 |Pty Ltd0..0...*.| +00000120 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....| +00000130 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 16 56 |.........Hs6~..V| +00000140 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 f6 b0 |.".=S.;M!=.ku...| +00000150 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 2f 1c |...&.....r2|.d/.| +00000160 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 e0 28 |...h#.~..%.H:i.(| +00000170 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 d8 81 |m.7...b....pb...| +00000180 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 de 76 |.d1...1...h..#.v| +00000190 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd 9b d8 |d?.\....XX._p...| +000001a0 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a 20 e2 |.........0f[f. .| +000001b0 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d 04 01 |'...;0...*.H.=..| +000001c0 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb e2 45 |....0...B...O..E| +000001d0 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e 1b b6 |.H}.......Gp.^..| +000001e0 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b 7e 92 |/...M.a@......~.| +000001f0 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 ec 47 |~.v..;~.?....Y.G| +00000200 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 4d fc |-|..N....o..B.M.| +00000210 be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 13 83 |.g..-...?..%.3..| +00000220 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd d7 11 |.....7z..z......| +00000230 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d ae cb |i..|V..1x+..x...| +00000240 be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f 2a 16 |..N6$1{j.9....*.| +00000250 03 03 00 b7 0c 00 00 b3 03 00 1d 20 2f e5 7d a3 |........... /.}.| +00000260 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...| +00000270 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 04 03 00 8b |......._X.;t....| +00000280 30 81 88 02 42 01 5c 2a 30 4f 9f dc df a8 33 06 |0...B.\*0O....3.| +00000290 3b bc 35 46 6a 9c a3 a1 26 ec 42 29 bf 63 b3 9b |;.5Fj...&.B).c..| +000002a0 8c bf 7b 07 8d 28 eb 41 68 7a 8a 1b f3 de a9 dc |..{..(.Ahz......| +000002b0 1e d1 21 3c 4d 24 df 89 90 b6 f2 fb ad 60 d2 27 |..!V..F.| +000002e0 b4 e5 90 72 ed af 71 0d fb e6 39 2f d5 4b 73 ba |...r..q...9/.Ks.| +000002f0 85 d2 a4 bf 99 74 d7 81 eb 3e 69 4d f0 12 1e 3c |.....t...>iM...<| +00000300 53 ca f0 35 85 ef ff ed cc 0f f7 16 03 03 00 04 |S..5............| +00000310 0e 00 00 00 |....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 e8 92 71 c8 12 80 |....%...! ..q...| -00000010 88 d0 7f 00 71 76 83 dc e6 e3 4c b6 e2 8a d2 0d |....qv....L.....| -00000020 61 7e 36 d9 a7 1d 6c 92 75 46 14 03 03 00 01 01 |a~6...l.uF......| -00000030 16 03 03 00 40 86 48 1a 6f 89 29 b3 8b c1 b6 ad |....@.H.o.).....| -00000040 b5 6f af eb 32 44 e9 8f c2 43 58 d1 71 ad 1f 13 |.o..2D...CX.q...| -00000050 2b e3 5c bc d5 07 8a 29 9d 30 40 cd 73 2d 0a 80 |+.\....).0@.s-..| -00000060 49 82 d5 2a 79 eb a5 3c 2e 69 ee 1a 3a d8 1a 69 |I..*y..<.i..:..i| -00000070 63 a6 30 8e 3f |c.0.?| +00000000 16 03 03 00 25 10 00 00 21 20 b8 a6 ed 33 20 59 |....%...! ...3 Y| +00000010 76 0b 7c 87 53 f1 12 c1 46 d9 db 68 c0 6f d6 30 |v.|.S...F..h.o.0| +00000020 ea e0 64 04 54 7a 4c 95 03 41 14 03 03 00 01 01 |..d.TzL..A......| +00000030 16 03 03 00 40 c0 70 29 39 a0 8a bd 59 58 88 44 |....@.p)9...YX.D| +00000040 ea 10 b4 79 3e 0e 72 b7 2a 03 6d 4d 5a 24 f5 c0 |...y>.r.*.mMZ$..| +00000050 4e e5 19 f0 fb 66 ca 97 89 4b 67 dc bb 19 cd 0b |N....f...Kg.....| +00000060 6e 74 01 d3 a4 9a ab af 8e 44 10 99 ac ff 9e 9e |nt.......D......| +00000070 17 04 56 78 55 |..VxU| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 33 ab 9b d6 4a |...........3...J| -00000020 bb e7 06 b0 d4 7e 1a 7f 78 cb d1 7a 44 26 a7 e6 |.....~..x..zD&..| -00000030 93 42 ae ec d3 44 0c dd b0 74 1b d8 99 75 a2 69 |.B...D...t...u.i| -00000040 98 d4 ed 2c b8 a0 26 69 80 1c 7f 17 03 03 00 40 |...,..&i.......@| +00000010 00 00 00 00 00 00 00 00 00 00 00 01 a0 6b 2c c5 |.............k,.| +00000020 7e 83 70 b5 2c 8c 43 b6 8b 2e 18 2a 1d be 11 6d |~.p.,.C....*...m| +00000030 13 f9 ba b5 de db 01 2a 64 d9 5b 24 c9 61 a1 4d |.......*d.[$.a.M| +00000040 11 bb fc b1 86 61 b0 04 a9 cd 1e 17 03 03 00 40 |.....a.........@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 a5 0b 57 10 11 ca 9e fb f4 8b 24 86 c7 58 b9 4c |..W.......$..X.L| -00000070 9a 1d 6a 60 2b 7c b1 21 7e 00 f2 e5 00 6f ab 04 |..j`+|.!~....o..| -00000080 2f 14 97 ae 70 05 0d 18 31 57 51 4a 0c c7 10 84 |/...p...1WQJ....| +00000060 d8 98 85 b4 cb 61 39 69 2f b1 1f 24 c1 5a 4f e3 |.....a9i/..$.ZO.| +00000070 0b 20 5d 6c 3f 3f 82 3a a3 8a b3 cf e9 41 bb 60 |. ]l??.:.....A.`| +00000080 ed b6 67 a0 76 39 ab 93 a5 35 d0 42 b3 a7 4c 92 |..g.v9...5.B..L.| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 d2 56 41 e1 58 30 76 2e 6e 6f 13 |......VA.X0v.no.| -000000b0 3b 72 5d bf c4 5c ef 63 2e 0a f0 6a 3a 98 ec 97 |;r]..\.c...j:...| -000000c0 07 b3 08 94 0d |.....| +000000a0 00 00 00 00 00 c7 0d 06 b2 2b 73 ab ed 16 88 6f |.........+s....o| +000000b0 62 77 fb 48 e4 5e 6d 7e 24 02 b6 08 fa 46 c8 76 |bw.H.^m~$....F.v| +000000c0 18 fc f4 c4 08 |.....| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA b/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA index 8959740c3bc..802aa1acbd4 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 cb 01 00 00 c7 03 03 a6 9c 71 27 48 |.............q'H| -00000010 24 f6 58 48 c8 2c 32 88 c9 01 eb f0 87 14 ba 7f |$.XH.,2.........| -00000020 f0 53 2d fd a1 b2 0a 72 e4 48 8e 00 00 38 c0 2c |.S-....r.H...8.,| +00000000 16 03 01 00 cb 01 00 00 c7 03 03 27 8a e9 f3 58 |...........'...X| +00000010 5a 08 90 d6 d4 97 23 b6 a7 92 73 3a a3 3c c1 a1 |Z.....#...s:.<..| +00000020 ca 06 23 c8 ed 4a 19 26 73 c9 62 00 00 38 c0 2c |..#..J.&s.b..8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| @@ -13,79 +13,80 @@ 000000b0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................| 000000c0 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 14 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d |;...............| -000002a0 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 | /.}.G.bC.(.._.)| -000002b0 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b |.0.........._X.;| -000002c0 74 04 01 00 80 10 af cc 7e b1 33 b1 87 08 e9 d5 |t.......~.3.....| -000002d0 b0 fc 70 a6 b6 f9 20 92 60 b2 01 90 e3 e2 0b 71 |..p... .`......q| -000002e0 4c b9 91 4e c7 28 60 cb b5 b7 d1 91 1f 01 f3 93 |L..N.(`.........| -000002f0 56 5b 14 91 bb e4 95 18 f5 0c 23 47 e6 4e d0 9e |V[........#G.N..| -00000300 2f 1a 4a d1 f5 08 71 c0 08 70 75 78 c1 c7 89 e4 |/.J...q..pux....| -00000310 b2 3c b9 49 c8 95 c7 ba 5b b0 04 20 18 b1 5a 3e |.<.I....[.. ..Z>| -00000320 2b 9f 7b 2b 9c f8 34 69 4b c2 a8 2f d1 73 ec d1 |+.{+..4iK../.s..| -00000330 c9 22 19 6b bc aa e4 d3 89 73 5a 88 27 75 4a b6 |.".k.....sZ.'uJ.| -00000340 c3 6d 32 b0 a2 16 03 03 00 04 0e 00 00 00 |.m2...........| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........| +000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.| +000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| +000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 42 86 d0 0a 5b |.._X.;t....B...[| +000002d0 d7 97 20 4d be 16 b8 eb 51 66 28 3b f9 45 35 f5 |.. M....Qf(;.E5.| +000002e0 de 1d 28 c9 36 63 5b 7b f6 a7 64 79 fb 39 20 c3 |..(.6c[{..dy.9 .| +000002f0 dd db 38 3e af 89 ce 91 f7 bd 51 b4 5e 01 d8 9b |..8>......Q.^...| +00000300 54 62 58 24 3b c2 43 59 a4 11 1a 2b 67 c5 5f 79 |TbX$;.CY...+g._y| +00000310 fe 68 9d c7 e6 8b 36 8b f9 cb 00 b0 b3 0f 52 fb |.h....6.......R.| +00000320 fe a5 e6 c6 26 9b d1 a2 17 4e e2 58 7f b2 80 78 |....&....N.X...x| +00000330 10 b4 0a 47 e1 18 92 d4 a5 5a 86 06 36 ca f7 b6 |...G.....Z..6...| +00000340 1c 83 81 0e eb 32 7d fe 06 c5 03 16 03 03 00 04 |.....2}.........| +00000350 0e 00 00 00 |....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 f3 07 eb 86 c5 e2 |....%...! ......| -00000010 28 7c be 7e 34 8d c5 74 19 0b b3 cc ce ce 90 3f |(|.~4..t.......?| -00000020 ac 06 c8 9f 79 3d 42 08 e2 01 14 03 03 00 01 01 |....y=B.........| -00000030 16 03 03 00 40 9b 6d a1 1e ca fb 27 67 ca 7b 57 |....@.m....'g.{W| -00000040 60 f4 60 95 b4 56 fd 97 cb 58 c5 cb bc 04 87 1d |`.`..V...X......| -00000050 74 a5 98 ec 3c 6f 25 5a ef c5 af 21 4b 2e 5c 97 |t......F.....| -00000070 08 62 88 25 1f |.b.%.| +00000000 16 03 03 00 25 10 00 00 21 20 14 7f fb 7d 0c ef |....%...! ...}..| +00000010 48 c4 8f 75 24 19 5f ee 5f 51 08 35 74 cf c3 ea |H..u$._._Q.5t...| +00000020 67 20 c4 f9 49 b2 cf 69 5a 77 14 03 03 00 01 01 |g ..I..iZw......| +00000030 16 03 03 00 40 2b d2 f4 dc 36 98 ef 1d 43 f9 3e |....@+...6...C.>| +00000040 83 33 c0 71 a6 e3 ac f1 3c cc 94 e4 d0 fe 81 bc |.3.q....<.......| +00000050 94 56 15 eb 6a 7b 17 33 e1 a0 ef d5 7a 86 af ea |.V..j{.3....z...| +00000060 1f bb d5 8c 80 56 d5 e4 08 cd 68 bf c0 53 c2 56 |.....V....h..S.V| +00000070 aa b3 38 1e 4e |..8.N| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 8e a1 9a 44 d4 |..............D.| -00000020 98 c6 5f 46 2f d9 e5 ac 78 b5 91 3f 15 89 6f fb |.._F/...x..?..o.| -00000030 39 79 65 0b c7 09 c7 fc eb 40 6d 8e 6d b7 8b 94 |9ye......@m.m...| -00000040 6f 30 5a a6 4c 9d 2a 13 ed f6 f4 17 03 03 00 40 |o0Z.L.*........@| +00000010 00 00 00 00 00 00 00 00 00 00 00 45 07 c3 ba 8c |...........E....| +00000020 d8 9f b6 f1 6a 14 bb b1 4e 84 3f 25 6a 3d ef f6 |....j...N.?%j=..| +00000030 88 89 1a 91 22 ef e3 ed ba 2a a3 7c 5b db e0 1d |...."....*.|[...| +00000040 b5 8d 7a ed e7 ad e1 31 b2 12 f5 17 03 03 00 40 |..z....1.......@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 5b 96 f1 fa c4 5b a3 22 74 ef 8c 34 52 50 c6 86 |[....[."t..4RP..| -00000070 32 19 40 b8 80 54 d9 c2 6a 43 a2 c2 fe 07 dd 37 |2.@..T..jC.....7| -00000080 89 62 bd 68 6a 1e e7 d9 1f ba 3a 1a 83 13 1f 7c |.b.hj.....:....|| +00000060 a6 f3 0b 33 f7 7a 7c fb fb b5 e6 eb 6e 0a 26 aa |...3.z|.....n.&.| +00000070 06 3b a6 bc 08 e5 3a b6 c9 a3 f3 77 28 93 45 08 |.;....:....w(.E.| +00000080 1d 54 5e a3 92 cd 89 a3 e6 34 ec 52 70 c0 97 3c |.T^......4.Rp..<| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 92 f0 3e 2e 3c d2 62 ce e8 2e 12 |.......>.<.b....| -000000b0 4e 1e 77 ba ff 61 97 f9 8e e8 d1 1b a0 00 3f 2c |N.w..a........?,| -000000c0 8c 5c 10 ac 05 |.\...| +000000a0 00 00 00 00 00 2d 0d 96 57 b8 6f 90 1e 84 4d 35 |.....-..W.o...M5| +000000b0 91 52 42 6b 8d a3 6b 21 22 60 1a c9 38 7f 5a ef |.RBk..k!"`..8.Z.| +000000c0 6e dd 84 06 79 |n...y| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven index b65a7b70f41..31776532f14 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 75 b5 bf db ae |...........u....| -00000010 ee 3a 8d d7 23 e1 22 9a 42 d9 7a de ac 41 81 60 |.:..#.".B.z..A.`| -00000020 4d 05 6e f1 11 c5 c0 de 21 46 d2 00 00 04 00 2f |M.n.....!F...../| +00000000 16 03 01 00 97 01 00 00 93 03 03 a8 4e d1 44 14 |............N.D.| +00000010 46 11 b2 4f 03 b6 6f 89 cf fd dd 9b 6a dd 4d 1e |F..O..o.....j.M.| +00000020 51 02 a2 10 d9 d3 a1 d8 54 a2 4a 00 00 04 00 2f |Q.......T.J..../| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,50 +10,51 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 1d 0d 00 00 19 02 01 40 |;..............@| -000002a0 00 12 04 01 04 03 08 07 05 01 06 01 05 03 06 03 |................| -000002b0 02 01 02 03 00 00 16 03 03 00 04 0e 00 00 00 |...............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d |.`.\!.;.......#.| +000002a0 00 00 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 |.....@..........| +000002b0 08 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 |................| +000002c0 00 00 16 03 03 00 04 0e 00 00 00 |...........| >>> Flow 3 (client to server) 00000000 16 03 03 02 0a 0b 00 02 06 00 02 03 00 02 00 30 |...............0| 00000010 82 01 fc 30 82 01 5e 02 09 00 9a 30 84 6c 26 35 |...0..^....0.l&5| @@ -88,40 +89,40 @@ 000001e0 be e8 91 b3 da 1a f5 5d a3 23 f5 26 8b 45 70 8d |.......].#.&.Ep.| 000001f0 65 62 9b 7e 01 99 3d 18 f6 10 9a 38 61 9b 2e 57 |eb.~..=....8a..W| 00000200 e4 fa cc b1 8a ce e2 23 a0 87 f0 e1 67 51 eb 16 |.......#....gQ..| -00000210 03 03 00 86 10 00 00 82 00 80 6c 1d a3 55 fb a0 |..........l..U..| -00000220 be 6f 49 64 67 b8 da 1c 27 91 f4 5d d9 9d 7e f0 |.oIdg...'..]..~.| -00000230 53 86 15 96 93 b2 0d 11 1a cf 3c 76 5e 76 24 ac |S.........wJ._.| -00000270 5f 51 0d 12 61 19 f6 fe 7d f7 b7 06 0d b1 de 09 |_Q..a...}.......| -00000280 45 17 4b 2a 15 97 ce 96 c5 f5 27 95 fb e8 c5 67 |E.K*......'....g| -00000290 5e cb 8c 98 c7 c5 68 41 36 99 16 03 03 00 91 0f |^.....hA6.......| -000002a0 00 00 8d 04 03 00 89 30 81 86 02 41 48 35 40 6e |.......0...AH5@n| -000002b0 03 2a 43 fe f8 a9 c5 f9 c7 05 f8 db 13 5e ee bb |.*C..........^..| -000002c0 a8 59 5b fc b4 5d 0a ec 32 18 d5 a0 01 d5 81 a5 |.Y[..]..2.......| -000002d0 f3 8e 4f 91 54 c7 8f a1 c1 77 4c 94 5c e4 68 c2 |..O.T....wL.\.h.| -000002e0 0b 22 e2 70 0c 32 e2 9d 6e 47 e4 0d f7 02 41 2d |.".p.2..nG....A-| -000002f0 0e bb 28 47 90 23 68 f2 fd 9e 7d 13 f0 ad 40 ed |..(G.#h...}...@.| -00000300 cb 32 e5 9d 5e a7 e1 12 d7 de 10 bc 93 df cb 03 |.2..^...........| -00000310 4e 16 5a cf 8f 25 1e 39 ff 7c 9f 59 55 f0 df b4 |N.Z..%.9.|.YU...| -00000320 ce 43 6d 15 8f e3 ef 76 5d 0d a9 31 a9 24 c6 58 |.Cm....v]..1.$.X| -00000330 14 03 03 00 01 01 16 03 03 00 40 71 ca 10 08 a9 |..........@q....| -00000340 1a f1 78 9d 6f 2d 76 1c b0 2a f8 26 d2 f6 89 db |..x.o-v..*.&....| -00000350 25 50 63 cc bf 12 cb fb 39 93 91 7f 7f f7 e4 fe |%Pc.....9.......| -00000360 fc 28 d0 01 3b e9 f9 1b 6a 77 db 16 14 71 3d 35 |.(..;...jw...q=5| -00000370 67 de b8 1d e3 4a 02 bc cf 0a a6 |g....J.....| +00000210 03 03 00 86 10 00 00 82 00 80 94 7b c5 f9 b7 fa |...........{....| +00000220 08 d2 59 d4 d5 ae 30 7f 9b d6 97 8e f8 ab 5c dc |..Y...0.......\.| +00000230 b2 f2 f7 c2 f3 4a 2d c0 88 11 84 42 bf fe b9 ca |.....J-....B....| +00000240 6f 6e b2 a4 c3 50 f1 bc 22 6e 12 bf 18 e2 12 1c |on...P.."n......| +00000250 c2 53 f5 b4 03 f2 c8 a4 a6 29 da cd 3e 62 6d c0 |.S.......)..>bm.| +00000260 34 58 5d 3b 1c 84 6e a6 d7 7c 63 67 0c 1a 7c a4 |4X];..n..|cg..|.| +00000270 ea 66 ce 70 6c 6d fd c9 d5 b5 63 38 93 02 7c 3b |.f.plm....c8..|;| +00000280 b2 0b 62 ff 32 2d 6a d0 59 27 e6 34 cc a6 25 aa |..b.2-j.Y'.4..%.| +00000290 5b 77 4a f6 79 72 1f bf 30 f1 16 03 03 00 92 0f |[wJ.yr..0.......| +000002a0 00 00 8e 04 03 00 8a 30 81 87 02 42 01 dc 84 5b |.......0...B...[| +000002b0 f3 56 ac 18 07 45 f0 3d 2c 96 e8 ff 12 c0 59 0e |.V...E.=,.....Y.| +000002c0 de ef 93 98 88 09 dd 82 14 65 20 72 a9 f2 bc 2d |.........e r...-| +000002d0 7a d1 d7 f0 fe 99 f1 80 54 b8 30 b2 b9 01 3d a6 |z.......T.0...=.| +000002e0 f2 c0 cd 8e 68 a2 e7 92 85 aa 13 8f 49 1c 02 41 |....h.......I..A| +000002f0 2c 4c 7d f6 27 ea 31 e1 4d 68 b3 39 4a 2d 26 ae |,L}.'.1.Mh.9J-&.| +00000300 42 4a 6c 4e cc fb bf b7 0b 1a bf df 57 0c fe b1 |BJlN........W...| +00000310 fd fc bd a2 08 a2 fc 4f 91 89 ec e0 ea e3 b3 38 |.......O.......8| +00000320 2f ba 17 8e 07 0a 4d cd a8 73 a4 e9 a3 02 ee 42 |/.....M..s.....B| +00000330 07 14 03 03 00 01 01 16 03 03 00 40 75 26 df cd |...........@u&..| +00000340 34 27 db 19 2f da d4 0d 0a ec b4 d5 03 1a a1 34 |4'../..........4| +00000350 fa fd df a9 31 1e e0 78 87 f6 9b 31 4a 27 4d 4e |....1..x...1J'MN| +00000360 54 d4 b0 a2 1a 72 52 02 89 47 93 a6 c4 57 d3 b8 |T....rR..G...W..| +00000370 60 e5 1e db 60 ea fd 08 6f 13 fc 9d |`...`...o...| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 0d f1 0c 52 89 |..............R.| -00000020 61 e6 21 95 8d 6f 5d e9 07 42 23 5f 1c 74 44 57 |a.!..o]..B#_.tDW| -00000030 38 a3 98 77 f2 62 99 71 d6 fe 03 a3 82 01 7a da |8..w.b.q......z.| -00000040 a5 fd 12 62 2b d2 1d e4 e2 51 25 17 03 03 00 40 |...b+....Q%....@| +00000010 00 00 00 00 00 00 00 00 00 00 00 b7 39 51 e9 91 |............9Q..| +00000020 8a f0 d0 a9 6d fb 0e 30 bd 74 44 94 48 b0 6e a7 |....m..0.tD.H.n.| +00000030 ab a8 8c ce 87 da 93 73 e1 da cc 53 e8 32 03 fe |.......s...S.2..| +00000040 57 66 cf e1 ed ef e6 6f 80 32 eb 17 03 03 00 40 |Wf.....o.2.....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 81 82 cc a9 4e 6f 78 41 28 b3 e6 c3 44 62 48 0b |....NoxA(...DbH.| -00000070 b3 70 f9 f8 7a fc c5 be 36 45 58 41 6f 77 69 40 |.p..z...6EXAowi@| -00000080 5b 6e fc 69 84 21 eb bc 95 36 e6 48 05 02 37 f5 |[n.i.!...6.H..7.| +00000060 37 8f 8a d3 8e 0a f5 24 28 95 5e 19 e1 40 b8 2a |7......$(.^..@.*| +00000070 eb 4f 2a ec 6d 4d 7f f3 fb 63 52 46 52 57 c1 4a |.O*.mM...cRFRW.J| +00000080 ec cc a0 6b 2e 49 41 51 38 25 e3 af 82 53 2a 15 |...k.IAQ8%...S*.| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 d3 2f 45 d3 65 3b 64 67 43 ef aa |....../E.e;dgC..| -000000b0 a7 bb 98 a0 99 70 7f 56 c6 13 b2 1b 62 35 62 ea |.....p.V....b5b.| -000000c0 51 75 94 be 32 |Qu..2| +000000a0 00 00 00 00 00 83 24 3c 9d 31 f3 41 a5 35 8c 01 |......$<.1.A.5..| +000000b0 70 f4 b7 6e 2b 9e 1a 48 cf ce a4 68 2a 2c 53 18 |p..n+..H...h*,S.| +000000c0 1e 26 24 50 92 |.&$P.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given index 0503b9def56..d535cb4d751 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 cb 01 00 00 c7 03 03 ec bb 63 30 5c |.............c0\| -00000010 ea 49 54 dc 44 f7 80 47 c9 4d ff fa d4 77 44 8a |.IT.D..G.M...wD.| -00000020 ce 4b bd ce d7 95 b2 0d f7 2e 88 00 00 38 c0 2c |.K...........8.,| +00000000 16 03 01 00 cb 01 00 00 c7 03 03 6e 46 fb 23 fe |...........nF.#.| +00000010 6d b0 f4 4f bf fb c6 93 f8 29 f8 93 0e 13 51 9e |m..O.....)....Q.| +00000020 d7 cc e8 bb d1 c1 69 06 66 4f 45 00 00 38 c0 2c |......i.fOE..8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| @@ -13,61 +13,62 @@ 000000b0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................| 000000c0 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 30 00 00 |...DOWNGRD...0..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d |;...............| -000002a0 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 | /.}.G.bC.(.._.)| -000002b0 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b |.0.........._X.;| -000002c0 74 04 01 00 80 94 e2 09 13 e0 7c e8 6d 3b 50 f1 |t.........|.m;P.| -000002d0 4f f3 58 57 da 87 f4 61 f5 04 fc ec 0d 28 f1 e9 |O.XW...a.....(..| -000002e0 be 93 20 4a 17 03 17 b1 7f 2c 32 24 2e 02 35 67 |.. J.....,2$..5g| -000002f0 9f e7 55 0a 6d 3d af ef e3 b2 27 2e ae 12 cd 2c |..U.m=....'....,| -00000300 d9 e1 60 d6 64 94 f5 f2 42 54 43 23 70 36 fe 8e |..`.d...BTC#p6..| -00000310 d2 0b a3 cf fd 04 74 6e 55 9b 7a 86 c8 dd 0d 40 |......tnU.z....@| -00000320 bc b1 4e 05 c2 7f b4 40 3a d9 66 01 af ee fb 54 |..N....@:.f....T| -00000330 b6 cc e4 5b a2 1a 39 dc 25 7d 5d 8c 37 a1 15 ae |...[..9.%}].7...| -00000340 ed 16 b5 25 14 16 03 03 00 1d 0d 00 00 19 02 01 |...%............| -00000350 40 00 12 04 01 04 03 08 07 05 01 06 01 05 03 06 |@...............| -00000360 03 02 01 02 03 00 00 16 03 03 00 04 0e 00 00 00 |................| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........| +000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.| +000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| +000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 17 9f 15 d6 26 |.._X.;t........&| +000002d0 36 78 d9 7f e6 48 27 56 a5 96 22 9f 9c f6 92 a0 |6x...H'V..".....| +000002e0 dc 7d eb 66 6e b8 94 34 74 ac 96 50 63 f1 cd 92 |.}.fn..4t..Pc...| +000002f0 bc 31 d2 f5 30 70 b2 d6 f3 09 0c 87 6a 8b f5 46 |.1..0p......j..F| +00000300 0d 9a 87 4c de 94 80 49 43 26 28 e9 67 fa a8 1f |...L...IC&(.g...| +00000310 dd 36 5c b1 49 05 37 ac 2d db b8 22 bf ed 64 dc |.6\.I.7.-.."..d.| +00000320 50 53 12 3e e6 5a 78 fc b2 c5 6f 4c a9 86 40 da |PS.>.Zx...oL..@.| +00000330 0a 9b 71 62 6d 12 c9 b7 9a 8b ca bd a5 77 37 0c |..qbm........w7.| +00000340 1c f1 66 2c 63 2d 7b c6 6b f1 48 16 03 03 00 23 |..f,c-{.k.H....#| +00000350 0d 00 00 1f 02 01 40 00 18 08 04 04 03 08 07 08 |......@.........| +00000360 05 08 06 04 01 05 01 06 01 05 03 06 03 02 01 02 |................| +00000370 03 00 00 16 03 03 00 04 0e 00 00 00 |............| >>> Flow 3 (client to server) 00000000 16 03 03 01 3c 0b 00 01 38 00 01 35 00 01 32 30 |....<...8..5..20| 00000010 82 01 2e 30 81 e1 a0 03 02 01 02 02 10 17 d1 81 |...0............| @@ -89,23 +90,23 @@ 00000110 8a 4e 34 40 39 d6 b3 10 dc 19 fe a0 22 71 b3 f5 |.N4@9......."q..| 00000120 8f a1 58 0d cd f4 f1 85 24 bf e6 3d 14 df df ed |..X.....$..=....| 00000130 0e e1 17 d8 11 a2 60 d0 8a 37 23 2a c2 46 aa 3a |......`..7#*.F.:| -00000140 08 16 03 03 00 25 10 00 00 21 20 f1 58 f8 db 86 |.....%...! .X...| -00000150 a5 97 07 c8 fc c8 c1 fe e4 c9 35 13 44 f8 9b 7f |..........5.D...| -00000160 4a 22 6a 61 75 70 be 23 76 f4 5f 16 03 03 00 48 |J"jaup.#v._....H| -00000170 0f 00 00 44 08 07 00 40 fb ab 8f 44 f1 7b cb 95 |...D...@...D.{..| -00000180 e3 83 4b 85 d0 4f 41 a6 39 f8 ba c1 7c b5 7d f0 |..K..OA.9...|.}.| -00000190 45 5b 2d e2 90 80 27 1a b9 88 dd 4b 0d bc e8 1b |E[-...'....K....| -000001a0 d4 fc 69 d1 ac 59 d8 b3 0b b6 f7 ae 76 12 da 80 |..i..Y......v...| -000001b0 6b 39 98 5b 55 c4 c1 09 14 03 03 00 01 01 16 03 |k9.[U...........| -000001c0 03 00 28 46 3a 98 32 bf 61 b0 d2 74 f8 f4 65 ef |..(F:.2.a..t..e.| -000001d0 89 5b f5 ef 49 42 56 67 97 23 f2 18 de 06 30 86 |.[..IBVg.#....0.| -000001e0 77 66 ac 0a ac 88 98 ab 93 2b 20 |wf.......+ | +00000140 08 16 03 03 00 25 10 00 00 21 20 87 e9 7b d5 6c |.....%...! ..{.l| +00000150 ed 43 f2 56 e4 00 5c 30 8b ec 63 cb ef da 90 aa |.C.V..\0..c.....| +00000160 e2 eb 0e ad 23 db 90 c5 02 47 7c 16 03 03 00 48 |....#....G|....H| +00000170 0f 00 00 44 08 07 00 40 71 03 0f a9 ed a8 cf 3c |...D...@q......<| +00000180 73 e6 ae 21 92 93 68 10 bc e0 fd 07 d8 58 30 7c |s..!..h......X0|| +00000190 8d f2 1d ee e6 20 4c a4 6a 4b b8 66 6c 51 b5 1a |..... L.jK.flQ..| +000001a0 06 f1 5d 13 83 43 60 6f b1 f7 56 97 b2 ef c6 b8 |..]..C`o..V.....| +000001b0 97 0b 9a fe 46 3e 9a 00 14 03 03 00 01 01 16 03 |....F>..........| +000001c0 03 00 28 de 17 73 c1 91 60 06 3d 0c 9c d0 5a c9 |..(..s..`.=...Z.| +000001d0 f2 2b f4 80 8b e8 01 dc 84 ff a1 16 08 1e af 76 |.+.............v| +000001e0 f2 fc 34 52 3f 87 60 9e 06 ff c2 |..4R?.`....| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -00000010 00 00 00 49 81 2d e8 88 dc 52 2a 44 51 18 2e 62 |...I.-...R*DQ..b| -00000020 28 9e 91 7a 87 b5 fb 46 89 27 01 5e dc b1 12 00 |(..z...F.'.^....| -00000030 72 fe 34 17 03 03 00 25 00 00 00 00 00 00 00 01 |r.4....%........| -00000040 ab a1 6a 44 4b 80 a8 2e f4 75 ff 09 9f 11 05 74 |..jDK....u.....t| -00000050 93 ab 97 de 54 16 36 f9 0a 3c a1 89 c0 15 03 03 |....T.6..<......| -00000060 00 1a 00 00 00 00 00 00 00 02 2d 63 e8 72 ab 7b |..........-c.r.{| -00000070 20 de f4 73 05 4a 26 a1 78 7a 1c 02 | ..s.J&.xz..| +00000010 00 00 00 db 9b a0 e5 96 0d ca 2b ce 8a 3c 9e bc |..........+..<..| +00000020 43 1a ad 0d fb a1 7e 0d 39 7d 3f b4 79 bd ee 7a |C.....~.9}?.y..z| +00000030 e4 a1 6e 17 03 03 00 25 00 00 00 00 00 00 00 01 |..n....%........| +00000040 05 bd 7f 40 dd 89 b2 fd 3c ef a6 72 a0 dd 9f be |...@....<..r....| +00000050 ee 27 ca a6 e0 f1 c8 3c 69 3c 35 02 48 15 03 03 |.'.....>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 de e6 7c 24 10 |.............|$.| -00000010 d1 3a 48 8f ba 9a cf 0f 4b 8d 81 8b 07 41 4f bd |.:H.....K....AO.| -00000020 46 9b c1 dc 24 51 aa 30 83 a2 49 00 00 04 00 2f |F...$Q.0..I..../| +00000000 16 03 01 00 97 01 00 00 93 03 03 b1 ad 52 31 a1 |.............R1.| +00000010 0a ff 18 7f 32 d2 83 f2 e2 9d 54 03 6f fc 58 66 |....2.....T.o.Xf| +00000020 29 e8 3e bc c3 4d d9 75 6e 06 53 00 00 04 00 2f |).>..M.un.S..../| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,77 +10,118 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 1d 0d 00 00 19 02 01 40 |;..............@| -000002a0 00 12 04 01 04 03 08 07 05 01 06 01 05 03 06 03 |................| -000002b0 02 01 02 03 00 00 16 03 03 00 04 0e 00 00 00 |...............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d |.`.\!.;.......#.| +000002a0 00 00 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 |.....@..........| +000002b0 08 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 |................| +000002c0 00 00 16 03 03 00 04 0e 00 00 00 |...........| >>> Flow 3 (client to server) -00000000 16 03 03 00 07 0b 00 00 03 00 00 00 16 03 03 00 |................| -00000010 86 10 00 00 82 00 80 2e 43 3b 39 9a be ef de 53 |........C;9....S| -00000020 4a 94 a3 a3 bd 92 93 44 e7 27 be f9 97 c9 1b fd |J......D.'......| -00000030 22 1b 6a 6c c3 79 87 45 01 a8 e0 ee 34 5a 23 61 |".jl.y.E....4Z#a| -00000040 25 e4 06 88 fd b5 0d a3 dc e4 64 02 14 7e 47 fb |%.........d..~G.| -00000050 3b 88 7d 7f a9 e2 63 64 1a 15 db c6 de 03 a0 ed |;.}...cd........| -00000060 3c 33 b6 2f cc 2a fe 44 8f d7 be 61 0f e5 ea 2f |<3./.*.D...a.../| -00000070 63 7f c1 fa bc de d3 fd 10 3e 89 48 2c cf ab 57 |c........>.H,..W| -00000080 ee b4 04 11 8c 2e 2d ec b9 e5 d0 ac e7 b7 4d 60 |......-.......M`| -00000090 fd fe 7f 88 f1 35 9b 14 03 03 00 01 01 16 03 03 |.....5..........| -000000a0 00 40 ae 7d 3a a0 36 5b 4c b2 fe d7 3d 8b e8 45 |.@.}:.6[L...=..E| -000000b0 f3 43 ae c4 d0 62 74 b5 44 38 3e f0 fd 68 f2 0b |.C...bt.D8>..h..| -000000c0 4a e6 b9 e8 59 4d 84 6a cd a3 83 5a 95 8f 7a a8 |J...YM.j...Z..z.| -000000d0 32 db b7 cd ef e8 5a dc 25 e5 1b 5f 02 7b e7 02 |2.....Z.%.._.{..| -000000e0 fd d1 |..| +00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0| +00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.| +00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.| +00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1| +00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C| +00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523| +00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231| +00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac| +00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.| +00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....| +000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x| +000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.| +000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4| +000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..| +000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#| +000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....| +00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......| +00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..| +00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U| +00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U| +00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......| +00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.| +00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0| +00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........| +00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..| +00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]| +000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A| +000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...| +000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...| +000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......| +000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{| +000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....| +00000200 e5 35 16 03 03 00 86 10 00 00 82 00 80 48 d4 42 |.5...........H.B| +00000210 f3 7f 89 ce 32 5a 89 32 c4 4e 6a 66 f7 0d 3d 63 |....2Z.2.Njf..=c| +00000220 e9 69 74 b5 f4 5e cb 99 74 6c c5 85 39 a3 24 ab |.it..^..tl..9.$.| +00000230 a0 0c 16 1b 9b 0f b5 57 8f 97 30 de ae 44 fd da |.......W..0..D..| +00000240 9f 0d 09 47 d7 a1 f7 aa 88 1d a5 e2 6d de 5b 92 |...G........m.[.| +00000250 25 8e 84 7e fd 21 fe 00 c2 c7 d8 4c df 0c 40 07 |%..~.!.....L..@.| +00000260 7a e6 61 45 37 6d 36 fd e8 44 8e 9c c7 04 31 46 |z.aE7m6..D....1F| +00000270 6b 24 51 37 e0 09 84 ba 56 39 5e df 99 9f 6e 8a |k$Q7....V9^...n.| +00000280 35 b2 27 a1 29 83 fb f7 c9 06 88 c5 6a 16 03 03 |5.'.).......j...| +00000290 00 88 0f 00 00 84 08 04 00 80 01 b3 d6 d0 58 c4 |..............X.| +000002a0 bc 36 b2 c5 6e a2 90 77 52 33 19 a1 9c 2f a4 ed |.6..n..wR3.../..| +000002b0 76 b7 7b 67 ce 36 e2 37 b3 23 68 78 c0 2f 80 d4 |v.{g.6.7.#hx./..| +000002c0 58 0e fc 11 dc 85 b6 9c 25 7f 02 48 b9 a3 24 8c |X.......%..H..$.| +000002d0 26 94 8c 6d 8d 87 6c 9b 20 97 b2 49 ea b6 4c 16 |&..m..l. ..I..L.| +000002e0 03 96 0a 93 e7 15 e4 cb 5a 43 5c 11 77 0e a9 cb |........ZC\.w...| +000002f0 5e c6 4a d3 84 9a 27 e7 81 84 56 ad fa 4b b3 fe |^.J...'...V..K..| +00000300 03 d9 91 1a cf 6e 5b 5e f9 b0 fb 59 27 29 e2 09 |.....n[^...Y')..| +00000310 db 63 69 05 28 7c 95 45 7b da 14 03 03 00 01 01 |.ci.(|.E{.......| +00000320 16 03 03 00 40 20 4f 52 fa e4 4b 92 8e 3f 52 18 |....@ OR..K..?R.| +00000330 42 ba 07 93 fe 1d 11 ee d9 2f 37 55 88 cd 03 18 |B......../7U....| +00000340 e7 44 95 b4 c2 69 91 38 f1 39 ba 14 f6 59 98 22 |.D...i.8.9...Y."| +00000350 64 a1 a0 a3 b9 2e ec cb 14 dc 85 60 b4 95 3a 5a |d..........`..:Z| +00000360 77 a7 65 eb 02 |w.e..| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 18 1c 14 83 35 |...............5| -00000020 c3 40 2a 62 72 5d 6f 23 98 1e 1c cf 3c 1f 76 f0 |.@*br]o#....<.v.| -00000030 49 cb 62 80 32 e6 d8 6d 95 9b 58 47 2d 65 ff 25 |I.b.2..m..XG-e.%| -00000040 00 99 db 92 58 e0 e9 09 90 c3 72 17 03 03 00 40 |....X.....r....@| +00000010 00 00 00 00 00 00 00 00 00 00 00 56 f9 31 18 46 |...........V.1.F| +00000020 ce f2 b8 78 c8 34 ec b4 33 d4 ee 42 9f cc a1 40 |...x.4..3..B...@| +00000030 45 fc 81 bd 33 86 93 6e 0d 59 01 15 2e 71 ae 8d |E...3..n.Y...q..| +00000040 18 1a 10 6d 86 d5 17 7d 80 3f a3 17 03 03 00 40 |...m...}.?.....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 b5 9c b1 d1 30 6e 93 66 69 07 47 f6 31 ad e9 e1 |....0n.fi.G.1...| -00000070 c5 d4 5c 98 ac 00 41 cd 84 c3 56 61 b1 36 fd ad |..\...A...Va.6..| -00000080 7f c6 b1 27 1d ef b9 ba 43 a1 7e f4 71 d9 55 6e |...'....C.~.q.Un| +00000060 c1 b4 84 5e 61 48 33 a2 91 ae 7c d9 ee 9a fc 78 |...^aH3...|....x| +00000070 57 c9 7d 1f fa c8 16 dc 6b c1 ec ff 1b 3f 4d d2 |W.}.....k....?M.| +00000080 69 57 aa e2 95 13 c5 92 81 14 63 bd ba 29 b9 3f |iW........c..).?| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 3f 1a f4 80 31 9b 60 c0 28 76 79 |.....?...1.`.(vy| -000000b0 c1 8f 65 f6 d3 b6 6d 99 6d 11 fa bc a6 b8 bf 7f |..e...m.m.......| -000000c0 8b ca c5 a1 cd |.....| +000000a0 00 00 00 00 00 b8 22 70 50 65 d6 ae 00 6b f7 e1 |......"pPe...k..| +000000b0 76 1d 03 d7 f7 80 56 74 73 af f2 6c 70 6f cb 4a |v.....Vts..lpo.J| +000000c0 b3 2a 18 1b b5 |.*...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given index 1bb602d0787..b38cb416f62 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 b1 59 5d 29 7f |............Y]).| -00000010 90 9c ef 9d ae 0a 91 6c ab 05 fb 58 f7 79 9b c4 |.......l...X.y..| -00000020 22 e1 ab 55 5c ea d1 24 27 2a 63 00 00 04 00 2f |"..U\..$'*c..../| +00000000 16 03 01 00 97 01 00 00 93 03 03 a1 ef 12 cf c0 |................| +00000010 c2 32 71 56 71 e0 e9 24 ae 63 20 58 0f c0 39 b3 |.2qVq..$.c X..9.| +00000020 74 89 9d 9c 00 96 e5 78 9c 0a 84 00 00 04 00 2f |t......x......./| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,50 +10,51 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 1d 0d 00 00 19 02 01 40 |;..............@| -000002a0 00 12 04 01 04 03 08 07 05 01 06 01 05 03 06 03 |................| -000002b0 02 01 02 03 00 00 16 03 03 00 04 0e 00 00 00 |...............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d |.`.\!.;.......#.| +000002a0 00 00 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 |.....@..........| +000002b0 08 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 |................| +000002c0 00 00 16 03 03 00 04 0e 00 00 00 |...........| >>> Flow 3 (client to server) 00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0| 00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.| @@ -87,40 +88,40 @@ 000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......| 000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{| 000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....| -00000200 e5 35 16 03 03 00 86 10 00 00 82 00 80 aa ad 37 |.5.............7| -00000210 05 40 cc 04 19 d0 de aa 25 9f 20 4e ce 74 f5 70 |.@......%. N.t.p| -00000220 ae 17 f0 29 a4 37 ac 84 67 06 da 17 9f 26 dc ab |...).7..g....&..| -00000230 96 c4 13 d6 a5 e5 93 57 70 17 f2 f1 fb 0e a2 e4 |.......Wp.......| -00000240 85 82 ea 63 ab 6f 6e 1f 0b 12 e7 35 ce b0 79 da |...c.on....5..y.| -00000250 95 cf de 7d 8b be 5e cc d5 8e 00 02 fe 67 61 b4 |...}..^......ga.| -00000260 69 2c 09 90 ae 6c df 29 45 67 79 8e fe 91 fb 3e |i,...l.)Egy....>| -00000270 1e ec 95 11 6c 6a 15 2f 93 59 41 34 8a 35 b0 7c |....lj./.YA4.5.|| -00000280 22 ee bb 99 cc 3d 05 1f 7b 1b 96 f6 bc 16 03 03 |"....=..{.......| -00000290 00 88 0f 00 00 84 04 01 00 80 a5 b1 55 c7 8c 86 |............U...| -000002a0 c1 c2 60 2d ad 40 f1 ca 56 25 39 e7 c1 83 7f 16 |..`-.@..V%9.....| -000002b0 08 6a c9 23 6a 82 73 63 bf 1a 32 de 85 82 2a bc |.j.#j.sc..2...*.| -000002c0 a0 99 db ea 34 26 27 8f c6 36 b7 53 b5 76 75 2e |....4&'..6.S.vu.| -000002d0 48 26 bb b0 65 55 68 57 12 cb 9c 93 96 fc 88 fc |H&..eUhW........| -000002e0 73 56 c1 1e 04 ae 41 aa ad b7 f8 58 7a 55 a9 74 |sV....A....XzU.t| -000002f0 5b b5 12 08 25 ef c1 0f 4c 39 7b c5 07 d9 34 66 |[...%...L9{...4f| -00000300 15 d3 76 a2 65 8c 4c ce 9a 89 0f 1f a9 5f d0 93 |..v.e.L......_..| -00000310 3e ed 92 be 42 4c fe 23 ea 40 14 03 03 00 01 01 |>...BL.#.@......| -00000320 16 03 03 00 40 89 ff 92 80 9b 37 4b 6f 8f 3a 22 |....@.....7Ko.:"| -00000330 aa ab 60 1f 4d 49 ba 75 b2 dc 83 06 22 5a 89 5d |..`.MI.u...."Z.]| -00000340 1f 95 fa 0c 18 80 a0 5a 96 09 93 7b 06 cb 6c aa |.......Z...{..l.| -00000350 74 79 ea ae 02 e7 a7 c9 44 0b 6d f7 f7 b2 04 8f |ty......D.m.....| -00000360 6e 46 2d f1 6b |nF-.k| +00000200 e5 35 16 03 03 00 86 10 00 00 82 00 80 64 8b 67 |.5...........d.g| +00000210 fe b0 0e a0 a6 2b 95 2b 35 24 91 d0 29 6e 0a 3b |.....+.+5$..)n.;| +00000220 bc 32 5f 28 30 a9 6e f3 b8 4a 1d 7c 11 7c c5 03 |.2_(0.n..J.|.|..| +00000230 70 51 99 8f f5 2e 91 78 b9 65 23 3c 3a 7f a7 63 |pQ.....x.e#<:..c| +00000240 1f ad 30 3c 91 b1 d8 79 76 b4 94 a7 76 26 20 c7 |..0<...yv...v& .| +00000250 f1 93 17 13 8a 25 6e 9e 84 9e e5 21 b8 87 46 8d |.....%n....!..F.| +00000260 46 37 7f ef 25 e2 8f 6e 52 58 cc a9 5c 40 ee 5e |F7..%..nRX..\@.^| +00000270 f8 25 04 e9 e1 1e 33 31 ea 9e bd 79 e8 d8 f8 0b |.%....31...y....| +00000280 a5 5d 63 79 1f 83 bc df 14 c9 92 a6 82 16 03 03 |.]cy............| +00000290 00 88 0f 00 00 84 04 01 00 80 06 8a 73 2b 2d 45 |............s+-E| +000002a0 09 3c cf 66 d9 ef d0 44 d0 89 07 03 67 56 b5 c9 |.<.f...D....gV..| +000002b0 de 89 49 32 6e 44 b0 01 db 10 8b 1a 68 5c 2e 0b |..I2nD......h\..| +000002c0 38 e7 75 60 0b 68 96 2e 3b ba bd a8 ce 1e ee 3d |8.u`.h..;......=| +000002d0 e6 a4 c4 3a 5c d0 14 3b 64 52 56 ef 5b 74 45 3c |...:\..;dRV.[tE<| +000002e0 2b eb f6 0b 6c 15 37 5c c3 d3 6d 4c 32 ea 3d 40 |+...l.7\..mL2.=@| +000002f0 7b 60 35 16 44 a4 3c 4a 2e 85 d9 a2 a5 a6 79 11 |{`5.D.>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 67 84 0f 78 e0 |...........g..x.| -00000020 91 c8 d4 4b 1c 69 95 f8 6c 30 23 55 2b 04 4b 24 |...K.i..l0#U+.K$| -00000030 58 0a 46 06 94 00 72 95 77 77 4c d7 82 87 69 0a |X.F...r.wwL...i.| -00000040 4c 78 8a 12 76 27 ae 65 c9 20 c4 17 03 03 00 40 |Lx..v'.e. .....@| +00000010 00 00 00 00 00 00 00 00 00 00 00 1a 60 c5 8b a5 |............`...| +00000020 6d be c2 a0 c7 23 e6 f8 e8 fb e7 31 7c 7f 37 67 |m....#.....1|.7g| +00000030 7c 1e 39 2b ea cd 26 47 5c 7f 19 ad 78 be 11 3d ||.9+..&G\...x..=| +00000040 98 f5 c8 97 22 1d 23 45 55 2b 25 17 03 03 00 40 |....".#EU+%....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 13 3b e0 4b cd 52 d3 6c 90 91 37 38 1d 9c 75 a2 |.;.K.R.l..78..u.| -00000070 02 a3 3f 1a 43 6c aa f4 17 da 4e 01 d7 8c 74 5e |..?.Cl....N...t^| -00000080 f4 d3 61 cf 3c 7f 55 73 17 e7 d1 c3 a0 da 24 c4 |..a.<.Us......$.| +00000060 e0 a5 72 92 b6 6c ee e8 2d 7f cf d9 df 2d 4f 70 |..r..l..-....-Op| +00000070 18 8a c3 9c 10 89 0f 11 df 83 d7 4c 35 ea 4e 19 |...........L5.N.| +00000080 7f ab 8b f0 0e de 32 6e 86 d1 e9 78 90 f6 3b e7 |......2n...x..;.| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 28 75 97 89 88 21 2e fe 9b 81 87 |.....(u...!.....| -000000b0 2a 37 f0 81 9f 76 a2 27 a4 78 69 30 87 2c 09 6e |*7...v.'.xi0.,.n| -000000c0 55 90 fb ab b6 |U....| +000000a0 00 00 00 00 00 db 5e ed de c0 26 10 13 a8 18 46 |......^...&....F| +000000b0 70 3e a4 bd b7 df a1 bd 86 06 c6 97 ae cb ca f6 |p>..............| +000000c0 8d 0f 85 82 f7 |.....| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven index 5711a3f6b6d..6f7c2884214 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 67 52 bd 6c 6c |...........gR.ll| -00000010 76 8e 81 75 11 23 27 99 07 bf 64 96 13 0b 85 78 |v..u.#'...d....x| -00000020 b4 5b b9 b0 a8 b5 fc 87 ef f2 0e 00 00 04 00 2f |.[............./| +00000000 16 03 01 00 97 01 00 00 93 03 03 07 72 d5 84 85 |............r...| +00000010 48 68 f6 83 2f 1d 22 96 61 9d 27 60 b9 70 d2 5f |Hh../.".a.'`.p._| +00000020 5e 9e 41 cb 82 9b 61 c6 ae af a7 00 00 04 00 2f |^.A...a......../| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,77 +10,78 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 1d 0d 00 00 19 02 01 40 |;..............@| -000002a0 00 12 04 01 04 03 08 07 05 01 06 01 05 03 06 03 |................| -000002b0 02 01 02 03 00 00 16 03 03 00 04 0e 00 00 00 |...............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d |.`.\!.;.......#.| +000002a0 00 00 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 |.....@..........| +000002b0 08 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 |................| +000002c0 00 00 16 03 03 00 04 0e 00 00 00 |...........| >>> Flow 3 (client to server) 00000000 16 03 03 00 07 0b 00 00 03 00 00 00 16 03 03 00 |................| -00000010 86 10 00 00 82 00 80 31 7f 5d 8c 38 ee d7 05 14 |.......1.].8....| -00000020 4c 0f 9d 01 2d 80 e9 71 0a 51 69 7b af 75 43 76 |L...-..q.Qi{.uCv| -00000030 d7 eb 18 14 11 00 82 df f4 e8 d1 83 5e 32 60 6e |............^2`n| -00000040 49 6d 1a 3f b2 ac 85 9f f3 3c 3c cd f2 0d a8 e0 |Im.?.....<<.....| -00000050 06 f3 6f 96 18 a0 76 06 c3 73 89 b4 de 30 ed 7b |..o...v..s...0.{| -00000060 7e 71 2d 13 88 43 ff a7 42 bb 2c 17 73 5f 67 8f |~q-..C..B.,.s_g.| -00000070 68 e7 52 84 72 34 08 69 c6 f5 1b e9 2b 42 93 90 |h.R.r4.i....+B..| -00000080 3f 76 f3 89 9f 70 65 da 9c ce 8c bf a3 38 65 e3 |?v...pe......8e.| -00000090 cf b9 f9 c6 d9 86 a5 14 03 03 00 01 01 16 03 03 |................| -000000a0 00 40 e7 dd bf f7 33 bc f2 90 a3 43 fa 43 ec 7e |.@....3....C.C.~| -000000b0 e6 06 28 c1 3f 83 c5 50 65 6d 6b e7 37 cf e7 4b |..(.?..Pemk.7..K| -000000c0 85 34 3b df 4f 48 82 30 d0 43 f7 00 c4 3f 03 dd |.4;.OH.0.C...?..| -000000d0 ef c0 d4 04 48 b4 9b ec f0 65 7c 2a bc 87 24 5f |....H....e|*..$_| -000000e0 7a d5 |z.| +00000010 86 10 00 00 82 00 80 60 6d 7c a2 1e 90 d3 14 55 |.......`m|.....U| +00000020 2b 65 e6 14 10 59 51 ba f0 55 89 1d f6 d2 6e 85 |+e...YQ..U....n.| +00000030 58 16 fc 45 a2 88 ae 24 b6 77 c0 f4 9e 6f de 76 |X..E...$.w...o.v| +00000040 d4 9c 06 a3 6c 4f 54 da e5 41 e4 f8 fd 2d ca c6 |....lOT..A...-..| +00000050 c4 7f 5a d4 c5 7b 3e 04 30 3e 64 b1 f5 c2 24 8f |..Z..{>.0>d...$.| +00000060 49 98 2c f7 29 89 06 7e 5e 8f 9e 8e 6c fc 4c 08 |I.,.)..~^...l.L.| +00000070 3e 05 f9 90 86 d9 38 b8 04 ff 7e a1 c2 a5 38 66 |>.....8...~...8f| +00000080 41 63 7a 8e d2 7b 27 22 0e a1 0c 17 1e d7 9f 29 |Acz..{'".......)| +00000090 5c fa fe 2d 11 b3 4a 14 03 03 00 01 01 16 03 03 |\..-..J.........| +000000a0 00 40 e3 e5 62 d6 c9 93 bd 91 a4 60 2e 2d 9d 0b |.@..b......`.-..| +000000b0 ce 75 2a e9 19 ed 36 03 ff 97 ee b7 b9 61 04 1b |.u*...6......a..| +000000c0 a9 a3 4c 8a a0 c9 40 c4 92 55 bb ed 17 1f 38 c4 |..L...@..U....8.| +000000d0 45 46 1f d6 53 b7 3b 6b 09 b6 d7 f1 a4 0e 25 21 |EF..S.;k......%!| +000000e0 10 21 |.!| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 da 0a 2a 09 ef |.............*..| -00000020 39 6c c9 6d cc c3 ae 56 cd e1 a8 47 26 ec 9c b7 |9l.m...V...G&...| -00000030 50 eb 2e 10 d4 15 3e 5e cc 65 78 2e 47 bf 18 e8 |P.....>^.ex.G...| -00000040 62 59 bb 7c b7 2c 28 b1 ea 82 10 17 03 03 00 40 |bY.|.,(........@| +00000010 00 00 00 00 00 00 00 00 00 00 00 17 ce 12 8e 1a |................| +00000020 1f c2 d2 9c c9 28 c0 89 cb fa 8c 48 28 a2 d2 93 |.....(.....H(...| +00000030 a6 aa 43 35 5f 29 ab e2 c6 f9 70 f6 8f d9 da af |..C5_)....p.....| +00000040 da 2a 02 24 9c 74 57 3d a2 0f 6d 17 03 03 00 40 |.*.$.tW=..m....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 9e 53 10 86 89 0c 8f 14 0c 22 6c 32 33 34 64 83 |.S......."l234d.| -00000070 28 7c 02 b3 59 b7 b2 60 5a ec f2 a7 1a 21 04 dd |(|..Y..`Z....!..| -00000080 2a c0 ca 68 07 85 8f 7d 6b da 26 97 52 91 40 e8 |*..h...}k.&.R.@.| +00000060 58 99 9f 9b 65 fd 53 7e 4a 82 47 99 d7 16 b7 4f |X...e.S~J.G....O| +00000070 84 7d 49 c0 af 42 84 54 e1 31 dc 01 00 de 8c 08 |.}I..B.T.1......| +00000080 a3 ee 9b 32 b4 f0 30 d1 ae 8e f5 5d 11 ad eb fb |...2..0....]....| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 f4 ae 69 5a bc af 94 f9 7f 60 d1 |.......iZ.....`.| -000000b0 36 83 e7 23 13 79 ae c1 5a 3b 35 d0 ed 16 12 ac |6..#.y..Z;5.....| -000000c0 52 b5 4e eb 31 |R.N.1| +000000a0 00 00 00 00 00 94 b8 23 55 00 7e 3a ba 67 86 03 |.......#U.~:.g..| +000000b0 e6 19 11 4a 7d 58 69 6f 79 bb be 6d ba a7 9f a2 |...J}Xioy..m....| +000000c0 1a 30 b7 83 2e |.0...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES b/libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES index d72746872e2..d7e61880363 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 85 04 eb 6f 6a |..............oj| -00000010 88 25 0b 90 fb 37 a8 63 c7 18 1a ac 91 a9 aa 24 |.%...7.c.......$| -00000020 c3 99 1a 69 e5 f5 1e 12 73 ef 1a 00 00 04 c0 0a |...i....s.......| +00000000 16 03 01 00 97 01 00 00 93 03 03 86 3b 10 1e 5f |............;.._| +00000010 81 eb 21 bd 77 47 61 e9 3f 82 85 14 91 8c ab 7d |..!.wGa.?......}| +00000020 84 bd b1 f0 06 20 8a 7b 06 d6 78 00 00 04 c0 0a |..... .{..x.....| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,75 +10,76 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 0a 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 03 02 0e 0b 00 02 0a 00 |................| -00000040 02 07 00 02 04 30 82 02 00 30 82 01 62 02 09 00 |.....0...0..b...| -00000050 b8 bf 2d 47 a0 d2 eb f4 30 09 06 07 2a 86 48 ce |..-G....0...*.H.| -00000060 3d 04 01 30 45 31 0b 30 09 06 03 55 04 06 13 02 |=..0E1.0...U....| -00000070 41 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d |AU1.0...U....Som| -00000080 65 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a |e-State1!0...U..| -00000090 13 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 |..Internet Widgi| -000000a0 74 73 20 50 74 79 20 4c 74 64 30 1e 17 0d 31 32 |ts Pty Ltd0...12| -000000b0 31 31 32 32 31 35 30 36 33 32 5a 17 0d 32 32 31 |1122150632Z..221| -000000c0 31 32 30 31 35 30 36 33 32 5a 30 45 31 0b 30 09 |120150632Z0E1.0.| -000000d0 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 55 |..U....AU1.0...U| -000000e0 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 21 |....Some-State1!| -000000f0 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e 65 |0...U....Interne| -00000100 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c 74 |t Widgits Pty Lt| -00000110 64 30 81 9b 30 10 06 07 2a 86 48 ce 3d 02 01 06 |d0..0...*.H.=...| -00000120 05 2b 81 04 00 23 03 81 86 00 04 00 c4 a1 ed be |.+...#..........| -00000130 98 f9 0b 48 73 36 7e c3 16 56 11 22 f2 3d 53 c3 |...Hs6~..V.".=S.| -00000140 3b 4d 21 3d cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc |;M!=.ku......&..| -00000150 b2 87 f0 72 32 7c b3 64 2f 1c 90 bc ea 68 23 10 |...r2|.d/....h#.| -00000160 7e fe e3 25 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 |~..%.H:i.(m.7...| -00000170 62 dd 0d a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 |b....pb....d1...| -00000180 31 bd 96 b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 |1...h..#.vd?.\..| -00000190 12 0e 58 58 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc |..XX._p.........| -000001a0 b9 b6 9f 30 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 |...0f[f. .'...;0| -000001b0 09 06 07 2a 86 48 ce 3d 04 01 03 81 8c 00 30 81 |...*.H.=......0.| -000001c0 88 02 42 01 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 |..B...O..E.H}...| -000001d0 ed 98 9d ae 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 |....Gp.^../...M.| -000001e0 61 40 d3 11 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b |a@......~.~.v..;| -000001f0 7e a5 3f ce fa 10 e2 59 ec 47 2d 7c ac da 4e 97 |~.?....Y.G-|..N.| -00000200 0e 15 a0 6f d0 02 42 01 4d fc be 67 13 9c 2d 05 |...o..B.M..g..-.| -00000210 0e bd 3f a3 8c 25 c1 33 13 83 0d 94 06 bb d4 37 |..?..%.3.......7| -00000220 7a f6 ec 7a c9 86 2e dd d7 11 69 7f 85 7c 56 de |z..z......i..|V.| -00000230 fb 31 78 2b e4 c7 78 0d ae cb be 9e 4e 36 24 31 |.1x+..x.....N6$1| -00000240 7b 6a 0f 39 95 12 07 8f 2a 16 03 03 00 b7 0c 00 |{j.9....*.......| -00000250 00 b3 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 |..... /.}.G.bC.(| -00000260 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 |.._.).0.........| -00000270 99 5f 58 cb 3b 74 04 03 00 8b 30 81 88 02 42 01 |._X.;t....0...B.| -00000280 4b 46 70 e2 b9 cb ea 38 8f 00 6e 47 5e 1a 1c a1 |KFp....8..nG^...| -00000290 fb a9 1c 3d a1 88 0d c4 8a 45 af 50 32 ba 36 e9 |...=.....E.P2.6.| -000002a0 f5 b0 09 aa 39 1a 96 9e c6 74 98 ad b8 09 79 b4 |....9....t....y.| -000002b0 5b 01 8f 9a 66 11 0e a8 6a ac 61 f4 40 3d 4f 9b |[...f...j.a.@=O.| -000002c0 9f 02 42 00 a1 2f b0 46 41 42 35 5a 4b 7b bb 22 |..B../.FAB5ZK{."| -000002d0 d9 a5 31 23 2c 94 8f 48 39 29 c6 33 6a 52 a6 22 |..1#,..H9).3jR."| -000002e0 5d 72 5b 2c 45 e9 0d 0a fb f4 24 26 d4 50 5e 20 |]r[,E.....$&.P^ | -000002f0 f4 fc 6c a9 62 4b db a1 74 88 1a ef bd 78 dd e8 |..l.bK..t....x..| -00000300 5a 04 be ca 25 16 03 03 00 04 0e 00 00 00 |Z...%.........| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 00 30 |...........0...0| +00000050 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 30 09 |..b.....-G....0.| +00000060 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 09 06 |..*.H.=..0E1.0..| +00000070 03 55 04 06 13 02 41 55 31 13 30 11 06 03 55 04 |.U....AU1.0...U.| +00000080 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 |...Some-State1!0| +00000090 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 |...U....Internet| +000000a0 20 57 69 64 67 69 74 73 20 50 74 79 20 4c 74 64 | Widgits Pty Ltd| +000000b0 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 33 32 |0...121122150632| +000000c0 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 32 5a |Z..221120150632Z| +000000d0 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 |0E1.0...U....AU1| +000000e0 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 |.0...U....Some-S| +000000f0 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 |tate1!0...U....I| +00000100 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 |nternet Widgits | +00000110 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 2a 86 |Pty Ltd0..0...*.| +00000120 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....| +00000130 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 16 56 |.........Hs6~..V| +00000140 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 f6 b0 |.".=S.;M!=.ku...| +00000150 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 2f 1c |...&.....r2|.d/.| +00000160 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 e0 28 |...h#.~..%.H:i.(| +00000170 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 d8 81 |m.7...b....pb...| +00000180 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 de 76 |.d1...1...h..#.v| +00000190 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd 9b d8 |d?.\....XX._p...| +000001a0 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a 20 e2 |.........0f[f. .| +000001b0 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d 04 01 |'...;0...*.H.=..| +000001c0 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb e2 45 |....0...B...O..E| +000001d0 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e 1b b6 |.H}.......Gp.^..| +000001e0 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b 7e 92 |/...M.a@......~.| +000001f0 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 ec 47 |~.v..;~.?....Y.G| +00000200 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 4d fc |-|..N....o..B.M.| +00000210 be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 13 83 |.g..-...?..%.3..| +00000220 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd d7 11 |.....7z..z......| +00000230 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d ae cb |i..|V..1x+..x...| +00000240 be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f 2a 16 |..N6$1{j.9....*.| +00000250 03 03 00 b7 0c 00 00 b3 03 00 1d 20 2f e5 7d a3 |........... /.}.| +00000260 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...| +00000270 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 04 03 00 8b |......._X.;t....| +00000280 30 81 88 02 42 01 c5 d1 36 97 5b 0e 5e a6 90 50 |0...B...6.[.^..P| +00000290 a0 2e 80 b5 df d7 5a f6 95 0d a4 c6 f0 da 2e e7 |......Z.........| +000002a0 91 79 9f 85 2e ef ca 66 3c f7 c4 7b bd 61 70 bb |.y.....f<..{.ap.| +000002b0 16 c5 aa 00 35 33 ae 58 00 b3 f1 fe 0f 77 52 23 |....53.X.....wR#| +000002c0 f4 40 ba 4b c7 e5 43 02 42 01 64 af ab 8a 87 38 |.@.K..C.B.d....8| +000002d0 a1 7f b8 ae 84 0e a4 ff ad 16 09 44 0b 65 67 70 |...........D.egp| +000002e0 12 7f 1a 37 9a 1d 5e b7 3b 63 df f9 6b f1 b9 ba |...7..^.;c..k...| +000002f0 6b 35 8f b3 03 da 3d 61 00 3d 4e 75 b4 d0 92 d5 |k5....=a.=Nu....| +00000300 ee 50 9d d7 f9 26 69 e6 ec cf 3b 16 03 03 00 04 |.P...&i...;.....| +00000310 0e 00 00 00 |....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 80 d6 42 fa 29 87 |....%...! ..B.).| -00000010 df 45 d0 44 75 c7 bd a9 be e7 8c ef 3f 74 3d bd |.E.Du.......?t=.| -00000020 e2 49 40 ad f9 7f 90 ff 5e 75 14 03 03 00 01 01 |.I@.....^u......| -00000030 16 03 03 00 40 dc c3 d3 7b 19 19 67 e1 f1 f7 3b |....@...{..g...;| -00000040 f7 76 0f da df 38 88 73 61 34 83 04 b9 ab 61 72 |.v...8.sa4....ar| -00000050 2f 38 cb c3 1b 04 60 20 32 a8 db 46 63 85 f2 21 |/8....` 2..Fc..!| -00000060 54 6e 9d 5d ba 0a 07 2e 9d 38 af 76 0e 29 b1 c6 |Tn.].....8.v.)..| -00000070 d5 b0 f8 b3 39 |....9| +00000000 16 03 03 00 25 10 00 00 21 20 54 db 5b a1 4c e0 |....%...! T.[.L.| +00000010 0e 52 a2 45 e3 b4 ac 91 3d e1 de a9 3e eb 80 9e |.R.E....=...>...| +00000020 f5 04 7b fc 82 10 2f d9 d1 41 14 03 03 00 01 01 |..{.../..A......| +00000030 16 03 03 00 40 47 68 cc 5e 68 3f 05 d6 f8 5c 11 |....@Gh.^h?...\.| +00000040 08 a3 91 72 ae 4c 98 67 2f 45 ee 16 6b 8b 2d 28 |...r.L.g/E..k.-(| +00000050 15 34 43 47 f9 46 f2 96 c2 85 d5 cc 03 e0 84 de |.4CG.F..........| +00000060 9c 03 fe bf c9 73 23 15 d0 0f 85 3a 76 db 9f 5d |.....s#....:v..]| +00000070 95 b7 de 9c c2 |.....| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 4f dc d7 df d3 |...........O....| -00000020 ab 43 f7 20 57 51 28 d2 0a ce ac e0 88 5c 01 c5 |.C. WQ(......\..| -00000030 22 f7 37 e8 ac d3 38 ab 1b 43 53 b1 a7 35 6f 86 |".7...8..CS..5o.| -00000040 2b a5 9b 98 8f 9d a3 ff 11 d2 c7 17 03 03 00 40 |+..............@| +00000010 00 00 00 00 00 00 00 00 00 00 00 98 34 52 f3 44 |............4R.D| +00000020 18 69 23 61 ef 8f e9 c0 88 9c ad 1f cb e4 8d 55 |.i#a...........U| +00000030 bd bb 77 9c 65 9d 21 f0 54 4c 46 db 4f e6 e8 ab |..w.e.!.TLF.O...| +00000040 6b 1d 60 38 7f e0 2c 38 ef e7 43 17 03 03 00 40 |k.`8..,8..C....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 3f 4c d0 ee d7 12 3c ef 73 55 b0 8d b7 78 8a de |?L....<.sU...x..| -00000070 d9 a5 c0 58 25 95 ae 8c 0f 85 bd ee 93 80 f6 3d |...X%..........=| -00000080 ac 28 a6 87 98 d2 4c e4 54 a6 a5 ef 12 70 0c 37 |.(....L.T....p.7| +00000060 44 68 90 07 1e 8c 7f db 3e 3f 8c 28 e1 d7 41 38 |Dh......>?.(..A8| +00000070 e2 78 04 e3 42 c2 a9 76 bb 0a ae b9 93 df 81 d7 |.x..B..v........| +00000080 9b 0f 1d 44 19 79 ff 7c 21 8f 75 ca e2 82 cc c4 |...D.y.|!.u.....| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 e3 51 95 2e 0c 71 a9 e6 c6 4d bc |......Q...q...M.| -000000b0 2e 89 99 c0 db e8 59 0a e0 a2 f8 46 ef 3b 20 c6 |......Y....F.; .| -000000c0 8d a4 55 a2 5e |..U.^| +000000a0 00 00 00 00 00 82 1f e6 2c 3f c7 55 19 01 0b 62 |........,?.U...b| +000000b0 1a 99 fc f8 d3 b0 38 21 41 92 1a d1 e0 43 96 da |......8!A....C..| +000000c0 80 4b 58 91 c8 |.KX..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-Ed25519 b/libgo/go/crypto/tls/testdata/Server-TLSv12-Ed25519 index f4247915f49..6d8b28b82a6 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-Ed25519 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-Ed25519 @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 cb 01 00 00 c7 03 03 a6 41 b7 62 67 |............A.bg| -00000010 34 b4 48 22 67 fd e6 a9 12 29 b7 85 6a 27 c9 fc |4.H"g....)..j'..| -00000020 70 3a cc 0c 94 61 88 d1 9e 22 3d 00 00 38 c0 2c |p:...a..."=..8.,| +00000000 16 03 01 00 cb 01 00 00 c7 03 03 b8 0c b4 c2 92 |................| +00000010 d9 b6 77 56 d9 9f 2b 94 c9 2f c8 28 4f bf 69 bc |..wV..+../.(O.i.| +00000020 8f 4c 81 46 a6 43 4b e7 e5 70 b2 00 00 38 c0 2c |.L.F.CK..p...8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| @@ -13,51 +13,51 @@ 000000b0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................| 000000c0 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 2c 00 00 |...DOWNGRD...,..| -00000030 05 ff 01 00 01 00 16 03 03 01 3c 0b 00 01 38 00 |..........<...8.| -00000040 01 35 00 01 32 30 82 01 2e 30 81 e1 a0 03 02 01 |.5..20...0......| -00000050 02 02 10 0f 43 1c 42 57 93 94 1d e9 87 e4 f1 ad |....C.BW........| -00000060 15 00 5d 30 05 06 03 2b 65 70 30 12 31 10 30 0e |..]0...+ep0.1.0.| -00000070 06 03 55 04 0a 13 07 41 63 6d 65 20 43 6f 30 1e |..U....Acme Co0.| -00000080 17 0d 31 39 30 35 31 36 32 31 33 38 30 31 5a 17 |..190516213801Z.| -00000090 0d 32 30 30 35 31 35 32 31 33 38 30 31 5a 30 12 |.200515213801Z0.| -000000a0 31 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 |1.0...U....Acme | -000000b0 43 6f 30 2a 30 05 06 03 2b 65 70 03 21 00 3f e2 |Co0*0...+ep.!.?.| -000000c0 15 2e e6 e3 ef 3f 4e 85 4a 75 77 a3 64 9e ed e0 |.....?N.Juw.d...| -000000d0 bf 84 2c cc 92 26 8f fa 6f 34 83 aa ec 8f a3 4d |..,..&..o4.....M| -000000e0 30 4b 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 |0K0...U.........| -000000f0 05 a0 30 13 06 03 55 1d 25 04 0c 30 0a 06 08 2b |..0...U.%..0...+| -00000100 06 01 05 05 07 03 01 30 0c 06 03 55 1d 13 01 01 |.......0...U....| -00000110 ff 04 02 30 00 30 16 06 03 55 1d 11 04 0f 30 0d |...0.0...U....0.| -00000120 82 0b 65 78 61 6d 70 6c 65 2e 63 6f 6d 30 05 06 |..example.com0..| -00000130 03 2b 65 70 03 41 00 63 44 ed 9c c4 be 53 24 53 |.+ep.A.cD....S$S| -00000140 9f d2 10 8d 9f e8 21 08 90 95 39 e5 0d c1 55 ff |......!...9...U.| -00000150 2c 16 b7 1d fc ab 7d 4d d4 e0 93 13 d0 a9 42 e0 |,.....}M......B.| -00000160 b6 6b fe 5d 67 48 d7 9f 50 bc 6c cd 4b 03 83 7c |.k.]gH..P.l.K..|| -00000170 f2 08 58 cd ac cf 0c 16 03 03 00 6c 0c 00 00 68 |..X........l...h| -00000180 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 da ac |... /.}.G.bC.(..| -00000190 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f |_.).0.........._| -000001a0 58 cb 3b 74 08 07 00 40 b8 a3 37 f4 74 44 64 eb |X.;t...@..7.tDd.| -000001b0 1f 4b a1 5c 6e 3b 46 a0 b8 ce ce da 79 8d 03 d8 |.K.\n;F.....y...| -000001c0 a2 c2 1d ca 25 21 d2 c3 cf 65 02 7e 4c d6 9a 5a |....%!...e.~L..Z| -000001d0 ba 60 51 71 e4 37 ab 70 18 73 f1 a0 e5 f9 e3 2d |.`Qq.7.p.s.....-| -000001e0 00 37 68 97 cf fa e4 08 16 03 03 00 04 0e 00 00 |.7h.............| -000001f0 00 |.| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 01 |................| +00000040 3c 0b 00 01 38 00 01 35 00 01 32 30 82 01 2e 30 |<...8..5..20...0| +00000050 81 e1 a0 03 02 01 02 02 10 0f 43 1c 42 57 93 94 |..........C.BW..| +00000060 1d e9 87 e4 f1 ad 15 00 5d 30 05 06 03 2b 65 70 |........]0...+ep| +00000070 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 6d |0.1.0...U....Acm| +00000080 65 20 43 6f 30 1e 17 0d 31 39 30 35 31 36 32 31 |e Co0...19051621| +00000090 33 38 30 31 5a 17 0d 32 30 30 35 31 35 32 31 33 |3801Z..200515213| +000000a0 38 30 31 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 |801Z0.1.0...U...| +000000b0 07 41 63 6d 65 20 43 6f 30 2a 30 05 06 03 2b 65 |.Acme Co0*0...+e| +000000c0 70 03 21 00 3f e2 15 2e e6 e3 ef 3f 4e 85 4a 75 |p.!.?......?N.Ju| +000000d0 77 a3 64 9e ed e0 bf 84 2c cc 92 26 8f fa 6f 34 |w.d.....,..&..o4| +000000e0 83 aa ec 8f a3 4d 30 4b 30 0e 06 03 55 1d 0f 01 |.....M0K0...U...| +000000f0 01 ff 04 04 03 02 05 a0 30 13 06 03 55 1d 25 04 |........0...U.%.| +00000100 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 30 0c 06 |.0...+.......0..| +00000110 03 55 1d 13 01 01 ff 04 02 30 00 30 16 06 03 55 |.U.......0.0...U| +00000120 1d 11 04 0f 30 0d 82 0b 65 78 61 6d 70 6c 65 2e |....0...example.| +00000130 63 6f 6d 30 05 06 03 2b 65 70 03 41 00 63 44 ed |com0...+ep.A.cD.| +00000140 9c c4 be 53 24 53 9f d2 10 8d 9f e8 21 08 90 95 |...S$S......!...| +00000150 39 e5 0d c1 55 ff 2c 16 b7 1d fc ab 7d 4d d4 e0 |9...U.,.....}M..| +00000160 93 13 d0 a9 42 e0 b6 6b fe 5d 67 48 d7 9f 50 bc |....B..k.]gH..P.| +00000170 6c cd 4b 03 83 7c f2 08 58 cd ac cf 0c 16 03 03 |l.K..|..X.......| +00000180 00 6c 0c 00 00 68 03 00 1d 20 2f e5 7d a3 47 cd |.l...h... /.}.G.| +00000190 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....| +000001a0 cf c2 ed 90 99 5f 58 cb 3b 74 08 07 00 40 b6 c5 |....._X.;t...@..| +000001b0 00 07 5f 16 0d c5 5a 13 26 8e 74 09 1a 16 7f d2 |.._...Z.&.t.....| +000001c0 4c 90 b5 ee 29 00 7b d6 d0 59 fe 79 1f f2 d9 66 |L...).{..Y.y...f| +000001d0 e2 5e 22 c9 27 b8 09 e5 f3 b6 c4 be 46 4a c2 a9 |.^".'.......FJ..| +000001e0 34 f8 ba ad b6 86 8d 47 58 00 55 d9 3c 03 16 03 |4......GX.U.<...| +000001f0 03 00 04 0e 00 00 00 |.......| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 51 d1 53 24 ee 09 |....%...! Q.S$..| -00000010 51 02 90 7e 6f 02 a2 54 db 6e 95 a4 af f9 43 51 |Q..~o..T.n....CQ| -00000020 d2 ff 6b e6 26 d0 88 4d c1 56 14 03 03 00 01 01 |..k.&..M.V......| -00000030 16 03 03 00 28 2a 7a 63 66 3f 53 88 0a cf ef 03 |....(*zcf?S.....| -00000040 ef 21 5b b5 57 ce 9e e5 da 84 e5 a7 d3 6d 90 c9 |.![.W........m..| -00000050 6c f8 c1 9d cc a2 ff cb 97 5a 7c 1a 62 |l........Z|.b| +00000000 16 03 03 00 25 10 00 00 21 20 6e 1a be aa e4 ca |....%...! n.....| +00000010 43 15 88 b6 fe f7 6c 69 26 1c 99 1c a9 01 75 e3 |C.....li&.....u.| +00000020 32 ef 37 85 6c 2e 15 6e 37 24 14 03 03 00 01 01 |2.7.l..n7$......| +00000030 16 03 03 00 28 e8 ca d2 ac 7b 38 5e 23 0a c0 62 |....(....{8^#..b| +00000040 05 c5 ec 9a 3b 99 48 6e 72 c0 30 b3 3c 69 a1 fd |....;.Hnr.0.>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -00000010 00 00 00 7a ee 1c df b7 14 c9 81 18 f3 51 de 24 |...z.........Q.$| -00000020 70 ed b7 87 b9 29 b3 f7 ef 43 d0 c9 8f 35 3e 0a |p....)...C...5>.| -00000030 a1 c4 72 17 03 03 00 25 00 00 00 00 00 00 00 01 |..r....%........| -00000040 f6 37 d9 31 d2 1f de a6 43 3b 60 a7 30 8c 76 cd |.7.1....C;`.0.v.| -00000050 47 f3 e3 a5 f3 6f e0 fe fd 93 76 1f 0a 15 03 03 |G....o....v.....| -00000060 00 1a 00 00 00 00 00 00 00 02 6d 2d 8d 6b f1 e3 |..........m-.k..| -00000070 8f 21 e4 8e af b2 90 69 5b 10 3a f9 |.!.....i[.:.| +00000010 00 00 00 09 61 1e 91 05 79 fe d3 ea 62 2c 4e 62 |....a...y...b,Nb| +00000020 42 b4 68 20 ca 47 e3 a4 4f 33 ce ba 8c d7 ea 63 |B.h .G..O3.....c| +00000030 54 c7 8c 17 03 03 00 25 00 00 00 00 00 00 00 01 |T......%........| +00000040 fb 97 f4 60 38 95 26 f2 69 ea c7 91 99 08 73 7a |...`8.&.i.....sz| +00000050 ca 96 97 6f 9f a6 be c2 ca 1d f1 2e 08 15 03 03 |...o............| +00000060 00 1a 00 00 00 00 00 00 00 02 b4 06 50 09 ec 73 |............P..s| +00000070 06 83 b4 fa bb 40 21 7f 4c d9 61 8a |.....@!.L.a.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial index b777c624157..ecf765be7da 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 cf 01 00 00 cb 03 03 54 13 f1 1a dc |...........T....| -00000010 39 72 b7 e7 86 ac 83 df 9b 75 9e 71 40 7a 14 b3 |9r.......u.q@z..| -00000020 fc ad 99 d1 8a 4f d0 d9 a3 f0 3d 00 00 38 c0 2c |.....O....=..8.,| +00000000 16 03 01 00 cf 01 00 00 cb 03 03 62 4c 73 03 fd |...........bLs..| +00000010 24 98 d0 f6 41 49 83 94 04 c8 17 51 3e 18 5d 6d |$...AI.....Q>.]m| +00000020 8a b8 52 c0 cf 0b 60 1e 02 53 d2 00 00 38 c0 2c |..R...`..S...8.,| 00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..| 00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....| 00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<| @@ -14,82 +14,82 @@ 000000c0 06 01 03 03 02 03 03 01 02 01 03 02 02 02 04 02 |................| 000000d0 05 02 06 02 |....| >>> Flow 2 (server to client) -00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| +00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 30 00 00 |...DOWNGRD...0..| -00000030 09 00 23 00 00 ff 01 00 01 00 16 03 03 02 59 0b |..#...........Y.| -00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| -00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| -00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| -00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| -00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| -00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| -000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| -000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| -000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| -000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| -000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| -000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| -00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| -00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| -00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| -00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| -00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| -00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| -00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| -00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| -00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| -00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| -000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| -000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| -000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| -000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| -000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| -000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| -00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| -00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| -00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| -00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| -00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | -00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| -00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| -00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| -00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| -00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 00 |.\!.;...........| -000002a0 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 28 da |.... /.}.G.bC.(.| -000002b0 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........| -000002c0 5f 58 cb 3b 74 04 01 00 80 8e 2b 18 d7 2c 6d 91 |_X.;t.....+..,m.| -000002d0 12 b3 ba 39 20 4f 43 60 08 d3 63 6e 55 01 50 3c |...9 OC`..cnU.P<| -000002e0 2b 6d 09 ca 27 d6 f7 42 d1 74 19 e1 6b 06 93 06 |+m..'..B.t..k...| -000002f0 6e e6 c4 23 cc 1b c8 de 8f 30 c2 4d 22 36 10 df |n..#.....0.M"6..| -00000300 32 cb f3 4e ec 9a b1 d6 63 7d 11 4e 58 d2 b7 7a |2..N....c}.NX..z| -00000310 70 31 4b 92 3e 27 ba f0 85 ca 7d 43 c7 68 04 6a |p1K.>'....}C.h.j| -00000320 fa c4 ac c1 16 8b 18 c9 2e 94 2e c2 a6 f3 f0 f3 |................| -00000330 fb 8a 21 6d 4f 3d bc 0f fa 21 fd d5 78 57 6c 38 |..!mO=...!..xWl8| -00000340 09 48 64 d6 ca b6 31 3c 39 16 03 03 00 04 0e 00 |.Hd...1<9.......| -00000350 00 00 |..| +00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............| +00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0| +00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............| +00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..| +00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.| +00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....| +00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010| +000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101| +000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U| +000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...| +000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...| +000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......| +000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.| +00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B| +00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.| +00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t| +00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l| +00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.| +00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....| +00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.| +00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U| +00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U| +00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......| +000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.| +000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...| +000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..| +000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...| +000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{| +000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa| +00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*| +00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0| +00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(| +00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C| +00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..| +00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.| +00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.| +00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr| +00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B| +00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| +000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G| +000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....| +000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 2d |......_X.;t....-| +000002d0 54 87 fa c9 e5 97 ad a0 6d 54 89 b1 37 24 af df |T.......mT..7$..| +000002e0 0f 3e ef 34 f7 6a 5f 1b 06 a5 b9 b4 6d 46 7f b1 |.>.4.j_.....mF..| +000002f0 ab e4 5c dd c1 3f 98 93 61 e5 81 8a 6c 3d 2f b3 |..\..?..a...l=/.| +00000300 3c 59 b9 78 45 ba bd 02 b1 a0 72 cb c3 59 b1 55 |>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 af 4c 6e 57 5e f7 |....%...! .LnW^.| -00000010 49 e2 89 33 f9 47 59 7c 81 5c 63 74 cd 27 6a 65 |I..3.GY|.\ct.'je| -00000020 b6 55 d1 72 ad 60 08 d0 c6 6a 14 03 03 00 01 01 |.U.r.`...j......| -00000030 16 03 03 00 28 69 f2 a5 05 8c a5 a7 5f 8f 8b cf |....(i......_...| -00000040 7a 18 fb f4 45 5e 1f f8 ba 60 2e fa c6 8c c6 57 |z...E^...`.....W| -00000050 89 ac 8a 85 71 00 21 65 f3 a6 99 5d 3b |....q.!e...];| +00000000 16 03 03 00 25 10 00 00 21 20 37 47 1b 8d ef 6c |....%...! 7G...l| +00000010 dc 59 b2 a5 a2 f6 8e 1b f6 1b ab da ec 9c a7 ff |.Y..............| +00000020 4a f9 0e 9b 02 b0 8f bc a1 55 14 03 03 00 01 01 |J........U......| +00000030 16 03 03 00 28 a2 53 52 8b df 86 63 d9 f8 a8 7e |....(.SR...c...~| +00000040 f5 b4 19 1a 5d 02 9a 48 94 68 6d a2 90 13 93 42 |....]..H.hm....B| +00000050 87 52 92 50 7c 45 91 b9 91 49 83 66 a6 |.R.P|E...I.f.| >>> Flow 4 (server to client) 00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f ec 80 83 61 0d 24 39 c2 e0 e0 85 93 37 1f 40 |o...a.$9.....7.@| -00000040 0a 0e a7 45 0e 81 37 6c 7a 11 ed e6 c0 f1 69 23 |...E..7lz.....i#| -00000050 df 14 01 ff ff 52 2f ac da 15 14 5b a2 07 c8 bc |.....R/....[....| -00000060 82 4f 2b 5b 71 33 94 09 17 b4 83 76 62 b7 46 9d |.O+[q3.....vb.F.| -00000070 6f 0d de c2 8b a8 ce 6e 2e df f4 a3 59 fc af f2 |o......n....Y...| -00000080 fe 3f 1e d6 75 b5 63 14 03 03 00 01 01 16 03 03 |.?..u.c.........| -00000090 00 28 00 00 00 00 00 00 00 00 ae 8b f0 21 94 08 |.(...........!..| -000000a0 ec aa a6 f5 40 81 5a a2 42 f7 0a 9b 6b e6 8d 7a |....@.Z.B...k..z| -000000b0 44 e1 85 41 fc 83 f0 e1 c0 c2 17 03 03 00 25 00 |D..A..........%.| -000000c0 00 00 00 00 00 00 01 c4 a7 e5 72 e4 09 d0 21 b8 |..........r...!.| -000000d0 99 ae f0 6a 2c 1c a4 ca ae 44 79 92 ae 25 f8 37 |...j,....Dy..%.7| -000000e0 d8 49 f3 21 15 03 03 00 1a 00 00 00 00 00 00 00 |.I.!............| -000000f0 02 76 b5 79 33 82 76 50 e3 2b 03 e9 b8 14 2d 51 |.v.y3.vP.+....-Q| -00000100 ac f9 6d |..m| +00000030 6f ec 80 83 61 a2 90 f4 4c 03 c8 09 b9 a6 c6 6f |o...a...L......o| +00000040 c7 52 57 3f 3f 92 71 f3 f8 02 43 69 19 f0 bf 78 |.RW??.q...Ci...x| +00000050 6a 00 cc 0a 96 6f 80 5d 62 42 9b 6b 7c 00 e0 26 |j....o.]bB.k|..&| +00000060 90 ef d9 26 f1 33 94 6e 13 9a ec be 91 00 1e 64 |...&.3.n.......d| +00000070 eb 12 ae b9 74 f9 85 d1 b7 91 bd e1 e2 da ac b0 |....t...........| +00000080 71 ca 1b 65 1a e7 83 14 03 03 00 01 01 16 03 03 |q..e............| +00000090 00 28 00 00 00 00 00 00 00 00 fa e4 1b 3b 28 9b |.(...........;(.| +000000a0 f8 28 d7 26 d7 6a 67 33 1f 4a 39 d9 ac 59 6f fc |.(.&.jg3.J9..Yo.| +000000b0 2b 84 6c b9 73 70 9b 30 8c d0 17 03 03 00 25 00 |+.l.sp.0......%.| +000000c0 00 00 00 00 00 00 01 0c 6e 13 cf 3d 10 65 2f e5 |........n..=.e/.| +000000d0 4f fd f9 b6 34 11 c2 05 60 d5 16 66 68 65 29 fa |O...4...`..fhe).| +000000e0 e6 97 e4 dc 15 03 03 00 1a 00 00 00 00 00 00 00 |................| +000000f0 02 58 9a 0d 41 6f 0f 72 c7 43 16 46 83 dd 26 5f |.X..Ao.r.C.F..&_| +00000100 3a ee 1a |:..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket index 925fad087f5..42cbc3420dd 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 9b 01 00 00 97 03 03 d7 1e 2f 33 47 |............./3G| -00000010 7e 92 97 4b 62 40 60 32 de ee 2e bd 5c 57 3c f8 |~..Kb@`2....\W<.| -00000020 6a 4a 78 23 4f ad db 3c 33 ea f2 00 00 04 00 2f |jJx#O..<3....../| +00000000 16 03 01 00 9b 01 00 00 97 03 03 22 89 61 60 36 |...........".a`6| +00000010 06 c6 00 3f af 09 28 13 d8 7e ae 18 55 40 4a 4e |...?..(..~..U@JN| +00000020 40 13 e2 f8 43 5f be e5 f6 51 04 00 00 04 00 2f |@...C_...Q...../| 00000030 00 ff 01 00 00 6a 00 00 00 0e 00 0c 00 00 09 31 |.....j.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,83 +10,83 @@ 00000080 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................| 00000090 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................| >>> Flow 2 (server to client) -00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| +00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 09 00 23 00 00 ff 01 00 01 00 16 03 03 02 59 0b |..#...........Y.| -00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| -00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| -00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| -00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| -00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| -00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| -000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| -000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| -000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| -000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| -000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| -000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| -00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| -00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| -00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| -00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| -00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| -00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| -00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| -00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| -00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| -00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| -000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| -000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| -000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| -000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| -000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| -000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| -00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| -00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| -00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| -00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| -00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | -00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| -00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| -00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| -00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| -00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| -000002a0 00 |.| +00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............| +00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0| +00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............| +00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..| +00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.| +00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....| +00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010| +000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101| +000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U| +000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...| +000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...| +000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......| +000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.| +00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B| +00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.| +00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t| +00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l| +00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.| +00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....| +00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.| +00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U| +00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U| +00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......| +000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.| +000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...| +000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..| +000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...| +000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{| +000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa| +00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*| +00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0| +00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(| +00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C| +00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..| +00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.| +00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.| +00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr| +00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B| +00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| +000002a0 03 00 04 0e 00 00 00 |.......| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 d7 37 f9 ec 2b |............7..+| -00000010 61 07 05 d0 90 28 33 64 14 8c 71 16 05 0f 72 31 |a....(3d..q...r1| -00000020 83 ea 88 be b3 27 1a 4a 09 c5 28 66 ea 14 bb 17 |.....'.J..(f....| -00000030 2e 12 56 d1 c5 7e cf 35 a8 77 4d 48 1a a1 b1 bd |..V..~.5.wMH....| -00000040 63 a4 40 8c 04 20 00 5c d7 ac 22 34 ac 46 08 ea |c.@.. .\.."4.F..| -00000050 53 e6 7e aa 6f 19 03 ec e8 17 3a f9 26 35 0e 3e |S.~.o.....:.&5.>| -00000060 47 1a 3e 13 57 a9 e9 71 7a 09 78 82 a9 7a ea d5 |G.>.W..qz.x..z..| -00000070 7d 14 15 b5 98 0b 92 9c e3 e3 82 6f 95 ba 00 b7 |}..........o....| -00000080 6f b6 24 e1 be 14 39 63 6f 57 cb 14 03 03 00 01 |o.$...9coW......| -00000090 01 16 03 03 00 40 3a 85 bc 9c 00 57 6c db cf e8 |.....@:....Wl...| -000000a0 99 7a 7c ee 09 df 56 8a 3a ac dd 1f f9 bf 1f 6c |.z|...V.:......l| -000000b0 dc 38 5b 2d 6a ad 36 26 b7 4f 23 7f 23 5f 69 fa |.8[-j.6&.O#.#_i.| -000000c0 e5 ea f4 1e 26 6e e4 a6 80 c1 b6 29 e7 0b b8 03 |....&n.....)....| -000000d0 8e 88 d3 29 a2 99 |...)..| +00000000 16 03 03 00 86 10 00 00 82 00 80 d0 71 60 6a 92 |............q`j.| +00000010 9b 01 87 1b d3 7d 28 a8 50 aa b9 c3 0e a3 b0 2d |.....}(.P......-| +00000020 2f 29 1d f1 42 39 6f 65 bb 1a 0e bc 82 43 e9 c6 |/)..B9oe.....C..| +00000030 c6 cc df 4e c6 f2 2b 85 26 cb 63 12 f7 a1 84 a1 |...N..+.&.c.....| +00000040 25 8b 8f 02 f2 c1 fe 09 79 89 ba da b7 b1 32 4c |%.......y.....2L| +00000050 56 4e d6 02 14 1a ed 03 87 ad d1 3e f1 5d 41 c5 |VN.........>.]A.| +00000060 c0 fe 8e ce 6c c2 ce 2e 4a f6 4f a0 f9 d7 a9 2d |....l...J.O....-| +00000070 22 62 78 5a a6 cb bb 62 98 20 fe f6 3d d3 b6 f8 |"bxZ...b. ..=...| +00000080 7f 1a 5a e5 59 32 93 bd f0 82 e5 14 03 03 00 01 |..Z.Y2..........| +00000090 01 16 03 03 00 40 96 3c c7 3f 87 d7 2e fb fb 2f |.....@.<.?...../| +000000a0 a0 0f 60 fc a9 9c 27 c2 0d e0 a6 f9 76 8c 94 59 |..`...'.....v..Y| +000000b0 02 ae 5c a3 b2 20 6f c7 a5 a3 ad 98 87 cf 29 02 |..\.. o.......).| +000000c0 87 ce db 09 ee b7 eb f4 81 59 37 13 15 5b 91 fe |.........Y7..[..| +000000d0 e7 b3 6f 69 fd d2 |..oi..| >>> Flow 4 (server to client) 00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f 2c 9f 83 61 fe 79 79 ae dc c2 a0 99 e2 59 46 |o,..a.yy......YF| -00000040 79 88 b8 ed 74 da ef da 3e 7e 69 af 34 63 b3 7f |y...t...>~i.4c..| -00000050 52 e1 07 4d f8 40 69 63 85 8c 66 a6 d6 f7 b7 b0 |R..M.@ic..f.....| -00000060 f2 d4 12 f4 2a 33 94 64 76 91 5b 6c 7d 49 37 3c |....*3.dv.[l}I7<| -00000070 0b 76 3e d6 5c 0b 65 79 96 31 51 46 01 51 94 38 |.v>.\.ey.1QF.Q.8| -00000080 5b 51 d5 2d 1a 8b 19 14 03 03 00 01 01 16 03 03 |[Q.-............| +00000030 6f 2c 9f 83 61 5c 5f 43 13 c2 76 91 3a c1 1a 8c |o,..a\_C..v.:...| +00000040 51 00 5c a0 93 a9 06 e2 0c b0 65 e3 8c 0d 4b 7b |Q.\.......e...K{| +00000050 7e 52 32 b8 3c b3 76 c5 bf 95 4d 29 71 50 81 e3 |~R2.<.v...M)qP..| +00000060 2b 6f 4a 32 dc 33 94 15 c5 fe 38 b4 0a fc 03 38 |+oJ2.3....8....8| +00000070 90 32 db c0 7f 99 62 a9 89 15 d0 f6 79 64 79 38 |.2....b.....ydy8| +00000080 b0 e2 19 07 82 82 0a 14 03 03 00 01 01 16 03 03 |................| 00000090 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.@..............| -000000a0 00 00 99 ca bd 2f c3 31 77 54 b5 70 de 96 e5 30 |...../.1wT.p...0| -000000b0 ad 2e 6b 03 af f0 42 38 b6 70 dd 81 35 65 b6 fe |..k...B8.p..5e..| -000000c0 f6 d8 44 f3 c1 98 30 f4 21 16 06 57 b4 e8 c1 ec |..D...0.!..W....| -000000d0 bc 12 17 03 03 00 40 00 00 00 00 00 00 00 00 00 |......@.........| -000000e0 00 00 00 00 00 00 00 f8 26 b5 28 2d 4d 0a 05 da |........&.(-M...| -000000f0 84 66 ae ac ee b1 fa 31 96 76 df bd 52 c6 d6 2c |.f.....1.v..R..,| -00000100 c5 39 c9 f9 eb c4 97 8f d1 c2 a4 1f e9 28 3d 81 |.9...........(=.| -00000110 64 7a 7d 41 f3 1d be 15 03 03 00 30 00 00 00 00 |dz}A.......0....| -00000120 00 00 00 00 00 00 00 00 00 00 00 00 20 cc 54 9c |............ .T.| -00000130 9e 4a cc fc 9b 0d 35 59 cd 9b 49 74 1a aa fd f6 |.J....5Y..It....| -00000140 4d dd 0e 9e c8 4f 3a 8b a8 7a a6 d5 |M....O:..z..| +000000a0 00 00 69 6f c8 63 ce 7b d5 82 6e f8 5f 59 ab ad |..io.c.{..n._Y..| +000000b0 55 0c 76 8b 11 56 77 ea 33 20 fd 0b 33 9d 72 12 |U.v..Vw.3 ..3.r.| +000000c0 85 fe 99 38 2a 70 49 fe 27 35 9d 43 5b 32 2b 77 |...8*pI.'5.C[2+w| +000000d0 31 66 17 03 03 00 40 00 00 00 00 00 00 00 00 00 |1f....@.........| +000000e0 00 00 00 00 00 00 00 05 36 d1 49 58 00 4d 5c bc |........6.IX.M\.| +000000f0 a8 c4 be 76 5d f7 cc 88 c7 5a 44 8c f6 d0 30 e6 |...v]....ZD...0.| +00000100 87 03 84 77 60 6c 47 70 2a 80 51 38 a8 8a fb 9f |...w`lGp*.Q8....| +00000110 31 45 f0 ab c9 e5 94 15 03 03 00 30 00 00 00 00 |1E.........0....| +00000120 00 00 00 00 00 00 00 00 00 00 00 00 19 f0 c7 ce |................| +00000130 92 87 25 dd 5b c3 68 3b dd ec 5c 26 c6 90 36 31 |..%.[.h;..\&..61| +00000140 a5 3c 9a 89 be 49 30 37 3b a5 5f 13 |.<...I07;._.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable index d1a34805e67..cc1b6b0173b 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 9b 01 00 00 97 03 03 b9 ed cc cc b2 |................| -00000010 93 69 38 bf d0 24 20 b1 24 99 8a 4d b2 81 5d 58 |.i8..$ .$..M..]X| -00000020 b7 a0 b1 a3 ef fd 21 01 75 01 b3 00 00 04 00 2f |......!.u....../| +00000000 16 03 01 00 9b 01 00 00 97 03 03 55 4e 24 f5 fd |...........UN$..| +00000010 2b 70 d1 b4 9c fd eb 53 1d 2f 7e f7 59 fe 20 c6 |+p.....S./~.Y. .| +00000020 4f 47 72 0f 7a 01 71 48 8a 21 9a 00 00 04 00 2f |OGr.z.qH.!...../| 00000030 00 ff 01 00 00 6a 00 00 00 0e 00 0c 00 00 09 31 |.....j.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,83 +10,83 @@ 00000080 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................| 00000090 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................| >>> Flow 2 (server to client) -00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......| +00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 09 00 23 00 00 ff 01 00 01 00 16 03 03 02 59 0b |..#...........Y.| -00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..| -00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.| -00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........| -00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1| -00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo| -00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000| -000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000| -000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go| -000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..| -000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........| -000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...| -000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R| -00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....| -00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.| -00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..| -00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.| -00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.| -00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C| -00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......| -00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......| -00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.| -00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...| -000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......| -000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........| -000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..| -000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~| -000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.| -000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g| -00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....| -00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.| -00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.| -00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....| -00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ | -00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\| -00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...| -00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.| -00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`| -00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| -000002a0 00 |.| +00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............| +00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0| +00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............| +00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..| +00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.| +00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....| +00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010| +000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101| +000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U| +000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...| +000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...| +000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......| +000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.| +00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B| +00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.| +00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t| +00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l| +00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.| +00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....| +00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.| +00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U| +00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U| +00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......| +000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.| +000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...| +000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..| +000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...| +000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{| +000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa| +00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*| +00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0| +00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(| +00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C| +00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..| +00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.| +00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.| +00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr| +00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B| +00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....| +000002a0 03 00 04 0e 00 00 00 |.......| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 35 f0 ea c2 96 |...........5....| -00000010 09 7c b6 2c 8a 53 e4 52 0f 70 ba 1d 61 cf 8f 2d |.|.,.S.R.p..a..-| -00000020 8a b8 c7 0f 3b 50 41 67 60 f1 e6 5c 72 4a 48 69 |....;PAg`..\rJHi| -00000030 a5 43 c8 ab cb 3a 33 ab fd 56 f1 53 1f 18 85 c0 |.C...:3..V.S....| -00000040 c0 3a 2d 97 65 e1 00 89 c0 9f 16 42 c7 ed 74 17 |.:-.e......B..t.| -00000050 f4 35 e9 6f c5 9f e2 68 70 b1 7d fc 6e 5b a5 5d |.5.o...hp.}.n[.]| -00000060 d0 16 28 c7 65 8a 7a 50 e4 48 d0 73 4a 94 59 cf |..(.e.zP.H.sJ.Y.| -00000070 ad 3f 44 78 3d 6b 90 53 2e 28 a2 9b c5 85 ea 51 |.?Dx=k.S.(.....Q| -00000080 58 2c 6d 40 c2 15 57 ad 76 6d 86 14 03 03 00 01 |X,m@..W.vm......| -00000090 01 16 03 03 00 40 84 60 b6 51 55 96 d1 32 48 dd |.....@.`.QU..2H.| -000000a0 d3 31 5e 18 3a fc 94 21 52 81 8f 48 5a a9 f3 71 |.1^.:..!R..HZ..q| -000000b0 e1 0e d6 1c 20 68 a3 94 c3 4c 84 b3 08 85 96 5c |.... h...L.....\| -000000c0 16 f3 1e 5d cc 6b 2b 42 3f f8 39 64 65 33 9b 18 |...].k+B?.9de3..| -000000d0 ee 67 13 ab 57 52 |.g..WR| +00000000 16 03 03 00 86 10 00 00 82 00 80 29 31 85 e2 ce |...........)1...| +00000010 42 63 7f 16 3a 0b 67 19 64 da bb 7a bc fe c7 a9 |Bc..:.g.d..z....| +00000020 fb f1 d0 c1 7e 3d 2e 69 f8 97 43 7e 73 8a eb 9a |....~=.i..C~s...| +00000030 e4 f4 d0 e8 93 47 ec c1 89 a0 d3 93 65 47 1c 33 |.....G......eG.3| +00000040 75 af 90 07 bb 46 27 09 c6 0c 4f 43 10 87 c9 a6 |u....F'...OC....| +00000050 da 58 02 a7 61 4b 67 40 05 72 9b 07 aa 9b 04 18 |.X..aKg@.r......| +00000060 6a 35 d1 54 f8 fc 08 f5 9f 49 8d aa aa 4c 2c bf |j5.T.....I...L,.| +00000070 55 85 ed 6b ae 7e cd 77 a2 9b e3 a7 03 8d 9e d9 |U..k.~.w........| +00000080 12 12 ce 1c c4 ba 10 f3 d5 f4 c2 14 03 03 00 01 |................| +00000090 01 16 03 03 00 40 2c 57 5d 8b 73 4f 31 ed 16 e5 |.....@,W].sO1...| +000000a0 17 bd 08 a9 26 95 51 0d f6 0c 82 af f2 26 9e 5e |....&.Q......&.^| +000000b0 31 71 e5 7c dc 41 62 10 da d5 20 f1 dc 00 ea 25 |1q.|.Ab... ....%| +000000c0 5a 4b 15 e1 ba 46 c1 5f 64 a6 59 58 55 2a 01 41 |ZK...F._d.YXU*.A| +000000d0 3e 6b 22 b8 79 27 |>k".y'| >>> Flow 4 (server to client) 00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP| 00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................| -00000030 6f 2c 9f 83 61 70 4f 8e 34 f4 65 e4 64 ba af 8d |o,..apO.4.e.d...| -00000040 55 d8 8a c4 90 a4 94 d1 84 44 51 72 f0 79 b3 2b |U........DQr.y.+| -00000050 c3 49 48 58 e7 66 8c 3d 60 dd 65 ba 93 0a f1 45 |.IHX.f.=`.e....E| -00000060 28 83 56 19 28 33 94 dd d4 29 db f0 80 d1 b2 0a |(.V.(3...)......| -00000070 ef 69 03 b5 fa 19 82 a9 0e 42 b0 bb c2 b5 c7 b5 |.i.......B......| -00000080 92 1f e6 3b 38 e3 85 14 03 03 00 01 01 16 03 03 |...;8...........| +00000030 6f 2c 9f 83 61 31 33 93 70 cd 6a 19 a2 67 e8 7d |o,..a13.p.j..g.}| +00000040 cb a4 dc bb 80 d9 23 20 05 4d 53 1f b6 9f 48 01 |......# .MS...H.| +00000050 e4 84 75 10 25 f9 ed 98 bb 39 7e fc 8b 16 d8 bc |..u.%....9~.....| +00000060 c7 e9 88 e8 1c 33 94 10 13 6b d4 3d fa d7 73 b2 |.....3...k.=..s.| +00000070 d4 ea 89 58 ed 38 f8 f3 6a e0 5f 1e f7 49 ed f7 |...X.8..j._..I..| +00000080 5f 64 39 6b b5 6c fb 14 03 03 00 01 01 16 03 03 |_d9k.l..........| 00000090 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.@..............| -000000a0 00 00 a3 42 c4 79 0d 44 92 ab af f9 a0 f2 3f 10 |...B.y.D......?.| -000000b0 f6 51 24 66 e4 e1 87 b1 5b 21 4e 0d 77 12 93 b8 |.Q$f....[!N.w...| -000000c0 19 21 2e c5 0f 29 3c 5a 3b dd 8f 96 41 7b 31 9e |.!...)...Ky..i\P| -00000140 24 dc 81 e0 28 97 53 e4 a1 36 ef bc |$...(.S..6..| +000000a0 00 00 fa f3 aa 48 54 5f 5b 88 69 fb 01 75 2a 90 |.....HT_[.i..u*.| +000000b0 49 46 7c 6a 3a aa 72 4e 35 db 8f 38 a3 4d 05 53 |IF|j:.rN5..8.M.S| +000000c0 38 93 63 ae 0d b9 e0 b4 81 2e ee 40 d5 2b 58 2a |8.c........@.+X*| +000000d0 18 9b 17 03 03 00 40 00 00 00 00 00 00 00 00 00 |......@.........| +000000e0 00 00 00 00 00 00 00 3c 84 3f 45 03 b0 60 ed 8f |.......<.?E..`..| +000000f0 d2 e5 10 98 03 1a 00 8a aa 19 d0 e9 03 fb 42 fc |..............B.| +00000100 cd 4d 13 3e 7d 39 0b 5f cf 2d b7 87 3a bf 43 d4 |.M.>}9._.-..:.C.| +00000110 ac 71 68 29 bf f8 ac 15 03 03 00 30 00 00 00 00 |.qh).......0....| +00000120 00 00 00 00 00 00 00 00 00 00 00 00 81 49 eb 3b |.............I.;| +00000130 28 e7 88 94 8b 6a cc 67 4d c4 03 66 80 af d7 c2 |(....j.gM..f....| +00000140 07 37 36 3b f0 a4 5d 16 2b 5f 5b 27 |.76;..].+_['| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-P256 b/libgo/go/crypto/tls/testdata/Server-TLSv12-P256 index 4e302b374cc..58b9bedc71d 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-P256 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-P256 @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 8f 01 00 00 8b 03 03 b1 a0 04 30 1e |..............0.| -00000010 a1 09 cb 31 c4 1a 15 e7 a6 06 b5 fb 51 da d6 01 |...1........Q...| -00000020 dc c0 cc 17 85 e5 c4 c6 b1 da be 00 00 04 c0 2f |.............../| +00000000 16 03 01 00 8f 01 00 00 8b 03 03 49 de 51 77 8e |...........I.Qw.| +00000010 58 03 e9 25 0b 9a 88 ef 35 2d 35 a8 30 29 22 61 |X..%....5-5.0)"a| +00000020 ae b4 af 8a a1 2c 45 59 40 5f aa 00 00 04 c0 2f |.....,EY@_...../| 00000030 00 ff 01 00 00 5e 00 00 00 0e 00 0c 00 00 09 31 |.....^.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 04 00 02 00 17 00 16 00 00 00 17 00 00 |................| @@ -10,76 +10,77 @@ 00000080 06 01 03 03 02 03 03 01 02 01 03 02 02 02 04 02 |................| 00000090 05 02 06 02 |....| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 cd 0c 00 00 c9 03 00 17 |;...............| -000002a0 41 04 1e 18 37 ef 0d 19 51 88 35 75 71 b5 e5 54 |A...7...Q.5uq..T| -000002b0 5b 12 2e 8f 09 67 fd a7 24 20 3e b2 56 1c ce 97 |[....g..$ >.V...| -000002c0 28 5e f8 2b 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 |(^.+-O....lK[.V.| -000002d0 32 42 e9 58 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc |2B.X..I..h.A.Vk.| -000002e0 5a 89 04 01 00 80 bb 79 4d c9 d6 77 df 13 46 e6 |Z......yM..w..F.| -000002f0 82 30 7a 03 2e 58 a8 bf 2a 53 c4 58 0a 9a 9a 0f |.0z..X..*S.X....| -00000300 72 51 a9 91 5b f7 88 f1 de 28 1d 56 79 2c da 89 |rQ..[....(.Vy,..| -00000310 a4 de 25 65 20 f7 a1 a4 b1 ff 3c 5a cd 67 24 9b |..%e .....I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 cd 0c |.`.\!.;.........| +000002a0 00 00 c9 03 00 17 41 04 1e 18 37 ef 0d 19 51 88 |......A...7...Q.| +000002b0 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd a7 24 20 |5uq..T[....g..$ | +000002c0 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e f1 07 9f |>.V...(^.+-O....| +000002d0 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 a6 b5 68 |lK[.V.2B.X..I..h| +000002e0 1a 41 03 56 6b dc 5a 89 08 04 00 80 7b bd 89 a1 |.A.Vk.Z.....{...| +000002f0 d8 9d cf e4 75 ac 15 60 a9 49 0c c7 68 61 4e e4 |....u..`.I..haN.| +00000300 2b 51 37 5a 65 38 a4 52 6a d0 4f 8b 76 93 a4 7c |+Q7Ze8.Rj.O.v..|| +00000310 ac 30 6b 89 f1 c7 88 8f f3 5c c7 e9 d6 7c 33 94 |.0k......\...|3.| +00000320 f7 fc f8 69 35 f3 f7 e0 ea fc 51 5c b2 e2 dc 9e |...i5.....Q\....| +00000330 57 03 af e6 19 0d 0d e4 25 b6 52 19 12 ad 35 fc |W.......%.R...5.| +00000340 7f c3 6a 1f ed 06 82 34 81 13 d7 c1 67 a9 18 88 |..j....4....g...| +00000350 2f bb 00 54 5d d9 01 16 29 dd 03 3c 69 f7 46 52 |/..T]...)..>> Flow 3 (client to server) -00000000 16 03 03 00 46 10 00 00 42 41 04 1b 28 eb 97 c5 |....F...BA..(...| -00000010 63 cc e1 64 31 f9 b3 5c 61 d8 d9 28 f9 1e 9a 4b |c..d1..\a..(...K| -00000020 09 2a 5a b9 64 42 15 d3 06 80 64 67 93 63 e2 c6 |.*Z.dB....dg.c..| -00000030 51 05 3c 8b 32 41 c2 a0 5a db 73 ba 77 86 7f 1b |Q.<.2A..Z.s.w...| -00000040 2e b4 33 9c 20 0a 40 3a c6 90 f1 14 03 03 00 01 |..3. .@:........| -00000050 01 16 03 03 00 28 56 75 52 fe f7 13 79 b6 c6 ba |.....(VuR...y...| -00000060 f1 6a 6d f2 3d 2c 8c c2 70 3e 19 ba 32 34 88 02 |.jm.=,..p>..24..| -00000070 73 d7 d5 db b9 52 21 32 34 fb 7e e8 17 49 |s....R!24.~..I| +00000000 16 03 03 00 46 10 00 00 42 41 04 a6 c3 8d d1 32 |....F...BA.....2| +00000010 8e b4 ac 27 75 4a 57 26 7f 6a 52 a7 82 ee c2 b1 |...'uJW&.jR.....| +00000020 a3 68 0a 8d 09 ff 82 61 57 f3 32 5e ec 1a 2f 20 |.h.....aW.2^../ | +00000030 8c c1 d4 cf 27 7b f0 1d f9 5d f6 24 80 6a 45 d2 |....'{...].$.jE.| +00000040 97 cf f1 5d a2 e3 b0 15 7d e6 a4 14 03 03 00 01 |...]....}.......| +00000050 01 16 03 03 00 28 21 36 fe 82 d2 4a b4 da f8 14 |.....(!6...J....| +00000060 d6 d6 8c be 56 1f ca 82 7f 20 bb 01 be fb 2a 0d |....V.... ....*.| +00000070 a8 31 ee 79 f7 8a 8b 4a 1b a7 66 3a 89 67 |.1.y...J..f:.g| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -00000010 00 00 00 41 e9 67 42 6b 79 56 59 80 41 c2 3a b9 |...A.gBkyVY.A.:.| -00000020 b2 3a 06 0e 31 76 18 ba 86 a4 2d 1a 71 19 f3 f1 |.:..1v....-.q...| -00000030 a3 bc b3 17 03 03 00 25 00 00 00 00 00 00 00 01 |.......%........| -00000040 57 ee 6f 74 4b 56 28 ca 71 34 c0 85 0e 26 db 9c |W.otKV(.q4...&..| -00000050 bb 8f 3c 3f 02 a3 d4 07 61 6e 20 93 5e 15 03 03 |..>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 ed c3 64 89 19 |.............d..| -00000010 3b fd 11 f4 d8 c9 2a d5 a8 8b 18 b5 92 cb ff c1 |;.....*.........| -00000020 10 9a b1 a7 e4 d5 bc 78 39 29 30 00 00 04 00 0a |.......x9)0.....| +00000000 16 03 01 00 97 01 00 00 93 03 03 e2 8f 43 82 4c |.............C.L| +00000010 13 33 88 d2 53 5d b6 02 d2 b6 b2 a1 11 f0 30 14 |.3..S]........0.| +00000020 41 1e 8c 79 85 38 75 cd e8 a6 a7 00 00 04 00 0a |A..y.8u.........| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,70 +10,71 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 0a 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 a3 a7 b7 b2 3e |...............>| -00000010 ee 37 62 8e 5b b3 d5 2e e2 0e b9 24 70 95 4c 4c |.7b.[......$p.LL| -00000020 52 e5 9f a3 e2 79 7f a1 dc 93 1f 89 2e f8 a2 8e |R....y..........| -00000030 7b d8 82 6c 89 57 64 44 e9 61 66 aa 8d 42 ff d1 |{..l.WdD.af..B..| -00000040 7f 62 21 55 78 e9 da 87 18 d5 51 dc 91 39 6b b9 |.b!Ux.....Q..9k.| -00000050 8f ec 76 57 f7 03 62 fa 54 36 0c 18 ad 7c 1c 5d |..vW..b.T6...|.]| -00000060 ce fd b4 97 c3 98 15 fc b5 e5 55 6b aa d5 d5 d4 |..........Uk....| -00000070 17 9c a7 55 ee 8d d1 85 2e 92 10 32 67 72 d5 27 |...U.......2gr.'| -00000080 0d aa b3 a9 5a ec d3 8c df d4 7f 14 03 03 00 01 |....Z...........| -00000090 01 16 03 03 00 30 8a 3c 9c 7d dd 50 68 ff 79 dc |.....0.<.}.Ph.y.| -000000a0 f4 b4 a7 73 8e de 93 01 85 a4 0c 9c cb 9a 2d 4d |...s..........-M| -000000b0 34 95 63 d7 73 9f c5 89 e0 81 8f a2 bd c1 3b e4 |4.c.s.........;.| -000000c0 5a fe 5a ef 6a 75 |Z.Z.ju| +00000000 16 03 03 00 86 10 00 00 82 00 80 57 ce 41 c0 4d |...........W.A.M| +00000010 b1 69 27 6e cb 92 a5 71 52 85 e7 a8 69 b0 31 d1 |.i'n...qR...i.1.| +00000020 0a b0 3d a6 9d ab 04 e8 a2 4c d8 67 95 97 da 63 |..=......L.g...c| +00000030 f7 0b 6e 62 29 5b 8b cf 77 f1 80 a5 1f 67 08 71 |..nb)[..w....g.q| +00000040 50 c3 a9 90 ea b8 11 3d 5d c9 f5 1c 37 fa 67 b1 |P......=]...7.g.| +00000050 64 b0 04 3e c1 0d db 77 fe b9 a0 ea f2 0f 1d af |d..>...w........| +00000060 9a 77 b3 96 4f 3f 3c 52 a7 ed c4 3f 48 ef ff f8 |.w..O?>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 30 00 00 00 00 00 |..........0.....| -00000010 00 00 00 f1 00 85 78 65 64 6e 44 50 3e 34 30 87 |......xednDP>40.| -00000020 b8 c2 b4 ed 76 e2 65 0a 4c 21 68 46 ca ae 97 ea |....v.e.L!hF....| -00000030 a2 46 38 b3 65 b8 63 45 8f aa 4c 17 03 03 00 30 |.F8.e.cE..L....0| -00000040 00 00 00 00 00 00 00 00 fd 9f bb a9 e3 72 fd 5f |.............r._| -00000050 5b b7 2d 34 e5 4c 19 f4 ef 1c ce 71 0f d3 0d a6 |[.-4.L.....q....| -00000060 5f f2 ca b4 3b f8 eb c7 20 85 e7 92 41 8c c8 08 |_...;... ...A...| -00000070 15 03 03 00 20 00 00 00 00 00 00 00 00 3b b8 8c |.... ........;..| -00000080 09 40 aa 11 20 a9 ee f7 e4 bb 80 a2 e6 5d e5 04 |.@.. ........]..| -00000090 98 65 e8 bd 85 |.e...| +00000010 00 00 00 0d 0f 3c 6a 28 f0 97 90 1a c3 7e c8 63 |...........su.| +00000070 15 03 03 00 20 00 00 00 00 00 00 00 00 5c 30 63 |.... ........\0c| +00000080 23 55 26 ee 8d 81 9a 2e b4 e7 38 6b 04 e7 42 43 |#U&.......8k..BC| +00000090 50 de 1e 40 2d |P..@-| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES index 25f1269e3ae..0196e21637b 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 1b 05 dc 80 93 |................| -00000010 90 62 51 a6 ce 10 03 8e f1 02 71 53 b0 9f 80 96 |.bQ.......qS....| -00000020 a0 48 c9 6f 1d df d9 cd 82 43 48 00 00 04 00 2f |.H.o.....CH..../| +00000000 16 03 01 00 97 01 00 00 93 03 03 dd 28 eb 68 4a |............(.hJ| +00000010 8a 71 d2 98 d0 2d 21 c7 e9 19 19 de c8 13 0b 67 |.q...-!........g| +00000020 f4 ff 4c d0 37 f5 72 9f 2d fb b3 00 00 04 00 2f |..L.7.r.-....../| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,74 +10,75 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 c7 bb d2 ee 1a |................| -00000010 38 b1 7b 2f ad ec e6 63 d3 11 f9 69 b6 7e b9 58 |8.{/...c...i.~.X| -00000020 79 37 c9 6e e5 6b 1e ce e5 b7 1f 69 ec 2c 71 94 |y7.n.k.....i.,q.| -00000030 f7 27 16 66 14 24 bd bb ca ac 80 20 68 46 6e b8 |.'.f.$..... hFn.| -00000040 3e f4 82 07 0a b7 0c 74 a5 66 1a 86 48 52 6e 80 |>......t.f..HRn.| -00000050 a1 88 a3 12 8c c9 ef fc 5c 90 a8 f5 2f 0a 69 ba |........\.../.i.| -00000060 ce 73 48 ca 25 ea be 3c 9f 1b b6 1c e9 d7 1d bf |.sH.%..<........| -00000070 38 0d 6f a1 ed c0 22 16 40 51 2e c3 78 5b 69 8a |8.o...".@Q..x[i.| -00000080 91 30 5b 15 b1 a5 c5 ea 5f 34 38 14 03 03 00 01 |.0[....._48.....| -00000090 01 16 03 03 00 40 78 f5 31 97 86 f4 48 5c 74 8f |.....@x.1...H\t.| -000000a0 ac b9 49 42 cb 83 e6 d9 bc a4 6f cc 3f f3 54 66 |..IB......o.?.Tf| -000000b0 93 01 2c 1a e3 b4 08 09 f8 41 d4 fe 2d fa ab a9 |..,......A..-...| -000000c0 f1 47 39 13 82 11 9e 7f 04 78 08 df 13 74 97 6c |.G9......x...t.l| -000000d0 ba ac a8 26 90 2e |...&..| +00000000 16 03 03 00 86 10 00 00 82 00 80 c0 37 ef f3 d9 |............7...| +00000010 6b 7b 3f c4 9f 46 d2 6b 8f 7f 8d ce 89 cf 8e 2b |k{?..F.k.......+| +00000020 1f 0d 86 f9 90 5a 23 28 6c d3 14 ce 2a 0b f1 0e |.....Z#(l...*...| +00000030 96 1c 11 7d c0 b8 fb 4b 2e cb 07 1c fe b9 e1 62 |...}...K.......b| +00000040 2c 38 1c 46 21 74 23 a9 f2 0b 15 36 ef 88 32 e8 |,8.F!t#....6..2.| +00000050 28 66 8e ab 14 be e9 02 04 9d 92 99 cc 6e 28 d0 |(f...........n(.| +00000060 f9 3d dc 61 7f f7 17 59 ab 1c 86 94 9a 28 7b 46 |.=.a...Y.....({F| +00000070 3c 36 ff d3 26 3c ad 2d 33 ef 99 83 09 a5 a8 2f |<6..&<.-3....../| +00000080 b3 a3 74 7f 49 a3 f1 47 7d 8c 12 14 03 03 00 01 |..t.I..G}.......| +00000090 01 16 03 03 00 40 32 68 cb ea 32 cb f2 7a 0e 4b |.....@2h..2..z.K| +000000a0 63 72 96 93 e8 2d 5b 22 a6 3a 05 9d 60 50 e5 d0 |cr...-[".:..`P..| +000000b0 f3 f8 14 ed 81 fe 17 a0 ee 3f 7b aa ca dc 06 bc |.........?{.....| +000000c0 28 90 73 33 84 0c 92 39 b7 cb da 06 08 05 0b 03 |(.s3...9........| +000000d0 86 be cc 70 0e c2 |...p..| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 53 48 ab 5a 17 |...........SH.Z.| -00000020 07 e4 14 04 4d 96 ae 33 b7 e7 6b 37 10 34 98 66 |....M..3..k7.4.f| -00000030 b8 38 6b 30 53 17 3e af 80 34 a6 29 0c 3b 8b 05 |.8k0S.>..4.).;..| -00000040 53 d6 53 fb 65 e3 ec 05 16 f2 c7 17 03 03 00 40 |S.S.e..........@| +00000010 00 00 00 00 00 00 00 00 00 00 00 10 a0 48 48 86 |.............HH.| +00000020 ac 1f f4 05 4d 12 9d 90 54 26 ec c8 1f 6d e7 d5 |....M...T&...m..| +00000030 0c 92 61 88 2f 43 77 75 0c 08 0f 33 ac c3 d3 b0 |..a./Cwu...3....| +00000040 94 68 e3 3f 9f c9 43 a5 8b ee ed 17 03 03 00 40 |.h.?..C........@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 46 14 e6 50 23 20 15 9f a4 cc 39 69 43 e7 35 ea |F..P# ....9iC.5.| -00000070 3c c3 71 a6 65 dc ba 66 7b 3e b8 8d bc cc 1b f5 |<.q.e..f{>......| -00000080 2b 65 55 9b 35 c7 30 08 ff 0b 7c b7 bb 75 f1 5c |+eU.5.0...|..u.\| +00000060 fd 7d d3 d6 3f a5 10 37 a1 93 20 ca c8 8c 9d c3 |.}..?..7.. .....| +00000070 90 df 2f 40 e6 83 af b6 be e4 3d 07 ff 0d 24 97 |../@......=...$.| +00000080 c2 ff af 81 eb b5 91 72 6b 6d 70 8c af 3f 9f 76 |.......rkmp..?.v| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 83 b1 d6 5e 78 d8 7d 8f 22 a2 c9 |........^x.}."..| -000000b0 81 2d 47 ed 7e a5 65 10 af a0 b4 01 be b3 70 a8 |.-G.~.e.......p.| -000000c0 9f 5a 07 87 f5 |.Z...| +000000a0 00 00 00 00 00 6b 80 aa 88 45 8c 39 a8 4c ca 33 |.....k...E.9.L.3| +000000b0 f2 33 85 a0 74 6a 64 a3 43 17 4c 5c 9b 50 e5 8d |.3..tjd.C.L\.P..| +000000c0 ff 26 03 e1 07 |.&...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM index 9f48c75bab2..fa4b47b5769 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 6d 19 64 2c f0 |...........m.d,.| -00000010 95 79 38 26 9b e3 db b3 97 ce f8 9c 46 62 08 15 |.y8&........Fb..| -00000020 a0 f0 7f 20 38 52 bb 27 f8 3b 60 00 00 04 c0 2f |... 8R.'.;`..../| +00000000 16 03 01 00 97 01 00 00 93 03 03 8a ca f1 8f ad |................| +00000010 fe 0b a3 e1 b8 08 10 1a 40 57 b6 f7 f7 e3 72 c4 |........@W....r.| +00000020 57 4a 71 f8 30 cd 62 62 c7 0f 2d 00 00 04 c0 2f |WJq.0.bb..-..../| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,72 +10,73 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d |;...............| -000002a0 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 | /.}.G.bC.(.._.)| -000002b0 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b |.0.........._X.;| -000002c0 74 04 01 00 80 99 cc 0d 3d 25 73 2d 21 00 0d 42 |t.......=%s-!..B| -000002d0 d1 6f 9e ba f4 04 58 30 5f a0 33 e9 b0 3a 69 6d |.o....X0_.3..:im| -000002e0 e2 a1 f2 74 f7 09 e7 ef fb cd 56 22 93 1c 56 8e |...t......V"..V.| -000002f0 8f 87 4b 1d 54 f6 34 fd e6 e0 2f 85 88 9a ab c9 |..K.T.4.../.....| -00000300 b5 38 cd f3 44 20 7a 68 fd bf 10 ea 14 7e ae 21 |.8..D zh.....~.!| -00000310 12 ad eb 91 2f 99 44 fb cf 9e fe 21 19 9f d1 a0 |..../.D....!....| -00000320 37 19 9e 48 92 0e 80 b7 51 95 45 ee 75 86 f9 52 |7..H....Q.E.u..R| -00000330 5a f8 67 65 56 af 4d f8 ca 92 8f b7 2a f5 be c1 |Z.geV.M.....*...| -00000340 04 e0 03 e1 b6 16 03 03 00 04 0e 00 00 00 |..............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........| +000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.| +000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| +000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 50 0b d9 1c 03 |.._X.;t....P....| +000002d0 6f 08 05 a6 39 cc 9f 7e 3d f1 fb af 8e 0b 9a ef |o...9..~=.......| +000002e0 39 d3 b6 e3 71 9c 5a 37 a1 86 f2 f0 59 01 fc b2 |9...q.Z7....Y...| +000002f0 51 1c 0e 22 42 24 3e c6 db fb a1 39 9d 75 f4 79 |Q.."B$>....9.u.y| +00000300 55 dd e5 99 0b 22 5b ed c7 19 ac db ed d3 ee 23 |U...."[........#| +00000310 b9 37 2b 51 ea 7f 39 4d 8b 0a bc a2 2e f2 ef 9e |.7+Q..9M........| +00000320 a5 8c 99 77 ff d2 fb 46 e4 10 4e a9 b2 a9 ce b6 |...w...F..N.....| +00000330 50 d4 0a 28 a5 3f 0e 2c 60 cd 0f 07 9c 7e 60 c3 |P..(.?.,`....~`.| +00000340 79 a5 cf f3 cd 77 5a 16 8d fc 14 16 03 03 00 04 |y....wZ.........| +00000350 0e 00 00 00 |....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 20 74 90 bd 53 18 |....%...! t..S.| -00000010 33 c6 a5 bf 51 71 f7 d7 c3 0c 7f 89 ad b3 73 7b |3...Qq........s{| -00000020 48 2f c1 ef 85 32 03 73 28 3b 14 03 03 00 01 01 |H/...2.s(;......| -00000030 16 03 03 00 28 94 4f 85 68 15 57 b4 8f f4 21 a7 |....(.O.h.W...!.| -00000040 e5 be 84 7d 3a e0 29 bd 99 20 24 d0 6b 9c 72 3a |...}:.).. $.k.r:| -00000050 fc f9 5d 1c 7e cb dd 7a 3b 7c 53 e6 3a |..].~..z;|S.:| +00000000 16 03 03 00 25 10 00 00 21 20 ef 3b b1 d2 a3 f6 |....%...! .;....| +00000010 be f2 fc 2e b5 ed d3 ec 6a fb 2f 0d 5a 04 98 61 |........j./.Z..a| +00000020 92 26 59 ba 17 26 1b 60 27 2b 14 03 03 00 01 01 |.&Y..&.`'+......| +00000030 16 03 03 00 28 e2 94 22 bb 71 70 c8 a6 63 e5 6f |....(..".qp..c.o| +00000040 2e 00 0f b9 bf 6b 54 34 dc ce b0 12 0b 16 e5 ac |.....kT4........| +00000050 8f 6b 1e 96 a1 e3 86 b7 6f 8c 76 09 da |.k......o.v..| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -00000010 00 00 00 e3 4f 34 0e 47 ae f2 62 e3 aa 62 f3 37 |....O4.G..b..b.7| -00000020 cf 78 ba 1d 8a 3c d8 29 0c 3c 9d 0c fa ff fd 9b |.x...<.).<......| -00000030 65 1b 3f 17 03 03 00 25 00 00 00 00 00 00 00 01 |e.?....%........| -00000040 fd e1 49 0e 0d 9f a1 51 9e 19 5c 80 a5 15 dc 05 |..I....Q..\.....| -00000050 ca f0 46 b3 da 03 5a 32 da 4e 2e 3d 33 15 03 03 |..F...Z2.N.=3...| -00000060 00 1a 00 00 00 00 00 00 00 02 51 78 d9 14 6e a8 |..........Qx..n.| -00000070 f4 62 60 6d db e0 d5 8c c5 17 ac aa |.b`m........| +00000010 00 00 00 f5 dc 00 28 06 03 50 9b b2 db 4d 89 25 |......(..P...M.%| +00000020 3a 94 04 85 5b 7a 3f 16 fb 55 8f e0 c3 a3 33 21 |:...[z?..U....3!| +00000030 65 84 c5 17 03 03 00 25 00 00 00 00 00 00 00 01 |e......%........| +00000040 a9 35 62 24 4b 63 6e 62 1c 8f 99 e4 e0 3e f0 a2 |.5b$Kcnb.....>..| +00000050 e3 02 34 6f 10 71 9c 6b b3 4a 2d 7f 71 15 03 03 |..4o.q.k.J-.q...| +00000060 00 1a 00 00 00 00 00 00 00 02 91 43 07 98 b1 ba |...........C....| +00000070 06 1b dd 21 46 82 63 67 8b bb 1f b5 |...!F.cg....| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384 b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384 index f6e5856f9cc..2cc2c28f6a1 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384 @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 5e 39 96 57 2e |...........^9.W.| -00000010 de 43 bd 55 30 40 20 95 29 a0 38 7f 69 a3 02 4d |.C.U0@ .).8.i..M| -00000020 df 59 4b 17 f1 d6 0b 2e 87 62 af 00 00 04 c0 30 |.YK......b.....0| +00000000 16 03 01 00 97 01 00 00 93 03 03 0f 13 d8 49 94 |..............I.| +00000010 b9 cc 41 1d d4 3d bb d2 c9 a3 2c 74 11 ca 01 e8 |..A..=....,t....| +00000020 5b b0 2e 57 60 b5 30 37 2d b9 f0 00 00 04 c0 30 |[..W`.07-......0| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,72 +10,73 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 30 00 00 |...DOWNGRD...0..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d |;...............| -000002a0 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 | /.}.G.bC.(.._.)| -000002b0 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b |.0.........._X.;| -000002c0 74 04 01 00 80 c0 53 9b 58 b3 88 7a 7d 7d 0f 8c |t.....S.X..z}}..| -000002d0 c4 10 e3 13 92 ae b4 87 ae a5 e2 2f f9 f0 db a0 |.........../....| -000002e0 55 72 00 2f 29 eb 12 13 f7 bf 4b 44 be f2 85 f2 |Ur./).....KD....| -000002f0 00 2d 2c 6a 14 21 44 d5 f8 78 99 67 07 db 27 74 |.-,j.!D..x.g..'t| -00000300 32 9d 75 8d 7e f5 c2 9b 3e ce 3b aa f4 3a 1d 2d |2.u.~...>.;..:.-| -00000310 69 e3 0b 1e a0 95 d9 dc 47 73 42 14 7c 13 60 1f |i.......GsB.|.`.| -00000320 73 a9 0f 3b 64 33 18 67 b0 a3 69 f7 da 1d cd d0 |s..;d3.g..i.....| -00000330 ea 65 9d 79 af aa a6 7f ea ba 8a c7 d7 3f 80 76 |.e.y.........?.v| -00000340 73 b0 c4 41 30 16 03 03 00 04 0e 00 00 00 |s..A0.........| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........| +000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.| +000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| +000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 40 f3 67 86 41 |.._X.;t....@.g.A| +000002d0 93 17 f7 db b2 80 ca 73 f9 f8 45 24 cc 46 57 47 |.......s..E$.FWG| +000002e0 28 83 19 df e8 63 e7 19 c4 a2 04 85 25 7d ec 55 |(....c......%}.U| +000002f0 91 d4 df eb 77 53 c2 3b d5 71 1a f7 39 d2 ee b4 |....wS.;.q..9...| +00000300 06 4b e4 07 b7 fa 8a 8e fa 64 22 83 dd 22 8b b8 |.K.......d".."..| +00000310 4d a5 1a f5 e3 81 01 81 6a a1 6e 62 54 3a 3a 09 |M.......j.nbT::.| +00000320 ed 76 f2 5a d3 4e 4b 74 be 46 50 0d 51 77 34 f6 |.v.Z.NKt.FP.Qw4.| +00000330 02 ef 57 39 29 bf d9 64 ad 65 06 ae a6 8d 94 86 |..W9)..d.e......| +00000340 84 76 cf 2c 36 98 04 5b a1 59 6c 16 03 03 00 04 |.v.,6..[.Yl.....| +00000350 0e 00 00 00 |....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 75 56 9a 51 e6 99 |....%...! uV.Q..| -00000010 e2 7f 36 c6 3e 7b e0 17 2a 28 73 77 24 6c e9 af |..6.>{..*(sw$l..| -00000020 76 68 30 6a 07 4f 49 26 45 6d 14 03 03 00 01 01 |vh0j.OI&Em......| -00000030 16 03 03 00 28 8e 42 ee 25 3a e2 8a 1a 51 f1 0c |....(.B.%:...Q..| -00000040 5b ce d2 2f 2b 86 c6 0f 10 d2 e2 44 da d8 4f 88 |[../+......D..O.| -00000050 b5 2b 9c 9f 21 06 da 76 93 06 42 43 1f |.+..!..v..BC.| +00000000 16 03 03 00 25 10 00 00 21 20 d5 2b 0e 3c e9 3e |....%...! .+.<.>| +00000010 e9 b0 3d 86 a9 85 b5 68 af cf 27 cf 4b d4 49 2e |..=....h..'.K.I.| +00000020 68 f2 9e 3c 32 7c cb fb dc 57 14 03 03 00 01 01 |h..<2|...W......| +00000030 16 03 03 00 28 5a cc f4 77 38 94 46 7b 39 5d 81 |....(Z..w8.F{9].| +00000040 be 77 a5 4a 76 c9 46 62 17 0b 2b ea 89 c2 29 bd |.w.Jv.Fb..+...).| +00000050 4b b0 dd 51 1e b8 7b a9 55 f5 fb b3 6a |K..Q..{.U...j| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -00000010 00 00 00 7c d4 b3 85 ea 5e 0c 8d 81 0c 7c 99 90 |...|....^....|..| -00000020 5f fd cc 32 b5 d8 fd 0c 0a 9c 93 a5 35 4d a8 50 |_..2........5M.P| -00000030 a8 6f 73 17 03 03 00 25 00 00 00 00 00 00 00 01 |.os....%........| -00000040 49 5c 12 84 e7 cb a4 fb b1 55 be 89 79 5c a8 df |I\.......U..y\..| -00000050 ab 0a e1 1b 98 e6 0f 40 fb f4 47 1f e1 15 03 03 |.......@..G.....| -00000060 00 1a 00 00 00 00 00 00 00 02 e7 17 b1 82 70 75 |..............pu| -00000070 42 d5 8f 2e 29 4b b3 a1 a2 3f c2 f8 |B...)K...?..| +00000010 00 00 00 b9 9b c0 b1 2b 71 af 0b 44 4e 4a cd e8 |.......+q..DNJ..| +00000020 c6 68 b8 2a d9 67 6f 7f 18 12 22 5c 4b 5c ca 43 |.h.*.go..."\K\.C| +00000030 ff c1 9d 17 03 03 00 25 00 00 00 00 00 00 00 01 |.......%........| +00000040 3c ae 33 dd 69 6c 01 a0 d2 a7 91 52 43 f3 78 38 |<.3.il.....RC.x8| +00000050 94 f4 24 0b 3d c9 bb 5f 02 27 89 bb 9b 15 03 03 |..$.=.._.'......| +00000060 00 1a 00 00 00 00 00 00 00 02 68 8d d7 d8 2f 95 |..........h.../.| +00000070 61 09 59 52 0d b8 12 fc 6a 07 28 37 |a.YR....j.(7| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4 b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4 index 78ea1ff9293..47a4ef2dc02 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RC4 @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 97 01 00 00 93 03 03 32 12 2b 12 44 |...........2.+.D| -00000010 4f 0c 98 c0 fc f6 44 06 3a b1 64 89 a5 8b f4 e4 |O.....D.:.d.....| -00000020 73 e1 60 1e 51 38 92 f3 83 f3 9f 00 00 04 00 05 |s.`.Q8..........| +00000000 16 03 01 00 97 01 00 00 93 03 03 2c 3c 18 04 94 |...........,<...| +00000010 e0 bb 10 99 7c 0c cd 0e e7 72 bc 83 4d f0 cf d7 |....|....r..M...| +00000020 4b 8e 2c 8b 52 bf ed 86 65 d2 a3 00 00 04 00 05 |K.,.R...e.......| 00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -10,66 +10,67 @@ 00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................| 00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 05 00 00 |...DOWNGRD......| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 85 ad 31 da a9 |.............1..| -00000010 fd 0f 5c ca aa 28 d1 08 7d 76 b4 5b b2 09 f4 e0 |..\..(..}v.[....| -00000020 65 3a 82 7e f8 03 5f c9 82 ae fb 04 f8 f1 dc bc |e:.~.._.........| -00000030 b9 2f e8 b4 4c b0 5a de c8 99 88 99 0b 03 ed 7f |./..L.Z.........| -00000040 e4 84 a0 6b 6d 55 1e f6 ea 9f 5a 55 1e 5c e5 f1 |...kmU....ZU.\..| -00000050 f4 8a f3 7b 7c 20 fc 4b 5d 31 98 c3 bb ce ba 6a |...{| .K]1.....j| -00000060 e8 e5 58 a1 db 5a 84 7d ef cd 17 52 2f 66 31 d2 |..X..Z.}...R/f1.| -00000070 27 e4 29 1c 9e e0 39 a9 e0 7f 5f 25 d7 49 95 28 |'.)...9..._%.I.(| -00000080 08 67 1e 25 5f 12 39 b0 a5 63 85 14 03 03 00 01 |.g.%_.9..c......| -00000090 01 16 03 03 00 24 88 e9 9e 1d 16 8f f7 6e b1 c9 |.....$.......n..| -000000a0 06 dc 50 e7 40 da 21 84 de 97 e6 a2 8d 78 96 9a |..P.@.!......x..| -000000b0 39 9d aa 91 43 15 0f cf f4 e9 |9...C.....| +00000000 16 03 03 00 86 10 00 00 82 00 80 a2 43 45 e6 1e |............CE..| +00000010 08 d3 29 62 0b 40 75 98 a3 f6 68 d7 78 31 b0 c9 |..)b.@u...h.x1..| +00000020 f4 f8 a6 98 dc d8 72 c1 2a 68 80 26 54 1c 16 af |......r.*h.&T...| +00000030 9f 67 cf ee 74 de 9e 29 b6 cd 0d eb df aa ea 44 |.g..t..).......D| +00000040 72 c9 aa fc ff c9 2d 9d bf bc f0 9b c1 7b 0d 5c |r.....-......{.\| +00000050 69 0c 75 d8 23 09 29 97 f6 38 9c f9 4f 1b 4a d5 |i.u.#.)..8..O.J.| +00000060 bd 04 d4 15 b3 a6 80 02 a4 11 32 d7 c0 cf 89 1f |..........2.....| +00000070 93 80 2b 48 49 51 44 b7 77 3c bf b1 a6 87 a3 ff |..+HIQD.w<......| +00000080 39 37 4a 42 49 92 93 25 0a 51 9a 14 03 03 00 01 |97JBI..%.Q......| +00000090 01 16 03 03 00 24 b5 c9 d6 9c ec 77 38 d2 30 79 |.....$.....w8.0y| +000000a0 f1 00 77 31 78 9b e6 ab ed 46 7c c6 e5 26 0b 44 |..w1x....F|..&.D| +000000b0 fd 30 b0 fe 0c 84 6f 9a cf 57 |.0....o..W| >>> Flow 4 (server to client) -00000000 14 03 03 00 01 01 16 03 03 00 24 c5 34 41 0f 31 |..........$.4A.1| -00000010 5a 94 d7 4b a9 0a 4e bf b9 22 ec 76 2c 1f f5 e9 |Z..K..N..".v,...| -00000020 6b 7b 26 df 41 62 91 b6 dc db 23 2b 8d 3d 49 17 |k{&.Ab....#+.=I.| -00000030 03 03 00 21 72 31 77 51 94 c5 d4 eb 7c 18 ab 87 |...!r1wQ....|...| -00000040 29 43 3b c5 78 aa 5c 4a 06 d3 42 5c 61 39 86 12 |)C;.x.\J..B\a9..| -00000050 b1 ae f6 f7 97 15 03 03 00 16 8a 0e 1d 5c e0 18 |.............\..| -00000060 12 93 ac 6c 69 32 59 b8 15 88 82 1c 97 f3 5b 9c |...li2Y.......[.| +00000000 14 03 03 00 01 01 16 03 03 00 24 58 cc 9f 3f ac |..........$X..?.| +00000010 2e 20 73 c9 5e 13 d3 12 3a 63 1e a9 ee 13 3d 0d |. s.^...:c....=.| +00000020 51 e9 15 5b 7b 33 92 85 6c fa d6 8a 15 16 dc 17 |Q..[{3..l.......| +00000030 03 03 00 21 bc af 01 72 48 0c 16 c9 7a c0 3c 27 |...!...rH...z.<'| +00000040 63 0a f8 34 e4 54 6a 39 39 61 02 bc c2 a0 07 03 |c..4.Tj99a......| +00000050 fb 2c d0 1b 6a 15 03 03 00 16 98 71 13 a6 5d f5 |.,..j......q..].| +00000060 7d aa 6d 05 2d a2 dc c0 7b 41 88 36 a2 49 a4 8b |}.m.-...{A.6.I..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 index 2c5237153a7..0e9be7fbdb0 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 91 01 00 00 8d 03 03 96 d3 ee ca ff |................| -00000010 77 00 8c e4 14 3a ee 2a bb 39 8c 62 72 c7 ae 46 |w....:.*.9.br..F| -00000020 8c 7e 8e 90 96 f1 c3 27 4d 37 3f 00 00 2a c0 30 |.~.....'M7?..*.0| +00000000 16 03 01 00 91 01 00 00 8d 03 03 84 aa e5 17 f4 |................| +00000010 80 c4 fb ca 14 f7 c9 d9 55 f0 8e 63 f9 e1 7e ad |........U..c..~.| +00000020 e7 5e 60 e9 2b dd 22 dd d1 11 93 00 00 2a c0 30 |.^`.+."......*.0| 00000030 00 9f cc a8 cc aa c0 2f 00 9e c0 28 00 6b c0 27 |......./...(.k.'| 00000040 00 67 c0 14 00 39 c0 13 00 33 00 9d 00 9c 00 3d |.g...9...3.....=| 00000050 00 3c 00 35 00 2f 00 ff 01 00 00 3a 00 00 00 0e |.<.5./.....:....| @@ -10,72 +10,73 @@ 00000080 00 1e 00 19 00 18 00 16 00 00 00 17 00 00 00 0d |................| 00000090 00 04 00 02 04 01 |......| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 30 00 00 |...DOWNGRD...0..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d |;...............| -000002a0 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 | /.}.G.bC.(.._.)| -000002b0 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b |.0.........._X.;| -000002c0 74 04 01 00 80 c9 24 3c 3d dd 65 45 f8 e4 92 b9 |t.....$<=.eE....| -000002d0 2b 03 c2 9f f5 73 1f 84 dd 9b da 82 2b 44 7c f1 |+....s......+D|.| -000002e0 7c 55 d8 53 39 e9 d9 ea f1 6a 23 7f b0 aa 30 94 ||U.S9....j#...0.| -000002f0 37 b7 06 59 1a fc 09 ba d9 68 f7 c8 96 5d 80 e1 |7..Y.....h...]..| -00000300 7c f4 1b 36 0a 8a dd 2e c5 d0 27 da 4a 75 98 fb ||..6......'.Ju..| -00000310 43 51 3f 8e 95 0d 7b 42 93 8a d5 dc 55 59 ef 69 |CQ?...{B....UY.i| -00000320 91 82 a3 d8 7e 54 a4 7b 05 17 06 58 21 62 79 b7 |....~T.{...X!by.| -00000330 67 bd ac 8c 9e 23 73 01 17 49 4b 5d 24 7a 29 0b |g....#s..IK]$z).| -00000340 05 ec 24 1e cb 16 03 03 00 04 0e 00 00 00 |..$...........| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........| +000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.| +000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| +000002c0 90 99 5f 58 cb 3b 74 04 01 00 80 2c d2 21 86 4f |.._X.;t....,.!.O| +000002d0 e0 b7 f1 7d f8 8f ca b3 e7 ef 34 e5 ea 78 12 b1 |...}......4..x..| +000002e0 92 1b 1b 7f 35 da 38 cb a9 1a 52 97 0e df 33 83 |....5.8...R...3.| +000002f0 e2 10 cb 72 78 41 66 9b 55 c9 a3 0b de ef b5 f3 |...rxAf.U.......| +00000300 8e 11 fa 5c a5 2a 93 29 b0 e2 42 9b 07 55 bd 6c |...\.*.)..B..U.l| +00000310 fa 3e a5 5b 2c 5b 3e d8 fa 76 6b d4 63 2c 47 22 |.>.[,[>..vk.c,G"| +00000320 17 92 9c 40 a4 f3 b3 a4 6d 12 da f7 d9 58 11 3f |...@....m....X.?| +00000330 1a 12 8a c8 19 a6 f8 e0 49 b8 6b 79 34 5f f2 46 |........I.ky4_.F| +00000340 27 62 e2 0e 13 93 74 b5 0b 63 8a 16 03 03 00 04 |'b....t..c......| +00000350 0e 00 00 00 |....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 8e 76 7a 64 15 47 |....%...! .vzd.G| -00000010 60 08 88 f8 3c ca 23 ce e3 f1 52 18 e0 94 6f 7a |`...<.#...R...oz| -00000020 be 7b 39 c6 42 eb 14 d9 f3 7a 14 03 03 00 01 01 |.{9.B....z......| -00000030 16 03 03 00 28 a8 16 b6 f4 4e 1e f1 5a 8a 04 a5 |....(....N..Z...| -00000040 4b a0 40 b1 9f 7e e7 42 22 45 01 03 52 5a 11 53 |K.@..~.B"E..RZ.S| -00000050 c1 1f a7 19 14 c0 9c d8 53 c3 41 ae 6f |........S.A.o| +00000000 16 03 03 00 25 10 00 00 21 20 0a 81 a9 76 78 5f |....%...! ...vx_| +00000010 f2 35 87 19 ed 3d 0b 1c 51 ff b7 51 c9 03 5a de |.5...=..Q..Q..Z.| +00000020 04 e6 47 3c d0 fe 32 75 64 28 14 03 03 00 01 01 |..G<..2ud(......| +00000030 16 03 03 00 28 90 38 86 3b 34 cf 30 74 00 91 55 |....(.8.;4.0t..U| +00000040 82 bd 9b 3a 78 34 09 3f a6 33 3f 7a 77 a5 53 67 |...:x4.?.3?zw.Sg| +00000050 30 94 30 cb 19 0c a8 ac 10 54 b8 90 57 |0.0......T..W| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -00000010 00 00 00 e8 93 95 10 51 dd 7c d1 07 72 73 c1 9d |.......Q.|..rs..| -00000020 6b 2a 47 ce f5 56 3f e0 2f c4 41 97 ea 6d 83 07 |k*G..V?./.A..m..| -00000030 3f 80 f5 17 03 03 00 25 00 00 00 00 00 00 00 01 |?......%........| -00000040 44 c5 ed 59 85 39 66 98 bb de 1a d3 03 f3 29 94 |D..Y.9f.......).| -00000050 4a 53 bd 25 bc 0a 23 11 10 68 c7 15 ad 15 03 03 |JS.%..#..h......| -00000060 00 1a 00 00 00 00 00 00 00 02 c8 a1 07 6c d8 6a |.............l.j| -00000070 cc f8 6a 5b d1 8c 32 93 71 23 c8 71 |..j[..2.q#.q| +00000010 00 00 00 e5 08 6e 55 df 84 0e 16 f9 e2 b0 44 3c |.....nU.......D<| +00000020 e7 e4 a1 e2 61 ee 18 cb bd c1 71 8f aa 23 c7 e1 |....a.....q..#..| +00000030 de ab 86 17 03 03 00 25 00 00 00 00 00 00 00 01 |.......%........| +00000040 6d 0c 13 09 51 5e 5b e8 2a 85 c6 99 7e 9a 7d 79 |m...Q^[.*...~.}y| +00000050 45 9b 63 18 d0 41 3d e7 78 24 93 52 11 15 03 03 |E.c..A=.x$.R....| +00000060 00 1a 00 00 00 00 00 00 00 02 ec a4 cf b9 7a 35 |..............z5| +00000070 9b 64 01 f4 7e 7d f0 08 05 79 7b 46 |.d..~}...y{F| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS index c260afe296b..465d8db01f6 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS @@ -1,54 +1,55 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 91 01 00 00 8d 03 03 de a3 85 5b 56 |..............[V| -00000010 34 e4 d0 57 07 66 8d 3c 39 00 eb 27 02 22 c9 f3 |4..W.f.<9..'."..| -00000020 23 a6 5e 08 3a 6d 06 09 8f d9 00 00 00 2a c0 30 |#.^.:m.......*.0| +00000000 16 03 01 00 91 01 00 00 8d 03 03 6d d9 a6 ff 3e |...........m...>| +00000010 4b 00 33 67 b4 8c c6 e8 07 ee f3 77 83 31 81 e9 |K.3g.......w.1..| +00000020 8f 3e 9e 77 8b 5c 8b 84 47 b4 33 00 00 2a c0 30 |.>.w.\..G.3..*.0| 00000030 00 9f cc a8 cc aa c0 2f 00 9e c0 28 00 6b c0 27 |......./...(.k.'| 00000040 00 67 c0 14 00 39 c0 13 00 33 00 9d 00 9c 00 3d |.g...9...3.....=| 00000050 00 3c 00 35 00 2f 00 ff 01 00 00 3a 00 00 00 0e |.<.5./.....:....| 00000060 00 0c 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b |.....127.0.0.1..| 00000070 00 04 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 |................| 00000080 00 1e 00 19 00 18 00 16 00 00 00 17 00 00 00 0d |................| -00000090 00 04 00 02 08 04 |......| +00000090 00 04 00 02 08 06 |......| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 30 00 00 |...DOWNGRD...0..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 15 03 03 00 02 02 28 |;.........(| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 15 03 03 00 02 02 |.`.\!.;.........| +000002a0 28 |(| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume b/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume index cebc00b5338..d1dba66d82d 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume @@ -1,48 +1,48 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 33 01 00 01 2f 03 03 b0 fe 51 14 a8 |....3.../....Q..| -00000010 15 64 e2 64 e4 8e 4f 93 bf 17 38 50 d8 fb 4c fb |.d.d..O...8P..L.| -00000020 03 04 a2 c0 9d b9 d2 19 8f e6 9a 20 5e e4 28 dd |........... ^.(.| -00000030 e1 a6 89 f5 b2 5e 1a 7b d3 af 0a bb 19 dc e1 2f |.....^.{......./| -00000040 58 d7 9e 59 a7 b7 de 07 bb 06 4d 0c 00 04 00 2f |X..Y......M..../| +00000000 16 03 01 01 33 01 00 01 2f 03 03 c0 ac ee 47 eb |....3.../.....G.| +00000010 75 70 12 a9 b7 d9 29 03 ba dd 0c 26 ef 07 cd c1 |up....)....&....| +00000020 ac 2b b5 14 8a 59 3a d7 58 7d 20 20 eb 74 37 f4 |.+...Y:.X} .t7.| +00000030 79 3b 34 ed e4 b1 51 00 b9 09 04 bc 48 82 07 a2 |y;4...Q.....H...| +00000040 cc 47 2d dc 16 54 a6 02 0c 5e f2 23 00 04 00 2f |.G-..T...^.#.../| 00000050 00 ff 01 00 00 e2 00 00 00 0e 00 0c 00 00 09 31 |...............1| 00000060 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000070 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| 00000080 00 23 00 78 50 46 ad c1 db a8 38 86 7b 2b bb fd |.#.xPF....8.{+..| 00000090 d0 c3 42 3e 00 00 00 00 00 00 00 00 00 00 00 00 |..B>............| -000000a0 00 00 00 00 94 6f 2c 9f 83 61 fe 79 79 ae dc c2 |.....o,..a.yy...| -000000b0 a0 99 e2 59 46 79 88 b8 ed 74 da ef da 3e 7e 69 |...YFy...t...>~i| -000000c0 af 34 63 b3 7f 52 e1 07 4d f8 40 69 63 85 8c 66 |.4c..R..M.@ic..f| -000000d0 a6 d6 f7 b7 b0 f2 d4 12 f4 2a 33 94 64 76 91 5b |.........*3.dv.[| -000000e0 6c 7d 49 37 3c 0b 76 3e d6 5c 0b 65 79 96 31 51 |l}I7<.v>.\.ey.1Q| -000000f0 46 01 51 94 38 5b 51 d5 2d 1a 8b 19 00 16 00 00 |F.Q.8[Q.-.......| +000000a0 00 00 00 00 94 6f 2c 9f 83 61 5c 5f 43 13 c2 76 |.....o,..a\_C..v| +000000b0 91 3a c1 1a 8c 51 00 5c a0 93 a9 06 e2 0c b0 65 |.:...Q.\.......e| +000000c0 e3 8c 0d 4b 7b 7e 52 32 b8 3c b3 76 c5 bf 95 4d |...K{~R2.<.v...M| +000000d0 29 71 50 81 e3 2b 6f 4a 32 dc 33 94 15 c5 fe 38 |)qP..+oJ2.3....8| +000000e0 b4 0a fc 03 38 90 32 db c0 7f 99 62 a9 89 15 d0 |....8.2....b....| +000000f0 f6 79 64 79 38 b0 e2 19 07 82 82 0a 00 16 00 00 |.ydy8...........| 00000100 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 |.......0........| 00000110 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| 00000120 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................| 00000130 02 02 04 02 05 02 06 02 |........| >>> Flow 2 (server to client) -00000000 16 03 03 00 51 02 00 00 4d 03 03 00 00 00 00 00 |....Q...M.......| +00000000 16 03 03 00 57 02 00 00 53 03 03 00 00 00 00 00 |....W...S.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000020 00 00 00 44 4f 57 4e 47 52 44 01 20 5e e4 28 dd |...DOWNGRD. ^.(.| -00000030 e1 a6 89 f5 b2 5e 1a 7b d3 af 0a bb 19 dc e1 2f |.....^.{......./| -00000040 58 d7 9e 59 a7 b7 de 07 bb 06 4d 0c 00 2f 00 00 |X..Y......M../..| -00000050 05 ff 01 00 01 00 14 03 03 00 01 01 16 03 03 00 |................| -00000060 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............| -00000070 00 c6 4d ae 43 25 3e 7a 8b 1d bc 77 6f 6d 05 c8 |..M.C%>z...wom..| -00000080 93 a1 d0 ee 81 0b e6 3e e6 0d 55 ff 3a 76 f3 e1 |.......>..U.:v..| -00000090 49 0b e4 3b d2 1c cb 2d 9f 1e 03 cb f9 8c 60 96 |I..;...-......`.| -000000a0 b1 |.| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 20 eb 74 37 f4 |...DOWNGRD. .t7.| +00000030 79 3b 34 ed e4 b1 51 00 b9 09 04 bc 48 82 07 a2 |y;4...Q.....H...| +00000040 cc 47 2d dc 16 54 a6 02 0c 5e f2 23 00 2f 00 00 |.G-..T...^.#./..| +00000050 0b ff 01 00 01 00 00 0b 00 02 01 00 14 03 03 00 |................| +00000060 01 01 16 03 03 00 40 00 00 00 00 00 00 00 00 00 |......@.........| +00000070 00 00 00 00 00 00 00 a6 49 4b 9d e0 3c e1 58 b4 |........IK..<.X.| +00000080 f9 50 e6 a6 32 ce 65 74 14 95 07 05 0c ef be 7d |.P..2.et.......}| +00000090 74 8c 46 3e 2a 07 de 5f 7a 08 b9 a0 80 f0 52 90 |t.F>*.._z.....R.| +000000a0 d4 6b c5 0f c5 ae 54 |.k....T| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 16 03 03 00 40 c9 ab 6e 5b 04 |..........@..n[.| -00000010 35 28 90 72 16 86 e8 ad a5 4d 2e f8 5a ee 42 8e |5(.r.....M..Z.B.| -00000020 6c 3f a4 00 3a de a8 c5 8f e3 59 15 10 09 31 91 |l?..:.....Y...1.| -00000030 5c ad a1 b1 15 bc fd a1 4a 91 4b 7a 50 a7 37 c4 |\.......J.KzP.7.| -00000040 3b 9d 3b 30 8e cd 8c ec b3 bc 94 |;.;0.......| +00000000 14 03 03 00 01 01 16 03 03 00 40 8c 59 48 06 01 |..........@.YH..| +00000010 a4 c6 35 ad a6 f5 a9 d3 31 ea 58 64 0e 45 91 4c |..5.....1.Xd.E.L| +00000020 fb e7 c6 6e 27 e8 92 a9 9c c3 c6 29 e9 6c 55 3a |...n'......).lU:| +00000030 2a fe 0f 40 d9 aa 3e fe ab 66 e1 38 91 d1 db ac |*..@..>..f.8....| +00000040 58 13 f0 3c 5e f1 a9 9c fd 07 04 |X..<^......| >>> Flow 4 (server to client) 00000000 17 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........| -00000010 00 00 00 00 00 95 7d fd bf 36 bd 7d 5f 42 2f 0a |......}..6.}_B/.| -00000020 84 27 ed 2d 76 07 cb 5a 96 93 74 68 9f 2a 66 fa |.'.-v..Z..th.*f.| -00000030 85 b0 38 bc da 8d 11 7f 80 80 21 ed 34 db 58 91 |..8.......!.4.X.| -00000040 b0 d7 8d 08 f1 15 03 03 00 30 00 00 00 00 00 00 |.........0......| -00000050 00 00 00 00 00 00 00 00 00 00 6f ed 4a be 10 ea |..........o.J...| -00000060 6a 75 ee 69 c2 2c f7 54 8a 18 aa 5f 7c 65 d0 d8 |ju.i.,.T..._|e..| -00000070 0c 94 dc a8 47 45 83 e6 68 09 |....GE..h.| +00000010 00 00 00 00 00 a6 4f 7a f8 b0 6e 25 13 fb b6 68 |......Oz..n%...h| +00000020 2d 1e 22 1b 95 93 63 e8 e1 9c 93 3e 53 78 bb aa |-."...c....>Sx..| +00000030 9f 6e 84 56 28 31 a0 ed a9 a3 06 fd e6 f9 c4 c4 |.n.V(1..........| +00000040 56 5f 5f c2 fb 15 03 03 00 30 00 00 00 00 00 00 |V__......0......| +00000050 00 00 00 00 00 00 00 00 00 00 c9 98 24 06 26 73 |............$.&s| +00000060 87 27 73 bd 7a 30 b5 85 28 f7 c4 b6 7a b0 96 9f |.'s.z0..(...z...| +00000070 a8 d4 43 1d 8e f5 a5 9f f3 f3 |..C.......| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled b/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled index 102ca95d8f9..2adf5862096 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled @@ -1,93 +1,94 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 33 01 00 01 2f 03 03 ec 14 e8 1f 51 |....3.../......Q| -00000010 60 0d 36 02 55 a0 c0 26 d1 a3 c4 e9 3a aa 95 4d |`.6.U..&....:..M| -00000020 6e 2b 72 fa 21 3d 26 0c 33 d6 87 20 12 fa 92 10 |n+r.!=&.3.. ....| -00000030 d6 81 cb 7d 83 97 81 0a 7b 02 0d b7 88 48 fd 14 |...}....{....H..| -00000040 82 23 7e c1 88 e7 2c 79 be 5c e1 30 00 04 00 2f |.#~...,y.\.0.../| +00000000 16 03 01 01 33 01 00 01 2f 03 03 3a 1d a7 55 e5 |....3.../..:..U.| +00000010 e7 ab ac 09 74 a3 4e e1 b9 cf 90 92 74 83 13 1c |....t.N.....t...| +00000020 e7 0b 57 c7 4a 48 bb a6 86 f0 93 20 29 15 61 8f |..W.JH..... ).a.| +00000030 f1 20 4a 95 e5 ce 8b 8d 60 4c 3c d6 2e 40 22 f4 |. J.....`L<..@".| +00000040 8d 4e 07 f7 76 c7 28 e8 b0 5d 79 4f 00 04 00 2f |.N..v.(..]yO.../| 00000050 00 ff 01 00 00 e2 00 00 00 0e 00 0c 00 00 09 31 |...............1| 00000060 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000070 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| 00000080 00 23 00 78 50 46 ad c1 db a8 38 86 7b 2b bb fd |.#.xPF....8.{+..| 00000090 d0 c3 42 3e 00 00 00 00 00 00 00 00 00 00 00 00 |..B>............| -000000a0 00 00 00 00 94 6f 2c 9f 83 61 70 4f 8e 34 f4 65 |.....o,..apO.4.e| -000000b0 e4 64 ba af 8d 55 d8 8a c4 90 a4 94 d1 84 44 51 |.d...U........DQ| -000000c0 72 f0 79 b3 2b c3 49 48 58 e7 66 8c 3d 60 dd 65 |r.y.+.IHX.f.=`.e| -000000d0 ba 93 0a f1 45 28 83 56 19 28 33 94 dd d4 29 db |....E(.V.(3...).| -000000e0 f0 80 d1 b2 0a ef 69 03 b5 fa 19 82 a9 0e 42 b0 |......i.......B.| -000000f0 bb c2 b5 c7 b5 92 1f e6 3b 38 e3 85 00 16 00 00 |........;8......| +000000a0 00 00 00 00 94 6f 2c 9f 83 61 31 33 93 70 cd 6a |.....o,..a13.p.j| +000000b0 19 a2 67 e8 7d cb a4 dc bb 80 d9 23 20 05 4d 53 |..g.}......# .MS| +000000c0 1f b6 9f 48 01 e4 84 75 10 25 f9 ed 98 bb 39 7e |...H...u.%....9~| +000000d0 fc 8b 16 d8 bc c7 e9 88 e8 1c 33 94 10 13 6b d4 |..........3...k.| +000000e0 3d fa d7 73 b2 d4 ea 89 58 ed 38 f8 f3 6a e0 5f |=..s....X.8..j._| +000000f0 1e f7 49 ed f7 5f 64 39 6b b5 6c fb 00 16 00 00 |..I.._d9k.l.....| 00000100 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 |.......0........| 00000110 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| 00000120 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................| 00000130 02 02 04 02 05 02 06 02 |........| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 a1 9c 83 96 72 |...............r| -00000010 04 cb dd 16 d6 02 0c fd ec 03 7f bb 23 9a a4 b5 |............#...| -00000020 f0 50 3e 0f 32 bb 92 9d 09 b0 20 f2 08 4b f0 37 |.P>.2..... ..K.7| -00000030 0d ef f6 22 0d 75 ad 2f 1b ce 1f 87 f0 fe 50 9a |...".u./......P.| -00000040 c5 3b a3 fa c7 59 bf dd 4c b6 04 95 a2 c4 83 97 |.;...Y..L.......| -00000050 04 e8 ab 3a ff 25 7b 2d aa c0 bd 0f 1f ef 55 34 |...:.%{-......U4| -00000060 c5 bf 7c 48 b7 9c d0 9a 37 ab fa 32 53 fb 5c 66 |..|H....7..2S.\f| -00000070 53 8a 81 cf bd 5a 8f d2 76 87 01 b9 29 72 b4 4e |S....Z..v...)r.N| -00000080 7c 25 6d b1 4f 59 8b a4 fc cf 27 14 03 03 00 01 ||%m.OY....'.....| -00000090 01 16 03 03 00 40 e2 b7 3e 75 4d 7a ee 8e 32 75 |.....@..>uMz..2u| -000000a0 e1 04 11 55 63 87 d6 f2 8d f1 78 de 8a fa bb 1e |...Uc.....x.....| -000000b0 74 1d 5c e3 c3 77 c4 10 6b 6d 63 ab 5c 08 b4 3e |t.\..w..kmc.\..>| -000000c0 f0 f7 cb 72 cd 5e 83 e2 6f 67 06 83 cf 22 73 05 |...r.^..og..."s.| -000000d0 2d 6f 12 58 2c 74 |-o.X,t| +00000000 16 03 03 00 86 10 00 00 82 00 80 70 09 52 14 dc |...........p.R..| +00000010 cd 33 63 59 1e 37 b2 30 ce 49 02 81 54 0e 94 ba |.3cY.7.0.I..T...| +00000020 9f a3 72 48 48 9d 52 65 a6 31 88 59 7d 23 26 78 |..rHH.Re.1.Y}#&x| +00000030 91 25 f7 35 81 b0 9f 7a 4f 3e df 6d f9 be 25 f2 |.%.5...zO>.m..%.| +00000040 05 ce d7 72 0c 2f b8 84 7f 05 ec 40 ba 06 b8 b2 |...r./.....@....| +00000050 a3 eb 3d 50 7d e0 23 c7 3e 4f cb 93 93 46 97 ee |..=P}.#.>O...F..| +00000060 ca 63 21 79 83 c6 24 6d 44 5c f5 a3 f0 5e 2c f5 |.c!y..$mD\...^,.| +00000070 33 f3 06 a9 9a 1a f9 b0 8a f1 21 38 2c 9e cd ba |3.........!8,...| +00000080 3c 63 07 76 dd 9c e7 19 a0 97 2a 14 03 03 00 01 |>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 d3 51 28 12 19 |............Q(..| -00000020 67 4f 60 7e 0e af f1 f9 31 4b 2c a3 87 a5 5c 61 |gO`~....1K,...\a| -00000030 1a d3 58 57 8f b5 a1 75 87 86 ca 7b e2 a3 bf 53 |..XW...u...{...S| -00000040 2a 92 09 04 43 29 9b 22 c5 19 a4 17 03 03 00 40 |*...C).".......@| +00000010 00 00 00 00 00 00 00 00 00 00 00 e2 e1 27 2b 83 |.............'+.| +00000020 17 2e 96 bc 84 93 99 10 b3 98 cc 1b 8e 2b 08 29 |.............+.)| +00000030 b1 fc 2d e6 33 78 11 82 a5 c7 e5 7d 28 8a e4 e3 |..-.3x.....}(...| +00000040 8a 5b 37 21 49 1b 45 b8 24 3a 24 17 03 03 00 40 |.[7!I.E.$:$....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 58 bf 73 aa ed 8a a0 61 c5 81 ac 22 1d ab 7b 75 |X.s....a..."..{u| -00000070 8b 31 97 fc df 6a e9 07 a7 3e c8 2d 3d 70 b1 b7 |.1...j...>.-=p..| -00000080 c1 ca 15 d5 c6 ac 32 ed 64 1f 98 d5 7e 17 3b 95 |......2.d...~.;.| +00000060 e8 cd 9a 90 f9 0c c7 cb 89 83 2c 0c fa 5b 02 d2 |..........,..[..| +00000070 d9 d3 0d a8 e8 60 ca 53 bd 8a d9 fb 70 6e a2 71 |.....`.S....pn.q| +00000080 46 b3 18 21 60 2d 4a 4a ee 14 40 99 3d 6f f6 bc |F..!`-JJ..@.=o..| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 e1 a6 0c 04 db 23 62 bb 99 9f b7 |..........#b....| -000000b0 1b 2b ae 6d 7d 9f 54 8e 39 60 6c d6 94 34 fa cd |.+.m}.T.9`l..4..| -000000c0 a8 7c ed a8 52 |.|..R| +000000a0 00 00 00 00 00 85 19 88 1d 3b 91 b4 ed 20 6c 24 |.........;... l$| +000000b0 de a3 ce 3f d6 3c 1a 8c db 28 56 6b df 55 ca 38 |...?.<...(Vk.U.8| +000000c0 61 7b 44 33 b1 |a{D3.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI b/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI index 380db2abb21..0ea8375fc51 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 99 01 00 00 95 03 03 dd e8 cc 23 63 |..............#c| -00000010 70 38 e5 f9 db 6c 77 0b be e9 53 ad 06 97 cb 02 |p8...lw...S.....| -00000020 d4 a7 bc d2 68 80 bf b8 0c 51 bc 00 00 04 00 2f |....h....Q...../| +00000000 16 03 01 00 99 01 00 00 95 03 03 fb d6 71 b2 32 |.............q.2| +00000010 74 6c e1 56 19 42 e6 46 a2 0e 37 1f ad 96 4b af |tl.V.B.F..7...K.| +00000020 8b 4c aa 71 2a 53 d8 df 74 7d 39 00 00 04 00 2f |.L.q*S..t}9..../| 00000030 00 ff 01 00 00 68 00 00 00 10 00 0e 00 00 0b 73 |.....h.........s| 00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 0b 00 04 03 00 |nitest.com......| 00000050 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| @@ -10,74 +10,75 @@ 00000080 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................| 00000090 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |..............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 88 3a 3f eb 46 |............:?.F| -00000010 28 cd 34 8f 95 5a 1e f8 c9 09 7d b0 97 9c 84 62 |(.4..Z....}....b| -00000020 20 fd c7 cd 2e 09 27 2e bb b7 1c b6 e1 05 7b f4 | .....'.......{.| -00000030 cc 52 14 ee 6c 9b 18 4e 31 5a 4d be 8c 84 e3 6c |.R..l..N1ZM....l| -00000040 27 ca e9 c4 e9 da 9a 84 cc 7c b5 87 27 e1 be 1c |'........|..'...| -00000050 7a 70 3b 2a 71 a4 7d c5 4b ab 28 0e 4b ff 1f c4 |zp;*q.}.K.(.K...| -00000060 d0 08 0b 9b ce e6 b8 ae a2 a9 c5 c9 0a 73 1d a0 |.............s..| -00000070 88 18 11 55 61 e1 1b 83 82 93 19 bb dc 29 f9 aa |...Ua........)..| -00000080 44 e0 b0 3b b9 dd 73 98 52 42 7b 14 03 03 00 01 |D..;..s.RB{.....| -00000090 01 16 03 03 00 40 a4 e7 a1 51 63 e2 d7 df 93 32 |.....@...Qc....2| -000000a0 01 f2 f1 14 a0 a3 1c 04 f1 c6 19 8c ab cb 51 b5 |..............Q.| -000000b0 78 12 a4 43 08 62 14 ff 5c a0 5f aa 61 d8 c3 2c |x..C.b..\._.a..,| -000000c0 c8 af 05 f8 83 ff fb 6a d9 a7 06 a9 ea b0 92 f5 |.......j........| -000000d0 75 5a bc e7 57 c3 |uZ..W.| +00000000 16 03 03 00 86 10 00 00 82 00 80 a4 48 88 75 7b |............H.u{| +00000010 a2 04 19 14 69 30 12 d6 14 00 0c 44 e4 68 06 c6 |....i0.....D.h..| +00000020 11 56 53 0c e5 52 fb 84 e2 6e b7 c6 eb 0d 79 25 |.VS..R...n....y%| +00000030 19 f0 bf e4 51 73 85 d5 82 5a 07 53 b2 65 97 6a |....Qs...Z.S.e.j| +00000040 a1 1b 56 bb 23 35 15 83 0f 60 ee de 16 a2 ea 61 |..V.#5...`.....a| +00000050 23 10 e1 5e cf 73 fe 5d 5a 53 16 42 0c 29 a5 ff |#..^.s.]ZS.B.)..| +00000060 06 e5 c4 87 11 d6 24 91 25 e5 58 81 40 80 9e 71 |......$.%.X.@..q| +00000070 49 40 47 50 37 28 7b ed 76 cc 5a fb 04 ba 9c f8 |I@GP7({.v.Z.....| +00000080 be ce 87 07 75 d2 30 88 09 cf bc 14 03 03 00 01 |....u.0.........| +00000090 01 16 03 03 00 40 60 1c 31 95 7d c2 a9 9b 29 c2 |.....@`.1.}...).| +000000a0 ef 59 58 dd fb 26 34 81 60 dc 17 19 c1 23 8d 8f |.YX..&4.`....#..| +000000b0 a8 d2 62 31 96 3d d2 61 b9 c8 7e bf 47 4c 04 fd |..b1.=.a..~.GL..| +000000c0 7c 30 05 37 8e 03 df 13 a1 4d f1 81 05 d7 4c 49 ||0.7.....M....LI| +000000d0 88 d6 c0 21 52 e3 |...!R.| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 63 e2 4a 8d 77 |...........c.J.w| -00000020 d8 d9 50 ae ba b0 44 d9 e2 7d 97 52 e6 65 07 5e |..P...D..}.R.e.^| -00000030 a1 03 19 a7 f6 a2 af 89 00 99 da 98 29 43 43 47 |............)CCG| -00000040 9b 3c 8f 03 1a 36 27 e3 d8 db b7 17 03 03 00 40 |.<...6'........@| +00000010 00 00 00 00 00 00 00 00 00 00 00 73 15 54 76 ad |...........s.Tv.| +00000020 c4 38 b0 40 45 32 a8 ca 05 19 bd ce 6e 39 77 6b |.8.@E2......n9wk| +00000030 46 a7 f8 45 a8 cd cd 98 8c aa cf 46 83 f0 20 93 |F..E.......F.. .| +00000040 0d 18 99 d4 2a f9 15 4a 2b f6 bf 17 03 03 00 40 |....*..J+......@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 c2 6b 34 e5 79 04 14 ec cf 14 4c 71 14 02 0d b3 |.k4.y.....Lq....| -00000070 29 31 ec d8 40 81 12 15 8e 17 8a 42 33 1a 82 9a |)1..@......B3...| -00000080 be e9 6c dc dc 49 56 7a fd 13 0a 20 37 79 e4 71 |..l..IVz... 7y.q| +00000060 79 8d 24 ef 72 b3 2c e2 10 a5 6d 3d 61 6c df c1 |y.$.r.,...m=al..| +00000070 26 bf 7e b5 cd b2 8e 87 b9 54 bf ee 35 07 bc 55 |&.~......T..5..U| +00000080 6c cd a2 d3 b4 bb 8c 63 fd ef b1 f0 2f 6d aa d9 |l......c..../m..| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -000000a0 00 00 00 00 00 4d 29 ee b6 bf f8 71 69 4e 96 a4 |.....M)....qiN..| -000000b0 5d 06 0e ef a9 aa 3f 16 19 c9 5d 8e 89 4f d2 cb |].....?...]..O..| -000000c0 17 1a e1 b0 63 |....c| +000000a0 00 00 00 00 00 7b f7 81 e6 5c f2 5c 9d 45 ec 1f |.....{...\.\.E..| +000000b0 7b 0d f8 62 19 d4 83 a8 e5 90 71 03 6e 6a 72 4b |{..b......q.njrK| +000000c0 7e 64 c4 c4 1a |~d...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate b/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate index 3e08bd4067f..199253f0732 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 99 01 00 00 95 03 03 78 fd 27 cc 09 |...........x.'..| -00000010 5e 07 db a2 78 ba 7a 4d a9 7f 74 f5 d1 6e a7 d2 |^...x.zM..t..n..| -00000020 bc f2 ee 22 2d 68 e7 59 c4 9c bc 00 00 04 00 2f |..."-h.Y......./| +00000000 16 03 01 00 99 01 00 00 95 03 03 cf 09 e7 0d ce |................| +00000010 ce d4 72 66 9d 30 e8 ee 39 b3 95 4c 3b 59 25 66 |..rf.0..9..L;Y%f| +00000020 d2 f5 d3 82 68 7d e7 26 2e 38 97 00 00 04 00 2f |....h}.&.8...../| 00000030 00 ff 01 00 00 68 00 00 00 10 00 0e 00 00 0b 73 |.....h.........s| 00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 0b 00 04 03 00 |nitest.com......| 00000050 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| @@ -10,74 +10,75 @@ 00000080 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................| 00000090 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |..............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 1f 30 ae eb ce |............0...| -00000010 57 b4 1c 5d f9 d0 5c 62 1e 89 6f b8 92 e3 c5 ef |W..]..\b..o.....| -00000020 ad cb 1b c2 86 e2 4e b5 88 4a d1 77 9d 89 07 87 |......N..J.w....| -00000030 43 a1 90 41 70 3e 5e b6 59 29 9c 05 79 8f 97 92 |C..Ap>^.Y)..y...| -00000040 77 6a 81 30 ec 30 ca e9 5e 66 10 6b 33 85 c8 c4 |wj.0.0..^f.k3...| -00000050 4f 9a 0d 8e 4b cb d2 d8 93 9c 9c b8 91 95 15 01 |O...K...........| -00000060 40 7c 61 cb bf a7 8e a9 ca dc 3e 78 ca 27 17 86 |@|a.......>x.'..| -00000070 40 50 c5 44 03 ad 87 7a dc 36 76 f5 79 6d 45 df |@P.D...z.6v.ymE.| -00000080 01 c1 d4 4f b0 d8 6a 2c fe 18 71 14 03 03 00 01 |...O..j,..q.....| -00000090 01 16 03 03 00 40 bc 90 46 f6 24 2f 68 47 7b 21 |.....@..F.$/hG{!| -000000a0 01 91 67 d4 94 39 c0 8e 9f d4 75 dc f6 3a ac 22 |..g..9....u..:."| -000000b0 4a a8 44 c9 ea 90 02 9b fa 5c d5 17 5c 3d 81 bb |J.D......\..\=..| -000000c0 90 72 29 5d 92 d8 b1 2d b7 a6 18 d1 7b 78 f4 7d |.r)]...-....{x.}| -000000d0 66 f8 2b 9c b1 90 |f.+...| +00000000 16 03 03 00 86 10 00 00 82 00 80 04 57 b2 56 f0 |............W.V.| +00000010 a5 fb c3 4d 4e 7d ba 29 18 04 ea 6e 66 d3 97 68 |...MN}.)...nf..h| +00000020 58 4e c1 47 fe 30 42 4d bf 5b 10 38 6a 01 83 98 |XN.G.0BM.[.8j...| +00000030 2b e3 3a ac c8 67 e5 41 0c 5c 3f 88 d5 15 a2 ab |+.:..g.A.\?.....| +00000040 6a 2b 70 24 d8 40 78 c1 d9 58 78 04 4d 90 03 eb |j+p$.@x..Xx.M...| +00000050 3c b1 61 da 26 62 db b3 41 ab dc 94 22 44 66 b8 |<.a.&b..A..."Df.| +00000060 49 2c fa 59 de c0 69 3c 20 f8 2f a5 e0 47 1d ec |I,.Y..i< ./..G..| +00000070 3c 49 2d 39 f6 41 09 06 79 5f 26 c4 12 3d 9c 8d |>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 c6 d9 32 9f b9 |.............2..| -00000020 e8 94 29 d3 62 fb ce 1d de 4e de be e4 bd 58 86 |..).b....N....X.| -00000030 96 07 c9 8e 34 77 b5 ca 18 67 39 d4 4c 33 c8 f0 |....4w...g9.L3..| -00000040 4f 6b a2 22 c7 c1 1e 73 a7 9f 91 17 03 03 00 40 |Ok."...s.......@| +00000010 00 00 00 00 00 00 00 00 00 00 00 5e ea d1 03 d7 |...........^....| +00000020 de 82 9a b4 07 52 46 16 fd 28 86 fe 17 2e 77 52 |.....RF..(....wR| +00000030 67 8f ec 64 93 1e 8e c9 fc fb 69 61 47 78 1a 1b |g..d......iaGx..| +00000040 97 8d fc 56 76 f6 53 8b 62 53 4f 17 03 03 00 40 |...Vv.S.bSO....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000060 74 73 d2 d5 5c 5d d7 0d 83 0f c6 8b bd 7c f6 31 |ts..\].......|.1| -00000070 2e cf 9d 01 14 f8 91 59 3d 2b 2f 4b 12 3f 72 1f |.......Y=+/K.?r.| -00000080 31 05 95 c9 a6 ab a4 15 b5 f3 a3 5c 68 15 f3 2f |1..........\h../| +00000060 f8 17 e8 ba c4 fb 0b 76 f5 a8 2d 3c 48 44 73 da |.......v..->> Flow 1 (client to server) -00000000 16 03 01 00 99 01 00 00 95 03 03 d9 85 58 6e 7f |.............Xn.| -00000010 2d b4 cd f0 04 75 ef 4a 41 8a f9 2e 87 ae 63 c8 |-....u.JA.....c.| -00000020 59 4b a2 4c 4f 46 c4 15 91 2e 7c 00 00 04 00 2f |YK.LOF....|..../| +00000000 16 03 01 00 99 01 00 00 95 03 03 34 7d 89 eb 2a |...........4}..*| +00000010 19 64 32 17 5d 37 0e dd 51 2c 7e 08 56 47 f3 2c |.d2.]7..Q,~.VG.,| +00000020 ca d0 08 51 86 a6 a3 10 85 5a 41 00 00 04 00 2f |...Q.....ZA..../| 00000030 00 ff 01 00 00 68 00 00 00 10 00 0e 00 00 0b 73 |.....h.........s| 00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 0b 00 04 03 00 |nitest.com......| 00000050 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| @@ -10,74 +10,75 @@ 00000080 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................| 00000090 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |..............| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 04 0e 00 00 00 |;............| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........| +000002a0 00 00 00 |...| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 5a 46 e5 a3 fb |...........ZF...| -00000010 1d 57 11 df 01 db d8 df 8c 2f 25 4a 23 7a 62 38 |.W......./%J#zb8| -00000020 49 b7 fa 2c 96 94 38 62 b5 9e db 5b 84 d8 8c 24 |I..,..8b...[...$| -00000030 ec 80 e8 f7 c6 bf 8f fc ba 2c 46 f6 ea e6 be 02 |.........,F.....| -00000040 fb 43 2c 97 82 6e 0e ce 1d 16 39 80 09 97 da 65 |.C,..n....9....e| -00000050 4a ad 87 02 2c f3 6a ce 44 c0 c3 16 ef 67 86 62 |J...,.j.D....g.b| -00000060 14 1a 85 7a 82 a7 b8 6f 55 8f 1e fb 5d 2d a8 cb |...z...oU...]-..| -00000070 ec 77 0d b0 b3 1b a1 99 c9 51 e8 63 98 1a 31 f4 |.w.......Q.c..1.| -00000080 b2 17 b5 bf 57 fb 23 47 ee 1e d3 14 03 03 00 01 |....W.#G........| -00000090 01 16 03 03 00 40 61 a2 82 3b 6f c3 f6 8b 1d 93 |.....@a..;o.....| -000000a0 42 f6 81 a4 e1 3b bd ab 6f d1 9d 04 a6 be f4 1b |B....;..o.......| -000000b0 c7 0b 63 c5 d2 4d 8b 69 41 5a 65 8d 8d b1 83 92 |..c..M.iAZe.....| -000000c0 2d d6 6c c5 45 c7 99 83 89 b7 d5 a1 ae 1b 33 05 |-.l.E.........3.| -000000d0 d5 00 9f cb 79 50 |....yP| +00000000 16 03 03 00 86 10 00 00 82 00 80 38 86 92 3e 9a |...........8..>.| +00000010 54 2d 44 46 76 d1 7c 07 04 83 2f 19 6d 89 c6 95 |T-DFv.|.../.m...| +00000020 07 63 17 7d ac e5 f7 95 7f f7 f2 3a f6 eb 38 26 |.c.}.......:..8&| +00000030 e5 c9 32 b1 27 88 46 85 f8 f6 eb 27 a8 9e de 5b |..2.'.F....'...[| +00000040 92 f7 3f 03 be 73 f0 de 2e b4 44 a8 89 4a 5a 6f |..?..s....D..JZo| +00000050 dc e7 16 9c dc f7 9f ca 40 9e 34 4b c2 45 58 7a |........@.4K.EXz| +00000060 6d 5c 4c 58 6a 45 10 21 fb b5 2a 58 17 7d d9 c4 |m\LXjE.!..*X.}..| +00000070 c9 7d d1 3b df 39 1b 59 6a 49 18 e1 fd 02 a2 1d |.}.;.9.YjI......| +00000080 5a 2d 3d c5 ab e7 f6 60 0d aa 38 14 03 03 00 01 |Z-=....`..8.....| +00000090 01 16 03 03 00 40 0e 2a fd e7 cd d0 72 ce 06 5c |.....@.*....r..\| +000000a0 40 c1 81 ef eb 27 e9 77 a8 d4 cc 5c 1e 15 7c 62 |@....'.w...\..|b| +000000b0 87 bd c5 8e b4 e6 6a 3f be 37 9d c0 fe f7 65 8b |......j?.7....e.| +000000c0 b1 3a b8 b4 76 67 ca 58 1c f5 3f f1 10 7c 5b 57 |.:..vg.X..?..|[W| +000000d0 90 e6 43 de d6 25 |..C..%| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -00000010 00 00 00 00 00 00 00 00 00 00 00 29 51 0e ac ef |...........)Q...| -00000020 7b ef 53 95 05 d9 4f 28 97 a2 d6 ff 44 e1 0f fb |{.S...O(....D...| -00000030 ed e2 ac f4 6c 46 5f 91 07 ba f0 8f 37 37 8d 77 |....lF_.....77.w| -00000040 7d a8 32 f5 4c f8 fd fc 86 ed 02 17 03 03 00 40 |}.2.L..........@| +00000010 00 00 00 00 00 00 00 00 00 00 00 8b 11 9a 67 af |..............g.| +00000020 5b 0e c9 01 dc 76 e8 48 2f 40 5c 76 13 ca 28 63 |[....v.H/@\v..(c| +00000030 a9 6d 3c 6b c1 d4 79 4d 39 17 55 a5 b9 0e b6 fd |.m.| +000000c0 b2 ea 47 71 1f |..Gq.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-X25519 b/libgo/go/crypto/tls/testdata/Server-TLSv12-X25519 index ca3e49b93b7..c196336dddc 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-X25519 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-X25519 @@ -1,7 +1,7 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 8f 01 00 00 8b 03 03 48 6b c4 66 fd |...........Hk.f.| -00000010 74 9f 73 e7 c8 4c 12 5b 6a e0 3d a6 5b ed f7 78 |t.s..L.[j.=.[..x| -00000020 f1 93 b3 1b 1f ee 2e bc 85 f7 4e 00 00 04 c0 2f |..........N..../| +00000000 16 03 01 00 8f 01 00 00 8b 03 03 5d ff d6 27 db |...........]..'.| +00000010 3b e5 2b 79 3a a6 cf 75 3d f7 c9 d9 0a d4 8c b2 |;.+y:..u=.......| +00000020 af 3c 29 84 65 a2 d6 98 52 e2 eb 00 00 04 c0 2f |.<).e...R....../| 00000030 00 ff 01 00 00 5e 00 00 00 0e 00 0c 00 00 09 31 |.....^.........1| 00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000050 00 0a 00 04 00 02 00 1d 00 16 00 00 00 17 00 00 |................| @@ -10,72 +10,73 @@ 00000080 06 01 03 03 02 03 03 01 02 01 03 02 02 02 04 02 |................| 00000090 05 02 06 02 |....| >>> Flow 2 (server to client) -00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....1...-.......| +00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 2f 00 00 |...DOWNGRD.../..| -00000030 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.| -00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......| -00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..| -00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.| -00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..| -00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..| -00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..| -000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1| -000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.| -000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...| -000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0| -000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.| -000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6| -00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.| -00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....| -00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......| -00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$| -00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..| -00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u| -00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.| -00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........| -00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.| -00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......| -000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.| -000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>| -000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#| -000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..| -000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0| -000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan| -00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........| -00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...| -00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1| -00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d| -00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..| -00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....| -00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......| -00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..| -00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.| -00000290 3b e9 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d |;...............| -000002a0 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 | /.}.G.bC.(.._.)| -000002b0 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b |.0.........._X.;| -000002c0 74 04 01 00 80 6f 80 d8 15 ba df d3 5d d9 71 5f |t....o......].q_| -000002d0 25 f0 4f 03 1f 62 11 f4 33 91 34 08 6e d0 49 b9 |%.O..b..3.4.n.I.| -000002e0 45 a6 37 85 73 36 c6 e7 45 c0 63 c9 66 0f b1 ae |E.7.s6..E.c.f...| -000002f0 86 33 b6 2a 24 d3 87 39 c8 62 da 0b 5d ae b0 74 |.3.*$..9.b..]..t| -00000300 0d b9 36 6b 1b 97 86 d8 65 fa 46 75 6f ef d9 87 |..6k....e.Fuo...| -00000310 6d b9 91 bb dc 47 42 23 c8 70 2a ba 65 0b 77 df |m....GB#.p*.e.w.| -00000320 57 6d 89 22 d8 36 f5 69 14 bc e1 c7 4c 80 22 0a |Wm.".6.i....L.".| -00000330 53 11 90 e0 61 30 48 29 2d 7c cf 17 94 a8 47 77 |S...a0H)-|....Gw| -00000340 24 17 21 ec 04 16 03 03 00 04 0e 00 00 00 |$.!...........| +00000030 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................| +00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0| +00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.| +00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......| +00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G| +00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R| +00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000| +000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000| +000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....| +000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0| +000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......| +000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.| +000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].| +00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...| +00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....| +00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4| +00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..| +00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. | +00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...| +00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....| +00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....| +00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..| +00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.| +000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....| +000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......| +000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0| +000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM| +000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...| +000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example| +00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..| +00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[| +00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..| +00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..| +00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.| +00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....| +00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.| +00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...| +00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=| +00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........| +000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.| +000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........| +000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 73 d6 a4 35 5f |.._X.;t....s..5_| +000002d0 3f 46 ad de 81 13 a8 d9 21 17 25 37 61 cb 62 0d |?F......!.%7a.b.| +000002e0 e2 bf 95 51 0e 9e e7 b1 ab bc be f6 ec 80 b1 f4 |...Q............| +000002f0 3e 9c 69 3f c8 1e a4 02 82 fd 57 01 e7 0c 18 be |>.i?......W.....| +00000300 c6 1b 01 68 cb ef dc d8 16 92 fb 1b 07 fd 98 f8 |...h............| +00000310 00 77 a9 8e 71 2a e0 6c 68 d5 83 f9 36 c3 3b 99 |.w..q*.lh...6.;.| +00000320 44 98 a0 96 00 1a 02 95 c5 7c ea ae 51 81 89 94 |D........|..Q...| +00000330 57 b6 37 c5 88 56 9f 49 bf 36 26 48 08 36 a1 69 |W.7..V.I.6&H.6.i| +00000340 48 a2 c4 b2 6f 0f 43 70 91 1e 8a 16 03 03 00 04 |H...o.Cp........| +00000350 0e 00 00 00 |....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 a0 e5 33 b9 5e e5 |....%...! ..3.^.| -00000010 11 68 48 53 f1 06 5b ea c7 2b 21 60 d1 ec e4 aa |.hHS..[..+!`....| -00000020 15 b9 38 bb c5 4d e4 c7 cf 17 14 03 03 00 01 01 |..8..M..........| -00000030 16 03 03 00 28 41 1f 89 64 4d bb 36 48 36 97 d7 |....(A..dM.6H6..| -00000040 1c 9c 44 9b 60 77 1e 73 87 7c f5 47 e4 e2 cd f8 |..D.`w.s.|.G....| -00000050 fc 76 fe f3 38 34 4f ab 4a ce 55 66 6e |.v..84O.J.Ufn| +00000000 16 03 03 00 25 10 00 00 21 20 0a 1b 78 c4 bb eb |....%...! ..x...| +00000010 a4 01 33 3b 69 95 c2 06 5d c9 3e b3 13 51 4b 93 |..3;i...].>..QK.| +00000020 5e 3c 3e a7 42 12 22 e8 7e 49 14 03 03 00 01 01 |^<>.B.".~I......| +00000030 16 03 03 00 28 fc c7 a1 45 50 e0 fe 27 fd ac a4 |....(...EP..'...| +00000040 d8 a2 c6 54 df e1 d3 6f e7 d8 45 a6 57 16 2f 1f |...T...o..E.W./.| +00000050 cf 89 26 c6 0a c3 4f 63 df ac bc c9 79 |..&...Oc....y| >>> Flow 4 (server to client) 00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -00000010 00 00 00 44 d3 59 7d fc 8a 85 c2 67 f6 b2 6c 43 |...D.Y}....g..lC| -00000020 5a 77 c0 96 a4 69 0f ec f6 fa 27 00 4c 04 e1 23 |Zw...i....'.L..#| -00000030 c5 1e d9 17 03 03 00 25 00 00 00 00 00 00 00 01 |.......%........| -00000040 3f 7f d6 e8 bb 6c 7f 1c d2 97 38 88 15 40 9c e5 |?....l....8..@..| -00000050 1f 0b ac 83 e7 8b 57 0d 6b 62 22 0b 8e 15 03 03 |......W.kb".....| -00000060 00 1a 00 00 00 00 00 00 00 02 d8 e7 53 15 ab a7 |............S...| -00000070 e4 62 10 fd 48 be f5 c8 09 98 92 ad |.b..H.......| +00000010 00 00 00 37 25 28 76 4e 31 dd 5e b0 5b 39 87 fc |...7%(vN1.^.[9..| +00000020 0f 10 3c bc 6d 12 9a dd 59 89 0b 09 bc f2 2c d8 |..<.m...Y.....,.| +00000030 05 a7 77 17 03 03 00 25 00 00 00 00 00 00 00 01 |..w....%........| +00000040 fe 79 9d dd d9 e3 bc 48 47 65 30 64 c7 74 82 0a |.y.....HGe0d.t..| +00000050 9f b7 45 a2 62 40 b5 dd 79 b9 ce 06 83 15 03 03 |..E.b@..y.......| +00000060 00 1a 00 00 00 00 00 00 00 02 58 ed 37 40 33 e4 |..........X.7@3.| +00000070 75 f0 a6 fa 14 f5 6b 93 9e 54 f2 a4 |u.....k..T..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-AES128-SHA256 b/libgo/go/crypto/tls/testdata/Server-TLSv13-AES128-SHA256 index 9e854036184..a071f60cd95 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-AES128-SHA256 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-AES128-SHA256 @@ -1,9 +1,9 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 dc 01 00 00 d8 03 03 8f 2d ec dc ac |............-...| -00000010 28 76 2d d2 5e b8 34 2f 3f b9 96 46 31 8a 12 d5 |(v-.^.4/?..F1...| -00000020 6a 9f a0 bf 11 00 3e d1 4c ba 17 20 72 a7 88 94 |j.....>.L.. r...| -00000030 ad d2 b6 e8 86 d8 34 45 42 44 b7 36 50 9b 64 36 |......4EBD.6P.d6| -00000040 de 03 b0 e5 99 8b f9 5a 67 5b f6 72 00 04 13 01 |.......Zg[.r....| +00000000 16 03 01 00 dc 01 00 00 d8 03 03 5f b5 79 18 5f |..........._.y._| +00000010 d2 f8 b0 fc da 39 90 af e1 ba 04 b5 70 86 c3 6b |.....9......p..k| +00000020 ba b4 87 e3 81 9a 86 02 9b 26 44 20 21 e3 5b 03 |.........&D !.[.| +00000030 0d 0a 6c 1f 71 ea b4 4c 56 aa b6 d1 e8 91 d6 7b |..l.q..LV......{| +00000040 59 12 63 af db d2 69 80 cd 5f 62 22 00 04 13 01 |Y.c...i.._b"....| 00000050 00 ff 01 00 00 8b 00 00 00 0e 00 0c 00 00 09 31 |...............1| 00000060 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 00000070 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| @@ -11,90 +11,90 @@ 00000090 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................| 000000a0 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 |...........+....| 000000b0 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 |..-.....3.&.$...| -000000c0 20 52 35 32 79 0e bf 01 91 5a b1 be 9b ff bf f4 | R52y....Z......| -000000d0 72 13 1a 3d a6 a8 15 9f ad c3 a9 b6 32 79 84 32 |r..=........2y.2| -000000e0 71 |q| +000000c0 20 57 12 bc 06 e0 46 c7 75 43 b8 af f9 c1 f6 b8 | W....F.uC......| +000000d0 e4 1e 13 6b 02 07 23 d2 e6 89 ec 18 ab c0 9f ae |...k..#.........| +000000e0 69 |i| >>> Flow 2 (server to client) 00000000 16 03 03 00 7a 02 00 00 76 03 03 00 00 00 00 00 |....z...v.......| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000020 00 00 00 00 00 00 00 00 00 00 00 20 72 a7 88 94 |........... r...| -00000030 ad d2 b6 e8 86 d8 34 45 42 44 b7 36 50 9b 64 36 |......4EBD.6P.d6| -00000040 de 03 b0 e5 99 8b f9 5a 67 5b f6 72 13 01 00 00 |.......Zg[.r....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 21 e3 5b 03 |........... !.[.| +00000030 0d 0a 6c 1f 71 ea b4 4c 56 aa b6 d1 e8 91 d6 7b |..l.q..LV......{| +00000040 59 12 63 af db d2 69 80 cd 5f 62 22 13 01 00 00 |Y.c...i.._b"....| 00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 2f |..+.....3.$... /| 00000060 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0| 00000070 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 14 |.........._X.;t.| -00000080 03 03 00 01 01 17 03 03 00 17 2a 27 a8 a8 aa f7 |..........*'....| -00000090 7f c4 74 12 f2 f5 b3 46 e3 fc 9f c6 8e 4d 81 4c |..t....F.....M.L| -000000a0 f2 17 03 03 02 6d 4c ad 3d 6f 2b c3 22 fc e0 3f |.....mL.=o+."..?| -000000b0 74 c2 f7 20 1a 37 ff 42 3e 5c c7 7e 0a 27 48 88 |t.. .7.B>\.~.'H.| -000000c0 23 77 d3 e9 96 d0 6c 44 67 e0 13 03 06 e3 f8 70 |#w....lDg......p| -000000d0 c0 e1 56 8f a3 18 58 8a d0 a0 f1 96 0a 4b 47 f8 |..V...X......KG.| -000000e0 a0 51 06 82 03 09 e8 82 e7 c1 91 5a fb 2e a4 a7 |.Q.........Z....| -000000f0 34 19 d8 c1 86 0d 56 e9 74 f1 28 7a 7e bf 50 30 |4.....V.t.(z~.P0| -00000100 e1 29 43 fa d9 67 6f d1 94 4c 7f 06 b9 b7 5d 6c |.)C..go..L....]l| -00000110 f1 a4 dc 48 53 de 7e d6 c2 8a 32 a3 78 94 2d 55 |...HS.~...2.x.-U| -00000120 76 0d 3c b8 93 76 98 70 36 c2 2e a2 b3 8c ec 32 |v.<..v.p6......2| -00000130 43 50 06 f8 76 28 19 3b a3 51 64 26 24 fa 97 43 |CP..v(.;.Qd&$..C| -00000140 65 12 aa 2f 55 c3 30 33 9a 88 dc 4c 86 e5 13 aa |e../U.03...L....| -00000150 4b 4d 85 e6 67 0c 87 61 26 cd 1b 7b 80 67 87 60 |KM..g..a&..{.g.`| -00000160 00 0d 7a eb 9a e4 d2 a6 72 b5 66 f4 5b 9c 2f 42 |..z.....r.f.[./B| -00000170 c1 4b d3 cf 9f e7 be bf a4 12 57 d4 15 83 ce 61 |.K........W....a| -00000180 c0 29 71 ed d5 c3 e3 68 a0 c7 02 ed 94 d7 1f b2 |.)q....h........| -00000190 11 c1 38 67 a6 42 d2 23 ae b8 16 ed 69 92 91 57 |..8g.B.#....i..W| -000001a0 ca b6 fd 93 8f 32 ab 2d 8b 74 f8 b0 bb 5a a0 16 |.....2.-.t...Z..| -000001b0 72 92 6e 9e 10 46 3a 7d 2f 55 de 0c d4 9d b6 d0 |r.n..F:}/U......| -000001c0 e1 f6 2d 10 de 97 c1 28 c8 d4 63 4a 5b f9 08 c7 |..-....(..cJ[...| -000001d0 8b 28 65 0b 07 e2 62 82 09 3e d2 dd 82 a6 72 79 |.(e...b..>....ry| -000001e0 1d 59 ef 58 87 5a b6 b1 38 20 3c 4c 55 c0 9d fb |.Y.X.Z..8 3.$oe7@..A_| -000003e0 43 3a dd 65 3d a7 b4 6c bf 21 f4 17 03 03 00 93 |C:.e=..l.!......| -000003f0 1a a6 3b b4 be dd c0 64 5f ae 2d 05 70 3b 5e fc |..;....d_.-.p;^.| -00000400 83 e0 ad 5b d0 b3 32 bc f9 98 b2 f5 9f 16 14 52 |...[..2........R| -00000410 37 2c 72 90 c1 be 97 49 a3 4d 10 97 0e d0 ec ff |7,r....I.M......| -00000420 98 50 87 90 ba f2 f0 81 08 14 ad f6 f9 3b d0 b8 |.P...........;..| -00000430 f8 c2 62 96 d1 4b 4f 5a 96 43 9f b6 96 6b 59 b8 |..b..KOZ.C...kY.| -00000440 f5 cc cf bc 79 1a a6 6e c6 7d 06 10 8f a0 21 39 |....y..n.}....!9| -00000450 67 5f 36 37 19 fa 0f 56 00 36 16 10 a2 80 9f 01 |g_67...V.6......| -00000460 0a 68 2d 50 a1 fc 67 c5 00 24 36 54 c2 5a 93 a4 |.h-P..g..$6T.Z..| -00000470 0a 6c cd aa 3f 22 bf ef f4 80 32 6a 14 e1 1e 6b |.l..?"....2j...k| -00000480 8a 38 40 |.8@| +00000080 03 03 00 01 01 17 03 03 00 17 be 8f 95 d9 22 d7 |..............".| +00000090 f7 ff 75 78 b6 9c bc 93 23 2f 76 62 c6 cd c6 92 |..ux....#/vb....| +000000a0 fe 17 03 03 02 6d 31 54 c9 32 d0 38 53 8f f0 15 |.....m1T.2.8S...| +000000b0 03 42 16 39 71 61 f9 17 f2 da c5 2e 4c 19 c3 30 |.B.9qa......L..0| +000000c0 d5 c6 b8 ea 5d 3b 47 1b d9 20 31 64 ab 5c f3 00 |....];G.. 1d.\..| +000000d0 43 5b e7 3b 36 69 12 c9 3b 3d e7 4f 91 72 e4 29 |C[.;6i..;=.O.r.)| +000000e0 93 54 65 50 88 07 b9 e2 ed 5e 18 f7 00 0a 49 e5 |.TeP.....^....I.| +000000f0 19 cc d8 e5 b2 c5 f6 bd 34 7a 7f e2 f1 7c 9d a0 |........4z...|..| +00000100 d6 0c 50 4f 80 8a c5 a1 fe b8 2e 54 7c 0c ae 48 |..PO.......T|..H| +00000110 c5 ff 46 d9 45 e6 c0 df 61 74 fc d5 e8 ec e1 84 |..F.E...at......| +00000120 0b c8 df 73 77 e4 9f 13 e5 52 e5 0b d8 9f 65 b7 |...sw....R....e.| +00000130 89 d5 04 74 f8 8d a6 2a c7 a1 76 ff 27 85 6a bb |...t...*..v.'.j.| +00000140 ee 86 c9 38 5a 54 bc ac bc ad 79 85 7c 26 65 c3 |...8ZT....y.|&e.| +00000150 36 97 56 76 d2 4c 55 32 71 82 ec d1 81 22 46 9e |6.Vv.LU2q...."F.| +00000160 75 d8 55 a8 1e 61 10 c8 dc e8 c7 ad fe 96 0e 54 |u.U..a.........T| +00000170 1c 79 0c 41 b9 98 b0 44 f8 45 6e c7 b3 41 68 2d |.y.A...D.En..Ah-| +00000180 ea 73 be 55 99 fe 88 02 e3 5d 0f f3 d1 70 9a 5e |.s.U.....]...p.^| +00000190 be e7 80 96 6c 94 7f 9f ec 1c b6 24 28 ef 90 95 |....l......$(...| +000001a0 d5 5b d4 7b 1b b1 a4 9c 66 09 11 23 ad f5 87 ee |.[.{....f..#....| +000001b0 0b 1f e5 d2 0e 57 16 e9 14 ae 0f 98 9b a1 bc 9e |.....W..........| +000001c0 68 dc d0 fb 76 aa c8 f2 bc e5 d3 ff e2 85 df 01 |h...v...........| +000001d0 2f ad 72 78 85 0f f7 0a 64 a4 cd 61 2a e6 2b a3 |/.rx....d..a*.+.| +000001e0 d5 4a c9 08 00 af 5c 6c 9d 35 e4 1e 7c 32 1a d0 |.J....\l.5..|2..| +000001f0 f3 6d 73 16 9c c8 72 28 4b 67 cf d8 ff 2b 1e 33 |.ms...r(Kg...+.3| +00000200 18 c4 ed c9 31 5d 6a 0f c5 05 bf 08 eb 0b 44 05 |....1]j.......D.| +00000210 83 49 40 d2 1f 7f 5c 08 ef 98 1f 09 f1 09 33 02 |.I@...\.......3.| +00000220 56 04 66 53 69 93 ef 07 0d 8a e7 84 b5 03 b9 78 |V.fSi..........x| +00000230 bb 52 84 3f bb 4e d3 f9 c4 8a 2a d1 59 02 59 36 |.R.?.N....*.Y.Y6| +00000240 88 52 6a 9d 1f 7e c1 5b a6 8a a4 cc 42 f4 44 59 |.Rj..~.[....B.DY| +00000250 ca d2 fa 0e 09 5f 25 e5 cc 27 55 8b 16 b5 f1 62 |....._%..'U....b| +00000260 aa f7 a9 bc 7a 36 fa 16 34 b7 ce 2d b8 bd 67 f0 |....z6..4..-..g.| +00000270 75 15 17 c4 49 81 55 b1 5a e0 d2 b8 45 79 d0 16 |u...I.U.Z...Ey..| +00000280 71 21 01 57 ad 10 48 1f 0d bf 43 da b7 c9 a8 93 |q!.W..H...C.....| +00000290 88 af be 2d 65 a0 81 26 23 de fe e2 a3 9c f6 40 |...-e..&#......@| +000002a0 96 f9 a1 21 0b fe 31 7f 24 ec 75 ae cf b0 8c a7 |...!..1.$.u.....| +000002b0 fe f8 2f ee 60 65 72 5c 86 a6 45 22 11 55 62 29 |../.`er\..E".Ub)| +000002c0 02 8b b5 ff 4b f8 73 71 3d 8c c3 37 68 2d 2c 24 |....K.sq=..7h-,$| +000002d0 b7 dc be 5a 37 d8 25 3b b6 16 e6 2a e9 80 48 0b |...Z7.%;...*..H.| +000002e0 77 be 05 35 b2 86 97 51 49 31 ac de 85 eb a9 a8 |w..5...QI1......| +000002f0 74 1d 00 07 4c 1b 8c a5 ec 1b b5 7a 57 84 da 40 |t...L......zW..@| +00000300 10 6c c9 ed b3 43 06 81 11 e2 84 3c 4c ae 22 6b |.l...C.....Y.3| +00000420 76 f0 23 23 27 94 df 2f 21 6a c0 a9 5a 3d af 41 |v.##'../!j..Z=.A| +00000430 31 4d 9b d5 75 57 f1 a9 c5 57 2a 7a c7 1d b1 a7 |1M..uW...W*z....| +00000440 15 a5 80 ae 63 f8 85 92 46 13 d2 31 26 62 7d 83 |....c...F..1&b}.| +00000450 95 f9 97 9d e8 86 7d 09 f3 cc 30 b1 db 54 2a 8d |......}...0..T*.| +00000460 0f 04 da d9 cf 59 52 2a e3 7d 64 20 f3 26 4a 2e |.....YR*.}d .&J.| +00000470 74 07 c5 2f 98 a2 f7 e1 53 01 e0 c2 3b c7 42 1b |t../....S...;.B.| +00000480 a0 48 12 |.H.| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 35 3c 0b 73 34 15 |..........5<.s4.| -00000010 e0 fc da 7f 3a 12 a0 50 95 09 0c ec 6a d5 7b 55 |....:..P....j.{U| -00000020 76 0f 7a 8e 25 e4 d2 b9 5f 5a 79 95 a5 a4 c6 9d |v.z.%..._Zy.....| -00000030 eb 0a ad 13 d1 97 a5 bd c4 d0 1e ce 59 59 04 16 |............YY..| +00000000 14 03 03 00 01 01 17 03 03 00 35 57 4a c4 5a c1 |..........5WJ.Z.| +00000010 3a b9 ae f0 1d e8 8f 31 38 0e 64 9e 61 13 e6 b2 |:......18.d.a...| +00000020 1b 02 aa b6 46 5a 50 97 07 93 86 13 dc 3d 76 6a |....FZP......=vj| +00000030 67 01 1b 18 9b 7e 21 b2 c1 d4 a5 25 22 4d 14 dc |g....~!....%"M..| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 9a 92 bf 83 9f 0b 36 66 2f 8e d5 |...........6f/..| -00000010 69 74 a7 a2 20 bb b2 d5 ac e8 99 b1 e6 df 4d 03 |it.. .........M.| -00000020 3e 9e 9c 17 03 03 00 13 7e 0c 85 34 9e 48 48 4a |>.......~..4.HHJ| -00000030 ce fa 96 dd 7b 7c 11 38 20 8d 33 |....{|.8 .3| +00000000 17 03 03 00 1e 61 63 5a 22 d2 e6 8e e8 8e 69 7d |.....acZ".....i}| +00000010 24 69 a5 b8 e3 59 98 ac 64 0b 34 6b 16 60 92 db |$i...Y..d.4k.`..| +00000020 6b 62 45 17 03 03 00 13 b7 12 c6 59 fe 23 f4 6c |kbE........Y.#.l| +00000030 a6 d3 8d 59 1b 40 60 72 d6 97 b4 |...Y.@`r...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS b/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS index 21f57b7b632..8151fd4d27e 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS @@ -1,101 +1,16 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 c6 01 00 00 c2 03 03 39 95 ab cc 1c |...........9....| -00000010 64 13 9d 19 2e 3e 73 33 48 b1 a9 f7 88 14 5a 83 |d....>s3H.....Z.| -00000020 19 f7 b5 08 8d e4 80 09 72 21 99 20 23 ad 4c 2c |........r!. #.L,| -00000030 66 84 1e e8 c3 0c 9f 66 19 76 df a3 e0 62 cd 7d |f......f.v...b.}| -00000040 95 85 70 4f 37 fb 39 58 50 b1 d5 7b 00 08 13 02 |..pO7.9XP..{....| +00000000 16 03 01 00 c6 01 00 00 c2 03 03 6b 64 fe be 82 |...........kd...| +00000010 d3 c7 f8 26 35 c1 7c 50 d0 a9 19 a5 1d 6b d5 1b |...&5.|P.....k..| +00000020 25 9b 47 fb 49 01 fc df 2e dc 8e 20 92 d0 73 81 |%.G.I...... ..s.| +00000030 91 5a 8a f9 2a cf 29 c7 9d 43 b2 b0 7d b9 5a a3 |.Z..*.)..C..}.Z.| +00000040 5f 74 53 a0 8e fe 4e 2e 83 0d 3b 0f 00 08 13 02 |_tS...N...;.....| 00000050 13 03 13 01 00 ff 01 00 00 71 00 00 00 0e 00 0c |.........q......| 00000060 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....| 00000070 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................| 00000080 00 19 00 18 00 16 00 00 00 17 00 00 00 0d 00 04 |................| -00000090 00 02 08 04 00 2b 00 03 02 03 04 00 2d 00 02 01 |.....+......-...| -000000a0 01 00 33 00 26 00 24 00 1d 00 20 be 29 89 8d 44 |..3.&.$... .)..D| -000000b0 4d e5 51 88 7a 1a 56 52 a8 86 74 13 0e e9 a5 a7 |M.Q.z.VR..t.....| -000000c0 b6 7f 38 b3 ef 62 e6 b0 c5 2a 0a |..8..b...*.| +00000090 00 02 08 06 00 2b 00 03 02 03 04 00 2d 00 02 01 |.....+......-...| +000000a0 01 00 33 00 26 00 24 00 1d 00 20 76 43 b3 ed 62 |..3.&.$... vC..b| +000000b0 22 72 15 69 b5 5b fd 9c ac 4a bd 36 4a 8d 3a 08 |"r.i.[...J.6J.:.| +000000c0 9d a0 5e 10 e6 13 87 2b 41 51 66 |..^....+AQf| >>> Flow 2 (server to client) -00000000 16 03 03 00 7a 02 00 00 76 03 03 00 00 00 00 00 |....z...v.......| -00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000020 00 00 00 00 00 00 00 00 00 00 00 20 23 ad 4c 2c |........... #.L,| -00000030 66 84 1e e8 c3 0c 9f 66 19 76 df a3 e0 62 cd 7d |f......f.v...b.}| -00000040 95 85 70 4f 37 fb 39 58 50 b1 d5 7b 13 02 00 00 |..pO7.9XP..{....| -00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 2f |..+.....3.$... /| -00000060 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0| -00000070 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 14 |.........._X.;t.| -00000080 03 03 00 01 01 17 03 03 00 17 49 c6 88 9c 3b 2f |..........I...;/| -00000090 3a 0a e6 8e 75 d0 39 11 ad 08 87 17 2c 14 96 28 |:...u.9.....,..(| -000000a0 85 17 03 03 02 6d 2a d6 89 4d 5d f3 6c 28 97 dd |.....m*..M].l(..| -000000b0 4e 45 88 e8 90 a4 f3 45 86 cf 59 d6 61 6e 1a a7 |NE.....E..Y.an..| -000000c0 b7 35 7e 9c 6e 11 19 c4 1b 89 b9 5a 7c aa 1f 96 |.5~.n......Z|...| -000000d0 e2 36 6d 54 09 12 2f 28 12 20 a3 41 06 bd 44 3c |.6mT../(. .A..D<| -000000e0 73 be d3 8c 78 18 a1 63 ad f9 9d 41 20 5e 32 55 |s...x..c...A ^2U| -000000f0 8e 18 c1 d8 b0 93 13 7e 88 a0 af 8a 59 e2 af 43 |.......~....Y..C| -00000100 d2 82 66 ba c5 a1 97 94 e8 63 40 1b 8f c4 eb 49 |..f......c@....I| -00000110 19 91 65 e9 54 d3 90 76 d6 f8 ff 15 20 31 3c 86 |..e.T..v.... 1<.| -00000120 88 8a 43 be 77 a0 28 de fa 9f d5 30 14 a8 35 2f |..C.w.(....0..5/| -00000130 5e ee 9d cf b5 69 d1 f5 f6 55 d1 1a 61 3f 4c a1 |^....i...U..a?L.| -00000140 97 38 5b 87 7e ce 88 23 8a d0 bd fc 4b c5 da f7 |.8[.~..#....K...| -00000150 25 6c 6c 0b ec 61 50 72 97 6b f7 fe 9b 5b 5a f9 |%ll..aPr.k...[Z.| -00000160 59 19 71 10 74 2d 14 8c 1b 52 8b 39 1c 56 ea 7e |Y.q.t-...R.9.V.~| -00000170 7a c9 8f 7c bd db 1e c5 02 9f 42 8b 63 ee 13 52 |z..|......B.c..R| -00000180 fe 46 40 de 7b 97 27 b0 16 87 75 96 c7 1c 88 5d |.F@.{.'...u....]| -00000190 2e 64 7f a8 df e0 16 b9 ee 27 7e b3 98 99 f7 4a |.d.......'~....J| -000001a0 83 05 78 bb 59 07 8e 1a 46 1d 0f 45 87 ae d9 ae |..x.Y...F..E....| -000001b0 6f 42 ed b1 72 14 8c 9d 33 72 95 ac 12 bb a0 20 |oB..r...3r..... | -000001c0 56 a8 8a 23 e4 51 6a 89 f5 8e bc 55 5a e2 8d 78 |V..#.Qj....UZ..x| -000001d0 84 24 55 99 cf 37 61 8c 7e 46 17 f3 26 ca 27 ec |.$U..7a.~F..&.'.| -000001e0 f4 04 f6 76 1d cf 82 0c bd 85 82 81 06 f1 96 ce |...v............| -000001f0 78 54 6c eb a0 f8 cf 30 6a 10 17 08 e6 94 83 4f |xTl....0j......O| -00000200 56 34 80 ef ac fa ab e7 59 9e 6b f9 f8 38 76 cc |V4......Y.k..8v.| -00000210 3b 09 b0 16 3f 3f 5c d3 6a ad d9 2c 65 d8 ce b4 |;...??\.j..,e...| -00000220 19 53 c4 c9 d1 82 e8 19 72 ec bc 85 ef 3a 6e e5 |.S......r....:n.| -00000230 ba 3c f8 37 98 98 80 47 5f 47 4f cd ed f5 0e bc |.<.7...G_GO.....| -00000240 4e 14 a2 7d 8d 43 0b 18 ba 3b 10 50 e4 18 fc ac |N..}.C...;.P....| -00000250 0e 01 21 73 68 da 50 51 8a 64 b6 18 28 ca e3 a4 |..!sh.PQ.d..(...| -00000260 aa d2 5c 28 ff 64 fd cb 28 00 db b1 5c bf 75 81 |..\(.d..(...\.u.| -00000270 bb d2 8c df 5c 26 70 1d d6 fe 7a 94 65 27 93 72 |....\&p...z.e'.r| -00000280 bc ba 17 92 8f be 61 ec f5 88 04 ed fb cc f3 5c |......a........\| -00000290 71 d0 a4 5d 13 a6 a3 82 89 e8 9e 1a 8e 31 fd 2f |q..].........1./| -000002a0 57 53 98 d5 1f c4 3f 8e 92 7f 1b 90 a3 ad 6c 96 |WS....?.......l.| -000002b0 42 cc f2 f0 1c 8d 3f 31 fd b2 53 29 79 16 9a 96 |B.....?1..S)y...| -000002c0 fd d6 fe d4 3f 13 aa 39 73 d4 73 6d 9a ff f6 db |....?..9s.sm....| -000002d0 52 0a 1e 76 71 0f d3 ee de a8 b3 05 3b 24 c4 72 |R..vq.......;$.r| -000002e0 67 78 f1 be df c5 c0 87 32 60 28 96 8e b2 2e 3f |gx......2`(....?| -000002f0 7d e9 aa b7 66 57 ee 67 e6 ac 70 da 60 ce c2 00 |}...fW.g..p.`...| -00000300 55 2f 20 25 39 a5 5e b9 65 c3 00 63 c7 5a a9 31 |U/ %9.^.e..c.Z.1| -00000310 de fe 65 17 03 03 00 99 95 83 6d be 56 ef 4f a3 |..e.......m.V.O.| -00000320 96 5f a8 3d d5 a1 f3 8e 9a 8c 40 35 f4 12 2c 0a |._.=......@5..,.| -00000330 b3 02 3b d2 14 d8 a4 f1 12 01 be e1 8a 6b 5f 01 |..;..........k_.| -00000340 71 de ac 70 e9 7a 90 78 2e 2a a8 29 64 20 85 dd |q..p.z.x.*.)d ..| -00000350 57 09 cf 48 29 d0 63 42 bc 9b ec 0c e2 2d 41 d0 |W..H).cB.....-A.| -00000360 cb d8 68 46 b7 17 fc 1d 95 12 5a 4c c3 10 67 32 |..hF......ZL..g2| -00000370 f7 7a 14 55 63 fb 57 6e 59 ee b6 66 b8 65 e1 37 |.z.Uc.WnY..f.e.7| -00000380 e6 7c 6c 07 8b d1 84 80 01 11 ce 7f 20 f0 4d 42 |.|l......... .MB| -00000390 a7 67 01 12 e6 b5 9b d4 6a fe 38 37 71 ca 60 d6 |.g......j.87q.`.| -000003a0 12 d7 00 b5 26 c3 97 1d 9f 37 6a 82 31 ef c3 12 |....&....7j.1...| -000003b0 bc 17 03 03 00 45 65 1e cf 1f 1e 73 93 8d 66 54 |.....Ee....s..fT| -000003c0 47 b0 73 9f d1 a4 9d 3b b0 72 b4 f2 5f 06 e1 d2 |G.s....;.r.._...| -000003d0 1f bb 3d 13 48 7c 7a e0 19 15 9f aa a5 ed 09 18 |..=.H|z.........| -000003e0 2e 4e 8a cd 66 2b 9c b3 fe 99 b0 57 06 2e b3 a0 |.N..f+.....W....| -000003f0 79 92 c1 bb 0e 29 44 02 f1 b0 43 17 03 03 00 a3 |y....)D...C.....| -00000400 52 cd d9 d7 60 1c f5 06 83 aa 2f e0 0c 0f 5e 6d |R...`...../...^m| -00000410 0f 29 93 b9 ae 50 04 c6 f7 d3 ff c7 d1 ac 9d 43 |.)...P.........C| -00000420 d7 b5 76 7a 16 b7 2c b7 79 48 a4 c3 28 2a 86 10 |..vz..,.yH..(*..| -00000430 d1 24 7c 04 ed af 1f 8a 0b 18 29 97 7a 7a 47 3f |.$|.......).zzG?| -00000440 1f fe ba 9c 72 d9 9b ae 9b 83 5f f4 5a 4f 10 b8 |....r....._.ZO..| -00000450 e5 45 35 76 77 a2 ac 99 1c bc 78 cf 6f 62 ef ef |.E5vw.....x.ob..| -00000460 9b 1b 90 eb 95 6b a1 25 82 b7 c1 1b 6f da 10 4c |.....k.%....o..L| -00000470 aa 3e a8 ba dd 77 b1 39 a0 b2 6a 11 18 44 2a 8d |.>...w.9..j..D*.| -00000480 58 9a 53 31 e1 d1 ec 8b 47 95 63 67 44 67 8d 09 |X.S1....G.cgDg..| -00000490 2f 16 f5 19 cd 65 1d 52 d7 bd 19 f0 bb ec 7b 55 |/....e.R......{U| -000004a0 33 4f 84 |3O.| ->>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 07 3f db d9 c7 |..........E.?...| -00000010 05 fd c4 0c 2d ae ee d8 d7 e7 ac 46 19 a2 17 e5 |....-......F....| -00000020 5e 10 30 65 05 be e0 c7 1e b3 e2 16 a4 d6 69 e1 |^.0e..........i.| -00000030 2c ff 18 ba e4 8f d0 3d 12 45 df c3 d4 08 0d e6 |,......=.E......| -00000040 94 6e 83 6d 99 9d f3 f1 02 48 6b 6f d1 2d f0 c6 |.n.m.....Hko.-..| ->>> Flow 4 (server to client) -00000000 17 03 03 00 1e 2a 3d 96 b4 6a 9e 7f 7f ca e0 8e |.....*=..j......| -00000010 41 4e bd 82 86 61 b8 59 19 e4 97 02 c2 00 7e 69 |AN...a.Y......~i| -00000020 81 b0 64 17 03 03 00 13 63 91 94 1a a3 51 bf 95 |..d.....c....Q..| -00000030 9e 09 a2 a1 f0 01 57 93 00 71 49 |......W..qI| +00000000 15 03 03 00 02 02 28 |......(| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall b/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall new file mode 100644 index 00000000000..94f5818ce15 --- /dev/null +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall @@ -0,0 +1,16 @@ +>>> Flow 1 (client to server) +00000000 16 03 01 00 c6 01 00 00 c2 03 03 7c a4 3e 3b dd |...........|.>;.| +00000010 d4 90 de 04 87 40 12 a6 f8 63 d9 9d b3 44 7b 52 |.....@...c...D{R| +00000020 9b b2 2d e2 da 0a 6b 87 30 2e 1f 20 38 be 06 6e |..-...k.0.. 8..n| +00000030 b8 2d 46 93 8d ed 31 ea 5c 44 5a 3a 6e 3a bd 3c |.-F...1.\DZ:n:.<| +00000040 0d 69 99 2c 5d 59 30 85 1a bc ce 59 00 08 13 02 |.i.,]Y0....Y....| +00000050 13 03 13 01 00 ff 01 00 00 71 00 00 00 0e 00 0c |.........q......| +00000060 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....| +00000070 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................| +00000080 00 19 00 18 00 16 00 00 00 17 00 00 00 0d 00 04 |................| +00000090 00 02 08 06 00 2b 00 03 02 03 04 00 2d 00 02 01 |.....+......-...| +000000a0 01 00 33 00 26 00 24 00 1d 00 20 d9 cb e9 03 27 |..3.&.$... ....'| +000000b0 59 f0 bd 7a 1f 17 88 c7 35 2b 92 0c d9 0c 0f 9a |Y..z....5+......| +000000c0 b5 47 c7 e2 97 aa 92 04 c6 63 2d |.G.......c-| +>>> Flow 2 (server to client) +00000000 15 03 03 00 02 02 28 |......(| diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go index ba6d5eba15b..228f4a79ab2 100644 --- a/libgo/go/crypto/tls/tls.go +++ b/libgo/go/crypto/tls/tls.go @@ -4,10 +4,6 @@ // Package tls partially implements TLS 1.2, as specified in RFC 5246, // and TLS 1.3, as specified in RFC 8446. -// -// TLS 1.3 is available on an opt-out basis in Go 1.13. To disable -// it, set the GODEBUG environment variable (comma-separated key=value -// options) such that it includes "tls13=0". package tls // BUG(agl): The crypto/tls package only implements some countermeasures @@ -79,8 +75,9 @@ func NewListener(inner net.Listener, config *Config) net.Listener { // The configuration config must be non-nil and must include // at least one certificate or else set GetCertificate. func Listen(network, laddr string, config *Config) (net.Listener, error) { - if config == nil || (len(config.Certificates) == 0 && config.GetCertificate == nil) { - return nil, errors.New("tls: neither Certificates nor GetCertificate set in Config") + if config == nil || len(config.Certificates) == 0 && + config.GetCertificate == nil && config.GetConfigForClient == nil { + return nil, errors.New("tls: neither Certificates, GetCertificate, nor GetConfigForClient set in Config") } l, err := net.Listen(network, laddr) if err != nil { diff --git a/libgo/go/crypto/tls/tls_test.go b/libgo/go/crypto/tls/tls_test.go index b68c074855f..178b519f1cc 100644 --- a/libgo/go/crypto/tls/tls_test.go +++ b/libgo/go/crypto/tls/tls_test.go @@ -6,6 +6,7 @@ package tls import ( "bytes" + "crypto" "crypto/x509" "encoding/json" "errors" @@ -18,7 +19,6 @@ import ( "os" "reflect" "strings" - "sync" "testing" "time" ) @@ -1023,60 +1023,6 @@ func TestConnectionState(t *testing.T) { } } -// TestEscapeRoute tests that the library will still work if support for TLS 1.3 -// is dropped later in the Go 1.12 cycle. -func TestEscapeRoute(t *testing.T) { - defer func(savedSupportedVersions []uint16) { - supportedVersions = savedSupportedVersions - }(supportedVersions) - supportedVersions = []uint16{ - VersionTLS12, - VersionTLS11, - VersionTLS10, - VersionSSL30, - } - - expectVersion(t, testConfig, testConfig, VersionTLS12) -} - -func expectVersion(t *testing.T, clientConfig, serverConfig *Config, v uint16) { - ss, cs, err := testHandshake(t, clientConfig, serverConfig) - if err != nil { - t.Fatalf("Handshake failed: %v", err) - } - if ss.Version != v { - t.Errorf("Server negotiated version %x, expected %x", cs.Version, v) - } - if cs.Version != v { - t.Errorf("Client negotiated version %x, expected %x", cs.Version, v) - } -} - -// TestTLS13Switch checks the behavior of GODEBUG=tls13=[0|1]. See Issue 30055. -func TestTLS13Switch(t *testing.T) { - defer func(savedGODEBUG string) { - os.Setenv("GODEBUG", savedGODEBUG) - }(os.Getenv("GODEBUG")) - - os.Setenv("GODEBUG", "tls13=0") - tls13Support.Once = sync.Once{} // reset the cache - - tls12Config := testConfig.Clone() - tls12Config.MaxVersion = VersionTLS12 - expectVersion(t, testConfig, testConfig, VersionTLS12) - expectVersion(t, tls12Config, testConfig, VersionTLS12) - expectVersion(t, testConfig, tls12Config, VersionTLS12) - expectVersion(t, tls12Config, tls12Config, VersionTLS12) - - os.Setenv("GODEBUG", "tls13=1") - tls13Support.Once = sync.Once{} // reset the cache - - expectVersion(t, testConfig, testConfig, VersionTLS13) - expectVersion(t, tls12Config, testConfig, VersionTLS12) - expectVersion(t, testConfig, tls12Config, VersionTLS12) - expectVersion(t, tls12Config, tls12Config, VersionTLS12) -} - // Issue 28744: Ensure that we don't modify memory // that Config doesn't own such as Certificates. func TestBuildNameToCertificate_doesntModifyCertificates(t *testing.T) { @@ -1100,3 +1046,289 @@ func TestBuildNameToCertificate_doesntModifyCertificates(t *testing.T) { } func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } + +func TestClientHelloInfo_SupportsCertificate(t *testing.T) { + rsaCert := &Certificate{ + Certificate: [][]byte{testRSACertificate}, + PrivateKey: testRSAPrivateKey, + } + pkcs1Cert := &Certificate{ + Certificate: [][]byte{testRSACertificate}, + PrivateKey: testRSAPrivateKey, + SupportedSignatureAlgorithms: []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256}, + } + ecdsaCert := &Certificate{ + // ECDSA P-256 certificate + Certificate: [][]byte{testP256Certificate}, + PrivateKey: testP256PrivateKey, + } + ed25519Cert := &Certificate{ + Certificate: [][]byte{testEd25519Certificate}, + PrivateKey: testEd25519PrivateKey, + } + + tests := []struct { + c *Certificate + chi *ClientHelloInfo + wantErr string + }{ + {rsaCert, &ClientHelloInfo{ + ServerName: "example.golang", + SignatureSchemes: []SignatureScheme{PSSWithSHA256}, + SupportedVersions: []uint16{VersionTLS13}, + }, ""}, + {ecdsaCert, &ClientHelloInfo{ + SignatureSchemes: []SignatureScheme{PSSWithSHA256, ECDSAWithP256AndSHA256}, + SupportedVersions: []uint16{VersionTLS13, VersionTLS12}, + }, ""}, + {rsaCert, &ClientHelloInfo{ + ServerName: "example.com", + SignatureSchemes: []SignatureScheme{PSSWithSHA256}, + SupportedVersions: []uint16{VersionTLS13}, + }, "not valid for requested server name"}, + {ecdsaCert, &ClientHelloInfo{ + SignatureSchemes: []SignatureScheme{ECDSAWithP384AndSHA384}, + SupportedVersions: []uint16{VersionTLS13}, + }, "signature algorithms"}, + {pkcs1Cert, &ClientHelloInfo{ + SignatureSchemes: []SignatureScheme{PSSWithSHA256, ECDSAWithP256AndSHA256}, + SupportedVersions: []uint16{VersionTLS13}, + }, "signature algorithms"}, + + {rsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + SignatureSchemes: []SignatureScheme{PKCS1WithSHA1}, + SupportedVersions: []uint16{VersionTLS13, VersionTLS12}, + }, "signature algorithms"}, + {rsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + SignatureSchemes: []SignatureScheme{PKCS1WithSHA1}, + SupportedVersions: []uint16{VersionTLS13, VersionTLS12}, + config: &Config{ + MaxVersion: VersionTLS12, + }, + }, ""}, // Check that mutual version selection works. + + {ecdsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256}, + SupportedVersions: []uint16{VersionTLS12}, + }, ""}, + {ecdsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{ECDSAWithP384AndSHA384}, + SupportedVersions: []uint16{VersionTLS12}, + }, ""}, // TLS 1.2 does not restrict curves based on the SignatureScheme. + {ecdsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: nil, + SupportedVersions: []uint16{VersionTLS12}, + }, ""}, // TLS 1.2 comes with default signature schemes. + {ecdsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256}, + SupportedVersions: []uint16{VersionTLS12}, + }, "cipher suite"}, + {ecdsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256}, + SupportedVersions: []uint16{VersionTLS12}, + config: &Config{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + }, + }, "cipher suite"}, + {ecdsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP384}, + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256}, + SupportedVersions: []uint16{VersionTLS12}, + }, "certificate curve"}, + {ecdsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, + SupportedPoints: []uint8{1}, + SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256}, + SupportedVersions: []uint16{VersionTLS12}, + }, "doesn't support ECDHE"}, + {ecdsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{PSSWithSHA256}, + SupportedVersions: []uint16{VersionTLS12}, + }, "signature algorithms"}, + + {ed25519Cert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, // only relevant for ECDHE support + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{Ed25519}, + SupportedVersions: []uint16{VersionTLS12}, + }, ""}, + {ed25519Cert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{CurveP256}, // only relevant for ECDHE support + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{Ed25519}, + SupportedVersions: []uint16{VersionTLS10}, + }, "doesn't support Ed25519"}, + {ed25519Cert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + SupportedCurves: []CurveID{}, + SupportedPoints: []uint8{pointFormatUncompressed}, + SignatureSchemes: []SignatureScheme{Ed25519}, + SupportedVersions: []uint16{VersionTLS12}, + }, "doesn't support ECDHE"}, + + {rsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, + SupportedCurves: []CurveID{CurveP256}, // only relevant for ECDHE support + SupportedPoints: []uint8{pointFormatUncompressed}, + SupportedVersions: []uint16{VersionTLS10}, + }, ""}, + {rsaCert, &ClientHelloInfo{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + SupportedVersions: []uint16{VersionTLS12}, + }, ""}, // static RSA fallback + } + for i, tt := range tests { + err := tt.chi.SupportsCertificate(tt.c) + switch { + case tt.wantErr == "" && err != nil: + t.Errorf("%d: unexpected error: %v", i, err) + case tt.wantErr != "" && err == nil: + t.Errorf("%d: unexpected success", i) + case tt.wantErr != "" && !strings.Contains(err.Error(), tt.wantErr): + t.Errorf("%d: got error %q, expected %q", i, err, tt.wantErr) + } + } +} + +func TestCipherSuites(t *testing.T) { + var lastID uint16 + for _, c := range CipherSuites() { + if lastID > c.ID { + t.Errorf("CipherSuites are not ordered by ID: got %#04x after %#04x", c.ID, lastID) + } else { + lastID = c.ID + } + + if c.Insecure { + t.Errorf("%#04x: Insecure CipherSuite returned by CipherSuites()", c.ID) + } + } + lastID = 0 + for _, c := range InsecureCipherSuites() { + if lastID > c.ID { + t.Errorf("InsecureCipherSuites are not ordered by ID: got %#04x after %#04x", c.ID, lastID) + } else { + lastID = c.ID + } + + if !c.Insecure { + t.Errorf("%#04x: not Insecure CipherSuite returned by InsecureCipherSuites()", c.ID) + } + } + + cipherSuiteByID := func(id uint16) *CipherSuite { + for _, c := range CipherSuites() { + if c.ID == id { + return c + } + } + for _, c := range InsecureCipherSuites() { + if c.ID == id { + return c + } + } + return nil + } + + for _, c := range cipherSuites { + cc := cipherSuiteByID(c.id) + if cc == nil { + t.Errorf("%#04x: no CipherSuite entry", c.id) + continue + } + + if defaultOff := c.flags&suiteDefaultOff != 0; defaultOff != cc.Insecure { + t.Errorf("%#04x: Insecure %v, expected %v", c.id, cc.Insecure, defaultOff) + } + if tls12Only := c.flags&suiteTLS12 != 0; tls12Only && len(cc.SupportedVersions) != 1 { + t.Errorf("%#04x: suite is TLS 1.2 only, but SupportedVersions is %v", c.id, cc.SupportedVersions) + } else if !tls12Only && len(cc.SupportedVersions) != 3 { + t.Errorf("%#04x: suite TLS 1.0-1.2, but SupportedVersions is %v", c.id, cc.SupportedVersions) + } + + if got := CipherSuiteName(c.id); got != cc.Name { + t.Errorf("%#04x: unexpected CipherSuiteName: got %q, expected %q", c.id, got, cc.Name) + } + } + for _, c := range cipherSuitesTLS13 { + cc := cipherSuiteByID(c.id) + if cc == nil { + t.Errorf("%#04x: no CipherSuite entry", c.id) + continue + } + + if cc.Insecure { + t.Errorf("%#04x: Insecure %v, expected false", c.id, cc.Insecure) + } + if len(cc.SupportedVersions) != 1 || cc.SupportedVersions[0] != VersionTLS13 { + t.Errorf("%#04x: suite is TLS 1.3 only, but SupportedVersions is %v", c.id, cc.SupportedVersions) + } + + if got := CipherSuiteName(c.id); got != cc.Name { + t.Errorf("%#04x: unexpected CipherSuiteName: got %q, expected %q", c.id, got, cc.Name) + } + } + + if got := CipherSuiteName(0xabc); got != "0x0ABC" { + t.Errorf("unexpected fallback CipherSuiteName: got %q, expected 0x0ABC", got) + } +} + +type brokenSigner struct{ crypto.Signer } + +func (s brokenSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { + // Replace opts with opts.HashFunc(), so rsa.PSSOptions are discarded. + return s.Signer.Sign(rand, digest, opts.HashFunc()) +} + +// TestPKCS1OnlyCert uses a client certificate with a broken crypto.Signer that +// always makes PKCS#1 v1.5 signatures, so can't be used with RSA-PSS. +func TestPKCS1OnlyCert(t *testing.T) { + clientConfig := testConfig.Clone() + clientConfig.Certificates = []Certificate{{ + Certificate: [][]byte{testRSACertificate}, + PrivateKey: brokenSigner{testRSAPrivateKey}, + }} + serverConfig := testConfig.Clone() + serverConfig.MaxVersion = VersionTLS12 // TLS 1.3 doesn't support PKCS#1 v1.5 + serverConfig.ClientAuth = RequireAnyClientCert + + // If RSA-PSS is selected, the handshake should fail. + if _, _, err := testHandshake(t, clientConfig, serverConfig); err == nil { + t.Fatal("expected broken certificate to cause connection to fail") + } + + clientConfig.Certificates[0].SupportedSignatureAlgorithms = + []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256} + + // But if the certificate restricts supported algorithms, RSA-PSS should not + // be selected, and the handshake should succeed. + if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil { + t.Error(err) + } +} diff --git a/libgo/go/crypto/x509/name_constraints_test.go b/libgo/go/crypto/x509/name_constraints_test.go index 2020e37a5b1..5469e28de24 100644 --- a/libgo/go/crypto/x509/name_constraints_test.go +++ b/libgo/go/crypto/x509/name_constraints_test.go @@ -1457,7 +1457,7 @@ var nameConstraintsTests = []nameConstraintsTest{ // that we can process CA certificates in the wild that have invalid SANs. // See https://github.com/golang/go/issues/23995 - // #77: an invalid DNS or mail SAN will not be detected if name constaint + // #77: an invalid DNS or mail SAN will not be detected if name constraint // checking is not triggered. { roots: make([]constraintsSpec, 1), diff --git a/libgo/go/crypto/x509/root_nacl.go b/libgo/go/crypto/x509/root_nacl.go deleted file mode 100644 index 4413f64738a..00000000000 --- a/libgo/go/crypto/x509/root_nacl.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package x509 - -// Possible certificate files; stop after finding one. -var certFiles = []string{} diff --git a/libgo/go/crypto/x509/root_unix.go b/libgo/go/crypto/x509/root_unix.go index eb8018e5640..a557ad671c3 100644 --- a/libgo/go/crypto/x509/root_unix.go +++ b/libgo/go/crypto/x509/root_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package x509 diff --git a/libgo/go/crypto/x509/root_windows.go b/libgo/go/crypto/x509/root_windows.go index 1e3ebe89422..54ab1dcf9c2 100644 --- a/libgo/go/crypto/x509/root_windows.go +++ b/libgo/go/crypto/x509/root_windows.go @@ -61,15 +61,15 @@ func extractSimpleChain(simpleChain **syscall.CertSimpleChain, count int) (chain return nil, errors.New("x509: invalid simple chain") } - simpleChains := (*[1 << 20]*syscall.CertSimpleChain)(unsafe.Pointer(simpleChain))[:] + simpleChains := (*[1 << 20]*syscall.CertSimpleChain)(unsafe.Pointer(simpleChain))[:count:count] lastChain := simpleChains[count-1] - elements := (*[1 << 20]*syscall.CertChainElement)(unsafe.Pointer(lastChain.Elements))[:] + elements := (*[1 << 20]*syscall.CertChainElement)(unsafe.Pointer(lastChain.Elements))[:lastChain.NumElements:lastChain.NumElements] for i := 0; i < int(lastChain.NumElements); i++ { // Copy the buf, since ParseCertificate does not create its own copy. cert := elements[i].CertContext - encodedCert := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:] + encodedCert := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:cert.Length:cert.Length] buf := make([]byte, cert.Length) - copy(buf, encodedCert[:]) + copy(buf, encodedCert) parsedCert, err := ParseCertificate(buf) if err != nil { return nil, err @@ -259,7 +259,7 @@ func loadSystemRoots() (*CertPool, error) { break } // Copy the buf, since ParseCertificate does not create its own copy. - buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:] + buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:cert.Length:cert.Length] buf2 := make([]byte, cert.Length) copy(buf2, buf) if c, err := ParseCertificate(buf2); err == nil { diff --git a/libgo/go/crypto/x509/sec1.go b/libgo/go/crypto/x509/sec1.go index 6cffa59d0e9..0bfb90cd546 100644 --- a/libgo/go/crypto/x509/sec1.go +++ b/libgo/go/crypto/x509/sec1.go @@ -28,9 +28,9 @@ type ecPrivateKey struct { PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` } -// ParseECPrivateKey parses an EC public key in SEC 1, ASN.1 DER form. +// ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form. // -// This kind of key is commonly encoded in PEM blocks of type "EC PUBLIC KEY". +// This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY". func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) { return parseECPrivateKey(nil, der) } diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go index 3b5b3576bdd..358fca4705b 100644 --- a/libgo/go/crypto/x509/verify.go +++ b/libgo/go/crypto/x509/verify.go @@ -80,7 +80,7 @@ func (e CertificateInvalidError) Error() string { case NotAuthorizedToSign: return "x509: certificate is not authorized to sign other certificates" case Expired: - return "x509: certificate has expired or is not yet valid" + return "x509: certificate has expired or is not yet valid: " + e.Detail case CANotAuthorizedForThisName: return "x509: a root or intermediate certificate is not authorized to sign for this name: " + e.Detail case CANotAuthorizedForExtKeyUsage: @@ -576,8 +576,18 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V if now.IsZero() { now = time.Now() } - if now.Before(c.NotBefore) || now.After(c.NotAfter) { - return CertificateInvalidError{c, Expired, ""} + if now.Before(c.NotBefore) { + return CertificateInvalidError{ + Cert: c, + Reason: Expired, + Detail: fmt.Sprintf("current time %s is before %s", now.Format(time.RFC3339), c.NotBefore.Format(time.RFC3339)), + } + } else if now.After(c.NotAfter) { + return CertificateInvalidError{ + Cert: c, + Reason: Expired, + Detail: fmt.Sprintf("current time %s is after %s", now.Format(time.RFC3339), c.NotAfter.Format(time.RFC3339)), + } } maxConstraintComparisons := opts.MaxConstraintComparisions diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 1cd8fdeb331..013f1c996d9 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -25,8 +25,6 @@ import ( "encoding/pem" "errors" "fmt" - "golang.org/x/crypto/cryptobyte" - cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" "io" "math/big" "net" @@ -35,6 +33,9 @@ import ( "strings" "time" "unicode/utf8" + + "golang.org/x/crypto/cryptobyte" + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" ) // pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo @@ -98,7 +99,7 @@ func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorith publicKeyBytes = pub publicKeyAlgorithm.Algorithm = oidPublicKeyEd25519 default: - return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only RSA and ECDSA public keys supported") + return nil, pkix.AlgorithmIdentifier{}, fmt.Errorf("x509: unsupported public key type: %T", pub) } return publicKeyBytes, publicKeyAlgorithm, nil @@ -780,6 +781,9 @@ func (ConstraintViolationError) Error() string { } func (c *Certificate) Equal(other *Certificate) bool { + if c == nil || other == nil { + return c == other + } return bytes.Equal(c.Raw, other.Raw) } @@ -787,55 +791,6 @@ func (c *Certificate) hasSANExtension() bool { return oidInExtensions(oidExtensionSubjectAltName, c.Extensions) } -// Entrust have a broken root certificate (CN=Entrust.net Certification -// Authority (2048)) which isn't marked as a CA certificate and is thus invalid -// according to PKIX. -// We recognise this certificate by its SubjectPublicKeyInfo and exempt it -// from the Basic Constraints requirement. -// See http://www.entrust.net/knowledge-base/technote.cfm?tn=7869 -// -// TODO(agl): remove this hack once their reissued root is sufficiently -// widespread. -var entrustBrokenSPKI = []byte{ - 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, - 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, - 0x00, 0x97, 0xa3, 0x2d, 0x3c, 0x9e, 0xde, 0x05, - 0xda, 0x13, 0xc2, 0x11, 0x8d, 0x9d, 0x8e, 0xe3, - 0x7f, 0xc7, 0x4b, 0x7e, 0x5a, 0x9f, 0xb3, 0xff, - 0x62, 0xab, 0x73, 0xc8, 0x28, 0x6b, 0xba, 0x10, - 0x64, 0x82, 0x87, 0x13, 0xcd, 0x57, 0x18, 0xff, - 0x28, 0xce, 0xc0, 0xe6, 0x0e, 0x06, 0x91, 0x50, - 0x29, 0x83, 0xd1, 0xf2, 0xc3, 0x2a, 0xdb, 0xd8, - 0xdb, 0x4e, 0x04, 0xcc, 0x00, 0xeb, 0x8b, 0xb6, - 0x96, 0xdc, 0xbc, 0xaa, 0xfa, 0x52, 0x77, 0x04, - 0xc1, 0xdb, 0x19, 0xe4, 0xae, 0x9c, 0xfd, 0x3c, - 0x8b, 0x03, 0xef, 0x4d, 0xbc, 0x1a, 0x03, 0x65, - 0xf9, 0xc1, 0xb1, 0x3f, 0x72, 0x86, 0xf2, 0x38, - 0xaa, 0x19, 0xae, 0x10, 0x88, 0x78, 0x28, 0xda, - 0x75, 0xc3, 0x3d, 0x02, 0x82, 0x02, 0x9c, 0xb9, - 0xc1, 0x65, 0x77, 0x76, 0x24, 0x4c, 0x98, 0xf7, - 0x6d, 0x31, 0x38, 0xfb, 0xdb, 0xfe, 0xdb, 0x37, - 0x02, 0x76, 0xa1, 0x18, 0x97, 0xa6, 0xcc, 0xde, - 0x20, 0x09, 0x49, 0x36, 0x24, 0x69, 0x42, 0xf6, - 0xe4, 0x37, 0x62, 0xf1, 0x59, 0x6d, 0xa9, 0x3c, - 0xed, 0x34, 0x9c, 0xa3, 0x8e, 0xdb, 0xdc, 0x3a, - 0xd7, 0xf7, 0x0a, 0x6f, 0xef, 0x2e, 0xd8, 0xd5, - 0x93, 0x5a, 0x7a, 0xed, 0x08, 0x49, 0x68, 0xe2, - 0x41, 0xe3, 0x5a, 0x90, 0xc1, 0x86, 0x55, 0xfc, - 0x51, 0x43, 0x9d, 0xe0, 0xb2, 0xc4, 0x67, 0xb4, - 0xcb, 0x32, 0x31, 0x25, 0xf0, 0x54, 0x9f, 0x4b, - 0xd1, 0x6f, 0xdb, 0xd4, 0xdd, 0xfc, 0xaf, 0x5e, - 0x6c, 0x78, 0x90, 0x95, 0xde, 0xca, 0x3a, 0x48, - 0xb9, 0x79, 0x3c, 0x9b, 0x19, 0xd6, 0x75, 0x05, - 0xa0, 0xf9, 0x88, 0xd7, 0xc1, 0xe8, 0xa5, 0x09, - 0xe4, 0x1a, 0x15, 0xdc, 0x87, 0x23, 0xaa, 0xb2, - 0x75, 0x8c, 0x63, 0x25, 0x87, 0xd8, 0xf8, 0x3d, - 0xa6, 0xc2, 0xcc, 0x66, 0xff, 0xa5, 0x66, 0x68, - 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, -} - // CheckSignatureFrom verifies that the signature on c is a valid signature // from parent. func (c *Certificate) CheckSignatureFrom(parent *Certificate) error { @@ -844,10 +799,8 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error { // certificate, or the extension is present but the cA boolean is not // asserted, then the certified public key MUST NOT be used to verify // certificate signatures." - // (except for Entrust, see comment above entrustBrokenSPKI) - if (parent.Version == 3 && !parent.BasicConstraintsValid || - parent.BasicConstraintsValid && !parent.IsCA) && - !bytes.Equal(c.RawSubjectPublicKeyInfo, entrustBrokenSPKI) { + if parent.Version == 3 && !parent.BasicConstraintsValid || + parent.BasicConstraintsValid && !parent.IsCA { return ConstraintViolationError{} } @@ -939,6 +892,11 @@ func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { return errors.New("x509: DSA signature contained zero or negative values") } + // According to FIPS 186-3, section 4.6, the hash must be truncated if it is longer + // than the key length, but crypto/dsa doesn't do it automatically. + if maxHashLen := pub.Q.BitLen() / 8; maxHashLen < len(signed) { + signed = signed[:maxHashLen] + } if !dsa.Verify(pub, signed, dsaSig.R, dsaSig.S) { return errors.New("x509: DSA verification failure") } @@ -2099,6 +2057,7 @@ var emptyASN1Subject = []byte{0x30, 0} // - ExcludedURIDomains // - ExtKeyUsage // - ExtraExtensions +// - IPAddresses // - IsCA // - IssuingCertificateURL // - KeyUsage @@ -2297,12 +2256,15 @@ func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts [ return } - h := hashFunc.New() - h.Write(tbsCertListContents) - digest := h.Sum(nil) + signed := tbsCertListContents + if hashFunc != 0 { + h := hashFunc.New() + h.Write(signed) + signed = h.Sum(nil) + } var signature []byte - signature, err = key.Sign(rand, digest, hashFunc) + signature, err = key.Sign(rand, signed, hashFunc) if err != nil { return } diff --git a/libgo/go/crypto/x509/x509_test.go b/libgo/go/crypto/x509/x509_test.go index 171509f7c45..9e15b8adbfe 100644 --- a/libgo/go/crypto/x509/x509_test.go +++ b/libgo/go/crypto/x509/x509_test.go @@ -450,6 +450,23 @@ func TestCertificateParse(t *testing.T) { } } +func TestCertificateEqualOnNil(t *testing.T) { + cNonNil := new(Certificate) + var cNil1, cNil2 *Certificate + if !cNil1.Equal(cNil2) { + t.Error("Nil certificates: cNil1 is not equal to cNil2") + } + if !cNil2.Equal(cNil1) { + t.Error("Nil certificates: cNil2 is not equal to cNil1") + } + if cNil1.Equal(cNonNil) { + t.Error("Unexpectedly cNil1 is equal to cNonNil") + } + if cNonNil.Equal(cNil1) { + t.Error("Unexpectedly cNonNil is equal to cNil1") + } +} + func TestMismatchedSignatureAlgorithm(t *testing.T) { der, _ := pem.Decode([]byte(rsaPSSSelfSignedPEM)) if der == nil { @@ -958,6 +975,49 @@ func TestVerifyCertificateWithDSASignature(t *testing.T) { } } +const dsaCert1024WithSha256 = `-----BEGIN CERTIFICATE----- +MIIDKzCCAumgAwIBAgIUOXWPK4gTRZVVY7OSXTU00QEWQU8wCwYJYIZIAWUDBAMC +MEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJ +bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMTkxMDAxMDYxODUyWhgPMzAxOTAy +MDEwNjE4NTJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggG4MIIBLAYHKoZIzjgE +ATCCAR8CgYEAr79m/1ypU1aUbbLX1jikTyX7w2QYP+EkxNtXUiiTuxkC1KBqqxT3 +0Aht2vxFR47ODEK4B79rHO+UevhaqDaAHSH7Z/9umS0h0aS32KLDLb+LI5AneCrn +eW5YbVhfD03N7uR4kKUCKOnWj5hAk9xiE3y7oFR0bBXzqrrHJF9LMd0CFQCB6lSj +HSW0rGmNxIZsBl72u7JFLQKBgQCOFd1PGEQmddn0cdFgby5QQfjrqmoD1zNlFZEt +L0x1EbndFwelLlF1ChNh3NPNUkjwRbla07FDlONs1GMJq6w4vW11ns+pUvAZ2+RM +EVFjugip8az2ncn3UujGTVdFxnSTLBsRlMP/tFDK3ky//8zn/5ha9SKKw4v1uv6M +JuoIbwOBhQACgYEAoeKeR90nwrnoPi5MOUPBLQvuzB87slfr+3kL8vFCmgjA6MtB +7TxQKoBTOo5aVgWDp0lMIMxLd6btzBrm6r3VdRlh/cL8/PtbxkFwBa+Upe4o5NAh +ISCe2/f2leT1PxtF8xxYjz/fszeUeHsJbVMilE2cuB2SYrR5tMExiqy+QpqjUzBR +MB0GA1UdDgQWBBQDMIEL8Z3jc1d9wCxWtksUWc8RkjAfBgNVHSMEGDAWgBQDMIEL +8Z3jc1d9wCxWtksUWc8RkjAPBgNVHRMBAf8EBTADAQH/MAsGCWCGSAFlAwQDAgMv +ADAsAhQFehZgI4OyKBGpfnXvyJ0Z/0a6nAIUTO265Ane87LfJuQr3FrqvuCI354= +-----END CERTIFICATE----- +` + +func TestVerifyCertificateWithDSATooLongHash(t *testing.T) { + pemBlock, _ := pem.Decode([]byte(dsaCert1024WithSha256)) + cert, err := ParseCertificate(pemBlock.Bytes) + if err != nil { + t.Fatalf("Failed to parse certificate: %s", err) + } + + // test cert is self-signed + if err = cert.CheckSignatureFrom(cert); err != nil { + t.Fatalf("DSA Certificate self-signature verification failed: %s", err) + } + + signed := []byte("A wild Gopher appears!\n") + signature, _ := hex.DecodeString("302c0214417aca7ff458f5b566e43e7b82f994953da84be50214625901e249e33f4e4838f8b5966020c286dd610e") + + // This signature is using SHA256, but only has 1024 DSA key. The hash has to be truncated + // in CheckSignature, otherwise it won't pass. + if err = cert.CheckSignature(DSAWithSHA256, signed, signature); err != nil { + t.Fatalf("DSA signature verification failed: %s", err) + } +} + var rsaPSSSelfSignedPEM = `-----BEGIN CERTIFICATE----- MIIGHjCCA9KgAwIBAgIBdjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUA oRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASAwbjELMAkGA1UEBhMC @@ -1133,11 +1193,77 @@ KVcg7fBd484ht/sS+l0dsB4KDOSpd8JzVDMF8OZqlaydizoJO0yWr9GbCN1+OKq5 EhLrEqU= -----END CERTIFICATE-----` +const ed25519CRLCertificate = ` +Certificate: +Data: + Version: 3 (0x2) + Serial Number: + 7a:07:a0:9d:14:04:16:fc:1f:d8:e5:fe:d1:1d:1f:8d + Signature Algorithm: ED25519 + Issuer: CN = Ed25519 CRL Test CA + Validity + Not Before: Oct 30 01:20:20 2019 GMT + Not After : Dec 31 23:59:59 9999 GMT + Subject: CN = Ed25519 CRL Test CA + Subject Public Key Info: + Public Key Algorithm: ED25519 + ED25519 Public-Key: + pub: + 95:73:3b:b0:06:2a:31:5a:b6:a7:a6:6e:ef:71:df: + ac:6f:6b:39:03:85:5e:63:4b:f8:a6:0f:68:c6:6f: + 75:21 + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication, OCSP Signing + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60 + X509v3 Authority Key Identifier: + keyid:B7:17:DA:16:EA:C5:ED:1F:18:49:44:D3:D2:E3:A0:35:0A:81:93:60 + +Signature Algorithm: ED25519 + fc:3e:14:ea:bb:70:c2:6f:38:34:70:bc:c8:a7:f4:7c:0d:1e: + 28:d7:2a:9f:22:8a:45:e8:02:76:84:1e:2d:64:2d:1e:09:b5: + 29:71:1f:95:8a:4e:79:87:51:60:9a:e7:86:40:f6:60:c7:d1: + ee:68:76:17:1d:90:cc:92:93:07 +-----BEGIN CERTIFICATE----- +MIIBijCCATygAwIBAgIQegegnRQEFvwf2OX+0R0fjTAFBgMrZXAwHjEcMBoGA1UE +AxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAgFw0xOTEwMzAwMTIwMjBaGA85OTk5MTIz +MTIzNTk1OVowHjEcMBoGA1UEAxMTRWQyNTUxOSBDUkwgVGVzdCBDQTAqMAUGAytl +cAMhAJVzO7AGKjFatqembu9x36xvazkDhV5jS/imD2jGb3Uho4GNMIGKMA4GA1Ud +DwEB/wQEAwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAgYIKwYBBQUHAwEGCCsGAQUF +BwMJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLcX2hbqxe0fGElE09LjoDUK +gZNgMB8GA1UdIwQYMBaAFLcX2hbqxe0fGElE09LjoDUKgZNgMAUGAytlcANBAPw+ +FOq7cMJvODRwvMin9HwNHijXKp8iikXoAnaEHi1kLR4JtSlxH5WKTnmHUWCa54ZA +9mDH0e5odhcdkMySkwc= +-----END CERTIFICATE-----` + +const ed25519CRLKey = `-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEINdKh2096vUBYu4EIFpjShsUSh3vimKya1sQ1YTT4RZG +-----END PRIVATE KEY-----` + func TestCRLCreation(t *testing.T) { block, _ := pem.Decode([]byte(pemPrivateKey)) - priv, _ := ParsePKCS1PrivateKey(block.Bytes) + privRSA, _ := ParsePKCS1PrivateKey(block.Bytes) block, _ = pem.Decode([]byte(pemCertificate)) - cert, _ := ParseCertificate(block.Bytes) + certRSA, _ := ParseCertificate(block.Bytes) + + block, _ = pem.Decode([]byte(ed25519CRLKey)) + privEd25519, _ := ParsePKCS8PrivateKey(block.Bytes) + block, _ = pem.Decode([]byte(ed25519CRLCertificate)) + certEd25519, _ := ParseCertificate(block.Bytes) + + tests := []struct { + name string + priv interface{} + cert *Certificate + }{ + {"RSA CA", privRSA, certRSA}, + {"Ed25519 CA", privEd25519, certEd25519}, + } loc := time.FixedZone("Oz/Atlantis", int((2 * time.Hour).Seconds())) @@ -1167,18 +1293,20 @@ func TestCRLCreation(t *testing.T) { }, } - crlBytes, err := cert.CreateCRL(rand.Reader, priv, revokedCerts, now, expiry) - if err != nil { - t.Errorf("error creating CRL: %s", err) - } + for _, test := range tests { + crlBytes, err := test.cert.CreateCRL(rand.Reader, test.priv, revokedCerts, now, expiry) + if err != nil { + t.Errorf("%s: error creating CRL: %s", test.name, err) + } - parsedCRL, err := ParseDERCRL(crlBytes) - if err != nil { - t.Errorf("error reparsing CRL: %s", err) - } - if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) { - t.Errorf("RevokedCertificates mismatch: got %v; want %v.", - parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) + parsedCRL, err := ParseDERCRL(crlBytes) + if err != nil { + t.Errorf("%s: error reparsing CRL: %s", test.name, err) + } + if !reflect.DeepEqual(parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) { + t.Errorf("%s: RevokedCertificates mismatch: got %v; want %v.", test.name, + parsedCRL.TBSCertList.RevokedCertificates, expectedCerts) + } } } diff --git a/libgo/go/database/sql/convert.go b/libgo/go/database/sql/convert.go index 4c056a1edad..b966ef970c1 100644 --- a/libgo/go/database/sql/convert.go +++ b/libgo/go/database/sql/convert.go @@ -565,7 +565,7 @@ func callValuerValue(vr driver.Valuer) (v driver.Value, err error) { // coefficient (also known as a significand) as a []byte, and an int32 exponent. // These are composed into a final value as "decimal = (neg) (form=finite) coefficient * 10 ^ exponent". // A zero length coefficient is a zero value. -// The big-endian integer coefficent stores the most significant byte first (at coefficent[0]). +// The big-endian integer coefficient stores the most significant byte first (at coefficient[0]). // If the form is not finite the coefficient and exponent should be ignored. // The negative parameter may be set to true for any form, although implementations are not required // to respect the negative parameter in the non-finite form. diff --git a/libgo/go/database/sql/convert_test.go b/libgo/go/database/sql/convert_test.go index 8a82891c253..2668a5ed5e7 100644 --- a/libgo/go/database/sql/convert_test.go +++ b/libgo/go/database/sql/convert_test.go @@ -525,7 +525,7 @@ func (d *dec) Compose(form byte, negative bool, coefficient []byte, exponent int // This isn't strictly correct, as the extra bytes could be all zero, // ignore this for this test. if len(coefficient) > 16 { - return fmt.Errorf("coefficent too large") + return fmt.Errorf("coefficient too large") } copy(d.coefficient[:], coefficient) @@ -558,7 +558,7 @@ func (d *decFinite) Compose(form byte, negative bool, coefficient []byte, expone // This isn't strictly correct, as the extra bytes could be all zero, // ignore this for this test. if len(coefficient) > 16 { - return fmt.Errorf("coefficent too large") + return fmt.Errorf("coefficient too large") } copy(d.coefficient[:], coefficient) diff --git a/libgo/go/database/sql/ctxutil.go b/libgo/go/database/sql/ctxutil.go index af2afd5aa57..4dbe6af6d2b 100644 --- a/libgo/go/database/sql/ctxutil.go +++ b/libgo/go/database/sql/ctxutil.go @@ -94,8 +94,6 @@ func ctxDriverStmtQuery(ctx context.Context, si driver.Stmt, nvdargs []driver.Na return si.Query(dargs) } -var errLevelNotSupported = errors.New("sql: selected isolation level is not supported") - func ctxDriverBegin(ctx context.Context, opts *TxOptions, ci driver.Conn) (driver.Tx, error) { if ciCtx, is := ci.(driver.ConnBeginTx); is { dopts := driver.TxOptions{} diff --git a/libgo/go/database/sql/fakedb_test.go b/libgo/go/database/sql/fakedb_test.go index c0371f3e784..a0028be0e57 100644 --- a/libgo/go/database/sql/fakedb_test.go +++ b/libgo/go/database/sql/fakedb_test.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "log" "reflect" "sort" "strconv" @@ -20,8 +19,6 @@ import ( "time" ) -var _ = log.Printf - // fakeDriver is a fake database that implements Go's driver.Driver // interface, just for testing. // diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go index 5c5b7dc7e97..0f5bbc01c9e 100644 --- a/libgo/go/database/sql/sql.go +++ b/libgo/go/database/sql/sql.go @@ -64,7 +64,7 @@ func unregisterAllDrivers() { func Drivers() []string { driversMu.RLock() defer driversMu.RUnlock() - var list []string + list := make([]string, 0, len(drivers)) for name := range drivers { list = append(list, name) } @@ -2040,7 +2040,7 @@ func (tx *Tx) grabConn(ctx context.Context) (*driverConn, releaseConn, error) { return nil, nil, ctx.Err() } - // closeme.RLock must come before the check for isDone to prevent the Tx from + // closemu.RLock must come before the check for isDone to prevent the Tx from // closing while a query is executing. tx.closemu.RLock() if tx.isDone() { diff --git a/libgo/go/database/sql/sql_test.go b/libgo/go/database/sql/sql_test.go index f68cefe43ae..ed0099e0e94 100644 --- a/libgo/go/database/sql/sql_test.go +++ b/libgo/go/database/sql/sql_test.go @@ -3783,7 +3783,7 @@ func (c *ctxOnlyConn) ExecContext(ctx context.Context, q string, args []driver.N // TestQueryExecContextOnly ensures drivers only need to implement QueryContext // and ExecContext methods. func TestQueryExecContextOnly(t *testing.T) { - // Ensure connection does not implment non-context interfaces. + // Ensure connection does not implement non-context interfaces. var connType driver.Conn = &ctxOnlyConn{} if _, ok := connType.(driver.Execer); ok { t.Fatalf("%T must not implement driver.Execer", connType) diff --git a/libgo/go/debug/dwarf/attr_string.go b/libgo/go/debug/dwarf/attr_string.go index 34e3659a64c..8a4fff85a40 100644 --- a/libgo/go/debug/dwarf/attr_string.go +++ b/libgo/go/debug/dwarf/attr_string.go @@ -4,81 +4,257 @@ package dwarf import "strconv" -const _Attr_name = "SiblingLocationNameOrderingByteSizeBitOffsetBitSizeStmtListLowpcHighpcLanguageDiscrDiscrValueVisibilityImportStringLengthCommonRefCompDirConstValueContainingTypeDefaultValueInlineIsOptionalLowerBoundProducerPrototypedReturnAddrStartScopeStrideSizeUpperBoundAbstractOriginAccessibilityAddrClassArtificialBaseTypesCallingCountDataMemberLocDeclColumnDeclFileDeclLineDeclarationDiscrListEncodingExternalFrameBaseFriendIdentifierCaseMacroInfoNamelistItemPrioritySegmentSpecificationStaticLinkTypeUseLocationVarParamVirtualityVtableElemLocAllocatedAssociatedDataLocationStrideEntrypcUseUTF8ExtensionRangesTrampolineCallColumnCallFileCallLineDescription" +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[AttrSibling-1] + _ = x[AttrLocation-2] + _ = x[AttrName-3] + _ = x[AttrOrdering-9] + _ = x[AttrByteSize-11] + _ = x[AttrBitOffset-12] + _ = x[AttrBitSize-13] + _ = x[AttrStmtList-16] + _ = x[AttrLowpc-17] + _ = x[AttrHighpc-18] + _ = x[AttrLanguage-19] + _ = x[AttrDiscr-21] + _ = x[AttrDiscrValue-22] + _ = x[AttrVisibility-23] + _ = x[AttrImport-24] + _ = x[AttrStringLength-25] + _ = x[AttrCommonRef-26] + _ = x[AttrCompDir-27] + _ = x[AttrConstValue-28] + _ = x[AttrContainingType-29] + _ = x[AttrDefaultValue-30] + _ = x[AttrInline-32] + _ = x[AttrIsOptional-33] + _ = x[AttrLowerBound-34] + _ = x[AttrProducer-37] + _ = x[AttrPrototyped-39] + _ = x[AttrReturnAddr-42] + _ = x[AttrStartScope-44] + _ = x[AttrStrideSize-46] + _ = x[AttrUpperBound-47] + _ = x[AttrAbstractOrigin-49] + _ = x[AttrAccessibility-50] + _ = x[AttrAddrClass-51] + _ = x[AttrArtificial-52] + _ = x[AttrBaseTypes-53] + _ = x[AttrCalling-54] + _ = x[AttrCount-55] + _ = x[AttrDataMemberLoc-56] + _ = x[AttrDeclColumn-57] + _ = x[AttrDeclFile-58] + _ = x[AttrDeclLine-59] + _ = x[AttrDeclaration-60] + _ = x[AttrDiscrList-61] + _ = x[AttrEncoding-62] + _ = x[AttrExternal-63] + _ = x[AttrFrameBase-64] + _ = x[AttrFriend-65] + _ = x[AttrIdentifierCase-66] + _ = x[AttrMacroInfo-67] + _ = x[AttrNamelistItem-68] + _ = x[AttrPriority-69] + _ = x[AttrSegment-70] + _ = x[AttrSpecification-71] + _ = x[AttrStaticLink-72] + _ = x[AttrType-73] + _ = x[AttrUseLocation-74] + _ = x[AttrVarParam-75] + _ = x[AttrVirtuality-76] + _ = x[AttrVtableElemLoc-77] + _ = x[AttrAllocated-78] + _ = x[AttrAssociated-79] + _ = x[AttrDataLocation-80] + _ = x[AttrStride-81] + _ = x[AttrEntrypc-82] + _ = x[AttrUseUTF8-83] + _ = x[AttrExtension-84] + _ = x[AttrRanges-85] + _ = x[AttrTrampoline-86] + _ = x[AttrCallColumn-87] + _ = x[AttrCallFile-88] + _ = x[AttrCallLine-89] + _ = x[AttrDescription-90] + _ = x[AttrBinaryScale-91] + _ = x[AttrDecimalScale-92] + _ = x[AttrSmall-93] + _ = x[AttrDecimalSign-94] + _ = x[AttrDigitCount-95] + _ = x[AttrPictureString-96] + _ = x[AttrMutable-97] + _ = x[AttrThreadsScaled-98] + _ = x[AttrExplicit-99] + _ = x[AttrObjectPointer-100] + _ = x[AttrEndianity-101] + _ = x[AttrElemental-102] + _ = x[AttrPure-103] + _ = x[AttrRecursive-104] + _ = x[AttrSignature-105] + _ = x[AttrMainSubprogram-106] + _ = x[AttrDataBitOffset-107] + _ = x[AttrConstExpr-108] + _ = x[AttrEnumClass-109] + _ = x[AttrLinkageName-110] + _ = x[AttrStringLengthBitSize-111] + _ = x[AttrStringLengthByteSize-112] + _ = x[AttrRank-113] + _ = x[AttrStrOffsetsBase-114] + _ = x[AttrAddrBase-115] + _ = x[AttrRnglistsBase-116] + _ = x[AttrDwoName-118] + _ = x[AttrReference-119] + _ = x[AttrRvalueReference-120] + _ = x[AttrMacros-121] + _ = x[AttrCallAllCalls-122] + _ = x[AttrCallAllSourceCalls-123] + _ = x[AttrCallAllTailCalls-124] + _ = x[AttrCallReturnPC-125] + _ = x[AttrCallValue-126] + _ = x[AttrCallOrigin-127] + _ = x[AttrCallParameter-128] + _ = x[AttrCallPC-129] + _ = x[AttrCallTailCall-130] + _ = x[AttrCallTarget-131] + _ = x[AttrCallTargetClobbered-132] + _ = x[AttrCallDataLocation-133] + _ = x[AttrCallDataValue-134] + _ = x[AttrNoreturn-135] + _ = x[AttrAlignment-136] + _ = x[AttrExportSymbols-137] + _ = x[AttrDeleted-138] + _ = x[AttrDefaulted-139] + _ = x[AttrLoclistsBase-140] +} + +const _Attr_name = "SiblingLocationNameOrderingByteSizeBitOffsetBitSizeStmtListLowpcHighpcLanguageDiscrDiscrValueVisibilityImportStringLengthCommonRefCompDirConstValueContainingTypeDefaultValueInlineIsOptionalLowerBoundProducerPrototypedReturnAddrStartScopeStrideSizeUpperBoundAbstractOriginAccessibilityAddrClassArtificialBaseTypesCallingCountDataMemberLocDeclColumnDeclFileDeclLineDeclarationDiscrListEncodingExternalFrameBaseFriendIdentifierCaseMacroInfoNamelistItemPrioritySegmentSpecificationStaticLinkTypeUseLocationVarParamVirtualityVtableElemLocAllocatedAssociatedDataLocationStrideEntrypcUseUTF8ExtensionRangesTrampolineCallColumnCallFileCallLineDescriptionBinaryScaleDecimalScaleSmallDecimalSignDigitCountPictureStringMutableThreadsScaledExplicitObjectPointerEndianityElementalPureRecursiveSignatureMainSubprogramDataBitOffsetConstExprEnumClassLinkageNameStringLengthBitSizeStringLengthByteSizeRankStrOffsetsBaseAddrBaseRnglistsBaseDwoNameReferenceRvalueReferenceMacrosCallAllCallsCallAllSourceCallsCallAllTailCallsCallReturnPCCallValueCallOriginCallParameterCallPCCallTailCallCallTargetCallTargetClobberedCallDataLocationCallDataValueNoreturnAlignmentExportSymbolsDeletedDefaultedLoclistsBase" var _Attr_map = map[Attr]string{ - 1: _Attr_name[0:7], - 2: _Attr_name[7:15], - 3: _Attr_name[15:19], - 9: _Attr_name[19:27], - 11: _Attr_name[27:35], - 12: _Attr_name[35:44], - 13: _Attr_name[44:51], - 16: _Attr_name[51:59], - 17: _Attr_name[59:64], - 18: _Attr_name[64:70], - 19: _Attr_name[70:78], - 21: _Attr_name[78:83], - 22: _Attr_name[83:93], - 23: _Attr_name[93:103], - 24: _Attr_name[103:109], - 25: _Attr_name[109:121], - 26: _Attr_name[121:130], - 27: _Attr_name[130:137], - 28: _Attr_name[137:147], - 29: _Attr_name[147:161], - 30: _Attr_name[161:173], - 32: _Attr_name[173:179], - 33: _Attr_name[179:189], - 34: _Attr_name[189:199], - 37: _Attr_name[199:207], - 39: _Attr_name[207:217], - 42: _Attr_name[217:227], - 44: _Attr_name[227:237], - 46: _Attr_name[237:247], - 47: _Attr_name[247:257], - 49: _Attr_name[257:271], - 50: _Attr_name[271:284], - 51: _Attr_name[284:293], - 52: _Attr_name[293:303], - 53: _Attr_name[303:312], - 54: _Attr_name[312:319], - 55: _Attr_name[319:324], - 56: _Attr_name[324:337], - 57: _Attr_name[337:347], - 58: _Attr_name[347:355], - 59: _Attr_name[355:363], - 60: _Attr_name[363:374], - 61: _Attr_name[374:383], - 62: _Attr_name[383:391], - 63: _Attr_name[391:399], - 64: _Attr_name[399:408], - 65: _Attr_name[408:414], - 66: _Attr_name[414:428], - 67: _Attr_name[428:437], - 68: _Attr_name[437:449], - 69: _Attr_name[449:457], - 70: _Attr_name[457:464], - 71: _Attr_name[464:477], - 72: _Attr_name[477:487], - 73: _Attr_name[487:491], - 74: _Attr_name[491:502], - 75: _Attr_name[502:510], - 76: _Attr_name[510:520], - 77: _Attr_name[520:533], - 78: _Attr_name[533:542], - 79: _Attr_name[542:552], - 80: _Attr_name[552:564], - 81: _Attr_name[564:570], - 82: _Attr_name[570:577], - 83: _Attr_name[577:584], - 84: _Attr_name[584:593], - 85: _Attr_name[593:599], - 86: _Attr_name[599:609], - 87: _Attr_name[609:619], - 88: _Attr_name[619:627], - 89: _Attr_name[627:635], - 90: _Attr_name[635:646], + 1: _Attr_name[0:7], + 2: _Attr_name[7:15], + 3: _Attr_name[15:19], + 9: _Attr_name[19:27], + 11: _Attr_name[27:35], + 12: _Attr_name[35:44], + 13: _Attr_name[44:51], + 16: _Attr_name[51:59], + 17: _Attr_name[59:64], + 18: _Attr_name[64:70], + 19: _Attr_name[70:78], + 21: _Attr_name[78:83], + 22: _Attr_name[83:93], + 23: _Attr_name[93:103], + 24: _Attr_name[103:109], + 25: _Attr_name[109:121], + 26: _Attr_name[121:130], + 27: _Attr_name[130:137], + 28: _Attr_name[137:147], + 29: _Attr_name[147:161], + 30: _Attr_name[161:173], + 32: _Attr_name[173:179], + 33: _Attr_name[179:189], + 34: _Attr_name[189:199], + 37: _Attr_name[199:207], + 39: _Attr_name[207:217], + 42: _Attr_name[217:227], + 44: _Attr_name[227:237], + 46: _Attr_name[237:247], + 47: _Attr_name[247:257], + 49: _Attr_name[257:271], + 50: _Attr_name[271:284], + 51: _Attr_name[284:293], + 52: _Attr_name[293:303], + 53: _Attr_name[303:312], + 54: _Attr_name[312:319], + 55: _Attr_name[319:324], + 56: _Attr_name[324:337], + 57: _Attr_name[337:347], + 58: _Attr_name[347:355], + 59: _Attr_name[355:363], + 60: _Attr_name[363:374], + 61: _Attr_name[374:383], + 62: _Attr_name[383:391], + 63: _Attr_name[391:399], + 64: _Attr_name[399:408], + 65: _Attr_name[408:414], + 66: _Attr_name[414:428], + 67: _Attr_name[428:437], + 68: _Attr_name[437:449], + 69: _Attr_name[449:457], + 70: _Attr_name[457:464], + 71: _Attr_name[464:477], + 72: _Attr_name[477:487], + 73: _Attr_name[487:491], + 74: _Attr_name[491:502], + 75: _Attr_name[502:510], + 76: _Attr_name[510:520], + 77: _Attr_name[520:533], + 78: _Attr_name[533:542], + 79: _Attr_name[542:552], + 80: _Attr_name[552:564], + 81: _Attr_name[564:570], + 82: _Attr_name[570:577], + 83: _Attr_name[577:584], + 84: _Attr_name[584:593], + 85: _Attr_name[593:599], + 86: _Attr_name[599:609], + 87: _Attr_name[609:619], + 88: _Attr_name[619:627], + 89: _Attr_name[627:635], + 90: _Attr_name[635:646], + 91: _Attr_name[646:657], + 92: _Attr_name[657:669], + 93: _Attr_name[669:674], + 94: _Attr_name[674:685], + 95: _Attr_name[685:695], + 96: _Attr_name[695:708], + 97: _Attr_name[708:715], + 98: _Attr_name[715:728], + 99: _Attr_name[728:736], + 100: _Attr_name[736:749], + 101: _Attr_name[749:758], + 102: _Attr_name[758:767], + 103: _Attr_name[767:771], + 104: _Attr_name[771:780], + 105: _Attr_name[780:789], + 106: _Attr_name[789:803], + 107: _Attr_name[803:816], + 108: _Attr_name[816:825], + 109: _Attr_name[825:834], + 110: _Attr_name[834:845], + 111: _Attr_name[845:864], + 112: _Attr_name[864:884], + 113: _Attr_name[884:888], + 114: _Attr_name[888:902], + 115: _Attr_name[902:910], + 116: _Attr_name[910:922], + 118: _Attr_name[922:929], + 119: _Attr_name[929:938], + 120: _Attr_name[938:953], + 121: _Attr_name[953:959], + 122: _Attr_name[959:971], + 123: _Attr_name[971:989], + 124: _Attr_name[989:1005], + 125: _Attr_name[1005:1017], + 126: _Attr_name[1017:1026], + 127: _Attr_name[1026:1036], + 128: _Attr_name[1036:1049], + 129: _Attr_name[1049:1055], + 130: _Attr_name[1055:1067], + 131: _Attr_name[1067:1077], + 132: _Attr_name[1077:1096], + 133: _Attr_name[1096:1112], + 134: _Attr_name[1112:1125], + 135: _Attr_name[1125:1133], + 136: _Attr_name[1133:1142], + 137: _Attr_name[1142:1155], + 138: _Attr_name[1155:1162], + 139: _Attr_name[1162:1171], + 140: _Attr_name[1171:1183], } func (i Attr) String() string { diff --git a/libgo/go/debug/dwarf/buf.go b/libgo/go/debug/dwarf/buf.go index 24d266db107..c3822a0dac7 100644 --- a/libgo/go/debug/dwarf/buf.go +++ b/libgo/go/debug/dwarf/buf.go @@ -7,6 +7,7 @@ package dwarf import ( + "bytes" "encoding/binary" "strconv" ) @@ -79,16 +80,16 @@ func (b *buf) bytes(n int) []byte { func (b *buf) skip(n int) { b.bytes(n) } func (b *buf) string() string { - for i := 0; i < len(b.data); i++ { - if b.data[i] == 0 { - s := string(b.data[0:i]) - b.data = b.data[i+1:] - b.off += Offset(i + 1) - return s - } + i := bytes.IndexByte(b.data, 0) + if i < 0 { + b.error("underflow") + return "" } - b.error("underflow") - return "" + + s := string(b.data[0:i]) + b.data = b.data[i+1:] + b.off += Offset(i + 1) + return s } func (b *buf) uint16() uint16 { @@ -99,6 +100,18 @@ func (b *buf) uint16() uint16 { return b.order.Uint16(a) } +func (b *buf) uint24() uint32 { + a := b.bytes(3) + if a == nil { + return 0 + } + if b.dwarf.bigEndian { + return uint32(a[2]) | uint32(a[1])<<8 | uint32(a[0])<<16 + } else { + return uint32(a[0]) | uint32(a[1])<<8 | uint32(a[2])<<16 + } +} + func (b *buf) uint32() uint32 { a := b.bytes(4) if a == nil { diff --git a/libgo/go/debug/dwarf/class_string.go b/libgo/go/debug/dwarf/class_string.go index a6aabff524f..76de7cad311 100644 --- a/libgo/go/debug/dwarf/class_string.go +++ b/libgo/go/debug/dwarf/class_string.go @@ -4,6 +4,27 @@ package dwarf import "strconv" +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[ClassUnknown-0] + _ = x[ClassAddress-1] + _ = x[ClassBlock-2] + _ = x[ClassConstant-3] + _ = x[ClassExprLoc-4] + _ = x[ClassFlag-5] + _ = x[ClassLinePtr-6] + _ = x[ClassLocListPtr-7] + _ = x[ClassMacPtr-8] + _ = x[ClassRangeListPtr-9] + _ = x[ClassReference-10] + _ = x[ClassReferenceSig-11] + _ = x[ClassString-12] + _ = x[ClassReferenceAlt-13] + _ = x[ClassStringAlt-14] +} + const _Class_name = "ClassUnknownClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAlt" var _Class_index = [...]uint8{0, 12, 24, 34, 47, 59, 68, 80, 95, 106, 123, 137, 154, 165, 182, 196} diff --git a/libgo/go/debug/dwarf/const.go b/libgo/go/debug/dwarf/const.go index 4dda83e6928..b11bf90c37a 100644 --- a/libgo/go/debug/dwarf/const.go +++ b/libgo/go/debug/dwarf/const.go @@ -71,19 +71,71 @@ const ( AttrVarParam Attr = 0x4B AttrVirtuality Attr = 0x4C AttrVtableElemLoc Attr = 0x4D - AttrAllocated Attr = 0x4E - AttrAssociated Attr = 0x4F - AttrDataLocation Attr = 0x50 - AttrStride Attr = 0x51 - AttrEntrypc Attr = 0x52 - AttrUseUTF8 Attr = 0x53 - AttrExtension Attr = 0x54 - AttrRanges Attr = 0x55 - AttrTrampoline Attr = 0x56 - AttrCallColumn Attr = 0x57 - AttrCallFile Attr = 0x58 - AttrCallLine Attr = 0x59 - AttrDescription Attr = 0x5A + // The following are new in DWARF 3. + AttrAllocated Attr = 0x4E + AttrAssociated Attr = 0x4F + AttrDataLocation Attr = 0x50 + AttrStride Attr = 0x51 + AttrEntrypc Attr = 0x52 + AttrUseUTF8 Attr = 0x53 + AttrExtension Attr = 0x54 + AttrRanges Attr = 0x55 + AttrTrampoline Attr = 0x56 + AttrCallColumn Attr = 0x57 + AttrCallFile Attr = 0x58 + AttrCallLine Attr = 0x59 + AttrDescription Attr = 0x5A + AttrBinaryScale Attr = 0x5B + AttrDecimalScale Attr = 0x5C + AttrSmall Attr = 0x5D + AttrDecimalSign Attr = 0x5E + AttrDigitCount Attr = 0x5F + AttrPictureString Attr = 0x60 + AttrMutable Attr = 0x61 + AttrThreadsScaled Attr = 0x62 + AttrExplicit Attr = 0x63 + AttrObjectPointer Attr = 0x64 + AttrEndianity Attr = 0x65 + AttrElemental Attr = 0x66 + AttrPure Attr = 0x67 + AttrRecursive Attr = 0x68 + // The following are new in DWARF 4. + AttrSignature Attr = 0x69 + AttrMainSubprogram Attr = 0x6A + AttrDataBitOffset Attr = 0x6B + AttrConstExpr Attr = 0x6C + AttrEnumClass Attr = 0x6D + AttrLinkageName Attr = 0x6E + // The following are new in DWARF 5. + AttrStringLengthBitSize Attr = 0x6F + AttrStringLengthByteSize Attr = 0x70 + AttrRank Attr = 0x71 + AttrStrOffsetsBase Attr = 0x72 + AttrAddrBase Attr = 0x73 + AttrRnglistsBase Attr = 0x74 + AttrDwoName Attr = 0x76 + AttrReference Attr = 0x77 + AttrRvalueReference Attr = 0x78 + AttrMacros Attr = 0x79 + AttrCallAllCalls Attr = 0x7A + AttrCallAllSourceCalls Attr = 0x7B + AttrCallAllTailCalls Attr = 0x7C + AttrCallReturnPC Attr = 0x7D + AttrCallValue Attr = 0x7E + AttrCallOrigin Attr = 0x7F + AttrCallParameter Attr = 0x80 + AttrCallPC Attr = 0x81 + AttrCallTailCall Attr = 0x82 + AttrCallTarget Attr = 0x83 + AttrCallTargetClobbered Attr = 0x84 + AttrCallDataLocation Attr = 0x85 + AttrCallDataValue Attr = 0x86 + AttrNoreturn Attr = 0x87 + AttrAlignment Attr = 0x88 + AttrExportSymbols Attr = 0x89 + AttrDeleted Attr = 0x8A + AttrDefaulted Attr = 0x8B + AttrLoclistsBase Attr = 0x8C ) func (a Attr) GoString() string { @@ -124,6 +176,25 @@ const ( formExprloc format = 0x18 formFlagPresent format = 0x19 formRefSig8 format = 0x20 + // The following are new in DWARF 5. + formStrx format = 0x1A + formAddrx format = 0x1B + formRefSup4 format = 0x1C + formStrpSup format = 0x1D + formData16 format = 0x1E + formLineStrp format = 0x1F + formImplicitConst format = 0x21 + formLoclistx format = 0x22 + formRnglistx format = 0x23 + formRefSup8 format = 0x24 + formStrx1 format = 0x25 + formStrx2 format = 0x26 + formStrx3 format = 0x27 + formStrx4 format = 0x28 + formAddrx1 format = 0x29 + formAddrx2 format = 0x2A + formAddrx3 format = 0x2B + formAddrx4 format = 0x2C // Extensions for multi-file compression (.dwz) // http://www.dwarfstd.org/ShowIssue.php?issue=120604.1 formGnuRefAlt format = 0x1f20 @@ -199,6 +270,15 @@ const ( TagTypeUnit Tag = 0x41 TagRvalueReferenceType Tag = 0x42 TagTemplateAlias Tag = 0x43 + // The following are new in DWARF 5. + TagCoarrayType Tag = 0x44 + TagGenericSubrange Tag = 0x45 + TagDynamicType Tag = 0x46 + TagAtomicType Tag = 0x47 + TagCallSite Tag = 0x48 + TagCallSiteParameter Tag = 0x49 + TagSkeletonUnit Tag = 0x4A + TagImmutableType Tag = 0x4B ) func (t Tag) GoString() string { @@ -269,25 +349,54 @@ const ( opDerefSize = 0x94 /* 1-byte size of data retrieved */ opXderefSize = 0x95 /* 1-byte size of data retrieved */ opNop = 0x96 - /* next four new in Dwarf v3 */ - opPushObjAddr = 0x97 - opCall2 = 0x98 /* 2-byte offset of DIE */ - opCall4 = 0x99 /* 4-byte offset of DIE */ - opCallRef = 0x9A /* 4- or 8- byte offset of DIE */ + // The following are new in DWARF 3. + opPushObjAddr = 0x97 + opCall2 = 0x98 /* 2-byte offset of DIE */ + opCall4 = 0x99 /* 4-byte offset of DIE */ + opCallRef = 0x9A /* 4- or 8- byte offset of DIE */ + opFormTLSAddress = 0x9B + opCallFrameCFA = 0x9C + opBitPiece = 0x9D + // The following are new in DWARF 4. + opImplicitValue = 0x9E + opStackValue = 0x9F + // The following a new in DWARF 5. + opImplicitPointer = 0xA0 + opAddrx = 0xA1 + opConstx = 0xA2 + opEntryValue = 0xA3 + opConstType = 0xA4 + opRegvalType = 0xA5 + opDerefType = 0xA6 + opXderefType = 0xA7 + opConvert = 0xA8 + opReinterpret = 0xA9 /* 0xE0-0xFF reserved for user-specific */ ) // Basic type encodings -- the value for AttrEncoding in a TagBaseType Entry. const ( - encAddress = 0x01 - encBoolean = 0x02 - encComplexFloat = 0x03 - encFloat = 0x04 - encSigned = 0x05 - encSignedChar = 0x06 - encUnsigned = 0x07 - encUnsignedChar = 0x08 + encAddress = 0x01 + encBoolean = 0x02 + encComplexFloat = 0x03 + encFloat = 0x04 + encSigned = 0x05 + encSignedChar = 0x06 + encUnsigned = 0x07 + encUnsignedChar = 0x08 + // The following are new in DWARF 3. encImaginaryFloat = 0x09 + encPackedDecimal = 0x0A + encNumericString = 0x0B + encEdited = 0x0C + encSignedFixed = 0x0D + encUnsignedFixed = 0x0E + encDecimalFloat = 0x0F + // The following are new in DWARF 4. + encUTF = 0x10 + // The following are new in DWARF 5. + encUCS = 0x11 + encASCII = 0x12 ) // Statement program standard opcode encodings. @@ -317,3 +426,38 @@ const ( // DWARF 4 lneSetDiscriminator = 4 ) + +// Line table directory directory and file name entry formats. +// These are new in DWARF 5. +const ( + lnctPath = 0x01 + lnctDirectoryIndex = 0x02 + lnctTimestamp = 0x03 + lnctSize = 0x04 + lnctMD5 = 0x05 +) + +// Location list entry codes. +// These are new in DWARF 5. +const ( + lleEndOfList = 0x00 + lleBaseAddressx = 0x01 + lleStartxEndx = 0x02 + lleStartxLength = 0x03 + lleOffsetPair = 0x04 + lleDefaultLocation = 0x05 + lleBaseAddress = 0x06 + lleStartEnd = 0x07 + lleStartLength = 0x08 +) + +// Unit header unit type encodings. +// These are new in DWARF 5. +const ( + utCompile = 0x01 + utType = 0x02 + utPartial = 0x03 + utSkeleton = 0x04 + utSplitCompile = 0x05 + utSplitType = 0x06 +) diff --git a/libgo/go/debug/dwarf/entry.go b/libgo/go/debug/dwarf/entry.go index 6be0700b7ef..01f2190db7c 100644 --- a/libgo/go/debug/dwarf/entry.go +++ b/libgo/go/debug/dwarf/entry.go @@ -11,6 +11,7 @@ package dwarf import ( + "encoding/binary" "errors" "strconv" ) @@ -26,6 +27,7 @@ type afield struct { attr Attr fmt format class Class + val int64 // for formImplicitConst } // a map from entry format ids to their descriptions @@ -67,6 +69,9 @@ func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) { if tag == 0 && fmt == 0 { break } + if format(fmt) == formImplicitConst { + b1.int() + } n++ } if b1.err != nil { @@ -82,6 +87,9 @@ func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) { a.field[i].attr = Attr(b.uint()) a.field[i].fmt = format(b.uint()) a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b) + if a.field[i].fmt == formImplicitConst { + a.field[i].val = b.int() + } } b.uint() b.uint() @@ -137,6 +145,11 @@ var attrPtrClass = map[Attr]Class{ AttrUseLocation: ClassLocListPtr, AttrVtableElemLoc: ClassLocListPtr, AttrRanges: ClassRangeListPtr, + // The following are new in DWARF 5. + AttrStrOffsetsBase: ClassStrOffsetsPtr, + AttrAddrBase: ClassAddrPtr, + AttrRnglistsBase: ClassRngListsPtr, + AttrLoclistsBase: ClassLocListPtr, } // formToClass returns the DWARF 4 Class for the given form. If the @@ -148,7 +161,10 @@ func formToClass(form format, attr Attr, vers int, b *buf) Class { b.error("cannot determine class of unknown attribute form") return 0 - case formAddr: + case formIndirect: + return ClassUnknown + + case formAddr, formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4: return ClassAddress case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock: @@ -163,7 +179,7 @@ func formToClass(form format, attr Attr, vers int, b *buf) Class { } return ClassBlock - case formData1, formData2, formData4, formData8, formSdata, formUdata: + case formData1, formData2, formData4, formData8, formSdata, formUdata, formData16, formImplicitConst: // In DWARF 2 and 3, ClassPtr was encoded as a // constant. Unlike ClassExprLoc/ClassBlock, some // DWARF 4 attributes need to distinguish Class*Ptr @@ -177,13 +193,13 @@ func formToClass(form format, attr Attr, vers int, b *buf) Class { case formFlag, formFlagPresent: return ClassFlag - case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata: + case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata, formRefSup4, formRefSup8: return ClassReference case formRefSig8: return ClassReferenceSig - case formString, formStrp: + case formString, formStrp, formStrx, formStrpSup, formLineStrp, formStrx1, formStrx2, formStrx3, formStrx4: return ClassString case formSecOffset: @@ -203,6 +219,12 @@ func formToClass(form format, attr Attr, vers int, b *buf) Class { case formGnuStrpAlt: return ClassStringAlt + + case formLoclistx: + return ClassLocList + + case formRnglistx: + return ClassRngList } } @@ -324,6 +346,27 @@ const ( // offset into the DWARF string section of an alternate object // file. ClassStringAlt + + // ClassAddrPtr represents values that are an int64 offset + // into the "addr" section. + ClassAddrPtr + + // ClassLocList represents values that are an int64 offset + // into the "loclists" section. + ClassLocList + + // ClassRngList represents values that are an int64 offset + // from the base of the "rnglists" section. + ClassRngList + + // ClassRngListsPtr represents values that are an int64 offset + // into the "rnglists" section. These are used as the base for + // ClassRngList values. + ClassRngListsPtr + + // ClassStrOffsetsPtr represents values that are an int64 + // offset into the "str_offsets" section. + ClassStrOffsetsPtr ) //go:generate stringer -type=Class @@ -363,7 +406,7 @@ type Offset uint32 // Entry reads a single entry from buf, decoding // according to the given abbreviation table. -func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { +func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry { off := b.off id := uint32(b.uint()) if id == 0 { @@ -386,6 +429,7 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { fmt := a.field[i].fmt if fmt == formIndirect { fmt = format(b.uint()) + e.Field[i].Class = formToClass(fmt, a.field[i].attr, vers, b) } var val interface{} switch fmt { @@ -395,6 +439,54 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { // address case formAddr: val = b.addr() + case formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4: + var off uint64 + switch fmt { + case formAddrx: + off = b.uint() + case formAddrx1: + off = uint64(b.uint8()) + case formAddrx2: + off = uint64(b.uint16()) + case formAddrx3: + off = uint64(b.uint24()) + case formAddrx4: + off = uint64(b.uint32()) + } + if len(b.dwarf.addr) == 0 { + b.error("DW_FORM_addrx with no .debug_addr section") + } + if b.err != nil { + return nil + } + addrsize := b.format.addrsize() + if addrsize == 0 { + b.error("unknown address size for DW_FORM_addrx") + } + off *= uint64(addrsize) + + // We have to adjust by the offset of the + // compilation unit. This won't work if the + // program uses Reader.Seek to skip over the + // unit. Not much we can do about that. + if cu != nil { + cuOff, ok := cu.Val(AttrAddrBase).(int64) + if ok { + off += uint64(cuOff) + } + } + + if uint64(int(off)) != off { + b.error("DW_FORM_addrx offset out of range") + } + + b1 := makeBuf(b.dwarf, b.format, "addr", 0, b.dwarf.addr) + b1.skip(int(off)) + val = b1.addr() + if b1.err != nil { + b.err = b1.err + return nil + } // block case formDwarfBlock1: @@ -415,10 +507,14 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { val = int64(b.uint32()) case formData8: val = int64(b.uint64()) + case formData16: + val = b.bytes(16) case formSdata: val = int64(b.int()) case formUdata: val = int64(b.uint()) + case formImplicitConst: + val = a.field[i].val // flag case formFlag: @@ -460,29 +556,112 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { // string case formString: val = b.string() - case formStrp: + case formStrp, formLineStrp: var off uint64 // offset into .debug_str is64, known := b.format.dwarf64() if !known { - b.error("unknown size for DW_FORM_strp") + b.error("unknown size for DW_FORM_strp/line_strp") } else if is64 { off = b.uint64() } else { off = uint64(b.uint32()) } if uint64(int(off)) != off { - b.error("DW_FORM_strp offset out of range") + b.error("DW_FORM_strp/line_strp offset out of range") } if b.err != nil { return nil } - b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str) + var b1 buf + if fmt == formStrp { + b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str) + } else { + if len(b.dwarf.lineStr) == 0 { + b.error("DW_FORM_line_strp with no .debug_line_str section") + } + b1 = makeBuf(b.dwarf, b.format, "line_str", 0, b.dwarf.lineStr) + } b1.skip(int(off)) val = b1.string() if b1.err != nil { b.err = b1.err return nil } + case formStrx, formStrx1, formStrx2, formStrx3, formStrx4: + var off uint64 + switch fmt { + case formStrx: + off = b.uint() + case formStrx1: + off = uint64(b.uint8()) + case formStrx2: + off = uint64(b.uint16()) + case formStrx3: + off = uint64(b.uint24()) + case formStrx4: + off = uint64(b.uint32()) + } + if len(b.dwarf.strOffsets) == 0 { + b.error("DW_FORM_strx with no .debug_str_offsets section") + } + is64, known := b.format.dwarf64() + if !known { + b.error("unknown offset size for DW_FORM_strx") + } + if b.err != nil { + return nil + } + if is64 { + off *= 8 + } else { + off *= 4 + } + + // We have to adjust by the offset of the + // compilation unit. This won't work if the + // program uses Reader.Seek to skip over the + // unit. Not much we can do about that. + if cu != nil { + cuOff, ok := cu.Val(AttrStrOffsetsBase).(int64) + if ok { + off += uint64(cuOff) + } + } + + if uint64(int(off)) != off { + b.error("DW_FORM_strx offset out of range") + } + + b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets) + b1.skip(int(off)) + if is64 { + off = b1.uint64() + } else { + off = uint64(b1.uint32()) + } + if b1.err != nil { + b.err = b1.err + return nil + } + if uint64(int(off)) != off { + b.error("DW_FORM_strx indirect offset out of range") + } + b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str) + b1.skip(int(off)) + val = b1.string() + if b1.err != nil { + b.err = b1.err + return nil + } + case formStrpSup: + is64, known := b.format.dwarf64() + if !known { + b.error("unknown size for DW_FORM_strp_sup") + } else if is64 { + val = b.uint64() + } else { + val = b.uint32() + } // lineptr, loclistptr, macptr, rangelistptr // New in DWARF 4, but clang can generate them with -gdwarf-2. @@ -507,6 +686,18 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { case formRefSig8: // 64-bit type signature. val = b.uint64() + case formRefSup4: + val = b.uint32() + case formRefSup8: + val = b.uint64() + + // loclist + case formLoclistx: + val = b.uint() + + // rnglist + case formRnglistx: + val = b.uint() } e.Field[i].Val = val } @@ -528,6 +719,7 @@ type Reader struct { unit int lastChildren bool // .Children of last entry returned by Next lastSibling Offset // .Val(AttrSibling) of last entry returned by Next + cu *Entry // current compilation unit } // Reader returns a new Reader for Data. @@ -544,6 +736,11 @@ func (r *Reader) AddressSize() int { return r.d.unit[r.unit].asize } +// ByteOrder returns the byte order in the current compilation unit. +func (r *Reader) ByteOrder() binary.ByteOrder { + return r.b.order +} + // Seek positions the Reader at offset off in the encoded entry stream. // Offset 0 can be used to denote the first entry. func (r *Reader) Seek(off Offset) { @@ -557,6 +754,7 @@ func (r *Reader) Seek(off Offset) { u := &d.unit[0] r.unit = 0 r.b = makeBuf(r.d, u, "info", u.off, u.data) + r.cu = nil return } @@ -565,6 +763,9 @@ func (r *Reader) Seek(off Offset) { r.err = errors.New("offset out of range") return } + if i != r.unit { + r.cu = nil + } u := &d.unit[i] r.unit = i r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:]) @@ -576,6 +777,7 @@ func (r *Reader) maybeNextUnit() { r.unit++ u := &r.d.unit[r.unit] r.b = makeBuf(r.d, u, "info", u.off, u.data) + r.cu = nil } } @@ -592,7 +794,7 @@ func (r *Reader) Next() (*Entry, error) { return nil, nil } u := &r.d.unit[r.unit] - e := r.b.entry(u.atable, u.base) + e := r.b.entry(r.cu, u.atable, u.base, u.vers) if r.b.err != nil { r.err = r.b.err return nil, r.err @@ -602,6 +804,9 @@ func (r *Reader) Next() (*Entry, error) { if r.lastChildren { r.lastSibling, _ = e.Val(AttrSibling).(Offset) } + if e.Tag == TagCompileUnit || e.Tag == TagPartialUnit { + r.cu = e + } } else { r.lastChildren = false } @@ -734,7 +939,7 @@ func (d *Data) Ranges(e *Entry) ([][2]uint64, error) { } u := &d.unit[i] b := makeBuf(d, u, "info", u.off, u.data) - cu = b.entry(u.atable, u.base) + cu = b.entry(nil, u.atable, u.base, u.vers) if b.err != nil { return nil, b.err } diff --git a/libgo/go/debug/dwarf/entry_test.go b/libgo/go/debug/dwarf/entry_test.go index 58f3023d296..4c9aad21f31 100644 --- a/libgo/go/debug/dwarf/entry_test.go +++ b/libgo/go/debug/dwarf/entry_test.go @@ -6,6 +6,7 @@ package dwarf_test import ( . "debug/dwarf" + "encoding/binary" "reflect" "testing" ) @@ -141,8 +142,10 @@ func Test64Bit(t *testing.T) { // compilation unit except by using XCOFF, so this is // hand-written. tests := []struct { - name string - info []byte + name string + info []byte + addrSize int + byteOrder binary.ByteOrder }{ { "32-bit little", @@ -157,6 +160,7 @@ func Test64Bit(t *testing.T) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + 8, binary.LittleEndian, }, { "64-bit little", @@ -171,6 +175,7 @@ func Test64Bit(t *testing.T) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + 8, binary.LittleEndian, }, { "64-bit big", @@ -185,13 +190,22 @@ func Test64Bit(t *testing.T) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + 8, binary.BigEndian, }, } for _, test := range tests { - _, err := New(nil, nil, nil, test.info, nil, nil, nil, nil) + data, err := New(nil, nil, nil, test.info, nil, nil, nil, nil) if err != nil { t.Errorf("%s: %v", test.name, err) } + + r := data.Reader() + if r.AddressSize() != test.addrSize { + t.Errorf("%s: got address size %d, want %d", test.name, r.AddressSize(), test.addrSize) + } + if r.ByteOrder() != test.byteOrder { + t.Errorf("%s: got byte order %s, want %s", test.name, r.ByteOrder(), test.byteOrder) + } } } diff --git a/libgo/go/debug/dwarf/line.go b/libgo/go/debug/dwarf/line.go index b862b49d627..7692f055521 100644 --- a/libgo/go/debug/dwarf/line.go +++ b/libgo/go/debug/dwarf/line.go @@ -23,8 +23,13 @@ type LineReader struct { // Original .debug_line section data. Used by Seek. section []byte + str []byte // .debug_str + lineStr []byte // .debug_line_str + // Header information version uint16 + addrsize int + segmentSelectorSize int minInstructionLength int maxOpsPerInstruction int defaultIsStmt bool @@ -158,10 +163,15 @@ func (d *Data) LineReader(cu *Entry) (*LineReader, error) { u := &d.unit[d.offsetToUnit(cu.Offset)] buf := makeBuf(d, u, "line", Offset(off), d.line[off:]) // The compilation directory is implicitly directories[0]. - r := LineReader{buf: buf, section: d.line, directories: []string{compDir}} + r := LineReader{ + buf: buf, + section: d.line, + str: d.str, + lineStr: d.lineStr, + } // Read the header. - if err := r.readHeader(); err != nil { + if err := r.readHeader(compDir); err != nil { return nil, err } @@ -173,7 +183,7 @@ func (d *Data) LineReader(cu *Entry) (*LineReader, error) { // readHeader reads the line number program header from r.buf and sets // all of the header fields in r. -func (r *LineReader) readHeader() error { +func (r *LineReader) readHeader(compDir string) error { buf := &r.buf // Read basic header fields [DWARF2 6.2.4]. @@ -184,7 +194,7 @@ func (r *LineReader) readHeader() error { return DecodeError{"line", hdrOffset, fmt.Sprintf("line table end %d exceeds section size %d", r.endOffset, buf.off+Offset(len(buf.data)))} } r.version = buf.uint16() - if buf.err == nil && (r.version < 2 || r.version > 4) { + if buf.err == nil && (r.version < 2 || r.version > 5) { // DWARF goes to all this effort to make new opcodes // backward-compatible, and then adds fields right in // the middle of the header in new versions, so we're @@ -192,6 +202,13 @@ func (r *LineReader) readHeader() error { // versions. return DecodeError{"line", hdrOffset, fmt.Sprintf("unknown line table version %d", r.version)} } + if r.version >= 5 { + r.addrsize = int(buf.uint8()) + r.segmentSelectorSize = int(buf.uint8()) + } else { + r.addrsize = buf.format.addrsize() + r.segmentSelectorSize = 0 + } var headerLength Offset if dwarf64 { headerLength = Offset(buf.uint64()) @@ -238,39 +255,170 @@ func (r *LineReader) readHeader() error { } } - // Read include directories table. The caller already set - // directories[0] to the compilation directory. - for { - directory := buf.string() - if buf.err != nil { - return buf.err + if r.version < 5 { + // Read include directories table. + r.directories = []string{compDir} + for { + directory := buf.string() + if buf.err != nil { + return buf.err + } + if len(directory) == 0 { + break + } + if !pathIsAbs(directory) { + // Relative paths are implicitly relative to + // the compilation directory. + directory = pathJoin(compDir, directory) + } + r.directories = append(r.directories, directory) + } + + // Read file name list. File numbering starts with 1, + // so leave the first entry nil. + r.fileEntries = make([]*LineFile, 1) + for { + if done, err := r.readFileEntry(); err != nil { + return err + } else if done { + break + } } - if len(directory) == 0 { - break + } else { + dirFormat := r.readLNCTFormat() + c := buf.uint() + r.directories = make([]string, c) + for i := range r.directories { + dir, _, _, err := r.readLNCT(dirFormat, dwarf64) + if err != nil { + return err + } + r.directories[i] = dir } - if !pathIsAbs(directory) { - // Relative paths are implicitly relative to - // the compilation directory. - directory = pathJoin(r.directories[0], directory) + fileFormat := r.readLNCTFormat() + c = buf.uint() + r.fileEntries = make([]*LineFile, c) + for i := range r.fileEntries { + name, mtime, size, err := r.readLNCT(fileFormat, dwarf64) + if err != nil { + return err + } + r.fileEntries[i] = &LineFile{name, mtime, int(size)} } - r.directories = append(r.directories, directory) } - // Read file name list. File numbering starts with 1, so leave - // the first entry nil. - r.fileEntries = make([]*LineFile, 1) - for { - if done, err := r.readFileEntry(); err != nil { - return err - } else if done { - break - } - } r.initialFileEntries = len(r.fileEntries) return buf.err } +// lnctForm is a pair of an LNCT code and a form. This represents an +// entry in the directory name or file name description in the DWARF 5 +// line number program header. +type lnctForm struct { + lnct int + form format +} + +// readLNCTFormat reads an LNCT format description. +func (r *LineReader) readLNCTFormat() []lnctForm { + c := r.buf.uint8() + ret := make([]lnctForm, c) + for i := range ret { + ret[i].lnct = int(r.buf.uint()) + ret[i].form = format(r.buf.uint()) + } + return ret +} + +// readLNCT reads a sequence of LNCT entries and returns path information. +func (r *LineReader) readLNCT(s []lnctForm, dwarf64 bool) (path string, mtime uint64, size uint64, err error) { + var dir string + for _, lf := range s { + var str string + var val uint64 + switch lf.form { + case formString: + str = r.buf.string() + case formStrp, formLineStrp: + var off uint64 + if dwarf64 { + off = r.buf.uint64() + } else { + off = uint64(r.buf.uint32()) + } + if uint64(int(off)) != off { + return "", 0, 0, DecodeError{"line", r.buf.off, "strp/line_strp offset out of range"} + } + var b1 buf + if lf.form == formStrp { + b1 = makeBuf(r.buf.dwarf, r.buf.format, "str", 0, r.str) + } else { + b1 = makeBuf(r.buf.dwarf, r.buf.format, "line_str", 0, r.lineStr) + } + b1.skip(int(off)) + str = b1.string() + if b1.err != nil { + return "", 0, 0, DecodeError{"line", r.buf.off, b1.err.Error()} + } + case formStrpSup: + // Supplemental sections not yet supported. + if dwarf64 { + r.buf.uint64() + } else { + r.buf.uint32() + } + case formStrx: + // .debug_line.dwo sections not yet supported. + r.buf.uint() + case formStrx1: + r.buf.uint8() + case formStrx2: + r.buf.uint16() + case formStrx3: + r.buf.uint24() + case formStrx4: + r.buf.uint32() + case formData1: + val = uint64(r.buf.uint8()) + case formData2: + val = uint64(r.buf.uint16()) + case formData4: + val = uint64(r.buf.uint32()) + case formData8: + val = r.buf.uint64() + case formData16: + r.buf.bytes(16) + case formDwarfBlock: + r.buf.bytes(int(r.buf.uint())) + case formUdata: + val = r.buf.uint() + } + + switch lf.lnct { + case lnctPath: + path = str + case lnctDirectoryIndex: + if val >= uint64(len(r.directories)) { + return "", 0, 0, DecodeError{"line", r.buf.off, "directory index out of range"} + } + dir = r.directories[val] + case lnctTimestamp: + mtime = val + case lnctSize: + size = val + case lnctMD5: + // Ignored. + } + } + + if dir != "" && path != "" { + path = pathJoin(dir, path) + } + + return path, mtime, size, nil +} + // readFileEntry reads a file entry from either the header or a // DW_LNE_define_file extended opcode and adds it to r.fileEntries. A // true return value indicates that there are no more entries to read. @@ -293,6 +441,19 @@ func (r *LineReader) readFileEntry() (bool, error) { mtime := r.buf.uint() length := int(r.buf.uint()) + // If this is a dynamically added path and the cursor was + // backed up, we may have already added this entry. Avoid + // updating existing line table entries in this case. This + // avoids an allocation and potential racy access to the slice + // backing store if the user called Files. + if len(r.fileEntries) < cap(r.fileEntries) { + fe := r.fileEntries[:len(r.fileEntries)+1] + if fe[len(fe)-1] != nil { + // We already processed this addition. + r.fileEntries = fe + return false, nil + } + } r.fileEntries = append(r.fileEntries, &LineFile{name, mtime, length}) return false, nil } @@ -381,7 +542,18 @@ func (r *LineReader) step(entry *LineEntry) bool { r.resetState() case lneSetAddress: - r.state.Address = r.buf.addr() + switch r.addrsize { + case 1: + r.state.Address = uint64(r.buf.uint8()) + case 2: + r.state.Address = uint64(r.buf.uint16()) + case 4: + r.state.Address = uint64(r.buf.uint32()) + case 8: + r.state.Address = r.buf.uint64() + default: + r.buf.error("unknown address size") + } case lneDefineFile: if done, err := r.readFileEntry(); err != nil { @@ -533,6 +705,22 @@ func (r *LineReader) resetState() { r.updateFile() } +// Files returns the file name table of this compilation unit as of +// the current position in the line table. The file name table may be +// referenced from attributes in this compilation unit such as +// AttrDeclFile. +// +// Entry 0 is always nil, since file index 0 represents "no file". +// +// The file name table of a compilation unit is not fixed. Files +// returns the file table as of the current position in the line +// table. This may contain more entries than the file table at an +// earlier position in the line table, though existing entries never +// change. +func (r *LineReader) Files() []*LineFile { + return r.fileEntries +} + // ErrUnknownPC is the error returned by LineReader.ScanPC when the // seek PC is not covered by any entry in the line table. var ErrUnknownPC = errors.New("ErrUnknownPC") @@ -618,7 +806,7 @@ func pathJoin(dirname, filename string) string { // DOS-style path. drive2, filename := splitDrive(filename) if drive2 != "" { - if strings.ToLower(drive) != strings.ToLower(drive2) { + if !strings.EqualFold(drive, drive2) { // Different drives. There's not much we can // do here, so just ignore the directory. return drive2 + filename diff --git a/libgo/go/debug/dwarf/line_test.go b/libgo/go/debug/dwarf/line_test.go index 11a254464a2..1fd9b19b035 100644 --- a/libgo/go/debug/dwarf/line_test.go +++ b/libgo/go/debug/dwarf/line_test.go @@ -43,8 +43,9 @@ func TestLineELFGCC(t *testing.T) { {Address: 0x40060f, File: file2C, Line: 6, IsStmt: true}, {Address: 0x400611, EndSequence: true}, } + files := [][]*LineFile{{nil, file1H, file1C}, {nil, file2C}} - testLineTable(t, want, elfData(t, "testdata/line-gcc.elf")) + testLineTable(t, want, files, elfData(t, "testdata/line-gcc.elf")) } func TestLineGCCWindows(t *testing.T) { @@ -83,8 +84,9 @@ func TestLineGCCWindows(t *testing.T) { {Address: 0x401595, File: file2C, Line: 6, IsStmt: true}, {Address: 0x40159b, EndSequence: true}, } + files := [][]*LineFile{{nil, file1H, file1C}, {nil, file2C}} - testLineTable(t, want, peData(t, "testdata/line-gcc-win.bin")) + testLineTable(t, want, files, peData(t, "testdata/line-gcc-win.bin")) } func TestLineELFClang(t *testing.T) { @@ -110,8 +112,9 @@ func TestLineELFClang(t *testing.T) { {Address: 0x4005a7, File: file2C, Line: 6, IsStmt: true}, {Address: 0x4005b0, EndSequence: true}, } + files := [][]*LineFile{{nil, file1C, file1H}, {nil, file2C}} - testLineTable(t, want, elfData(t, "testdata/line-clang.elf")) + testLineTable(t, want, files, elfData(t, "testdata/line-clang.elf")) } func TestLineSeek(t *testing.T) { @@ -190,7 +193,7 @@ func TestLineSeek(t *testing.T) { } } -func testLineTable(t *testing.T, want []LineEntry, d *Data) { +func testLineTable(t *testing.T, want []LineEntry, files [][]*LineFile, d *Data) { // Get line table from d. var got []LineEntry dr := d.Reader() @@ -207,6 +210,12 @@ func testLineTable(t *testing.T, want []LineEntry, d *Data) { continue } + // Ignore system compilation units (this happens in + // the Windows binary). We'll still decode the line + // table, but won't check it. + name := ent.Val(AttrName).(string) + ignore := strings.HasPrefix(name, "C:/crossdev/") || strings.HasPrefix(name, "../../") + // Decode CU's line table. lr, err := d.LineReader(ent) if err != nil { @@ -225,12 +234,23 @@ func testLineTable(t *testing.T, want []LineEntry, d *Data) { t.Fatal("lr.Next:", err) } // Ignore sources from the Windows build environment. - if strings.HasPrefix(line.File.Name, "C:\\crossdev\\") || - strings.HasPrefix(line.File.Name, "C:/crossdev/") { + if ignore { continue } got = append(got, line) } + + // Check file table. + if !ignore { + if !compareFiles(files[0], lr.Files()) { + t.Log("File tables do not match. Got:") + dumpFiles(t, lr.Files()) + t.Log("Want:") + dumpFiles(t, files[0]) + t.Fail() + } + files = files[1:] + } } // Compare line tables. @@ -243,6 +263,32 @@ func testLineTable(t *testing.T, want []LineEntry, d *Data) { } } +func compareFiles(a, b []*LineFile) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if a[i] == nil && b[i] == nil { + continue + } + if a[i] != nil && b[i] != nil && a[i].Name == b[i].Name { + continue + } + return false + } + return true +} + +func dumpFiles(t *testing.T, files []*LineFile) { + for i, f := range files { + name := "" + if f != nil { + name = f.Name + } + t.Logf(" %d %s", i, name) + } +} + func compareLines(a, b []LineEntry) bool { if len(a) != len(b) { return false diff --git a/libgo/go/debug/dwarf/open.go b/libgo/go/debug/dwarf/open.go index 938186998ff..d6d4f78b27f 100644 --- a/libgo/go/debug/dwarf/open.go +++ b/libgo/go/debug/dwarf/open.go @@ -22,8 +22,14 @@ type Data struct { ranges []byte str []byte + // New sections added in DWARF 5. + addr []byte + lineStr []byte + strOffsets []byte + // parsed data abbrevCache map[uint64]abbrevTable + bigEndian bool order binary.ByteOrder typeCache map[Offset]Type typeSigs map[uint64]*typeUnit @@ -72,8 +78,10 @@ func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Dat case x == 0 && y == 0: return nil, DecodeError{"info", 4, "unsupported version 0"} case x == 0: + d.bigEndian = true d.order = binary.BigEndian case y == 0: + d.bigEndian = false d.order = binary.LittleEndian default: return nil, DecodeError{"info", 4, "cannot determine byte order"} @@ -94,3 +102,20 @@ func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Dat func (d *Data) AddTypes(name string, types []byte) error { return d.parseTypes(name, types) } + +// AddSection adds another DWARF section by name. The name should be a +// DWARF section name such as ".debug_addr", ".debug_str_offsets", and +// so forth. This approach is used for new DWARF sections added in +// DWARF 5 and later. +func (d *Data) AddSection(name string, contents []byte) error { + switch name { + case ".debug_addr": + d.addr = contents + case ".debug_line_str": + d.lineStr = contents + case ".debug_str_offsets": + d.strOffsets = contents + } + // Just ignore names that we don't yet support. + return nil +} diff --git a/libgo/go/debug/dwarf/tag_string.go b/libgo/go/debug/dwarf/tag_string.go index ac396af050f..b79ea175b06 100644 --- a/libgo/go/debug/dwarf/tag_string.go +++ b/libgo/go/debug/dwarf/tag_string.go @@ -4,20 +4,95 @@ package dwarf import "strconv" +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[TagArrayType-1] + _ = x[TagClassType-2] + _ = x[TagEntryPoint-3] + _ = x[TagEnumerationType-4] + _ = x[TagFormalParameter-5] + _ = x[TagImportedDeclaration-8] + _ = x[TagLabel-10] + _ = x[TagLexDwarfBlock-11] + _ = x[TagMember-13] + _ = x[TagPointerType-15] + _ = x[TagReferenceType-16] + _ = x[TagCompileUnit-17] + _ = x[TagStringType-18] + _ = x[TagStructType-19] + _ = x[TagSubroutineType-21] + _ = x[TagTypedef-22] + _ = x[TagUnionType-23] + _ = x[TagUnspecifiedParameters-24] + _ = x[TagVariant-25] + _ = x[TagCommonDwarfBlock-26] + _ = x[TagCommonInclusion-27] + _ = x[TagInheritance-28] + _ = x[TagInlinedSubroutine-29] + _ = x[TagModule-30] + _ = x[TagPtrToMemberType-31] + _ = x[TagSetType-32] + _ = x[TagSubrangeType-33] + _ = x[TagWithStmt-34] + _ = x[TagAccessDeclaration-35] + _ = x[TagBaseType-36] + _ = x[TagCatchDwarfBlock-37] + _ = x[TagConstType-38] + _ = x[TagConstant-39] + _ = x[TagEnumerator-40] + _ = x[TagFileType-41] + _ = x[TagFriend-42] + _ = x[TagNamelist-43] + _ = x[TagNamelistItem-44] + _ = x[TagPackedType-45] + _ = x[TagSubprogram-46] + _ = x[TagTemplateTypeParameter-47] + _ = x[TagTemplateValueParameter-48] + _ = x[TagThrownType-49] + _ = x[TagTryDwarfBlock-50] + _ = x[TagVariantPart-51] + _ = x[TagVariable-52] + _ = x[TagVolatileType-53] + _ = x[TagDwarfProcedure-54] + _ = x[TagRestrictType-55] + _ = x[TagInterfaceType-56] + _ = x[TagNamespace-57] + _ = x[TagImportedModule-58] + _ = x[TagUnspecifiedType-59] + _ = x[TagPartialUnit-60] + _ = x[TagImportedUnit-61] + _ = x[TagMutableType-62] + _ = x[TagCondition-63] + _ = x[TagSharedType-64] + _ = x[TagTypeUnit-65] + _ = x[TagRvalueReferenceType-66] + _ = x[TagTemplateAlias-67] + _ = x[TagCoarrayType-68] + _ = x[TagGenericSubrange-69] + _ = x[TagDynamicType-70] + _ = x[TagAtomicType-71] + _ = x[TagCallSite-72] + _ = x[TagCallSiteParameter-73] + _ = x[TagSkeletonUnit-74] + _ = x[TagImmutableType-75] +} + const ( _Tag_name_0 = "ArrayTypeClassTypeEntryPointEnumerationTypeFormalParameter" _Tag_name_1 = "ImportedDeclaration" _Tag_name_2 = "LabelLexDwarfBlock" _Tag_name_3 = "Member" _Tag_name_4 = "PointerTypeReferenceTypeCompileUnitStringTypeStructType" - _Tag_name_5 = "SubroutineTypeTypedefUnionTypeUnspecifiedParametersVariantCommonDwarfBlockCommonInclusionInheritanceInlinedSubroutineModulePtrToMemberTypeSetTypeSubrangeTypeWithStmtAccessDeclarationBaseTypeCatchDwarfBlockConstTypeConstantEnumeratorFileTypeFriendNamelistNamelistItemPackedTypeSubprogramTemplateTypeParameterTemplateValueParameterThrownTypeTryDwarfBlockVariantPartVariableVolatileTypeDwarfProcedureRestrictTypeInterfaceTypeNamespaceImportedModuleUnspecifiedTypePartialUnitImportedUnitMutableTypeConditionSharedTypeTypeUnitRvalueReferenceTypeTemplateAlias" + _Tag_name_5 = "SubroutineTypeTypedefUnionTypeUnspecifiedParametersVariantCommonDwarfBlockCommonInclusionInheritanceInlinedSubroutineModulePtrToMemberTypeSetTypeSubrangeTypeWithStmtAccessDeclarationBaseTypeCatchDwarfBlockConstTypeConstantEnumeratorFileTypeFriendNamelistNamelistItemPackedTypeSubprogramTemplateTypeParameterTemplateValueParameterThrownTypeTryDwarfBlockVariantPartVariableVolatileTypeDwarfProcedureRestrictTypeInterfaceTypeNamespaceImportedModuleUnspecifiedTypePartialUnitImportedUnitMutableTypeConditionSharedTypeTypeUnitRvalueReferenceTypeTemplateAliasCoarrayTypeGenericSubrangeDynamicTypeAtomicTypeCallSiteCallSiteParameterSkeletonUnitImmutableType" ) var ( _Tag_index_0 = [...]uint8{0, 9, 18, 28, 43, 58} _Tag_index_2 = [...]uint8{0, 5, 18} _Tag_index_4 = [...]uint8{0, 11, 24, 35, 45, 55} - _Tag_index_5 = [...]uint16{0, 14, 21, 30, 51, 58, 74, 89, 100, 117, 123, 138, 145, 157, 165, 182, 190, 205, 214, 222, 232, 240, 246, 254, 266, 276, 286, 307, 329, 339, 352, 363, 371, 383, 397, 409, 422, 431, 445, 460, 471, 483, 494, 503, 513, 521, 540, 553} + _Tag_index_5 = [...]uint16{0, 14, 21, 30, 51, 58, 74, 89, 100, 117, 123, 138, 145, 157, 165, 182, 190, 205, 214, 222, 232, 240, 246, 254, 266, 276, 286, 307, 329, 339, 352, 363, 371, 383, 397, 409, 422, 431, 445, 460, 471, 483, 494, 503, 513, 521, 540, 553, 564, 579, 590, 600, 608, 625, 637, 650} ) func (i Tag) String() string { @@ -35,7 +110,7 @@ func (i Tag) String() string { case 15 <= i && i <= 19: i -= 15 return _Tag_name_4[_Tag_index_4[i]:_Tag_index_4[i+1]] - case 21 <= i && i <= 67: + case 21 <= i && i <= 75: i -= 21 return _Tag_name_5[_Tag_index_5[i]:_Tag_index_5[i+1]] default: diff --git a/libgo/go/debug/dwarf/type_test.go b/libgo/go/debug/dwarf/type_test.go index aa2fbeca0b3..fda03fdbb09 100644 --- a/libgo/go/debug/dwarf/type_test.go +++ b/libgo/go/debug/dwarf/type_test.go @@ -223,7 +223,7 @@ func TestUnsupportedTypes(t *testing.T) { } } if dumpseen { - for k, _ := range seen { + for k := range seen { fmt.Printf("seen: %s\n", k) } } diff --git a/libgo/go/debug/dwarf/typeunit.go b/libgo/go/debug/dwarf/typeunit.go index 76b357ce28b..27aa0784f02 100644 --- a/libgo/go/debug/dwarf/typeunit.go +++ b/libgo/go/debug/dwarf/typeunit.go @@ -137,7 +137,7 @@ func (tur *typeUnitReader) Next() (*Entry, error) { if len(tur.tu.data) == 0 { return nil, nil } - e := tur.b.entry(tur.tu.atable, tur.tu.base) + e := tur.b.entry(nil, tur.tu.atable, tur.tu.base, tur.tu.vers) if tur.b.err != nil { tur.err = tur.b.err return nil, tur.err diff --git a/libgo/go/debug/dwarf/unit.go b/libgo/go/debug/dwarf/unit.go index 98024ca1f84..29a744fd184 100644 --- a/libgo/go/debug/dwarf/unit.go +++ b/libgo/go/debug/dwarf/unit.go @@ -19,7 +19,8 @@ type unit struct { atable abbrevTable asize int vers int - is64 bool // True for 64-bit DWARF format + utype uint8 // DWARF 5 unit type + is64 bool // True for 64-bit DWARF format } // Implement the dataFormat interface. @@ -63,11 +64,15 @@ func (d *Data) parseUnits() ([]unit, error) { n, u.is64 = b.unitLength() dataOff := b.off vers := b.uint16() - if vers != 2 && vers != 3 && vers != 4 { + if vers < 2 || vers > 5 { b.error("unsupported DWARF version " + strconv.Itoa(int(vers))) break } u.vers = int(vers) + if vers >= 5 { + u.utype = b.uint8() + u.asize = int(b.uint8()) + } var abbrevOff uint64 if u.is64 { abbrevOff = b.uint64() @@ -82,7 +87,22 @@ func (d *Data) parseUnits() ([]unit, error) { break } u.atable = atable - u.asize = int(b.uint8()) + if vers < 5 { + u.asize = int(b.uint8()) + } + + switch u.utype { + case utSkeleton, utSplitCompile: + b.uint64() // unit ID + case utType, utSplitType: + b.uint64() // type signature + if u.is64 { // type offset + b.uint64() + } else { + b.uint32() + } + } + u.off = b.off u.data = b.bytes(int(n - (b.off - dataOff))) } diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go index e2a58203d9d..b9a8b1e0cbb 100644 --- a/libgo/go/debug/elf/file.go +++ b/libgo/go/debug/elf/file.go @@ -632,6 +632,25 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error { } } +// relocSymbolTargetOK decides whether we should try to apply a +// relocation to a DWARF data section, given a pointer to the symbol +// targeted by the relocation. Most relocations in DWARF data tend to +// be section-relative, but some target non-section symbols (for +// example, low_PC attrs on subprogram or compilation unit DIEs that +// target function symbols), and we need to include these as well. +// Return value is a pair (X,Y) where X is a boolean indicating +// whether the relocation is needed, and Y is the symbol value in the +// case of a non-section relocation that needs to be applied. +func relocSymbolTargetOK(sym *Symbol) (bool, uint64) { + if ST_TYPE(sym.Info) == STT_SECTION { + return true, 0 + } + if sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE { + return true, sym.Value + } + return false, 0 +} + func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error { // 24 is the size of Rela64. if len(rels)%24 != 0 { @@ -655,26 +674,28 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. + needed, val := relocSymbolTargetOK(sym) + if !needed { continue } // There are relocations, so this must be a normal - // object file, and we only look at section symbols, - // so we assume that the symbol value is 0. + // object file. The code below handles only basic relocations + // of the form S + A (symbol plus addend). switch t { case R_X86_64_64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) + val64 := val + uint64(rela.Addend) + f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64) case R_X86_64_32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -779,26 +800,28 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. + needed, val := relocSymbolTargetOK(sym) + if !needed { continue } // There are relocations, so this must be a normal - // object file, and we only look at section symbols, - // so we assume that the symbol value is 0. + // object file. The code below handles only basic relocations + // of the form S + A (symbol plus addend). switch t { case R_AARCH64_ABS64: if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) + val64 := uint64(val) + uint64(rela.Addend) + f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64) case R_AARCH64_ABS32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -828,8 +851,8 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. + needed, val := relocSymbolTargetOK(sym) + if !needed { continue } @@ -838,7 +861,8 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error { if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -868,8 +892,8 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. + needed, val := relocSymbolTargetOK(sym) + if !needed { continue } @@ -878,12 +902,14 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) + val64 := val + uint64(rela.Addend) + f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64) case R_PPC64_ADDR32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -958,8 +984,8 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. + needed, val := relocSymbolTargetOK(sym) + if !needed { continue } @@ -968,12 +994,14 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) + val64 := val + uint64(rela.Addend) + f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64) case R_MIPS_32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -1003,10 +1031,8 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - switch SymType(sym.Info & 0xf) { - case STT_SECTION, STT_NOTYPE: - break - default: + needed, val := relocSymbolTargetOK(sym) + if !needed { continue } @@ -1015,14 +1041,14 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val := sym.Value + uint64(rela.Addend) - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val) + val64 := val + uint64(rela.Addend) + f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64) case R_RISCV_32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val := uint32(sym.Value) + uint32(rela.Addend) - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val) + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -1052,10 +1078,8 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - switch SymType(sym.Info & 0xf) { - case STT_SECTION, STT_NOTYPE: - break - default: + needed, val := relocSymbolTargetOK(sym) + if !needed { continue } @@ -1064,14 +1088,14 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val := sym.Value + uint64(rela.Addend) - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val) + val64 := val + uint64(rela.Addend) + f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64) case R_390_32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val := uint32(sym.Value) + uint32(rela.Addend) - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val) + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -1141,8 +1165,8 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. + needed, val := relocSymbolTargetOK(sym) + if !needed { continue } @@ -1151,12 +1175,14 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) + val64 := val + uint64(rela.Addend) + f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64) case R_SPARC_32, R_SPARC_UA32: if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { continue } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) + val32 := uint32(val) + uint32(rela.Addend) + f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -1267,9 +1293,8 @@ func (f *File) DWARF() (*dwarf.Data, error) { return b, nil } - // There are many other DWARF sections, but these - // are the ones the debug/dwarf package uses. - // Don't bother loading others. + // There are many DWARf sections, but these are the ones + // the debug/dwarf package started with. var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil} for i, s := range f.Sections { suffix := dwarfSuffix(s) @@ -1291,10 +1316,14 @@ func (f *File) DWARF() (*dwarf.Data, error) { return nil, err } - // Look for DWARF4 .debug_types sections. + // Look for DWARF4 .debug_types sections and DWARF5 sections. for i, s := range f.Sections { suffix := dwarfSuffix(s) - if suffix != "types" { + if suffix == "" { + continue + } + if _, ok := dat[suffix]; ok { + // Already handled. continue } @@ -1303,9 +1332,14 @@ func (f *File) DWARF() (*dwarf.Data, error) { return nil, err } - err = d.AddTypes(fmt.Sprintf("types-%d", i), b) - if err != nil { - return nil, err + if suffix == "types" { + if err := d.AddTypes(fmt.Sprintf("types-%d", i), b); err != nil { + return nil, err + } + } else { + if err := d.AddSection(".debug_"+suffix, b); err != nil { + return nil, err + } } } diff --git a/libgo/go/debug/elf/file_test.go b/libgo/go/debug/elf/file_test.go index b826a0ff050..b13d13ebf09 100644 --- a/libgo/go/debug/elf/file_test.go +++ b/libgo/go/debug/elf/file_test.go @@ -784,7 +784,7 @@ func TestCompressedSection(t *testing.T) { func TestNoSectionOverlaps(t *testing.T) { // Ensure cmd/link outputs sections without overlaps. switch runtime.GOOS { - case "aix", "android", "darwin", "js", "nacl", "plan9", "windows": + case "aix", "android", "darwin", "js", "plan9", "windows": t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS) } _ = net.ResolveIPAddr // force dynamic linkage @@ -818,6 +818,6 @@ func TestIssue10996(t *testing.T) { "0000") _, err := NewFile(bytes.NewReader(data)) if err == nil { - t.Fatalf("opening invalid ELF file unexpectedly suceeded") + t.Fatalf("opening invalid ELF file unexpectedly succeeded") } } diff --git a/libgo/go/debug/macho/file.go b/libgo/go/debug/macho/file.go index 16708e5247f..085b0c8219b 100644 --- a/libgo/go/debug/macho/file.go +++ b/libgo/go/debug/macho/file.go @@ -473,7 +473,12 @@ func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset if n.Name >= uint32(len(strtab)) { return nil, &FormatError{offset, "invalid name in symbol table", n.Name} } - sym.Name = cstring(strtab[n.Name:]) + // We add "_" to Go symbols. Strip it here. See issue 33808. + name := cstring(strtab[n.Name:]) + if strings.Contains(name, ".") && name[0] == '_' { + name = name[1:] + } + sym.Name = name sym.Type = n.Type sym.Sect = n.Sect sym.Desc = n.Desc diff --git a/libgo/go/debug/macho/file_test.go b/libgo/go/debug/macho/file_test.go index 28b76f93d7a..03915c86e23 100644 --- a/libgo/go/debug/macho/file_test.go +++ b/libgo/go/debug/macho/file_test.go @@ -5,6 +5,9 @@ package macho import ( + "bytes" + "internal/obscuretestdata" + "io" "reflect" "testing" ) @@ -19,7 +22,7 @@ type fileTest struct { var fileTests = []fileTest{ { - "testdata/gcc-386-darwin-exec", + "testdata/gcc-386-darwin-exec.base64", FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0xc, 0x3c0, 0x85}, []interface{}{ &SegmentHeader{LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, @@ -45,7 +48,7 @@ var fileTests = []fileTest{ nil, }, { - "testdata/gcc-amd64-darwin-exec", + "testdata/gcc-amd64-darwin-exec.base64", FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0xb, 0x568, 0x85}, []interface{}{ &SegmentHeader{LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, @@ -73,7 +76,7 @@ var fileTests = []fileTest{ nil, }, { - "testdata/gcc-amd64-darwin-exec-debug", + "testdata/gcc-amd64-darwin-exec-debug.base64", FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0xa, 0x4, 0x5a0, 0}, []interface{}{ nil, // LC_UUID @@ -101,7 +104,7 @@ var fileTests = []fileTest{ nil, }, { - "testdata/clang-386-darwin-exec-with-rpath", + "testdata/clang-386-darwin-exec-with-rpath.base64", FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0x10, 0x42c, 0x1200085}, []interface{}{ nil, // LC_SEGMENT @@ -125,7 +128,7 @@ var fileTests = []fileTest{ nil, }, { - "testdata/clang-amd64-darwin-exec-with-rpath", + "testdata/clang-amd64-darwin-exec-with-rpath.base64", FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0x10, 0x4c8, 0x200085}, []interface{}{ nil, // LC_SEGMENT @@ -149,7 +152,7 @@ var fileTests = []fileTest{ nil, }, { - "testdata/clang-386-darwin.obj", + "testdata/clang-386-darwin.obj.base64", FileHeader{0xfeedface, Cpu386, 0x3, 0x1, 0x4, 0x138, 0x2000}, nil, nil, @@ -184,7 +187,7 @@ var fileTests = []fileTest{ }, }, { - "testdata/clang-amd64-darwin.obj", + "testdata/clang-amd64-darwin.obj.base64", FileHeader{0xfeedfacf, CpuAmd64, 0x3, 0x1, 0x4, 0x200, 0x2000}, nil, nil, @@ -221,11 +224,47 @@ var fileTests = []fileTest{ }, } +func readerAtFromObscured(name string) (io.ReaderAt, error) { + b, err := obscuretestdata.ReadFile(name) + if err != nil { + return nil, err + } + return bytes.NewReader(b), nil +} + +func openObscured(name string) (*File, error) { + ra, err := readerAtFromObscured(name) + if err != nil { + return nil, err + } + ff, err := NewFile(ra) + if err != nil { + return nil, err + } + return ff, nil +} + +func openFatObscured(name string) (*FatFile, error) { + ra, err := readerAtFromObscured(name) + if err != nil { + return nil, err + } + ff, err := NewFatFile(ra) + if err != nil { + return nil, err + } + return ff, nil +} + func TestOpen(t *testing.T) { for i := range fileTests { tt := &fileTests[i] - f, err := Open(tt.file) + // Use obscured files to prevent Apple’s notarization service from + // mistaking them as candidates for notarization and rejecting the entire + // toolchain. + // See golang.org/issue/34986 + f, err := openObscured(tt.file) if err != nil { t.Error(err) continue @@ -318,7 +357,7 @@ func TestOpenFailure(t *testing.T) { } func TestOpenFat(t *testing.T) { - ff, err := OpenFat("testdata/fat-gcc-386-amd64-darwin-exec") + ff, err := openFatObscured("testdata/fat-gcc-386-amd64-darwin-exec.base64") if err != nil { t.Fatal(err) } @@ -350,8 +389,8 @@ func TestOpenFatFailure(t *testing.T) { t.Errorf("OpenFat %s: succeeded unexpectedly", filename) } - filename = "testdata/gcc-386-darwin-exec" // not a fat Mach-O - ff, err := OpenFat(filename) + filename = "testdata/gcc-386-darwin-exec.base64" // not a fat Mach-O + ff, err := openFatObscured(filename) if err != ErrNotFat { t.Errorf("OpenFat %s: got %v, want ErrNotFat", filename, err) } diff --git a/libgo/go/debug/macho/testdata/clang-386-darwin-exec-with-rpath b/libgo/go/debug/macho/testdata/clang-386-darwin-exec-with-rpath deleted file mode 100644 index a8720feb923..00000000000 Binary files a/libgo/go/debug/macho/testdata/clang-386-darwin-exec-with-rpath and /dev/null differ diff --git a/libgo/go/debug/macho/testdata/clang-386-darwin-exec-with-rpath.base64 b/libgo/go/debug/macho/testdata/clang-386-darwin-exec-with-rpath.base64 new file mode 100644 index 00000000000..64047f1b1e7 --- /dev/null +++ b/libgo/go/debug/macho/testdata/clang-386-darwin-exec-with-rpath.base64 @@ -0,0 +1 @@ +zvrt/gcAAAADAAAAAgAAABAAAAAsBAAAhQAgAQEAAAA4AAAAX19QQUdFWkVSTwAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAIwBAABfX1RFWFQAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAcAAAAFAAAABQAAAAAAAABfX3RleHQAAAAAAAAAAAAAX19URVhUAAAAAAAAAAAAAGAfAAAtAAAAYA8AAAQAAAAAAAAAAAAAAAAEAIAAAAAAAAAAAF9fc3ltYm9sX3N0dWIAAABfX1RFWFQAAAAAAAAAAAAAjh8AAAYAAACODwAAAQAAAAAAAAAAAAAACAUAgAAAAAAGAAAAX19zdHViX2hlbHBlcgAAAF9fVEVYVAAAAAAAAAAAAACUHwAAFgAAAJQPAAACAAAAAAAAAAAAAAAABQCAAAAAAAAAAABfX2NzdHJpbmcAAAAAAAAAX19URVhUAAAAAAAAAAAAAKofAAAOAAAAqg8AAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAF9fdW53aW5kX2luZm8AAABfX1RFWFQAAAAAAAAAAAAAuB8AAEgAAAC4DwAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAMAAAABfX0RBVEEAAAAAAAAAAAAAACAAAAAQAAAAEAAAABAAAAcAAAADAAAAAgAAAAAAAABfX25sX3N5bWJvbF9wdHIAX19EQVRBAAAAAAAAAAAAAAAgAAAIAAAAABAAAAIAAAAAAAAAAAAAAAYAAAABAAAAAAAAAF9fbGFfc3ltYm9sX3B0cgBfX0RBVEEAAAAAAAAAAAAACCAAAAQAAAAIEAAAAgAAAAAAAAAAAAAABwAAAAMAAAAAAAAAAQAAADgAAABfX0xJTktFRElUAAAAAAAAADAAAAAQAAAAIAAA4AAAAAcAAAABAAAAAAAAAAAAAAAiAACAMAAAAAAgAAAQAAAAECAAABgAAAAAAAAAAAAAACggAAAQAAAAOCAAACwAAAACAAAAGAAAAGggAAAEAAAAqCAAADgAAAALAAAAUAAAAAAAAAAAAAAAAAAAAAIAAAACAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJggAAAEAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAcAAAADAAAAC91c3IvbGliL2R5bGQAAAAbAAAAGAAAABvekfnOVjeLrRdKs5wg1L0kAAAAEAAAAAAMCgAADAoAKgAAABAAAAAAAAAAAAAAACgAAIAYAAAAYA8AAAAAAAAAAAAAAAAAAAwAAAA0AAAAGAAAAAIAAAACPNYEAAABAC91c3IvbGliL2xpYlN5c3RlbS5CLmR5bGliAAAcAACAGAAAAAwAAAAvbXkvcnBhdGgAAAAmAAAAEAAAAGQgAAAEAAAAKQAAABAAAABoIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVYnlg+wY6AAAAABYjYA/AAAAx0X8AAAAAIkEJOgNAAAAMcmJRfiJyIPEGF3DkP8lCCAAAGgEIAAA/yUAIAAAkGgAAAAA6er///9oZWxsbywgd29ybGQKAAEAAAAcAAAAAAAAABwAAAAAAAAAHAAAAAIAAABgDwAANAAAADQAAACODwAAAAAAADQAAAADAAAADAABABAAAQAAAAAAAAAAAAAAAAAAAAAAoB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARIghREiGQH3ABcAJRAAAAEUBkeWxkX3N0dWJfYmluZGVyAFFyAJAAcggRQF9wcmludGYAkAAAAAABXwAFAAJfbWhfZXhlY3V0ZV9oZWFkZXIAIW1haW4AJQIAAAADAOAeAAAA4B4AAAIAAAAPARAAABAAABYAAAAPAQAAYB8AABwAAAABAAABAAAAACQAAAABAAABAAAAAAIAAAADAAAAAAAAQAIAAAAgAF9fbWhfZXhlY3V0ZV9oZWFkZXIAX21haW4AX3ByaW50ZgBkeWxkX3N0dWJfYmluZGVyAAAAAA== diff --git a/libgo/go/debug/macho/testdata/clang-386-darwin.obj b/libgo/go/debug/macho/testdata/clang-386-darwin.obj deleted file mode 100644 index e79dc57a4b4..00000000000 Binary files a/libgo/go/debug/macho/testdata/clang-386-darwin.obj and /dev/null differ diff --git a/libgo/go/debug/macho/testdata/clang-386-darwin.obj.base64 b/libgo/go/debug/macho/testdata/clang-386-darwin.obj.base64 new file mode 100644 index 00000000000..60a07658c98 --- /dev/null +++ b/libgo/go/debug/macho/testdata/clang-386-darwin.obj.base64 @@ -0,0 +1 @@ +zvrt/gcAAAADAAAAAQAAAAQAAAA4AQAAACAAAAEAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7AAAAVAEAADsAAAAHAAAABwAAAAIAAAAAAAAAX190ZXh0AAAAAAAAAAAAAF9fVEVYVAAAAAAAAAAAAAAAAAAALQAAAFQBAAAEAAAAkAEAAAMAAAAABACAAAAAAAAAAABfX2NzdHJpbmcAAAAAAAAAX19URVhUAAAAAAAAAAAAAC0AAAAOAAAAgQEAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAACQAAAAQAAAAAAwKAAAAAAACAAAAGAAAAKgBAAACAAAAwAEAABAAAAALAAAAUAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFWJ5YPsGOgAAAAAWI2AIgAAAMdF/AAAAACJBCTo3////zHJiUX4iciDxBhdw2hlbGxvLCB3b3JsZAoAAB0AAAABAAANDgAApC0AAAAAAAChCwAAAAEAAAAPAQAAAAAAAAcAAAABAAAAAAAAAABfbWFpbgBfcHJpbnRmAAA= diff --git a/libgo/go/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath b/libgo/go/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath deleted file mode 100644 index 191c7688cbf..00000000000 Binary files a/libgo/go/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath and /dev/null differ diff --git a/libgo/go/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath.base64 b/libgo/go/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath.base64 new file mode 100644 index 00000000000..26821814cfa --- /dev/null +++ b/libgo/go/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath.base64 @@ -0,0 +1 @@ +z/rt/gcAAAEDAACAAgAAABAAAADIBAAAhQAgAAAAAAAZAAAASAAAAF9fUEFHRVpFUk8AAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAA2AEAAF9fVEVYVAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAcAAAAFAAAABQAAAAAAAABfX3RleHQAAAAAAAAAAAAAX19URVhUAAAAAAAAAAAAAGAPAAABAAAAKgAAAAAAAABgDwAABAAAAAAAAAAAAAAAAAQAgAAAAAAAAAAAAAAAAF9fc3R1YnMAAAAAAAAAAABfX1RFWFQAAAAAAAAAAAAAig8AAAEAAAAGAAAAAAAAAIoPAAABAAAAAAAAAAAAAAAIBACAAAAAAAYAAAAAAAAAX19zdHViX2hlbHBlcgAAAF9fVEVYVAAAAAAAAAAAAACQDwAAAQAAABoAAAAAAAAAkA8AAAIAAAAAAAAAAAAAAAAEAIAAAAAAAAAAAAAAAABfX2NzdHJpbmcAAAAAAAAAX19URVhUAAAAAAAAAAAAAKoPAAABAAAADgAAAAAAAACqDwAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAF9fdW53aW5kX2luZm8AAABfX1RFWFQAAAAAAAAAAAAAuA8AAAEAAABIAAAAAAAAALgPAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAAOgAAABfX0RBVEEAAAAAAAAAAAAAABAAAAEAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAAAAAHAAAAAwAAAAIAAAAAAAAAX19ubF9zeW1ib2xfcHRyAF9fREFUQQAAAAAAAAAAAAAAEAAAAQAAABAAAAAAAAAAABAAAAMAAAAAAAAAAAAAAAYAAAABAAAAAAAAAAAAAABfX2xhX3N5bWJvbF9wdHIAX19EQVRBAAAAAAAAAAAAABAQAAABAAAACAAAAAAAAAAQEAAAAwAAAAAAAAAAAAAABwAAAAMAAAAAAAAAAAAAABkAAABIAAAAX19MSU5LRURJVAAAAAAAAAAgAAABAAAAABAAAAAAAAAAIAAAAAAAAPAAAAAAAAAABwAAAAEAAAAAAAAAAAAAACIAAIAwAAAAACAAAAgAAAAIIAAAGAAAAAAAAAAAAAAAICAAABAAAAAwIAAAMAAAAAIAAAAYAAAAaCAAAAQAAAC4IAAAOAAAAAsAAABQAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqCAAAAQAAAAAAAAAAAAAAAAAAAAAAAAADgAAACAAAAAMAAAAL3Vzci9saWIvZHlsZAAAAAAAAAAbAAAAGAAAAH8sLvoxGjvSjEmpyV1N+kkkAAAAEAAAAAAMCgAADAoAKgAAABAAAAAAAAAAAAAAACgAAIAYAAAAYA8AAAAAAAAAAAAAAAAAAAwAAAA4AAAAGAAAAAIAAAACPNYEAAABAC91c3IvbGliL2xpYlN5c3RlbS5CLmR5bGliAAAAAAAAHAAAgBgAAAAMAAAAL215L3JwYXRoAAAAJgAAABAAAABgIAAACAAAACkAAAAQAAAAaCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVUiJ5UiD7BBIjT07AAAAx0X8AAAAALAA6A0AAAAxyYlF+InISIPEEF3D/yWAAAAATI0dcQAAAEFT/yVhAAAAkGgAAAAA6eb///9oZWxsbywgd29ybGQKAAEAAAAcAAAAAAAAABwAAAAAAAAAHAAAAAIAAABgDwAANAAAADQAAACLDwAAAAAAADQAAAADAAAADAABABAAAQAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAACgDwAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARIhBRAAAAABFAZHlsZF9zdHViX2JpbmRlcgBRcgCQAHIQEUBfcHJpbnRmAJAAAAAAAV8ABQACX21oX2V4ZWN1dGVfaGVhZGVyACFtYWluACUCAAAAAwDgHgAAAAAAAADgHgAAAAAAAAIAAAAPARAAAAAAAAEAAAAWAAAADwEAAGAPAAABAAAAHAAAAAEAAAEAAAAAAAAAACQAAAABAAABAAAAAAAAAAACAAAAAwAAAAAAAEACAAAAIABfX21oX2V4ZWN1dGVfaGVhZGVyAF9tYWluAF9wcmludGYAZHlsZF9zdHViX2JpbmRlcgAAAAA= diff --git a/libgo/go/debug/macho/testdata/clang-amd64-darwin.obj b/libgo/go/debug/macho/testdata/clang-amd64-darwin.obj deleted file mode 100644 index 23cc3c1bcb1..00000000000 Binary files a/libgo/go/debug/macho/testdata/clang-amd64-darwin.obj and /dev/null differ diff --git a/libgo/go/debug/macho/testdata/clang-amd64-darwin.obj.base64 b/libgo/go/debug/macho/testdata/clang-amd64-darwin.obj.base64 new file mode 100644 index 00000000000..b8f1fce9887 --- /dev/null +++ b/libgo/go/debug/macho/testdata/clang-amd64-darwin.obj.base64 @@ -0,0 +1 @@ +z/rt/gcAAAEDAAAAAQAAAAQAAAAAAgAAACAAAAAAAAAZAAAAiAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgAAAAAAAAAIAIAAAAAAACYAAAAAAAAAAcAAAAHAAAABAAAAAAAAABfX3RleHQAAAAAAAAAAAAAX19URVhUAAAAAAAAAAAAAAAAAAAAAAAAKgAAAAAAAAAgAgAABAAAALgCAAACAAAAAAQAgAAAAAAAAAAAAAAAAF9fY3N0cmluZwAAAAAAAABfX1RFWFQAAAAAAAAAAAAAKgAAAAAAAAAOAAAAAAAAAEoCAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAX19jb21wYWN0X3Vud2luZF9fTEQAAAAAAAAAAAAAAAA4AAAAAAAAACAAAAAAAAAAWAIAAAMAAADIAgAAAQAAAAAAAAIAAAAAAAAAAAAAAABfX2VoX2ZyYW1lAAAAAAAAX19URVhUAAAAAAAAAAAAAFgAAAAAAAAAQAAAAAAAAAB4AgAAAwAAAAAAAAAAAAAACwAAaAAAAAAAAAAAAAAAACQAAAAQAAAAAAwKAAAAAAACAAAAGAAAANACAAACAAAA8AIAABAAAAALAAAAUAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFVIieVIg+wQSI09GwAAAMdF/AAAAACwAOgAAAAAMcmJRfiJyEiDxBBdw2hlbGxvLCB3b3JsZAoAAAAAAAAAAAAqAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAF6UgABeBABEAwHCJABAAAkAAAAHAAAAIj/////////KgAAAAAAAAAAQQ4QhgJDDQYAAAAAAAAAGQAAAAEAAC0LAAAAAgAAFQAAAAABAAAGAQAAAA8BAAAAAAAAAAAAAAcAAAABAAAAAAAAAAAAAAAAX21haW4AX3ByaW50ZgAA diff --git a/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec b/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec deleted file mode 100644 index 7efd19300b2..00000000000 Binary files a/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec and /dev/null differ diff --git a/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec.base64 b/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec.base64 new file mode 100644 index 00000000000..407d9773c41 --- /dev/null +++ b/libgo/go/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec.base64 @@ -0,0 +1 @@ +yv66vgAAAAIAAAAHAAAAAwAAEAAAADEsAAAADAEAAAeAAAADAABQAAAAIUAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM767f4HAAAAAwAAAAIAAAAMAAAAwAMAAIUAAAABAAAAOAAAAF9fUEFHRVpFUk8AAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAADAAAAAX19URVhUAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAQAAAHAAAABQAAAAIAAAAAAAAAX190ZXh0AAAAAAAAAAAAAF9fVEVYVAAAAAAAAAAAAABoHwAAiAAAAGgPAAACAAAAAAAAAAAAAAAABACAAAAAAAAAAABfX2NzdHJpbmcAAAAAAAAAX19URVhUAAAAAAAAAAAAAPAfAAANAAAA8A8AAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAEAAADAAAAAX19EQVRBAAAAAAAAAAAAAAAgAAAAEAAAABAAAAAQAAAHAAAAAwAAAAIAAAAAAAAAX19kYXRhAAAAAAAAAAAAAF9fREFUQQAAAAAAAAAAAAAAIAAAFAAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2R5bGQAAAAAAAAAAAAAX19EQVRBAAAAAAAAAAAAABQgAAAcAAAAFBAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAB8AAAAX19JTVBPUlQAAAAAAAAAAAAwAAAAEAAAACAAAAAQAAAHAAAABwAAAAEAAAAAAAAAX19qdW1wX3RhYmxlAAAAAF9fSU1QT1JUAAAAAAAAAAAAMAAACgAAAAAgAAAGAAAAAAAAAAAAAAAIAAAEAAAAAAUAAAABAAAAOAAAAF9fTElOS0VESVQAAAAAAAAAQAAAABAAAAAwAAAsAQAABwAAAAEAAAAAAAAAAAAAAAIAAAAYAAAAADAAAAwAAACYMAAAlAAAAAsAAABQAAAAAAAAAAMAAAADAAAABwAAAAoAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkDAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgAAABwAAAAMAAAAL3Vzci9saWIvZHlsZAAAABsAAAAYAAAAWjdZMZZTYrr96h48KqvuxAUAAABQAAAAAQAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAADQAAAAYAAAAAgAAAAAAAQAAAAEAL3Vzci9saWIvbGliZ2NjX3MuMS5keWxpYgAAAAwAAAA0AAAAGAAAAAIAAAAEAW8AAAABAC91c3IvbGliL2xpYlN5c3RlbS5CLmR5bGliAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAagCJ5YPk8IPsEItdBIlcJACNTQiJTCQEg8MBweMCAcuJXCQIiwODwwSFwHX3iVwkDOgsAAAAiUQkAOhZEAAA9OgAAAAAWP+wYwAAAIuAZwAAAP/g6AAAAABYi4BXAAAA/+BVieVTg+wU6AAAAABbjYMaAAAAiQQk6CAQAAC4AAAAAIPEFFvJw2hlbGxvLCB3b3JsZAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQ4I8IEOCPABAAAAwgAAAIIAAABCAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9PT09PT09PT09AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAeAQAAqB8AABsAAAAeAQAAvB8AAC4AAAAOAwAAECAAAEAAAAAPAwAADCAAAEgAAAAPAwAACCAAAFAAAAAPAwAAACAAAFwAAAADABAAABAAAHAAAAAPAwAABCAAAHkAAAAPAQAAyh8AAH8AAAAPAQAAaB8AAIUAAAABAAECAAAAAIsAAAABAAECAAAAAAoAAAALAAAAIABkeWxkX3N0dWJfYmluZGluZ19oZWxwZXIAX19keWxkX2Z1bmNfbG9va3VwAGR5bGRfX21hY2hfaGVhZGVyAF9OWEFyZ2MAX05YQXJndgBfX19wcm9nbmFtZQBfX21oX2V4ZWN1dGVfaGVhZGVyAF9lbnZpcm9uAF9tYWluAHN0YXJ0AF9leGl0AF9wdXRzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADP+u3+BwAAAQMAAIACAAAACwAAAGgFAACFAAAAAAAAABkAAABIAAAAX19QQUdFWkVSTwAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkAAADYAQAAX19URVhUAAAAAAAAAAAAAAAAAAABAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAABwAAAAUAAAAFAAAAAAAAAF9fdGV4dAAAAAAAAAAAAABfX1RFWFQAAAAAAAAAAAAAFA8AAAEAAABtAAAAAAAAABQPAAACAAAAAAAAAAAAAAAABACAAAAAAAAAAAAAAAAAX19zeW1ib2xfc3R1YjEAAF9fVEVYVAAAAAAAAAAAAACBDwAAAQAAAAwAAAAAAAAAgQ8AAAAAAAAAAAAAAAAAAAgEAIAAAAAABgAAAAAAAABfX3N0dWJfaGVscGVyAAAAX19URVhUAAAAAAAAAAAAAJAPAAABAAAAGAAAAAAAAACQDwAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9fY3N0cmluZwAAAAAAAABfX1RFWFQAAAAAAAAAAAAAqA8AAAEAAAANAAAAAAAAAKgPAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAX19laF9mcmFtZQAAAAAAAF9fVEVYVAAAAAAAAAAAAAC4DwAAAQAAAEgAAAAAAAAAuA8AAAMAAAAAAAAAAAAAAAsAAGAAAAAAAAAAAAAAAAAZAAAAOAEAAF9fREFUQQAAAAAAAAAAAAAAEAAAAQAAAAAQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAcAAAADAAAAAwAAAAAAAABfX2RhdGEAAAAAAAAAAAAAX19EQVRBAAAAAAAAAAAAAAAQAAABAAAAHAAAAAAAAAAAEAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9fZHlsZAAAAAAAAAAAAABfX0RBVEEAAAAAAAAAAAAAIBAAAAEAAAA4AAAAAAAAACAQAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX19sYV9zeW1ib2xfcHRyAF9fREFUQQAAAAAAAAAAAABYEAAAAQAAABAAAAAAAAAAWBAAAAIAAAAAAAAAAAAAAAcAAAACAAAAAAAAAAAAAAAZAAAASAAAAF9fTElOS0VESVQAAAAAAAAAIAAAAQAAAAAQAAAAAAAAACAAAAAAAABAAQAAAAAAAAcAAAABAAAAAAAAAAAAAAACAAAAGAAAAAAgAAALAAAAwCAAAIAAAAALAAAAUAAAAAAAAAACAAAAAgAAAAcAAAAJAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAgAAAEAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAgAAAADAAAAC91c3IvbGliL2R5bGQAAAAAAAAAGwAAABgAAAA7JLhyDkV21Ciq7omwwSFdBQAAALgAAAAEAAAAKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFA8AAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAA4AAAAGAAAAAIAAAAAAAEAAAABAC91c3IvbGliL2xpYmdjY19zLjEuZHlsaWIAAAAAAAAADAAAADgAAAAYAAAAAgAAAAQBbwAAAAEAL3Vzci9saWIvbGliU3lzdGVtLkIuZHlsaWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGoASInlSIPk8EiLfQhIjXUQifqDwgHB4gNIAfJIidHrBEiDwQhIgzkAdfZIg8EI6CIAAACJx+gyAAAA9EFTTI0dp/D//0FT/yW/AAAADx8A/yW+AAAAVUiJ5UiNPTMAAADoDQAAALgAAAAAycP/JdEAAAD/JdMAAAAAAABMjR3BAAAA6bT///9MjR29AAAA6aj///9oZWxsbywgd29ybGQAAAAAFAAAAAAAAAABelIAAXgQARAMBwiQAQAALAAAABwAAACS/////////xcAAAAAAAAAAAQBAAAADhCGAgQDAAAADQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMBf/38AAAgQwF//fwAAAAAAAAEAAAAYEAAAAQAAABAQAAABAAAACBAAAAEAAAAAEAAAAQAAAJAPAAABAAAAnA8AAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAeAQAAUA8AAAEAAAAbAAAAHgEAAGQPAAABAAAALgAAAA8GAAAYEAAAAQAAADYAAAAPBgAAEBAAAAEAAAA+AAAADwYAAAAQAAABAAAASgAAAAMAEAAAAAAAAQAAAF4AAAAPBgAACBAAAAEAAABnAAAADwEAAGoPAAABAAAAbQAAAA8BAAAUDwAAAQAAAHMAAAABAAECAAAAAAAAAAB5AAAAAQABAgAAAAAAAAAACQAAAAoAAAAJAAAACgAAACAAZHlsZF9zdHViX2JpbmRpbmdfaGVscGVyAF9fZHlsZF9mdW5jX2xvb2t1cABfTlhBcmdjAF9OWEFyZ3YAX19fcHJvZ25hbWUAX19taF9leGVjdXRlX2hlYWRlcgBfZW52aXJvbgBfbWFpbgBzdGFydABfZXhpdABfcHV0cwAA diff --git a/libgo/go/debug/macho/testdata/gcc-386-darwin-exec b/libgo/go/debug/macho/testdata/gcc-386-darwin-exec deleted file mode 100755 index 03ba1bafac0..00000000000 Binary files a/libgo/go/debug/macho/testdata/gcc-386-darwin-exec and /dev/null differ diff --git a/libgo/go/debug/macho/testdata/gcc-386-darwin-exec.base64 b/libgo/go/debug/macho/testdata/gcc-386-darwin-exec.base64 new file mode 100644 index 00000000000..5e40ed6f0d7 --- /dev/null +++ b/libgo/go/debug/macho/testdata/gcc-386-darwin-exec.base64 @@ -0,0 +1 @@ +zvrt/gcAAAADAAAAAgAAAAwAAADAAwAAhQAAAAEAAAA4AAAAX19QQUdFWkVSTwAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAMAAAABfX1RFWFQAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAcAAAAFAAAAAgAAAAAAAABfX3RleHQAAAAAAAAAAAAAX19URVhUAAAAAAAAAAAAAGgfAACIAAAAaA8AAAIAAAAAAAAAAAAAAAAEAIAAAAAAAAAAAF9fY3N0cmluZwAAAAAAAABfX1RFWFQAAAAAAAAAAAAA8B8AAA0AAADwDwAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAQAAAMAAAABfX0RBVEEAAAAAAAAAAAAAACAAAAAQAAAAEAAAABAAAAcAAAADAAAAAgAAAAAAAABfX2RhdGEAAAAAAAAAAAAAX19EQVRBAAAAAAAAAAAAAAAgAAAUAAAAABAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9fZHlsZAAAAAAAAAAAAABfX0RBVEEAAAAAAAAAAAAAFCAAABwAAAAUEAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAHwAAABfX0lNUE9SVAAAAAAAAAAAADAAAAAQAAAAIAAAABAAAAcAAAAHAAAAAQAAAAAAAABfX2p1bXBfdGFibGUAAAAAX19JTVBPUlQAAAAAAAAAAAAwAAAKAAAAACAAAAYAAAAAAAAAAAAAAAgAAAQAAAAABQAAAAEAAAA4AAAAX19MSU5LRURJVAAAAAAAAABAAAAAEAAAADAAACwBAAAHAAAAAQAAAAAAAAAAAAAAAgAAABgAAAAAMAAADAAAAJgwAACUAAAACwAAAFAAAAAAAAAAAwAAAAMAAAAHAAAACgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQMAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAHAAAAAwAAAAvdXNyL2xpYi9keWxkAAAAGwAAABgAAABaN1kxllNiuv3qHjwqq+7EBQAAAFAAAAABAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAANAAAABgAAAACAAAAAAABAAAAAQAvdXNyL2xpYi9saWJnY2Nfcy4xLmR5bGliAAAADAAAADQAAAAYAAAAAgAAAAQBbwAAAAEAL3Vzci9saWIvbGliU3lzdGVtLkIuZHlsaWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqAInlg+Twg+wQi10EiVwkAI1NCIlMJASDwwHB4wIBy4lcJAiLA4PDBIXAdfeJXCQM6CwAAACJRCQA6FkQAAD06AAAAABY/7BjAAAAi4BnAAAA/+DoAAAAAFiLgFcAAAD/4FWJ5VOD7BToAAAAAFuNgxoAAACJBCToIBAAALgAAAAAg8QUW8nDaGVsbG8sIHdvcmxkAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABDgjwgQ4I8AEAAADCAAAAggAAAEIAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD09PT09PT09PT0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAB4BAACoHwAAGwAAAB4BAAC8HwAALgAAAA4DAAAQIAAAQAAAAA8DAAAMIAAASAAAAA8DAAAIIAAAUAAAAA8DAAAAIAAAXAAAAAMAEAAAEAAAcAAAAA8DAAAEIAAAeQAAAA8BAADKHwAAfwAAAA8BAABoHwAAhQAAAAEAAQIAAAAAiwAAAAEAAQIAAAAACgAAAAsAAAAgAGR5bGRfc3R1Yl9iaW5kaW5nX2hlbHBlcgBfX2R5bGRfZnVuY19sb29rdXAAZHlsZF9fbWFjaF9oZWFkZXIAX05YQXJnYwBfTlhBcmd2AF9fX3Byb2duYW1lAF9fbWhfZXhlY3V0ZV9oZWFkZXIAX2Vudmlyb24AX21haW4Ac3RhcnQAX2V4aXQAX3B1dHMAAAAA diff --git a/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec b/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec deleted file mode 100755 index 5155a5a26f6..00000000000 Binary files a/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec and /dev/null differ diff --git a/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec-debug b/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec-debug deleted file mode 100644 index a47d3aef782..00000000000 Binary files a/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec-debug and /dev/null differ diff --git a/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec-debug.base64 b/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec-debug.base64 new file mode 100644 index 00000000000..8884566a185 --- /dev/null +++ b/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec-debug.base64 @@ -0,0 +1 @@ +z/rt/gcAAAEDAACACgAAAAQAAACgBQAAAAAAAAAAAAAbAAAAGAAAACIO+tkFWYMH+V6fhzclOW8ZAAAA2AEAAF9fVEVYVAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAFAAAABQAAAAAAAABfX3RleHQAAAAAAAAAAAAAX19URVhUAAAAAAAAAAAAABQPAAABAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAQAgAAAAAAAAAAAAAAAAF9fc3ltYm9sX3N0dWIxAABfX1RFWFQAAAAAAAAAAAAAgQ8AAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBACAAAAAAAYAAAAAAAAAX19zdHViX2hlbHBlcgAAAF9fVEVYVAAAAAAAAAAAAACQDwAAAQAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2NzdHJpbmcAAAAAAAAAX19URVhUAAAAAAAAAAAAAKgPAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAF9fZWhfZnJhbWUAAAAAAABfX1RFWFQAAAAAAAAAAAAAuA8AAAEAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAALAABgAAAAAAAAAAAAAAAAGQAAADgBAABfX0RBVEEAAAAAAAAAAAAAABAAAAEAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAwAAAAMAAAAAAAAAX19kYXRhAAAAAAAAAAAAAF9fREFUQQAAAAAAAAAAAAAAEAAAAQAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2R5bGQAAAAAAAAAAAAAX19EQVRBAAAAAAAAAAAAACAQAAABAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9fbGFfc3ltYm9sX3B0cgBfX0RBVEEAAAAAAAAAAAAAWBAAAAEAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAHAAAAAgAAAAAAAAAAAAAAGQAAAHgCAABfX0RXQVJGAAAAAAAAAAAAACAAAAEAAAAAEAAAAAAAAAAQAAAAAAAAvAEAAAAAAAAHAAAAAwAAAAcAAAAAAAAAX19kZWJ1Z19hYmJyZXYAAF9fRFdBUkYAAAAAAAAAAAAAIAAAAQAAADYAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2RlYnVnX2FyYW5nZXMAX19EV0FSRgAAAAAAAAAAADYgAAABAAAAMAAAAAAAAAA2EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9fZGVidWdfZnJhbWUAAABfX0RXQVJGAAAAAAAAAAAAZiAAAAEAAABAAAAAAAAAAGYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX19kZWJ1Z19pbmZvAAAAAF9fRFdBUkYAAAAAAAAAAACmIAAAAQAAAFQAAAAAAAAAphAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2RlYnVnX2xpbmUAAAAAX19EV0FSRgAAAAAAAAAAAPogAAABAAAARwAAAAAAAAD6EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9fZGVidWdfcHVibmFtZXNfX0RXQVJGAAAAAAAAAAAAQSEAAAEAAAAbAAAAAAAAAEERAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAX19kZWJ1Z19zdHIAAAAAAF9fRFdBUkYAAAAAAAAAAABcIQAAAQAAAGAAAAAAAAAAXBEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERASUOEwsDDhsOEQESARAGAAACJAALCz4LAw4AAAMuAD8MAw46CzsLJwxJExEBEgFACgAAACwAAAACAAAAAAAIAAAAAABqDwAAAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAD/////AQABeBAMBwiQAQAAAAAAACQAAAAAAAAAag8AAAEAAAAXAAAAAAAAAAQBAAAADhCGAgQDAAAADQZQAAAAAgAAAAAACAEBAAAAASUAAAAtAAAAag8AAAEAAACBDwAAAQAAAAAAAAACBAVXAAAAAwFbAAAAAQMBLQAAAGoPAAABAAAAgQ8AAAEAAAABVgBDAAAAAgAbAAAAAQH29QoAAQEBAQAAAAEAaGVsbG8uYwAAAAAAAAkCag8AAAEAAAADAhQDAQIEAQMBAgwBAwECBQECAgABARcAAAACAAAAAABUAAAANAAAAG1haW4AAAAAAABHTlUgQyA0LjAuMSAoQXBwbGUgSW5jLiBidWlsZCA1NDg0KQBoZWxsby5jAC9ob21lL3JzYy9nby9zcmMvcGtnL2RlYnVnL21hY2hvL3Rlc3RkYXRhAGludABtYWluAA== diff --git a/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec.base64 b/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec.base64 new file mode 100644 index 00000000000..b48ae5657e1 --- /dev/null +++ b/libgo/go/debug/macho/testdata/gcc-amd64-darwin-exec.base64 @@ -0,0 +1 @@ +z/rt/gcAAAEDAACAAgAAAAsAAABoBQAAhQAAAAAAAAAZAAAASAAAAF9fUEFHRVpFUk8AAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAA2AEAAF9fVEVYVAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAcAAAAFAAAABQAAAAAAAABfX3RleHQAAAAAAAAAAAAAX19URVhUAAAAAAAAAAAAABQPAAABAAAAbQAAAAAAAAAUDwAAAgAAAAAAAAAAAAAAAAQAgAAAAAAAAAAAAAAAAF9fc3ltYm9sX3N0dWIxAABfX1RFWFQAAAAAAAAAAAAAgQ8AAAEAAAAMAAAAAAAAAIEPAAAAAAAAAAAAAAAAAAAIBACAAAAAAAYAAAAAAAAAX19zdHViX2hlbHBlcgAAAF9fVEVYVAAAAAAAAAAAAACQDwAAAQAAABgAAAAAAAAAkA8AAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2NzdHJpbmcAAAAAAAAAX19URVhUAAAAAAAAAAAAAKgPAAABAAAADQAAAAAAAACoDwAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAF9fZWhfZnJhbWUAAAAAAABfX1RFWFQAAAAAAAAAAAAAuA8AAAEAAABIAAAAAAAAALgPAAADAAAAAAAAAAAAAAALAABgAAAAAAAAAAAAAAAAGQAAADgBAABfX0RBVEEAAAAAAAAAAAAAABAAAAEAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAAAAAHAAAAAwAAAAMAAAAAAAAAX19kYXRhAAAAAAAAAAAAAF9fREFUQQAAAAAAAAAAAAAAEAAAAQAAABwAAAAAAAAAABAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABfX2R5bGQAAAAAAAAAAAAAX19EQVRBAAAAAAAAAAAAACAQAAABAAAAOAAAAAAAAAAgEAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF9fbGFfc3ltYm9sX3B0cgBfX0RBVEEAAAAAAAAAAAAAWBAAAAEAAAAQAAAAAAAAAFgQAAACAAAAAAAAAAAAAAAHAAAAAgAAAAAAAAAAAAAAGQAAAEgAAABfX0xJTktFRElUAAAAAAAAACAAAAEAAAAAEAAAAAAAAAAgAAAAAAAAQAEAAAAAAAAHAAAAAQAAAAAAAAAAAAAAAgAAABgAAAAAIAAACwAAAMAgAACAAAAACwAAAFAAAAAAAAAAAgAAAAIAAAAHAAAACQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwIAAABAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAIAAAAAwAAAAvdXNyL2xpYi9keWxkAAAAAAAAABsAAAAYAAAAOyS4cg5FdtQoqu6JsMEhXQUAAAC4AAAABAAAACoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQPAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAOAAAABgAAAACAAAAAAABAAAAAQAvdXNyL2xpYi9saWJnY2Nfcy4xLmR5bGliAAAAAAAAAAwAAAA4AAAAGAAAAAIAAAAEAW8AAAABAC91c3IvbGliL2xpYlN5c3RlbS5CLmR5bGliAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqAEiJ5UiD5PBIi30ISI11EIn6g8IBweIDSAHySInR6wRIg8EISIM5AHX2SIPBCOgiAAAAicfoMgAAAPRBU0yNHafw//9BU/8lvwAAAA8fAP8lvgAAAFVIieVIjT0zAAAA6A0AAAC4AAAAAMnD/yXRAAAA/yXTAAAAAAAATI0dwQAAAOm0////TI0dvQAAAOmo////aGVsbG8sIHdvcmxkAAAAABQAAAAAAAAAAXpSAAF4EAEQDAcIkAEAACwAAAAcAAAAkv////////8XAAAAAAAAAAAEAQAAAA4QhgIEAwAAAA0GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDAX/9/AAAIEMBf/38AAAAAAAABAAAAGBAAAAEAAAAQEAAAAQAAAAgQAAABAAAAABAAAAEAAACQDwAAAQAAAJwPAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAHgEAAFAPAAABAAAAGwAAAB4BAABkDwAAAQAAAC4AAAAPBgAAGBAAAAEAAAA2AAAADwYAABAQAAABAAAAPgAAAA8GAAAAEAAAAQAAAEoAAAADABAAAAAAAAEAAABeAAAADwYAAAgQAAABAAAAZwAAAA8BAABqDwAAAQAAAG0AAAAPAQAAFA8AAAEAAABzAAAAAQABAgAAAAAAAAAAeQAAAAEAAQIAAAAAAAAAAAkAAAAKAAAACQAAAAoAAAAgAGR5bGRfc3R1Yl9iaW5kaW5nX2hlbHBlcgBfX2R5bGRfZnVuY19sb29rdXAAX05YQXJnYwBfTlhBcmd2AF9fX3Byb2duYW1lAF9fbWhfZXhlY3V0ZV9oZWFkZXIAX2Vudmlyb24AX21haW4Ac3RhcnQAX2V4aXQAX3B1dHMAAA== diff --git a/libgo/go/debug/pe/file.go b/libgo/go/debug/pe/file.go index 58814162bcf..7d763fff19d 100644 --- a/libgo/go/debug/pe/file.go +++ b/libgo/go/debug/pe/file.go @@ -58,11 +58,6 @@ func (f *File) Close() error { return err } -var ( - sizeofOptionalHeader32 = uint16(binary.Size(OptionalHeader32{})) - sizeofOptionalHeader64 = uint16(binary.Size(OptionalHeader64{})) -) - // TODO(brainman): add Load function, as a replacement for NewFile, that does not call removeAuxSymbols (for performance) // NewFile creates a new File for accessing a PE binary in an underlying reader. @@ -114,31 +109,17 @@ func NewFile(r io.ReaderAt) (*File, error) { return nil, err } + // Seek past file header. + _, err = sr.Seek(base+int64(binary.Size(f.FileHeader)), seekStart) + if err != nil { + return nil, fmt.Errorf("failure to seek past the file header: %v", err) + } + // Read optional header. - sr.Seek(base, seekStart) - if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil { + f.OptionalHeader, err = readOptionalHeader(sr, f.FileHeader.SizeOfOptionalHeader) + if err != nil { return nil, err } - var oh32 OptionalHeader32 - var oh64 OptionalHeader64 - switch f.FileHeader.SizeOfOptionalHeader { - case sizeofOptionalHeader32: - if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil { - return nil, err - } - if oh32.Magic != 0x10b { // PE32 - return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic) - } - f.OptionalHeader = &oh32 - case sizeofOptionalHeader64: - if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil { - return nil, err - } - if oh64.Magic != 0x20b { // PE32+ - return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic) - } - f.OptionalHeader = &oh64 - } // Process sections. f.Sections = make([]*Section, f.FileHeader.NumberOfSections) @@ -453,3 +434,168 @@ type FormatError struct { func (e *FormatError) Error() string { return "unknown error" } + +// readOptionalHeader accepts a io.ReadSeeker pointing to optional header in the PE file +// and its size as seen in the file header. +// It parses the given size of bytes and returns optional header. It infers whether the +// bytes being parsed refer to 32 bit or 64 bit version of optional header. +func readOptionalHeader(r io.ReadSeeker, sz uint16) (interface{}, error) { + // If optional header size is 0, return empty optional header. + if sz == 0 { + return nil, nil + } + + var ( + // First couple of bytes in option header state its type. + // We need to read them first to determine the type and + // validity of optional header. + ohMagic uint16 + ohMagicSz = binary.Size(ohMagic) + ) + + // If optional header size is greater than 0 but less than its magic size, return error. + if sz < uint16(ohMagicSz) { + return nil, fmt.Errorf("optional header size is less than optional header magic size") + } + + // read reads from io.ReadSeeke, r, into data. + var err error + read := func(data interface{}) bool { + err = binary.Read(r, binary.LittleEndian, data) + return err == nil + } + + if !read(&ohMagic) { + return nil, fmt.Errorf("failure to read optional header magic: %v", err) + + } + + switch ohMagic { + case 0x10b: // PE32 + var ( + oh32 OptionalHeader32 + // There can be 0 or more data directories. So the minimum size of optional + // header is calculated by subtracting oh32.DataDirectory size from oh32 size. + oh32MinSz = binary.Size(oh32) - binary.Size(oh32.DataDirectory) + ) + + if sz < uint16(oh32MinSz) { + return nil, fmt.Errorf("optional header size(%d) is less minimum size (%d) of PE32 optional header", sz, oh32MinSz) + } + + // Init oh32 fields + oh32.Magic = ohMagic + if !read(&oh32.MajorLinkerVersion) || + !read(&oh32.MinorLinkerVersion) || + !read(&oh32.SizeOfCode) || + !read(&oh32.SizeOfInitializedData) || + !read(&oh32.SizeOfUninitializedData) || + !read(&oh32.AddressOfEntryPoint) || + !read(&oh32.BaseOfCode) || + !read(&oh32.BaseOfData) || + !read(&oh32.ImageBase) || + !read(&oh32.SectionAlignment) || + !read(&oh32.FileAlignment) || + !read(&oh32.MajorOperatingSystemVersion) || + !read(&oh32.MinorOperatingSystemVersion) || + !read(&oh32.MajorImageVersion) || + !read(&oh32.MinorImageVersion) || + !read(&oh32.MajorSubsystemVersion) || + !read(&oh32.MinorSubsystemVersion) || + !read(&oh32.Win32VersionValue) || + !read(&oh32.SizeOfImage) || + !read(&oh32.SizeOfHeaders) || + !read(&oh32.CheckSum) || + !read(&oh32.Subsystem) || + !read(&oh32.DllCharacteristics) || + !read(&oh32.SizeOfStackReserve) || + !read(&oh32.SizeOfStackCommit) || + !read(&oh32.SizeOfHeapReserve) || + !read(&oh32.SizeOfHeapCommit) || + !read(&oh32.LoaderFlags) || + !read(&oh32.NumberOfRvaAndSizes) { + return nil, fmt.Errorf("failure to read PE32 optional header: %v", err) + } + + dd, err := readDataDirectories(r, sz-uint16(oh32MinSz), oh32.NumberOfRvaAndSizes) + if err != nil { + return nil, err + } + + copy(oh32.DataDirectory[:], dd) + + return &oh32, nil + case 0x20b: // PE32+ + var ( + oh64 OptionalHeader64 + // There can be 0 or more data directories. So the minimum size of optional + // header is calculated by subtracting oh64.DataDirectory size from oh64 size. + oh64MinSz = binary.Size(oh64) - binary.Size(oh64.DataDirectory) + ) + + if sz < uint16(oh64MinSz) { + return nil, fmt.Errorf("optional header size(%d) is less minimum size (%d) for PE32+ optional header", sz, oh64MinSz) + } + + // Init oh64 fields + oh64.Magic = ohMagic + if !read(&oh64.MajorLinkerVersion) || + !read(&oh64.MinorLinkerVersion) || + !read(&oh64.SizeOfCode) || + !read(&oh64.SizeOfInitializedData) || + !read(&oh64.SizeOfUninitializedData) || + !read(&oh64.AddressOfEntryPoint) || + !read(&oh64.BaseOfCode) || + !read(&oh64.ImageBase) || + !read(&oh64.SectionAlignment) || + !read(&oh64.FileAlignment) || + !read(&oh64.MajorOperatingSystemVersion) || + !read(&oh64.MinorOperatingSystemVersion) || + !read(&oh64.MajorImageVersion) || + !read(&oh64.MinorImageVersion) || + !read(&oh64.MajorSubsystemVersion) || + !read(&oh64.MinorSubsystemVersion) || + !read(&oh64.Win32VersionValue) || + !read(&oh64.SizeOfImage) || + !read(&oh64.SizeOfHeaders) || + !read(&oh64.CheckSum) || + !read(&oh64.Subsystem) || + !read(&oh64.DllCharacteristics) || + !read(&oh64.SizeOfStackReserve) || + !read(&oh64.SizeOfStackCommit) || + !read(&oh64.SizeOfHeapReserve) || + !read(&oh64.SizeOfHeapCommit) || + !read(&oh64.LoaderFlags) || + !read(&oh64.NumberOfRvaAndSizes) { + return nil, fmt.Errorf("failure to read PE32+ optional header: %v", err) + } + + dd, err := readDataDirectories(r, sz-uint16(oh64MinSz), oh64.NumberOfRvaAndSizes) + if err != nil { + return nil, err + } + + copy(oh64.DataDirectory[:], dd) + + return &oh64, nil + default: + return nil, fmt.Errorf("optional header has unexpected Magic of 0x%x", ohMagic) + } +} + +// readDataDirectories accepts a io.ReadSeeker pointing to data directories in the PE file, +// its size and number of data directories as seen in optional header. +// It parses the given size of bytes and returns given number of data directories. +func readDataDirectories(r io.ReadSeeker, sz uint16, n uint32) ([]DataDirectory, error) { + ddSz := binary.Size(DataDirectory{}) + if uint32(sz) != n*uint32(ddSz) { + return nil, fmt.Errorf("size of data directories(%d) is inconsistent with number of data directories(%d)", sz, n) + } + + dd := make([]DataDirectory, n) + if err := binary.Read(r, binary.LittleEndian, dd); err != nil { + return nil, fmt.Errorf("failure to read data directories: %v", err) + } + + return dd, nil +} diff --git a/libgo/go/debug/pe/file_test.go b/libgo/go/debug/pe/file_test.go index 6c7fe13caf0..bc41be26691 100644 --- a/libgo/go/debug/pe/file_test.go +++ b/libgo/go/debug/pe/file_test.go @@ -211,6 +211,44 @@ var fileTests = []fileTest{ {".debug_ranges", 0xa70, 0x44000, 0xc00, 0x38a00, 0x0, 0x0, 0x0, 0x0, 0x42100040}, }, }, + { + // testdata/vmlinuz-4.15.0-47-generic is a trimmed down version of Linux Kernel image. + // The original Linux Kernel image is about 8M and it is not recommended to add such a big binary file to the repo. + // Moreover only a very small portion of the original Kernel image was being parsed by debug/pe package. + // In order to identify this portion, the original image was first parsed by modified debug/pe package. + // Modification essentially communicated reader's positions before and after parsing. + // Finally, bytes between those positions where written to a separate file, + // generating trimmed down version Linux Kernel image used in this test case. + file: "testdata/vmlinuz-4.15.0-47-generic", + hdr: FileHeader{0x8664, 0x4, 0x0, 0x0, 0x1, 0xa0, 0x206}, + opthdr: &OptionalHeader64{ + 0x20b, 0x2, 0x14, 0x7c0590, 0x0, 0x168f870, 0x4680, 0x200, 0x0, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e50000, 0x200, 0x7c3ab0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, + [16]DataDirectory{ + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x7c07a0, 0x778}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + }}, + sections: []*SectionHeader{ + {".setup", 0x41e0, 0x200, 0x41e0, 0x200, 0x0, 0x0, 0x0, 0x0, 0x60500020}, + {".reloc", 0x20, 0x43e0, 0x20, 0x43e0, 0x0, 0x0, 0x0, 0x0, 0x42100040}, + {".text", 0x7bc390, 0x4400, 0x7bc390, 0x4400, 0x0, 0x0, 0x0, 0x0, 0x60500020}, + {".bss", 0x168f870, 0x7c0790, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc8000080}, + }, + hasNoDwarfInfo: true, + }, } func isOptHdrEq(a, b interface{}) bool { @@ -629,51 +667,95 @@ func TestImportTableInUnknownSection(t *testing.T) { } } -func TestInvalidFormat(t *testing.T) { - crashers := [][]byte{ - // https://golang.org/issue/30250 - []byte("\x00\x00\x00\x0000000\x00\x00\x00\x00\x00\x00\x000000" + - "00000000000000000000" + - "000000000\x00\x00\x0000000000" + - "00000000000000000000" + - "0000000000000000"), - // https://golang.org/issue/30253 - []byte("L\x01\b\x00regi\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x0f\x03" + - "\v\x01\x02\x18\x00\x0e\x00\x00\x00\x1e\x00\x00\x00\x02\x00\x00\x80\x12\x00\x00" + - "\x00\x10\x00\x00\x00 \x00\x00\x00\x00@\x00\x00\x10\x00\x00\x00\x02\x00\x00" + - "\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00" + - "\x00\x04\x00\x00\x06S\x00\x00\x03\x00\x00\x00\x00\x00 \x00\x00\x10\x00\x00" + - "\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x00\x00`\x00\x00x\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x80\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8`\x00\x00|\x00\x00\x00" + - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "\x00\x00\x00\x00.text\x00\x00\x00d\f\x00\x00\x00\x10\x00\x00" + - "\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "`\x00P`.data\x00\x00\x00\x10\x00\x00\x00\x00 \x00\x00" + - "\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "@\x000\xc0.rdata\x00\x004\x01\x00\x00\x000\x00\x00" + - "\x00\x02\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "@\x000@.eh_fram\xa0\x03\x00\x00\x00@\x00\x00" + - "\x00\x04\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "@\x000@.bss\x00\x00\x00\x00`\x00\x00\x00\x00P\x00\x00" + - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + - "\x80\x000\xc0.idata\x00\x00x\x03\x00\x00\x00`\x00\x00" + - "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" + - "0\xc0.CRT\x00\x00\x00\x00\x18\x00\x00\x00\x00p\x00\x00\x00\x02" + - "\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" + - "0\xc0.tls\x00\x00\x00\x00 \x00\x00\x00\x00\x80\x00\x00\x00\x02" + - "\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\xc9" + - "H\x895\x1d"), - } - - for _, data := range crashers { - f, err := NewFile(bytes.NewReader(data)) - if err != nil { - t.Error(err) - } - f.ImportedSymbols() +func TestInvalidOptionalHeaderMagic(t *testing.T) { + // Files with invalid optional header magic should return error from NewFile() + // (see https://golang.org/issue/30250 and https://golang.org/issue/32126 for details). + // Input generated by gofuzz + data := []byte("\x00\x00\x00\x0000000\x00\x00\x00\x00\x00\x00\x000000" + + "00000000000000000000" + + "000000000\x00\x00\x0000000000" + + "00000000000000000000" + + "0000000000000000") + + _, err := NewFile(bytes.NewReader(data)) + if err == nil { + t.Fatal("NewFile succeeded unexpectedly") + } +} + +func TestImportedSymbolsNoPanicMissingOptionalHeader(t *testing.T) { + // https://golang.org/issue/30250 + // ImportedSymbols shouldn't panic if optional headers is missing + data, err := ioutil.ReadFile("testdata/gcc-amd64-mingw-obj") + if err != nil { + t.Fatal(err) + } + + f, err := NewFile(bytes.NewReader(data)) + if err != nil { + t.Fatal(err) + } + + if f.OptionalHeader != nil { + t.Fatal("expected f.OptionalHeader to be nil, received non-nil optional header") + } + + syms, err := f.ImportedSymbols() + if err != nil { + t.Fatal(err) + } + + if len(syms) != 0 { + t.Fatalf("expected len(syms) == 0, received len(syms) = %d", len(syms)) + } + +} + +func TestImportedSymbolsNoPanicWithSliceOutOfBound(t *testing.T) { + // https://golang.org/issue/30253 + // ImportedSymbols shouldn't panic with slice out of bounds + // Input generated by gofuzz + data := []byte("L\x01\b\x00regi\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x0f\x03" + + "\v\x01\x02\x18\x00\x0e\x00\x00\x00\x1e\x00\x00\x00\x02\x00\x00\x80\x12\x00\x00" + + "\x00\x10\x00\x00\x00 \x00\x00\x00\x00@\x00\x00\x10\x00\x00\x00\x02\x00\x00" + + "\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00" + + "\x00\x04\x00\x00\x06S\x00\x00\x03\x00\x00\x00\x00\x00 \x00\x00\x10\x00\x00" + + "\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00`\x00\x00x\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x80\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8`\x00\x00|\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00.text\x00\x00\x00d\f\x00\x00\x00\x10\x00\x00" + + "\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "`\x00P`.data\x00\x00\x00\x10\x00\x00\x00\x00 \x00\x00" + + "\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "@\x000\xc0.rdata\x00\x004\x01\x00\x00\x000\x00\x00" + + "\x00\x02\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "@\x000@.eh_fram\xa0\x03\x00\x00\x00@\x00\x00" + + "\x00\x04\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "@\x000@.bss\x00\x00\x00\x00`\x00\x00\x00\x00P\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x80\x000\xc0.idata\x00\x00x\x03\x00\x00\x00`\x00\x00" + + "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" + + "0\xc0.CRT\x00\x00\x00\x00\x18\x00\x00\x00\x00p\x00\x00\x00\x02" + + "\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" + + "0\xc0.tls\x00\x00\x00\x00 \x00\x00\x00\x00\x80\x00\x00\x00\x02" + + "\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\xc9" + + "H\x895\x1d") + + f, err := NewFile(bytes.NewReader(data)) + if err != nil { + t.Fatal(err) + } + + syms, err := f.ImportedSymbols() + if err != nil { + t.Fatal(err) + } + + if len(syms) != 0 { + t.Fatalf("expected len(syms) == 0, received len(syms) = %d", len(syms)) } } diff --git a/libgo/go/debug/pe/testdata/vmlinuz-4.15.0-47-generic b/libgo/go/debug/pe/testdata/vmlinuz-4.15.0-47-generic new file mode 100644 index 00000000000..d01cf61d05f Binary files /dev/null and b/libgo/go/debug/pe/testdata/vmlinuz-4.15.0-47-generic differ diff --git a/libgo/go/encoding/asn1/asn1.go b/libgo/go/encoding/asn1/asn1.go index 3cfd9d12764..fd4dd68021b 100644 --- a/libgo/go/encoding/asn1/asn1.go +++ b/libgo/go/encoding/asn1/asn1.go @@ -27,6 +27,7 @@ import ( "reflect" "strconv" "time" + "unicode/utf16" "unicode/utf8" ) @@ -475,6 +476,29 @@ func parseUTF8String(bytes []byte) (ret string, err error) { return string(bytes), nil } +// BMPString + +// parseBMPString parses an ASN.1 BMPString (Basic Multilingual Plane of +// ISO/IEC/ITU 10646-1) from the given byte slice and returns it. +func parseBMPString(bmpString []byte) (string, error) { + if len(bmpString)%2 != 0 { + return "", errors.New("pkcs12: odd-length BMP string") + } + + // Strip terminator if present. + if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 { + bmpString = bmpString[:l-2] + } + + s := make([]uint16, 0, len(bmpString)/2) + for len(bmpString) > 0 { + s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1])) + bmpString = bmpString[2:] + } + + return string(utf16.Decode(s)), nil +} + // A RawValue represents an undecoded ASN.1 object. type RawValue struct { Class, Tag int @@ -589,7 +613,7 @@ func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type return } switch t.tag { - case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString: + case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString: // We pretend that various other string types are // PRINTABLE STRINGs so that a sequence of them can be // parsed into a []string. @@ -691,6 +715,8 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam result, err = parseGeneralizedTime(innerBytes) case TagOctetString: result = innerBytes + case TagBMPString: + result, err = parseBMPString(innerBytes) default: // If we don't know how to handle the type, we just leave Value as nil. } @@ -759,7 +785,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam if universalTag == TagPrintableString { if t.class == ClassUniversal { switch t.tag { - case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString: + case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString: universalTag = t.tag } } else if params.stringType != 0 { @@ -957,6 +983,9 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam // that allow the encoding to change midstring and // such. We give up and pass it as an 8-bit string. v, err = parseT61String(innerBytes) + case TagBMPString: + v, err = parseBMPString(innerBytes) + default: err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)} } diff --git a/libgo/go/encoding/asn1/asn1_test.go b/libgo/go/encoding/asn1/asn1_test.go index f0a54e0cb2e..d5649bff9fa 100644 --- a/libgo/go/encoding/asn1/asn1_test.go +++ b/libgo/go/encoding/asn1/asn1_test.go @@ -6,6 +6,7 @@ package asn1 import ( "bytes" + "encoding/hex" "fmt" "math" "math/big" @@ -1096,3 +1097,35 @@ func TestTaggedRawValue(t *testing.T) { } } } + +var bmpStringTests = []struct { + decoded string + encodedHex string +}{ + {"", "0000"}, + // Example from https://tools.ietf.org/html/rfc7292#appendix-B. + {"Beavis", "0042006500610076006900730000"}, + // Some characters from the "Letterlike Symbols Unicode block". + {"\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000"}, +} + +func TestBMPString(t *testing.T) { + for i, test := range bmpStringTests { + encoded, err := hex.DecodeString(test.encodedHex) + if err != nil { + t.Fatalf("#%d: failed to decode from hex string", i) + } + + decoded, err := parseBMPString(encoded) + + if err != nil { + t.Errorf("#%d: decoding output gave an error: %s", i, err) + continue + } + + if decoded != test.decoded { + t.Errorf("#%d: decoding output resulted in %q, but it should have been %q", i, decoded, test.decoded) + continue + } + } +} diff --git a/libgo/go/encoding/asn1/common.go b/libgo/go/encoding/asn1/common.go index 255d1ebfa89..e2aa8bd9c57 100644 --- a/libgo/go/encoding/asn1/common.go +++ b/libgo/go/encoding/asn1/common.go @@ -37,6 +37,7 @@ const ( TagUTCTime = 23 TagGeneralizedTime = 24 TagGeneralString = 27 + TagBMPString = 30 ) // ASN.1 class types represent the namespace of the tag. diff --git a/libgo/go/encoding/base32/base32.go b/libgo/go/encoding/base32/base32.go index e14d2d49871..2f7d3637e5a 100644 --- a/libgo/go/encoding/base32/base32.go +++ b/libgo/go/encoding/base32/base32.go @@ -6,10 +6,8 @@ package base32 import ( - "bytes" "io" "strconv" - "strings" ) /* @@ -62,13 +60,6 @@ var StdEncoding = NewEncoding(encodeStd) // It is typically used in DNS. var HexEncoding = NewEncoding(encodeHex) -var removeNewlinesMapper = func(r rune) rune { - if r == '\r' || r == '\n' { - return -1 - } - return r -} - // WithPadding creates a new encoding identical to enc except // with a specified padding character, or NoPadding to disable padding. // The padding character must not be '\r' or '\n', must not @@ -302,7 +293,7 @@ func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) { // We have reached the end and are missing padding return n, false, CorruptInputError(olen - len(src) - j) } - // We have reached the end and are not expecing any padding + // We have reached the end and are not expecting any padding dlen, end = j, true break } @@ -372,17 +363,18 @@ func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) { // number of bytes successfully written and CorruptInputError. // New line characters (\r and \n) are ignored. func (enc *Encoding) Decode(dst, src []byte) (n int, err error) { - src = bytes.Map(removeNewlinesMapper, src) - n, _, err = enc.decode(dst, src) + buf := make([]byte, len(src)) + l := stripNewlines(buf, src) + n, _, err = enc.decode(dst, buf[:l]) return } // DecodeString returns the bytes represented by the base32 string s. func (enc *Encoding) DecodeString(s string) ([]byte, error) { - s = strings.Map(removeNewlinesMapper, s) - dbuf := make([]byte, enc.DecodedLen(len(s))) - n, _, err := enc.decode(dbuf, []byte(s)) - return dbuf[:n], err + buf := []byte(s) + l := stripNewlines(buf, buf) + n, _, err := enc.decode(buf, buf[:l]) + return buf[:n], err } type decoder struct { @@ -497,18 +489,25 @@ type newlineFilteringReader struct { wrapped io.Reader } +// stripNewlines removes newline characters and returns the number +// of non-newline characters copied to dst. +func stripNewlines(dst, src []byte) int { + offset := 0 + for _, b := range src { + if b == '\r' || b == '\n' { + continue + } + dst[offset] = b + offset++ + } + return offset +} + func (r *newlineFilteringReader) Read(p []byte) (int, error) { n, err := r.wrapped.Read(p) for n > 0 { - offset := 0 - for i, b := range p[0:n] { - if b != '\r' && b != '\n' { - if i != offset { - p[offset] = b - } - offset++ - } - } + s := p[0:n] + offset := stripNewlines(s, s) if err != nil || offset > 0 { return offset, err } diff --git a/libgo/go/encoding/base32/base32_test.go b/libgo/go/encoding/base32/base32_test.go index eb14f1eb26a..0b611db0b24 100644 --- a/libgo/go/encoding/base32/base32_test.go +++ b/libgo/go/encoding/base32/base32_test.go @@ -445,6 +445,15 @@ LNEBUWIIDFON2CA3DBMJXXE5LNFY== } } +func BenchmarkEncode(b *testing.B) { + data := make([]byte, 8192) + buf := make([]byte, StdEncoding.EncodedLen(len(data))) + b.SetBytes(int64(len(data))) + for i := 0; i < b.N; i++ { + StdEncoding.Encode(buf, data) + } +} + func BenchmarkEncodeToString(b *testing.B) { data := make([]byte, 8192) b.SetBytes(int64(len(data))) @@ -453,6 +462,15 @@ func BenchmarkEncodeToString(b *testing.B) { } } +func BenchmarkDecode(b *testing.B) { + data := make([]byte, StdEncoding.EncodedLen(8192)) + StdEncoding.Encode(data, make([]byte, 8192)) + buf := make([]byte, 8192) + b.SetBytes(int64(len(data))) + for i := 0; i < b.N; i++ { + StdEncoding.Decode(buf, data) + } +} func BenchmarkDecodeString(b *testing.B) { data := StdEncoding.EncodeToString(make([]byte, 8192)) b.SetBytes(int64(len(data))) diff --git a/libgo/go/encoding/base64/base64.go b/libgo/go/encoding/base64/base64.go index 082210198f3..690d3ce0421 100644 --- a/libgo/go/encoding/base64/base64.go +++ b/libgo/go/encoding/base64/base64.go @@ -86,6 +86,9 @@ func (enc Encoding) WithPadding(padding rune) *Encoding { // Strict creates a new encoding identical to enc except with // strict decoding enabled. In this mode, the decoder requires that // trailing padding bits are zero, as described in RFC 4648 section 3.5. +// +// Note that the input is still malleable, as new line characters +// (CR and LF) are still ignored. func (enc Encoding) Strict() *Encoding { enc.strict = true return &enc diff --git a/libgo/go/encoding/binary/binary.go b/libgo/go/encoding/binary/binary.go index 8c2d1d9da47..a99ca019949 100644 --- a/libgo/go/encoding/binary/binary.go +++ b/libgo/go/encoding/binary/binary.go @@ -26,6 +26,7 @@ import ( "io" "math" "reflect" + "sync" ) // A ByteOrder specifies how to convert byte sequences into @@ -184,6 +185,10 @@ func Read(r io.Reader, order ByteOrder, data interface{}) error { *data = int64(order.Uint64(bs)) case *uint64: *data = order.Uint64(bs) + case *float32: + *data = math.Float32frombits(order.Uint32(bs)) + case *float64: + *data = math.Float64frombits(order.Uint64(bs)) case []bool: for i, x := range bs { // Easier to loop over the input for 8-bit values. data[i] = x != 0 @@ -218,8 +223,20 @@ func Read(r io.Reader, order ByteOrder, data interface{}) error { for i := range data { data[i] = order.Uint64(bs[8*i:]) } + case []float32: + for i := range data { + data[i] = math.Float32frombits(order.Uint32(bs[4*i:])) + } + case []float64: + for i := range data { + data[i] = math.Float64frombits(order.Uint64(bs[8*i:])) + } + default: + n = 0 // fast path doesn't apply + } + if n != 0 { + return nil } - return nil } // Fallback to reflect-based decoding. @@ -338,6 +355,22 @@ func Write(w io.Writer, order ByteOrder, data interface{}) error { for i, x := range v { order.PutUint64(bs[8*i:], x) } + case *float32: + order.PutUint32(bs, math.Float32bits(*v)) + case float32: + order.PutUint32(bs, math.Float32bits(v)) + case []float32: + for i, x := range v { + order.PutUint32(bs[4*i:], math.Float32bits(x)) + } + case *float64: + order.PutUint64(bs, math.Float64bits(*v)) + case float64: + order.PutUint64(bs, math.Float64bits(v)) + case []float64: + for i, x := range v { + order.PutUint64(bs[8*i:], math.Float64bits(x)) + } } _, err := w.Write(bs) return err @@ -363,18 +396,32 @@ func Size(v interface{}) int { return dataSize(reflect.Indirect(reflect.ValueOf(v))) } +var structSize sync.Map // map[reflect.Type]int + // dataSize returns the number of bytes the actual data represented by v occupies in memory. // For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice // it returns the length of the slice times the element size and does not count the memory // occupied by the header. If the type of v is not acceptable, dataSize returns -1. func dataSize(v reflect.Value) int { - if v.Kind() == reflect.Slice { + switch v.Kind() { + case reflect.Slice: if s := sizeof(v.Type().Elem()); s >= 0 { return s * v.Len() } return -1 + + case reflect.Struct: + t := v.Type() + if size, ok := structSize.Load(t); ok { + return size.(int) + } + size := sizeof(t) + structSize.Store(t, size) + return size + + default: + return sizeof(v.Type()) } - return sizeof(v.Type()) } // sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable. @@ -677,6 +724,14 @@ func intDataSize(data interface{}) int { return 8 * len(data) case []uint64: return 8 * len(data) + case float32, *float32: + return 4 + case float64, *float64: + return 8 + case []float32: + return 4 * len(data) + case []float64: + return 8 * len(data) } return 0 } diff --git a/libgo/go/encoding/binary/binary_test.go b/libgo/go/encoding/binary/binary_test.go index af402575e45..aeb4212ec2e 100644 --- a/libgo/go/encoding/binary/binary_test.go +++ b/libgo/go/encoding/binary/binary_test.go @@ -6,10 +6,13 @@ package binary import ( "bytes" + "fmt" "io" + "io/ioutil" "math" "reflect" "strings" + "sync" "testing" ) @@ -296,6 +299,58 @@ func TestBlankFields(t *testing.T) { } } +func TestSizeStructCache(t *testing.T) { + // Reset the cache, otherwise multiple test runs fail. + structSize = sync.Map{} + + count := func() int { + var i int + structSize.Range(func(_, _ interface{}) bool { + i++ + return true + }) + return i + } + + var total int + added := func() int { + delta := count() - total + total += delta + return delta + } + + type foo struct { + A uint32 + } + + type bar struct { + A Struct + B foo + C Struct + } + + testcases := []struct { + val interface{} + want int + }{ + {new(foo), 1}, + {new(bar), 1}, + {new(bar), 0}, + {new(struct{ A Struct }), 1}, + {new(struct{ A Struct }), 0}, + } + + for _, tc := range testcases { + if Size(tc.val) == -1 { + t.Fatalf("Can't get the size of %T", tc.val) + } + + if n := added(); n != tc.want { + t.Errorf("Sizing %T added %d entries to the cache, want %d", tc.val, n, tc.want) + } + } +} + // An attempt to read into a struct with an unexported field will // panic. This is probably not the best choice, but at this point // anything else would be an API change. @@ -397,6 +452,35 @@ func TestEarlyBoundsChecks(t *testing.T) { } } +func TestReadInvalidDestination(t *testing.T) { + testReadInvalidDestination(t, BigEndian) + testReadInvalidDestination(t, LittleEndian) +} + +func testReadInvalidDestination(t *testing.T, order ByteOrder) { + destinations := []interface{}{ + int8(0), + int16(0), + int32(0), + int64(0), + + uint8(0), + uint16(0), + uint32(0), + uint64(0), + + bool(false), + } + + for _, dst := range destinations { + err := Read(bytes.NewReader([]byte{1, 2, 3, 4, 5, 6, 7, 8}), order, dst) + want := fmt.Sprintf("binary.Read: invalid type %T", dst) + if err == nil || err.Error() != want { + t.Fatalf("for type %T: got %q; want %q", dst, err, want) + } + } +} + type byteSliceReader struct { remain []byte } @@ -436,6 +520,14 @@ func BenchmarkReadStruct(b *testing.B) { } } +func BenchmarkWriteStruct(b *testing.B) { + b.SetBytes(int64(Size(&s))) + b.ResetTimer() + for i := 0; i < b.N; i++ { + Write(ioutil.Discard, BigEndian, &s) + } +} + func BenchmarkReadInts(b *testing.B) { var ls Struct bsr := &byteSliceReader{} @@ -542,3 +634,75 @@ func BenchmarkLittleEndianPutUint64(b *testing.B) { LittleEndian.PutUint64(putbuf[:], uint64(i)) } } + +func BenchmarkReadFloats(b *testing.B) { + var ls Struct + bsr := &byteSliceReader{} + var r io.Reader = bsr + b.SetBytes(4 + 8) + b.ResetTimer() + for i := 0; i < b.N; i++ { + bsr.remain = big[30:] + Read(r, BigEndian, &ls.Float32) + Read(r, BigEndian, &ls.Float64) + } + b.StopTimer() + want := s + want.Int8 = 0 + want.Int16 = 0 + want.Int32 = 0 + want.Int64 = 0 + want.Uint8 = 0 + want.Uint16 = 0 + want.Uint32 = 0 + want.Uint64 = 0 + want.Complex64 = 0 + want.Complex128 = 0 + want.Array = [4]uint8{0, 0, 0, 0} + want.Bool = false + want.BoolArray = [4]bool{false, false, false, false} + if b.N > 0 && !reflect.DeepEqual(ls, want) { + b.Fatalf("struct doesn't match:\ngot %v;\nwant %v", ls, want) + } +} + +func BenchmarkWriteFloats(b *testing.B) { + buf := new(bytes.Buffer) + var w io.Writer = buf + b.SetBytes(4 + 8) + b.ResetTimer() + for i := 0; i < b.N; i++ { + buf.Reset() + Write(w, BigEndian, s.Float32) + Write(w, BigEndian, s.Float64) + } + b.StopTimer() + if b.N > 0 && !bytes.Equal(buf.Bytes(), big[30:30+4+8]) { + b.Fatalf("first half doesn't match: %x %x", buf.Bytes(), big[30:30+4+8]) + } +} + +func BenchmarkReadSlice1000Float32s(b *testing.B) { + bsr := &byteSliceReader{} + slice := make([]float32, 1000) + buf := make([]byte, len(slice)*4) + b.SetBytes(int64(len(buf))) + b.ResetTimer() + for i := 0; i < b.N; i++ { + bsr.remain = buf + Read(bsr, BigEndian, slice) + } +} + +func BenchmarkWriteSlice1000Float32s(b *testing.B) { + slice := make([]float32, 1000) + buf := new(bytes.Buffer) + var w io.Writer = buf + b.SetBytes(4 * 1000) + b.ResetTimer() + for i := 0; i < b.N; i++ { + buf.Reset() + Write(w, BigEndian, slice) + } + b.StopTimer() +} diff --git a/libgo/go/encoding/csv/fuzz.go b/libgo/go/encoding/csv/fuzz.go index dc33893dd74..8be21d5d289 100644 --- a/libgo/go/encoding/csv/fuzz.go +++ b/libgo/go/encoding/csv/fuzz.go @@ -17,13 +17,13 @@ func Fuzz(data []byte) int { buf := new(bytes.Buffer) for _, tt := range []Reader{ - Reader{}, - Reader{Comma: ';'}, - Reader{Comma: '\t'}, - Reader{LazyQuotes: true}, - Reader{TrimLeadingSpace: true}, - Reader{Comment: '#'}, - Reader{Comment: ';'}, + {}, + {Comma: ';'}, + {Comma: '\t'}, + {LazyQuotes: true}, + {TrimLeadingSpace: true}, + {Comment: '#'}, + {Comment: ';'}, } { r := NewReader(bytes.NewReader(data)) r.Comma = tt.Comma diff --git a/libgo/go/encoding/gob/codec_test.go b/libgo/go/encoding/gob/codec_test.go index 494abc9b913..f38e88b638a 100644 --- a/libgo/go/encoding/gob/codec_test.go +++ b/libgo/go/encoding/gob/codec_test.go @@ -591,7 +591,7 @@ func TestEndToEnd(t *testing.T) { B: 18, C: -5, M: map[string]*float64{"pi": &pi, "e": &e}, - M2: map[int]T3{4: T3{X: pi, Z: &meaning}, 10: T3{X: e, Z: &fingers}}, + M2: map[int]T3{4: {X: pi, Z: &meaning}, 10: {X: e, Z: &fingers}}, Mstring: map[string]string{"pi": "3.14", "e": "2.71"}, Mintptr: map[int]*int{meaning: &fingers, fingers: &meaning}, Mcomp: map[complex128]complex128{comp1: comp2, comp2: comp1}, diff --git a/libgo/go/encoding/gob/gobencdec_test.go b/libgo/go/encoding/gob/gobencdec_test.go index 41a06b26c87..6d2c8db42d0 100644 --- a/libgo/go/encoding/gob/gobencdec_test.go +++ b/libgo/go/encoding/gob/gobencdec_test.go @@ -707,7 +707,7 @@ func TestGobEncoderExtraIndirect(t *testing.T) { // Another bug: this caused a crash with the new Go1 Time type. // We throw in a gob-encoding array, to test another case of isZero, -// and a struct containing an nil interface, to test a third. +// and a struct containing a nil interface, to test a third. type isZeroBug struct { T time.Time S string diff --git a/libgo/go/encoding/json/bench_test.go b/libgo/go/encoding/json/bench_test.go index f2592e3dbdf..4a5fe7ec84e 100644 --- a/libgo/go/encoding/json/bench_test.go +++ b/libgo/go/encoding/json/bench_test.go @@ -297,6 +297,22 @@ func BenchmarkIssue10335(b *testing.B) { }) } +func BenchmarkIssue34127(b *testing.B) { + b.ReportAllocs() + j := struct { + Bar string `json:"bar,string"` + }{ + Bar: `foobar`, + } + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + if _, err := Marshal(&j); err != nil { + b.Fatal(err) + } + } + }) +} + func BenchmarkUnmapped(b *testing.B) { b.ReportAllocs() j := []byte(`{"s": "hello", "y": 2, "o": {"x": 0}, "a": [1, 99, {"x": 1}]}`) @@ -373,3 +389,22 @@ func BenchmarkTypeFieldsCache(b *testing.B) { }) } } + +func BenchmarkEncodeMarshaler(b *testing.B) { + b.ReportAllocs() + + m := struct { + A int + B RawMessage + }{} + + b.RunParallel(func(pb *testing.PB) { + enc := NewEncoder(ioutil.Discard) + + for pb.Next() { + if err := enc.Encode(&m); err != nil { + b.Fatal("Encode:", err) + } + } + }) +} diff --git a/libgo/go/encoding/json/decode.go b/libgo/go/encoding/json/decode.go index cbd71acfc6c..b43484692e1 100644 --- a/libgo/go/encoding/json/decode.go +++ b/libgo/go/encoding/json/decode.go @@ -72,7 +72,8 @@ import ( // use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal // reuses the existing map, keeping existing entries. Unmarshal then stores // key-value pairs from the JSON object into the map. The map's key type must -// either be a string, an integer, or implement encoding.TextUnmarshaler. +// either be any string type, an integer, implement json.Unmarshaler, or +// implement encoding.TextUnmarshaler. // // If a JSON value is not appropriate for a given target type, // or if a JSON number overflows the target type, Unmarshal @@ -199,66 +200,6 @@ func (n Number) Int64() (int64, error) { return strconv.ParseInt(string(n), 10, 64) } -// isValidNumber reports whether s is a valid JSON number literal. -func isValidNumber(s string) bool { - // This function implements the JSON numbers grammar. - // See https://tools.ietf.org/html/rfc7159#section-6 - // and https://json.org/number.gif - - if s == "" { - return false - } - - // Optional - - if s[0] == '-' { - s = s[1:] - if s == "" { - return false - } - } - - // Digits - switch { - default: - return false - - case s[0] == '0': - s = s[1:] - - case '1' <= s[0] && s[0] <= '9': - s = s[1:] - for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { - s = s[1:] - } - } - - // . followed by 1 or more digits. - if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { - s = s[2:] - for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { - s = s[1:] - } - } - - // e or E followed by an optional - or + and - // 1 or more digits. - if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { - s = s[1:] - if s[0] == '+' || s[0] == '-' { - s = s[1:] - if s == "" { - return false - } - } - for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { - s = s[1:] - } - } - - // Make sure we are at the end. - return s == "" -} - // decodeState represents the state while decoding a JSON value. type decodeState struct { data []byte @@ -272,6 +213,9 @@ type decodeState struct { savedError error useNumber bool disallowUnknownFields bool + // safeUnquote is the number of current string literal bytes that don't + // need to be unquoted. When negative, no bytes need unquoting. + safeUnquote int } // readIndex returns the position of the last byte read. @@ -373,13 +317,27 @@ func (d *decodeState) rescanLiteral() { Switch: switch data[i-1] { case '"': // string + // safeUnquote is initialized at -1, which means that all bytes + // checked so far can be unquoted at a later time with no work + // at all. When reaching the closing '"', if safeUnquote is + // still -1, all bytes can be unquoted with no work. Otherwise, + // only those bytes up until the first '\\' or non-ascii rune + // can be safely unquoted. + safeUnquote := -1 for ; i < len(data); i++ { - switch data[i] { - case '\\': + if c := data[i]; c == '\\' { + if safeUnquote < 0 { // first unsafe byte + safeUnquote = int(i - d.off) + } i++ // escaped char - case '"': + } else if c == '"' { + d.safeUnquote = safeUnquote i++ // tokenize the closing quote too break Switch + } else if c >= utf8.RuneSelf { + if safeUnquote < 0 { // first unsafe byte + safeUnquote = int(i - d.off) + } } } case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': // number @@ -475,8 +433,9 @@ func (d *decodeState) valueQuoted() interface{} { // indirect walks down v allocating pointers as needed, // until it gets to a non-pointer. -// if it encounters an Unmarshaler, indirect stops and returns that. -// if decodingNull is true, indirect stops at the last pointer so it can be set to nil. +// If it encounters an Unmarshaler, indirect stops and returns that. +// If decodingNull is true, indirect stops at the first settable pointer so it +// can be set to nil. func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) { // Issue #24153 indicates that it is generally not a guaranteed property // that you may round-trip a reflect.Value by calling Value.Addr().Elem() @@ -515,7 +474,7 @@ func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnm break } - if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() { + if decodingNull && v.CanSet() { break } @@ -732,7 +691,7 @@ func (d *decodeState) object(v reflect.Value) error { start := d.readIndex() d.rescanLiteral() item := d.data[start:d.readIndex()] - key, ok := unquoteBytes(item) + key, ok := d.unquoteBytes(item) if !ok { panic(phasePanicMsg) } @@ -831,14 +790,14 @@ func (d *decodeState) object(v reflect.Value) error { kt := t.Key() var kv reflect.Value switch { - case kt.Kind() == reflect.String: - kv = reflect.ValueOf(key).Convert(kt) case reflect.PtrTo(kt).Implements(textUnmarshalerType): kv = reflect.New(kt) if err := d.literalStore(item, kv, true); err != nil { return err } kv = kv.Elem() + case kt.Kind() == reflect.String: + kv = reflect.ValueOf(key).Convert(kt) default: switch kt.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: @@ -933,7 +892,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool d.saveError(&UnmarshalTypeError{Value: val, Type: v.Type(), Offset: int64(d.readIndex())}) return nil } - s, ok := unquoteBytes(item) + s, ok := d.unquoteBytes(item) if !ok { if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) @@ -984,7 +943,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool } case '"': // string - s, ok := unquoteBytes(item) + s, ok := d.unquoteBytes(item) if !ok { if fromQuoted { return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()) @@ -1007,6 +966,9 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool } v.SetBytes(b[:n]) case reflect.String: + if v.Type() == numberType && !isValidNumber(string(s)) { + return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item) + } v.SetString(string(s)) case reflect.Interface: if v.NumMethod() == 0 { @@ -1027,10 +989,9 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool switch v.Kind() { default: if v.Kind() == reflect.String && v.Type() == numberType { + // s must be a valid number, because it's + // already been tokenized. v.SetString(s) - if !isValidNumber(s) { - return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item) - } break } if fromQuoted { @@ -1142,7 +1103,7 @@ func (d *decodeState) objectInterface() map[string]interface{} { start := d.readIndex() d.rescanLiteral() item := d.data[start:d.readIndex()] - key, ok := unquote(item) + key, ok := d.unquote(item) if !ok { panic(phasePanicMsg) } @@ -1191,7 +1152,7 @@ func (d *decodeState) literalInterface() interface{} { return c == 't' case '"': // string - s, ok := unquote(item) + s, ok := d.unquote(item) if !ok { panic(phasePanicMsg) } @@ -1234,38 +1195,26 @@ func getu4(s []byte) rune { // unquote converts a quoted JSON string literal s into an actual string t. // The rules are different than for Go, so cannot use strconv.Unquote. -func unquote(s []byte) (t string, ok bool) { - s, ok = unquoteBytes(s) +// The first byte in s must be '"'. +func (d *decodeState) unquote(s []byte) (t string, ok bool) { + s, ok = d.unquoteBytes(s) t = string(s) return } -func unquoteBytes(s []byte) (t []byte, ok bool) { - if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' { +func (d *decodeState) unquoteBytes(s []byte) (t []byte, ok bool) { + // We already know that s[0] == '"'. However, we don't know that the + // closing quote exists in all cases, such as when the string is nested + // via the ",string" option. + if len(s) < 2 || s[len(s)-1] != '"' { return } s = s[1 : len(s)-1] - // Check for unusual characters. If there are none, - // then no unquoting is needed, so return a slice of the - // original bytes. - r := 0 - for r < len(s) { - c := s[r] - if c == '\\' || c == '"' || c < ' ' { - break - } - if c < utf8.RuneSelf { - r++ - continue - } - rr, size := utf8.DecodeRune(s[r:]) - if rr == utf8.RuneError && size == 1 { - break - } - r += size - } - if r == len(s) { + // If there are no unusual characters, no unquoting is needed, so return + // a slice of the original bytes. + r := d.safeUnquote + if r == -1 { return s, true } diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index 3f25893b419..498bd97b46e 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -145,23 +145,15 @@ func (u8 *u8marshal) UnmarshalText(b []byte) error { var _ encoding.TextUnmarshaler = (*u8marshal)(nil) var ( - um0, um1 unmarshaler // target2 of unmarshaling - ump = &um1 umtrue = unmarshaler{true} umslice = []unmarshaler{{true}} - umslicep = new([]unmarshaler) umstruct = ustruct{unmarshaler{true}} - um0T, um1T unmarshalerText // target2 of unmarshaling - umpType = &um1T - umtrueXY = unmarshalerText{"x", "y"} - umsliceXY = []unmarshalerText{{"x", "y"}} - umslicepType = new([]unmarshalerText) - umstructType = new(ustructText) - umstructXY = ustructText{unmarshalerText{"x", "y"}} + umtrueXY = unmarshalerText{"x", "y"} + umsliceXY = []unmarshalerText{{"x", "y"}} + umstructXY = ustructText{unmarshalerText{"x", "y"}} - ummapType = map[unmarshalerText]bool{} - ummapXY = map[unmarshalerText]bool{{"x", "y"}: true} + ummapXY = map[unmarshalerText]bool{{"x", "y"}: true} ) // Test data structures for anonymous fields. @@ -279,9 +271,6 @@ type unexportedWithMethods struct{} func (unexportedWithMethods) F() {} -func sliceAddr(x []int) *[]int { return &x } -func mapAddr(x map[string]int) *map[string]int { return &x } - type byteWithMarshalJSON byte func (b byteWithMarshalJSON) MarshalJSON() ([]byte, error) { @@ -400,7 +389,7 @@ type mapStringToStringData struct { type unmarshalTest struct { in string - ptr interface{} + ptr interface{} // new(type) out interface{} err error useNumber bool @@ -412,6 +401,11 @@ type B struct { B bool `json:",string"` } +type DoublePtr struct { + I **int + J **int +} + var unmarshalTests = []unmarshalTest{ // basic types {in: `true`, ptr: new(bool), out: true}, @@ -459,6 +453,7 @@ var unmarshalTests = []unmarshalTest{ {in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}}, {in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true}, {in: `[2, 3`, err: &SyntaxError{msg: "unexpected end of JSON input", Offset: 5}}, + {in: `{"F3": -}`, ptr: new(V), out: V{F3: Number("-")}, err: &SyntaxError{msg: "invalid character '}' in numeric literal", Offset: 9}}, // raw value errors {in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}}, @@ -493,18 +488,18 @@ var unmarshalTests = []unmarshalTest{ {in: pallValueCompact, ptr: new(*All), out: &pallValue}, // unmarshal interface test - {in: `{"T":false}`, ptr: &um0, out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called - {in: `{"T":false}`, ptr: &ump, out: &umtrue}, - {in: `[{"T":false}]`, ptr: &umslice, out: umslice}, - {in: `[{"T":false}]`, ptr: &umslicep, out: &umslice}, - {in: `{"M":{"T":"x:y"}}`, ptr: &umstruct, out: umstruct}, + {in: `{"T":false}`, ptr: new(unmarshaler), out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called + {in: `{"T":false}`, ptr: new(*unmarshaler), out: &umtrue}, + {in: `[{"T":false}]`, ptr: new([]unmarshaler), out: umslice}, + {in: `[{"T":false}]`, ptr: new(*[]unmarshaler), out: &umslice}, + {in: `{"M":{"T":"x:y"}}`, ptr: new(ustruct), out: umstruct}, // UnmarshalText interface test - {in: `"x:y"`, ptr: &um0T, out: umtrueXY}, - {in: `"x:y"`, ptr: &umpType, out: &umtrueXY}, - {in: `["x:y"]`, ptr: &umsliceXY, out: umsliceXY}, - {in: `["x:y"]`, ptr: &umslicepType, out: &umsliceXY}, - {in: `{"M":"x:y"}`, ptr: umstructType, out: umstructXY}, + {in: `"x:y"`, ptr: new(unmarshalerText), out: umtrueXY}, + {in: `"x:y"`, ptr: new(*unmarshalerText), out: &umtrueXY}, + {in: `["x:y"]`, ptr: new([]unmarshalerText), out: umsliceXY}, + {in: `["x:y"]`, ptr: new(*[]unmarshalerText), out: &umsliceXY}, + {in: `{"M":"x:y"}`, ptr: new(ustructText), out: umstructXY}, // integer-keyed map test { @@ -579,15 +574,9 @@ var unmarshalTests = []unmarshalTest{ }, // Map keys can be encoding.TextUnmarshalers. - {in: `{"x:y":true}`, ptr: &ummapType, out: ummapXY}, + {in: `{"x:y":true}`, ptr: new(map[unmarshalerText]bool), out: ummapXY}, // If multiple values for the same key exists, only the most recent value is used. - {in: `{"x:y":false,"x:y":true}`, ptr: &ummapType, out: ummapXY}, - - // Overwriting of data. - // This is different from package xml, but it's what we've always done. - // Now documented and tested. - {in: `[2]`, ptr: sliceAddr([]int{1}), out: []int{2}}, - {in: `{"key": 2}`, ptr: mapAddr(map[string]int{"old": 0, "key": 1}), out: map[string]int{"key": 2}}, + {in: `{"x:y":false,"x:y":true}`, ptr: new(map[unmarshalerText]bool), out: ummapXY}, { in: `{ @@ -672,6 +661,11 @@ var unmarshalTests = []unmarshalTest{ err: fmt.Errorf("json: unknown field \"X\""), disallowUnknownFields: true, }, + { + in: `{"I": 0, "I": null, "J": null}`, + ptr: new(DoublePtr), + out: DoublePtr{I: nil, J: nil}, + }, // invalid UTF-8 is coerced to valid UTF-8. { @@ -713,19 +707,19 @@ var unmarshalTests = []unmarshalTest{ // Used to be issue 8305, but time.Time implements encoding.TextUnmarshaler so this works now. { in: `{"2009-11-10T23:00:00Z": "hello world"}`, - ptr: &map[time.Time]string{}, + ptr: new(map[time.Time]string), out: map[time.Time]string{time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC): "hello world"}, }, // issue 8305 { in: `{"2009-11-10T23:00:00Z": "hello world"}`, - ptr: &map[Point]string{}, + ptr: new(map[Point]string), err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(map[Point]string{}), Offset: 1}, }, { in: `{"asdf": "hello world"}`, - ptr: &map[unmarshaler]string{}, + ptr: new(map[unmarshaler]string), err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(map[unmarshaler]string{}), Offset: 1}, }, @@ -955,6 +949,37 @@ var unmarshalTests = []unmarshalTest{ Offset: 29, }, }, + // #14702 + { + in: `invalid`, + ptr: new(Number), + err: &SyntaxError{ + msg: "invalid character 'i' looking for beginning of value", + Offset: 1, + }, + }, + { + in: `"invalid"`, + ptr: new(Number), + err: fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", `"invalid"`), + }, + { + in: `{"A":"invalid"}`, + ptr: new(struct{ A Number }), + err: fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", `"invalid"`), + }, + { + in: `{"A":"invalid"}`, + ptr: new(struct { + A Number `json:",string"` + }), + err: fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into json.Number", `invalid`), + }, + { + in: `{"A":"invalid"}`, + ptr: new(map[string]Number), + err: fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", `"invalid"`), + }, } func TestMarshal(t *testing.T) { @@ -1077,8 +1102,27 @@ func TestUnmarshal(t *testing.T) { continue } + typ := reflect.TypeOf(tt.ptr) + if typ.Kind() != reflect.Ptr { + t.Errorf("#%d: unmarshalTest.ptr %T is not a pointer type", i, tt.ptr) + continue + } + typ = typ.Elem() + // v = new(right-type) - v := reflect.New(reflect.TypeOf(tt.ptr).Elem()) + v := reflect.New(typ) + + if !reflect.DeepEqual(tt.ptr, v.Interface()) { + // There's no reason for ptr to point to non-zero data, + // as we decode into new(right-type), so the data is + // discarded. + // This can easily mean tests that silently don't test + // what they should. To test decoding into existing + // data, see TestPrefilled. + t.Errorf("#%d: unmarshalTest.ptr %#v is not a pointer to a zero value", i, tt.ptr) + continue + } + dec := NewDecoder(bytes.NewReader(in)) if tt.useNumber { dec.UseNumber() @@ -1741,41 +1785,6 @@ type NullTest struct { Struct struct{} } -type NullTestStrings struct { - Bool bool `json:",string"` - Int int `json:",string"` - Int8 int8 `json:",string"` - Int16 int16 `json:",string"` - Int32 int32 `json:",string"` - Int64 int64 `json:",string"` - Uint uint `json:",string"` - Uint8 uint8 `json:",string"` - Uint16 uint16 `json:",string"` - Uint32 uint32 `json:",string"` - Uint64 uint64 `json:",string"` - Float32 float32 `json:",string"` - Float64 float64 `json:",string"` - String string `json:",string"` - PBool *bool `json:",string"` - Map map[string]string `json:",string"` - Slice []string `json:",string"` - Interface interface{} `json:",string"` - - PRaw *RawMessage `json:",string"` - PTime *time.Time `json:",string"` - PBigInt *big.Int `json:",string"` - PText *MustNotUnmarshalText `json:",string"` - PBuffer *bytes.Buffer `json:",string"` - PStruct *struct{} `json:",string"` - - Raw RawMessage `json:",string"` - Time time.Time `json:",string"` - BigInt big.Int `json:",string"` - Text MustNotUnmarshalText `json:",string"` - Buffer bytes.Buffer `json:",string"` - Struct struct{} `json:",string"` -} - // JSON null values should be ignored for primitives and string values instead of resulting in an error. // Issue 2540 func TestUnmarshalNulls(t *testing.T) { @@ -2086,11 +2095,10 @@ func TestSkipArrayObjects(t *testing.T) { } } -// Test semantics of pre-filled struct fields and pre-filled map fields. -// Issue 4900. +// Test semantics of pre-filled data, such as struct fields, map elements, +// slices, and arrays. +// Issues 4900 and 8837, among others. func TestPrefilled(t *testing.T) { - ptrToMap := func(m map[string]interface{}) *map[string]interface{} { return &m } - // Values here change, cannot reuse table across runs. var prefillTests = []struct { in string @@ -2104,8 +2112,28 @@ func TestPrefilled(t *testing.T) { }, { in: `{"X": 1, "Y": 2}`, - ptr: ptrToMap(map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}), - out: ptrToMap(map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}), + ptr: &map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}, + out: &map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}, + }, + { + in: `[2]`, + ptr: &[]int{1}, + out: &[]int{2}, + }, + { + in: `[2, 3]`, + ptr: &[]int{1}, + out: &[]int{2, 3}, + }, + { + in: `[2, 3]`, + ptr: &[...]int{1}, + out: &[...]int{2}, + }, + { + in: `[3]`, + ptr: &[...]int{1, 2}, + out: &[...]int{3, 0}, }, } @@ -2323,6 +2351,41 @@ func TestUnmarshalEmbeddedUnexported(t *testing.T) { } } +func TestUnmarshalErrorAfterMultipleJSON(t *testing.T) { + tests := []struct { + in string + err error + }{{ + in: `1 false null :`, + err: &SyntaxError{"invalid character ':' looking for beginning of value", 14}, + }, { + in: `1 [] [,]`, + err: &SyntaxError{"invalid character ',' looking for beginning of value", 7}, + }, { + in: `1 [] [true:]`, + err: &SyntaxError{"invalid character ':' after array element", 11}, + }, { + in: `1 {} {"x"=}`, + err: &SyntaxError{"invalid character '=' after object key", 14}, + }, { + in: `falsetruenul#`, + err: &SyntaxError{"invalid character '#' in literal null (expecting 'l')", 13}, + }} + for i, tt := range tests { + dec := NewDecoder(strings.NewReader(tt.in)) + var err error + for { + var v interface{} + if err = dec.Decode(&v); err != nil { + break + } + } + if !reflect.DeepEqual(err, tt.err) { + t.Errorf("#%d: got %#v, want %#v", i, err, tt.err) + } + } +} + type unmarshalPanic struct{} func (unmarshalPanic) UnmarshalJSON([]byte) error { panic(0xdead) } @@ -2348,3 +2411,23 @@ func TestUnmarshalRecursivePointer(t *testing.T) { t.Fatal(err) } } + +type textUnmarshalerString string + +func (m *textUnmarshalerString) UnmarshalText(text []byte) error { + *m = textUnmarshalerString(strings.ToLower(string(text))) + return nil +} + +// Test unmarshal to a map, with map key is a user defined type. +// See golang.org/issues/34437. +func TestUnmarshalMapWithTextUnmarshalerStringKey(t *testing.T) { + var p map[textUnmarshalerString]string + if err := Unmarshal([]byte(`{"FOO": "1"}`), &p); err != nil { + t.Fatalf("Unmarshal unexpected error: %v", err) + } + + if _, ok := p["foo"]; !ok { + t.Errorf(`Key "foo" is not existed in map: %v`, p) + } +} diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go index 67412763d64..39cdaebde7b 100644 --- a/libgo/go/encoding/json/encode.go +++ b/libgo/go/encoding/json/encode.go @@ -153,7 +153,7 @@ import ( // // JSON cannot represent cyclic data structures and Marshal does not // handle them. Passing cyclic structures to Marshal will result in -// an infinite recursion. +// an error. // func Marshal(v interface{}) ([]byte, error) { e := newEncodeState() @@ -164,7 +164,6 @@ func Marshal(v interface{}) ([]byte, error) { } buf := append([]byte(nil), e.Bytes()...) - e.Reset() encodeStatePool.Put(e) return buf, nil @@ -262,14 +261,22 @@ func (e *InvalidUTF8Error) Error() string { // A MarshalerError represents an error from calling a MarshalJSON or MarshalText method. type MarshalerError struct { - Type reflect.Type - Err error + Type reflect.Type + Err error + sourceFunc string } func (e *MarshalerError) Error() string { - return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error() + srcFunc := e.sourceFunc + if srcFunc == "" { + srcFunc = "MarshalJSON" + } + return "json: error calling " + srcFunc + + " for type " + e.Type.String() + + ": " + e.Err.Error() } +// Unwrap returns the underlying error. func (e *MarshalerError) Unwrap() error { return e.Err } var hex = "0123456789abcdef" @@ -278,17 +285,31 @@ var hex = "0123456789abcdef" type encodeState struct { bytes.Buffer // accumulated output scratch [64]byte + + // Keep track of what pointers we've seen in the current recursive call + // path, to avoid cycles that could lead to a stack overflow. Only do + // the relatively expensive map operations if ptrLevel is larger than + // startDetectingCyclesAfter, so that we skip the work if we're within a + // reasonable amount of nested pointers deep. + ptrLevel uint + ptrSeen map[interface{}]struct{} } +const startDetectingCyclesAfter = 1000 + var encodeStatePool sync.Pool func newEncodeState() *encodeState { if v := encodeStatePool.Get(); v != nil { e := v.(*encodeState) e.Reset() + if len(e.ptrSeen) > 0 { + panic("ptrEncoder.encode should have emptied ptrSeen via defers") + } + e.ptrLevel = 0 return e } - return new(encodeState) + return &encodeState{ptrSeen: make(map[interface{}]struct{})} } // jsonError is an error wrapper type for internal use only. @@ -392,19 +413,22 @@ var ( // newTypeEncoder constructs an encoderFunc for a type. // The returned encoder only checks CanAddr when allowAddr is true. func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { - if t.Implements(marshalerType) { - return marshalerEncoder - } + // If we have a non-pointer value whose type implements + // Marshaler with a value receiver, then we're better off taking + // the address of the value - otherwise we end up with an + // allocation as we cast the value to an interface. if t.Kind() != reflect.Ptr && allowAddr && reflect.PtrTo(t).Implements(marshalerType) { return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false)) } - - if t.Implements(textMarshalerType) { - return textMarshalerEncoder + if t.Implements(marshalerType) { + return marshalerEncoder } if t.Kind() != reflect.Ptr && allowAddr && reflect.PtrTo(t).Implements(textMarshalerType) { return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false)) } + if t.Implements(textMarshalerType) { + return textMarshalerEncoder + } switch t.Kind() { case reflect.Bool: @@ -456,7 +480,7 @@ func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { err = compact(&e.Buffer, b, opts.escapeHTML) } if err != nil { - e.error(&MarshalerError{v.Type(), err}) + e.error(&MarshalerError{v.Type(), err, "MarshalJSON"}) } } @@ -473,7 +497,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { err = compact(&e.Buffer, b, opts.escapeHTML) } if err != nil { - e.error(&MarshalerError{v.Type(), err}) + e.error(&MarshalerError{v.Type(), err, "MarshalJSON"}) } } @@ -482,10 +506,14 @@ func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { e.WriteString("null") return } - m := v.Interface().(encoding.TextMarshaler) + m, ok := v.Interface().(encoding.TextMarshaler) + if !ok { + e.WriteString("null") + return + } b, err := m.MarshalText() if err != nil { - e.error(&MarshalerError{v.Type(), err}) + e.error(&MarshalerError{v.Type(), err, "MarshalText"}) } e.stringBytes(b, opts.escapeHTML) } @@ -499,7 +527,7 @@ func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) { m := va.Interface().(encoding.TextMarshaler) b, err := m.MarshalText() if err != nil { - e.error(&MarshalerError{v.Type(), err}) + e.error(&MarshalerError{v.Type(), err, "MarshalText"}) } e.stringBytes(b, opts.escapeHTML) } @@ -597,20 +625,86 @@ func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) { if !isValidNumber(numStr) { e.error(fmt.Errorf("json: invalid number literal %q", numStr)) } + if opts.quoted { + e.WriteByte('"') + } e.WriteString(numStr) + if opts.quoted { + e.WriteByte('"') + } return } if opts.quoted { - sb, err := Marshal(v.String()) - if err != nil { - e.error(err) - } - e.string(string(sb), opts.escapeHTML) + b := make([]byte, 0, v.Len()+2) + b = append(b, '"') + b = append(b, []byte(v.String())...) + b = append(b, '"') + e.stringBytes(b, opts.escapeHTML) } else { e.string(v.String(), opts.escapeHTML) } } +// isValidNumber reports whether s is a valid JSON number literal. +func isValidNumber(s string) bool { + // This function implements the JSON numbers grammar. + // See https://tools.ietf.org/html/rfc7159#section-6 + // and https://json.org/number.gif + + if s == "" { + return false + } + + // Optional - + if s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + + // Digits + switch { + default: + return false + + case s[0] == '0': + s = s[1:] + + case '1' <= s[0] && s[0] <= '9': + s = s[1:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // . followed by 1 or more digits. + if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' { + s = s[2:] + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // e or E followed by an optional - or + and + // 1 or more digits. + if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') { + s = s[1:] + if s[0] == '+' || s[0] == '-' { + s = s[1:] + if s == "" { + return false + } + } + for len(s) > 0 && '0' <= s[0] && s[0] <= '9' { + s = s[1:] + } + } + + // Make sure we are at the end. + return s == "" +} + func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) { if v.IsNil() { e.WriteString("null") @@ -692,7 +786,7 @@ func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { for i, v := range keys { sv[i].v = v if err := sv[i].resolve(); err != nil { - e.error(&MarshalerError{v.Type(), err}) + e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error())) } } sort.Slice(sv, func(i, j int) bool { return sv[i].s < sv[j].s }) @@ -807,7 +901,18 @@ func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { e.WriteString("null") return } + if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter { + // We're a large number of nested ptrEncoder.encode calls deep; + // start checking if we've run into a pointer cycle. + ptr := v.Interface() + if _, ok := e.ptrSeen[ptr]; ok { + e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())}) + } + e.ptrSeen[ptr] = struct{}{} + defer delete(e.ptrSeen, ptr) + } pe.elemEnc(e, v.Elem(), opts) + e.ptrLevel-- } func newPtrEncoder(t reflect.Type) encoderFunc { @@ -872,6 +977,9 @@ func (w *reflectWithString) resolve() error { return nil } if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok { + if w.v.Kind() == reflect.Ptr && w.v.IsNil() { + return nil + } buf, err := tm.MarshalText() w.s = string(buf) return err diff --git a/libgo/go/encoding/json/encode_test.go b/libgo/go/encoding/json/encode_test.go index bdf2a9f0792..5110c7de9b1 100644 --- a/libgo/go/encoding/json/encode_test.go +++ b/libgo/go/encoding/json/encode_test.go @@ -6,6 +6,7 @@ package json import ( "bytes" + "encoding" "fmt" "log" "math" @@ -75,13 +76,15 @@ type StringTag struct { IntStr int64 `json:",string"` UintptrStr uintptr `json:",string"` StrStr string `json:",string"` + NumberStr Number `json:",string"` } var stringTagExpected = `{ "BoolStr": "true", "IntStr": "42", "UintptrStr": "44", - "StrStr": "\"xzbit\"" + "StrStr": "\"xzbit\"", + "NumberStr": "46" }` func TestStringTag(t *testing.T) { @@ -90,6 +93,7 @@ func TestStringTag(t *testing.T) { s.IntStr = 42 s.UintptrStr = 44 s.StrStr = "xzbit" + s.NumberStr = "46" got, err := MarshalIndent(&s, "", " ") if err != nil { t.Fatal(err) @@ -134,10 +138,45 @@ func TestEncodeRenamedByteSlice(t *testing.T) { } } +type SamePointerNoCycle struct { + Ptr1, Ptr2 *SamePointerNoCycle +} + +var samePointerNoCycle = &SamePointerNoCycle{} + +type PointerCycle struct { + Ptr *PointerCycle +} + +var pointerCycle = &PointerCycle{} + +type PointerCycleIndirect struct { + Ptrs []interface{} +} + +var pointerCycleIndirect = &PointerCycleIndirect{} + +func init() { + ptr := &SamePointerNoCycle{} + samePointerNoCycle.Ptr1 = ptr + samePointerNoCycle.Ptr2 = ptr + + pointerCycle.Ptr = pointerCycle + pointerCycleIndirect.Ptrs = []interface{}{pointerCycleIndirect} +} + +func TestSamePointerNoCycle(t *testing.T) { + if _, err := Marshal(samePointerNoCycle); err != nil { + t.Fatalf("unexpected error: %v", err) + } +} + var unsupportedValues = []interface{}{ math.NaN(), math.Inf(-1), math.Inf(1), + pointerCycle, + pointerCycleIndirect, } func TestUnsupportedValues(t *testing.T) { @@ -453,18 +492,31 @@ type BugX struct { BugB } -// Issue 16042. Even if a nil interface value is passed in -// as long as it implements MarshalJSON, it should be marshaled. -type nilMarshaler string +// golang.org/issue/16042. +// Even if a nil interface value is passed in, as long as +// it implements Marshaler, it should be marshaled. +type nilJSONMarshaler string -func (nm *nilMarshaler) MarshalJSON() ([]byte, error) { +func (nm *nilJSONMarshaler) MarshalJSON() ([]byte, error) { if nm == nil { return Marshal("0zenil0") } return Marshal("zenil:" + string(*nm)) } -// Issue 16042. +// golang.org/issue/34235. +// Even if a nil interface value is passed in, as long as +// it implements encoding.TextMarshaler, it should be marshaled. +type nilTextMarshaler string + +func (nm *nilTextMarshaler) MarshalText() ([]byte, error) { + if nm == nil { + return []byte("0zenil0"), nil + } + return []byte("zenil:" + string(*nm)), nil +} + +// See golang.org/issue/16042 and golang.org/issue/34235. func TestNilMarshal(t *testing.T) { testCases := []struct { v interface{} @@ -478,8 +530,11 @@ func TestNilMarshal(t *testing.T) { {v: []byte(nil), want: `null`}, {v: struct{ M string }{"gopher"}, want: `{"M":"gopher"}`}, {v: struct{ M Marshaler }{}, want: `{"M":null}`}, - {v: struct{ M Marshaler }{(*nilMarshaler)(nil)}, want: `{"M":"0zenil0"}`}, - {v: struct{ M interface{} }{(*nilMarshaler)(nil)}, want: `{"M":null}`}, + {v: struct{ M Marshaler }{(*nilJSONMarshaler)(nil)}, want: `{"M":"0zenil0"}`}, + {v: struct{ M interface{} }{(*nilJSONMarshaler)(nil)}, want: `{"M":null}`}, + {v: struct{ M encoding.TextMarshaler }{}, want: `{"M":null}`}, + {v: struct{ M encoding.TextMarshaler }{(*nilTextMarshaler)(nil)}, want: `{"M":"0zenil0"}`}, + {v: struct{ M interface{} }{(*nilTextMarshaler)(nil)}, want: `{"M":null}`}, } for _, tt := range testCases { @@ -793,6 +848,21 @@ func TestTextMarshalerMapKeysAreSorted(t *testing.T) { } } +// https://golang.org/issue/33675 +func TestNilMarshalerTextMapKey(t *testing.T) { + b, err := Marshal(map[*unmarshalerText]int{ + (*unmarshalerText)(nil): 1, + {"A", "B"}: 2, + }) + if err != nil { + t.Fatalf("Failed to Marshal *text.Marshaler: %v", err) + } + const want = `{"":1,"A:B":2}` + if string(b) != want { + t.Errorf("Marshal map with *text.Marshaler keys: got %#q, want %#q", b, want) + } +} + var re = regexp.MustCompile // syntactic checks on form of marshaled floating point numbers. @@ -1029,3 +1099,30 @@ func TestMarshalUncommonFieldNames(t *testing.T) { t.Fatalf("Marshal: got %s want %s", got, want) } } + +func TestMarshalerError(t *testing.T) { + s := "test variable" + st := reflect.TypeOf(s) + errText := "json: test error" + + tests := []struct { + err *MarshalerError + want string + }{ + { + &MarshalerError{st, fmt.Errorf(errText), ""}, + "json: error calling MarshalJSON for type " + st.String() + ": " + errText, + }, + { + &MarshalerError{st, fmt.Errorf(errText), "TestMarshalerError"}, + "json: error calling TestMarshalerError for type " + st.String() + ": " + errText, + }, + } + + for i, tt := range tests { + got := tt.err.Error() + if got != tt.want { + t.Errorf("MarshalerError test %d, got: %s, want: %s", i, got, tt.want) + } + } +} diff --git a/libgo/go/encoding/json/indent.go b/libgo/go/encoding/json/indent.go index fba19548c92..2924d3b49b9 100644 --- a/libgo/go/encoding/json/indent.go +++ b/libgo/go/encoding/json/indent.go @@ -4,7 +4,9 @@ package json -import "bytes" +import ( + "bytes" +) // Compact appends to dst the JSON-encoded src with // insignificant space characters elided. @@ -14,8 +16,8 @@ func Compact(dst *bytes.Buffer, src []byte) error { func compact(dst *bytes.Buffer, src []byte, escape bool) error { origLen := dst.Len() - var scan scanner - scan.reset() + scan := newScanner() + defer freeScanner(scan) start := 0 for i, c := range src { if escape && (c == '<' || c == '>' || c == '&') { @@ -28,7 +30,7 @@ func compact(dst *bytes.Buffer, src []byte, escape bool) error { start = i + 1 } // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9). - if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 { + if escape && c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 { if start < i { dst.Write(src[start:i]) } @@ -36,7 +38,7 @@ func compact(dst *bytes.Buffer, src []byte, escape bool) error { dst.WriteByte(hex[src[i+2]&0xF]) start = i + 3 } - v := scan.step(&scan, c) + v := scan.step(scan, c) if v >= scanSkipSpace { if v == scanError { break @@ -78,13 +80,13 @@ func newline(dst *bytes.Buffer, prefix, indent string, depth int) { // if src ends in a trailing newline, so will dst. func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error { origLen := dst.Len() - var scan scanner - scan.reset() + scan := newScanner() + defer freeScanner(scan) needIndent := false depth := 0 for _, c := range src { scan.bytes++ - v := scan.step(&scan, c) + v := scan.step(scan, c) if v == scanSkipSpace { continue } diff --git a/libgo/go/encoding/json/scanner.go b/libgo/go/encoding/json/scanner.go index 88572245fc7..552bd703604 100644 --- a/libgo/go/encoding/json/scanner.go +++ b/libgo/go/encoding/json/scanner.go @@ -13,11 +13,16 @@ package json // This file starts with two simple examples using the scanner // before diving into the scanner itself. -import "strconv" +import ( + "strconv" + "sync" +) // Valid reports whether data is a valid JSON encoding. func Valid(data []byte) bool { - return checkValid(data, &scanner{}) == nil + scan := newScanner() + defer freeScanner(scan) + return checkValid(data, scan) == nil } // checkValid verifies that data is valid JSON-encoded data. @@ -45,7 +50,7 @@ type SyntaxError struct { func (e *SyntaxError) Error() string { return e.msg } // A scanner is a JSON scanning state machine. -// Callers call scan.reset() and then pass bytes in one at a time +// Callers call scan.reset and then pass bytes in one at a time // by calling scan.step(&scan, c) for each byte. // The return value, referred to as an opcode, tells the // caller about significant parsing events like beginning @@ -72,10 +77,33 @@ type scanner struct { // Error that happened, if any. err error - // total bytes consumed, updated by decoder.Decode + // total bytes consumed, updated by decoder.Decode (and deliberately + // not set to zero by scan.reset) bytes int64 } +var scannerPool = sync.Pool{ + New: func() interface{} { + return &scanner{} + }, +} + +func newScanner() *scanner { + scan := scannerPool.Get().(*scanner) + // scan.reset by design doesn't set bytes to zero + scan.bytes = 0 + scan.reset() + return scan +} + +func freeScanner(scan *scanner) { + // Avoid hanging on to too much memory in extreme cases. + if len(scan.parseState) > 1024 { + scan.parseState = nil + } + scannerPool.Put(scan) +} + // These values are returned by the state transition functions // assigned to scanner.state and the method scanner.eof. // They give details about the current state of the scan that diff --git a/libgo/go/encoding/json/scanner_test.go b/libgo/go/encoding/json/scanner_test.go index 6cdbe7d301e..3737516a450 100644 --- a/libgo/go/encoding/json/scanner_test.go +++ b/libgo/go/encoding/json/scanner_test.go @@ -48,6 +48,7 @@ var examples = []example{ {`[1,2,3]`, "[\n\t1,\n\t2,\n\t3\n]"}, {`{"x":1}`, "{\n\t\"x\": 1\n}"}, {ex1, ex1i}, + {"{\"\":\"<>&\u2028\u2029\"}", "{\n\t\"\": \"<>&\u2028\u2029\"\n}"}, // See golang.org/issue/34070 } var ex1 = `[true,false,null,"x",1,1.5,0,-5e+2]` @@ -89,8 +90,8 @@ func TestCompactSeparators(t *testing.T) { tests := []struct { in, compact string }{ - {"{\"\u2028\": 1}", `{"\u2028":1}`}, - {"{\"\u2029\" :2}", `{"\u2029":2}`}, + {"{\"\u2028\": 1}", "{\"\u2028\":1}"}, + {"{\"\u2029\" :2}", "{\"\u2029\":2}"}, } for _, tt := range tests { var buf bytes.Buffer diff --git a/libgo/go/encoding/json/stream.go b/libgo/go/encoding/json/stream.go index e29127499b6..81f404f4267 100644 --- a/libgo/go/encoding/json/stream.go +++ b/libgo/go/encoding/json/stream.go @@ -56,7 +56,7 @@ func (dec *Decoder) Decode(v interface{}) error { } if !dec.tokenValueAllowed() { - return &SyntaxError{msg: "not at beginning of value", Offset: dec.offset()} + return &SyntaxError{msg: "not at beginning of value", Offset: dec.InputOffset()} } // Read whole value into buffer. @@ -102,6 +102,10 @@ Input: dec.scan.bytes++ switch dec.scan.step(&dec.scan, c) { case scanEnd: + // scanEnd is delayed one byte so we decrement + // the scanner bytes count by 1 to ensure that + // this value is correct in the next call of Decode. + dec.scan.bytes-- break Input case scanEndObject, scanEndArray: // scanEnd is delayed one byte. @@ -310,7 +314,7 @@ func (dec *Decoder) tokenPrepareForDecode() error { return err } if c != ',' { - return &SyntaxError{"expected comma after array element", dec.offset()} + return &SyntaxError{"expected comma after array element", dec.InputOffset()} } dec.scanp++ dec.tokenState = tokenArrayValue @@ -320,7 +324,7 @@ func (dec *Decoder) tokenPrepareForDecode() error { return err } if c != ':' { - return &SyntaxError{"expected colon after object key", dec.offset()} + return &SyntaxError{"expected colon after object key", dec.InputOffset()} } dec.scanp++ dec.tokenState = tokenObjectValue @@ -473,7 +477,7 @@ func (dec *Decoder) tokenError(c byte) (Token, error) { case tokenObjectComma: context = " after object key:value pair" } - return nil, &SyntaxError{"invalid character " + quoteChar(c) + context, dec.offset()} + return nil, &SyntaxError{"invalid character " + quoteChar(c) + context, dec.InputOffset()} } // More reports whether there is another element in the @@ -502,6 +506,9 @@ func (dec *Decoder) peek() (byte, error) { } } -func (dec *Decoder) offset() int64 { +// InputOffset returns the input stream byte offset of the current decoder position. +// The offset gives the location of the end of the most recently returned token +// and the beginning of the next token. +func (dec *Decoder) InputOffset() int64 { return dec.scanned + int64(dec.scanp) } diff --git a/libgo/go/encoding/json/stream_test.go b/libgo/go/encoding/json/stream_test.go index e3317ddeb0b..ebb4f231d15 100644 --- a/libgo/go/encoding/json/stream_test.go +++ b/libgo/go/encoding/json/stream_test.go @@ -118,6 +118,11 @@ func TestEncoderSetEscapeHTML(t *testing.T) { Ptr strPtrMarshaler }{`""`, `""`} + // https://golang.org/issue/34154 + stringOption := struct { + Bar string `json:"bar,string"` + }{`foobar`} + for _, tt := range []struct { name string v interface{} @@ -137,6 +142,11 @@ func TestEncoderSetEscapeHTML(t *testing.T) { `{"NonPtr":"\u003cstr\u003e","Ptr":"\u003cstr\u003e"}`, `{"NonPtr":"","Ptr":""}`, }, + { + "stringOption", stringOption, + `{"bar":"\"\u003chtml\u003efoobar\u003c/html\u003e\""}`, + `{"bar":"\"foobar\""}`, + }, } { var buf bytes.Buffer enc := NewEncoder(&buf) diff --git a/libgo/go/encoding/xml/marshal.go b/libgo/go/encoding/xml/marshal.go index add5ece7821..e325f313743 100644 --- a/libgo/go/encoding/xml/marshal.go +++ b/libgo/go/encoding/xml/marshal.go @@ -914,7 +914,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { p.WriteString("-->") continue - case fInnerXml: + case fInnerXML: vf = indirect(vf) iface := vf.Interface() switch raw := iface.(type) { diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go index a0ccf44028b..8473158bcd0 100644 --- a/libgo/go/encoding/xml/marshal_test.go +++ b/libgo/go/encoding/xml/marshal_test.go @@ -392,7 +392,6 @@ func stringptr(x string) *string { type T1 struct{} type T2 struct{} -type T3 struct{} type IndirComment struct { T1 T1 diff --git a/libgo/go/encoding/xml/read.go b/libgo/go/encoding/xml/read.go index 12102bc804e..10a60eed1a9 100644 --- a/libgo/go/encoding/xml/read.go +++ b/libgo/go/encoding/xml/read.go @@ -491,7 +491,7 @@ func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error { saveAny = finfo.value(sv) } - case fInnerXml: + case fInnerXML: if !saveXML.IsValid() { saveXML = finfo.value(sv) if d.saved == nil { diff --git a/libgo/go/encoding/xml/typeinfo.go b/libgo/go/encoding/xml/typeinfo.go index 48de3d7e9e9..639952c74ad 100644 --- a/libgo/go/encoding/xml/typeinfo.go +++ b/libgo/go/encoding/xml/typeinfo.go @@ -33,13 +33,13 @@ const ( fAttr fCDATA fCharData - fInnerXml + fInnerXML fComment fAny fOmitEmpty - fMode = fElement | fAttr | fCDATA | fCharData | fInnerXml | fComment | fAny + fMode = fElement | fAttr | fCDATA | fCharData | fInnerXML | fComment | fAny xmlName = "XMLName" ) @@ -134,7 +134,7 @@ func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, erro case "chardata": finfo.flags |= fCharData case "innerxml": - finfo.flags |= fInnerXml + finfo.flags |= fInnerXML case "comment": finfo.flags |= fComment case "any": @@ -149,7 +149,7 @@ func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, erro switch mode := finfo.flags & fMode; mode { case 0: finfo.flags |= fElement - case fAttr, fCDATA, fCharData, fInnerXml, fComment, fAny, fAny | fAttr: + case fAttr, fCDATA, fCharData, fInnerXML, fComment, fAny, fAny | fAttr: if f.Name == xmlName || tag != "" && mode != fAttr { valid = false } diff --git a/libgo/go/encoding/xml/xml.go b/libgo/go/encoding/xml/xml.go index ca059440a1b..5e73dcf7316 100644 --- a/libgo/go/encoding/xml/xml.go +++ b/libgo/go/encoding/xml/xml.go @@ -286,7 +286,10 @@ func (d *Decoder) Token() (Token, error) { t = d.nextToken d.nextToken = nil } else if t, err = d.rawToken(); err != nil { - if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF { + switch { + case err == io.EOF && d.t != nil: + err = nil + case err == io.EOF && d.stk != nil && d.stk.kind != stkEOF: err = d.syntaxError("unexpected EOF") } return t, err diff --git a/libgo/go/encoding/xml/xml_test.go b/libgo/go/encoding/xml/xml_test.go index ee4ffa24208..efddca43e91 100644 --- a/libgo/go/encoding/xml/xml_test.go +++ b/libgo/go/encoding/xml/xml_test.go @@ -14,6 +14,51 @@ import ( "unicode/utf8" ) +type toks struct { + earlyEOF bool + t []Token +} + +func (t *toks) Token() (Token, error) { + if len(t.t) == 0 { + return nil, io.EOF + } + var tok Token + tok, t.t = t.t[0], t.t[1:] + if t.earlyEOF && len(t.t) == 0 { + return tok, io.EOF + } + return tok, nil +} + +func TestDecodeEOF(t *testing.T) { + start := StartElement{Name: Name{Local: "test"}} + t.Run("EarlyEOF", func(t *testing.T) { + d := NewTokenDecoder(&toks{earlyEOF: true, t: []Token{ + start, + start.End(), + }}) + err := d.Decode(&struct { + XMLName Name `xml:"test"` + }{}) + if err != nil { + t.Error(err) + } + }) + t.Run("LateEOF", func(t *testing.T) { + d := NewTokenDecoder(&toks{t: []Token{ + start, + start.End(), + }}) + err := d.Decode(&struct { + XMLName Name `xml:"test"` + }{}) + if err != nil { + t.Error(err) + } + }) +} + const testInput = ` > 63) ) +// scanPercent scans a literal percent character. +func (s *ss) scanPercent() { + s.SkipSpace() + s.notEOF() + if !s.accept("%") { + s.errorString("missing literal %") + } +} + // scanOne scans a single value, deriving the scanner from the type of the argument. func (s *ss) scanOne(verb rune, arg interface{}) { s.buf = s.buf[:0] @@ -1203,6 +1212,10 @@ func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err erro if c != 'c' { s.SkipSpace() } + if c == '%' { + s.scanPercent() + continue // Do not consume an argument. + } s.argLimit = s.limit if f := s.count + s.maxWid; f < s.argLimit { s.argLimit = f diff --git a/libgo/go/fmt/scan_test.go b/libgo/go/fmt/scan_test.go index b14a6f5deb7..1cc469ce361 100644 --- a/libgo/go/fmt/scan_test.go +++ b/libgo/go/fmt/scan_test.go @@ -318,13 +318,15 @@ var scanfTests = []ScanfTest{ {"%2s", "sssss", &xVal, Xs("ss")}, // Fixed bugs - {"%d\n", "27\n", &intVal, 27}, // ok - {"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline" - {"%v", "0", &intVal, 0}, // was: "EOF"; 0 was taken as base prefix and not counted. - {"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted. - {"%c", " ", &uintVal, uint(' ')}, // %c must accept a blank. - {"%c", "\t", &uintVal, uint('\t')}, // %c must accept any space. - {"%c", "\n", &uintVal, uint('\n')}, // %c must accept any space. + {"%d\n", "27\n", &intVal, 27}, // ok + {"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline" + {"%v", "0", &intVal, 0}, // was: "EOF"; 0 was taken as base prefix and not counted. + {"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted. + {"%c", " ", &uintVal, uint(' ')}, // %c must accept a blank. + {"%c", "\t", &uintVal, uint('\t')}, // %c must accept any space. + {"%c", "\n", &uintVal, uint('\n')}, // %c must accept any space. + {"%d%%", "23%\n", &uintVal, uint(23)}, // %% matches literal %. + {"%%%d", "%23\n", &uintVal, uint(23)}, // %% matches literal %. // space handling {"%d", "27", &intVal, 27}, @@ -467,6 +469,9 @@ var multiTests = []ScanfMultiTest{ {"X%d", "10X", args(&intVal), nil, "input does not match format"}, {"%d%", "42%", args(&intVal), args(42), "missing verb: % at end of format string"}, {"%d% ", "42%", args(&intVal), args(42), "too few operands for format '% '"}, // Slightly odd error, but correct. + {"%%%d", "xxx 42", args(&intVal), args(42), "missing literal %"}, + {"%%%d", "x42", args(&intVal), args(42), "missing literal %"}, + {"%%%d", "42", args(&intVal), args(42), "missing literal %"}, // Bad UTF-8: should see every byte. {"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""}, diff --git a/libgo/go/go/ast/ast.go b/libgo/go/go/ast/ast.go index d8f6f668cc4..aca510f6a51 100644 --- a/libgo/go/go/ast/ast.go +++ b/libgo/go/go/ast/ast.go @@ -292,7 +292,7 @@ type ( Rbrack token.Pos // position of "]" } - // An SliceExpr node represents an expression followed by slice indices. + // A SliceExpr node represents an expression followed by slice indices. SliceExpr struct { X Expr // expression Lbrack token.Pos // position of "[" @@ -634,7 +634,7 @@ type ( BlockStmt struct { Lbrace token.Pos // position of "{" List []Stmt - Rbrace token.Pos // position of "}" + Rbrace token.Pos // position of "}", if any (may be absent due to syntax error) } // An IfStmt node represents an if statement. @@ -662,7 +662,7 @@ type ( Body *BlockStmt // CaseClauses only } - // An TypeSwitchStmt node represents a type switch statement. + // A TypeSwitchStmt node represents a type switch statement. TypeSwitchStmt struct { Switch token.Pos // position of "switch" keyword Init Stmt // initialization statement; or nil @@ -678,7 +678,7 @@ type ( Body []Stmt // statement list; or nil } - // An SelectStmt node represents a select statement. + // A SelectStmt node represents a select statement. SelectStmt struct { Select token.Pos // position of "select" keyword Body *BlockStmt // CommClauses only @@ -757,7 +757,15 @@ func (s *BranchStmt) End() token.Pos { } return token.Pos(int(s.TokPos) + len(s.Tok.String())) } -func (s *BlockStmt) End() token.Pos { return s.Rbrace + 1 } +func (s *BlockStmt) End() token.Pos { + if s.Rbrace.IsValid() { + return s.Rbrace + 1 + } + if n := len(s.List); n > 0 { + return s.List[n-1].End() + } + return s.Lbrace + 1 +} func (s *IfStmt) End() token.Pos { if s.Else != nil { return s.Else.End() diff --git a/libgo/go/go/ast/filter.go b/libgo/go/go/ast/filter.go index 32352cb92c5..c398e6e603a 100644 --- a/libgo/go/go/ast/filter.go +++ b/libgo/go/go/ast/filter.go @@ -474,7 +474,9 @@ func MergePackageFiles(pkg *Package, mode MergeMode) *File { } } } else { - for _, f := range pkg.Files { + // Iterate over filenames for deterministic order. + for _, filename := range filenames { + f := pkg.Files[filename] imports = append(imports, f.Imports...) } } @@ -484,7 +486,8 @@ func MergePackageFiles(pkg *Package, mode MergeMode) *File { if mode&FilterUnassociatedComments == 0 { comments = make([]*CommentGroup, ncomments) i := 0 - for _, f := range pkg.Files { + for _, filename := range filenames { + f := pkg.Files[filename] i += copy(comments[i:], f.Comments) } } diff --git a/libgo/go/go/ast/import.go b/libgo/go/go/ast/import.go index be23c7fc432..7fdf137d146 100644 --- a/libgo/go/go/ast/import.go +++ b/libgo/go/go/ast/import.go @@ -30,7 +30,7 @@ func SortImports(fset *token.FileSet, f *File) { i := 0 specs := d.Specs[:0] for j, s := range d.Specs { - if j > i && fset.Position(s.Pos()).Line > 1+fset.Position(d.Specs[j-1].End()).Line { + if j > i && lineAt(fset, s.Pos()) > 1+lineAt(fset, d.Specs[j-1].End()) { // j begins a new run. End this one. specs = append(specs, sortSpecs(fset, f, d.Specs[i:j])...) i = j @@ -42,8 +42,8 @@ func SortImports(fset *token.FileSet, f *File) { // Deduping can leave a blank line before the rparen; clean that up. if len(d.Specs) > 0 { lastSpec := d.Specs[len(d.Specs)-1] - lastLine := fset.Position(lastSpec.Pos()).Line - rParenLine := fset.Position(d.Rparen).Line + lastLine := lineAt(fset, lastSpec.Pos()) + rParenLine := lineAt(fset, d.Rparen) for rParenLine > lastLine+1 { rParenLine-- fset.File(d.Rparen).MergeLine(rParenLine) @@ -52,6 +52,10 @@ func SortImports(fset *token.FileSet, f *File) { } } +func lineAt(fset *token.FileSet, pos token.Pos) int { + return fset.PositionFor(pos, false).Line +} + func importPath(s Spec) string { t, err := strconv.Unquote(s.(*ImportSpec).Path.Value) if err == nil { @@ -89,6 +93,11 @@ type posSpan struct { End token.Pos } +type cgPos struct { + left bool // true if comment is to the left of the spec, false otherwise. + cg *CommentGroup +} + func sortSpecs(fset *token.FileSet, f *File, specs []Spec) []Spec { // Can't short-circuit here even if specs are already sorted, // since they might yet need deduplication. @@ -104,39 +113,64 @@ func sortSpecs(fset *token.FileSet, f *File, specs []Spec) []Spec { } // Identify comments in this range. - // Any comment from pos[0].Start to the final line counts. - lastLine := fset.Position(pos[len(pos)-1].End).Line - cstart := len(f.Comments) - cend := len(f.Comments) + begSpecs := pos[0].Start + endSpecs := pos[len(pos)-1].End + beg := fset.File(begSpecs).LineStart(lineAt(fset, begSpecs)) + endLine := lineAt(fset, endSpecs) + endFile := fset.File(endSpecs) + var end token.Pos + if endLine == endFile.LineCount() { + end = endSpecs + } else { + end = endFile.LineStart(endLine + 1) // beginning of next line + } + first := len(f.Comments) + last := -1 for i, g := range f.Comments { - if g.Pos() < pos[0].Start { - continue - } - if i < cstart { - cstart = i - } - if fset.Position(g.End()).Line > lastLine { - cend = i + if g.End() >= end { break } + // g.End() < end + if beg <= g.Pos() { + // comment is within the range [beg, end[ of import declarations + if i < first { + first = i + } + if i > last { + last = i + } + } } - comments := f.Comments[cstart:cend] - // Assign each comment to the import spec preceding it. - importComments := map[*ImportSpec][]*CommentGroup{} + var comments []*CommentGroup + if last >= 0 { + comments = f.Comments[first : last+1] + } + + // Assign each comment to the import spec on the same line. + importComments := map[*ImportSpec][]cgPos{} specIndex := 0 for _, g := range comments { for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() { specIndex++ } + var left bool + // A block comment can appear before the first import spec. + if specIndex == 0 && pos[specIndex].Start > g.Pos() { + left = true + } else if specIndex+1 < len(specs) && // Or it can appear on the left of an import spec. + lineAt(fset, pos[specIndex].Start)+1 == lineAt(fset, g.Pos()) { + specIndex++ + left = true + } s := specs[specIndex].(*ImportSpec) - importComments[s] = append(importComments[s], g) + importComments[s] = append(importComments[s], cgPos{left: left, cg: g}) } // Sort the import specs by import path. // Remove duplicates, when possible without data loss. // Reassign the import paths to have the same position sequence. - // Reassign each comment to abut the end of its spec. + // Reassign each comment to the spec on the same line. // Sort the comments by new position. sort.Slice(specs, func(i, j int) bool { ipath := importPath(specs[i]) @@ -160,7 +194,7 @@ func sortSpecs(fset *token.FileSet, f *File, specs []Spec) []Spec { deduped = append(deduped, s) } else { p := s.Pos() - fset.File(p).MergeLine(fset.Position(p).Line) + fset.File(p).MergeLine(lineAt(fset, p)) } } specs = deduped @@ -174,8 +208,16 @@ func sortSpecs(fset *token.FileSet, f *File, specs []Spec) []Spec { s.Path.ValuePos = pos[i].Start s.EndPos = pos[i].End for _, g := range importComments[s] { - for _, c := range g.List { - c.Slash = pos[i].End + for _, c := range g.cg.List { + if g.left { + c.Slash = pos[i].Start - 1 + } else { + // An import spec can have both block comment and a line comment + // to its right. In that case, both of them will have the same pos. + // But while formatting the AST, the line comment gets moved to + // after the block comment. + c.Slash = pos[i].End + } } } } diff --git a/libgo/go/go/ast/issues_test.go b/libgo/go/go/ast/issues_test.go new file mode 100644 index 00000000000..788c5578b87 --- /dev/null +++ b/libgo/go/go/ast/issues_test.go @@ -0,0 +1,42 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ast_test + +import ( + "go/ast" + "go/parser" + "go/token" + "testing" +) + +func TestIssue33649(t *testing.T) { + for _, src := range []string{ + `package p; func _()`, + `package p; func _() {`, + `package p; func _() { _ = 0`, + `package p; func _() { _ = 0 }`, + } { + fset := token.NewFileSet() + f, _ := parser.ParseFile(fset, "", src, parser.AllErrors) + if f == nil { + panic("invalid test setup: parser didn't return an AST") + } + + // find corresponding token.File + var tf *token.File + fset.Iterate(func(f *token.File) bool { + tf = f + return true + }) + tfEnd := tf.Base() + tf.Size() + + fd := f.Decls[len(f.Decls)-1].(*ast.FuncDecl) + fdEnd := int(fd.End()) + + if fdEnd != tfEnd { + t.Errorf("%q: got fdEnd = %d; want %d (base = %d, size = %d)", src, fdEnd, tfEnd, tf.Base(), tf.Size()) + } + } +} diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go index 021c6eca22f..e250ae71125 100644 --- a/libgo/go/go/build/build.go +++ b/libgo/go/go/build/build.go @@ -31,10 +31,19 @@ import ( // A Context specifies the supporting context for a build. type Context struct { - GOARCH string // target architecture - GOOS string // target operating system - GOROOT string // Go root - GOPATH string // Go path + GOARCH string // target architecture + GOOS string // target operating system + GOROOT string // Go root + GOPATH string // Go path + + // Dir is the caller's working directory, or the empty string to use + // the current directory of the running process. In module mode, this is used + // to locate the main module. + // + // If Dir is non-empty, directories passed to Import and ImportDir must + // be absolute. + Dir string + CgoEnabled bool // whether cgo files are included UseAllFiles bool // use files regardless of +build lines, file names Compiler string // compiler to assume when computing target paths @@ -594,13 +603,14 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa return p, fmt.Errorf("import %q: cannot import absolute path", path) } - gopath := ctxt.gopath() // needed by both importGo and below; avoid computing twice - if err := ctxt.importGo(p, path, srcDir, mode, gopath); err == nil { + if err := ctxt.importGo(p, path, srcDir, mode); err == nil { goto Found } else if err != errNoModules { return p, err } + gopath := ctxt.gopath() // needed twice below; avoid computing many times + // tried records the location of unsuccessful package lookups var tried struct { vendor []string @@ -775,7 +785,7 @@ Found: } var badGoError error - var Sfiles []string // files with ".S" (capital S) + var Sfiles []string // files with ".S"(capital S)/.sx(capital s equivalent for case insensitive filesystems) var firstFile, firstCommentFile string imported := make(map[string][]token.Position) testImported := make(map[string][]token.Position) @@ -829,7 +839,7 @@ Found: case ".s": p.SFiles = append(p.SFiles, name) continue - case ".S": + case ".S", ".sx": Sfiles = append(Sfiles, name) continue case ".swig": @@ -897,6 +907,11 @@ Found: } // Record imports and information about cgo. + type importPos struct { + path string + pos token.Pos + } + var fileImports []importPos isCgo := false for _, decl := range pf.Decls { d, ok := decl.(*ast.GenDecl) @@ -913,13 +928,7 @@ Found: if err != nil { log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted) } - if isXTest { - xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos())) - } else if isTest { - testImported[path] = append(testImported[path], fset.Position(spec.Pos())) - } else { - imported[path] = append(imported[path], fset.Position(spec.Pos())) - } + fileImports = append(fileImports, importPos{path, spec.Pos()}) if path == "C" { if isTest { badFile(fmt.Errorf("use of cgo in test %s not supported", filename)) @@ -938,26 +947,35 @@ Found: } } } - if isCgo { + + var fileList *[]string + var importMap map[string][]token.Position + switch { + case isCgo: allTags["cgo"] = true if ctxt.CgoEnabled { - p.CgoFiles = append(p.CgoFiles, name) + fileList = &p.CgoFiles + importMap = imported } else { - p.IgnoredGoFiles = append(p.IgnoredGoFiles, name) + // Ignore imports from cgo files if cgo is disabled. + fileList = &p.IgnoredGoFiles + } + case isXTest: + fileList = &p.XTestGoFiles + importMap = xTestImported + case isTest: + fileList = &p.TestGoFiles + importMap = testImported + default: + fileList = &p.GoFiles + importMap = imported + } + *fileList = append(*fileList, name) + if importMap != nil { + for _, imp := range fileImports { + importMap[imp.path] = append(importMap[imp.path], fset.Position(imp.pos)) } - } else if isXTest { - p.XTestGoFiles = append(p.XTestGoFiles, name) - } else if isTest { - p.TestGoFiles = append(p.TestGoFiles, name) - } else { - p.GoFiles = append(p.GoFiles, name) } - } - if badGoError != nil { - return p, badGoError - } - if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { - return p, &NoGoError{p.Dir} } for tag := range allTags { @@ -969,7 +987,7 @@ Found: p.TestImports, p.TestImportPos = cleanImports(testImported) p.XTestImports, p.XTestImportPos = cleanImports(xTestImported) - // add the .S files only if we are using cgo + // add the .S/.sx files only if we are using cgo // (which means gcc will compile them). // The standard assemblers expect .s files. if len(p.CgoFiles) > 0 { @@ -977,13 +995,19 @@ Found: sort.Strings(p.SFiles) } + if badGoError != nil { + return p, badGoError + } + if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { + return p, &NoGoError{p.Dir} + } return p, pkgerr } var errNoModules = errors.New("not using modules") // importGo checks whether it can use the go command to find the directory for path. -// If using the go command is not appopriate, importGo returns errNoModules. +// If using the go command is not appropriate, importGo returns errNoModules. // Otherwise, importGo tries using the go command and reports whether that succeeded. // Using the go command lets build.Import and build.Context.Import find code // in Go modules. In the long term we want tools to use go/packages (currently golang.org/x/tools/go/packages), @@ -992,37 +1016,51 @@ var errNoModules = errors.New("not using modules") // about the requested package and all dependencies and then only reports about the requested package. // Then we reinvoke it for every dependency. But this is still better than not working at all. // See golang.org/issue/26504. -func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode, gopath []string) error { +func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) error { const debugImportGo = false - // To invoke the go command, we must know the source directory, + // To invoke the go command, // we must not being doing special things like AllowBinary or IgnoreVendor, // and all the file system callbacks must be nil (we're meant to use the local file system). - if srcDir == "" || mode&AllowBinary != 0 || mode&IgnoreVendor != 0 || + if mode&AllowBinary != 0 || mode&IgnoreVendor != 0 || ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ReleaseTags, defaultReleaseTags) { return errNoModules } - // Find the absolute source directory. hasSubdir does not handle - // relative paths (and can't because the callbacks don't support this). - absSrcDir, err := filepath.Abs(srcDir) - if err != nil { - return errNoModules - } - - // If modules are not enabled, then the in-process code works fine and we should keep using it. - switch os.Getenv("GO111MODULE") { + // Predict whether module aware mode is enabled by checking the value of + // GO111MODULE and looking for a go.mod file in the source directory or + // one of its parents. Running 'go env GOMOD' in the source directory would + // give a canonical answer, but we'd prefer not to execute another command. + go111Module := os.Getenv("GO111MODULE") + switch go111Module { case "off": return errNoModules default: // "", "on", "auto", anything else // Maybe use modules. } - // If the source directory is in GOROOT, then the in-process code works fine - // and we should keep using it. Moreover, the 'go list' approach below doesn't - // take standard-library vendoring into account and will fail. - if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), absSrcDir); ok { - return errNoModules + if srcDir != "" { + var absSrcDir string + if filepath.IsAbs(srcDir) { + absSrcDir = srcDir + } else if ctxt.Dir != "" { + return fmt.Errorf("go/build: Dir is non-empty, so relative srcDir is not allowed: %v", srcDir) + } else { + // Find the absolute source directory. hasSubdir does not handle + // relative paths (and can't because the callbacks don't support this). + var err error + absSrcDir, err = filepath.Abs(srcDir) + if err != nil { + return errNoModules + } + } + + // If the source directory is in GOROOT, then the in-process code works fine + // and we should keep using it. Moreover, the 'go list' approach below doesn't + // take standard-library vendoring into account and will fail. + if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), absSrcDir); ok { + return errNoModules + } } // For efficiency, if path is a standard library package, let the usual lookup code handle it. @@ -1033,27 +1071,45 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode, } } - // Look to see if there is a go.mod. + // Unless GO111MODULE=on, look to see if there is a go.mod. // Since go1.13, it doesn't matter if we're inside GOPATH. - parent := absSrcDir - for { - info, err := os.Stat(filepath.Join(parent, "go.mod")) - if err == nil && !info.IsDir() { - break + if go111Module != "on" { + var ( + parent string + err error + ) + if ctxt.Dir == "" { + parent, err = os.Getwd() + if err != nil { + // A nonexistent working directory can't be in a module. + return errNoModules + } + } else { + parent, err = filepath.Abs(ctxt.Dir) + if err != nil { + // If the caller passed a bogus Dir explicitly, that's materially + // different from not having modules enabled. + return err + } } - d := filepath.Dir(parent) - if len(d) >= len(parent) { - return errNoModules // reached top of file system, no go.mod + for { + info, err := os.Stat(filepath.Join(parent, "go.mod")) + if err == nil && !info.IsDir() { + break + } + d := filepath.Dir(parent) + if len(d) >= len(parent) { + return errNoModules // reached top of file system, no go.mod + } + parent = d } - parent = d } - cmd := exec.Command("go", "list", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n", path) + cmd := exec.Command("go", "list", "-e", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n{{if .Error}}{{.Error}}{{end}}\n", "--", path) - // TODO(bcmills): This is wrong if srcDir is in a vendor directory, or if - // srcDir is in some module dependency of the main module. The main module - // chooses what the import paths mean: individual packages don't. - cmd.Dir = srcDir + if ctxt.Dir != "" { + cmd.Dir = ctxt.Dir + } var stdout, stderr strings.Builder cmd.Stdout = &stdout @@ -1072,15 +1128,25 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode, ) if err := cmd.Run(); err != nil { - return fmt.Errorf("go/build: importGo %s: %v\n%s\n", path, err, stderr.String()) + return fmt.Errorf("go/build: go list %s: %v\n%s\n", path, err, stderr.String()) } - f := strings.Split(stdout.String(), "\n") - if len(f) != 5 || f[4] != "" { + f := strings.SplitN(stdout.String(), "\n", 5) + if len(f) != 5 { return fmt.Errorf("go/build: importGo %s: unexpected output:\n%s\n", path, stdout.String()) } + dir := f[0] + errStr := strings.TrimSpace(f[4]) + if errStr != "" && p.Dir == "" { + // If 'go list' could not locate the package, return the same error that + // 'go list' reported. + // If 'go list' did locate the package (p.Dir is not empty), ignore the + // error. It was probably related to loading source files, and we'll + // encounter it ourselves shortly. + return errors.New(errStr) + } - p.Dir = f[0] + p.Dir = dir p.ImportPath = f[1] p.Root = f[2] p.Goroot = f[3] == "true" @@ -1260,7 +1326,7 @@ func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binary } switch ext { - case ".go", ".c", ".cc", ".cxx", ".cpp", ".m", ".s", ".h", ".hh", ".hpp", ".hxx", ".f", ".F", ".f90", ".S", ".swig", ".swigcxx": + case ".go", ".c", ".cc", ".cxx", ".cpp", ".m", ".s", ".h", ".hh", ".hpp", ".hxx", ".f", ".F", ".f90", ".S", ".sx", ".swig", ".swigcxx": // tentatively okay - read to make sure case ".syso": // binary, no reading @@ -1554,7 +1620,8 @@ func (ctxt *Context) makePathsAbsolute(args []string, srcDir string) { // The @ is for OS X. See golang.org/issue/13720. // The % is for Jenkins. See golang.org/issue/16959. // The ! is because module paths may use them. See golang.org/issue/26716. -const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%! " +// The ~ and ^ are for sr.ht. See golang.org/issue/32260. +const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%! ~^" func safeCgoName(s string) bool { if s == "" { diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go index f86e470a113..086a42e04d8 100644 --- a/libgo/go/go/build/build_test.go +++ b/libgo/go/go/build/build_test.go @@ -7,6 +7,7 @@ package build import ( "internal/testenv" "io" + "io/ioutil" "os" "path/filepath" "reflect" @@ -297,7 +298,7 @@ func TestShellSafety(t *testing.T) { result bool }{ {"-I${SRCDIR}/../include", "/projects/src/issue 11868", "-I/projects/src/issue 11868/../include", true}, - {"-I${SRCDIR}", "wtf$@%", "-Iwtf$@%", true}, + {"-I${SRCDIR}", "~wtf$@%^", "-I~wtf$@%^", true}, {"-X${SRCDIR}/1,${SRCDIR}/2", "/projects/src/issue 11868", "-X/projects/src/issue 11868/1,/projects/src/issue 11868/2", true}, {"-I/tmp -I/tmp", "/tmp2", "-I/tmp -I/tmp", true}, {"-I/tmp", "/tmp/[0]", "-I/tmp", true}, @@ -321,7 +322,15 @@ func TestShellSafety(t *testing.T) { func TestImportDirNotExist(t *testing.T) { testenv.MustHaveGoBuild(t) // really must just have source ctxt := Default - ctxt.GOPATH = "" + + emptyDir, err := ioutil.TempDir("", t.Name()) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(emptyDir) + + ctxt.GOPATH = emptyDir + ctxt.Dir = emptyDir tests := []struct { label string @@ -421,6 +430,47 @@ func TestImportVendorParentFailure(t *testing.T) { } } +// Check that a package is loaded in module mode if GO111MODULE=on, even when +// no go.mod file is present. It should fail to resolve packages outside std. +// Verifies golang.org/issue/34669. +func TestImportPackageOutsideModule(t *testing.T) { + testenv.MustHaveGoBuild(t) + + // Disable module fetching for this test so that 'go list' fails quickly + // without trying to find the latest version of a module. + defer os.Setenv("GOPROXY", os.Getenv("GOPROXY")) + os.Setenv("GOPROXY", "off") + + // Create a GOPATH in a temporary directory. We don't use testdata + // because it's in GOROOT, which interferes with the module heuristic. + gopath, err := ioutil.TempDir("", "gobuild-notmodule") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(gopath) + if err := os.MkdirAll(filepath.Join(gopath, "src/example.com/p"), 0777); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(filepath.Join(gopath, "src/example.com/p/p.go"), []byte("package p"), 0666); err != nil { + t.Fatal(err) + } + + defer os.Setenv("GO111MODULE", os.Getenv("GO111MODULE")) + os.Setenv("GO111MODULE", "on") + defer os.Setenv("GOPATH", os.Getenv("GOPATH")) + os.Setenv("GOPATH", gopath) + ctxt := Default + ctxt.GOPATH = gopath + ctxt.Dir = filepath.Join(gopath, "src/example.com/p") + + want := "cannot find module providing package" + if _, err := ctxt.Import("example.com/p", gopath, FindOnly); err == nil { + t.Fatal("importing package when no go.mod is present succeeded unexpectedly") + } else if errStr := err.Error(); !strings.Contains(errStr, want) { + t.Fatalf("error when importing package when no go.mod is present: got %q; want %q", errStr, want) + } +} + func TestImportDirTarget(t *testing.T) { testenv.MustHaveGoBuild(t) // really must just have source ctxt := Default @@ -449,3 +499,56 @@ func TestIssue23594(t *testing.T) { t.Fatalf("incorrectly set .Doc to %q", p.Doc) } } + +// TestMissingImportErrorRepetition checks that when an unknown package is +// imported, the package path is only shown once in the error. +// Verifies golang.org/issue/34752. +func TestMissingImportErrorRepetition(t *testing.T) { + testenv.MustHaveGoBuild(t) // need 'go list' internally + tmp, err := ioutil.TempDir("", "") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmp) + if err := ioutil.WriteFile(filepath.Join(tmp, "go.mod"), []byte("module m"), 0666); err != nil { + t.Fatal(err) + } + defer os.Setenv("GO111MODULE", os.Getenv("GO111MODULE")) + os.Setenv("GO111MODULE", "on") + defer os.Setenv("GOPROXY", os.Getenv("GOPROXY")) + os.Setenv("GOPROXY", "off") + defer os.Setenv("GONOPROXY", os.Getenv("GONOPROXY")) + os.Setenv("GONOPROXY", "none") + + ctxt := Default + ctxt.Dir = tmp + + pkgPath := "example.com/hello" + _, err = ctxt.Import(pkgPath, tmp, FindOnly) + if err == nil { + t.Fatal("unexpected success") + } + // Don't count the package path with a URL like https://...?go-get=1. + // See golang.org/issue/35986. + errStr := strings.ReplaceAll(err.Error(), "://"+pkgPath+"?go-get=1", "://...?go-get=1") + if n := strings.Count(errStr, pkgPath); n != 1 { + t.Fatalf("package path %q appears in error %d times; should appear once\nerror: %v", pkgPath, n, err) + } +} + +// TestCgoImportsIgnored checks that imports in cgo files are not included +// in the imports list when cgo is disabled. +// Verifies golang.org/issue/35946. +func TestCgoImportsIgnored(t *testing.T) { + ctxt := Default + ctxt.CgoEnabled = false + p, err := ctxt.ImportDir("testdata/cgo_disabled", 0) + if err != nil { + t.Fatal(err) + } + for _, path := range p.Imports { + if path == "should/be/ignored" { + t.Errorf("found import %q in ignored cgo file", path) + } + } +} diff --git a/libgo/go/go/build/deps_test.go b/libgo/go/go/build/deps_test.go index fb862459c8a..fd256ee000c 100644 --- a/libgo/go/go/build/deps_test.go +++ b/libgo/go/go/build/deps_test.go @@ -114,6 +114,7 @@ var pkgDeps = map[string][]string{ "hash/crc32": {"L2", "hash"}, "hash/crc64": {"L2", "hash"}, "hash/fnv": {"L2", "hash"}, + "hash/maphash": {"L2", "hash"}, "image": {"L2", "image/color"}, // interfaces "image/color": {"L2"}, // interfaces "image/color/palette": {"L2", "image/color"}, @@ -150,7 +151,7 @@ var pkgDeps = map[string][]string{ "syscall/js": {"L0"}, "internal/oserror": {"L0"}, "internal/syscall/unix": {"L0", "syscall"}, - "internal/syscall/windows": {"L0", "syscall", "internal/syscall/windows/sysdll"}, + "internal/syscall/windows": {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"}, "internal/syscall/windows/registry": {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"}, "time": { // "L0" without the "io" package: @@ -197,12 +198,13 @@ var pkgDeps = map[string][]string{ "runtime/trace": {"L0", "context", "fmt"}, "text/tabwriter": {"L2"}, - "testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"}, - "testing/iotest": {"L2", "log"}, - "testing/quick": {"L2", "flag", "fmt", "reflect", "time"}, - "internal/testenv": {"L2", "OS", "flag", "testing", "syscall", "internal/cfg"}, - "internal/lazyregexp": {"L2", "OS", "regexp"}, - "internal/lazytemplate": {"L2", "OS", "text/template"}, + "testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"}, + "testing/iotest": {"L2", "log"}, + "testing/quick": {"L2", "flag", "fmt", "reflect", "time"}, + "internal/obscuretestdata": {"L2", "OS", "encoding/base64"}, + "internal/testenv": {"L2", "OS", "flag", "testing", "syscall", "internal/cfg"}, + "internal/lazyregexp": {"L2", "OS", "regexp"}, + "internal/lazytemplate": {"L2", "OS", "text/template"}, // L4 is defined as L3+fmt+log+time, because in general once // you're using L3 packages, use of fmt, log, or time is not a big deal. @@ -250,7 +252,7 @@ var pkgDeps = map[string][]string{ "compress/gzip": {"L4", "compress/flate"}, "compress/lzw": {"L4"}, "compress/zlib": {"L4", "compress/flate"}, - "context": {"errors", "internal/reflectlite", "sync", "time"}, + "context": {"errors", "internal/reflectlite", "sync", "sync/atomic", "time"}, "database/sql": {"L4", "container/list", "context", "database/sql/driver", "database/sql/internal"}, "database/sql/driver": {"L4", "context", "time", "database/sql/internal"}, "debug/dwarf": {"L4"}, @@ -512,7 +514,7 @@ func listStdPkgs(goroot string) ([]string, error) { func TestDependencies(t *testing.T) { iOS := runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") - if runtime.GOOS == "nacl" || iOS { + if iOS { // Tests run in a limited file system and we do not // provide access to every source file. t.Skipf("skipping on %s/%s, missing full GOROOT", runtime.GOOS, runtime.GOARCH) diff --git a/libgo/go/go/build/doc.go b/libgo/go/go/build/doc.go index de793efa873..47dec5a05df 100644 --- a/libgo/go/go/build/doc.go +++ b/libgo/go/go/build/doc.go @@ -111,6 +111,7 @@ // - "go1.11", from Go version 1.11 onward // - "go1.12", from Go version 1.12 onward // - "go1.13", from Go version 1.13 onward +// - "go1.14", from Go version 1.14 onward // - any additional words listed in ctxt.BuildTags // // There are no build tags for beta or minor releases. diff --git a/libgo/go/go/build/syslist.go b/libgo/go/go/build/syslist.go index 1af1ae8e5e5..d72649b8b41 100644 --- a/libgo/go/go/build/syslist.go +++ b/libgo/go/go/build/syslist.go @@ -4,5 +4,8 @@ package build +// List of past, present, and future known GOOS and GOARCH values. +// Do not remove from this list, as these are used for go/build filename matching. + const goosList = "aix android darwin dragonfly freebsd hurd illumos js linux nacl netbsd openbsd plan9 solaris windows zos " const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv riscv64 s390 s390x sparc sparc64 wasm alpha m68k nios2 sh shbe " diff --git a/libgo/go/go/build/testdata/cgo_disabled/cgo_disabled.go b/libgo/go/go/build/testdata/cgo_disabled/cgo_disabled.go new file mode 100644 index 00000000000..d1edb99fa47 --- /dev/null +++ b/libgo/go/go/build/testdata/cgo_disabled/cgo_disabled.go @@ -0,0 +1,5 @@ +package cgo_disabled + +import "C" + +import _ "should/be/ignored" diff --git a/libgo/go/go/build/testdata/cgo_disabled/empty.go b/libgo/go/go/build/testdata/cgo_disabled/empty.go new file mode 100644 index 00000000000..63afe42d6ad --- /dev/null +++ b/libgo/go/go/build/testdata/cgo_disabled/empty.go @@ -0,0 +1 @@ +package cgo_disabled diff --git a/libgo/go/go/doc/comment.go b/libgo/go/go/doc/comment.go index 88be45bb8fb..da33f21612f 100644 --- a/libgo/go/go/doc/comment.go +++ b/libgo/go/go/doc/comment.go @@ -300,6 +300,9 @@ func anchorID(line string) string { // in the words map, the link is taken from the map (if the corresponding map // value is the empty string, the URL is not converted into a link). // +// A pair of (consecutive) backticks (`) is converted to a unicode left quote (“), and a pair of (consecutive) +// single quotes (') is converted to a unicode right quote (”). +// // 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. @@ -417,6 +420,9 @@ func blocks(text string) []block { // It wraps paragraphs of text to width or fewer Unicode code points // and then prefixes each line with the indent. In preformatted sections // (such as program text), it prefixes each non-blank line with preIndent. +// +// A pair of (consecutive) backticks (`) is converted to a unicode left quote (“), and a pair of (consecutive) +// single quotes (') is converted to a unicode right quote (”). func ToText(w io.Writer, text string, indent, preIndent string, width int) { l := lineWrapper{ out: w, diff --git a/libgo/go/go/doc/doc.go b/libgo/go/go/doc/doc.go index d0d4d3265b6..0e50af04f62 100644 --- a/libgo/go/go/doc/doc.go +++ b/libgo/go/go/doc/doc.go @@ -6,8 +6,10 @@ package doc import ( + "fmt" "go/ast" "go/token" + "strings" ) // Package is the documentation for an entire package. @@ -28,6 +30,11 @@ type Package struct { Types []*Type Vars []*Value Funcs []*Func + + // Examples is a sorted list of examples associated with + // the package. Examples are extracted from _test.go files + // provided to NewFromFiles. + Examples []*Example } // Value is the documentation for a (possibly grouped) var or const declaration. @@ -50,6 +57,11 @@ type Type struct { Vars []*Value // sorted list of variables of (mostly) this type Funcs []*Func // sorted list of functions returning this type Methods []*Func // sorted list of methods (including embedded ones) of this type + + // Examples is a sorted list of examples associated with + // this type. Examples are extracted from _test.go files + // provided to NewFromFiles. + Examples []*Example } // Func is the documentation for a func declaration. @@ -63,6 +75,11 @@ type Func struct { Recv string // actual receiver "T" or "*T" Orig string // original receiver "T" or "*T" Level int // embedding level; 0 means not embedded + + // Examples is a sorted list of examples associated with this + // function or method. Examples are extracted from _test.go files + // provided to NewFromFiles. + Examples []*Example } // A Note represents a marked comment starting with "MARKER(uid): note body". @@ -75,7 +92,7 @@ type Note struct { Body string // note body text } -// Mode values control the operation of New. +// Mode values control the operation of New and NewFromFiles. type Mode int const ( @@ -95,6 +112,8 @@ const ( // New computes the package documentation for the given package AST. // New takes ownership of the AST pkg and may edit or overwrite it. +// To have the Examples fields populated, use NewFromFiles and include +// the package's _test.go files. // func New(pkg *ast.Package, importPath string, mode Mode) *Package { var r reader @@ -115,3 +134,86 @@ func New(pkg *ast.Package, importPath string, mode Mode) *Package { Funcs: sortedFuncs(r.funcs, true), } } + +// NewFromFiles computes documentation for a package. +// +// The package is specified by a list of *ast.Files and corresponding +// file set, which must not be nil. NewFromFiles does not skip files +// based on build constraints, so it is the caller's responsibility to +// provide only the files that are matched by the build context. +// The import path of the package is specified by importPath. +// +// Examples found in _test.go files are associated with the corresponding +// type, function, method, or the package, based on their name. +// If the example has a suffix in its name, it is set in the +// Example.Suffix field. Examples with malformed names are skipped. +// +// Optionally, a single extra argument of type Mode can be provided to +// control low-level aspects of the documentation extraction behavior. +// +// NewFromFiles takes ownership of the AST files and may edit them, +// unless the PreserveAST Mode bit is on. +// +func NewFromFiles(fset *token.FileSet, files []*ast.File, importPath string, opts ...interface{}) (*Package, error) { + // Check for invalid API usage. + if fset == nil { + panic(fmt.Errorf("doc.NewFromFiles: no token.FileSet provided (fset == nil)")) + } + var mode Mode + switch len(opts) { // There can only be 0 or 1 options, so a simple switch works for now. + case 0: + // Nothing to do. + case 1: + m, ok := opts[0].(Mode) + if !ok { + panic(fmt.Errorf("doc.NewFromFiles: option argument type must be doc.Mode")) + } + mode = m + default: + panic(fmt.Errorf("doc.NewFromFiles: there must not be more than 1 option argument")) + } + + // Collect .go and _test.go files. + var ( + goFiles = make(map[string]*ast.File) + testGoFiles []*ast.File + ) + for i := range files { + f := fset.File(files[i].Pos()) + if f == nil { + return nil, fmt.Errorf("file files[%d] is not found in the provided file set", i) + } + switch name := f.Name(); { + case strings.HasSuffix(name, ".go") && !strings.HasSuffix(name, "_test.go"): + goFiles[name] = files[i] + case strings.HasSuffix(name, "_test.go"): + testGoFiles = append(testGoFiles, files[i]) + default: + return nil, fmt.Errorf("file files[%d] filename %q does not have a .go extension", i, name) + } + } + + // TODO(dmitshur,gri): A relatively high level call to ast.NewPackage with a simpleImporter + // ast.Importer implementation is made below. It might be possible to short-circuit and simplify. + + // Compute package documentation. + pkg, _ := ast.NewPackage(fset, goFiles, simpleImporter, nil) // Ignore errors that can happen due to unresolved identifiers. + p := New(pkg, importPath, mode) + classifyExamples(p, Examples(testGoFiles...)) + return p, nil +} + +// simpleImporter returns a (dummy) package object named by the last path +// component of the provided package path (as is the convention for packages). +// This is sufficient to resolve package identifiers without doing an actual +// import. It never returns an error. +func simpleImporter(imports map[string]*ast.Object, path string) (*ast.Object, error) { + pkg := imports[path] + if pkg == nil { + // note that strings.LastIndex returns -1 if there is no "/" + pkg = ast.NewObj(ast.Pkg, path[strings.LastIndex(path, "/")+1:]) + pkg.Data = ast.NewScope(nil) // required by ast.NewPackage for dot-import + imports[path] = pkg + } + return pkg, nil +} diff --git a/libgo/go/go/doc/doc_test.go b/libgo/go/go/doc/doc_test.go index 0b2d2b63ccc..f1e612c18bf 100644 --- a/libgo/go/go/doc/doc_test.go +++ b/libgo/go/go/doc/doc_test.go @@ -8,6 +8,7 @@ import ( "bytes" "flag" "fmt" + "go/ast" "go/parser" "go/printer" "go/token" @@ -99,8 +100,16 @@ func test(t *testing.T, mode Mode) { // test packages for _, pkg := range pkgs { - importpath := dataDir + "/" + pkg.Name - doc := New(pkg, importpath, mode) + importPath := dataDir + "/" + pkg.Name + var files []*ast.File + for _, f := range pkg.Files { + files = append(files, f) + } + doc, err := NewFromFiles(fset, files, importPath, mode) + if err != nil { + t.Error(err) + continue + } // golden files always use / in filenames - canonicalize them for i, filename := range doc.Filenames { diff --git a/libgo/go/go/doc/example.go b/libgo/go/go/doc/example.go index 7d1a57058ae..868db8a23fa 100644 --- a/libgo/go/go/doc/example.go +++ b/libgo/go/go/doc/example.go @@ -18,9 +18,10 @@ import ( "unicode/utf8" ) -// An Example represents an example function found in a source files. +// An Example represents an example function found in a test source file. type Example struct { - Name string // name of the item being exemplified + Name string // name of the item being exemplified (including optional suffix) + Suffix string // example suffix, without leading '_' (only populated by NewFromFiles) Doc string // example function doc string Code ast.Node Play *ast.File // a whole program version of the example @@ -31,8 +32,10 @@ type Example struct { Order int // original source code order } -// Examples returns the examples found in the files, sorted by Name field. +// Examples returns the examples found in testFiles, sorted by Name field. // The Order fields record the order in which the examples were encountered. +// The Suffix field is not populated when Examples is called directly, it is +// only populated by NewFromFiles for examples it finds in _test.go files. // // Playable Examples must be in a package whose name ends in "_test". // An Example is "playable" (the Play field is non-nil) in either of these @@ -44,9 +47,9 @@ type Example struct { // example function, zero test or benchmark functions, and at least one // top-level function, type, variable, or constant declaration other // than the example function. -func Examples(files ...*ast.File) []*Example { +func Examples(testFiles ...*ast.File) []*Example { var list []*Example - for _, file := range files { + for _, file := range testFiles { hasTests := false // file contains tests or benchmarks numDecl := 0 // number of non-import declarations in the file var flist []*Example @@ -59,6 +62,9 @@ func Examples(files ...*ast.File) []*Example { if !ok || f.Recv != nil { continue } + if params := f.Type.Params; params.List != nil { + continue // function has params; not a valid example + } numDecl++ name := f.Name.Name if isTest(name, "Test") || isTest(name, "Benchmark") { @@ -441,3 +447,101 @@ func lastComment(b *ast.BlockStmt, c []*ast.CommentGroup) (i int, last *ast.Comm } return } + +// classifyExamples classifies examples and assigns them to the Examples field +// of the relevant Func, Type, or Package that the example is associated with. +// +// The classification process is ambiguous in some cases: +// +// - ExampleFoo_Bar matches a type named Foo_Bar +// or a method named Foo.Bar. +// - ExampleFoo_bar matches a type named Foo_bar +// or Foo (with a "bar" suffix). +// +// Examples with malformed names are not associated with anything. +// +func classifyExamples(p *Package, examples []*Example) { + if len(examples) == 0 { + return + } + + // Mapping of names for funcs, types, and methods to the example listing. + ids := make(map[string]*[]*Example) + ids[""] = &p.Examples // package-level examples have an empty name + for _, f := range p.Funcs { + if !token.IsExported(f.Name) { + continue + } + ids[f.Name] = &f.Examples + } + for _, t := range p.Types { + if !token.IsExported(t.Name) { + continue + } + ids[t.Name] = &t.Examples + for _, f := range t.Funcs { + if !token.IsExported(f.Name) { + continue + } + ids[f.Name] = &f.Examples + } + for _, m := range t.Methods { + if !token.IsExported(m.Name) || m.Level != 0 { // avoid forwarded methods from embedding + continue + } + ids[strings.TrimPrefix(m.Recv, "*")+"_"+m.Name] = &m.Examples + } + } + + // Group each example with the associated func, type, or method. + for _, ex := range examples { + // Consider all possible split points for the suffix + // by starting at the end of string (no suffix case), + // then trying all positions that contain a '_' character. + // + // An association is made on the first successful match. + // Examples with malformed names that match nothing are skipped. + for i := len(ex.Name); i >= 0; i = strings.LastIndexByte(ex.Name[:i], '_') { + prefix, suffix, ok := splitExampleName(ex.Name, i) + if !ok { + continue + } + exs, ok := ids[prefix] + if !ok { + continue + } + ex.Suffix = suffix + *exs = append(*exs, ex) + break + } + } + + // Sort list of example according to the user-specified suffix name. + for _, exs := range ids { + sort.Slice((*exs), func(i, j int) bool { + return (*exs)[i].Suffix < (*exs)[j].Suffix + }) + } +} + +// splitExampleName attempts to split example name s at index i, +// and reports if that produces a valid split. The suffix may be +// absent. Otherwise, it must start with a lower-case letter and +// be preceded by '_'. +// +// One of i == len(s) or s[i] == '_' must be true. +func splitExampleName(s string, i int) (prefix, suffix string, ok bool) { + if i == len(s) { + return s, "", true + } + if i == len(s)-1 { + return "", "", false + } + prefix, suffix = s[:i], s[i+1:] + return prefix, suffix, isExampleSuffix(suffix) +} + +func isExampleSuffix(s string) bool { + r, size := utf8.DecodeRuneInString(s) + return size > 0 && unicode.IsLower(r) +} diff --git a/libgo/go/go/doc/example_test.go b/libgo/go/go/doc/example_test.go index 74fd10626d2..cd2f469c2fb 100644 --- a/libgo/go/go/doc/example_test.go +++ b/libgo/go/go/doc/example_test.go @@ -6,11 +6,13 @@ package doc_test import ( "bytes" + "fmt" "go/ast" "go/doc" "go/format" "go/parser" "go/token" + "reflect" "strings" "testing" ) @@ -458,3 +460,212 @@ func formatFile(t *testing.T, fset *token.FileSet, n *ast.File) string { } return buf.String() } + +// This example illustrates how to use NewFromFiles +// to compute package documentation with examples. +func ExampleNewFromFiles() { + // src and test are two source files that make up + // a package whose documentation will be computed. + const src = ` +// This is the package comment. +package p + +import "fmt" + +// This comment is associated with the Greet function. +func Greet(who string) { + fmt.Printf("Hello, %s!\n", who) +} +` + const test = ` +package p_test + +// This comment is associated with the ExampleGreet_world example. +func ExampleGreet_world() { + Greet("world") +} +` + + // Create the AST by parsing src and test. + fset := token.NewFileSet() + files := []*ast.File{ + mustParse(fset, "src.go", src), + mustParse(fset, "src_test.go", test), + } + + // Compute package documentation with examples. + p, err := doc.NewFromFiles(fset, files, "example.com/p") + if err != nil { + panic(err) + } + + fmt.Printf("package %s - %s", p.Name, p.Doc) + fmt.Printf("func %s - %s", p.Funcs[0].Name, p.Funcs[0].Doc) + fmt.Printf(" ⤷ example with suffix %q - %s", p.Funcs[0].Examples[0].Suffix, p.Funcs[0].Examples[0].Doc) + + // Output: + // package p - This is the package comment. + // func Greet - This comment is associated with the Greet function. + // ⤷ example with suffix "world" - This comment is associated with the ExampleGreet_world example. +} + +func TestClassifyExamples(t *testing.T) { + const src = ` +package p + +const Const1 = 0 +var Var1 = 0 + +type ( + Type1 int + Type1_Foo int + Type1_foo int + type2 int + + Embed struct { Type1 } +) + +func Func1() {} +func Func1_Foo() {} +func Func1_foo() {} +func func2() {} + +func (Type1) Func1() {} +func (Type1) Func1_Foo() {} +func (Type1) Func1_foo() {} +func (Type1) func2() {} + +type ( + Conflict int + Conflict_Conflict int + Conflict_conflict int +) + +func (Conflict) Conflict() {} +` + const test = ` +package p_test + +func ExampleConst1() {} // invalid - no support for consts and vars +func ExampleVar1() {} // invalid - no support for consts and vars + +func Example() {} +func Example_() {} // invalid - suffix must start with a lower-case letter +func Example_suffix() {} +func Example_suffix_xX_X_x() {} +func Example_世界() {} // invalid - suffix must start with a lower-case letter +func Example_123() {} // invalid - suffix must start with a lower-case letter +func Example_BadSuffix() {} // invalid - suffix must start with a lower-case letter + +func ExampleType1() {} +func ExampleType1_() {} // invalid - suffix must start with a lower-case letter +func ExampleType1_suffix() {} +func ExampleType1_BadSuffix() {} // invalid - suffix must start with a lower-case letter +func ExampleType1_Foo() {} +func ExampleType1_Foo_suffix() {} +func ExampleType1_Foo_BadSuffix() {} // invalid - suffix must start with a lower-case letter +func ExampleType1_foo() {} +func ExampleType1_foo_suffix() {} +func ExampleType1_foo_Suffix() {} // matches Type1, instead of Type1_foo +func Exampletype2() {} // invalid - cannot match unexported + +func ExampleFunc1() {} +func ExampleFunc1_() {} // invalid - suffix must start with a lower-case letter +func ExampleFunc1_suffix() {} +func ExampleFunc1_BadSuffix() {} // invalid - suffix must start with a lower-case letter +func ExampleFunc1_Foo() {} +func ExampleFunc1_Foo_suffix() {} +func ExampleFunc1_Foo_BadSuffix() {} // invalid - suffix must start with a lower-case letter +func ExampleFunc1_foo() {} +func ExampleFunc1_foo_suffix() {} +func ExampleFunc1_foo_Suffix() {} // matches Func1, instead of Func1_foo +func Examplefunc1() {} // invalid - cannot match unexported + +func ExampleType1_Func1() {} +func ExampleType1_Func1_() {} // invalid - suffix must start with a lower-case letter +func ExampleType1_Func1_suffix() {} +func ExampleType1_Func1_BadSuffix() {} // invalid - suffix must start with a lower-case letter +func ExampleType1_Func1_Foo() {} +func ExampleType1_Func1_Foo_suffix() {} +func ExampleType1_Func1_Foo_BadSuffix() {} // invalid - suffix must start with a lower-case letter +func ExampleType1_Func1_foo() {} +func ExampleType1_Func1_foo_suffix() {} +func ExampleType1_Func1_foo_Suffix() {} // matches Type1.Func1, instead of Type1.Func1_foo +func ExampleType1_func2() {} // matches Type1, instead of Type1.func2 + +func ExampleEmbed_Func1() {} // invalid - no support for forwarded methods from embedding + +func ExampleConflict_Conflict() {} // ambiguous with either Conflict or Conflict_Conflict type +func ExampleConflict_conflict() {} // ambiguous with either Conflict or Conflict_conflict type +func ExampleConflict_Conflict_suffix() {} // ambiguous with either Conflict or Conflict_Conflict type +func ExampleConflict_conflict_suffix() {} // ambiguous with either Conflict or Conflict_conflict type +` + + // Parse literal source code as a *doc.Package. + fset := token.NewFileSet() + files := []*ast.File{ + mustParse(fset, "src.go", src), + mustParse(fset, "src_test.go", test), + } + p, err := doc.NewFromFiles(fset, files, "example.com/p") + if err != nil { + t.Fatalf("doc.NewFromFiles: %v", err) + } + + // Collect the association of examples to top-level identifiers. + got := map[string][]string{} + got[""] = exampleNames(p.Examples) + for _, f := range p.Funcs { + got[f.Name] = exampleNames(f.Examples) + } + for _, t := range p.Types { + got[t.Name] = exampleNames(t.Examples) + for _, f := range t.Funcs { + got[f.Name] = exampleNames(f.Examples) + } + for _, m := range t.Methods { + got[t.Name+"."+m.Name] = exampleNames(m.Examples) + } + } + + want := map[string][]string{ + "": {"", "suffix", "suffix_xX_X_x"}, // Package-level examples. + + "Type1": {"", "foo_Suffix", "func2", "suffix"}, + "Type1_Foo": {"", "suffix"}, + "Type1_foo": {"", "suffix"}, + + "Func1": {"", "foo_Suffix", "suffix"}, + "Func1_Foo": {"", "suffix"}, + "Func1_foo": {"", "suffix"}, + + "Type1.Func1": {"", "foo_Suffix", "suffix"}, + "Type1.Func1_Foo": {"", "suffix"}, + "Type1.Func1_foo": {"", "suffix"}, + + // These are implementation dependent due to the ambiguous parsing. + "Conflict_Conflict": {"", "suffix"}, + "Conflict_conflict": {"", "suffix"}, + } + + for id := range got { + if !reflect.DeepEqual(got[id], want[id]) { + t.Errorf("classification mismatch for %q:\ngot %q\nwant %q", id, got[id], want[id]) + } + } +} + +func exampleNames(exs []*doc.Example) (out []string) { + for _, ex := range exs { + out = append(out, ex.Suffix) + } + return out +} + +func mustParse(fset *token.FileSet, filename, src string) *ast.File { + f, err := parser.ParseFile(fset, filename, src, parser.ParseComments) + if err != nil { + panic(err) + } + return f +} diff --git a/libgo/go/go/doc/testdata/bugpara.go b/libgo/go/go/doc/testdata/bugpara.go index f5345a79753..0360a6f6673 100644 --- a/libgo/go/go/doc/testdata/bugpara.go +++ b/libgo/go/go/doc/testdata/bugpara.go @@ -1,3 +1,7 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package bugpara // BUG(rsc): Sometimes bugs have multiple paragraphs. diff --git a/libgo/go/go/doc/testdata/issue10858.0.golden b/libgo/go/go/doc/testdata/issue10858.0.golden deleted file mode 100644 index 51f8f1e0d30..00000000000 --- a/libgo/go/go/doc/testdata/issue10858.0.golden +++ /dev/null @@ -1,79 +0,0 @@ -// -PACKAGE issue10858 - -IMPORTPATH - testdata/issue10858 - -IMPORTS - unsafe - -FILENAMES - testdata/issue10858.go - -CONSTANTS - // First line Second line - const ( - - // C1 comment - C1 int = 1 << 0 - - C2 int = 1 << 1 - - // C3 comment - // - // with a line gap - C3 int = 1 << 2 - ) - - -TYPES - // StructTag is a comment with 2 connecting lines - type StructTag string // adjacent comment - - // Get returns the value associated with key in the tag string. - func (tag StructTag) Get(key string) string - - // First line Second line - type Type interface { - // Should be present - - // Align returns the alignment in bytes of a value of - // this type when allocated in memory. - Align() int - - // FieldAlign returns the alignment in bytes of a value of - // this type when used as a field in a struct. - FieldAlign() int // adjacent comment - - // Ptr: Elem - // Slice: Elem - - // Bits returns the size of the type in bits. - - // - // It panics if the type's Kind is not one of the - // sized or unsized Int, Uint, Float, or Complex kinds. - Bits() int - } - - // NewType is a comment ending with this line. - func NewType() Type - - // TypeAlg is a copy of runtime.typeAlg - type TypeAlg struct { - // function for hashing objects of this type - // - // - // (ptr to object, seed) -> hash - Hash func(unsafe.Pointer, uintptr) uintptr - - // include - // include - - // include - - // function for comparing objects of this type - // (ptr to object A, ptr to object B) -> ==? - Equal func(unsafe.Pointer, unsafe.Pointer) bool - } - diff --git a/libgo/go/go/doc/testdata/issue10858.1.golden b/libgo/go/go/doc/testdata/issue10858.1.golden deleted file mode 100644 index 51f8f1e0d30..00000000000 --- a/libgo/go/go/doc/testdata/issue10858.1.golden +++ /dev/null @@ -1,79 +0,0 @@ -// -PACKAGE issue10858 - -IMPORTPATH - testdata/issue10858 - -IMPORTS - unsafe - -FILENAMES - testdata/issue10858.go - -CONSTANTS - // First line Second line - const ( - - // C1 comment - C1 int = 1 << 0 - - C2 int = 1 << 1 - - // C3 comment - // - // with a line gap - C3 int = 1 << 2 - ) - - -TYPES - // StructTag is a comment with 2 connecting lines - type StructTag string // adjacent comment - - // Get returns the value associated with key in the tag string. - func (tag StructTag) Get(key string) string - - // First line Second line - type Type interface { - // Should be present - - // Align returns the alignment in bytes of a value of - // this type when allocated in memory. - Align() int - - // FieldAlign returns the alignment in bytes of a value of - // this type when used as a field in a struct. - FieldAlign() int // adjacent comment - - // Ptr: Elem - // Slice: Elem - - // Bits returns the size of the type in bits. - - // - // It panics if the type's Kind is not one of the - // sized or unsized Int, Uint, Float, or Complex kinds. - Bits() int - } - - // NewType is a comment ending with this line. - func NewType() Type - - // TypeAlg is a copy of runtime.typeAlg - type TypeAlg struct { - // function for hashing objects of this type - // - // - // (ptr to object, seed) -> hash - Hash func(unsafe.Pointer, uintptr) uintptr - - // include - // include - - // include - - // function for comparing objects of this type - // (ptr to object A, ptr to object B) -> ==? - Equal func(unsafe.Pointer, unsafe.Pointer) bool - } - diff --git a/libgo/go/go/doc/testdata/issue10858.2.golden b/libgo/go/go/doc/testdata/issue10858.2.golden deleted file mode 100644 index 51f8f1e0d30..00000000000 --- a/libgo/go/go/doc/testdata/issue10858.2.golden +++ /dev/null @@ -1,79 +0,0 @@ -// -PACKAGE issue10858 - -IMPORTPATH - testdata/issue10858 - -IMPORTS - unsafe - -FILENAMES - testdata/issue10858.go - -CONSTANTS - // First line Second line - const ( - - // C1 comment - C1 int = 1 << 0 - - C2 int = 1 << 1 - - // C3 comment - // - // with a line gap - C3 int = 1 << 2 - ) - - -TYPES - // StructTag is a comment with 2 connecting lines - type StructTag string // adjacent comment - - // Get returns the value associated with key in the tag string. - func (tag StructTag) Get(key string) string - - // First line Second line - type Type interface { - // Should be present - - // Align returns the alignment in bytes of a value of - // this type when allocated in memory. - Align() int - - // FieldAlign returns the alignment in bytes of a value of - // this type when used as a field in a struct. - FieldAlign() int // adjacent comment - - // Ptr: Elem - // Slice: Elem - - // Bits returns the size of the type in bits. - - // - // It panics if the type's Kind is not one of the - // sized or unsized Int, Uint, Float, or Complex kinds. - Bits() int - } - - // NewType is a comment ending with this line. - func NewType() Type - - // TypeAlg is a copy of runtime.typeAlg - type TypeAlg struct { - // function for hashing objects of this type - // - // - // (ptr to object, seed) -> hash - Hash func(unsafe.Pointer, uintptr) uintptr - - // include - // include - - // include - - // function for comparing objects of this type - // (ptr to object A, ptr to object B) -> ==? - Equal func(unsafe.Pointer, unsafe.Pointer) bool - } - diff --git a/libgo/go/go/internal/gccgoimporter/importer_test.go b/libgo/go/go/internal/gccgoimporter/importer_test.go index 37250fde413..a74a4568680 100644 --- a/libgo/go/go/internal/gccgoimporter/importer_test.go +++ b/libgo/go/go/internal/gccgoimporter/importer_test.go @@ -100,7 +100,7 @@ var importerTests = [...]importerTest{ } func TestGoxImporter(t *testing.T) { - testenv.MustHaveExec(t) // this is to skip nacl, js + testenv.MustHaveExec(t) initmap := make(map[*types.Package]InitData) imp := GetImporter([]string{"testdata"}, initmap) diff --git a/libgo/go/go/internal/gccgoimporter/parser.go b/libgo/go/go/internal/gccgoimporter/parser.go index c089b5e0541..9204b004f9b 100644 --- a/libgo/go/go/internal/gccgoimporter/parser.go +++ b/libgo/go/go/internal/gccgoimporter/parser.go @@ -475,13 +475,11 @@ func (p *parser) reserve(n int) { // used to resolve pointers to named types in case they are referenced // by embedded fields. func (p *parser) update(t types.Type, nlist []interface{}) { - if len(nlist) != 0 { - if t == reserved { - p.errorf("internal error: update(%v) invoked on reserved", nlist) - } - if t == nil { - p.errorf("internal error: update(%v) invoked on nil", nlist) - } + if t == reserved { + p.errorf("internal error: update(%v) invoked on reserved", nlist) + } + if t == nil { + p.errorf("internal error: update(%v) invoked on nil", nlist) } for _, n := range nlist { switch n := n.(type) { diff --git a/libgo/go/go/internal/gcimporter/bimport.go b/libgo/go/go/internal/gcimporter/bimport.go index cf03632aa20..1019ccb8f77 100644 --- a/libgo/go/go/internal/gcimporter/bimport.go +++ b/libgo/go/go/internal/gcimporter/bimport.go @@ -328,7 +328,7 @@ func (p *importer) pos() token.Pos { p.prevFile = file p.prevLine = line - return p.fake.pos(file, line) + return p.fake.pos(file, line, 0) } // Synthesize a token.Pos @@ -337,7 +337,9 @@ type fakeFileSet struct { files map[string]*token.File } -func (s *fakeFileSet) pos(file string, line int) token.Pos { +func (s *fakeFileSet) pos(file string, line, column int) token.Pos { + // TODO(mdempsky): Make use of column. + // Since we don't know the set of needed file positions, we // reserve maxlines positions per file. const maxlines = 64 * 1024 diff --git a/libgo/go/go/internal/gcimporter/gcimporter_test.go b/libgo/go/go/internal/gcimporter/gcimporter_test.go index 3b7636806e7..df93f3f0628 100644 --- a/libgo/go/go/internal/gcimporter/gcimporter_test.go +++ b/libgo/go/go/internal/gcimporter/gcimporter_test.go @@ -26,10 +26,7 @@ import ( // import. func skipSpecialPlatforms(t *testing.T) { switch platform := runtime.GOOS + "-" + runtime.GOARCH; platform { - case "nacl-amd64p32", - "nacl-386", - "nacl-arm", - "darwin-arm", + case "darwin-arm", "darwin-arm64": t.Skipf("no compiled packages available for import on %s", platform) } @@ -140,7 +137,7 @@ func TestImportTestdata(t *testing.T) { } func TestVersionHandling(t *testing.T) { - skipSpecialPlatforms(t) // we really only need to exclude nacl platforms, but this is fine + skipSpecialPlatforms(t) // This package only handles gc export data. if runtime.Compiler != "gc" { diff --git a/libgo/go/go/internal/gcimporter/iimport.go b/libgo/go/go/internal/gcimporter/iimport.go index bf480641df9..c59dd165331 100644 --- a/libgo/go/go/internal/gcimporter/iimport.go +++ b/libgo/go/go/internal/gcimporter/iimport.go @@ -61,8 +61,8 @@ const ( // If the export data version is not recognized or the format is otherwise // compromised, an error is returned. func iImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { - const currentVersion = 0 - version := -1 + const currentVersion = 1 + version := int64(-1) defer func() { if e := recover(); e != nil { if version > currentVersion { @@ -75,9 +75,9 @@ func iImportData(fset *token.FileSet, imports map[string]*types.Package, data [] r := &intReader{bytes.NewReader(data), path} - version = int(r.uint64()) + version = int64(r.uint64()) switch version { - case currentVersion: + case currentVersion, 0: default: errorf("unknown iexport format version %d", version) } @@ -91,7 +91,8 @@ func iImportData(fset *token.FileSet, imports map[string]*types.Package, data [] r.Seek(sLen+dLen, io.SeekCurrent) p := iimporter{ - ipath: path, + ipath: path, + version: int(version), stringData: stringData, stringCache: make(map[uint64]string), @@ -169,7 +170,8 @@ func iImportData(fset *token.FileSet, imports map[string]*types.Package, data [] } type iimporter struct { - ipath string + ipath string + version int stringData []byte stringCache map[uint64]string @@ -249,6 +251,7 @@ type importReader struct { currPkg *types.Package prevFile string prevLine int64 + prevColumn int64 } func (r *importReader) obj(name string) { @@ -438,6 +441,19 @@ func (r *importReader) qualifiedIdent() (*types.Package, string) { } func (r *importReader) pos() token.Pos { + if r.p.version >= 1 { + r.posv1() + } else { + r.posv0() + } + + if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 { + return token.NoPos + } + return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn)) +} + +func (r *importReader) posv0() { delta := r.int64() if delta != deltaNewFile { r.prevLine += delta @@ -447,12 +463,18 @@ func (r *importReader) pos() token.Pos { r.prevFile = r.string() r.prevLine = l } +} - if r.prevFile == "" && r.prevLine == 0 { - return token.NoPos +func (r *importReader) posv1() { + delta := r.int64() + r.prevColumn += delta >> 1 + if delta&1 != 0 { + delta = r.int64() + r.prevLine += delta >> 1 + if delta&1 != 0 { + r.prevFile = r.string() + } } - - return r.p.fake.pos(r.prevFile, int(r.prevLine)) } func (r *importReader) typ() types.Type { diff --git a/libgo/go/go/parser/interface.go b/libgo/go/go/parser/interface.go index 9de160a7988..500c98d4966 100644 --- a/libgo/go/go/parser/interface.go +++ b/libgo/go/go/parser/interface.go @@ -75,7 +75,7 @@ const ( // indicates the specific failure. If the source was read but syntax // errors were found, the result is a partial AST (with ast.Bad* nodes // representing the fragments of erroneous source code). Multiple errors -// are returned via a scanner.ErrorList which is sorted by file position. +// are returned via a scanner.ErrorList which is sorted by source position. // func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (f *ast.File, err error) { if fset == nil { @@ -173,7 +173,13 @@ func ParseDir(fset *token.FileSet, path string, filter func(os.FileInfo) bool, m // be a valid Go (type or value) expression. Specifically, fset must not // be nil. // -func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode Mode) (ast.Expr, error) { +// If the source couldn't be read, the returned AST is nil and the error +// indicates the specific failure. If the source was read but syntax +// errors were found, the result is a partial AST (with ast.Bad* nodes +// representing the fragments of erroneous source code). Multiple errors +// are returned via a scanner.ErrorList which is sorted by source position. +// +func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode Mode) (expr ast.Expr, err error) { if fset == nil { panic("parser.ParseExprFrom: no token.FileSet provided (fset == nil)") } @@ -204,7 +210,7 @@ func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode M // in case of an erroneous x. p.openScope() p.pkgScope = p.topScope - e := p.parseRhsOrType() + expr = p.parseRhsOrType() p.closeScope() assert(p.topScope == nil, "unbalanced scopes") @@ -215,18 +221,17 @@ func ParseExprFrom(fset *token.FileSet, filename string, src interface{}, mode M } p.expect(token.EOF) - if p.errors.Len() > 0 { - p.errors.Sort() - return nil, p.errors.Err() - } - - return e, nil + return } // ParseExpr is a convenience function for obtaining the AST of an expression x. // The position information recorded in the AST is undefined. The filename used // in error messages is the empty string. // +// If syntax errors were found, the result is a partial AST (with ast.Bad* nodes +// representing the fragments of erroneous source code). Multiple errors are +// returned via a scanner.ErrorList which is sorted by source position. +// func ParseExpr(x string) (ast.Expr, error) { return ParseExprFrom(token.NewFileSet(), "", []byte(x), 0) } diff --git a/libgo/go/go/parser/parser.go b/libgo/go/go/parser/parser.go index ba16b652246..31a73985bf3 100644 --- a/libgo/go/go/parser/parser.go +++ b/libgo/go/go/parser/parser.go @@ -397,6 +397,18 @@ func (p *parser) expect(tok token.Token) token.Pos { return pos } +// expect2 is like expect, but it returns an invalid position +// if the expected token is not found. +func (p *parser) expect2(tok token.Token) (pos token.Pos) { + if p.tok == tok { + pos = p.pos + } else { + p.errorExpected(p.pos, "'"+tok.String()+"'") + } + p.next() // make progress + return +} + // expectClosing is like expect but provides a better error message // for the common case of a missing comma before a newline. // @@ -1082,7 +1094,7 @@ func (p *parser) parseBody(scope *ast.Scope) *ast.BlockStmt { list := p.parseStmtList() p.closeLabelScope() p.closeScope() - rbrace := p.expect(token.RBRACE) + rbrace := p.expect2(token.RBRACE) return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace} } @@ -1096,7 +1108,7 @@ func (p *parser) parseBlockStmt() *ast.BlockStmt { p.openScope() list := p.parseStmtList() p.closeScope() - rbrace := p.expect(token.RBRACE) + rbrace := p.expect2(token.RBRACE) return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace} } @@ -1446,7 +1458,6 @@ func (p *parser) checkExprOrType(x ast.Expr) ast.Expr { switch t := unparen(x).(type) { case *ast.ParenExpr: panic("unreachable") - case *ast.UnaryExpr: case *ast.ArrayType: if len, isEllipsis := t.Len.(*ast.Ellipsis); isEllipsis { p.error(len.Pos(), "expected array length, found '...'") @@ -2439,8 +2450,18 @@ func (p *parser) parseFuncDecl() *ast.FuncDecl { var body *ast.BlockStmt if p.tok == token.LBRACE { body = p.parseBody(scope) + p.expectSemi() + } else if p.tok == token.SEMICOLON { + p.next() + if p.tok == token.LBRACE { + // opening { of function declaration on next line + p.error(p.pos, "unexpected semicolon or newline before {") + body = p.parseBody(scope) + p.expectSemi() + } + } else { + p.expectSemi() } - p.expectSemi() decl := &ast.FuncDecl{ Doc: doc, diff --git a/libgo/go/go/parser/parser_test.go b/libgo/go/go/parser/parser_test.go index fb35a88ba1a..25a374eeefc 100644 --- a/libgo/go/go/parser/parser_test.go +++ b/libgo/go/go/parser/parser_test.go @@ -42,6 +42,22 @@ func nameFilter(filename string) bool { func dirFilter(f os.FileInfo) bool { return nameFilter(f.Name()) } +func TestParseFile(t *testing.T) { + src := "package p\nvar _=s[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]" + _, err := ParseFile(token.NewFileSet(), "", src, 0) + if err == nil { + t.Errorf("ParseFile(%s) succeeded unexpectedly", src) + } +} + +func TestParseExprFrom(t *testing.T) { + src := "s[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]+\ns[::]" + _, err := ParseExprFrom(token.NewFileSet(), "", src, 0) + if err == nil { + t.Errorf("ParseExprFrom(%s) succeeded unexpectedly", src) + } +} + func TestParseDir(t *testing.T) { path := "." pkgs, err := ParseDir(token.NewFileSet(), path, dirFilter, 0) @@ -92,9 +108,16 @@ func TestParseExpr(t *testing.T) { // an invalid expression src = "a + *" - if _, err := ParseExpr(src); err == nil { + x, err = ParseExpr(src) + if err == nil { t.Errorf("ParseExpr(%q): got no error", src) } + if x == nil { + t.Errorf("ParseExpr(%q): got no (partial) result", src) + } + if _, ok := x.(*ast.BinaryExpr); !ok { + t.Errorf("ParseExpr(%q): got %T, want *ast.BinaryExpr", src, x) + } // a valid expression followed by extra tokens is invalid src = "a[i] := x" diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go index fa7589e8684..e4cb58a87fc 100644 --- a/libgo/go/go/printer/nodes.go +++ b/libgo/go/go/printer/nodes.go @@ -794,8 +794,11 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) { p.print(x) case *ast.FuncLit: - p.expr(x.Type) - p.funcBody(p.distanceFrom(x.Type.Pos()), blank, x.Body) + p.print(x.Type.Pos(), token.FUNC) + // See the comment in funcDecl about how the header size is computed. + startCol := p.out.Column - len("func") + p.signature(x.Type.Params, x.Type.Results) + p.funcBody(p.distanceFrom(x.Type.Pos(), startCol), blank, x.Body) case *ast.ParenExpr: if _, hasParens := x.X.(*ast.ParenExpr); hasParens { @@ -1237,10 +1240,12 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) { // lead to more nicely formatted code in general. if p.indentList(s.Results) { p.print(indent) - p.exprList(s.Pos(), s.Results, 1, noIndent, token.NoPos, false) + // Use NoPos so that a newline never goes before + // the results (see issue #32854). + p.exprList(token.NoPos, s.Results, 1, noIndent, token.NoPos, false) p.print(unindent) } else { - p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos, false) + p.exprList(token.NoPos, s.Results, 1, 0, token.NoPos, false) } } @@ -1687,14 +1692,12 @@ func (p *printer) funcBody(headerSize int, sep whiteSpace, b *ast.BlockStmt) { p.block(b, 1) } -// distanceFrom returns the column difference between from and p.pos (the current -// estimated position) if both are on the same line; if they are on different lines -// (or unknown) the result is infinity. -func (p *printer) distanceFrom(from token.Pos) int { - if from.IsValid() && p.pos.IsValid() { - if f := p.posFor(from); f.Line == p.pos.Line { - return p.pos.Column - f.Column - } +// distanceFrom returns the column difference between p.out (the current output +// position) and startOutCol. If the start position is on a different line from +// the current position (or either is unknown), the result is infinity. +func (p *printer) distanceFrom(startPos token.Pos, startOutCol int) int { + if startPos.IsValid() && p.pos.IsValid() && p.posFor(startPos).Line == p.pos.Line { + return p.out.Column - startOutCol } return infinity } @@ -1702,13 +1705,17 @@ func (p *printer) distanceFrom(from token.Pos) int { func (p *printer) funcDecl(d *ast.FuncDecl) { p.setComment(d.Doc) p.print(d.Pos(), token.FUNC, blank) + // We have to save startCol only after emitting FUNC; otherwise it can be on a + // different line (all whitespace preceding the FUNC is emitted only when the + // FUNC is emitted). + startCol := p.out.Column - len("func ") if d.Recv != nil { p.parameters(d.Recv) // method: print receiver p.print(blank) } p.expr(d.Name) p.signature(d.Type.Params, d.Type.Results) - p.funcBody(p.distanceFrom(d.Pos()), vtab, d.Body) + p.funcBody(p.distanceFrom(d.Pos(), startCol), vtab, d.Body) } func (p *printer) decl(decl ast.Decl) { diff --git a/libgo/go/go/printer/printer_test.go b/libgo/go/go/printer/printer_test.go index a240bf48465..8f9cd534b43 100644 --- a/libgo/go/go/printer/printer_test.go +++ b/libgo/go/go/printer/printer_test.go @@ -775,3 +775,34 @@ func TestParenthesizedDecl(t *testing.T) { t.Errorf("got %q, want %q", noparen, original) } } + +// Verify that we don't print a newline between "return" and its results, as +// that would incorrectly cause a naked return. +func TestIssue32854(t *testing.T) { + src := `package foo + +func f() { + return Composite{ + call(), + } +}` + fset := token.NewFileSet() + file, err := parser.ParseFile(fset, "", src, 0) + if err != nil { + panic(err) + } + + // Replace the result with call(), which is on the next line. + fd := file.Decls[0].(*ast.FuncDecl) + ret := fd.Body.List[0].(*ast.ReturnStmt) + ret.Results[0] = ret.Results[0].(*ast.CompositeLit).Elts[0] + + var buf bytes.Buffer + if err := Fprint(&buf, fset, ret); err != nil { + t.Fatal(err) + } + want := "return call()" + if got := buf.String(); got != want { + t.Fatalf("got %q, want %q", got, want) + } +} diff --git a/libgo/go/go/types/api.go b/libgo/go/go/types/api.go index 1252aade35f..2a21ad0c53f 100644 --- a/libgo/go/go/types/api.go +++ b/libgo/go/go/types/api.go @@ -259,9 +259,6 @@ type TypeAndValue struct { Value constant.Value } -// TODO(gri) Consider eliminating the IsVoid predicate. Instead, report -// "void" values as regular values but with the empty tuple type. - // IsVoid reports whether the corresponding expression // is a function call without results. func (tv TypeAndValue) IsVoid() bool { @@ -374,3 +371,15 @@ func Implements(V Type, T *Interface) bool { f, _ := MissingMethod(V, T, true) return f == nil } + +// Identical reports whether x and y are identical types. +// Receivers of Signature types are ignored. +func Identical(x, y Type) bool { + return (*Checker)(nil).identical(x, y) +} + +// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored. +// Receivers of Signature types are ignored. +func IdenticalIgnoreTags(x, y Type) bool { + return (*Checker)(nil).identicalIgnoreTags(x, y) +} diff --git a/libgo/go/go/types/builtins.go b/libgo/go/go/types/builtins.go index ece6d4f530c..af374b70c69 100644 --- a/libgo/go/go/types/builtins.go +++ b/libgo/go/go/types/builtins.go @@ -257,7 +257,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b } // both argument types must be identical - if !Identical(x.typ, y.typ) { + if !check.identical(x.typ, y.typ) { check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ) return } @@ -322,7 +322,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b return } - if !Identical(dst, src) { + if !check.identical(dst, src) { check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src) return } @@ -362,7 +362,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // convert or check untyped argument if isUntyped(x.typ) { if x.mode == constant_ { - // an untyped constant number can alway be considered + // an untyped constant number can always be considered // as a complex constant if isNumeric(x.typ) { x.typ = Typ[UntypedComplex] @@ -559,7 +559,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b base := derefStructPtr(x.typ) sel := selx.Sel.Name - obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel) + obj, index, indirect := check.LookupFieldOrMethod(base, false, check.pkg, sel) switch obj.(type) { case nil: check.invalidArg(x.pos(), "%s has no single field %s", base, sel) diff --git a/libgo/go/go/types/call.go b/libgo/go/go/types/call.go index 88e3336136e..31f93726446 100644 --- a/libgo/go/go/types/call.go +++ b/libgo/go/go/types/call.go @@ -370,7 +370,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { goto Error } - obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel) + obj, index, indirect = check.LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel) if obj == nil { switch { case index != nil: @@ -437,6 +437,10 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { if debug { // Verify that LookupFieldOrMethod and MethodSet.Lookup agree. + // TODO(gri) This only works because we call LookupFieldOrMethod + // _before_ calling NewMethodSet: LookupFieldOrMethod completes + // any incomplete interfaces so they are available to NewMethodSet + // (which assumes that interfaces have been completed already). typ := x.typ if x.mode == variable { // If typ is not an (unnamed) pointer or an interface, @@ -460,6 +464,11 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj { check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m) check.dump("%s\n", mset) + // Caution: MethodSets are supposed to be used externally + // only (after all interface types were completed). It's + // now possible that we get here incorrectly. Not urgent + // to fix since we only run this code in debug mode. + // TODO(gri) fix this eventually. panic("method sets and lookup don't agree") } } diff --git a/libgo/go/go/types/check.go b/libgo/go/go/types/check.go index b48d09de22a..b599df1c50d 100644 --- a/libgo/go/go/types/check.go +++ b/libgo/go/go/types/check.go @@ -76,8 +76,10 @@ type Checker struct { fset *token.FileSet pkg *Package *Info - objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info - impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package + objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info + impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package + posMap map[*Interface][]token.Pos // maps interface types to lists of embedded interface positions + pkgCnt map[string]int // counts number of imported packages with a given name (for better error messages) // information collected during type-checking of a set of package files // (initialized by Files, valid only for the duration of check.Files; @@ -86,12 +88,11 @@ type Checker struct { unusedDotImports map[*Scope]map[*Package]token.Pos // positions of unused dot-imported packages for each file scope firstErr error // first error encountered - methods map[*TypeName][]*Func // maps package scope type names to associated non-blank, non-interface methods - // TODO(gri) move interfaces up to the group of fields persistent across check.Files invocations (see also comment in Checker.initFiles) - interfaces map[*TypeName]*ifaceInfo // maps interface type names to corresponding interface infos - untyped map[ast.Expr]exprInfo // map of expressions without final type - delayed []func() // stack of delayed actions - objPath []Object // path of object dependencies during type inference (for cycle reporting) + methods map[*TypeName][]*Func // maps package scope type names to associated non-blank (non-interface) methods + untyped map[ast.Expr]exprInfo // map of expressions without final type + delayed []func() // stack of delayed action segments; segments are processed in FIFO order + finals []func() // list of final actions; processed at the end of type-checking the current set of files + objPath []Object // path of object dependencies during type inference (for cycle reporting) // context within which the current object is type-checked // (valid only for the duration of type-checking a specific object) @@ -146,6 +147,14 @@ func (check *Checker) later(f func()) { check.delayed = append(check.delayed, f) } +// atEnd adds f to the list of actions processed at the end +// of type-checking, before initialization order computation. +// Actions added by atEnd are processed after any actions +// added by later. +func (check *Checker) atEnd(f func()) { + check.finals = append(check.finals, f) +} + // push pushes obj onto the object path and returns its index in the path. func (check *Checker) push(obj Object) int { check.objPath = append(check.objPath, obj) @@ -181,6 +190,8 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch Info: info, objMap: make(map[Object]*declInfo), impMap: make(map[importKey]*Package), + posMap: make(map[*Interface][]token.Pos), + pkgCnt: make(map[string]int), } } @@ -193,17 +204,9 @@ func (check *Checker) initFiles(files []*ast.File) { check.firstErr = nil check.methods = nil - // Don't clear the interfaces cache! It's important that we don't recompute - // ifaceInfos repeatedly (due to multiple check.Files calls) because when - // they are recomputed, they are not used in the context of their original - // declaration (because those types are already type-checked, typically) and - // then they will get the wrong receiver types, which matters for go/types - // clients. It is also safe to not reset the interfaces cache because files - // added to a package cannot change (add methods to) existing interface types; - // they can only add new interfaces. See also the respective comment in - // checker.infoFromTypeName (interfaces.go). Was bug - see issue #29029. check.untyped = nil check.delayed = nil + check.finals = nil // determine package name and collect valid files pkg := check.pkg @@ -254,6 +257,7 @@ func (check *Checker) checkFiles(files []*ast.File) (err error) { check.packageObjects() check.processDelayed(0) // incl. all functions + check.processFinals() check.initOrder() @@ -267,6 +271,31 @@ func (check *Checker) checkFiles(files []*ast.File) (err error) { return } +// processDelayed processes all delayed actions pushed after top. +func (check *Checker) processDelayed(top int) { + // If each delayed action pushes a new action, the + // stack will continue to grow during this loop. + // However, it is only processing functions (which + // are processed in a delayed fashion) that may + // add more actions (such as nested functions), so + // this is a sufficiently bounded process. + for i := top; i < len(check.delayed); i++ { + check.delayed[i]() // may append to check.delayed + } + assert(top <= len(check.delayed)) // stack must not have shrunk + check.delayed = check.delayed[:top] +} + +func (check *Checker) processFinals() { + n := len(check.finals) + for _, f := range check.finals { + f() // must not append to check.finals + } + if len(check.finals) != n { + panic("internal error: final action list grew") + } +} + func (check *Checker) recordUntyped() { if !debug && check.Types == nil { return // nothing to do diff --git a/libgo/go/go/types/check_test.go b/libgo/go/go/types/check_test.go index 358e7c5cc81..89122d75fff 100644 --- a/libgo/go/go/types/check_test.go +++ b/libgo/go/go/types/check_test.go @@ -42,8 +42,9 @@ import ( ) var ( - listErrors = flag.Bool("errlist", false, "list errors") - testFiles = flag.String("files", "", "space-separated list of test files") + haltOnError = flag.Bool("halt", false, "halt on error") + listErrors = flag.Bool("errlist", false, "list errors") + testFiles = flag.String("files", "", "space-separated list of test files") ) // The test filenames do not end in .go so that they are invisible @@ -96,6 +97,7 @@ var tests = [][]string{ {"testdata/issue23203a.src"}, {"testdata/issue23203b.src"}, {"testdata/issue28251.src"}, + {"testdata/issue6977.src"}, } var fset = token.NewFileSet() @@ -262,6 +264,9 @@ func checkFiles(t *testing.T, testfiles []string) { } conf.Importer = importer.Default() conf.Error = func(err error) { + if *haltOnError { + defer panic(err) + } if *listErrors { t.Error(err) return diff --git a/libgo/go/go/types/conversions.go b/libgo/go/go/types/conversions.go index fecb7b617ff..7ea8fd70aab 100644 --- a/libgo/go/go/types/conversions.go +++ b/libgo/go/go/types/conversions.go @@ -89,7 +89,7 @@ func (x *operand) convertibleTo(check *Checker, T Type) bool { V := x.typ Vu := V.Underlying() Tu := T.Underlying() - if IdenticalIgnoreTags(Vu, Tu) { + if check.identicalIgnoreTags(Vu, Tu) { return true } @@ -97,7 +97,7 @@ func (x *operand) convertibleTo(check *Checker, T Type) bool { // have identical underlying types if tags are ignored" if V, ok := V.(*Pointer); ok { if T, ok := T.(*Pointer); ok { - if IdenticalIgnoreTags(V.base.Underlying(), T.base.Underlying()) { + if check.identicalIgnoreTags(V.base.Underlying(), T.base.Underlying()) { return true } } diff --git a/libgo/go/go/types/decl.go b/libgo/go/go/types/decl.go index 1e2790a1711..5c0e611c519 100644 --- a/libgo/go/go/types/decl.go +++ b/libgo/go/go/types/decl.go @@ -38,22 +38,7 @@ func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token } // pathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g]. -// TODO(gri) remove once we don't need the old cycle detection (explicitly passed -// []*TypeName path) anymore -func pathString(path []*TypeName) string { - var s string - for i, p := range path { - if i > 0 { - s += "->" - } - s += p.Name() - } - return s -} - -// objPathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g]. -// TODO(gri) s/objPathString/pathString/ once we got rid of pathString above -func objPathString(path []Object) string { +func pathString(path []Object) string { var s string for i, p := range path { if i > 0 { @@ -68,11 +53,11 @@ func objPathString(path []Object) string { // For the meaning of def, see Checker.definedType, in typexpr.go. func (check *Checker) objDecl(obj Object, def *Named) { if trace { - check.trace(obj.Pos(), "-- checking %s %s (objPath = %s)", obj.color(), obj, objPathString(check.objPath)) + check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath)) check.indent++ defer func() { check.indent-- - check.trace(obj.Pos(), "=> %s", obj) + check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color()) }() } @@ -140,17 +125,17 @@ func (check *Checker) objDecl(obj Object, def *Named) { // order code. switch obj := obj.(type) { case *Const: - if check.typeCycle(obj) || obj.typ == nil { + if check.cycle(obj) || obj.typ == nil { obj.typ = Typ[Invalid] } case *Var: - if check.typeCycle(obj) || obj.typ == nil { + if check.cycle(obj) || obj.typ == nil { obj.typ = Typ[Invalid] } case *TypeName: - if check.typeCycle(obj) { + if check.cycle(obj) { // break cycle // (without this, calling underlying() // below may lead to an endless loop @@ -160,7 +145,7 @@ func (check *Checker) objDecl(obj Object, def *Named) { } case *Func: - if check.typeCycle(obj) { + if check.cycle(obj) { // Don't set obj.typ to Typ[Invalid] here // because plenty of code type-asserts that // functions have a *Signature type. Grey @@ -213,18 +198,9 @@ func (check *Checker) objDecl(obj Object, def *Named) { } } -// indir is a sentinel type name that is pushed onto the object path -// to indicate an "indirection" in the dependency from one type name -// to the next. For instance, for "type p *p" the object path contains -// p followed by indir, indicating that there's an indirection *p. -// Indirections are used to break type cycles. -var indir = NewTypeName(token.NoPos, nil, "*", nil) - -// typeCycle checks if the cycle starting with obj is valid and +// cycle checks if the cycle starting with obj is valid and // reports an error if it is not. -// TODO(gri) rename s/typeCycle/cycle/ once we don't need the other -// cycle method anymore. -func (check *Checker) typeCycle(obj Object) (isCycle bool) { +func (check *Checker) cycle(obj Object) (isCycle bool) { // The object map contains the package scope objects and the non-interface methods. if debug { info := check.objMap[obj] @@ -236,52 +212,34 @@ func (check *Checker) typeCycle(obj Object) (isCycle bool) { } } - // Given the number of constants and variables (nval) in the cycle - // and the cycle length (ncycle = number of named objects in the cycle), - // we distinguish between cycles involving only constants and variables - // (nval = ncycle), cycles involving types (and functions) only - // (nval == 0), and mixed cycles (nval != 0 && nval != ncycle). - // We ignore functions at the moment (taking them into account correctly - // is complicated and it doesn't improve error reporting significantly). - // - // A cycle must have at least one indirection and one type definition - // to be permitted: If there is no indirection, the size of the type - // cannot be computed (it's either infinite or 0); if there is no type - // definition, we have a sequence of alias type names which will expand - // ad infinitum. - var nval, ncycle int - var hasIndir, hasTDef bool + // Count cycle objects. assert(obj.color() >= grey) start := obj.color() - grey // index of obj in objPath cycle := check.objPath[start:] - ncycle = len(cycle) // including indirections + nval := 0 // number of (constant or variable) values in the cycle + ndef := 0 // number of type definitions in the cycle for _, obj := range cycle { switch obj := obj.(type) { case *Const, *Var: nval++ case *TypeName: - if obj == indir { - ncycle-- // don't count (indirections are not objects) - hasIndir = true + // Determine if the type name is an alias or not. For + // package-level objects, use the object map which + // provides syntactic information (which doesn't rely + // on the order in which the objects are set up). For + // local objects, we can rely on the order, so use + // the object's predicate. + // TODO(gri) It would be less fragile to always access + // the syntactic information. We should consider storing + // this information explicitly in the object. + var alias bool + if d := check.objMap[obj]; d != nil { + alias = d.alias // package-level object } else { - // Determine if the type name is an alias or not. For - // package-level objects, use the object map which - // provides syntactic information (which doesn't rely - // on the order in which the objects are set up). For - // local objects, we can rely on the order, so use - // the object's predicate. - // TODO(gri) It would be less fragile to always access - // the syntactic information. We should consider storing - // this information explicitly in the object. - var alias bool - if d := check.objMap[obj]; d != nil { - alias = d.alias // package-level object - } else { - alias = obj.IsAlias() // function local object - } - if !alias { - hasTDef = true - } + alias = obj.IsAlias() // function local object + } + if !alias { + ndef++ } case *Func: // ignored for now @@ -291,8 +249,8 @@ func (check *Checker) typeCycle(obj Object) (isCycle bool) { } if trace { - check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", objPathString(cycle), obj.Name(), ncycle) - check.trace(obj.Pos(), "## cycle contains: %d values, has indirection = %v, has type definition = %v", nval, hasIndir, hasTDef) + check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle)) + check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef) defer func() { if isCycle { check.trace(obj.Pos(), "=> error: cycle is invalid") @@ -303,38 +261,132 @@ func (check *Checker) typeCycle(obj Object) (isCycle bool) { // A cycle involving only constants and variables is invalid but we // ignore them here because they are reported via the initialization // cycle check. - if nval == ncycle { + if nval == len(cycle) { return false } - // A cycle involving only types (and possibly functions) must have at - // least one indirection and one type definition to be permitted: If - // there is no indirection, the size of the type cannot be computed - // (it's either infinite or 0); if there is no type definition, we + // A cycle involving only types (and possibly functions) must have at least + // one type definition to be permitted: If there is no type definition, we // have a sequence of alias type names which will expand ad infinitum. - if nval == 0 && hasIndir && hasTDef { + if nval == 0 && ndef > 0 { return false // cycle is permitted } - // report cycle - check.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name()) - for _, obj := range cycle { - if obj == indir { - continue // don't print indir sentinels + check.cycleError(cycle) + + return true +} + +type typeInfo uint + +// validType verifies that the given type does not "expand" infinitely +// producing a cycle in the type graph. Cycles are detected by marking +// defined types. +// (Cycles involving alias types, as in "type A = [10]A" are detected +// earlier, via the objDecl cycle detection mechanism.) +func (check *Checker) validType(typ Type, path []Object) typeInfo { + const ( + unknown typeInfo = iota + marked + valid + invalid + ) + + switch t := typ.(type) { + case *Array: + return check.validType(t.elem, path) + + case *Struct: + for _, f := range t.fields { + if check.validType(f.typ, path) == invalid { + return invalid + } + } + + case *Interface: + for _, etyp := range t.embeddeds { + if check.validType(etyp, path) == invalid { + return invalid + } } + + case *Named: + // don't touch the type if it is from a different package or the Universe scope + // (doing so would lead to a race condition - was issue #35049) + if t.obj.pkg != check.pkg { + return valid + } + + // don't report a 2nd error if we already know the type is invalid + // (e.g., if a cycle was detected earlier, via Checker.underlying). + if t.underlying == Typ[Invalid] { + t.info = invalid + return invalid + } + + switch t.info { + case unknown: + t.info = marked + t.info = check.validType(t.orig, append(path, t.obj)) // only types of current package added to path + case marked: + // cycle detected + for i, tn := range path { + if t.obj.pkg != check.pkg { + panic("internal error: type cycle via package-external type") + } + if tn == t.obj { + check.cycleError(path[i:]) + t.info = invalid + t.underlying = Typ[Invalid] + return t.info + } + } + panic("internal error: cycle start not found") + } + return t.info + } + + return valid +} + +// cycleError reports a declaration cycle starting with +// the object in cycle that is "first" in the source. +func (check *Checker) cycleError(cycle []Object) { + // TODO(gri) Should we start with the last (rather than the first) object in the cycle + // since that is the earliest point in the source where we start seeing the + // cycle? That would be more consistent with other error messages. + i := firstInSrc(cycle) + obj := cycle[i] + check.errorf(obj.Pos(), "illegal cycle in declaration of %s", obj.Name()) + for range cycle { check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented + i++ + if i >= len(cycle) { + i = 0 + } + obj = cycle[i] } check.errorf(obj.Pos(), "\t%s", obj.Name()) +} - return true +// firstInSrc reports the index of the object with the "smallest" +// source position in path. path must not be empty. +func firstInSrc(path []Object) int { + fst, pos := 0, path[0].Pos() + for i, t := range path[1:] { + if t.Pos() < pos { + fst, pos = i+1, t.Pos() + } + } + return fst } func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { assert(obj.typ == nil) // use the correct value of iota + defer func(iota constant.Value) { check.iota = iota }(check.iota) check.iota = obj.val - defer func() { check.iota = nil }() // provide valid constant value under all circumstances obj.val = constant.MakeUnknown() @@ -424,15 +476,60 @@ func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { // underlying returns the underlying type of typ; possibly by following // forward chains of named types. Such chains only exist while named types -// are incomplete. -func underlying(typ Type) Type { +// are incomplete. If an underlying type is found, resolve the chain by +// setting the underlying type for each defined type in the chain before +// returning it. +// +// If no underlying type is found, a cycle error is reported and Typ[Invalid] +// is used as underlying type for each defined type in the chain and returned +// as result. +func (check *Checker) underlying(typ Type) Type { + // If typ is not a defined type, its underlying type is itself. + n0, _ := typ.(*Named) + if n0 == nil { + return typ // nothing to do + } + + // If the underlying type of a defined type is not a defined + // type, then that is the desired underlying type. + typ = n0.underlying + n, _ := typ.(*Named) + if n == nil { + return typ // common case + } + + // Otherwise, follow the forward chain. + seen := map[*Named]int{n0: 0} + path := []Object{n0.obj} for { - n, _ := typ.(*Named) - if n == nil { + typ = n.underlying + n1, _ := typ.(*Named) + if n1 == nil { + break // end of chain + } + + seen[n] = len(seen) + path = append(path, n.obj) + n = n1 + + if i, ok := seen[n]; ok { + // cycle + check.cycleError(path[i:]) + typ = Typ[Invalid] break } - typ = n.underlying } + + for n := range seen { + // We should never have to update the underlying type of an imported type; + // those underlying types should have been resolved during the import. + // Also, doing so would lead to a race condition (was issue #31749). + if n.obj.pkg != check.pkg { + panic("internal error: imported type with unresolved underlying type") + } + n.underlying = typ + } + return typ } @@ -445,6 +542,10 @@ func (n *Named) setUnderlying(typ Type) { func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bool) { assert(obj.typ == nil) + check.later(func() { + check.validType(obj.typ, nil) + }) + if alias { obj.typ = Typ[Invalid] @@ -457,7 +558,7 @@ func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bo obj.typ = named // make sure recursive type declarations terminate // determine underlying type of named - check.definedType(typ, named) + named.orig = check.definedType(typ, named) // The underlying type of named may be itself a named type that is // incomplete: @@ -471,8 +572,8 @@ func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bo // The type of C is the (named) type of A which is incomplete, // and which has as its underlying type the named type B. // Determine the (final, unnamed) underlying type by resolving - // any forward chain (they always end in an unnamed type). - named.underlying = underlying(named.underlying) + // any forward chain. + named.underlying = check.underlying(named) } diff --git a/libgo/go/go/types/errors.go b/libgo/go/go/types/errors.go index 68c96c037ea..91b077163c4 100644 --- a/libgo/go/go/types/errors.go +++ b/libgo/go/go/types/errors.go @@ -10,7 +10,7 @@ import ( "fmt" "go/ast" "go/token" - "path" + "strconv" "strings" ) @@ -25,8 +25,13 @@ func unreachable() { } func (check *Checker) qualifier(pkg *Package) string { + // Qualify the package unless it's the package being type-checked. if pkg != check.pkg { - return path.Base(pkg.path) // avoid excessively long path names in error messages + // If the same package name was used by multiple packages, display the full path. + if check.pkgCnt[pkg.name] > 1 { + return strconv.Quote(pkg.path) + } + return pkg.name } return "" } @@ -82,6 +87,10 @@ func (check *Checker) err(pos token.Pos, msg string, soft bool) { check.firstErr = err } + if trace { + check.trace(pos, "ERROR: %s", msg) + } + f := check.conf.Error if f == nil { panic(bailout{}) // report only first error diff --git a/libgo/go/go/types/example_test.go b/libgo/go/go/types/example_test.go index 5619d20d494..d041087ff7d 100644 --- a/libgo/go/go/types/example_test.go +++ b/libgo/go/go/types/example_test.go @@ -5,7 +5,7 @@ // Only run where builders (build.golang.org) have // access to compiled packages for import. // -// +build !arm,!arm64,!nacl +// +build !arm,!arm64 package types_test diff --git a/libgo/go/go/types/expr.go b/libgo/go/go/types/expr.go index 66d62d68856..d49ccdf67e7 100644 --- a/libgo/go/go/types/expr.go +++ b/libgo/go/go/types/expr.go @@ -548,9 +548,6 @@ func (check *Checker) convertUntyped(x *operand, target Type) { } } case *Interface: - if !x.isNil() && !t.Empty() /* empty interfaces are ok */ { - goto Error - } // Update operand types to the default type rather then // the target (interface) type: values must have concrete // dynamic types. If the value is nil, keep it untyped @@ -561,6 +558,7 @@ func (check *Checker) convertUntyped(x *operand, target Type) { target = Typ[UntypedNil] } else { // cannot assign untyped values to non-empty interfaces + check.completeInterface(t) if !t.Empty() { goto Error } @@ -809,7 +807,7 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o return } - if !Identical(x.typ, y.typ) { + if !check.identical(x.typ, y.typ) { // only report an error if we have valid types // (otherwise we had an error reported elsewhere already) if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] { @@ -1159,12 +1157,9 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { } case *Array: - // Prevent crash if the array referred to is not yet set up. - // This is a stop-gap solution; a better approach would use the mechanism of - // Checker.ident (typexpr.go) using a path of types. But that would require - // passing the path everywhere (all expression-checking methods, not just - // type expression checking), and we're not set up for that (quite possibly - // an indication that cycle detection needs to be rethought). Was issue #18643. + // Prevent crash if the array referred to is not yet set up. Was issue #18643. + // This is a stop-gap solution. Should use Checker.objPath to report entire + // path starting with earliest declaration in the source. TODO(gri) fix this. if utyp.elem == nil { check.error(e.Pos(), "illegal cycle in type declaration") goto Error @@ -1223,7 +1218,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { xkey := keyVal(x.val) if _, ok := utyp.key.Underlying().(*Interface); ok { for _, vtyp := range visited[xkey] { - if Identical(vtyp, x.typ) { + if check.identical(vtyp, x.typ) { duplicate = true break } diff --git a/libgo/go/go/types/initorder.go b/libgo/go/go/types/initorder.go index 966dccb8289..9d5e9165ad8 100644 --- a/libgo/go/go/types/initorder.go +++ b/libgo/go/go/types/initorder.go @@ -69,7 +69,7 @@ func (check *Checker) initOrder() { // if n still depends on other nodes, we have a cycle if n.ndeps > 0 { - cycle := findPath(check.objMap, n.obj, n.obj, make(objSet)) + cycle := findPath(check.objMap, n.obj, n.obj, make(map[Object]bool)) // If n.obj is not part of the cycle (e.g., n.obj->b->c->d->c), // cycle will be nil. Don't report anything in that case since // the cycle is reported when the algorithm gets to an object @@ -130,17 +130,17 @@ func (check *Checker) initOrder() { // findPath returns the (reversed) list of objects []Object{to, ... from} // such that there is a path of object dependencies from 'from' to 'to'. // If there is no such path, the result is nil. -func findPath(objMap map[Object]*declInfo, from, to Object, visited objSet) []Object { - if visited[from] { - return nil // node already seen +func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool) []Object { + if seen[from] { + return nil } - visited[from] = true + seen[from] = true for d := range objMap[from].deps { if d == to { return []Object{d} } - if P := findPath(objMap, d, to, visited); P != nil { + if P := findPath(objMap, d, to, seen); P != nil { return append(P, d) } } diff --git a/libgo/go/go/types/interfaces.go b/libgo/go/go/types/interfaces.go deleted file mode 100644 index e0ef83adcc5..00000000000 --- a/libgo/go/go/types/interfaces.go +++ /dev/null @@ -1,451 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this src code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package types - -import ( - "bytes" - "fmt" - "go/ast" - "go/token" -) - -// This file implements the collection of an interface's methods -// without relying on partially computed types of methods or interfaces -// for interface types declared at the package level. -// -// Because interfaces must not embed themselves, directly or indirectly, -// the method set of a valid interface can always be computed independent -// of any cycles that might exist via method signatures (see also issue #18395). -// -// Except for blank method name and interface cycle errors, no errors -// are reported. Affected methods or embedded interfaces are silently -// dropped. Subsequent type-checking of the interface will check -// signatures and embedded interfaces and report errors at that time. -// -// Only infoFromTypeLit should be called directly from code outside this file -// to compute an ifaceInfo. - -// ifaceInfo describes the method set for an interface. -// The zero value for an ifaceInfo is a ready-to-use ifaceInfo representing -// the empty interface. -type ifaceInfo struct { - explicits int // number of explicitly declared methods - methods []*methodInfo // all methods, starting with explicitly declared ones in source order -} - -// emptyIfaceInfo represents the ifaceInfo for the empty interface. -var emptyIfaceInfo ifaceInfo - -func (info *ifaceInfo) String() string { - var buf bytes.Buffer - fmt.Fprintf(&buf, "interface{") - for i, m := range info.methods { - if i > 0 { - fmt.Fprint(&buf, " ") - } - fmt.Fprint(&buf, m) - } - fmt.Fprintf(&buf, "}") - return buf.String() -} - -// methodInfo represents an interface method. -// At least one of src or fun must be non-nil. -// (Methods declared in the current package have a non-nil scope -// and src, and eventually a non-nil fun field; imported and pre- -// declared methods have a nil scope and src, and only a non-nil -// fun field.) -type methodInfo struct { - scope *Scope // scope of interface method; or nil - src *ast.Field // syntax tree representation of interface method; or nil - fun *Func // corresponding fully type-checked method type; or nil -} - -func (info *methodInfo) String() string { - if info.fun != nil { - return info.fun.name - } - return info.src.Names[0].Name -} - -func (info *methodInfo) Pos() token.Pos { - if info.fun != nil { - return info.fun.Pos() - } - return info.src.Pos() -} - -func (info *methodInfo) id(pkg *Package) string { - if info.fun != nil { - return info.fun.Id() - } - return Id(pkg, info.src.Names[0].Name) -} - -// A methodInfoSet maps method ids to methodInfos. -// It is used to determine duplicate declarations. -// (A methodInfo set is the equivalent of an objset -// but for methodInfos rather than Objects.) -type methodInfoSet map[string]*methodInfo - -// insert attempts to insert an method m into the method set s. -// If s already contains an alternative method alt with -// the same name, insert leaves s unchanged and returns alt. -// Otherwise it inserts m and returns nil. -func (s *methodInfoSet) insert(pkg *Package, m *methodInfo) *methodInfo { - id := m.id(pkg) - if alt := (*s)[id]; alt != nil { - return alt - } - if *s == nil { - *s = make(methodInfoSet) - } - (*s)[id] = m - return nil -} - -// like Checker.declareInSet but for method infos. -func (check *Checker) declareInMethodSet(mset *methodInfoSet, pos token.Pos, m *methodInfo) bool { - if alt := mset.insert(check.pkg, m); alt != nil { - check.errorf(pos, "%s redeclared", m) - check.reportAltMethod(alt) - return false - } - return true -} - -// like Checker.reportAltDecl but for method infos. -func (check *Checker) reportAltMethod(m *methodInfo) { - if pos := m.Pos(); pos.IsValid() { - // We use "other" rather than "previous" here because - // the first declaration seen may not be textually - // earlier in the source. - check.errorf(pos, "\tother declaration of %s", m) // secondary error, \t indented - } -} - -// infoFromTypeLit computes the method set for the given interface iface -// declared in scope. -// If a corresponding type name exists (tname != nil), it is used for -// cycle detection and to cache the method set. -// The result is the method set, or nil if there is a cycle via embedded -// interfaces. A non-nil result doesn't mean that there were no errors, -// but they were either reported (e.g., blank methods), or will be found -// (again) when computing the interface's type. -// If tname is not nil it must be the last element in path. -func (check *Checker) infoFromTypeLit(scope *Scope, iface *ast.InterfaceType, tname *TypeName, path []*TypeName) (info *ifaceInfo) { - assert(iface != nil) - - // lazy-allocate interfaces map - if check.interfaces == nil { - check.interfaces = make(map[*TypeName]*ifaceInfo) - } - - if trace { - check.trace(iface.Pos(), "-- collect methods for %v (path = %s, objPath = %s)", iface, pathString(path), objPathString(check.objPath)) - check.indent++ - defer func() { - check.indent-- - check.trace(iface.Pos(), "=> %s", info) - }() - } - - // If the interface is named, check if we computed info already. - // - // This is not simply an optimization; we may run into stack - // overflow with recursive interface declarations. Example: - // - // type T interface { - // m() interface { T } - // } - // - // (Since recursive definitions can only be expressed via names, - // it is sufficient to track named interfaces here.) - // - // While at it, use the same mechanism to detect cycles. (We still - // have the path-based cycle check because we want to report the - // entire cycle if present.) - if tname != nil { - assert(path[len(path)-1] == tname) // tname must be last path element - var found bool - if info, found = check.interfaces[tname]; found { - if info == nil { - // We have a cycle and use check.cycle to report it. - // We are guaranteed that check.cycle also finds the - // cycle because when infoFromTypeLit is called, any - // tname that's already in check.interfaces was also - // added to the path. (But the converse is not true: - // A non-nil tname is always the last element in path.) - ok := check.cycle(tname, path, true) - assert(ok) - } - return - } - check.interfaces[tname] = nil // computation started but not complete - } - - if iface.Methods.List == nil { - // fast track for empty interface - info = &emptyIfaceInfo - } else { - // (syntactically) non-empty interface - info = new(ifaceInfo) - - // collect explicitly declared methods and embedded interfaces - var mset methodInfoSet - var embeddeds []*ifaceInfo - var positions []token.Pos // entries correspond to positions of embeddeds; used for error reporting - for _, f := range iface.Methods.List { - if len(f.Names) > 0 { - // We have a method with name f.Names[0]. - // (The parser ensures that there's only one method - // and we don't care if a constructed AST has more.) - - // spec: "As with all method sets, in an interface type, - // each method must have a unique non-blank name." - if name := f.Names[0]; name.Name == "_" { - check.errorf(name.Pos(), "invalid method name _") - continue // ignore - } - - m := &methodInfo{scope: scope, src: f} - if check.declareInMethodSet(&mset, f.Pos(), m) { - info.methods = append(info.methods, m) - } - } else { - // We have an embedded interface and f.Type is its - // (possibly qualified) embedded type name. Collect - // it if it's a valid interface. - var e *ifaceInfo - switch ename := f.Type.(type) { - case *ast.Ident: - e = check.infoFromTypeName(scope, ename, path) - case *ast.SelectorExpr: - e = check.infoFromQualifiedTypeName(scope, ename) - default: - // The parser makes sure we only see one of the above. - // Constructed ASTs may contain other (invalid) nodes; - // we simply ignore them. The full type-checking pass - // will report those as errors later. - } - if e != nil { - embeddeds = append(embeddeds, e) - positions = append(positions, f.Type.Pos()) - } - } - } - info.explicits = len(info.methods) - - // collect methods of embedded interfaces - for i, e := range embeddeds { - pos := positions[i] // position of type name of embedded interface - for _, m := range e.methods { - if check.declareInMethodSet(&mset, pos, m) { - info.methods = append(info.methods, m) - } - } - } - } - - // mark check.interfaces as complete - assert(info != nil) - if tname != nil { - check.interfaces[tname] = info - } - - return -} - -// infoFromTypeName computes the method set for the given type name -// which must denote a type whose underlying type is an interface. -// The same result qualifications apply as for infoFromTypeLit. -// infoFromTypeName should only be called from infoFromTypeLit. -func (check *Checker) infoFromTypeName(scope *Scope, name *ast.Ident, path []*TypeName) *ifaceInfo { - // A single call of infoFromTypeName handles a sequence of (possibly - // recursive) type declarations connected via unqualified type names. - // Each type declaration leading to another typename causes a "tail call" - // (goto) of this function. The general scenario looks like this: - // - // ... - // type Pn T // previous declarations leading to T, path = [..., Pn] - // type T interface { T0; ... } // T0 leads to call of infoFromTypeName - // - // // infoFromTypeName(name = T0, path = [..., Pn, T]) - // type T0 T1 // path = [..., Pn, T, T0] - // type T1 T2 <-+ // path = [..., Pn, T, T0, T1] - // type T2 ... | // path = [..., Pn, T, T0, T1, T2] - // type Tn T1 --+ // path = [..., Pn, T, T0, T1, T2, Tn] and T1 is in path => cycle - // - // infoFromTypeName returns nil when such a cycle is detected. But in - // contrast to cycles involving interfaces, we must not report the - // error for "type name only" cycles because they will be found again - // during type-checking of embedded interfaces. Reporting those cycles - // here would lead to double reporting. Cycles involving embedding are - // not reported again later because type-checking of interfaces relies - // on the ifaceInfos computed here which are cycle-free by design. - // - // Remember the path length to detect "type name only" cycles. - start := len(path) - -typenameLoop: - // name must be a type name denoting a type whose underlying type is an interface - _, obj := scope.LookupParent(name.Name, check.pos) - if obj == nil { - return nil - } - tname, _ := obj.(*TypeName) - if tname == nil { - return nil - } - - // We have a type name. It may be predeclared (error type), - // imported (dot import), or declared by a type declaration. - // It may not be an interface (e.g., predeclared type int). - // Resolve it by analyzing each possible case. - - // Abort but don't report an error if we have a "type name only" - // cycle (see big function comment). - if check.cycle(tname, path[start:], false) { - return nil - } - - // Abort and report an error if we have a general cycle. - if check.cycle(tname, path, true) { - return nil - } - - path = append(path, tname) - - // If tname is a package-level type declaration, it must be - // in the objMap. Follow the RHS of that declaration if so. - // The RHS may be a literal type (likely case), or another - // (possibly parenthesized and/or qualified) type name. - // (The declaration may be an alias declaration, but it - // doesn't matter for the purpose of determining the under- - // lying interface.) - if decl := check.objMap[tname]; decl != nil { - switch typ := unparen(decl.typ).(type) { - case *ast.Ident: - // type tname T - name = typ - goto typenameLoop - case *ast.SelectorExpr: - // type tname p.T - return check.infoFromQualifiedTypeName(decl.file, typ) - case *ast.InterfaceType: - // type tname interface{...} - // If tname is fully type-checked at this point (tname.color() == black) - // we could use infoFromType here. But in this case, the interface must - // be in the check.interfaces cache as well, which will be hit when we - // call infoFromTypeLit below, and which will be faster. It is important - // that we use that previously computed interface because its methods - // have the correct receiver type (for go/types clients). Thus, the - // check.interfaces cache must be up-to-date across even across multiple - // check.Files calls (was bug - see issue #29029). - return check.infoFromTypeLit(decl.file, typ, tname, path) - } - // type tname X // and X is not an interface type - return nil - } - - // If tname is not a package-level declaration, in a well-typed - // program it should be a predeclared (error type), imported (dot - // import), or function local declaration. Either way, it should - // have been fully declared before use, except if there is a direct - // cycle, and direct cycles will be caught above. Also, the denoted - // type should be an interface (e.g., int is not an interface). - if typ := tname.typ; typ != nil { - // typ should be an interface - if ityp, _ := typ.Underlying().(*Interface); ityp != nil { - return infoFromType(ityp) - } - } - - // In all other cases we have some error. - return nil -} - -// infoFromQualifiedTypeName computes the method set for the given qualified type name, or nil. -func (check *Checker) infoFromQualifiedTypeName(scope *Scope, qname *ast.SelectorExpr) *ifaceInfo { - // see also Checker.selector - name, _ := qname.X.(*ast.Ident) - if name == nil { - return nil - } - _, obj1 := scope.LookupParent(name.Name, check.pos) - if obj1 == nil { - return nil - } - pname, _ := obj1.(*PkgName) - if pname == nil { - return nil - } - assert(pname.pkg == check.pkg) - obj2 := pname.imported.scope.Lookup(qname.Sel.Name) - if obj2 == nil || !obj2.Exported() { - return nil - } - tname, _ := obj2.(*TypeName) - if tname == nil { - return nil - } - ityp, _ := tname.typ.Underlying().(*Interface) - if ityp == nil { - return nil - } - return infoFromType(ityp) -} - -// infoFromType computes the method set for the given interface type. -// The result is never nil. -func infoFromType(typ *Interface) *ifaceInfo { - assert(typ.allMethods != nil) // typ must be completely set up - - // fast track for empty interface - n := len(typ.allMethods) - if n == 0 { - return &emptyIfaceInfo - } - - info := new(ifaceInfo) - info.explicits = len(typ.methods) - info.methods = make([]*methodInfo, n) - - // If there are no embedded interfaces, simply collect the - // explicitly declared methods (optimization of common case). - if len(typ.methods) == n { - for i, m := range typ.methods { - info.methods[i] = &methodInfo{fun: m} - } - return info - } - - // Interface types have a separate list for explicitly declared methods - // which shares its methods with the list of all (explicitly declared or - // embedded) methods. Collect all methods in a set so we can separate - // the embedded methods from the explicitly declared ones. - all := make(map[*Func]bool, n) - for _, m := range typ.allMethods { - all[m] = true - } - assert(len(all) == n) // methods must be unique - - // collect explicitly declared methods - info.methods = make([]*methodInfo, n) - for i, m := range typ.methods { - info.methods[i] = &methodInfo{fun: m} - delete(all, m) - } - - // collect remaining (embedded) methods - i := len(typ.methods) - for m := range all { - info.methods[i] = &methodInfo{fun: m} - i++ - } - assert(i == n) - - return info -} diff --git a/libgo/go/go/types/issues_test.go b/libgo/go/go/types/issues_test.go index c9f54139206..f59f9053979 100644 --- a/libgo/go/go/types/issues_test.go +++ b/libgo/go/go/types/issues_test.go @@ -465,3 +465,61 @@ func TestIssue29029(t *testing.T) { t.Errorf("\ngot : %swant: %s", got, want) } } + +func TestIssue34151(t *testing.T) { + const asrc = `package a; type I interface{ M() }; type T struct { F interface { I } }` + const bsrc = `package b; import "a"; type T struct { F interface { a.I } }; var _ = a.T(T{})` + + a, err := pkgFor("a", asrc, nil) + if err != nil { + t.Fatalf("package %s failed to typecheck: %v", a.Name(), err) + } + + bast := mustParse(t, bsrc) + conf := Config{Importer: importHelper{a}} + b, err := conf.Check(bast.Name.Name, fset, []*ast.File{bast}, nil) + if err != nil { + t.Errorf("package %s failed to typecheck: %v", b.Name(), err) + } +} + +type importHelper struct { + pkg *Package +} + +func (h importHelper) Import(path string) (*Package, error) { + if path != h.pkg.Path() { + return nil, fmt.Errorf("got package path %q; want %q", path, h.pkg.Path()) + } + return h.pkg, nil +} + +// TestIssue34921 verifies that we don't update an imported type's underlying +// type when resolving an underlying type. Specifically, when determining the +// underlying type of b.T (which is the underlying type of a.T, which is int) +// we must not set the underlying type of a.T again since that would lead to +// a race condition if package b is imported elsewhere, in a package that is +// concurrently type-checked. +func TestIssue34921(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Error(r) + } + }() + + var sources = []string{ + `package a; type T int`, + `package b; import "a"; type T a.T`, + } + + var pkg *Package + for _, src := range sources { + f := mustParse(t, src) + conf := Config{Importer: importHelper{pkg}} + res, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) + if err != nil { + t.Errorf("%q failed to typecheck: %v", src, err) + } + pkg = res // res is imported by the next package in this test + } +} diff --git a/libgo/go/go/types/lookup.go b/libgo/go/go/types/lookup.go index e6764f45a0e..648e100060b 100644 --- a/libgo/go/go/types/lookup.go +++ b/libgo/go/go/types/lookup.go @@ -6,11 +6,6 @@ package types -// Internal use of LookupFieldOrMethod: If the obj result is a method -// associated with a concrete (non-interface) type, the method's signature -// may not be fully set up. Call Checker.objDecl(obj, nil) before accessing -// the method's type. - // LookupFieldOrMethod looks up a field or method with given package and name // in T and returns the corresponding *Var or *Func, an index sequence, and a // bool indicating if there were any pointer indirections on the path to the @@ -38,6 +33,19 @@ package types // the method's formal receiver base type, nor was the receiver addressable. // func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { + return (*Checker)(nil).LookupFieldOrMethod(T, addressable, pkg, name) +} + +// Internal use of Checker.LookupFieldOrMethod: If the obj result is a method +// associated with a concrete (non-interface) type, the method's signature +// may not be fully set up. Call Checker.objDecl(obj, nil) before accessing +// the method's type. +// TODO(gri) Now that we provide the *Checker, we can probably remove this +// caveat by calling Checker.objDecl from LookupFieldOrMethod. Investigate. + +// LookupFieldOrMethod is like the external version but completes interfaces +// as necessary. +func (check *Checker) LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { // Methods cannot be associated to a named pointer type // (spec: "The type denoted by T is called the receiver base type; // it must not be a pointer or interface type and it must be declared @@ -47,7 +55,7 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o // not have found it for T (see also issue 8590). if t, _ := T.(*Named); t != nil { if p, _ := t.underlying.(*Pointer); p != nil { - obj, index, indirect = lookupFieldOrMethod(p, false, pkg, name) + obj, index, indirect = check.lookupFieldOrMethod(p, false, pkg, name) if _, ok := obj.(*Func); ok { return nil, nil, false } @@ -55,7 +63,7 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o } } - return lookupFieldOrMethod(T, addressable, pkg, name) + return check.lookupFieldOrMethod(T, addressable, pkg, name) } // TODO(gri) The named type consolidation and seen maps below must be @@ -63,7 +71,8 @@ func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o // types always have only one representation (even when imported // indirectly via different packages.) -func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { +// lookupFieldOrMethod should only be called by LookupFieldOrMethod and missingMethod. +func (check *Checker) lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) { // WARNING: The code in this function is extremely subtle - do not modify casually! // This function and NewMethodSet should be kept in sync. @@ -166,6 +175,7 @@ func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o case *Interface: // look for a matching method // TODO(gri) t.allMethods is sorted - use binary search + check.completeInterface(t) if i, m := lookupMethod(t.allMethods, pkg, name); m != nil { assert(m.typ != nil) index = concat(e.index, i) @@ -190,7 +200,7 @@ func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (o return } - current = consolidateMultiples(next) + current = check.consolidateMultiples(next) } return nil, nil, false // not found @@ -207,7 +217,7 @@ type embeddedType struct { // consolidateMultiples collects multiple list entries with the same type // into a single entry marked as containing multiples. The result is the // consolidated list. -func consolidateMultiples(list []embeddedType) []embeddedType { +func (check *Checker) consolidateMultiples(list []embeddedType) []embeddedType { if len(list) <= 1 { return list // at most one entry - nothing to do } @@ -215,7 +225,7 @@ func consolidateMultiples(list []embeddedType) []embeddedType { n := 0 // number of entries w/ unique type prev := make(map[Type]int) // index at which type was previously seen for _, e := range list { - if i, found := lookupType(prev, e.typ); found { + if i, found := check.lookupType(prev, e.typ); found { list[i].multiples = true // ignore this entry } else { @@ -227,14 +237,14 @@ func consolidateMultiples(list []embeddedType) []embeddedType { return list[:n] } -func lookupType(m map[Type]int, typ Type) (int, bool) { +func (check *Checker) lookupType(m map[Type]int, typ Type) (int, bool) { // fast path: maybe the types are equal if i, found := m[typ]; found { return i, true } for t, i := range m { - if Identical(t, typ) { + if check.identical(t, typ) { return i, true } } @@ -261,14 +271,15 @@ func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType b // an exported API call (such as MissingMethod), i.e., when all // methods have been type-checked. func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) { + check.completeInterface(T) + // fast path for common case if T.Empty() { return } - // TODO(gri) Consider using method sets here. Might be more efficient. - if ityp, _ := V.Underlying().(*Interface); ityp != nil { + check.completeInterface(ityp) // TODO(gri) allMethods is sorted - can do this more efficiently for _, m := range T.allMethods { _, obj := lookupMethod(ityp.allMethods, m.pkg, m.name) @@ -277,7 +288,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method * if static { return m, false } - case !Identical(obj.Type(), m.typ): + case !check.identical(obj.Type(), m.typ): return m, true } } @@ -286,7 +297,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method * // A concrete type implements T if it implements all methods of T. for _, m := range T.allMethods { - obj, _, _ := lookupFieldOrMethod(V, false, m.pkg, m.name) + obj, _, _ := check.lookupFieldOrMethod(V, false, m.pkg, m.name) // we must have a method (not a field of matching function type) f, _ := obj.(*Func) @@ -299,7 +310,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method * check.objDecl(f, nil) } - if !Identical(f.typ, m.typ) { + if !check.identical(f.typ, m.typ) { return m, true } } diff --git a/libgo/go/go/types/methodset.go b/libgo/go/go/types/methodset.go index 619c4484923..a236fe2ea8b 100644 --- a/libgo/go/go/types/methodset.go +++ b/libgo/go/go/types/methodset.go @@ -62,6 +62,11 @@ func (s *MethodSet) Lookup(pkg *Package, name string) *Selection { // Shared empty method set. var emptyMethodSet MethodSet +// Note: NewMethodSet is intended for external use only as it +// requires interfaces to be complete. If may be used +// internally if LookupFieldOrMethod completed the same +// interfaces beforehand. + // NewMethodSet returns the method set for the given type T. // It always returns a non-nil method set, even if it is empty. func NewMethodSet(T Type) *MethodSet { @@ -175,7 +180,12 @@ func NewMethodSet(T Type) *MethodSet { } } - current = consolidateMultiples(next) + // It's ok to call consolidateMultiples with a nil *Checker because + // MethodSets are not used internally (outside debug mode). When used + // externally, interfaces are expected to be completed and then we do + // not need a *Checker to complete them when (indirectly) calling + // Checker.identical via consolidateMultiples. + current = (*Checker)(nil).consolidateMultiples(next) } if len(base) == 0 { diff --git a/libgo/go/go/types/object_test.go b/libgo/go/go/types/object_test.go index 88cd8757416..2b6057bd934 100644 --- a/libgo/go/go/types/object_test.go +++ b/libgo/go/go/types/object_test.go @@ -4,7 +4,12 @@ package types -import "testing" +import ( + "go/ast" + "go/parser" + "go/token" + "testing" +) func TestIsAlias(t *testing.T) { check := func(obj *TypeName, want bool) { @@ -42,3 +47,40 @@ func TestIsAlias(t *testing.T) { check(test.name, test.alias) } } + +// TestEmbeddedMethod checks that an embedded method is represented by +// the same Func Object as the original method. See also issue #34421. +func TestEmbeddedMethod(t *testing.T) { + const src = `package p; type I interface { error }` + + // type-check src + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, "", src, 0) + if err != nil { + t.Fatalf("parse failed: %s", err) + } + var conf Config + pkg, err := conf.Check(f.Name.Name, fset, []*ast.File{f}, nil) + if err != nil { + t.Fatalf("typecheck failed: %s", err) + } + + // get original error.Error method + eface := Universe.Lookup("error") + orig, _, _ := LookupFieldOrMethod(eface.Type(), false, nil, "Error") + if orig == nil { + t.Fatalf("original error.Error not found") + } + + // get embedded error.Error method + iface := pkg.Scope().Lookup("I") + embed, _, _ := LookupFieldOrMethod(iface.Type(), false, nil, "Error") + if embed == nil { + t.Fatalf("embedded error.Error not found") + } + + // original and embedded Error object should be identical + if orig != embed { + t.Fatalf("%s (%p) != %s (%p)", orig, orig, embed, embed) + } +} diff --git a/libgo/go/go/types/operand.go b/libgo/go/go/types/operand.go index 97ca6c622fd..1259f443000 100644 --- a/libgo/go/go/types/operand.go +++ b/libgo/go/go/types/operand.go @@ -211,7 +211,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool { V := x.typ // x's type is identical to T - if Identical(V, T) { + if check.identical(V, T) { return true } @@ -236,6 +236,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool { return Vb.kind == UntypedBool && isBoolean(Tu) } case *Interface: + check.completeInterface(t) return x.isNil() || t.Empty() case *Pointer, *Signature, *Slice, *Map, *Chan: return x.isNil() @@ -245,7 +246,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool { // x's type V and T have identical underlying types // and at least one of V or T is not a named type - if Identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) { + if check.identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) { return true } @@ -268,7 +269,7 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool { // type, x's type V and T have identical element types, // and at least one of V or T is not a named type if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv { - if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) { + if Tc, ok := Tu.(*Chan); ok && check.identical(Vc.elem, Tc.elem) { return !isNamed(V) || !isNamed(T) } } diff --git a/libgo/go/go/types/predicates.go b/libgo/go/go/types/predicates.go index 46ad4e2dc40..057908eacd8 100644 --- a/libgo/go/go/types/predicates.go +++ b/libgo/go/go/types/predicates.go @@ -110,16 +110,16 @@ func hasNil(typ Type) bool { return false } -// Identical reports whether x and y are identical types. +// identical reports whether x and y are identical types. // Receivers of Signature types are ignored. -func Identical(x, y Type) bool { - return identical(x, y, true, nil) +func (check *Checker) identical(x, y Type) bool { + return check.identical0(x, y, true, nil) } -// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored. +// identicalIgnoreTags reports whether x and y are identical types if tags are ignored. // Receivers of Signature types are ignored. -func IdenticalIgnoreTags(x, y Type) bool { - return identical(x, y, false, nil) +func (check *Checker) identicalIgnoreTags(x, y Type) bool { + return check.identical0(x, y, false, nil) } // An ifacePair is a node in a stack of interface type pairs compared for identity. @@ -132,7 +132,7 @@ func (p *ifacePair) identical(q *ifacePair) bool { return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x } -func identical(x, y Type, cmpTags bool, p *ifacePair) bool { +func (check *Checker) identical0(x, y Type, cmpTags bool, p *ifacePair) bool { if x == y { return true } @@ -152,13 +152,13 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool { if y, ok := y.(*Array); ok { // If one or both array lengths are unknown (< 0) due to some error, // assume they are the same to avoid spurious follow-on errors. - return (x.len < 0 || y.len < 0 || x.len == y.len) && identical(x.elem, y.elem, cmpTags, p) + return (x.len < 0 || y.len < 0 || x.len == y.len) && check.identical0(x.elem, y.elem, cmpTags, p) } case *Slice: // Two slice types are identical if they have identical element types. if y, ok := y.(*Slice); ok { - return identical(x.elem, y.elem, cmpTags, p) + return check.identical0(x.elem, y.elem, cmpTags, p) } case *Struct: @@ -173,7 +173,7 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool { if f.embedded != g.embedded || cmpTags && x.Tag(i) != y.Tag(i) || !f.sameId(g.pkg, g.name) || - !identical(f.typ, g.typ, cmpTags, p) { + !check.identical0(f.typ, g.typ, cmpTags, p) { return false } } @@ -184,7 +184,7 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool { case *Pointer: // Two pointer types are identical if they have identical base types. if y, ok := y.(*Pointer); ok { - return identical(x.base, y.base, cmpTags, p) + return check.identical0(x.base, y.base, cmpTags, p) } case *Tuple: @@ -195,7 +195,7 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool { if x != nil { for i, v := range x.vars { w := y.vars[i] - if !identical(v.typ, w.typ, cmpTags, p) { + if !check.identical0(v.typ, w.typ, cmpTags, p) { return false } } @@ -211,8 +211,8 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool { // names are not required to match. if y, ok := y.(*Signature); ok { return x.variadic == y.variadic && - identical(x.params, y.params, cmpTags, p) && - identical(x.results, y.results, cmpTags, p) + check.identical0(x.params, y.params, cmpTags, p) && + check.identical0(x.results, y.results, cmpTags, p) } case *Interface: @@ -220,6 +220,14 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool { // the same names and identical function types. Lower-case method names from // different packages are always different. The order of the methods is irrelevant. if y, ok := y.(*Interface); ok { + // If identical0 is called (indirectly) via an external API entry point + // (such as Identical, IdenticalIgnoreTags, etc.), check is nil. But in + // that case, interfaces are expected to be complete and lazy completion + // here is not needed. + if check != nil { + check.completeInterface(x) + check.completeInterface(y) + } a := x.allMethods b := y.allMethods if len(a) == len(b) { @@ -258,7 +266,7 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool { } for i, f := range a { g := b[i] - if f.Id() != g.Id() || !identical(f.typ, g.typ, cmpTags, q) { + if f.Id() != g.Id() || !check.identical0(f.typ, g.typ, cmpTags, q) { return false } } @@ -269,14 +277,14 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool { case *Map: // Two map types are identical if they have identical key and value types. if y, ok := y.(*Map); ok { - return identical(x.key, y.key, cmpTags, p) && identical(x.elem, y.elem, cmpTags, p) + return check.identical0(x.key, y.key, cmpTags, p) && check.identical0(x.elem, y.elem, cmpTags, p) } case *Chan: // Two channel types are identical if they have identical value types // and the same direction. if y, ok := y.(*Chan); ok { - return x.dir == y.dir && identical(x.elem, y.elem, cmpTags, p) + return x.dir == y.dir && check.identical0(x.elem, y.elem, cmpTags, p) } case *Named: diff --git a/libgo/go/go/types/resolver.go b/libgo/go/go/types/resolver.go index 417e4e79aa0..839d076e361 100644 --- a/libgo/go/go/types/resolver.go +++ b/libgo/go/go/types/resolver.go @@ -25,12 +25,9 @@ type declInfo struct { alias bool // type alias declaration // The deps field tracks initialization expression dependencies. - deps objSet // lazily initialized + deps map[Object]bool // lazily initialized } -// An objSet is simply a set of objects. -type objSet map[Object]bool - // hasInitializer reports whether the declared object has an initialization // expression or function body. func (d *declInfo) hasInitializer() bool { @@ -41,7 +38,7 @@ func (d *declInfo) hasInitializer() bool { func (d *declInfo) addDep(obj Object) { m := d.deps if m == nil { - m = make(objSet) + m = make(map[Object]bool) d.deps = m } m[obj] = true @@ -191,6 +188,7 @@ func (check *Checker) importPackage(pos token.Pos, path, dir string) *Package { // package should be complete or marked fake, but be cautious if imp.complete || imp.fake { check.impMap[key] = imp + check.pkgCnt[imp.name]++ return imp } @@ -482,7 +480,7 @@ func (check *Checker) resolveBaseTypeName(typ ast.Expr) (ptr bool, base *TypeNam // non-alias type name. If we encounter anything but pointer types or // parentheses we're done. If we encounter more than one pointer type // we're done. - var path []*TypeName + var seen map[*TypeName]bool for { typ = unparen(typ) @@ -496,7 +494,7 @@ func (check *Checker) resolveBaseTypeName(typ ast.Expr) (ptr bool, base *TypeNam typ = unparen(pexpr.X) // continue with pointer base type } - // typ must be the name + // typ must be a name name, _ := typ.(*ast.Ident) if name == nil { return false, nil @@ -516,7 +514,7 @@ func (check *Checker) resolveBaseTypeName(typ ast.Expr) (ptr bool, base *TypeNam } // ... which we have not seen before - if check.cycle(tname, path, false) { + if seen[tname] { return false, nil } @@ -529,28 +527,11 @@ func (check *Checker) resolveBaseTypeName(typ ast.Expr) (ptr bool, base *TypeNam // otherwise, continue resolving typ = tdecl.typ - path = append(path, tname) - } -} - -// cycle reports whether obj appears in path or not. -// If it does, and report is set, it also reports a cycle error. -func (check *Checker) cycle(obj *TypeName, path []*TypeName, report bool) bool { - // (it's ok to iterate forward because each named type appears at most once in path) - for i, prev := range path { - if prev == obj { - if report { - check.errorf(obj.pos, "illegal cycle in declaration of %s", obj.name) - // print cycle - for _, obj := range path[i:] { - check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented - } - check.errorf(obj.Pos(), "\t%s", obj.Name()) - } - return true + if seen == nil { + seen = make(map[*TypeName]bool) } + seen[tname] = true } - return false } // packageObjects typechecks all package objects, but not function bodies. @@ -607,16 +588,6 @@ func (a inSourceOrder) Len() int { return len(a) } func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() } func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -// processDelayed processes all delayed actions pushed after top. -func (check *Checker) processDelayed(top int) { - for len(check.delayed) > top { - i := len(check.delayed) - 1 - f := check.delayed[i] - check.delayed = check.delayed[:i] - f() // may append to check.delayed - } -} - // unusedImports checks for unused imports. func (check *Checker) unusedImports() { // if function bodies are not checked, packages' uses are likely missing - don't check diff --git a/libgo/go/go/types/scope.go b/libgo/go/go/types/scope.go index 409b468f20a..8c9d9ab8b80 100644 --- a/libgo/go/go/types/scope.go +++ b/libgo/go/go/types/scope.go @@ -77,7 +77,7 @@ func (s *Scope) Lookup(name string) Object { // // Note that obj.Parent() may be different from the returned scope if the // object was inserted into the scope and already had a parent at that -// time (see Insert, below). This can only happen for dot-imported objects +// time (see Insert). This can only happen for dot-imported objects // whose scope is the scope of the package that exported them. func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object) { for ; s != nil; s = s.parent { diff --git a/libgo/go/go/types/selection.go b/libgo/go/go/types/selection.go index 124e0d39f02..6ec69d21dba 100644 --- a/libgo/go/go/types/selection.go +++ b/libgo/go/go/types/selection.go @@ -31,11 +31,11 @@ const ( // // the following relations exist: // -// Selector Kind Recv Obj Type Index Indirect +// Selector Kind Recv Obj Type Index Indirect // -// p.x FieldVal T x int {0} true -// p.m MethodVal *T m func (e *T) m() {1, 0} true -// T.m MethodExpr T m func m(_ T) {1, 0} false +// p.x FieldVal T x int {0} true +// p.m MethodVal *T m func() {1, 0} true +// T.m MethodExpr T m func(T) {1, 0} false // type Selection struct { kind SelectionKind diff --git a/libgo/go/go/types/stdlib_test.go b/libgo/go/go/types/stdlib_test.go index dc189870bc9..4257bd9005b 100644 --- a/libgo/go/go/types/stdlib_test.go +++ b/libgo/go/go/types/stdlib_test.go @@ -186,6 +186,8 @@ func TestStdFixed(t *testing.T) { "issue25507.go", // go/types does not have constraints on stack size "issue20780.go", // go/types does not have constraints on stack size "issue31747.go", // go/types does not have constraints on language level (-lang=go1.12) (see #31793) + "issue34329.go", // go/types does not have constraints on language level (-lang=go1.13) (see #31793) + "bug251.go", // issue #34333 which was exposed with fix for #34151 ) } diff --git a/libgo/go/go/types/stmt.go b/libgo/go/go/types/stmt.go index abd9d05ef2a..c1593bbee9d 100644 --- a/libgo/go/go/types/stmt.go +++ b/libgo/go/go/types/stmt.go @@ -249,7 +249,7 @@ L: // look for duplicate types for a given value // (quadratic algorithm, but these lists tend to be very short) for _, vt := range seen[val] { - if Identical(v.typ, vt.typ) { + if check.identical(v.typ, vt.typ) { check.errorf(v.pos(), "duplicate case %s in expression switch", &v) check.error(vt.pos, "\tprevious case") // secondary error, \t indented continue L @@ -270,7 +270,7 @@ L: // look for duplicate types // (quadratic algorithm, but type switches tend to be reasonably small) for t, pos := range seen { - if T == nil && t == nil || T != nil && t != nil && Identical(T, t) { + if T == nil && t == nil || T != nil && t != nil && check.identical(T, t) { // talk about "case" rather than "type" because of nil case Ts := "nil" if T != nil { diff --git a/libgo/go/go/types/testdata/const0.src b/libgo/go/go/types/testdata/const0.src index 19fb1bdbbee..adbbf2863b0 100644 --- a/libgo/go/go/types/testdata/const0.src +++ b/libgo/go/go/types/testdata/const0.src @@ -308,6 +308,8 @@ const ( _ = unsafe.Sizeof([iota-1]int{} == x) // assert types are equal _ = unsafe.Sizeof([Two]int{} == x) // assert types are equal ) + var z [iota]int // [2]int + _ = unsafe.Sizeof([2]int{} == z) // assert types are equal }) three = iota // the sequence continues ) @@ -334,3 +336,15 @@ var _ = []int64{ 1 * 1e9, 5 * 1e9, } + +const _ = unsafe.Sizeof(func() { + const _ = 0 + _ = iota + + const ( + zero = iota + one + ) + assert(one == 1) + assert(iota == 0) +}) diff --git a/libgo/go/go/types/testdata/cycles.src b/libgo/go/go/types/testdata/cycles.src index a9af46a9337..b2ee8ecd5f6 100644 --- a/libgo/go/go/types/testdata/cycles.src +++ b/libgo/go/go/types/testdata/cycles.src @@ -71,6 +71,15 @@ type ( C0 chan C0 ) +// test case for issue #34771 +type ( + AA /* ERROR cycle */ B + B C + C [10]D + D E + E AA +) + func _() { type ( t1 /* ERROR cycle */ t1 @@ -147,7 +156,7 @@ type ( // test cases for issue 18643 // (type cycle detection when non-type expressions are involved) type ( - T14 /* ERROR cycle */ [len(T14{})]int + T14 [len(T14 /* ERROR cycle */ {})]int T15 [][len(T15 /* ERROR cycle */ {})]int T16 map[[len(T16 /* ERROR cycle */ {1:2})]int]int T17 map[int][len(T17 /* ERROR cycle */ {1:2})]int diff --git a/libgo/go/go/types/testdata/cycles2.src b/libgo/go/go/types/testdata/cycles2.src index fd0df4bf272..5fd9e838b60 100644 --- a/libgo/go/go/types/testdata/cycles2.src +++ b/libgo/go/go/types/testdata/cycles2.src @@ -22,13 +22,13 @@ func _() { t.f(t) t.f(u) - + u.f(t) u.f(u) } -// Test case for issue 6589. +// Test case for issues #6589, #33656. type A interface { a() interface { @@ -45,26 +45,28 @@ type B interface { type AB interface { a() interface { A - B /* ERROR a redeclared */ + B } b() interface { A - B /* ERROR a redeclared */ + B } } var x AB var y interface { A - B /* ERROR a redeclared */ + B } + +// TODO(gri) This should be a valid compare. See #33656. var _ = x /* ERROR cannot compare */ == y // Test case for issue 6638. type T interface { - m() [T /* ERROR no value */ (nil).m()[0]]int + m() [T(nil).m /* ERROR undefined */ ()[0]]int } // Variations of this test case. diff --git a/libgo/go/go/types/testdata/cycles5.src b/libgo/go/go/types/testdata/cycles5.src new file mode 100644 index 00000000000..397adcce015 --- /dev/null +++ b/libgo/go/go/types/testdata/cycles5.src @@ -0,0 +1,200 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +import "unsafe" + +// test case from issue #18395 + +type ( + A interface { B } + B interface { C } + C interface { D; F() A } + D interface { G() B } +) + +var _ = A(nil).G // G must be found + + +// test case from issue #21804 + +type sourceBridge interface { + listVersions() ([]Version, error) +} + +type Constraint interface { + copyTo(*ConstraintMsg) +} + +type ConstraintMsg struct{} + +func (m *ConstraintMsg) asUnpairedVersion() UnpairedVersion { + return nil +} + +type Version interface { + Constraint +} + +type UnpairedVersion interface { + Version +} + +var _ Constraint = UnpairedVersion(nil) + + +// derived test case from issue #21804 + +type ( + _ interface{ m(B1) } + A1 interface{ a(D1) } + B1 interface{ A1 } + C1 interface{ B1 } + D1 interface{ C1 } +) + +var _ A1 = C1(nil) + + +// derived test case from issue #22701 + +func F(x I4) interface{} { + return x.Method() +} + +type Unused interface { + RefersToI1(a I1) +} + +type I1 interface { + I2 + I3 +} + +type I2 interface { + RefersToI4() I4 +} + +type I3 interface { + Method() interface{} +} + +type I4 interface { + I1 +} + + +// check embedding of error interface + +type Error interface{ error } + +var err Error +var _ = err.Error() + + +// more esoteric cases + +type ( + T1 interface { T2 } + T2 /* ERROR cycle */ T2 +) + +type ( + T3 interface { T4 } + T4 /* ERROR cycle */ T5 + T5 = T6 + T6 = T7 + T7 = T4 +) + + +// arbitrary code may appear inside an interface + +const n = unsafe.Sizeof(func(){}) + +type I interface { + m([unsafe.Sizeof(func() { I.m(nil, [n]byte{}) })]byte) +} + + +// test cases for varias alias cycles + +type T10 /* ERROR cycle */ = *T10 // issue #25141 +type T11 /* ERROR cycle */ = interface{ f(T11) } // issue #23139 + +// issue #18640 +type ( + aa = bb + bb struct { + *aa + } +) + +type ( + a struct{ *b } + b = c + c struct{ *b } +) + +// issue #24939 +type ( + _ interface { + M(P) + } + + M interface { + F() P + } + + P = interface { + I() M + } +) + +// issue #8699 +type T12 /* ERROR cycle */ [len(a12)]int +var a12 = makeArray() +func makeArray() (res T12) { return } + +// issue #20770 +var r /* ERROR cycle */ = newReader() +func newReader() r + +// variations of the theme of #8699 and #20770 +var arr /* ERROR cycle */ = f() +func f() [len(arr)]int + +// issue #25790 +func ff(ff /* ERROR not a type */ ) +func gg((gg /* ERROR not a type */ )) + +type T13 /* ERROR cycle */ [len(b13)]int +var b13 T13 + +func g1() [unsafe.Sizeof(g1)]int +func g2() [unsafe.Sizeof(x2)]int +var x2 = g2 + +// verify that we get the correct sizes for the functions above +// (note: assert is statically evaluated in go/types test mode) +func init() { + assert(unsafe.Sizeof(g1) == 8) + assert(unsafe.Sizeof(x2) == 8) +} + +func h() [h /* ERROR no value */ ()[0]]int { panic(0) } + +var c14 /* ERROR cycle */ T14 +type T14 [uintptr(unsafe.Sizeof(&c14))]byte + +// issue #34333 +type T15 /* ERROR cycle */ struct { + f func() T16 + b T16 +} + +type T16 struct { + T15 +} \ No newline at end of file diff --git a/libgo/go/go/types/testdata/decls0.src b/libgo/go/go/types/testdata/decls0.src index 56adbbfaae6..5501b659153 100644 --- a/libgo/go/go/types/testdata/decls0.src +++ b/libgo/go/go/types/testdata/decls0.src @@ -72,10 +72,6 @@ type ( a /* ERROR "illegal cycle" */ a a /* ERROR "redeclared" */ int - // where the cycle error appears depends on the - // order in which declarations are processed - // (which depends on the order in which a map - // is iterated through) b /* ERROR "illegal cycle" */ c c d d e @@ -139,7 +135,7 @@ type ( } I3 interface { m1() - m1 /* ERROR "redeclared" */ () + m1 /* ERROR "duplicate method" */ () } I4 interface { m1(x, y, x /* ERROR "redeclared" */ float32) diff --git a/libgo/go/go/types/testdata/decls1.src b/libgo/go/go/types/testdata/decls1.src index 07405469a44..e6beb783589 100644 --- a/libgo/go/go/types/testdata/decls1.src +++ b/libgo/go/go/types/testdata/decls1.src @@ -43,7 +43,7 @@ var ( s11 = &v s12 = -(u + *t11) / *&v s13 = a /* ERROR "shifted operand" */ << d - s14 = i << j /* ERROR "must be unsigned" */ + s14 = i << j s18 = math.Pi * 10.0 s19 = s1 /* ERROR "cannot call" */ () s20 = f0 /* ERROR "no value" */ () @@ -62,7 +62,7 @@ var ( t11 *complex64 = &v t12 complex64 = -(u + *t11) / *&v t13 int = a /* ERROR "shifted operand" */ << d - t14 int = i << j /* ERROR "must be unsigned" */ + t14 int = i << j t15 math /* ERROR "not in selector" */ t16 math.xxx /* ERROR "not declared" */ t17 math /* ERROR "not a type" */ .Pi diff --git a/libgo/go/go/types/testdata/decls4.src b/libgo/go/go/types/testdata/decls4.src new file mode 100644 index 00000000000..ab7c67988b1 --- /dev/null +++ b/libgo/go/go/types/testdata/decls4.src @@ -0,0 +1,199 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// type aliases + +package decls4 + +type ( + T0 [10]int + T1 []byte + T2 struct { + x int + } + T3 interface{ + m() T2 + } + T4 func(int, T0) chan T2 +) + +type ( + Ai = int + A0 = T0 + A1 = T1 + A2 = T2 + A3 = T3 + A4 = T4 + + A10 = [10]int + A11 = []byte + A12 = struct { + x int + } + A13 = interface{ + m() A2 + } + A14 = func(int, A0) chan A2 +) + +// check assignment compatibility due to equality of types +var ( + xi_ int + ai Ai = xi_ + + x0 T0 + a0 A0 = x0 + + x1 T1 + a1 A1 = x1 + + x2 T2 + a2 A2 = x2 + + x3 T3 + a3 A3 = x3 + + x4 T4 + a4 A4 = x4 +) + +// alias receiver types +func (Ai /* ERROR "invalid receiver" */) m1() {} +func (T0) m1() {} +func (A0) m1 /* ERROR already declared */ () {} +func (A0) m2 () {} +func (A3 /* ERROR invalid receiver */ ) m1 () {} +func (A10 /* ERROR invalid receiver */ ) m1() {} + +// x0 has methods m1, m2 declared via receiver type names T0 and A0 +var _ interface{ m1(); m2() } = x0 + +// alias receiver types (test case for issue #23042) +type T struct{} + +var ( + _ = T.m + _ = T{}.m + _ interface{m()} = T{} +) + +var ( + _ = T.n + _ = T{}.n + _ interface{m(); n()} = T{} +) + +type U = T +func (U) m() {} + +// alias receiver types (long type declaration chains) +type ( + V0 = V1 + V1 = (V2) + V2 = ((V3)) + V3 = T +) + +func (V0) m /* ERROR already declared */ () {} +func (V1) n() {} + +// alias receiver types (invalid due to cycles) +type ( + W0 /* ERROR illegal cycle */ = W1 + W1 = (W2) + W2 = ((W0)) +) + +func (W0) m() {} // no error expected (due to above cycle error) +func (W1) n() {} + +// alias receiver types (invalid due to builtin underlying type) +type ( + B0 = B1 + B1 = B2 + B2 = int +) + +func (B0 /* ERROR invalid receiver */ ) m() {} +func (B1 /* ERROR invalid receiver */ ) n() {} + +// cycles +type ( + C2 /* ERROR illegal cycle */ = C2 + C3 /* ERROR illegal cycle */ = C4 + C4 = C3 + C5 struct { + f *C6 + } + C6 = C5 + C7 /* ERROR illegal cycle */ struct { + f C8 + } + C8 = C7 +) + +// embedded fields +var ( + s0 struct { T0 } + s1 struct { A0 } = s0 /* ERROR cannot use */ // embedded field names are different +) + +// embedding and lookup of fields and methods +func _(s struct{A0}) { s.A0 = x0 } + +type eX struct{xf int} + +func (eX) xm() + +type eY = struct{eX} // field/method set of eY includes xf, xm + +type eZ = *struct{eX} // field/method set of eZ includes xf, xm + +type eA struct { + eX // eX contributes xf, xm to eA +} + +type eA2 struct { + *eX // *eX contributes xf, xm to eA +} + +type eB struct { + eY // eY contributes xf, xm to eB +} + +type eB2 struct { + *eY // *eY contributes xf, xm to eB +} + +type eC struct { + eZ // eZ contributes xf, xm to eC +} + +var ( + _ = eA{}.xf + _ = eA{}.xm + _ = eA2{}.xf + _ = eA2{}.xm + _ = eB{}.xf + _ = eB{}.xm + _ = eB2{}.xf + _ = eB2{}.xm + _ = eC{}.xf + _ = eC{}.xm +) + +// ambiguous selectors due to embedding via type aliases +type eD struct { + eY + eZ +} + +var ( + _ = eD{}.xf /* ERROR ambiguous selector */ + _ = eD{}.xm /* ERROR ambiguous selector */ +) + +var ( + _ interface{ xm() } = eD /* ERROR missing method xm */ {} +) \ No newline at end of file diff --git a/libgo/go/go/types/testdata/decls5.src b/libgo/go/go/types/testdata/decls5.src new file mode 100644 index 00000000000..88d31946da4 --- /dev/null +++ b/libgo/go/go/types/testdata/decls5.src @@ -0,0 +1,10 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// declarations of main +const _, main /* ERROR "cannot declare main" */ , _ = 0, 1, 2 +type main /* ERROR "cannot declare main" */ struct{} +var _, main /* ERROR "cannot declare main" */ int diff --git a/libgo/go/go/types/testdata/expr1.src b/libgo/go/go/types/testdata/expr1.src index eaaf610b03b..4ead815158f 100644 --- a/libgo/go/go/types/testdata/expr1.src +++ b/libgo/go/go/types/testdata/expr1.src @@ -35,8 +35,8 @@ func _(x, y int, z myint) { x = x * y x = x / y x = x % y - x = x << y // ERROR must be unsigned integer - x = x >> y // ERROR must be unsigned integer + x = x << y + x = x >> y z = z + 1 z = z + 1.0 @@ -46,8 +46,8 @@ func _(x, y int, z myint) { z = z /* ERROR mismatched types */ * y z = z /* ERROR mismatched types */ / y z = z /* ERROR mismatched types */ % y - z = z << y // ERROR must be unsigned integer - z = z >> y // ERROR must be unsigned integer + z = z << y + z = z >> y } type myuint uint diff --git a/libgo/go/go/types/testdata/issue23203a.src b/libgo/go/go/types/testdata/issue23203a.src new file mode 100644 index 00000000000..48cb5889cd9 --- /dev/null +++ b/libgo/go/go/types/testdata/issue23203a.src @@ -0,0 +1,14 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "unsafe" + +type T struct{} + +func (T) m1() {} +func (T) m2([unsafe.Sizeof(T.m1)]int) {} + +func main() {} diff --git a/libgo/go/go/types/testdata/issue23203b.src b/libgo/go/go/types/testdata/issue23203b.src new file mode 100644 index 00000000000..638ec6c5ce3 --- /dev/null +++ b/libgo/go/go/types/testdata/issue23203b.src @@ -0,0 +1,14 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "unsafe" + +type T struct{} + +func (T) m2([unsafe.Sizeof(T.m1)]int) {} +func (T) m1() {} + +func main() {} diff --git a/libgo/go/go/types/testdata/issue25008a.src b/libgo/go/go/types/testdata/issue25008a.src new file mode 100644 index 00000000000..cf71ca10e48 --- /dev/null +++ b/libgo/go/go/types/testdata/issue25008a.src @@ -0,0 +1,15 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +import "io" + +type A interface { + io.Reader +} + +func f(a A) { + a.Read(nil) +} diff --git a/libgo/go/go/types/testdata/issue25008b.src b/libgo/go/go/types/testdata/issue25008b.src new file mode 100644 index 00000000000..f132b7fab3f --- /dev/null +++ b/libgo/go/go/types/testdata/issue25008b.src @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type B interface { + A +} diff --git a/libgo/go/go/types/testdata/issue26390.src b/libgo/go/go/types/testdata/issue26390.src new file mode 100644 index 00000000000..b8e67e9bddb --- /dev/null +++ b/libgo/go/go/types/testdata/issue26390.src @@ -0,0 +1,11 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package issue26390 + +type A = T + +func (t *T) m() *A { return t } + +type T struct{} diff --git a/libgo/go/go/types/testdata/issue28251.src b/libgo/go/go/types/testdata/issue28251.src new file mode 100644 index 00000000000..a456f5c27ed --- /dev/null +++ b/libgo/go/go/types/testdata/issue28251.src @@ -0,0 +1,65 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file contains test cases for various forms of +// method receiver declarations, per the spec clarification +// https://golang.org/cl/142757. + +package issue28251 + +// test case from issue28251 +type T struct{} + +type T0 = *T + +func (T0) m() {} + +func _() { (&T{}).m() } + +// various alternative forms +type ( + T1 = (((T))) +) + +func ((*(T1))) m1() {} +func _() { (T{}).m2() } +func _() { (&T{}).m2() } + +type ( + T2 = (((T3))) + T3 = T +) + +func (T2) m2() {} +func _() { (T{}).m2() } +func _() { (&T{}).m2() } + +type ( + T4 = ((*(T5))) + T5 = T +) + +func (T4) m4() {} +func _() { (T{}).m4 /* ERROR m4 is not in method set of T */ () } +func _() { (&T{}).m4() } + +type ( + T6 = (((T7))) + T7 = (*(T8)) + T8 = T +) + +func (T6) m6() {} +func _() { (T{}).m6 /* ERROR m6 is not in method set of T */ () } +func _() { (&T{}).m6() } + +type ( + T9 = *T10 + T10 = *T11 + T11 = T +) + +func (T9 /* ERROR invalid receiver \*\*T */ ) m9() {} +func _() { (T{}).m9 /* ERROR has no field or method m9 */ () } +func _() { (&T{}).m9 /* ERROR has no field or method m9 */ () } diff --git a/libgo/go/go/types/testdata/issue6977.src b/libgo/go/go/types/testdata/issue6977.src new file mode 100644 index 00000000000..8f4e9ba2b21 --- /dev/null +++ b/libgo/go/go/types/testdata/issue6977.src @@ -0,0 +1,82 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +import "io" + +// Alan's initial report. + +type I interface { f(); String() string } +type J interface { g(); String() string } + +type IJ1 = interface { I; J } +type IJ2 = interface { f(); g(); String() string } + +var _ = (*IJ1)(nil) == (*IJ2)(nil) // static assert that IJ1 and IJ2 are identical types + +// The canonical example. + +type ReadWriteCloser interface { io.ReadCloser; io.WriteCloser } + +// Some more cases. + +type M interface { m() } +type M32 interface { m() int32 } +type M64 interface { m() int64 } + +type U1 interface { m() } +type U2 interface { m(); M } +type U3 interface { M; m() } +type U4 interface { M; M; M } +type U5 interface { U1; U2; U3; U4 } + +type U6 interface { m(); m /* ERROR duplicate method */ () } +type U7 interface { M32 /* ERROR duplicate method */ ; m() } +type U8 interface { m(); M32 /* ERROR duplicate method */ } +type U9 interface { M32; M64 /* ERROR duplicate method */ } + +// Verify that repeated embedding of the same interface(s) +// eliminates duplicate methods early (rather than at the +// end) to prevent exponential memory and time use. +// Without early elimination, computing T29 may take dozens +// of minutes. +type ( + T0 interface { m() } + T1 interface { T0; T0 } + T2 interface { T1; T1 } + T3 interface { T2; T2 } + T4 interface { T3; T3 } + T5 interface { T4; T4 } + T6 interface { T5; T5 } + T7 interface { T6; T6 } + T8 interface { T7; T7 } + T9 interface { T8; T8 } + + T10 interface { T9; T9 } + T11 interface { T10; T10 } + T12 interface { T11; T11 } + T13 interface { T12; T12 } + T14 interface { T13; T13 } + T15 interface { T14; T14 } + T16 interface { T15; T15 } + T17 interface { T16; T16 } + T18 interface { T17; T17 } + T19 interface { T18; T18 } + + T20 interface { T19; T19 } + T21 interface { T20; T20 } + T22 interface { T21; T21 } + T23 interface { T22; T22 } + T24 interface { T23; T23 } + T25 interface { T24; T24 } + T26 interface { T25; T25 } + T27 interface { T26; T26 } + T28 interface { T27; T27 } + T29 interface { T28; T28 } +) + +// Verify that m is present. +var x T29 +var _ = x.m diff --git a/libgo/go/go/types/testdata/issues.src b/libgo/go/go/types/testdata/issues.src index d0203011093..fe2407999c5 100644 --- a/libgo/go/go/types/testdata/issues.src +++ b/libgo/go/go/types/testdata/issues.src @@ -4,8 +4,12 @@ package issues -import "fmt" -import syn "cmd/compile/internal/syntax" +import ( + "fmt" + syn "cmd/compile/internal/syntax" + t1 "text/template" + t2 "html/template" +) func issue7035() { type T struct{ X int } @@ -91,7 +95,7 @@ func issue10979() { nosuchpkg /* ERROR undeclared name: nosuchpkg */ .Nosuchtype } type I interface { - I /* ERROR I\.m \(value of type func\(I\)\) is not a type */ .m + I.m /* ERROR no field or method m */ m() } } @@ -259,10 +263,9 @@ type E = interface { m() } -// Test case from issue. Eventually we may disallow this due -// to the cycle via the alias type name. But for now we make -// sure this is accepted. -type issue25301b = interface { +// Test case from issue. +// cmd/compile reports a cycle as well. +type issue25301b /* ERROR cycle */ = interface { m() interface{ issue25301b } } @@ -317,7 +320,7 @@ func issue28281g() (... /* ERROR expected type */ TT) // Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output func issue26234a(f *syn.File) { - // The error message below should refer to the actual package path base (syntax) + // The error message below should refer to the actual package name (syntax) // not the local package name (syn). f.foo /* ERROR f.foo undefined \(type \*syntax.File has no field or method foo\) */ } @@ -338,3 +341,15 @@ func issue26234b(x T) { func issue26234c() { T.x /* ERROR T.x undefined \(type T has no method x\) */ () } + +func issue35895() { + // T is defined in this package, don't qualify its name with the package name. + var _ T = 0 // ERROR cannot convert 0 \(untyped int constant\) to T + + // There is only one package with name syntax imported, only use the (global) package name in error messages. + var _ *syn.File = 0 // ERROR cannot convert 0 \(untyped int constant\) to \*syntax.File + + // Because both t1 and t2 have the same global package name (template), + // qualify packages with full path name in this case. + var _ t1.Template = t2 /* ERROR cannot use .* \(value of type "html/template".Template\) as "text/template".Template */ .Template{} +} \ No newline at end of file diff --git a/libgo/go/go/types/testdata/literals.src b/libgo/go/go/types/testdata/literals.src new file mode 100644 index 00000000000..494a465f487 --- /dev/null +++ b/libgo/go/go/types/testdata/literals.src @@ -0,0 +1,111 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file tests various representations of literals +// and compares them with literals or constant expressions +// of equal values. + +package literals + +func _() { + // 0-octals + assert(0_123 == 0123) + assert(0123_456 == 0123456) + + // decimals + assert(1_234 == 1234) + assert(1_234_567 == 1234567) + + // hexadecimals + assert(0X_0 == 0) + assert(0X_1234 == 0x1234) + assert(0X_CAFE_f00d == 0xcafef00d) + + // octals + assert(0o0 == 0) + assert(0o1234 == 01234) + assert(0o01234567 == 01234567) + + assert(0O0 == 0) + assert(0O1234 == 01234) + assert(0O01234567 == 01234567) + + assert(0o_0 == 0) + assert(0o_1234 == 01234) + assert(0o0123_4567 == 01234567) + + assert(0O_0 == 0) + assert(0O_1234 == 01234) + assert(0O0123_4567 == 01234567) + + // binaries + assert(0b0 == 0) + assert(0b1011 == 0xb) + assert(0b00101101 == 0x2d) + + assert(0B0 == 0) + assert(0B1011 == 0xb) + assert(0B00101101 == 0x2d) + + assert(0b_0 == 0) + assert(0b10_11 == 0xb) + assert(0b_0010_1101 == 0x2d) + + // decimal floats + assert(1_2_3. == 123.) + assert(0_123. == 123.) + + assert(0_0e0 == 0.) + assert(1_2_3e0 == 123.) + assert(0_123e0 == 123.) + + assert(0e-0_0 == 0.) + assert(1_2_3E+0 == 123.) + assert(0123E1_2_3 == 123e123) + + assert(0.e+1 == 0.) + assert(123.E-1_0 == 123e-10) + assert(01_23.e123 == 123e123) + + assert(.0e-1 == .0) + assert(.123E+10 == .123e10) + assert(.0123E123 == .0123e123) + + assert(1_2_3.123 == 123.123) + assert(0123.01_23 == 123.0123) + + // hexadecimal floats + assert(0x0.p+0 == 0.) + assert(0Xdeadcafe.p-10 == 0xdeadcafe/1024.0) + assert(0x1234.P84 == 0x1234000000000000000000000) + + assert(0x.1p-0 == 1./16) + assert(0X.deadcafep4 == 1.0*0xdeadcafe/0x10000000) + assert(0x.1234P+12 == 1.0*0x1234/0x10) + + assert(0x0p0 == 0.) + assert(0Xdeadcafep+1 == 0x1bd5b95fc) + assert(0x1234P-10 == 0x1234/1024.0) + + assert(0x0.0p0 == 0.) + assert(0Xdead.cafep+1 == 1.0*0x1bd5b95fc/0x10000) + assert(0x12.34P-10 == 1.0*0x1234/0x40000) + + assert(0Xdead_cafep+1 == 0xdeadcafep+1) + assert(0x_1234P-10 == 0x1234p-10) + + assert(0X_dead_cafe.p-10 == 0xdeadcafe.p-10) + assert(0x12_34.P1_2_3 == 0x1234.p123) + + assert(1_234i == 1234i) + assert(1_234_567i == 1234567i) + + assert(0.i == 0i) + assert(123.i == 123i) + assert(0123.i == 123i) + + assert(0.e+1i == 0i) + assert(123.E-1_0i == 123e-10i) + assert(01_23.e123i == 123e123i) +} diff --git a/libgo/go/go/types/testdata/shifts.src b/libgo/go/go/types/testdata/shifts.src index 52e340ec65c..ebc95ba4d79 100644 --- a/libgo/go/go/types/testdata/shifts.src +++ b/libgo/go/go/types/testdata/shifts.src @@ -10,9 +10,21 @@ func shifts0() { s = 10 _ = 0<<0 _ = 1< 0 { - // All embedded types should be interfaces; however, defined types - // may not yet be fully resolved. Only verify that non-defined types - // are interfaces. This matches the behavior of the code before the - // fix for #25301 (issue #25596). - for _, t := range embeddeds { - if _, ok := t.(*Named); !ok && !IsInterface(t) { - panic("embedded type is not an interface") - } + // All embedded types should be interfaces; however, defined types + // may not yet be fully resolved. Only verify that non-defined types + // are interfaces. This matches the behavior of the code before the + // fix for #25301 (issue #25596). + for _, t := range embeddeds { + if _, ok := t.(*Named); !ok && !IsInterface(t) { + panic("embedded type is not an interface") } - sort.Stable(byUniqueTypeName(embeddeds)) } + // sort for API stability + sort.Sort(byUniqueMethodName(methods)) + sort.Stable(byUniqueTypeName(embeddeds)) + typ.methods = methods typ.embeddeds = embeddeds return typ @@ -334,40 +329,76 @@ func (t *Interface) Embedded(i int) *Named { tname, _ := t.embeddeds[i].(*Named) func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] } // NumMethods returns the total number of methods of interface t. -func (t *Interface) NumMethods() int { return len(t.allMethods) } +// The interface must have been completed. +func (t *Interface) NumMethods() int { t.assertCompleteness(); return len(t.allMethods) } + +func (t *Interface) assertCompleteness() { + if t.allMethods == nil { + panic("interface is incomplete") + } +} // Method returns the i'th method of interface t for 0 <= i < t.NumMethods(). // The methods are ordered by their unique Id. -func (t *Interface) Method(i int) *Func { return t.allMethods[i] } +// The interface must have been completed. +func (t *Interface) Method(i int) *Func { t.assertCompleteness(); return t.allMethods[i] } // Empty reports whether t is the empty interface. -func (t *Interface) Empty() bool { return len(t.allMethods) == 0 } +// The interface must have been completed. +func (t *Interface) Empty() bool { t.assertCompleteness(); return len(t.allMethods) == 0 } // Complete computes the interface's method set. It must be called by users of // NewInterfaceType and NewInterface after the interface's embedded types are // fully defined and before using the interface type in any way other than to -// form other types. Complete returns the receiver. +// form other types. The interface must not contain duplicate methods or a +// panic occurs. Complete returns the receiver. func (t *Interface) Complete() *Interface { + // TODO(gri) consolidate this method with Checker.completeInterface if t.allMethods != nil { return t } - // collect all methods - var allMethods []*Func - allMethods = append(allMethods, t.methods...) - for _, et := range t.embeddeds { - it := et.Underlying().(*Interface) - it.Complete() - // copy embedded methods unchanged (see issue #28282) - allMethods = append(allMethods, it.allMethods...) + t.allMethods = markComplete // avoid infinite recursion + + var todo []*Func + var methods []*Func + var seen objset + addMethod := func(m *Func, explicit bool) { + switch other := seen.insert(m); { + case other == nil: + methods = append(methods, m) + case explicit: + panic("duplicate method " + m.name) + default: + // check method signatures after all locally embedded interfaces are computed + todo = append(todo, m, other.(*Func)) + } + } + + for _, m := range t.methods { + addMethod(m, true) + } + + for _, typ := range t.embeddeds { + typ := typ.Underlying().(*Interface) + typ.Complete() + for _, m := range typ.allMethods { + addMethod(m, false) + } + } + + for i := 0; i < len(todo); i += 2 { + m := todo[i] + other := todo[i+1] + if !Identical(m.typ, other.typ) { + panic("duplicate method " + m.name) + } } - sort.Sort(byUniqueMethodName(allMethods)) - // t.methods and/or t.embeddeds may have been empty - if allMethods == nil { - allMethods = markComplete + if methods != nil { + sort.Sort(byUniqueMethodName(methods)) + t.allMethods = methods } - t.allMethods = allMethods return t } @@ -417,7 +448,9 @@ func (c *Chan) Elem() Type { return c.elem } // A Named represents a named type. type Named struct { + info typeInfo // for cycle detection obj *TypeName // corresponding declared object + orig Type // type (on RHS of declaration) this *Named type is derived of (for cycle reporting) underlying Type // possibly a *Named during setup; never a *Named once set up completely methods []*Func // methods declared for this type (not the method set of this type); signatures are type-checked lazily } @@ -429,7 +462,7 @@ func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named { if _, ok := underlying.(*Named); ok { panic("types.NewNamed: underlying type must not be *Named") } - typ := &Named{obj: obj, underlying: underlying, methods: methods} + typ := &Named{obj: obj, orig: underlying, underlying: underlying, methods: methods} if obj.typ == nil { obj.typ = typ } diff --git a/libgo/go/go/types/typestring_test.go b/libgo/go/go/types/typestring_test.go index d12c60fe0af..a2241ca9eb8 100644 --- a/libgo/go/go/types/typestring_test.go +++ b/libgo/go/go/types/typestring_test.go @@ -148,11 +148,11 @@ func TestIncompleteInterfaces(t *testing.T) { {new(Interface), "interface{/* incomplete */}"}, {new(Interface).Complete(), "interface{}"}, - {NewInterface(nil, nil), "interface{/* incomplete */}"}, + {NewInterface(nil, nil), "interface{}"}, {NewInterface(nil, nil).Complete(), "interface{}"}, - {NewInterface([]*Func{}, nil), "interface{/* incomplete */}"}, + {NewInterface([]*Func{}, nil), "interface{}"}, {NewInterface([]*Func{}, nil).Complete(), "interface{}"}, - {NewInterface(nil, []*Named{}), "interface{/* incomplete */}"}, + {NewInterface(nil, []*Named{}), "interface{}"}, {NewInterface(nil, []*Named{}).Complete(), "interface{}"}, {NewInterface([]*Func{m}, nil), "interface{m() /* incomplete */}"}, {NewInterface([]*Func{m}, nil).Complete(), "interface{m()}"}, @@ -162,11 +162,11 @@ func TestIncompleteInterfaces(t *testing.T) { {NewInterface(nil, []*Named{newDefined(NewInterface([]*Func{m}, nil).Complete())}), "interface{T /* incomplete */}"}, {NewInterface(nil, []*Named{newDefined(NewInterface([]*Func{m}, nil).Complete())}).Complete(), "interface{T}"}, - {NewInterfaceType(nil, nil), "interface{/* incomplete */}"}, + {NewInterfaceType(nil, nil), "interface{}"}, {NewInterfaceType(nil, nil).Complete(), "interface{}"}, - {NewInterfaceType([]*Func{}, nil), "interface{/* incomplete */}"}, + {NewInterfaceType([]*Func{}, nil), "interface{}"}, {NewInterfaceType([]*Func{}, nil).Complete(), "interface{}"}, - {NewInterfaceType(nil, []Type{}), "interface{/* incomplete */}"}, + {NewInterfaceType(nil, []Type{}), "interface{}"}, {NewInterfaceType(nil, []Type{}).Complete(), "interface{}"}, {NewInterfaceType([]*Func{m}, nil), "interface{m() /* incomplete */}"}, {NewInterfaceType([]*Func{m}, nil).Complete(), "interface{m()}"}, diff --git a/libgo/go/go/types/typexpr.go b/libgo/go/go/types/typexpr.go index b16bf962cdb..d5837c4f0e1 100644 --- a/libgo/go/go/types/typexpr.go +++ b/libgo/go/go/types/typexpr.go @@ -142,16 +142,6 @@ func (check *Checker) definedType(e ast.Expr, def *Named) (T Type) { return } -// indirectType is like typ but it also breaks the (otherwise) infinite size of recursive -// types by introducing an indirection. It should be called for components of types that -// are not laid out in place in memory, such as pointer base types, slice or map element -// types, function parameter types, etc. -func (check *Checker) indirectType(e ast.Expr) Type { - check.push(indir) - defer check.pop() - return check.definedType(e, nil) -} - // funcType type-checks a function or method type. func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) { scope := NewScope(check.scope, token.NoPos, token.NoPos, "function") @@ -273,7 +263,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type { } else { typ := new(Slice) def.setUnderlying(typ) - typ.elem = check.indirectType(e.Elt) + typ.elem = check.typ(e.Elt) return typ } @@ -286,7 +276,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type { case *ast.StarExpr: typ := new(Pointer) def.setUnderlying(typ) - typ.base = check.indirectType(e.X) + typ.base = check.typ(e.X) return typ case *ast.FuncType: @@ -305,8 +295,8 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type { typ := new(Map) def.setUnderlying(typ) - typ.key = check.indirectType(e.Key) - typ.elem = check.indirectType(e.Value) + typ.key = check.typ(e.Key) + typ.elem = check.typ(e.Value) // spec: "The comparison operators == and != must be fully defined // for operands of the key type; thus the key type must not be a @@ -314,7 +304,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type { // // Delay this check because it requires fully setup types; // it is safe to continue in any case (was issue 6667). - check.later(func() { + check.atEnd(func() { if !Comparable(typ.key) { check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key) } @@ -340,7 +330,7 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type { } typ.dir = dir - typ.elem = check.indirectType(e.Value) + typ.elem = check.typ(e.Value) return typ default: @@ -421,7 +411,7 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO // ignore ... and continue } } - typ := check.indirectType(ftype) + typ := check.typ(ftype) // The parser ensures that f.Tag is nil and we don't // care if a constructed AST contains a non-nil tag. if len(field.Names) > 0 { @@ -472,171 +462,154 @@ func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool } func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) { - // fast-track empty interface - if iface.Methods.List == nil { - ityp.allMethods = markComplete - return - } - - // collect embedded interfaces - // Only needed for printing and API. Delay collection - // to end of type-checking (for package-global interfaces) - // when all types are complete. Local interfaces are handled - // after each statement (as each statement processes delayed - // functions). - interfaceContext := check.context // capture for use in closure below - check.later(func() { - if trace { - check.trace(iface.Pos(), "-- delayed checking embedded interfaces of %v", iface) - check.indent++ - defer func() { - check.indent-- - }() - } + for _, f := range iface.Methods.List { + if len(f.Names) > 0 { + // We have a method with name f.Names[0]. + // (The parser ensures that there's only one method + // and we don't care if a constructed AST has more.) + name := f.Names[0] + if name.Name == "_" { + check.errorf(name.Pos(), "invalid method name _") + continue // ignore + } - // The context must be restored since for local interfaces - // delayed functions are processed after each statement - // (was issue #24140). - defer func(ctxt context) { - check.context = ctxt - }(check.context) - check.context = interfaceContext - - for _, f := range iface.Methods.List { - if len(f.Names) == 0 { - typ := check.indirectType(f.Type) - // typ should be a named type denoting an interface - // (the parser will make sure it's a named type but - // constructed ASTs may be wrong). - if typ == Typ[Invalid] { - continue // error reported before + typ := check.typ(f.Type) + sig, _ := typ.(*Signature) + if sig == nil { + if typ != Typ[Invalid] { + check.invalidAST(f.Type.Pos(), "%s is not a method signature", typ) } - embed, _ := typ.Underlying().(*Interface) - if embed == nil { + continue // ignore + } + + // use named receiver type if available (for better error messages) + var recvTyp Type = ityp + if def != nil { + recvTyp = def + } + sig.recv = NewVar(name.Pos(), check.pkg, "", recvTyp) + + m := NewFunc(name.Pos(), check.pkg, name.Name, sig) + check.recordDef(name, m) + ityp.methods = append(ityp.methods, m) + } else { + // We have an embedded interface and f.Type is its + // (possibly qualified) embedded type name. Collect + // it if it's a valid interface. + typ := check.typ(f.Type) + + utyp := check.underlying(typ) + if _, ok := utyp.(*Interface); !ok { + if utyp != Typ[Invalid] { check.errorf(f.Type.Pos(), "%s is not an interface", typ) - continue - } - // Correct embedded interfaces must be complete - - // don't just assert, but report error since this - // used to be the underlying cause for issue #18395. - if embed.allMethods == nil { - check.dump("%v: incomplete embedded interface %s", f.Type.Pos(), typ) - unreachable() } - // collect interface - ityp.embeddeds = append(ityp.embeddeds, typ) + continue } + + ityp.embeddeds = append(ityp.embeddeds, typ) + check.posMap[ityp] = append(check.posMap[ityp], f.Type.Pos()) } - // sort to match NewInterface/NewInterface2 - // TODO(gri) we may be able to switch to source order - sort.Stable(byUniqueTypeName(ityp.embeddeds)) - }) - - // compute method set - var tname *TypeName - var path []*TypeName - if def != nil { - tname = def.obj - path = []*TypeName{tname} } - info := check.infoFromTypeLit(check.scope, iface, tname, path) - if info == nil || info == &emptyIfaceInfo { - // we got an error or the empty interface - exit early + + if len(ityp.methods) == 0 && len(ityp.embeddeds) == 0 { + // empty interface ityp.allMethods = markComplete return } - // use named receiver type if available (for better error messages) - var recvTyp Type = ityp - if def != nil { - recvTyp = def + // sort for API stability + sort.Sort(byUniqueMethodName(ityp.methods)) + sort.Stable(byUniqueTypeName(ityp.embeddeds)) + + check.later(func() { check.completeInterface(ityp) }) +} + +func (check *Checker) completeInterface(ityp *Interface) { + if ityp.allMethods != nil { + return + } + + // completeInterface may be called via the LookupFieldOrMethod, + // MissingMethod, Identical, or IdenticalIgnoreTags external API + // in which case check will be nil. In this case, type-checking + // must be finished and all interfaces should have been completed. + if check == nil { + panic("internal error: incomplete interface") } - // Correct receiver type for all methods explicitly declared - // by this interface after we're done with type-checking at - // this level. See comment below for details. - check.later(func() { - for _, m := range ityp.methods { - m.typ.(*Signature).recv.typ = recvTyp - } - }) - - // collect methods - var sigfix []*methodInfo - for i, minfo := range info.methods { - fun := minfo.fun - if fun == nil { - name := minfo.src.Names[0] - pos := name.Pos() - // Don't type-check signature yet - use an - // empty signature now and update it later. - // But set up receiver since we know it and - // its position, and because interface method - // signatures don't get a receiver via regular - // type-checking (there isn't a receiver in the - // method's AST). Setting the receiver type is - // also important for ptrRecv() (see methodset.go). - // - // Note: For embedded methods, the receiver type - // should be the type of the interface that declared - // the methods in the first place. Since we get the - // methods here via methodInfo, which may be computed - // before we have all relevant interface types, we use - // the current interface's type (recvType). This may be - // the type of the interface embedding the interface that - // declared the methods. This doesn't matter for type- - // checking (we only care about the receiver type for - // the ptrRecv predicate, and it's never a pointer recv - // for interfaces), but it matters for go/types clients - // and for printing. We correct the receiver after type- - // checking. - // - // TODO(gri) Consider marking methods signatures - // as incomplete, for better error messages. See - // also the T4 and T5 tests in testdata/cycles2.src. - sig := new(Signature) - sig.recv = NewVar(pos, check.pkg, "", recvTyp) - fun = NewFunc(pos, check.pkg, name.Name, sig) - minfo.fun = fun - check.recordDef(name, fun) - sigfix = append(sigfix, minfo) - } - // fun != nil - if i < info.explicits { - ityp.methods = append(ityp.methods, fun) - } - ityp.allMethods = append(ityp.allMethods, fun) + if trace { + check.trace(token.NoPos, "complete %s", ityp) + check.indent++ + defer func() { + check.indent-- + check.trace(token.NoPos, "=> %s", ityp) + }() } - // fix signatures now that we have collected all methods - savedContext := check.context - for _, minfo := range sigfix { - // (possibly embedded) methods must be type-checked within their scope and - // type-checking them must not affect the current context (was issue #23914) - check.context = context{scope: minfo.scope} - typ := check.indirectType(minfo.src.Type) - sig, _ := typ.(*Signature) - if sig == nil { - if typ != Typ[Invalid] { - check.invalidAST(minfo.src.Type.Pos(), "%s is not a method signature", typ) - } - continue // keep method with empty method signature + // An infinitely expanding interface (due to a cycle) is detected + // elsewhere (Checker.validType), so here we simply assume we only + // have valid interfaces. Mark the interface as complete to avoid + // infinite recursion if the validType check occurs later for some + // reason. + ityp.allMethods = markComplete + + // Methods of embedded interfaces are collected unchanged; i.e., the identity + // of a method I.m's Func Object of an interface I is the same as that of + // the method m in an interface that embeds interface I. On the other hand, + // if a method is embedded via multiple overlapping embedded interfaces, we + // don't provide a guarantee which "original m" got chosen for the embedding + // interface. See also issue #34421. + // + // If we don't care to provide this identity guarantee anymore, instead of + // reusing the original method in embeddings, we can clone the method's Func + // Object and give it the position of a corresponding embedded interface. Then + // we can get rid of the mpos map below and simply use the cloned method's + // position. + + var seen objset + var methods []*Func + mpos := make(map[*Func]token.Pos) // method specification or method embedding position, for good error messages + addMethod := func(pos token.Pos, m *Func, explicit bool) { + switch other := seen.insert(m); { + case other == nil: + methods = append(methods, m) + mpos[m] = pos + case explicit: + check.errorf(pos, "duplicate method %s", m.name) + check.errorf(mpos[other.(*Func)], "\tother declaration of %s", m.name) // secondary error, \t indented + default: + // check method signatures after all types are computed (issue #33656) + check.atEnd(func() { + if !check.identical(m.typ, other.Type()) { + check.errorf(pos, "duplicate method %s", m.name) + check.errorf(mpos[other.(*Func)], "\tother declaration of %s", m.name) // secondary error, \t indented + } + }) } - // update signature, but keep recv that was set up before - old := minfo.fun.typ.(*Signature) - sig.recv = old.recv - *old = *sig // update signature (don't replace pointer!) } - check.context = savedContext - // sort to match NewInterface/NewInterface2 - // TODO(gri) we may be able to switch to source order - sort.Sort(byUniqueMethodName(ityp.methods)) + for _, m := range ityp.methods { + addMethod(m.pos, m, true) + } - if ityp.allMethods == nil { - ityp.allMethods = markComplete - } else { - sort.Sort(byUniqueMethodName(ityp.allMethods)) + posList := check.posMap[ityp] + for i, typ := range ityp.embeddeds { + pos := posList[i] // embedding position + typ, ok := check.underlying(typ).(*Interface) + if !ok { + // An error was reported when collecting the embedded types. + // Ignore it. + continue + } + check.completeInterface(typ) + for _, m := range typ.allMethods { + addMethod(pos, m, false) // use embedding position pos rather than m.pos + } + } + + if methods != nil { + sort.Sort(byUniqueMethodName(methods)) + ityp.allMethods = methods } } diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_arm64.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_arm64.go new file mode 100644 index 00000000000..87f1e369cc2 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_arm64.go @@ -0,0 +1,17 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.11 +// +build !gccgo,!appengine + +package chacha20 + +const bufSize = 256 + +//go:noescape +func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) + +func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) { + xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter) +} diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_generic.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_generic.go new file mode 100644 index 00000000000..098ec9f6be0 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_generic.go @@ -0,0 +1,364 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package chacha20 implements the ChaCha20 and XChaCha20 encryption algorithms +// as specified in RFC 8439 and draft-irtf-cfrg-xchacha-01. +package chacha20 + +import ( + "crypto/cipher" + "encoding/binary" + "errors" + "math/bits" + + "golang.org/x/crypto/internal/subtle" +) + +const ( + // KeySize is the size of the key used by this cipher, in bytes. + KeySize = 32 + + // NonceSize is the size of the nonce used with the standard variant of this + // cipher, in bytes. + // + // Note that this is too short to be safely generated at random if the same + // key is reused more than 2³² times. + NonceSize = 12 + + // NonceSizeX is the size of the nonce used with the XChaCha20 variant of + // this cipher, in bytes. + NonceSizeX = 24 +) + +// Cipher is a stateful instance of ChaCha20 or XChaCha20 using a particular key +// and nonce. A *Cipher implements the cipher.Stream interface. +type Cipher struct { + // The ChaCha20 state is 16 words: 4 constant, 8 of key, 1 of counter + // (incremented after each block), and 3 of nonce. + key [8]uint32 + counter uint32 + nonce [3]uint32 + + // The last len bytes of buf are leftover key stream bytes from the previous + // XORKeyStream invocation. The size of buf depends on how many blocks are + // computed at a time. + buf [bufSize]byte + len int + + // The counter-independent results of the first round are cached after they + // are computed the first time. + precompDone bool + p1, p5, p9, p13 uint32 + p2, p6, p10, p14 uint32 + p3, p7, p11, p15 uint32 +} + +var _ cipher.Stream = (*Cipher)(nil) + +// NewUnauthenticatedCipher creates a new ChaCha20 stream cipher with the given +// 32 bytes key and a 12 or 24 bytes nonce. If a nonce of 24 bytes is provided, +// the XChaCha20 construction will be used. It returns an error if key or nonce +// have any other length. +// +// Note that ChaCha20, like all stream ciphers, is not authenticated and allows +// attackers to silently tamper with the plaintext. For this reason, it is more +// appropriate as a building block than as a standalone encryption mechanism. +// Instead, consider using package golang.org/x/crypto/chacha20poly1305. +func NewUnauthenticatedCipher(key, nonce []byte) (*Cipher, error) { + // This function is split into a wrapper so that the Cipher allocation will + // be inlined, and depending on how the caller uses the return value, won't + // escape to the heap. + c := &Cipher{} + return newUnauthenticatedCipher(c, key, nonce) +} + +func newUnauthenticatedCipher(c *Cipher, key, nonce []byte) (*Cipher, error) { + if len(key) != KeySize { + return nil, errors.New("chacha20: wrong key size") + } + if len(nonce) == NonceSizeX { + // XChaCha20 uses the ChaCha20 core to mix 16 bytes of the nonce into a + // derived key, allowing it to operate on a nonce of 24 bytes. See + // draft-irtf-cfrg-xchacha-01, Section 2.3. + key, _ = HChaCha20(key, nonce[0:16]) + cNonce := make([]byte, NonceSize) + copy(cNonce[4:12], nonce[16:24]) + nonce = cNonce + } else if len(nonce) != NonceSize { + return nil, errors.New("chacha20: wrong nonce size") + } + + c.key = [8]uint32{ + binary.LittleEndian.Uint32(key[0:4]), + binary.LittleEndian.Uint32(key[4:8]), + binary.LittleEndian.Uint32(key[8:12]), + binary.LittleEndian.Uint32(key[12:16]), + binary.LittleEndian.Uint32(key[16:20]), + binary.LittleEndian.Uint32(key[20:24]), + binary.LittleEndian.Uint32(key[24:28]), + binary.LittleEndian.Uint32(key[28:32]), + } + c.nonce = [3]uint32{ + binary.LittleEndian.Uint32(nonce[0:4]), + binary.LittleEndian.Uint32(nonce[4:8]), + binary.LittleEndian.Uint32(nonce[8:12]), + } + return c, nil +} + +// The constant first 4 words of the ChaCha20 state. +const ( + j0 uint32 = 0x61707865 // expa + j1 uint32 = 0x3320646e // nd 3 + j2 uint32 = 0x79622d32 // 2-by + j3 uint32 = 0x6b206574 // te k +) + +const blockSize = 64 + +// quarterRound is the core of ChaCha20. It shuffles the bits of 4 state words. +// It's executed 4 times for each of the 20 ChaCha20 rounds, operating on all 16 +// words each round, in columnar or diagonal groups of 4 at a time. +func quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) { + a += b + d ^= a + d = bits.RotateLeft32(d, 16) + c += d + b ^= c + b = bits.RotateLeft32(b, 12) + a += b + d ^= a + d = bits.RotateLeft32(d, 8) + c += d + b ^= c + b = bits.RotateLeft32(b, 7) + return a, b, c, d +} + +// XORKeyStream XORs each byte in the given slice with a byte from the +// cipher's key stream. Dst and src must overlap entirely or not at all. +// +// If len(dst) < len(src), XORKeyStream will panic. It is acceptable +// to pass a dst bigger than src, and in that case, XORKeyStream will +// only update dst[:len(src)] and will not touch the rest of dst. +// +// Multiple calls to XORKeyStream behave as if the concatenation of +// the src buffers was passed in a single run. That is, Cipher +// maintains state and does not reset at each XORKeyStream call. +func (s *Cipher) XORKeyStream(dst, src []byte) { + if len(src) == 0 { + return + } + if len(dst) < len(src) { + panic("chacha20: output smaller than input") + } + dst = dst[:len(src)] + if subtle.InexactOverlap(dst, src) { + panic("chacha20: invalid buffer overlap") + } + + // First, drain any remaining key stream from a previous XORKeyStream. + if s.len != 0 { + keyStream := s.buf[bufSize-s.len:] + if len(src) < len(keyStream) { + keyStream = keyStream[:len(src)] + } + _ = src[len(keyStream)-1] // bounds check elimination hint + for i, b := range keyStream { + dst[i] = src[i] ^ b + } + s.len -= len(keyStream) + src = src[len(keyStream):] + dst = dst[len(keyStream):] + } + + const blocksPerBuf = bufSize / blockSize + numBufs := (uint64(len(src)) + bufSize - 1) / bufSize + if uint64(s.counter)+numBufs*blocksPerBuf >= 1<<32 { + panic("chacha20: counter overflow") + } + + // xorKeyStreamBlocks implementations expect input lengths that are a + // multiple of bufSize. Platform-specific ones process multiple blocks at a + // time, so have bufSizes that are a multiple of blockSize. + + rem := len(src) % bufSize + full := len(src) - rem + + if full > 0 { + s.xorKeyStreamBlocks(dst[:full], src[:full]) + } + + // If we have a partial (multi-)block, pad it for xorKeyStreamBlocks, and + // keep the leftover keystream for the next XORKeyStream invocation. + if rem > 0 { + s.buf = [bufSize]byte{} + copy(s.buf[:], src[full:]) + s.xorKeyStreamBlocks(s.buf[:], s.buf[:]) + s.len = bufSize - copy(dst[full:], s.buf[:]) + } +} + +func (s *Cipher) xorKeyStreamBlocksGeneric(dst, src []byte) { + if len(dst) != len(src) || len(dst)%blockSize != 0 { + panic("chacha20: internal error: wrong dst and/or src length") + } + + // To generate each block of key stream, the initial cipher state + // (represented below) is passed through 20 rounds of shuffling, + // alternatively applying quarterRounds by columns (like 1, 5, 9, 13) + // or by diagonals (like 1, 6, 11, 12). + // + // 0:cccccccc 1:cccccccc 2:cccccccc 3:cccccccc + // 4:kkkkkkkk 5:kkkkkkkk 6:kkkkkkkk 7:kkkkkkkk + // 8:kkkkkkkk 9:kkkkkkkk 10:kkkkkkkk 11:kkkkkkkk + // 12:bbbbbbbb 13:nnnnnnnn 14:nnnnnnnn 15:nnnnnnnn + // + // c=constant k=key b=blockcount n=nonce + var ( + c0, c1, c2, c3 = j0, j1, j2, j3 + c4, c5, c6, c7 = s.key[0], s.key[1], s.key[2], s.key[3] + c8, c9, c10, c11 = s.key[4], s.key[5], s.key[6], s.key[7] + _, c13, c14, c15 = s.counter, s.nonce[0], s.nonce[1], s.nonce[2] + ) + + // Three quarters of the first round don't depend on the counter, so we can + // calculate them here, and reuse them for multiple blocks in the loop, and + // for future XORKeyStream invocations. + if !s.precompDone { + s.p1, s.p5, s.p9, s.p13 = quarterRound(c1, c5, c9, c13) + s.p2, s.p6, s.p10, s.p14 = quarterRound(c2, c6, c10, c14) + s.p3, s.p7, s.p11, s.p15 = quarterRound(c3, c7, c11, c15) + s.precompDone = true + } + + for i := 0; i < len(src); i += blockSize { + // The remainder of the first column round. + fcr0, fcr4, fcr8, fcr12 := quarterRound(c0, c4, c8, s.counter) + + // The second diagonal round. + x0, x5, x10, x15 := quarterRound(fcr0, s.p5, s.p10, s.p15) + x1, x6, x11, x12 := quarterRound(s.p1, s.p6, s.p11, fcr12) + x2, x7, x8, x13 := quarterRound(s.p2, s.p7, fcr8, s.p13) + x3, x4, x9, x14 := quarterRound(s.p3, fcr4, s.p9, s.p14) + + // The remaining 18 rounds. + for i := 0; i < 9; i++ { + // Column round. + x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12) + x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13) + x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14) + x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15) + + // Diagonal round. + x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15) + x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12) + x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13) + x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14) + } + + // Finally, add back the initial state to generate the key stream. + x0 += c0 + x1 += c1 + x2 += c2 + x3 += c3 + x4 += c4 + x5 += c5 + x6 += c6 + x7 += c7 + x8 += c8 + x9 += c9 + x10 += c10 + x11 += c11 + x12 += s.counter + x13 += c13 + x14 += c14 + x15 += c15 + + s.counter += 1 + if s.counter == 0 { + panic("chacha20: internal error: counter overflow") + } + + in, out := src[i:], dst[i:] + in, out = in[:blockSize], out[:blockSize] // bounds check elimination hint + + // XOR the key stream with the source and write out the result. + xor(out[0:], in[0:], x0) + xor(out[4:], in[4:], x1) + xor(out[8:], in[8:], x2) + xor(out[12:], in[12:], x3) + xor(out[16:], in[16:], x4) + xor(out[20:], in[20:], x5) + xor(out[24:], in[24:], x6) + xor(out[28:], in[28:], x7) + xor(out[32:], in[32:], x8) + xor(out[36:], in[36:], x9) + xor(out[40:], in[40:], x10) + xor(out[44:], in[44:], x11) + xor(out[48:], in[48:], x12) + xor(out[52:], in[52:], x13) + xor(out[56:], in[56:], x14) + xor(out[60:], in[60:], x15) + } +} + +// HChaCha20 uses the ChaCha20 core to generate a derived key from a 32 bytes +// key and a 16 bytes nonce. It returns an error if key or nonce have any other +// length. It is used as part of the XChaCha20 construction. +func HChaCha20(key, nonce []byte) ([]byte, error) { + // This function is split into a wrapper so that the slice allocation will + // be inlined, and depending on how the caller uses the return value, won't + // escape to the heap. + out := make([]byte, 32) + return hChaCha20(out, key, nonce) +} + +func hChaCha20(out, key, nonce []byte) ([]byte, error) { + if len(key) != KeySize { + return nil, errors.New("chacha20: wrong HChaCha20 key size") + } + if len(nonce) != 16 { + return nil, errors.New("chacha20: wrong HChaCha20 nonce size") + } + + x0, x1, x2, x3 := j0, j1, j2, j3 + x4 := binary.LittleEndian.Uint32(key[0:4]) + x5 := binary.LittleEndian.Uint32(key[4:8]) + x6 := binary.LittleEndian.Uint32(key[8:12]) + x7 := binary.LittleEndian.Uint32(key[12:16]) + x8 := binary.LittleEndian.Uint32(key[16:20]) + x9 := binary.LittleEndian.Uint32(key[20:24]) + x10 := binary.LittleEndian.Uint32(key[24:28]) + x11 := binary.LittleEndian.Uint32(key[28:32]) + x12 := binary.LittleEndian.Uint32(nonce[0:4]) + x13 := binary.LittleEndian.Uint32(nonce[4:8]) + x14 := binary.LittleEndian.Uint32(nonce[8:12]) + x15 := binary.LittleEndian.Uint32(nonce[12:16]) + + for i := 0; i < 10; i++ { + // Diagonal round. + x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12) + x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13) + x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14) + x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15) + + // Column round. + x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15) + x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12) + x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13) + x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14) + } + + _ = out[31] // bounds check elimination hint + binary.LittleEndian.PutUint32(out[0:4], x0) + binary.LittleEndian.PutUint32(out[4:8], x1) + binary.LittleEndian.PutUint32(out[8:12], x2) + binary.LittleEndian.PutUint32(out[12:16], x3) + binary.LittleEndian.PutUint32(out[16:20], x12) + binary.LittleEndian.PutUint32(out[20:24], x13) + binary.LittleEndian.PutUint32(out[24:28], x14) + binary.LittleEndian.PutUint32(out[28:32], x15) + return out, nil +} diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_noasm.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_noasm.go new file mode 100644 index 00000000000..ec609ed868b --- /dev/null +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_noasm.go @@ -0,0 +1,13 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !arm64,!s390x,!ppc64le arm64,!go1.11 gccgo appengine + +package chacha20 + +const bufSize = blockSize + +func (s *Cipher) xorKeyStreamBlocks(dst, src []byte) { + s.xorKeyStreamBlocksGeneric(dst, src) +} diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_ppc64le.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_ppc64le.go new file mode 100644 index 00000000000..d0ec61f08d9 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_ppc64le.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo,!appengine + +package chacha20 + +const bufSize = 256 + +//go:noescape +func chaCha20_ctr32_vsx(out, inp *byte, len int, key *[8]uint32, counter *uint32) + +func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) { + chaCha20_ctr32_vsx(&dst[0], &src[0], len(src), &c.key, &c.counter) +} diff --git a/libgo/go/golang.org/x/crypto/chacha20/chacha_s390x.go b/libgo/go/golang.org/x/crypto/chacha20/chacha_s390x.go new file mode 100644 index 00000000000..cd55f45a333 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/chacha20/chacha_s390x.go @@ -0,0 +1,26 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !gccgo,!appengine + +package chacha20 + +import "golang.org/x/sys/cpu" + +var haveAsm = cpu.S390X.HasVX + +const bufSize = 256 + +// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only +// be called when the vector facility is available. Implementation in asm_s390x.s. +//go:noescape +func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) + +func (c *Cipher) xorKeyStreamBlocks(dst, src []byte) { + if cpu.S390X.HasVX { + xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter) + } else { + c.xorKeyStreamBlocksGeneric(dst, src) + } +} diff --git a/libgo/go/golang.org/x/crypto/chacha20/xor.go b/libgo/go/golang.org/x/crypto/chacha20/xor.go new file mode 100644 index 00000000000..0110c9865af --- /dev/null +++ b/libgo/go/golang.org/x/crypto/chacha20/xor.go @@ -0,0 +1,41 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found src the LICENSE file. + +package chacha20 + +import "runtime" + +// Platforms that have fast unaligned 32-bit little endian accesses. +const unaligned = runtime.GOARCH == "386" || + runtime.GOARCH == "amd64" || + runtime.GOARCH == "arm64" || + runtime.GOARCH == "ppc64le" || + runtime.GOARCH == "s390x" + +// xor reads a little endian uint32 from src, XORs it with u and +// places the result in little endian byte order in dst. +func xor(dst, src []byte, u uint32) { + _, _ = src[3], dst[3] // eliminate bounds checks + if unaligned { + // The compiler should optimize this code into + // 32-bit unaligned little endian loads and stores. + // TODO: delete once the compiler does a reliably + // good job with the generic code below. + // See issue #25111 for more details. + v := uint32(src[0]) + v |= uint32(src[1]) << 8 + v |= uint32(src[2]) << 16 + v |= uint32(src[3]) << 24 + v ^= u + dst[0] = byte(v) + dst[1] = byte(v >> 8) + dst[2] = byte(v >> 16) + dst[3] = byte(v >> 24) + } else { + dst[0] = src[0] ^ byte(u) + dst[1] = src[1] ^ byte(u>>8) + dst[2] = src[2] ^ byte(u>>16) + dst[3] = src[3] ^ byte(u>>24) + } +} diff --git a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go index bbb86efef55..0d7bac3f7db 100644 --- a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go +++ b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD as specified in RFC 7539, -// and its extended nonce variant XChaCha20-Poly1305. +// Package chacha20poly1305 implements the ChaCha20-Poly1305 AEAD and its +// extended nonce variant XChaCha20-Poly1305, as specified in RFC 8439 and +// draft-irtf-cfrg-xchacha-01. package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305" import ( "crypto/cipher" - "encoding/binary" "errors" ) @@ -29,7 +29,7 @@ const ( ) type chacha20poly1305 struct { - key [8]uint32 + key [KeySize]byte } // New returns a ChaCha20-Poly1305 AEAD that uses the given 256-bit key. @@ -38,14 +38,7 @@ func New(key []byte) (cipher.AEAD, error) { return nil, errors.New("chacha20poly1305: bad key length") } ret := new(chacha20poly1305) - ret.key[0] = binary.LittleEndian.Uint32(key[0:4]) - ret.key[1] = binary.LittleEndian.Uint32(key[4:8]) - ret.key[2] = binary.LittleEndian.Uint32(key[8:12]) - ret.key[3] = binary.LittleEndian.Uint32(key[12:16]) - ret.key[4] = binary.LittleEndian.Uint32(key[16:20]) - ret.key[5] = binary.LittleEndian.Uint32(key[20:24]) - ret.key[6] = binary.LittleEndian.Uint32(key[24:28]) - ret.key[7] = binary.LittleEndian.Uint32(key[28:32]) + copy(ret.key[:], key) return ret, nil } diff --git a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go index 2aa4fd89dba..737e46aa5a4 100644 --- a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go +++ b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go @@ -25,23 +25,23 @@ var ( // setupState writes a ChaCha20 input matrix to state. See // https://tools.ietf.org/html/rfc7539#section-2.3. -func setupState(state *[16]uint32, key *[8]uint32, nonce []byte) { +func setupState(state *[16]uint32, key *[32]byte, nonce []byte) { state[0] = 0x61707865 state[1] = 0x3320646e state[2] = 0x79622d32 state[3] = 0x6b206574 - state[4] = key[0] - state[5] = key[1] - state[6] = key[2] - state[7] = key[3] - state[8] = key[4] - state[9] = key[5] - state[10] = key[6] - state[11] = key[7] + state[4] = binary.LittleEndian.Uint32(key[0:4]) + state[5] = binary.LittleEndian.Uint32(key[4:8]) + state[6] = binary.LittleEndian.Uint32(key[8:12]) + state[7] = binary.LittleEndian.Uint32(key[12:16]) + state[8] = binary.LittleEndian.Uint32(key[16:20]) + state[9] = binary.LittleEndian.Uint32(key[20:24]) + state[10] = binary.LittleEndian.Uint32(key[24:28]) + state[11] = binary.LittleEndian.Uint32(key[28:32]) state[12] = 0 - state[13] = binary.LittleEndian.Uint32(nonce[:4]) + state[13] = binary.LittleEndian.Uint32(nonce[0:4]) state[14] = binary.LittleEndian.Uint32(nonce[4:8]) state[15] = binary.LittleEndian.Uint32(nonce[8:12]) } diff --git a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go index c27971216c9..91b38568ce1 100644 --- a/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go +++ b/libgo/go/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go @@ -7,7 +7,7 @@ package chacha20poly1305 import ( "encoding/binary" - "golang.org/x/crypto/internal/chacha20" + "golang.org/x/crypto/chacha20" "golang.org/x/crypto/internal/subtle" "golang.org/x/crypto/poly1305" ) @@ -22,14 +22,10 @@ func (c *chacha20poly1305) sealGeneric(dst, nonce, plaintext, additionalData []b panic("chacha20poly1305: invalid buffer overlap") } - var polyKey [32]byte - s := chacha20.New(c.key, [3]uint32{ - binary.LittleEndian.Uint32(nonce[0:4]), - binary.LittleEndian.Uint32(nonce[4:8]), - binary.LittleEndian.Uint32(nonce[8:12]), - }) + var polyKey, discardBuf [32]byte + s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce) s.XORKeyStream(polyKey[:], polyKey[:]) - s.Advance() // skip the next 32 bytes + s.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes s.XORKeyStream(out, plaintext) polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(plaintext))+8+8) @@ -50,14 +46,10 @@ func (c *chacha20poly1305) openGeneric(dst, nonce, ciphertext, additionalData [] copy(tag[:], ciphertext[len(ciphertext)-16:]) ciphertext = ciphertext[:len(ciphertext)-16] - var polyKey [32]byte - s := chacha20.New(c.key, [3]uint32{ - binary.LittleEndian.Uint32(nonce[0:4]), - binary.LittleEndian.Uint32(nonce[4:8]), - binary.LittleEndian.Uint32(nonce[8:12]), - }) + var polyKey, discardBuf [32]byte + s, _ := chacha20.NewUnauthenticatedCipher(c.key[:], nonce) s.XORKeyStream(polyKey[:], polyKey[:]) - s.Advance() // skip the next 32 bytes + s.XORKeyStream(discardBuf[:], discardBuf[:]) // skip the next 32 bytes polyInput := make([]byte, roundTo16(len(additionalData))+roundTo16(len(ciphertext))+8+8) copy(polyInput, additionalData) diff --git a/libgo/go/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go b/libgo/go/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go index a02fa571924..d9d46b96396 100644 --- a/libgo/go/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go +++ b/libgo/go/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go @@ -6,14 +6,13 @@ package chacha20poly1305 import ( "crypto/cipher" - "encoding/binary" "errors" - "golang.org/x/crypto/internal/chacha20" + "golang.org/x/crypto/chacha20" ) type xchacha20poly1305 struct { - key [8]uint32 + key [KeySize]byte } // NewX returns a XChaCha20-Poly1305 AEAD that uses the given 256-bit key. @@ -27,14 +26,7 @@ func NewX(key []byte) (cipher.AEAD, error) { return nil, errors.New("chacha20poly1305: bad key length") } ret := new(xchacha20poly1305) - ret.key[0] = binary.LittleEndian.Uint32(key[0:4]) - ret.key[1] = binary.LittleEndian.Uint32(key[4:8]) - ret.key[2] = binary.LittleEndian.Uint32(key[8:12]) - ret.key[3] = binary.LittleEndian.Uint32(key[12:16]) - ret.key[4] = binary.LittleEndian.Uint32(key[16:20]) - ret.key[5] = binary.LittleEndian.Uint32(key[20:24]) - ret.key[6] = binary.LittleEndian.Uint32(key[24:28]) - ret.key[7] = binary.LittleEndian.Uint32(key[28:32]) + copy(ret.key[:], key) return ret, nil } @@ -60,15 +52,10 @@ func (x *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) [ panic("chacha20poly1305: plaintext too large") } - hNonce := [4]uint32{ - binary.LittleEndian.Uint32(nonce[0:4]), - binary.LittleEndian.Uint32(nonce[4:8]), - binary.LittleEndian.Uint32(nonce[8:12]), - binary.LittleEndian.Uint32(nonce[12:16]), - } - c := &chacha20poly1305{ - key: chacha20.HChaCha20(&x.key, &hNonce), - } + c := new(chacha20poly1305) + hKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16]) + copy(c.key[:], hKey) + // The first 4 bytes of the final nonce are unused counter space. cNonce := make([]byte, NonceSize) copy(cNonce[4:12], nonce[16:24]) @@ -87,15 +74,10 @@ func (x *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) panic("chacha20poly1305: ciphertext too large") } - hNonce := [4]uint32{ - binary.LittleEndian.Uint32(nonce[0:4]), - binary.LittleEndian.Uint32(nonce[4:8]), - binary.LittleEndian.Uint32(nonce[8:12]), - binary.LittleEndian.Uint32(nonce[12:16]), - } - c := &chacha20poly1305{ - key: chacha20.HChaCha20(&x.key, &hNonce), - } + c := new(chacha20poly1305) + hKey, _ := chacha20.HChaCha20(x.key[:], nonce[0:16]) + copy(c.key[:], hKey) + // The first 4 bytes of the final nonce are unused counter space. cNonce := make([]byte, NonceSize) copy(cNonce[4:12], nonce[16:24]) diff --git a/libgo/go/golang.org/x/crypto/curve25519/curve25519.go b/libgo/go/golang.org/x/crypto/curve25519/curve25519.go index 75f24babb69..4b9a655d1b5 100644 --- a/libgo/go/golang.org/x/crypto/curve25519/curve25519.go +++ b/libgo/go/golang.org/x/crypto/curve25519/curve25519.go @@ -1,834 +1,95 @@ -// Copyright 2013 The Go Authors. All rights reserved. +// Copyright 2019 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// We have an implementation in amd64 assembly so this code is only run on -// non-amd64 platforms. The amd64 assembly does not support gccgo. -// +build !amd64 gccgo appengine - -package curve25519 +// Package curve25519 provides an implementation of the X25519 function, which +// performs scalar multiplication on the elliptic curve known as Curve25519. +// See RFC 7748. +package curve25519 // import "golang.org/x/crypto/curve25519" import ( - "encoding/binary" + "crypto/subtle" + "fmt" ) -// This code is a port of the public domain, "ref10" implementation of -// curve25519 from SUPERCOP 20130419 by D. J. Bernstein. - -// fieldElement represents an element of the field GF(2^255 - 19). An element -// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 -// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on -// context. -type fieldElement [10]int32 - -func feZero(fe *fieldElement) { - for i := range fe { - fe[i] = 0 - } -} - -func feOne(fe *fieldElement) { - feZero(fe) - fe[0] = 1 -} - -func feAdd(dst, a, b *fieldElement) { - for i := range dst { - dst[i] = a[i] + b[i] - } -} - -func feSub(dst, a, b *fieldElement) { - for i := range dst { - dst[i] = a[i] - b[i] - } -} - -func feCopy(dst, src *fieldElement) { - for i := range dst { - dst[i] = src[i] - } -} - -// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0. -// -// Preconditions: b in {0,1}. -func feCSwap(f, g *fieldElement, b int32) { - b = -b - for i := range f { - t := b & (f[i] ^ g[i]) - f[i] ^= t - g[i] ^= t - } -} - -// load3 reads a 24-bit, little-endian value from in. -func load3(in []byte) int64 { - var r int64 - r = int64(in[0]) - r |= int64(in[1]) << 8 - r |= int64(in[2]) << 16 - return r -} - -// load4 reads a 32-bit, little-endian value from in. -func load4(in []byte) int64 { - return int64(binary.LittleEndian.Uint32(in)) -} - -func feFromBytes(dst *fieldElement, src *[32]byte) { - h0 := load4(src[:]) - h1 := load3(src[4:]) << 6 - h2 := load3(src[7:]) << 5 - h3 := load3(src[10:]) << 3 - h4 := load3(src[13:]) << 2 - h5 := load4(src[16:]) - h6 := load3(src[20:]) << 7 - h7 := load3(src[23:]) << 5 - h8 := load3(src[26:]) << 4 - h9 := (load3(src[29:]) & 0x7fffff) << 2 - - var carry [10]int64 - carry[9] = (h9 + 1<<24) >> 25 - h0 += carry[9] * 19 - h9 -= carry[9] << 25 - carry[1] = (h1 + 1<<24) >> 25 - h2 += carry[1] - h1 -= carry[1] << 25 - carry[3] = (h3 + 1<<24) >> 25 - h4 += carry[3] - h3 -= carry[3] << 25 - carry[5] = (h5 + 1<<24) >> 25 - h6 += carry[5] - h5 -= carry[5] << 25 - carry[7] = (h7 + 1<<24) >> 25 - h8 += carry[7] - h7 -= carry[7] << 25 - - carry[0] = (h0 + 1<<25) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - carry[2] = (h2 + 1<<25) >> 26 - h3 += carry[2] - h2 -= carry[2] << 26 - carry[4] = (h4 + 1<<25) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - carry[6] = (h6 + 1<<25) >> 26 - h7 += carry[6] - h6 -= carry[6] << 26 - carry[8] = (h8 + 1<<25) >> 26 - h9 += carry[8] - h8 -= carry[8] << 26 - - dst[0] = int32(h0) - dst[1] = int32(h1) - dst[2] = int32(h2) - dst[3] = int32(h3) - dst[4] = int32(h4) - dst[5] = int32(h5) - dst[6] = int32(h6) - dst[7] = int32(h7) - dst[8] = int32(h8) - dst[9] = int32(h9) -} - -// feToBytes marshals h to s. -// Preconditions: -// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -// -// Write p=2^255-19; q=floor(h/p). -// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). -// -// Proof: -// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. -// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4. -// -// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). -// Then 0> 25 - q = (h[0] + q) >> 26 - q = (h[1] + q) >> 25 - q = (h[2] + q) >> 26 - q = (h[3] + q) >> 25 - q = (h[4] + q) >> 26 - q = (h[5] + q) >> 25 - q = (h[6] + q) >> 26 - q = (h[7] + q) >> 25 - q = (h[8] + q) >> 26 - q = (h[9] + q) >> 25 - - // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. - h[0] += 19 * q - // Goal: Output h-2^255 q, which is between 0 and 2^255-20. - - carry[0] = h[0] >> 26 - h[1] += carry[0] - h[0] -= carry[0] << 26 - carry[1] = h[1] >> 25 - h[2] += carry[1] - h[1] -= carry[1] << 25 - carry[2] = h[2] >> 26 - h[3] += carry[2] - h[2] -= carry[2] << 26 - carry[3] = h[3] >> 25 - h[4] += carry[3] - h[3] -= carry[3] << 25 - carry[4] = h[4] >> 26 - h[5] += carry[4] - h[4] -= carry[4] << 26 - carry[5] = h[5] >> 25 - h[6] += carry[5] - h[5] -= carry[5] << 25 - carry[6] = h[6] >> 26 - h[7] += carry[6] - h[6] -= carry[6] << 26 - carry[7] = h[7] >> 25 - h[8] += carry[7] - h[7] -= carry[7] << 25 - carry[8] = h[8] >> 26 - h[9] += carry[8] - h[8] -= carry[8] << 26 - carry[9] = h[9] >> 25 - h[9] -= carry[9] << 25 - // h10 = carry9 - - // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. - // Have h[0]+...+2^230 h[9] between 0 and 2^255-1; - // evidently 2^255 h10-2^255 q = 0. - // Goal: Output h[0]+...+2^230 h[9]. - - s[0] = byte(h[0] >> 0) - s[1] = byte(h[0] >> 8) - s[2] = byte(h[0] >> 16) - s[3] = byte((h[0] >> 24) | (h[1] << 2)) - s[4] = byte(h[1] >> 6) - s[5] = byte(h[1] >> 14) - s[6] = byte((h[1] >> 22) | (h[2] << 3)) - s[7] = byte(h[2] >> 5) - s[8] = byte(h[2] >> 13) - s[9] = byte((h[2] >> 21) | (h[3] << 5)) - s[10] = byte(h[3] >> 3) - s[11] = byte(h[3] >> 11) - s[12] = byte((h[3] >> 19) | (h[4] << 6)) - s[13] = byte(h[4] >> 2) - s[14] = byte(h[4] >> 10) - s[15] = byte(h[4] >> 18) - s[16] = byte(h[5] >> 0) - s[17] = byte(h[5] >> 8) - s[18] = byte(h[5] >> 16) - s[19] = byte((h[5] >> 24) | (h[6] << 1)) - s[20] = byte(h[6] >> 7) - s[21] = byte(h[6] >> 15) - s[22] = byte((h[6] >> 23) | (h[7] << 3)) - s[23] = byte(h[7] >> 5) - s[24] = byte(h[7] >> 13) - s[25] = byte((h[7] >> 21) | (h[8] << 4)) - s[26] = byte(h[8] >> 4) - s[27] = byte(h[8] >> 12) - s[28] = byte((h[8] >> 20) | (h[9] << 6)) - s[29] = byte(h[9] >> 2) - s[30] = byte(h[9] >> 10) - s[31] = byte(h[9] >> 18) +// Deprecated: when provided a low-order point, ScalarMult will set dst to all +// zeroes, irrespective of the scalar. Instead, use the X25519 function, which +// will return an error. +func ScalarMult(dst, scalar, point *[32]byte) { + scalarMult(dst, scalar, point) } -// feMul calculates h = f * g -// Can overlap h with f or g. -// -// Preconditions: -// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -// -// Postconditions: -// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -// -// Notes on implementation strategy: -// -// Using schoolbook multiplication. -// Karatsuba would save a little in some cost models. +// ScalarBaseMult sets dst to the product scalar * base where base is the +// standard generator. // -// Most multiplications by 2 and 19 are 32-bit precomputations; -// cheaper than 64-bit postcomputations. -// -// There is one remaining multiplication by 19 in the carry chain; -// one *19 precomputation can be merged into this, -// but the resulting data flow is considerably less clean. -// -// There are 12 carries below. -// 10 of them are 2-way parallelizable and vectorizable. -// Can get away with 11 carries, but then data flow is much deeper. -// -// With tighter constraints on inputs can squeeze carries into int32. -func feMul(h, f, g *fieldElement) { - f0 := f[0] - f1 := f[1] - f2 := f[2] - f3 := f[3] - f4 := f[4] - f5 := f[5] - f6 := f[6] - f7 := f[7] - f8 := f[8] - f9 := f[9] - g0 := g[0] - g1 := g[1] - g2 := g[2] - g3 := g[3] - g4 := g[4] - g5 := g[5] - g6 := g[6] - g7 := g[7] - g8 := g[8] - g9 := g[9] - g1_19 := 19 * g1 // 1.4*2^29 - g2_19 := 19 * g2 // 1.4*2^30; still ok - g3_19 := 19 * g3 - g4_19 := 19 * g4 - g5_19 := 19 * g5 - g6_19 := 19 * g6 - g7_19 := 19 * g7 - g8_19 := 19 * g8 - g9_19 := 19 * g9 - f1_2 := 2 * f1 - f3_2 := 2 * f3 - f5_2 := 2 * f5 - f7_2 := 2 * f7 - f9_2 := 2 * f9 - f0g0 := int64(f0) * int64(g0) - f0g1 := int64(f0) * int64(g1) - f0g2 := int64(f0) * int64(g2) - f0g3 := int64(f0) * int64(g3) - f0g4 := int64(f0) * int64(g4) - f0g5 := int64(f0) * int64(g5) - f0g6 := int64(f0) * int64(g6) - f0g7 := int64(f0) * int64(g7) - f0g8 := int64(f0) * int64(g8) - f0g9 := int64(f0) * int64(g9) - f1g0 := int64(f1) * int64(g0) - f1g1_2 := int64(f1_2) * int64(g1) - f1g2 := int64(f1) * int64(g2) - f1g3_2 := int64(f1_2) * int64(g3) - f1g4 := int64(f1) * int64(g4) - f1g5_2 := int64(f1_2) * int64(g5) - f1g6 := int64(f1) * int64(g6) - f1g7_2 := int64(f1_2) * int64(g7) - f1g8 := int64(f1) * int64(g8) - f1g9_38 := int64(f1_2) * int64(g9_19) - f2g0 := int64(f2) * int64(g0) - f2g1 := int64(f2) * int64(g1) - f2g2 := int64(f2) * int64(g2) - f2g3 := int64(f2) * int64(g3) - f2g4 := int64(f2) * int64(g4) - f2g5 := int64(f2) * int64(g5) - f2g6 := int64(f2) * int64(g6) - f2g7 := int64(f2) * int64(g7) - f2g8_19 := int64(f2) * int64(g8_19) - f2g9_19 := int64(f2) * int64(g9_19) - f3g0 := int64(f3) * int64(g0) - f3g1_2 := int64(f3_2) * int64(g1) - f3g2 := int64(f3) * int64(g2) - f3g3_2 := int64(f3_2) * int64(g3) - f3g4 := int64(f3) * int64(g4) - f3g5_2 := int64(f3_2) * int64(g5) - f3g6 := int64(f3) * int64(g6) - f3g7_38 := int64(f3_2) * int64(g7_19) - f3g8_19 := int64(f3) * int64(g8_19) - f3g9_38 := int64(f3_2) * int64(g9_19) - f4g0 := int64(f4) * int64(g0) - f4g1 := int64(f4) * int64(g1) - f4g2 := int64(f4) * int64(g2) - f4g3 := int64(f4) * int64(g3) - f4g4 := int64(f4) * int64(g4) - f4g5 := int64(f4) * int64(g5) - f4g6_19 := int64(f4) * int64(g6_19) - f4g7_19 := int64(f4) * int64(g7_19) - f4g8_19 := int64(f4) * int64(g8_19) - f4g9_19 := int64(f4) * int64(g9_19) - f5g0 := int64(f5) * int64(g0) - f5g1_2 := int64(f5_2) * int64(g1) - f5g2 := int64(f5) * int64(g2) - f5g3_2 := int64(f5_2) * int64(g3) - f5g4 := int64(f5) * int64(g4) - f5g5_38 := int64(f5_2) * int64(g5_19) - f5g6_19 := int64(f5) * int64(g6_19) - f5g7_38 := int64(f5_2) * int64(g7_19) - f5g8_19 := int64(f5) * int64(g8_19) - f5g9_38 := int64(f5_2) * int64(g9_19) - f6g0 := int64(f6) * int64(g0) - f6g1 := int64(f6) * int64(g1) - f6g2 := int64(f6) * int64(g2) - f6g3 := int64(f6) * int64(g3) - f6g4_19 := int64(f6) * int64(g4_19) - f6g5_19 := int64(f6) * int64(g5_19) - f6g6_19 := int64(f6) * int64(g6_19) - f6g7_19 := int64(f6) * int64(g7_19) - f6g8_19 := int64(f6) * int64(g8_19) - f6g9_19 := int64(f6) * int64(g9_19) - f7g0 := int64(f7) * int64(g0) - f7g1_2 := int64(f7_2) * int64(g1) - f7g2 := int64(f7) * int64(g2) - f7g3_38 := int64(f7_2) * int64(g3_19) - f7g4_19 := int64(f7) * int64(g4_19) - f7g5_38 := int64(f7_2) * int64(g5_19) - f7g6_19 := int64(f7) * int64(g6_19) - f7g7_38 := int64(f7_2) * int64(g7_19) - f7g8_19 := int64(f7) * int64(g8_19) - f7g9_38 := int64(f7_2) * int64(g9_19) - f8g0 := int64(f8) * int64(g0) - f8g1 := int64(f8) * int64(g1) - f8g2_19 := int64(f8) * int64(g2_19) - f8g3_19 := int64(f8) * int64(g3_19) - f8g4_19 := int64(f8) * int64(g4_19) - f8g5_19 := int64(f8) * int64(g5_19) - f8g6_19 := int64(f8) * int64(g6_19) - f8g7_19 := int64(f8) * int64(g7_19) - f8g8_19 := int64(f8) * int64(g8_19) - f8g9_19 := int64(f8) * int64(g9_19) - f9g0 := int64(f9) * int64(g0) - f9g1_38 := int64(f9_2) * int64(g1_19) - f9g2_19 := int64(f9) * int64(g2_19) - f9g3_38 := int64(f9_2) * int64(g3_19) - f9g4_19 := int64(f9) * int64(g4_19) - f9g5_38 := int64(f9_2) * int64(g5_19) - f9g6_19 := int64(f9) * int64(g6_19) - f9g7_38 := int64(f9_2) * int64(g7_19) - f9g8_19 := int64(f9) * int64(g8_19) - f9g9_38 := int64(f9_2) * int64(g9_19) - h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38 - h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19 - h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38 - h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19 - h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38 - h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19 - h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38 - h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19 - h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38 - h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 - var carry [10]int64 - - // |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38)) - // i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8 - // |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19)) - // i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - // |h0| <= 2^25 - // |h4| <= 2^25 - // |h1| <= 1.51*2^58 - // |h5| <= 1.51*2^58 - - carry[1] = (h1 + (1 << 24)) >> 25 - h2 += carry[1] - h1 -= carry[1] << 25 - carry[5] = (h5 + (1 << 24)) >> 25 - h6 += carry[5] - h5 -= carry[5] << 25 - // |h1| <= 2^24; from now on fits into int32 - // |h5| <= 2^24; from now on fits into int32 - // |h2| <= 1.21*2^59 - // |h6| <= 1.21*2^59 - - carry[2] = (h2 + (1 << 25)) >> 26 - h3 += carry[2] - h2 -= carry[2] << 26 - carry[6] = (h6 + (1 << 25)) >> 26 - h7 += carry[6] - h6 -= carry[6] << 26 - // |h2| <= 2^25; from now on fits into int32 unchanged - // |h6| <= 2^25; from now on fits into int32 unchanged - // |h3| <= 1.51*2^58 - // |h7| <= 1.51*2^58 - - carry[3] = (h3 + (1 << 24)) >> 25 - h4 += carry[3] - h3 -= carry[3] << 25 - carry[7] = (h7 + (1 << 24)) >> 25 - h8 += carry[7] - h7 -= carry[7] << 25 - // |h3| <= 2^24; from now on fits into int32 unchanged - // |h7| <= 2^24; from now on fits into int32 unchanged - // |h4| <= 1.52*2^33 - // |h8| <= 1.52*2^33 - - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - carry[8] = (h8 + (1 << 25)) >> 26 - h9 += carry[8] - h8 -= carry[8] << 26 - // |h4| <= 2^25; from now on fits into int32 unchanged - // |h8| <= 2^25; from now on fits into int32 unchanged - // |h5| <= 1.01*2^24 - // |h9| <= 1.51*2^58 - - carry[9] = (h9 + (1 << 24)) >> 25 - h0 += carry[9] * 19 - h9 -= carry[9] << 25 - // |h9| <= 2^24; from now on fits into int32 unchanged - // |h0| <= 1.8*2^37 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - // |h0| <= 2^25; from now on fits into int32 unchanged - // |h1| <= 1.01*2^24 - - h[0] = int32(h0) - h[1] = int32(h1) - h[2] = int32(h2) - h[3] = int32(h3) - h[4] = int32(h4) - h[5] = int32(h5) - h[6] = int32(h6) - h[7] = int32(h7) - h[8] = int32(h8) - h[9] = int32(h9) +// It is recommended to use the X25519 function with Basepoint instead, as +// copying into fixed size arrays can lead to unexpected bugs. +func ScalarBaseMult(dst, scalar *[32]byte) { + ScalarMult(dst, scalar, &basePoint) } -// feSquare calculates h = f*f. Can overlap h with f. -// -// Preconditions: -// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -// -// Postconditions: -// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -func feSquare(h, f *fieldElement) { - f0 := f[0] - f1 := f[1] - f2 := f[2] - f3 := f[3] - f4 := f[4] - f5 := f[5] - f6 := f[6] - f7 := f[7] - f8 := f[8] - f9 := f[9] - f0_2 := 2 * f0 - f1_2 := 2 * f1 - f2_2 := 2 * f2 - f3_2 := 2 * f3 - f4_2 := 2 * f4 - f5_2 := 2 * f5 - f6_2 := 2 * f6 - f7_2 := 2 * f7 - f5_38 := 38 * f5 // 1.31*2^30 - f6_19 := 19 * f6 // 1.31*2^30 - f7_38 := 38 * f7 // 1.31*2^30 - f8_19 := 19 * f8 // 1.31*2^30 - f9_38 := 38 * f9 // 1.31*2^30 - f0f0 := int64(f0) * int64(f0) - f0f1_2 := int64(f0_2) * int64(f1) - f0f2_2 := int64(f0_2) * int64(f2) - f0f3_2 := int64(f0_2) * int64(f3) - f0f4_2 := int64(f0_2) * int64(f4) - f0f5_2 := int64(f0_2) * int64(f5) - f0f6_2 := int64(f0_2) * int64(f6) - f0f7_2 := int64(f0_2) * int64(f7) - f0f8_2 := int64(f0_2) * int64(f8) - f0f9_2 := int64(f0_2) * int64(f9) - f1f1_2 := int64(f1_2) * int64(f1) - f1f2_2 := int64(f1_2) * int64(f2) - f1f3_4 := int64(f1_2) * int64(f3_2) - f1f4_2 := int64(f1_2) * int64(f4) - f1f5_4 := int64(f1_2) * int64(f5_2) - f1f6_2 := int64(f1_2) * int64(f6) - f1f7_4 := int64(f1_2) * int64(f7_2) - f1f8_2 := int64(f1_2) * int64(f8) - f1f9_76 := int64(f1_2) * int64(f9_38) - f2f2 := int64(f2) * int64(f2) - f2f3_2 := int64(f2_2) * int64(f3) - f2f4_2 := int64(f2_2) * int64(f4) - f2f5_2 := int64(f2_2) * int64(f5) - f2f6_2 := int64(f2_2) * int64(f6) - f2f7_2 := int64(f2_2) * int64(f7) - f2f8_38 := int64(f2_2) * int64(f8_19) - f2f9_38 := int64(f2) * int64(f9_38) - f3f3_2 := int64(f3_2) * int64(f3) - f3f4_2 := int64(f3_2) * int64(f4) - f3f5_4 := int64(f3_2) * int64(f5_2) - f3f6_2 := int64(f3_2) * int64(f6) - f3f7_76 := int64(f3_2) * int64(f7_38) - f3f8_38 := int64(f3_2) * int64(f8_19) - f3f9_76 := int64(f3_2) * int64(f9_38) - f4f4 := int64(f4) * int64(f4) - f4f5_2 := int64(f4_2) * int64(f5) - f4f6_38 := int64(f4_2) * int64(f6_19) - f4f7_38 := int64(f4) * int64(f7_38) - f4f8_38 := int64(f4_2) * int64(f8_19) - f4f9_38 := int64(f4) * int64(f9_38) - f5f5_38 := int64(f5) * int64(f5_38) - f5f6_38 := int64(f5_2) * int64(f6_19) - f5f7_76 := int64(f5_2) * int64(f7_38) - f5f8_38 := int64(f5_2) * int64(f8_19) - f5f9_76 := int64(f5_2) * int64(f9_38) - f6f6_19 := int64(f6) * int64(f6_19) - f6f7_38 := int64(f6) * int64(f7_38) - f6f8_38 := int64(f6_2) * int64(f8_19) - f6f9_38 := int64(f6) * int64(f9_38) - f7f7_38 := int64(f7) * int64(f7_38) - f7f8_38 := int64(f7_2) * int64(f8_19) - f7f9_76 := int64(f7_2) * int64(f9_38) - f8f8_19 := int64(f8) * int64(f8_19) - f8f9_38 := int64(f8) * int64(f9_38) - f9f9_38 := int64(f9) * int64(f9_38) - h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38 - h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38 - h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19 - h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38 - h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38 - h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38 - h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19 - h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38 - h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38 - h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2 - var carry [10]int64 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - - carry[1] = (h1 + (1 << 24)) >> 25 - h2 += carry[1] - h1 -= carry[1] << 25 - carry[5] = (h5 + (1 << 24)) >> 25 - h6 += carry[5] - h5 -= carry[5] << 25 - - carry[2] = (h2 + (1 << 25)) >> 26 - h3 += carry[2] - h2 -= carry[2] << 26 - carry[6] = (h6 + (1 << 25)) >> 26 - h7 += carry[6] - h6 -= carry[6] << 26 - - carry[3] = (h3 + (1 << 24)) >> 25 - h4 += carry[3] - h3 -= carry[3] << 25 - carry[7] = (h7 + (1 << 24)) >> 25 - h8 += carry[7] - h7 -= carry[7] << 25 +const ( + // ScalarSize is the size of the scalar input to X25519. + ScalarSize = 32 + // PointSize is the size of the point input to X25519. + PointSize = 32 +) - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - carry[8] = (h8 + (1 << 25)) >> 26 - h9 += carry[8] - h8 -= carry[8] << 26 +// Basepoint is the canonical Curve25519 generator. +var Basepoint []byte - carry[9] = (h9 + (1 << 24)) >> 25 - h0 += carry[9] * 19 - h9 -= carry[9] << 25 +var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 +func init() { Basepoint = basePoint[:] } - h[0] = int32(h0) - h[1] = int32(h1) - h[2] = int32(h2) - h[3] = int32(h3) - h[4] = int32(h4) - h[5] = int32(h5) - h[6] = int32(h6) - h[7] = int32(h7) - h[8] = int32(h8) - h[9] = int32(h9) +func checkBasepoint() { + if subtle.ConstantTimeCompare(Basepoint, []byte{ + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }) != 1 { + panic("curve25519: global Basepoint value was modified") + } } -// feMul121666 calculates h = f * 121666. Can overlap h with f. +// X25519 returns the result of the scalar multiplication (scalar * point), +// according to RFC 7748, Section 5. scalar, point and the return value are +// slices of 32 bytes. // -// Preconditions: -// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// scalar can be generated at random, for example with crypto/rand. point should +// be either Basepoint or the output of another X25519 call. // -// Postconditions: -// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -func feMul121666(h, f *fieldElement) { - h0 := int64(f[0]) * 121666 - h1 := int64(f[1]) * 121666 - h2 := int64(f[2]) * 121666 - h3 := int64(f[3]) * 121666 - h4 := int64(f[4]) * 121666 - h5 := int64(f[5]) * 121666 - h6 := int64(f[6]) * 121666 - h7 := int64(f[7]) * 121666 - h8 := int64(f[8]) * 121666 - h9 := int64(f[9]) * 121666 - var carry [10]int64 - - carry[9] = (h9 + (1 << 24)) >> 25 - h0 += carry[9] * 19 - h9 -= carry[9] << 25 - carry[1] = (h1 + (1 << 24)) >> 25 - h2 += carry[1] - h1 -= carry[1] << 25 - carry[3] = (h3 + (1 << 24)) >> 25 - h4 += carry[3] - h3 -= carry[3] << 25 - carry[5] = (h5 + (1 << 24)) >> 25 - h6 += carry[5] - h5 -= carry[5] << 25 - carry[7] = (h7 + (1 << 24)) >> 25 - h8 += carry[7] - h7 -= carry[7] << 25 - - carry[0] = (h0 + (1 << 25)) >> 26 - h1 += carry[0] - h0 -= carry[0] << 26 - carry[2] = (h2 + (1 << 25)) >> 26 - h3 += carry[2] - h2 -= carry[2] << 26 - carry[4] = (h4 + (1 << 25)) >> 26 - h5 += carry[4] - h4 -= carry[4] << 26 - carry[6] = (h6 + (1 << 25)) >> 26 - h7 += carry[6] - h6 -= carry[6] << 26 - carry[8] = (h8 + (1 << 25)) >> 26 - h9 += carry[8] - h8 -= carry[8] << 26 - - h[0] = int32(h0) - h[1] = int32(h1) - h[2] = int32(h2) - h[3] = int32(h3) - h[4] = int32(h4) - h[5] = int32(h5) - h[6] = int32(h6) - h[7] = int32(h7) - h[8] = int32(h8) - h[9] = int32(h9) -} - -// feInvert sets out = z^-1. -func feInvert(out, z *fieldElement) { - var t0, t1, t2, t3 fieldElement - var i int - - feSquare(&t0, z) - for i = 1; i < 1; i++ { - feSquare(&t0, &t0) - } - feSquare(&t1, &t0) - for i = 1; i < 2; i++ { - feSquare(&t1, &t1) - } - feMul(&t1, z, &t1) - feMul(&t0, &t0, &t1) - feSquare(&t2, &t0) - for i = 1; i < 1; i++ { - feSquare(&t2, &t2) - } - feMul(&t1, &t1, &t2) - feSquare(&t2, &t1) - for i = 1; i < 5; i++ { - feSquare(&t2, &t2) - } - feMul(&t1, &t2, &t1) - feSquare(&t2, &t1) - for i = 1; i < 10; i++ { - feSquare(&t2, &t2) - } - feMul(&t2, &t2, &t1) - feSquare(&t3, &t2) - for i = 1; i < 20; i++ { - feSquare(&t3, &t3) - } - feMul(&t2, &t3, &t2) - feSquare(&t2, &t2) - for i = 1; i < 10; i++ { - feSquare(&t2, &t2) - } - feMul(&t1, &t2, &t1) - feSquare(&t2, &t1) - for i = 1; i < 50; i++ { - feSquare(&t2, &t2) - } - feMul(&t2, &t2, &t1) - feSquare(&t3, &t2) - for i = 1; i < 100; i++ { - feSquare(&t3, &t3) - } - feMul(&t2, &t3, &t2) - feSquare(&t2, &t2) - for i = 1; i < 50; i++ { - feSquare(&t2, &t2) - } - feMul(&t1, &t2, &t1) - feSquare(&t1, &t1) - for i = 1; i < 5; i++ { - feSquare(&t1, &t1) - } - feMul(out, &t1, &t0) +// If point is Basepoint (but not if it's a different slice with the same +// contents) a precomputed implementation might be used for performance. +func X25519(scalar, point []byte) ([]byte, error) { + // Outline the body of function, to let the allocation be inlined in the + // caller, and possibly avoid escaping to the heap. + var dst [32]byte + return x25519(&dst, scalar, point) } -func scalarMult(out, in, base *[32]byte) { - var e [32]byte - - copy(e[:], in[:]) - e[0] &= 248 - e[31] &= 127 - e[31] |= 64 - - var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement - feFromBytes(&x1, base) - feOne(&x2) - feCopy(&x3, &x1) - feOne(&z3) - - swap := int32(0) - for pos := 254; pos >= 0; pos-- { - b := e[pos/8] >> uint(pos&7) - b &= 1 - swap ^= int32(b) - feCSwap(&x2, &x3, swap) - feCSwap(&z2, &z3, swap) - swap = int32(b) - - feSub(&tmp0, &x3, &z3) - feSub(&tmp1, &x2, &z2) - feAdd(&x2, &x2, &z2) - feAdd(&z2, &x3, &z3) - feMul(&z3, &tmp0, &x2) - feMul(&z2, &z2, &tmp1) - feSquare(&tmp0, &tmp1) - feSquare(&tmp1, &x2) - feAdd(&x3, &z3, &z2) - feSub(&z2, &z3, &z2) - feMul(&x2, &tmp1, &tmp0) - feSub(&tmp1, &tmp1, &tmp0) - feSquare(&z2, &z2) - feMul121666(&z3, &tmp1) - feSquare(&x3, &x3) - feAdd(&tmp0, &tmp0, &z3) - feMul(&z3, &x1, &z2) - feMul(&z2, &tmp1, &tmp0) - } - - feCSwap(&x2, &x3, swap) - feCSwap(&z2, &z3, swap) - - feInvert(&z2, &z2) - feMul(&x2, &x2, &z2) - feToBytes(out, &x2) +func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { + var in [32]byte + if l := len(scalar); l != 32 { + return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32) + } + if l := len(point); l != 32 { + return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32) + } + copy(in[:], scalar) + if &point[0] == &Basepoint[0] { + checkBasepoint() + ScalarBaseMult(dst, &in) + } else { + var base, zero [32]byte + copy(base[:], point) + ScalarMult(dst, &in, &base) + if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 { + return nil, fmt.Errorf("bad input point: low order point") + } + } + return dst[:], nil } diff --git a/libgo/go/golang.org/x/crypto/curve25519/curve25519_amd64.go b/libgo/go/golang.org/x/crypto/curve25519/curve25519_amd64.go new file mode 100644 index 00000000000..5120b779b9b --- /dev/null +++ b/libgo/go/golang.org/x/crypto/curve25519/curve25519_amd64.go @@ -0,0 +1,240 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64,!gccgo,!appengine,!purego + +package curve25519 + +// These functions are implemented in the .s files. The names of the functions +// in the rest of the file are also taken from the SUPERCOP sources to help +// people following along. + +//go:noescape + +func cswap(inout *[5]uint64, v uint64) + +//go:noescape + +func ladderstep(inout *[5][5]uint64) + +//go:noescape + +func freeze(inout *[5]uint64) + +//go:noescape + +func mul(dest, a, b *[5]uint64) + +//go:noescape + +func square(out, in *[5]uint64) + +// mladder uses a Montgomery ladder to calculate (xr/zr) *= s. +func mladder(xr, zr *[5]uint64, s *[32]byte) { + var work [5][5]uint64 + + work[0] = *xr + setint(&work[1], 1) + setint(&work[2], 0) + work[3] = *xr + setint(&work[4], 1) + + j := uint(6) + var prevbit byte + + for i := 31; i >= 0; i-- { + for j < 8 { + bit := ((*s)[i] >> j) & 1 + swap := bit ^ prevbit + prevbit = bit + cswap(&work[1], uint64(swap)) + ladderstep(&work) + j-- + } + j = 7 + } + + *xr = work[1] + *zr = work[2] +} + +func scalarMult(out, in, base *[32]byte) { + var e [32]byte + copy(e[:], (*in)[:]) + e[0] &= 248 + e[31] &= 127 + e[31] |= 64 + + var t, z [5]uint64 + unpack(&t, base) + mladder(&t, &z, &e) + invert(&z, &z) + mul(&t, &t, &z) + pack(out, &t) +} + +func setint(r *[5]uint64, v uint64) { + r[0] = v + r[1] = 0 + r[2] = 0 + r[3] = 0 + r[4] = 0 +} + +// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian +// order. +func unpack(r *[5]uint64, x *[32]byte) { + r[0] = uint64(x[0]) | + uint64(x[1])<<8 | + uint64(x[2])<<16 | + uint64(x[3])<<24 | + uint64(x[4])<<32 | + uint64(x[5])<<40 | + uint64(x[6]&7)<<48 + + r[1] = uint64(x[6])>>3 | + uint64(x[7])<<5 | + uint64(x[8])<<13 | + uint64(x[9])<<21 | + uint64(x[10])<<29 | + uint64(x[11])<<37 | + uint64(x[12]&63)<<45 + + r[2] = uint64(x[12])>>6 | + uint64(x[13])<<2 | + uint64(x[14])<<10 | + uint64(x[15])<<18 | + uint64(x[16])<<26 | + uint64(x[17])<<34 | + uint64(x[18])<<42 | + uint64(x[19]&1)<<50 + + r[3] = uint64(x[19])>>1 | + uint64(x[20])<<7 | + uint64(x[21])<<15 | + uint64(x[22])<<23 | + uint64(x[23])<<31 | + uint64(x[24])<<39 | + uint64(x[25]&15)<<47 + + r[4] = uint64(x[25])>>4 | + uint64(x[26])<<4 | + uint64(x[27])<<12 | + uint64(x[28])<<20 | + uint64(x[29])<<28 | + uint64(x[30])<<36 | + uint64(x[31]&127)<<44 +} + +// pack sets out = x where out is the usual, little-endian form of the 5, +// 51-bit limbs in x. +func pack(out *[32]byte, x *[5]uint64) { + t := *x + freeze(&t) + + out[0] = byte(t[0]) + out[1] = byte(t[0] >> 8) + out[2] = byte(t[0] >> 16) + out[3] = byte(t[0] >> 24) + out[4] = byte(t[0] >> 32) + out[5] = byte(t[0] >> 40) + out[6] = byte(t[0] >> 48) + + out[6] ^= byte(t[1]<<3) & 0xf8 + out[7] = byte(t[1] >> 5) + out[8] = byte(t[1] >> 13) + out[9] = byte(t[1] >> 21) + out[10] = byte(t[1] >> 29) + out[11] = byte(t[1] >> 37) + out[12] = byte(t[1] >> 45) + + out[12] ^= byte(t[2]<<6) & 0xc0 + out[13] = byte(t[2] >> 2) + out[14] = byte(t[2] >> 10) + out[15] = byte(t[2] >> 18) + out[16] = byte(t[2] >> 26) + out[17] = byte(t[2] >> 34) + out[18] = byte(t[2] >> 42) + out[19] = byte(t[2] >> 50) + + out[19] ^= byte(t[3]<<1) & 0xfe + out[20] = byte(t[3] >> 7) + out[21] = byte(t[3] >> 15) + out[22] = byte(t[3] >> 23) + out[23] = byte(t[3] >> 31) + out[24] = byte(t[3] >> 39) + out[25] = byte(t[3] >> 47) + + out[25] ^= byte(t[4]<<4) & 0xf0 + out[26] = byte(t[4] >> 4) + out[27] = byte(t[4] >> 12) + out[28] = byte(t[4] >> 20) + out[29] = byte(t[4] >> 28) + out[30] = byte(t[4] >> 36) + out[31] = byte(t[4] >> 44) +} + +// invert calculates r = x^-1 mod p using Fermat's little theorem. +func invert(r *[5]uint64, x *[5]uint64) { + var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64 + + square(&z2, x) /* 2 */ + square(&t, &z2) /* 4 */ + square(&t, &t) /* 8 */ + mul(&z9, &t, x) /* 9 */ + mul(&z11, &z9, &z2) /* 11 */ + square(&t, &z11) /* 22 */ + mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */ + + square(&t, &z2_5_0) /* 2^6 - 2^1 */ + for i := 1; i < 5; i++ { /* 2^20 - 2^10 */ + square(&t, &t) + } + mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */ + + square(&t, &z2_10_0) /* 2^11 - 2^1 */ + for i := 1; i < 10; i++ { /* 2^20 - 2^10 */ + square(&t, &t) + } + mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */ + + square(&t, &z2_20_0) /* 2^21 - 2^1 */ + for i := 1; i < 20; i++ { /* 2^40 - 2^20 */ + square(&t, &t) + } + mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */ + + square(&t, &t) /* 2^41 - 2^1 */ + for i := 1; i < 10; i++ { /* 2^50 - 2^10 */ + square(&t, &t) + } + mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */ + + square(&t, &z2_50_0) /* 2^51 - 2^1 */ + for i := 1; i < 50; i++ { /* 2^100 - 2^50 */ + square(&t, &t) + } + mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */ + + square(&t, &z2_100_0) /* 2^101 - 2^1 */ + for i := 1; i < 100; i++ { /* 2^200 - 2^100 */ + square(&t, &t) + } + mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */ + + square(&t, &t) /* 2^201 - 2^1 */ + for i := 1; i < 50; i++ { /* 2^250 - 2^50 */ + square(&t, &t) + } + mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */ + + square(&t, &t) /* 2^251 - 2^1 */ + square(&t, &t) /* 2^252 - 2^2 */ + square(&t, &t) /* 2^253 - 2^3 */ + + square(&t, &t) /* 2^254 - 2^4 */ + + square(&t, &t) /* 2^255 - 2^5 */ + mul(r, &t, &z11) /* 2^255 - 21 */ +} diff --git a/libgo/go/golang.org/x/crypto/curve25519/curve25519_generic.go b/libgo/go/golang.org/x/crypto/curve25519/curve25519_generic.go new file mode 100644 index 00000000000..c43b13fc83e --- /dev/null +++ b/libgo/go/golang.org/x/crypto/curve25519/curve25519_generic.go @@ -0,0 +1,828 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package curve25519 + +import "encoding/binary" + +// This code is a port of the public domain, "ref10" implementation of +// curve25519 from SUPERCOP 20130419 by D. J. Bernstein. + +// fieldElement represents an element of the field GF(2^255 - 19). An element +// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 +// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on +// context. +type fieldElement [10]int32 + +func feZero(fe *fieldElement) { + for i := range fe { + fe[i] = 0 + } +} + +func feOne(fe *fieldElement) { + feZero(fe) + fe[0] = 1 +} + +func feAdd(dst, a, b *fieldElement) { + for i := range dst { + dst[i] = a[i] + b[i] + } +} + +func feSub(dst, a, b *fieldElement) { + for i := range dst { + dst[i] = a[i] - b[i] + } +} + +func feCopy(dst, src *fieldElement) { + for i := range dst { + dst[i] = src[i] + } +} + +// feCSwap replaces (f,g) with (g,f) if b == 1; replaces (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +func feCSwap(f, g *fieldElement, b int32) { + b = -b + for i := range f { + t := b & (f[i] ^ g[i]) + f[i] ^= t + g[i] ^= t + } +} + +// load3 reads a 24-bit, little-endian value from in. +func load3(in []byte) int64 { + var r int64 + r = int64(in[0]) + r |= int64(in[1]) << 8 + r |= int64(in[2]) << 16 + return r +} + +// load4 reads a 32-bit, little-endian value from in. +func load4(in []byte) int64 { + return int64(binary.LittleEndian.Uint32(in)) +} + +func feFromBytes(dst *fieldElement, src *[32]byte) { + h0 := load4(src[:]) + h1 := load3(src[4:]) << 6 + h2 := load3(src[7:]) << 5 + h3 := load3(src[10:]) << 3 + h4 := load3(src[13:]) << 2 + h5 := load4(src[16:]) + h6 := load3(src[20:]) << 7 + h7 := load3(src[23:]) << 5 + h8 := load3(src[26:]) << 4 + h9 := (load3(src[29:]) & 0x7fffff) << 2 + + var carry [10]int64 + carry[9] = (h9 + 1<<24) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + carry[1] = (h1 + 1<<24) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[3] = (h3 + 1<<24) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[5] = (h5 + 1<<24) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + carry[7] = (h7 + 1<<24) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[0] = (h0 + 1<<25) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[2] = (h2 + 1<<25) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[4] = (h4 + 1<<25) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[6] = (h6 + 1<<25) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + carry[8] = (h8 + 1<<25) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + dst[0] = int32(h0) + dst[1] = int32(h1) + dst[2] = int32(h2) + dst[3] = int32(h3) + dst[4] = int32(h4) + dst[5] = int32(h5) + dst[6] = int32(h6) + dst[7] = int32(h7) + dst[8] = int32(h8) + dst[9] = int32(h9) +} + +// feToBytes marshals h to s. +// Preconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Write p=2^255-19; q=floor(h/p). +// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). +// +// Proof: +// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. +// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4. +// +// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). +// Then 0> 25 + q = (h[0] + q) >> 26 + q = (h[1] + q) >> 25 + q = (h[2] + q) >> 26 + q = (h[3] + q) >> 25 + q = (h[4] + q) >> 26 + q = (h[5] + q) >> 25 + q = (h[6] + q) >> 26 + q = (h[7] + q) >> 25 + q = (h[8] + q) >> 26 + q = (h[9] + q) >> 25 + + // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. + h[0] += 19 * q + // Goal: Output h-2^255 q, which is between 0 and 2^255-20. + + carry[0] = h[0] >> 26 + h[1] += carry[0] + h[0] -= carry[0] << 26 + carry[1] = h[1] >> 25 + h[2] += carry[1] + h[1] -= carry[1] << 25 + carry[2] = h[2] >> 26 + h[3] += carry[2] + h[2] -= carry[2] << 26 + carry[3] = h[3] >> 25 + h[4] += carry[3] + h[3] -= carry[3] << 25 + carry[4] = h[4] >> 26 + h[5] += carry[4] + h[4] -= carry[4] << 26 + carry[5] = h[5] >> 25 + h[6] += carry[5] + h[5] -= carry[5] << 25 + carry[6] = h[6] >> 26 + h[7] += carry[6] + h[6] -= carry[6] << 26 + carry[7] = h[7] >> 25 + h[8] += carry[7] + h[7] -= carry[7] << 25 + carry[8] = h[8] >> 26 + h[9] += carry[8] + h[8] -= carry[8] << 26 + carry[9] = h[9] >> 25 + h[9] -= carry[9] << 25 + // h10 = carry9 + + // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + // Have h[0]+...+2^230 h[9] between 0 and 2^255-1; + // evidently 2^255 h10-2^255 q = 0. + // Goal: Output h[0]+...+2^230 h[9]. + + s[0] = byte(h[0] >> 0) + s[1] = byte(h[0] >> 8) + s[2] = byte(h[0] >> 16) + s[3] = byte((h[0] >> 24) | (h[1] << 2)) + s[4] = byte(h[1] >> 6) + s[5] = byte(h[1] >> 14) + s[6] = byte((h[1] >> 22) | (h[2] << 3)) + s[7] = byte(h[2] >> 5) + s[8] = byte(h[2] >> 13) + s[9] = byte((h[2] >> 21) | (h[3] << 5)) + s[10] = byte(h[3] >> 3) + s[11] = byte(h[3] >> 11) + s[12] = byte((h[3] >> 19) | (h[4] << 6)) + s[13] = byte(h[4] >> 2) + s[14] = byte(h[4] >> 10) + s[15] = byte(h[4] >> 18) + s[16] = byte(h[5] >> 0) + s[17] = byte(h[5] >> 8) + s[18] = byte(h[5] >> 16) + s[19] = byte((h[5] >> 24) | (h[6] << 1)) + s[20] = byte(h[6] >> 7) + s[21] = byte(h[6] >> 15) + s[22] = byte((h[6] >> 23) | (h[7] << 3)) + s[23] = byte(h[7] >> 5) + s[24] = byte(h[7] >> 13) + s[25] = byte((h[7] >> 21) | (h[8] << 4)) + s[26] = byte(h[8] >> 4) + s[27] = byte(h[8] >> 12) + s[28] = byte((h[8] >> 20) | (h[9] << 6)) + s[29] = byte(h[9] >> 2) + s[30] = byte(h[9] >> 10) + s[31] = byte(h[9] >> 18) +} + +// feMul calculates h = f * g +// Can overlap h with f or g. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Notes on implementation strategy: +// +// Using schoolbook multiplication. +// Karatsuba would save a little in some cost models. +// +// Most multiplications by 2 and 19 are 32-bit precomputations; +// cheaper than 64-bit postcomputations. +// +// There is one remaining multiplication by 19 in the carry chain; +// one *19 precomputation can be merged into this, +// but the resulting data flow is considerably less clean. +// +// There are 12 carries below. +// 10 of them are 2-way parallelizable and vectorizable. +// Can get away with 11 carries, but then data flow is much deeper. +// +// With tighter constraints on inputs can squeeze carries into int32. +func feMul(h, f, g *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + g0 := g[0] + g1 := g[1] + g2 := g[2] + g3 := g[3] + g4 := g[4] + g5 := g[5] + g6 := g[6] + g7 := g[7] + g8 := g[8] + g9 := g[9] + g1_19 := 19 * g1 // 1.4*2^29 + g2_19 := 19 * g2 // 1.4*2^30; still ok + g3_19 := 19 * g3 + g4_19 := 19 * g4 + g5_19 := 19 * g5 + g6_19 := 19 * g6 + g7_19 := 19 * g7 + g8_19 := 19 * g8 + g9_19 := 19 * g9 + f1_2 := 2 * f1 + f3_2 := 2 * f3 + f5_2 := 2 * f5 + f7_2 := 2 * f7 + f9_2 := 2 * f9 + f0g0 := int64(f0) * int64(g0) + f0g1 := int64(f0) * int64(g1) + f0g2 := int64(f0) * int64(g2) + f0g3 := int64(f0) * int64(g3) + f0g4 := int64(f0) * int64(g4) + f0g5 := int64(f0) * int64(g5) + f0g6 := int64(f0) * int64(g6) + f0g7 := int64(f0) * int64(g7) + f0g8 := int64(f0) * int64(g8) + f0g9 := int64(f0) * int64(g9) + f1g0 := int64(f1) * int64(g0) + f1g1_2 := int64(f1_2) * int64(g1) + f1g2 := int64(f1) * int64(g2) + f1g3_2 := int64(f1_2) * int64(g3) + f1g4 := int64(f1) * int64(g4) + f1g5_2 := int64(f1_2) * int64(g5) + f1g6 := int64(f1) * int64(g6) + f1g7_2 := int64(f1_2) * int64(g7) + f1g8 := int64(f1) * int64(g8) + f1g9_38 := int64(f1_2) * int64(g9_19) + f2g0 := int64(f2) * int64(g0) + f2g1 := int64(f2) * int64(g1) + f2g2 := int64(f2) * int64(g2) + f2g3 := int64(f2) * int64(g3) + f2g4 := int64(f2) * int64(g4) + f2g5 := int64(f2) * int64(g5) + f2g6 := int64(f2) * int64(g6) + f2g7 := int64(f2) * int64(g7) + f2g8_19 := int64(f2) * int64(g8_19) + f2g9_19 := int64(f2) * int64(g9_19) + f3g0 := int64(f3) * int64(g0) + f3g1_2 := int64(f3_2) * int64(g1) + f3g2 := int64(f3) * int64(g2) + f3g3_2 := int64(f3_2) * int64(g3) + f3g4 := int64(f3) * int64(g4) + f3g5_2 := int64(f3_2) * int64(g5) + f3g6 := int64(f3) * int64(g6) + f3g7_38 := int64(f3_2) * int64(g7_19) + f3g8_19 := int64(f3) * int64(g8_19) + f3g9_38 := int64(f3_2) * int64(g9_19) + f4g0 := int64(f4) * int64(g0) + f4g1 := int64(f4) * int64(g1) + f4g2 := int64(f4) * int64(g2) + f4g3 := int64(f4) * int64(g3) + f4g4 := int64(f4) * int64(g4) + f4g5 := int64(f4) * int64(g5) + f4g6_19 := int64(f4) * int64(g6_19) + f4g7_19 := int64(f4) * int64(g7_19) + f4g8_19 := int64(f4) * int64(g8_19) + f4g9_19 := int64(f4) * int64(g9_19) + f5g0 := int64(f5) * int64(g0) + f5g1_2 := int64(f5_2) * int64(g1) + f5g2 := int64(f5) * int64(g2) + f5g3_2 := int64(f5_2) * int64(g3) + f5g4 := int64(f5) * int64(g4) + f5g5_38 := int64(f5_2) * int64(g5_19) + f5g6_19 := int64(f5) * int64(g6_19) + f5g7_38 := int64(f5_2) * int64(g7_19) + f5g8_19 := int64(f5) * int64(g8_19) + f5g9_38 := int64(f5_2) * int64(g9_19) + f6g0 := int64(f6) * int64(g0) + f6g1 := int64(f6) * int64(g1) + f6g2 := int64(f6) * int64(g2) + f6g3 := int64(f6) * int64(g3) + f6g4_19 := int64(f6) * int64(g4_19) + f6g5_19 := int64(f6) * int64(g5_19) + f6g6_19 := int64(f6) * int64(g6_19) + f6g7_19 := int64(f6) * int64(g7_19) + f6g8_19 := int64(f6) * int64(g8_19) + f6g9_19 := int64(f6) * int64(g9_19) + f7g0 := int64(f7) * int64(g0) + f7g1_2 := int64(f7_2) * int64(g1) + f7g2 := int64(f7) * int64(g2) + f7g3_38 := int64(f7_2) * int64(g3_19) + f7g4_19 := int64(f7) * int64(g4_19) + f7g5_38 := int64(f7_2) * int64(g5_19) + f7g6_19 := int64(f7) * int64(g6_19) + f7g7_38 := int64(f7_2) * int64(g7_19) + f7g8_19 := int64(f7) * int64(g8_19) + f7g9_38 := int64(f7_2) * int64(g9_19) + f8g0 := int64(f8) * int64(g0) + f8g1 := int64(f8) * int64(g1) + f8g2_19 := int64(f8) * int64(g2_19) + f8g3_19 := int64(f8) * int64(g3_19) + f8g4_19 := int64(f8) * int64(g4_19) + f8g5_19 := int64(f8) * int64(g5_19) + f8g6_19 := int64(f8) * int64(g6_19) + f8g7_19 := int64(f8) * int64(g7_19) + f8g8_19 := int64(f8) * int64(g8_19) + f8g9_19 := int64(f8) * int64(g9_19) + f9g0 := int64(f9) * int64(g0) + f9g1_38 := int64(f9_2) * int64(g1_19) + f9g2_19 := int64(f9) * int64(g2_19) + f9g3_38 := int64(f9_2) * int64(g3_19) + f9g4_19 := int64(f9) * int64(g4_19) + f9g5_38 := int64(f9_2) * int64(g5_19) + f9g6_19 := int64(f9) * int64(g6_19) + f9g7_38 := int64(f9_2) * int64(g7_19) + f9g8_19 := int64(f9) * int64(g8_19) + f9g9_38 := int64(f9_2) * int64(g9_19) + h0 := f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38 + h1 := f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19 + h2 := f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38 + h3 := f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19 + h4 := f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38 + h5 := f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19 + h6 := f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38 + h7 := f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19 + h8 := f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38 + h9 := f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0 + var carry [10]int64 + + // |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38)) + // i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8 + // |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19)) + // i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + // |h0| <= 2^25 + // |h4| <= 2^25 + // |h1| <= 1.51*2^58 + // |h5| <= 1.51*2^58 + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + // |h1| <= 2^24; from now on fits into int32 + // |h5| <= 2^24; from now on fits into int32 + // |h2| <= 1.21*2^59 + // |h6| <= 1.21*2^59 + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + // |h2| <= 2^25; from now on fits into int32 unchanged + // |h6| <= 2^25; from now on fits into int32 unchanged + // |h3| <= 1.51*2^58 + // |h7| <= 1.51*2^58 + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + // |h3| <= 2^24; from now on fits into int32 unchanged + // |h7| <= 2^24; from now on fits into int32 unchanged + // |h4| <= 1.52*2^33 + // |h8| <= 1.52*2^33 + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + // |h4| <= 2^25; from now on fits into int32 unchanged + // |h8| <= 2^25; from now on fits into int32 unchanged + // |h5| <= 1.01*2^24 + // |h9| <= 1.51*2^58 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + // |h9| <= 2^24; from now on fits into int32 unchanged + // |h0| <= 1.8*2^37 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + // |h0| <= 2^25; from now on fits into int32 unchanged + // |h1| <= 1.01*2^24 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feSquare calculates h = f*f. Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func feSquare(h, f *fieldElement) { + f0 := f[0] + f1 := f[1] + f2 := f[2] + f3 := f[3] + f4 := f[4] + f5 := f[5] + f6 := f[6] + f7 := f[7] + f8 := f[8] + f9 := f[9] + f0_2 := 2 * f0 + f1_2 := 2 * f1 + f2_2 := 2 * f2 + f3_2 := 2 * f3 + f4_2 := 2 * f4 + f5_2 := 2 * f5 + f6_2 := 2 * f6 + f7_2 := 2 * f7 + f5_38 := 38 * f5 // 1.31*2^30 + f6_19 := 19 * f6 // 1.31*2^30 + f7_38 := 38 * f7 // 1.31*2^30 + f8_19 := 19 * f8 // 1.31*2^30 + f9_38 := 38 * f9 // 1.31*2^30 + f0f0 := int64(f0) * int64(f0) + f0f1_2 := int64(f0_2) * int64(f1) + f0f2_2 := int64(f0_2) * int64(f2) + f0f3_2 := int64(f0_2) * int64(f3) + f0f4_2 := int64(f0_2) * int64(f4) + f0f5_2 := int64(f0_2) * int64(f5) + f0f6_2 := int64(f0_2) * int64(f6) + f0f7_2 := int64(f0_2) * int64(f7) + f0f8_2 := int64(f0_2) * int64(f8) + f0f9_2 := int64(f0_2) * int64(f9) + f1f1_2 := int64(f1_2) * int64(f1) + f1f2_2 := int64(f1_2) * int64(f2) + f1f3_4 := int64(f1_2) * int64(f3_2) + f1f4_2 := int64(f1_2) * int64(f4) + f1f5_4 := int64(f1_2) * int64(f5_2) + f1f6_2 := int64(f1_2) * int64(f6) + f1f7_4 := int64(f1_2) * int64(f7_2) + f1f8_2 := int64(f1_2) * int64(f8) + f1f9_76 := int64(f1_2) * int64(f9_38) + f2f2 := int64(f2) * int64(f2) + f2f3_2 := int64(f2_2) * int64(f3) + f2f4_2 := int64(f2_2) * int64(f4) + f2f5_2 := int64(f2_2) * int64(f5) + f2f6_2 := int64(f2_2) * int64(f6) + f2f7_2 := int64(f2_2) * int64(f7) + f2f8_38 := int64(f2_2) * int64(f8_19) + f2f9_38 := int64(f2) * int64(f9_38) + f3f3_2 := int64(f3_2) * int64(f3) + f3f4_2 := int64(f3_2) * int64(f4) + f3f5_4 := int64(f3_2) * int64(f5_2) + f3f6_2 := int64(f3_2) * int64(f6) + f3f7_76 := int64(f3_2) * int64(f7_38) + f3f8_38 := int64(f3_2) * int64(f8_19) + f3f9_76 := int64(f3_2) * int64(f9_38) + f4f4 := int64(f4) * int64(f4) + f4f5_2 := int64(f4_2) * int64(f5) + f4f6_38 := int64(f4_2) * int64(f6_19) + f4f7_38 := int64(f4) * int64(f7_38) + f4f8_38 := int64(f4_2) * int64(f8_19) + f4f9_38 := int64(f4) * int64(f9_38) + f5f5_38 := int64(f5) * int64(f5_38) + f5f6_38 := int64(f5_2) * int64(f6_19) + f5f7_76 := int64(f5_2) * int64(f7_38) + f5f8_38 := int64(f5_2) * int64(f8_19) + f5f9_76 := int64(f5_2) * int64(f9_38) + f6f6_19 := int64(f6) * int64(f6_19) + f6f7_38 := int64(f6) * int64(f7_38) + f6f8_38 := int64(f6_2) * int64(f8_19) + f6f9_38 := int64(f6) * int64(f9_38) + f7f7_38 := int64(f7) * int64(f7_38) + f7f8_38 := int64(f7_2) * int64(f8_19) + f7f9_76 := int64(f7_2) * int64(f9_38) + f8f8_19 := int64(f8) * int64(f8_19) + f8f9_38 := int64(f8) * int64(f9_38) + f9f9_38 := int64(f9) * int64(f9_38) + h0 := f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38 + h1 := f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38 + h2 := f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19 + h3 := f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38 + h4 := f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38 + h5 := f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38 + h6 := f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19 + h7 := f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38 + h8 := f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38 + h9 := f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2 + var carry [10]int64 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feMul121666 calculates h = f * 121666. Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func feMul121666(h, f *fieldElement) { + h0 := int64(f[0]) * 121666 + h1 := int64(f[1]) * 121666 + h2 := int64(f[2]) * 121666 + h3 := int64(f[3]) * 121666 + h4 := int64(f[4]) * 121666 + h5 := int64(f[5]) * 121666 + h6 := int64(f[6]) * 121666 + h7 := int64(f[7]) * 121666 + h8 := int64(f[8]) * 121666 + h9 := int64(f[9]) * 121666 + var carry [10]int64 + + carry[9] = (h9 + (1 << 24)) >> 25 + h0 += carry[9] * 19 + h9 -= carry[9] << 25 + carry[1] = (h1 + (1 << 24)) >> 25 + h2 += carry[1] + h1 -= carry[1] << 25 + carry[3] = (h3 + (1 << 24)) >> 25 + h4 += carry[3] + h3 -= carry[3] << 25 + carry[5] = (h5 + (1 << 24)) >> 25 + h6 += carry[5] + h5 -= carry[5] << 25 + carry[7] = (h7 + (1 << 24)) >> 25 + h8 += carry[7] + h7 -= carry[7] << 25 + + carry[0] = (h0 + (1 << 25)) >> 26 + h1 += carry[0] + h0 -= carry[0] << 26 + carry[2] = (h2 + (1 << 25)) >> 26 + h3 += carry[2] + h2 -= carry[2] << 26 + carry[4] = (h4 + (1 << 25)) >> 26 + h5 += carry[4] + h4 -= carry[4] << 26 + carry[6] = (h6 + (1 << 25)) >> 26 + h7 += carry[6] + h6 -= carry[6] << 26 + carry[8] = (h8 + (1 << 25)) >> 26 + h9 += carry[8] + h8 -= carry[8] << 26 + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// feInvert sets out = z^-1. +func feInvert(out, z *fieldElement) { + var t0, t1, t2, t3 fieldElement + var i int + + feSquare(&t0, z) + for i = 1; i < 1; i++ { + feSquare(&t0, &t0) + } + feSquare(&t1, &t0) + for i = 1; i < 2; i++ { + feSquare(&t1, &t1) + } + feMul(&t1, z, &t1) + feMul(&t0, &t0, &t1) + feSquare(&t2, &t0) + for i = 1; i < 1; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t1, &t2) + feSquare(&t2, &t1) + for i = 1; i < 5; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t2, &t1) + for i = 1; i < 10; i++ { + feSquare(&t2, &t2) + } + feMul(&t2, &t2, &t1) + feSquare(&t3, &t2) + for i = 1; i < 20; i++ { + feSquare(&t3, &t3) + } + feMul(&t2, &t3, &t2) + feSquare(&t2, &t2) + for i = 1; i < 10; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t2, &t1) + for i = 1; i < 50; i++ { + feSquare(&t2, &t2) + } + feMul(&t2, &t2, &t1) + feSquare(&t3, &t2) + for i = 1; i < 100; i++ { + feSquare(&t3, &t3) + } + feMul(&t2, &t3, &t2) + feSquare(&t2, &t2) + for i = 1; i < 50; i++ { + feSquare(&t2, &t2) + } + feMul(&t1, &t2, &t1) + feSquare(&t1, &t1) + for i = 1; i < 5; i++ { + feSquare(&t1, &t1) + } + feMul(out, &t1, &t0) +} + +func scalarMultGeneric(out, in, base *[32]byte) { + var e [32]byte + + copy(e[:], in[:]) + e[0] &= 248 + e[31] &= 127 + e[31] |= 64 + + var x1, x2, z2, x3, z3, tmp0, tmp1 fieldElement + feFromBytes(&x1, base) + feOne(&x2) + feCopy(&x3, &x1) + feOne(&z3) + + swap := int32(0) + for pos := 254; pos >= 0; pos-- { + b := e[pos/8] >> uint(pos&7) + b &= 1 + swap ^= int32(b) + feCSwap(&x2, &x3, swap) + feCSwap(&z2, &z3, swap) + swap = int32(b) + + feSub(&tmp0, &x3, &z3) + feSub(&tmp1, &x2, &z2) + feAdd(&x2, &x2, &z2) + feAdd(&z2, &x3, &z3) + feMul(&z3, &tmp0, &x2) + feMul(&z2, &z2, &tmp1) + feSquare(&tmp0, &tmp1) + feSquare(&tmp1, &x2) + feAdd(&x3, &z3, &z2) + feSub(&z2, &z3, &z2) + feMul(&x2, &tmp1, &tmp0) + feSub(&tmp1, &tmp1, &tmp0) + feSquare(&z2, &z2) + feMul121666(&z3, &tmp1) + feSquare(&x3, &x3) + feAdd(&tmp0, &tmp0, &z3) + feMul(&z3, &x1, &z2) + feMul(&z2, &tmp1, &tmp0) + } + + feCSwap(&x2, &x3, swap) + feCSwap(&z2, &z3, swap) + + feInvert(&z2, &z2) + feMul(&x2, &x2, &z2) + feToBytes(out, &x2) +} diff --git a/libgo/go/golang.org/x/crypto/curve25519/curve25519_noasm.go b/libgo/go/golang.org/x/crypto/curve25519/curve25519_noasm.go new file mode 100644 index 00000000000..047d49afc27 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/curve25519/curve25519_noasm.go @@ -0,0 +1,11 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !amd64 gccgo appengine purego + +package curve25519 + +func scalarMult(out, in, base *[32]byte) { + scalarMultGeneric(out, in, base) +} diff --git a/libgo/go/golang.org/x/crypto/curve25519/doc.go b/libgo/go/golang.org/x/crypto/curve25519/doc.go deleted file mode 100644 index da9b10d9c1f..00000000000 --- a/libgo/go/golang.org/x/crypto/curve25519/doc.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package curve25519 provides an implementation of scalar multiplication on -// the elliptic curve known as curve25519. See https://cr.yp.to/ecdh.html -package curve25519 // import "golang.org/x/crypto/curve25519" - -// basePoint is the x coordinate of the generator of the curve. -var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - -// ScalarMult sets dst to the product in*base where dst and base are the x -// coordinates of group points and all values are in little-endian form. -func ScalarMult(dst, in, base *[32]byte) { - scalarMult(dst, in, base) -} - -// ScalarBaseMult sets dst to the product in*base where dst and base are the x -// coordinates of group points, base is the standard generator and all values -// are in little-endian form. -func ScalarBaseMult(dst, in *[32]byte) { - ScalarMult(dst, in, &basePoint) -} diff --git a/libgo/go/golang.org/x/crypto/curve25519/mont25519_amd64.go b/libgo/go/golang.org/x/crypto/curve25519/mont25519_amd64.go deleted file mode 100644 index 5822bd53383..00000000000 --- a/libgo/go/golang.org/x/crypto/curve25519/mont25519_amd64.go +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build amd64,!gccgo,!appengine - -package curve25519 - -// These functions are implemented in the .s files. The names of the functions -// in the rest of the file are also taken from the SUPERCOP sources to help -// people following along. - -//go:noescape - -func cswap(inout *[5]uint64, v uint64) - -//go:noescape - -func ladderstep(inout *[5][5]uint64) - -//go:noescape - -func freeze(inout *[5]uint64) - -//go:noescape - -func mul(dest, a, b *[5]uint64) - -//go:noescape - -func square(out, in *[5]uint64) - -// mladder uses a Montgomery ladder to calculate (xr/zr) *= s. -func mladder(xr, zr *[5]uint64, s *[32]byte) { - var work [5][5]uint64 - - work[0] = *xr - setint(&work[1], 1) - setint(&work[2], 0) - work[3] = *xr - setint(&work[4], 1) - - j := uint(6) - var prevbit byte - - for i := 31; i >= 0; i-- { - for j < 8 { - bit := ((*s)[i] >> j) & 1 - swap := bit ^ prevbit - prevbit = bit - cswap(&work[1], uint64(swap)) - ladderstep(&work) - j-- - } - j = 7 - } - - *xr = work[1] - *zr = work[2] -} - -func scalarMult(out, in, base *[32]byte) { - var e [32]byte - copy(e[:], (*in)[:]) - e[0] &= 248 - e[31] &= 127 - e[31] |= 64 - - var t, z [5]uint64 - unpack(&t, base) - mladder(&t, &z, &e) - invert(&z, &z) - mul(&t, &t, &z) - pack(out, &t) -} - -func setint(r *[5]uint64, v uint64) { - r[0] = v - r[1] = 0 - r[2] = 0 - r[3] = 0 - r[4] = 0 -} - -// unpack sets r = x where r consists of 5, 51-bit limbs in little-endian -// order. -func unpack(r *[5]uint64, x *[32]byte) { - r[0] = uint64(x[0]) | - uint64(x[1])<<8 | - uint64(x[2])<<16 | - uint64(x[3])<<24 | - uint64(x[4])<<32 | - uint64(x[5])<<40 | - uint64(x[6]&7)<<48 - - r[1] = uint64(x[6])>>3 | - uint64(x[7])<<5 | - uint64(x[8])<<13 | - uint64(x[9])<<21 | - uint64(x[10])<<29 | - uint64(x[11])<<37 | - uint64(x[12]&63)<<45 - - r[2] = uint64(x[12])>>6 | - uint64(x[13])<<2 | - uint64(x[14])<<10 | - uint64(x[15])<<18 | - uint64(x[16])<<26 | - uint64(x[17])<<34 | - uint64(x[18])<<42 | - uint64(x[19]&1)<<50 - - r[3] = uint64(x[19])>>1 | - uint64(x[20])<<7 | - uint64(x[21])<<15 | - uint64(x[22])<<23 | - uint64(x[23])<<31 | - uint64(x[24])<<39 | - uint64(x[25]&15)<<47 - - r[4] = uint64(x[25])>>4 | - uint64(x[26])<<4 | - uint64(x[27])<<12 | - uint64(x[28])<<20 | - uint64(x[29])<<28 | - uint64(x[30])<<36 | - uint64(x[31]&127)<<44 -} - -// pack sets out = x where out is the usual, little-endian form of the 5, -// 51-bit limbs in x. -func pack(out *[32]byte, x *[5]uint64) { - t := *x - freeze(&t) - - out[0] = byte(t[0]) - out[1] = byte(t[0] >> 8) - out[2] = byte(t[0] >> 16) - out[3] = byte(t[0] >> 24) - out[4] = byte(t[0] >> 32) - out[5] = byte(t[0] >> 40) - out[6] = byte(t[0] >> 48) - - out[6] ^= byte(t[1]<<3) & 0xf8 - out[7] = byte(t[1] >> 5) - out[8] = byte(t[1] >> 13) - out[9] = byte(t[1] >> 21) - out[10] = byte(t[1] >> 29) - out[11] = byte(t[1] >> 37) - out[12] = byte(t[1] >> 45) - - out[12] ^= byte(t[2]<<6) & 0xc0 - out[13] = byte(t[2] >> 2) - out[14] = byte(t[2] >> 10) - out[15] = byte(t[2] >> 18) - out[16] = byte(t[2] >> 26) - out[17] = byte(t[2] >> 34) - out[18] = byte(t[2] >> 42) - out[19] = byte(t[2] >> 50) - - out[19] ^= byte(t[3]<<1) & 0xfe - out[20] = byte(t[3] >> 7) - out[21] = byte(t[3] >> 15) - out[22] = byte(t[3] >> 23) - out[23] = byte(t[3] >> 31) - out[24] = byte(t[3] >> 39) - out[25] = byte(t[3] >> 47) - - out[25] ^= byte(t[4]<<4) & 0xf0 - out[26] = byte(t[4] >> 4) - out[27] = byte(t[4] >> 12) - out[28] = byte(t[4] >> 20) - out[29] = byte(t[4] >> 28) - out[30] = byte(t[4] >> 36) - out[31] = byte(t[4] >> 44) -} - -// invert calculates r = x^-1 mod p using Fermat's little theorem. -func invert(r *[5]uint64, x *[5]uint64) { - var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t [5]uint64 - - square(&z2, x) /* 2 */ - square(&t, &z2) /* 4 */ - square(&t, &t) /* 8 */ - mul(&z9, &t, x) /* 9 */ - mul(&z11, &z9, &z2) /* 11 */ - square(&t, &z11) /* 22 */ - mul(&z2_5_0, &t, &z9) /* 2^5 - 2^0 = 31 */ - - square(&t, &z2_5_0) /* 2^6 - 2^1 */ - for i := 1; i < 5; i++ { /* 2^20 - 2^10 */ - square(&t, &t) - } - mul(&z2_10_0, &t, &z2_5_0) /* 2^10 - 2^0 */ - - square(&t, &z2_10_0) /* 2^11 - 2^1 */ - for i := 1; i < 10; i++ { /* 2^20 - 2^10 */ - square(&t, &t) - } - mul(&z2_20_0, &t, &z2_10_0) /* 2^20 - 2^0 */ - - square(&t, &z2_20_0) /* 2^21 - 2^1 */ - for i := 1; i < 20; i++ { /* 2^40 - 2^20 */ - square(&t, &t) - } - mul(&t, &t, &z2_20_0) /* 2^40 - 2^0 */ - - square(&t, &t) /* 2^41 - 2^1 */ - for i := 1; i < 10; i++ { /* 2^50 - 2^10 */ - square(&t, &t) - } - mul(&z2_50_0, &t, &z2_10_0) /* 2^50 - 2^0 */ - - square(&t, &z2_50_0) /* 2^51 - 2^1 */ - for i := 1; i < 50; i++ { /* 2^100 - 2^50 */ - square(&t, &t) - } - mul(&z2_100_0, &t, &z2_50_0) /* 2^100 - 2^0 */ - - square(&t, &z2_100_0) /* 2^101 - 2^1 */ - for i := 1; i < 100; i++ { /* 2^200 - 2^100 */ - square(&t, &t) - } - mul(&t, &t, &z2_100_0) /* 2^200 - 2^0 */ - - square(&t, &t) /* 2^201 - 2^1 */ - for i := 1; i < 50; i++ { /* 2^250 - 2^50 */ - square(&t, &t) - } - mul(&t, &t, &z2_50_0) /* 2^250 - 2^0 */ - - square(&t, &t) /* 2^251 - 2^1 */ - square(&t, &t) /* 2^252 - 2^2 */ - square(&t, &t) /* 2^253 - 2^3 */ - - square(&t, &t) /* 2^254 - 2^4 */ - - square(&t, &t) /* 2^255 - 2^5 */ - mul(r, &t, &z11) /* 2^255 - 21 */ -} diff --git a/libgo/go/golang.org/x/crypto/ed25519/ed25519.go b/libgo/go/golang.org/x/crypto/ed25519/ed25519.go new file mode 100644 index 00000000000..c7f8c7e64ec --- /dev/null +++ b/libgo/go/golang.org/x/crypto/ed25519/ed25519.go @@ -0,0 +1,222 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// In Go 1.13, the ed25519 package was promoted to the standard library as +// crypto/ed25519, and this package became a wrapper for the standard library one. +// +// +build !go1.13 + +// Package ed25519 implements the Ed25519 signature algorithm. See +// https://ed25519.cr.yp.to/. +// +// These functions are also compatible with the “Ed25519” function defined in +// RFC 8032. However, unlike RFC 8032's formulation, this package's private key +// representation includes a public key suffix to make multiple signing +// operations with the same key more efficient. This package refers to the RFC +// 8032 private key as the “seed”. +package ed25519 + +// This code is a port of the public domain, “ref10” implementation of ed25519 +// from SUPERCOP. + +import ( + "bytes" + "crypto" + cryptorand "crypto/rand" + "crypto/sha512" + "errors" + "io" + "strconv" + + "golang.org/x/crypto/ed25519/internal/edwards25519" +) + +const ( + // PublicKeySize is the size, in bytes, of public keys as used in this package. + PublicKeySize = 32 + // PrivateKeySize is the size, in bytes, of private keys as used in this package. + PrivateKeySize = 64 + // SignatureSize is the size, in bytes, of signatures generated and verified by this package. + SignatureSize = 64 + // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. + SeedSize = 32 +) + +// PublicKey is the type of Ed25519 public keys. +type PublicKey []byte + +// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. +type PrivateKey []byte + +// Public returns the PublicKey corresponding to priv. +func (priv PrivateKey) Public() crypto.PublicKey { + publicKey := make([]byte, PublicKeySize) + copy(publicKey, priv[32:]) + return PublicKey(publicKey) +} + +// Seed returns the private key seed corresponding to priv. It is provided for +// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds +// in this package. +func (priv PrivateKey) Seed() []byte { + seed := make([]byte, SeedSize) + copy(seed, priv[:32]) + return seed +} + +// Sign signs the given message with priv. +// Ed25519 performs two passes over messages to be signed and therefore cannot +// handle pre-hashed messages. Thus opts.HashFunc() must return zero to +// indicate the message hasn't been hashed. This can be achieved by passing +// crypto.Hash(0) as the value for opts. +func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) { + if opts.HashFunc() != crypto.Hash(0) { + return nil, errors.New("ed25519: cannot sign hashed message") + } + + return Sign(priv, message), nil +} + +// GenerateKey generates a public/private key pair using entropy from rand. +// If rand is nil, crypto/rand.Reader will be used. +func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { + if rand == nil { + rand = cryptorand.Reader + } + + seed := make([]byte, SeedSize) + if _, err := io.ReadFull(rand, seed); err != nil { + return nil, nil, err + } + + privateKey := NewKeyFromSeed(seed) + publicKey := make([]byte, PublicKeySize) + copy(publicKey, privateKey[32:]) + + return publicKey, privateKey, nil +} + +// NewKeyFromSeed calculates a private key from a seed. It will panic if +// len(seed) is not SeedSize. This function is provided for interoperability +// with RFC 8032. RFC 8032's private keys correspond to seeds in this +// package. +func NewKeyFromSeed(seed []byte) PrivateKey { + if l := len(seed); l != SeedSize { + panic("ed25519: bad seed length: " + strconv.Itoa(l)) + } + + digest := sha512.Sum512(seed) + digest[0] &= 248 + digest[31] &= 127 + digest[31] |= 64 + + var A edwards25519.ExtendedGroupElement + var hBytes [32]byte + copy(hBytes[:], digest[:]) + edwards25519.GeScalarMultBase(&A, &hBytes) + var publicKeyBytes [32]byte + A.ToBytes(&publicKeyBytes) + + privateKey := make([]byte, PrivateKeySize) + copy(privateKey, seed) + copy(privateKey[32:], publicKeyBytes[:]) + + return privateKey +} + +// Sign signs the message with privateKey and returns a signature. It will +// panic if len(privateKey) is not PrivateKeySize. +func Sign(privateKey PrivateKey, message []byte) []byte { + if l := len(privateKey); l != PrivateKeySize { + panic("ed25519: bad private key length: " + strconv.Itoa(l)) + } + + h := sha512.New() + h.Write(privateKey[:32]) + + var digest1, messageDigest, hramDigest [64]byte + var expandedSecretKey [32]byte + h.Sum(digest1[:0]) + copy(expandedSecretKey[:], digest1[:]) + expandedSecretKey[0] &= 248 + expandedSecretKey[31] &= 63 + expandedSecretKey[31] |= 64 + + h.Reset() + h.Write(digest1[32:]) + h.Write(message) + h.Sum(messageDigest[:0]) + + var messageDigestReduced [32]byte + edwards25519.ScReduce(&messageDigestReduced, &messageDigest) + var R edwards25519.ExtendedGroupElement + edwards25519.GeScalarMultBase(&R, &messageDigestReduced) + + var encodedR [32]byte + R.ToBytes(&encodedR) + + h.Reset() + h.Write(encodedR[:]) + h.Write(privateKey[32:]) + h.Write(message) + h.Sum(hramDigest[:0]) + var hramDigestReduced [32]byte + edwards25519.ScReduce(&hramDigestReduced, &hramDigest) + + var s [32]byte + edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced) + + signature := make([]byte, SignatureSize) + copy(signature[:], encodedR[:]) + copy(signature[32:], s[:]) + + return signature +} + +// Verify reports whether sig is a valid signature of message by publicKey. It +// will panic if len(publicKey) is not PublicKeySize. +func Verify(publicKey PublicKey, message, sig []byte) bool { + if l := len(publicKey); l != PublicKeySize { + panic("ed25519: bad public key length: " + strconv.Itoa(l)) + } + + if len(sig) != SignatureSize || sig[63]&224 != 0 { + return false + } + + var A edwards25519.ExtendedGroupElement + var publicKeyBytes [32]byte + copy(publicKeyBytes[:], publicKey) + if !A.FromBytes(&publicKeyBytes) { + return false + } + edwards25519.FeNeg(&A.X, &A.X) + edwards25519.FeNeg(&A.T, &A.T) + + h := sha512.New() + h.Write(sig[:32]) + h.Write(publicKey[:]) + h.Write(message) + var digest [64]byte + h.Sum(digest[:0]) + + var hReduced [32]byte + edwards25519.ScReduce(&hReduced, &digest) + + var R edwards25519.ProjectiveGroupElement + var s [32]byte + copy(s[:], sig[32:]) + + // https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in + // the range [0, order) in order to prevent signature malleability. + if !edwards25519.ScMinimal(&s) { + return false + } + + edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &s) + + var checkR [32]byte + R.ToBytes(&checkR) + return bytes.Equal(sig[:32], checkR[:]) +} diff --git a/libgo/go/golang.org/x/crypto/ed25519/ed25519_go113.go b/libgo/go/golang.org/x/crypto/ed25519/ed25519_go113.go new file mode 100644 index 00000000000..d1448d8d220 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/ed25519/ed25519_go113.go @@ -0,0 +1,73 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.13 + +// Package ed25519 implements the Ed25519 signature algorithm. See +// https://ed25519.cr.yp.to/. +// +// These functions are also compatible with the “Ed25519” function defined in +// RFC 8032. However, unlike RFC 8032's formulation, this package's private key +// representation includes a public key suffix to make multiple signing +// operations with the same key more efficient. This package refers to the RFC +// 8032 private key as the “seed”. +// +// Beginning with Go 1.13, the functionality of this package was moved to the +// standard library as crypto/ed25519. This package only acts as a compatibility +// wrapper. +package ed25519 + +import ( + "crypto/ed25519" + "io" +) + +const ( + // PublicKeySize is the size, in bytes, of public keys as used in this package. + PublicKeySize = 32 + // PrivateKeySize is the size, in bytes, of private keys as used in this package. + PrivateKeySize = 64 + // SignatureSize is the size, in bytes, of signatures generated and verified by this package. + SignatureSize = 64 + // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. + SeedSize = 32 +) + +// PublicKey is the type of Ed25519 public keys. +// +// This type is an alias for crypto/ed25519's PublicKey type. +// See the crypto/ed25519 package for the methods on this type. +type PublicKey = ed25519.PublicKey + +// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. +// +// This type is an alias for crypto/ed25519's PrivateKey type. +// See the crypto/ed25519 package for the methods on this type. +type PrivateKey = ed25519.PrivateKey + +// GenerateKey generates a public/private key pair using entropy from rand. +// If rand is nil, crypto/rand.Reader will be used. +func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { + return ed25519.GenerateKey(rand) +} + +// NewKeyFromSeed calculates a private key from a seed. It will panic if +// len(seed) is not SeedSize. This function is provided for interoperability +// with RFC 8032. RFC 8032's private keys correspond to seeds in this +// package. +func NewKeyFromSeed(seed []byte) PrivateKey { + return ed25519.NewKeyFromSeed(seed) +} + +// Sign signs the message with privateKey and returns a signature. It will +// panic if len(privateKey) is not PrivateKeySize. +func Sign(privateKey PrivateKey, message []byte) []byte { + return ed25519.Sign(privateKey, message) +} + +// Verify reports whether sig is a valid signature of message by publicKey. It +// will panic if len(publicKey) is not PublicKeySize. +func Verify(publicKey PublicKey, message, sig []byte) bool { + return ed25519.Verify(publicKey, message, sig) +} diff --git a/libgo/go/golang.org/x/crypto/ed25519/internal/edwards25519/const.go b/libgo/go/golang.org/x/crypto/ed25519/internal/edwards25519/const.go new file mode 100644 index 00000000000..e39f086c1d8 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/ed25519/internal/edwards25519/const.go @@ -0,0 +1,1422 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package edwards25519 + +// These values are from the public domain, “ref10” implementation of ed25519 +// from SUPERCOP. + +// d is a constant in the Edwards curve equation. +var d = FieldElement{ + -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116, +} + +// d2 is 2*d. +var d2 = FieldElement{ + -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199, +} + +// SqrtM1 is the square-root of -1 in the field. +var SqrtM1 = FieldElement{ + -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482, +} + +// A is a constant in the Montgomery-form of curve25519. +var A = FieldElement{ + 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0, +} + +// bi contains precomputed multiples of the base-point. See the Ed25519 paper +// for a discussion about how these values are used. +var bi = [8]PreComputedGroupElement{ + { + FieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, + FieldElement{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}, + FieldElement{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}, + }, + { + FieldElement{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}, + FieldElement{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}, + FieldElement{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}, + }, + { + FieldElement{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}, + FieldElement{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}, + FieldElement{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}, + }, + { + FieldElement{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}, + FieldElement{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}, + FieldElement{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}, + }, + { + FieldElement{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877}, + FieldElement{-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951}, + FieldElement{4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784}, + }, + { + FieldElement{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436}, + FieldElement{25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918}, + FieldElement{23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877}, + }, + { + FieldElement{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800}, + FieldElement{-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305}, + FieldElement{-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300}, + }, + { + FieldElement{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876}, + FieldElement{-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619}, + FieldElement{-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683}, + }, +} + +// base contains precomputed multiples of the base-point. See the Ed25519 paper +// for a discussion about how these values are used. +var base = [32][8]PreComputedGroupElement{ + { + { + FieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, + FieldElement{-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}, + FieldElement{-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}, + }, + { + FieldElement{-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303}, + FieldElement{-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081}, + FieldElement{26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697}, + }, + { + FieldElement{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}, + FieldElement{16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}, + FieldElement{30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}, + }, + { + FieldElement{-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540}, + FieldElement{23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397}, + FieldElement{7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325}, + }, + { + FieldElement{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}, + FieldElement{4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}, + FieldElement{19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}, + }, + { + FieldElement{-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777}, + FieldElement{-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737}, + FieldElement{-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652}, + }, + { + FieldElement{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}, + FieldElement{-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}, + FieldElement{28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}, + }, + { + FieldElement{14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726}, + FieldElement{-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955}, + FieldElement{27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425}, + }, + }, + { + { + FieldElement{-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171}, + FieldElement{27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510}, + FieldElement{17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660}, + }, + { + FieldElement{-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639}, + FieldElement{29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963}, + FieldElement{5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950}, + }, + { + FieldElement{-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568}, + FieldElement{12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335}, + FieldElement{25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628}, + }, + { + FieldElement{-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007}, + FieldElement{-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772}, + FieldElement{-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653}, + }, + { + FieldElement{2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567}, + FieldElement{13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686}, + FieldElement{21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372}, + }, + { + FieldElement{-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887}, + FieldElement{-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954}, + FieldElement{-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953}, + }, + { + FieldElement{24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833}, + FieldElement{-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532}, + FieldElement{-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876}, + }, + { + FieldElement{2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268}, + FieldElement{33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214}, + FieldElement{1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038}, + }, + }, + { + { + FieldElement{6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800}, + FieldElement{4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645}, + FieldElement{-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664}, + }, + { + FieldElement{1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933}, + FieldElement{-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182}, + FieldElement{-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222}, + }, + { + FieldElement{-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991}, + FieldElement{20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880}, + FieldElement{9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092}, + }, + { + FieldElement{-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295}, + FieldElement{19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788}, + FieldElement{8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553}, + }, + { + FieldElement{-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026}, + FieldElement{11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347}, + FieldElement{-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033}, + }, + { + FieldElement{-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395}, + FieldElement{-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278}, + FieldElement{1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890}, + }, + { + FieldElement{32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995}, + FieldElement{-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596}, + FieldElement{-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891}, + }, + { + FieldElement{31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060}, + FieldElement{11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608}, + FieldElement{-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606}, + }, + }, + { + { + FieldElement{7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389}, + FieldElement{-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016}, + FieldElement{-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341}, + }, + { + FieldElement{-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505}, + FieldElement{14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553}, + FieldElement{-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655}, + }, + { + FieldElement{15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220}, + FieldElement{12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631}, + FieldElement{-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099}, + }, + { + FieldElement{26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556}, + FieldElement{14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749}, + FieldElement{236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930}, + }, + { + FieldElement{1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391}, + FieldElement{5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253}, + FieldElement{20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066}, + }, + { + FieldElement{24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958}, + FieldElement{-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082}, + FieldElement{-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383}, + }, + { + FieldElement{-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521}, + FieldElement{-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807}, + FieldElement{23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948}, + }, + { + FieldElement{9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134}, + FieldElement{-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455}, + FieldElement{27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629}, + }, + }, + { + { + FieldElement{-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069}, + FieldElement{-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746}, + FieldElement{24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919}, + }, + { + FieldElement{11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837}, + FieldElement{8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906}, + FieldElement{-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771}, + }, + { + FieldElement{-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817}, + FieldElement{10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098}, + FieldElement{10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409}, + }, + { + FieldElement{-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504}, + FieldElement{-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727}, + FieldElement{28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420}, + }, + { + FieldElement{-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003}, + FieldElement{-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605}, + FieldElement{-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384}, + }, + { + FieldElement{-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701}, + FieldElement{-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683}, + FieldElement{29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708}, + }, + { + FieldElement{-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563}, + FieldElement{-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260}, + FieldElement{-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387}, + }, + { + FieldElement{-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672}, + FieldElement{23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686}, + FieldElement{-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665}, + }, + }, + { + { + FieldElement{11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182}, + FieldElement{-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277}, + FieldElement{14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628}, + }, + { + FieldElement{-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474}, + FieldElement{-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539}, + FieldElement{-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822}, + }, + { + FieldElement{-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970}, + FieldElement{19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756}, + FieldElement{-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508}, + }, + { + FieldElement{-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683}, + FieldElement{-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655}, + FieldElement{-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158}, + }, + { + FieldElement{-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125}, + FieldElement{-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839}, + FieldElement{-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664}, + }, + { + FieldElement{27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294}, + FieldElement{-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899}, + FieldElement{-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070}, + }, + { + FieldElement{3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294}, + FieldElement{-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949}, + FieldElement{-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083}, + }, + { + FieldElement{31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420}, + FieldElement{-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940}, + FieldElement{29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396}, + }, + }, + { + { + FieldElement{-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567}, + FieldElement{20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127}, + FieldElement{-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294}, + }, + { + FieldElement{-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887}, + FieldElement{22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964}, + FieldElement{16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195}, + }, + { + FieldElement{9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244}, + FieldElement{24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999}, + FieldElement{-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762}, + }, + { + FieldElement{-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274}, + FieldElement{-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236}, + FieldElement{-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605}, + }, + { + FieldElement{-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761}, + FieldElement{-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884}, + FieldElement{-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482}, + }, + { + FieldElement{-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638}, + FieldElement{-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490}, + FieldElement{-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170}, + }, + { + FieldElement{5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736}, + FieldElement{10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124}, + FieldElement{-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392}, + }, + { + FieldElement{8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029}, + FieldElement{6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048}, + FieldElement{28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958}, + }, + }, + { + { + FieldElement{24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593}, + FieldElement{26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071}, + FieldElement{-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692}, + }, + { + FieldElement{11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687}, + FieldElement{-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441}, + FieldElement{-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001}, + }, + { + FieldElement{-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460}, + FieldElement{-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007}, + FieldElement{-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762}, + }, + { + FieldElement{15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005}, + FieldElement{-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674}, + FieldElement{4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035}, + }, + { + FieldElement{7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590}, + FieldElement{-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957}, + FieldElement{-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812}, + }, + { + FieldElement{33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740}, + FieldElement{-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122}, + FieldElement{-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158}, + }, + { + FieldElement{8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885}, + FieldElement{26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140}, + FieldElement{19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857}, + }, + { + FieldElement{801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155}, + FieldElement{19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260}, + FieldElement{19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483}, + }, + }, + { + { + FieldElement{-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677}, + FieldElement{32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815}, + FieldElement{22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751}, + }, + { + FieldElement{-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203}, + FieldElement{-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208}, + FieldElement{1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230}, + }, + { + FieldElement{16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850}, + FieldElement{-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389}, + FieldElement{-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968}, + }, + { + FieldElement{-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689}, + FieldElement{14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880}, + FieldElement{5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304}, + }, + { + FieldElement{30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632}, + FieldElement{-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412}, + FieldElement{20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566}, + }, + { + FieldElement{-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038}, + FieldElement{-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232}, + FieldElement{-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943}, + }, + { + FieldElement{17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856}, + FieldElement{23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738}, + FieldElement{15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971}, + }, + { + FieldElement{-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718}, + FieldElement{-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697}, + FieldElement{-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883}, + }, + }, + { + { + FieldElement{5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912}, + FieldElement{-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358}, + FieldElement{3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849}, + }, + { + FieldElement{29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307}, + FieldElement{-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977}, + FieldElement{-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335}, + }, + { + FieldElement{-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644}, + FieldElement{-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616}, + FieldElement{-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735}, + }, + { + FieldElement{-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099}, + FieldElement{29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341}, + FieldElement{-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336}, + }, + { + FieldElement{-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646}, + FieldElement{31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425}, + FieldElement{-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388}, + }, + { + FieldElement{-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743}, + FieldElement{-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822}, + FieldElement{-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462}, + }, + { + FieldElement{18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985}, + FieldElement{9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702}, + FieldElement{-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797}, + }, + { + FieldElement{21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293}, + FieldElement{27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100}, + FieldElement{19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688}, + }, + }, + { + { + FieldElement{12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186}, + FieldElement{2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610}, + FieldElement{-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707}, + }, + { + FieldElement{7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220}, + FieldElement{915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025}, + FieldElement{32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044}, + }, + { + FieldElement{32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992}, + FieldElement{-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027}, + FieldElement{21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197}, + }, + { + FieldElement{8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901}, + FieldElement{31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952}, + FieldElement{19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878}, + }, + { + FieldElement{-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390}, + FieldElement{32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730}, + FieldElement{2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730}, + }, + { + FieldElement{-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180}, + FieldElement{-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272}, + FieldElement{-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715}, + }, + { + FieldElement{-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970}, + FieldElement{-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772}, + FieldElement{-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865}, + }, + { + FieldElement{15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750}, + FieldElement{20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373}, + FieldElement{32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348}, + }, + }, + { + { + FieldElement{9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144}, + FieldElement{-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195}, + FieldElement{5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086}, + }, + { + FieldElement{-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684}, + FieldElement{-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518}, + FieldElement{-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233}, + }, + { + FieldElement{-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793}, + FieldElement{-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794}, + FieldElement{580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435}, + }, + { + FieldElement{23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921}, + FieldElement{13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518}, + FieldElement{2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563}, + }, + { + FieldElement{14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278}, + FieldElement{-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024}, + FieldElement{4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030}, + }, + { + FieldElement{10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783}, + FieldElement{27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717}, + FieldElement{6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844}, + }, + { + FieldElement{14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333}, + FieldElement{16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048}, + FieldElement{22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760}, + }, + { + FieldElement{-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760}, + FieldElement{-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757}, + FieldElement{-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112}, + }, + }, + { + { + FieldElement{-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468}, + FieldElement{3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184}, + FieldElement{10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289}, + }, + { + FieldElement{15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066}, + FieldElement{24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882}, + FieldElement{13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226}, + }, + { + FieldElement{16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101}, + FieldElement{29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279}, + FieldElement{-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811}, + }, + { + FieldElement{27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709}, + FieldElement{20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714}, + FieldElement{-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121}, + }, + { + FieldElement{9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464}, + FieldElement{12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847}, + FieldElement{13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400}, + }, + { + FieldElement{4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414}, + FieldElement{-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158}, + FieldElement{17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045}, + }, + { + FieldElement{-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415}, + FieldElement{-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459}, + FieldElement{-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079}, + }, + { + FieldElement{21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412}, + FieldElement{-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743}, + FieldElement{-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836}, + }, + }, + { + { + FieldElement{12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022}, + FieldElement{18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429}, + FieldElement{-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065}, + }, + { + FieldElement{30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861}, + FieldElement{10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000}, + FieldElement{-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101}, + }, + { + FieldElement{32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815}, + FieldElement{29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642}, + FieldElement{10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966}, + }, + { + FieldElement{25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574}, + FieldElement{-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742}, + FieldElement{-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689}, + }, + { + FieldElement{12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020}, + FieldElement{-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772}, + FieldElement{3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982}, + }, + { + FieldElement{-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953}, + FieldElement{-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218}, + FieldElement{-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265}, + }, + { + FieldElement{29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073}, + FieldElement{-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325}, + FieldElement{-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798}, + }, + { + FieldElement{-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870}, + FieldElement{-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863}, + FieldElement{-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927}, + }, + }, + { + { + FieldElement{-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267}, + FieldElement{-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663}, + FieldElement{22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862}, + }, + { + FieldElement{-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673}, + FieldElement{15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943}, + FieldElement{15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020}, + }, + { + FieldElement{-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238}, + FieldElement{11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064}, + FieldElement{14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795}, + }, + { + FieldElement{15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052}, + FieldElement{-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904}, + FieldElement{29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531}, + }, + { + FieldElement{-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979}, + FieldElement{-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841}, + FieldElement{10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431}, + }, + { + FieldElement{10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324}, + FieldElement{-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940}, + FieldElement{10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320}, + }, + { + FieldElement{-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184}, + FieldElement{14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114}, + FieldElement{30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878}, + }, + { + FieldElement{12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784}, + FieldElement{-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091}, + FieldElement{-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585}, + }, + }, + { + { + FieldElement{-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208}, + FieldElement{10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864}, + FieldElement{17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661}, + }, + { + FieldElement{7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233}, + FieldElement{26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212}, + FieldElement{-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525}, + }, + { + FieldElement{-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068}, + FieldElement{9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397}, + FieldElement{-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988}, + }, + { + FieldElement{5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889}, + FieldElement{32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038}, + FieldElement{14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697}, + }, + { + FieldElement{20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875}, + FieldElement{-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905}, + FieldElement{-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656}, + }, + { + FieldElement{11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818}, + FieldElement{27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714}, + FieldElement{10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203}, + }, + { + FieldElement{20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931}, + FieldElement{-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024}, + FieldElement{-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084}, + }, + { + FieldElement{-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204}, + FieldElement{20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817}, + FieldElement{27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667}, + }, + }, + { + { + FieldElement{11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504}, + FieldElement{-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768}, + FieldElement{-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255}, + }, + { + FieldElement{6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790}, + FieldElement{1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438}, + FieldElement{-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333}, + }, + { + FieldElement{17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971}, + FieldElement{31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905}, + FieldElement{29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409}, + }, + { + FieldElement{12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409}, + FieldElement{6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499}, + FieldElement{-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363}, + }, + { + FieldElement{28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664}, + FieldElement{-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324}, + FieldElement{-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940}, + }, + { + FieldElement{13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990}, + FieldElement{-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914}, + FieldElement{-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290}, + }, + { + FieldElement{24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257}, + FieldElement{-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433}, + FieldElement{-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236}, + }, + { + FieldElement{-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045}, + FieldElement{11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093}, + FieldElement{-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347}, + }, + }, + { + { + FieldElement{-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191}, + FieldElement{-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507}, + FieldElement{-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906}, + }, + { + FieldElement{3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018}, + FieldElement{-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109}, + FieldElement{-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926}, + }, + { + FieldElement{-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528}, + FieldElement{8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625}, + FieldElement{-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286}, + }, + { + FieldElement{2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033}, + FieldElement{27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866}, + FieldElement{21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896}, + }, + { + FieldElement{30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075}, + FieldElement{26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347}, + FieldElement{-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437}, + }, + { + FieldElement{-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165}, + FieldElement{-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588}, + FieldElement{-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193}, + }, + { + FieldElement{-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017}, + FieldElement{-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883}, + FieldElement{21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961}, + }, + { + FieldElement{8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043}, + FieldElement{29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663}, + FieldElement{-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362}, + }, + }, + { + { + FieldElement{-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860}, + FieldElement{2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466}, + FieldElement{-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063}, + }, + { + FieldElement{-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997}, + FieldElement{-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295}, + FieldElement{-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369}, + }, + { + FieldElement{9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385}, + FieldElement{18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109}, + FieldElement{2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906}, + }, + { + FieldElement{4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424}, + FieldElement{-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185}, + FieldElement{7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962}, + }, + { + FieldElement{-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325}, + FieldElement{10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593}, + FieldElement{696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404}, + }, + { + FieldElement{-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644}, + FieldElement{17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801}, + FieldElement{26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804}, + }, + { + FieldElement{-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884}, + FieldElement{-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577}, + FieldElement{-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849}, + }, + { + FieldElement{32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473}, + FieldElement{-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644}, + FieldElement{-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319}, + }, + }, + { + { + FieldElement{-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599}, + FieldElement{-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768}, + FieldElement{-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084}, + }, + { + FieldElement{-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328}, + FieldElement{-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369}, + FieldElement{20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920}, + }, + { + FieldElement{12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815}, + FieldElement{-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025}, + FieldElement{-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397}, + }, + { + FieldElement{-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448}, + FieldElement{6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981}, + FieldElement{30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165}, + }, + { + FieldElement{32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501}, + FieldElement{17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073}, + FieldElement{-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861}, + }, + { + FieldElement{14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845}, + FieldElement{-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211}, + FieldElement{18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870}, + }, + { + FieldElement{10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096}, + FieldElement{33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803}, + FieldElement{-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168}, + }, + { + FieldElement{30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965}, + FieldElement{-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505}, + FieldElement{18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598}, + }, + }, + { + { + FieldElement{5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782}, + FieldElement{5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900}, + FieldElement{-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479}, + }, + { + FieldElement{-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208}, + FieldElement{8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232}, + FieldElement{17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719}, + }, + { + FieldElement{16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271}, + FieldElement{-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326}, + FieldElement{-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132}, + }, + { + FieldElement{14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300}, + FieldElement{8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570}, + FieldElement{15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670}, + }, + { + FieldElement{-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994}, + FieldElement{-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913}, + FieldElement{31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317}, + }, + { + FieldElement{-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730}, + FieldElement{842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096}, + FieldElement{-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078}, + }, + { + FieldElement{-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411}, + FieldElement{-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905}, + FieldElement{-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654}, + }, + { + FieldElement{-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870}, + FieldElement{-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498}, + FieldElement{12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579}, + }, + }, + { + { + FieldElement{14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677}, + FieldElement{10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647}, + FieldElement{-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743}, + }, + { + FieldElement{-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468}, + FieldElement{21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375}, + FieldElement{-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155}, + }, + { + FieldElement{6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725}, + FieldElement{-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612}, + FieldElement{-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943}, + }, + { + FieldElement{-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944}, + FieldElement{30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928}, + FieldElement{9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406}, + }, + { + FieldElement{22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139}, + FieldElement{-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963}, + FieldElement{-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693}, + }, + { + FieldElement{1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734}, + FieldElement{-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680}, + FieldElement{-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410}, + }, + { + FieldElement{-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931}, + FieldElement{-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654}, + FieldElement{22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710}, + }, + { + FieldElement{29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180}, + FieldElement{-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684}, + FieldElement{-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895}, + }, + }, + { + { + FieldElement{22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501}, + FieldElement{-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413}, + FieldElement{6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880}, + }, + { + FieldElement{-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874}, + FieldElement{22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962}, + FieldElement{-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899}, + }, + { + FieldElement{21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152}, + FieldElement{9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063}, + FieldElement{7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080}, + }, + { + FieldElement{-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146}, + FieldElement{-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183}, + FieldElement{-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133}, + }, + { + FieldElement{-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421}, + FieldElement{-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622}, + FieldElement{-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197}, + }, + { + FieldElement{2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663}, + FieldElement{31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753}, + FieldElement{4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755}, + }, + { + FieldElement{-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862}, + FieldElement{-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118}, + FieldElement{26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171}, + }, + { + FieldElement{15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380}, + FieldElement{16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824}, + FieldElement{28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270}, + }, + }, + { + { + FieldElement{-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438}, + FieldElement{-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584}, + FieldElement{-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562}, + }, + { + FieldElement{30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471}, + FieldElement{18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610}, + FieldElement{19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269}, + }, + { + FieldElement{-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650}, + FieldElement{14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369}, + FieldElement{19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461}, + }, + { + FieldElement{30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462}, + FieldElement{-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793}, + FieldElement{-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218}, + }, + { + FieldElement{-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226}, + FieldElement{18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019}, + FieldElement{-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037}, + }, + { + FieldElement{31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171}, + FieldElement{-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132}, + FieldElement{-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841}, + }, + { + FieldElement{21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181}, + FieldElement{-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210}, + FieldElement{-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040}, + }, + { + FieldElement{3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935}, + FieldElement{24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105}, + FieldElement{-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814}, + }, + }, + { + { + FieldElement{793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852}, + FieldElement{5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581}, + FieldElement{-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646}, + }, + { + FieldElement{10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844}, + FieldElement{10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025}, + FieldElement{27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453}, + }, + { + FieldElement{-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068}, + FieldElement{4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192}, + FieldElement{-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921}, + }, + { + FieldElement{-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259}, + FieldElement{-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426}, + FieldElement{-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072}, + }, + { + FieldElement{-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305}, + FieldElement{13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832}, + FieldElement{28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943}, + }, + { + FieldElement{-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011}, + FieldElement{24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447}, + FieldElement{17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494}, + }, + { + FieldElement{-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245}, + FieldElement{-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859}, + FieldElement{28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915}, + }, + { + FieldElement{16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707}, + FieldElement{10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848}, + FieldElement{-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224}, + }, + }, + { + { + FieldElement{-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391}, + FieldElement{15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215}, + FieldElement{-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101}, + }, + { + FieldElement{23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713}, + FieldElement{21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849}, + FieldElement{-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930}, + }, + { + FieldElement{-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940}, + FieldElement{-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031}, + FieldElement{-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404}, + }, + { + FieldElement{-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243}, + FieldElement{-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116}, + FieldElement{-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525}, + }, + { + FieldElement{-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509}, + FieldElement{-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883}, + FieldElement{15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865}, + }, + { + FieldElement{-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660}, + FieldElement{4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273}, + FieldElement{-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138}, + }, + { + FieldElement{-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560}, + FieldElement{-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135}, + FieldElement{2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941}, + }, + { + FieldElement{-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739}, + FieldElement{18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756}, + FieldElement{-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819}, + }, + }, + { + { + FieldElement{-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347}, + FieldElement{-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028}, + FieldElement{21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075}, + }, + { + FieldElement{16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799}, + FieldElement{-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609}, + FieldElement{-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817}, + }, + { + FieldElement{-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989}, + FieldElement{-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523}, + FieldElement{4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278}, + }, + { + FieldElement{31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045}, + FieldElement{19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377}, + FieldElement{24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480}, + }, + { + FieldElement{17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016}, + FieldElement{510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426}, + FieldElement{18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525}, + }, + { + FieldElement{13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396}, + FieldElement{9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080}, + FieldElement{12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892}, + }, + { + FieldElement{15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275}, + FieldElement{11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074}, + FieldElement{20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140}, + }, + { + FieldElement{-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717}, + FieldElement{-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101}, + FieldElement{24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127}, + }, + }, + { + { + FieldElement{-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632}, + FieldElement{-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415}, + FieldElement{-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160}, + }, + { + FieldElement{31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876}, + FieldElement{22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625}, + FieldElement{-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478}, + }, + { + FieldElement{27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164}, + FieldElement{26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595}, + FieldElement{-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248}, + }, + { + FieldElement{-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858}, + FieldElement{15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193}, + FieldElement{8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184}, + }, + { + FieldElement{-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942}, + FieldElement{-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635}, + FieldElement{21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948}, + }, + { + FieldElement{11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935}, + FieldElement{-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415}, + FieldElement{-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416}, + }, + { + FieldElement{-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018}, + FieldElement{4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778}, + FieldElement{366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659}, + }, + { + FieldElement{-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385}, + FieldElement{18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503}, + FieldElement{476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329}, + }, + }, + { + { + FieldElement{20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056}, + FieldElement{-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838}, + FieldElement{24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948}, + }, + { + FieldElement{-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691}, + FieldElement{-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118}, + FieldElement{-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517}, + }, + { + FieldElement{-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269}, + FieldElement{-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904}, + FieldElement{-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589}, + }, + { + FieldElement{-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193}, + FieldElement{-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910}, + FieldElement{-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930}, + }, + { + FieldElement{-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667}, + FieldElement{25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481}, + FieldElement{-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876}, + }, + { + FieldElement{22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640}, + FieldElement{-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278}, + FieldElement{-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112}, + }, + { + FieldElement{26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272}, + FieldElement{17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012}, + FieldElement{-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221}, + }, + { + FieldElement{30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046}, + FieldElement{13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345}, + FieldElement{-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310}, + }, + }, + { + { + FieldElement{19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937}, + FieldElement{31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636}, + FieldElement{-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008}, + }, + { + FieldElement{-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429}, + FieldElement{-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576}, + FieldElement{31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066}, + }, + { + FieldElement{-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490}, + FieldElement{-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104}, + FieldElement{33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053}, + }, + { + FieldElement{31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275}, + FieldElement{-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511}, + FieldElement{22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095}, + }, + { + FieldElement{-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439}, + FieldElement{23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939}, + FieldElement{-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424}, + }, + { + FieldElement{2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310}, + FieldElement{3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608}, + FieldElement{-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079}, + }, + { + FieldElement{-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101}, + FieldElement{21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418}, + FieldElement{18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576}, + }, + { + FieldElement{30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356}, + FieldElement{9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996}, + FieldElement{-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099}, + }, + }, + { + { + FieldElement{-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728}, + FieldElement{-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658}, + FieldElement{-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242}, + }, + { + FieldElement{-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001}, + FieldElement{-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766}, + FieldElement{18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373}, + }, + { + FieldElement{26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458}, + FieldElement{-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628}, + FieldElement{-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657}, + }, + { + FieldElement{-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062}, + FieldElement{25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616}, + FieldElement{31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014}, + }, + { + FieldElement{24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383}, + FieldElement{-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814}, + FieldElement{-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718}, + }, + { + FieldElement{30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417}, + FieldElement{2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222}, + FieldElement{33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444}, + }, + { + FieldElement{-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597}, + FieldElement{23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970}, + FieldElement{1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799}, + }, + { + FieldElement{-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647}, + FieldElement{13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511}, + FieldElement{-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032}, + }, + }, + { + { + FieldElement{9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834}, + FieldElement{-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461}, + FieldElement{29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062}, + }, + { + FieldElement{-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516}, + FieldElement{-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547}, + FieldElement{-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240}, + }, + { + FieldElement{-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038}, + FieldElement{-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741}, + FieldElement{16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103}, + }, + { + FieldElement{-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747}, + FieldElement{-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323}, + FieldElement{31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016}, + }, + { + FieldElement{-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373}, + FieldElement{15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228}, + FieldElement{-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141}, + }, + { + FieldElement{16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399}, + FieldElement{11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831}, + FieldElement{-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376}, + }, + { + FieldElement{-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313}, + FieldElement{-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958}, + FieldElement{-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577}, + }, + { + FieldElement{-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743}, + FieldElement{29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684}, + FieldElement{-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476}, + }, + }, +} diff --git a/libgo/go/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go b/libgo/go/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go new file mode 100644 index 00000000000..fd03c252af4 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go @@ -0,0 +1,1793 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package edwards25519 + +import "encoding/binary" + +// This code is a port of the public domain, “ref10” implementation of ed25519 +// from SUPERCOP. + +// FieldElement represents an element of the field GF(2^255 - 19). An element +// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 +// t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on +// context. +type FieldElement [10]int32 + +var zero FieldElement + +func FeZero(fe *FieldElement) { + copy(fe[:], zero[:]) +} + +func FeOne(fe *FieldElement) { + FeZero(fe) + fe[0] = 1 +} + +func FeAdd(dst, a, b *FieldElement) { + dst[0] = a[0] + b[0] + dst[1] = a[1] + b[1] + dst[2] = a[2] + b[2] + dst[3] = a[3] + b[3] + dst[4] = a[4] + b[4] + dst[5] = a[5] + b[5] + dst[6] = a[6] + b[6] + dst[7] = a[7] + b[7] + dst[8] = a[8] + b[8] + dst[9] = a[9] + b[9] +} + +func FeSub(dst, a, b *FieldElement) { + dst[0] = a[0] - b[0] + dst[1] = a[1] - b[1] + dst[2] = a[2] - b[2] + dst[3] = a[3] - b[3] + dst[4] = a[4] - b[4] + dst[5] = a[5] - b[5] + dst[6] = a[6] - b[6] + dst[7] = a[7] - b[7] + dst[8] = a[8] - b[8] + dst[9] = a[9] - b[9] +} + +func FeCopy(dst, src *FieldElement) { + copy(dst[:], src[:]) +} + +// Replace (f,g) with (g,g) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +func FeCMove(f, g *FieldElement, b int32) { + b = -b + f[0] ^= b & (f[0] ^ g[0]) + f[1] ^= b & (f[1] ^ g[1]) + f[2] ^= b & (f[2] ^ g[2]) + f[3] ^= b & (f[3] ^ g[3]) + f[4] ^= b & (f[4] ^ g[4]) + f[5] ^= b & (f[5] ^ g[5]) + f[6] ^= b & (f[6] ^ g[6]) + f[7] ^= b & (f[7] ^ g[7]) + f[8] ^= b & (f[8] ^ g[8]) + f[9] ^= b & (f[9] ^ g[9]) +} + +func load3(in []byte) int64 { + var r int64 + r = int64(in[0]) + r |= int64(in[1]) << 8 + r |= int64(in[2]) << 16 + return r +} + +func load4(in []byte) int64 { + var r int64 + r = int64(in[0]) + r |= int64(in[1]) << 8 + r |= int64(in[2]) << 16 + r |= int64(in[3]) << 24 + return r +} + +func FeFromBytes(dst *FieldElement, src *[32]byte) { + h0 := load4(src[:]) + h1 := load3(src[4:]) << 6 + h2 := load3(src[7:]) << 5 + h3 := load3(src[10:]) << 3 + h4 := load3(src[13:]) << 2 + h5 := load4(src[16:]) + h6 := load3(src[20:]) << 7 + h7 := load3(src[23:]) << 5 + h8 := load3(src[26:]) << 4 + h9 := (load3(src[29:]) & 8388607) << 2 + + FeCombine(dst, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9) +} + +// FeToBytes marshals h to s. +// Preconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Write p=2^255-19; q=floor(h/p). +// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). +// +// Proof: +// Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. +// Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4. +// +// Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). +// Then 0> 25 + q = (h[0] + q) >> 26 + q = (h[1] + q) >> 25 + q = (h[2] + q) >> 26 + q = (h[3] + q) >> 25 + q = (h[4] + q) >> 26 + q = (h[5] + q) >> 25 + q = (h[6] + q) >> 26 + q = (h[7] + q) >> 25 + q = (h[8] + q) >> 26 + q = (h[9] + q) >> 25 + + // Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. + h[0] += 19 * q + // Goal: Output h-2^255 q, which is between 0 and 2^255-20. + + carry[0] = h[0] >> 26 + h[1] += carry[0] + h[0] -= carry[0] << 26 + carry[1] = h[1] >> 25 + h[2] += carry[1] + h[1] -= carry[1] << 25 + carry[2] = h[2] >> 26 + h[3] += carry[2] + h[2] -= carry[2] << 26 + carry[3] = h[3] >> 25 + h[4] += carry[3] + h[3] -= carry[3] << 25 + carry[4] = h[4] >> 26 + h[5] += carry[4] + h[4] -= carry[4] << 26 + carry[5] = h[5] >> 25 + h[6] += carry[5] + h[5] -= carry[5] << 25 + carry[6] = h[6] >> 26 + h[7] += carry[6] + h[6] -= carry[6] << 26 + carry[7] = h[7] >> 25 + h[8] += carry[7] + h[7] -= carry[7] << 25 + carry[8] = h[8] >> 26 + h[9] += carry[8] + h[8] -= carry[8] << 26 + carry[9] = h[9] >> 25 + h[9] -= carry[9] << 25 + // h10 = carry9 + + // Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + // Have h[0]+...+2^230 h[9] between 0 and 2^255-1; + // evidently 2^255 h10-2^255 q = 0. + // Goal: Output h[0]+...+2^230 h[9]. + + s[0] = byte(h[0] >> 0) + s[1] = byte(h[0] >> 8) + s[2] = byte(h[0] >> 16) + s[3] = byte((h[0] >> 24) | (h[1] << 2)) + s[4] = byte(h[1] >> 6) + s[5] = byte(h[1] >> 14) + s[6] = byte((h[1] >> 22) | (h[2] << 3)) + s[7] = byte(h[2] >> 5) + s[8] = byte(h[2] >> 13) + s[9] = byte((h[2] >> 21) | (h[3] << 5)) + s[10] = byte(h[3] >> 3) + s[11] = byte(h[3] >> 11) + s[12] = byte((h[3] >> 19) | (h[4] << 6)) + s[13] = byte(h[4] >> 2) + s[14] = byte(h[4] >> 10) + s[15] = byte(h[4] >> 18) + s[16] = byte(h[5] >> 0) + s[17] = byte(h[5] >> 8) + s[18] = byte(h[5] >> 16) + s[19] = byte((h[5] >> 24) | (h[6] << 1)) + s[20] = byte(h[6] >> 7) + s[21] = byte(h[6] >> 15) + s[22] = byte((h[6] >> 23) | (h[7] << 3)) + s[23] = byte(h[7] >> 5) + s[24] = byte(h[7] >> 13) + s[25] = byte((h[7] >> 21) | (h[8] << 4)) + s[26] = byte(h[8] >> 4) + s[27] = byte(h[8] >> 12) + s[28] = byte((h[8] >> 20) | (h[9] << 6)) + s[29] = byte(h[9] >> 2) + s[30] = byte(h[9] >> 10) + s[31] = byte(h[9] >> 18) +} + +func FeIsNegative(f *FieldElement) byte { + var s [32]byte + FeToBytes(&s, f) + return s[0] & 1 +} + +func FeIsNonZero(f *FieldElement) int32 { + var s [32]byte + FeToBytes(&s, f) + var x uint8 + for _, b := range s { + x |= b + } + x |= x >> 4 + x |= x >> 2 + x |= x >> 1 + return int32(x & 1) +} + +// FeNeg sets h = -f +// +// Preconditions: +// |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func FeNeg(h, f *FieldElement) { + h[0] = -f[0] + h[1] = -f[1] + h[2] = -f[2] + h[3] = -f[3] + h[4] = -f[4] + h[5] = -f[5] + h[6] = -f[6] + h[7] = -f[7] + h[8] = -f[8] + h[9] = -f[9] +} + +func FeCombine(h *FieldElement, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64) { + var c0, c1, c2, c3, c4, c5, c6, c7, c8, c9 int64 + + /* + |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9 + */ + + c0 = (h0 + (1 << 25)) >> 26 + h1 += c0 + h0 -= c0 << 26 + c4 = (h4 + (1 << 25)) >> 26 + h5 += c4 + h4 -= c4 << 26 + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.51*2^58 */ + /* |h5| <= 1.51*2^58 */ + + c1 = (h1 + (1 << 24)) >> 25 + h2 += c1 + h1 -= c1 << 25 + c5 = (h5 + (1 << 24)) >> 25 + h6 += c5 + h5 -= c5 << 25 + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.21*2^59 */ + /* |h6| <= 1.21*2^59 */ + + c2 = (h2 + (1 << 25)) >> 26 + h3 += c2 + h2 -= c2 << 26 + c6 = (h6 + (1 << 25)) >> 26 + h7 += c6 + h6 -= c6 << 26 + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.51*2^58 */ + /* |h7| <= 1.51*2^58 */ + + c3 = (h3 + (1 << 24)) >> 25 + h4 += c3 + h3 -= c3 << 25 + c7 = (h7 + (1 << 24)) >> 25 + h8 += c7 + h7 -= c7 << 25 + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.52*2^33 */ + /* |h8| <= 1.52*2^33 */ + + c4 = (h4 + (1 << 25)) >> 26 + h5 += c4 + h4 -= c4 << 26 + c8 = (h8 + (1 << 25)) >> 26 + h9 += c8 + h8 -= c8 << 26 + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.51*2^58 */ + + c9 = (h9 + (1 << 24)) >> 25 + h0 += c9 * 19 + h9 -= c9 << 25 + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.8*2^37 */ + + c0 = (h0 + (1 << 25)) >> 26 + h1 += c0 + h0 -= c0 << 26 + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = int32(h0) + h[1] = int32(h1) + h[2] = int32(h2) + h[3] = int32(h3) + h[4] = int32(h4) + h[5] = int32(h5) + h[6] = int32(h6) + h[7] = int32(h7) + h[8] = int32(h8) + h[9] = int32(h9) +} + +// FeMul calculates h = f * g +// Can overlap h with f or g. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +// +// Notes on implementation strategy: +// +// Using schoolbook multiplication. +// Karatsuba would save a little in some cost models. +// +// Most multiplications by 2 and 19 are 32-bit precomputations; +// cheaper than 64-bit postcomputations. +// +// There is one remaining multiplication by 19 in the carry chain; +// one *19 precomputation can be merged into this, +// but the resulting data flow is considerably less clean. +// +// There are 12 carries below. +// 10 of them are 2-way parallelizable and vectorizable. +// Can get away with 11 carries, but then data flow is much deeper. +// +// With tighter constraints on inputs, can squeeze carries into int32. +func FeMul(h, f, g *FieldElement) { + f0 := int64(f[0]) + f1 := int64(f[1]) + f2 := int64(f[2]) + f3 := int64(f[3]) + f4 := int64(f[4]) + f5 := int64(f[5]) + f6 := int64(f[6]) + f7 := int64(f[7]) + f8 := int64(f[8]) + f9 := int64(f[9]) + + f1_2 := int64(2 * f[1]) + f3_2 := int64(2 * f[3]) + f5_2 := int64(2 * f[5]) + f7_2 := int64(2 * f[7]) + f9_2 := int64(2 * f[9]) + + g0 := int64(g[0]) + g1 := int64(g[1]) + g2 := int64(g[2]) + g3 := int64(g[3]) + g4 := int64(g[4]) + g5 := int64(g[5]) + g6 := int64(g[6]) + g7 := int64(g[7]) + g8 := int64(g[8]) + g9 := int64(g[9]) + + g1_19 := int64(19 * g[1]) /* 1.4*2^29 */ + g2_19 := int64(19 * g[2]) /* 1.4*2^30; still ok */ + g3_19 := int64(19 * g[3]) + g4_19 := int64(19 * g[4]) + g5_19 := int64(19 * g[5]) + g6_19 := int64(19 * g[6]) + g7_19 := int64(19 * g[7]) + g8_19 := int64(19 * g[8]) + g9_19 := int64(19 * g[9]) + + h0 := f0*g0 + f1_2*g9_19 + f2*g8_19 + f3_2*g7_19 + f4*g6_19 + f5_2*g5_19 + f6*g4_19 + f7_2*g3_19 + f8*g2_19 + f9_2*g1_19 + h1 := f0*g1 + f1*g0 + f2*g9_19 + f3*g8_19 + f4*g7_19 + f5*g6_19 + f6*g5_19 + f7*g4_19 + f8*g3_19 + f9*g2_19 + h2 := f0*g2 + f1_2*g1 + f2*g0 + f3_2*g9_19 + f4*g8_19 + f5_2*g7_19 + f6*g6_19 + f7_2*g5_19 + f8*g4_19 + f9_2*g3_19 + h3 := f0*g3 + f1*g2 + f2*g1 + f3*g0 + f4*g9_19 + f5*g8_19 + f6*g7_19 + f7*g6_19 + f8*g5_19 + f9*g4_19 + h4 := f0*g4 + f1_2*g3 + f2*g2 + f3_2*g1 + f4*g0 + f5_2*g9_19 + f6*g8_19 + f7_2*g7_19 + f8*g6_19 + f9_2*g5_19 + h5 := f0*g5 + f1*g4 + f2*g3 + f3*g2 + f4*g1 + f5*g0 + f6*g9_19 + f7*g8_19 + f8*g7_19 + f9*g6_19 + h6 := f0*g6 + f1_2*g5 + f2*g4 + f3_2*g3 + f4*g2 + f5_2*g1 + f6*g0 + f7_2*g9_19 + f8*g8_19 + f9_2*g7_19 + h7 := f0*g7 + f1*g6 + f2*g5 + f3*g4 + f4*g3 + f5*g2 + f6*g1 + f7*g0 + f8*g9_19 + f9*g8_19 + h8 := f0*g8 + f1_2*g7 + f2*g6 + f3_2*g5 + f4*g4 + f5_2*g3 + f6*g2 + f7_2*g1 + f8*g0 + f9_2*g9_19 + h9 := f0*g9 + f1*g8 + f2*g7 + f3*g6 + f4*g5 + f5*g4 + f6*g3 + f7*g2 + f8*g1 + f9*g0 + + FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9) +} + +func feSquare(f *FieldElement) (h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 int64) { + f0 := int64(f[0]) + f1 := int64(f[1]) + f2 := int64(f[2]) + f3 := int64(f[3]) + f4 := int64(f[4]) + f5 := int64(f[5]) + f6 := int64(f[6]) + f7 := int64(f[7]) + f8 := int64(f[8]) + f9 := int64(f[9]) + f0_2 := int64(2 * f[0]) + f1_2 := int64(2 * f[1]) + f2_2 := int64(2 * f[2]) + f3_2 := int64(2 * f[3]) + f4_2 := int64(2 * f[4]) + f5_2 := int64(2 * f[5]) + f6_2 := int64(2 * f[6]) + f7_2 := int64(2 * f[7]) + f5_38 := 38 * f5 // 1.31*2^30 + f6_19 := 19 * f6 // 1.31*2^30 + f7_38 := 38 * f7 // 1.31*2^30 + f8_19 := 19 * f8 // 1.31*2^30 + f9_38 := 38 * f9 // 1.31*2^30 + + h0 = f0*f0 + f1_2*f9_38 + f2_2*f8_19 + f3_2*f7_38 + f4_2*f6_19 + f5*f5_38 + h1 = f0_2*f1 + f2*f9_38 + f3_2*f8_19 + f4*f7_38 + f5_2*f6_19 + h2 = f0_2*f2 + f1_2*f1 + f3_2*f9_38 + f4_2*f8_19 + f5_2*f7_38 + f6*f6_19 + h3 = f0_2*f3 + f1_2*f2 + f4*f9_38 + f5_2*f8_19 + f6*f7_38 + h4 = f0_2*f4 + f1_2*f3_2 + f2*f2 + f5_2*f9_38 + f6_2*f8_19 + f7*f7_38 + h5 = f0_2*f5 + f1_2*f4 + f2_2*f3 + f6*f9_38 + f7_2*f8_19 + h6 = f0_2*f6 + f1_2*f5_2 + f2_2*f4 + f3_2*f3 + f7_2*f9_38 + f8*f8_19 + h7 = f0_2*f7 + f1_2*f6 + f2_2*f5 + f3_2*f4 + f8*f9_38 + h8 = f0_2*f8 + f1_2*f7_2 + f2_2*f6 + f3_2*f5_2 + f4*f4 + f9*f9_38 + h9 = f0_2*f9 + f1_2*f8 + f2_2*f7 + f3_2*f6 + f4_2*f5 + + return +} + +// FeSquare calculates h = f*f. Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +func FeSquare(h, f *FieldElement) { + h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 := feSquare(f) + FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9) +} + +// FeSquare2 sets h = 2 * f * f +// +// Can overlap h with f. +// +// Preconditions: +// |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. +// +// Postconditions: +// |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +// See fe_mul.c for discussion of implementation strategy. +func FeSquare2(h, f *FieldElement) { + h0, h1, h2, h3, h4, h5, h6, h7, h8, h9 := feSquare(f) + + h0 += h0 + h1 += h1 + h2 += h2 + h3 += h3 + h4 += h4 + h5 += h5 + h6 += h6 + h7 += h7 + h8 += h8 + h9 += h9 + + FeCombine(h, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9) +} + +func FeInvert(out, z *FieldElement) { + var t0, t1, t2, t3 FieldElement + var i int + + FeSquare(&t0, z) // 2^1 + FeSquare(&t1, &t0) // 2^2 + for i = 1; i < 2; i++ { // 2^3 + FeSquare(&t1, &t1) + } + FeMul(&t1, z, &t1) // 2^3 + 2^0 + FeMul(&t0, &t0, &t1) // 2^3 + 2^1 + 2^0 + FeSquare(&t2, &t0) // 2^4 + 2^2 + 2^1 + FeMul(&t1, &t1, &t2) // 2^4 + 2^3 + 2^2 + 2^1 + 2^0 + FeSquare(&t2, &t1) // 5,4,3,2,1 + for i = 1; i < 5; i++ { // 9,8,7,6,5 + FeSquare(&t2, &t2) + } + FeMul(&t1, &t2, &t1) // 9,8,7,6,5,4,3,2,1,0 + FeSquare(&t2, &t1) // 10..1 + for i = 1; i < 10; i++ { // 19..10 + FeSquare(&t2, &t2) + } + FeMul(&t2, &t2, &t1) // 19..0 + FeSquare(&t3, &t2) // 20..1 + for i = 1; i < 20; i++ { // 39..20 + FeSquare(&t3, &t3) + } + FeMul(&t2, &t3, &t2) // 39..0 + FeSquare(&t2, &t2) // 40..1 + for i = 1; i < 10; i++ { // 49..10 + FeSquare(&t2, &t2) + } + FeMul(&t1, &t2, &t1) // 49..0 + FeSquare(&t2, &t1) // 50..1 + for i = 1; i < 50; i++ { // 99..50 + FeSquare(&t2, &t2) + } + FeMul(&t2, &t2, &t1) // 99..0 + FeSquare(&t3, &t2) // 100..1 + for i = 1; i < 100; i++ { // 199..100 + FeSquare(&t3, &t3) + } + FeMul(&t2, &t3, &t2) // 199..0 + FeSquare(&t2, &t2) // 200..1 + for i = 1; i < 50; i++ { // 249..50 + FeSquare(&t2, &t2) + } + FeMul(&t1, &t2, &t1) // 249..0 + FeSquare(&t1, &t1) // 250..1 + for i = 1; i < 5; i++ { // 254..5 + FeSquare(&t1, &t1) + } + FeMul(out, &t1, &t0) // 254..5,3,1,0 +} + +func fePow22523(out, z *FieldElement) { + var t0, t1, t2 FieldElement + var i int + + FeSquare(&t0, z) + for i = 1; i < 1; i++ { + FeSquare(&t0, &t0) + } + FeSquare(&t1, &t0) + for i = 1; i < 2; i++ { + FeSquare(&t1, &t1) + } + FeMul(&t1, z, &t1) + FeMul(&t0, &t0, &t1) + FeSquare(&t0, &t0) + for i = 1; i < 1; i++ { + FeSquare(&t0, &t0) + } + FeMul(&t0, &t1, &t0) + FeSquare(&t1, &t0) + for i = 1; i < 5; i++ { + FeSquare(&t1, &t1) + } + FeMul(&t0, &t1, &t0) + FeSquare(&t1, &t0) + for i = 1; i < 10; i++ { + FeSquare(&t1, &t1) + } + FeMul(&t1, &t1, &t0) + FeSquare(&t2, &t1) + for i = 1; i < 20; i++ { + FeSquare(&t2, &t2) + } + FeMul(&t1, &t2, &t1) + FeSquare(&t1, &t1) + for i = 1; i < 10; i++ { + FeSquare(&t1, &t1) + } + FeMul(&t0, &t1, &t0) + FeSquare(&t1, &t0) + for i = 1; i < 50; i++ { + FeSquare(&t1, &t1) + } + FeMul(&t1, &t1, &t0) + FeSquare(&t2, &t1) + for i = 1; i < 100; i++ { + FeSquare(&t2, &t2) + } + FeMul(&t1, &t2, &t1) + FeSquare(&t1, &t1) + for i = 1; i < 50; i++ { + FeSquare(&t1, &t1) + } + FeMul(&t0, &t1, &t0) + FeSquare(&t0, &t0) + for i = 1; i < 2; i++ { + FeSquare(&t0, &t0) + } + FeMul(out, &t0, z) +} + +// Group elements are members of the elliptic curve -x^2 + y^2 = 1 + d * x^2 * +// y^2 where d = -121665/121666. +// +// Several representations are used: +// ProjectiveGroupElement: (X:Y:Z) satisfying x=X/Z, y=Y/Z +// ExtendedGroupElement: (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT +// CompletedGroupElement: ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T +// PreComputedGroupElement: (y+x,y-x,2dxy) + +type ProjectiveGroupElement struct { + X, Y, Z FieldElement +} + +type ExtendedGroupElement struct { + X, Y, Z, T FieldElement +} + +type CompletedGroupElement struct { + X, Y, Z, T FieldElement +} + +type PreComputedGroupElement struct { + yPlusX, yMinusX, xy2d FieldElement +} + +type CachedGroupElement struct { + yPlusX, yMinusX, Z, T2d FieldElement +} + +func (p *ProjectiveGroupElement) Zero() { + FeZero(&p.X) + FeOne(&p.Y) + FeOne(&p.Z) +} + +func (p *ProjectiveGroupElement) Double(r *CompletedGroupElement) { + var t0 FieldElement + + FeSquare(&r.X, &p.X) + FeSquare(&r.Z, &p.Y) + FeSquare2(&r.T, &p.Z) + FeAdd(&r.Y, &p.X, &p.Y) + FeSquare(&t0, &r.Y) + FeAdd(&r.Y, &r.Z, &r.X) + FeSub(&r.Z, &r.Z, &r.X) + FeSub(&r.X, &t0, &r.Y) + FeSub(&r.T, &r.T, &r.Z) +} + +func (p *ProjectiveGroupElement) ToBytes(s *[32]byte) { + var recip, x, y FieldElement + + FeInvert(&recip, &p.Z) + FeMul(&x, &p.X, &recip) + FeMul(&y, &p.Y, &recip) + FeToBytes(s, &y) + s[31] ^= FeIsNegative(&x) << 7 +} + +func (p *ExtendedGroupElement) Zero() { + FeZero(&p.X) + FeOne(&p.Y) + FeOne(&p.Z) + FeZero(&p.T) +} + +func (p *ExtendedGroupElement) Double(r *CompletedGroupElement) { + var q ProjectiveGroupElement + p.ToProjective(&q) + q.Double(r) +} + +func (p *ExtendedGroupElement) ToCached(r *CachedGroupElement) { + FeAdd(&r.yPlusX, &p.Y, &p.X) + FeSub(&r.yMinusX, &p.Y, &p.X) + FeCopy(&r.Z, &p.Z) + FeMul(&r.T2d, &p.T, &d2) +} + +func (p *ExtendedGroupElement) ToProjective(r *ProjectiveGroupElement) { + FeCopy(&r.X, &p.X) + FeCopy(&r.Y, &p.Y) + FeCopy(&r.Z, &p.Z) +} + +func (p *ExtendedGroupElement) ToBytes(s *[32]byte) { + var recip, x, y FieldElement + + FeInvert(&recip, &p.Z) + FeMul(&x, &p.X, &recip) + FeMul(&y, &p.Y, &recip) + FeToBytes(s, &y) + s[31] ^= FeIsNegative(&x) << 7 +} + +func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool { + var u, v, v3, vxx, check FieldElement + + FeFromBytes(&p.Y, s) + FeOne(&p.Z) + FeSquare(&u, &p.Y) + FeMul(&v, &u, &d) + FeSub(&u, &u, &p.Z) // y = y^2-1 + FeAdd(&v, &v, &p.Z) // v = dy^2+1 + + FeSquare(&v3, &v) + FeMul(&v3, &v3, &v) // v3 = v^3 + FeSquare(&p.X, &v3) + FeMul(&p.X, &p.X, &v) + FeMul(&p.X, &p.X, &u) // x = uv^7 + + fePow22523(&p.X, &p.X) // x = (uv^7)^((q-5)/8) + FeMul(&p.X, &p.X, &v3) + FeMul(&p.X, &p.X, &u) // x = uv^3(uv^7)^((q-5)/8) + + var tmpX, tmp2 [32]byte + + FeSquare(&vxx, &p.X) + FeMul(&vxx, &vxx, &v) + FeSub(&check, &vxx, &u) // vx^2-u + if FeIsNonZero(&check) == 1 { + FeAdd(&check, &vxx, &u) // vx^2+u + if FeIsNonZero(&check) == 1 { + return false + } + FeMul(&p.X, &p.X, &SqrtM1) + + FeToBytes(&tmpX, &p.X) + for i, v := range tmpX { + tmp2[31-i] = v + } + } + + if FeIsNegative(&p.X) != (s[31] >> 7) { + FeNeg(&p.X, &p.X) + } + + FeMul(&p.T, &p.X, &p.Y) + return true +} + +func (p *CompletedGroupElement) ToProjective(r *ProjectiveGroupElement) { + FeMul(&r.X, &p.X, &p.T) + FeMul(&r.Y, &p.Y, &p.Z) + FeMul(&r.Z, &p.Z, &p.T) +} + +func (p *CompletedGroupElement) ToExtended(r *ExtendedGroupElement) { + FeMul(&r.X, &p.X, &p.T) + FeMul(&r.Y, &p.Y, &p.Z) + FeMul(&r.Z, &p.Z, &p.T) + FeMul(&r.T, &p.X, &p.Y) +} + +func (p *PreComputedGroupElement) Zero() { + FeOne(&p.yPlusX) + FeOne(&p.yMinusX) + FeZero(&p.xy2d) +} + +func geAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) { + var t0 FieldElement + + FeAdd(&r.X, &p.Y, &p.X) + FeSub(&r.Y, &p.Y, &p.X) + FeMul(&r.Z, &r.X, &q.yPlusX) + FeMul(&r.Y, &r.Y, &q.yMinusX) + FeMul(&r.T, &q.T2d, &p.T) + FeMul(&r.X, &p.Z, &q.Z) + FeAdd(&t0, &r.X, &r.X) + FeSub(&r.X, &r.Z, &r.Y) + FeAdd(&r.Y, &r.Z, &r.Y) + FeAdd(&r.Z, &t0, &r.T) + FeSub(&r.T, &t0, &r.T) +} + +func geSub(r *CompletedGroupElement, p *ExtendedGroupElement, q *CachedGroupElement) { + var t0 FieldElement + + FeAdd(&r.X, &p.Y, &p.X) + FeSub(&r.Y, &p.Y, &p.X) + FeMul(&r.Z, &r.X, &q.yMinusX) + FeMul(&r.Y, &r.Y, &q.yPlusX) + FeMul(&r.T, &q.T2d, &p.T) + FeMul(&r.X, &p.Z, &q.Z) + FeAdd(&t0, &r.X, &r.X) + FeSub(&r.X, &r.Z, &r.Y) + FeAdd(&r.Y, &r.Z, &r.Y) + FeSub(&r.Z, &t0, &r.T) + FeAdd(&r.T, &t0, &r.T) +} + +func geMixedAdd(r *CompletedGroupElement, p *ExtendedGroupElement, q *PreComputedGroupElement) { + var t0 FieldElement + + FeAdd(&r.X, &p.Y, &p.X) + FeSub(&r.Y, &p.Y, &p.X) + FeMul(&r.Z, &r.X, &q.yPlusX) + FeMul(&r.Y, &r.Y, &q.yMinusX) + FeMul(&r.T, &q.xy2d, &p.T) + FeAdd(&t0, &p.Z, &p.Z) + FeSub(&r.X, &r.Z, &r.Y) + FeAdd(&r.Y, &r.Z, &r.Y) + FeAdd(&r.Z, &t0, &r.T) + FeSub(&r.T, &t0, &r.T) +} + +func geMixedSub(r *CompletedGroupElement, p *ExtendedGroupElement, q *PreComputedGroupElement) { + var t0 FieldElement + + FeAdd(&r.X, &p.Y, &p.X) + FeSub(&r.Y, &p.Y, &p.X) + FeMul(&r.Z, &r.X, &q.yMinusX) + FeMul(&r.Y, &r.Y, &q.yPlusX) + FeMul(&r.T, &q.xy2d, &p.T) + FeAdd(&t0, &p.Z, &p.Z) + FeSub(&r.X, &r.Z, &r.Y) + FeAdd(&r.Y, &r.Z, &r.Y) + FeSub(&r.Z, &t0, &r.T) + FeAdd(&r.T, &t0, &r.T) +} + +func slide(r *[256]int8, a *[32]byte) { + for i := range r { + r[i] = int8(1 & (a[i>>3] >> uint(i&7))) + } + + for i := range r { + if r[i] != 0 { + for b := 1; b <= 6 && i+b < 256; b++ { + if r[i+b] != 0 { + if r[i]+(r[i+b]<= -15 { + r[i] -= r[i+b] << uint(b) + for k := i + b; k < 256; k++ { + if r[k] == 0 { + r[k] = 1 + break + } + r[k] = 0 + } + } else { + break + } + } + } + } + } +} + +// GeDoubleScalarMultVartime sets r = a*A + b*B +// where a = a[0]+256*a[1]+...+256^31 a[31]. +// and b = b[0]+256*b[1]+...+256^31 b[31]. +// B is the Ed25519 base point (x,4/5) with x positive. +func GeDoubleScalarMultVartime(r *ProjectiveGroupElement, a *[32]byte, A *ExtendedGroupElement, b *[32]byte) { + var aSlide, bSlide [256]int8 + var Ai [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A + var t CompletedGroupElement + var u, A2 ExtendedGroupElement + var i int + + slide(&aSlide, a) + slide(&bSlide, b) + + A.ToCached(&Ai[0]) + A.Double(&t) + t.ToExtended(&A2) + + for i := 0; i < 7; i++ { + geAdd(&t, &A2, &Ai[i]) + t.ToExtended(&u) + u.ToCached(&Ai[i+1]) + } + + r.Zero() + + for i = 255; i >= 0; i-- { + if aSlide[i] != 0 || bSlide[i] != 0 { + break + } + } + + for ; i >= 0; i-- { + r.Double(&t) + + if aSlide[i] > 0 { + t.ToExtended(&u) + geAdd(&t, &u, &Ai[aSlide[i]/2]) + } else if aSlide[i] < 0 { + t.ToExtended(&u) + geSub(&t, &u, &Ai[(-aSlide[i])/2]) + } + + if bSlide[i] > 0 { + t.ToExtended(&u) + geMixedAdd(&t, &u, &bi[bSlide[i]/2]) + } else if bSlide[i] < 0 { + t.ToExtended(&u) + geMixedSub(&t, &u, &bi[(-bSlide[i])/2]) + } + + t.ToProjective(r) + } +} + +// equal returns 1 if b == c and 0 otherwise, assuming that b and c are +// non-negative. +func equal(b, c int32) int32 { + x := uint32(b ^ c) + x-- + return int32(x >> 31) +} + +// negative returns 1 if b < 0 and 0 otherwise. +func negative(b int32) int32 { + return (b >> 31) & 1 +} + +func PreComputedGroupElementCMove(t, u *PreComputedGroupElement, b int32) { + FeCMove(&t.yPlusX, &u.yPlusX, b) + FeCMove(&t.yMinusX, &u.yMinusX, b) + FeCMove(&t.xy2d, &u.xy2d, b) +} + +func selectPoint(t *PreComputedGroupElement, pos int32, b int32) { + var minusT PreComputedGroupElement + bNegative := negative(b) + bAbs := b - (((-bNegative) & b) << 1) + + t.Zero() + for i := int32(0); i < 8; i++ { + PreComputedGroupElementCMove(t, &base[pos][i], equal(bAbs, i+1)) + } + FeCopy(&minusT.yPlusX, &t.yMinusX) + FeCopy(&minusT.yMinusX, &t.yPlusX) + FeNeg(&minusT.xy2d, &t.xy2d) + PreComputedGroupElementCMove(t, &minusT, bNegative) +} + +// GeScalarMultBase computes h = a*B, where +// a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base point (x,4/5) with x positive. +// +// Preconditions: +// a[31] <= 127 +func GeScalarMultBase(h *ExtendedGroupElement, a *[32]byte) { + var e [64]int8 + + for i, v := range a { + e[2*i] = int8(v & 15) + e[2*i+1] = int8((v >> 4) & 15) + } + + // each e[i] is between 0 and 15 and e[63] is between 0 and 7. + + carry := int8(0) + for i := 0; i < 63; i++ { + e[i] += carry + carry = (e[i] + 8) >> 4 + e[i] -= carry << 4 + } + e[63] += carry + // each e[i] is between -8 and 8. + + h.Zero() + var t PreComputedGroupElement + var r CompletedGroupElement + for i := int32(1); i < 64; i += 2 { + selectPoint(&t, i/2, int32(e[i])) + geMixedAdd(&r, h, &t) + r.ToExtended(h) + } + + var s ProjectiveGroupElement + + h.Double(&r) + r.ToProjective(&s) + s.Double(&r) + r.ToProjective(&s) + s.Double(&r) + r.ToProjective(&s) + s.Double(&r) + r.ToExtended(h) + + for i := int32(0); i < 64; i += 2 { + selectPoint(&t, i/2, int32(e[i])) + geMixedAdd(&r, h, &t) + r.ToExtended(h) + } +} + +// The scalars are GF(2^252 + 27742317777372353535851937790883648493). + +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// b[0]+256*b[1]+...+256^31*b[31] = b +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +func ScMulAdd(s, a, b, c *[32]byte) { + a0 := 2097151 & load3(a[:]) + a1 := 2097151 & (load4(a[2:]) >> 5) + a2 := 2097151 & (load3(a[5:]) >> 2) + a3 := 2097151 & (load4(a[7:]) >> 7) + a4 := 2097151 & (load4(a[10:]) >> 4) + a5 := 2097151 & (load3(a[13:]) >> 1) + a6 := 2097151 & (load4(a[15:]) >> 6) + a7 := 2097151 & (load3(a[18:]) >> 3) + a8 := 2097151 & load3(a[21:]) + a9 := 2097151 & (load4(a[23:]) >> 5) + a10 := 2097151 & (load3(a[26:]) >> 2) + a11 := (load4(a[28:]) >> 7) + b0 := 2097151 & load3(b[:]) + b1 := 2097151 & (load4(b[2:]) >> 5) + b2 := 2097151 & (load3(b[5:]) >> 2) + b3 := 2097151 & (load4(b[7:]) >> 7) + b4 := 2097151 & (load4(b[10:]) >> 4) + b5 := 2097151 & (load3(b[13:]) >> 1) + b6 := 2097151 & (load4(b[15:]) >> 6) + b7 := 2097151 & (load3(b[18:]) >> 3) + b8 := 2097151 & load3(b[21:]) + b9 := 2097151 & (load4(b[23:]) >> 5) + b10 := 2097151 & (load3(b[26:]) >> 2) + b11 := (load4(b[28:]) >> 7) + c0 := 2097151 & load3(c[:]) + c1 := 2097151 & (load4(c[2:]) >> 5) + c2 := 2097151 & (load3(c[5:]) >> 2) + c3 := 2097151 & (load4(c[7:]) >> 7) + c4 := 2097151 & (load4(c[10:]) >> 4) + c5 := 2097151 & (load3(c[13:]) >> 1) + c6 := 2097151 & (load4(c[15:]) >> 6) + c7 := 2097151 & (load3(c[18:]) >> 3) + c8 := 2097151 & load3(c[21:]) + c9 := 2097151 & (load4(c[23:]) >> 5) + c10 := 2097151 & (load3(c[26:]) >> 2) + c11 := (load4(c[28:]) >> 7) + var carry [23]int64 + + s0 := c0 + a0*b0 + s1 := c1 + a0*b1 + a1*b0 + s2 := c2 + a0*b2 + a1*b1 + a2*b0 + s3 := c3 + a0*b3 + a1*b2 + a2*b1 + a3*b0 + s4 := c4 + a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0 + s5 := c5 + a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0 + s6 := c6 + a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0 + s7 := c7 + a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0 + s8 := c8 + a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0 + s9 := c9 + a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0 + s10 := c10 + a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0 + s11 := c11 + a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0 + s12 := a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1 + s13 := a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2 + s14 := a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3 + s15 := a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4 + s16 := a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5 + s17 := a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6 + s18 := a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7 + s19 := a8*b11 + a9*b10 + a10*b9 + a11*b8 + s20 := a9*b11 + a10*b10 + a11*b9 + s21 := a10*b11 + a11*b10 + s22 := a11 * b11 + s23 := int64(0) + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + carry[18] = (s18 + (1 << 20)) >> 21 + s19 += carry[18] + s18 -= carry[18] << 21 + carry[20] = (s20 + (1 << 20)) >> 21 + s21 += carry[20] + s20 -= carry[20] << 21 + carry[22] = (s22 + (1 << 20)) >> 21 + s23 += carry[22] + s22 -= carry[22] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + carry[17] = (s17 + (1 << 20)) >> 21 + s18 += carry[17] + s17 -= carry[17] << 21 + carry[19] = (s19 + (1 << 20)) >> 21 + s20 += carry[19] + s19 -= carry[19] << 21 + carry[21] = (s21 + (1 << 20)) >> 21 + s22 += carry[21] + s21 -= carry[21] << 21 + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + s[0] = byte(s0 >> 0) + s[1] = byte(s0 >> 8) + s[2] = byte((s0 >> 16) | (s1 << 5)) + s[3] = byte(s1 >> 3) + s[4] = byte(s1 >> 11) + s[5] = byte((s1 >> 19) | (s2 << 2)) + s[6] = byte(s2 >> 6) + s[7] = byte((s2 >> 14) | (s3 << 7)) + s[8] = byte(s3 >> 1) + s[9] = byte(s3 >> 9) + s[10] = byte((s3 >> 17) | (s4 << 4)) + s[11] = byte(s4 >> 4) + s[12] = byte(s4 >> 12) + s[13] = byte((s4 >> 20) | (s5 << 1)) + s[14] = byte(s5 >> 7) + s[15] = byte((s5 >> 15) | (s6 << 6)) + s[16] = byte(s6 >> 2) + s[17] = byte(s6 >> 10) + s[18] = byte((s6 >> 18) | (s7 << 3)) + s[19] = byte(s7 >> 5) + s[20] = byte(s7 >> 13) + s[21] = byte(s8 >> 0) + s[22] = byte(s8 >> 8) + s[23] = byte((s8 >> 16) | (s9 << 5)) + s[24] = byte(s9 >> 3) + s[25] = byte(s9 >> 11) + s[26] = byte((s9 >> 19) | (s10 << 2)) + s[27] = byte(s10 >> 6) + s[28] = byte((s10 >> 14) | (s11 << 7)) + s[29] = byte(s11 >> 1) + s[30] = byte(s11 >> 9) + s[31] = byte(s11 >> 17) +} + +// Input: +// s[0]+256*s[1]+...+256^63*s[63] = s +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = s mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +func ScReduce(out *[32]byte, s *[64]byte) { + s0 := 2097151 & load3(s[:]) + s1 := 2097151 & (load4(s[2:]) >> 5) + s2 := 2097151 & (load3(s[5:]) >> 2) + s3 := 2097151 & (load4(s[7:]) >> 7) + s4 := 2097151 & (load4(s[10:]) >> 4) + s5 := 2097151 & (load3(s[13:]) >> 1) + s6 := 2097151 & (load4(s[15:]) >> 6) + s7 := 2097151 & (load3(s[18:]) >> 3) + s8 := 2097151 & load3(s[21:]) + s9 := 2097151 & (load4(s[23:]) >> 5) + s10 := 2097151 & (load3(s[26:]) >> 2) + s11 := 2097151 & (load4(s[28:]) >> 7) + s12 := 2097151 & (load4(s[31:]) >> 4) + s13 := 2097151 & (load3(s[34:]) >> 1) + s14 := 2097151 & (load4(s[36:]) >> 6) + s15 := 2097151 & (load3(s[39:]) >> 3) + s16 := 2097151 & load3(s[42:]) + s17 := 2097151 & (load4(s[44:]) >> 5) + s18 := 2097151 & (load3(s[47:]) >> 2) + s19 := 2097151 & (load4(s[49:]) >> 7) + s20 := 2097151 & (load4(s[52:]) >> 4) + s21 := 2097151 & (load3(s[55:]) >> 1) + s22 := 2097151 & (load4(s[57:]) >> 6) + s23 := (load4(s[60:]) >> 3) + + s11 += s23 * 666643 + s12 += s23 * 470296 + s13 += s23 * 654183 + s14 -= s23 * 997805 + s15 += s23 * 136657 + s16 -= s23 * 683901 + s23 = 0 + + s10 += s22 * 666643 + s11 += s22 * 470296 + s12 += s22 * 654183 + s13 -= s22 * 997805 + s14 += s22 * 136657 + s15 -= s22 * 683901 + s22 = 0 + + s9 += s21 * 666643 + s10 += s21 * 470296 + s11 += s21 * 654183 + s12 -= s21 * 997805 + s13 += s21 * 136657 + s14 -= s21 * 683901 + s21 = 0 + + s8 += s20 * 666643 + s9 += s20 * 470296 + s10 += s20 * 654183 + s11 -= s20 * 997805 + s12 += s20 * 136657 + s13 -= s20 * 683901 + s20 = 0 + + s7 += s19 * 666643 + s8 += s19 * 470296 + s9 += s19 * 654183 + s10 -= s19 * 997805 + s11 += s19 * 136657 + s12 -= s19 * 683901 + s19 = 0 + + s6 += s18 * 666643 + s7 += s18 * 470296 + s8 += s18 * 654183 + s9 -= s18 * 997805 + s10 += s18 * 136657 + s11 -= s18 * 683901 + s18 = 0 + + var carry [17]int64 + + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[12] = (s12 + (1 << 20)) >> 21 + s13 += carry[12] + s12 -= carry[12] << 21 + carry[14] = (s14 + (1 << 20)) >> 21 + s15 += carry[14] + s14 -= carry[14] << 21 + carry[16] = (s16 + (1 << 20)) >> 21 + s17 += carry[16] + s16 -= carry[16] << 21 + + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + carry[13] = (s13 + (1 << 20)) >> 21 + s14 += carry[13] + s13 -= carry[13] << 21 + carry[15] = (s15 + (1 << 20)) >> 21 + s16 += carry[15] + s15 -= carry[15] << 21 + + s5 += s17 * 666643 + s6 += s17 * 470296 + s7 += s17 * 654183 + s8 -= s17 * 997805 + s9 += s17 * 136657 + s10 -= s17 * 683901 + s17 = 0 + + s4 += s16 * 666643 + s5 += s16 * 470296 + s6 += s16 * 654183 + s7 -= s16 * 997805 + s8 += s16 * 136657 + s9 -= s16 * 683901 + s16 = 0 + + s3 += s15 * 666643 + s4 += s15 * 470296 + s5 += s15 * 654183 + s6 -= s15 * 997805 + s7 += s15 * 136657 + s8 -= s15 * 683901 + s15 = 0 + + s2 += s14 * 666643 + s3 += s14 * 470296 + s4 += s14 * 654183 + s5 -= s14 * 997805 + s6 += s14 * 136657 + s7 -= s14 * 683901 + s14 = 0 + + s1 += s13 * 666643 + s2 += s13 * 470296 + s3 += s13 * 654183 + s4 -= s13 * 997805 + s5 += s13 * 136657 + s6 -= s13 * 683901 + s13 = 0 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = (s0 + (1 << 20)) >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[2] = (s2 + (1 << 20)) >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[4] = (s4 + (1 << 20)) >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[6] = (s6 + (1 << 20)) >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[8] = (s8 + (1 << 20)) >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[10] = (s10 + (1 << 20)) >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + carry[1] = (s1 + (1 << 20)) >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[3] = (s3 + (1 << 20)) >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[5] = (s5 + (1 << 20)) >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[7] = (s7 + (1 << 20)) >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[9] = (s9 + (1 << 20)) >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[11] = (s11 + (1 << 20)) >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + carry[11] = s11 >> 21 + s12 += carry[11] + s11 -= carry[11] << 21 + + s0 += s12 * 666643 + s1 += s12 * 470296 + s2 += s12 * 654183 + s3 -= s12 * 997805 + s4 += s12 * 136657 + s5 -= s12 * 683901 + s12 = 0 + + carry[0] = s0 >> 21 + s1 += carry[0] + s0 -= carry[0] << 21 + carry[1] = s1 >> 21 + s2 += carry[1] + s1 -= carry[1] << 21 + carry[2] = s2 >> 21 + s3 += carry[2] + s2 -= carry[2] << 21 + carry[3] = s3 >> 21 + s4 += carry[3] + s3 -= carry[3] << 21 + carry[4] = s4 >> 21 + s5 += carry[4] + s4 -= carry[4] << 21 + carry[5] = s5 >> 21 + s6 += carry[5] + s5 -= carry[5] << 21 + carry[6] = s6 >> 21 + s7 += carry[6] + s6 -= carry[6] << 21 + carry[7] = s7 >> 21 + s8 += carry[7] + s7 -= carry[7] << 21 + carry[8] = s8 >> 21 + s9 += carry[8] + s8 -= carry[8] << 21 + carry[9] = s9 >> 21 + s10 += carry[9] + s9 -= carry[9] << 21 + carry[10] = s10 >> 21 + s11 += carry[10] + s10 -= carry[10] << 21 + + out[0] = byte(s0 >> 0) + out[1] = byte(s0 >> 8) + out[2] = byte((s0 >> 16) | (s1 << 5)) + out[3] = byte(s1 >> 3) + out[4] = byte(s1 >> 11) + out[5] = byte((s1 >> 19) | (s2 << 2)) + out[6] = byte(s2 >> 6) + out[7] = byte((s2 >> 14) | (s3 << 7)) + out[8] = byte(s3 >> 1) + out[9] = byte(s3 >> 9) + out[10] = byte((s3 >> 17) | (s4 << 4)) + out[11] = byte(s4 >> 4) + out[12] = byte(s4 >> 12) + out[13] = byte((s4 >> 20) | (s5 << 1)) + out[14] = byte(s5 >> 7) + out[15] = byte((s5 >> 15) | (s6 << 6)) + out[16] = byte(s6 >> 2) + out[17] = byte(s6 >> 10) + out[18] = byte((s6 >> 18) | (s7 << 3)) + out[19] = byte(s7 >> 5) + out[20] = byte(s7 >> 13) + out[21] = byte(s8 >> 0) + out[22] = byte(s8 >> 8) + out[23] = byte((s8 >> 16) | (s9 << 5)) + out[24] = byte(s9 >> 3) + out[25] = byte(s9 >> 11) + out[26] = byte((s9 >> 19) | (s10 << 2)) + out[27] = byte(s10 >> 6) + out[28] = byte((s10 >> 14) | (s11 << 7)) + out[29] = byte(s11 >> 1) + out[30] = byte(s11 >> 9) + out[31] = byte(s11 >> 17) +} + +// order is the order of Curve25519 in little-endian form. +var order = [4]uint64{0x5812631a5cf5d3ed, 0x14def9dea2f79cd6, 0, 0x1000000000000000} + +// ScMinimal returns true if the given scalar is less than the order of the +// curve. +func ScMinimal(scalar *[32]byte) bool { + for i := 3; ; i-- { + v := binary.LittleEndian.Uint64(scalar[i*8:]) + if v > order[i] { + return false + } else if v < order[i] { + break + } else if i == 0 { + return false + } + } + + return true +} diff --git a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_arm64.go b/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_arm64.go deleted file mode 100644 index ad74e23aef4..00000000000 --- a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_arm64.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build go1.11 -// +build !gccgo - -package chacha20 - -const ( - haveAsm = true - bufSize = 256 -) - -//go:noescape -func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32) - -func (c *Cipher) xorKeyStreamAsm(dst, src []byte) { - - if len(src) >= bufSize { - xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter) - } - - if len(src)%bufSize != 0 { - i := len(src) - len(src)%bufSize - c.buf = [bufSize]byte{} - copy(c.buf[:], src[i:]) - xorKeyStreamVX(c.buf[:], c.buf[:], &c.key, &c.nonce, &c.counter) - c.len = bufSize - copy(dst[i:], c.buf[:len(src)%bufSize]) - } -} diff --git a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_generic.go b/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_generic.go deleted file mode 100644 index 6570847f5e0..00000000000 --- a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_generic.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ChaCha20 implements the core ChaCha20 function as specified -// in https://tools.ietf.org/html/rfc7539#section-2.3. -package chacha20 - -import ( - "crypto/cipher" - "encoding/binary" - - "golang.org/x/crypto/internal/subtle" -) - -// assert that *Cipher implements cipher.Stream -var _ cipher.Stream = (*Cipher)(nil) - -// Cipher is a stateful instance of ChaCha20 using a particular key -// and nonce. A *Cipher implements the cipher.Stream interface. -type Cipher struct { - key [8]uint32 - counter uint32 // incremented after each block - nonce [3]uint32 - buf [bufSize]byte // buffer for unused keystream bytes - len int // number of unused keystream bytes at end of buf -} - -// New creates a new ChaCha20 stream cipher with the given key and nonce. -// The initial counter value is set to 0. -func New(key [8]uint32, nonce [3]uint32) *Cipher { - return &Cipher{key: key, nonce: nonce} -} - -// ChaCha20 constants spelling "expand 32-byte k" -const ( - j0 uint32 = 0x61707865 - j1 uint32 = 0x3320646e - j2 uint32 = 0x79622d32 - j3 uint32 = 0x6b206574 -) - -func quarterRound(a, b, c, d uint32) (uint32, uint32, uint32, uint32) { - a += b - d ^= a - d = (d << 16) | (d >> 16) - c += d - b ^= c - b = (b << 12) | (b >> 20) - a += b - d ^= a - d = (d << 8) | (d >> 24) - c += d - b ^= c - b = (b << 7) | (b >> 25) - return a, b, c, d -} - -// XORKeyStream XORs each byte in the given slice with a byte from the -// cipher's key stream. Dst and src must overlap entirely or not at all. -// -// If len(dst) < len(src), XORKeyStream will panic. It is acceptable -// to pass a dst bigger than src, and in that case, XORKeyStream will -// only update dst[:len(src)] and will not touch the rest of dst. -// -// Multiple calls to XORKeyStream behave as if the concatenation of -// the src buffers was passed in a single run. That is, Cipher -// maintains state and does not reset at each XORKeyStream call. -func (s *Cipher) XORKeyStream(dst, src []byte) { - if len(dst) < len(src) { - panic("chacha20: output smaller than input") - } - if subtle.InexactOverlap(dst[:len(src)], src) { - panic("chacha20: invalid buffer overlap") - } - - // xor src with buffered keystream first - if s.len != 0 { - buf := s.buf[len(s.buf)-s.len:] - if len(src) < len(buf) { - buf = buf[:len(src)] - } - td, ts := dst[:len(buf)], src[:len(buf)] // BCE hint - for i, b := range buf { - td[i] = ts[i] ^ b - } - s.len -= len(buf) - if s.len != 0 { - return - } - s.buf = [len(s.buf)]byte{} // zero the empty buffer - src = src[len(buf):] - dst = dst[len(buf):] - } - - if len(src) == 0 { - return - } - if haveAsm { - if uint64(len(src))+uint64(s.counter)*64 > (1<<38)-64 { - panic("chacha20: counter overflow") - } - s.xorKeyStreamAsm(dst, src) - return - } - - // set up a 64-byte buffer to pad out the final block if needed - // (hoisted out of the main loop to avoid spills) - rem := len(src) % 64 // length of final block - fin := len(src) - rem // index of final block - if rem > 0 { - copy(s.buf[len(s.buf)-64:], src[fin:]) - } - - // pre-calculate most of the first round - s1, s5, s9, s13 := quarterRound(j1, s.key[1], s.key[5], s.nonce[0]) - s2, s6, s10, s14 := quarterRound(j2, s.key[2], s.key[6], s.nonce[1]) - s3, s7, s11, s15 := quarterRound(j3, s.key[3], s.key[7], s.nonce[2]) - - n := len(src) - src, dst = src[:n:n], dst[:n:n] // BCE hint - for i := 0; i < n; i += 64 { - // calculate the remainder of the first round - s0, s4, s8, s12 := quarterRound(j0, s.key[0], s.key[4], s.counter) - - // execute the second round - x0, x5, x10, x15 := quarterRound(s0, s5, s10, s15) - x1, x6, x11, x12 := quarterRound(s1, s6, s11, s12) - x2, x7, x8, x13 := quarterRound(s2, s7, s8, s13) - x3, x4, x9, x14 := quarterRound(s3, s4, s9, s14) - - // execute the remaining 18 rounds - for i := 0; i < 9; i++ { - x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12) - x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13) - x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14) - x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15) - - x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15) - x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12) - x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13) - x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14) - } - - x0 += j0 - x1 += j1 - x2 += j2 - x3 += j3 - - x4 += s.key[0] - x5 += s.key[1] - x6 += s.key[2] - x7 += s.key[3] - x8 += s.key[4] - x9 += s.key[5] - x10 += s.key[6] - x11 += s.key[7] - - x12 += s.counter - x13 += s.nonce[0] - x14 += s.nonce[1] - x15 += s.nonce[2] - - // increment the counter - s.counter += 1 - if s.counter == 0 { - panic("chacha20: counter overflow") - } - - // pad to 64 bytes if needed - in, out := src[i:], dst[i:] - if i == fin { - // src[fin:] has already been copied into s.buf before - // the main loop - in, out = s.buf[len(s.buf)-64:], s.buf[len(s.buf)-64:] - } - in, out = in[:64], out[:64] // BCE hint - - // XOR the key stream with the source and write out the result - xor(out[0:], in[0:], x0) - xor(out[4:], in[4:], x1) - xor(out[8:], in[8:], x2) - xor(out[12:], in[12:], x3) - xor(out[16:], in[16:], x4) - xor(out[20:], in[20:], x5) - xor(out[24:], in[24:], x6) - xor(out[28:], in[28:], x7) - xor(out[32:], in[32:], x8) - xor(out[36:], in[36:], x9) - xor(out[40:], in[40:], x10) - xor(out[44:], in[44:], x11) - xor(out[48:], in[48:], x12) - xor(out[52:], in[52:], x13) - xor(out[56:], in[56:], x14) - xor(out[60:], in[60:], x15) - } - // copy any trailing bytes out of the buffer and into dst - if rem != 0 { - s.len = 64 - rem - copy(dst[fin:], s.buf[len(s.buf)-64:]) - } -} - -// Advance discards bytes in the key stream until the next 64 byte block -// boundary is reached and updates the counter accordingly. If the key -// stream is already at a block boundary no bytes will be discarded and -// the counter will be unchanged. -func (s *Cipher) Advance() { - s.len -= s.len % 64 - if s.len == 0 { - s.buf = [len(s.buf)]byte{} - } -} - -// XORKeyStream crypts bytes from in to out using the given key and counters. -// In and out must overlap entirely or not at all. Counter contains the raw -// ChaCha20 counter bytes (i.e. block counter followed by nonce). -func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { - s := Cipher{ - key: [8]uint32{ - binary.LittleEndian.Uint32(key[0:4]), - binary.LittleEndian.Uint32(key[4:8]), - binary.LittleEndian.Uint32(key[8:12]), - binary.LittleEndian.Uint32(key[12:16]), - binary.LittleEndian.Uint32(key[16:20]), - binary.LittleEndian.Uint32(key[20:24]), - binary.LittleEndian.Uint32(key[24:28]), - binary.LittleEndian.Uint32(key[28:32]), - }, - nonce: [3]uint32{ - binary.LittleEndian.Uint32(counter[4:8]), - binary.LittleEndian.Uint32(counter[8:12]), - binary.LittleEndian.Uint32(counter[12:16]), - }, - counter: binary.LittleEndian.Uint32(counter[0:4]), - } - s.XORKeyStream(out, in) -} - -// HChaCha20 uses the ChaCha20 core to generate a derived key from a key and a -// nonce. It should only be used as part of the XChaCha20 construction. -func HChaCha20(key *[8]uint32, nonce *[4]uint32) [8]uint32 { - x0, x1, x2, x3 := j0, j1, j2, j3 - x4, x5, x6, x7 := key[0], key[1], key[2], key[3] - x8, x9, x10, x11 := key[4], key[5], key[6], key[7] - x12, x13, x14, x15 := nonce[0], nonce[1], nonce[2], nonce[3] - - for i := 0; i < 10; i++ { - x0, x4, x8, x12 = quarterRound(x0, x4, x8, x12) - x1, x5, x9, x13 = quarterRound(x1, x5, x9, x13) - x2, x6, x10, x14 = quarterRound(x2, x6, x10, x14) - x3, x7, x11, x15 = quarterRound(x3, x7, x11, x15) - - x0, x5, x10, x15 = quarterRound(x0, x5, x10, x15) - x1, x6, x11, x12 = quarterRound(x1, x6, x11, x12) - x2, x7, x8, x13 = quarterRound(x2, x7, x8, x13) - x3, x4, x9, x14 = quarterRound(x3, x4, x9, x14) - } - - var out [8]uint32 - out[0], out[1], out[2], out[3] = x0, x1, x2, x3 - out[4], out[5], out[6], out[7] = x12, x13, x14, x15 - return out -} diff --git a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_noasm.go b/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_noasm.go deleted file mode 100644 index bf8beba6708..00000000000 --- a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_noasm.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build !ppc64le,!arm64,!s390x arm64,!go1.11 gccgo appengine - -package chacha20 - -const ( - bufSize = 64 - haveAsm = false -) - -func (*Cipher) xorKeyStreamAsm(dst, src []byte) { - panic("not implemented") -} diff --git a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_ppc64le.go b/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_ppc64le.go deleted file mode 100644 index 638cb5e5de5..00000000000 --- a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_ppc64le.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ppc64le,!gccgo,!appengine - -package chacha20 - -import "encoding/binary" - -const ( - bufSize = 256 - haveAsm = true -) - -//go:noescape -func chaCha20_ctr32_vmx(out, inp *byte, len int, key *[8]uint32, counter *uint32) - -func (c *Cipher) xorKeyStreamAsm(dst, src []byte) { - if len(src) >= bufSize { - chaCha20_ctr32_vmx(&dst[0], &src[0], len(src)-len(src)%bufSize, &c.key, &c.counter) - } - if len(src)%bufSize != 0 { - chaCha20_ctr32_vmx(&c.buf[0], &c.buf[0], bufSize, &c.key, &c.counter) - start := len(src) - len(src)%bufSize - ts, td, tb := src[start:], dst[start:], c.buf[:] - // Unroll loop to XOR 32 bytes per iteration. - for i := 0; i < len(ts)-32; i += 32 { - td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination - s0 := binary.LittleEndian.Uint64(ts[0:8]) - s1 := binary.LittleEndian.Uint64(ts[8:16]) - s2 := binary.LittleEndian.Uint64(ts[16:24]) - s3 := binary.LittleEndian.Uint64(ts[24:32]) - b0 := binary.LittleEndian.Uint64(tb[0:8]) - b1 := binary.LittleEndian.Uint64(tb[8:16]) - b2 := binary.LittleEndian.Uint64(tb[16:24]) - b3 := binary.LittleEndian.Uint64(tb[24:32]) - binary.LittleEndian.PutUint64(td[0:8], s0^b0) - binary.LittleEndian.PutUint64(td[8:16], s1^b1) - binary.LittleEndian.PutUint64(td[16:24], s2^b2) - binary.LittleEndian.PutUint64(td[24:32], s3^b3) - ts, td, tb = ts[32:], td[32:], tb[32:] - } - td, tb = td[:len(ts)], tb[:len(ts)] // bounds check elimination - for i, v := range ts { - td[i] = tb[i] ^ v - } - c.len = bufSize - (len(src) % bufSize) - - } - -} diff --git a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_s390x.go b/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_s390x.go deleted file mode 100644 index aad645b4476..00000000000 --- a/libgo/go/golang.org/x/crypto/internal/chacha20/chacha_s390x.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build s390x,!gccgo,!appengine - -package chacha20 - -import ( - "golang.org/x/sys/cpu" -) - -var haveAsm = cpu.S390X.HasVX - -const bufSize = 256 - -// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only -// be called when the vector facility is available. -// Implementation in asm_s390x.s. -//go:noescape -func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32, buf *[256]byte, len *int) - -func (c *Cipher) xorKeyStreamAsm(dst, src []byte) { - xorKeyStreamVX(dst, src, &c.key, &c.nonce, &c.counter, &c.buf, &c.len) -} - -// EXRL targets, DO NOT CALL! -func mvcSrcToBuf() -func mvcBufToDst() diff --git a/libgo/go/golang.org/x/crypto/internal/chacha20/xor.go b/libgo/go/golang.org/x/crypto/internal/chacha20/xor.go deleted file mode 100644 index 9c5ba0b33ae..00000000000 --- a/libgo/go/golang.org/x/crypto/internal/chacha20/xor.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found src the LICENSE file. - -package chacha20 - -import ( - "runtime" -) - -// Platforms that have fast unaligned 32-bit little endian accesses. -const unaligned = runtime.GOARCH == "386" || - runtime.GOARCH == "amd64" || - runtime.GOARCH == "arm64" || - runtime.GOARCH == "ppc64le" || - runtime.GOARCH == "s390x" - -// xor reads a little endian uint32 from src, XORs it with u and -// places the result in little endian byte order in dst. -func xor(dst, src []byte, u uint32) { - _, _ = src[3], dst[3] // eliminate bounds checks - if unaligned { - // The compiler should optimize this code into - // 32-bit unaligned little endian loads and stores. - // TODO: delete once the compiler does a reliably - // good job with the generic code below. - // See issue #25111 for more details. - v := uint32(src[0]) - v |= uint32(src[1]) << 8 - v |= uint32(src[2]) << 16 - v |= uint32(src[3]) << 24 - v ^= u - dst[0] = byte(v) - dst[1] = byte(v >> 8) - dst[2] = byte(v >> 16) - dst[3] = byte(v >> 24) - } else { - dst[0] = src[0] ^ byte(u) - dst[1] = src[1] ^ byte(u>>8) - dst[2] = src[2] ^ byte(u>>16) - dst[3] = src[3] ^ byte(u>>24) - } -} diff --git a/libgo/go/golang.org/x/crypto/poly1305/bits_compat.go b/libgo/go/golang.org/x/crypto/poly1305/bits_compat.go new file mode 100644 index 00000000000..157a69f61bd --- /dev/null +++ b/libgo/go/golang.org/x/crypto/poly1305/bits_compat.go @@ -0,0 +1,39 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.13 + +package poly1305 + +// Generic fallbacks for the math/bits intrinsics, copied from +// src/math/bits/bits.go. They were added in Go 1.12, but Add64 and Sum64 had +// variable time fallbacks until Go 1.13. + +func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) { + sum = x + y + carry + carryOut = ((x & y) | ((x | y) &^ sum)) >> 63 + return +} + +func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) { + diff = x - y - borrow + borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63 + return +} + +func bitsMul64(x, y uint64) (hi, lo uint64) { + const mask32 = 1<<32 - 1 + x0 := x & mask32 + x1 := x >> 32 + y0 := y & mask32 + y1 := y >> 32 + w0 := x0 * y0 + t := x1*y0 + w0>>32 + w1 := t & mask32 + w2 := t >> 32 + w1 += x0 * y1 + hi = x1*y1 + w2 + w1>>32 + lo = x * y + return +} diff --git a/libgo/go/golang.org/x/crypto/poly1305/bits_go1.13.go b/libgo/go/golang.org/x/crypto/poly1305/bits_go1.13.go new file mode 100644 index 00000000000..a0a185f0fc7 --- /dev/null +++ b/libgo/go/golang.org/x/crypto/poly1305/bits_go1.13.go @@ -0,0 +1,21 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.13 + +package poly1305 + +import "math/bits" + +func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) { + return bits.Add64(x, y, carry) +} + +func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) { + return bits.Sub64(x, y, borrow) +} + +func bitsMul64(x, y uint64) (hi, lo uint64) { + return bits.Mul64(x, y) +} diff --git a/libgo/go/golang.org/x/crypto/poly1305/poly1305.go b/libgo/go/golang.org/x/crypto/poly1305/poly1305.go index d076a562351..066159b797d 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/poly1305.go +++ b/libgo/go/golang.org/x/crypto/poly1305/poly1305.go @@ -22,8 +22,14 @@ import "crypto/subtle" // TagSize is the size, in bytes, of a poly1305 authenticator. const TagSize = 16 -// Verify returns true if mac is a valid authenticator for m with the given -// key. +// Sum generates an authenticator for msg using a one-time key and puts the +// 16-byte result into out. Authenticating two different messages with the same +// key allows an attacker to forge messages at will. +func Sum(out *[16]byte, m []byte, key *[32]byte) { + sum(out, m, key) +} + +// Verify returns true if mac is a valid authenticator for m with the given key. func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { var tmp [16]byte Sum(&tmp, m, key) diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_amd64.go b/libgo/go/golang.org/x/crypto/poly1305/sum_amd64.go index 2dbf42aa537..df56a652ff0 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_amd64.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_amd64.go @@ -7,62 +7,52 @@ package poly1305 //go:noescape -func initialize(state *[7]uint64, key *[32]byte) +func update(state *macState, msg []byte) -//go:noescape -func update(state *[7]uint64, msg []byte) - -//go:noescape -func finalize(tag *[TagSize]byte, state *[7]uint64) - -// Sum generates an authenticator for m using a one-time key and puts the -// 16-byte result into out. Authenticating two different messages with the same -// key allows an attacker to forge messages at will. -func Sum(out *[16]byte, m []byte, key *[32]byte) { +func sum(out *[16]byte, m []byte, key *[32]byte) { h := newMAC(key) h.Write(m) h.Sum(out) } func newMAC(key *[32]byte) (h mac) { - initialize(&h.state, key) + initialize(key, &h.r, &h.s) return } -type mac struct { - state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 } - - buffer [TagSize]byte - offset int -} +// mac is a wrapper for macGeneric that redirects calls that would have gone to +// updateGeneric to update. +// +// Its Write and Sum methods are otherwise identical to the macGeneric ones, but +// using function pointers would carry a major performance cost. +type mac struct{ macGeneric } -func (h *mac) Write(p []byte) (n int, err error) { - n = len(p) +func (h *mac) Write(p []byte) (int, error) { + nn := len(p) if h.offset > 0 { - remaining := TagSize - h.offset - if n < remaining { - h.offset += copy(h.buffer[h.offset:], p) - return n, nil + n := copy(h.buffer[h.offset:], p) + if h.offset+n < TagSize { + h.offset += n + return nn, nil } - copy(h.buffer[h.offset:], p[:remaining]) - p = p[remaining:] + p = p[n:] h.offset = 0 - update(&h.state, h.buffer[:]) + update(&h.macState, h.buffer[:]) } - if nn := len(p) - (len(p) % TagSize); nn > 0 { - update(&h.state, p[:nn]) - p = p[nn:] + if n := len(p) - (len(p) % TagSize); n > 0 { + update(&h.macState, p[:n]) + p = p[n:] } if len(p) > 0 { h.offset += copy(h.buffer[h.offset:], p) } - return n, nil + return nn, nil } func (h *mac) Sum(out *[16]byte) { - state := h.state + state := h.macState if h.offset > 0 { update(&state, h.buffer[:h.offset]) } - finalize(out, &state) + finalize(out, &state.h, &state.s) } diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_arm.go b/libgo/go/golang.org/x/crypto/poly1305/sum_arm.go index 5dc321c2f39..6e695e4272e 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_arm.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_arm.go @@ -6,14 +6,11 @@ package poly1305 -// This function is implemented in sum_arm.s +// poly1305_auth_armv6 is implemented in sum_arm.s //go:noescape func poly1305_auth_armv6(out *[16]byte, m *byte, mlen uint32, key *[32]byte) -// Sum generates an authenticator for m using a one-time key and puts the -// 16-byte result into out. Authenticating two different messages with the same -// key allows an attacker to forge messages at will. -func Sum(out *[16]byte, m []byte, key *[32]byte) { +func sum(out *[16]byte, m []byte, key *[32]byte) { var mPtr *byte if len(m) > 0 { mPtr = &m[0] diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_generic.go b/libgo/go/golang.org/x/crypto/poly1305/sum_generic.go index bab76ef0d83..1187eab78fd 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_generic.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_generic.go @@ -2,18 +2,29 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// This file provides the generic implementation of Sum and MAC. Other files +// might provide optimized assembly implementations of some of this code. + package poly1305 import "encoding/binary" -const ( - msgBlock = uint32(1 << 24) - finalBlock = uint32(0) -) +// Poly1305 [RFC 7539] is a relatively simple algorithm: the authentication tag +// for a 64 bytes message is approximately +// +// s + m[0:16] * r⁴ + m[16:32] * r³ + m[32:48] * r² + m[48:64] * r mod 2¹³⁰ - 5 +// +// for some secret r and s. It can be computed sequentially like +// +// for len(msg) > 0: +// h += read(msg, 16) +// h *= r +// h %= 2¹³⁰ - 5 +// return h + s +// +// All the complexity is about doing performant constant-time math on numbers +// larger than any available numeric type. -// sumGeneric generates an authenticator for msg using a one-time key and -// puts the 16-byte result into out. This is the generic implementation of -// Sum and should be called if no assembly implementation is available. func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) { h := newMACGeneric(key) h.Write(msg) @@ -21,152 +32,276 @@ func sumGeneric(out *[TagSize]byte, msg []byte, key *[32]byte) { } func newMACGeneric(key *[32]byte) (h macGeneric) { - h.r[0] = binary.LittleEndian.Uint32(key[0:]) & 0x3ffffff - h.r[1] = (binary.LittleEndian.Uint32(key[3:]) >> 2) & 0x3ffff03 - h.r[2] = (binary.LittleEndian.Uint32(key[6:]) >> 4) & 0x3ffc0ff - h.r[3] = (binary.LittleEndian.Uint32(key[9:]) >> 6) & 0x3f03fff - h.r[4] = (binary.LittleEndian.Uint32(key[12:]) >> 8) & 0x00fffff - - h.s[0] = binary.LittleEndian.Uint32(key[16:]) - h.s[1] = binary.LittleEndian.Uint32(key[20:]) - h.s[2] = binary.LittleEndian.Uint32(key[24:]) - h.s[3] = binary.LittleEndian.Uint32(key[28:]) + initialize(key, &h.r, &h.s) return } +// macState holds numbers in saturated 64-bit little-endian limbs. That is, +// the value of [x0, x1, x2] is x[0] + x[1] * 2⁶⁴ + x[2] * 2¹²⁸. +type macState struct { + // h is the main accumulator. It is to be interpreted modulo 2¹³⁰ - 5, but + // can grow larger during and after rounds. + h [3]uint64 + // r and s are the private key components. + r [2]uint64 + s [2]uint64 +} + type macGeneric struct { - h, r [5]uint32 - s [4]uint32 + macState buffer [TagSize]byte offset int } -func (h *macGeneric) Write(p []byte) (n int, err error) { - n = len(p) +// Write splits the incoming message into TagSize chunks, and passes them to +// update. It buffers incomplete chunks. +func (h *macGeneric) Write(p []byte) (int, error) { + nn := len(p) if h.offset > 0 { - remaining := TagSize - h.offset - if n < remaining { - h.offset += copy(h.buffer[h.offset:], p) - return n, nil + n := copy(h.buffer[h.offset:], p) + if h.offset+n < TagSize { + h.offset += n + return nn, nil } - copy(h.buffer[h.offset:], p[:remaining]) - p = p[remaining:] + p = p[n:] h.offset = 0 - updateGeneric(h.buffer[:], msgBlock, &(h.h), &(h.r)) + updateGeneric(&h.macState, h.buffer[:]) } - if nn := len(p) - (len(p) % TagSize); nn > 0 { - updateGeneric(p, msgBlock, &(h.h), &(h.r)) - p = p[nn:] + if n := len(p) - (len(p) % TagSize); n > 0 { + updateGeneric(&h.macState, p[:n]) + p = p[n:] } if len(p) > 0 { h.offset += copy(h.buffer[h.offset:], p) } - return n, nil + return nn, nil } -func (h *macGeneric) Sum(out *[16]byte) { - H, R := h.h, h.r +// Sum flushes the last incomplete chunk from the buffer, if any, and generates +// the MAC output. It does not modify its state, in order to allow for multiple +// calls to Sum, even if no Write is allowed after Sum. +func (h *macGeneric) Sum(out *[TagSize]byte) { + state := h.macState if h.offset > 0 { - var buffer [TagSize]byte - copy(buffer[:], h.buffer[:h.offset]) - buffer[h.offset] = 1 // invariant: h.offset < TagSize - updateGeneric(buffer[:], finalBlock, &H, &R) + updateGeneric(&state, h.buffer[:h.offset]) } - finalizeGeneric(out, &H, &(h.s)) + finalize(out, &state.h, &state.s) +} + +// [rMask0, rMask1] is the specified Poly1305 clamping mask in little-endian. It +// clears some bits of the secret coefficient to make it possible to implement +// multiplication more efficiently. +const ( + rMask0 = 0x0FFFFFFC0FFFFFFF + rMask1 = 0x0FFFFFFC0FFFFFFC +) + +func initialize(key *[32]byte, r, s *[2]uint64) { + r[0] = binary.LittleEndian.Uint64(key[0:8]) & rMask0 + r[1] = binary.LittleEndian.Uint64(key[8:16]) & rMask1 + s[0] = binary.LittleEndian.Uint64(key[16:24]) + s[1] = binary.LittleEndian.Uint64(key[24:32]) +} + +// uint128 holds a 128-bit number as two 64-bit limbs, for use with the +// bits.Mul64 and bits.Add64 intrinsics. +type uint128 struct { + lo, hi uint64 +} + +func mul64(a, b uint64) uint128 { + hi, lo := bitsMul64(a, b) + return uint128{lo, hi} } -func updateGeneric(msg []byte, flag uint32, h, r *[5]uint32) { - h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] - r0, r1, r2, r3, r4 := uint64(r[0]), uint64(r[1]), uint64(r[2]), uint64(r[3]), uint64(r[4]) - R1, R2, R3, R4 := r1*5, r2*5, r3*5, r4*5 - - for len(msg) >= TagSize { - // h += msg - h0 += binary.LittleEndian.Uint32(msg[0:]) & 0x3ffffff - h1 += (binary.LittleEndian.Uint32(msg[3:]) >> 2) & 0x3ffffff - h2 += (binary.LittleEndian.Uint32(msg[6:]) >> 4) & 0x3ffffff - h3 += (binary.LittleEndian.Uint32(msg[9:]) >> 6) & 0x3ffffff - h4 += (binary.LittleEndian.Uint32(msg[12:]) >> 8) | flag - - // h *= r - d0 := (uint64(h0) * r0) + (uint64(h1) * R4) + (uint64(h2) * R3) + (uint64(h3) * R2) + (uint64(h4) * R1) - d1 := (d0 >> 26) + (uint64(h0) * r1) + (uint64(h1) * r0) + (uint64(h2) * R4) + (uint64(h3) * R3) + (uint64(h4) * R2) - d2 := (d1 >> 26) + (uint64(h0) * r2) + (uint64(h1) * r1) + (uint64(h2) * r0) + (uint64(h3) * R4) + (uint64(h4) * R3) - d3 := (d2 >> 26) + (uint64(h0) * r3) + (uint64(h1) * r2) + (uint64(h2) * r1) + (uint64(h3) * r0) + (uint64(h4) * R4) - d4 := (d3 >> 26) + (uint64(h0) * r4) + (uint64(h1) * r3) + (uint64(h2) * r2) + (uint64(h3) * r1) + (uint64(h4) * r0) - - // h %= p - h0 = uint32(d0) & 0x3ffffff - h1 = uint32(d1) & 0x3ffffff - h2 = uint32(d2) & 0x3ffffff - h3 = uint32(d3) & 0x3ffffff - h4 = uint32(d4) & 0x3ffffff - - h0 += uint32(d4>>26) * 5 - h1 += h0 >> 26 - h0 = h0 & 0x3ffffff - - msg = msg[TagSize:] +func add128(a, b uint128) uint128 { + lo, c := bitsAdd64(a.lo, b.lo, 0) + hi, c := bitsAdd64(a.hi, b.hi, c) + if c != 0 { + panic("poly1305: unexpected overflow") } + return uint128{lo, hi} +} - h[0], h[1], h[2], h[3], h[4] = h0, h1, h2, h3, h4 +func shiftRightBy2(a uint128) uint128 { + a.lo = a.lo>>2 | (a.hi&3)<<62 + a.hi = a.hi >> 2 + return a } -func finalizeGeneric(out *[TagSize]byte, h *[5]uint32, s *[4]uint32) { - h0, h1, h2, h3, h4 := h[0], h[1], h[2], h[3], h[4] - - // h %= p reduction - h2 += h1 >> 26 - h1 &= 0x3ffffff - h3 += h2 >> 26 - h2 &= 0x3ffffff - h4 += h3 >> 26 - h3 &= 0x3ffffff - h0 += 5 * (h4 >> 26) - h4 &= 0x3ffffff - h1 += h0 >> 26 - h0 &= 0x3ffffff - - // h - p - t0 := h0 + 5 - t1 := h1 + (t0 >> 26) - t2 := h2 + (t1 >> 26) - t3 := h3 + (t2 >> 26) - t4 := h4 + (t3 >> 26) - (1 << 26) - t0 &= 0x3ffffff - t1 &= 0x3ffffff - t2 &= 0x3ffffff - t3 &= 0x3ffffff - - // select h if h < p else h - p - t_mask := (t4 >> 31) - 1 - h_mask := ^t_mask - h0 = (h0 & h_mask) | (t0 & t_mask) - h1 = (h1 & h_mask) | (t1 & t_mask) - h2 = (h2 & h_mask) | (t2 & t_mask) - h3 = (h3 & h_mask) | (t3 & t_mask) - h4 = (h4 & h_mask) | (t4 & t_mask) - - // h %= 2^128 - h0 |= h1 << 26 - h1 = ((h1 >> 6) | (h2 << 20)) - h2 = ((h2 >> 12) | (h3 << 14)) - h3 = ((h3 >> 18) | (h4 << 8)) - - // s: the s part of the key - // tag = (h + s) % (2^128) - t := uint64(h0) + uint64(s[0]) - h0 = uint32(t) - t = uint64(h1) + uint64(s[1]) + (t >> 32) - h1 = uint32(t) - t = uint64(h2) + uint64(s[2]) + (t >> 32) - h2 = uint32(t) - t = uint64(h3) + uint64(s[3]) + (t >> 32) - h3 = uint32(t) - - binary.LittleEndian.PutUint32(out[0:], h0) - binary.LittleEndian.PutUint32(out[4:], h1) - binary.LittleEndian.PutUint32(out[8:], h2) - binary.LittleEndian.PutUint32(out[12:], h3) +// updateGeneric absorbs msg into the state.h accumulator. For each chunk m of +// 128 bits of message, it computes +// +// h₊ = (h + m) * r mod 2¹³⁰ - 5 +// +// If the msg length is not a multiple of TagSize, it assumes the last +// incomplete chunk is the final one. +func updateGeneric(state *macState, msg []byte) { + h0, h1, h2 := state.h[0], state.h[1], state.h[2] + r0, r1 := state.r[0], state.r[1] + + for len(msg) > 0 { + var c uint64 + + // For the first step, h + m, we use a chain of bits.Add64 intrinsics. + // The resulting value of h might exceed 2¹³⁰ - 5, but will be partially + // reduced at the end of the multiplication below. + // + // The spec requires us to set a bit just above the message size, not to + // hide leading zeroes. For full chunks, that's 1 << 128, so we can just + // add 1 to the most significant (2¹²⁸) limb, h2. + if len(msg) >= TagSize { + h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(msg[0:8]), 0) + h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(msg[8:16]), c) + h2 += c + 1 + + msg = msg[TagSize:] + } else { + var buf [TagSize]byte + copy(buf[:], msg) + buf[len(msg)] = 1 + + h0, c = bitsAdd64(h0, binary.LittleEndian.Uint64(buf[0:8]), 0) + h1, c = bitsAdd64(h1, binary.LittleEndian.Uint64(buf[8:16]), c) + h2 += c + + msg = nil + } + + // Multiplication of big number limbs is similar to elementary school + // columnar multiplication. Instead of digits, there are 64-bit limbs. + // + // We are multiplying a 3 limbs number, h, by a 2 limbs number, r. + // + // h2 h1 h0 x + // r1 r0 = + // ---------------- + // h2r0 h1r0 h0r0 <-- individual 128-bit products + // + h2r1 h1r1 h0r1 + // ------------------------ + // m3 m2 m1 m0 <-- result in 128-bit overlapping limbs + // ------------------------ + // m3.hi m2.hi m1.hi m0.hi <-- carry propagation + // + m3.lo m2.lo m1.lo m0.lo + // ------------------------------- + // t4 t3 t2 t1 t0 <-- final result in 64-bit limbs + // + // The main difference from pen-and-paper multiplication is that we do + // carry propagation in a separate step, as if we wrote two digit sums + // at first (the 128-bit limbs), and then carried the tens all at once. + + h0r0 := mul64(h0, r0) + h1r0 := mul64(h1, r0) + h2r0 := mul64(h2, r0) + h0r1 := mul64(h0, r1) + h1r1 := mul64(h1, r1) + h2r1 := mul64(h2, r1) + + // Since h2 is known to be at most 7 (5 + 1 + 1), and r0 and r1 have their + // top 4 bits cleared by rMask{0,1}, we know that their product is not going + // to overflow 64 bits, so we can ignore the high part of the products. + // + // This also means that the product doesn't have a fifth limb (t4). + if h2r0.hi != 0 { + panic("poly1305: unexpected overflow") + } + if h2r1.hi != 0 { + panic("poly1305: unexpected overflow") + } + + m0 := h0r0 + m1 := add128(h1r0, h0r1) // These two additions don't overflow thanks again + m2 := add128(h2r0, h1r1) // to the 4 masked bits at the top of r0 and r1. + m3 := h2r1 + + t0 := m0.lo + t1, c := bitsAdd64(m1.lo, m0.hi, 0) + t2, c := bitsAdd64(m2.lo, m1.hi, c) + t3, _ := bitsAdd64(m3.lo, m2.hi, c) + + // Now we have the result as 4 64-bit limbs, and we need to reduce it + // modulo 2¹³⁰ - 5. The special shape of this Crandall prime lets us do + // a cheap partial reduction according to the reduction identity + // + // c * 2¹³⁰ + n = c * 5 + n mod 2¹³⁰ - 5 + // + // because 2¹³⁰ = 5 mod 2¹³⁰ - 5. Partial reduction since the result is + // likely to be larger than 2¹³⁰ - 5, but still small enough to fit the + // assumptions we make about h in the rest of the code. + // + // See also https://speakerdeck.com/gtank/engineering-prime-numbers?slide=23 + + // We split the final result at the 2¹³⁰ mark into h and cc, the carry. + // Note that the carry bits are effectively shifted left by 2, in other + // words, cc = c * 4 for the c in the reduction identity. + h0, h1, h2 = t0, t1, t2&maskLow2Bits + cc := uint128{t2 & maskNotLow2Bits, t3} + + // To add c * 5 to h, we first add cc = c * 4, and then add (cc >> 2) = c. + + h0, c = bitsAdd64(h0, cc.lo, 0) + h1, c = bitsAdd64(h1, cc.hi, c) + h2 += c + + cc = shiftRightBy2(cc) + + h0, c = bitsAdd64(h0, cc.lo, 0) + h1, c = bitsAdd64(h1, cc.hi, c) + h2 += c + + // h2 is at most 3 + 1 + 1 = 5, making the whole of h at most + // + // 5 * 2¹²⁸ + (2¹²⁸ - 1) = 6 * 2¹²⁸ - 1 + } + + state.h[0], state.h[1], state.h[2] = h0, h1, h2 +} + +const ( + maskLow2Bits uint64 = 0x0000000000000003 + maskNotLow2Bits uint64 = ^maskLow2Bits +) + +// select64 returns x if v == 1 and y if v == 0, in constant time. +func select64(v, x, y uint64) uint64 { return ^(v-1)&x | (v-1)&y } + +// [p0, p1, p2] is 2¹³⁰ - 5 in little endian order. +const ( + p0 = 0xFFFFFFFFFFFFFFFB + p1 = 0xFFFFFFFFFFFFFFFF + p2 = 0x0000000000000003 +) + +// finalize completes the modular reduction of h and computes +// +// out = h + s mod 2¹²⁸ +// +func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) { + h0, h1, h2 := h[0], h[1], h[2] + + // After the partial reduction in updateGeneric, h might be more than + // 2¹³⁰ - 5, but will be less than 2 * (2¹³⁰ - 5). To complete the reduction + // in constant time, we compute t = h - (2¹³⁰ - 5), and select h as the + // result if the subtraction underflows, and t otherwise. + + hMinusP0, b := bitsSub64(h0, p0, 0) + hMinusP1, b := bitsSub64(h1, p1, b) + _, b = bitsSub64(h2, p2, b) + + // h = h if h < p else h - p + h0 = select64(b, h0, hMinusP0) + h1 = select64(b, h1, hMinusP1) + + // Finally, we compute the last Poly1305 step + // + // tag = h + s mod 2¹²⁸ + // + // by just doing a wide addition with the 128 low bits of h and discarding + // the overflow. + h0, c := bitsAdd64(h0, s[0], 0) + h1, _ = bitsAdd64(h1, s[1], c) + + binary.LittleEndian.PutUint64(out[0:8], h0) + binary.LittleEndian.PutUint64(out[8:16], h1) } diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_noasm.go b/libgo/go/golang.org/x/crypto/poly1305/sum_noasm.go index 8a9c2070b9f..1682eda45f1 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_noasm.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_noasm.go @@ -6,10 +6,7 @@ package poly1305 -// Sum generates an authenticator for msg using a one-time key and puts the -// 16-byte result into out. Authenticating two different messages with the same -// key allows an attacker to forge messages at will. -func Sum(out *[TagSize]byte, msg []byte, key *[32]byte) { +func sum(out *[TagSize]byte, msg []byte, key *[32]byte) { h := newMAC(key) h.Write(msg) h.Sum(out) diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_ppc64le.go b/libgo/go/golang.org/x/crypto/poly1305/sum_ppc64le.go index 2402b6371bf..3233616935b 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_ppc64le.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_ppc64le.go @@ -7,62 +7,52 @@ package poly1305 //go:noescape -func initialize(state *[7]uint64, key *[32]byte) +func update(state *macState, msg []byte) -//go:noescape -func update(state *[7]uint64, msg []byte) - -//go:noescape -func finalize(tag *[TagSize]byte, state *[7]uint64) - -// Sum generates an authenticator for m using a one-time key and puts the -// 16-byte result into out. Authenticating two different messages with the same -// key allows an attacker to forge messages at will. -func Sum(out *[16]byte, m []byte, key *[32]byte) { +func sum(out *[16]byte, m []byte, key *[32]byte) { h := newMAC(key) h.Write(m) h.Sum(out) } func newMAC(key *[32]byte) (h mac) { - initialize(&h.state, key) + initialize(key, &h.r, &h.s) return } -type mac struct { - state [7]uint64 // := uint64{ h0, h1, h2, r0, r1, pad0, pad1 } - - buffer [TagSize]byte - offset int -} +// mac is a wrapper for macGeneric that redirects calls that would have gone to +// updateGeneric to update. +// +// Its Write and Sum methods are otherwise identical to the macGeneric ones, but +// using function pointers would carry a major performance cost. +type mac struct{ macGeneric } -func (h *mac) Write(p []byte) (n int, err error) { - n = len(p) +func (h *mac) Write(p []byte) (int, error) { + nn := len(p) if h.offset > 0 { - remaining := TagSize - h.offset - if n < remaining { - h.offset += copy(h.buffer[h.offset:], p) - return n, nil + n := copy(h.buffer[h.offset:], p) + if h.offset+n < TagSize { + h.offset += n + return nn, nil } - copy(h.buffer[h.offset:], p[:remaining]) - p = p[remaining:] + p = p[n:] h.offset = 0 - update(&h.state, h.buffer[:]) + update(&h.macState, h.buffer[:]) } - if nn := len(p) - (len(p) % TagSize); nn > 0 { - update(&h.state, p[:nn]) - p = p[nn:] + if n := len(p) - (len(p) % TagSize); n > 0 { + update(&h.macState, p[:n]) + p = p[n:] } if len(p) > 0 { h.offset += copy(h.buffer[h.offset:], p) } - return n, nil + return nn, nil } func (h *mac) Sum(out *[16]byte) { - state := h.state + state := h.macState if h.offset > 0 { update(&state, h.buffer[:h.offset]) } - finalize(out, &state) + finalize(out, &state.h, &state.s) } diff --git a/libgo/go/golang.org/x/crypto/poly1305/sum_s390x.go b/libgo/go/golang.org/x/crypto/poly1305/sum_s390x.go index ec99e07e9fb..a8920ee9d21 100644 --- a/libgo/go/golang.org/x/crypto/poly1305/sum_s390x.go +++ b/libgo/go/golang.org/x/crypto/poly1305/sum_s390x.go @@ -22,10 +22,7 @@ func poly1305vx(out *[16]byte, m *byte, mlen uint64, key *[32]byte) //go:noescape func poly1305vmsl(out *[16]byte, m *byte, mlen uint64, key *[32]byte) -// Sum generates an authenticator for m using a one-time key and puts the -// 16-byte result into out. Authenticating two different messages with the same -// key allows an attacker to forge messages at will. -func Sum(out *[16]byte, m []byte, key *[32]byte) { +func sum(out *[16]byte, m []byte, key *[32]byte) { if cpu.S390X.HasVX { var mPtr *byte if len(m) > 0 { diff --git a/libgo/go/golang.org/x/mod/LICENSE b/libgo/go/golang.org/x/mod/LICENSE new file mode 100644 index 00000000000..6a66aea5eaf --- /dev/null +++ b/libgo/go/golang.org/x/mod/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libgo/go/golang.org/x/mod/PATENTS b/libgo/go/golang.org/x/mod/PATENTS new file mode 100644 index 00000000000..733099041f8 --- /dev/null +++ b/libgo/go/golang.org/x/mod/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/libgo/go/golang.org/x/mod/internal/lazyregexp/lazyre.go b/libgo/go/golang.org/x/mod/internal/lazyregexp/lazyre.go new file mode 100644 index 00000000000..2681af35af1 --- /dev/null +++ b/libgo/go/golang.org/x/mod/internal/lazyregexp/lazyre.go @@ -0,0 +1,78 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package lazyregexp is a thin wrapper over regexp, allowing the use of global +// regexp variables without forcing them to be compiled at init. +package lazyregexp + +import ( + "os" + "regexp" + "strings" + "sync" +) + +// Regexp is a wrapper around regexp.Regexp, where the underlying regexp will be +// compiled the first time it is needed. +type Regexp struct { + str string + once sync.Once + rx *regexp.Regexp +} + +func (r *Regexp) re() *regexp.Regexp { + r.once.Do(r.build) + return r.rx +} + +func (r *Regexp) build() { + r.rx = regexp.MustCompile(r.str) + r.str = "" +} + +func (r *Regexp) FindSubmatch(s []byte) [][]byte { + return r.re().FindSubmatch(s) +} + +func (r *Regexp) FindStringSubmatch(s string) []string { + return r.re().FindStringSubmatch(s) +} + +func (r *Regexp) FindStringSubmatchIndex(s string) []int { + return r.re().FindStringSubmatchIndex(s) +} + +func (r *Regexp) ReplaceAllString(src, repl string) string { + return r.re().ReplaceAllString(src, repl) +} + +func (r *Regexp) FindString(s string) string { + return r.re().FindString(s) +} + +func (r *Regexp) FindAllString(s string, n int) []string { + return r.re().FindAllString(s, n) +} + +func (r *Regexp) MatchString(s string) bool { + return r.re().MatchString(s) +} + +func (r *Regexp) SubexpNames() []string { + return r.re().SubexpNames() +} + +var inTest = len(os.Args) > 0 && strings.HasSuffix(strings.TrimSuffix(os.Args[0], ".exe"), ".test") + +// New creates a new lazy regexp, delaying the compiling work until it is first +// needed. If the code is being run as part of tests, the regexp compiling will +// happen immediately. +func New(str string) *Regexp { + lr := &Regexp{str: str} + if inTest { + // In tests, always compile the regexps early. + lr.re() + } + return lr +} diff --git a/libgo/go/golang.org/x/mod/modfile/print.go b/libgo/go/golang.org/x/mod/modfile/print.go new file mode 100644 index 00000000000..3bbea38529f --- /dev/null +++ b/libgo/go/golang.org/x/mod/modfile/print.go @@ -0,0 +1,165 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Module file printer. + +package modfile + +import ( + "bytes" + "fmt" + "strings" +) + +// Format returns a go.mod file as a byte slice, formatted in standard style. +func Format(f *FileSyntax) []byte { + pr := &printer{} + pr.file(f) + return pr.Bytes() +} + +// A printer collects the state during printing of a file or expression. +type printer struct { + bytes.Buffer // output buffer + comment []Comment // pending end-of-line comments + margin int // left margin (indent), a number of tabs +} + +// printf prints to the buffer. +func (p *printer) printf(format string, args ...interface{}) { + fmt.Fprintf(p, format, args...) +} + +// indent returns the position on the current line, in bytes, 0-indexed. +func (p *printer) indent() int { + b := p.Bytes() + n := 0 + for n < len(b) && b[len(b)-1-n] != '\n' { + n++ + } + return n +} + +// newline ends the current line, flushing end-of-line comments. +func (p *printer) newline() { + if len(p.comment) > 0 { + p.printf(" ") + for i, com := range p.comment { + if i > 0 { + p.trim() + p.printf("\n") + for i := 0; i < p.margin; i++ { + p.printf("\t") + } + } + p.printf("%s", strings.TrimSpace(com.Token)) + } + p.comment = p.comment[:0] + } + + p.trim() + p.printf("\n") + for i := 0; i < p.margin; i++ { + p.printf("\t") + } +} + +// trim removes trailing spaces and tabs from the current line. +func (p *printer) trim() { + // Remove trailing spaces and tabs from line we're about to end. + b := p.Bytes() + n := len(b) + for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') { + n-- + } + p.Truncate(n) +} + +// file formats the given file into the print buffer. +func (p *printer) file(f *FileSyntax) { + for _, com := range f.Before { + p.printf("%s", strings.TrimSpace(com.Token)) + p.newline() + } + + for i, stmt := range f.Stmt { + switch x := stmt.(type) { + case *CommentBlock: + // comments already handled + p.expr(x) + + default: + p.expr(x) + p.newline() + } + + for _, com := range stmt.Comment().After { + p.printf("%s", strings.TrimSpace(com.Token)) + p.newline() + } + + if i+1 < len(f.Stmt) { + p.newline() + } + } +} + +func (p *printer) expr(x Expr) { + // Emit line-comments preceding this expression. + if before := x.Comment().Before; len(before) > 0 { + // Want to print a line comment. + // Line comments must be at the current margin. + p.trim() + if p.indent() > 0 { + // There's other text on the line. Start a new line. + p.printf("\n") + } + // Re-indent to margin. + for i := 0; i < p.margin; i++ { + p.printf("\t") + } + for _, com := range before { + p.printf("%s", strings.TrimSpace(com.Token)) + p.newline() + } + } + + switch x := x.(type) { + default: + panic(fmt.Errorf("printer: unexpected type %T", x)) + + case *CommentBlock: + // done + + case *LParen: + p.printf("(") + case *RParen: + p.printf(")") + + case *Line: + sep := "" + for _, tok := range x.Token { + p.printf("%s%s", sep, tok) + sep = " " + } + + case *LineBlock: + for _, tok := range x.Token { + p.printf("%s ", tok) + } + p.expr(&x.LParen) + p.margin++ + for _, l := range x.Line { + p.newline() + p.expr(l) + } + p.margin-- + p.newline() + p.expr(&x.RParen) + } + + // Queue end-of-line comments for printing when we + // reach the end of the line. + p.comment = append(p.comment, x.Comment().Suffix...) +} diff --git a/libgo/go/golang.org/x/mod/modfile/read.go b/libgo/go/golang.org/x/mod/modfile/read.go new file mode 100644 index 00000000000..616d00efdb1 --- /dev/null +++ b/libgo/go/golang.org/x/mod/modfile/read.go @@ -0,0 +1,909 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Module file parser. +// This is a simplified copy of Google's buildifier parser. + +package modfile + +import ( + "bytes" + "fmt" + "os" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// A Position describes an arbitrary source position in a file, including the +// file, line, column, and byte offset. +type Position struct { + Line int // line in input (starting at 1) + LineRune int // rune in line (starting at 1) + Byte int // byte in input (starting at 0) +} + +// add returns the position at the end of s, assuming it starts at p. +func (p Position) add(s string) Position { + p.Byte += len(s) + if n := strings.Count(s, "\n"); n > 0 { + p.Line += n + s = s[strings.LastIndex(s, "\n")+1:] + p.LineRune = 1 + } + p.LineRune += utf8.RuneCountInString(s) + return p +} + +// An Expr represents an input element. +type Expr interface { + // Span returns the start and end position of the expression, + // excluding leading or trailing comments. + Span() (start, end Position) + + // Comment returns the comments attached to the expression. + // This method would normally be named 'Comments' but that + // would interfere with embedding a type of the same name. + Comment() *Comments +} + +// A Comment represents a single // comment. +type Comment struct { + Start Position + Token string // without trailing newline + Suffix bool // an end of line (not whole line) comment +} + +// Comments collects the comments associated with an expression. +type Comments struct { + Before []Comment // whole-line comments before this expression + Suffix []Comment // end-of-line comments after this expression + + // For top-level expressions only, After lists whole-line + // comments following the expression. + After []Comment +} + +// Comment returns the receiver. This isn't useful by itself, but +// a Comments struct is embedded into all the expression +// implementation types, and this gives each of those a Comment +// method to satisfy the Expr interface. +func (c *Comments) Comment() *Comments { + return c +} + +// A FileSyntax represents an entire go.mod file. +type FileSyntax struct { + Name string // file path + Comments + Stmt []Expr +} + +func (x *FileSyntax) Span() (start, end Position) { + if len(x.Stmt) == 0 { + return + } + start, _ = x.Stmt[0].Span() + _, end = x.Stmt[len(x.Stmt)-1].Span() + return start, end +} + +// addLine adds a line containing the given tokens to the file. +// +// If the first token of the hint matches the first token of the +// line, the new line is added at the end of the block containing hint, +// extracting hint into a new block if it is not yet in one. +// +// If the hint is non-nil buts its first token does not match, +// the new line is added after the block containing hint +// (or hint itself, if not in a block). +// +// If no hint is provided, addLine appends the line to the end of +// the last block with a matching first token, +// or to the end of the file if no such block exists. +func (x *FileSyntax) addLine(hint Expr, tokens ...string) *Line { + if hint == nil { + // If no hint given, add to the last statement of the given type. + Loop: + for i := len(x.Stmt) - 1; i >= 0; i-- { + stmt := x.Stmt[i] + switch stmt := stmt.(type) { + case *Line: + if stmt.Token != nil && stmt.Token[0] == tokens[0] { + hint = stmt + break Loop + } + case *LineBlock: + if stmt.Token[0] == tokens[0] { + hint = stmt + break Loop + } + } + } + } + + newLineAfter := func(i int) *Line { + new := &Line{Token: tokens} + if i == len(x.Stmt) { + x.Stmt = append(x.Stmt, new) + } else { + x.Stmt = append(x.Stmt, nil) + copy(x.Stmt[i+2:], x.Stmt[i+1:]) + x.Stmt[i+1] = new + } + return new + } + + if hint != nil { + for i, stmt := range x.Stmt { + switch stmt := stmt.(type) { + case *Line: + if stmt == hint { + if stmt.Token == nil || stmt.Token[0] != tokens[0] { + return newLineAfter(i) + } + + // Convert line to line block. + stmt.InBlock = true + block := &LineBlock{Token: stmt.Token[:1], Line: []*Line{stmt}} + stmt.Token = stmt.Token[1:] + x.Stmt[i] = block + new := &Line{Token: tokens[1:], InBlock: true} + block.Line = append(block.Line, new) + return new + } + + case *LineBlock: + if stmt == hint { + if stmt.Token[0] != tokens[0] { + return newLineAfter(i) + } + + new := &Line{Token: tokens[1:], InBlock: true} + stmt.Line = append(stmt.Line, new) + return new + } + + for j, line := range stmt.Line { + if line == hint { + if stmt.Token[0] != tokens[0] { + return newLineAfter(i) + } + + // Add new line after hint within the block. + stmt.Line = append(stmt.Line, nil) + copy(stmt.Line[j+2:], stmt.Line[j+1:]) + new := &Line{Token: tokens[1:], InBlock: true} + stmt.Line[j+1] = new + return new + } + } + } + } + } + + new := &Line{Token: tokens} + x.Stmt = append(x.Stmt, new) + return new +} + +func (x *FileSyntax) updateLine(line *Line, tokens ...string) { + if line.InBlock { + tokens = tokens[1:] + } + line.Token = tokens +} + +func (x *FileSyntax) removeLine(line *Line) { + line.Token = nil +} + +// Cleanup cleans up the file syntax x after any edit operations. +// To avoid quadratic behavior, removeLine marks the line as dead +// by setting line.Token = nil but does not remove it from the slice +// in which it appears. After edits have all been indicated, +// calling Cleanup cleans out the dead lines. +func (x *FileSyntax) Cleanup() { + w := 0 + for _, stmt := range x.Stmt { + switch stmt := stmt.(type) { + case *Line: + if stmt.Token == nil { + continue + } + case *LineBlock: + ww := 0 + for _, line := range stmt.Line { + if line.Token != nil { + stmt.Line[ww] = line + ww++ + } + } + if ww == 0 { + continue + } + if ww == 1 { + // Collapse block into single line. + line := &Line{ + Comments: Comments{ + Before: commentsAdd(stmt.Before, stmt.Line[0].Before), + Suffix: commentsAdd(stmt.Line[0].Suffix, stmt.Suffix), + After: commentsAdd(stmt.Line[0].After, stmt.After), + }, + Token: stringsAdd(stmt.Token, stmt.Line[0].Token), + } + x.Stmt[w] = line + w++ + continue + } + stmt.Line = stmt.Line[:ww] + } + x.Stmt[w] = stmt + w++ + } + x.Stmt = x.Stmt[:w] +} + +func commentsAdd(x, y []Comment) []Comment { + return append(x[:len(x):len(x)], y...) +} + +func stringsAdd(x, y []string) []string { + return append(x[:len(x):len(x)], y...) +} + +// A CommentBlock represents a top-level block of comments separate +// from any rule. +type CommentBlock struct { + Comments + Start Position +} + +func (x *CommentBlock) Span() (start, end Position) { + return x.Start, x.Start +} + +// A Line is a single line of tokens. +type Line struct { + Comments + Start Position + Token []string + InBlock bool + End Position +} + +func (x *Line) Span() (start, end Position) { + return x.Start, x.End +} + +// A LineBlock is a factored block of lines, like +// +// require ( +// "x" +// "y" +// ) +// +type LineBlock struct { + Comments + Start Position + LParen LParen + Token []string + Line []*Line + RParen RParen +} + +func (x *LineBlock) Span() (start, end Position) { + return x.Start, x.RParen.Pos.add(")") +} + +// An LParen represents the beginning of a parenthesized line block. +// It is a place to store suffix comments. +type LParen struct { + Comments + Pos Position +} + +func (x *LParen) Span() (start, end Position) { + return x.Pos, x.Pos.add(")") +} + +// An RParen represents the end of a parenthesized line block. +// It is a place to store whole-line (before) comments. +type RParen struct { + Comments + Pos Position +} + +func (x *RParen) Span() (start, end Position) { + return x.Pos, x.Pos.add(")") +} + +// An input represents a single input file being parsed. +type input struct { + // Lexing state. + filename string // name of input file, for errors + complete []byte // entire input + remaining []byte // remaining input + token []byte // token being scanned + lastToken string // most recently returned token, for error messages + pos Position // current input position + comments []Comment // accumulated comments + endRule int // position of end of current rule + + // Parser state. + file *FileSyntax // returned top-level syntax tree + parseError error // error encountered during parsing + + // Comment assignment state. + pre []Expr // all expressions, in preorder traversal + post []Expr // all expressions, in postorder traversal +} + +func newInput(filename string, data []byte) *input { + return &input{ + filename: filename, + complete: data, + remaining: data, + pos: Position{Line: 1, LineRune: 1, Byte: 0}, + } +} + +// parse parses the input file. +func parse(file string, data []byte) (f *FileSyntax, err error) { + in := newInput(file, data) + // The parser panics for both routine errors like syntax errors + // and for programmer bugs like array index errors. + // Turn both into error returns. Catching bug panics is + // especially important when processing many files. + defer func() { + if e := recover(); e != nil { + if e == in.parseError { + err = in.parseError + } else { + err = fmt.Errorf("%s:%d:%d: internal error: %v", in.filename, in.pos.Line, in.pos.LineRune, e) + } + } + }() + + // Invoke the parser. + in.parseFile() + if in.parseError != nil { + return nil, in.parseError + } + in.file.Name = in.filename + + // Assign comments to nearby syntax. + in.assignComments() + + return in.file, nil +} + +// Error is called to report an error. +// The reason s is often "syntax error". +// Error does not return: it panics. +func (in *input) Error(s string) { + if s == "syntax error" && in.lastToken != "" { + s += " near " + in.lastToken + } + in.parseError = fmt.Errorf("%s:%d:%d: %v", in.filename, in.pos.Line, in.pos.LineRune, s) + panic(in.parseError) +} + +// eof reports whether the input has reached end of file. +func (in *input) eof() bool { + return len(in.remaining) == 0 +} + +// peekRune returns the next rune in the input without consuming it. +func (in *input) peekRune() int { + if len(in.remaining) == 0 { + return 0 + } + r, _ := utf8.DecodeRune(in.remaining) + return int(r) +} + +// peekPrefix reports whether the remaining input begins with the given prefix. +func (in *input) peekPrefix(prefix string) bool { + // This is like bytes.HasPrefix(in.remaining, []byte(prefix)) + // but without the allocation of the []byte copy of prefix. + for i := 0; i < len(prefix); i++ { + if i >= len(in.remaining) || in.remaining[i] != prefix[i] { + return false + } + } + return true +} + +// readRune consumes and returns the next rune in the input. +func (in *input) readRune() int { + if len(in.remaining) == 0 { + in.Error("internal lexer error: readRune at EOF") + } + r, size := utf8.DecodeRune(in.remaining) + in.remaining = in.remaining[size:] + if r == '\n' { + in.pos.Line++ + in.pos.LineRune = 1 + } else { + in.pos.LineRune++ + } + in.pos.Byte += size + return int(r) +} + +type symType struct { + pos Position + endPos Position + text string +} + +// startToken marks the beginning of the next input token. +// It must be followed by a call to endToken, once the token has +// been consumed using readRune. +func (in *input) startToken(sym *symType) { + in.token = in.remaining + sym.text = "" + sym.pos = in.pos +} + +// endToken marks the end of an input token. +// It records the actual token string in sym.text if the caller +// has not done that already. +func (in *input) endToken(sym *symType) { + if sym.text == "" { + tok := string(in.token[:len(in.token)-len(in.remaining)]) + sym.text = tok + in.lastToken = sym.text + } + sym.endPos = in.pos +} + +// lex is called from the parser to obtain the next input token. +// It returns the token value (either a rune like '+' or a symbolic token _FOR) +// and sets val to the data associated with the token. +// For all our input tokens, the associated data is +// val.Pos (the position where the token begins) +// and val.Token (the input string corresponding to the token). +func (in *input) lex(sym *symType) int { + // Skip past spaces, stopping at non-space or EOF. + countNL := 0 // number of newlines we've skipped past + for !in.eof() { + // Skip over spaces. Count newlines so we can give the parser + // information about where top-level blank lines are, + // for top-level comment assignment. + c := in.peekRune() + if c == ' ' || c == '\t' || c == '\r' { + in.readRune() + continue + } + + // Comment runs to end of line. + if in.peekPrefix("//") { + in.startToken(sym) + + // Is this comment the only thing on its line? + // Find the last \n before this // and see if it's all + // spaces from there to here. + i := bytes.LastIndex(in.complete[:in.pos.Byte], []byte("\n")) + suffix := len(bytes.TrimSpace(in.complete[i+1:in.pos.Byte])) > 0 + in.readRune() + in.readRune() + + // Consume comment. + for len(in.remaining) > 0 && in.readRune() != '\n' { + } + in.endToken(sym) + + sym.text = strings.TrimRight(sym.text, "\n") + in.lastToken = "comment" + + // If we are at top level (not in a statement), hand the comment to + // the parser as a _COMMENT token. The grammar is written + // to handle top-level comments itself. + if !suffix { + // Not in a statement. Tell parser about top-level comment. + return _COMMENT + } + + // Otherwise, save comment for later attachment to syntax tree. + if countNL > 1 { + in.comments = append(in.comments, Comment{sym.pos, "", false}) + } + in.comments = append(in.comments, Comment{sym.pos, sym.text, suffix}) + countNL = 1 + return _EOL + } + + if in.peekPrefix("/*") { + in.Error(fmt.Sprintf("mod files must use // comments (not /* */ comments)")) + } + + // Found non-space non-comment. + break + } + + // Found the beginning of the next token. + in.startToken(sym) + defer in.endToken(sym) + + // End of file. + if in.eof() { + in.lastToken = "EOF" + return _EOF + } + + // Punctuation tokens. + switch c := in.peekRune(); c { + case '\n': + in.readRune() + return c + + case '(': + in.readRune() + return c + + case ')': + in.readRune() + return c + + case '"', '`': // quoted string + quote := c + in.readRune() + for { + if in.eof() { + in.pos = sym.pos + in.Error("unexpected EOF in string") + } + if in.peekRune() == '\n' { + in.Error("unexpected newline in string") + } + c := in.readRune() + if c == quote { + break + } + if c == '\\' && quote != '`' { + if in.eof() { + in.pos = sym.pos + in.Error("unexpected EOF in string") + } + in.readRune() + } + } + in.endToken(sym) + return _STRING + } + + // Checked all punctuation. Must be identifier token. + if c := in.peekRune(); !isIdent(c) { + in.Error(fmt.Sprintf("unexpected input character %#q", c)) + } + + // Scan over identifier. + for isIdent(in.peekRune()) { + if in.peekPrefix("//") { + break + } + if in.peekPrefix("/*") { + in.Error(fmt.Sprintf("mod files must use // comments (not /* */ comments)")) + } + in.readRune() + } + return _IDENT +} + +// isIdent reports whether c is an identifier rune. +// We treat nearly all runes as identifier runes. +func isIdent(c int) bool { + return c != 0 && !unicode.IsSpace(rune(c)) +} + +// Comment assignment. +// We build two lists of all subexpressions, preorder and postorder. +// The preorder list is ordered by start location, with outer expressions first. +// The postorder list is ordered by end location, with outer expressions last. +// We use the preorder list to assign each whole-line comment to the syntax +// immediately following it, and we use the postorder list to assign each +// end-of-line comment to the syntax immediately preceding it. + +// order walks the expression adding it and its subexpressions to the +// preorder and postorder lists. +func (in *input) order(x Expr) { + if x != nil { + in.pre = append(in.pre, x) + } + switch x := x.(type) { + default: + panic(fmt.Errorf("order: unexpected type %T", x)) + case nil: + // nothing + case *LParen, *RParen: + // nothing + case *CommentBlock: + // nothing + case *Line: + // nothing + case *FileSyntax: + for _, stmt := range x.Stmt { + in.order(stmt) + } + case *LineBlock: + in.order(&x.LParen) + for _, l := range x.Line { + in.order(l) + } + in.order(&x.RParen) + } + if x != nil { + in.post = append(in.post, x) + } +} + +// assignComments attaches comments to nearby syntax. +func (in *input) assignComments() { + const debug = false + + // Generate preorder and postorder lists. + in.order(in.file) + + // Split into whole-line comments and suffix comments. + var line, suffix []Comment + for _, com := range in.comments { + if com.Suffix { + suffix = append(suffix, com) + } else { + line = append(line, com) + } + } + + if debug { + for _, c := range line { + fmt.Fprintf(os.Stderr, "LINE %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte) + } + } + + // Assign line comments to syntax immediately following. + for _, x := range in.pre { + start, _ := x.Span() + if debug { + fmt.Printf("pre %T :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte) + } + xcom := x.Comment() + for len(line) > 0 && start.Byte >= line[0].Start.Byte { + if debug { + fmt.Fprintf(os.Stderr, "ASSIGN LINE %q #%d\n", line[0].Token, line[0].Start.Byte) + } + xcom.Before = append(xcom.Before, line[0]) + line = line[1:] + } + } + + // Remaining line comments go at end of file. + in.file.After = append(in.file.After, line...) + + if debug { + for _, c := range suffix { + fmt.Fprintf(os.Stderr, "SUFFIX %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte) + } + } + + // Assign suffix comments to syntax immediately before. + for i := len(in.post) - 1; i >= 0; i-- { + x := in.post[i] + + start, end := x.Span() + if debug { + fmt.Printf("post %T :%d:%d #%d :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte, end.Line, end.LineRune, end.Byte) + } + + // Do not assign suffix comments to end of line block or whole file. + // Instead assign them to the last element inside. + switch x.(type) { + case *FileSyntax: + continue + } + + // Do not assign suffix comments to something that starts + // on an earlier line, so that in + // + // x ( y + // z ) // comment + // + // we assign the comment to z and not to x ( ... ). + if start.Line != end.Line { + continue + } + xcom := x.Comment() + for len(suffix) > 0 && end.Byte <= suffix[len(suffix)-1].Start.Byte { + if debug { + fmt.Fprintf(os.Stderr, "ASSIGN SUFFIX %q #%d\n", suffix[len(suffix)-1].Token, suffix[len(suffix)-1].Start.Byte) + } + xcom.Suffix = append(xcom.Suffix, suffix[len(suffix)-1]) + suffix = suffix[:len(suffix)-1] + } + } + + // We assigned suffix comments in reverse. + // If multiple suffix comments were appended to the same + // expression node, they are now in reverse. Fix that. + for _, x := range in.post { + reverseComments(x.Comment().Suffix) + } + + // Remaining suffix comments go at beginning of file. + in.file.Before = append(in.file.Before, suffix...) +} + +// reverseComments reverses the []Comment list. +func reverseComments(list []Comment) { + for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 { + list[i], list[j] = list[j], list[i] + } +} + +func (in *input) parseFile() { + in.file = new(FileSyntax) + var sym symType + var cb *CommentBlock + for { + tok := in.lex(&sym) + switch tok { + case '\n': + if cb != nil { + in.file.Stmt = append(in.file.Stmt, cb) + cb = nil + } + case _COMMENT: + if cb == nil { + cb = &CommentBlock{Start: sym.pos} + } + com := cb.Comment() + com.Before = append(com.Before, Comment{Start: sym.pos, Token: sym.text}) + case _EOF: + if cb != nil { + in.file.Stmt = append(in.file.Stmt, cb) + } + return + default: + in.parseStmt(&sym) + if cb != nil { + in.file.Stmt[len(in.file.Stmt)-1].Comment().Before = cb.Before + cb = nil + } + } + } +} + +func (in *input) parseStmt(sym *symType) { + start := sym.pos + end := sym.endPos + token := []string{sym.text} + for { + tok := in.lex(sym) + switch tok { + case '\n', _EOF, _EOL: + in.file.Stmt = append(in.file.Stmt, &Line{ + Start: start, + Token: token, + End: end, + }) + return + case '(': + in.file.Stmt = append(in.file.Stmt, in.parseLineBlock(start, token, sym)) + return + default: + token = append(token, sym.text) + end = sym.endPos + } + } +} + +func (in *input) parseLineBlock(start Position, token []string, sym *symType) *LineBlock { + x := &LineBlock{ + Start: start, + Token: token, + LParen: LParen{Pos: sym.pos}, + } + var comments []Comment + for { + tok := in.lex(sym) + switch tok { + case _EOL: + // ignore + case '\n': + if len(comments) == 0 && len(x.Line) > 0 || len(comments) > 0 && comments[len(comments)-1].Token != "" { + comments = append(comments, Comment{}) + } + case _COMMENT: + comments = append(comments, Comment{Start: sym.pos, Token: sym.text}) + case _EOF: + in.Error(fmt.Sprintf("syntax error (unterminated block started at %s:%d:%d)", in.filename, x.Start.Line, x.Start.LineRune)) + case ')': + x.RParen.Before = comments + x.RParen.Pos = sym.pos + tok = in.lex(sym) + if tok != '\n' && tok != _EOF && tok != _EOL { + in.Error("syntax error (expected newline after closing paren)") + } + return x + default: + l := in.parseLine(sym) + x.Line = append(x.Line, l) + l.Comment().Before = comments + comments = nil + } + } +} + +func (in *input) parseLine(sym *symType) *Line { + start := sym.pos + end := sym.endPos + token := []string{sym.text} + for { + tok := in.lex(sym) + switch tok { + case '\n', _EOF, _EOL: + return &Line{ + Start: start, + Token: token, + End: end, + InBlock: true, + } + default: + token = append(token, sym.text) + end = sym.endPos + } + } +} + +const ( + _EOF = -(1 + iota) + _EOL + _IDENT + _STRING + _COMMENT +) + +var ( + slashSlash = []byte("//") + moduleStr = []byte("module") +) + +// ModulePath returns the module path from the gomod file text. +// If it cannot find a module path, it returns an empty string. +// It is tolerant of unrelated problems in the go.mod file. +func ModulePath(mod []byte) string { + for len(mod) > 0 { + line := mod + mod = nil + if i := bytes.IndexByte(line, '\n'); i >= 0 { + line, mod = line[:i], line[i+1:] + } + if i := bytes.Index(line, slashSlash); i >= 0 { + line = line[:i] + } + line = bytes.TrimSpace(line) + if !bytes.HasPrefix(line, moduleStr) { + continue + } + line = line[len(moduleStr):] + n := len(line) + line = bytes.TrimSpace(line) + if len(line) == n || len(line) == 0 { + continue + } + + if line[0] == '"' || line[0] == '`' { + p, err := strconv.Unquote(string(line)) + if err != nil { + return "" // malformed quoted string or multiline module path + } + return p + } + + return string(line) + } + return "" // missing module path +} diff --git a/libgo/go/golang.org/x/mod/modfile/rule.go b/libgo/go/golang.org/x/mod/modfile/rule.go new file mode 100644 index 00000000000..62af06889f6 --- /dev/null +++ b/libgo/go/golang.org/x/mod/modfile/rule.go @@ -0,0 +1,776 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modfile + +import ( + "bytes" + "errors" + "fmt" + "path/filepath" + "sort" + "strconv" + "strings" + "unicode" + + "golang.org/x/mod/internal/lazyregexp" + "golang.org/x/mod/module" +) + +// A File is the parsed, interpreted form of a go.mod file. +type File struct { + Module *Module + Go *Go + Require []*Require + Exclude []*Exclude + Replace []*Replace + + Syntax *FileSyntax +} + +// A Module is the module statement. +type Module struct { + Mod module.Version + Syntax *Line +} + +// A Go is the go statement. +type Go struct { + Version string // "1.23" + Syntax *Line +} + +// A Require is a single require statement. +type Require struct { + Mod module.Version + Indirect bool // has "// indirect" comment + Syntax *Line +} + +// An Exclude is a single exclude statement. +type Exclude struct { + Mod module.Version + Syntax *Line +} + +// A Replace is a single replace statement. +type Replace struct { + Old module.Version + New module.Version + Syntax *Line +} + +func (f *File) AddModuleStmt(path string) error { + if f.Syntax == nil { + f.Syntax = new(FileSyntax) + } + if f.Module == nil { + f.Module = &Module{ + Mod: module.Version{Path: path}, + Syntax: f.Syntax.addLine(nil, "module", AutoQuote(path)), + } + } else { + f.Module.Mod.Path = path + f.Syntax.updateLine(f.Module.Syntax, "module", AutoQuote(path)) + } + return nil +} + +func (f *File) AddComment(text string) { + if f.Syntax == nil { + f.Syntax = new(FileSyntax) + } + f.Syntax.Stmt = append(f.Syntax.Stmt, &CommentBlock{ + Comments: Comments{ + Before: []Comment{ + { + Token: text, + }, + }, + }, + }) +} + +type VersionFixer func(path, version string) (string, error) + +// Parse parses the data, reported in errors as being from file, +// into a File struct. It applies fix, if non-nil, to canonicalize all module versions found. +func Parse(file string, data []byte, fix VersionFixer) (*File, error) { + return parseToFile(file, data, fix, true) +} + +// ParseLax is like Parse but ignores unknown statements. +// It is used when parsing go.mod files other than the main module, +// under the theory that most statement types we add in the future will +// only apply in the main module, like exclude and replace, +// and so we get better gradual deployments if old go commands +// simply ignore those statements when found in go.mod files +// in dependencies. +func ParseLax(file string, data []byte, fix VersionFixer) (*File, error) { + return parseToFile(file, data, fix, false) +} + +func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File, error) { + fs, err := parse(file, data) + if err != nil { + return nil, err + } + f := &File{ + Syntax: fs, + } + + var errs bytes.Buffer + for _, x := range fs.Stmt { + switch x := x.(type) { + case *Line: + f.add(&errs, x, x.Token[0], x.Token[1:], fix, strict) + + case *LineBlock: + if len(x.Token) > 1 { + if strict { + fmt.Fprintf(&errs, "%s:%d: unknown block type: %s\n", file, x.Start.Line, strings.Join(x.Token, " ")) + } + continue + } + switch x.Token[0] { + default: + if strict { + fmt.Fprintf(&errs, "%s:%d: unknown block type: %s\n", file, x.Start.Line, strings.Join(x.Token, " ")) + } + continue + case "module", "require", "exclude", "replace": + for _, l := range x.Line { + f.add(&errs, l, x.Token[0], l.Token, fix, strict) + } + } + } + } + + if errs.Len() > 0 { + return nil, errors.New(strings.TrimRight(errs.String(), "\n")) + } + return f, nil +} + +var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) + +func (f *File) add(errs *bytes.Buffer, line *Line, verb string, args []string, fix VersionFixer, strict bool) { + // If strict is false, this module is a dependency. + // We ignore all unknown directives as well as main-module-only + // directives like replace and exclude. It will work better for + // forward compatibility if we can depend on modules that have unknown + // statements (presumed relevant only when acting as the main module) + // and simply ignore those statements. + if !strict { + switch verb { + case "module", "require", "go": + // want these even for dependency go.mods + default: + return + } + } + + switch verb { + default: + fmt.Fprintf(errs, "%s:%d: unknown directive: %s\n", f.Syntax.Name, line.Start.Line, verb) + + case "go": + if f.Go != nil { + fmt.Fprintf(errs, "%s:%d: repeated go statement\n", f.Syntax.Name, line.Start.Line) + return + } + if len(args) != 1 || !GoVersionRE.MatchString(args[0]) { + fmt.Fprintf(errs, "%s:%d: usage: go 1.23\n", f.Syntax.Name, line.Start.Line) + return + } + f.Go = &Go{Syntax: line} + f.Go.Version = args[0] + case "module": + if f.Module != nil { + fmt.Fprintf(errs, "%s:%d: repeated module statement\n", f.Syntax.Name, line.Start.Line) + return + } + f.Module = &Module{Syntax: line} + if len(args) != 1 { + + fmt.Fprintf(errs, "%s:%d: usage: module module/path\n", f.Syntax.Name, line.Start.Line) + return + } + s, err := parseString(&args[0]) + if err != nil { + fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + f.Module.Mod = module.Version{Path: s} + case "require", "exclude": + if len(args) != 2 { + fmt.Fprintf(errs, "%s:%d: usage: %s module/path v1.2.3\n", f.Syntax.Name, line.Start.Line, verb) + return + } + s, err := parseString(&args[0]) + if err != nil { + fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + v, err := parseVersion(verb, s, &args[1], fix) + if err != nil { + fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + pathMajor, err := modulePathMajor(s) + if err != nil { + fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + if err := module.CheckPathMajor(v, pathMajor); err != nil { + fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, &Error{Verb: verb, ModPath: s, Err: err}) + return + } + if verb == "require" { + f.Require = append(f.Require, &Require{ + Mod: module.Version{Path: s, Version: v}, + Syntax: line, + Indirect: isIndirect(line), + }) + } else { + f.Exclude = append(f.Exclude, &Exclude{ + Mod: module.Version{Path: s, Version: v}, + Syntax: line, + }) + } + case "replace": + arrow := 2 + if len(args) >= 2 && args[1] == "=>" { + arrow = 1 + } + if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { + fmt.Fprintf(errs, "%s:%d: usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory\n", f.Syntax.Name, line.Start.Line, verb, verb) + return + } + s, err := parseString(&args[0]) + if err != nil { + fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + pathMajor, err := modulePathMajor(s) + if err != nil { + fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + var v string + if arrow == 2 { + v, err = parseVersion(verb, s, &args[1], fix) + if err != nil { + fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + if err := module.CheckPathMajor(v, pathMajor); err != nil { + fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, &Error{Verb: verb, ModPath: s, Err: err}) + return + } + } + ns, err := parseString(&args[arrow+1]) + if err != nil { + fmt.Fprintf(errs, "%s:%d: invalid quoted string: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + nv := "" + if len(args) == arrow+2 { + if !IsDirectoryPath(ns) { + fmt.Fprintf(errs, "%s:%d: replacement module without version must be directory path (rooted or starting with ./ or ../)\n", f.Syntax.Name, line.Start.Line) + return + } + if filepath.Separator == '/' && strings.Contains(ns, `\`) { + fmt.Fprintf(errs, "%s:%d: replacement directory appears to be Windows path (on a non-windows system)\n", f.Syntax.Name, line.Start.Line) + return + } + } + if len(args) == arrow+3 { + nv, err = parseVersion(verb, ns, &args[arrow+2], fix) + if err != nil { + fmt.Fprintf(errs, "%s:%d: %v\n", f.Syntax.Name, line.Start.Line, err) + return + } + if IsDirectoryPath(ns) { + fmt.Fprintf(errs, "%s:%d: replacement module directory path %q cannot have version\n", f.Syntax.Name, line.Start.Line, ns) + return + } + } + f.Replace = append(f.Replace, &Replace{ + Old: module.Version{Path: s, Version: v}, + New: module.Version{Path: ns, Version: nv}, + Syntax: line, + }) + } +} + +// isIndirect reports whether line has a "// indirect" comment, +// meaning it is in go.mod only for its effect on indirect dependencies, +// so that it can be dropped entirely once the effective version of the +// indirect dependency reaches the given minimum version. +func isIndirect(line *Line) bool { + if len(line.Suffix) == 0 { + return false + } + f := strings.Fields(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash))) + return (len(f) == 1 && f[0] == "indirect" || len(f) > 1 && f[0] == "indirect;") +} + +// setIndirect sets line to have (or not have) a "// indirect" comment. +func setIndirect(line *Line, indirect bool) { + if isIndirect(line) == indirect { + return + } + if indirect { + // Adding comment. + if len(line.Suffix) == 0 { + // New comment. + line.Suffix = []Comment{{Token: "// indirect", Suffix: true}} + return + } + + com := &line.Suffix[0] + text := strings.TrimSpace(strings.TrimPrefix(com.Token, string(slashSlash))) + if text == "" { + // Empty comment. + com.Token = "// indirect" + return + } + + // Insert at beginning of existing comment. + com.Token = "// indirect; " + text + return + } + + // Removing comment. + f := strings.Fields(line.Suffix[0].Token) + if len(f) == 2 { + // Remove whole comment. + line.Suffix = nil + return + } + + // Remove comment prefix. + com := &line.Suffix[0] + i := strings.Index(com.Token, "indirect;") + com.Token = "//" + com.Token[i+len("indirect;"):] +} + +// IsDirectoryPath reports whether the given path should be interpreted +// as a directory path. Just like on the go command line, relative paths +// and rooted paths are directory paths; the rest are module paths. +func IsDirectoryPath(ns string) bool { + // Because go.mod files can move from one system to another, + // we check all known path syntaxes, both Unix and Windows. + return strings.HasPrefix(ns, "./") || strings.HasPrefix(ns, "../") || strings.HasPrefix(ns, "/") || + strings.HasPrefix(ns, `.\`) || strings.HasPrefix(ns, `..\`) || strings.HasPrefix(ns, `\`) || + len(ns) >= 2 && ('A' <= ns[0] && ns[0] <= 'Z' || 'a' <= ns[0] && ns[0] <= 'z') && ns[1] == ':' +} + +// MustQuote reports whether s must be quoted in order to appear as +// a single token in a go.mod line. +func MustQuote(s string) bool { + for _, r := range s { + if !unicode.IsPrint(r) || r == ' ' || r == '"' || r == '\'' || r == '`' { + return true + } + } + return s == "" || strings.Contains(s, "//") || strings.Contains(s, "/*") +} + +// AutoQuote returns s or, if quoting is required for s to appear in a go.mod, +// the quotation of s. +func AutoQuote(s string) string { + if MustQuote(s) { + return strconv.Quote(s) + } + return s +} + +func parseString(s *string) (string, error) { + t := *s + if strings.HasPrefix(t, `"`) { + var err error + if t, err = strconv.Unquote(t); err != nil { + return "", err + } + } else if strings.ContainsAny(t, "\"'`") { + // Other quotes are reserved both for possible future expansion + // and to avoid confusion. For example if someone types 'x' + // we want that to be a syntax error and not a literal x in literal quotation marks. + return "", fmt.Errorf("unquoted string cannot contain quote") + } + *s = AutoQuote(t) + return t, nil +} + +type Error struct { + Verb string + ModPath string + Err error +} + +func (e *Error) Error() string { + return fmt.Sprintf("%s %s: %v", e.Verb, e.ModPath, e.Err) +} + +func (e *Error) Unwrap() error { return e.Err } + +func parseVersion(verb string, path string, s *string, fix VersionFixer) (string, error) { + t, err := parseString(s) + if err != nil { + return "", &Error{ + Verb: verb, + ModPath: path, + Err: &module.InvalidVersionError{ + Version: *s, + Err: err, + }, + } + } + if fix != nil { + var err error + t, err = fix(path, t) + if err != nil { + if err, ok := err.(*module.ModuleError); ok { + return "", &Error{ + Verb: verb, + ModPath: path, + Err: err.Err, + } + } + return "", err + } + } + if v := module.CanonicalVersion(t); v != "" { + *s = v + return *s, nil + } + return "", &Error{ + Verb: verb, + ModPath: path, + Err: &module.InvalidVersionError{ + Version: t, + Err: errors.New("must be of the form v1.2.3"), + }, + } +} + +func modulePathMajor(path string) (string, error) { + _, major, ok := module.SplitPathVersion(path) + if !ok { + return "", fmt.Errorf("invalid module path") + } + return major, nil +} + +func (f *File) Format() ([]byte, error) { + return Format(f.Syntax), nil +} + +// Cleanup cleans up the file f after any edit operations. +// To avoid quadratic behavior, modifications like DropRequire +// clear the entry but do not remove it from the slice. +// Cleanup cleans out all the cleared entries. +func (f *File) Cleanup() { + w := 0 + for _, r := range f.Require { + if r.Mod.Path != "" { + f.Require[w] = r + w++ + } + } + f.Require = f.Require[:w] + + w = 0 + for _, x := range f.Exclude { + if x.Mod.Path != "" { + f.Exclude[w] = x + w++ + } + } + f.Exclude = f.Exclude[:w] + + w = 0 + for _, r := range f.Replace { + if r.Old.Path != "" { + f.Replace[w] = r + w++ + } + } + f.Replace = f.Replace[:w] + + f.Syntax.Cleanup() +} + +func (f *File) AddGoStmt(version string) error { + if !GoVersionRE.MatchString(version) { + return fmt.Errorf("invalid language version string %q", version) + } + if f.Go == nil { + var hint Expr + if f.Module != nil && f.Module.Syntax != nil { + hint = f.Module.Syntax + } + f.Go = &Go{ + Version: version, + Syntax: f.Syntax.addLine(hint, "go", version), + } + } else { + f.Go.Version = version + f.Syntax.updateLine(f.Go.Syntax, "go", version) + } + return nil +} + +func (f *File) AddRequire(path, vers string) error { + need := true + for _, r := range f.Require { + if r.Mod.Path == path { + if need { + r.Mod.Version = vers + f.Syntax.updateLine(r.Syntax, "require", AutoQuote(path), vers) + need = false + } else { + f.Syntax.removeLine(r.Syntax) + *r = Require{} + } + } + } + + if need { + f.AddNewRequire(path, vers, false) + } + return nil +} + +func (f *File) AddNewRequire(path, vers string, indirect bool) { + line := f.Syntax.addLine(nil, "require", AutoQuote(path), vers) + setIndirect(line, indirect) + f.Require = append(f.Require, &Require{module.Version{Path: path, Version: vers}, indirect, line}) +} + +func (f *File) SetRequire(req []*Require) { + need := make(map[string]string) + indirect := make(map[string]bool) + for _, r := range req { + need[r.Mod.Path] = r.Mod.Version + indirect[r.Mod.Path] = r.Indirect + } + + for _, r := range f.Require { + if v, ok := need[r.Mod.Path]; ok { + r.Mod.Version = v + r.Indirect = indirect[r.Mod.Path] + } else { + *r = Require{} + } + } + + var newStmts []Expr + for _, stmt := range f.Syntax.Stmt { + switch stmt := stmt.(type) { + case *LineBlock: + if len(stmt.Token) > 0 && stmt.Token[0] == "require" { + var newLines []*Line + for _, line := range stmt.Line { + if p, err := parseString(&line.Token[0]); err == nil && need[p] != "" { + if len(line.Comments.Before) == 1 && len(line.Comments.Before[0].Token) == 0 { + line.Comments.Before = line.Comments.Before[:0] + } + line.Token[1] = need[p] + delete(need, p) + setIndirect(line, indirect[p]) + newLines = append(newLines, line) + } + } + if len(newLines) == 0 { + continue // drop stmt + } + stmt.Line = newLines + } + + case *Line: + if len(stmt.Token) > 0 && stmt.Token[0] == "require" { + if p, err := parseString(&stmt.Token[1]); err == nil && need[p] != "" { + stmt.Token[2] = need[p] + delete(need, p) + setIndirect(stmt, indirect[p]) + } else { + continue // drop stmt + } + } + } + newStmts = append(newStmts, stmt) + } + f.Syntax.Stmt = newStmts + + for path, vers := range need { + f.AddNewRequire(path, vers, indirect[path]) + } + f.SortBlocks() +} + +func (f *File) DropRequire(path string) error { + for _, r := range f.Require { + if r.Mod.Path == path { + f.Syntax.removeLine(r.Syntax) + *r = Require{} + } + } + return nil +} + +func (f *File) AddExclude(path, vers string) error { + var hint *Line + for _, x := range f.Exclude { + if x.Mod.Path == path && x.Mod.Version == vers { + return nil + } + if x.Mod.Path == path { + hint = x.Syntax + } + } + + f.Exclude = append(f.Exclude, &Exclude{Mod: module.Version{Path: path, Version: vers}, Syntax: f.Syntax.addLine(hint, "exclude", AutoQuote(path), vers)}) + return nil +} + +func (f *File) DropExclude(path, vers string) error { + for _, x := range f.Exclude { + if x.Mod.Path == path && x.Mod.Version == vers { + f.Syntax.removeLine(x.Syntax) + *x = Exclude{} + } + } + return nil +} + +func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { + need := true + old := module.Version{Path: oldPath, Version: oldVers} + new := module.Version{Path: newPath, Version: newVers} + tokens := []string{"replace", AutoQuote(oldPath)} + if oldVers != "" { + tokens = append(tokens, oldVers) + } + tokens = append(tokens, "=>", AutoQuote(newPath)) + if newVers != "" { + tokens = append(tokens, newVers) + } + + var hint *Line + for _, r := range f.Replace { + if r.Old.Path == oldPath && (oldVers == "" || r.Old.Version == oldVers) { + if need { + // Found replacement for old; update to use new. + r.New = new + f.Syntax.updateLine(r.Syntax, tokens...) + need = false + continue + } + // Already added; delete other replacements for same. + f.Syntax.removeLine(r.Syntax) + *r = Replace{} + } + if r.Old.Path == oldPath { + hint = r.Syntax + } + } + if need { + f.Replace = append(f.Replace, &Replace{Old: old, New: new, Syntax: f.Syntax.addLine(hint, tokens...)}) + } + return nil +} + +func (f *File) DropReplace(oldPath, oldVers string) error { + for _, r := range f.Replace { + if r.Old.Path == oldPath && r.Old.Version == oldVers { + f.Syntax.removeLine(r.Syntax) + *r = Replace{} + } + } + return nil +} + +func (f *File) SortBlocks() { + f.removeDups() // otherwise sorting is unsafe + + for _, stmt := range f.Syntax.Stmt { + block, ok := stmt.(*LineBlock) + if !ok { + continue + } + sort.Slice(block.Line, func(i, j int) bool { + li := block.Line[i] + lj := block.Line[j] + for k := 0; k < len(li.Token) && k < len(lj.Token); k++ { + if li.Token[k] != lj.Token[k] { + return li.Token[k] < lj.Token[k] + } + } + return len(li.Token) < len(lj.Token) + }) + } +} + +func (f *File) removeDups() { + have := make(map[module.Version]bool) + kill := make(map[*Line]bool) + for _, x := range f.Exclude { + if have[x.Mod] { + kill[x.Syntax] = true + continue + } + have[x.Mod] = true + } + var excl []*Exclude + for _, x := range f.Exclude { + if !kill[x.Syntax] { + excl = append(excl, x) + } + } + f.Exclude = excl + + have = make(map[module.Version]bool) + // Later replacements take priority over earlier ones. + for i := len(f.Replace) - 1; i >= 0; i-- { + x := f.Replace[i] + if have[x.Old] { + kill[x.Syntax] = true + continue + } + have[x.Old] = true + } + var repl []*Replace + for _, x := range f.Replace { + if !kill[x.Syntax] { + repl = append(repl, x) + } + } + f.Replace = repl + + var stmts []Expr + for _, stmt := range f.Syntax.Stmt { + switch stmt := stmt.(type) { + case *Line: + if kill[stmt] { + continue + } + case *LineBlock: + var lines []*Line + for _, line := range stmt.Line { + if !kill[line] { + lines = append(lines, line) + } + } + stmt.Line = lines + if len(lines) == 0 { + continue + } + } + stmts = append(stmts, stmt) + } + f.Syntax.Stmt = stmts +} diff --git a/libgo/go/golang.org/x/mod/module/module.go b/libgo/go/golang.org/x/mod/module/module.go new file mode 100644 index 00000000000..6cd37280a85 --- /dev/null +++ b/libgo/go/golang.org/x/mod/module/module.go @@ -0,0 +1,718 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package module defines the module.Version type along with support code. +// +// The module.Version type is a simple Path, Version pair: +// +// type Version struct { +// Path string +// Version string +// } +// +// There are no restrictions imposed directly by use of this structure, +// but additional checking functions, most notably Check, verify that +// a particular path, version pair is valid. +// +// Escaped Paths +// +// Module paths appear as substrings of file system paths +// (in the download cache) and of web server URLs in the proxy protocol. +// In general we cannot rely on file systems to be case-sensitive, +// nor can we rely on web servers, since they read from file systems. +// That is, we cannot rely on the file system to keep rsc.io/QUOTE +// and rsc.io/quote separate. Windows and macOS don't. +// Instead, we must never require two different casings of a file path. +// Because we want the download cache to match the proxy protocol, +// and because we want the proxy protocol to be possible to serve +// from a tree of static files (which might be stored on a case-insensitive +// file system), the proxy protocol must never require two different casings +// of a URL path either. +// +// One possibility would be to make the escaped form be the lowercase +// hexadecimal encoding of the actual path bytes. This would avoid ever +// needing different casings of a file path, but it would be fairly illegible +// to most programmers when those paths appeared in the file system +// (including in file paths in compiler errors and stack traces) +// in web server logs, and so on. Instead, we want a safe escaped form that +// leaves most paths unaltered. +// +// The safe escaped form is to replace every uppercase letter +// with an exclamation mark followed by the letter's lowercase equivalent. +// +// For example, +// +// github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go. +// github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy +// github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus. +// +// Import paths that avoid upper-case letters are left unchanged. +// Note that because import paths are ASCII-only and avoid various +// problematic punctuation (like : < and >), the escaped form is also ASCII-only +// and avoids the same problematic punctuation. +// +// Import paths have never allowed exclamation marks, so there is no +// need to define how to escape a literal !. +// +// Unicode Restrictions +// +// Today, paths are disallowed from using Unicode. +// +// Although paths are currently disallowed from using Unicode, +// we would like at some point to allow Unicode letters as well, to assume that +// file systems and URLs are Unicode-safe (storing UTF-8), and apply +// the !-for-uppercase convention for escaping them in the file system. +// But there are at least two subtle considerations. +// +// First, note that not all case-fold equivalent distinct runes +// form an upper/lower pair. +// For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin) +// are three distinct runes that case-fold to each other. +// When we do add Unicode letters, we must not assume that upper/lower +// are the only case-equivalent pairs. +// Perhaps the Kelvin symbol would be disallowed entirely, for example. +// Or perhaps it would escape as "!!k", or perhaps as "(212A)". +// +// Second, it would be nice to allow Unicode marks as well as letters, +// but marks include combining marks, and then we must deal not +// only with case folding but also normalization: both U+00E9 ('é') +// and U+0065 U+0301 ('e' followed by combining acute accent) +// look the same on the page and are treated by some file systems +// as the same path. If we do allow Unicode marks in paths, there +// must be some kind of normalization to allow only one canonical +// encoding of any character used in an import path. +package module + +// IMPORTANT NOTE +// +// This file essentially defines the set of valid import paths for the go command. +// There are many subtle considerations, including Unicode ambiguity, +// security, network, and file system representations. +// +// This file also defines the set of valid module path and version combinations, +// another topic with many subtle considerations. +// +// Changes to the semantics in this file require approval from rsc. + +import ( + "fmt" + "sort" + "strings" + "unicode" + "unicode/utf8" + + "golang.org/x/mod/semver" + errors "golang.org/x/xerrors" +) + +// A Version (for clients, a module.Version) is defined by a module path and version pair. +// These are stored in their plain (unescaped) form. +type Version struct { + // Path is a module path, like "golang.org/x/text" or "rsc.io/quote/v2". + Path string + + // Version is usually a semantic version in canonical form. + // There are three exceptions to this general rule. + // First, the top-level target of a build has no specific version + // and uses Version = "". + // Second, during MVS calculations the version "none" is used + // to represent the decision to take no version of a given module. + // Third, filesystem paths found in "replace" directives are + // represented by a path with an empty version. + Version string `json:",omitempty"` +} + +// String returns a representation of the Version suitable for logging +// (Path@Version, or just Path if Version is empty). +func (m Version) String() string { + if m.Version == "" { + return m.Path + } + return m.Path + "@" + m.Version +} + +// A ModuleError indicates an error specific to a module. +type ModuleError struct { + Path string + Version string + Err error +} + +// VersionError returns a ModuleError derived from a Version and error, +// or err itself if it is already such an error. +func VersionError(v Version, err error) error { + var mErr *ModuleError + if errors.As(err, &mErr) && mErr.Path == v.Path && mErr.Version == v.Version { + return err + } + return &ModuleError{ + Path: v.Path, + Version: v.Version, + Err: err, + } +} + +func (e *ModuleError) Error() string { + if v, ok := e.Err.(*InvalidVersionError); ok { + return fmt.Sprintf("%s@%s: invalid %s: %v", e.Path, v.Version, v.noun(), v.Err) + } + if e.Version != "" { + return fmt.Sprintf("%s@%s: %v", e.Path, e.Version, e.Err) + } + return fmt.Sprintf("module %s: %v", e.Path, e.Err) +} + +func (e *ModuleError) Unwrap() error { return e.Err } + +// An InvalidVersionError indicates an error specific to a version, with the +// module path unknown or specified externally. +// +// A ModuleError may wrap an InvalidVersionError, but an InvalidVersionError +// must not wrap a ModuleError. +type InvalidVersionError struct { + Version string + Pseudo bool + Err error +} + +// noun returns either "version" or "pseudo-version", depending on whether +// e.Version is a pseudo-version. +func (e *InvalidVersionError) noun() string { + if e.Pseudo { + return "pseudo-version" + } + return "version" +} + +func (e *InvalidVersionError) Error() string { + return fmt.Sprintf("%s %q invalid: %s", e.noun(), e.Version, e.Err) +} + +func (e *InvalidVersionError) Unwrap() error { return e.Err } + +// Check checks that a given module path, version pair is valid. +// In addition to the path being a valid module path +// and the version being a valid semantic version, +// the two must correspond. +// For example, the path "yaml/v2" only corresponds to +// semantic versions beginning with "v2.". +func Check(path, version string) error { + if err := CheckPath(path); err != nil { + return err + } + if !semver.IsValid(version) { + return &ModuleError{ + Path: path, + Err: &InvalidVersionError{Version: version, Err: errors.New("not a semantic version")}, + } + } + _, pathMajor, _ := SplitPathVersion(path) + if err := CheckPathMajor(version, pathMajor); err != nil { + return &ModuleError{Path: path, Err: err} + } + return nil +} + +// firstPathOK reports whether r can appear in the first element of a module path. +// The first element of the path must be an LDH domain name, at least for now. +// To avoid case ambiguity, the domain name must be entirely lower case. +func firstPathOK(r rune) bool { + return r == '-' || r == '.' || + '0' <= r && r <= '9' || + 'a' <= r && r <= 'z' +} + +// pathOK reports whether r can appear in an import path element. +// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: + - . _ and ~. +// This matches what "go get" has historically recognized in import paths. +// TODO(rsc): We would like to allow Unicode letters, but that requires additional +// care in the safe encoding (see "escaped paths" above). +func pathOK(r rune) bool { + if r < utf8.RuneSelf { + return r == '+' || r == '-' || r == '.' || r == '_' || r == '~' || + '0' <= r && r <= '9' || + 'A' <= r && r <= 'Z' || + 'a' <= r && r <= 'z' + } + return false +} + +// fileNameOK reports whether r can appear in a file name. +// For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters. +// If we expand the set of allowed characters here, we have to +// work harder at detecting potential case-folding and normalization collisions. +// See note about "escaped paths" above. +func fileNameOK(r rune) bool { + if r < utf8.RuneSelf { + // Entire set of ASCII punctuation, from which we remove characters: + // ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~ + // We disallow some shell special characters: " ' * < > ? ` | + // (Note that some of those are disallowed by the Windows file system as well.) + // We also disallow path separators / : and \ (fileNameOK is only called on path element characters). + // We allow spaces (U+0020) in file names. + const allowed = "!#$%&()+,-.=@[]^_{}~ " + if '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' { + return true + } + for i := 0; i < len(allowed); i++ { + if rune(allowed[i]) == r { + return true + } + } + return false + } + // It may be OK to add more ASCII punctuation here, but only carefully. + // For example Windows disallows < > \, and macOS disallows :, so we must not allow those. + return unicode.IsLetter(r) +} + +// CheckPath checks that a module path is valid. +// A valid module path is a valid import path, as checked by CheckImportPath, +// with two additional constraints. +// First, the leading path element (up to the first slash, if any), +// by convention a domain name, must contain only lower-case ASCII letters, +// ASCII digits, dots (U+002E), and dashes (U+002D); +// it must contain at least one dot and cannot start with a dash. +// Second, for a final path element of the form /vN, where N looks numeric +// (ASCII digits and dots) must not begin with a leading zero, must not be /v1, +// and must not contain any dots. For paths beginning with "gopkg.in/", +// this second requirement is replaced by a requirement that the path +// follow the gopkg.in server's conventions. +func CheckPath(path string) error { + if err := checkPath(path, false); err != nil { + return fmt.Errorf("malformed module path %q: %v", path, err) + } + i := strings.Index(path, "/") + if i < 0 { + i = len(path) + } + if i == 0 { + return fmt.Errorf("malformed module path %q: leading slash", path) + } + if !strings.Contains(path[:i], ".") { + return fmt.Errorf("malformed module path %q: missing dot in first path element", path) + } + if path[0] == '-' { + return fmt.Errorf("malformed module path %q: leading dash in first path element", path) + } + for _, r := range path[:i] { + if !firstPathOK(r) { + return fmt.Errorf("malformed module path %q: invalid char %q in first path element", path, r) + } + } + if _, _, ok := SplitPathVersion(path); !ok { + return fmt.Errorf("malformed module path %q: invalid version", path) + } + return nil +} + +// CheckImportPath checks that an import path is valid. +// +// A valid import path consists of one or more valid path elements +// separated by slashes (U+002F). (It must not begin with nor end in a slash.) +// +// A valid path element is a non-empty string made up of +// ASCII letters, ASCII digits, and limited ASCII punctuation: + - . _ and ~. +// It must not begin or end with a dot (U+002E), nor contain two dots in a row. +// +// The element prefix up to the first dot must not be a reserved file name +// on Windows, regardless of case (CON, com1, NuL, and so on). +// +// CheckImportPath may be less restrictive in the future, but see the +// top-level package documentation for additional information about +// subtleties of Unicode. +func CheckImportPath(path string) error { + if err := checkPath(path, false); err != nil { + return fmt.Errorf("malformed import path %q: %v", path, err) + } + return nil +} + +// checkPath checks that a general path is valid. +// It returns an error describing why but not mentioning path. +// Because these checks apply to both module paths and import paths, +// the caller is expected to add the "malformed ___ path %q: " prefix. +// fileName indicates whether the final element of the path is a file name +// (as opposed to a directory name). +func checkPath(path string, fileName bool) error { + if !utf8.ValidString(path) { + return fmt.Errorf("invalid UTF-8") + } + if path == "" { + return fmt.Errorf("empty string") + } + if path[0] == '-' { + return fmt.Errorf("leading dash") + } + if strings.Contains(path, "//") { + return fmt.Errorf("double slash") + } + if path[len(path)-1] == '/' { + return fmt.Errorf("trailing slash") + } + elemStart := 0 + for i, r := range path { + if r == '/' { + if err := checkElem(path[elemStart:i], fileName); err != nil { + return err + } + elemStart = i + 1 + } + } + if err := checkElem(path[elemStart:], fileName); err != nil { + return err + } + return nil +} + +// checkElem checks whether an individual path element is valid. +// fileName indicates whether the element is a file name (not a directory name). +func checkElem(elem string, fileName bool) error { + if elem == "" { + return fmt.Errorf("empty path element") + } + if strings.Count(elem, ".") == len(elem) { + return fmt.Errorf("invalid path element %q", elem) + } + if elem[0] == '.' && !fileName { + return fmt.Errorf("leading dot in path element") + } + if elem[len(elem)-1] == '.' { + return fmt.Errorf("trailing dot in path element") + } + charOK := pathOK + if fileName { + charOK = fileNameOK + } + for _, r := range elem { + if !charOK(r) { + return fmt.Errorf("invalid char %q", r) + } + } + + // Windows disallows a bunch of path elements, sadly. + // See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file + short := elem + if i := strings.Index(short, "."); i >= 0 { + short = short[:i] + } + for _, bad := range badWindowsNames { + if strings.EqualFold(bad, short) { + return fmt.Errorf("%q disallowed as path element component on Windows", short) + } + } + return nil +} + +// CheckFilePath checks that a slash-separated file path is valid. +// The definition of a valid file path is the same as the definition +// of a valid import path except that the set of allowed characters is larger: +// all Unicode letters, ASCII digits, the ASCII space character (U+0020), +// and the ASCII punctuation characters +// “!#$%&()+,-.=@[]^_{}~”. +// (The excluded punctuation characters, " * < > ? ` ' | / \ and :, +// have special meanings in certain shells or operating systems.) +// +// CheckFilePath may be less restrictive in the future, but see the +// top-level package documentation for additional information about +// subtleties of Unicode. +func CheckFilePath(path string) error { + if err := checkPath(path, true); err != nil { + return fmt.Errorf("malformed file path %q: %v", path, err) + } + return nil +} + +// badWindowsNames are the reserved file path elements on Windows. +// See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file +var badWindowsNames = []string{ + "CON", + "PRN", + "AUX", + "NUL", + "COM1", + "COM2", + "COM3", + "COM4", + "COM5", + "COM6", + "COM7", + "COM8", + "COM9", + "LPT1", + "LPT2", + "LPT3", + "LPT4", + "LPT5", + "LPT6", + "LPT7", + "LPT8", + "LPT9", +} + +// SplitPathVersion returns prefix and major version such that prefix+pathMajor == path +// and version is either empty or "/vN" for N >= 2. +// As a special case, gopkg.in paths are recognized directly; +// they require ".vN" instead of "/vN", and for all N, not just N >= 2. +// SplitPathVersion returns with ok = false when presented with +// a path whose last path element does not satisfy the constraints +// applied by CheckPath, such as "example.com/pkg/v1" or "example.com/pkg/v1.2". +func SplitPathVersion(path string) (prefix, pathMajor string, ok bool) { + if strings.HasPrefix(path, "gopkg.in/") { + return splitGopkgIn(path) + } + + i := len(path) + dot := false + for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9' || path[i-1] == '.') { + if path[i-1] == '.' { + dot = true + } + i-- + } + if i <= 1 || i == len(path) || path[i-1] != 'v' || path[i-2] != '/' { + return path, "", true + } + prefix, pathMajor = path[:i-2], path[i-2:] + if dot || len(pathMajor) <= 2 || pathMajor[2] == '0' || pathMajor == "/v1" { + return path, "", false + } + return prefix, pathMajor, true +} + +// splitGopkgIn is like SplitPathVersion but only for gopkg.in paths. +func splitGopkgIn(path string) (prefix, pathMajor string, ok bool) { + if !strings.HasPrefix(path, "gopkg.in/") { + return path, "", false + } + i := len(path) + if strings.HasSuffix(path, "-unstable") { + i -= len("-unstable") + } + for i > 0 && ('0' <= path[i-1] && path[i-1] <= '9') { + i-- + } + if i <= 1 || path[i-1] != 'v' || path[i-2] != '.' { + // All gopkg.in paths must end in vN for some N. + return path, "", false + } + prefix, pathMajor = path[:i-2], path[i-2:] + if len(pathMajor) <= 2 || pathMajor[2] == '0' && pathMajor != ".v0" { + return path, "", false + } + return prefix, pathMajor, true +} + +// MatchPathMajor reports whether the semantic version v +// matches the path major version pathMajor. +// +// MatchPathMajor returns true if and only if CheckPathMajor returns nil. +func MatchPathMajor(v, pathMajor string) bool { + return CheckPathMajor(v, pathMajor) == nil +} + +// CheckPathMajor returns a non-nil error if the semantic version v +// does not match the path major version pathMajor. +func CheckPathMajor(v, pathMajor string) error { + // TODO(jayconrod): return errors or panic for invalid inputs. This function + // (and others) was covered by integration tests for cmd/go, and surrounding + // code protected against invalid inputs like non-canonical versions. + if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { + pathMajor = strings.TrimSuffix(pathMajor, "-unstable") + } + if strings.HasPrefix(v, "v0.0.0-") && pathMajor == ".v1" { + // Allow old bug in pseudo-versions that generated v0.0.0- pseudoversion for gopkg .v1. + // For example, gopkg.in/yaml.v2@v2.2.1's go.mod requires gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405. + return nil + } + m := semver.Major(v) + if pathMajor == "" { + if m == "v0" || m == "v1" || semver.Build(v) == "+incompatible" { + return nil + } + pathMajor = "v0 or v1" + } else if pathMajor[0] == '/' || pathMajor[0] == '.' { + if m == pathMajor[1:] { + return nil + } + pathMajor = pathMajor[1:] + } + return &InvalidVersionError{ + Version: v, + Err: fmt.Errorf("should be %s, not %s", pathMajor, semver.Major(v)), + } +} + +// PathMajorPrefix returns the major-version tag prefix implied by pathMajor. +// An empty PathMajorPrefix allows either v0 or v1. +// +// Note that MatchPathMajor may accept some versions that do not actually begin +// with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1' +// pathMajor, even though that pathMajor implies 'v1' tagging. +func PathMajorPrefix(pathMajor string) string { + if pathMajor == "" { + return "" + } + if pathMajor[0] != '/' && pathMajor[0] != '.' { + panic("pathMajor suffix " + pathMajor + " passed to PathMajorPrefix lacks separator") + } + if strings.HasPrefix(pathMajor, ".v") && strings.HasSuffix(pathMajor, "-unstable") { + pathMajor = strings.TrimSuffix(pathMajor, "-unstable") + } + m := pathMajor[1:] + if m != semver.Major(m) { + panic("pathMajor suffix " + pathMajor + "passed to PathMajorPrefix is not a valid major version") + } + return m +} + +// CanonicalVersion returns the canonical form of the version string v. +// It is the same as semver.Canonical(v) except that it preserves the special build suffix "+incompatible". +func CanonicalVersion(v string) string { + cv := semver.Canonical(v) + if semver.Build(v) == "+incompatible" { + cv += "+incompatible" + } + return cv +} + +// Sort sorts the list by Path, breaking ties by comparing Version fields. +// The Version fields are interpreted as semantic versions (using semver.Compare) +// optionally followed by a tie-breaking suffix introduced by a slash character, +// like in "v0.0.1/go.mod". +func Sort(list []Version) { + sort.Slice(list, func(i, j int) bool { + mi := list[i] + mj := list[j] + if mi.Path != mj.Path { + return mi.Path < mj.Path + } + // To help go.sum formatting, allow version/file. + // Compare semver prefix by semver rules, + // file by string order. + vi := mi.Version + vj := mj.Version + var fi, fj string + if k := strings.Index(vi, "/"); k >= 0 { + vi, fi = vi[:k], vi[k:] + } + if k := strings.Index(vj, "/"); k >= 0 { + vj, fj = vj[:k], vj[k:] + } + if vi != vj { + return semver.Compare(vi, vj) < 0 + } + return fi < fj + }) +} + +// EscapePath returns the escaped form of the given module path. +// It fails if the module path is invalid. +func EscapePath(path string) (escaped string, err error) { + if err := CheckPath(path); err != nil { + return "", err + } + + return escapeString(path) +} + +// EscapeVersion returns the escaped form of the given module version. +// Versions are allowed to be in non-semver form but must be valid file names +// and not contain exclamation marks. +func EscapeVersion(v string) (escaped string, err error) { + if err := checkElem(v, true); err != nil || strings.Contains(v, "!") { + return "", &InvalidVersionError{ + Version: v, + Err: fmt.Errorf("disallowed version string"), + } + } + return escapeString(v) +} + +func escapeString(s string) (escaped string, err error) { + haveUpper := false + for _, r := range s { + if r == '!' || r >= utf8.RuneSelf { + // This should be disallowed by CheckPath, but diagnose anyway. + // The correctness of the escaping loop below depends on it. + return "", fmt.Errorf("internal error: inconsistency in EscapePath") + } + if 'A' <= r && r <= 'Z' { + haveUpper = true + } + } + + if !haveUpper { + return s, nil + } + + var buf []byte + for _, r := range s { + if 'A' <= r && r <= 'Z' { + buf = append(buf, '!', byte(r+'a'-'A')) + } else { + buf = append(buf, byte(r)) + } + } + return string(buf), nil +} + +// UnescapePath returns the module path for the given escaped path. +// It fails if the escaped path is invalid or describes an invalid path. +func UnescapePath(escaped string) (path string, err error) { + path, ok := unescapeString(escaped) + if !ok { + return "", fmt.Errorf("invalid escaped module path %q", escaped) + } + if err := CheckPath(path); err != nil { + return "", fmt.Errorf("invalid escaped module path %q: %v", escaped, err) + } + return path, nil +} + +// UnescapeVersion returns the version string for the given escaped version. +// It fails if the escaped form is invalid or describes an invalid version. +// Versions are allowed to be in non-semver form but must be valid file names +// and not contain exclamation marks. +func UnescapeVersion(escaped string) (v string, err error) { + v, ok := unescapeString(escaped) + if !ok { + return "", fmt.Errorf("invalid escaped version %q", escaped) + } + if err := checkElem(v, true); err != nil { + return "", fmt.Errorf("invalid escaped version %q: %v", v, err) + } + return v, nil +} + +func unescapeString(escaped string) (string, bool) { + var buf []byte + + bang := false + for _, r := range escaped { + if r >= utf8.RuneSelf { + return "", false + } + if bang { + bang = false + if r < 'a' || 'z' < r { + return "", false + } + buf = append(buf, byte(r+'A'-'a')) + continue + } + if r == '!' { + bang = true + continue + } + if 'A' <= r && r <= 'Z' { + return "", false + } + buf = append(buf, byte(r)) + } + if bang { + return "", false + } + return string(buf), true +} diff --git a/libgo/go/golang.org/x/mod/semver/semver.go b/libgo/go/golang.org/x/mod/semver/semver.go new file mode 100644 index 00000000000..2988e3cf9c5 --- /dev/null +++ b/libgo/go/golang.org/x/mod/semver/semver.go @@ -0,0 +1,388 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package semver implements comparison of semantic version strings. +// In this package, semantic version strings must begin with a leading "v", +// as in "v1.0.0". +// +// The general form of a semantic version string accepted by this package is +// +// vMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]] +// +// where square brackets indicate optional parts of the syntax; +// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros; +// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers +// using only alphanumeric characters and hyphens; and +// all-numeric PRERELEASE identifiers must not have leading zeros. +// +// This package follows Semantic Versioning 2.0.0 (see semver.org) +// with two exceptions. First, it requires the "v" prefix. Second, it recognizes +// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes) +// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0. +package semver + +// parsed returns the parsed form of a semantic version string. +type parsed struct { + major string + minor string + patch string + short string + prerelease string + build string + err string +} + +// IsValid reports whether v is a valid semantic version string. +func IsValid(v string) bool { + _, ok := parse(v) + return ok +} + +// Canonical returns the canonical formatting of the semantic version v. +// It fills in any missing .MINOR or .PATCH and discards build metadata. +// Two semantic versions compare equal only if their canonical formattings +// are identical strings. +// The canonical invalid semantic version is the empty string. +func Canonical(v string) string { + p, ok := parse(v) + if !ok { + return "" + } + if p.build != "" { + return v[:len(v)-len(p.build)] + } + if p.short != "" { + return v + p.short + } + return v +} + +// Major returns the major version prefix of the semantic version v. +// For example, Major("v2.1.0") == "v2". +// If v is an invalid semantic version string, Major returns the empty string. +func Major(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return v[:1+len(pv.major)] +} + +// MajorMinor returns the major.minor version prefix of the semantic version v. +// For example, MajorMinor("v2.1.0") == "v2.1". +// If v is an invalid semantic version string, MajorMinor returns the empty string. +func MajorMinor(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + i := 1 + len(pv.major) + if j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor { + return v[:j] + } + return v[:i] + "." + pv.minor +} + +// Prerelease returns the prerelease suffix of the semantic version v. +// For example, Prerelease("v2.1.0-pre+meta") == "-pre". +// If v is an invalid semantic version string, Prerelease returns the empty string. +func Prerelease(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.prerelease +} + +// Build returns the build suffix of the semantic version v. +// For example, Build("v2.1.0+meta") == "+meta". +// If v is an invalid semantic version string, Build returns the empty string. +func Build(v string) string { + pv, ok := parse(v) + if !ok { + return "" + } + return pv.build +} + +// Compare returns an integer comparing two versions according to +// semantic version precedence. +// The result will be 0 if v == w, -1 if v < w, or +1 if v > w. +// +// An invalid semantic version string is considered less than a valid one. +// All invalid semantic version strings compare equal to each other. +func Compare(v, w string) int { + pv, ok1 := parse(v) + pw, ok2 := parse(w) + if !ok1 && !ok2 { + return 0 + } + if !ok1 { + return -1 + } + if !ok2 { + return +1 + } + if c := compareInt(pv.major, pw.major); c != 0 { + return c + } + if c := compareInt(pv.minor, pw.minor); c != 0 { + return c + } + if c := compareInt(pv.patch, pw.patch); c != 0 { + return c + } + return comparePrerelease(pv.prerelease, pw.prerelease) +} + +// Max canonicalizes its arguments and then returns the version string +// that compares greater. +func Max(v, w string) string { + v = Canonical(v) + w = Canonical(w) + if Compare(v, w) > 0 { + return v + } + return w +} + +func parse(v string) (p parsed, ok bool) { + if v == "" || v[0] != 'v' { + p.err = "missing v prefix" + return + } + p.major, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad major version" + return + } + if v == "" { + p.minor = "0" + p.patch = "0" + p.short = ".0.0" + return + } + if v[0] != '.' { + p.err = "bad minor prefix" + ok = false + return + } + p.minor, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad minor version" + return + } + if v == "" { + p.patch = "0" + p.short = ".0" + return + } + if v[0] != '.' { + p.err = "bad patch prefix" + ok = false + return + } + p.patch, v, ok = parseInt(v[1:]) + if !ok { + p.err = "bad patch version" + return + } + if len(v) > 0 && v[0] == '-' { + p.prerelease, v, ok = parsePrerelease(v) + if !ok { + p.err = "bad prerelease" + return + } + } + if len(v) > 0 && v[0] == '+' { + p.build, v, ok = parseBuild(v) + if !ok { + p.err = "bad build" + return + } + } + if v != "" { + p.err = "junk on end" + ok = false + return + } + ok = true + return +} + +func parseInt(v string) (t, rest string, ok bool) { + if v == "" { + return + } + if v[0] < '0' || '9' < v[0] { + return + } + i := 1 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + if v[0] == '0' && i != 1 { + return + } + return v[:i], v[i:], true +} + +func parsePrerelease(v string) (t, rest string, ok bool) { + // "A pre-release version MAY be denoted by appending a hyphen and + // a series of dot separated identifiers immediately following the patch version. + // Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + // Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes." + if v == "" || v[0] != '-' { + return + } + i := 1 + start := 1 + for i < len(v) && v[i] != '+' { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i || isBadNum(v[start:i]) { + return + } + start = i + 1 + } + i++ + } + if start == i || isBadNum(v[start:i]) { + return + } + return v[:i], v[i:], true +} + +func parseBuild(v string) (t, rest string, ok bool) { + if v == "" || v[0] != '+' { + return + } + i := 1 + start := 1 + for i < len(v) { + if !isIdentChar(v[i]) && v[i] != '.' { + return + } + if v[i] == '.' { + if start == i { + return + } + start = i + 1 + } + i++ + } + if start == i { + return + } + return v[:i], v[i:], true +} + +func isIdentChar(c byte) bool { + return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' +} + +func isBadNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) && i > 1 && v[0] == '0' +} + +func isNum(v string) bool { + i := 0 + for i < len(v) && '0' <= v[i] && v[i] <= '9' { + i++ + } + return i == len(v) +} + +func compareInt(x, y string) int { + if x == y { + return 0 + } + if len(x) < len(y) { + return -1 + } + if len(x) > len(y) { + return +1 + } + if x < y { + return -1 + } else { + return +1 + } +} + +func comparePrerelease(x, y string) int { + // "When major, minor, and patch are equal, a pre-release version has + // lower precedence than a normal version. + // Example: 1.0.0-alpha < 1.0.0. + // Precedence for two pre-release versions with the same major, minor, + // and patch version MUST be determined by comparing each dot separated + // identifier from left to right until a difference is found as follows: + // identifiers consisting of only digits are compared numerically and + // identifiers with letters or hyphens are compared lexically in ASCII + // sort order. Numeric identifiers always have lower precedence than + // non-numeric identifiers. A larger set of pre-release fields has a + // higher precedence than a smaller set, if all of the preceding + // identifiers are equal. + // Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < + // 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0." + if x == y { + return 0 + } + if x == "" { + return +1 + } + if y == "" { + return -1 + } + for x != "" && y != "" { + x = x[1:] // skip - or . + y = y[1:] // skip - or . + var dx, dy string + dx, x = nextIdent(x) + dy, y = nextIdent(y) + if dx != dy { + ix := isNum(dx) + iy := isNum(dy) + if ix != iy { + if ix { + return -1 + } else { + return +1 + } + } + if ix { + if len(dx) < len(dy) { + return -1 + } + if len(dx) > len(dy) { + return +1 + } + } + if dx < dy { + return -1 + } else { + return +1 + } + } + } + if x == "" { + return -1 + } else { + return +1 + } +} + +func nextIdent(x string) (dx, rest string) { + i := 0 + for i < len(x) && x[i] != '.' { + i++ + } + return x[:i], x[i:] +} diff --git a/libgo/go/golang.org/x/mod/sumdb/cache.go b/libgo/go/golang.org/x/mod/sumdb/cache.go new file mode 100644 index 00000000000..629e591f425 --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/cache.go @@ -0,0 +1,59 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Parallel cache. +// This file is copied from cmd/go/internal/par. + +package sumdb + +import ( + "sync" + "sync/atomic" +) + +// parCache runs an action once per key and caches the result. +type parCache struct { + m sync.Map +} + +type cacheEntry struct { + done uint32 + mu sync.Mutex + result interface{} +} + +// Do calls the function f if and only if Do is being called for the first time with this key. +// No call to Do with a given key returns until the one call to f returns. +// Do returns the value returned by the one call to f. +func (c *parCache) Do(key interface{}, f func() interface{}) interface{} { + entryIface, ok := c.m.Load(key) + if !ok { + entryIface, _ = c.m.LoadOrStore(key, new(cacheEntry)) + } + e := entryIface.(*cacheEntry) + if atomic.LoadUint32(&e.done) == 0 { + e.mu.Lock() + if atomic.LoadUint32(&e.done) == 0 { + e.result = f() + atomic.StoreUint32(&e.done, 1) + } + e.mu.Unlock() + } + return e.result +} + +// Get returns the cached result associated with key. +// It returns nil if there is no such result. +// If the result for key is being computed, Get does not wait for the computation to finish. +func (c *parCache) Get(key interface{}) interface{} { + entryIface, ok := c.m.Load(key) + if !ok { + return nil + } + e := entryIface.(*cacheEntry) + if atomic.LoadUint32(&e.done) == 0 { + return nil + } + return e.result +} diff --git a/libgo/go/golang.org/x/mod/sumdb/client.go b/libgo/go/golang.org/x/mod/sumdb/client.go new file mode 100644 index 00000000000..70dd56f1037 --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/client.go @@ -0,0 +1,671 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sumdb + +import ( + "bytes" + "errors" + "fmt" + "path" + "strings" + "sync" + "sync/atomic" + + "golang.org/x/mod/module" + "golang.org/x/mod/sumdb/note" + "golang.org/x/mod/sumdb/tlog" +) + +// A ClientOps provides the external operations +// (file caching, HTTP fetches, and so on) needed by the Client. +// The methods must be safe for concurrent use by multiple goroutines. +type ClientOps interface { + // ReadRemote reads and returns the content served at the given path + // on the remote database server. The path begins with "/lookup" or "/tile/", + // and there is no need to parse the path in any way. + // It is the implementation's responsibility to turn that path into a full URL + // and make the HTTP request. ReadRemote should return an error for + // any non-200 HTTP response status. + ReadRemote(path string) ([]byte, error) + + // ReadConfig reads and returns the content of the named configuration file. + // There are only a fixed set of configuration files. + // + // "key" returns a file containing the verifier key for the server. + // + // serverName + "/latest" returns a file containing the latest known + // signed tree from the server. + // To signal that the client wishes to start with an "empty" signed tree, + // ReadConfig can return a successful empty result (0 bytes of data). + ReadConfig(file string) ([]byte, error) + + // WriteConfig updates the content of the named configuration file, + // changing it from the old []byte to the new []byte. + // If the old []byte does not match the stored configuration, + // WriteConfig must return ErrWriteConflict. + // Otherwise, WriteConfig should atomically replace old with new. + // The "key" configuration file is never written using WriteConfig. + WriteConfig(file string, old, new []byte) error + + // ReadCache reads and returns the content of the named cache file. + // Any returned error will be treated as equivalent to the file not existing. + // There can be arbitrarily many cache files, such as: + // serverName/lookup/pkg@version + // serverName/tile/8/1/x123/456 + ReadCache(file string) ([]byte, error) + + // WriteCache writes the named cache file. + WriteCache(file string, data []byte) + + // Log prints the given log message (such as with log.Print) + Log(msg string) + + // SecurityError prints the given security error log message. + // The Client returns ErrSecurity from any operation that invokes SecurityError, + // but the return value is mainly for testing. In a real program, + // SecurityError should typically print the message and call log.Fatal or os.Exit. + SecurityError(msg string) +} + +// ErrWriteConflict signals a write conflict during Client.WriteConfig. +var ErrWriteConflict = errors.New("write conflict") + +// ErrSecurity is returned by Client operations that invoke Client.SecurityError. +var ErrSecurity = errors.New("security error: misbehaving server") + +// A Client is a client connection to a checksum database. +// All the methods are safe for simultaneous use by multiple goroutines. +type Client struct { + ops ClientOps // access to operations in the external world + + didLookup uint32 + + // one-time initialized data + initOnce sync.Once + initErr error // init error, if any + name string // name of accepted verifier + verifiers note.Verifiers // accepted verifiers (just one, but Verifiers for note.Open) + tileReader tileReader + tileHeight int + nosumdb string + + record parCache // cache of record lookup, keyed by path@vers + tileCache parCache // cache of c.readTile, keyed by tile + + latestMu sync.Mutex + latest tlog.Tree // latest known tree head + latestMsg []byte // encoded signed note for latest + + tileSavedMu sync.Mutex + tileSaved map[tlog.Tile]bool // which tiles have been saved using c.ops.WriteCache already +} + +// NewClient returns a new Client using the given Client. +func NewClient(ops ClientOps) *Client { + return &Client{ + ops: ops, + } +} + +// init initiailzes the client (if not already initialized) +// and returns any initialization error. +func (c *Client) init() error { + c.initOnce.Do(c.initWork) + return c.initErr +} + +// initWork does the actual initialization work. +func (c *Client) initWork() { + defer func() { + if c.initErr != nil { + c.initErr = fmt.Errorf("initializing sumdb.Client: %v", c.initErr) + } + }() + + c.tileReader.c = c + if c.tileHeight == 0 { + c.tileHeight = 8 + } + c.tileSaved = make(map[tlog.Tile]bool) + + vkey, err := c.ops.ReadConfig("key") + if err != nil { + c.initErr = err + return + } + verifier, err := note.NewVerifier(strings.TrimSpace(string(vkey))) + if err != nil { + c.initErr = err + return + } + c.verifiers = note.VerifierList(verifier) + c.name = verifier.Name() + + data, err := c.ops.ReadConfig(c.name + "/latest") + if err != nil { + c.initErr = err + return + } + if err := c.mergeLatest(data); err != nil { + c.initErr = err + return + } +} + +// SetTileHeight sets the tile height for the Client. +// Any call to SetTileHeight must happen before the first call to Lookup. +// If SetTileHeight is not called, the Client defaults to tile height 8. +// SetTileHeight can be called at most once, +// and if so it must be called before the first call to Lookup. +func (c *Client) SetTileHeight(height int) { + if atomic.LoadUint32(&c.didLookup) != 0 { + panic("SetTileHeight used after Lookup") + } + if height <= 0 { + panic("invalid call to SetTileHeight") + } + if c.tileHeight != 0 { + panic("multiple calls to SetTileHeight") + } + c.tileHeight = height +} + +// SetGONOSUMDB sets the list of comma-separated GONOSUMDB patterns for the Client. +// For any module path matching one of the patterns, +// Lookup will return ErrGONOSUMDB. +// SetGONOSUMDB can be called at most once, +// and if so it must be called before the first call to Lookup. +func (c *Client) SetGONOSUMDB(list string) { + if atomic.LoadUint32(&c.didLookup) != 0 { + panic("SetGONOSUMDB used after Lookup") + } + if c.nosumdb != "" { + panic("multiple calls to SetGONOSUMDB") + } + c.nosumdb = list +} + +// ErrGONOSUMDB is returned by Lookup for paths that match +// a pattern listed in the GONOSUMDB list (set by SetGONOSUMDB, +// usually from the environment variable). +var ErrGONOSUMDB = errors.New("skipped (listed in GONOSUMDB)") + +func (c *Client) skip(target string) bool { + return globsMatchPath(c.nosumdb, target) +} + +// globsMatchPath reports whether any path prefix of target +// matches one of the glob patterns (as defined by path.Match) +// in the comma-separated globs list. +// It ignores any empty or malformed patterns in the list. +func globsMatchPath(globs, target string) bool { + for globs != "" { + // Extract next non-empty glob in comma-separated list. + var glob string + if i := strings.Index(globs, ","); i >= 0 { + glob, globs = globs[:i], globs[i+1:] + } else { + glob, globs = globs, "" + } + if glob == "" { + continue + } + + // A glob with N+1 path elements (N slashes) needs to be matched + // against the first N+1 path elements of target, + // which end just before the N+1'th slash. + n := strings.Count(glob, "/") + prefix := target + // Walk target, counting slashes, truncating at the N+1'th slash. + for i := 0; i < len(target); i++ { + if target[i] == '/' { + if n == 0 { + prefix = target[:i] + break + } + n-- + } + } + if n > 0 { + // Not enough prefix elements. + continue + } + matched, _ := path.Match(glob, prefix) + if matched { + return true + } + } + return false +} + +// Lookup returns the go.sum lines for the given module path and version. +// The version may end in a /go.mod suffix, in which case Lookup returns +// the go.sum lines for the module's go.mod-only hash. +func (c *Client) Lookup(path, vers string) (lines []string, err error) { + atomic.StoreUint32(&c.didLookup, 1) + + if c.skip(path) { + return nil, ErrGONOSUMDB + } + + defer func() { + if err != nil { + err = fmt.Errorf("%s@%s: %v", path, vers, err) + } + }() + + if err := c.init(); err != nil { + return nil, err + } + + // Prepare encoded cache filename / URL. + epath, err := module.EscapePath(path) + if err != nil { + return nil, err + } + evers, err := module.EscapeVersion(strings.TrimSuffix(vers, "/go.mod")) + if err != nil { + return nil, err + } + remotePath := "/lookup/" + epath + "@" + evers + file := c.name + remotePath + + // Fetch the data. + // The lookupCache avoids redundant ReadCache/GetURL operations + // (especially since go.sum lines tend to come in pairs for a given + // path and version) and also avoids having multiple of the same + // request in flight at once. + type cached struct { + data []byte + err error + } + result := c.record.Do(file, func() interface{} { + // Try the on-disk cache, or else get from web. + writeCache := false + data, err := c.ops.ReadCache(file) + if err != nil { + data, err = c.ops.ReadRemote(remotePath) + if err != nil { + return cached{nil, err} + } + writeCache = true + } + + // Validate the record before using it for anything. + id, text, treeMsg, err := tlog.ParseRecord(data) + if err != nil { + return cached{nil, err} + } + if err := c.mergeLatest(treeMsg); err != nil { + return cached{nil, err} + } + if err := c.checkRecord(id, text); err != nil { + return cached{nil, err} + } + + // Now that we've validated the record, + // save it to the on-disk cache (unless that's where it came from). + if writeCache { + c.ops.WriteCache(file, data) + } + + return cached{data, nil} + }).(cached) + if result.err != nil { + return nil, result.err + } + + // Extract the lines for the specific version we want + // (with or without /go.mod). + prefix := path + " " + vers + " " + var hashes []string + for _, line := range strings.Split(string(result.data), "\n") { + if strings.HasPrefix(line, prefix) { + hashes = append(hashes, line) + } + } + return hashes, nil +} + +// mergeLatest merges the tree head in msg +// with the Client's current latest tree head, +// ensuring the result is a consistent timeline. +// If the result is inconsistent, mergeLatest calls c.ops.SecurityError +// with a detailed security error message and then +// (only if c.ops.SecurityError does not exit the program) returns ErrSecurity. +// If the Client's current latest tree head moves forward, +// mergeLatest updates the underlying configuration file as well, +// taking care to merge any independent updates to that configuration. +func (c *Client) mergeLatest(msg []byte) error { + // Merge msg into our in-memory copy of the latest tree head. + when, err := c.mergeLatestMem(msg) + if err != nil { + return err + } + if when != msgFuture { + // msg matched our present or was in the past. + // No change to our present, so no update of config file. + return nil + } + + // Flush our extended timeline back out to the configuration file. + // If the configuration file has been updated in the interim, + // we need to merge any updates made there as well. + // Note that writeConfig is an atomic compare-and-swap. + for { + msg, err := c.ops.ReadConfig(c.name + "/latest") + if err != nil { + return err + } + when, err := c.mergeLatestMem(msg) + if err != nil { + return err + } + if when != msgPast { + // msg matched our present or was from the future, + // and now our in-memory copy matches. + return nil + } + + // msg (== config) is in the past, so we need to update it. + c.latestMu.Lock() + latestMsg := c.latestMsg + c.latestMu.Unlock() + if err := c.ops.WriteConfig(c.name+"/latest", msg, latestMsg); err != ErrWriteConflict { + // Success or a non-write-conflict error. + return err + } + } +} + +const ( + msgPast = 1 + iota + msgNow + msgFuture +) + +// mergeLatestMem is like mergeLatest but is only concerned with +// updating the in-memory copy of the latest tree head (c.latest) +// not the configuration file. +// The when result explains when msg happened relative to our +// previous idea of c.latest: +// msgPast means msg was from before c.latest, +// msgNow means msg was exactly c.latest, and +// msgFuture means msg was from after c.latest, which has now been updated. +func (c *Client) mergeLatestMem(msg []byte) (when int, err error) { + if len(msg) == 0 { + // Accept empty msg as the unsigned, empty timeline. + c.latestMu.Lock() + latest := c.latest + c.latestMu.Unlock() + if latest.N == 0 { + return msgNow, nil + } + return msgPast, nil + } + + note, err := note.Open(msg, c.verifiers) + if err != nil { + return 0, fmt.Errorf("reading tree note: %v\nnote:\n%s", err, msg) + } + tree, err := tlog.ParseTree([]byte(note.Text)) + if err != nil { + return 0, fmt.Errorf("reading tree: %v\ntree:\n%s", err, note.Text) + } + + // Other lookups may be calling mergeLatest with other heads, + // so c.latest is changing underfoot. We don't want to hold the + // c.mu lock during tile fetches, so loop trying to update c.latest. + c.latestMu.Lock() + latest := c.latest + latestMsg := c.latestMsg + c.latestMu.Unlock() + + for { + // If the tree head looks old, check that it is on our timeline. + if tree.N <= latest.N { + if err := c.checkTrees(tree, msg, latest, latestMsg); err != nil { + return 0, err + } + if tree.N < latest.N { + return msgPast, nil + } + return msgNow, nil + } + + // The tree head looks new. Check that we are on its timeline and try to move our timeline forward. + if err := c.checkTrees(latest, latestMsg, tree, msg); err != nil { + return 0, err + } + + // Install our msg if possible. + // Otherwise we will go around again. + c.latestMu.Lock() + installed := false + if c.latest == latest { + installed = true + c.latest = tree + c.latestMsg = msg + } else { + latest = c.latest + latestMsg = c.latestMsg + } + c.latestMu.Unlock() + + if installed { + return msgFuture, nil + } + } +} + +// checkTrees checks that older (from olderNote) is contained in newer (from newerNote). +// If an error occurs, such as malformed data or a network problem, checkTrees returns that error. +// If on the other hand checkTrees finds evidence of misbehavior, it prepares a detailed +// message and calls log.Fatal. +func (c *Client) checkTrees(older tlog.Tree, olderNote []byte, newer tlog.Tree, newerNote []byte) error { + thr := tlog.TileHashReader(newer, &c.tileReader) + h, err := tlog.TreeHash(older.N, thr) + if err != nil { + if older.N == newer.N { + return fmt.Errorf("checking tree#%d: %v", older.N, err) + } + return fmt.Errorf("checking tree#%d against tree#%d: %v", older.N, newer.N, err) + } + if h == older.Hash { + return nil + } + + // Detected a fork in the tree timeline. + // Start by reporting the inconsistent signed tree notes. + var buf bytes.Buffer + fmt.Fprintf(&buf, "SECURITY ERROR\n") + fmt.Fprintf(&buf, "go.sum database server misbehavior detected!\n\n") + indent := func(b []byte) []byte { + return bytes.Replace(b, []byte("\n"), []byte("\n\t"), -1) + } + fmt.Fprintf(&buf, "old database:\n\t%s\n", indent(olderNote)) + fmt.Fprintf(&buf, "new database:\n\t%s\n", indent(newerNote)) + + // The notes alone are not enough to prove the inconsistency. + // We also need to show that the newer note's tree hash for older.N + // does not match older.Hash. The consumer of this report could + // of course consult the server to try to verify the inconsistency, + // but we are holding all the bits we need to prove it right now, + // so we might as well print them and make the report not depend + // on the continued availability of the misbehaving server. + // Preparing this data only reuses the tiled hashes needed for + // tlog.TreeHash(older.N, thr) above, so assuming thr is caching tiles, + // there are no new access to the server here, and these operations cannot fail. + fmt.Fprintf(&buf, "proof of misbehavior:\n\t%v", h) + if p, err := tlog.ProveTree(newer.N, older.N, thr); err != nil { + fmt.Fprintf(&buf, "\tinternal error: %v\n", err) + } else if err := tlog.CheckTree(p, newer.N, newer.Hash, older.N, h); err != nil { + fmt.Fprintf(&buf, "\tinternal error: generated inconsistent proof\n") + } else { + for _, h := range p { + fmt.Fprintf(&buf, "\n\t%v", h) + } + } + c.ops.SecurityError(buf.String()) + return ErrSecurity +} + +// checkRecord checks that record #id's hash matches data. +func (c *Client) checkRecord(id int64, data []byte) error { + c.latestMu.Lock() + latest := c.latest + c.latestMu.Unlock() + + if id >= latest.N { + return fmt.Errorf("cannot validate record %d in tree of size %d", id, latest.N) + } + hashes, err := tlog.TileHashReader(latest, &c.tileReader).ReadHashes([]int64{tlog.StoredHashIndex(0, id)}) + if err != nil { + return err + } + if hashes[0] == tlog.RecordHash(data) { + return nil + } + return fmt.Errorf("cannot authenticate record data in server response") +} + +// tileReader is a *Client wrapper that implements tlog.TileReader. +// The separate type avoids exposing the ReadTiles and SaveTiles +// methods on Client itself. +type tileReader struct { + c *Client +} + +func (r *tileReader) Height() int { + return r.c.tileHeight +} + +// ReadTiles reads and returns the requested tiles, +// either from the on-disk cache or the server. +func (r *tileReader) ReadTiles(tiles []tlog.Tile) ([][]byte, error) { + // Read all the tiles in parallel. + data := make([][]byte, len(tiles)) + errs := make([]error, len(tiles)) + var wg sync.WaitGroup + for i, tile := range tiles { + wg.Add(1) + go func(i int, tile tlog.Tile) { + defer wg.Done() + data[i], errs[i] = r.c.readTile(tile) + }(i, tile) + } + wg.Wait() + + for _, err := range errs { + if err != nil { + return nil, err + } + } + + return data, nil +} + +// tileCacheKey returns the cache key for the tile. +func (c *Client) tileCacheKey(tile tlog.Tile) string { + return c.name + "/" + tile.Path() +} + +// tileRemotePath returns the remote path for the tile. +func (c *Client) tileRemotePath(tile tlog.Tile) string { + return "/" + tile.Path() +} + +// readTile reads a single tile, either from the on-disk cache or the server. +func (c *Client) readTile(tile tlog.Tile) ([]byte, error) { + type cached struct { + data []byte + err error + } + + result := c.tileCache.Do(tile, func() interface{} { + // Try the requested tile in on-disk cache. + data, err := c.ops.ReadCache(c.tileCacheKey(tile)) + if err == nil { + c.markTileSaved(tile) + return cached{data, nil} + } + + // Try the full tile in on-disk cache (if requested tile not already full). + // We only save authenticated tiles to the on-disk cache, + // so the recreated prefix is equally authenticated. + full := tile + full.W = 1 << uint(tile.H) + if tile != full { + data, err := c.ops.ReadCache(c.tileCacheKey(full)) + if err == nil { + c.markTileSaved(tile) // don't save tile later; we already have full + return cached{data[:len(data)/full.W*tile.W], nil} + } + } + + // Try requested tile from server. + data, err = c.ops.ReadRemote(c.tileRemotePath(tile)) + if err == nil { + return cached{data, nil} + } + + // Try full tile on server. + // If the partial tile does not exist, it should be because + // the tile has been completed and only the complete one + // is available. + if tile != full { + data, err := c.ops.ReadRemote(c.tileRemotePath(full)) + if err == nil { + // Note: We could save the full tile in the on-disk cache here, + // but we don't know if it is valid yet, and we will only find out + // about the partial data, not the full data. So let SaveTiles + // save the partial tile, and we'll just refetch the full tile later + // once we can validate more (or all) of it. + return cached{data[:len(data)/full.W*tile.W], nil} + } + } + + // Nothing worked. + // Return the error from the server fetch for the requested (not full) tile. + return cached{nil, err} + }).(cached) + + return result.data, result.err +} + +// markTileSaved records that tile is already present in the on-disk cache, +// so that a future SaveTiles for that tile can be ignored. +func (c *Client) markTileSaved(tile tlog.Tile) { + c.tileSavedMu.Lock() + c.tileSaved[tile] = true + c.tileSavedMu.Unlock() +} + +// SaveTiles saves the now validated tiles. +func (r *tileReader) SaveTiles(tiles []tlog.Tile, data [][]byte) { + c := r.c + + // Determine which tiles need saving. + // (Tiles that came from the cache need not be saved back.) + save := make([]bool, len(tiles)) + c.tileSavedMu.Lock() + for i, tile := range tiles { + if !c.tileSaved[tile] { + save[i] = true + c.tileSaved[tile] = true + } + } + c.tileSavedMu.Unlock() + + for i, tile := range tiles { + if save[i] { + // If WriteCache fails here (out of disk space? i/o error?), + // c.tileSaved[tile] is still true and we will not try to write it again. + // Next time we run maybe we'll redownload it again and be + // more successful. + c.ops.WriteCache(c.name+"/"+tile.Path(), data[i]) + } + } +} diff --git a/libgo/go/golang.org/x/mod/sumdb/dirhash/hash.go b/libgo/go/golang.org/x/mod/sumdb/dirhash/hash.go new file mode 100644 index 00000000000..ef5df6f5b5e --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/dirhash/hash.go @@ -0,0 +1,132 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package dirhash defines hashes over directory trees. +// These hashes are recorded in go.sum files and in the Go checksum database, +// to allow verifying that a newly-downloaded module has the expected content. +package dirhash + +import ( + "archive/zip" + "crypto/sha256" + "encoding/base64" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "sort" + "strings" +) + +// DefaultHash is the default hash function used in new go.sum entries. +var DefaultHash Hash = Hash1 + +// A Hash is a directory hash function. +// It accepts a list of files along with a function that opens the content of each file. +// It opens, reads, hashes, and closes each file and returns the overall directory hash. +type Hash func(files []string, open func(string) (io.ReadCloser, error)) (string, error) + +// Hash1 is the "h1:" directory hash function, using SHA-256. +// +// Hash1 is "h1:" followed by the base64-encoded SHA-256 hash of a summary +// prepared as if by the Unix command: +// +// find . -type f | sort | sha256sum +// +// More precisely, the hashed summary contains a single line for each file in the list, +// ordered by sort.Strings applied to the file names, where each line consists of +// the hexadecimal SHA-256 hash of the file content, +// two spaces (U+0020), the file name, and a newline (U+000A). +// +// File names with newlines (U+000A) are disallowed. +func Hash1(files []string, open func(string) (io.ReadCloser, error)) (string, error) { + h := sha256.New() + files = append([]string(nil), files...) + sort.Strings(files) + for _, file := range files { + if strings.Contains(file, "\n") { + return "", errors.New("dirhash: filenames with newlines are not supported") + } + r, err := open(file) + if err != nil { + return "", err + } + hf := sha256.New() + _, err = io.Copy(hf, r) + r.Close() + if err != nil { + return "", err + } + fmt.Fprintf(h, "%x %s\n", hf.Sum(nil), file) + } + return "h1:" + base64.StdEncoding.EncodeToString(h.Sum(nil)), nil +} + +// HashDir returns the hash of the local file system directory dir, +// replacing the directory name itself with prefix in the file names +// used in the hash function. +func HashDir(dir, prefix string, hash Hash) (string, error) { + files, err := DirFiles(dir, prefix) + if err != nil { + return "", err + } + osOpen := func(name string) (io.ReadCloser, error) { + return os.Open(filepath.Join(dir, strings.TrimPrefix(name, prefix))) + } + return hash(files, osOpen) +} + +// DirFiles returns the list of files in the tree rooted at dir, +// replacing the directory name dir with prefix in each name. +// The resulting names always use forward slashes. +func DirFiles(dir, prefix string) ([]string, error) { + var files []string + dir = filepath.Clean(dir) + err := filepath.Walk(dir, func(file string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + rel := file + if dir != "." { + rel = file[len(dir)+1:] + } + f := filepath.Join(prefix, rel) + files = append(files, filepath.ToSlash(f)) + return nil + }) + if err != nil { + return nil, err + } + return files, nil +} + +// HashZip returns the hash of the file content in the named zip file. +// Only the file names and their contents are included in the hash: +// the exact zip file format encoding, compression method, +// per-file modification times, and other metadata are ignored. +func HashZip(zipfile string, hash Hash) (string, error) { + z, err := zip.OpenReader(zipfile) + if err != nil { + return "", err + } + defer z.Close() + var files []string + zfiles := make(map[string]*zip.File) + for _, file := range z.File { + files = append(files, file.Name) + zfiles[file.Name] = file + } + zipOpen := func(name string) (io.ReadCloser, error) { + f := zfiles[name] + if f == nil { + return nil, fmt.Errorf("file %q not found in zip", name) // should never happen + } + return f.Open() + } + return hash(files, zipOpen) +} diff --git a/libgo/go/golang.org/x/mod/sumdb/note/note.go b/libgo/go/golang.org/x/mod/sumdb/note/note.go new file mode 100644 index 00000000000..3c8e67bc3d5 --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/note/note.go @@ -0,0 +1,681 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package note defines the notes signed by the Go module database server. +// +// This package is part of a DRAFT of what the Go module database server will look like. +// Do not assume the details here are final! +// +// A note is text signed by one or more server keys. +// The text should be ignored unless the note is signed by +// a trusted server key and the signature has been verified +// using the server's public key. +// +// A server's public key is identified by a name, typically the "host[/path]" +// giving the base URL of the server's transparency log. +// The syntactic restrictions on a name are that it be non-empty, +// well-formed UTF-8 containing neither Unicode spaces nor plus (U+002B). +// +// A Go module database server signs texts using public key cryptography. +// A given server may have multiple public keys, each +// identified by the first 32 bits of the SHA-256 hash of +// the concatenation of the server name, a newline, and +// the encoded public key. +// +// Verifying Notes +// +// A Verifier allows verification of signatures by one server public key. +// It can report the name of the server and the uint32 hash of the key, +// and it can verify a purported signature by that key. +// +// The standard implementation of a Verifier is constructed +// by NewVerifier starting from a verifier key, which is a +// plain text string of the form "++". +// +// A Verifiers allows looking up a Verifier by the combination +// of server name and key hash. +// +// The standard implementation of a Verifiers is constructed +// by VerifierList from a list of known verifiers. +// +// A Note represents a text with one or more signatures. +// An implementation can reject a note with too many signatures +// (for example, more than 100 signatures). +// +// A Signature represents a signature on a note, verified or not. +// +// The Open function takes as input a signed message +// and a set of known verifiers. It decodes and verifies +// the message signatures and returns a Note structure +// containing the message text and (verified or unverified) signatures. +// +// Signing Notes +// +// A Signer allows signing a text with a given key. +// It can report the name of the server and the hash of the key +// and can sign a raw text using that key. +// +// The standard implementation of a Signer is constructed +// by NewSigner starting from an encoded signer key, which is a +// plain text string of the form "PRIVATE+KEY+++". +// Anyone with an encoded signer key can sign messages using that key, +// so it must be kept secret. The encoding begins with the literal text +// "PRIVATE+KEY" to avoid confusion with the public server key. +// +// The Sign function takes as input a Note and a list of Signers +// and returns an encoded, signed message. +// +// Signed Note Format +// +// A signed note consists of a text ending in newline (U+000A), +// followed by a blank line (only a newline), +// followed by one or more signature lines of this form: +// em dash (U+2014), space (U+0020), +// server name, space, base64-encoded signature, newline. +// +// Signed notes must be valid UTF-8 and must not contain any +// ASCII control characters (those below U+0020) other than newline. +// +// A signature is a base64 encoding of 4+n bytes. +// +// The first four bytes in the signature are the uint32 key hash +// stored in big-endian order, which is to say they are the first +// four bytes of the truncated SHA-256 used to derive the key hash +// in the first place. +// +// The remaining n bytes are the result of using the specified key +// to sign the note text (including the final newline but not the +// separating blank line). +// +// Generating Keys +// +// There is only one key type, Ed25519 with algorithm identifier 1. +// New key types may be introduced in the future as needed, +// although doing so will require deploying the new algorithms to all clients +// before starting to depend on them for signatures. +// +// The GenerateKey function generates and returns a new signer +// and corresponding verifier. +// +// Example +// +// Here is a well-formed signed note: +// +// If you think cryptography is the answer to your problem, +// then you don't know what your problem is. +// +// — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM= +// +// It can be constructed and displayed using: +// +// skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz" +// text := "If you think cryptography is the answer to your problem,\n" + +// "then you don't know what your problem is.\n" +// +// signer, err := note.NewSigner(skey) +// if err != nil { +// log.Fatal(err) +// } +// +// msg, err := note.Sign(¬e.Note{Text: text}, signer) +// if err != nil { +// log.Fatal(err) +// } +// os.Stdout.Write(msg) +// +// The note's text is two lines, including the final newline, +// and the text is purportedly signed by a server named +// "PeterNeumann". (Although server names are canonically +// base URLs, the only syntactic requirement is that they +// not contain spaces or newlines). +// +// If Open is given access to a Verifiers including the +// Verifier for this key, then it will succeed at verifiying +// the encoded message and returning the parsed Note: +// +// vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW" +// msg := []byte("If you think cryptography is the answer to your problem,\n" + +// "then you don't know what your problem is.\n" + +// "\n" + +// "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n") +// +// verifier, err := note.NewVerifier(vkey) +// if err != nil { +// log.Fatal(err) +// } +// verifiers := note.VerifierList(verifier) +// +// n, err := note.Open([]byte(msg), verifiers) +// if err != nil { +// log.Fatal(err) +// } +// fmt.Printf("%s (%08x):\n%s", n.Sigs[0].Name, n.Sigs[0].Hash, n.Text) +// +// You can add your own signature to this message by re-signing the note: +// +// skey, vkey, err := note.GenerateKey(rand.Reader, "EnochRoot") +// if err != nil { +// log.Fatal(err) +// } +// _ = vkey // give to verifiers +// +// me, err := note.NewSigner(skey) +// if err != nil { +// log.Fatal(err) +// } +// +// msg, err := note.Sign(n, me) +// if err != nil { +// log.Fatal(err) +// } +// os.Stdout.Write(msg) +// +// This will print a doubly-signed message, like: +// +// If you think cryptography is the answer to your problem, +// then you don't know what your problem is. +// +// — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM= +// — EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ= +// +package note + +import ( + "bytes" + "crypto/sha256" + "encoding/base64" + "encoding/binary" + "errors" + "fmt" + "io" + "strconv" + "strings" + "unicode" + "unicode/utf8" + + "golang.org/x/crypto/ed25519" +) + +// A Verifier verifies messages signed with a specific key. +type Verifier interface { + // Name returns the server name associated with the key. + Name() string + + // KeyHash returns the key hash. + KeyHash() uint32 + + // Verify reports whether sig is a valid signature of msg. + Verify(msg, sig []byte) bool +} + +// A Signer signs messages using a specific key. +type Signer interface { + // Name returns the server name associated with the key. + Name() string + + // KeyHash returns the key hash. + KeyHash() uint32 + + // Sign returns a signature for the given message. + Sign(msg []byte) ([]byte, error) +} + +// keyHash computes the key hash for the given server name and encoded public key. +func keyHash(name string, key []byte) uint32 { + h := sha256.New() + h.Write([]byte(name)) + h.Write([]byte("\n")) + h.Write(key) + sum := h.Sum(nil) + return binary.BigEndian.Uint32(sum) +} + +var ( + errVerifierID = errors.New("malformed verifier id") + errVerifierAlg = errors.New("unknown verifier algorithm") + errVerifierHash = errors.New("invalid verifier hash") +) + +const ( + algEd25519 = 1 +) + +// isValidName reports whether name is valid. +// It must be non-empty and not have any Unicode spaces or pluses. +func isValidName(name string) bool { + return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+") +} + +// NewVerifier construct a new Verifier from an encoded verifier key. +func NewVerifier(vkey string) (Verifier, error) { + name, vkey := chop(vkey, "+") + hash16, key64 := chop(vkey, "+") + hash, err1 := strconv.ParseUint(hash16, 16, 32) + key, err2 := base64.StdEncoding.DecodeString(key64) + if len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 { + return nil, errVerifierID + } + if uint32(hash) != keyHash(name, key) { + return nil, errVerifierHash + } + + v := &verifier{ + name: name, + hash: uint32(hash), + } + + alg, key := key[0], key[1:] + switch alg { + default: + return nil, errVerifierAlg + + case algEd25519: + if len(key) != 32 { + return nil, errVerifierID + } + v.verify = func(msg, sig []byte) bool { + return ed25519.Verify(key, msg, sig) + } + } + + return v, nil +} + +// chop chops s at the first instance of sep, if any, +// and returns the text before and after sep. +// If sep is not present, chop returns before is s and after is empty. +func chop(s, sep string) (before, after string) { + i := strings.Index(s, sep) + if i < 0 { + return s, "" + } + return s[:i], s[i+len(sep):] +} + +// verifier is a trivial Verifier implementation. +type verifier struct { + name string + hash uint32 + verify func([]byte, []byte) bool +} + +func (v *verifier) Name() string { return v.name } +func (v *verifier) KeyHash() uint32 { return v.hash } +func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) } + +// NewSigner constructs a new Signer from an encoded signer key. +func NewSigner(skey string) (Signer, error) { + priv1, skey := chop(skey, "+") + priv2, skey := chop(skey, "+") + name, skey := chop(skey, "+") + hash16, key64 := chop(skey, "+") + hash, err1 := strconv.ParseUint(hash16, 16, 32) + key, err2 := base64.StdEncoding.DecodeString(key64) + if priv1 != "PRIVATE" || priv2 != "KEY" || len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 { + return nil, errSignerID + } + + // Note: hash is the hash of the public key and we have the private key. + // Must verify hash after deriving public key. + + s := &signer{ + name: name, + hash: uint32(hash), + } + + var pubkey []byte + + alg, key := key[0], key[1:] + switch alg { + default: + return nil, errSignerAlg + + case algEd25519: + if len(key) != 32 { + return nil, errSignerID + } + key = ed25519.NewKeyFromSeed(key) + pubkey = append([]byte{algEd25519}, key[32:]...) + s.sign = func(msg []byte) ([]byte, error) { + return ed25519.Sign(key, msg), nil + } + } + + if uint32(hash) != keyHash(name, pubkey) { + return nil, errSignerHash + } + + return s, nil +} + +var ( + errSignerID = errors.New("malformed verifier id") + errSignerAlg = errors.New("unknown verifier algorithm") + errSignerHash = errors.New("invalid verifier hash") +) + +// signer is a trivial Signer implementation. +type signer struct { + name string + hash uint32 + sign func([]byte) ([]byte, error) +} + +func (s *signer) Name() string { return s.name } +func (s *signer) KeyHash() uint32 { return s.hash } +func (s *signer) Sign(msg []byte) ([]byte, error) { return s.sign(msg) } + +// GenerateKey generates a signer and verifier key pair for a named server. +// The signer key skey is private and must be kept secret. +func GenerateKey(rand io.Reader, name string) (skey, vkey string, err error) { + pub, priv, err := ed25519.GenerateKey(rand) + if err != nil { + return "", "", err + } + pubkey := append([]byte{algEd25519}, pub...) + privkey := append([]byte{algEd25519}, priv.Seed()...) + h := keyHash(name, pubkey) + + skey = fmt.Sprintf("PRIVATE+KEY+%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(privkey)) + vkey = fmt.Sprintf("%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(pubkey)) + return skey, vkey, nil +} + +// NewEd25519VerifierKey returns an encoded verifier key using the given name +// and Ed25519 public key. +func NewEd25519VerifierKey(name string, key ed25519.PublicKey) (string, error) { + if len(key) != ed25519.PublicKeySize { + return "", fmt.Errorf("invalid public key size %d, expected %d", len(key), ed25519.PublicKeySize) + } + + pubkey := append([]byte{algEd25519}, key...) + hash := keyHash(name, pubkey) + + b64Key := base64.StdEncoding.EncodeToString(pubkey) + return fmt.Sprintf("%s+%08x+%s", name, hash, b64Key), nil +} + +// A Verifiers is a collection of known verifier keys. +type Verifiers interface { + // Verifier returns the Verifier associated with the key + // identified by the name and hash. + // If the name, hash pair is unknown, Verifier should return + // an UnknownVerifierError. + Verifier(name string, hash uint32) (Verifier, error) +} + +// An UnknownVerifierError indicates that the given key is not known. +// The Open function records signatures without associated verifiers as +// unverified signatures. +type UnknownVerifierError struct { + Name string + KeyHash uint32 +} + +func (e *UnknownVerifierError) Error() string { + return fmt.Sprintf("unknown key %s+%08x", e.Name, e.KeyHash) +} + +// An ambiguousVerifierError indicates that the given name and hash +// match multiple keys passed to VerifierList. +// (If this happens, some malicious actor has taken control of the +// verifier list, at which point we may as well give up entirely, +// but we diagnose the problem instead.) +type ambiguousVerifierError struct { + name string + hash uint32 +} + +func (e *ambiguousVerifierError) Error() string { + return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash) +} + +// VerifierList returns a Verifiers implementation that uses the given list of verifiers. +func VerifierList(list ...Verifier) Verifiers { + m := make(verifierMap) + for _, v := range list { + k := nameHash{v.Name(), v.KeyHash()} + m[k] = append(m[k], v) + } + return m +} + +type nameHash struct { + name string + hash uint32 +} + +type verifierMap map[nameHash][]Verifier + +func (m verifierMap) Verifier(name string, hash uint32) (Verifier, error) { + v, ok := m[nameHash{name, hash}] + if !ok { + return nil, &UnknownVerifierError{name, hash} + } + if len(v) > 1 { + return nil, &ambiguousVerifierError{name, hash} + } + return v[0], nil +} + +// A Note is a text and signatures. +type Note struct { + Text string // text of note + Sigs []Signature // verified signatures + UnverifiedSigs []Signature // unverified signatures +} + +// A Signature is a single signature found in a note. +type Signature struct { + // Name and Hash give the name and key hash + // for the key that generated the signature. + Name string + Hash uint32 + + // Base64 records the base64-encoded signature bytes. + Base64 string +} + +// An UnverifiedNoteError indicates that the note +// successfully parsed but had no verifiable signatures. +type UnverifiedNoteError struct { + Note *Note +} + +func (e *UnverifiedNoteError) Error() string { + return "note has no verifiable signatures" +} + +// An InvalidSignatureError indicates that the given key was known +// and the associated Verifier rejected the signature. +type InvalidSignatureError struct { + Name string + Hash uint32 +} + +func (e *InvalidSignatureError) Error() string { + return fmt.Sprintf("invalid signature for key %s+%08x", e.Name, e.Hash) +} + +var ( + errMalformedNote = errors.New("malformed note") + errInvalidSigner = errors.New("invalid signer") + + sigSplit = []byte("\n\n") + sigPrefix = []byte("— ") +) + +// Open opens and parses the message msg, checking signatures from the known verifiers. +// +// For each signature in the message, Open calls known.Verifier to find a verifier. +// If known.Verifier returns a verifier and the verifier accepts the signature, +// Open records the signature in the returned note's Sigs field. +// If known.Verifier returns a verifier but the verifier rejects the signature, +// Open returns an InvalidSignatureError. +// If known.Verifier returns an UnknownVerifierError, +// Open records the signature in the returned note's UnverifiedSigs field. +// If known.Verifier returns any other error, Open returns that error. +// +// If no known verifier has signed an otherwise valid note, +// Open returns an UnverifiedNoteError. +// In this case, the unverified note can be fetched from inside the error. +func Open(msg []byte, known Verifiers) (*Note, error) { + if known == nil { + // Treat nil Verifiers as empty list, to produce useful error instead of crash. + known = VerifierList() + } + + // Must have valid UTF-8 with no non-newline ASCII control characters. + for i := 0; i < len(msg); { + r, size := utf8.DecodeRune(msg[i:]) + if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 { + return nil, errMalformedNote + } + i += size + } + + // Must end with signature block preceded by blank line. + split := bytes.LastIndex(msg, sigSplit) + if split < 0 { + return nil, errMalformedNote + } + text, sigs := msg[:split+1], msg[split+2:] + if len(sigs) == 0 || sigs[len(sigs)-1] != '\n' { + return nil, errMalformedNote + } + + n := &Note{ + Text: string(text), + } + + // Parse and verify signatures. + // Ignore duplicate signatures. + seen := make(map[nameHash]bool) + seenUnverified := make(map[string]bool) + numSig := 0 + for len(sigs) > 0 { + // Pull out next signature line. + // We know sigs[len(sigs)-1] == '\n', so IndexByte always finds one. + i := bytes.IndexByte(sigs, '\n') + line := sigs[:i] + sigs = sigs[i+1:] + + if !bytes.HasPrefix(line, sigPrefix) { + return nil, errMalformedNote + } + line = line[len(sigPrefix):] + name, b64 := chop(string(line), " ") + sig, err := base64.StdEncoding.DecodeString(b64) + if err != nil || !isValidName(name) || b64 == "" || len(sig) < 5 { + return nil, errMalformedNote + } + hash := binary.BigEndian.Uint32(sig[0:4]) + sig = sig[4:] + + if numSig++; numSig > 100 { + // Avoid spending forever parsing a note with many signatures. + return nil, errMalformedNote + } + + v, err := known.Verifier(name, hash) + if _, ok := err.(*UnknownVerifierError); ok { + // Drop repeated identical unverified signatures. + if seenUnverified[string(line)] { + continue + } + seenUnverified[string(line)] = true + n.UnverifiedSigs = append(n.UnverifiedSigs, Signature{Name: name, Hash: hash, Base64: b64}) + continue + } + if err != nil { + return nil, err + } + + // Drop repeated signatures by a single verifier. + if seen[nameHash{name, hash}] { + continue + } + seen[nameHash{name, hash}] = true + + ok := v.Verify(text, sig) + if !ok { + return nil, &InvalidSignatureError{name, hash} + } + + n.Sigs = append(n.Sigs, Signature{Name: name, Hash: hash, Base64: b64}) + } + + // Parsed and verified all the signatures. + if len(n.Sigs) == 0 { + return nil, &UnverifiedNoteError{n} + } + return n, nil +} + +// Sign signs the note with the given signers and returns the encoded message. +// The new signatures from signers are listed in the encoded message after +// the existing signatures already present in n.Sigs. +// If any signer uses the same key as an existing signature, +// the existing signature is elided from the output. +func Sign(n *Note, signers ...Signer) ([]byte, error) { + var buf bytes.Buffer + if !strings.HasSuffix(n.Text, "\n") { + return nil, errMalformedNote + } + buf.WriteString(n.Text) + + // Prepare signatures. + var sigs bytes.Buffer + have := make(map[nameHash]bool) + for _, s := range signers { + name := s.Name() + hash := s.KeyHash() + have[nameHash{name, hash}] = true + if !isValidName(name) { + return nil, errInvalidSigner + } + + sig, err := s.Sign(buf.Bytes()) // buf holds n.Text + if err != nil { + return nil, err + } + + var hbuf [4]byte + binary.BigEndian.PutUint32(hbuf[:], hash) + b64 := base64.StdEncoding.EncodeToString(append(hbuf[:], sig...)) + sigs.WriteString("— ") + sigs.WriteString(name) + sigs.WriteString(" ") + sigs.WriteString(b64) + sigs.WriteString("\n") + } + + buf.WriteString("\n") + + // Emit existing signatures not replaced by new ones. + for _, list := range [][]Signature{n.Sigs, n.UnverifiedSigs} { + for _, sig := range list { + name, hash := sig.Name, sig.Hash + if !isValidName(name) { + return nil, errMalformedNote + } + if have[nameHash{name, hash}] { + continue + } + // Double-check hash against base64. + raw, err := base64.StdEncoding.DecodeString(sig.Base64) + if err != nil || len(raw) < 4 || binary.BigEndian.Uint32(raw) != hash { + return nil, errMalformedNote + } + buf.WriteString("— ") + buf.WriteString(sig.Name) + buf.WriteString(" ") + buf.WriteString(sig.Base64) + buf.WriteString("\n") + } + } + buf.Write(sigs.Bytes()) + + return buf.Bytes(), nil +} diff --git a/libgo/go/golang.org/x/mod/sumdb/server.go b/libgo/go/golang.org/x/mod/sumdb/server.go new file mode 100644 index 00000000000..28866f18f8b --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/server.go @@ -0,0 +1,181 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package sumdb implements the HTTP protocols for serving or accessing a module checksum database. +package sumdb + +import ( + "context" + "net/http" + "os" + "strings" + + "golang.org/x/mod/internal/lazyregexp" + "golang.org/x/mod/module" + "golang.org/x/mod/sumdb/tlog" +) + +// A ServerOps provides the external operations +// (underlying database access and so on) needed by the Server. +type ServerOps interface { + // Signed returns the signed hash of the latest tree. + Signed(ctx context.Context) ([]byte, error) + + // ReadRecords returns the content for the n records id through id+n-1. + ReadRecords(ctx context.Context, id, n int64) ([][]byte, error) + + // Lookup looks up a record for the given module, + // returning the record ID. + Lookup(ctx context.Context, m module.Version) (int64, error) + + // ReadTileData reads the content of tile t. + // It is only invoked for hash tiles (t.L ≥ 0). + ReadTileData(ctx context.Context, t tlog.Tile) ([]byte, error) +} + +// A Server is the checksum database HTTP server, +// which implements http.Handler and should be invoked +// to serve the paths listed in ServerPaths. +type Server struct { + ops ServerOps +} + +// NewServer returns a new Server using the given operations. +func NewServer(ops ServerOps) *Server { + return &Server{ops: ops} +} + +// ServerPaths are the URL paths the Server can (and should) serve. +// +// Typically a server will do: +// +// srv := sumdb.NewServer(ops) +// for _, path := range sumdb.ServerPaths { +// http.Handle(path, srv) +// } +// +var ServerPaths = []string{ + "/lookup/", + "/latest", + "/tile/", +} + +var modVerRE = lazyregexp.New(`^[^@]+@v[0-9]+\.[0-9]+\.[0-9]+(-[^@]*)?(\+incompatible)?$`) + +func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + switch { + default: + http.NotFound(w, r) + + case strings.HasPrefix(r.URL.Path, "/lookup/"): + mod := strings.TrimPrefix(r.URL.Path, "/lookup/") + if !modVerRE.MatchString(mod) { + http.Error(w, "invalid module@version syntax", http.StatusBadRequest) + return + } + i := strings.Index(mod, "@") + escPath, escVers := mod[:i], mod[i+1:] + path, err := module.UnescapePath(escPath) + if err != nil { + reportError(w, err) + return + } + vers, err := module.UnescapeVersion(escVers) + if err != nil { + reportError(w, err) + return + } + id, err := s.ops.Lookup(ctx, module.Version{Path: path, Version: vers}) + if err != nil { + reportError(w, err) + return + } + records, err := s.ops.ReadRecords(ctx, id, 1) + if err != nil { + // This should never happen - the lookup says the record exists. + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if len(records) != 1 { + http.Error(w, "invalid record count returned by ReadRecords", http.StatusInternalServerError) + return + } + msg, err := tlog.FormatRecord(id, records[0]) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + signed, err := s.ops.Signed(ctx) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/plain; charset=UTF-8") + w.Write(msg) + w.Write(signed) + + case r.URL.Path == "/latest": + data, err := s.ops.Signed(ctx) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/plain; charset=UTF-8") + w.Write(data) + + case strings.HasPrefix(r.URL.Path, "/tile/"): + t, err := tlog.ParseTilePath(r.URL.Path[1:]) + if err != nil { + http.Error(w, "invalid tile syntax", http.StatusBadRequest) + return + } + if t.L == -1 { + // Record data. + start := t.N << uint(t.H) + records, err := s.ops.ReadRecords(ctx, start, int64(t.W)) + if err != nil { + reportError(w, err) + return + } + if len(records) != t.W { + http.Error(w, "invalid record count returned by ReadRecords", http.StatusInternalServerError) + return + } + var data []byte + for i, text := range records { + msg, err := tlog.FormatRecord(start+int64(i), text) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + data = append(data, msg...) + } + w.Header().Set("Content-Type", "text/plain; charset=UTF-8") + w.Write(data) + return + } + + data, err := s.ops.ReadTileData(ctx, t) + if err != nil { + reportError(w, err) + return + } + w.Header().Set("Content-Type", "application/octet-stream") + w.Write(data) + } +} + +// reportError reports err to w. +// If it's a not-found, the reported error is 404. +// Otherwise it is an internal server error. +// The caller must only call reportError in contexts where +// a not-found err should be reported as 404. +func reportError(w http.ResponseWriter, err error) { + if os.IsNotExist(err) { + http.Error(w, err.Error(), http.StatusNotFound) + return + } + http.Error(w, err.Error(), http.StatusInternalServerError) +} diff --git a/libgo/go/golang.org/x/mod/sumdb/test.go b/libgo/go/golang.org/x/mod/sumdb/test.go new file mode 100644 index 00000000000..e4c166d87e5 --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/test.go @@ -0,0 +1,124 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sumdb + +import ( + "context" + "fmt" + "sync" + + "golang.org/x/mod/module" + "golang.org/x/mod/sumdb/note" + "golang.org/x/mod/sumdb/tlog" +) + +// NewTestServer constructs a new TestServer +// that will sign its tree with the given signer key +// (see golang.org/x/mod/sumdb/note) +// and fetch new records as needed by calling gosum. +func NewTestServer(signer string, gosum func(path, vers string) ([]byte, error)) *TestServer { + return &TestServer{signer: signer, gosum: gosum} +} + +// A TestServer is an in-memory implementation of Server for testing. +type TestServer struct { + signer string + gosum func(path, vers string) ([]byte, error) + + mu sync.Mutex + hashes testHashes + records [][]byte + lookup map[string]int64 +} + +// testHashes implements tlog.HashReader, reading from a slice. +type testHashes []tlog.Hash + +func (h testHashes) ReadHashes(indexes []int64) ([]tlog.Hash, error) { + var list []tlog.Hash + for _, id := range indexes { + list = append(list, h[id]) + } + return list, nil +} + +func (s *TestServer) Signed(ctx context.Context) ([]byte, error) { + s.mu.Lock() + defer s.mu.Unlock() + + size := int64(len(s.records)) + h, err := tlog.TreeHash(size, s.hashes) + if err != nil { + return nil, err + } + text := tlog.FormatTree(tlog.Tree{N: size, Hash: h}) + signer, err := note.NewSigner(s.signer) + if err != nil { + return nil, err + } + return note.Sign(¬e.Note{Text: string(text)}, signer) +} + +func (s *TestServer) ReadRecords(ctx context.Context, id, n int64) ([][]byte, error) { + s.mu.Lock() + defer s.mu.Unlock() + + var list [][]byte + for i := int64(0); i < n; i++ { + if id+i >= int64(len(s.records)) { + return nil, fmt.Errorf("missing records") + } + list = append(list, s.records[id+i]) + } + return list, nil +} + +func (s *TestServer) Lookup(ctx context.Context, m module.Version) (int64, error) { + key := m.String() + s.mu.Lock() + id, ok := s.lookup[key] + s.mu.Unlock() + if ok { + return id, nil + } + + // Look up module and compute go.sum lines. + data, err := s.gosum(m.Path, m.Version) + if err != nil { + return 0, err + } + + s.mu.Lock() + defer s.mu.Unlock() + + // We ran the fetch without the lock. + // If another fetch happened and committed, use it instead. + id, ok = s.lookup[key] + if ok { + return id, nil + } + + // Add record. + id = int64(len(s.records)) + s.records = append(s.records, data) + if s.lookup == nil { + s.lookup = make(map[string]int64) + } + s.lookup[key] = id + hashes, err := tlog.StoredHashesForRecordHash(id, tlog.RecordHash([]byte(data)), s.hashes) + if err != nil { + panic(err) + } + s.hashes = append(s.hashes, hashes...) + + return id, nil +} + +func (s *TestServer) ReadTileData(ctx context.Context, t tlog.Tile) ([]byte, error) { + s.mu.Lock() + defer s.mu.Unlock() + + return tlog.ReadTileData(t, s.hashes) +} diff --git a/libgo/go/golang.org/x/mod/sumdb/tlog/note.go b/libgo/go/golang.org/x/mod/sumdb/tlog/note.go new file mode 100644 index 00000000000..ce5353e0feb --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/tlog/note.go @@ -0,0 +1,135 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tlog + +import ( + "bytes" + "encoding/base64" + "errors" + "fmt" + "strconv" + "strings" + "unicode/utf8" +) + +// A Tree is a tree description, to be signed by a go.sum database server. +type Tree struct { + N int64 + Hash Hash +} + +// FormatTree formats a tree description for inclusion in a note. +// +// The encoded form is three lines, each ending in a newline (U+000A): +// +// go.sum database tree +// N +// Hash +// +// where N is in decimal and Hash is in base64. +// +// A future backwards-compatible encoding may add additional lines, +// which the parser can ignore. +// A future backwards-incompatible encoding would use a different +// first line (for example, "go.sum database tree v2"). +func FormatTree(tree Tree) []byte { + return []byte(fmt.Sprintf("go.sum database tree\n%d\n%s\n", tree.N, tree.Hash)) +} + +var errMalformedTree = errors.New("malformed tree note") +var treePrefix = []byte("go.sum database tree\n") + +// ParseTree parses a formatted tree root description. +func ParseTree(text []byte) (tree Tree, err error) { + // The message looks like: + // + // go.sum database tree + // 2 + // nND/nri/U0xuHUrYSy0HtMeal2vzD9V4k/BO79C+QeI= + // + // For forwards compatibility, extra text lines after the encoding are ignored. + if !bytes.HasPrefix(text, treePrefix) || bytes.Count(text, []byte("\n")) < 3 || len(text) > 1e6 { + return Tree{}, errMalformedTree + } + + lines := strings.SplitN(string(text), "\n", 4) + n, err := strconv.ParseInt(lines[1], 10, 64) + if err != nil || n < 0 || lines[1] != strconv.FormatInt(n, 10) { + return Tree{}, errMalformedTree + } + + h, err := base64.StdEncoding.DecodeString(lines[2]) + if err != nil || len(h) != HashSize { + return Tree{}, errMalformedTree + } + + var hash Hash + copy(hash[:], h) + return Tree{n, hash}, nil +} + +var errMalformedRecord = errors.New("malformed record data") + +// FormatRecord formats a record for serving to a client +// in a lookup response or data tile. +// +// The encoded form is the record ID as a single number, +// then the text of the record, and then a terminating blank line. +// Record text must be valid UTF-8 and must not contain any ASCII control +// characters (those below U+0020) other than newline (U+000A). +// It must end in a terminating newline and not contain any blank lines. +func FormatRecord(id int64, text []byte) (msg []byte, err error) { + if !isValidRecordText(text) { + return nil, errMalformedRecord + } + msg = []byte(fmt.Sprintf("%d\n", id)) + msg = append(msg, text...) + msg = append(msg, '\n') + return msg, nil +} + +// isValidRecordText reports whether text is syntactically valid record text. +func isValidRecordText(text []byte) bool { + var last rune + for i := 0; i < len(text); { + r, size := utf8.DecodeRune(text[i:]) + if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 || last == '\n' && r == '\n' { + return false + } + i += size + last = r + } + if last != '\n' { + return false + } + return true +} + +// ParseRecord parses a record description at the start of text, +// stopping immediately after the terminating blank line. +// It returns the record id, the record text, and the remainder of text. +func ParseRecord(msg []byte) (id int64, text, rest []byte, err error) { + // Leading record id. + i := bytes.IndexByte(msg, '\n') + if i < 0 { + return 0, nil, nil, errMalformedRecord + } + id, err = strconv.ParseInt(string(msg[:i]), 10, 64) + if err != nil { + return 0, nil, nil, errMalformedRecord + } + msg = msg[i+1:] + + // Record text. + i = bytes.Index(msg, []byte("\n\n")) + if i < 0 { + return 0, nil, nil, errMalformedRecord + } + text, rest = msg[:i+1], msg[i+2:] + if !isValidRecordText(text) { + return 0, nil, nil, errMalformedRecord + } + return id, text, rest, nil +} diff --git a/libgo/go/golang.org/x/mod/sumdb/tlog/tile.go b/libgo/go/golang.org/x/mod/sumdb/tlog/tile.go new file mode 100644 index 00000000000..e4aeb14eff4 --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/tlog/tile.go @@ -0,0 +1,435 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tlog + +import ( + "fmt" + "strconv" + "strings" +) + +// A Tile is a description of a transparency log tile. +// A tile of height H at level L offset N lists W consecutive hashes +// at level H*L of the tree starting at offset N*(2**H). +// A complete tile lists 2**H hashes; a partial tile lists fewer. +// Note that a tile represents the entire subtree of height H +// with those hashes as the leaves. The levels above H*L +// can be reconstructed by hashing the leaves. +// +// Each Tile can be encoded as a “tile coordinate path” +// of the form tile/H/L/NNN[.p/W]. +// The .p/W suffix is present only for partial tiles, meaning W < 2**H. +// The NNN element is an encoding of N into 3-digit path elements. +// All but the last path element begins with an "x". +// For example, +// Tile{H: 3, L: 4, N: 1234067, W: 1}'s path +// is tile/3/4/x001/x234/067.p/1, and +// Tile{H: 3, L: 4, N: 1234067, W: 8}'s path +// is tile/3/4/x001/x234/067. +// See Tile's Path method and the ParseTilePath function. +// +// The special level L=-1 holds raw record data instead of hashes. +// In this case, the level encodes into a tile path as the path element +// "data" instead of "-1". +// +// See also https://golang.org/design/25530-sumdb#checksum-database +// and https://research.swtch.com/tlog#tiling_a_log. +type Tile struct { + H int // height of tile (1 ≤ H ≤ 30) + L int // level in tiling (-1 ≤ L ≤ 63) + N int64 // number within level (0 ≤ N, unbounded) + W int // width of tile (1 ≤ W ≤ 2**H; 2**H is complete tile) +} + +// TileForIndex returns the tile of fixed height h ≥ 1 +// and least width storing the given hash storage index. +// +// If h ≤ 0, TileForIndex panics. +func TileForIndex(h int, index int64) Tile { + if h <= 0 { + panic(fmt.Sprintf("TileForIndex: invalid height %d", h)) + } + t, _, _ := tileForIndex(h, index) + return t +} + +// tileForIndex returns the tile of height h ≥ 1 +// storing the given hash index, which can be +// reconstructed using tileHash(data[start:end]). +func tileForIndex(h int, index int64) (t Tile, start, end int) { + level, n := SplitStoredHashIndex(index) + t.H = h + t.L = level / h + level -= t.L * h // now level within tile + t.N = n << uint(level) >> uint(t.H) + n -= t.N << uint(t.H) >> uint(level) // now n within tile at level + t.W = int((n + 1) << uint(level)) + return t, int(n< 30 || t.L < 0 || t.L >= 64 || t.W < 1 || t.W > 1<>(H*level) > 0; level++ { + oldN := oldTreeSize >> (H * level) + newN := newTreeSize >> (H * level) + for n := oldN >> H; n < newN>>H; n++ { + tiles = append(tiles, Tile{H: h, L: int(level), N: n, W: 1 << H}) + } + n := newN >> H + maxW := int(newN - n< n<= pathBase { + n /= pathBase + nStr = fmt.Sprintf("x%03d/%s", n%pathBase, nStr) + } + pStr := "" + if t.W != 1< 30 { + return Tile{}, &badPathError{path} + } + w := 1 << uint(h) + if dotP := f[len(f)-2]; strings.HasSuffix(dotP, ".p") { + ww, err := strconv.Atoi(f[len(f)-1]) + if err != nil || ww <= 0 || ww >= w { + return Tile{}, &badPathError{path} + } + w = ww + f[len(f)-2] = dotP[:len(dotP)-len(".p")] + f = f[:len(f)-1] + } + f = f[3:] + n := int64(0) + for _, s := range f { + nn, err := strconv.Atoi(strings.TrimPrefix(s, "x")) + if err != nil || nn < 0 || nn >= pathBase { + return Tile{}, &badPathError{path} + } + n = n*pathBase + int64(nn) + } + if isData { + l = -1 + } + t := Tile{H: h, L: l, N: n, W: w} + if path != t.Path() { + return Tile{}, &badPathError{path} + } + return t, nil +} + +type badPathError struct { + path string +} + +func (e *badPathError) Error() string { + return fmt.Sprintf("malformed tile path %q", e.path) +} + +// A TileReader reads tiles from a go.sum database log. +type TileReader interface { + // Height returns the height of the available tiles. + Height() int + + // ReadTiles returns the data for each requested tile. + // If ReadTiles returns err == nil, it must also return + // a data record for each tile (len(data) == len(tiles)) + // and each data record must be the correct length + // (len(data[i]) == tiles[i].W*HashSize). + // + // An implementation of ReadTiles typically reads + // them from an on-disk cache or else from a remote + // tile server. Tile data downloaded from a server should + // be considered suspect and not saved into a persistent + // on-disk cache before returning from ReadTiles. + // When the client confirms the validity of the tile data, + // it will call SaveTiles to signal that they can be safely + // written to persistent storage. + // See also https://research.swtch.com/tlog#authenticating_tiles. + ReadTiles(tiles []Tile) (data [][]byte, err error) + + // SaveTiles informs the TileReader that the tile data + // returned by ReadTiles has been confirmed as valid + // and can be saved in persistent storage (on disk). + SaveTiles(tiles []Tile, data [][]byte) +} + +// TileHashReader returns a HashReader that satisfies requests +// by loading tiles of the given tree. +// +// The returned HashReader checks that loaded tiles are +// valid for the given tree. Therefore, any hashes returned +// by the HashReader are already proven to be in the tree. +func TileHashReader(tree Tree, tr TileReader) HashReader { + return &tileHashReader{tree: tree, tr: tr} +} + +type tileHashReader struct { + tree Tree + tr TileReader +} + +// tileParent returns t's k'th tile parent in the tiles for a tree of size n. +// If there is no such parent, tileParent returns Tile{}. +func tileParent(t Tile, k int, n int64) Tile { + t.L += k + t.N >>= uint(k * t.H) + t.W = 1 << uint(t.H) + if max := n >> uint(t.L*t.H); t.N<= max { + if t.N<= max { + return Tile{} + } + t.W = int(max - t.N<= StoredHashIndex(0, r.tree.N) { + return nil, fmt.Errorf("indexes not in tree") + } + + tile, _, _ := tileForIndex(h, x) + + // Walk up parent tiles until we find one we've requested. + // That one will be authenticated. + k := 0 + for ; ; k++ { + p := tileParent(tile, k, r.tree.N) + if j, ok := tileOrder[p]; ok { + if k == 0 { + indexTileOrder[i] = j + } + break + } + } + + // Walk back down recording child tiles after parents. + // This loop ends by revisiting the tile for this index + // (tileParent(tile, 0, r.tree.N)) unless k == 0, in which + // case the previous loop did it. + for k--; k >= 0; k-- { + p := tileParent(tile, k, r.tree.N) + if p.W != 1<= 0; i-- { + h, err := HashFromTile(tiles[stxTileOrder[i]], data[stxTileOrder[i]], stx[i]) + if err != nil { + return nil, err + } + th = NodeHash(h, th) + } + if th != r.tree.Hash { + // The tiles do not support the tree hash. + // We know at least one is wrong, but not which one. + return nil, fmt.Errorf("downloaded inconsistent tile") + } + + // Authenticate full tiles against their parents. + for i := len(stx); i < len(tiles); i++ { + tile := tiles[i] + p := tileParent(tile, 1, r.tree.N) + j, ok := tileOrder[p] + if !ok { + return nil, fmt.Errorf("bad math in tileHashReader %d %v: lost parent of %v", r.tree.N, indexes, tile) + } + h, err := HashFromTile(p, data[j], StoredHashIndex(p.L*p.H, tile.N)) + if err != nil { + return nil, fmt.Errorf("bad math in tileHashReader %d %v: lost hash of %v: %v", r.tree.N, indexes, tile, err) + } + if h != tileHash(data[i]) { + return nil, fmt.Errorf("downloaded inconsistent tile") + } + } + + // Now we have all the tiles needed for the requested hashes, + // and we've authenticated the full tile set against the trusted tree hash. + r.tr.SaveTiles(tiles, data) + + // Pull out the requested hashes. + hashes := make([]Hash, len(indexes)) + for i, x := range indexes { + j := indexTileOrder[i] + h, err := HashFromTile(tiles[j], data[j], x) + if err != nil { + return nil, fmt.Errorf("bad math in tileHashReader %d %v: lost hash %v: %v", r.tree.N, indexes, x, err) + } + hashes[i] = h + } + + return hashes, nil +} diff --git a/libgo/go/golang.org/x/mod/sumdb/tlog/tlog.go b/libgo/go/golang.org/x/mod/sumdb/tlog/tlog.go new file mode 100644 index 00000000000..01d06c4e260 --- /dev/null +++ b/libgo/go/golang.org/x/mod/sumdb/tlog/tlog.go @@ -0,0 +1,598 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package tlog implements a tamper-evident log +// used in the Go module go.sum database server. +// +// This package follows the design of Certificate Transparency (RFC 6962) +// and its proofs are compatible with that system. +// See TestCertificateTransparency. +// +package tlog + +import ( + "crypto/sha256" + "encoding/base64" + "errors" + "fmt" + "math/bits" +) + +// A Hash is a hash identifying a log record or tree root. +type Hash [HashSize]byte + +// HashSize is the size of a Hash in bytes. +const HashSize = 32 + +// String returns a base64 representation of the hash for printing. +func (h Hash) String() string { + return base64.StdEncoding.EncodeToString(h[:]) +} + +// MarshalJSON marshals the hash as a JSON string containing the base64-encoded hash. +func (h Hash) MarshalJSON() ([]byte, error) { + return []byte(`"` + h.String() + `"`), nil +} + +// UnmarshalJSON unmarshals a hash from JSON string containing the a base64-encoded hash. +func (h *Hash) UnmarshalJSON(data []byte) error { + if len(data) != 1+44+1 || data[0] != '"' || data[len(data)-2] != '=' || data[len(data)-1] != '"' { + return errors.New("cannot decode hash") + } + + // As of Go 1.12, base64.StdEncoding.Decode insists on + // slicing into target[33:] even when it only writes 32 bytes. + // Since we already checked that the hash ends in = above, + // we can use base64.RawStdEncoding with the = removed; + // RawStdEncoding does not exhibit the same bug. + // We decode into a temporary to avoid writing anything to *h + // unless the entire input is well-formed. + var tmp Hash + n, err := base64.RawStdEncoding.Decode(tmp[:], data[1:len(data)-2]) + if err != nil || n != HashSize { + return errors.New("cannot decode hash") + } + *h = tmp + return nil +} + +// ParseHash parses the base64-encoded string form of a hash. +func ParseHash(s string) (Hash, error) { + data, err := base64.StdEncoding.DecodeString(s) + if err != nil || len(data) != HashSize { + return Hash{}, fmt.Errorf("malformed hash") + } + var h Hash + copy(h[:], data) + return h, nil +} + +// maxpow2 returns k, the maximum power of 2 smaller than n, +// as well as l = log₂ k (so k = 1< 0; l-- { + n = 2*n + 1 + } + + // Level 0's n'th hash is written at n+n/2+n/4+... (eventually n/2ⁱ hits zero). + i := int64(0) + for ; n > 0; n >>= 1 { + i += n + } + + return i + int64(level) +} + +// SplitStoredHashIndex is the inverse of StoredHashIndex. +// That is, SplitStoredHashIndex(StoredHashIndex(level, n)) == level, n. +func SplitStoredHashIndex(index int64) (level int, n int64) { + // Determine level 0 record before index. + // StoredHashIndex(0, n) < 2*n, + // so the n we want is in [index/2, index/2+log₂(index)]. + n = index / 2 + indexN := StoredHashIndex(0, n) + if indexN > index { + panic("bad math") + } + for { + // Each new record n adds 1 + trailingZeros(n) hashes. + x := indexN + 1 + int64(bits.TrailingZeros64(uint64(n+1))) + if x > index { + break + } + n++ + indexN = x + } + // The hash we want was committed with record n, + // meaning it is one of (0, n), (1, n/2), (2, n/4), ... + level = int(index - indexN) + return level, n >> uint(level) +} + +// StoredHashCount returns the number of stored hashes +// that are expected for a tree with n records. +func StoredHashCount(n int64) int64 { + if n == 0 { + return 0 + } + // The tree will have the hashes up to the last leaf hash. + numHash := StoredHashIndex(0, n-1) + 1 + // And it will have any hashes for subtrees completed by that leaf. + for i := uint64(n - 1); i&1 != 0; i >>= 1 { + numHash++ + } + return numHash +} + +// StoredHashes returns the hashes that must be stored when writing +// record n with the given data. The hashes should be stored starting +// at StoredHashIndex(0, n). The result will have at most 1 + log₂ n hashes, +// but it will average just under two per call for a sequence of calls for n=1..k. +// +// StoredHashes may read up to log n earlier hashes from r +// in order to compute hashes for completed subtrees. +func StoredHashes(n int64, data []byte, r HashReader) ([]Hash, error) { + return StoredHashesForRecordHash(n, RecordHash(data), r) +} + +// StoredHashesForRecordHash is like StoredHashes but takes +// as its second argument RecordHash(data) instead of data itself. +func StoredHashesForRecordHash(n int64, h Hash, r HashReader) ([]Hash, error) { + // Start with the record hash. + hashes := []Hash{h} + + // Build list of indexes needed for hashes for completed subtrees. + // Each trailing 1 bit in the binary representation of n completes a subtree + // and consumes a hash from an adjacent subtree. + m := int(bits.TrailingZeros64(uint64(n + 1))) + indexes := make([]int64, m) + for i := 0; i < m; i++ { + // We arrange indexes in sorted order. + // Note that n>>i is always odd. + indexes[m-1-i] = StoredHashIndex(i, n>>uint(i)-1) + } + + // Fetch hashes. + old, err := r.ReadHashes(indexes) + if err != nil { + return nil, err + } + if len(old) != len(indexes) { + return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(old)) + } + + // Build new hashes. + for i := 0; i < m; i++ { + h = NodeHash(old[m-1-i], h) + hashes = append(hashes, h) + } + return hashes, nil +} + +// A HashReader can read hashes for nodes in the log's tree structure. +type HashReader interface { + // ReadHashes returns the hashes with the given stored hash indexes + // (see StoredHashIndex and SplitStoredHashIndex). + // ReadHashes must return a slice of hashes the same length as indexes, + // or else it must return a non-nil error. + // ReadHashes may run faster if indexes is sorted in increasing order. + ReadHashes(indexes []int64) ([]Hash, error) +} + +// A HashReaderFunc is a function implementing HashReader. +type HashReaderFunc func([]int64) ([]Hash, error) + +func (f HashReaderFunc) ReadHashes(indexes []int64) ([]Hash, error) { + return f(indexes) +} + +// TreeHash computes the hash for the root of the tree with n records, +// using the HashReader to obtain previously stored hashes +// (those returned by StoredHashes during the writes of those n records). +// TreeHash makes a single call to ReadHash requesting at most 1 + log₂ n hashes. +// The tree of size zero is defined to have an all-zero Hash. +func TreeHash(n int64, r HashReader) (Hash, error) { + if n == 0 { + return Hash{}, nil + } + indexes := subTreeIndex(0, n, nil) + hashes, err := r.ReadHashes(indexes) + if err != nil { + return Hash{}, err + } + if len(hashes) != len(indexes) { + return Hash{}, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes)) + } + hash, hashes := subTreeHash(0, n, hashes) + if len(hashes) != 0 { + panic("tlog: bad index math in TreeHash") + } + return hash, nil +} + +// subTreeIndex returns the storage indexes needed to compute +// the hash for the subtree containing records [lo, hi), +// appending them to need and returning the result. +// See https://tools.ietf.org/html/rfc6962#section-2.1 +func subTreeIndex(lo, hi int64, need []int64) []int64 { + // See subTreeHash below for commentary. + for lo < hi { + k, level := maxpow2(hi - lo + 1) + if lo&(k-1) != 0 { + panic("tlog: bad math in subTreeIndex") + } + need = append(need, StoredHashIndex(level, lo>>uint(level))) + lo += k + } + return need +} + +// subTreeHash computes the hash for the subtree containing records [lo, hi), +// assuming that hashes are the hashes corresponding to the indexes +// returned by subTreeIndex(lo, hi). +// It returns any leftover hashes. +func subTreeHash(lo, hi int64, hashes []Hash) (Hash, []Hash) { + // Repeatedly partition the tree into a left side with 2^level nodes, + // for as large a level as possible, and a right side with the fringe. + // The left hash is stored directly and can be read from storage. + // The right side needs further computation. + numTree := 0 + for lo < hi { + k, _ := maxpow2(hi - lo + 1) + if lo&(k-1) != 0 || lo >= hi { + panic("tlog: bad math in subTreeHash") + } + numTree++ + lo += k + } + + if len(hashes) < numTree { + panic("tlog: bad index math in subTreeHash") + } + + // Reconstruct hash. + h := hashes[numTree-1] + for i := numTree - 2; i >= 0; i-- { + h = NodeHash(hashes[i], h) + } + return h, hashes[numTree:] +} + +// A RecordProof is a verifiable proof that a particular log root contains a particular record. +// RFC 6962 calls this a “Merkle audit path.” +type RecordProof []Hash + +// ProveRecord returns the proof that the tree of size t contains the record with index n. +func ProveRecord(t, n int64, r HashReader) (RecordProof, error) { + if t < 0 || n < 0 || n >= t { + return nil, fmt.Errorf("tlog: invalid inputs in ProveRecord") + } + indexes := leafProofIndex(0, t, n, nil) + if len(indexes) == 0 { + return RecordProof{}, nil + } + hashes, err := r.ReadHashes(indexes) + if err != nil { + return nil, err + } + if len(hashes) != len(indexes) { + return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes)) + } + + p, hashes := leafProof(0, t, n, hashes) + if len(hashes) != 0 { + panic("tlog: bad index math in ProveRecord") + } + return p, nil +} + +// leafProofIndex builds the list of indexes needed to construct the proof +// that leaf n is contained in the subtree with leaves [lo, hi). +// It appends those indexes to need and returns the result. +// See https://tools.ietf.org/html/rfc6962#section-2.1.1 +func leafProofIndex(lo, hi, n int64, need []int64) []int64 { + // See leafProof below for commentary. + if !(lo <= n && n < hi) { + panic("tlog: bad math in leafProofIndex") + } + if lo+1 == hi { + return need + } + if k, _ := maxpow2(hi - lo); n < lo+k { + need = leafProofIndex(lo, lo+k, n, need) + need = subTreeIndex(lo+k, hi, need) + } else { + need = subTreeIndex(lo, lo+k, need) + need = leafProofIndex(lo+k, hi, n, need) + } + return need +} + +// leafProof constructs the proof that leaf n is contained in the subtree with leaves [lo, hi). +// It returns any leftover hashes as well. +// See https://tools.ietf.org/html/rfc6962#section-2.1.1 +func leafProof(lo, hi, n int64, hashes []Hash) (RecordProof, []Hash) { + // We must have lo <= n < hi or else the code here has a bug. + if !(lo <= n && n < hi) { + panic("tlog: bad math in leafProof") + } + + if lo+1 == hi { // n == lo + // Reached the leaf node. + // The verifier knows what the leaf hash is, so we don't need to send it. + return RecordProof{}, hashes + } + + // Walk down the tree toward n. + // Record the hash of the path not taken (needed for verifying the proof). + var p RecordProof + var th Hash + if k, _ := maxpow2(hi - lo); n < lo+k { + // n is on left side + p, hashes = leafProof(lo, lo+k, n, hashes) + th, hashes = subTreeHash(lo+k, hi, hashes) + } else { + // n is on right side + th, hashes = subTreeHash(lo, lo+k, hashes) + p, hashes = leafProof(lo+k, hi, n, hashes) + } + return append(p, th), hashes +} + +var errProofFailed = errors.New("invalid transparency proof") + +// CheckRecord verifies that p is a valid proof that the tree of size t +// with hash th has an n'th record with hash h. +func CheckRecord(p RecordProof, t int64, th Hash, n int64, h Hash) error { + if t < 0 || n < 0 || n >= t { + return fmt.Errorf("tlog: invalid inputs in CheckRecord") + } + th2, err := runRecordProof(p, 0, t, n, h) + if err != nil { + return err + } + if th2 == th { + return nil + } + return errProofFailed +} + +// runRecordProof runs the proof p that leaf n is contained in the subtree with leaves [lo, hi). +// Running the proof means constructing and returning the implied hash of that +// subtree. +func runRecordProof(p RecordProof, lo, hi, n int64, leafHash Hash) (Hash, error) { + // We must have lo <= n < hi or else the code here has a bug. + if !(lo <= n && n < hi) { + panic("tlog: bad math in runRecordProof") + } + + if lo+1 == hi { // m == lo + // Reached the leaf node. + // The proof must not have any unnecessary hashes. + if len(p) != 0 { + return Hash{}, errProofFailed + } + return leafHash, nil + } + + if len(p) == 0 { + return Hash{}, errProofFailed + } + + k, _ := maxpow2(hi - lo) + if n < lo+k { + th, err := runRecordProof(p[:len(p)-1], lo, lo+k, n, leafHash) + if err != nil { + return Hash{}, err + } + return NodeHash(th, p[len(p)-1]), nil + } else { + th, err := runRecordProof(p[:len(p)-1], lo+k, hi, n, leafHash) + if err != nil { + return Hash{}, err + } + return NodeHash(p[len(p)-1], th), nil + } +} + +// A TreeProof is a verifiable proof that a particular log tree contains +// as a prefix all records present in an earlier tree. +// RFC 6962 calls this a “Merkle consistency proof.” +type TreeProof []Hash + +// ProveTree returns the proof that the tree of size t contains +// as a prefix all the records from the tree of smaller size n. +func ProveTree(t, n int64, h HashReader) (TreeProof, error) { + if t < 1 || n < 1 || n > t { + return nil, fmt.Errorf("tlog: invalid inputs in ProveTree") + } + indexes := treeProofIndex(0, t, n, nil) + if len(indexes) == 0 { + return TreeProof{}, nil + } + hashes, err := h.ReadHashes(indexes) + if err != nil { + return nil, err + } + if len(hashes) != len(indexes) { + return nil, fmt.Errorf("tlog: ReadHashes(%d indexes) = %d hashes", len(indexes), len(hashes)) + } + + p, hashes := treeProof(0, t, n, hashes) + if len(hashes) != 0 { + panic("tlog: bad index math in ProveTree") + } + return p, nil +} + +// treeProofIndex builds the list of indexes needed to construct +// the sub-proof related to the subtree containing records [lo, hi). +// See https://tools.ietf.org/html/rfc6962#section-2.1.2. +func treeProofIndex(lo, hi, n int64, need []int64) []int64 { + // See treeProof below for commentary. + if !(lo < n && n <= hi) { + panic("tlog: bad math in treeProofIndex") + } + + if n == hi { + if lo == 0 { + return need + } + return subTreeIndex(lo, hi, need) + } + + if k, _ := maxpow2(hi - lo); n <= lo+k { + need = treeProofIndex(lo, lo+k, n, need) + need = subTreeIndex(lo+k, hi, need) + } else { + need = subTreeIndex(lo, lo+k, need) + need = treeProofIndex(lo+k, hi, n, need) + } + return need +} + +// treeProof constructs the sub-proof related to the subtree containing records [lo, hi). +// It returns any leftover hashes as well. +// See https://tools.ietf.org/html/rfc6962#section-2.1.2. +func treeProof(lo, hi, n int64, hashes []Hash) (TreeProof, []Hash) { + // We must have lo < n <= hi or else the code here has a bug. + if !(lo < n && n <= hi) { + panic("tlog: bad math in treeProof") + } + + // Reached common ground. + if n == hi { + if lo == 0 { + // This subtree corresponds exactly to the old tree. + // The verifier knows that hash, so we don't need to send it. + return TreeProof{}, hashes + } + th, hashes := subTreeHash(lo, hi, hashes) + return TreeProof{th}, hashes + } + + // Interior node for the proof. + // Decide whether to walk down the left or right side. + var p TreeProof + var th Hash + if k, _ := maxpow2(hi - lo); n <= lo+k { + // m is on left side + p, hashes = treeProof(lo, lo+k, n, hashes) + th, hashes = subTreeHash(lo+k, hi, hashes) + } else { + // m is on right side + th, hashes = subTreeHash(lo, lo+k, hashes) + p, hashes = treeProof(lo+k, hi, n, hashes) + } + return append(p, th), hashes +} + +// CheckTree verifies that p is a valid proof that the tree of size t with hash th +// contains as a prefix the tree of size n with hash h. +func CheckTree(p TreeProof, t int64, th Hash, n int64, h Hash) error { + if t < 1 || n < 1 || n > t { + return fmt.Errorf("tlog: invalid inputs in CheckTree") + } + h2, th2, err := runTreeProof(p, 0, t, n, h) + if err != nil { + return err + } + if th2 == th && h2 == h { + return nil + } + return errProofFailed +} + +// runTreeProof runs the sub-proof p related to the subtree containing records [lo, hi), +// where old is the hash of the old tree with n records. +// Running the proof means constructing and returning the implied hashes of that +// subtree in both the old and new tree. +func runTreeProof(p TreeProof, lo, hi, n int64, old Hash) (Hash, Hash, error) { + // We must have lo < n <= hi or else the code here has a bug. + if !(lo < n && n <= hi) { + panic("tlog: bad math in runTreeProof") + } + + // Reached common ground. + if n == hi { + if lo == 0 { + if len(p) != 0 { + return Hash{}, Hash{}, errProofFailed + } + return old, old, nil + } + if len(p) != 1 { + return Hash{}, Hash{}, errProofFailed + } + return p[0], p[0], nil + } + + if len(p) == 0 { + return Hash{}, Hash{}, errProofFailed + } + + // Interior node for the proof. + k, _ := maxpow2(hi - lo) + if n <= lo+k { + oh, th, err := runTreeProof(p[:len(p)-1], lo, lo+k, n, old) + if err != nil { + return Hash{}, Hash{}, err + } + return oh, NodeHash(th, p[len(p)-1]), nil + } else { + oh, th, err := runTreeProof(p[:len(p)-1], lo+k, hi, n, old) + if err != nil { + return Hash{}, Hash{}, err + } + return NodeHash(p[len(p)-1], oh), NodeHash(p[len(p)-1], th), nil + } +} diff --git a/libgo/go/golang.org/x/mod/zip/zip.go b/libgo/go/golang.org/x/mod/zip/zip.go new file mode 100644 index 00000000000..37c764257e4 --- /dev/null +++ b/libgo/go/golang.org/x/mod/zip/zip.go @@ -0,0 +1,570 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package zip provides functions for creating and extracting module zip files. +// +// Module zip files have several restrictions listed below. These are necessary +// to ensure that module zip files can be extracted consistently on supported +// platforms and file systems. +// +// • All file paths within a zip file must start with "@/", +// where "" is the module path and "" is the version. +// The module path must be valid (see golang.org/x/mod/module.CheckPath). +// The version must be valid and canonical (see +// golang.org/x/mod/module.CanonicalVersion). The path must have a major +// version suffix consistent with the version (see +// golang.org/x/mod/module.Check). The part of the file path after the +// "@/" prefix must be valid (see +// golang.org/x/mod/module.CheckFilePath). +// +// • No two file paths may be equal under Unicode case-folding (see +// strings.EqualFold). +// +// • A go.mod file may or may not appear in the top-level directory. If present, +// it must be named "go.mod", not any other case. Files named "go.mod" +// are not allowed in any other directory. +// +// • The total size in bytes of a module zip file may be at most MaxZipFile +// bytes (500 MiB). The total uncompressed size of the files within the +// zip may also be at most MaxZipFile bytes. +// +// • Each file's uncompressed size must match its declared 64-bit uncompressed +// size in the zip file header. +// +// • If the zip contains files named "@/go.mod" or +// "@/LICENSE", their sizes in bytes may be at most +// MaxGoMod or MaxLICENSE, respectively (both are 16 MiB). +// +// • Empty directories are ignored. File permissions and timestamps are also +// ignored. +// +// • Symbolic links and other irregular files are not allowed. +// +// Note that this package does not provide hashing functionality. See +// golang.org/x/mod/sumdb/dirhash. +package zip + +import ( + "archive/zip" + "bytes" + "fmt" + "io" + "io/ioutil" + "os" + "path" + "path/filepath" + "strings" + "unicode" + "unicode/utf8" + + "golang.org/x/mod/module" +) + +const ( + // MaxZipFile is the maximum size in bytes of a module zip file. The + // go command will report an error if either the zip file or its extracted + // content is larger than this. + MaxZipFile = 500 << 20 + + // MaxGoMod is the maximum size in bytes of a go.mod file within a + // module zip file. + MaxGoMod = 16 << 20 + + // MaxLICENSE is the maximum size in bytes of a LICENSE file within a + // module zip file. + MaxLICENSE = 16 << 20 +) + +// File provides an abstraction for a file in a directory, zip, or anything +// else that looks like a file. +type File interface { + // Path returns a clean slash-separated relative path from the module root + // directory to the file. + Path() string + + // Lstat returns information about the file. If the file is a symbolic link, + // Lstat returns information about the link itself, not the file it points to. + Lstat() (os.FileInfo, error) + + // Open provides access to the data within a regular file. Open may return + // an error if called on a directory or symbolic link. + Open() (io.ReadCloser, error) +} + +// Create builds a zip archive for module m from an abstract list of files +// and writes it to w. +// +// Create verifies the restrictions described in the package documentation +// and should not produce an archive that Unzip cannot extract. Create does not +// include files in the output archive if they don't belong in the module zip. +// In particular, Create will not include files in modules found in +// subdirectories, most files in vendor directories, or irregular files (such +// as symbolic links) in the output archive. +func Create(w io.Writer, m module.Version, files []File) (err error) { + defer func() { + if err != nil { + err = &zipError{verb: "create zip", err: err} + } + }() + + // Check that the version is canonical, the module path is well-formed, and + // the major version suffix matches the major version. + if vers := module.CanonicalVersion(m.Version); vers != m.Version { + return fmt.Errorf("version %q is not canonical (should be %q)", m.Version, vers) + } + if err := module.Check(m.Path, m.Version); err != nil { + return err + } + + // Find directories containing go.mod files (other than the root). + // These directories will not be included in the output zip. + haveGoMod := make(map[string]bool) + for _, f := range files { + dir, base := path.Split(f.Path()) + if strings.EqualFold(base, "go.mod") { + info, err := f.Lstat() + if err != nil { + return err + } + if info.Mode().IsRegular() { + haveGoMod[dir] = true + } + } + } + + inSubmodule := func(p string) bool { + for { + dir, _ := path.Split(p) + if dir == "" { + return false + } + if haveGoMod[dir] { + return true + } + p = dir[:len(dir)-1] + } + } + + // Create the module zip file. + zw := zip.NewWriter(w) + prefix := fmt.Sprintf("%s@%s/", m.Path, m.Version) + + addFile := func(f File, path string, size int64) error { + rc, err := f.Open() + if err != nil { + return err + } + defer rc.Close() + w, err := zw.Create(prefix + path) + if err != nil { + return err + } + lr := &io.LimitedReader{R: rc, N: size + 1} + if _, err := io.Copy(w, lr); err != nil { + return err + } + if lr.N <= 0 { + return fmt.Errorf("file %q is larger than declared size", path) + } + return nil + } + + collisions := make(collisionChecker) + maxSize := int64(MaxZipFile) + for _, f := range files { + p := f.Path() + if p != path.Clean(p) { + return fmt.Errorf("file path %s is not clean", p) + } + if path.IsAbs(p) { + return fmt.Errorf("file path %s is not relative", p) + } + if isVendoredPackage(p) || inSubmodule(p) { + continue + } + if p == ".hg_archival.txt" { + // Inserted by hg archive. + // The go command drops this regardless of the VCS being used. + continue + } + if err := module.CheckFilePath(p); err != nil { + return err + } + if strings.ToLower(p) == "go.mod" && p != "go.mod" { + return fmt.Errorf("found file named %s, want all lower-case go.mod", p) + } + info, err := f.Lstat() + if err != nil { + return err + } + if err := collisions.check(p, info.IsDir()); err != nil { + return err + } + if !info.Mode().IsRegular() { + // Skip symbolic links (golang.org/issue/27093). + continue + } + size := info.Size() + if size < 0 || maxSize < size { + return fmt.Errorf("module source tree too large (max size is %d bytes)", MaxZipFile) + } + maxSize -= size + if p == "go.mod" && size > MaxGoMod { + return fmt.Errorf("go.mod file too large (max size is %d bytes)", MaxGoMod) + } + if p == "LICENSE" && size > MaxLICENSE { + return fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE) + } + + if err := addFile(f, p, size); err != nil { + return err + } + } + + return zw.Close() +} + +// CreateFromDir creates a module zip file for module m from the contents of +// a directory, dir. The zip content is written to w. +// +// CreateFromDir verifies the restrictions described in the package +// documentation and should not produce an archive that Unzip cannot extract. +// CreateFromDir does not include files in the output archive if they don't +// belong in the module zip. In particular, CreateFromDir will not include +// files in modules found in subdirectories, most files in vendor directories, +// or irregular files (such as symbolic links) in the output archive. +// Additionally, unlike Create, CreateFromDir will not include directories +// named ".bzr", ".git", ".hg", or ".svn". +func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) { + defer func() { + if zerr, ok := err.(*zipError); ok { + zerr.path = dir + } else if err != nil { + err = &zipError{verb: "create zip", path: dir, err: err} + } + }() + + var files []File + err = filepath.Walk(dir, func(filePath string, info os.FileInfo, err error) error { + relPath, err := filepath.Rel(dir, filePath) + if err != nil { + return err + } + slashPath := filepath.ToSlash(relPath) + + if info.IsDir() { + if filePath == dir { + // Don't skip the top-level directory. + return nil + } + + // Skip VCS directories. + // fossil repos are regular files with arbitrary names, so we don't try + // to exclude them. + switch filepath.Base(filePath) { + case ".bzr", ".git", ".hg", ".svn": + return filepath.SkipDir + } + + // Skip some subdirectories inside vendor, but maintain bug + // golang.org/issue/31562, described in isVendoredPackage. + // We would like Create and CreateFromDir to produce the same result + // for a set of files, whether expressed as a directory tree or zip. + if isVendoredPackage(slashPath) { + return filepath.SkipDir + } + + // Skip submodules (directories containing go.mod files). + if goModInfo, err := os.Lstat(filepath.Join(filePath, "go.mod")); err == nil && !goModInfo.IsDir() { + return filepath.SkipDir + } + return nil + } + + if info.Mode().IsRegular() { + if !isVendoredPackage(slashPath) { + files = append(files, dirFile{ + filePath: filePath, + slashPath: slashPath, + info: info, + }) + } + return nil + } + + // Not a regular file or a directory. Probably a symbolic link. + // Irregular files are ignored, so skip it. + return nil + }) + if err != nil { + return err + } + + return Create(w, m, files) +} + +type dirFile struct { + filePath, slashPath string + info os.FileInfo +} + +func (f dirFile) Path() string { return f.slashPath } +func (f dirFile) Lstat() (os.FileInfo, error) { return f.info, nil } +func (f dirFile) Open() (io.ReadCloser, error) { return os.Open(f.filePath) } + +func isVendoredPackage(name string) bool { + var i int + if strings.HasPrefix(name, "vendor/") { + i += len("vendor/") + } else if j := strings.Index(name, "/vendor/"); j >= 0 { + // This offset looks incorrect; this should probably be + // + // i = j + len("/vendor/") + // + // (See https://golang.org/issue/31562.) + // + // Unfortunately, we can't fix it without invalidating checksums. + // Fortunately, the error appears to be strictly conservative: we'll retain + // vendored packages that we should have pruned, but we won't prune + // non-vendored packages that we should have retained. + // + // Since this defect doesn't seem to break anything, it's not worth fixing + // for now. + i += len("/vendor/") + } else { + return false + } + return strings.Contains(name[i:], "/") +} + +// Unzip extracts the contents of a module zip file to a directory. +// +// Unzip checks all restrictions listed in the package documentation and returns +// an error if the zip archive is not valid. In some cases, files may be written +// to dir before an error is returned (for example, if a file's uncompressed +// size does not match its declared size). +// +// dir may or may not exist: Unzip will create it and any missing parent +// directories if it doesn't exist. If dir exists, it must be empty. +func Unzip(dir string, m module.Version, zipFile string) (err error) { + defer func() { + if err != nil { + err = &zipError{verb: "unzip", path: zipFile, err: err} + } + }() + + if vers := module.CanonicalVersion(m.Version); vers != m.Version { + return fmt.Errorf("version %q is not canonical (should be %q)", m.Version, vers) + } + if err := module.Check(m.Path, m.Version); err != nil { + return err + } + + // Check that the directory is empty. Don't create it yet in case there's + // an error reading the zip. + files, _ := ioutil.ReadDir(dir) + if len(files) > 0 { + return fmt.Errorf("target directory %v exists and is not empty", dir) + } + + // Open the zip file and ensure it's under the size limit. + f, err := os.Open(zipFile) + if err != nil { + return err + } + defer f.Close() + info, err := f.Stat() + if err != nil { + return err + } + zipSize := info.Size() + if zipSize > MaxZipFile { + return fmt.Errorf("module zip file is too large (%d bytes; limit is %d bytes)", zipSize, MaxZipFile) + } + + z, err := zip.NewReader(f, zipSize) + if err != nil { + return err + } + + // Check total size, valid file names. + collisions := make(collisionChecker) + prefix := fmt.Sprintf("%s@%s/", m.Path, m.Version) + var size int64 + for _, zf := range z.File { + if !strings.HasPrefix(zf.Name, prefix) { + return fmt.Errorf("unexpected file name %s", zf.Name) + } + name := zf.Name[len(prefix):] + if name == "" { + continue + } + isDir := strings.HasSuffix(name, "/") + if isDir { + name = name[:len(name)-1] + } + if path.Clean(name) != name { + return fmt.Errorf("invalid file name %s", zf.Name) + } + if err := module.CheckFilePath(name); err != nil { + return err + } + if err := collisions.check(name, isDir); err != nil { + return err + } + if isDir { + continue + } + if base := path.Base(name); strings.EqualFold(base, "go.mod") { + if base != name { + return fmt.Errorf("found go.mod file not in module root directory (%s)", zf.Name) + } else if name != "go.mod" { + return fmt.Errorf("found file named %s, want all lower-case go.mod", zf.Name) + } + } + s := int64(zf.UncompressedSize64) + if s < 0 || MaxZipFile-size < s { + return fmt.Errorf("total uncompressed size of module contents too large (max size is %d bytes)", MaxZipFile) + } + size += s + if name == "go.mod" && s > MaxGoMod { + return fmt.Errorf("go.mod file too large (max size is %d bytes)", MaxGoMod) + } + if name == "LICENSE" && s > MaxLICENSE { + return fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE) + } + } + + // Unzip, enforcing sizes checked earlier. + if err := os.MkdirAll(dir, 0777); err != nil { + return err + } + for _, zf := range z.File { + name := zf.Name[len(prefix):] + if name == "" || strings.HasSuffix(name, "/") { + continue + } + dst := filepath.Join(dir, name) + if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil { + return err + } + w, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0444) + if err != nil { + return err + } + r, err := zf.Open() + if err != nil { + w.Close() + return err + } + lr := &io.LimitedReader{R: r, N: int64(zf.UncompressedSize64) + 1} + _, err = io.Copy(w, lr) + r.Close() + if err != nil { + w.Close() + return err + } + if err := w.Close(); err != nil { + return err + } + if lr.N <= 0 { + return fmt.Errorf("uncompressed size of file %s is larger than declared size (%d bytes)", zf.Name, zf.UncompressedSize64) + } + } + + return nil +} + +// collisionChecker finds case-insensitive name collisions and paths that +// are listed as both files and directories. +// +// The keys of this map are processed with strToFold. pathInfo has the original +// path for each folded path. +type collisionChecker map[string]pathInfo + +type pathInfo struct { + path string + isDir bool +} + +func (cc collisionChecker) check(p string, isDir bool) error { + fold := strToFold(p) + if other, ok := cc[fold]; ok { + if p != other.path { + return fmt.Errorf("case-insensitive file name collision: %q and %q", other.path, p) + } + if isDir != other.isDir { + return fmt.Errorf("entry %q is both a file and a directory", p) + } + if !isDir { + return fmt.Errorf("multiple entries for file %q", p) + } + // It's not an error if check is called with the same directory multiple + // times. check is called recursively on parent directories, so check + // may be called on the same directory many times. + } else { + cc[fold] = pathInfo{path: p, isDir: isDir} + } + + if parent := path.Dir(p); parent != "." { + return cc.check(parent, true) + } + return nil +} + +type zipError struct { + verb, path string + err error +} + +func (e *zipError) Error() string { + if e.path == "" { + return fmt.Sprintf("%s: %v", e.verb, e.err) + } else { + return fmt.Sprintf("%s %s: %v", e.verb, e.path, e.err) + } +} + +func (e *zipError) Unwrap() error { + return e.err +} + +// strToFold returns a string with the property that +// strings.EqualFold(s, t) iff strToFold(s) == strToFold(t) +// This lets us test a large set of strings for fold-equivalent +// duplicates without making a quadratic number of calls +// to EqualFold. Note that strings.ToUpper and strings.ToLower +// do not have the desired property in some corner cases. +func strToFold(s string) string { + // Fast path: all ASCII, no upper case. + // Most paths look like this already. + for i := 0; i < len(s); i++ { + c := s[i] + if c >= utf8.RuneSelf || 'A' <= c && c <= 'Z' { + goto Slow + } + } + return s + +Slow: + var buf bytes.Buffer + for _, r := range s { + // SimpleFold(x) cycles to the next equivalent rune > x + // or wraps around to smaller values. Iterate until it wraps, + // and we've found the minimum value. + for { + r0 := r + r = unicode.SimpleFold(r0) + if r <= r0 { + break + } + } + // Exception to allow fast path above: A-Z => a-z + if 'A' <= r && r <= 'Z' { + r += 'a' - 'A' + } + buf.WriteRune(r) + } + return buf.String() +} diff --git a/libgo/go/golang.org/x/net/dns/dnsmessage/message.go b/libgo/go/golang.org/x/net/dns/dnsmessage/message.go index 13fbc0814e5..82bcdcc838c 100644 --- a/libgo/go/golang.org/x/net/dns/dnsmessage/message.go +++ b/libgo/go/golang.org/x/net/dns/dnsmessage/message.go @@ -1660,7 +1660,7 @@ func (h *ResourceHeader) fixLen(msg []byte, lenOff int, preLen int) error { return nil } -// EDNS(0) wire costants. +// EDNS(0) wire constants. const ( edns0Version = 0 diff --git a/libgo/go/golang.org/x/net/http2/hpack/encode.go b/libgo/go/golang.org/x/net/http2/hpack/encode.go index 1565cf2702d..97f17831fc5 100644 --- a/libgo/go/golang.org/x/net/http2/hpack/encode.go +++ b/libgo/go/golang.org/x/net/http2/hpack/encode.go @@ -150,7 +150,7 @@ func appendIndexed(dst []byte, i uint64) []byte { // extended buffer. // // If f.Sensitive is true, "Never Indexed" representation is used. If -// f.Sensitive is false and indexing is true, "Inremental Indexing" +// f.Sensitive is false and indexing is true, "Incremental Indexing" // representation is used. func appendNewName(dst []byte, f HeaderField, indexing bool) []byte { dst = append(dst, encodeTypeByte(indexing, f.Sensitive)) diff --git a/libgo/go/golang.org/x/net/idna/tables11.0.0.go b/libgo/go/golang.org/x/net/idna/tables11.0.0.go index c515d7ad2a2..8ce0811fdf3 100644 --- a/libgo/go/golang.org/x/net/idna/tables11.0.0.go +++ b/libgo/go/golang.org/x/net/idna/tables11.0.0.go @@ -1,6 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. -// +build go1.13 +// +build go1.13,!go1.14 package idna diff --git a/libgo/go/golang.org/x/net/idna/tables12.00.go b/libgo/go/golang.org/x/net/idna/tables12.00.go new file mode 100644 index 00000000000..f4b8ea3638e --- /dev/null +++ b/libgo/go/golang.org/x/net/idna/tables12.00.go @@ -0,0 +1,4733 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.14 + +package idna + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "12.0.0" + +var mappings string = "" + // Size: 8178 bytes + "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" + + "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03â±¥\x03ⱦ\x01h\x01j\x01r\x01w\x01y" + + "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" + + "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" + + "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" + + "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" + + "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" + + "в\x02д\x02о\x02с\x02т\x02ъ\x02Ñ£\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" + + "\x01m\x01n\x02È£\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" + + "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" + + "\x02É¡\x02É¥\x02ɨ\x02É©\x02ɪ\x02ʝ\x02É­\x02ʟ\x02ɱ\x02É°\x02ɲ\x02ɳ\x02É´\x02ɵ" + + "\x02ɸ\x02ʂ\x02ʃ\x02Æ«\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" + + "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" + + "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" + + "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" + + "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" + + "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" + + "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" + + "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02Ã¥\x02א\x02ב\x02ג" + + "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" + + "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" + + "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" + + "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" + + "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" + + "\x02==\x05⫝̸\x02É«\x02ɽ\x02È¿\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" + + "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" + + ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" + + "\x05(자)\x05(ì°¨)\x05(ì¹´)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" + + "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" + + "\x05(火)\x05(æ°´)\x05(木)\x05(金)\x05(土)\x05(日)\x05(æ ª)\x05(有)\x05(社)\x05(名)" + + "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(å­¦)\x05(監)\x05(企)\x05(資)" + + "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" + + "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" + + "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" + + "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" + + "月\x0511月\x0512月\x02hg\x02ev\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニング\x09" + + "インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー\x09ガロ" + + "ン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0fキロワッ" + + "ト\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル\x0fサンチ" + + "ーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット\x09ハイツ" + + "\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0cフィート" + + "\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ\x0cポイ" + + "ント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク\x0fマ" + + "ンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09ユアン" + + "\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x042点" + + "\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" + + "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" + + "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0cæ ª" + + "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" + + "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" + + "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" + + "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" + + "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" + + "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" + + "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" + + "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" + + "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x04𤋮\x04𢡊\x04𢡄\x04𣏕\x04𥉉" + + "\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04Õ´Õ¶\x04Õ´Õ¥\x04Õ´Õ«\x04Õ¾Õ¶\x04Õ´Õ­\x04יִ" + + "\x04ײַ\x02×¢\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּׂ\x04א" + + "Ö·\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04ךּ\x04" + + "כּ\x04לּ\x04מּ\x04× Ö¼\x04סּ\x04×£Ö¼\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ\x04תּ" + + "\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02Ù±\x02Ù»\x02Ù¾\x02ڀ\x02Ùº\x02Ù¿\x02Ù¹\x02Ú¤" + + "\x02Ú¦\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02Ú©\x02Ú¯\x02Ú³" + + "\x02Ú±\x02Úº\x02Ú»\x02ۀ\x02ہ\x02Ú¾\x02ے\x02ۓ\x02Ú­\x02ۇ\x02ۆ\x02ۈ\x02ۋ\x02ۅ" + + "\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02ی\x04" + + "ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04تح" + + "\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج\x04حم" + + "\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح\x04ضخ" + + "\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ\x04فم" + + "\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل\x04كم" + + "\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ\x04مم" + + "\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى\x04هي" + + "\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 ٍّ\x05" + + " َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04تر\x04تز" + + "\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04ين\x04ئخ" + + "\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه\x04شم\x04شه" + + "\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي\x04سى\x04سي" + + "\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي\x04ضى\x04ضي" + + "\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06تحج\x06تحم" + + "\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سجح\x06سجى" + + "\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم\x06ضحى" + + "\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي\x06غمى" + + "\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح\x06محج" + + "\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم\x06نحم" + + "\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى\x06تخي" + + "\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي\x06ضحي" + + "\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي\x06كمي" + + "\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي\x06سخي" + + "\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08عليه" + + "\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:\x01!" + + "\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\\x01$" + + "\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02Ø¡\x02Ø¢\x02Ø£\x02ؤ\x02Ø¥" + + "\x02ئ\x02ا\x02ب\x02Ø©\x02ت\x02Ø«\x02ج\x02Ø­\x02Ø®\x02د\x02Ø°\x02ر\x02ز\x02س" + + "\x02Ø´\x02ص\x02ض\x02Ø·\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن\x02ه" + + "\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~\x02¢" + + "\x02£\x02¬\x02¦\x02Â¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲\x08𝆹" + + "𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02È·\x02α\x02ε\x02ζ\x02η\x02" + + "κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02Ù®\x02Ú¡" + + "\x02Ù¯\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029,\x03(a)" + + "\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)\x03(k)" + + "\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)\x03(u)" + + "\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03ppv\x02w" + + "c\x02mc\x02md\x02mr\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ\x03二\x03多" + + "\x03解\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終\x03生\x03販" + + "\x03声\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03å·¦\x03中\x03右\x03指\x03èµ°\x03打" + + "\x03禁\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔三〕\x09〔二〕" + + "\x09〔安〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03丸\x03乁\x03ä½ " + + "\x03ä¾®\x03ä¾»\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03具\x03㒹\x03內" + + "\x03冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03㔕\x03勇\x03勉" + + "\x03勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03灰\x03及\x03叟" + + "\x03叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03啣\x03善\x03喙" + + "\x03喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03埴\x03堍\x03型" + + "\x03å ²\x03å ±\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03姘\x03婦\x03㛮" + + "\x03嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03å°¢\x03㞁\x03å± \x03å±®\x03峀\x03岍" + + "\x03嵃\x03åµ®\x03嵫\x03åµ¼\x03å·¡\x03å·¢\x03ã ¯\x03å·½\x03帨\x03帽\x03幩\x03ã¡¢\x03㡼\x03庰" + + "\x03庳\x03庶\x03廊\x03廾\x03舁\x03å¼¢\x03㣇\x03å½¢\x03彫\x03㣣\x03徚\x03忍\x03志\x03忹" + + "\x03悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03憤\x03憯\x03懞" + + "\x03懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03掃\x03揤\x03搢" + + "\x03揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03書\x03晉\x03㬙" + + "\x03暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03朡\x03杞\x03杓" + + "\x03㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03槪\x03檨\x03櫛" + + "\x03㰘\x03次\x03歔\x03㱎\x03æ­²\x03殟\x03殺\x03æ®»\x03汎\x03沿\x03泍\x03汧\x03洖\x03æ´¾" + + "\x03æµ·\x03流\x03浩\x03浸\x03涅\x03æ´´\x03港\x03æ¹®\x03ã´³\x03滋\x03滇\x03æ·¹\x03æ½®\x03濆" + + "\x03瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03爵\x03牐\x03犀" + + "\x03犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03㼛\x03甤\x03甾" + + "\x03異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03䂖\x03硎\x03碌" + + "\x03磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03築\x03䈧\x03糒" + + "\x03䊠\x03糨\x03ç³£\x03紀\x03çµ£\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03罺\x03羕\x03翺" + + "\x03者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03䑫\x03芑\x03芋" + + "\x03芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03莽\x03菧\x03著" + + "\x03荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03䕫\x03虐\x03虜" + + "\x03虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03蠁\x03䗹\x03è¡ " + + "\x03è¡£\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03è«­\x03變\x03豕\x03貫\x03賁" + + "\x03贛\x03èµ·\x03跋\x03趼\x03è·°\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03鈸\x03鋗\x03鋘" + + "\x03鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03ä©®\x03䩶\x03韠\x03䪲" + + "\x03頋\x03é ©\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03é³½\x03䳎\x03ä³­" + + "\x03鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03é¼»" + +var xorData string = "" + // Size: 4862 bytes + "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" + + "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" + + "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" + + "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" + + "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" + + "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" + + "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" + + "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" + + "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" + + "\x03\x037 \x03\x0b+\x03\x021\x00\x02\x01\x04\x02\x01\x02\x02\x019\x02" + + "\x03\x1c\x02\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03" + + "\xc1r\x02\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<" + + "\x03\xc1s*\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03" + + "\x83\xab\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96" + + "\xe1\xcd\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03" + + "\x9a\xec\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c" + + "!\x03\x01\x0c#\x03Ê \x9d\x03Ê£\x9c\x03Ê¢\x9f\x03Ê¥\x9e\x03ʤ\x91\x03ʧ\x90\x03" + + "ʦ\x93\x03Ê©\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7" + + "\x03\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca" + + "\xfa\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e" + + "\x03\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca" + + "\xe3\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99" + + "\x03\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca" + + "\xe8\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03" + + "\x0b\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06" + + "\x05\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03" + + "\x0786\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/" + + "\x03\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f" + + "\x03\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-" + + "\x03\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03" + + "\x07\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03" + + "\x07\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03" + + "\x07\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b" + + "\x0a\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03" + + "\x07\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+" + + "\x03\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03" + + "\x044\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03" + + "\x04+ \x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!" + + "\x22\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04" + + "\x03\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>" + + "\x03\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03" + + "\x054\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03" + + "\x05):\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$" + + "\x1e\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226" + + "\x03\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05" + + "\x1b\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05" + + "\x03\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03" + + "\x06\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08" + + "\x03\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03" + + "\x0a6\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a" + + "\x1f\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03" + + "\x0a\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f" + + "\x02\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/" + + "\x03\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a" + + "\x00\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+" + + "\x10\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#" + + "<\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!" + + "\x00\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18." + + "\x03\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15" + + "\x22\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b" + + "\x12\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05" + + "<\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" + + "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" + + "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" + + "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" + + "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" + + "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" + + "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" + + "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" + + "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" + + "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" + + "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" + + "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" + + "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" + + "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" + + "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" + + "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" + + "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" + + "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" + + "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" + + "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" + + "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" + + "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" + + "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" + + "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" + + "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" + + "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" + + "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" + + "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," + + "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" + + "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" + + "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" + + "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" + + ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" + + "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" + + "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" + + "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" + + "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" + + "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" + + "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" + + "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" + + "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" + + "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" + + "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" + + "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" + + "(\x04\x023 \x03\x0b)\x08\x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!" + + "\x10\x03\x0b!0\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b" + + "\x03\x09\x1f\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14" + + "\x03\x0a\x01\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03" + + "\x08='\x03\x08\x1a\x0a\x03\x07\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07" + + "\x01\x00\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03" + + "\x09\x11\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03" + + "\x0a/1\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03" + + "\x07<3\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06" + + "\x13\x00\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(" + + ";\x03\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08" + + "\x14$\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03" + + "\x0a\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19" + + "\x01\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18" + + "\x03\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03" + + "\x07\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03" + + "\x0a\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03" + + "\x0b\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03" + + "\x08\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05" + + "\x03\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11" + + "\x03\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03" + + "\x09\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a" + + ".\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" + + "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" + + "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " + + "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" + + "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" + + "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" + + "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" + + "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" + + "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" + + "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," + + "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" + + "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" + + "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" + + "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" + + "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" + + "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" + + "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" + + "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" + + "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" + + "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" + + "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" + + "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" + + "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" + + "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" + + "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" + + "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" + + "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" + + "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" + + "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" + + "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" + + "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" + + "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" + + "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" + + "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" + + "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" + + "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" + + "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" + + "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" + + "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" + + "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" + + "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" + + "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" + + "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" + + "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" + + "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" + + "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" + + "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" + + "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" + + "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," + + "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" + + "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" + + "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" + + "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" + + "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" + + "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" + + "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" + + "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" + + "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" + + "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" + + "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" + + "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" + + "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" + + "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" + + "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" + + "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" + + "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" + + "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" + + "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" + + "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" + + "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" + + "\x04\x03\x0c?\x05\x03\x0c" + + "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" + + "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" + + "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" + + "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" + + "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" + + "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" + + "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" + + "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" + + "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" + + "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" + + "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" + + "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" + + "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" + + "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" + + "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" + + "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" + + "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" + + "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" + + "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" + + "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" + + "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" + + "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" + + "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" + + "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" + + "\x05\x22\x05\x03\x050\x1d" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *idnaTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return idnaValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := idnaIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = idnaIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = idnaIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *idnaTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return idnaValues[c0] + } + i := idnaIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = idnaIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// idnaTrie. Total size: 29708 bytes (29.01 KiB). Checksum: c3ecc76d8fffa6e6. +type idnaTrie struct{} + +func newIdnaTrie(i int) *idnaTrie { + return &idnaTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 125: + return uint16(idnaValues[n<<6+uint32(b)]) + default: + n -= 125 + return uint16(idnaSparse.lookup(n, b)) + } +} + +// idnaValues: 127 blocks, 8128 entries, 16256 bytes +// The third block is the zero block. +var idnaValues = [8128]uint16{ + // Block 0x0, offset 0x0 + 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080, + 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080, + 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080, + 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080, + 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080, + 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080, + 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080, + 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080, + 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008, + 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080, + 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080, + // Block 0x1, offset 0x40 + 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105, + 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105, + 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105, + 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105, + 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080, + 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008, + 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008, + 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008, + 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008, + 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080, + 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018, + 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018, + 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a, + 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005, + 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018, + 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018, + // Block 0x4, offset 0x100 + 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008, + 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008, + 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008, + 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008, + 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008, + 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008, + 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008, + 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008, + 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008, + 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d, + 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199, + // Block 0x5, offset 0x140 + 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d, + 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008, + 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008, + 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008, + 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008, + 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008, + 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008, + 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008, + 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008, + 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d, + 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9, + // Block 0x6, offset 0x180 + 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008, + 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d, + 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d, + 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d, + 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155, + 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008, + 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d, + 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd, + 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d, + 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008, + 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9, + 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d, + 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d, + 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d, + 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008, + 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008, + 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008, + 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008, + 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008, + 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008, + 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008, + // Block 0x8, offset 0x200 + 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008, + 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008, + 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008, + 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008, + 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008, + 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008, + 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008, + 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008, + 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008, + 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d, + 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008, + // Block 0x9, offset 0x240 + 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018, + 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008, + 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008, + 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018, + 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a, + 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369, + 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018, + 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018, + 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018, + 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018, + 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018, + // Block 0xa, offset 0x280 + 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d, + 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308, + 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308, + 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308, + 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308, + 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308, + 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308, + 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308, + 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008, + 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008, + 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2, + 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040, + 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105, + 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105, + 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105, + 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d, + 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d, + 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008, + 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008, + 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008, + 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008, + // Block 0xc, offset 0x300 + 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008, + 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008, + 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd, + 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008, + 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008, + 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008, + 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008, + 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008, + 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd, + 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008, + 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d, + // Block 0xd, offset 0x340 + 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008, + 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008, + 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008, + 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008, + 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008, + 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008, + 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008, + 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008, + 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008, + 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008, + 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008, + // Block 0xe, offset 0x380 + 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308, + 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008, + 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008, + 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008, + 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008, + 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008, + 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008, + 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008, + 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008, + 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008, + 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d, + 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d, + 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008, + 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008, + 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008, + 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008, + 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008, + 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008, + 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008, + 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008, + 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008, + // Block 0x10, offset 0x400 + 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008, + 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008, + 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008, + 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008, + 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008, + 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008, + 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008, + 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008, + 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5, + 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5, + 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5, + // Block 0x11, offset 0x440 + 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840, + 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818, + 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308, + 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308, + 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040, + 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08, + 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08, + 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08, + 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08, + 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08, + 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08, + // Block 0x12, offset 0x480 + 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08, + 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308, + 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308, + 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308, + 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308, + 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808, + 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808, + 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08, + 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429, + 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08, + 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08, + 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08, + 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08, + 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308, + 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840, + 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308, + 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018, + 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08, + 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008, + 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08, + 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08, + // Block 0x14, offset 0x500 + 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818, + 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818, + 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308, + 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08, + 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08, + 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08, + 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08, + 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08, + 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308, + 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308, + 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308, + // Block 0x15, offset 0x540 + 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08, + 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08, + 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08, + 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808, + 0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040, + 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08, + 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08, + 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040, + 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040, + 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040, + 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040, + // Block 0x16, offset 0x580 + 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308, + 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008, + 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308, + 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308, + 0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1, + 0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308, + 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008, + 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008, + 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008, + 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008, + 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008, + 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008, + 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040, + 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008, + 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008, + 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008, + 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040, + 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008, + 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040, + 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040, + 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008, + // Block 0x18, offset 0x600 + 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040, + 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008, + 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040, + 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008, + 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1, + 0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308, + 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008, + 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008, + 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018, + 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018, + 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040, + // Block 0x19, offset 0x640 + 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008, + 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040, + 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040, + 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008, + 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008, + 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008, + 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040, + 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008, + 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008, + 0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040, + 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008, + // Block 0x1a, offset 0x680 + 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040, + 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308, + 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308, + 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040, + 0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040, + 0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040, + 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008, + 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008, + 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308, + 0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040, + 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008, + 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008, + 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008, + 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008, + 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008, + 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008, + 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040, + 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008, + 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008, + 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040, + 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008, + // Block 0x1c, offset 0x700 + 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308, + 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008, + 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040, + 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040, + 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040, + 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308, + 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008, + 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008, + 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040, + 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308, + 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308, + // Block 0x1d, offset 0x740 + 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008, + 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008, + 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040, + 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008, + 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008, + 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008, + 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040, + 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008, + 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008, + 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040, + 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308, + // Block 0x1e, offset 0x780 + 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040, + 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008, + 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040, + 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008, + 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9, + 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308, + 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008, + 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008, + 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018, + 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040, + 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008, + 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040, + 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040, + 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040, + 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040, + 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008, + 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008, + 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008, + 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008, + 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040, + 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008, + // Block 0x20, offset 0x800 + 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040, + 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308, + 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040, + 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040, + 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040, + 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308, + 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008, + 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008, + 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040, + 0x836: 0x0040, 0x837: 0x0018, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018, + 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018, + // Block 0x21, offset 0x840 + 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008, + 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008, + 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040, + 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008, + 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008, + 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008, + 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040, + 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008, + 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008, + 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040, + 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308, + // Block 0x22, offset 0x880 + 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040, + 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008, + 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040, + 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040, + 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040, + 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308, + 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008, + 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008, + 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040, + 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040, + 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040, + 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008, + 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040, + 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008, + 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018, + 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308, + 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008, + 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008, + 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018, + 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008, + 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008, + // Block 0x24, offset 0x900 + 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040, + 0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0040, + 0x90c: 0x0008, 0x90d: 0x0008, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008, + 0x912: 0x0008, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008, + 0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008, + 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008, + 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0008, + 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008, + 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308, + 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x3b08, 0x93b: 0x3308, + 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040, + // Block 0x25, offset 0x940 + 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008, + 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008, + 0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008, + 0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79, + 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008, + 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008, + 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9, + 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040, + 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59, + 0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308, + 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008, + // Block 0x26, offset 0x980 + 0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018, + 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008, + 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308, + 0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308, + 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11, + 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308, + 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308, + 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308, + 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308, + 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308, + 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008, + 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008, + 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008, + 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008, + 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008, + 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008, + 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008, + 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008, + 0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41, + 0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008, + 0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269, + // Block 0x28, offset 0xa00 + 0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1, + 0xa06: 0x05b5, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011, + 0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041, + 0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05cd, 0xa15: 0x05cd, 0xa16: 0x0f99, 0xa17: 0x0fa9, + 0xa18: 0x0fb9, 0xa19: 0x05b5, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05e5, 0xa1d: 0x1099, + 0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269, + 0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1, + 0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008, + 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008, + 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008, + 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008, + // Block 0x29, offset 0xa40 + 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008, + 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008, + 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008, + 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008, + 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169, + 0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9, + 0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05fd, 0xa68: 0x1239, 0xa69: 0x1251, + 0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9, + 0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359, + 0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x0615, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1, + 0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429, + // Block 0x2a, offset 0xa80 + 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008, + 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008, + 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008, + 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008, + 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008, + 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008, + 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008, + 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008, + 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008, + 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008, + 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008, + // Block 0x2b, offset 0xac0 + 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008, + 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008, + 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008, + 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008, + 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x062d, 0xadb: 0x064d, 0xadc: 0x0008, 0xadd: 0x0008, + 0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008, + 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008, + 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008, + 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008, + 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008, + 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008, + // Block 0x2c, offset 0xb00 + 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008, + 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045, + 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008, + 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008, + 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045, + 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008, + 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045, + 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045, + 0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489, + 0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1, + 0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040, + // Block 0x2d, offset 0xb40 + 0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1, + 0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591, + 0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1, + 0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1, + 0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771, + 0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891, + 0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831, + 0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951, + 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040, + 0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x0665, 0xb7b: 0x1459, + 0xb7c: 0x19b1, 0xb7d: 0x067e, 0xb7e: 0x1a31, 0xb7f: 0x069e, + // Block 0x2e, offset 0xb80 + 0xb80: 0x06be, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040, + 0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06dd, 0xb89: 0x1471, 0xb8a: 0x06f5, 0xb8b: 0x1489, + 0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008, + 0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008, + 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x070d, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2, + 0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61, + 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045, + 0xbaa: 0x0725, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa, + 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040, + 0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x073d, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9, + 0xbbc: 0x1ce9, 0xbbd: 0x0756, 0xbbe: 0x0776, 0xbbf: 0x0040, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a, + 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0, + 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d, + 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x0796, + 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018, + 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018, + 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040, + 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a, + 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018, + 0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018, + 0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x07b6, 0xbff: 0x0018, + // Block 0x30, offset 0xc00 + 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018, + 0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018, + 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018, + 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9, + 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018, + 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340, + 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040, + 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340, + 0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61, + 0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07d5, + 0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71, + // Block 0x31, offset 0xc40 + 0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61, + 0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07ed, + 0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09, + 0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359, + 0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040, + 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018, + 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018, + 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018, + 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018, + 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018, + 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018, + // Block 0x32, offset 0xc80 + 0xc80: 0x0806, 0xc81: 0x0826, 0xc82: 0x1159, 0xc83: 0x0845, 0xc84: 0x0018, 0xc85: 0x0866, + 0xc86: 0x0886, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x08a5, 0xc8a: 0x0f31, 0xc8b: 0x0249, + 0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41, + 0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018, + 0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269, + 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08c5, 0xca2: 0x2061, 0xca3: 0x0018, + 0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018, + 0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09, + 0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9, + 0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08e5, + 0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x0905, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9, + 0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018, + 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151, + 0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279, + 0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399, + 0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x091d, 0xce3: 0x2439, + 0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x093d, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369, + 0xcea: 0x24a9, 0xceb: 0x095d, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61, + 0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x097d, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451, + 0xcf6: 0x099d, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09bd, + 0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61, + // Block 0x34, offset 0xd00 + 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018, + 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040, + 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040, + 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040, + 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040, + 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51, + 0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601, + 0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691, + 0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a1e, 0xd35: 0x0a3e, + 0xd36: 0x0a5e, 0xd37: 0x0a7e, 0xd38: 0x0a9e, 0xd39: 0x0abe, 0xd3a: 0x0ade, 0xd3b: 0x0afe, + 0xd3c: 0x0b1e, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a, + // Block 0x35, offset 0xd40 + 0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a, + 0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040, + 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040, + 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040, + 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b3e, 0xd5d: 0x0b5e, + 0xd5e: 0x0b7e, 0xd5f: 0x0b9e, 0xd60: 0x0bbe, 0xd61: 0x0bde, 0xd62: 0x0bfe, 0xd63: 0x0c1e, + 0xd64: 0x0c3e, 0xd65: 0x0c5e, 0xd66: 0x0c7e, 0xd67: 0x0c9e, 0xd68: 0x0cbe, 0xd69: 0x0cde, + 0xd6a: 0x0cfe, 0xd6b: 0x0d1e, 0xd6c: 0x0d3e, 0xd6d: 0x0d5e, 0xd6e: 0x0d7e, 0xd6f: 0x0d9e, + 0xd70: 0x0dbe, 0xd71: 0x0dde, 0xd72: 0x0dfe, 0xd73: 0x0e1e, 0xd74: 0x0e3e, 0xd75: 0x0e5e, + 0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199, + 0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259, + // Block 0x36, offset 0xd80 + 0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99, + 0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089, + 0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9, + 0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249, + 0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71, + 0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9, + 0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1, + 0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018, + 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018, + 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018, + 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008, + 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008, + 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008, + 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008, + 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008, + 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ed5, + 0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d, + 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9, + 0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d, + 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008, + 0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9, + // Block 0x38, offset 0xe00 + 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008, + 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008, + 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008, + 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008, + 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008, + 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008, + 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018, + 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308, + 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040, + 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018, + 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018, + // Block 0x39, offset 0xe40 + 0xe40: 0x2715, 0xe41: 0x2735, 0xe42: 0x2755, 0xe43: 0x2775, 0xe44: 0x2795, 0xe45: 0x27b5, + 0xe46: 0x27d5, 0xe47: 0x27f5, 0xe48: 0x2815, 0xe49: 0x2835, 0xe4a: 0x2855, 0xe4b: 0x2875, + 0xe4c: 0x2895, 0xe4d: 0x28b5, 0xe4e: 0x28d5, 0xe4f: 0x28f5, 0xe50: 0x2915, 0xe51: 0x2935, + 0xe52: 0x2955, 0xe53: 0x2975, 0xe54: 0x2995, 0xe55: 0x29b5, 0xe56: 0x0040, 0xe57: 0x0040, + 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040, + 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040, + 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040, + 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040, + 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040, + 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040, + 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040, + // Block 0x3a, offset 0xe80 + 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008, + 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018, + 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018, + 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018, + 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018, + 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018, + 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018, + 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018, + 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018, + 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29d5, 0xeb9: 0x29f5, 0xeba: 0x2a15, 0xebb: 0x0018, + 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018, + // Block 0x3b, offset 0xec0 + 0xec0: 0x2b55, 0xec1: 0x2b75, 0xec2: 0x2b95, 0xec3: 0x2bb5, 0xec4: 0x2bd5, 0xec5: 0x2bf5, + 0xec6: 0x2bf5, 0xec7: 0x2bf5, 0xec8: 0x2c15, 0xec9: 0x2c15, 0xeca: 0x2c15, 0xecb: 0x2c15, + 0xecc: 0x2c35, 0xecd: 0x2c35, 0xece: 0x2c35, 0xecf: 0x2c55, 0xed0: 0x2c75, 0xed1: 0x2c75, + 0xed2: 0x2a95, 0xed3: 0x2a95, 0xed4: 0x2c75, 0xed5: 0x2c75, 0xed6: 0x2c95, 0xed7: 0x2c95, + 0xed8: 0x2c75, 0xed9: 0x2c75, 0xeda: 0x2a95, 0xedb: 0x2a95, 0xedc: 0x2c75, 0xedd: 0x2c75, + 0xede: 0x2c55, 0xedf: 0x2c55, 0xee0: 0x2cb5, 0xee1: 0x2cb5, 0xee2: 0x2cd5, 0xee3: 0x2cd5, + 0xee4: 0x0040, 0xee5: 0x2cf5, 0xee6: 0x2d15, 0xee7: 0x2d35, 0xee8: 0x2d35, 0xee9: 0x2d55, + 0xeea: 0x2d75, 0xeeb: 0x2d95, 0xeec: 0x2db5, 0xeed: 0x2dd5, 0xeee: 0x2df5, 0xeef: 0x2e15, + 0xef0: 0x2e35, 0xef1: 0x2e55, 0xef2: 0x2e55, 0xef3: 0x2e75, 0xef4: 0x2e95, 0xef5: 0x2e95, + 0xef6: 0x2eb5, 0xef7: 0x2ed5, 0xef8: 0x2e75, 0xef9: 0x2ef5, 0xefa: 0x2f15, 0xefb: 0x2ef5, + 0xefc: 0x2e75, 0xefd: 0x2f35, 0xefe: 0x2f55, 0xeff: 0x2f75, + // Block 0x3c, offset 0xf00 + 0xf00: 0x2f95, 0xf01: 0x2fb5, 0xf02: 0x2d15, 0xf03: 0x2cf5, 0xf04: 0x2fd5, 0xf05: 0x2ff5, + 0xf06: 0x3015, 0xf07: 0x3035, 0xf08: 0x3055, 0xf09: 0x3075, 0xf0a: 0x3095, 0xf0b: 0x30b5, + 0xf0c: 0x30d5, 0xf0d: 0x30f5, 0xf0e: 0x3115, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018, + 0xf12: 0x3135, 0xf13: 0x3155, 0xf14: 0x3175, 0xf15: 0x3195, 0xf16: 0x31b5, 0xf17: 0x31d5, + 0xf18: 0x31f5, 0xf19: 0x3215, 0xf1a: 0x3235, 0xf1b: 0x3255, 0xf1c: 0x3175, 0xf1d: 0x3275, + 0xf1e: 0x3295, 0xf1f: 0x32b5, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008, + 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008, + 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008, + 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008, + 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040, + 0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040, + // Block 0x3d, offset 0xf40 + 0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32d5, 0xf45: 0x32f5, + 0xf46: 0x3315, 0xf47: 0x3335, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018, + 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x3355, 0xf51: 0x3761, + 0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1, + 0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881, + 0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x3375, 0xf61: 0x3395, 0xf62: 0x33b5, 0xf63: 0x33d5, + 0xf64: 0x33f5, 0xf65: 0x33f5, 0xf66: 0x3415, 0xf67: 0x3435, 0xf68: 0x3455, 0xf69: 0x3475, + 0xf6a: 0x3495, 0xf6b: 0x34b5, 0xf6c: 0x34d5, 0xf6d: 0x34f5, 0xf6e: 0x3515, 0xf6f: 0x3535, + 0xf70: 0x3555, 0xf71: 0x3575, 0xf72: 0x3595, 0xf73: 0x35b5, 0xf74: 0x35d5, 0xf75: 0x35f5, + 0xf76: 0x3615, 0xf77: 0x3635, 0xf78: 0x3655, 0xf79: 0x3675, 0xf7a: 0x3695, 0xf7b: 0x36b5, + 0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36d5, 0xf7f: 0x0018, + // Block 0x3e, offset 0xf80 + 0xf80: 0x36f5, 0xf81: 0x3715, 0xf82: 0x3735, 0xf83: 0x3755, 0xf84: 0x3775, 0xf85: 0x3795, + 0xf86: 0x37b5, 0xf87: 0x37d5, 0xf88: 0x37f5, 0xf89: 0x3815, 0xf8a: 0x3835, 0xf8b: 0x3855, + 0xf8c: 0x3875, 0xf8d: 0x3895, 0xf8e: 0x38b5, 0xf8f: 0x38d5, 0xf90: 0x38f5, 0xf91: 0x3915, + 0xf92: 0x3935, 0xf93: 0x3955, 0xf94: 0x3975, 0xf95: 0x3995, 0xf96: 0x39b5, 0xf97: 0x39d5, + 0xf98: 0x39f5, 0xf99: 0x3a15, 0xf9a: 0x3a35, 0xf9b: 0x3a55, 0xf9c: 0x3a75, 0xf9d: 0x3a95, + 0xf9e: 0x3ab5, 0xf9f: 0x3ad5, 0xfa0: 0x3af5, 0xfa1: 0x3b15, 0xfa2: 0x3b35, 0xfa3: 0x3b55, + 0xfa4: 0x3b75, 0xfa5: 0x3b95, 0xfa6: 0x1295, 0xfa7: 0x3bb5, 0xfa8: 0x3bd5, 0xfa9: 0x3bf5, + 0xfaa: 0x3c15, 0xfab: 0x3c35, 0xfac: 0x3c55, 0xfad: 0x3c75, 0xfae: 0x23b5, 0xfaf: 0x3c95, + 0xfb0: 0x3cb5, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999, + 0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29, + 0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69, + 0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69, + 0xfcc: 0x3c99, 0xfcd: 0x3cd5, 0xfce: 0x3cb1, 0xfcf: 0x3cf5, 0xfd0: 0x3d15, 0xfd1: 0x3d2d, + 0xfd2: 0x3d45, 0xfd3: 0x3d5d, 0xfd4: 0x3d75, 0xfd5: 0x3d75, 0xfd6: 0x3d5d, 0xfd7: 0x3d8d, + 0xfd8: 0x07d5, 0xfd9: 0x3da5, 0xfda: 0x3dbd, 0xfdb: 0x3dd5, 0xfdc: 0x3ded, 0xfdd: 0x3e05, + 0xfde: 0x3e1d, 0xfdf: 0x3e35, 0xfe0: 0x3e4d, 0xfe1: 0x3e65, 0xfe2: 0x3e7d, 0xfe3: 0x3e95, + 0xfe4: 0x3ead, 0xfe5: 0x3ead, 0xfe6: 0x3ec5, 0xfe7: 0x3ec5, 0xfe8: 0x3edd, 0xfe9: 0x3edd, + 0xfea: 0x3ef5, 0xfeb: 0x3f0d, 0xfec: 0x3f25, 0xfed: 0x3f3d, 0xfee: 0x3f55, 0xfef: 0x3f55, + 0xff0: 0x3f6d, 0xff1: 0x3f6d, 0xff2: 0x3f6d, 0xff3: 0x3f85, 0xff4: 0x3f9d, 0xff5: 0x3fb5, + 0xff6: 0x3fcd, 0xff7: 0x3fb5, 0xff8: 0x3fe5, 0xff9: 0x3ffd, 0xffa: 0x3f85, 0xffb: 0x4015, + 0xffc: 0x402d, 0xffd: 0x402d, 0xffe: 0x402d, 0xfff: 0x0040, + // Block 0x40, offset 0x1000 + 0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9, + 0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1, + 0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9, + 0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549, + 0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1, + 0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11, + 0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91, + 0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9, + 0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011, + 0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209, + 0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361, + // Block 0x41, offset 0x1040 + 0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541, + 0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781, + 0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979, + 0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89, + 0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1, + 0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99, + 0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9, + 0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9, + 0x1070: 0x6009, 0x1071: 0x4045, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x4065, 0x1075: 0x6069, + 0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x4085, 0x1079: 0x4085, 0x107a: 0x60b1, 0x107b: 0x60c9, + 0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9, + // Block 0x42, offset 0x1080 + 0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x40a5, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271, + 0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40c5, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9, + 0x108c: 0x40e5, 0x108d: 0x40e5, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x4105, + 0x1092: 0x4125, 0x1093: 0x4145, 0x1094: 0x4165, 0x1095: 0x4185, 0x1096: 0x6359, 0x1097: 0x6371, + 0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x41a5, 0x109c: 0x63d1, 0x109d: 0x63e9, + 0x109e: 0x6401, 0x109f: 0x41c5, 0x10a0: 0x41e5, 0x10a1: 0x6419, 0x10a2: 0x4205, 0x10a3: 0x4225, + 0x10a4: 0x4245, 0x10a5: 0x6431, 0x10a6: 0x4265, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211, + 0x10aa: 0x4285, 0x10ab: 0x42a5, 0x10ac: 0x42c5, 0x10ad: 0x42e5, 0x10ae: 0x64b1, 0x10af: 0x64f1, + 0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x4305, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599, + 0x10b6: 0x4325, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9, + 0x10bc: 0x4345, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x4365, 0x10c1: 0x4385, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671, + 0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709, + 0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781, + 0x10d2: 0x43a5, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43c5, 0x10d6: 0x43e5, 0x10d7: 0x67b1, + 0x10d8: 0x0040, 0x10d9: 0x4405, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811, + 0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901, + 0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1, + 0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11, + 0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31, + 0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51, + 0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x4425, + // Block 0x44, offset 0x1100 + 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008, + 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008, + 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008, + 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008, + 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008, + 0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008, + 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008, + 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308, + 0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308, + 0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308, + 0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008, + // Block 0x45, offset 0x1140 + 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008, + 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008, + 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008, + 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008, + 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11, + 0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008, + 0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008, + 0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008, + 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008, + 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008, + 0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008, + // Block 0x46, offset 0x1180 + 0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018, + 0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018, + 0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018, + 0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008, + 0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008, + 0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008, + 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008, + 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008, + 0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008, + 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008, + 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008, + // Block 0x47, offset 0x11c0 + 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008, + 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008, + 0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008, + 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008, + 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008, + 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008, + 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008, + 0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008, + 0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008, + 0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d, + 0x11fc: 0x0008, 0x11fd: 0x4445, 0x11fe: 0xe00d, 0x11ff: 0x0008, + // Block 0x48, offset 0x1200 + 0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008, + 0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d, + 0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008, + 0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008, + 0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008, + 0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008, + 0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008, + 0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0008, + 0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x4465, 0x1234: 0xe00d, 0x1235: 0x0008, + 0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0xe00d, 0x1239: 0x0008, 0x123a: 0xe00d, 0x123b: 0x0008, + 0x123c: 0xe00d, 0x123d: 0x0008, 0x123e: 0xe00d, 0x123f: 0x0008, + // Block 0x49, offset 0x1240 + 0x1240: 0x650d, 0x1241: 0x652d, 0x1242: 0x654d, 0x1243: 0x656d, 0x1244: 0x658d, 0x1245: 0x65ad, + 0x1246: 0x65cd, 0x1247: 0x65ed, 0x1248: 0x660d, 0x1249: 0x662d, 0x124a: 0x664d, 0x124b: 0x666d, + 0x124c: 0x668d, 0x124d: 0x66ad, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x66cd, 0x1251: 0x0008, + 0x1252: 0x66ed, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x670d, 0x1256: 0x672d, 0x1257: 0x674d, + 0x1258: 0x676d, 0x1259: 0x678d, 0x125a: 0x67ad, 0x125b: 0x67cd, 0x125c: 0x67ed, 0x125d: 0x680d, + 0x125e: 0x682d, 0x125f: 0x0008, 0x1260: 0x684d, 0x1261: 0x0008, 0x1262: 0x686d, 0x1263: 0x0008, + 0x1264: 0x0008, 0x1265: 0x688d, 0x1266: 0x68ad, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008, + 0x126a: 0x68cd, 0x126b: 0x68ed, 0x126c: 0x690d, 0x126d: 0x692d, 0x126e: 0x694d, 0x126f: 0x696d, + 0x1270: 0x698d, 0x1271: 0x69ad, 0x1272: 0x69cd, 0x1273: 0x69ed, 0x1274: 0x6a0d, 0x1275: 0x6a2d, + 0x1276: 0x6a4d, 0x1277: 0x6a6d, 0x1278: 0x6a8d, 0x1279: 0x6aad, 0x127a: 0x6acd, 0x127b: 0x6aed, + 0x127c: 0x6b0d, 0x127d: 0x6b2d, 0x127e: 0x6b4d, 0x127f: 0x6b6d, + // Block 0x4a, offset 0x1280 + 0x1280: 0x7acd, 0x1281: 0x7aed, 0x1282: 0x7b0d, 0x1283: 0x7b2d, 0x1284: 0x7b4d, 0x1285: 0x7b6d, + 0x1286: 0x7b8d, 0x1287: 0x7bad, 0x1288: 0x7bcd, 0x1289: 0x7bed, 0x128a: 0x7c0d, 0x128b: 0x7c2d, + 0x128c: 0x7c4d, 0x128d: 0x7c6d, 0x128e: 0x7c8d, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19, + 0x1292: 0x7cad, 0x1293: 0x7ccd, 0x1294: 0x7ced, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91, + 0x1298: 0x7d0d, 0x1299: 0x7d2d, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040, + 0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040, + 0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040, + 0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040, + 0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040, + 0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040, + 0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d4d, 0x12c4: 0x7d6d, 0x12c5: 0x7001, + 0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040, + 0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040, + 0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9, + 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1, + 0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149, + 0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2, + 0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1, + 0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1, + 0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479, + 0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040, + // Block 0x4c, offset 0x1300 + 0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040, + 0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659, + 0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721, + 0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751, + 0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769, + 0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799, + 0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1, + 0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1, + 0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9, + 0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829, + 0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841, + // Block 0x4d, offset 0x1340 + 0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871, + 0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9, + 0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9, + 0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919, + 0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931, + 0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961, + 0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991, + 0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1, + 0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818, + 0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818, + 0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040, + 0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040, + 0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040, + 0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09, + 0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479, + 0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81, + 0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1, + 0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19, + 0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91, + 0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1, + 0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1, + 0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1, + 0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1, + 0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991, + 0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81, + 0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a, + 0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99, + 0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89, + 0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79, + 0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19, + 0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469, + // Block 0x50, offset 0x1400 + 0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649, + 0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9, + 0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49, + 0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21, + 0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9, + 0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01, + 0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91, + 0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9, + 0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171, + 0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289, + 0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329, + // Block 0x51, offset 0x1440 + 0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1, + 0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621, + 0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739, + 0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1, + 0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9, + 0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29, + 0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079, + 0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1, + 0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171, + 0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261, + 0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301, + // Block 0x52, offset 0x1480 + 0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1, + 0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1, + 0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171, + 0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261, + 0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351, + 0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441, + 0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509, + 0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1, + 0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081, + 0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239, + 0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040, + 0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040, + 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609, + 0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721, + 0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839, + 0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919, + 0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9, + 0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9, + 0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9, + 0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1, + 0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79, + // Block 0x54, offset 0x1500 + 0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989, + 0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040, + 0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040, + 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040, + 0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040, + 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040, + 0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040, + 0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040, + 0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9, + 0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12, + 0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040, + // Block 0x55, offset 0x1540 + 0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0, + 0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0, + 0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d8d, + 0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7dad, + 0x1558: 0x7dcd, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040, + 0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308, + 0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308, + 0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308, + 0x1570: 0x0040, 0x1571: 0x7ded, 0x1572: 0x7e0d, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2, + 0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7e2d, 0x157a: 0x7e4d, 0x157b: 0x7e6d, + 0x157c: 0x7e2d, 0x157d: 0x7e8d, 0x157e: 0x7ead, 0x157f: 0x7e8d, + // Block 0x56, offset 0x1580 + 0x1580: 0x7ecd, 0x1581: 0x7eed, 0x1582: 0x7f0d, 0x1583: 0x7eed, 0x1584: 0x7f2d, 0x1585: 0x0018, + 0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f4e, 0x158a: 0x7f6e, 0x158b: 0x7f8e, + 0x158c: 0x7fae, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7fcd, + 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa, + 0x1598: 0x7fed, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7ecd, + 0x159e: 0x7f2d, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99, + 0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda, + 0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040, + 0x15b0: 0x800e, 0x15b1: 0xb009, 0x15b2: 0x802e, 0x15b3: 0x0808, 0x15b4: 0x804e, 0x15b5: 0x0040, + 0x15b6: 0x806e, 0x15b7: 0xb031, 0x15b8: 0x808e, 0x15b9: 0xb059, 0x15ba: 0x80ae, 0x15bb: 0xb081, + 0x15bc: 0x80ce, 0x15bd: 0xb0a9, 0x15be: 0x80ee, 0x15bf: 0xb0d1, + // Block 0x57, offset 0x15c0 + 0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141, + 0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171, + 0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1, + 0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1, + 0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201, + 0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219, + 0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249, + 0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291, + 0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1, + 0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9, + 0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1, + // Block 0x58, offset 0x1600 + 0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321, + 0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339, + 0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369, + 0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381, + 0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1, + 0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9, + 0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9, + 0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1, + 0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441, + 0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9, + 0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea, + 0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2, + 0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9, + 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81, + 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2, + 0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159, + 0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41, + 0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9, + 0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9, + 0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a, + 0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09, + 0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51, + 0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039, + 0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279, + 0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a, + 0x169e: 0xb532, 0x169f: 0x810d, 0x16a0: 0x812d, 0x16a1: 0x29d1, 0x16a2: 0x814d, 0x16a3: 0x814d, + 0x16a4: 0x816d, 0x16a5: 0x818d, 0x16a6: 0x81ad, 0x16a7: 0x81cd, 0x16a8: 0x81ed, 0x16a9: 0x820d, + 0x16aa: 0x822d, 0x16ab: 0x824d, 0x16ac: 0x826d, 0x16ad: 0x828d, 0x16ae: 0x82ad, 0x16af: 0x82cd, + 0x16b0: 0x82ed, 0x16b1: 0x830d, 0x16b2: 0x832d, 0x16b3: 0x834d, 0x16b4: 0x836d, 0x16b5: 0x838d, + 0x16b6: 0x83ad, 0x16b7: 0x83cd, 0x16b8: 0x83ed, 0x16b9: 0x840d, 0x16ba: 0x842d, 0x16bb: 0x844d, + 0x16bc: 0x81ed, 0x16bd: 0x846d, 0x16be: 0x848d, 0x16bf: 0x824d, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x84ad, 0x16c1: 0x84cd, 0x16c2: 0x84ed, 0x16c3: 0x850d, 0x16c4: 0x852d, 0x16c5: 0x854d, + 0x16c6: 0x856d, 0x16c7: 0x858d, 0x16c8: 0x850d, 0x16c9: 0x85ad, 0x16ca: 0x850d, 0x16cb: 0x85cd, + 0x16cc: 0x85cd, 0x16cd: 0x85ed, 0x16ce: 0x85ed, 0x16cf: 0x860d, 0x16d0: 0x854d, 0x16d1: 0x862d, + 0x16d2: 0x864d, 0x16d3: 0x862d, 0x16d4: 0x866d, 0x16d5: 0x864d, 0x16d6: 0x868d, 0x16d7: 0x868d, + 0x16d8: 0x86ad, 0x16d9: 0x86ad, 0x16da: 0x86cd, 0x16db: 0x86cd, 0x16dc: 0x864d, 0x16dd: 0x814d, + 0x16de: 0x86ed, 0x16df: 0x870d, 0x16e0: 0x0040, 0x16e1: 0x872d, 0x16e2: 0x874d, 0x16e3: 0x876d, + 0x16e4: 0x878d, 0x16e5: 0x876d, 0x16e6: 0x87ad, 0x16e7: 0x87cd, 0x16e8: 0x87ed, 0x16e9: 0x87ed, + 0x16ea: 0x880d, 0x16eb: 0x880d, 0x16ec: 0x882d, 0x16ed: 0x882d, 0x16ee: 0x880d, 0x16ef: 0x880d, + 0x16f0: 0x884d, 0x16f1: 0x886d, 0x16f2: 0x888d, 0x16f3: 0x88ad, 0x16f4: 0x88cd, 0x16f5: 0x88ed, + 0x16f6: 0x88ed, 0x16f7: 0x88ed, 0x16f8: 0x890d, 0x16f9: 0x890d, 0x16fa: 0x890d, 0x16fb: 0x890d, + 0x16fc: 0x87ed, 0x16fd: 0x87ed, 0x16fe: 0x87ed, 0x16ff: 0x0040, + // Block 0x5c, offset 0x1700 + 0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x874d, 0x1703: 0x872d, 0x1704: 0x892d, 0x1705: 0x872d, + 0x1706: 0x874d, 0x1707: 0x872d, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x894d, 0x170b: 0x874d, + 0x170c: 0x896d, 0x170d: 0x892d, 0x170e: 0x896d, 0x170f: 0x874d, 0x1710: 0x0040, 0x1711: 0x0040, + 0x1712: 0x898d, 0x1713: 0x89ad, 0x1714: 0x88ad, 0x1715: 0x896d, 0x1716: 0x892d, 0x1717: 0x896d, + 0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x89cd, 0x171b: 0x89ed, 0x171c: 0x89cd, 0x171d: 0x0040, + 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x8a0e, + 0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x8a2d, 0x1727: 0x0040, 0x1728: 0x8a4d, 0x1729: 0x8a6d, + 0x172a: 0x8a8d, 0x172b: 0x8a6d, 0x172c: 0x8aad, 0x172d: 0x8acd, 0x172e: 0x8aed, 0x172f: 0x0040, + 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040, + 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340, + 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040, + // Block 0x5d, offset 0x1740 + 0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08, + 0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808, + 0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08, + 0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908, + 0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08, + 0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808, + 0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040, + 0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18, + 0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818, + 0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040, + 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040, + // Block 0x5e, offset 0x1780 + 0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08, + 0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08, + 0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08, + 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040, + 0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040, + 0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040, + 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18, + 0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818, + 0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040, + 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040, + 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008, + 0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008, + 0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040, + 0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008, + 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008, + 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008, + 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040, + 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008, + 0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008, + 0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x3308, + 0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008, + // Block 0x60, offset 0x1800 + 0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040, + 0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008, + 0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040, + 0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008, + 0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008, + 0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008, + 0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308, + 0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040, + 0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040, + 0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040, + 0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040, + // Block 0x61, offset 0x1840 + 0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199, + 0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359, + 0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269, + 0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369, + 0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9, + 0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259, + 0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99, + 0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089, + 0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9, + 0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249, + 0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359, + // Block 0x62, offset 0x1880 + 0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269, + 0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369, + 0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9, + 0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259, + 0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99, + 0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089, + 0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9, + 0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249, + 0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71, + 0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9, + 0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9, + 0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259, + 0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99, + 0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089, + 0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040, + 0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040, + 0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71, + 0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9, + 0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1, + 0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199, + 0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259, + // Block 0x64, offset 0x1900 + 0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99, + 0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089, + 0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9, + 0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249, + 0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71, + 0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9, + 0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1, + 0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199, + 0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359, + 0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269, + 0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089, + // Block 0x65, offset 0x1940 + 0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9, + 0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040, + 0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71, + 0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9, + 0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040, + 0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199, + 0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359, + 0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269, + 0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369, + 0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9, + 0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040, + // Block 0x66, offset 0x1980 + 0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040, + 0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9, + 0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040, + 0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199, + 0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359, + 0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269, + 0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369, + 0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9, + 0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259, + 0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99, + 0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1, + 0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199, + 0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359, + 0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269, + 0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369, + 0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9, + 0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259, + 0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99, + 0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089, + 0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9, + 0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359, + 0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269, + 0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369, + 0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9, + 0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259, + 0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99, + 0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089, + 0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9, + 0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249, + 0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71, + 0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369, + 0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9, + 0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259, + 0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99, + 0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089, + 0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9, + 0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249, + 0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71, + 0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9, + 0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1, + 0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259, + 0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99, + 0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089, + 0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9, + 0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249, + 0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71, + 0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9, + 0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1, + 0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199, + 0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359, + 0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089, + 0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9, + 0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249, + 0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71, + 0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9, + 0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1, + 0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099, + 0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429, + 0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71, + 0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9, + 0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9, + 0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11, + 0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109, + 0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1, + 0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429, + 0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099, + 0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429, + 0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71, + 0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9, + 0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01, + 0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11, + 0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109, + 0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1, + 0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429, + 0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099, + 0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429, + 0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71, + 0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9, + 0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01, + 0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1, + 0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109, + 0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1, + 0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429, + 0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099, + 0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429, + 0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71, + 0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9, + 0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01, + 0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1, + 0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41, + 0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1, + 0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429, + 0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099, + 0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429, + 0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71, + 0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9, + 0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01, + 0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1, + 0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41, + 0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1, + 0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429, + 0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41, + 0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079, + 0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1, + 0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61, + 0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9, + 0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81, + 0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079, + 0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1, + 0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61, + 0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1, + // Block 0x71, offset 0x1c40 + 0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115, + 0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135, + 0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115, + 0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175, + 0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115, + 0x1c5e: 0x8b3d, 0x1c5f: 0x8b3d, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08, + 0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08, + 0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08, + 0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08, + 0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08, + 0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08, + // Block 0x72, offset 0x1c80 + 0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411, + 0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1, + 0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9, + 0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231, + 0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949, + 0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040, + 0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429, + 0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339, + 0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1, + 0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351, + 0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040, + 0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1, + 0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9, + 0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231, + 0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949, + 0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040, + 0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429, + 0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339, + 0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1, + 0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351, + 0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040, + // Block 0x74, offset 0x1d00 + 0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411, + 0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1, + 0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9, + 0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231, + 0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040, + 0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249, + 0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429, + 0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339, + 0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1, + 0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351, + 0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02, + 0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018, + 0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2, + 0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72, + 0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32, + 0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2, + 0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2, + 0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0018, + 0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199, + 0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359, + 0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089, + 0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1, + 0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018, + 0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018, + 0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018, + 0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018, + 0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018, + 0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0xc1c1, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040, + 0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018, + 0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018, + 0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0xc1f1, 0x1dc1: 0xc229, 0x1dc2: 0xc261, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040, + 0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040, + 0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc281, 0x1dd1: 0xc2a1, + 0x1dd2: 0xc2c1, 0x1dd3: 0xc2e1, 0x1dd4: 0xc301, 0x1dd5: 0xc321, 0x1dd6: 0xc341, 0x1dd7: 0xc361, + 0x1dd8: 0xc381, 0x1dd9: 0xc3a1, 0x1dda: 0xc3c1, 0x1ddb: 0xc3e1, 0x1ddc: 0xc401, 0x1ddd: 0xc421, + 0x1dde: 0xc441, 0x1ddf: 0xc461, 0x1de0: 0xc481, 0x1de1: 0xc4a1, 0x1de2: 0xc4c1, 0x1de3: 0xc4e1, + 0x1de4: 0xc501, 0x1de5: 0xc521, 0x1de6: 0xc541, 0x1de7: 0xc561, 0x1de8: 0xc581, 0x1de9: 0xc5a1, + 0x1dea: 0xc5c1, 0x1deb: 0xc5e1, 0x1dec: 0xc601, 0x1ded: 0xc621, 0x1dee: 0xc641, 0x1def: 0xc661, + 0x1df0: 0xc681, 0x1df1: 0xc6a1, 0x1df2: 0xc6c1, 0x1df3: 0xc6e1, 0x1df4: 0xc701, 0x1df5: 0xc721, + 0x1df6: 0xc741, 0x1df7: 0xc761, 0x1df8: 0xc781, 0x1df9: 0xc7a1, 0x1dfa: 0xc7c1, 0x1dfb: 0xc7e1, + 0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040, + // Block 0x78, offset 0x1e00 + 0x1e00: 0xcb11, 0x1e01: 0xcb31, 0x1e02: 0xcb51, 0x1e03: 0x8b55, 0x1e04: 0xcb71, 0x1e05: 0xcb91, + 0x1e06: 0xcbb1, 0x1e07: 0xcbd1, 0x1e08: 0xcbf1, 0x1e09: 0xcc11, 0x1e0a: 0xcc31, 0x1e0b: 0xcc51, + 0x1e0c: 0xcc71, 0x1e0d: 0x8b75, 0x1e0e: 0xcc91, 0x1e0f: 0xccb1, 0x1e10: 0xccd1, 0x1e11: 0xccf1, + 0x1e12: 0x8b95, 0x1e13: 0xcd11, 0x1e14: 0xcd31, 0x1e15: 0xc441, 0x1e16: 0x8bb5, 0x1e17: 0xcd51, + 0x1e18: 0xcd71, 0x1e19: 0xcd91, 0x1e1a: 0xcdb1, 0x1e1b: 0xcdd1, 0x1e1c: 0x8bd5, 0x1e1d: 0xcdf1, + 0x1e1e: 0xce11, 0x1e1f: 0xce31, 0x1e20: 0xce51, 0x1e21: 0xce71, 0x1e22: 0xc7a1, 0x1e23: 0xce91, + 0x1e24: 0xceb1, 0x1e25: 0xced1, 0x1e26: 0xcef1, 0x1e27: 0xcf11, 0x1e28: 0xcf31, 0x1e29: 0xcf51, + 0x1e2a: 0xcf71, 0x1e2b: 0xcf91, 0x1e2c: 0xcfb1, 0x1e2d: 0xcfd1, 0x1e2e: 0xcff1, 0x1e2f: 0xd011, + 0x1e30: 0xd031, 0x1e31: 0xd051, 0x1e32: 0xd051, 0x1e33: 0xd051, 0x1e34: 0x8bf5, 0x1e35: 0xd071, + 0x1e36: 0xd091, 0x1e37: 0xd0b1, 0x1e38: 0x8c15, 0x1e39: 0xd0d1, 0x1e3a: 0xd0f1, 0x1e3b: 0xd111, + 0x1e3c: 0xd131, 0x1e3d: 0xd151, 0x1e3e: 0xd171, 0x1e3f: 0xd191, + // Block 0x79, offset 0x1e40 + 0x1e40: 0xd1b1, 0x1e41: 0xd1d1, 0x1e42: 0xd1f1, 0x1e43: 0xd211, 0x1e44: 0xd231, 0x1e45: 0xd251, + 0x1e46: 0xd251, 0x1e47: 0xd271, 0x1e48: 0xd291, 0x1e49: 0xd2b1, 0x1e4a: 0xd2d1, 0x1e4b: 0xd2f1, + 0x1e4c: 0xd311, 0x1e4d: 0xd331, 0x1e4e: 0xd351, 0x1e4f: 0xd371, 0x1e50: 0xd391, 0x1e51: 0xd3b1, + 0x1e52: 0xd3d1, 0x1e53: 0xd3f1, 0x1e54: 0xd411, 0x1e55: 0xd431, 0x1e56: 0xd451, 0x1e57: 0xd471, + 0x1e58: 0xd491, 0x1e59: 0x8c35, 0x1e5a: 0xd4b1, 0x1e5b: 0xd4d1, 0x1e5c: 0xd4f1, 0x1e5d: 0xc321, + 0x1e5e: 0xd511, 0x1e5f: 0xd531, 0x1e60: 0x8c55, 0x1e61: 0x8c75, 0x1e62: 0xd551, 0x1e63: 0xd571, + 0x1e64: 0xd591, 0x1e65: 0xd5b1, 0x1e66: 0xd5d1, 0x1e67: 0xd5f1, 0x1e68: 0x2040, 0x1e69: 0xd611, + 0x1e6a: 0xd631, 0x1e6b: 0xd631, 0x1e6c: 0x8c95, 0x1e6d: 0xd651, 0x1e6e: 0xd671, 0x1e6f: 0xd691, + 0x1e70: 0xd6b1, 0x1e71: 0x8cb5, 0x1e72: 0xd6d1, 0x1e73: 0xd6f1, 0x1e74: 0x2040, 0x1e75: 0xd711, + 0x1e76: 0xd731, 0x1e77: 0xd751, 0x1e78: 0xd771, 0x1e79: 0xd791, 0x1e7a: 0xd7b1, 0x1e7b: 0x8cd5, + 0x1e7c: 0xd7d1, 0x1e7d: 0x8cf5, 0x1e7e: 0xd7f1, 0x1e7f: 0xd811, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0xd831, 0x1e81: 0xd851, 0x1e82: 0xd871, 0x1e83: 0xd891, 0x1e84: 0xd8b1, 0x1e85: 0xd8d1, + 0x1e86: 0xd8f1, 0x1e87: 0xd911, 0x1e88: 0xd931, 0x1e89: 0x8d15, 0x1e8a: 0xd951, 0x1e8b: 0xd971, + 0x1e8c: 0xd991, 0x1e8d: 0xd9b1, 0x1e8e: 0xd9d1, 0x1e8f: 0x8d35, 0x1e90: 0xd9f1, 0x1e91: 0x8d55, + 0x1e92: 0x8d75, 0x1e93: 0xda11, 0x1e94: 0xda31, 0x1e95: 0xda31, 0x1e96: 0xda51, 0x1e97: 0x8d95, + 0x1e98: 0x8db5, 0x1e99: 0xda71, 0x1e9a: 0xda91, 0x1e9b: 0xdab1, 0x1e9c: 0xdad1, 0x1e9d: 0xdaf1, + 0x1e9e: 0xdb11, 0x1e9f: 0xdb31, 0x1ea0: 0xdb51, 0x1ea1: 0xdb71, 0x1ea2: 0xdb91, 0x1ea3: 0xdbb1, + 0x1ea4: 0x8dd5, 0x1ea5: 0xdbd1, 0x1ea6: 0xdbf1, 0x1ea7: 0xdc11, 0x1ea8: 0xdc31, 0x1ea9: 0xdc11, + 0x1eaa: 0xdc51, 0x1eab: 0xdc71, 0x1eac: 0xdc91, 0x1ead: 0xdcb1, 0x1eae: 0xdcd1, 0x1eaf: 0xdcf1, + 0x1eb0: 0xdd11, 0x1eb1: 0xdd31, 0x1eb2: 0xdd51, 0x1eb3: 0xdd71, 0x1eb4: 0xdd91, 0x1eb5: 0xddb1, + 0x1eb6: 0xddd1, 0x1eb7: 0xddf1, 0x1eb8: 0x8df5, 0x1eb9: 0xde11, 0x1eba: 0xde31, 0x1ebb: 0xde51, + 0x1ebc: 0xde71, 0x1ebd: 0xde91, 0x1ebe: 0x8e15, 0x1ebf: 0xdeb1, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xe5b1, 0x1ec1: 0xe5d1, 0x1ec2: 0xe5f1, 0x1ec3: 0xe611, 0x1ec4: 0xe631, 0x1ec5: 0xe651, + 0x1ec6: 0x8f35, 0x1ec7: 0xe671, 0x1ec8: 0xe691, 0x1ec9: 0xe6b1, 0x1eca: 0xe6d1, 0x1ecb: 0xe6f1, + 0x1ecc: 0xe711, 0x1ecd: 0x8f55, 0x1ece: 0xe731, 0x1ecf: 0xe751, 0x1ed0: 0x8f75, 0x1ed1: 0x8f95, + 0x1ed2: 0xe771, 0x1ed3: 0xe791, 0x1ed4: 0xe7b1, 0x1ed5: 0xe7d1, 0x1ed6: 0xe7f1, 0x1ed7: 0xe811, + 0x1ed8: 0xe831, 0x1ed9: 0xe851, 0x1eda: 0xe871, 0x1edb: 0x8fb5, 0x1edc: 0xe891, 0x1edd: 0x8fd5, + 0x1ede: 0xe8b1, 0x1edf: 0x2040, 0x1ee0: 0xe8d1, 0x1ee1: 0xe8f1, 0x1ee2: 0xe911, 0x1ee3: 0x8ff5, + 0x1ee4: 0xe931, 0x1ee5: 0xe951, 0x1ee6: 0x9015, 0x1ee7: 0x9035, 0x1ee8: 0xe971, 0x1ee9: 0xe991, + 0x1eea: 0xe9b1, 0x1eeb: 0xe9d1, 0x1eec: 0xe9f1, 0x1eed: 0xe9f1, 0x1eee: 0xea11, 0x1eef: 0xea31, + 0x1ef0: 0xea51, 0x1ef1: 0xea71, 0x1ef2: 0xea91, 0x1ef3: 0xeab1, 0x1ef4: 0xead1, 0x1ef5: 0x9055, + 0x1ef6: 0xeaf1, 0x1ef7: 0x9075, 0x1ef8: 0xeb11, 0x1ef9: 0x9095, 0x1efa: 0xeb31, 0x1efb: 0x90b5, + 0x1efc: 0x90d5, 0x1efd: 0x90f5, 0x1efe: 0xeb51, 0x1eff: 0xeb71, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0xeb91, 0x1f01: 0x9115, 0x1f02: 0x9135, 0x1f03: 0x9155, 0x1f04: 0x9175, 0x1f05: 0xebb1, + 0x1f06: 0xebd1, 0x1f07: 0xebd1, 0x1f08: 0xebf1, 0x1f09: 0xec11, 0x1f0a: 0xec31, 0x1f0b: 0xec51, + 0x1f0c: 0xec71, 0x1f0d: 0x9195, 0x1f0e: 0xec91, 0x1f0f: 0xecb1, 0x1f10: 0xecd1, 0x1f11: 0xecf1, + 0x1f12: 0x91b5, 0x1f13: 0xed11, 0x1f14: 0x91d5, 0x1f15: 0x91f5, 0x1f16: 0xed31, 0x1f17: 0xed51, + 0x1f18: 0xed71, 0x1f19: 0xed91, 0x1f1a: 0xedb1, 0x1f1b: 0xedd1, 0x1f1c: 0x9215, 0x1f1d: 0x9235, + 0x1f1e: 0x9255, 0x1f1f: 0x2040, 0x1f20: 0xedf1, 0x1f21: 0x9275, 0x1f22: 0xee11, 0x1f23: 0xee31, + 0x1f24: 0xee51, 0x1f25: 0x9295, 0x1f26: 0xee71, 0x1f27: 0xee91, 0x1f28: 0xeeb1, 0x1f29: 0xeed1, + 0x1f2a: 0xeef1, 0x1f2b: 0x92b5, 0x1f2c: 0xef11, 0x1f2d: 0xef31, 0x1f2e: 0xef51, 0x1f2f: 0xef71, + 0x1f30: 0xef91, 0x1f31: 0xefb1, 0x1f32: 0x92d5, 0x1f33: 0x92f5, 0x1f34: 0xefd1, 0x1f35: 0x9315, + 0x1f36: 0xeff1, 0x1f37: 0x9335, 0x1f38: 0xf011, 0x1f39: 0xf031, 0x1f3a: 0xf051, 0x1f3b: 0x9355, + 0x1f3c: 0x9375, 0x1f3d: 0xf071, 0x1f3e: 0x9395, 0x1f3f: 0xf091, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xf6d1, 0x1f41: 0xf6f1, 0x1f42: 0xf711, 0x1f43: 0xf731, 0x1f44: 0xf751, 0x1f45: 0x9555, + 0x1f46: 0xf771, 0x1f47: 0xf791, 0x1f48: 0xf7b1, 0x1f49: 0xf7d1, 0x1f4a: 0xf7f1, 0x1f4b: 0x9575, + 0x1f4c: 0x9595, 0x1f4d: 0xf811, 0x1f4e: 0xf831, 0x1f4f: 0xf851, 0x1f50: 0xf871, 0x1f51: 0xf891, + 0x1f52: 0xf8b1, 0x1f53: 0x95b5, 0x1f54: 0xf8d1, 0x1f55: 0xf8f1, 0x1f56: 0xf911, 0x1f57: 0xf931, + 0x1f58: 0x95d5, 0x1f59: 0x95f5, 0x1f5a: 0xf951, 0x1f5b: 0xf971, 0x1f5c: 0xf991, 0x1f5d: 0x9615, + 0x1f5e: 0xf9b1, 0x1f5f: 0xf9d1, 0x1f60: 0x684d, 0x1f61: 0x9635, 0x1f62: 0xf9f1, 0x1f63: 0xfa11, + 0x1f64: 0xfa31, 0x1f65: 0x9655, 0x1f66: 0xfa51, 0x1f67: 0xfa71, 0x1f68: 0xfa91, 0x1f69: 0xfab1, + 0x1f6a: 0xfad1, 0x1f6b: 0xfaf1, 0x1f6c: 0xfb11, 0x1f6d: 0x9675, 0x1f6e: 0xfb31, 0x1f6f: 0xfb51, + 0x1f70: 0xfb71, 0x1f71: 0x9695, 0x1f72: 0xfb91, 0x1f73: 0xfbb1, 0x1f74: 0xfbd1, 0x1f75: 0xfbf1, + 0x1f76: 0x7b6d, 0x1f77: 0x96b5, 0x1f78: 0xfc11, 0x1f79: 0xfc31, 0x1f7a: 0xfc51, 0x1f7b: 0x96d5, + 0x1f7c: 0xfc71, 0x1f7d: 0x96f5, 0x1f7e: 0xfc91, 0x1f7f: 0xfc91, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0xfcb1, 0x1f81: 0x9715, 0x1f82: 0xfcd1, 0x1f83: 0xfcf1, 0x1f84: 0xfd11, 0x1f85: 0xfd31, + 0x1f86: 0xfd51, 0x1f87: 0xfd71, 0x1f88: 0xfd91, 0x1f89: 0x9735, 0x1f8a: 0xfdb1, 0x1f8b: 0xfdd1, + 0x1f8c: 0xfdf1, 0x1f8d: 0xfe11, 0x1f8e: 0xfe31, 0x1f8f: 0xfe51, 0x1f90: 0x9755, 0x1f91: 0xfe71, + 0x1f92: 0x9775, 0x1f93: 0x9795, 0x1f94: 0x97b5, 0x1f95: 0xfe91, 0x1f96: 0xfeb1, 0x1f97: 0xfed1, + 0x1f98: 0xfef1, 0x1f99: 0xff11, 0x1f9a: 0xff31, 0x1f9b: 0xff51, 0x1f9c: 0xff71, 0x1f9d: 0x97d5, + 0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040, + 0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040, + 0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040, + 0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040, + 0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040, + 0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040, +} + +// idnaIndex: 36 blocks, 2304 entries, 4608 bytes +// Block 0 is the zero block. +var idnaIndex = [2304]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c, + 0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21, + // Block 0x4, offset 0x100 + 0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16, + 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d, + 0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91, + 0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96, + // Block 0x5, offset 0x140 + 0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e, + 0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6, + 0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f, + 0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae, + 0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6, + 0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe, + 0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3, + 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c, + // Block 0x6, offset 0x180 + 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b, + 0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b, + 0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b, + 0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b, + 0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b, + 0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0x9b, + 0x1b0: 0xd0, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd1, 0x1b5: 0xd2, 0x1b6: 0xd3, 0x1b7: 0xd4, + 0x1b8: 0xd5, 0x1b9: 0xd6, 0x1ba: 0xd7, 0x1bb: 0xd8, 0x1bc: 0xd9, 0x1bd: 0xda, 0x1be: 0xdb, 0x1bf: 0x37, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x38, 0x1c1: 0xdc, 0x1c2: 0xdd, 0x1c3: 0xde, 0x1c4: 0xdf, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe0, + 0x1c8: 0xe1, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41, + 0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f, + 0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f, + 0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f, + 0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f, + 0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f, + 0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f, + // Block 0x8, offset 0x200 + 0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f, + 0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f, + 0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f, + 0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f, + 0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f, + 0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f, + 0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b, + 0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f, + // Block 0x9, offset 0x240 + 0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f, + 0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f, + 0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f, + 0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f, + 0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f, + 0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f, + 0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f, + 0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f, + // Block 0xa, offset 0x280 + 0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f, + 0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f, + 0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f, + 0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f, + 0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f, + 0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f, + 0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f, + 0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe2, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f, + 0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f, + 0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe3, 0x2d3: 0xe4, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f, + 0x2d8: 0xe5, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe6, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe7, + 0x2e0: 0xe8, 0x2e1: 0xe9, 0x2e2: 0xea, 0x2e3: 0xeb, 0x2e4: 0xec, 0x2e5: 0xed, 0x2e6: 0xee, 0x2e7: 0xef, + 0x2e8: 0xf0, 0x2e9: 0xf1, 0x2ea: 0xf2, 0x2eb: 0xf3, 0x2ec: 0xf4, 0x2ed: 0xf5, 0x2ee: 0xf6, 0x2ef: 0xf7, + 0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f, + 0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f, + // Block 0xc, offset 0x300 + 0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f, + 0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f, + 0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f, + 0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf8, 0x31f: 0xf9, + // Block 0xd, offset 0x340 + 0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba, + 0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba, + 0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba, + 0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba, + 0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba, + 0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba, + 0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba, + 0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba, + // Block 0xe, offset 0x380 + 0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba, + 0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba, + 0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba, + 0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba, + 0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfa, 0x3a5: 0xfb, 0x3a6: 0xfc, 0x3a7: 0xfd, + 0x3a8: 0x47, 0x3a9: 0xfe, 0x3aa: 0xff, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c, + 0x3b0: 0x100, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x101, 0x3b7: 0x52, + 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x102, 0x3c1: 0x103, 0x3c2: 0x9f, 0x3c3: 0x104, 0x3c4: 0x105, 0x3c5: 0x9b, 0x3c6: 0x106, 0x3c7: 0x107, + 0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x108, 0x3cb: 0x109, 0x3cc: 0x10a, 0x3cd: 0x10b, 0x3ce: 0x10c, 0x3cf: 0x10d, + 0x3d0: 0x10e, 0x3d1: 0x9f, 0x3d2: 0x10f, 0x3d3: 0x110, 0x3d4: 0x111, 0x3d5: 0x112, 0x3d6: 0xba, 0x3d7: 0xba, + 0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x113, 0x3dd: 0x114, 0x3de: 0xba, 0x3df: 0xba, + 0x3e0: 0x115, 0x3e1: 0x116, 0x3e2: 0x117, 0x3e3: 0x118, 0x3e4: 0x119, 0x3e5: 0xba, 0x3e6: 0x11a, 0x3e7: 0x11b, + 0x3e8: 0x11c, 0x3e9: 0x11d, 0x3ea: 0x11e, 0x3eb: 0x5b, 0x3ec: 0x11f, 0x3ed: 0x120, 0x3ee: 0x5c, 0x3ef: 0xba, + 0x3f0: 0x121, 0x3f1: 0x122, 0x3f2: 0x123, 0x3f3: 0x124, 0x3f4: 0x125, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba, + 0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0x127, 0x3fd: 0x128, 0x3fe: 0xba, 0x3ff: 0x129, + // Block 0x10, offset 0x400 + 0x400: 0x12a, 0x401: 0x12b, 0x402: 0x12c, 0x403: 0x12d, 0x404: 0x12e, 0x405: 0x12f, 0x406: 0x130, 0x407: 0x131, + 0x408: 0x132, 0x409: 0xba, 0x40a: 0x133, 0x40b: 0x134, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba, + 0x410: 0x135, 0x411: 0x136, 0x412: 0x137, 0x413: 0x138, 0x414: 0xba, 0x415: 0xba, 0x416: 0x139, 0x417: 0x13a, + 0x418: 0x13b, 0x419: 0x13c, 0x41a: 0x13d, 0x41b: 0x13e, 0x41c: 0x13f, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba, + 0x420: 0x140, 0x421: 0xba, 0x422: 0x141, 0x423: 0x142, 0x424: 0xba, 0x425: 0xba, 0x426: 0x143, 0x427: 0x144, + 0x428: 0x145, 0x429: 0x146, 0x42a: 0x147, 0x42b: 0x148, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba, + 0x430: 0x149, 0x431: 0x14a, 0x432: 0x14b, 0x433: 0xba, 0x434: 0x14c, 0x435: 0x14d, 0x436: 0x14e, 0x437: 0xba, + 0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0x14f, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0x150, + // Block 0x11, offset 0x440 + 0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f, + 0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x151, 0x44f: 0xba, + 0x450: 0x9b, 0x451: 0x152, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x153, 0x456: 0xba, 0x457: 0xba, + 0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba, + 0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba, + 0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba, + 0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba, + 0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba, + // Block 0x12, offset 0x480 + 0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f, + 0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f, + 0x490: 0x154, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba, + 0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba, + 0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba, + 0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba, + 0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba, + 0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba, + // Block 0x13, offset 0x4c0 + 0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba, + 0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba, + 0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f, + 0x4d8: 0x9f, 0x4d9: 0x155, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba, + 0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba, + 0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba, + 0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba, + 0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba, + // Block 0x14, offset 0x500 + 0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba, + 0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba, + 0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba, + 0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba, + 0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f, + 0x528: 0x148, 0x529: 0x156, 0x52a: 0xba, 0x52b: 0x157, 0x52c: 0x158, 0x52d: 0x159, 0x52e: 0x15a, 0x52f: 0xba, + 0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba, + 0x538: 0xba, 0x539: 0x15b, 0x53a: 0x15c, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x15d, 0x53e: 0x15e, 0x53f: 0x15f, + // Block 0x15, offset 0x540 + 0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f, + 0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f, + 0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f, + 0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x160, + 0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f, + 0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x161, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba, + 0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba, + 0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba, + // Block 0x16, offset 0x580 + 0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x162, 0x585: 0x163, 0x586: 0x9f, 0x587: 0x9f, + 0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x164, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba, + 0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba, + 0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba, + 0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba, + 0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba, + 0x5b0: 0x9f, 0x5b1: 0x165, 0x5b2: 0x166, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba, + 0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x167, 0x5c4: 0x168, 0x5c5: 0x169, 0x5c6: 0x16a, 0x5c7: 0x16b, + 0x5c8: 0x9b, 0x5c9: 0x16c, 0x5ca: 0xba, 0x5cb: 0x16d, 0x5cc: 0x9b, 0x5cd: 0x16e, 0x5ce: 0xba, 0x5cf: 0xba, + 0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66, + 0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e, + 0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b, + 0x5e8: 0x16f, 0x5e9: 0x170, 0x5ea: 0x171, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba, + 0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba, + 0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba, + // Block 0x18, offset 0x600 + 0x600: 0x172, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0x173, 0x605: 0x174, 0x606: 0xba, 0x607: 0xba, + 0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0x175, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba, + 0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba, + 0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba, + 0x620: 0x121, 0x621: 0x121, 0x622: 0x121, 0x623: 0x176, 0x624: 0x6f, 0x625: 0x177, 0x626: 0xba, 0x627: 0xba, + 0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba, + 0x630: 0xba, 0x631: 0x178, 0x632: 0x179, 0x633: 0xba, 0x634: 0x17a, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba, + 0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x17b, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba, + // Block 0x19, offset 0x640 + 0x640: 0x17c, 0x641: 0x9b, 0x642: 0x17d, 0x643: 0x17e, 0x644: 0x73, 0x645: 0x74, 0x646: 0x17f, 0x647: 0x180, + 0x648: 0x75, 0x649: 0x181, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b, + 0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b, + 0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x182, 0x65c: 0x9b, 0x65d: 0x183, 0x65e: 0x9b, 0x65f: 0x184, + 0x660: 0x185, 0x661: 0x186, 0x662: 0x187, 0x663: 0xba, 0x664: 0x188, 0x665: 0x189, 0x666: 0x18a, 0x667: 0x18b, + 0x668: 0x9b, 0x669: 0x18c, 0x66a: 0x18d, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba, + 0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba, + 0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba, + // Block 0x1a, offset 0x680 + 0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f, + 0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f, + 0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f, + 0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x18e, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f, + 0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f, + 0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f, + 0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f, + 0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f, + 0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f, + 0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f, + 0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x18f, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f, + 0x6e0: 0x190, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f, + 0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f, + 0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f, + 0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f, + // Block 0x1c, offset 0x700 + 0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f, + 0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f, + 0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f, + 0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f, + 0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f, + 0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f, + 0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f, + 0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x191, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f, + // Block 0x1d, offset 0x740 + 0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f, + 0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f, + 0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f, + 0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f, + 0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f, + 0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x192, + 0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba, + 0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba, + // Block 0x1e, offset 0x780 + 0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba, + 0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba, + 0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba, + 0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba, + 0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x193, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x194, 0x7a7: 0x7b, + 0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba, + 0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba, + 0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba, + // Block 0x1f, offset 0x7c0 + 0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07, + 0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17, + 0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07, + 0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c, + 0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b, + 0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b, + // Block 0x20, offset 0x800 + 0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b, + 0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b, + 0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b, + 0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b, + 0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b, + 0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b, + 0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b, + 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b, + // Block 0x21, offset 0x840 + 0x840: 0x195, 0x841: 0x196, 0x842: 0xba, 0x843: 0xba, 0x844: 0x197, 0x845: 0x197, 0x846: 0x197, 0x847: 0x198, + 0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba, + 0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba, + 0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba, + 0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba, + 0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba, + 0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba, + 0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba, + // Block 0x22, offset 0x880 + 0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b, + 0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b, + 0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b, + 0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b, + 0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b, + 0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b, + 0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b, + 0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b, + 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b, +} + +// idnaSparseOffset: 284 entries, 568 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x86, 0x8b, 0x94, 0xa4, 0xb2, 0xbe, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x224, 0x22e, 0x23a, 0x246, 0x252, 0x25a, 0x25f, 0x26c, 0x27d, 0x281, 0x28c, 0x290, 0x299, 0x2a1, 0x2a7, 0x2ac, 0x2af, 0x2b3, 0x2b9, 0x2bd, 0x2c1, 0x2c5, 0x2cb, 0x2d3, 0x2da, 0x2e5, 0x2ef, 0x2f3, 0x2f6, 0x2fc, 0x300, 0x302, 0x305, 0x307, 0x30a, 0x314, 0x317, 0x326, 0x32a, 0x32f, 0x332, 0x336, 0x33b, 0x340, 0x346, 0x352, 0x361, 0x367, 0x36b, 0x37a, 0x37f, 0x387, 0x391, 0x39c, 0x3a4, 0x3b5, 0x3be, 0x3ce, 0x3db, 0x3e5, 0x3ea, 0x3f7, 0x3fb, 0x400, 0x402, 0x406, 0x408, 0x40c, 0x415, 0x41b, 0x41f, 0x42f, 0x439, 0x43e, 0x441, 0x447, 0x44e, 0x453, 0x457, 0x45d, 0x462, 0x46b, 0x470, 0x476, 0x47d, 0x484, 0x48b, 0x48f, 0x494, 0x497, 0x49c, 0x4a8, 0x4ae, 0x4b3, 0x4ba, 0x4c2, 0x4c7, 0x4cb, 0x4db, 0x4e2, 0x4e6, 0x4ea, 0x4f1, 0x4f3, 0x4f6, 0x4f9, 0x4fd, 0x506, 0x50a, 0x512, 0x51a, 0x51e, 0x524, 0x52d, 0x539, 0x540, 0x549, 0x553, 0x55a, 0x568, 0x575, 0x582, 0x58b, 0x58f, 0x59f, 0x5a7, 0x5b2, 0x5bb, 0x5c1, 0x5c9, 0x5d2, 0x5dd, 0x5e0, 0x5ec, 0x5f5, 0x5f8, 0x5fd, 0x602, 0x60f, 0x61a, 0x623, 0x62d, 0x630, 0x63a, 0x643, 0x64f, 0x65c, 0x669, 0x677, 0x67e, 0x682, 0x685, 0x68a, 0x68d, 0x692, 0x695, 0x69c, 0x6a3, 0x6a7, 0x6b2, 0x6b5, 0x6b8, 0x6bb, 0x6c1, 0x6c7, 0x6cd, 0x6d0, 0x6d3, 0x6d6, 0x6dd, 0x6e0, 0x6e5, 0x6ef, 0x6f2, 0x6f6, 0x705, 0x711, 0x715, 0x71a, 0x71e, 0x723, 0x727, 0x72c, 0x735, 0x740, 0x746, 0x74c, 0x752, 0x758, 0x761, 0x764, 0x767, 0x76b, 0x76f, 0x773, 0x779, 0x77f, 0x784, 0x787, 0x797, 0x79e, 0x7a1, 0x7a6, 0x7aa, 0x7b0, 0x7b5, 0x7b9, 0x7bf, 0x7c5, 0x7c9, 0x7d2, 0x7d7, 0x7da, 0x7dd, 0x7e1, 0x7e5, 0x7e8, 0x7f8, 0x809, 0x80e, 0x810, 0x812} + +// idnaSparseValues: 2069 entries, 8276 bytes +var idnaSparseValues = [2069]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x07}, + {value: 0xe105, lo: 0x80, hi: 0x96}, + {value: 0x0018, lo: 0x97, hi: 0x97}, + {value: 0xe105, lo: 0x98, hi: 0x9e}, + {value: 0x001f, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbf}, + // Block 0x1, offset 0x8 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0xe01d, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0335, lo: 0x83, hi: 0x83}, + {value: 0x034d, lo: 0x84, hi: 0x84}, + {value: 0x0365, lo: 0x85, hi: 0x85}, + {value: 0xe00d, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0xe00d, lo: 0x88, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x89}, + {value: 0xe00d, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe00d, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0x8d}, + {value: 0xe00d, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0xbf}, + // Block 0x2, offset 0x19 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0249, lo: 0xb0, hi: 0xb0}, + {value: 0x037d, lo: 0xb1, hi: 0xb1}, + {value: 0x0259, lo: 0xb2, hi: 0xb2}, + {value: 0x0269, lo: 0xb3, hi: 0xb3}, + {value: 0x034d, lo: 0xb4, hi: 0xb4}, + {value: 0x0395, lo: 0xb5, hi: 0xb5}, + {value: 0xe1bd, lo: 0xb6, hi: 0xb6}, + {value: 0x0279, lo: 0xb7, hi: 0xb7}, + {value: 0x0289, lo: 0xb8, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbf}, + // Block 0x3, offset 0x25 + {value: 0x0000, lo: 0x01}, + {value: 0x3308, lo: 0x80, hi: 0xbf}, + // Block 0x4, offset 0x27 + {value: 0x0000, lo: 0x04}, + {value: 0x03f5, lo: 0x80, hi: 0x8f}, + {value: 0xe105, lo: 0x90, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x5, offset 0x2c + {value: 0x0000, lo: 0x06}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x0545, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x0008, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x6, offset 0x33 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0401, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0018, lo: 0x89, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x7, offset 0x3e + {value: 0x0000, lo: 0x0b}, + {value: 0x0818, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x82}, + {value: 0x0818, lo: 0x83, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x85}, + {value: 0x0818, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xae}, + {value: 0x0808, lo: 0xaf, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x8, offset 0x4a + {value: 0x0000, lo: 0x03}, + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0c08, lo: 0x88, hi: 0x99}, + {value: 0x0a08, lo: 0x9a, hi: 0xbf}, + // Block 0x9, offset 0x4e + {value: 0x0000, lo: 0x0e}, + {value: 0x3308, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0c08, lo: 0x8d, hi: 0x8d}, + {value: 0x0a08, lo: 0x8e, hi: 0x98}, + {value: 0x0c08, lo: 0x99, hi: 0x9b}, + {value: 0x0a08, lo: 0x9c, hi: 0xaa}, + {value: 0x0c08, lo: 0xab, hi: 0xac}, + {value: 0x0a08, lo: 0xad, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb4}, + {value: 0x0a08, lo: 0xb5, hi: 0xb7}, + {value: 0x0c08, lo: 0xb8, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbf}, + // Block 0xa, offset 0x5d + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xb, offset 0x62 + {value: 0x0000, lo: 0x09}, + {value: 0x0808, lo: 0x80, hi: 0x89}, + {value: 0x0a08, lo: 0x8a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0818, lo: 0xbe, hi: 0xbf}, + // Block 0xc, offset 0x6c + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x99}, + {value: 0x0808, lo: 0x9a, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa3}, + {value: 0x0808, lo: 0xa4, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa7}, + {value: 0x0808, lo: 0xa8, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0818, lo: 0xb0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xd, offset 0x78 + {value: 0x0000, lo: 0x0d}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0a08, lo: 0xa0, hi: 0xa9}, + {value: 0x0c08, lo: 0xaa, hi: 0xac}, + {value: 0x0808, lo: 0xad, hi: 0xad}, + {value: 0x0c08, lo: 0xae, hi: 0xae}, + {value: 0x0a08, lo: 0xaf, hi: 0xb0}, + {value: 0x0c08, lo: 0xb1, hi: 0xb2}, + {value: 0x0a08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0a08, lo: 0xb6, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xb9}, + {value: 0x0a08, lo: 0xba, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xe, offset 0x86 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0xa1}, + {value: 0x0840, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xbf}, + // Block 0xf, offset 0x8b + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x10, offset 0x94 + {value: 0x0000, lo: 0x0f}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x85}, + {value: 0x3008, lo: 0x86, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8c}, + {value: 0x3b08, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x11, offset 0xa4 + {value: 0x0000, lo: 0x0d}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x12, offset 0xb2 + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0xba}, + {value: 0x3b08, lo: 0xbb, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x13, offset 0xbe + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x14, offset 0xca + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x89}, + {value: 0x3b08, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x3008, lo: 0x98, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x15, offset 0xdb + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb2}, + {value: 0x08f1, lo: 0xb3, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb9}, + {value: 0x3b08, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0x16, offset 0xe5 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x8e}, + {value: 0x0018, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0xbf}, + // Block 0x17, offset 0xec + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0961, lo: 0x9c, hi: 0x9c}, + {value: 0x0999, lo: 0x9d, hi: 0x9d}, + {value: 0x0008, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x18, offset 0xf9 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0x8b}, + {value: 0xe03d, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x19, offset 0x10a + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0x1a, offset 0x111 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x1b, offset 0x11c + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xa1}, + {value: 0x3008, lo: 0xa2, hi: 0xa4}, + {value: 0x0008, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xbf}, + // Block 0x1c, offset 0x12b + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x8c}, + {value: 0x3308, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x8e}, + {value: 0x3008, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x3008, lo: 0x9a, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0x1d, offset 0x139 + {value: 0x0000, lo: 0x09}, + {value: 0x0040, lo: 0x80, hi: 0x86}, + {value: 0x055d, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8c}, + {value: 0x055d, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0xe105, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0x1e, offset 0x143 + {value: 0x0000, lo: 0x01}, + {value: 0x0018, lo: 0x80, hi: 0xbf}, + // Block 0x1f, offset 0x145 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa0}, + {value: 0x2018, lo: 0xa1, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x20, offset 0x14a + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa7}, + {value: 0x2018, lo: 0xa8, hi: 0xbf}, + // Block 0x21, offset 0x14d + {value: 0x0000, lo: 0x02}, + {value: 0x2018, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0xbf}, + // Block 0x22, offset 0x150 + {value: 0x0000, lo: 0x01}, + {value: 0x0008, lo: 0x80, hi: 0xbf}, + // Block 0x23, offset 0x152 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x99}, + {value: 0x0008, lo: 0x9a, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x24, offset 0x15e + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x25, offset 0x169 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x26, offset 0x171 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0x0008, lo: 0x92, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbf}, + // Block 0x27, offset 0x177 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x28, offset 0x17d + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x29, offset 0x182 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x2a, offset 0x187 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x2b, offset 0x18a + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xbf}, + // Block 0x2c, offset 0x18e + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x2d, offset 0x194 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x2e, offset 0x199 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x3b08, lo: 0x94, hi: 0x94}, + {value: 0x0040, lo: 0x95, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x2f, offset 0x1a5 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x30, offset 0x1af + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xb3}, + {value: 0x3340, lo: 0xb4, hi: 0xb5}, + {value: 0x3008, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x31, offset 0x1b5 + {value: 0x0000, lo: 0x10}, + {value: 0x3008, lo: 0x80, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x3008, lo: 0x87, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x91}, + {value: 0x3b08, lo: 0x92, hi: 0x92}, + {value: 0x3308, lo: 0x93, hi: 0x93}, + {value: 0x0018, lo: 0x94, hi: 0x96}, + {value: 0x0008, lo: 0x97, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x32, offset 0x1c6 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x86}, + {value: 0x0218, lo: 0x87, hi: 0x87}, + {value: 0x0018, lo: 0x88, hi: 0x8a}, + {value: 0x33c0, lo: 0x8b, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0208, lo: 0xa0, hi: 0xbf}, + // Block 0x33, offset 0x1d0 + {value: 0x0000, lo: 0x02}, + {value: 0x0208, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0x34, offset 0x1d3 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0208, lo: 0x87, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xa9}, + {value: 0x0208, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x35, offset 0x1db + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0x36, offset 0x1de + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb8}, + {value: 0x3308, lo: 0xb9, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x37, offset 0x1eb + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x38, offset 0x1f3 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x39, offset 0x1f7 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0028, lo: 0x9a, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xbf}, + // Block 0x3a, offset 0x1fe + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x3308, lo: 0x97, hi: 0x98}, + {value: 0x3008, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x3b, offset 0x206 + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x94}, + {value: 0x3008, lo: 0x95, hi: 0x95}, + {value: 0x3308, lo: 0x96, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xac}, + {value: 0x3008, lo: 0xad, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3c, offset 0x216 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xbd}, + {value: 0x3318, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x222 + {value: 0x0000, lo: 0x01}, + {value: 0x0040, lo: 0x80, hi: 0xbf}, + // Block 0x3e, offset 0x224 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3008, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbf}, + // Block 0x3f, offset 0x22e + {value: 0x0000, lo: 0x0b}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x3808, lo: 0x84, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x40, offset 0x23a + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3808, lo: 0xaa, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xbf}, + // Block 0x41, offset 0x246 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa9}, + {value: 0x3008, lo: 0xaa, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3808, lo: 0xb2, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbf}, + // Block 0x42, offset 0x252 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x3008, lo: 0xa4, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbf}, + // Block 0x43, offset 0x25a + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x44, offset 0x25f + {value: 0x0000, lo: 0x0c}, + {value: 0x0e29, lo: 0x80, hi: 0x80}, + {value: 0x0e41, lo: 0x81, hi: 0x81}, + {value: 0x0e59, lo: 0x82, hi: 0x82}, + {value: 0x0e71, lo: 0x83, hi: 0x83}, + {value: 0x0e89, lo: 0x84, hi: 0x85}, + {value: 0x0ea1, lo: 0x86, hi: 0x86}, + {value: 0x0eb9, lo: 0x87, hi: 0x87}, + {value: 0x057d, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x059d, lo: 0x90, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbc}, + {value: 0x059d, lo: 0xbd, hi: 0xbf}, + // Block 0x45, offset 0x26c + {value: 0x0000, lo: 0x10}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x92}, + {value: 0x0018, lo: 0x93, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0xa0}, + {value: 0x3008, lo: 0xa1, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa8}, + {value: 0x0008, lo: 0xa9, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x0008, lo: 0xae, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x46, offset 0x27d + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0x47, offset 0x281 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x87}, + {value: 0xe045, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0xe045, lo: 0x98, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0xe045, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb7}, + {value: 0xe045, lo: 0xb8, hi: 0xbf}, + // Block 0x48, offset 0x28c + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x3318, lo: 0x90, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbf}, + // Block 0x49, offset 0x290 + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x24c1, lo: 0x89, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x4a, offset 0x299 + {value: 0x0000, lo: 0x07}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x24f1, lo: 0xac, hi: 0xac}, + {value: 0x2529, lo: 0xad, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xae}, + {value: 0x2579, lo: 0xaf, hi: 0xaf}, + {value: 0x25b1, lo: 0xb0, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0x4b, offset 0x2a1 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x9f}, + {value: 0x0080, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xad}, + {value: 0x0080, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x4c, offset 0x2a7 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xa8}, + {value: 0x09dd, lo: 0xa9, hi: 0xa9}, + {value: 0x09fd, lo: 0xaa, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xbf}, + // Block 0x4d, offset 0x2ac + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0x4e, offset 0x2af + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x28c1, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x4f, offset 0x2b3 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0e7e, lo: 0xb4, hi: 0xb4}, + {value: 0x292a, lo: 0xb5, hi: 0xb5}, + {value: 0x0e9e, lo: 0xb6, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x50, offset 0x2b9 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x9b}, + {value: 0x2941, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0xbf}, + // Block 0x51, offset 0x2bd + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0x52, offset 0x2c1 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0018, lo: 0x98, hi: 0xbf}, + // Block 0x53, offset 0x2c5 + {value: 0x0000, lo: 0x05}, + {value: 0xe185, lo: 0x80, hi: 0x8f}, + {value: 0x03f5, lo: 0x90, hi: 0x9f}, + {value: 0x0ebd, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x54, offset 0x2cb + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x55, offset 0x2d3 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xae}, + {value: 0xe075, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0x56, offset 0x2da + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x57, offset 0x2e5 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xbf}, + // Block 0x58, offset 0x2ef + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0008, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x59, offset 0x2f3 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0x5a, offset 0x2f6 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9e}, + {value: 0x0ef5, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x5b, offset 0x2fc + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb2}, + {value: 0x0f15, lo: 0xb3, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x5c, offset 0x300 + {value: 0x0020, lo: 0x01}, + {value: 0x0f35, lo: 0x80, hi: 0xbf}, + // Block 0x5d, offset 0x302 + {value: 0x0020, lo: 0x02}, + {value: 0x1735, lo: 0x80, hi: 0x8f}, + {value: 0x1915, lo: 0x90, hi: 0xbf}, + // Block 0x5e, offset 0x305 + {value: 0x0020, lo: 0x01}, + {value: 0x1f15, lo: 0x80, hi: 0xbf}, + // Block 0x5f, offset 0x307 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x60, offset 0x30a + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9a}, + {value: 0x29e2, lo: 0x9b, hi: 0x9b}, + {value: 0x2a0a, lo: 0x9c, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9e}, + {value: 0x2a31, lo: 0x9f, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xbf}, + // Block 0x61, offset 0x314 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbe}, + {value: 0x2a69, lo: 0xbf, hi: 0xbf}, + // Block 0x62, offset 0x317 + {value: 0x0000, lo: 0x0e}, + {value: 0x0040, lo: 0x80, hi: 0x84}, + {value: 0x0008, lo: 0x85, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xb0}, + {value: 0x2a35, lo: 0xb1, hi: 0xb1}, + {value: 0x2a55, lo: 0xb2, hi: 0xb2}, + {value: 0x2a75, lo: 0xb3, hi: 0xb3}, + {value: 0x2a95, lo: 0xb4, hi: 0xb4}, + {value: 0x2a75, lo: 0xb5, hi: 0xb5}, + {value: 0x2ab5, lo: 0xb6, hi: 0xb6}, + {value: 0x2ad5, lo: 0xb7, hi: 0xb7}, + {value: 0x2af5, lo: 0xb8, hi: 0xb9}, + {value: 0x2b15, lo: 0xba, hi: 0xbb}, + {value: 0x2b35, lo: 0xbc, hi: 0xbd}, + {value: 0x2b15, lo: 0xbe, hi: 0xbf}, + // Block 0x63, offset 0x326 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x64, offset 0x32a + {value: 0x0030, lo: 0x04}, + {value: 0x2aa2, lo: 0x80, hi: 0x9d}, + {value: 0x305a, lo: 0x9e, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x30a2, lo: 0xa0, hi: 0xbf}, + // Block 0x65, offset 0x32f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x66, offset 0x332 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0040, lo: 0x8d, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x67, offset 0x336 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0x68, offset 0x33b + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0x69, offset 0x340 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb1}, + {value: 0x0018, lo: 0xb2, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6a, offset 0x346 + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0x81}, + {value: 0xe00d, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0x83}, + {value: 0x03f5, lo: 0x84, hi: 0x84}, + {value: 0x1329, lo: 0x85, hi: 0x85}, + {value: 0x447d, lo: 0x86, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xb6}, + {value: 0x0008, lo: 0xb7, hi: 0xb7}, + {value: 0x2009, lo: 0xb8, hi: 0xb8}, + {value: 0x6e89, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xbf}, + // Block 0x6b, offset 0x352 + {value: 0x0000, lo: 0x0e}, + {value: 0x0008, lo: 0x80, hi: 0x81}, + {value: 0x3308, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x3308, lo: 0x8b, hi: 0x8b}, + {value: 0x0008, lo: 0x8c, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa6}, + {value: 0x3008, lo: 0xa7, hi: 0xa7}, + {value: 0x0018, lo: 0xa8, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x6c, offset 0x361 + {value: 0x0000, lo: 0x05}, + {value: 0x0208, lo: 0x80, hi: 0xb1}, + {value: 0x0108, lo: 0xb2, hi: 0xb2}, + {value: 0x0008, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0x6d, offset 0x367 + {value: 0x0000, lo: 0x03}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xbf}, + // Block 0x6e, offset 0x36b + {value: 0x0000, lo: 0x0e}, + {value: 0x3008, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8d}, + {value: 0x0018, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0008, lo: 0xbb, hi: 0xbb}, + {value: 0x0018, lo: 0xbc, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x6f, offset 0x37a + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x70, offset 0x37f + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x91}, + {value: 0x3008, lo: 0x92, hi: 0x92}, + {value: 0x3808, lo: 0x93, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x71, offset 0x387 + {value: 0x0000, lo: 0x09}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x3008, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb9}, + {value: 0x3008, lo: 0xba, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbf}, + // Block 0x72, offset 0x391 + {value: 0x0000, lo: 0x0a}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0x73, offset 0x39c + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xa8}, + {value: 0x3308, lo: 0xa9, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x74, offset 0x3a4 + {value: 0x0000, lo: 0x10}, + {value: 0x0008, lo: 0x80, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8c}, + {value: 0x3008, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbc}, + {value: 0x3008, lo: 0xbd, hi: 0xbd}, + {value: 0x0008, lo: 0xbe, hi: 0xbf}, + // Block 0x75, offset 0x3b5 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb0}, + {value: 0x0008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb4}, + {value: 0x0008, lo: 0xb5, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb8}, + {value: 0x0008, lo: 0xb9, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbf}, + // Block 0x76, offset 0x3be + {value: 0x0000, lo: 0x0f}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x9a}, + {value: 0x0008, lo: 0x9b, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xaa}, + {value: 0x3008, lo: 0xab, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb5}, + {value: 0x3b08, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x77, offset 0x3ce + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x88}, + {value: 0x0008, lo: 0x89, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x90}, + {value: 0x0008, lo: 0x91, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x78, offset 0x3db + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x449d, lo: 0x9c, hi: 0x9c}, + {value: 0x44b5, lo: 0x9d, hi: 0x9d}, + {value: 0x2971, lo: 0x9e, hi: 0x9e}, + {value: 0xe06d, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x44cd, lo: 0xb0, hi: 0xbf}, + // Block 0x79, offset 0x3e5 + {value: 0x0000, lo: 0x04}, + {value: 0x44ed, lo: 0x80, hi: 0x8f}, + {value: 0x450d, lo: 0x90, hi: 0x9f}, + {value: 0x452d, lo: 0xa0, hi: 0xaf}, + {value: 0x450d, lo: 0xb0, hi: 0xbf}, + // Block 0x7a, offset 0x3ea + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0xa2}, + {value: 0x3008, lo: 0xa3, hi: 0xa4}, + {value: 0x3308, lo: 0xa5, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa7}, + {value: 0x3308, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xaa}, + {value: 0x0018, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3b08, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x7b, offset 0x3f7 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x7c, offset 0x3fb + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x7d, offset 0x400 + {value: 0x0020, lo: 0x01}, + {value: 0x454d, lo: 0x80, hi: 0xbf}, + // Block 0x7e, offset 0x402 + {value: 0x0020, lo: 0x03}, + {value: 0x4d4d, lo: 0x80, hi: 0x94}, + {value: 0x4b0d, lo: 0x95, hi: 0x95}, + {value: 0x4fed, lo: 0x96, hi: 0xbf}, + // Block 0x7f, offset 0x406 + {value: 0x0020, lo: 0x01}, + {value: 0x552d, lo: 0x80, hi: 0xbf}, + // Block 0x80, offset 0x408 + {value: 0x0020, lo: 0x03}, + {value: 0x5d2d, lo: 0x80, hi: 0x84}, + {value: 0x568d, lo: 0x85, hi: 0x85}, + {value: 0x5dcd, lo: 0x86, hi: 0xbf}, + // Block 0x81, offset 0x40c + {value: 0x0020, lo: 0x08}, + {value: 0x6b8d, lo: 0x80, hi: 0x8f}, + {value: 0x6d4d, lo: 0x90, hi: 0x90}, + {value: 0x6d8d, lo: 0x91, hi: 0xab}, + {value: 0x6ea1, lo: 0xac, hi: 0xac}, + {value: 0x70ed, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x710d, lo: 0xb0, hi: 0xbf}, + // Block 0x82, offset 0x415 + {value: 0x0020, lo: 0x05}, + {value: 0x730d, lo: 0x80, hi: 0xad}, + {value: 0x656d, lo: 0xae, hi: 0xae}, + {value: 0x78cd, lo: 0xaf, hi: 0xb5}, + {value: 0x6f8d, lo: 0xb6, hi: 0xb6}, + {value: 0x79ad, lo: 0xb7, hi: 0xbf}, + // Block 0x83, offset 0x41b + {value: 0x0028, lo: 0x03}, + {value: 0x7c21, lo: 0x80, hi: 0x82}, + {value: 0x7be1, lo: 0x83, hi: 0x83}, + {value: 0x7c99, lo: 0x84, hi: 0xbf}, + // Block 0x84, offset 0x41f + {value: 0x0038, lo: 0x0f}, + {value: 0x9db1, lo: 0x80, hi: 0x83}, + {value: 0x9e59, lo: 0x84, hi: 0x85}, + {value: 0x9e91, lo: 0x86, hi: 0x87}, + {value: 0x9ec9, lo: 0x88, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0xa089, lo: 0x92, hi: 0x97}, + {value: 0xa1a1, lo: 0x98, hi: 0x9c}, + {value: 0xa281, lo: 0x9d, hi: 0xb3}, + {value: 0x9d41, lo: 0xb4, hi: 0xb4}, + {value: 0x9db1, lo: 0xb5, hi: 0xb5}, + {value: 0xa789, lo: 0xb6, hi: 0xbb}, + {value: 0xa869, lo: 0xbc, hi: 0xbc}, + {value: 0xa7f9, lo: 0xbd, hi: 0xbd}, + {value: 0xa8d9, lo: 0xbe, hi: 0xbf}, + // Block 0x85, offset 0x42f + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0008, lo: 0x8d, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x0008, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0x86, offset 0x439 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0x87, offset 0x43e + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x88, offset 0x441 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0x89, offset 0x447 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x8a, offset 0x44e + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x8b, offset 0x453 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x8c, offset 0x457 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x9f}, + {value: 0x3308, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x8d, offset 0x45d + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xac}, + {value: 0x0008, lo: 0xad, hi: 0xbf}, + // Block 0x8e, offset 0x462 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x81}, + {value: 0x0008, lo: 0x82, hi: 0x89}, + {value: 0x0018, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x8f, offset 0x46b + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x90, offset 0x470 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x91, offset 0x476 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x97}, + {value: 0x8b0d, lo: 0x98, hi: 0x9f}, + {value: 0x8b25, lo: 0xa0, hi: 0xa7}, + {value: 0x0008, lo: 0xa8, hi: 0xbf}, + // Block 0x92, offset 0x47d + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x8b25, lo: 0xb0, hi: 0xb7}, + {value: 0x8b0d, lo: 0xb8, hi: 0xbf}, + // Block 0x93, offset 0x484 + {value: 0x0000, lo: 0x06}, + {value: 0xe145, lo: 0x80, hi: 0x87}, + {value: 0xe1c5, lo: 0x88, hi: 0x8f}, + {value: 0xe145, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0x94, offset 0x48b + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x95, offset 0x48f + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xae}, + {value: 0x0018, lo: 0xaf, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x96, offset 0x494 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x97, offset 0x497 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xbf}, + // Block 0x98, offset 0x49c + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x87}, + {value: 0x0808, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0808, lo: 0x8a, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb6}, + {value: 0x0808, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbb}, + {value: 0x0808, lo: 0xbc, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbe}, + {value: 0x0808, lo: 0xbf, hi: 0xbf}, + // Block 0x99, offset 0x4a8 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x96}, + {value: 0x0818, lo: 0x97, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0818, lo: 0xb7, hi: 0xbf}, + // Block 0x9a, offset 0x4ae + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xa6}, + {value: 0x0818, lo: 0xa7, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0x9b, offset 0x4b3 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb3}, + {value: 0x0808, lo: 0xb4, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xba}, + {value: 0x0818, lo: 0xbb, hi: 0xbf}, + // Block 0x9c, offset 0x4ba + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0818, lo: 0x96, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbe}, + {value: 0x0818, lo: 0xbf, hi: 0xbf}, + // Block 0x9d, offset 0x4c2 + {value: 0x0000, lo: 0x04}, + {value: 0x0808, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbb}, + {value: 0x0818, lo: 0xbc, hi: 0xbd}, + {value: 0x0808, lo: 0xbe, hi: 0xbf}, + // Block 0x9e, offset 0x4c7 + {value: 0x0000, lo: 0x03}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0x9f, offset 0x4cb + {value: 0x0000, lo: 0x0f}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0x84}, + {value: 0x3308, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8b}, + {value: 0x3308, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x94}, + {value: 0x0808, lo: 0x95, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x98}, + {value: 0x0808, lo: 0x99, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xa0, offset 0x4db + {value: 0x0000, lo: 0x06}, + {value: 0x0818, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0818, lo: 0x90, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xbc}, + {value: 0x0818, lo: 0xbd, hi: 0xbf}, + // Block 0xa1, offset 0x4e2 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xa2, offset 0x4e6 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb8}, + {value: 0x0018, lo: 0xb9, hi: 0xbf}, + // Block 0xa3, offset 0x4ea + {value: 0x0000, lo: 0x06}, + {value: 0x0808, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x97}, + {value: 0x0818, lo: 0x98, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb7}, + {value: 0x0818, lo: 0xb8, hi: 0xbf}, + // Block 0xa4, offset 0x4f1 + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa5, offset 0x4f3 + {value: 0x0000, lo: 0x02}, + {value: 0x0808, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xa6, offset 0x4f6 + {value: 0x0000, lo: 0x02}, + {value: 0x03dd, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xa7, offset 0x4f9 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xa8, offset 0x4fd + {value: 0x0000, lo: 0x08}, + {value: 0x0908, lo: 0x80, hi: 0x80}, + {value: 0x0a08, lo: 0x81, hi: 0xa1}, + {value: 0x0c08, lo: 0xa2, hi: 0xa2}, + {value: 0x0a08, lo: 0xa3, hi: 0xa3}, + {value: 0x3308, lo: 0xa4, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0808, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xa9, offset 0x506 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xaa, offset 0x50a + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0xa6}, + {value: 0x0808, lo: 0xa7, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0a08, lo: 0xb0, hi: 0xb2}, + {value: 0x0c08, lo: 0xb3, hi: 0xb3}, + {value: 0x0a08, lo: 0xb4, hi: 0xbf}, + // Block 0xab, offset 0x512 + {value: 0x0000, lo: 0x07}, + {value: 0x0a08, lo: 0x80, hi: 0x84}, + {value: 0x0808, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x90}, + {value: 0x0a18, lo: 0x91, hi: 0x93}, + {value: 0x0c18, lo: 0x94, hi: 0x94}, + {value: 0x0818, lo: 0x95, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xac, offset 0x51a + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xad, offset 0x51e + {value: 0x0000, lo: 0x05}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xae, offset 0x524 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x85}, + {value: 0x3b08, lo: 0x86, hi: 0x86}, + {value: 0x0018, lo: 0x87, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x91}, + {value: 0x0018, lo: 0x92, hi: 0xa5}, + {value: 0x0008, lo: 0xa6, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xaf, offset 0x52d + {value: 0x0000, lo: 0x0b}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb6}, + {value: 0x3008, lo: 0xb7, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbd}, + {value: 0x0018, lo: 0xbe, hi: 0xbf}, + // Block 0xb0, offset 0x539 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb1, offset 0x540 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xb2}, + {value: 0x3b08, lo: 0xb3, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xbf}, + // Block 0xb2, offset 0x549 + {value: 0x0000, lo: 0x09}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x0018, lo: 0xb4, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xb3, offset 0x553 + {value: 0x0000, lo: 0x06}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x0008, lo: 0x83, hi: 0xb2}, + {value: 0x3008, lo: 0xb3, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xbe}, + {value: 0x3008, lo: 0xbf, hi: 0xbf}, + // Block 0xb4, offset 0x55a + {value: 0x0000, lo: 0x0d}, + {value: 0x3808, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x88}, + {value: 0x3308, lo: 0x89, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x0018, lo: 0xa1, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xb5, offset 0x568 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb1}, + {value: 0x3008, lo: 0xb2, hi: 0xb3}, + {value: 0x3308, lo: 0xb4, hi: 0xb4}, + {value: 0x3808, lo: 0xb5, hi: 0xb5}, + {value: 0x3308, lo: 0xb6, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xbd}, + {value: 0x3308, lo: 0xbe, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xb6, offset 0x575 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8d}, + {value: 0x0040, lo: 0x8e, hi: 0x8e}, + {value: 0x0008, lo: 0x8f, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9e}, + {value: 0x0008, lo: 0x9f, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xb7, offset 0x582 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x3308, lo: 0x9f, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa9}, + {value: 0x3b08, lo: 0xaa, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0xb8, offset 0x58b + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xb9, offset 0x58f + {value: 0x0000, lo: 0x0f}, + {value: 0x3008, lo: 0x80, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x85}, + {value: 0x3308, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x8a}, + {value: 0x0018, lo: 0x8b, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0x9b}, + {value: 0x0040, lo: 0x9c, hi: 0x9c}, + {value: 0x0018, lo: 0x9d, hi: 0x9d}, + {value: 0x3308, lo: 0x9e, hi: 0x9e}, + {value: 0x0008, lo: 0x9f, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xba, offset 0x59f + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xbb, offset 0x5a7 + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x3008, lo: 0x81, hi: 0x81}, + {value: 0x3b08, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x85}, + {value: 0x0018, lo: 0x86, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xbc, offset 0x5b2 + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbd, offset 0x5bb + {value: 0x0000, lo: 0x05}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x9b}, + {value: 0x3308, lo: 0x9c, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0xbe, offset 0x5c1 + {value: 0x0000, lo: 0x07}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xba}, + {value: 0x3008, lo: 0xbb, hi: 0xbc}, + {value: 0x3308, lo: 0xbd, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xbf, offset 0x5c9 + {value: 0x0000, lo: 0x08}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0xc0, offset 0x5d2 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xac}, + {value: 0x3308, lo: 0xad, hi: 0xad}, + {value: 0x3008, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb5}, + {value: 0x3808, lo: 0xb6, hi: 0xb6}, + {value: 0x3308, lo: 0xb7, hi: 0xb7}, + {value: 0x0008, lo: 0xb8, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xc1, offset 0x5dd + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0xc2, offset 0x5e0 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9f}, + {value: 0x3008, lo: 0xa0, hi: 0xa1}, + {value: 0x3308, lo: 0xa2, hi: 0xa5}, + {value: 0x3008, lo: 0xa6, hi: 0xa6}, + {value: 0x3308, lo: 0xa7, hi: 0xaa}, + {value: 0x3b08, lo: 0xab, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0xc3, offset 0x5ec + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x3008, lo: 0xac, hi: 0xae}, + {value: 0x3308, lo: 0xaf, hi: 0xb7}, + {value: 0x3008, lo: 0xb8, hi: 0xb8}, + {value: 0x3b08, lo: 0xb9, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0018, lo: 0xbb, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xc4, offset 0x5f5 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xbf}, + // Block 0xc5, offset 0x5f8 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbe}, + {value: 0x0008, lo: 0xbf, hi: 0xbf}, + // Block 0xc6, offset 0x5fd + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xbf}, + // Block 0xc7, offset 0x602 + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x90}, + {value: 0x3008, lo: 0x91, hi: 0x93}, + {value: 0x3308, lo: 0x94, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x99}, + {value: 0x3308, lo: 0x9a, hi: 0x9b}, + {value: 0x3008, lo: 0x9c, hi: 0x9f}, + {value: 0x3b08, lo: 0xa0, hi: 0xa0}, + {value: 0x0008, lo: 0xa1, hi: 0xa1}, + {value: 0x0018, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xa3}, + {value: 0x3008, lo: 0xa4, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xbf}, + // Block 0xc8, offset 0x60f + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb3}, + {value: 0x3b08, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb8}, + {value: 0x3008, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xc9, offset 0x61a + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x3b08, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3308, lo: 0x91, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x98}, + {value: 0x3308, lo: 0x99, hi: 0x9b}, + {value: 0x0008, lo: 0x9c, hi: 0xbf}, + // Block 0xca, offset 0x623 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x3308, lo: 0x8a, hi: 0x96}, + {value: 0x3008, lo: 0x97, hi: 0x97}, + {value: 0x3308, lo: 0x98, hi: 0x98}, + {value: 0x3b08, lo: 0x99, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0x9c}, + {value: 0x0008, lo: 0x9d, hi: 0x9d}, + {value: 0x0018, lo: 0x9e, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xbf}, + // Block 0xcb, offset 0x62d + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xcc, offset 0x630 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0xae}, + {value: 0x3008, lo: 0xaf, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbd}, + {value: 0x3008, lo: 0xbe, hi: 0xbe}, + {value: 0x3b08, lo: 0xbf, hi: 0xbf}, + // Block 0xcd, offset 0x63a + {value: 0x0000, lo: 0x08}, + {value: 0x0008, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0018, lo: 0x9a, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0008, lo: 0xb2, hi: 0xbf}, + // Block 0xce, offset 0x643 + {value: 0x0000, lo: 0x0b}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x3308, lo: 0x92, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xa8}, + {value: 0x3008, lo: 0xa9, hi: 0xa9}, + {value: 0x3308, lo: 0xaa, hi: 0xb0}, + {value: 0x3008, lo: 0xb1, hi: 0xb1}, + {value: 0x3308, lo: 0xb2, hi: 0xb3}, + {value: 0x3008, lo: 0xb4, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xcf, offset 0x64f + {value: 0x0000, lo: 0x0c}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8a}, + {value: 0x0008, lo: 0x8b, hi: 0xb0}, + {value: 0x3308, lo: 0xb1, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x3308, lo: 0xba, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbb}, + {value: 0x3308, lo: 0xbc, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbe}, + {value: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0xd0, offset 0x65c + {value: 0x0000, lo: 0x0c}, + {value: 0x3308, lo: 0x80, hi: 0x83}, + {value: 0x3b08, lo: 0x84, hi: 0x85}, + {value: 0x0008, lo: 0x86, hi: 0x86}, + {value: 0x3308, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xa6}, + {value: 0x0008, lo: 0xa7, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xa9}, + {value: 0x0008, lo: 0xaa, hi: 0xbf}, + // Block 0xd1, offset 0x669 + {value: 0x0000, lo: 0x0d}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x3008, lo: 0x8a, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x92}, + {value: 0x3008, lo: 0x93, hi: 0x94}, + {value: 0x3308, lo: 0x95, hi: 0x95}, + {value: 0x3008, lo: 0x96, hi: 0x96}, + {value: 0x3b08, lo: 0x97, hi: 0x97}, + {value: 0x0008, lo: 0x98, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xbf}, + // Block 0xd2, offset 0x677 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xb2}, + {value: 0x3308, lo: 0xb3, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xd3, offset 0x67e + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xd4, offset 0x682 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xd5, offset 0x685 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xd6, offset 0x68a + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0xbf}, + // Block 0xd7, offset 0x68d + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xaf}, + {value: 0x0340, lo: 0xb0, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xd8, offset 0x692 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xbf}, + // Block 0xd9, offset 0x695 + {value: 0x0000, lo: 0x06}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xda, offset 0x69c + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb4}, + {value: 0x0018, lo: 0xb5, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xdb, offset 0x6a3 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0xdc, offset 0x6a7 + {value: 0x0000, lo: 0x0a}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9a}, + {value: 0x0018, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbc}, + {value: 0x0008, lo: 0xbd, hi: 0xbf}, + // Block 0xdd, offset 0x6b2 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xde, offset 0x6b5 + {value: 0x0000, lo: 0x02}, + {value: 0xe105, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0xdf, offset 0x6b8 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0xe0, offset 0x6bb + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x90}, + {value: 0x3008, lo: 0x91, hi: 0xbf}, + // Block 0xe1, offset 0x6c1 + {value: 0x0000, lo: 0x05}, + {value: 0x3008, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, hi: 0x92}, + {value: 0x0008, lo: 0x93, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xe2, offset 0x6c7 + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xa1}, + {value: 0x0018, lo: 0xa2, hi: 0xa2}, + {value: 0x0008, lo: 0xa3, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xbf}, + // Block 0xe3, offset 0x6cd + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0xe4, offset 0x6d0 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xe5, offset 0x6d3 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xe6, offset 0x6d6 + {value: 0x0000, lo: 0x06}, + {value: 0x0040, lo: 0x80, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x92}, + {value: 0x0040, lo: 0x93, hi: 0xa3}, + {value: 0x0008, lo: 0xa4, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0xe7, offset 0x6dd + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xe8, offset 0x6e0 + {value: 0x0000, lo: 0x04}, + {value: 0x0008, lo: 0x80, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0xe9, offset 0x6e5 + {value: 0x0000, lo: 0x09}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9b}, + {value: 0x0018, lo: 0x9c, hi: 0x9c}, + {value: 0x3308, lo: 0x9d, hi: 0x9e}, + {value: 0x0018, lo: 0x9f, hi: 0x9f}, + {value: 0x03c0, lo: 0xa0, hi: 0xa3}, + {value: 0x0040, lo: 0xa4, hi: 0xbf}, + // Block 0xea, offset 0x6ef + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xeb, offset 0x6f2 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xbf}, + // Block 0xec, offset 0x6f6 + {value: 0x0000, lo: 0x0e}, + {value: 0x0018, lo: 0x80, hi: 0x9d}, + {value: 0xb5b9, lo: 0x9e, hi: 0x9e}, + {value: 0xb601, lo: 0x9f, hi: 0x9f}, + {value: 0xb649, lo: 0xa0, hi: 0xa0}, + {value: 0xb6b1, lo: 0xa1, hi: 0xa1}, + {value: 0xb719, lo: 0xa2, hi: 0xa2}, + {value: 0xb781, lo: 0xa3, hi: 0xa3}, + {value: 0xb7e9, lo: 0xa4, hi: 0xa4}, + {value: 0x3018, lo: 0xa5, hi: 0xa6}, + {value: 0x3318, lo: 0xa7, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xac}, + {value: 0x3018, lo: 0xad, hi: 0xb2}, + {value: 0x0340, lo: 0xb3, hi: 0xba}, + {value: 0x3318, lo: 0xbb, hi: 0xbf}, + // Block 0xed, offset 0x705 + {value: 0x0000, lo: 0x0b}, + {value: 0x3318, lo: 0x80, hi: 0x82}, + {value: 0x0018, lo: 0x83, hi: 0x84}, + {value: 0x3318, lo: 0x85, hi: 0x8b}, + {value: 0x0018, lo: 0x8c, hi: 0xa9}, + {value: 0x3318, lo: 0xaa, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xba}, + {value: 0xb851, lo: 0xbb, hi: 0xbb}, + {value: 0xb899, lo: 0xbc, hi: 0xbc}, + {value: 0xb8e1, lo: 0xbd, hi: 0xbd}, + {value: 0xb949, lo: 0xbe, hi: 0xbe}, + {value: 0xb9b1, lo: 0xbf, hi: 0xbf}, + // Block 0xee, offset 0x711 + {value: 0x0000, lo: 0x03}, + {value: 0xba19, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xbf}, + // Block 0xef, offset 0x715 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x81}, + {value: 0x3318, lo: 0x82, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x85}, + {value: 0x0040, lo: 0x86, hi: 0xbf}, + // Block 0xf0, offset 0x71a + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0xf1, offset 0x71e + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xf2, offset 0x723 + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xf3, offset 0x727 + {value: 0x0000, lo: 0x04}, + {value: 0x3308, lo: 0x80, hi: 0xac}, + {value: 0x0018, lo: 0xad, hi: 0xb4}, + {value: 0x3308, lo: 0xb5, hi: 0xb5}, + {value: 0x0018, lo: 0xb6, hi: 0xbf}, + // Block 0xf4, offset 0x72c + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x84}, + {value: 0x0018, lo: 0x85, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xa0}, + {value: 0x3308, lo: 0xa1, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, + // Block 0xf5, offset 0x735 + {value: 0x0000, lo: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x87}, + {value: 0x3308, lo: 0x88, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9a}, + {value: 0x3308, lo: 0x9b, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xa2}, + {value: 0x3308, lo: 0xa3, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xa5}, + {value: 0x3308, lo: 0xa6, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xbf}, + // Block 0xf6, offset 0x740 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0008, lo: 0xb7, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xf7, offset 0x746 + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0x8d}, + {value: 0x0008, lo: 0x8e, hi: 0x8e}, + {value: 0x0018, lo: 0x8f, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xf8, offset 0x74c + {value: 0x0000, lo: 0x05}, + {value: 0x0008, lo: 0x80, hi: 0xab}, + {value: 0x3308, lo: 0xac, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xf9, offset 0x752 + {value: 0x0000, lo: 0x05}, + {value: 0x0808, lo: 0x80, hi: 0x84}, + {value: 0x0040, lo: 0x85, hi: 0x86}, + {value: 0x0818, lo: 0x87, hi: 0x8f}, + {value: 0x3308, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0xfa, offset 0x758 + {value: 0x0000, lo: 0x08}, + {value: 0x0a08, lo: 0x80, hi: 0x83}, + {value: 0x3308, lo: 0x84, hi: 0x8a}, + {value: 0x0b08, lo: 0x8b, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0808, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9d}, + {value: 0x0818, lo: 0x9e, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xfb, offset 0x761 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xb0}, + {value: 0x0818, lo: 0xb1, hi: 0xbf}, + // Block 0xfc, offset 0x764 + {value: 0x0000, lo: 0x02}, + {value: 0x0818, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0xfd, offset 0x767 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0818, lo: 0x81, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0xfe, offset 0x76b + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xff, offset 0x76f + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x100, offset 0x773 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xae}, + {value: 0x0040, lo: 0xaf, hi: 0xb0}, + {value: 0x0018, lo: 0xb1, hi: 0xbf}, + // Block 0x101, offset 0x779 + {value: 0x0000, lo: 0x05}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0x102, offset 0x77f + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0xc1d9, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xbf}, + // Block 0x103, offset 0x784 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xbf}, + // Block 0x104, offset 0x787 + {value: 0x0000, lo: 0x0f}, + {value: 0xc801, lo: 0x80, hi: 0x80}, + {value: 0xc851, lo: 0x81, hi: 0x81}, + {value: 0xc8a1, lo: 0x82, hi: 0x82}, + {value: 0xc8f1, lo: 0x83, hi: 0x83}, + {value: 0xc941, lo: 0x84, hi: 0x84}, + {value: 0xc991, lo: 0x85, hi: 0x85}, + {value: 0xc9e1, lo: 0x86, hi: 0x86}, + {value: 0xca31, lo: 0x87, hi: 0x87}, + {value: 0xca81, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0xcad1, lo: 0x90, hi: 0x90}, + {value: 0xcaf1, lo: 0x91, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xbf}, + // Block 0x105, offset 0x797 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x106, offset 0x79e + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x107, offset 0x7a1 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x98}, + {value: 0x0040, lo: 0x99, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xbf}, + // Block 0x108, offset 0x7a6 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x109, offset 0x7aa + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xbf}, + // Block 0x10a, offset 0x7b0 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0x10b, offset 0x7b5 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x10c, offset 0x7b9 + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xb2}, + {value: 0x0018, lo: 0xb3, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0x10d, offset 0x7bf + {value: 0x0000, lo: 0x05}, + {value: 0x0018, lo: 0x80, hi: 0xa2}, + {value: 0x0040, lo: 0xa3, hi: 0xa4}, + {value: 0x0018, lo: 0xa5, hi: 0xaa}, + {value: 0x0040, lo: 0xab, hi: 0xad}, + {value: 0x0018, lo: 0xae, hi: 0xbf}, + // Block 0x10e, offset 0x7c5 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x10f, offset 0x7c9 + {value: 0x0000, lo: 0x08}, + {value: 0x0018, lo: 0x80, hi: 0x93}, + {value: 0x0040, lo: 0x94, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x110, offset 0x7d2 + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0x111, offset 0x7d7 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0x112, offset 0x7da + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x113, offset 0x7dd + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x114, offset 0x7e1 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x115, offset 0x7e5 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x116, offset 0x7e8 + {value: 0x0020, lo: 0x0f}, + {value: 0xded1, lo: 0x80, hi: 0x89}, + {value: 0x8e35, lo: 0x8a, hi: 0x8a}, + {value: 0xe011, lo: 0x8b, hi: 0x9c}, + {value: 0x8e55, lo: 0x9d, hi: 0x9d}, + {value: 0xe251, lo: 0x9e, hi: 0xa2}, + {value: 0x8e75, lo: 0xa3, hi: 0xa3}, + {value: 0xe2f1, lo: 0xa4, hi: 0xab}, + {value: 0x7f0d, lo: 0xac, hi: 0xac}, + {value: 0xe3f1, lo: 0xad, hi: 0xaf}, + {value: 0x8e95, lo: 0xb0, hi: 0xb0}, + {value: 0xe451, lo: 0xb1, hi: 0xb6}, + {value: 0x8eb5, lo: 0xb7, hi: 0xb9}, + {value: 0xe511, lo: 0xba, hi: 0xba}, + {value: 0x8f15, lo: 0xbb, hi: 0xbb}, + {value: 0xe531, lo: 0xbc, hi: 0xbf}, + // Block 0x117, offset 0x7f8 + {value: 0x0020, lo: 0x10}, + {value: 0x93b5, lo: 0x80, hi: 0x80}, + {value: 0xf0b1, lo: 0x81, hi: 0x86}, + {value: 0x93d5, lo: 0x87, hi: 0x8a}, + {value: 0xda11, lo: 0x8b, hi: 0x8b}, + {value: 0xf171, lo: 0x8c, hi: 0x96}, + {value: 0x9455, lo: 0x97, hi: 0x97}, + {value: 0xf2d1, lo: 0x98, hi: 0xa3}, + {value: 0x9475, lo: 0xa4, hi: 0xa6}, + {value: 0xf451, lo: 0xa7, hi: 0xaa}, + {value: 0x94d5, lo: 0xab, hi: 0xab}, + {value: 0xf4d1, lo: 0xac, hi: 0xac}, + {value: 0x94f5, lo: 0xad, hi: 0xad}, + {value: 0xf4f1, lo: 0xae, hi: 0xaf}, + {value: 0x9515, lo: 0xb0, hi: 0xb1}, + {value: 0xf531, lo: 0xb2, hi: 0xbe}, + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0x118, offset 0x809 + {value: 0x0000, lo: 0x04}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0340, lo: 0x81, hi: 0x81}, + {value: 0x0040, lo: 0x82, hi: 0x9f}, + {value: 0x0340, lo: 0xa0, hi: 0xbf}, + // Block 0x119, offset 0x80e + {value: 0x0000, lo: 0x01}, + {value: 0x0340, lo: 0x80, hi: 0xbf}, + // Block 0x11a, offset 0x810 + {value: 0x0000, lo: 0x01}, + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x11b, offset 0x812 + {value: 0x0000, lo: 0x02}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, +} + +// Total table size 42780 bytes (41KiB); checksum: 29936AB9 diff --git a/libgo/go/golang.org/x/net/nettest/nettest.go b/libgo/go/golang.org/x/net/nettest/nettest.go index 717bbb06402..a402a46bb33 100644 --- a/libgo/go/golang.org/x/net/nettest/nettest.go +++ b/libgo/go/golang.org/x/net/nettest/nettest.go @@ -20,11 +20,11 @@ import ( ) var ( - stackOnce sync.Once - ipv4Enabled bool - ipv6Enabled bool - rawSocketSess bool - aixTechLvl int + stackOnce sync.Once + ipv4Enabled bool + ipv6Enabled bool + unStrmDgramEnabled bool + rawSocketSess bool aLongTimeAgo = time.Unix(233431200, 0) neverTimeout = time.Time{} @@ -43,17 +43,24 @@ func probeStack() { ipv6Enabled = true } rawSocketSess = supportsRawSocket() - if runtime.GOOS == "aix" { - out, err := exec.Command("oslevel", "-s").Output() - if err == nil { - aixTechLvl, _ = strconv.Atoi(string(out[5:7])) + switch runtime.GOOS { + case "aix": + // Unix network isn't properly working on AIX 7.2 with + // Technical Level < 2. + out, _ := exec.Command("oslevel", "-s").Output() + if len(out) >= len("7200-XX-ZZ-YYMM") { // AIX 7.2, Tech Level XX, Service Pack ZZ, date YYMM + ver := string(out[:4]) + tl, _ := strconv.Atoi(string(out[5:7])) + unStrmDgramEnabled = ver > "7200" || (ver == "7200" && tl >= 2) } + default: + unStrmDgramEnabled = true } } -func aixTechLevel() int { +func unixStrmDgramEnabled() bool { stackOnce.Do(probeStack) - return aixTechLvl + return unStrmDgramEnabled } // SupportsIPv4 reports whether the platform supports IPv4 networking @@ -110,12 +117,7 @@ func TestableNetwork(network string) bool { case "android", "fuchsia", "hurd", "js", "nacl", "plan9", "windows": return false case "aix": - // Unix network isn't properly working on AIX - // 7.2 with Technical Level < 2. - if aixTechLevel() < 2 { - return false - } - return true + return unixStrmDgramEnabled() case "darwin": // iOS does not support unix, unixgram. if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { diff --git a/libgo/go/golang.org/x/net/route/address.go b/libgo/go/golang.org/x/net/route/address.go index e6bfa39e93b..b71528191f6 100644 --- a/libgo/go/golang.org/x/net/route/address.go +++ b/libgo/go/golang.org/x/net/route/address.go @@ -222,7 +222,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) { // the routing message boundary l := int(b[0]) if runtime.GOOS == "darwin" { - // On Darwn, an address in the kernel form is also + // On Darwin, an address in the kernel form is also // used as a message filler. if l == 0 || len(b) > roundup(l) { l = roundup(l) diff --git a/libgo/go/golang.org/x/net/route/message.go b/libgo/go/golang.org/x/net/route/message.go index 0fa7e09f468..80c482ae94a 100644 --- a/libgo/go/golang.org/x/net/route/message.go +++ b/libgo/go/golang.org/x/net/route/message.go @@ -45,7 +45,7 @@ func ParseRIB(typ RIBType, b []byte) ([]Message, error) { if len(b) < l { return nil, errMessageTooShort } - if b[2] != sysRTM_VERSION { + if b[2] != rtmVersion { b = b[l:] continue } diff --git a/libgo/go/golang.org/x/net/route/route.go b/libgo/go/golang.org/x/net/route/route.go index 8cb64f789b3..bba7ed7ef4e 100644 --- a/libgo/go/golang.org/x/net/route/route.go +++ b/libgo/go/golang.org/x/net/route/route.go @@ -73,7 +73,7 @@ type RouteMessage struct { Version int // message version Type int // message type Flags int // route flags - Index int // interface index when atatched + Index int // interface index when attached ID uintptr // sender's identifier; usually process ID Seq int // sequence number Err error // error on requested operation diff --git a/libgo/go/golang.org/x/net/route/route_classic.go b/libgo/go/golang.org/x/net/route/route_classic.go index 02fa688309c..a7d3864646b 100644 --- a/libgo/go/golang.org/x/net/route/route_classic.go +++ b/libgo/go/golang.org/x/net/route/route_classic.go @@ -25,7 +25,7 @@ func (m *RouteMessage) marshal() ([]byte, error) { b := make([]byte, l) nativeEndian.PutUint16(b[:2], uint16(l)) if m.Version == 0 { - b[2] = sysRTM_VERSION + b[2] = rtmVersion } else { b[2] = byte(m.Version) } diff --git a/libgo/go/golang.org/x/net/route/sys.go b/libgo/go/golang.org/x/net/route/sys.go index 13933f9af75..a0ab3e9c73b 100644 --- a/libgo/go/golang.org/x/net/route/sys.go +++ b/libgo/go/golang.org/x/net/route/sys.go @@ -11,6 +11,7 @@ import "unsafe" var ( nativeEndian binaryByteOrder kernelAlign int + rtmVersion byte wireFormats map[int]*wireFormat ) @@ -22,6 +23,8 @@ func init() { } else { nativeEndian = bigEndian } + // might get overridden in probeRoutingStack + rtmVersion = sysRTM_VERSION kernelAlign, wireFormats = probeRoutingStack() } diff --git a/libgo/go/golang.org/x/net/route/sys_dragonfly.go b/libgo/go/golang.org/x/net/route/sys_dragonfly.go index 0c14bc2b4d4..a138951f945 100644 --- a/libgo/go/golang.org/x/net/route/sys_dragonfly.go +++ b/libgo/go/golang.org/x/net/route/sys_dragonfly.go @@ -4,7 +4,10 @@ package route -import "unsafe" +import ( + "syscall" + "unsafe" +) func (typ RIBType) parseable() bool { return true } @@ -56,6 +59,15 @@ func probeRoutingStack() (int, map[int]*wireFormat) { ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage ifanm := &wireFormat{extOff: sizeofIfAnnouncemsghdrDragonFlyBSD4, bodyOff: sizeofIfAnnouncemsghdrDragonFlyBSD4} ifanm.parse = ifanm.parseInterfaceAnnounceMessage + + rel, _ := syscall.SysctlUint32("kern.osreldate") + if rel >= 500705 { + // https://github.com/DragonFlyBSD/DragonFlyBSD/commit/43a373152df2d405c9940983e584e6a25e76632d + // but only the size of struct ifa_msghdr actually changed + rtmVersion = 7 + ifam.bodyOff = sizeofIfaMsghdrDragonFlyBSD58 + } + return int(unsafe.Sizeof(p)), map[int]*wireFormat{ sysRTM_ADD: rtm, sysRTM_DELETE: rtm, diff --git a/libgo/go/golang.org/x/net/route/zsys_dragonfly.go b/libgo/go/golang.org/x/net/route/zsys_dragonfly.go index 8ed2d4d550c..34f0eaaa42b 100644 --- a/libgo/go/golang.org/x/net/route/zsys_dragonfly.go +++ b/libgo/go/golang.org/x/net/route/zsys_dragonfly.go @@ -46,8 +46,6 @@ const ( sysRTM_REDIRECT = 0x6 sysRTM_MISS = 0x7 sysRTM_LOCK = 0x8 - sysRTM_OLDADD = 0x9 - sysRTM_OLDDEL = 0xa sysRTM_RESOLVE = 0xb sysRTM_NEWADDR = 0xc sysRTM_DELADDR = 0xd @@ -89,6 +87,8 @@ const ( sizeofIfmaMsghdrDragonFlyBSD4 = 0x10 sizeofIfAnnouncemsghdrDragonFlyBSD4 = 0x18 + sizeofIfaMsghdrDragonFlyBSD58 = 0x18 + sizeofRtMsghdrDragonFlyBSD4 = 0x98 sizeofRtMetricsDragonFlyBSD4 = 0x70 diff --git a/libgo/go/golang.org/x/text/unicode/bidi/tables11.0.0.go b/libgo/go/golang.org/x/text/unicode/bidi/tables11.0.0.go index 022e3c69092..16b11db5388 100644 --- a/libgo/go/golang.org/x/text/unicode/bidi/tables11.0.0.go +++ b/libgo/go/golang.org/x/text/unicode/bidi/tables11.0.0.go @@ -1,6 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. -// +build go1.13 +// +build go1.13,!go1.14 package bidi diff --git a/libgo/go/golang.org/x/text/unicode/bidi/tables12.0.0.go b/libgo/go/golang.org/x/text/unicode/bidi/tables12.0.0.go new file mode 100644 index 00000000000..7ffa365121c --- /dev/null +++ b/libgo/go/golang.org/x/text/unicode/bidi/tables12.0.0.go @@ -0,0 +1,1923 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.14 + +package bidi + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "12.0.0" + +// xorMasks contains masks to be xor-ed with brackets to get the reverse +// version. +var xorMasks = []int32{ // 8 elements + 0, 1, 6, 7, 3, 15, 29, 63, +} // Size: 56 bytes + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *bidiTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return bidiValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *bidiTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return bidiValues[c0] + } + i := bidiIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *bidiTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return bidiValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := bidiIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = bidiIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = bidiIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *bidiTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return bidiValues[c0] + } + i := bidiIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = bidiIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// bidiTrie. Total size: 16896 bytes (16.50 KiB). Checksum: 6f0927067913dc6d. +type bidiTrie struct{} + +func newBidiTrie(i int) *bidiTrie { + return &bidiTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *bidiTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(bidiValues[n<<6+uint32(b)]) + } +} + +// bidiValues: 240 blocks, 15360 entries, 15360 bytes +// The third block is the zero block. +var bidiValues = [15360]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x000b, 0x01: 0x000b, 0x02: 0x000b, 0x03: 0x000b, 0x04: 0x000b, 0x05: 0x000b, + 0x06: 0x000b, 0x07: 0x000b, 0x08: 0x000b, 0x09: 0x0008, 0x0a: 0x0007, 0x0b: 0x0008, + 0x0c: 0x0009, 0x0d: 0x0007, 0x0e: 0x000b, 0x0f: 0x000b, 0x10: 0x000b, 0x11: 0x000b, + 0x12: 0x000b, 0x13: 0x000b, 0x14: 0x000b, 0x15: 0x000b, 0x16: 0x000b, 0x17: 0x000b, + 0x18: 0x000b, 0x19: 0x000b, 0x1a: 0x000b, 0x1b: 0x000b, 0x1c: 0x0007, 0x1d: 0x0007, + 0x1e: 0x0007, 0x1f: 0x0008, 0x20: 0x0009, 0x21: 0x000a, 0x22: 0x000a, 0x23: 0x0004, + 0x24: 0x0004, 0x25: 0x0004, 0x26: 0x000a, 0x27: 0x000a, 0x28: 0x003a, 0x29: 0x002a, + 0x2a: 0x000a, 0x2b: 0x0003, 0x2c: 0x0006, 0x2d: 0x0003, 0x2e: 0x0006, 0x2f: 0x0006, + 0x30: 0x0002, 0x31: 0x0002, 0x32: 0x0002, 0x33: 0x0002, 0x34: 0x0002, 0x35: 0x0002, + 0x36: 0x0002, 0x37: 0x0002, 0x38: 0x0002, 0x39: 0x0002, 0x3a: 0x0006, 0x3b: 0x000a, + 0x3c: 0x000a, 0x3d: 0x000a, 0x3e: 0x000a, 0x3f: 0x000a, + // Block 0x1, offset 0x40 + 0x40: 0x000a, + 0x5b: 0x005a, 0x5c: 0x000a, 0x5d: 0x004a, + 0x5e: 0x000a, 0x5f: 0x000a, 0x60: 0x000a, + 0x7b: 0x005a, + 0x7c: 0x000a, 0x7d: 0x004a, 0x7e: 0x000a, 0x7f: 0x000b, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x000b, 0xc1: 0x000b, 0xc2: 0x000b, 0xc3: 0x000b, 0xc4: 0x000b, 0xc5: 0x0007, + 0xc6: 0x000b, 0xc7: 0x000b, 0xc8: 0x000b, 0xc9: 0x000b, 0xca: 0x000b, 0xcb: 0x000b, + 0xcc: 0x000b, 0xcd: 0x000b, 0xce: 0x000b, 0xcf: 0x000b, 0xd0: 0x000b, 0xd1: 0x000b, + 0xd2: 0x000b, 0xd3: 0x000b, 0xd4: 0x000b, 0xd5: 0x000b, 0xd6: 0x000b, 0xd7: 0x000b, + 0xd8: 0x000b, 0xd9: 0x000b, 0xda: 0x000b, 0xdb: 0x000b, 0xdc: 0x000b, 0xdd: 0x000b, + 0xde: 0x000b, 0xdf: 0x000b, 0xe0: 0x0006, 0xe1: 0x000a, 0xe2: 0x0004, 0xe3: 0x0004, + 0xe4: 0x0004, 0xe5: 0x0004, 0xe6: 0x000a, 0xe7: 0x000a, 0xe8: 0x000a, 0xe9: 0x000a, + 0xeb: 0x000a, 0xec: 0x000a, 0xed: 0x000b, 0xee: 0x000a, 0xef: 0x000a, + 0xf0: 0x0004, 0xf1: 0x0004, 0xf2: 0x0002, 0xf3: 0x0002, 0xf4: 0x000a, + 0xf6: 0x000a, 0xf7: 0x000a, 0xf8: 0x000a, 0xf9: 0x0002, 0xfb: 0x000a, + 0xfc: 0x000a, 0xfd: 0x000a, 0xfe: 0x000a, 0xff: 0x000a, + // Block 0x4, offset 0x100 + 0x117: 0x000a, + 0x137: 0x000a, + // Block 0x5, offset 0x140 + 0x179: 0x000a, 0x17a: 0x000a, + // Block 0x6, offset 0x180 + 0x182: 0x000a, 0x183: 0x000a, 0x184: 0x000a, 0x185: 0x000a, + 0x186: 0x000a, 0x187: 0x000a, 0x188: 0x000a, 0x189: 0x000a, 0x18a: 0x000a, 0x18b: 0x000a, + 0x18c: 0x000a, 0x18d: 0x000a, 0x18e: 0x000a, 0x18f: 0x000a, + 0x192: 0x000a, 0x193: 0x000a, 0x194: 0x000a, 0x195: 0x000a, 0x196: 0x000a, 0x197: 0x000a, + 0x198: 0x000a, 0x199: 0x000a, 0x19a: 0x000a, 0x19b: 0x000a, 0x19c: 0x000a, 0x19d: 0x000a, + 0x19e: 0x000a, 0x19f: 0x000a, + 0x1a5: 0x000a, 0x1a6: 0x000a, 0x1a7: 0x000a, 0x1a8: 0x000a, 0x1a9: 0x000a, + 0x1aa: 0x000a, 0x1ab: 0x000a, 0x1ac: 0x000a, 0x1ad: 0x000a, 0x1af: 0x000a, + 0x1b0: 0x000a, 0x1b1: 0x000a, 0x1b2: 0x000a, 0x1b3: 0x000a, 0x1b4: 0x000a, 0x1b5: 0x000a, + 0x1b6: 0x000a, 0x1b7: 0x000a, 0x1b8: 0x000a, 0x1b9: 0x000a, 0x1ba: 0x000a, 0x1bb: 0x000a, + 0x1bc: 0x000a, 0x1bd: 0x000a, 0x1be: 0x000a, 0x1bf: 0x000a, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x000c, 0x1c1: 0x000c, 0x1c2: 0x000c, 0x1c3: 0x000c, 0x1c4: 0x000c, 0x1c5: 0x000c, + 0x1c6: 0x000c, 0x1c7: 0x000c, 0x1c8: 0x000c, 0x1c9: 0x000c, 0x1ca: 0x000c, 0x1cb: 0x000c, + 0x1cc: 0x000c, 0x1cd: 0x000c, 0x1ce: 0x000c, 0x1cf: 0x000c, 0x1d0: 0x000c, 0x1d1: 0x000c, + 0x1d2: 0x000c, 0x1d3: 0x000c, 0x1d4: 0x000c, 0x1d5: 0x000c, 0x1d6: 0x000c, 0x1d7: 0x000c, + 0x1d8: 0x000c, 0x1d9: 0x000c, 0x1da: 0x000c, 0x1db: 0x000c, 0x1dc: 0x000c, 0x1dd: 0x000c, + 0x1de: 0x000c, 0x1df: 0x000c, 0x1e0: 0x000c, 0x1e1: 0x000c, 0x1e2: 0x000c, 0x1e3: 0x000c, + 0x1e4: 0x000c, 0x1e5: 0x000c, 0x1e6: 0x000c, 0x1e7: 0x000c, 0x1e8: 0x000c, 0x1e9: 0x000c, + 0x1ea: 0x000c, 0x1eb: 0x000c, 0x1ec: 0x000c, 0x1ed: 0x000c, 0x1ee: 0x000c, 0x1ef: 0x000c, + 0x1f0: 0x000c, 0x1f1: 0x000c, 0x1f2: 0x000c, 0x1f3: 0x000c, 0x1f4: 0x000c, 0x1f5: 0x000c, + 0x1f6: 0x000c, 0x1f7: 0x000c, 0x1f8: 0x000c, 0x1f9: 0x000c, 0x1fa: 0x000c, 0x1fb: 0x000c, + 0x1fc: 0x000c, 0x1fd: 0x000c, 0x1fe: 0x000c, 0x1ff: 0x000c, + // Block 0x8, offset 0x200 + 0x200: 0x000c, 0x201: 0x000c, 0x202: 0x000c, 0x203: 0x000c, 0x204: 0x000c, 0x205: 0x000c, + 0x206: 0x000c, 0x207: 0x000c, 0x208: 0x000c, 0x209: 0x000c, 0x20a: 0x000c, 0x20b: 0x000c, + 0x20c: 0x000c, 0x20d: 0x000c, 0x20e: 0x000c, 0x20f: 0x000c, 0x210: 0x000c, 0x211: 0x000c, + 0x212: 0x000c, 0x213: 0x000c, 0x214: 0x000c, 0x215: 0x000c, 0x216: 0x000c, 0x217: 0x000c, + 0x218: 0x000c, 0x219: 0x000c, 0x21a: 0x000c, 0x21b: 0x000c, 0x21c: 0x000c, 0x21d: 0x000c, + 0x21e: 0x000c, 0x21f: 0x000c, 0x220: 0x000c, 0x221: 0x000c, 0x222: 0x000c, 0x223: 0x000c, + 0x224: 0x000c, 0x225: 0x000c, 0x226: 0x000c, 0x227: 0x000c, 0x228: 0x000c, 0x229: 0x000c, + 0x22a: 0x000c, 0x22b: 0x000c, 0x22c: 0x000c, 0x22d: 0x000c, 0x22e: 0x000c, 0x22f: 0x000c, + 0x234: 0x000a, 0x235: 0x000a, + 0x23e: 0x000a, + // Block 0x9, offset 0x240 + 0x244: 0x000a, 0x245: 0x000a, + 0x247: 0x000a, + // Block 0xa, offset 0x280 + 0x2b6: 0x000a, + // Block 0xb, offset 0x2c0 + 0x2c3: 0x000c, 0x2c4: 0x000c, 0x2c5: 0x000c, + 0x2c6: 0x000c, 0x2c7: 0x000c, 0x2c8: 0x000c, 0x2c9: 0x000c, + // Block 0xc, offset 0x300 + 0x30a: 0x000a, + 0x30d: 0x000a, 0x30e: 0x000a, 0x30f: 0x0004, 0x310: 0x0001, 0x311: 0x000c, + 0x312: 0x000c, 0x313: 0x000c, 0x314: 0x000c, 0x315: 0x000c, 0x316: 0x000c, 0x317: 0x000c, + 0x318: 0x000c, 0x319: 0x000c, 0x31a: 0x000c, 0x31b: 0x000c, 0x31c: 0x000c, 0x31d: 0x000c, + 0x31e: 0x000c, 0x31f: 0x000c, 0x320: 0x000c, 0x321: 0x000c, 0x322: 0x000c, 0x323: 0x000c, + 0x324: 0x000c, 0x325: 0x000c, 0x326: 0x000c, 0x327: 0x000c, 0x328: 0x000c, 0x329: 0x000c, + 0x32a: 0x000c, 0x32b: 0x000c, 0x32c: 0x000c, 0x32d: 0x000c, 0x32e: 0x000c, 0x32f: 0x000c, + 0x330: 0x000c, 0x331: 0x000c, 0x332: 0x000c, 0x333: 0x000c, 0x334: 0x000c, 0x335: 0x000c, + 0x336: 0x000c, 0x337: 0x000c, 0x338: 0x000c, 0x339: 0x000c, 0x33a: 0x000c, 0x33b: 0x000c, + 0x33c: 0x000c, 0x33d: 0x000c, 0x33e: 0x0001, 0x33f: 0x000c, + // Block 0xd, offset 0x340 + 0x340: 0x0001, 0x341: 0x000c, 0x342: 0x000c, 0x343: 0x0001, 0x344: 0x000c, 0x345: 0x000c, + 0x346: 0x0001, 0x347: 0x000c, 0x348: 0x0001, 0x349: 0x0001, 0x34a: 0x0001, 0x34b: 0x0001, + 0x34c: 0x0001, 0x34d: 0x0001, 0x34e: 0x0001, 0x34f: 0x0001, 0x350: 0x0001, 0x351: 0x0001, + 0x352: 0x0001, 0x353: 0x0001, 0x354: 0x0001, 0x355: 0x0001, 0x356: 0x0001, 0x357: 0x0001, + 0x358: 0x0001, 0x359: 0x0001, 0x35a: 0x0001, 0x35b: 0x0001, 0x35c: 0x0001, 0x35d: 0x0001, + 0x35e: 0x0001, 0x35f: 0x0001, 0x360: 0x0001, 0x361: 0x0001, 0x362: 0x0001, 0x363: 0x0001, + 0x364: 0x0001, 0x365: 0x0001, 0x366: 0x0001, 0x367: 0x0001, 0x368: 0x0001, 0x369: 0x0001, + 0x36a: 0x0001, 0x36b: 0x0001, 0x36c: 0x0001, 0x36d: 0x0001, 0x36e: 0x0001, 0x36f: 0x0001, + 0x370: 0x0001, 0x371: 0x0001, 0x372: 0x0001, 0x373: 0x0001, 0x374: 0x0001, 0x375: 0x0001, + 0x376: 0x0001, 0x377: 0x0001, 0x378: 0x0001, 0x379: 0x0001, 0x37a: 0x0001, 0x37b: 0x0001, + 0x37c: 0x0001, 0x37d: 0x0001, 0x37e: 0x0001, 0x37f: 0x0001, + // Block 0xe, offset 0x380 + 0x380: 0x0005, 0x381: 0x0005, 0x382: 0x0005, 0x383: 0x0005, 0x384: 0x0005, 0x385: 0x0005, + 0x386: 0x000a, 0x387: 0x000a, 0x388: 0x000d, 0x389: 0x0004, 0x38a: 0x0004, 0x38b: 0x000d, + 0x38c: 0x0006, 0x38d: 0x000d, 0x38e: 0x000a, 0x38f: 0x000a, 0x390: 0x000c, 0x391: 0x000c, + 0x392: 0x000c, 0x393: 0x000c, 0x394: 0x000c, 0x395: 0x000c, 0x396: 0x000c, 0x397: 0x000c, + 0x398: 0x000c, 0x399: 0x000c, 0x39a: 0x000c, 0x39b: 0x000d, 0x39c: 0x000d, 0x39d: 0x000d, + 0x39e: 0x000d, 0x39f: 0x000d, 0x3a0: 0x000d, 0x3a1: 0x000d, 0x3a2: 0x000d, 0x3a3: 0x000d, + 0x3a4: 0x000d, 0x3a5: 0x000d, 0x3a6: 0x000d, 0x3a7: 0x000d, 0x3a8: 0x000d, 0x3a9: 0x000d, + 0x3aa: 0x000d, 0x3ab: 0x000d, 0x3ac: 0x000d, 0x3ad: 0x000d, 0x3ae: 0x000d, 0x3af: 0x000d, + 0x3b0: 0x000d, 0x3b1: 0x000d, 0x3b2: 0x000d, 0x3b3: 0x000d, 0x3b4: 0x000d, 0x3b5: 0x000d, + 0x3b6: 0x000d, 0x3b7: 0x000d, 0x3b8: 0x000d, 0x3b9: 0x000d, 0x3ba: 0x000d, 0x3bb: 0x000d, + 0x3bc: 0x000d, 0x3bd: 0x000d, 0x3be: 0x000d, 0x3bf: 0x000d, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x000d, 0x3c1: 0x000d, 0x3c2: 0x000d, 0x3c3: 0x000d, 0x3c4: 0x000d, 0x3c5: 0x000d, + 0x3c6: 0x000d, 0x3c7: 0x000d, 0x3c8: 0x000d, 0x3c9: 0x000d, 0x3ca: 0x000d, 0x3cb: 0x000c, + 0x3cc: 0x000c, 0x3cd: 0x000c, 0x3ce: 0x000c, 0x3cf: 0x000c, 0x3d0: 0x000c, 0x3d1: 0x000c, + 0x3d2: 0x000c, 0x3d3: 0x000c, 0x3d4: 0x000c, 0x3d5: 0x000c, 0x3d6: 0x000c, 0x3d7: 0x000c, + 0x3d8: 0x000c, 0x3d9: 0x000c, 0x3da: 0x000c, 0x3db: 0x000c, 0x3dc: 0x000c, 0x3dd: 0x000c, + 0x3de: 0x000c, 0x3df: 0x000c, 0x3e0: 0x0005, 0x3e1: 0x0005, 0x3e2: 0x0005, 0x3e3: 0x0005, + 0x3e4: 0x0005, 0x3e5: 0x0005, 0x3e6: 0x0005, 0x3e7: 0x0005, 0x3e8: 0x0005, 0x3e9: 0x0005, + 0x3ea: 0x0004, 0x3eb: 0x0005, 0x3ec: 0x0005, 0x3ed: 0x000d, 0x3ee: 0x000d, 0x3ef: 0x000d, + 0x3f0: 0x000c, 0x3f1: 0x000d, 0x3f2: 0x000d, 0x3f3: 0x000d, 0x3f4: 0x000d, 0x3f5: 0x000d, + 0x3f6: 0x000d, 0x3f7: 0x000d, 0x3f8: 0x000d, 0x3f9: 0x000d, 0x3fa: 0x000d, 0x3fb: 0x000d, + 0x3fc: 0x000d, 0x3fd: 0x000d, 0x3fe: 0x000d, 0x3ff: 0x000d, + // Block 0x10, offset 0x400 + 0x400: 0x000d, 0x401: 0x000d, 0x402: 0x000d, 0x403: 0x000d, 0x404: 0x000d, 0x405: 0x000d, + 0x406: 0x000d, 0x407: 0x000d, 0x408: 0x000d, 0x409: 0x000d, 0x40a: 0x000d, 0x40b: 0x000d, + 0x40c: 0x000d, 0x40d: 0x000d, 0x40e: 0x000d, 0x40f: 0x000d, 0x410: 0x000d, 0x411: 0x000d, + 0x412: 0x000d, 0x413: 0x000d, 0x414: 0x000d, 0x415: 0x000d, 0x416: 0x000d, 0x417: 0x000d, + 0x418: 0x000d, 0x419: 0x000d, 0x41a: 0x000d, 0x41b: 0x000d, 0x41c: 0x000d, 0x41d: 0x000d, + 0x41e: 0x000d, 0x41f: 0x000d, 0x420: 0x000d, 0x421: 0x000d, 0x422: 0x000d, 0x423: 0x000d, + 0x424: 0x000d, 0x425: 0x000d, 0x426: 0x000d, 0x427: 0x000d, 0x428: 0x000d, 0x429: 0x000d, + 0x42a: 0x000d, 0x42b: 0x000d, 0x42c: 0x000d, 0x42d: 0x000d, 0x42e: 0x000d, 0x42f: 0x000d, + 0x430: 0x000d, 0x431: 0x000d, 0x432: 0x000d, 0x433: 0x000d, 0x434: 0x000d, 0x435: 0x000d, + 0x436: 0x000d, 0x437: 0x000d, 0x438: 0x000d, 0x439: 0x000d, 0x43a: 0x000d, 0x43b: 0x000d, + 0x43c: 0x000d, 0x43d: 0x000d, 0x43e: 0x000d, 0x43f: 0x000d, + // Block 0x11, offset 0x440 + 0x440: 0x000d, 0x441: 0x000d, 0x442: 0x000d, 0x443: 0x000d, 0x444: 0x000d, 0x445: 0x000d, + 0x446: 0x000d, 0x447: 0x000d, 0x448: 0x000d, 0x449: 0x000d, 0x44a: 0x000d, 0x44b: 0x000d, + 0x44c: 0x000d, 0x44d: 0x000d, 0x44e: 0x000d, 0x44f: 0x000d, 0x450: 0x000d, 0x451: 0x000d, + 0x452: 0x000d, 0x453: 0x000d, 0x454: 0x000d, 0x455: 0x000d, 0x456: 0x000c, 0x457: 0x000c, + 0x458: 0x000c, 0x459: 0x000c, 0x45a: 0x000c, 0x45b: 0x000c, 0x45c: 0x000c, 0x45d: 0x0005, + 0x45e: 0x000a, 0x45f: 0x000c, 0x460: 0x000c, 0x461: 0x000c, 0x462: 0x000c, 0x463: 0x000c, + 0x464: 0x000c, 0x465: 0x000d, 0x466: 0x000d, 0x467: 0x000c, 0x468: 0x000c, 0x469: 0x000a, + 0x46a: 0x000c, 0x46b: 0x000c, 0x46c: 0x000c, 0x46d: 0x000c, 0x46e: 0x000d, 0x46f: 0x000d, + 0x470: 0x0002, 0x471: 0x0002, 0x472: 0x0002, 0x473: 0x0002, 0x474: 0x0002, 0x475: 0x0002, + 0x476: 0x0002, 0x477: 0x0002, 0x478: 0x0002, 0x479: 0x0002, 0x47a: 0x000d, 0x47b: 0x000d, + 0x47c: 0x000d, 0x47d: 0x000d, 0x47e: 0x000d, 0x47f: 0x000d, + // Block 0x12, offset 0x480 + 0x480: 0x000d, 0x481: 0x000d, 0x482: 0x000d, 0x483: 0x000d, 0x484: 0x000d, 0x485: 0x000d, + 0x486: 0x000d, 0x487: 0x000d, 0x488: 0x000d, 0x489: 0x000d, 0x48a: 0x000d, 0x48b: 0x000d, + 0x48c: 0x000d, 0x48d: 0x000d, 0x48e: 0x000d, 0x48f: 0x000d, 0x490: 0x000d, 0x491: 0x000c, + 0x492: 0x000d, 0x493: 0x000d, 0x494: 0x000d, 0x495: 0x000d, 0x496: 0x000d, 0x497: 0x000d, + 0x498: 0x000d, 0x499: 0x000d, 0x49a: 0x000d, 0x49b: 0x000d, 0x49c: 0x000d, 0x49d: 0x000d, + 0x49e: 0x000d, 0x49f: 0x000d, 0x4a0: 0x000d, 0x4a1: 0x000d, 0x4a2: 0x000d, 0x4a3: 0x000d, + 0x4a4: 0x000d, 0x4a5: 0x000d, 0x4a6: 0x000d, 0x4a7: 0x000d, 0x4a8: 0x000d, 0x4a9: 0x000d, + 0x4aa: 0x000d, 0x4ab: 0x000d, 0x4ac: 0x000d, 0x4ad: 0x000d, 0x4ae: 0x000d, 0x4af: 0x000d, + 0x4b0: 0x000c, 0x4b1: 0x000c, 0x4b2: 0x000c, 0x4b3: 0x000c, 0x4b4: 0x000c, 0x4b5: 0x000c, + 0x4b6: 0x000c, 0x4b7: 0x000c, 0x4b8: 0x000c, 0x4b9: 0x000c, 0x4ba: 0x000c, 0x4bb: 0x000c, + 0x4bc: 0x000c, 0x4bd: 0x000c, 0x4be: 0x000c, 0x4bf: 0x000c, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x000c, 0x4c1: 0x000c, 0x4c2: 0x000c, 0x4c3: 0x000c, 0x4c4: 0x000c, 0x4c5: 0x000c, + 0x4c6: 0x000c, 0x4c7: 0x000c, 0x4c8: 0x000c, 0x4c9: 0x000c, 0x4ca: 0x000c, 0x4cb: 0x000d, + 0x4cc: 0x000d, 0x4cd: 0x000d, 0x4ce: 0x000d, 0x4cf: 0x000d, 0x4d0: 0x000d, 0x4d1: 0x000d, + 0x4d2: 0x000d, 0x4d3: 0x000d, 0x4d4: 0x000d, 0x4d5: 0x000d, 0x4d6: 0x000d, 0x4d7: 0x000d, + 0x4d8: 0x000d, 0x4d9: 0x000d, 0x4da: 0x000d, 0x4db: 0x000d, 0x4dc: 0x000d, 0x4dd: 0x000d, + 0x4de: 0x000d, 0x4df: 0x000d, 0x4e0: 0x000d, 0x4e1: 0x000d, 0x4e2: 0x000d, 0x4e3: 0x000d, + 0x4e4: 0x000d, 0x4e5: 0x000d, 0x4e6: 0x000d, 0x4e7: 0x000d, 0x4e8: 0x000d, 0x4e9: 0x000d, + 0x4ea: 0x000d, 0x4eb: 0x000d, 0x4ec: 0x000d, 0x4ed: 0x000d, 0x4ee: 0x000d, 0x4ef: 0x000d, + 0x4f0: 0x000d, 0x4f1: 0x000d, 0x4f2: 0x000d, 0x4f3: 0x000d, 0x4f4: 0x000d, 0x4f5: 0x000d, + 0x4f6: 0x000d, 0x4f7: 0x000d, 0x4f8: 0x000d, 0x4f9: 0x000d, 0x4fa: 0x000d, 0x4fb: 0x000d, + 0x4fc: 0x000d, 0x4fd: 0x000d, 0x4fe: 0x000d, 0x4ff: 0x000d, + // Block 0x14, offset 0x500 + 0x500: 0x000d, 0x501: 0x000d, 0x502: 0x000d, 0x503: 0x000d, 0x504: 0x000d, 0x505: 0x000d, + 0x506: 0x000d, 0x507: 0x000d, 0x508: 0x000d, 0x509: 0x000d, 0x50a: 0x000d, 0x50b: 0x000d, + 0x50c: 0x000d, 0x50d: 0x000d, 0x50e: 0x000d, 0x50f: 0x000d, 0x510: 0x000d, 0x511: 0x000d, + 0x512: 0x000d, 0x513: 0x000d, 0x514: 0x000d, 0x515: 0x000d, 0x516: 0x000d, 0x517: 0x000d, + 0x518: 0x000d, 0x519: 0x000d, 0x51a: 0x000d, 0x51b: 0x000d, 0x51c: 0x000d, 0x51d: 0x000d, + 0x51e: 0x000d, 0x51f: 0x000d, 0x520: 0x000d, 0x521: 0x000d, 0x522: 0x000d, 0x523: 0x000d, + 0x524: 0x000d, 0x525: 0x000d, 0x526: 0x000c, 0x527: 0x000c, 0x528: 0x000c, 0x529: 0x000c, + 0x52a: 0x000c, 0x52b: 0x000c, 0x52c: 0x000c, 0x52d: 0x000c, 0x52e: 0x000c, 0x52f: 0x000c, + 0x530: 0x000c, 0x531: 0x000d, 0x532: 0x000d, 0x533: 0x000d, 0x534: 0x000d, 0x535: 0x000d, + 0x536: 0x000d, 0x537: 0x000d, 0x538: 0x000d, 0x539: 0x000d, 0x53a: 0x000d, 0x53b: 0x000d, + 0x53c: 0x000d, 0x53d: 0x000d, 0x53e: 0x000d, 0x53f: 0x000d, + // Block 0x15, offset 0x540 + 0x540: 0x0001, 0x541: 0x0001, 0x542: 0x0001, 0x543: 0x0001, 0x544: 0x0001, 0x545: 0x0001, + 0x546: 0x0001, 0x547: 0x0001, 0x548: 0x0001, 0x549: 0x0001, 0x54a: 0x0001, 0x54b: 0x0001, + 0x54c: 0x0001, 0x54d: 0x0001, 0x54e: 0x0001, 0x54f: 0x0001, 0x550: 0x0001, 0x551: 0x0001, + 0x552: 0x0001, 0x553: 0x0001, 0x554: 0x0001, 0x555: 0x0001, 0x556: 0x0001, 0x557: 0x0001, + 0x558: 0x0001, 0x559: 0x0001, 0x55a: 0x0001, 0x55b: 0x0001, 0x55c: 0x0001, 0x55d: 0x0001, + 0x55e: 0x0001, 0x55f: 0x0001, 0x560: 0x0001, 0x561: 0x0001, 0x562: 0x0001, 0x563: 0x0001, + 0x564: 0x0001, 0x565: 0x0001, 0x566: 0x0001, 0x567: 0x0001, 0x568: 0x0001, 0x569: 0x0001, + 0x56a: 0x0001, 0x56b: 0x000c, 0x56c: 0x000c, 0x56d: 0x000c, 0x56e: 0x000c, 0x56f: 0x000c, + 0x570: 0x000c, 0x571: 0x000c, 0x572: 0x000c, 0x573: 0x000c, 0x574: 0x0001, 0x575: 0x0001, + 0x576: 0x000a, 0x577: 0x000a, 0x578: 0x000a, 0x579: 0x000a, 0x57a: 0x0001, 0x57b: 0x0001, + 0x57c: 0x0001, 0x57d: 0x000c, 0x57e: 0x0001, 0x57f: 0x0001, + // Block 0x16, offset 0x580 + 0x580: 0x0001, 0x581: 0x0001, 0x582: 0x0001, 0x583: 0x0001, 0x584: 0x0001, 0x585: 0x0001, + 0x586: 0x0001, 0x587: 0x0001, 0x588: 0x0001, 0x589: 0x0001, 0x58a: 0x0001, 0x58b: 0x0001, + 0x58c: 0x0001, 0x58d: 0x0001, 0x58e: 0x0001, 0x58f: 0x0001, 0x590: 0x0001, 0x591: 0x0001, + 0x592: 0x0001, 0x593: 0x0001, 0x594: 0x0001, 0x595: 0x0001, 0x596: 0x000c, 0x597: 0x000c, + 0x598: 0x000c, 0x599: 0x000c, 0x59a: 0x0001, 0x59b: 0x000c, 0x59c: 0x000c, 0x59d: 0x000c, + 0x59e: 0x000c, 0x59f: 0x000c, 0x5a0: 0x000c, 0x5a1: 0x000c, 0x5a2: 0x000c, 0x5a3: 0x000c, + 0x5a4: 0x0001, 0x5a5: 0x000c, 0x5a6: 0x000c, 0x5a7: 0x000c, 0x5a8: 0x0001, 0x5a9: 0x000c, + 0x5aa: 0x000c, 0x5ab: 0x000c, 0x5ac: 0x000c, 0x5ad: 0x000c, 0x5ae: 0x0001, 0x5af: 0x0001, + 0x5b0: 0x0001, 0x5b1: 0x0001, 0x5b2: 0x0001, 0x5b3: 0x0001, 0x5b4: 0x0001, 0x5b5: 0x0001, + 0x5b6: 0x0001, 0x5b7: 0x0001, 0x5b8: 0x0001, 0x5b9: 0x0001, 0x5ba: 0x0001, 0x5bb: 0x0001, + 0x5bc: 0x0001, 0x5bd: 0x0001, 0x5be: 0x0001, 0x5bf: 0x0001, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x0001, 0x5c1: 0x0001, 0x5c2: 0x0001, 0x5c3: 0x0001, 0x5c4: 0x0001, 0x5c5: 0x0001, + 0x5c6: 0x0001, 0x5c7: 0x0001, 0x5c8: 0x0001, 0x5c9: 0x0001, 0x5ca: 0x0001, 0x5cb: 0x0001, + 0x5cc: 0x0001, 0x5cd: 0x0001, 0x5ce: 0x0001, 0x5cf: 0x0001, 0x5d0: 0x0001, 0x5d1: 0x0001, + 0x5d2: 0x0001, 0x5d3: 0x0001, 0x5d4: 0x0001, 0x5d5: 0x0001, 0x5d6: 0x0001, 0x5d7: 0x0001, + 0x5d8: 0x0001, 0x5d9: 0x000c, 0x5da: 0x000c, 0x5db: 0x000c, 0x5dc: 0x0001, 0x5dd: 0x0001, + 0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x000d, 0x5e1: 0x000d, 0x5e2: 0x000d, 0x5e3: 0x000d, + 0x5e4: 0x000d, 0x5e5: 0x000d, 0x5e6: 0x000d, 0x5e7: 0x000d, 0x5e8: 0x000d, 0x5e9: 0x000d, + 0x5ea: 0x000d, 0x5eb: 0x000d, 0x5ec: 0x000d, 0x5ed: 0x000d, 0x5ee: 0x000d, 0x5ef: 0x000d, + 0x5f0: 0x0001, 0x5f1: 0x0001, 0x5f2: 0x0001, 0x5f3: 0x0001, 0x5f4: 0x0001, 0x5f5: 0x0001, + 0x5f6: 0x0001, 0x5f7: 0x0001, 0x5f8: 0x0001, 0x5f9: 0x0001, 0x5fa: 0x0001, 0x5fb: 0x0001, + 0x5fc: 0x0001, 0x5fd: 0x0001, 0x5fe: 0x0001, 0x5ff: 0x0001, + // Block 0x18, offset 0x600 + 0x600: 0x0001, 0x601: 0x0001, 0x602: 0x0001, 0x603: 0x0001, 0x604: 0x0001, 0x605: 0x0001, + 0x606: 0x0001, 0x607: 0x0001, 0x608: 0x0001, 0x609: 0x0001, 0x60a: 0x0001, 0x60b: 0x0001, + 0x60c: 0x0001, 0x60d: 0x0001, 0x60e: 0x0001, 0x60f: 0x0001, 0x610: 0x0001, 0x611: 0x0001, + 0x612: 0x0001, 0x613: 0x0001, 0x614: 0x0001, 0x615: 0x0001, 0x616: 0x0001, 0x617: 0x0001, + 0x618: 0x0001, 0x619: 0x0001, 0x61a: 0x0001, 0x61b: 0x0001, 0x61c: 0x0001, 0x61d: 0x0001, + 0x61e: 0x0001, 0x61f: 0x0001, 0x620: 0x000d, 0x621: 0x000d, 0x622: 0x000d, 0x623: 0x000d, + 0x624: 0x000d, 0x625: 0x000d, 0x626: 0x000d, 0x627: 0x000d, 0x628: 0x000d, 0x629: 0x000d, + 0x62a: 0x000d, 0x62b: 0x000d, 0x62c: 0x000d, 0x62d: 0x000d, 0x62e: 0x000d, 0x62f: 0x000d, + 0x630: 0x000d, 0x631: 0x000d, 0x632: 0x000d, 0x633: 0x000d, 0x634: 0x000d, 0x635: 0x000d, + 0x636: 0x000d, 0x637: 0x000d, 0x638: 0x000d, 0x639: 0x000d, 0x63a: 0x000d, 0x63b: 0x000d, + 0x63c: 0x000d, 0x63d: 0x000d, 0x63e: 0x000d, 0x63f: 0x000d, + // Block 0x19, offset 0x640 + 0x640: 0x000d, 0x641: 0x000d, 0x642: 0x000d, 0x643: 0x000d, 0x644: 0x000d, 0x645: 0x000d, + 0x646: 0x000d, 0x647: 0x000d, 0x648: 0x000d, 0x649: 0x000d, 0x64a: 0x000d, 0x64b: 0x000d, + 0x64c: 0x000d, 0x64d: 0x000d, 0x64e: 0x000d, 0x64f: 0x000d, 0x650: 0x000d, 0x651: 0x000d, + 0x652: 0x000d, 0x653: 0x000c, 0x654: 0x000c, 0x655: 0x000c, 0x656: 0x000c, 0x657: 0x000c, + 0x658: 0x000c, 0x659: 0x000c, 0x65a: 0x000c, 0x65b: 0x000c, 0x65c: 0x000c, 0x65d: 0x000c, + 0x65e: 0x000c, 0x65f: 0x000c, 0x660: 0x000c, 0x661: 0x000c, 0x662: 0x0005, 0x663: 0x000c, + 0x664: 0x000c, 0x665: 0x000c, 0x666: 0x000c, 0x667: 0x000c, 0x668: 0x000c, 0x669: 0x000c, + 0x66a: 0x000c, 0x66b: 0x000c, 0x66c: 0x000c, 0x66d: 0x000c, 0x66e: 0x000c, 0x66f: 0x000c, + 0x670: 0x000c, 0x671: 0x000c, 0x672: 0x000c, 0x673: 0x000c, 0x674: 0x000c, 0x675: 0x000c, + 0x676: 0x000c, 0x677: 0x000c, 0x678: 0x000c, 0x679: 0x000c, 0x67a: 0x000c, 0x67b: 0x000c, + 0x67c: 0x000c, 0x67d: 0x000c, 0x67e: 0x000c, 0x67f: 0x000c, + // Block 0x1a, offset 0x680 + 0x680: 0x000c, 0x681: 0x000c, 0x682: 0x000c, + 0x6ba: 0x000c, + 0x6bc: 0x000c, + // Block 0x1b, offset 0x6c0 + 0x6c1: 0x000c, 0x6c2: 0x000c, 0x6c3: 0x000c, 0x6c4: 0x000c, 0x6c5: 0x000c, + 0x6c6: 0x000c, 0x6c7: 0x000c, 0x6c8: 0x000c, + 0x6cd: 0x000c, 0x6d1: 0x000c, + 0x6d2: 0x000c, 0x6d3: 0x000c, 0x6d4: 0x000c, 0x6d5: 0x000c, 0x6d6: 0x000c, 0x6d7: 0x000c, + 0x6e2: 0x000c, 0x6e3: 0x000c, + // Block 0x1c, offset 0x700 + 0x701: 0x000c, + 0x73c: 0x000c, + // Block 0x1d, offset 0x740 + 0x741: 0x000c, 0x742: 0x000c, 0x743: 0x000c, 0x744: 0x000c, + 0x74d: 0x000c, + 0x762: 0x000c, 0x763: 0x000c, + 0x772: 0x0004, 0x773: 0x0004, + 0x77b: 0x0004, + 0x77e: 0x000c, + // Block 0x1e, offset 0x780 + 0x781: 0x000c, 0x782: 0x000c, + 0x7bc: 0x000c, + // Block 0x1f, offset 0x7c0 + 0x7c1: 0x000c, 0x7c2: 0x000c, + 0x7c7: 0x000c, 0x7c8: 0x000c, 0x7cb: 0x000c, + 0x7cc: 0x000c, 0x7cd: 0x000c, 0x7d1: 0x000c, + 0x7f0: 0x000c, 0x7f1: 0x000c, 0x7f5: 0x000c, + // Block 0x20, offset 0x800 + 0x801: 0x000c, 0x802: 0x000c, 0x803: 0x000c, 0x804: 0x000c, 0x805: 0x000c, + 0x807: 0x000c, 0x808: 0x000c, + 0x80d: 0x000c, + 0x822: 0x000c, 0x823: 0x000c, + 0x831: 0x0004, + 0x83a: 0x000c, 0x83b: 0x000c, + 0x83c: 0x000c, 0x83d: 0x000c, 0x83e: 0x000c, 0x83f: 0x000c, + // Block 0x21, offset 0x840 + 0x841: 0x000c, + 0x87c: 0x000c, 0x87f: 0x000c, + // Block 0x22, offset 0x880 + 0x881: 0x000c, 0x882: 0x000c, 0x883: 0x000c, 0x884: 0x000c, + 0x88d: 0x000c, + 0x896: 0x000c, + 0x8a2: 0x000c, 0x8a3: 0x000c, + // Block 0x23, offset 0x8c0 + 0x8c2: 0x000c, + // Block 0x24, offset 0x900 + 0x900: 0x000c, + 0x90d: 0x000c, + 0x933: 0x000a, 0x934: 0x000a, 0x935: 0x000a, + 0x936: 0x000a, 0x937: 0x000a, 0x938: 0x000a, 0x939: 0x0004, 0x93a: 0x000a, + // Block 0x25, offset 0x940 + 0x940: 0x000c, 0x944: 0x000c, + 0x97e: 0x000c, 0x97f: 0x000c, + // Block 0x26, offset 0x980 + 0x980: 0x000c, + 0x986: 0x000c, 0x987: 0x000c, 0x988: 0x000c, 0x98a: 0x000c, 0x98b: 0x000c, + 0x98c: 0x000c, 0x98d: 0x000c, + 0x995: 0x000c, 0x996: 0x000c, + 0x9a2: 0x000c, 0x9a3: 0x000c, + 0x9b8: 0x000a, 0x9b9: 0x000a, 0x9ba: 0x000a, 0x9bb: 0x000a, + 0x9bc: 0x000a, 0x9bd: 0x000a, 0x9be: 0x000a, + // Block 0x27, offset 0x9c0 + 0x9cc: 0x000c, 0x9cd: 0x000c, + 0x9e2: 0x000c, 0x9e3: 0x000c, + // Block 0x28, offset 0xa00 + 0xa00: 0x000c, 0xa01: 0x000c, + 0xa3b: 0x000c, + 0xa3c: 0x000c, + // Block 0x29, offset 0xa40 + 0xa41: 0x000c, 0xa42: 0x000c, 0xa43: 0x000c, 0xa44: 0x000c, + 0xa4d: 0x000c, + 0xa62: 0x000c, 0xa63: 0x000c, + // Block 0x2a, offset 0xa80 + 0xa8a: 0x000c, + 0xa92: 0x000c, 0xa93: 0x000c, 0xa94: 0x000c, 0xa96: 0x000c, + // Block 0x2b, offset 0xac0 + 0xaf1: 0x000c, 0xaf4: 0x000c, 0xaf5: 0x000c, + 0xaf6: 0x000c, 0xaf7: 0x000c, 0xaf8: 0x000c, 0xaf9: 0x000c, 0xafa: 0x000c, + 0xaff: 0x0004, + // Block 0x2c, offset 0xb00 + 0xb07: 0x000c, 0xb08: 0x000c, 0xb09: 0x000c, 0xb0a: 0x000c, 0xb0b: 0x000c, + 0xb0c: 0x000c, 0xb0d: 0x000c, 0xb0e: 0x000c, + // Block 0x2d, offset 0xb40 + 0xb71: 0x000c, 0xb74: 0x000c, 0xb75: 0x000c, + 0xb76: 0x000c, 0xb77: 0x000c, 0xb78: 0x000c, 0xb79: 0x000c, 0xb7a: 0x000c, 0xb7b: 0x000c, + 0xb7c: 0x000c, + // Block 0x2e, offset 0xb80 + 0xb88: 0x000c, 0xb89: 0x000c, 0xb8a: 0x000c, 0xb8b: 0x000c, + 0xb8c: 0x000c, 0xb8d: 0x000c, + // Block 0x2f, offset 0xbc0 + 0xbd8: 0x000c, 0xbd9: 0x000c, + 0xbf5: 0x000c, + 0xbf7: 0x000c, 0xbf9: 0x000c, 0xbfa: 0x003a, 0xbfb: 0x002a, + 0xbfc: 0x003a, 0xbfd: 0x002a, + // Block 0x30, offset 0xc00 + 0xc31: 0x000c, 0xc32: 0x000c, 0xc33: 0x000c, 0xc34: 0x000c, 0xc35: 0x000c, + 0xc36: 0x000c, 0xc37: 0x000c, 0xc38: 0x000c, 0xc39: 0x000c, 0xc3a: 0x000c, 0xc3b: 0x000c, + 0xc3c: 0x000c, 0xc3d: 0x000c, 0xc3e: 0x000c, + // Block 0x31, offset 0xc40 + 0xc40: 0x000c, 0xc41: 0x000c, 0xc42: 0x000c, 0xc43: 0x000c, 0xc44: 0x000c, + 0xc46: 0x000c, 0xc47: 0x000c, + 0xc4d: 0x000c, 0xc4e: 0x000c, 0xc4f: 0x000c, 0xc50: 0x000c, 0xc51: 0x000c, + 0xc52: 0x000c, 0xc53: 0x000c, 0xc54: 0x000c, 0xc55: 0x000c, 0xc56: 0x000c, 0xc57: 0x000c, + 0xc59: 0x000c, 0xc5a: 0x000c, 0xc5b: 0x000c, 0xc5c: 0x000c, 0xc5d: 0x000c, + 0xc5e: 0x000c, 0xc5f: 0x000c, 0xc60: 0x000c, 0xc61: 0x000c, 0xc62: 0x000c, 0xc63: 0x000c, + 0xc64: 0x000c, 0xc65: 0x000c, 0xc66: 0x000c, 0xc67: 0x000c, 0xc68: 0x000c, 0xc69: 0x000c, + 0xc6a: 0x000c, 0xc6b: 0x000c, 0xc6c: 0x000c, 0xc6d: 0x000c, 0xc6e: 0x000c, 0xc6f: 0x000c, + 0xc70: 0x000c, 0xc71: 0x000c, 0xc72: 0x000c, 0xc73: 0x000c, 0xc74: 0x000c, 0xc75: 0x000c, + 0xc76: 0x000c, 0xc77: 0x000c, 0xc78: 0x000c, 0xc79: 0x000c, 0xc7a: 0x000c, 0xc7b: 0x000c, + 0xc7c: 0x000c, + // Block 0x32, offset 0xc80 + 0xc86: 0x000c, + // Block 0x33, offset 0xcc0 + 0xced: 0x000c, 0xcee: 0x000c, 0xcef: 0x000c, + 0xcf0: 0x000c, 0xcf2: 0x000c, 0xcf3: 0x000c, 0xcf4: 0x000c, 0xcf5: 0x000c, + 0xcf6: 0x000c, 0xcf7: 0x000c, 0xcf9: 0x000c, 0xcfa: 0x000c, + 0xcfd: 0x000c, 0xcfe: 0x000c, + // Block 0x34, offset 0xd00 + 0xd18: 0x000c, 0xd19: 0x000c, + 0xd1e: 0x000c, 0xd1f: 0x000c, 0xd20: 0x000c, + 0xd31: 0x000c, 0xd32: 0x000c, 0xd33: 0x000c, 0xd34: 0x000c, + // Block 0x35, offset 0xd40 + 0xd42: 0x000c, 0xd45: 0x000c, + 0xd46: 0x000c, + 0xd4d: 0x000c, + 0xd5d: 0x000c, + // Block 0x36, offset 0xd80 + 0xd9d: 0x000c, + 0xd9e: 0x000c, 0xd9f: 0x000c, + // Block 0x37, offset 0xdc0 + 0xdd0: 0x000a, 0xdd1: 0x000a, + 0xdd2: 0x000a, 0xdd3: 0x000a, 0xdd4: 0x000a, 0xdd5: 0x000a, 0xdd6: 0x000a, 0xdd7: 0x000a, + 0xdd8: 0x000a, 0xdd9: 0x000a, + // Block 0x38, offset 0xe00 + 0xe00: 0x000a, + // Block 0x39, offset 0xe40 + 0xe40: 0x0009, + 0xe5b: 0x007a, 0xe5c: 0x006a, + // Block 0x3a, offset 0xe80 + 0xe92: 0x000c, 0xe93: 0x000c, 0xe94: 0x000c, + 0xeb2: 0x000c, 0xeb3: 0x000c, 0xeb4: 0x000c, + // Block 0x3b, offset 0xec0 + 0xed2: 0x000c, 0xed3: 0x000c, + 0xef2: 0x000c, 0xef3: 0x000c, + // Block 0x3c, offset 0xf00 + 0xf34: 0x000c, 0xf35: 0x000c, + 0xf37: 0x000c, 0xf38: 0x000c, 0xf39: 0x000c, 0xf3a: 0x000c, 0xf3b: 0x000c, + 0xf3c: 0x000c, 0xf3d: 0x000c, + // Block 0x3d, offset 0xf40 + 0xf46: 0x000c, 0xf49: 0x000c, 0xf4a: 0x000c, 0xf4b: 0x000c, + 0xf4c: 0x000c, 0xf4d: 0x000c, 0xf4e: 0x000c, 0xf4f: 0x000c, 0xf50: 0x000c, 0xf51: 0x000c, + 0xf52: 0x000c, 0xf53: 0x000c, + 0xf5b: 0x0004, 0xf5d: 0x000c, + 0xf70: 0x000a, 0xf71: 0x000a, 0xf72: 0x000a, 0xf73: 0x000a, 0xf74: 0x000a, 0xf75: 0x000a, + 0xf76: 0x000a, 0xf77: 0x000a, 0xf78: 0x000a, 0xf79: 0x000a, + // Block 0x3e, offset 0xf80 + 0xf80: 0x000a, 0xf81: 0x000a, 0xf82: 0x000a, 0xf83: 0x000a, 0xf84: 0x000a, 0xf85: 0x000a, + 0xf86: 0x000a, 0xf87: 0x000a, 0xf88: 0x000a, 0xf89: 0x000a, 0xf8a: 0x000a, 0xf8b: 0x000c, + 0xf8c: 0x000c, 0xf8d: 0x000c, 0xf8e: 0x000b, + // Block 0x3f, offset 0xfc0 + 0xfc5: 0x000c, + 0xfc6: 0x000c, + 0xfe9: 0x000c, + // Block 0x40, offset 0x1000 + 0x1020: 0x000c, 0x1021: 0x000c, 0x1022: 0x000c, + 0x1027: 0x000c, 0x1028: 0x000c, + 0x1032: 0x000c, + 0x1039: 0x000c, 0x103a: 0x000c, 0x103b: 0x000c, + // Block 0x41, offset 0x1040 + 0x1040: 0x000a, 0x1044: 0x000a, 0x1045: 0x000a, + // Block 0x42, offset 0x1080 + 0x109e: 0x000a, 0x109f: 0x000a, 0x10a0: 0x000a, 0x10a1: 0x000a, 0x10a2: 0x000a, 0x10a3: 0x000a, + 0x10a4: 0x000a, 0x10a5: 0x000a, 0x10a6: 0x000a, 0x10a7: 0x000a, 0x10a8: 0x000a, 0x10a9: 0x000a, + 0x10aa: 0x000a, 0x10ab: 0x000a, 0x10ac: 0x000a, 0x10ad: 0x000a, 0x10ae: 0x000a, 0x10af: 0x000a, + 0x10b0: 0x000a, 0x10b1: 0x000a, 0x10b2: 0x000a, 0x10b3: 0x000a, 0x10b4: 0x000a, 0x10b5: 0x000a, + 0x10b6: 0x000a, 0x10b7: 0x000a, 0x10b8: 0x000a, 0x10b9: 0x000a, 0x10ba: 0x000a, 0x10bb: 0x000a, + 0x10bc: 0x000a, 0x10bd: 0x000a, 0x10be: 0x000a, 0x10bf: 0x000a, + // Block 0x43, offset 0x10c0 + 0x10d7: 0x000c, + 0x10d8: 0x000c, 0x10db: 0x000c, + // Block 0x44, offset 0x1100 + 0x1116: 0x000c, + 0x1118: 0x000c, 0x1119: 0x000c, 0x111a: 0x000c, 0x111b: 0x000c, 0x111c: 0x000c, 0x111d: 0x000c, + 0x111e: 0x000c, 0x1120: 0x000c, 0x1122: 0x000c, + 0x1125: 0x000c, 0x1126: 0x000c, 0x1127: 0x000c, 0x1128: 0x000c, 0x1129: 0x000c, + 0x112a: 0x000c, 0x112b: 0x000c, 0x112c: 0x000c, + 0x1133: 0x000c, 0x1134: 0x000c, 0x1135: 0x000c, + 0x1136: 0x000c, 0x1137: 0x000c, 0x1138: 0x000c, 0x1139: 0x000c, 0x113a: 0x000c, 0x113b: 0x000c, + 0x113c: 0x000c, 0x113f: 0x000c, + // Block 0x45, offset 0x1140 + 0x1170: 0x000c, 0x1171: 0x000c, 0x1172: 0x000c, 0x1173: 0x000c, 0x1174: 0x000c, 0x1175: 0x000c, + 0x1176: 0x000c, 0x1177: 0x000c, 0x1178: 0x000c, 0x1179: 0x000c, 0x117a: 0x000c, 0x117b: 0x000c, + 0x117c: 0x000c, 0x117d: 0x000c, 0x117e: 0x000c, + // Block 0x46, offset 0x1180 + 0x1180: 0x000c, 0x1181: 0x000c, 0x1182: 0x000c, 0x1183: 0x000c, + 0x11b4: 0x000c, + 0x11b6: 0x000c, 0x11b7: 0x000c, 0x11b8: 0x000c, 0x11b9: 0x000c, 0x11ba: 0x000c, + 0x11bc: 0x000c, + // Block 0x47, offset 0x11c0 + 0x11c2: 0x000c, + 0x11eb: 0x000c, 0x11ec: 0x000c, 0x11ed: 0x000c, 0x11ee: 0x000c, 0x11ef: 0x000c, + 0x11f0: 0x000c, 0x11f1: 0x000c, 0x11f2: 0x000c, 0x11f3: 0x000c, + // Block 0x48, offset 0x1200 + 0x1200: 0x000c, 0x1201: 0x000c, + 0x1222: 0x000c, 0x1223: 0x000c, + 0x1224: 0x000c, 0x1225: 0x000c, 0x1228: 0x000c, 0x1229: 0x000c, + 0x122b: 0x000c, 0x122c: 0x000c, 0x122d: 0x000c, + // Block 0x49, offset 0x1240 + 0x1266: 0x000c, 0x1268: 0x000c, 0x1269: 0x000c, + 0x126d: 0x000c, 0x126f: 0x000c, + 0x1270: 0x000c, 0x1271: 0x000c, + // Block 0x4a, offset 0x1280 + 0x12ac: 0x000c, 0x12ad: 0x000c, 0x12ae: 0x000c, 0x12af: 0x000c, + 0x12b0: 0x000c, 0x12b1: 0x000c, 0x12b2: 0x000c, 0x12b3: 0x000c, + 0x12b6: 0x000c, 0x12b7: 0x000c, + // Block 0x4b, offset 0x12c0 + 0x12d0: 0x000c, 0x12d1: 0x000c, + 0x12d2: 0x000c, 0x12d4: 0x000c, 0x12d5: 0x000c, 0x12d6: 0x000c, 0x12d7: 0x000c, + 0x12d8: 0x000c, 0x12d9: 0x000c, 0x12da: 0x000c, 0x12db: 0x000c, 0x12dc: 0x000c, 0x12dd: 0x000c, + 0x12de: 0x000c, 0x12df: 0x000c, 0x12e0: 0x000c, 0x12e2: 0x000c, 0x12e3: 0x000c, + 0x12e4: 0x000c, 0x12e5: 0x000c, 0x12e6: 0x000c, 0x12e7: 0x000c, 0x12e8: 0x000c, + 0x12ed: 0x000c, + 0x12f4: 0x000c, + 0x12f8: 0x000c, 0x12f9: 0x000c, + // Block 0x4c, offset 0x1300 + 0x1300: 0x000c, 0x1301: 0x000c, 0x1302: 0x000c, 0x1303: 0x000c, 0x1304: 0x000c, 0x1305: 0x000c, + 0x1306: 0x000c, 0x1307: 0x000c, 0x1308: 0x000c, 0x1309: 0x000c, 0x130a: 0x000c, 0x130b: 0x000c, + 0x130c: 0x000c, 0x130d: 0x000c, 0x130e: 0x000c, 0x130f: 0x000c, 0x1310: 0x000c, 0x1311: 0x000c, + 0x1312: 0x000c, 0x1313: 0x000c, 0x1314: 0x000c, 0x1315: 0x000c, 0x1316: 0x000c, 0x1317: 0x000c, + 0x1318: 0x000c, 0x1319: 0x000c, 0x131a: 0x000c, 0x131b: 0x000c, 0x131c: 0x000c, 0x131d: 0x000c, + 0x131e: 0x000c, 0x131f: 0x000c, 0x1320: 0x000c, 0x1321: 0x000c, 0x1322: 0x000c, 0x1323: 0x000c, + 0x1324: 0x000c, 0x1325: 0x000c, 0x1326: 0x000c, 0x1327: 0x000c, 0x1328: 0x000c, 0x1329: 0x000c, + 0x132a: 0x000c, 0x132b: 0x000c, 0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c, + 0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c, 0x1334: 0x000c, 0x1335: 0x000c, + 0x1336: 0x000c, 0x1337: 0x000c, 0x1338: 0x000c, 0x1339: 0x000c, 0x133b: 0x000c, + 0x133c: 0x000c, 0x133d: 0x000c, 0x133e: 0x000c, 0x133f: 0x000c, + // Block 0x4d, offset 0x1340 + 0x137d: 0x000a, 0x137f: 0x000a, + // Block 0x4e, offset 0x1380 + 0x1380: 0x000a, 0x1381: 0x000a, + 0x138d: 0x000a, 0x138e: 0x000a, 0x138f: 0x000a, + 0x139d: 0x000a, + 0x139e: 0x000a, 0x139f: 0x000a, + 0x13ad: 0x000a, 0x13ae: 0x000a, 0x13af: 0x000a, + 0x13bd: 0x000a, 0x13be: 0x000a, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x0009, 0x13c1: 0x0009, 0x13c2: 0x0009, 0x13c3: 0x0009, 0x13c4: 0x0009, 0x13c5: 0x0009, + 0x13c6: 0x0009, 0x13c7: 0x0009, 0x13c8: 0x0009, 0x13c9: 0x0009, 0x13ca: 0x0009, 0x13cb: 0x000b, + 0x13cc: 0x000b, 0x13cd: 0x000b, 0x13cf: 0x0001, 0x13d0: 0x000a, 0x13d1: 0x000a, + 0x13d2: 0x000a, 0x13d3: 0x000a, 0x13d4: 0x000a, 0x13d5: 0x000a, 0x13d6: 0x000a, 0x13d7: 0x000a, + 0x13d8: 0x000a, 0x13d9: 0x000a, 0x13da: 0x000a, 0x13db: 0x000a, 0x13dc: 0x000a, 0x13dd: 0x000a, + 0x13de: 0x000a, 0x13df: 0x000a, 0x13e0: 0x000a, 0x13e1: 0x000a, 0x13e2: 0x000a, 0x13e3: 0x000a, + 0x13e4: 0x000a, 0x13e5: 0x000a, 0x13e6: 0x000a, 0x13e7: 0x000a, 0x13e8: 0x0009, 0x13e9: 0x0007, + 0x13ea: 0x000e, 0x13eb: 0x000e, 0x13ec: 0x000e, 0x13ed: 0x000e, 0x13ee: 0x000e, 0x13ef: 0x0006, + 0x13f0: 0x0004, 0x13f1: 0x0004, 0x13f2: 0x0004, 0x13f3: 0x0004, 0x13f4: 0x0004, 0x13f5: 0x000a, + 0x13f6: 0x000a, 0x13f7: 0x000a, 0x13f8: 0x000a, 0x13f9: 0x000a, 0x13fa: 0x000a, 0x13fb: 0x000a, + 0x13fc: 0x000a, 0x13fd: 0x000a, 0x13fe: 0x000a, 0x13ff: 0x000a, + // Block 0x50, offset 0x1400 + 0x1400: 0x000a, 0x1401: 0x000a, 0x1402: 0x000a, 0x1403: 0x000a, 0x1404: 0x0006, 0x1405: 0x009a, + 0x1406: 0x008a, 0x1407: 0x000a, 0x1408: 0x000a, 0x1409: 0x000a, 0x140a: 0x000a, 0x140b: 0x000a, + 0x140c: 0x000a, 0x140d: 0x000a, 0x140e: 0x000a, 0x140f: 0x000a, 0x1410: 0x000a, 0x1411: 0x000a, + 0x1412: 0x000a, 0x1413: 0x000a, 0x1414: 0x000a, 0x1415: 0x000a, 0x1416: 0x000a, 0x1417: 0x000a, + 0x1418: 0x000a, 0x1419: 0x000a, 0x141a: 0x000a, 0x141b: 0x000a, 0x141c: 0x000a, 0x141d: 0x000a, + 0x141e: 0x000a, 0x141f: 0x0009, 0x1420: 0x000b, 0x1421: 0x000b, 0x1422: 0x000b, 0x1423: 0x000b, + 0x1424: 0x000b, 0x1425: 0x000b, 0x1426: 0x000e, 0x1427: 0x000e, 0x1428: 0x000e, 0x1429: 0x000e, + 0x142a: 0x000b, 0x142b: 0x000b, 0x142c: 0x000b, 0x142d: 0x000b, 0x142e: 0x000b, 0x142f: 0x000b, + 0x1430: 0x0002, 0x1434: 0x0002, 0x1435: 0x0002, + 0x1436: 0x0002, 0x1437: 0x0002, 0x1438: 0x0002, 0x1439: 0x0002, 0x143a: 0x0003, 0x143b: 0x0003, + 0x143c: 0x000a, 0x143d: 0x009a, 0x143e: 0x008a, + // Block 0x51, offset 0x1440 + 0x1440: 0x0002, 0x1441: 0x0002, 0x1442: 0x0002, 0x1443: 0x0002, 0x1444: 0x0002, 0x1445: 0x0002, + 0x1446: 0x0002, 0x1447: 0x0002, 0x1448: 0x0002, 0x1449: 0x0002, 0x144a: 0x0003, 0x144b: 0x0003, + 0x144c: 0x000a, 0x144d: 0x009a, 0x144e: 0x008a, + 0x1460: 0x0004, 0x1461: 0x0004, 0x1462: 0x0004, 0x1463: 0x0004, + 0x1464: 0x0004, 0x1465: 0x0004, 0x1466: 0x0004, 0x1467: 0x0004, 0x1468: 0x0004, 0x1469: 0x0004, + 0x146a: 0x0004, 0x146b: 0x0004, 0x146c: 0x0004, 0x146d: 0x0004, 0x146e: 0x0004, 0x146f: 0x0004, + 0x1470: 0x0004, 0x1471: 0x0004, 0x1472: 0x0004, 0x1473: 0x0004, 0x1474: 0x0004, 0x1475: 0x0004, + 0x1476: 0x0004, 0x1477: 0x0004, 0x1478: 0x0004, 0x1479: 0x0004, 0x147a: 0x0004, 0x147b: 0x0004, + 0x147c: 0x0004, 0x147d: 0x0004, 0x147e: 0x0004, 0x147f: 0x0004, + // Block 0x52, offset 0x1480 + 0x1480: 0x0004, 0x1481: 0x0004, 0x1482: 0x0004, 0x1483: 0x0004, 0x1484: 0x0004, 0x1485: 0x0004, + 0x1486: 0x0004, 0x1487: 0x0004, 0x1488: 0x0004, 0x1489: 0x0004, 0x148a: 0x0004, 0x148b: 0x0004, + 0x148c: 0x0004, 0x148d: 0x0004, 0x148e: 0x0004, 0x148f: 0x0004, 0x1490: 0x000c, 0x1491: 0x000c, + 0x1492: 0x000c, 0x1493: 0x000c, 0x1494: 0x000c, 0x1495: 0x000c, 0x1496: 0x000c, 0x1497: 0x000c, + 0x1498: 0x000c, 0x1499: 0x000c, 0x149a: 0x000c, 0x149b: 0x000c, 0x149c: 0x000c, 0x149d: 0x000c, + 0x149e: 0x000c, 0x149f: 0x000c, 0x14a0: 0x000c, 0x14a1: 0x000c, 0x14a2: 0x000c, 0x14a3: 0x000c, + 0x14a4: 0x000c, 0x14a5: 0x000c, 0x14a6: 0x000c, 0x14a7: 0x000c, 0x14a8: 0x000c, 0x14a9: 0x000c, + 0x14aa: 0x000c, 0x14ab: 0x000c, 0x14ac: 0x000c, 0x14ad: 0x000c, 0x14ae: 0x000c, 0x14af: 0x000c, + 0x14b0: 0x000c, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x000a, 0x14c1: 0x000a, 0x14c3: 0x000a, 0x14c4: 0x000a, 0x14c5: 0x000a, + 0x14c6: 0x000a, 0x14c8: 0x000a, 0x14c9: 0x000a, + 0x14d4: 0x000a, 0x14d6: 0x000a, 0x14d7: 0x000a, + 0x14d8: 0x000a, + 0x14de: 0x000a, 0x14df: 0x000a, 0x14e0: 0x000a, 0x14e1: 0x000a, 0x14e2: 0x000a, 0x14e3: 0x000a, + 0x14e5: 0x000a, 0x14e7: 0x000a, 0x14e9: 0x000a, + 0x14ee: 0x0004, + 0x14fa: 0x000a, 0x14fb: 0x000a, + // Block 0x54, offset 0x1500 + 0x1500: 0x000a, 0x1501: 0x000a, 0x1502: 0x000a, 0x1503: 0x000a, 0x1504: 0x000a, + 0x150a: 0x000a, 0x150b: 0x000a, + 0x150c: 0x000a, 0x150d: 0x000a, 0x1510: 0x000a, 0x1511: 0x000a, + 0x1512: 0x000a, 0x1513: 0x000a, 0x1514: 0x000a, 0x1515: 0x000a, 0x1516: 0x000a, 0x1517: 0x000a, + 0x1518: 0x000a, 0x1519: 0x000a, 0x151a: 0x000a, 0x151b: 0x000a, 0x151c: 0x000a, 0x151d: 0x000a, + 0x151e: 0x000a, 0x151f: 0x000a, + // Block 0x55, offset 0x1540 + 0x1549: 0x000a, 0x154a: 0x000a, 0x154b: 0x000a, + 0x1550: 0x000a, 0x1551: 0x000a, + 0x1552: 0x000a, 0x1553: 0x000a, 0x1554: 0x000a, 0x1555: 0x000a, 0x1556: 0x000a, 0x1557: 0x000a, + 0x1558: 0x000a, 0x1559: 0x000a, 0x155a: 0x000a, 0x155b: 0x000a, 0x155c: 0x000a, 0x155d: 0x000a, + 0x155e: 0x000a, 0x155f: 0x000a, 0x1560: 0x000a, 0x1561: 0x000a, 0x1562: 0x000a, 0x1563: 0x000a, + 0x1564: 0x000a, 0x1565: 0x000a, 0x1566: 0x000a, 0x1567: 0x000a, 0x1568: 0x000a, 0x1569: 0x000a, + 0x156a: 0x000a, 0x156b: 0x000a, 0x156c: 0x000a, 0x156d: 0x000a, 0x156e: 0x000a, 0x156f: 0x000a, + 0x1570: 0x000a, 0x1571: 0x000a, 0x1572: 0x000a, 0x1573: 0x000a, 0x1574: 0x000a, 0x1575: 0x000a, + 0x1576: 0x000a, 0x1577: 0x000a, 0x1578: 0x000a, 0x1579: 0x000a, 0x157a: 0x000a, 0x157b: 0x000a, + 0x157c: 0x000a, 0x157d: 0x000a, 0x157e: 0x000a, 0x157f: 0x000a, + // Block 0x56, offset 0x1580 + 0x1580: 0x000a, 0x1581: 0x000a, 0x1582: 0x000a, 0x1583: 0x000a, 0x1584: 0x000a, 0x1585: 0x000a, + 0x1586: 0x000a, 0x1587: 0x000a, 0x1588: 0x000a, 0x1589: 0x000a, 0x158a: 0x000a, 0x158b: 0x000a, + 0x158c: 0x000a, 0x158d: 0x000a, 0x158e: 0x000a, 0x158f: 0x000a, 0x1590: 0x000a, 0x1591: 0x000a, + 0x1592: 0x000a, 0x1593: 0x000a, 0x1594: 0x000a, 0x1595: 0x000a, 0x1596: 0x000a, 0x1597: 0x000a, + 0x1598: 0x000a, 0x1599: 0x000a, 0x159a: 0x000a, 0x159b: 0x000a, 0x159c: 0x000a, 0x159d: 0x000a, + 0x159e: 0x000a, 0x159f: 0x000a, 0x15a0: 0x000a, 0x15a1: 0x000a, 0x15a2: 0x000a, 0x15a3: 0x000a, + 0x15a4: 0x000a, 0x15a5: 0x000a, 0x15a6: 0x000a, 0x15a7: 0x000a, 0x15a8: 0x000a, 0x15a9: 0x000a, + 0x15aa: 0x000a, 0x15ab: 0x000a, 0x15ac: 0x000a, 0x15ad: 0x000a, 0x15ae: 0x000a, 0x15af: 0x000a, + 0x15b0: 0x000a, 0x15b1: 0x000a, 0x15b2: 0x000a, 0x15b3: 0x000a, 0x15b4: 0x000a, 0x15b5: 0x000a, + 0x15b6: 0x000a, 0x15b7: 0x000a, 0x15b8: 0x000a, 0x15b9: 0x000a, 0x15ba: 0x000a, 0x15bb: 0x000a, + 0x15bc: 0x000a, 0x15bd: 0x000a, 0x15be: 0x000a, 0x15bf: 0x000a, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x000a, 0x15c1: 0x000a, 0x15c2: 0x000a, 0x15c3: 0x000a, 0x15c4: 0x000a, 0x15c5: 0x000a, + 0x15c6: 0x000a, 0x15c7: 0x000a, 0x15c8: 0x000a, 0x15c9: 0x000a, 0x15ca: 0x000a, 0x15cb: 0x000a, + 0x15cc: 0x000a, 0x15cd: 0x000a, 0x15ce: 0x000a, 0x15cf: 0x000a, 0x15d0: 0x000a, 0x15d1: 0x000a, + 0x15d2: 0x0003, 0x15d3: 0x0004, 0x15d4: 0x000a, 0x15d5: 0x000a, 0x15d6: 0x000a, 0x15d7: 0x000a, + 0x15d8: 0x000a, 0x15d9: 0x000a, 0x15da: 0x000a, 0x15db: 0x000a, 0x15dc: 0x000a, 0x15dd: 0x000a, + 0x15de: 0x000a, 0x15df: 0x000a, 0x15e0: 0x000a, 0x15e1: 0x000a, 0x15e2: 0x000a, 0x15e3: 0x000a, + 0x15e4: 0x000a, 0x15e5: 0x000a, 0x15e6: 0x000a, 0x15e7: 0x000a, 0x15e8: 0x000a, 0x15e9: 0x000a, + 0x15ea: 0x000a, 0x15eb: 0x000a, 0x15ec: 0x000a, 0x15ed: 0x000a, 0x15ee: 0x000a, 0x15ef: 0x000a, + 0x15f0: 0x000a, 0x15f1: 0x000a, 0x15f2: 0x000a, 0x15f3: 0x000a, 0x15f4: 0x000a, 0x15f5: 0x000a, + 0x15f6: 0x000a, 0x15f7: 0x000a, 0x15f8: 0x000a, 0x15f9: 0x000a, 0x15fa: 0x000a, 0x15fb: 0x000a, + 0x15fc: 0x000a, 0x15fd: 0x000a, 0x15fe: 0x000a, 0x15ff: 0x000a, + // Block 0x58, offset 0x1600 + 0x1600: 0x000a, 0x1601: 0x000a, 0x1602: 0x000a, 0x1603: 0x000a, 0x1604: 0x000a, 0x1605: 0x000a, + 0x1606: 0x000a, 0x1607: 0x000a, 0x1608: 0x003a, 0x1609: 0x002a, 0x160a: 0x003a, 0x160b: 0x002a, + 0x160c: 0x000a, 0x160d: 0x000a, 0x160e: 0x000a, 0x160f: 0x000a, 0x1610: 0x000a, 0x1611: 0x000a, + 0x1612: 0x000a, 0x1613: 0x000a, 0x1614: 0x000a, 0x1615: 0x000a, 0x1616: 0x000a, 0x1617: 0x000a, + 0x1618: 0x000a, 0x1619: 0x000a, 0x161a: 0x000a, 0x161b: 0x000a, 0x161c: 0x000a, 0x161d: 0x000a, + 0x161e: 0x000a, 0x161f: 0x000a, 0x1620: 0x000a, 0x1621: 0x000a, 0x1622: 0x000a, 0x1623: 0x000a, + 0x1624: 0x000a, 0x1625: 0x000a, 0x1626: 0x000a, 0x1627: 0x000a, 0x1628: 0x000a, 0x1629: 0x009a, + 0x162a: 0x008a, 0x162b: 0x000a, 0x162c: 0x000a, 0x162d: 0x000a, 0x162e: 0x000a, 0x162f: 0x000a, + 0x1630: 0x000a, 0x1631: 0x000a, 0x1632: 0x000a, 0x1633: 0x000a, 0x1634: 0x000a, 0x1635: 0x000a, + // Block 0x59, offset 0x1640 + 0x167b: 0x000a, + 0x167c: 0x000a, 0x167d: 0x000a, 0x167e: 0x000a, 0x167f: 0x000a, + // Block 0x5a, offset 0x1680 + 0x1680: 0x000a, 0x1681: 0x000a, 0x1682: 0x000a, 0x1683: 0x000a, 0x1684: 0x000a, 0x1685: 0x000a, + 0x1686: 0x000a, 0x1687: 0x000a, 0x1688: 0x000a, 0x1689: 0x000a, 0x168a: 0x000a, 0x168b: 0x000a, + 0x168c: 0x000a, 0x168d: 0x000a, 0x168e: 0x000a, 0x168f: 0x000a, 0x1690: 0x000a, 0x1691: 0x000a, + 0x1692: 0x000a, 0x1693: 0x000a, 0x1694: 0x000a, 0x1696: 0x000a, 0x1697: 0x000a, + 0x1698: 0x000a, 0x1699: 0x000a, 0x169a: 0x000a, 0x169b: 0x000a, 0x169c: 0x000a, 0x169d: 0x000a, + 0x169e: 0x000a, 0x169f: 0x000a, 0x16a0: 0x000a, 0x16a1: 0x000a, 0x16a2: 0x000a, 0x16a3: 0x000a, + 0x16a4: 0x000a, 0x16a5: 0x000a, 0x16a6: 0x000a, 0x16a7: 0x000a, 0x16a8: 0x000a, 0x16a9: 0x000a, + 0x16aa: 0x000a, 0x16ab: 0x000a, 0x16ac: 0x000a, 0x16ad: 0x000a, 0x16ae: 0x000a, 0x16af: 0x000a, + 0x16b0: 0x000a, 0x16b1: 0x000a, 0x16b2: 0x000a, 0x16b3: 0x000a, 0x16b4: 0x000a, 0x16b5: 0x000a, + 0x16b6: 0x000a, 0x16b7: 0x000a, 0x16b8: 0x000a, 0x16b9: 0x000a, 0x16ba: 0x000a, 0x16bb: 0x000a, + 0x16bc: 0x000a, 0x16bd: 0x000a, 0x16be: 0x000a, 0x16bf: 0x000a, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x000a, 0x16c1: 0x000a, 0x16c2: 0x000a, 0x16c3: 0x000a, 0x16c4: 0x000a, 0x16c5: 0x000a, + 0x16c6: 0x000a, 0x16c7: 0x000a, 0x16c8: 0x000a, 0x16c9: 0x000a, 0x16ca: 0x000a, 0x16cb: 0x000a, + 0x16cc: 0x000a, 0x16cd: 0x000a, 0x16ce: 0x000a, 0x16cf: 0x000a, 0x16d0: 0x000a, 0x16d1: 0x000a, + 0x16d2: 0x000a, 0x16d3: 0x000a, 0x16d4: 0x000a, 0x16d5: 0x000a, 0x16d6: 0x000a, 0x16d7: 0x000a, + 0x16d8: 0x000a, 0x16d9: 0x000a, 0x16da: 0x000a, 0x16db: 0x000a, 0x16dc: 0x000a, 0x16dd: 0x000a, + 0x16de: 0x000a, 0x16df: 0x000a, 0x16e0: 0x000a, 0x16e1: 0x000a, 0x16e2: 0x000a, 0x16e3: 0x000a, + 0x16e4: 0x000a, 0x16e5: 0x000a, 0x16e6: 0x000a, + // Block 0x5c, offset 0x1700 + 0x1700: 0x000a, 0x1701: 0x000a, 0x1702: 0x000a, 0x1703: 0x000a, 0x1704: 0x000a, 0x1705: 0x000a, + 0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a, + 0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a, + 0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a, 0x1727: 0x000a, 0x1728: 0x000a, 0x1729: 0x000a, + 0x172a: 0x000a, 0x172b: 0x000a, 0x172c: 0x000a, 0x172d: 0x000a, 0x172e: 0x000a, 0x172f: 0x000a, + 0x1730: 0x000a, 0x1731: 0x000a, 0x1732: 0x000a, 0x1733: 0x000a, 0x1734: 0x000a, 0x1735: 0x000a, + 0x1736: 0x000a, 0x1737: 0x000a, 0x1738: 0x000a, 0x1739: 0x000a, 0x173a: 0x000a, 0x173b: 0x000a, + 0x173c: 0x000a, 0x173d: 0x000a, 0x173e: 0x000a, 0x173f: 0x000a, + // Block 0x5d, offset 0x1740 + 0x1740: 0x000a, 0x1741: 0x000a, 0x1742: 0x000a, 0x1743: 0x000a, 0x1744: 0x000a, 0x1745: 0x000a, + 0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x0002, 0x1749: 0x0002, 0x174a: 0x0002, 0x174b: 0x0002, + 0x174c: 0x0002, 0x174d: 0x0002, 0x174e: 0x0002, 0x174f: 0x0002, 0x1750: 0x0002, 0x1751: 0x0002, + 0x1752: 0x0002, 0x1753: 0x0002, 0x1754: 0x0002, 0x1755: 0x0002, 0x1756: 0x0002, 0x1757: 0x0002, + 0x1758: 0x0002, 0x1759: 0x0002, 0x175a: 0x0002, 0x175b: 0x0002, + // Block 0x5e, offset 0x1780 + 0x17aa: 0x000a, 0x17ab: 0x000a, 0x17ac: 0x000a, 0x17ad: 0x000a, 0x17ae: 0x000a, 0x17af: 0x000a, + 0x17b0: 0x000a, 0x17b1: 0x000a, 0x17b2: 0x000a, 0x17b3: 0x000a, 0x17b4: 0x000a, 0x17b5: 0x000a, + 0x17b6: 0x000a, 0x17b7: 0x000a, 0x17b8: 0x000a, 0x17b9: 0x000a, 0x17ba: 0x000a, 0x17bb: 0x000a, + 0x17bc: 0x000a, 0x17bd: 0x000a, 0x17be: 0x000a, 0x17bf: 0x000a, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x000a, 0x17c1: 0x000a, 0x17c2: 0x000a, 0x17c3: 0x000a, 0x17c4: 0x000a, 0x17c5: 0x000a, + 0x17c6: 0x000a, 0x17c7: 0x000a, 0x17c8: 0x000a, 0x17c9: 0x000a, 0x17ca: 0x000a, 0x17cb: 0x000a, + 0x17cc: 0x000a, 0x17cd: 0x000a, 0x17ce: 0x000a, 0x17cf: 0x000a, 0x17d0: 0x000a, 0x17d1: 0x000a, + 0x17d2: 0x000a, 0x17d3: 0x000a, 0x17d4: 0x000a, 0x17d5: 0x000a, 0x17d6: 0x000a, 0x17d7: 0x000a, + 0x17d8: 0x000a, 0x17d9: 0x000a, 0x17da: 0x000a, 0x17db: 0x000a, 0x17dc: 0x000a, 0x17dd: 0x000a, + 0x17de: 0x000a, 0x17df: 0x000a, 0x17e0: 0x000a, 0x17e1: 0x000a, 0x17e2: 0x000a, 0x17e3: 0x000a, + 0x17e4: 0x000a, 0x17e5: 0x000a, 0x17e6: 0x000a, 0x17e7: 0x000a, 0x17e8: 0x000a, 0x17e9: 0x000a, + 0x17ea: 0x000a, 0x17eb: 0x000a, 0x17ed: 0x000a, 0x17ee: 0x000a, 0x17ef: 0x000a, + 0x17f0: 0x000a, 0x17f1: 0x000a, 0x17f2: 0x000a, 0x17f3: 0x000a, 0x17f4: 0x000a, 0x17f5: 0x000a, + 0x17f6: 0x000a, 0x17f7: 0x000a, 0x17f8: 0x000a, 0x17f9: 0x000a, 0x17fa: 0x000a, 0x17fb: 0x000a, + 0x17fc: 0x000a, 0x17fd: 0x000a, 0x17fe: 0x000a, 0x17ff: 0x000a, + // Block 0x60, offset 0x1800 + 0x1800: 0x000a, 0x1801: 0x000a, 0x1802: 0x000a, 0x1803: 0x000a, 0x1804: 0x000a, 0x1805: 0x000a, + 0x1806: 0x000a, 0x1807: 0x000a, 0x1808: 0x000a, 0x1809: 0x000a, 0x180a: 0x000a, 0x180b: 0x000a, + 0x180c: 0x000a, 0x180d: 0x000a, 0x180e: 0x000a, 0x180f: 0x000a, 0x1810: 0x000a, 0x1811: 0x000a, + 0x1812: 0x000a, 0x1813: 0x000a, 0x1814: 0x000a, 0x1815: 0x000a, 0x1816: 0x000a, 0x1817: 0x000a, + 0x1818: 0x000a, 0x1819: 0x000a, 0x181a: 0x000a, 0x181b: 0x000a, 0x181c: 0x000a, 0x181d: 0x000a, + 0x181e: 0x000a, 0x181f: 0x000a, 0x1820: 0x000a, 0x1821: 0x000a, 0x1822: 0x000a, 0x1823: 0x000a, + 0x1824: 0x000a, 0x1825: 0x000a, 0x1826: 0x000a, 0x1827: 0x000a, 0x1828: 0x003a, 0x1829: 0x002a, + 0x182a: 0x003a, 0x182b: 0x002a, 0x182c: 0x003a, 0x182d: 0x002a, 0x182e: 0x003a, 0x182f: 0x002a, + 0x1830: 0x003a, 0x1831: 0x002a, 0x1832: 0x003a, 0x1833: 0x002a, 0x1834: 0x003a, 0x1835: 0x002a, + 0x1836: 0x000a, 0x1837: 0x000a, 0x1838: 0x000a, 0x1839: 0x000a, 0x183a: 0x000a, 0x183b: 0x000a, + 0x183c: 0x000a, 0x183d: 0x000a, 0x183e: 0x000a, 0x183f: 0x000a, + // Block 0x61, offset 0x1840 + 0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x009a, + 0x1846: 0x008a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a, + 0x184c: 0x000a, 0x184d: 0x000a, 0x184e: 0x000a, 0x184f: 0x000a, 0x1850: 0x000a, 0x1851: 0x000a, + 0x1852: 0x000a, 0x1853: 0x000a, 0x1854: 0x000a, 0x1855: 0x000a, 0x1856: 0x000a, 0x1857: 0x000a, + 0x1858: 0x000a, 0x1859: 0x000a, 0x185a: 0x000a, 0x185b: 0x000a, 0x185c: 0x000a, 0x185d: 0x000a, + 0x185e: 0x000a, 0x185f: 0x000a, 0x1860: 0x000a, 0x1861: 0x000a, 0x1862: 0x000a, 0x1863: 0x000a, + 0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x003a, 0x1867: 0x002a, 0x1868: 0x003a, 0x1869: 0x002a, + 0x186a: 0x003a, 0x186b: 0x002a, 0x186c: 0x003a, 0x186d: 0x002a, 0x186e: 0x003a, 0x186f: 0x002a, + 0x1870: 0x000a, 0x1871: 0x000a, 0x1872: 0x000a, 0x1873: 0x000a, 0x1874: 0x000a, 0x1875: 0x000a, + 0x1876: 0x000a, 0x1877: 0x000a, 0x1878: 0x000a, 0x1879: 0x000a, 0x187a: 0x000a, 0x187b: 0x000a, + 0x187c: 0x000a, 0x187d: 0x000a, 0x187e: 0x000a, 0x187f: 0x000a, + // Block 0x62, offset 0x1880 + 0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x007a, 0x1884: 0x006a, 0x1885: 0x009a, + 0x1886: 0x008a, 0x1887: 0x00ba, 0x1888: 0x00aa, 0x1889: 0x009a, 0x188a: 0x008a, 0x188b: 0x007a, + 0x188c: 0x006a, 0x188d: 0x00da, 0x188e: 0x002a, 0x188f: 0x003a, 0x1890: 0x00ca, 0x1891: 0x009a, + 0x1892: 0x008a, 0x1893: 0x007a, 0x1894: 0x006a, 0x1895: 0x009a, 0x1896: 0x008a, 0x1897: 0x00ba, + 0x1898: 0x00aa, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a, + 0x189e: 0x000a, 0x189f: 0x000a, 0x18a0: 0x000a, 0x18a1: 0x000a, 0x18a2: 0x000a, 0x18a3: 0x000a, + 0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x000a, 0x18a7: 0x000a, 0x18a8: 0x000a, 0x18a9: 0x000a, + 0x18aa: 0x000a, 0x18ab: 0x000a, 0x18ac: 0x000a, 0x18ad: 0x000a, 0x18ae: 0x000a, 0x18af: 0x000a, + 0x18b0: 0x000a, 0x18b1: 0x000a, 0x18b2: 0x000a, 0x18b3: 0x000a, 0x18b4: 0x000a, 0x18b5: 0x000a, + 0x18b6: 0x000a, 0x18b7: 0x000a, 0x18b8: 0x000a, 0x18b9: 0x000a, 0x18ba: 0x000a, 0x18bb: 0x000a, + 0x18bc: 0x000a, 0x18bd: 0x000a, 0x18be: 0x000a, 0x18bf: 0x000a, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x000a, 0x18c4: 0x000a, 0x18c5: 0x000a, + 0x18c6: 0x000a, 0x18c7: 0x000a, 0x18c8: 0x000a, 0x18c9: 0x000a, 0x18ca: 0x000a, 0x18cb: 0x000a, + 0x18cc: 0x000a, 0x18cd: 0x000a, 0x18ce: 0x000a, 0x18cf: 0x000a, 0x18d0: 0x000a, 0x18d1: 0x000a, + 0x18d2: 0x000a, 0x18d3: 0x000a, 0x18d4: 0x000a, 0x18d5: 0x000a, 0x18d6: 0x000a, 0x18d7: 0x000a, + 0x18d8: 0x003a, 0x18d9: 0x002a, 0x18da: 0x003a, 0x18db: 0x002a, 0x18dc: 0x000a, 0x18dd: 0x000a, + 0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a, + 0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x000a, 0x18e7: 0x000a, 0x18e8: 0x000a, 0x18e9: 0x000a, + 0x18ea: 0x000a, 0x18eb: 0x000a, 0x18ec: 0x000a, 0x18ed: 0x000a, 0x18ee: 0x000a, 0x18ef: 0x000a, + 0x18f0: 0x000a, 0x18f1: 0x000a, 0x18f2: 0x000a, 0x18f3: 0x000a, 0x18f4: 0x000a, 0x18f5: 0x000a, + 0x18f6: 0x000a, 0x18f7: 0x000a, 0x18f8: 0x000a, 0x18f9: 0x000a, 0x18fa: 0x000a, 0x18fb: 0x000a, + 0x18fc: 0x003a, 0x18fd: 0x002a, 0x18fe: 0x000a, 0x18ff: 0x000a, + // Block 0x64, offset 0x1900 + 0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x000a, 0x1904: 0x000a, 0x1905: 0x000a, + 0x1906: 0x000a, 0x1907: 0x000a, 0x1908: 0x000a, 0x1909: 0x000a, 0x190a: 0x000a, 0x190b: 0x000a, + 0x190c: 0x000a, 0x190d: 0x000a, 0x190e: 0x000a, 0x190f: 0x000a, 0x1910: 0x000a, 0x1911: 0x000a, + 0x1912: 0x000a, 0x1913: 0x000a, 0x1914: 0x000a, 0x1915: 0x000a, 0x1916: 0x000a, 0x1917: 0x000a, + 0x1918: 0x000a, 0x1919: 0x000a, 0x191a: 0x000a, 0x191b: 0x000a, 0x191c: 0x000a, 0x191d: 0x000a, + 0x191e: 0x000a, 0x191f: 0x000a, 0x1920: 0x000a, 0x1921: 0x000a, 0x1922: 0x000a, 0x1923: 0x000a, + 0x1924: 0x000a, 0x1925: 0x000a, 0x1926: 0x000a, 0x1927: 0x000a, 0x1928: 0x000a, 0x1929: 0x000a, + 0x192a: 0x000a, 0x192b: 0x000a, 0x192c: 0x000a, 0x192d: 0x000a, 0x192e: 0x000a, 0x192f: 0x000a, + 0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a, + 0x1936: 0x000a, 0x1937: 0x000a, 0x1938: 0x000a, 0x1939: 0x000a, 0x193a: 0x000a, 0x193b: 0x000a, + 0x193c: 0x000a, 0x193d: 0x000a, 0x193e: 0x000a, 0x193f: 0x000a, + // Block 0x65, offset 0x1940 + 0x1940: 0x000a, 0x1941: 0x000a, 0x1942: 0x000a, 0x1943: 0x000a, 0x1944: 0x000a, 0x1945: 0x000a, + 0x1946: 0x000a, 0x1947: 0x000a, 0x1948: 0x000a, 0x1949: 0x000a, 0x194a: 0x000a, 0x194b: 0x000a, + 0x194c: 0x000a, 0x194d: 0x000a, 0x194e: 0x000a, 0x194f: 0x000a, 0x1950: 0x000a, 0x1951: 0x000a, + 0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a, + 0x1958: 0x000a, 0x1959: 0x000a, 0x195a: 0x000a, 0x195b: 0x000a, 0x195c: 0x000a, 0x195d: 0x000a, + 0x195e: 0x000a, 0x195f: 0x000a, 0x1960: 0x000a, 0x1961: 0x000a, 0x1962: 0x000a, 0x1963: 0x000a, + 0x1964: 0x000a, 0x1965: 0x000a, 0x1966: 0x000a, 0x1967: 0x000a, 0x1968: 0x000a, 0x1969: 0x000a, + 0x196a: 0x000a, 0x196b: 0x000a, 0x196c: 0x000a, 0x196d: 0x000a, 0x196e: 0x000a, 0x196f: 0x000a, + 0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a, 0x1974: 0x000a, 0x1975: 0x000a, + 0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a, 0x197a: 0x000a, 0x197b: 0x000a, + 0x197c: 0x000a, 0x197d: 0x000a, 0x197e: 0x000a, 0x197f: 0x000a, + // Block 0x66, offset 0x1980 + 0x19a5: 0x000a, 0x19a6: 0x000a, 0x19a7: 0x000a, 0x19a8: 0x000a, 0x19a9: 0x000a, + 0x19aa: 0x000a, 0x19af: 0x000c, + 0x19b0: 0x000c, 0x19b1: 0x000c, + 0x19b9: 0x000a, 0x19ba: 0x000a, 0x19bb: 0x000a, + 0x19bc: 0x000a, 0x19bd: 0x000a, 0x19be: 0x000a, 0x19bf: 0x000a, + // Block 0x67, offset 0x19c0 + 0x19ff: 0x000c, + // Block 0x68, offset 0x1a00 + 0x1a20: 0x000c, 0x1a21: 0x000c, 0x1a22: 0x000c, 0x1a23: 0x000c, + 0x1a24: 0x000c, 0x1a25: 0x000c, 0x1a26: 0x000c, 0x1a27: 0x000c, 0x1a28: 0x000c, 0x1a29: 0x000c, + 0x1a2a: 0x000c, 0x1a2b: 0x000c, 0x1a2c: 0x000c, 0x1a2d: 0x000c, 0x1a2e: 0x000c, 0x1a2f: 0x000c, + 0x1a30: 0x000c, 0x1a31: 0x000c, 0x1a32: 0x000c, 0x1a33: 0x000c, 0x1a34: 0x000c, 0x1a35: 0x000c, + 0x1a36: 0x000c, 0x1a37: 0x000c, 0x1a38: 0x000c, 0x1a39: 0x000c, 0x1a3a: 0x000c, 0x1a3b: 0x000c, + 0x1a3c: 0x000c, 0x1a3d: 0x000c, 0x1a3e: 0x000c, 0x1a3f: 0x000c, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x000a, 0x1a41: 0x000a, 0x1a42: 0x000a, 0x1a43: 0x000a, 0x1a44: 0x000a, 0x1a45: 0x000a, + 0x1a46: 0x000a, 0x1a47: 0x000a, 0x1a48: 0x000a, 0x1a49: 0x000a, 0x1a4a: 0x000a, 0x1a4b: 0x000a, + 0x1a4c: 0x000a, 0x1a4d: 0x000a, 0x1a4e: 0x000a, 0x1a4f: 0x000a, 0x1a50: 0x000a, 0x1a51: 0x000a, + 0x1a52: 0x000a, 0x1a53: 0x000a, 0x1a54: 0x000a, 0x1a55: 0x000a, 0x1a56: 0x000a, 0x1a57: 0x000a, + 0x1a58: 0x000a, 0x1a59: 0x000a, 0x1a5a: 0x000a, 0x1a5b: 0x000a, 0x1a5c: 0x000a, 0x1a5d: 0x000a, + 0x1a5e: 0x000a, 0x1a5f: 0x000a, 0x1a60: 0x000a, 0x1a61: 0x000a, 0x1a62: 0x003a, 0x1a63: 0x002a, + 0x1a64: 0x003a, 0x1a65: 0x002a, 0x1a66: 0x003a, 0x1a67: 0x002a, 0x1a68: 0x003a, 0x1a69: 0x002a, + 0x1a6a: 0x000a, 0x1a6b: 0x000a, 0x1a6c: 0x000a, 0x1a6d: 0x000a, 0x1a6e: 0x000a, 0x1a6f: 0x000a, + 0x1a70: 0x000a, 0x1a71: 0x000a, 0x1a72: 0x000a, 0x1a73: 0x000a, 0x1a74: 0x000a, 0x1a75: 0x000a, + 0x1a76: 0x000a, 0x1a77: 0x000a, 0x1a78: 0x000a, 0x1a79: 0x000a, 0x1a7a: 0x000a, 0x1a7b: 0x000a, + 0x1a7c: 0x000a, 0x1a7d: 0x000a, 0x1a7e: 0x000a, 0x1a7f: 0x000a, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x000a, 0x1a81: 0x000a, 0x1a82: 0x000a, 0x1a83: 0x000a, 0x1a84: 0x000a, 0x1a85: 0x000a, + 0x1a86: 0x000a, 0x1a87: 0x000a, 0x1a88: 0x000a, 0x1a89: 0x000a, 0x1a8a: 0x000a, 0x1a8b: 0x000a, + 0x1a8c: 0x000a, 0x1a8d: 0x000a, 0x1a8e: 0x000a, 0x1a8f: 0x000a, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x000a, 0x1ac1: 0x000a, 0x1ac2: 0x000a, 0x1ac3: 0x000a, 0x1ac4: 0x000a, 0x1ac5: 0x000a, + 0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a, 0x1aca: 0x000a, 0x1acb: 0x000a, + 0x1acc: 0x000a, 0x1acd: 0x000a, 0x1ace: 0x000a, 0x1acf: 0x000a, 0x1ad0: 0x000a, 0x1ad1: 0x000a, + 0x1ad2: 0x000a, 0x1ad3: 0x000a, 0x1ad4: 0x000a, 0x1ad5: 0x000a, 0x1ad6: 0x000a, 0x1ad7: 0x000a, + 0x1ad8: 0x000a, 0x1ad9: 0x000a, 0x1adb: 0x000a, 0x1adc: 0x000a, 0x1add: 0x000a, + 0x1ade: 0x000a, 0x1adf: 0x000a, 0x1ae0: 0x000a, 0x1ae1: 0x000a, 0x1ae2: 0x000a, 0x1ae3: 0x000a, + 0x1ae4: 0x000a, 0x1ae5: 0x000a, 0x1ae6: 0x000a, 0x1ae7: 0x000a, 0x1ae8: 0x000a, 0x1ae9: 0x000a, + 0x1aea: 0x000a, 0x1aeb: 0x000a, 0x1aec: 0x000a, 0x1aed: 0x000a, 0x1aee: 0x000a, 0x1aef: 0x000a, + 0x1af0: 0x000a, 0x1af1: 0x000a, 0x1af2: 0x000a, 0x1af3: 0x000a, 0x1af4: 0x000a, 0x1af5: 0x000a, + 0x1af6: 0x000a, 0x1af7: 0x000a, 0x1af8: 0x000a, 0x1af9: 0x000a, 0x1afa: 0x000a, 0x1afb: 0x000a, + 0x1afc: 0x000a, 0x1afd: 0x000a, 0x1afe: 0x000a, 0x1aff: 0x000a, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a, 0x1b05: 0x000a, + 0x1b06: 0x000a, 0x1b07: 0x000a, 0x1b08: 0x000a, 0x1b09: 0x000a, 0x1b0a: 0x000a, 0x1b0b: 0x000a, + 0x1b0c: 0x000a, 0x1b0d: 0x000a, 0x1b0e: 0x000a, 0x1b0f: 0x000a, 0x1b10: 0x000a, 0x1b11: 0x000a, + 0x1b12: 0x000a, 0x1b13: 0x000a, 0x1b14: 0x000a, 0x1b15: 0x000a, 0x1b16: 0x000a, 0x1b17: 0x000a, + 0x1b18: 0x000a, 0x1b19: 0x000a, 0x1b1a: 0x000a, 0x1b1b: 0x000a, 0x1b1c: 0x000a, 0x1b1d: 0x000a, + 0x1b1e: 0x000a, 0x1b1f: 0x000a, 0x1b20: 0x000a, 0x1b21: 0x000a, 0x1b22: 0x000a, 0x1b23: 0x000a, + 0x1b24: 0x000a, 0x1b25: 0x000a, 0x1b26: 0x000a, 0x1b27: 0x000a, 0x1b28: 0x000a, 0x1b29: 0x000a, + 0x1b2a: 0x000a, 0x1b2b: 0x000a, 0x1b2c: 0x000a, 0x1b2d: 0x000a, 0x1b2e: 0x000a, 0x1b2f: 0x000a, + 0x1b30: 0x000a, 0x1b31: 0x000a, 0x1b32: 0x000a, 0x1b33: 0x000a, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x000a, 0x1b41: 0x000a, 0x1b42: 0x000a, 0x1b43: 0x000a, 0x1b44: 0x000a, 0x1b45: 0x000a, + 0x1b46: 0x000a, 0x1b47: 0x000a, 0x1b48: 0x000a, 0x1b49: 0x000a, 0x1b4a: 0x000a, 0x1b4b: 0x000a, + 0x1b4c: 0x000a, 0x1b4d: 0x000a, 0x1b4e: 0x000a, 0x1b4f: 0x000a, 0x1b50: 0x000a, 0x1b51: 0x000a, + 0x1b52: 0x000a, 0x1b53: 0x000a, 0x1b54: 0x000a, 0x1b55: 0x000a, + 0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a, 0x1b74: 0x000a, 0x1b75: 0x000a, + 0x1b76: 0x000a, 0x1b77: 0x000a, 0x1b78: 0x000a, 0x1b79: 0x000a, 0x1b7a: 0x000a, 0x1b7b: 0x000a, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x0009, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, + 0x1b88: 0x003a, 0x1b89: 0x002a, 0x1b8a: 0x003a, 0x1b8b: 0x002a, + 0x1b8c: 0x003a, 0x1b8d: 0x002a, 0x1b8e: 0x003a, 0x1b8f: 0x002a, 0x1b90: 0x003a, 0x1b91: 0x002a, + 0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x003a, 0x1b95: 0x002a, 0x1b96: 0x003a, 0x1b97: 0x002a, + 0x1b98: 0x003a, 0x1b99: 0x002a, 0x1b9a: 0x003a, 0x1b9b: 0x002a, 0x1b9c: 0x000a, 0x1b9d: 0x000a, + 0x1b9e: 0x000a, 0x1b9f: 0x000a, 0x1ba0: 0x000a, + 0x1baa: 0x000c, 0x1bab: 0x000c, 0x1bac: 0x000c, 0x1bad: 0x000c, + 0x1bb0: 0x000a, + 0x1bb6: 0x000a, 0x1bb7: 0x000a, + 0x1bbd: 0x000a, 0x1bbe: 0x000a, 0x1bbf: 0x000a, + // Block 0x6f, offset 0x1bc0 + 0x1bd9: 0x000c, 0x1bda: 0x000c, 0x1bdb: 0x000a, 0x1bdc: 0x000a, + 0x1be0: 0x000a, + // Block 0x70, offset 0x1c00 + 0x1c3b: 0x000a, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x000a, 0x1c41: 0x000a, 0x1c42: 0x000a, 0x1c43: 0x000a, 0x1c44: 0x000a, 0x1c45: 0x000a, + 0x1c46: 0x000a, 0x1c47: 0x000a, 0x1c48: 0x000a, 0x1c49: 0x000a, 0x1c4a: 0x000a, 0x1c4b: 0x000a, + 0x1c4c: 0x000a, 0x1c4d: 0x000a, 0x1c4e: 0x000a, 0x1c4f: 0x000a, 0x1c50: 0x000a, 0x1c51: 0x000a, + 0x1c52: 0x000a, 0x1c53: 0x000a, 0x1c54: 0x000a, 0x1c55: 0x000a, 0x1c56: 0x000a, 0x1c57: 0x000a, + 0x1c58: 0x000a, 0x1c59: 0x000a, 0x1c5a: 0x000a, 0x1c5b: 0x000a, 0x1c5c: 0x000a, 0x1c5d: 0x000a, + 0x1c5e: 0x000a, 0x1c5f: 0x000a, 0x1c60: 0x000a, 0x1c61: 0x000a, 0x1c62: 0x000a, 0x1c63: 0x000a, + // Block 0x72, offset 0x1c80 + 0x1c9d: 0x000a, + 0x1c9e: 0x000a, + // Block 0x73, offset 0x1cc0 + 0x1cd0: 0x000a, 0x1cd1: 0x000a, + 0x1cd2: 0x000a, 0x1cd3: 0x000a, 0x1cd4: 0x000a, 0x1cd5: 0x000a, 0x1cd6: 0x000a, 0x1cd7: 0x000a, + 0x1cd8: 0x000a, 0x1cd9: 0x000a, 0x1cda: 0x000a, 0x1cdb: 0x000a, 0x1cdc: 0x000a, 0x1cdd: 0x000a, + 0x1cde: 0x000a, 0x1cdf: 0x000a, + 0x1cfc: 0x000a, 0x1cfd: 0x000a, 0x1cfe: 0x000a, + // Block 0x74, offset 0x1d00 + 0x1d31: 0x000a, 0x1d32: 0x000a, 0x1d33: 0x000a, 0x1d34: 0x000a, 0x1d35: 0x000a, + 0x1d36: 0x000a, 0x1d37: 0x000a, 0x1d38: 0x000a, 0x1d39: 0x000a, 0x1d3a: 0x000a, 0x1d3b: 0x000a, + 0x1d3c: 0x000a, 0x1d3d: 0x000a, 0x1d3e: 0x000a, 0x1d3f: 0x000a, + // Block 0x75, offset 0x1d40 + 0x1d4c: 0x000a, 0x1d4d: 0x000a, 0x1d4e: 0x000a, 0x1d4f: 0x000a, + // Block 0x76, offset 0x1d80 + 0x1db7: 0x000a, 0x1db8: 0x000a, 0x1db9: 0x000a, 0x1dba: 0x000a, + // Block 0x77, offset 0x1dc0 + 0x1dde: 0x000a, 0x1ddf: 0x000a, + 0x1dff: 0x000a, + // Block 0x78, offset 0x1e00 + 0x1e10: 0x000a, 0x1e11: 0x000a, + 0x1e12: 0x000a, 0x1e13: 0x000a, 0x1e14: 0x000a, 0x1e15: 0x000a, 0x1e16: 0x000a, 0x1e17: 0x000a, + 0x1e18: 0x000a, 0x1e19: 0x000a, 0x1e1a: 0x000a, 0x1e1b: 0x000a, 0x1e1c: 0x000a, 0x1e1d: 0x000a, + 0x1e1e: 0x000a, 0x1e1f: 0x000a, 0x1e20: 0x000a, 0x1e21: 0x000a, 0x1e22: 0x000a, 0x1e23: 0x000a, + 0x1e24: 0x000a, 0x1e25: 0x000a, 0x1e26: 0x000a, 0x1e27: 0x000a, 0x1e28: 0x000a, 0x1e29: 0x000a, + 0x1e2a: 0x000a, 0x1e2b: 0x000a, 0x1e2c: 0x000a, 0x1e2d: 0x000a, 0x1e2e: 0x000a, 0x1e2f: 0x000a, + 0x1e30: 0x000a, 0x1e31: 0x000a, 0x1e32: 0x000a, 0x1e33: 0x000a, 0x1e34: 0x000a, 0x1e35: 0x000a, + 0x1e36: 0x000a, 0x1e37: 0x000a, 0x1e38: 0x000a, 0x1e39: 0x000a, 0x1e3a: 0x000a, 0x1e3b: 0x000a, + 0x1e3c: 0x000a, 0x1e3d: 0x000a, 0x1e3e: 0x000a, 0x1e3f: 0x000a, + // Block 0x79, offset 0x1e40 + 0x1e40: 0x000a, 0x1e41: 0x000a, 0x1e42: 0x000a, 0x1e43: 0x000a, 0x1e44: 0x000a, 0x1e45: 0x000a, + 0x1e46: 0x000a, + // Block 0x7a, offset 0x1e80 + 0x1e8d: 0x000a, 0x1e8e: 0x000a, 0x1e8f: 0x000a, + // Block 0x7b, offset 0x1ec0 + 0x1eef: 0x000c, + 0x1ef0: 0x000c, 0x1ef1: 0x000c, 0x1ef2: 0x000c, 0x1ef3: 0x000a, 0x1ef4: 0x000c, 0x1ef5: 0x000c, + 0x1ef6: 0x000c, 0x1ef7: 0x000c, 0x1ef8: 0x000c, 0x1ef9: 0x000c, 0x1efa: 0x000c, 0x1efb: 0x000c, + 0x1efc: 0x000c, 0x1efd: 0x000c, 0x1efe: 0x000a, 0x1eff: 0x000a, + // Block 0x7c, offset 0x1f00 + 0x1f1e: 0x000c, 0x1f1f: 0x000c, + // Block 0x7d, offset 0x1f40 + 0x1f70: 0x000c, 0x1f71: 0x000c, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0x000a, 0x1f81: 0x000a, 0x1f82: 0x000a, 0x1f83: 0x000a, 0x1f84: 0x000a, 0x1f85: 0x000a, + 0x1f86: 0x000a, 0x1f87: 0x000a, 0x1f88: 0x000a, 0x1f89: 0x000a, 0x1f8a: 0x000a, 0x1f8b: 0x000a, + 0x1f8c: 0x000a, 0x1f8d: 0x000a, 0x1f8e: 0x000a, 0x1f8f: 0x000a, 0x1f90: 0x000a, 0x1f91: 0x000a, + 0x1f92: 0x000a, 0x1f93: 0x000a, 0x1f94: 0x000a, 0x1f95: 0x000a, 0x1f96: 0x000a, 0x1f97: 0x000a, + 0x1f98: 0x000a, 0x1f99: 0x000a, 0x1f9a: 0x000a, 0x1f9b: 0x000a, 0x1f9c: 0x000a, 0x1f9d: 0x000a, + 0x1f9e: 0x000a, 0x1f9f: 0x000a, 0x1fa0: 0x000a, 0x1fa1: 0x000a, + // Block 0x7f, offset 0x1fc0 + 0x1fc8: 0x000a, + // Block 0x80, offset 0x2000 + 0x2002: 0x000c, + 0x2006: 0x000c, 0x200b: 0x000c, + 0x2025: 0x000c, 0x2026: 0x000c, 0x2028: 0x000a, 0x2029: 0x000a, + 0x202a: 0x000a, 0x202b: 0x000a, + 0x2038: 0x0004, 0x2039: 0x0004, + // Block 0x81, offset 0x2040 + 0x2074: 0x000a, 0x2075: 0x000a, + 0x2076: 0x000a, 0x2077: 0x000a, + // Block 0x82, offset 0x2080 + 0x2084: 0x000c, 0x2085: 0x000c, + 0x20a0: 0x000c, 0x20a1: 0x000c, 0x20a2: 0x000c, 0x20a3: 0x000c, + 0x20a4: 0x000c, 0x20a5: 0x000c, 0x20a6: 0x000c, 0x20a7: 0x000c, 0x20a8: 0x000c, 0x20a9: 0x000c, + 0x20aa: 0x000c, 0x20ab: 0x000c, 0x20ac: 0x000c, 0x20ad: 0x000c, 0x20ae: 0x000c, 0x20af: 0x000c, + 0x20b0: 0x000c, 0x20b1: 0x000c, + 0x20bf: 0x000c, + // Block 0x83, offset 0x20c0 + 0x20e6: 0x000c, 0x20e7: 0x000c, 0x20e8: 0x000c, 0x20e9: 0x000c, + 0x20ea: 0x000c, 0x20eb: 0x000c, 0x20ec: 0x000c, 0x20ed: 0x000c, + // Block 0x84, offset 0x2100 + 0x2107: 0x000c, 0x2108: 0x000c, 0x2109: 0x000c, 0x210a: 0x000c, 0x210b: 0x000c, + 0x210c: 0x000c, 0x210d: 0x000c, 0x210e: 0x000c, 0x210f: 0x000c, 0x2110: 0x000c, 0x2111: 0x000c, + // Block 0x85, offset 0x2140 + 0x2140: 0x000c, 0x2141: 0x000c, 0x2142: 0x000c, + 0x2173: 0x000c, + 0x2176: 0x000c, 0x2177: 0x000c, 0x2178: 0x000c, 0x2179: 0x000c, + 0x217c: 0x000c, 0x217d: 0x000c, + // Block 0x86, offset 0x2180 + 0x21a5: 0x000c, + // Block 0x87, offset 0x21c0 + 0x21e9: 0x000c, + 0x21ea: 0x000c, 0x21eb: 0x000c, 0x21ec: 0x000c, 0x21ed: 0x000c, 0x21ee: 0x000c, + 0x21f1: 0x000c, 0x21f2: 0x000c, 0x21f5: 0x000c, + 0x21f6: 0x000c, + // Block 0x88, offset 0x2200 + 0x2203: 0x000c, + 0x220c: 0x000c, + 0x223c: 0x000c, + // Block 0x89, offset 0x2240 + 0x2270: 0x000c, 0x2272: 0x000c, 0x2273: 0x000c, 0x2274: 0x000c, + 0x2277: 0x000c, 0x2278: 0x000c, + 0x227e: 0x000c, 0x227f: 0x000c, + // Block 0x8a, offset 0x2280 + 0x2281: 0x000c, + 0x22ac: 0x000c, 0x22ad: 0x000c, + 0x22b6: 0x000c, + // Block 0x8b, offset 0x22c0 + 0x22e5: 0x000c, 0x22e8: 0x000c, + 0x22ed: 0x000c, + // Block 0x8c, offset 0x2300 + 0x231d: 0x0001, + 0x231e: 0x000c, 0x231f: 0x0001, 0x2320: 0x0001, 0x2321: 0x0001, 0x2322: 0x0001, 0x2323: 0x0001, + 0x2324: 0x0001, 0x2325: 0x0001, 0x2326: 0x0001, 0x2327: 0x0001, 0x2328: 0x0001, 0x2329: 0x0003, + 0x232a: 0x0001, 0x232b: 0x0001, 0x232c: 0x0001, 0x232d: 0x0001, 0x232e: 0x0001, 0x232f: 0x0001, + 0x2330: 0x0001, 0x2331: 0x0001, 0x2332: 0x0001, 0x2333: 0x0001, 0x2334: 0x0001, 0x2335: 0x0001, + 0x2336: 0x0001, 0x2337: 0x0001, 0x2338: 0x0001, 0x2339: 0x0001, 0x233a: 0x0001, 0x233b: 0x0001, + 0x233c: 0x0001, 0x233d: 0x0001, 0x233e: 0x0001, 0x233f: 0x0001, + // Block 0x8d, offset 0x2340 + 0x2340: 0x0001, 0x2341: 0x0001, 0x2342: 0x0001, 0x2343: 0x0001, 0x2344: 0x0001, 0x2345: 0x0001, + 0x2346: 0x0001, 0x2347: 0x0001, 0x2348: 0x0001, 0x2349: 0x0001, 0x234a: 0x0001, 0x234b: 0x0001, + 0x234c: 0x0001, 0x234d: 0x0001, 0x234e: 0x0001, 0x234f: 0x0001, 0x2350: 0x000d, 0x2351: 0x000d, + 0x2352: 0x000d, 0x2353: 0x000d, 0x2354: 0x000d, 0x2355: 0x000d, 0x2356: 0x000d, 0x2357: 0x000d, + 0x2358: 0x000d, 0x2359: 0x000d, 0x235a: 0x000d, 0x235b: 0x000d, 0x235c: 0x000d, 0x235d: 0x000d, + 0x235e: 0x000d, 0x235f: 0x000d, 0x2360: 0x000d, 0x2361: 0x000d, 0x2362: 0x000d, 0x2363: 0x000d, + 0x2364: 0x000d, 0x2365: 0x000d, 0x2366: 0x000d, 0x2367: 0x000d, 0x2368: 0x000d, 0x2369: 0x000d, + 0x236a: 0x000d, 0x236b: 0x000d, 0x236c: 0x000d, 0x236d: 0x000d, 0x236e: 0x000d, 0x236f: 0x000d, + 0x2370: 0x000d, 0x2371: 0x000d, 0x2372: 0x000d, 0x2373: 0x000d, 0x2374: 0x000d, 0x2375: 0x000d, + 0x2376: 0x000d, 0x2377: 0x000d, 0x2378: 0x000d, 0x2379: 0x000d, 0x237a: 0x000d, 0x237b: 0x000d, + 0x237c: 0x000d, 0x237d: 0x000d, 0x237e: 0x000d, 0x237f: 0x000d, + // Block 0x8e, offset 0x2380 + 0x2380: 0x000d, 0x2381: 0x000d, 0x2382: 0x000d, 0x2383: 0x000d, 0x2384: 0x000d, 0x2385: 0x000d, + 0x2386: 0x000d, 0x2387: 0x000d, 0x2388: 0x000d, 0x2389: 0x000d, 0x238a: 0x000d, 0x238b: 0x000d, + 0x238c: 0x000d, 0x238d: 0x000d, 0x238e: 0x000d, 0x238f: 0x000d, 0x2390: 0x000d, 0x2391: 0x000d, + 0x2392: 0x000d, 0x2393: 0x000d, 0x2394: 0x000d, 0x2395: 0x000d, 0x2396: 0x000d, 0x2397: 0x000d, + 0x2398: 0x000d, 0x2399: 0x000d, 0x239a: 0x000d, 0x239b: 0x000d, 0x239c: 0x000d, 0x239d: 0x000d, + 0x239e: 0x000d, 0x239f: 0x000d, 0x23a0: 0x000d, 0x23a1: 0x000d, 0x23a2: 0x000d, 0x23a3: 0x000d, + 0x23a4: 0x000d, 0x23a5: 0x000d, 0x23a6: 0x000d, 0x23a7: 0x000d, 0x23a8: 0x000d, 0x23a9: 0x000d, + 0x23aa: 0x000d, 0x23ab: 0x000d, 0x23ac: 0x000d, 0x23ad: 0x000d, 0x23ae: 0x000d, 0x23af: 0x000d, + 0x23b0: 0x000d, 0x23b1: 0x000d, 0x23b2: 0x000d, 0x23b3: 0x000d, 0x23b4: 0x000d, 0x23b5: 0x000d, + 0x23b6: 0x000d, 0x23b7: 0x000d, 0x23b8: 0x000d, 0x23b9: 0x000d, 0x23ba: 0x000d, 0x23bb: 0x000d, + 0x23bc: 0x000d, 0x23bd: 0x000d, 0x23be: 0x000a, 0x23bf: 0x000a, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x000d, 0x23c1: 0x000d, 0x23c2: 0x000d, 0x23c3: 0x000d, 0x23c4: 0x000d, 0x23c5: 0x000d, + 0x23c6: 0x000d, 0x23c7: 0x000d, 0x23c8: 0x000d, 0x23c9: 0x000d, 0x23ca: 0x000d, 0x23cb: 0x000d, + 0x23cc: 0x000d, 0x23cd: 0x000d, 0x23ce: 0x000d, 0x23cf: 0x000d, 0x23d0: 0x000b, 0x23d1: 0x000b, + 0x23d2: 0x000b, 0x23d3: 0x000b, 0x23d4: 0x000b, 0x23d5: 0x000b, 0x23d6: 0x000b, 0x23d7: 0x000b, + 0x23d8: 0x000b, 0x23d9: 0x000b, 0x23da: 0x000b, 0x23db: 0x000b, 0x23dc: 0x000b, 0x23dd: 0x000b, + 0x23de: 0x000b, 0x23df: 0x000b, 0x23e0: 0x000b, 0x23e1: 0x000b, 0x23e2: 0x000b, 0x23e3: 0x000b, + 0x23e4: 0x000b, 0x23e5: 0x000b, 0x23e6: 0x000b, 0x23e7: 0x000b, 0x23e8: 0x000b, 0x23e9: 0x000b, + 0x23ea: 0x000b, 0x23eb: 0x000b, 0x23ec: 0x000b, 0x23ed: 0x000b, 0x23ee: 0x000b, 0x23ef: 0x000b, + 0x23f0: 0x000d, 0x23f1: 0x000d, 0x23f2: 0x000d, 0x23f3: 0x000d, 0x23f4: 0x000d, 0x23f5: 0x000d, + 0x23f6: 0x000d, 0x23f7: 0x000d, 0x23f8: 0x000d, 0x23f9: 0x000d, 0x23fa: 0x000d, 0x23fb: 0x000d, + 0x23fc: 0x000d, 0x23fd: 0x000a, 0x23fe: 0x000d, 0x23ff: 0x000d, + // Block 0x90, offset 0x2400 + 0x2400: 0x000c, 0x2401: 0x000c, 0x2402: 0x000c, 0x2403: 0x000c, 0x2404: 0x000c, 0x2405: 0x000c, + 0x2406: 0x000c, 0x2407: 0x000c, 0x2408: 0x000c, 0x2409: 0x000c, 0x240a: 0x000c, 0x240b: 0x000c, + 0x240c: 0x000c, 0x240d: 0x000c, 0x240e: 0x000c, 0x240f: 0x000c, 0x2410: 0x000a, 0x2411: 0x000a, + 0x2412: 0x000a, 0x2413: 0x000a, 0x2414: 0x000a, 0x2415: 0x000a, 0x2416: 0x000a, 0x2417: 0x000a, + 0x2418: 0x000a, 0x2419: 0x000a, + 0x2420: 0x000c, 0x2421: 0x000c, 0x2422: 0x000c, 0x2423: 0x000c, + 0x2424: 0x000c, 0x2425: 0x000c, 0x2426: 0x000c, 0x2427: 0x000c, 0x2428: 0x000c, 0x2429: 0x000c, + 0x242a: 0x000c, 0x242b: 0x000c, 0x242c: 0x000c, 0x242d: 0x000c, 0x242e: 0x000c, 0x242f: 0x000c, + 0x2430: 0x000a, 0x2431: 0x000a, 0x2432: 0x000a, 0x2433: 0x000a, 0x2434: 0x000a, 0x2435: 0x000a, + 0x2436: 0x000a, 0x2437: 0x000a, 0x2438: 0x000a, 0x2439: 0x000a, 0x243a: 0x000a, 0x243b: 0x000a, + 0x243c: 0x000a, 0x243d: 0x000a, 0x243e: 0x000a, 0x243f: 0x000a, + // Block 0x91, offset 0x2440 + 0x2440: 0x000a, 0x2441: 0x000a, 0x2442: 0x000a, 0x2443: 0x000a, 0x2444: 0x000a, 0x2445: 0x000a, + 0x2446: 0x000a, 0x2447: 0x000a, 0x2448: 0x000a, 0x2449: 0x000a, 0x244a: 0x000a, 0x244b: 0x000a, + 0x244c: 0x000a, 0x244d: 0x000a, 0x244e: 0x000a, 0x244f: 0x000a, 0x2450: 0x0006, 0x2451: 0x000a, + 0x2452: 0x0006, 0x2454: 0x000a, 0x2455: 0x0006, 0x2456: 0x000a, 0x2457: 0x000a, + 0x2458: 0x000a, 0x2459: 0x009a, 0x245a: 0x008a, 0x245b: 0x007a, 0x245c: 0x006a, 0x245d: 0x009a, + 0x245e: 0x008a, 0x245f: 0x0004, 0x2460: 0x000a, 0x2461: 0x000a, 0x2462: 0x0003, 0x2463: 0x0003, + 0x2464: 0x000a, 0x2465: 0x000a, 0x2466: 0x000a, 0x2468: 0x000a, 0x2469: 0x0004, + 0x246a: 0x0004, 0x246b: 0x000a, + 0x2470: 0x000d, 0x2471: 0x000d, 0x2472: 0x000d, 0x2473: 0x000d, 0x2474: 0x000d, 0x2475: 0x000d, + 0x2476: 0x000d, 0x2477: 0x000d, 0x2478: 0x000d, 0x2479: 0x000d, 0x247a: 0x000d, 0x247b: 0x000d, + 0x247c: 0x000d, 0x247d: 0x000d, 0x247e: 0x000d, 0x247f: 0x000d, + // Block 0x92, offset 0x2480 + 0x2480: 0x000d, 0x2481: 0x000d, 0x2482: 0x000d, 0x2483: 0x000d, 0x2484: 0x000d, 0x2485: 0x000d, + 0x2486: 0x000d, 0x2487: 0x000d, 0x2488: 0x000d, 0x2489: 0x000d, 0x248a: 0x000d, 0x248b: 0x000d, + 0x248c: 0x000d, 0x248d: 0x000d, 0x248e: 0x000d, 0x248f: 0x000d, 0x2490: 0x000d, 0x2491: 0x000d, + 0x2492: 0x000d, 0x2493: 0x000d, 0x2494: 0x000d, 0x2495: 0x000d, 0x2496: 0x000d, 0x2497: 0x000d, + 0x2498: 0x000d, 0x2499: 0x000d, 0x249a: 0x000d, 0x249b: 0x000d, 0x249c: 0x000d, 0x249d: 0x000d, + 0x249e: 0x000d, 0x249f: 0x000d, 0x24a0: 0x000d, 0x24a1: 0x000d, 0x24a2: 0x000d, 0x24a3: 0x000d, + 0x24a4: 0x000d, 0x24a5: 0x000d, 0x24a6: 0x000d, 0x24a7: 0x000d, 0x24a8: 0x000d, 0x24a9: 0x000d, + 0x24aa: 0x000d, 0x24ab: 0x000d, 0x24ac: 0x000d, 0x24ad: 0x000d, 0x24ae: 0x000d, 0x24af: 0x000d, + 0x24b0: 0x000d, 0x24b1: 0x000d, 0x24b2: 0x000d, 0x24b3: 0x000d, 0x24b4: 0x000d, 0x24b5: 0x000d, + 0x24b6: 0x000d, 0x24b7: 0x000d, 0x24b8: 0x000d, 0x24b9: 0x000d, 0x24ba: 0x000d, 0x24bb: 0x000d, + 0x24bc: 0x000d, 0x24bd: 0x000d, 0x24be: 0x000d, 0x24bf: 0x000b, + // Block 0x93, offset 0x24c0 + 0x24c1: 0x000a, 0x24c2: 0x000a, 0x24c3: 0x0004, 0x24c4: 0x0004, 0x24c5: 0x0004, + 0x24c6: 0x000a, 0x24c7: 0x000a, 0x24c8: 0x003a, 0x24c9: 0x002a, 0x24ca: 0x000a, 0x24cb: 0x0003, + 0x24cc: 0x0006, 0x24cd: 0x0003, 0x24ce: 0x0006, 0x24cf: 0x0006, 0x24d0: 0x0002, 0x24d1: 0x0002, + 0x24d2: 0x0002, 0x24d3: 0x0002, 0x24d4: 0x0002, 0x24d5: 0x0002, 0x24d6: 0x0002, 0x24d7: 0x0002, + 0x24d8: 0x0002, 0x24d9: 0x0002, 0x24da: 0x0006, 0x24db: 0x000a, 0x24dc: 0x000a, 0x24dd: 0x000a, + 0x24de: 0x000a, 0x24df: 0x000a, 0x24e0: 0x000a, + 0x24fb: 0x005a, + 0x24fc: 0x000a, 0x24fd: 0x004a, 0x24fe: 0x000a, 0x24ff: 0x000a, + // Block 0x94, offset 0x2500 + 0x2500: 0x000a, + 0x251b: 0x005a, 0x251c: 0x000a, 0x251d: 0x004a, + 0x251e: 0x000a, 0x251f: 0x00fa, 0x2520: 0x00ea, 0x2521: 0x000a, 0x2522: 0x003a, 0x2523: 0x002a, + 0x2524: 0x000a, 0x2525: 0x000a, + // Block 0x95, offset 0x2540 + 0x2560: 0x0004, 0x2561: 0x0004, 0x2562: 0x000a, 0x2563: 0x000a, + 0x2564: 0x000a, 0x2565: 0x0004, 0x2566: 0x0004, 0x2568: 0x000a, 0x2569: 0x000a, + 0x256a: 0x000a, 0x256b: 0x000a, 0x256c: 0x000a, 0x256d: 0x000a, 0x256e: 0x000a, + 0x2570: 0x000b, 0x2571: 0x000b, 0x2572: 0x000b, 0x2573: 0x000b, 0x2574: 0x000b, 0x2575: 0x000b, + 0x2576: 0x000b, 0x2577: 0x000b, 0x2578: 0x000b, 0x2579: 0x000a, 0x257a: 0x000a, 0x257b: 0x000a, + 0x257c: 0x000a, 0x257d: 0x000a, 0x257e: 0x000b, 0x257f: 0x000b, + // Block 0x96, offset 0x2580 + 0x2581: 0x000a, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x000a, 0x25c1: 0x000a, 0x25c2: 0x000a, 0x25c3: 0x000a, 0x25c4: 0x000a, 0x25c5: 0x000a, + 0x25c6: 0x000a, 0x25c7: 0x000a, 0x25c8: 0x000a, 0x25c9: 0x000a, 0x25ca: 0x000a, 0x25cb: 0x000a, + 0x25cc: 0x000a, 0x25d0: 0x000a, 0x25d1: 0x000a, + 0x25d2: 0x000a, 0x25d3: 0x000a, 0x25d4: 0x000a, 0x25d5: 0x000a, 0x25d6: 0x000a, 0x25d7: 0x000a, + 0x25d8: 0x000a, 0x25d9: 0x000a, 0x25da: 0x000a, 0x25db: 0x000a, + 0x25e0: 0x000a, + // Block 0x98, offset 0x2600 + 0x263d: 0x000c, + // Block 0x99, offset 0x2640 + 0x2660: 0x000c, 0x2661: 0x0002, 0x2662: 0x0002, 0x2663: 0x0002, + 0x2664: 0x0002, 0x2665: 0x0002, 0x2666: 0x0002, 0x2667: 0x0002, 0x2668: 0x0002, 0x2669: 0x0002, + 0x266a: 0x0002, 0x266b: 0x0002, 0x266c: 0x0002, 0x266d: 0x0002, 0x266e: 0x0002, 0x266f: 0x0002, + 0x2670: 0x0002, 0x2671: 0x0002, 0x2672: 0x0002, 0x2673: 0x0002, 0x2674: 0x0002, 0x2675: 0x0002, + 0x2676: 0x0002, 0x2677: 0x0002, 0x2678: 0x0002, 0x2679: 0x0002, 0x267a: 0x0002, 0x267b: 0x0002, + // Block 0x9a, offset 0x2680 + 0x26b6: 0x000c, 0x26b7: 0x000c, 0x26b8: 0x000c, 0x26b9: 0x000c, 0x26ba: 0x000c, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x0001, 0x26c1: 0x0001, 0x26c2: 0x0001, 0x26c3: 0x0001, 0x26c4: 0x0001, 0x26c5: 0x0001, + 0x26c6: 0x0001, 0x26c7: 0x0001, 0x26c8: 0x0001, 0x26c9: 0x0001, 0x26ca: 0x0001, 0x26cb: 0x0001, + 0x26cc: 0x0001, 0x26cd: 0x0001, 0x26ce: 0x0001, 0x26cf: 0x0001, 0x26d0: 0x0001, 0x26d1: 0x0001, + 0x26d2: 0x0001, 0x26d3: 0x0001, 0x26d4: 0x0001, 0x26d5: 0x0001, 0x26d6: 0x0001, 0x26d7: 0x0001, + 0x26d8: 0x0001, 0x26d9: 0x0001, 0x26da: 0x0001, 0x26db: 0x0001, 0x26dc: 0x0001, 0x26dd: 0x0001, + 0x26de: 0x0001, 0x26df: 0x0001, 0x26e0: 0x0001, 0x26e1: 0x0001, 0x26e2: 0x0001, 0x26e3: 0x0001, + 0x26e4: 0x0001, 0x26e5: 0x0001, 0x26e6: 0x0001, 0x26e7: 0x0001, 0x26e8: 0x0001, 0x26e9: 0x0001, + 0x26ea: 0x0001, 0x26eb: 0x0001, 0x26ec: 0x0001, 0x26ed: 0x0001, 0x26ee: 0x0001, 0x26ef: 0x0001, + 0x26f0: 0x0001, 0x26f1: 0x0001, 0x26f2: 0x0001, 0x26f3: 0x0001, 0x26f4: 0x0001, 0x26f5: 0x0001, + 0x26f6: 0x0001, 0x26f7: 0x0001, 0x26f8: 0x0001, 0x26f9: 0x0001, 0x26fa: 0x0001, 0x26fb: 0x0001, + 0x26fc: 0x0001, 0x26fd: 0x0001, 0x26fe: 0x0001, 0x26ff: 0x0001, + // Block 0x9c, offset 0x2700 + 0x2700: 0x0001, 0x2701: 0x0001, 0x2702: 0x0001, 0x2703: 0x0001, 0x2704: 0x0001, 0x2705: 0x0001, + 0x2706: 0x0001, 0x2707: 0x0001, 0x2708: 0x0001, 0x2709: 0x0001, 0x270a: 0x0001, 0x270b: 0x0001, + 0x270c: 0x0001, 0x270d: 0x0001, 0x270e: 0x0001, 0x270f: 0x0001, 0x2710: 0x0001, 0x2711: 0x0001, + 0x2712: 0x0001, 0x2713: 0x0001, 0x2714: 0x0001, 0x2715: 0x0001, 0x2716: 0x0001, 0x2717: 0x0001, + 0x2718: 0x0001, 0x2719: 0x0001, 0x271a: 0x0001, 0x271b: 0x0001, 0x271c: 0x0001, 0x271d: 0x0001, + 0x271e: 0x0001, 0x271f: 0x000a, 0x2720: 0x0001, 0x2721: 0x0001, 0x2722: 0x0001, 0x2723: 0x0001, + 0x2724: 0x0001, 0x2725: 0x0001, 0x2726: 0x0001, 0x2727: 0x0001, 0x2728: 0x0001, 0x2729: 0x0001, + 0x272a: 0x0001, 0x272b: 0x0001, 0x272c: 0x0001, 0x272d: 0x0001, 0x272e: 0x0001, 0x272f: 0x0001, + 0x2730: 0x0001, 0x2731: 0x0001, 0x2732: 0x0001, 0x2733: 0x0001, 0x2734: 0x0001, 0x2735: 0x0001, + 0x2736: 0x0001, 0x2737: 0x0001, 0x2738: 0x0001, 0x2739: 0x0001, 0x273a: 0x0001, 0x273b: 0x0001, + 0x273c: 0x0001, 0x273d: 0x0001, 0x273e: 0x0001, 0x273f: 0x0001, + // Block 0x9d, offset 0x2740 + 0x2740: 0x0001, 0x2741: 0x000c, 0x2742: 0x000c, 0x2743: 0x000c, 0x2744: 0x0001, 0x2745: 0x000c, + 0x2746: 0x000c, 0x2747: 0x0001, 0x2748: 0x0001, 0x2749: 0x0001, 0x274a: 0x0001, 0x274b: 0x0001, + 0x274c: 0x000c, 0x274d: 0x000c, 0x274e: 0x000c, 0x274f: 0x000c, 0x2750: 0x0001, 0x2751: 0x0001, + 0x2752: 0x0001, 0x2753: 0x0001, 0x2754: 0x0001, 0x2755: 0x0001, 0x2756: 0x0001, 0x2757: 0x0001, + 0x2758: 0x0001, 0x2759: 0x0001, 0x275a: 0x0001, 0x275b: 0x0001, 0x275c: 0x0001, 0x275d: 0x0001, + 0x275e: 0x0001, 0x275f: 0x0001, 0x2760: 0x0001, 0x2761: 0x0001, 0x2762: 0x0001, 0x2763: 0x0001, + 0x2764: 0x0001, 0x2765: 0x0001, 0x2766: 0x0001, 0x2767: 0x0001, 0x2768: 0x0001, 0x2769: 0x0001, + 0x276a: 0x0001, 0x276b: 0x0001, 0x276c: 0x0001, 0x276d: 0x0001, 0x276e: 0x0001, 0x276f: 0x0001, + 0x2770: 0x0001, 0x2771: 0x0001, 0x2772: 0x0001, 0x2773: 0x0001, 0x2774: 0x0001, 0x2775: 0x0001, + 0x2776: 0x0001, 0x2777: 0x0001, 0x2778: 0x000c, 0x2779: 0x000c, 0x277a: 0x000c, 0x277b: 0x0001, + 0x277c: 0x0001, 0x277d: 0x0001, 0x277e: 0x0001, 0x277f: 0x000c, + // Block 0x9e, offset 0x2780 + 0x2780: 0x0001, 0x2781: 0x0001, 0x2782: 0x0001, 0x2783: 0x0001, 0x2784: 0x0001, 0x2785: 0x0001, + 0x2786: 0x0001, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001, + 0x278c: 0x0001, 0x278d: 0x0001, 0x278e: 0x0001, 0x278f: 0x0001, 0x2790: 0x0001, 0x2791: 0x0001, + 0x2792: 0x0001, 0x2793: 0x0001, 0x2794: 0x0001, 0x2795: 0x0001, 0x2796: 0x0001, 0x2797: 0x0001, + 0x2798: 0x0001, 0x2799: 0x0001, 0x279a: 0x0001, 0x279b: 0x0001, 0x279c: 0x0001, 0x279d: 0x0001, + 0x279e: 0x0001, 0x279f: 0x0001, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001, + 0x27a4: 0x0001, 0x27a5: 0x000c, 0x27a6: 0x000c, 0x27a7: 0x0001, 0x27a8: 0x0001, 0x27a9: 0x0001, + 0x27aa: 0x0001, 0x27ab: 0x0001, 0x27ac: 0x0001, 0x27ad: 0x0001, 0x27ae: 0x0001, 0x27af: 0x0001, + 0x27b0: 0x0001, 0x27b1: 0x0001, 0x27b2: 0x0001, 0x27b3: 0x0001, 0x27b4: 0x0001, 0x27b5: 0x0001, + 0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x0001, 0x27b9: 0x0001, 0x27ba: 0x0001, 0x27bb: 0x0001, + 0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x0001, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x0001, 0x27c1: 0x0001, 0x27c2: 0x0001, 0x27c3: 0x0001, 0x27c4: 0x0001, 0x27c5: 0x0001, + 0x27c6: 0x0001, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001, + 0x27cc: 0x0001, 0x27cd: 0x0001, 0x27ce: 0x0001, 0x27cf: 0x0001, 0x27d0: 0x0001, 0x27d1: 0x0001, + 0x27d2: 0x0001, 0x27d3: 0x0001, 0x27d4: 0x0001, 0x27d5: 0x0001, 0x27d6: 0x0001, 0x27d7: 0x0001, + 0x27d8: 0x0001, 0x27d9: 0x0001, 0x27da: 0x0001, 0x27db: 0x0001, 0x27dc: 0x0001, 0x27dd: 0x0001, + 0x27de: 0x0001, 0x27df: 0x0001, 0x27e0: 0x0001, 0x27e1: 0x0001, 0x27e2: 0x0001, 0x27e3: 0x0001, + 0x27e4: 0x0001, 0x27e5: 0x0001, 0x27e6: 0x0001, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001, + 0x27ea: 0x0001, 0x27eb: 0x0001, 0x27ec: 0x0001, 0x27ed: 0x0001, 0x27ee: 0x0001, 0x27ef: 0x0001, + 0x27f0: 0x0001, 0x27f1: 0x0001, 0x27f2: 0x0001, 0x27f3: 0x0001, 0x27f4: 0x0001, 0x27f5: 0x0001, + 0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x0001, 0x27f9: 0x000a, 0x27fa: 0x000a, 0x27fb: 0x000a, + 0x27fc: 0x000a, 0x27fd: 0x000a, 0x27fe: 0x000a, 0x27ff: 0x000a, + // Block 0xa0, offset 0x2800 + 0x2800: 0x000d, 0x2801: 0x000d, 0x2802: 0x000d, 0x2803: 0x000d, 0x2804: 0x000d, 0x2805: 0x000d, + 0x2806: 0x000d, 0x2807: 0x000d, 0x2808: 0x000d, 0x2809: 0x000d, 0x280a: 0x000d, 0x280b: 0x000d, + 0x280c: 0x000d, 0x280d: 0x000d, 0x280e: 0x000d, 0x280f: 0x000d, 0x2810: 0x000d, 0x2811: 0x000d, + 0x2812: 0x000d, 0x2813: 0x000d, 0x2814: 0x000d, 0x2815: 0x000d, 0x2816: 0x000d, 0x2817: 0x000d, + 0x2818: 0x000d, 0x2819: 0x000d, 0x281a: 0x000d, 0x281b: 0x000d, 0x281c: 0x000d, 0x281d: 0x000d, + 0x281e: 0x000d, 0x281f: 0x000d, 0x2820: 0x000d, 0x2821: 0x000d, 0x2822: 0x000d, 0x2823: 0x000d, + 0x2824: 0x000c, 0x2825: 0x000c, 0x2826: 0x000c, 0x2827: 0x000c, 0x2828: 0x000d, 0x2829: 0x000d, + 0x282a: 0x000d, 0x282b: 0x000d, 0x282c: 0x000d, 0x282d: 0x000d, 0x282e: 0x000d, 0x282f: 0x000d, + 0x2830: 0x0005, 0x2831: 0x0005, 0x2832: 0x0005, 0x2833: 0x0005, 0x2834: 0x0005, 0x2835: 0x0005, + 0x2836: 0x0005, 0x2837: 0x0005, 0x2838: 0x0005, 0x2839: 0x0005, 0x283a: 0x000d, 0x283b: 0x000d, + 0x283c: 0x000d, 0x283d: 0x000d, 0x283e: 0x000d, 0x283f: 0x000d, + // Block 0xa1, offset 0x2840 + 0x2840: 0x0001, 0x2841: 0x0001, 0x2842: 0x0001, 0x2843: 0x0001, 0x2844: 0x0001, 0x2845: 0x0001, + 0x2846: 0x0001, 0x2847: 0x0001, 0x2848: 0x0001, 0x2849: 0x0001, 0x284a: 0x0001, 0x284b: 0x0001, + 0x284c: 0x0001, 0x284d: 0x0001, 0x284e: 0x0001, 0x284f: 0x0001, 0x2850: 0x0001, 0x2851: 0x0001, + 0x2852: 0x0001, 0x2853: 0x0001, 0x2854: 0x0001, 0x2855: 0x0001, 0x2856: 0x0001, 0x2857: 0x0001, + 0x2858: 0x0001, 0x2859: 0x0001, 0x285a: 0x0001, 0x285b: 0x0001, 0x285c: 0x0001, 0x285d: 0x0001, + 0x285e: 0x0001, 0x285f: 0x0001, 0x2860: 0x0005, 0x2861: 0x0005, 0x2862: 0x0005, 0x2863: 0x0005, + 0x2864: 0x0005, 0x2865: 0x0005, 0x2866: 0x0005, 0x2867: 0x0005, 0x2868: 0x0005, 0x2869: 0x0005, + 0x286a: 0x0005, 0x286b: 0x0005, 0x286c: 0x0005, 0x286d: 0x0005, 0x286e: 0x0005, 0x286f: 0x0005, + 0x2870: 0x0005, 0x2871: 0x0005, 0x2872: 0x0005, 0x2873: 0x0005, 0x2874: 0x0005, 0x2875: 0x0005, + 0x2876: 0x0005, 0x2877: 0x0005, 0x2878: 0x0005, 0x2879: 0x0005, 0x287a: 0x0005, 0x287b: 0x0005, + 0x287c: 0x0005, 0x287d: 0x0005, 0x287e: 0x0005, 0x287f: 0x0001, + // Block 0xa2, offset 0x2880 + 0x2880: 0x0001, 0x2881: 0x0001, 0x2882: 0x0001, 0x2883: 0x0001, 0x2884: 0x0001, 0x2885: 0x0001, + 0x2886: 0x0001, 0x2887: 0x0001, 0x2888: 0x0001, 0x2889: 0x0001, 0x288a: 0x0001, 0x288b: 0x0001, + 0x288c: 0x0001, 0x288d: 0x0001, 0x288e: 0x0001, 0x288f: 0x0001, 0x2890: 0x0001, 0x2891: 0x0001, + 0x2892: 0x0001, 0x2893: 0x0001, 0x2894: 0x0001, 0x2895: 0x0001, 0x2896: 0x0001, 0x2897: 0x0001, + 0x2898: 0x0001, 0x2899: 0x0001, 0x289a: 0x0001, 0x289b: 0x0001, 0x289c: 0x0001, 0x289d: 0x0001, + 0x289e: 0x0001, 0x289f: 0x0001, 0x28a0: 0x0001, 0x28a1: 0x0001, 0x28a2: 0x0001, 0x28a3: 0x0001, + 0x28a4: 0x0001, 0x28a5: 0x0001, 0x28a6: 0x0001, 0x28a7: 0x0001, 0x28a8: 0x0001, 0x28a9: 0x0001, + 0x28aa: 0x0001, 0x28ab: 0x0001, 0x28ac: 0x0001, 0x28ad: 0x0001, 0x28ae: 0x0001, 0x28af: 0x0001, + 0x28b0: 0x000d, 0x28b1: 0x000d, 0x28b2: 0x000d, 0x28b3: 0x000d, 0x28b4: 0x000d, 0x28b5: 0x000d, + 0x28b6: 0x000d, 0x28b7: 0x000d, 0x28b8: 0x000d, 0x28b9: 0x000d, 0x28ba: 0x000d, 0x28bb: 0x000d, + 0x28bc: 0x000d, 0x28bd: 0x000d, 0x28be: 0x000d, 0x28bf: 0x000d, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x000d, 0x28c1: 0x000d, 0x28c2: 0x000d, 0x28c3: 0x000d, 0x28c4: 0x000d, 0x28c5: 0x000d, + 0x28c6: 0x000c, 0x28c7: 0x000c, 0x28c8: 0x000c, 0x28c9: 0x000c, 0x28ca: 0x000c, 0x28cb: 0x000c, + 0x28cc: 0x000c, 0x28cd: 0x000c, 0x28ce: 0x000c, 0x28cf: 0x000c, 0x28d0: 0x000c, 0x28d1: 0x000d, + 0x28d2: 0x000d, 0x28d3: 0x000d, 0x28d4: 0x000d, 0x28d5: 0x000d, 0x28d6: 0x000d, 0x28d7: 0x000d, + 0x28d8: 0x000d, 0x28d9: 0x000d, 0x28da: 0x000d, 0x28db: 0x000d, 0x28dc: 0x000d, 0x28dd: 0x000d, + 0x28de: 0x000d, 0x28df: 0x000d, 0x28e0: 0x000d, 0x28e1: 0x000d, 0x28e2: 0x000d, 0x28e3: 0x000d, + 0x28e4: 0x000d, 0x28e5: 0x000d, 0x28e6: 0x000d, 0x28e7: 0x000d, 0x28e8: 0x000d, 0x28e9: 0x000d, + 0x28ea: 0x000d, 0x28eb: 0x000d, 0x28ec: 0x000d, 0x28ed: 0x000d, 0x28ee: 0x000d, 0x28ef: 0x000d, + 0x28f0: 0x0001, 0x28f1: 0x0001, 0x28f2: 0x0001, 0x28f3: 0x0001, 0x28f4: 0x0001, 0x28f5: 0x0001, + 0x28f6: 0x0001, 0x28f7: 0x0001, 0x28f8: 0x0001, 0x28f9: 0x0001, 0x28fa: 0x0001, 0x28fb: 0x0001, + 0x28fc: 0x0001, 0x28fd: 0x0001, 0x28fe: 0x0001, 0x28ff: 0x0001, + // Block 0xa4, offset 0x2900 + 0x2901: 0x000c, + 0x2938: 0x000c, 0x2939: 0x000c, 0x293a: 0x000c, 0x293b: 0x000c, + 0x293c: 0x000c, 0x293d: 0x000c, 0x293e: 0x000c, 0x293f: 0x000c, + // Block 0xa5, offset 0x2940 + 0x2940: 0x000c, 0x2941: 0x000c, 0x2942: 0x000c, 0x2943: 0x000c, 0x2944: 0x000c, 0x2945: 0x000c, + 0x2946: 0x000c, + 0x2952: 0x000a, 0x2953: 0x000a, 0x2954: 0x000a, 0x2955: 0x000a, 0x2956: 0x000a, 0x2957: 0x000a, + 0x2958: 0x000a, 0x2959: 0x000a, 0x295a: 0x000a, 0x295b: 0x000a, 0x295c: 0x000a, 0x295d: 0x000a, + 0x295e: 0x000a, 0x295f: 0x000a, 0x2960: 0x000a, 0x2961: 0x000a, 0x2962: 0x000a, 0x2963: 0x000a, + 0x2964: 0x000a, 0x2965: 0x000a, + 0x297f: 0x000c, + // Block 0xa6, offset 0x2980 + 0x2980: 0x000c, 0x2981: 0x000c, + 0x29b3: 0x000c, 0x29b4: 0x000c, 0x29b5: 0x000c, + 0x29b6: 0x000c, 0x29b9: 0x000c, 0x29ba: 0x000c, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x000c, 0x29c1: 0x000c, 0x29c2: 0x000c, + 0x29e7: 0x000c, 0x29e8: 0x000c, 0x29e9: 0x000c, + 0x29ea: 0x000c, 0x29eb: 0x000c, 0x29ed: 0x000c, 0x29ee: 0x000c, 0x29ef: 0x000c, + 0x29f0: 0x000c, 0x29f1: 0x000c, 0x29f2: 0x000c, 0x29f3: 0x000c, 0x29f4: 0x000c, + // Block 0xa8, offset 0x2a00 + 0x2a33: 0x000c, + // Block 0xa9, offset 0x2a40 + 0x2a40: 0x000c, 0x2a41: 0x000c, + 0x2a76: 0x000c, 0x2a77: 0x000c, 0x2a78: 0x000c, 0x2a79: 0x000c, 0x2a7a: 0x000c, 0x2a7b: 0x000c, + 0x2a7c: 0x000c, 0x2a7d: 0x000c, 0x2a7e: 0x000c, + // Block 0xaa, offset 0x2a80 + 0x2a89: 0x000c, 0x2a8a: 0x000c, 0x2a8b: 0x000c, + 0x2a8c: 0x000c, + // Block 0xab, offset 0x2ac0 + 0x2aef: 0x000c, + 0x2af0: 0x000c, 0x2af1: 0x000c, 0x2af4: 0x000c, + 0x2af6: 0x000c, 0x2af7: 0x000c, + 0x2afe: 0x000c, + // Block 0xac, offset 0x2b00 + 0x2b1f: 0x000c, 0x2b23: 0x000c, + 0x2b24: 0x000c, 0x2b25: 0x000c, 0x2b26: 0x000c, 0x2b27: 0x000c, 0x2b28: 0x000c, 0x2b29: 0x000c, + 0x2b2a: 0x000c, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x000c, + 0x2b66: 0x000c, 0x2b67: 0x000c, 0x2b68: 0x000c, 0x2b69: 0x000c, + 0x2b6a: 0x000c, 0x2b6b: 0x000c, 0x2b6c: 0x000c, + 0x2b70: 0x000c, 0x2b71: 0x000c, 0x2b72: 0x000c, 0x2b73: 0x000c, 0x2b74: 0x000c, + // Block 0xae, offset 0x2b80 + 0x2bb8: 0x000c, 0x2bb9: 0x000c, 0x2bba: 0x000c, 0x2bbb: 0x000c, + 0x2bbc: 0x000c, 0x2bbd: 0x000c, 0x2bbe: 0x000c, 0x2bbf: 0x000c, + // Block 0xaf, offset 0x2bc0 + 0x2bc2: 0x000c, 0x2bc3: 0x000c, 0x2bc4: 0x000c, + 0x2bc6: 0x000c, + 0x2bde: 0x000c, + // Block 0xb0, offset 0x2c00 + 0x2c33: 0x000c, 0x2c34: 0x000c, 0x2c35: 0x000c, + 0x2c36: 0x000c, 0x2c37: 0x000c, 0x2c38: 0x000c, 0x2c3a: 0x000c, + 0x2c3f: 0x000c, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0x000c, 0x2c42: 0x000c, 0x2c43: 0x000c, + // Block 0xb2, offset 0x2c80 + 0x2cb2: 0x000c, 0x2cb3: 0x000c, 0x2cb4: 0x000c, 0x2cb5: 0x000c, + 0x2cbc: 0x000c, 0x2cbd: 0x000c, 0x2cbf: 0x000c, + // Block 0xb3, offset 0x2cc0 + 0x2cc0: 0x000c, + 0x2cdc: 0x000c, 0x2cdd: 0x000c, + // Block 0xb4, offset 0x2d00 + 0x2d33: 0x000c, 0x2d34: 0x000c, 0x2d35: 0x000c, + 0x2d36: 0x000c, 0x2d37: 0x000c, 0x2d38: 0x000c, 0x2d39: 0x000c, 0x2d3a: 0x000c, + 0x2d3d: 0x000c, 0x2d3f: 0x000c, + // Block 0xb5, offset 0x2d40 + 0x2d40: 0x000c, + 0x2d60: 0x000a, 0x2d61: 0x000a, 0x2d62: 0x000a, 0x2d63: 0x000a, + 0x2d64: 0x000a, 0x2d65: 0x000a, 0x2d66: 0x000a, 0x2d67: 0x000a, 0x2d68: 0x000a, 0x2d69: 0x000a, + 0x2d6a: 0x000a, 0x2d6b: 0x000a, 0x2d6c: 0x000a, + // Block 0xb6, offset 0x2d80 + 0x2dab: 0x000c, 0x2dad: 0x000c, + 0x2db0: 0x000c, 0x2db1: 0x000c, 0x2db2: 0x000c, 0x2db3: 0x000c, 0x2db4: 0x000c, 0x2db5: 0x000c, + 0x2db7: 0x000c, + // Block 0xb7, offset 0x2dc0 + 0x2ddd: 0x000c, + 0x2dde: 0x000c, 0x2ddf: 0x000c, 0x2de2: 0x000c, 0x2de3: 0x000c, + 0x2de4: 0x000c, 0x2de5: 0x000c, 0x2de7: 0x000c, 0x2de8: 0x000c, 0x2de9: 0x000c, + 0x2dea: 0x000c, 0x2deb: 0x000c, + // Block 0xb8, offset 0x2e00 + 0x2e2f: 0x000c, + 0x2e30: 0x000c, 0x2e31: 0x000c, 0x2e32: 0x000c, 0x2e33: 0x000c, 0x2e34: 0x000c, 0x2e35: 0x000c, + 0x2e36: 0x000c, 0x2e37: 0x000c, 0x2e39: 0x000c, 0x2e3a: 0x000c, + // Block 0xb9, offset 0x2e40 + 0x2e54: 0x000c, 0x2e55: 0x000c, 0x2e56: 0x000c, 0x2e57: 0x000c, + 0x2e5a: 0x000c, 0x2e5b: 0x000c, + 0x2e60: 0x000c, + // Block 0xba, offset 0x2e80 + 0x2e81: 0x000c, 0x2e82: 0x000c, 0x2e83: 0x000c, 0x2e84: 0x000c, 0x2e85: 0x000c, + 0x2e86: 0x000c, 0x2e89: 0x000c, 0x2e8a: 0x000c, + 0x2eb3: 0x000c, 0x2eb4: 0x000c, 0x2eb5: 0x000c, + 0x2eb6: 0x000c, 0x2eb7: 0x000c, 0x2eb8: 0x000c, 0x2ebb: 0x000c, + 0x2ebc: 0x000c, 0x2ebd: 0x000c, 0x2ebe: 0x000c, + // Block 0xbb, offset 0x2ec0 + 0x2ec7: 0x000c, + 0x2ed1: 0x000c, + 0x2ed2: 0x000c, 0x2ed3: 0x000c, 0x2ed4: 0x000c, 0x2ed5: 0x000c, 0x2ed6: 0x000c, + 0x2ed9: 0x000c, 0x2eda: 0x000c, 0x2edb: 0x000c, + // Block 0xbc, offset 0x2f00 + 0x2f0a: 0x000c, 0x2f0b: 0x000c, + 0x2f0c: 0x000c, 0x2f0d: 0x000c, 0x2f0e: 0x000c, 0x2f0f: 0x000c, 0x2f10: 0x000c, 0x2f11: 0x000c, + 0x2f12: 0x000c, 0x2f13: 0x000c, 0x2f14: 0x000c, 0x2f15: 0x000c, 0x2f16: 0x000c, + 0x2f18: 0x000c, 0x2f19: 0x000c, + // Block 0xbd, offset 0x2f40 + 0x2f70: 0x000c, 0x2f71: 0x000c, 0x2f72: 0x000c, 0x2f73: 0x000c, 0x2f74: 0x000c, 0x2f75: 0x000c, + 0x2f76: 0x000c, 0x2f78: 0x000c, 0x2f79: 0x000c, 0x2f7a: 0x000c, 0x2f7b: 0x000c, + 0x2f7c: 0x000c, 0x2f7d: 0x000c, + // Block 0xbe, offset 0x2f80 + 0x2f92: 0x000c, 0x2f93: 0x000c, 0x2f94: 0x000c, 0x2f95: 0x000c, 0x2f96: 0x000c, 0x2f97: 0x000c, + 0x2f98: 0x000c, 0x2f99: 0x000c, 0x2f9a: 0x000c, 0x2f9b: 0x000c, 0x2f9c: 0x000c, 0x2f9d: 0x000c, + 0x2f9e: 0x000c, 0x2f9f: 0x000c, 0x2fa0: 0x000c, 0x2fa1: 0x000c, 0x2fa2: 0x000c, 0x2fa3: 0x000c, + 0x2fa4: 0x000c, 0x2fa5: 0x000c, 0x2fa6: 0x000c, 0x2fa7: 0x000c, + 0x2faa: 0x000c, 0x2fab: 0x000c, 0x2fac: 0x000c, 0x2fad: 0x000c, 0x2fae: 0x000c, 0x2faf: 0x000c, + 0x2fb0: 0x000c, 0x2fb2: 0x000c, 0x2fb3: 0x000c, 0x2fb5: 0x000c, + 0x2fb6: 0x000c, + // Block 0xbf, offset 0x2fc0 + 0x2ff1: 0x000c, 0x2ff2: 0x000c, 0x2ff3: 0x000c, 0x2ff4: 0x000c, 0x2ff5: 0x000c, + 0x2ff6: 0x000c, 0x2ffa: 0x000c, + 0x2ffc: 0x000c, 0x2ffd: 0x000c, 0x2fff: 0x000c, + // Block 0xc0, offset 0x3000 + 0x3000: 0x000c, 0x3001: 0x000c, 0x3002: 0x000c, 0x3003: 0x000c, 0x3004: 0x000c, 0x3005: 0x000c, + 0x3007: 0x000c, + // Block 0xc1, offset 0x3040 + 0x3050: 0x000c, 0x3051: 0x000c, + 0x3055: 0x000c, 0x3057: 0x000c, + // Block 0xc2, offset 0x3080 + 0x30b3: 0x000c, 0x30b4: 0x000c, + // Block 0xc3, offset 0x30c0 + 0x30d5: 0x000a, 0x30d6: 0x000a, 0x30d7: 0x000a, + 0x30d8: 0x000a, 0x30d9: 0x000a, 0x30da: 0x000a, 0x30db: 0x000a, 0x30dc: 0x000a, 0x30dd: 0x0004, + 0x30de: 0x0004, 0x30df: 0x0004, 0x30e0: 0x0004, 0x30e1: 0x000a, 0x30e2: 0x000a, 0x30e3: 0x000a, + 0x30e4: 0x000a, 0x30e5: 0x000a, 0x30e6: 0x000a, 0x30e7: 0x000a, 0x30e8: 0x000a, 0x30e9: 0x000a, + 0x30ea: 0x000a, 0x30eb: 0x000a, 0x30ec: 0x000a, 0x30ed: 0x000a, 0x30ee: 0x000a, 0x30ef: 0x000a, + 0x30f0: 0x000a, 0x30f1: 0x000a, + // Block 0xc4, offset 0x3100 + 0x3130: 0x000c, 0x3131: 0x000c, 0x3132: 0x000c, 0x3133: 0x000c, 0x3134: 0x000c, + // Block 0xc5, offset 0x3140 + 0x3170: 0x000c, 0x3171: 0x000c, 0x3172: 0x000c, 0x3173: 0x000c, 0x3174: 0x000c, 0x3175: 0x000c, + 0x3176: 0x000c, + // Block 0xc6, offset 0x3180 + 0x318f: 0x000c, + // Block 0xc7, offset 0x31c0 + 0x31cf: 0x000c, 0x31d0: 0x000c, 0x31d1: 0x000c, + 0x31d2: 0x000c, + // Block 0xc8, offset 0x3200 + 0x3222: 0x000a, + // Block 0xc9, offset 0x3240 + 0x325d: 0x000c, + 0x325e: 0x000c, 0x3260: 0x000b, 0x3261: 0x000b, 0x3262: 0x000b, 0x3263: 0x000b, + // Block 0xca, offset 0x3280 + 0x32a7: 0x000c, 0x32a8: 0x000c, 0x32a9: 0x000c, + 0x32b3: 0x000b, 0x32b4: 0x000b, 0x32b5: 0x000b, + 0x32b6: 0x000b, 0x32b7: 0x000b, 0x32b8: 0x000b, 0x32b9: 0x000b, 0x32ba: 0x000b, 0x32bb: 0x000c, + 0x32bc: 0x000c, 0x32bd: 0x000c, 0x32be: 0x000c, 0x32bf: 0x000c, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x000c, 0x32c1: 0x000c, 0x32c2: 0x000c, 0x32c5: 0x000c, + 0x32c6: 0x000c, 0x32c7: 0x000c, 0x32c8: 0x000c, 0x32c9: 0x000c, 0x32ca: 0x000c, 0x32cb: 0x000c, + 0x32ea: 0x000c, 0x32eb: 0x000c, 0x32ec: 0x000c, 0x32ed: 0x000c, + // Block 0xcc, offset 0x3300 + 0x3300: 0x000a, 0x3301: 0x000a, 0x3302: 0x000c, 0x3303: 0x000c, 0x3304: 0x000c, 0x3305: 0x000a, + // Block 0xcd, offset 0x3340 + 0x3340: 0x000a, 0x3341: 0x000a, 0x3342: 0x000a, 0x3343: 0x000a, 0x3344: 0x000a, 0x3345: 0x000a, + 0x3346: 0x000a, 0x3347: 0x000a, 0x3348: 0x000a, 0x3349: 0x000a, 0x334a: 0x000a, 0x334b: 0x000a, + 0x334c: 0x000a, 0x334d: 0x000a, 0x334e: 0x000a, 0x334f: 0x000a, 0x3350: 0x000a, 0x3351: 0x000a, + 0x3352: 0x000a, 0x3353: 0x000a, 0x3354: 0x000a, 0x3355: 0x000a, 0x3356: 0x000a, + // Block 0xce, offset 0x3380 + 0x339b: 0x000a, + // Block 0xcf, offset 0x33c0 + 0x33d5: 0x000a, + // Block 0xd0, offset 0x3400 + 0x340f: 0x000a, + // Block 0xd1, offset 0x3440 + 0x3449: 0x000a, + // Block 0xd2, offset 0x3480 + 0x3483: 0x000a, + 0x348e: 0x0002, 0x348f: 0x0002, 0x3490: 0x0002, 0x3491: 0x0002, + 0x3492: 0x0002, 0x3493: 0x0002, 0x3494: 0x0002, 0x3495: 0x0002, 0x3496: 0x0002, 0x3497: 0x0002, + 0x3498: 0x0002, 0x3499: 0x0002, 0x349a: 0x0002, 0x349b: 0x0002, 0x349c: 0x0002, 0x349d: 0x0002, + 0x349e: 0x0002, 0x349f: 0x0002, 0x34a0: 0x0002, 0x34a1: 0x0002, 0x34a2: 0x0002, 0x34a3: 0x0002, + 0x34a4: 0x0002, 0x34a5: 0x0002, 0x34a6: 0x0002, 0x34a7: 0x0002, 0x34a8: 0x0002, 0x34a9: 0x0002, + 0x34aa: 0x0002, 0x34ab: 0x0002, 0x34ac: 0x0002, 0x34ad: 0x0002, 0x34ae: 0x0002, 0x34af: 0x0002, + 0x34b0: 0x0002, 0x34b1: 0x0002, 0x34b2: 0x0002, 0x34b3: 0x0002, 0x34b4: 0x0002, 0x34b5: 0x0002, + 0x34b6: 0x0002, 0x34b7: 0x0002, 0x34b8: 0x0002, 0x34b9: 0x0002, 0x34ba: 0x0002, 0x34bb: 0x0002, + 0x34bc: 0x0002, 0x34bd: 0x0002, 0x34be: 0x0002, 0x34bf: 0x0002, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x000c, 0x34c1: 0x000c, 0x34c2: 0x000c, 0x34c3: 0x000c, 0x34c4: 0x000c, 0x34c5: 0x000c, + 0x34c6: 0x000c, 0x34c7: 0x000c, 0x34c8: 0x000c, 0x34c9: 0x000c, 0x34ca: 0x000c, 0x34cb: 0x000c, + 0x34cc: 0x000c, 0x34cd: 0x000c, 0x34ce: 0x000c, 0x34cf: 0x000c, 0x34d0: 0x000c, 0x34d1: 0x000c, + 0x34d2: 0x000c, 0x34d3: 0x000c, 0x34d4: 0x000c, 0x34d5: 0x000c, 0x34d6: 0x000c, 0x34d7: 0x000c, + 0x34d8: 0x000c, 0x34d9: 0x000c, 0x34da: 0x000c, 0x34db: 0x000c, 0x34dc: 0x000c, 0x34dd: 0x000c, + 0x34de: 0x000c, 0x34df: 0x000c, 0x34e0: 0x000c, 0x34e1: 0x000c, 0x34e2: 0x000c, 0x34e3: 0x000c, + 0x34e4: 0x000c, 0x34e5: 0x000c, 0x34e6: 0x000c, 0x34e7: 0x000c, 0x34e8: 0x000c, 0x34e9: 0x000c, + 0x34ea: 0x000c, 0x34eb: 0x000c, 0x34ec: 0x000c, 0x34ed: 0x000c, 0x34ee: 0x000c, 0x34ef: 0x000c, + 0x34f0: 0x000c, 0x34f1: 0x000c, 0x34f2: 0x000c, 0x34f3: 0x000c, 0x34f4: 0x000c, 0x34f5: 0x000c, + 0x34f6: 0x000c, 0x34fb: 0x000c, + 0x34fc: 0x000c, 0x34fd: 0x000c, 0x34fe: 0x000c, 0x34ff: 0x000c, + // Block 0xd4, offset 0x3500 + 0x3500: 0x000c, 0x3501: 0x000c, 0x3502: 0x000c, 0x3503: 0x000c, 0x3504: 0x000c, 0x3505: 0x000c, + 0x3506: 0x000c, 0x3507: 0x000c, 0x3508: 0x000c, 0x3509: 0x000c, 0x350a: 0x000c, 0x350b: 0x000c, + 0x350c: 0x000c, 0x350d: 0x000c, 0x350e: 0x000c, 0x350f: 0x000c, 0x3510: 0x000c, 0x3511: 0x000c, + 0x3512: 0x000c, 0x3513: 0x000c, 0x3514: 0x000c, 0x3515: 0x000c, 0x3516: 0x000c, 0x3517: 0x000c, + 0x3518: 0x000c, 0x3519: 0x000c, 0x351a: 0x000c, 0x351b: 0x000c, 0x351c: 0x000c, 0x351d: 0x000c, + 0x351e: 0x000c, 0x351f: 0x000c, 0x3520: 0x000c, 0x3521: 0x000c, 0x3522: 0x000c, 0x3523: 0x000c, + 0x3524: 0x000c, 0x3525: 0x000c, 0x3526: 0x000c, 0x3527: 0x000c, 0x3528: 0x000c, 0x3529: 0x000c, + 0x352a: 0x000c, 0x352b: 0x000c, 0x352c: 0x000c, + 0x3535: 0x000c, + // Block 0xd5, offset 0x3540 + 0x3544: 0x000c, + 0x355b: 0x000c, 0x355c: 0x000c, 0x355d: 0x000c, + 0x355e: 0x000c, 0x355f: 0x000c, 0x3561: 0x000c, 0x3562: 0x000c, 0x3563: 0x000c, + 0x3564: 0x000c, 0x3565: 0x000c, 0x3566: 0x000c, 0x3567: 0x000c, 0x3568: 0x000c, 0x3569: 0x000c, + 0x356a: 0x000c, 0x356b: 0x000c, 0x356c: 0x000c, 0x356d: 0x000c, 0x356e: 0x000c, 0x356f: 0x000c, + // Block 0xd6, offset 0x3580 + 0x3580: 0x000c, 0x3581: 0x000c, 0x3582: 0x000c, 0x3583: 0x000c, 0x3584: 0x000c, 0x3585: 0x000c, + 0x3586: 0x000c, 0x3588: 0x000c, 0x3589: 0x000c, 0x358a: 0x000c, 0x358b: 0x000c, + 0x358c: 0x000c, 0x358d: 0x000c, 0x358e: 0x000c, 0x358f: 0x000c, 0x3590: 0x000c, 0x3591: 0x000c, + 0x3592: 0x000c, 0x3593: 0x000c, 0x3594: 0x000c, 0x3595: 0x000c, 0x3596: 0x000c, 0x3597: 0x000c, + 0x3598: 0x000c, 0x359b: 0x000c, 0x359c: 0x000c, 0x359d: 0x000c, + 0x359e: 0x000c, 0x359f: 0x000c, 0x35a0: 0x000c, 0x35a1: 0x000c, 0x35a3: 0x000c, + 0x35a4: 0x000c, 0x35a6: 0x000c, 0x35a7: 0x000c, 0x35a8: 0x000c, 0x35a9: 0x000c, + 0x35aa: 0x000c, + // Block 0xd7, offset 0x35c0 + 0x35ec: 0x000c, 0x35ed: 0x000c, 0x35ee: 0x000c, 0x35ef: 0x000c, + 0x35ff: 0x0004, + // Block 0xd8, offset 0x3600 + 0x3600: 0x0001, 0x3601: 0x0001, 0x3602: 0x0001, 0x3603: 0x0001, 0x3604: 0x0001, 0x3605: 0x0001, + 0x3606: 0x0001, 0x3607: 0x0001, 0x3608: 0x0001, 0x3609: 0x0001, 0x360a: 0x0001, 0x360b: 0x0001, + 0x360c: 0x0001, 0x360d: 0x0001, 0x360e: 0x0001, 0x360f: 0x0001, 0x3610: 0x000c, 0x3611: 0x000c, + 0x3612: 0x000c, 0x3613: 0x000c, 0x3614: 0x000c, 0x3615: 0x000c, 0x3616: 0x000c, 0x3617: 0x0001, + 0x3618: 0x0001, 0x3619: 0x0001, 0x361a: 0x0001, 0x361b: 0x0001, 0x361c: 0x0001, 0x361d: 0x0001, + 0x361e: 0x0001, 0x361f: 0x0001, 0x3620: 0x0001, 0x3621: 0x0001, 0x3622: 0x0001, 0x3623: 0x0001, + 0x3624: 0x0001, 0x3625: 0x0001, 0x3626: 0x0001, 0x3627: 0x0001, 0x3628: 0x0001, 0x3629: 0x0001, + 0x362a: 0x0001, 0x362b: 0x0001, 0x362c: 0x0001, 0x362d: 0x0001, 0x362e: 0x0001, 0x362f: 0x0001, + 0x3630: 0x0001, 0x3631: 0x0001, 0x3632: 0x0001, 0x3633: 0x0001, 0x3634: 0x0001, 0x3635: 0x0001, + 0x3636: 0x0001, 0x3637: 0x0001, 0x3638: 0x0001, 0x3639: 0x0001, 0x363a: 0x0001, 0x363b: 0x0001, + 0x363c: 0x0001, 0x363d: 0x0001, 0x363e: 0x0001, 0x363f: 0x0001, + // Block 0xd9, offset 0x3640 + 0x3640: 0x0001, 0x3641: 0x0001, 0x3642: 0x0001, 0x3643: 0x0001, 0x3644: 0x000c, 0x3645: 0x000c, + 0x3646: 0x000c, 0x3647: 0x000c, 0x3648: 0x000c, 0x3649: 0x000c, 0x364a: 0x000c, 0x364b: 0x0001, + 0x364c: 0x0001, 0x364d: 0x0001, 0x364e: 0x0001, 0x364f: 0x0001, 0x3650: 0x0001, 0x3651: 0x0001, + 0x3652: 0x0001, 0x3653: 0x0001, 0x3654: 0x0001, 0x3655: 0x0001, 0x3656: 0x0001, 0x3657: 0x0001, + 0x3658: 0x0001, 0x3659: 0x0001, 0x365a: 0x0001, 0x365b: 0x0001, 0x365c: 0x0001, 0x365d: 0x0001, + 0x365e: 0x0001, 0x365f: 0x0001, 0x3660: 0x0001, 0x3661: 0x0001, 0x3662: 0x0001, 0x3663: 0x0001, + 0x3664: 0x0001, 0x3665: 0x0001, 0x3666: 0x0001, 0x3667: 0x0001, 0x3668: 0x0001, 0x3669: 0x0001, + 0x366a: 0x0001, 0x366b: 0x0001, 0x366c: 0x0001, 0x366d: 0x0001, 0x366e: 0x0001, 0x366f: 0x0001, + 0x3670: 0x0001, 0x3671: 0x0001, 0x3672: 0x0001, 0x3673: 0x0001, 0x3674: 0x0001, 0x3675: 0x0001, + 0x3676: 0x0001, 0x3677: 0x0001, 0x3678: 0x0001, 0x3679: 0x0001, 0x367a: 0x0001, 0x367b: 0x0001, + 0x367c: 0x0001, 0x367d: 0x0001, 0x367e: 0x0001, 0x367f: 0x0001, + // Block 0xda, offset 0x3680 + 0x3680: 0x000d, 0x3681: 0x000d, 0x3682: 0x000d, 0x3683: 0x000d, 0x3684: 0x000d, 0x3685: 0x000d, + 0x3686: 0x000d, 0x3687: 0x000d, 0x3688: 0x000d, 0x3689: 0x000d, 0x368a: 0x000d, 0x368b: 0x000d, + 0x368c: 0x000d, 0x368d: 0x000d, 0x368e: 0x000d, 0x368f: 0x000d, 0x3690: 0x0001, 0x3691: 0x0001, + 0x3692: 0x0001, 0x3693: 0x0001, 0x3694: 0x0001, 0x3695: 0x0001, 0x3696: 0x0001, 0x3697: 0x0001, + 0x3698: 0x0001, 0x3699: 0x0001, 0x369a: 0x0001, 0x369b: 0x0001, 0x369c: 0x0001, 0x369d: 0x0001, + 0x369e: 0x0001, 0x369f: 0x0001, 0x36a0: 0x0001, 0x36a1: 0x0001, 0x36a2: 0x0001, 0x36a3: 0x0001, + 0x36a4: 0x0001, 0x36a5: 0x0001, 0x36a6: 0x0001, 0x36a7: 0x0001, 0x36a8: 0x0001, 0x36a9: 0x0001, + 0x36aa: 0x0001, 0x36ab: 0x0001, 0x36ac: 0x0001, 0x36ad: 0x0001, 0x36ae: 0x0001, 0x36af: 0x0001, + 0x36b0: 0x0001, 0x36b1: 0x0001, 0x36b2: 0x0001, 0x36b3: 0x0001, 0x36b4: 0x0001, 0x36b5: 0x0001, + 0x36b6: 0x0001, 0x36b7: 0x0001, 0x36b8: 0x0001, 0x36b9: 0x0001, 0x36ba: 0x0001, 0x36bb: 0x0001, + 0x36bc: 0x0001, 0x36bd: 0x0001, 0x36be: 0x0001, 0x36bf: 0x0001, + // Block 0xdb, offset 0x36c0 + 0x36c0: 0x000d, 0x36c1: 0x000d, 0x36c2: 0x000d, 0x36c3: 0x000d, 0x36c4: 0x000d, 0x36c5: 0x000d, + 0x36c6: 0x000d, 0x36c7: 0x000d, 0x36c8: 0x000d, 0x36c9: 0x000d, 0x36ca: 0x000d, 0x36cb: 0x000d, + 0x36cc: 0x000d, 0x36cd: 0x000d, 0x36ce: 0x000d, 0x36cf: 0x000d, 0x36d0: 0x000d, 0x36d1: 0x000d, + 0x36d2: 0x000d, 0x36d3: 0x000d, 0x36d4: 0x000d, 0x36d5: 0x000d, 0x36d6: 0x000d, 0x36d7: 0x000d, + 0x36d8: 0x000d, 0x36d9: 0x000d, 0x36da: 0x000d, 0x36db: 0x000d, 0x36dc: 0x000d, 0x36dd: 0x000d, + 0x36de: 0x000d, 0x36df: 0x000d, 0x36e0: 0x000d, 0x36e1: 0x000d, 0x36e2: 0x000d, 0x36e3: 0x000d, + 0x36e4: 0x000d, 0x36e5: 0x000d, 0x36e6: 0x000d, 0x36e7: 0x000d, 0x36e8: 0x000d, 0x36e9: 0x000d, + 0x36ea: 0x000d, 0x36eb: 0x000d, 0x36ec: 0x000d, 0x36ed: 0x000d, 0x36ee: 0x000d, 0x36ef: 0x000d, + 0x36f0: 0x000a, 0x36f1: 0x000a, 0x36f2: 0x000d, 0x36f3: 0x000d, 0x36f4: 0x000d, 0x36f5: 0x000d, + 0x36f6: 0x000d, 0x36f7: 0x000d, 0x36f8: 0x000d, 0x36f9: 0x000d, 0x36fa: 0x000d, 0x36fb: 0x000d, + 0x36fc: 0x000d, 0x36fd: 0x000d, 0x36fe: 0x000d, 0x36ff: 0x000d, + // Block 0xdc, offset 0x3700 + 0x3700: 0x000a, 0x3701: 0x000a, 0x3702: 0x000a, 0x3703: 0x000a, 0x3704: 0x000a, 0x3705: 0x000a, + 0x3706: 0x000a, 0x3707: 0x000a, 0x3708: 0x000a, 0x3709: 0x000a, 0x370a: 0x000a, 0x370b: 0x000a, + 0x370c: 0x000a, 0x370d: 0x000a, 0x370e: 0x000a, 0x370f: 0x000a, 0x3710: 0x000a, 0x3711: 0x000a, + 0x3712: 0x000a, 0x3713: 0x000a, 0x3714: 0x000a, 0x3715: 0x000a, 0x3716: 0x000a, 0x3717: 0x000a, + 0x3718: 0x000a, 0x3719: 0x000a, 0x371a: 0x000a, 0x371b: 0x000a, 0x371c: 0x000a, 0x371d: 0x000a, + 0x371e: 0x000a, 0x371f: 0x000a, 0x3720: 0x000a, 0x3721: 0x000a, 0x3722: 0x000a, 0x3723: 0x000a, + 0x3724: 0x000a, 0x3725: 0x000a, 0x3726: 0x000a, 0x3727: 0x000a, 0x3728: 0x000a, 0x3729: 0x000a, + 0x372a: 0x000a, 0x372b: 0x000a, + 0x3730: 0x000a, 0x3731: 0x000a, 0x3732: 0x000a, 0x3733: 0x000a, 0x3734: 0x000a, 0x3735: 0x000a, + 0x3736: 0x000a, 0x3737: 0x000a, 0x3738: 0x000a, 0x3739: 0x000a, 0x373a: 0x000a, 0x373b: 0x000a, + 0x373c: 0x000a, 0x373d: 0x000a, 0x373e: 0x000a, 0x373f: 0x000a, + // Block 0xdd, offset 0x3740 + 0x3740: 0x000a, 0x3741: 0x000a, 0x3742: 0x000a, 0x3743: 0x000a, 0x3744: 0x000a, 0x3745: 0x000a, + 0x3746: 0x000a, 0x3747: 0x000a, 0x3748: 0x000a, 0x3749: 0x000a, 0x374a: 0x000a, 0x374b: 0x000a, + 0x374c: 0x000a, 0x374d: 0x000a, 0x374e: 0x000a, 0x374f: 0x000a, 0x3750: 0x000a, 0x3751: 0x000a, + 0x3752: 0x000a, 0x3753: 0x000a, + 0x3760: 0x000a, 0x3761: 0x000a, 0x3762: 0x000a, 0x3763: 0x000a, + 0x3764: 0x000a, 0x3765: 0x000a, 0x3766: 0x000a, 0x3767: 0x000a, 0x3768: 0x000a, 0x3769: 0x000a, + 0x376a: 0x000a, 0x376b: 0x000a, 0x376c: 0x000a, 0x376d: 0x000a, 0x376e: 0x000a, + 0x3771: 0x000a, 0x3772: 0x000a, 0x3773: 0x000a, 0x3774: 0x000a, 0x3775: 0x000a, + 0x3776: 0x000a, 0x3777: 0x000a, 0x3778: 0x000a, 0x3779: 0x000a, 0x377a: 0x000a, 0x377b: 0x000a, + 0x377c: 0x000a, 0x377d: 0x000a, 0x377e: 0x000a, 0x377f: 0x000a, + // Block 0xde, offset 0x3780 + 0x3781: 0x000a, 0x3782: 0x000a, 0x3783: 0x000a, 0x3784: 0x000a, 0x3785: 0x000a, + 0x3786: 0x000a, 0x3787: 0x000a, 0x3788: 0x000a, 0x3789: 0x000a, 0x378a: 0x000a, 0x378b: 0x000a, + 0x378c: 0x000a, 0x378d: 0x000a, 0x378e: 0x000a, 0x378f: 0x000a, 0x3791: 0x000a, + 0x3792: 0x000a, 0x3793: 0x000a, 0x3794: 0x000a, 0x3795: 0x000a, 0x3796: 0x000a, 0x3797: 0x000a, + 0x3798: 0x000a, 0x3799: 0x000a, 0x379a: 0x000a, 0x379b: 0x000a, 0x379c: 0x000a, 0x379d: 0x000a, + 0x379e: 0x000a, 0x379f: 0x000a, 0x37a0: 0x000a, 0x37a1: 0x000a, 0x37a2: 0x000a, 0x37a3: 0x000a, + 0x37a4: 0x000a, 0x37a5: 0x000a, 0x37a6: 0x000a, 0x37a7: 0x000a, 0x37a8: 0x000a, 0x37a9: 0x000a, + 0x37aa: 0x000a, 0x37ab: 0x000a, 0x37ac: 0x000a, 0x37ad: 0x000a, 0x37ae: 0x000a, 0x37af: 0x000a, + 0x37b0: 0x000a, 0x37b1: 0x000a, 0x37b2: 0x000a, 0x37b3: 0x000a, 0x37b4: 0x000a, 0x37b5: 0x000a, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x0002, 0x37c1: 0x0002, 0x37c2: 0x0002, 0x37c3: 0x0002, 0x37c4: 0x0002, 0x37c5: 0x0002, + 0x37c6: 0x0002, 0x37c7: 0x0002, 0x37c8: 0x0002, 0x37c9: 0x0002, 0x37ca: 0x0002, 0x37cb: 0x000a, + 0x37cc: 0x000a, + 0x37ef: 0x000a, + // Block 0xe0, offset 0x3800 + 0x382a: 0x000a, 0x382b: 0x000a, 0x382c: 0x000a, + // Block 0xe1, offset 0x3840 + 0x3860: 0x000a, 0x3861: 0x000a, 0x3862: 0x000a, 0x3863: 0x000a, + 0x3864: 0x000a, 0x3865: 0x000a, + // Block 0xe2, offset 0x3880 + 0x3880: 0x000a, 0x3881: 0x000a, 0x3882: 0x000a, 0x3883: 0x000a, 0x3884: 0x000a, 0x3885: 0x000a, + 0x3886: 0x000a, 0x3887: 0x000a, 0x3888: 0x000a, 0x3889: 0x000a, 0x388a: 0x000a, 0x388b: 0x000a, + 0x388c: 0x000a, 0x388d: 0x000a, 0x388e: 0x000a, 0x388f: 0x000a, 0x3890: 0x000a, 0x3891: 0x000a, + 0x3892: 0x000a, 0x3893: 0x000a, 0x3894: 0x000a, 0x3895: 0x000a, + 0x38a0: 0x000a, 0x38a1: 0x000a, 0x38a2: 0x000a, 0x38a3: 0x000a, + 0x38a4: 0x000a, 0x38a5: 0x000a, 0x38a6: 0x000a, 0x38a7: 0x000a, 0x38a8: 0x000a, 0x38a9: 0x000a, + 0x38aa: 0x000a, 0x38ab: 0x000a, 0x38ac: 0x000a, + 0x38b0: 0x000a, 0x38b1: 0x000a, 0x38b2: 0x000a, 0x38b3: 0x000a, 0x38b4: 0x000a, 0x38b5: 0x000a, + 0x38b6: 0x000a, 0x38b7: 0x000a, 0x38b8: 0x000a, 0x38b9: 0x000a, 0x38ba: 0x000a, + // Block 0xe3, offset 0x38c0 + 0x38c0: 0x000a, 0x38c1: 0x000a, 0x38c2: 0x000a, 0x38c3: 0x000a, 0x38c4: 0x000a, 0x38c5: 0x000a, + 0x38c6: 0x000a, 0x38c7: 0x000a, 0x38c8: 0x000a, 0x38c9: 0x000a, 0x38ca: 0x000a, 0x38cb: 0x000a, + 0x38cc: 0x000a, 0x38cd: 0x000a, 0x38ce: 0x000a, 0x38cf: 0x000a, 0x38d0: 0x000a, 0x38d1: 0x000a, + 0x38d2: 0x000a, 0x38d3: 0x000a, 0x38d4: 0x000a, 0x38d5: 0x000a, 0x38d6: 0x000a, 0x38d7: 0x000a, + 0x38d8: 0x000a, + 0x38e0: 0x000a, 0x38e1: 0x000a, 0x38e2: 0x000a, 0x38e3: 0x000a, + 0x38e4: 0x000a, 0x38e5: 0x000a, 0x38e6: 0x000a, 0x38e7: 0x000a, 0x38e8: 0x000a, 0x38e9: 0x000a, + 0x38ea: 0x000a, 0x38eb: 0x000a, + // Block 0xe4, offset 0x3900 + 0x3900: 0x000a, 0x3901: 0x000a, 0x3902: 0x000a, 0x3903: 0x000a, 0x3904: 0x000a, 0x3905: 0x000a, + 0x3906: 0x000a, 0x3907: 0x000a, 0x3908: 0x000a, 0x3909: 0x000a, 0x390a: 0x000a, 0x390b: 0x000a, + 0x3910: 0x000a, 0x3911: 0x000a, + 0x3912: 0x000a, 0x3913: 0x000a, 0x3914: 0x000a, 0x3915: 0x000a, 0x3916: 0x000a, 0x3917: 0x000a, + 0x3918: 0x000a, 0x3919: 0x000a, 0x391a: 0x000a, 0x391b: 0x000a, 0x391c: 0x000a, 0x391d: 0x000a, + 0x391e: 0x000a, 0x391f: 0x000a, 0x3920: 0x000a, 0x3921: 0x000a, 0x3922: 0x000a, 0x3923: 0x000a, + 0x3924: 0x000a, 0x3925: 0x000a, 0x3926: 0x000a, 0x3927: 0x000a, 0x3928: 0x000a, 0x3929: 0x000a, + 0x392a: 0x000a, 0x392b: 0x000a, 0x392c: 0x000a, 0x392d: 0x000a, 0x392e: 0x000a, 0x392f: 0x000a, + 0x3930: 0x000a, 0x3931: 0x000a, 0x3932: 0x000a, 0x3933: 0x000a, 0x3934: 0x000a, 0x3935: 0x000a, + 0x3936: 0x000a, 0x3937: 0x000a, 0x3938: 0x000a, 0x3939: 0x000a, 0x393a: 0x000a, 0x393b: 0x000a, + 0x393c: 0x000a, 0x393d: 0x000a, 0x393e: 0x000a, 0x393f: 0x000a, + // Block 0xe5, offset 0x3940 + 0x3940: 0x000a, 0x3941: 0x000a, 0x3942: 0x000a, 0x3943: 0x000a, 0x3944: 0x000a, 0x3945: 0x000a, + 0x3946: 0x000a, 0x3947: 0x000a, + 0x3950: 0x000a, 0x3951: 0x000a, + 0x3952: 0x000a, 0x3953: 0x000a, 0x3954: 0x000a, 0x3955: 0x000a, 0x3956: 0x000a, 0x3957: 0x000a, + 0x3958: 0x000a, 0x3959: 0x000a, + 0x3960: 0x000a, 0x3961: 0x000a, 0x3962: 0x000a, 0x3963: 0x000a, + 0x3964: 0x000a, 0x3965: 0x000a, 0x3966: 0x000a, 0x3967: 0x000a, 0x3968: 0x000a, 0x3969: 0x000a, + 0x396a: 0x000a, 0x396b: 0x000a, 0x396c: 0x000a, 0x396d: 0x000a, 0x396e: 0x000a, 0x396f: 0x000a, + 0x3970: 0x000a, 0x3971: 0x000a, 0x3972: 0x000a, 0x3973: 0x000a, 0x3974: 0x000a, 0x3975: 0x000a, + 0x3976: 0x000a, 0x3977: 0x000a, 0x3978: 0x000a, 0x3979: 0x000a, 0x397a: 0x000a, 0x397b: 0x000a, + 0x397c: 0x000a, 0x397d: 0x000a, 0x397e: 0x000a, 0x397f: 0x000a, + // Block 0xe6, offset 0x3980 + 0x3980: 0x000a, 0x3981: 0x000a, 0x3982: 0x000a, 0x3983: 0x000a, 0x3984: 0x000a, 0x3985: 0x000a, + 0x3986: 0x000a, 0x3987: 0x000a, + 0x3990: 0x000a, 0x3991: 0x000a, + 0x3992: 0x000a, 0x3993: 0x000a, 0x3994: 0x000a, 0x3995: 0x000a, 0x3996: 0x000a, 0x3997: 0x000a, + 0x3998: 0x000a, 0x3999: 0x000a, 0x399a: 0x000a, 0x399b: 0x000a, 0x399c: 0x000a, 0x399d: 0x000a, + 0x399e: 0x000a, 0x399f: 0x000a, 0x39a0: 0x000a, 0x39a1: 0x000a, 0x39a2: 0x000a, 0x39a3: 0x000a, + 0x39a4: 0x000a, 0x39a5: 0x000a, 0x39a6: 0x000a, 0x39a7: 0x000a, 0x39a8: 0x000a, 0x39a9: 0x000a, + 0x39aa: 0x000a, 0x39ab: 0x000a, 0x39ac: 0x000a, 0x39ad: 0x000a, + // Block 0xe7, offset 0x39c0 + 0x39c0: 0x000a, 0x39c1: 0x000a, 0x39c2: 0x000a, 0x39c3: 0x000a, 0x39c4: 0x000a, 0x39c5: 0x000a, + 0x39c6: 0x000a, 0x39c7: 0x000a, 0x39c8: 0x000a, 0x39c9: 0x000a, 0x39ca: 0x000a, 0x39cb: 0x000a, + 0x39cd: 0x000a, 0x39ce: 0x000a, 0x39cf: 0x000a, 0x39d0: 0x000a, 0x39d1: 0x000a, + 0x39d2: 0x000a, 0x39d3: 0x000a, 0x39d4: 0x000a, 0x39d5: 0x000a, 0x39d6: 0x000a, 0x39d7: 0x000a, + 0x39d8: 0x000a, 0x39d9: 0x000a, 0x39da: 0x000a, 0x39db: 0x000a, 0x39dc: 0x000a, 0x39dd: 0x000a, + 0x39de: 0x000a, 0x39df: 0x000a, 0x39e0: 0x000a, 0x39e1: 0x000a, 0x39e2: 0x000a, 0x39e3: 0x000a, + 0x39e4: 0x000a, 0x39e5: 0x000a, 0x39e6: 0x000a, 0x39e7: 0x000a, 0x39e8: 0x000a, 0x39e9: 0x000a, + 0x39ea: 0x000a, 0x39eb: 0x000a, 0x39ec: 0x000a, 0x39ed: 0x000a, 0x39ee: 0x000a, 0x39ef: 0x000a, + 0x39f0: 0x000a, 0x39f1: 0x000a, 0x39f2: 0x000a, 0x39f3: 0x000a, 0x39f4: 0x000a, 0x39f5: 0x000a, + 0x39f6: 0x000a, 0x39f7: 0x000a, 0x39f8: 0x000a, 0x39f9: 0x000a, 0x39fa: 0x000a, 0x39fb: 0x000a, + 0x39fc: 0x000a, 0x39fd: 0x000a, 0x39fe: 0x000a, 0x39ff: 0x000a, + // Block 0xe8, offset 0x3a00 + 0x3a00: 0x000a, 0x3a01: 0x000a, 0x3a02: 0x000a, 0x3a03: 0x000a, 0x3a04: 0x000a, 0x3a05: 0x000a, + 0x3a06: 0x000a, 0x3a07: 0x000a, 0x3a08: 0x000a, 0x3a09: 0x000a, 0x3a0a: 0x000a, 0x3a0b: 0x000a, + 0x3a0c: 0x000a, 0x3a0d: 0x000a, 0x3a0e: 0x000a, 0x3a0f: 0x000a, 0x3a10: 0x000a, 0x3a11: 0x000a, + 0x3a12: 0x000a, 0x3a13: 0x000a, 0x3a14: 0x000a, 0x3a15: 0x000a, 0x3a16: 0x000a, 0x3a17: 0x000a, + 0x3a18: 0x000a, 0x3a19: 0x000a, 0x3a1a: 0x000a, 0x3a1b: 0x000a, 0x3a1c: 0x000a, 0x3a1d: 0x000a, + 0x3a1e: 0x000a, 0x3a1f: 0x000a, 0x3a20: 0x000a, 0x3a21: 0x000a, 0x3a22: 0x000a, 0x3a23: 0x000a, + 0x3a24: 0x000a, 0x3a25: 0x000a, 0x3a26: 0x000a, 0x3a27: 0x000a, 0x3a28: 0x000a, 0x3a29: 0x000a, + 0x3a2a: 0x000a, 0x3a2b: 0x000a, 0x3a2c: 0x000a, 0x3a2d: 0x000a, 0x3a2e: 0x000a, 0x3a2f: 0x000a, + 0x3a30: 0x000a, 0x3a31: 0x000a, 0x3a33: 0x000a, 0x3a34: 0x000a, 0x3a35: 0x000a, + 0x3a36: 0x000a, 0x3a3a: 0x000a, 0x3a3b: 0x000a, + 0x3a3c: 0x000a, 0x3a3d: 0x000a, 0x3a3e: 0x000a, 0x3a3f: 0x000a, + // Block 0xe9, offset 0x3a40 + 0x3a40: 0x000a, 0x3a41: 0x000a, 0x3a42: 0x000a, 0x3a43: 0x000a, 0x3a44: 0x000a, 0x3a45: 0x000a, + 0x3a46: 0x000a, 0x3a47: 0x000a, 0x3a48: 0x000a, 0x3a49: 0x000a, 0x3a4a: 0x000a, 0x3a4b: 0x000a, + 0x3a4c: 0x000a, 0x3a4d: 0x000a, 0x3a4e: 0x000a, 0x3a4f: 0x000a, 0x3a50: 0x000a, 0x3a51: 0x000a, + 0x3a52: 0x000a, 0x3a53: 0x000a, 0x3a54: 0x000a, 0x3a55: 0x000a, 0x3a56: 0x000a, 0x3a57: 0x000a, + 0x3a58: 0x000a, 0x3a59: 0x000a, 0x3a5a: 0x000a, 0x3a5b: 0x000a, 0x3a5c: 0x000a, 0x3a5d: 0x000a, + 0x3a5e: 0x000a, 0x3a5f: 0x000a, 0x3a60: 0x000a, 0x3a61: 0x000a, 0x3a62: 0x000a, + 0x3a65: 0x000a, 0x3a66: 0x000a, 0x3a67: 0x000a, 0x3a68: 0x000a, 0x3a69: 0x000a, + 0x3a6a: 0x000a, 0x3a6e: 0x000a, 0x3a6f: 0x000a, + 0x3a70: 0x000a, 0x3a71: 0x000a, 0x3a72: 0x000a, 0x3a73: 0x000a, 0x3a74: 0x000a, 0x3a75: 0x000a, + 0x3a76: 0x000a, 0x3a77: 0x000a, 0x3a78: 0x000a, 0x3a79: 0x000a, 0x3a7a: 0x000a, 0x3a7b: 0x000a, + 0x3a7c: 0x000a, 0x3a7d: 0x000a, 0x3a7e: 0x000a, 0x3a7f: 0x000a, + // Block 0xea, offset 0x3a80 + 0x3a80: 0x000a, 0x3a81: 0x000a, 0x3a82: 0x000a, 0x3a83: 0x000a, 0x3a84: 0x000a, 0x3a85: 0x000a, + 0x3a86: 0x000a, 0x3a87: 0x000a, 0x3a88: 0x000a, 0x3a89: 0x000a, 0x3a8a: 0x000a, + 0x3a8d: 0x000a, 0x3a8e: 0x000a, 0x3a8f: 0x000a, 0x3a90: 0x000a, 0x3a91: 0x000a, + 0x3a92: 0x000a, 0x3a93: 0x000a, 0x3a94: 0x000a, 0x3a95: 0x000a, 0x3a96: 0x000a, 0x3a97: 0x000a, + 0x3a98: 0x000a, 0x3a99: 0x000a, 0x3a9a: 0x000a, 0x3a9b: 0x000a, 0x3a9c: 0x000a, 0x3a9d: 0x000a, + 0x3a9e: 0x000a, 0x3a9f: 0x000a, 0x3aa0: 0x000a, 0x3aa1: 0x000a, 0x3aa2: 0x000a, 0x3aa3: 0x000a, + 0x3aa4: 0x000a, 0x3aa5: 0x000a, 0x3aa6: 0x000a, 0x3aa7: 0x000a, 0x3aa8: 0x000a, 0x3aa9: 0x000a, + 0x3aaa: 0x000a, 0x3aab: 0x000a, 0x3aac: 0x000a, 0x3aad: 0x000a, 0x3aae: 0x000a, 0x3aaf: 0x000a, + 0x3ab0: 0x000a, 0x3ab1: 0x000a, 0x3ab2: 0x000a, 0x3ab3: 0x000a, 0x3ab4: 0x000a, 0x3ab5: 0x000a, + 0x3ab6: 0x000a, 0x3ab7: 0x000a, 0x3ab8: 0x000a, 0x3ab9: 0x000a, 0x3aba: 0x000a, 0x3abb: 0x000a, + 0x3abc: 0x000a, 0x3abd: 0x000a, 0x3abe: 0x000a, 0x3abf: 0x000a, + // Block 0xeb, offset 0x3ac0 + 0x3ac0: 0x000a, 0x3ac1: 0x000a, 0x3ac2: 0x000a, 0x3ac3: 0x000a, 0x3ac4: 0x000a, 0x3ac5: 0x000a, + 0x3ac6: 0x000a, 0x3ac7: 0x000a, 0x3ac8: 0x000a, 0x3ac9: 0x000a, 0x3aca: 0x000a, 0x3acb: 0x000a, + 0x3acc: 0x000a, 0x3acd: 0x000a, 0x3ace: 0x000a, 0x3acf: 0x000a, 0x3ad0: 0x000a, 0x3ad1: 0x000a, + 0x3ad2: 0x000a, 0x3ad3: 0x000a, + 0x3ae0: 0x000a, 0x3ae1: 0x000a, 0x3ae2: 0x000a, 0x3ae3: 0x000a, + 0x3ae4: 0x000a, 0x3ae5: 0x000a, 0x3ae6: 0x000a, 0x3ae7: 0x000a, 0x3ae8: 0x000a, 0x3ae9: 0x000a, + 0x3aea: 0x000a, 0x3aeb: 0x000a, 0x3aec: 0x000a, 0x3aed: 0x000a, + 0x3af0: 0x000a, 0x3af1: 0x000a, 0x3af2: 0x000a, 0x3af3: 0x000a, + 0x3af8: 0x000a, 0x3af9: 0x000a, 0x3afa: 0x000a, + // Block 0xec, offset 0x3b00 + 0x3b00: 0x000a, 0x3b01: 0x000a, 0x3b02: 0x000a, + 0x3b10: 0x000a, 0x3b11: 0x000a, + 0x3b12: 0x000a, 0x3b13: 0x000a, 0x3b14: 0x000a, 0x3b15: 0x000a, + // Block 0xed, offset 0x3b40 + 0x3b7e: 0x000b, 0x3b7f: 0x000b, + // Block 0xee, offset 0x3b80 + 0x3b80: 0x000b, 0x3b81: 0x000b, 0x3b82: 0x000b, 0x3b83: 0x000b, 0x3b84: 0x000b, 0x3b85: 0x000b, + 0x3b86: 0x000b, 0x3b87: 0x000b, 0x3b88: 0x000b, 0x3b89: 0x000b, 0x3b8a: 0x000b, 0x3b8b: 0x000b, + 0x3b8c: 0x000b, 0x3b8d: 0x000b, 0x3b8e: 0x000b, 0x3b8f: 0x000b, 0x3b90: 0x000b, 0x3b91: 0x000b, + 0x3b92: 0x000b, 0x3b93: 0x000b, 0x3b94: 0x000b, 0x3b95: 0x000b, 0x3b96: 0x000b, 0x3b97: 0x000b, + 0x3b98: 0x000b, 0x3b99: 0x000b, 0x3b9a: 0x000b, 0x3b9b: 0x000b, 0x3b9c: 0x000b, 0x3b9d: 0x000b, + 0x3b9e: 0x000b, 0x3b9f: 0x000b, 0x3ba0: 0x000b, 0x3ba1: 0x000b, 0x3ba2: 0x000b, 0x3ba3: 0x000b, + 0x3ba4: 0x000b, 0x3ba5: 0x000b, 0x3ba6: 0x000b, 0x3ba7: 0x000b, 0x3ba8: 0x000b, 0x3ba9: 0x000b, + 0x3baa: 0x000b, 0x3bab: 0x000b, 0x3bac: 0x000b, 0x3bad: 0x000b, 0x3bae: 0x000b, 0x3baf: 0x000b, + 0x3bb0: 0x000b, 0x3bb1: 0x000b, 0x3bb2: 0x000b, 0x3bb3: 0x000b, 0x3bb4: 0x000b, 0x3bb5: 0x000b, + 0x3bb6: 0x000b, 0x3bb7: 0x000b, 0x3bb8: 0x000b, 0x3bb9: 0x000b, 0x3bba: 0x000b, 0x3bbb: 0x000b, + 0x3bbc: 0x000b, 0x3bbd: 0x000b, 0x3bbe: 0x000b, 0x3bbf: 0x000b, + // Block 0xef, offset 0x3bc0 + 0x3bc0: 0x000c, 0x3bc1: 0x000c, 0x3bc2: 0x000c, 0x3bc3: 0x000c, 0x3bc4: 0x000c, 0x3bc5: 0x000c, + 0x3bc6: 0x000c, 0x3bc7: 0x000c, 0x3bc8: 0x000c, 0x3bc9: 0x000c, 0x3bca: 0x000c, 0x3bcb: 0x000c, + 0x3bcc: 0x000c, 0x3bcd: 0x000c, 0x3bce: 0x000c, 0x3bcf: 0x000c, 0x3bd0: 0x000c, 0x3bd1: 0x000c, + 0x3bd2: 0x000c, 0x3bd3: 0x000c, 0x3bd4: 0x000c, 0x3bd5: 0x000c, 0x3bd6: 0x000c, 0x3bd7: 0x000c, + 0x3bd8: 0x000c, 0x3bd9: 0x000c, 0x3bda: 0x000c, 0x3bdb: 0x000c, 0x3bdc: 0x000c, 0x3bdd: 0x000c, + 0x3bde: 0x000c, 0x3bdf: 0x000c, 0x3be0: 0x000c, 0x3be1: 0x000c, 0x3be2: 0x000c, 0x3be3: 0x000c, + 0x3be4: 0x000c, 0x3be5: 0x000c, 0x3be6: 0x000c, 0x3be7: 0x000c, 0x3be8: 0x000c, 0x3be9: 0x000c, + 0x3bea: 0x000c, 0x3beb: 0x000c, 0x3bec: 0x000c, 0x3bed: 0x000c, 0x3bee: 0x000c, 0x3bef: 0x000c, + 0x3bf0: 0x000b, 0x3bf1: 0x000b, 0x3bf2: 0x000b, 0x3bf3: 0x000b, 0x3bf4: 0x000b, 0x3bf5: 0x000b, + 0x3bf6: 0x000b, 0x3bf7: 0x000b, 0x3bf8: 0x000b, 0x3bf9: 0x000b, 0x3bfa: 0x000b, 0x3bfb: 0x000b, + 0x3bfc: 0x000b, 0x3bfd: 0x000b, 0x3bfe: 0x000b, 0x3bff: 0x000b, +} + +// bidiIndex: 24 blocks, 1536 entries, 1536 bytes +// Block 0 is the zero block. +var bidiIndex = [1536]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, + 0xca: 0x03, 0xcb: 0x04, 0xcc: 0x05, 0xcd: 0x06, 0xce: 0x07, 0xcf: 0x08, + 0xd2: 0x09, 0xd6: 0x0a, 0xd7: 0x0b, + 0xd8: 0x0c, 0xd9: 0x0d, 0xda: 0x0e, 0xdb: 0x0f, 0xdc: 0x10, 0xdd: 0x11, 0xde: 0x12, 0xdf: 0x13, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, + 0xea: 0x07, 0xef: 0x08, + 0xf0: 0x11, 0xf1: 0x12, 0xf2: 0x12, 0xf3: 0x14, 0xf4: 0x15, + // Block 0x4, offset 0x100 + 0x120: 0x14, 0x121: 0x15, 0x122: 0x16, 0x123: 0x17, 0x124: 0x18, 0x125: 0x19, 0x126: 0x1a, 0x127: 0x1b, + 0x128: 0x1c, 0x129: 0x1d, 0x12a: 0x1c, 0x12b: 0x1e, 0x12c: 0x1f, 0x12d: 0x20, 0x12e: 0x21, 0x12f: 0x22, + 0x130: 0x23, 0x131: 0x24, 0x132: 0x1a, 0x133: 0x25, 0x134: 0x26, 0x135: 0x27, 0x137: 0x28, + 0x138: 0x29, 0x139: 0x2a, 0x13a: 0x2b, 0x13b: 0x2c, 0x13c: 0x2d, 0x13d: 0x2e, 0x13e: 0x2f, 0x13f: 0x30, + // Block 0x5, offset 0x140 + 0x140: 0x31, 0x141: 0x32, 0x142: 0x33, + 0x14d: 0x34, 0x14e: 0x35, + 0x150: 0x36, + 0x15a: 0x37, 0x15c: 0x38, 0x15d: 0x39, 0x15e: 0x3a, 0x15f: 0x3b, + 0x160: 0x3c, 0x162: 0x3d, 0x164: 0x3e, 0x165: 0x3f, 0x167: 0x40, + 0x168: 0x41, 0x169: 0x42, 0x16a: 0x43, 0x16c: 0x44, 0x16d: 0x45, 0x16e: 0x46, 0x16f: 0x47, + 0x170: 0x48, 0x173: 0x49, 0x177: 0x4a, + 0x17e: 0x4b, 0x17f: 0x4c, + // Block 0x6, offset 0x180 + 0x180: 0x4d, 0x181: 0x4e, 0x182: 0x4f, 0x183: 0x50, 0x184: 0x51, 0x185: 0x52, 0x186: 0x53, 0x187: 0x54, + 0x188: 0x55, 0x189: 0x54, 0x18a: 0x54, 0x18b: 0x54, 0x18c: 0x56, 0x18d: 0x57, 0x18e: 0x58, 0x18f: 0x54, + 0x190: 0x59, 0x191: 0x5a, 0x192: 0x5b, 0x193: 0x5c, 0x194: 0x54, 0x195: 0x54, 0x196: 0x54, 0x197: 0x54, + 0x198: 0x54, 0x199: 0x54, 0x19a: 0x5d, 0x19b: 0x54, 0x19c: 0x54, 0x19d: 0x5e, 0x19e: 0x54, 0x19f: 0x5f, + 0x1a4: 0x54, 0x1a5: 0x54, 0x1a6: 0x60, 0x1a7: 0x61, + 0x1a8: 0x54, 0x1a9: 0x54, 0x1aa: 0x54, 0x1ab: 0x54, 0x1ac: 0x54, 0x1ad: 0x62, 0x1ae: 0x63, 0x1af: 0x54, + 0x1b3: 0x64, 0x1b5: 0x65, 0x1b7: 0x66, + 0x1b8: 0x67, 0x1b9: 0x68, 0x1ba: 0x69, 0x1bb: 0x6a, 0x1bc: 0x54, 0x1bd: 0x54, 0x1be: 0x54, 0x1bf: 0x6b, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x6c, 0x1c2: 0x6d, 0x1c3: 0x6e, 0x1c7: 0x6f, + 0x1c8: 0x70, 0x1c9: 0x71, 0x1ca: 0x72, 0x1cb: 0x73, 0x1cd: 0x74, 0x1cf: 0x75, + // Block 0x8, offset 0x200 + 0x237: 0x54, + // Block 0x9, offset 0x240 + 0x252: 0x76, 0x253: 0x77, + 0x258: 0x78, 0x259: 0x79, 0x25a: 0x7a, 0x25b: 0x7b, 0x25c: 0x7c, 0x25e: 0x7d, + 0x260: 0x7e, 0x261: 0x7f, 0x263: 0x80, 0x264: 0x81, 0x265: 0x82, 0x266: 0x83, 0x267: 0x84, + 0x268: 0x85, 0x269: 0x86, 0x26a: 0x87, 0x26b: 0x88, 0x26f: 0x89, + // Block 0xa, offset 0x280 + 0x2ac: 0x8a, 0x2ad: 0x8b, 0x2ae: 0x0e, 0x2af: 0x0e, + 0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8c, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x8d, + 0x2b8: 0x8e, 0x2b9: 0x8f, 0x2ba: 0x0e, 0x2bb: 0x90, 0x2bc: 0x91, 0x2bd: 0x92, 0x2bf: 0x93, + // Block 0xb, offset 0x2c0 + 0x2c4: 0x94, 0x2c5: 0x54, 0x2c6: 0x95, 0x2c7: 0x96, + 0x2cb: 0x97, 0x2cd: 0x98, + 0x2e0: 0x99, 0x2e1: 0x99, 0x2e2: 0x99, 0x2e3: 0x99, 0x2e4: 0x9a, 0x2e5: 0x99, 0x2e6: 0x99, 0x2e7: 0x99, + 0x2e8: 0x9b, 0x2e9: 0x99, 0x2ea: 0x99, 0x2eb: 0x9c, 0x2ec: 0x9d, 0x2ed: 0x99, 0x2ee: 0x99, 0x2ef: 0x99, + 0x2f0: 0x99, 0x2f1: 0x99, 0x2f2: 0x99, 0x2f3: 0x99, 0x2f4: 0x9e, 0x2f5: 0x99, 0x2f6: 0x99, 0x2f7: 0x99, + 0x2f8: 0x99, 0x2f9: 0x9f, 0x2fa: 0x99, 0x2fb: 0x99, 0x2fc: 0xa0, 0x2fd: 0xa1, 0x2fe: 0x99, 0x2ff: 0x99, + // Block 0xc, offset 0x300 + 0x300: 0xa2, 0x301: 0xa3, 0x302: 0xa4, 0x304: 0xa5, 0x305: 0xa6, 0x306: 0xa7, 0x307: 0xa8, + 0x308: 0xa9, 0x30b: 0xaa, 0x30c: 0x26, 0x30d: 0xab, + 0x310: 0xac, 0x311: 0xad, 0x312: 0xae, 0x313: 0xaf, 0x316: 0xb0, 0x317: 0xb1, + 0x318: 0xb2, 0x319: 0xb3, 0x31a: 0xb4, 0x31c: 0xb5, + 0x320: 0xb6, 0x327: 0xb7, + 0x328: 0xb8, 0x329: 0xb9, 0x32a: 0xba, + 0x330: 0xbb, 0x332: 0xbc, 0x334: 0xbd, 0x335: 0xbe, 0x336: 0xbf, + 0x33b: 0xc0, 0x33f: 0xc1, + // Block 0xd, offset 0x340 + 0x36b: 0xc2, 0x36c: 0xc3, + 0x37d: 0xc4, 0x37e: 0xc5, 0x37f: 0xc6, + // Block 0xe, offset 0x380 + 0x3b2: 0xc7, + // Block 0xf, offset 0x3c0 + 0x3c5: 0xc8, 0x3c6: 0xc9, + 0x3c8: 0x54, 0x3c9: 0xca, 0x3cc: 0x54, 0x3cd: 0xcb, + 0x3db: 0xcc, 0x3dc: 0xcd, 0x3dd: 0xce, 0x3de: 0xcf, 0x3df: 0xd0, + 0x3e8: 0xd1, 0x3e9: 0xd2, 0x3ea: 0xd3, + // Block 0x10, offset 0x400 + 0x400: 0xd4, 0x404: 0xc3, + 0x40b: 0xd5, + 0x420: 0x99, 0x421: 0x99, 0x422: 0x99, 0x423: 0xd6, 0x424: 0x99, 0x425: 0xd7, 0x426: 0x99, 0x427: 0x99, + 0x428: 0x99, 0x429: 0x99, 0x42a: 0x99, 0x42b: 0x99, 0x42c: 0x99, 0x42d: 0x99, 0x42e: 0x99, 0x42f: 0x99, + 0x430: 0x99, 0x431: 0xa0, 0x432: 0x0e, 0x433: 0x99, 0x434: 0x0e, 0x435: 0xd8, 0x436: 0x99, 0x437: 0x99, + 0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xd9, 0x43c: 0x99, 0x43d: 0x99, 0x43e: 0x99, 0x43f: 0x99, + // Block 0x11, offset 0x440 + 0x440: 0xda, 0x441: 0x54, 0x442: 0xdb, 0x443: 0xdc, 0x444: 0xdd, 0x445: 0xde, + 0x449: 0xdf, 0x44c: 0x54, 0x44d: 0x54, 0x44e: 0x54, 0x44f: 0x54, + 0x450: 0x54, 0x451: 0x54, 0x452: 0x54, 0x453: 0x54, 0x454: 0x54, 0x455: 0x54, 0x456: 0x54, 0x457: 0x54, + 0x458: 0x54, 0x459: 0x54, 0x45a: 0x54, 0x45b: 0xe0, 0x45c: 0x54, 0x45d: 0x6a, 0x45e: 0x54, 0x45f: 0xe1, + 0x460: 0xe2, 0x461: 0xe3, 0x462: 0xe4, 0x464: 0xe5, 0x465: 0xe6, 0x466: 0xe7, 0x467: 0xe8, + 0x468: 0x54, 0x469: 0xe9, 0x46a: 0xea, + 0x47f: 0xeb, + // Block 0x12, offset 0x480 + 0x4bf: 0xeb, + // Block 0x13, offset 0x4c0 + 0x4d0: 0x09, 0x4d1: 0x0a, 0x4d6: 0x0b, + 0x4db: 0x0c, 0x4dd: 0x0d, 0x4de: 0x0e, 0x4df: 0x0f, + 0x4ef: 0x10, + 0x4ff: 0x10, + // Block 0x14, offset 0x500 + 0x50f: 0x10, + 0x51f: 0x10, + 0x52f: 0x10, + 0x53f: 0x10, + // Block 0x15, offset 0x540 + 0x540: 0xec, 0x541: 0xec, 0x542: 0xec, 0x543: 0xec, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xed, + 0x548: 0xec, 0x549: 0xec, 0x54a: 0xec, 0x54b: 0xec, 0x54c: 0xec, 0x54d: 0xec, 0x54e: 0xec, 0x54f: 0xec, + 0x550: 0xec, 0x551: 0xec, 0x552: 0xec, 0x553: 0xec, 0x554: 0xec, 0x555: 0xec, 0x556: 0xec, 0x557: 0xec, + 0x558: 0xec, 0x559: 0xec, 0x55a: 0xec, 0x55b: 0xec, 0x55c: 0xec, 0x55d: 0xec, 0x55e: 0xec, 0x55f: 0xec, + 0x560: 0xec, 0x561: 0xec, 0x562: 0xec, 0x563: 0xec, 0x564: 0xec, 0x565: 0xec, 0x566: 0xec, 0x567: 0xec, + 0x568: 0xec, 0x569: 0xec, 0x56a: 0xec, 0x56b: 0xec, 0x56c: 0xec, 0x56d: 0xec, 0x56e: 0xec, 0x56f: 0xec, + 0x570: 0xec, 0x571: 0xec, 0x572: 0xec, 0x573: 0xec, 0x574: 0xec, 0x575: 0xec, 0x576: 0xec, 0x577: 0xec, + 0x578: 0xec, 0x579: 0xec, 0x57a: 0xec, 0x57b: 0xec, 0x57c: 0xec, 0x57d: 0xec, 0x57e: 0xec, 0x57f: 0xec, + // Block 0x16, offset 0x580 + 0x58f: 0x10, + 0x59f: 0x10, + 0x5a0: 0x13, + 0x5af: 0x10, + 0x5bf: 0x10, + // Block 0x17, offset 0x5c0 + 0x5cf: 0x10, +} + +// Total table size 16952 bytes (16KiB); checksum: F50EF68C diff --git a/libgo/go/golang.org/x/text/unicode/norm/tables11.0.0.go b/libgo/go/golang.org/x/text/unicode/norm/tables11.0.0.go index 7297cce32b7..2c58f09baa4 100644 --- a/libgo/go/golang.org/x/text/unicode/norm/tables11.0.0.go +++ b/libgo/go/golang.org/x/text/unicode/norm/tables11.0.0.go @@ -1,6 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. -// +build go1.13 +// +build go1.13,!go1.14 package norm diff --git a/libgo/go/golang.org/x/text/unicode/norm/tables12.0.0.go b/libgo/go/golang.org/x/text/unicode/norm/tables12.0.0.go new file mode 100644 index 00000000000..10f5202c693 --- /dev/null +++ b/libgo/go/golang.org/x/text/unicode/norm/tables12.0.0.go @@ -0,0 +1,7710 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.14 + +package norm + +import "sync" + +const ( + // Version is the Unicode edition from which the tables are derived. + Version = "12.0.0" + + // MaxTransformChunkSize indicates the maximum number of bytes that Transform + // may need to write atomically for any Form. Making a destination buffer at + // least this size ensures that Transform can always make progress and that + // the user does not need to grow the buffer on an ErrShortDst. + MaxTransformChunkSize = 35 + maxNonStarters*4 +) + +var ccc = [55]uint8{ + 0, 1, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, + 84, 91, 103, 107, 118, 122, 129, 130, + 132, 202, 214, 216, 218, 220, 222, 224, + 226, 228, 230, 232, 233, 234, 240, +} + +const ( + firstMulti = 0x186D + firstCCC = 0x2CA1 + endMulti = 0x2F63 + firstLeadingCCC = 0x49B1 + firstCCCZeroExcept = 0x4A7B + firstStarterWithNLead = 0x4AA2 + lastDecomp = 0x4AA4 + maxDecomp = 0x8000 +) + +// decomps: 19108 bytes +var decomps = [...]byte{ + // Bytes 0 - 3f + 0x00, 0x41, 0x20, 0x41, 0x21, 0x41, 0x22, 0x41, + 0x23, 0x41, 0x24, 0x41, 0x25, 0x41, 0x26, 0x41, + 0x27, 0x41, 0x28, 0x41, 0x29, 0x41, 0x2A, 0x41, + 0x2B, 0x41, 0x2C, 0x41, 0x2D, 0x41, 0x2E, 0x41, + 0x2F, 0x41, 0x30, 0x41, 0x31, 0x41, 0x32, 0x41, + 0x33, 0x41, 0x34, 0x41, 0x35, 0x41, 0x36, 0x41, + 0x37, 0x41, 0x38, 0x41, 0x39, 0x41, 0x3A, 0x41, + 0x3B, 0x41, 0x3C, 0x41, 0x3D, 0x41, 0x3E, 0x41, + // Bytes 40 - 7f + 0x3F, 0x41, 0x40, 0x41, 0x41, 0x41, 0x42, 0x41, + 0x43, 0x41, 0x44, 0x41, 0x45, 0x41, 0x46, 0x41, + 0x47, 0x41, 0x48, 0x41, 0x49, 0x41, 0x4A, 0x41, + 0x4B, 0x41, 0x4C, 0x41, 0x4D, 0x41, 0x4E, 0x41, + 0x4F, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41, + 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, + 0x57, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41, + 0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41, + // Bytes 80 - bf + 0x5F, 0x41, 0x60, 0x41, 0x61, 0x41, 0x62, 0x41, + 0x63, 0x41, 0x64, 0x41, 0x65, 0x41, 0x66, 0x41, + 0x67, 0x41, 0x68, 0x41, 0x69, 0x41, 0x6A, 0x41, + 0x6B, 0x41, 0x6C, 0x41, 0x6D, 0x41, 0x6E, 0x41, + 0x6F, 0x41, 0x70, 0x41, 0x71, 0x41, 0x72, 0x41, + 0x73, 0x41, 0x74, 0x41, 0x75, 0x41, 0x76, 0x41, + 0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7A, 0x41, + 0x7B, 0x41, 0x7C, 0x41, 0x7D, 0x41, 0x7E, 0x42, + // Bytes c0 - ff + 0xC2, 0xA2, 0x42, 0xC2, 0xA3, 0x42, 0xC2, 0xA5, + 0x42, 0xC2, 0xA6, 0x42, 0xC2, 0xAC, 0x42, 0xC2, + 0xB7, 0x42, 0xC3, 0x86, 0x42, 0xC3, 0xB0, 0x42, + 0xC4, 0xA6, 0x42, 0xC4, 0xA7, 0x42, 0xC4, 0xB1, + 0x42, 0xC5, 0x8B, 0x42, 0xC5, 0x93, 0x42, 0xC6, + 0x8E, 0x42, 0xC6, 0x90, 0x42, 0xC6, 0xAB, 0x42, + 0xC8, 0xA2, 0x42, 0xC8, 0xB7, 0x42, 0xC9, 0x90, + 0x42, 0xC9, 0x91, 0x42, 0xC9, 0x92, 0x42, 0xC9, + // Bytes 100 - 13f + 0x94, 0x42, 0xC9, 0x95, 0x42, 0xC9, 0x99, 0x42, + 0xC9, 0x9B, 0x42, 0xC9, 0x9C, 0x42, 0xC9, 0x9F, + 0x42, 0xC9, 0xA1, 0x42, 0xC9, 0xA3, 0x42, 0xC9, + 0xA5, 0x42, 0xC9, 0xA6, 0x42, 0xC9, 0xA8, 0x42, + 0xC9, 0xA9, 0x42, 0xC9, 0xAA, 0x42, 0xC9, 0xAB, + 0x42, 0xC9, 0xAD, 0x42, 0xC9, 0xAF, 0x42, 0xC9, + 0xB0, 0x42, 0xC9, 0xB1, 0x42, 0xC9, 0xB2, 0x42, + 0xC9, 0xB3, 0x42, 0xC9, 0xB4, 0x42, 0xC9, 0xB5, + // Bytes 140 - 17f + 0x42, 0xC9, 0xB8, 0x42, 0xC9, 0xB9, 0x42, 0xC9, + 0xBB, 0x42, 0xCA, 0x81, 0x42, 0xCA, 0x82, 0x42, + 0xCA, 0x83, 0x42, 0xCA, 0x89, 0x42, 0xCA, 0x8A, + 0x42, 0xCA, 0x8B, 0x42, 0xCA, 0x8C, 0x42, 0xCA, + 0x90, 0x42, 0xCA, 0x91, 0x42, 0xCA, 0x92, 0x42, + 0xCA, 0x95, 0x42, 0xCA, 0x9D, 0x42, 0xCA, 0x9F, + 0x42, 0xCA, 0xB9, 0x42, 0xCE, 0x91, 0x42, 0xCE, + 0x92, 0x42, 0xCE, 0x93, 0x42, 0xCE, 0x94, 0x42, + // Bytes 180 - 1bf + 0xCE, 0x95, 0x42, 0xCE, 0x96, 0x42, 0xCE, 0x97, + 0x42, 0xCE, 0x98, 0x42, 0xCE, 0x99, 0x42, 0xCE, + 0x9A, 0x42, 0xCE, 0x9B, 0x42, 0xCE, 0x9C, 0x42, + 0xCE, 0x9D, 0x42, 0xCE, 0x9E, 0x42, 0xCE, 0x9F, + 0x42, 0xCE, 0xA0, 0x42, 0xCE, 0xA1, 0x42, 0xCE, + 0xA3, 0x42, 0xCE, 0xA4, 0x42, 0xCE, 0xA5, 0x42, + 0xCE, 0xA6, 0x42, 0xCE, 0xA7, 0x42, 0xCE, 0xA8, + 0x42, 0xCE, 0xA9, 0x42, 0xCE, 0xB1, 0x42, 0xCE, + // Bytes 1c0 - 1ff + 0xB2, 0x42, 0xCE, 0xB3, 0x42, 0xCE, 0xB4, 0x42, + 0xCE, 0xB5, 0x42, 0xCE, 0xB6, 0x42, 0xCE, 0xB7, + 0x42, 0xCE, 0xB8, 0x42, 0xCE, 0xB9, 0x42, 0xCE, + 0xBA, 0x42, 0xCE, 0xBB, 0x42, 0xCE, 0xBC, 0x42, + 0xCE, 0xBD, 0x42, 0xCE, 0xBE, 0x42, 0xCE, 0xBF, + 0x42, 0xCF, 0x80, 0x42, 0xCF, 0x81, 0x42, 0xCF, + 0x82, 0x42, 0xCF, 0x83, 0x42, 0xCF, 0x84, 0x42, + 0xCF, 0x85, 0x42, 0xCF, 0x86, 0x42, 0xCF, 0x87, + // Bytes 200 - 23f + 0x42, 0xCF, 0x88, 0x42, 0xCF, 0x89, 0x42, 0xCF, + 0x9C, 0x42, 0xCF, 0x9D, 0x42, 0xD0, 0xBD, 0x42, + 0xD1, 0x8A, 0x42, 0xD1, 0x8C, 0x42, 0xD7, 0x90, + 0x42, 0xD7, 0x91, 0x42, 0xD7, 0x92, 0x42, 0xD7, + 0x93, 0x42, 0xD7, 0x94, 0x42, 0xD7, 0x9B, 0x42, + 0xD7, 0x9C, 0x42, 0xD7, 0x9D, 0x42, 0xD7, 0xA2, + 0x42, 0xD7, 0xA8, 0x42, 0xD7, 0xAA, 0x42, 0xD8, + 0xA1, 0x42, 0xD8, 0xA7, 0x42, 0xD8, 0xA8, 0x42, + // Bytes 240 - 27f + 0xD8, 0xA9, 0x42, 0xD8, 0xAA, 0x42, 0xD8, 0xAB, + 0x42, 0xD8, 0xAC, 0x42, 0xD8, 0xAD, 0x42, 0xD8, + 0xAE, 0x42, 0xD8, 0xAF, 0x42, 0xD8, 0xB0, 0x42, + 0xD8, 0xB1, 0x42, 0xD8, 0xB2, 0x42, 0xD8, 0xB3, + 0x42, 0xD8, 0xB4, 0x42, 0xD8, 0xB5, 0x42, 0xD8, + 0xB6, 0x42, 0xD8, 0xB7, 0x42, 0xD8, 0xB8, 0x42, + 0xD8, 0xB9, 0x42, 0xD8, 0xBA, 0x42, 0xD9, 0x81, + 0x42, 0xD9, 0x82, 0x42, 0xD9, 0x83, 0x42, 0xD9, + // Bytes 280 - 2bf + 0x84, 0x42, 0xD9, 0x85, 0x42, 0xD9, 0x86, 0x42, + 0xD9, 0x87, 0x42, 0xD9, 0x88, 0x42, 0xD9, 0x89, + 0x42, 0xD9, 0x8A, 0x42, 0xD9, 0xAE, 0x42, 0xD9, + 0xAF, 0x42, 0xD9, 0xB1, 0x42, 0xD9, 0xB9, 0x42, + 0xD9, 0xBA, 0x42, 0xD9, 0xBB, 0x42, 0xD9, 0xBE, + 0x42, 0xD9, 0xBF, 0x42, 0xDA, 0x80, 0x42, 0xDA, + 0x83, 0x42, 0xDA, 0x84, 0x42, 0xDA, 0x86, 0x42, + 0xDA, 0x87, 0x42, 0xDA, 0x88, 0x42, 0xDA, 0x8C, + // Bytes 2c0 - 2ff + 0x42, 0xDA, 0x8D, 0x42, 0xDA, 0x8E, 0x42, 0xDA, + 0x91, 0x42, 0xDA, 0x98, 0x42, 0xDA, 0xA1, 0x42, + 0xDA, 0xA4, 0x42, 0xDA, 0xA6, 0x42, 0xDA, 0xA9, + 0x42, 0xDA, 0xAD, 0x42, 0xDA, 0xAF, 0x42, 0xDA, + 0xB1, 0x42, 0xDA, 0xB3, 0x42, 0xDA, 0xBA, 0x42, + 0xDA, 0xBB, 0x42, 0xDA, 0xBE, 0x42, 0xDB, 0x81, + 0x42, 0xDB, 0x85, 0x42, 0xDB, 0x86, 0x42, 0xDB, + 0x87, 0x42, 0xDB, 0x88, 0x42, 0xDB, 0x89, 0x42, + // Bytes 300 - 33f + 0xDB, 0x8B, 0x42, 0xDB, 0x8C, 0x42, 0xDB, 0x90, + 0x42, 0xDB, 0x92, 0x43, 0xE0, 0xBC, 0x8B, 0x43, + 0xE1, 0x83, 0x9C, 0x43, 0xE1, 0x84, 0x80, 0x43, + 0xE1, 0x84, 0x81, 0x43, 0xE1, 0x84, 0x82, 0x43, + 0xE1, 0x84, 0x83, 0x43, 0xE1, 0x84, 0x84, 0x43, + 0xE1, 0x84, 0x85, 0x43, 0xE1, 0x84, 0x86, 0x43, + 0xE1, 0x84, 0x87, 0x43, 0xE1, 0x84, 0x88, 0x43, + 0xE1, 0x84, 0x89, 0x43, 0xE1, 0x84, 0x8A, 0x43, + // Bytes 340 - 37f + 0xE1, 0x84, 0x8B, 0x43, 0xE1, 0x84, 0x8C, 0x43, + 0xE1, 0x84, 0x8D, 0x43, 0xE1, 0x84, 0x8E, 0x43, + 0xE1, 0x84, 0x8F, 0x43, 0xE1, 0x84, 0x90, 0x43, + 0xE1, 0x84, 0x91, 0x43, 0xE1, 0x84, 0x92, 0x43, + 0xE1, 0x84, 0x94, 0x43, 0xE1, 0x84, 0x95, 0x43, + 0xE1, 0x84, 0x9A, 0x43, 0xE1, 0x84, 0x9C, 0x43, + 0xE1, 0x84, 0x9D, 0x43, 0xE1, 0x84, 0x9E, 0x43, + 0xE1, 0x84, 0xA0, 0x43, 0xE1, 0x84, 0xA1, 0x43, + // Bytes 380 - 3bf + 0xE1, 0x84, 0xA2, 0x43, 0xE1, 0x84, 0xA3, 0x43, + 0xE1, 0x84, 0xA7, 0x43, 0xE1, 0x84, 0xA9, 0x43, + 0xE1, 0x84, 0xAB, 0x43, 0xE1, 0x84, 0xAC, 0x43, + 0xE1, 0x84, 0xAD, 0x43, 0xE1, 0x84, 0xAE, 0x43, + 0xE1, 0x84, 0xAF, 0x43, 0xE1, 0x84, 0xB2, 0x43, + 0xE1, 0x84, 0xB6, 0x43, 0xE1, 0x85, 0x80, 0x43, + 0xE1, 0x85, 0x87, 0x43, 0xE1, 0x85, 0x8C, 0x43, + 0xE1, 0x85, 0x97, 0x43, 0xE1, 0x85, 0x98, 0x43, + // Bytes 3c0 - 3ff + 0xE1, 0x85, 0x99, 0x43, 0xE1, 0x85, 0xA0, 0x43, + 0xE1, 0x86, 0x84, 0x43, 0xE1, 0x86, 0x85, 0x43, + 0xE1, 0x86, 0x88, 0x43, 0xE1, 0x86, 0x91, 0x43, + 0xE1, 0x86, 0x92, 0x43, 0xE1, 0x86, 0x94, 0x43, + 0xE1, 0x86, 0x9E, 0x43, 0xE1, 0x86, 0xA1, 0x43, + 0xE1, 0x87, 0x87, 0x43, 0xE1, 0x87, 0x88, 0x43, + 0xE1, 0x87, 0x8C, 0x43, 0xE1, 0x87, 0x8E, 0x43, + 0xE1, 0x87, 0x93, 0x43, 0xE1, 0x87, 0x97, 0x43, + // Bytes 400 - 43f + 0xE1, 0x87, 0x99, 0x43, 0xE1, 0x87, 0x9D, 0x43, + 0xE1, 0x87, 0x9F, 0x43, 0xE1, 0x87, 0xB1, 0x43, + 0xE1, 0x87, 0xB2, 0x43, 0xE1, 0xB4, 0x82, 0x43, + 0xE1, 0xB4, 0x96, 0x43, 0xE1, 0xB4, 0x97, 0x43, + 0xE1, 0xB4, 0x9C, 0x43, 0xE1, 0xB4, 0x9D, 0x43, + 0xE1, 0xB4, 0xA5, 0x43, 0xE1, 0xB5, 0xBB, 0x43, + 0xE1, 0xB6, 0x85, 0x43, 0xE2, 0x80, 0x82, 0x43, + 0xE2, 0x80, 0x83, 0x43, 0xE2, 0x80, 0x90, 0x43, + // Bytes 440 - 47f + 0xE2, 0x80, 0x93, 0x43, 0xE2, 0x80, 0x94, 0x43, + 0xE2, 0x82, 0xA9, 0x43, 0xE2, 0x86, 0x90, 0x43, + 0xE2, 0x86, 0x91, 0x43, 0xE2, 0x86, 0x92, 0x43, + 0xE2, 0x86, 0x93, 0x43, 0xE2, 0x88, 0x82, 0x43, + 0xE2, 0x88, 0x87, 0x43, 0xE2, 0x88, 0x91, 0x43, + 0xE2, 0x88, 0x92, 0x43, 0xE2, 0x94, 0x82, 0x43, + 0xE2, 0x96, 0xA0, 0x43, 0xE2, 0x97, 0x8B, 0x43, + 0xE2, 0xA6, 0x85, 0x43, 0xE2, 0xA6, 0x86, 0x43, + // Bytes 480 - 4bf + 0xE2, 0xB5, 0xA1, 0x43, 0xE3, 0x80, 0x81, 0x43, + 0xE3, 0x80, 0x82, 0x43, 0xE3, 0x80, 0x88, 0x43, + 0xE3, 0x80, 0x89, 0x43, 0xE3, 0x80, 0x8A, 0x43, + 0xE3, 0x80, 0x8B, 0x43, 0xE3, 0x80, 0x8C, 0x43, + 0xE3, 0x80, 0x8D, 0x43, 0xE3, 0x80, 0x8E, 0x43, + 0xE3, 0x80, 0x8F, 0x43, 0xE3, 0x80, 0x90, 0x43, + 0xE3, 0x80, 0x91, 0x43, 0xE3, 0x80, 0x92, 0x43, + 0xE3, 0x80, 0x94, 0x43, 0xE3, 0x80, 0x95, 0x43, + // Bytes 4c0 - 4ff + 0xE3, 0x80, 0x96, 0x43, 0xE3, 0x80, 0x97, 0x43, + 0xE3, 0x82, 0xA1, 0x43, 0xE3, 0x82, 0xA2, 0x43, + 0xE3, 0x82, 0xA3, 0x43, 0xE3, 0x82, 0xA4, 0x43, + 0xE3, 0x82, 0xA5, 0x43, 0xE3, 0x82, 0xA6, 0x43, + 0xE3, 0x82, 0xA7, 0x43, 0xE3, 0x82, 0xA8, 0x43, + 0xE3, 0x82, 0xA9, 0x43, 0xE3, 0x82, 0xAA, 0x43, + 0xE3, 0x82, 0xAB, 0x43, 0xE3, 0x82, 0xAD, 0x43, + 0xE3, 0x82, 0xAF, 0x43, 0xE3, 0x82, 0xB1, 0x43, + // Bytes 500 - 53f + 0xE3, 0x82, 0xB3, 0x43, 0xE3, 0x82, 0xB5, 0x43, + 0xE3, 0x82, 0xB7, 0x43, 0xE3, 0x82, 0xB9, 0x43, + 0xE3, 0x82, 0xBB, 0x43, 0xE3, 0x82, 0xBD, 0x43, + 0xE3, 0x82, 0xBF, 0x43, 0xE3, 0x83, 0x81, 0x43, + 0xE3, 0x83, 0x83, 0x43, 0xE3, 0x83, 0x84, 0x43, + 0xE3, 0x83, 0x86, 0x43, 0xE3, 0x83, 0x88, 0x43, + 0xE3, 0x83, 0x8A, 0x43, 0xE3, 0x83, 0x8B, 0x43, + 0xE3, 0x83, 0x8C, 0x43, 0xE3, 0x83, 0x8D, 0x43, + // Bytes 540 - 57f + 0xE3, 0x83, 0x8E, 0x43, 0xE3, 0x83, 0x8F, 0x43, + 0xE3, 0x83, 0x92, 0x43, 0xE3, 0x83, 0x95, 0x43, + 0xE3, 0x83, 0x98, 0x43, 0xE3, 0x83, 0x9B, 0x43, + 0xE3, 0x83, 0x9E, 0x43, 0xE3, 0x83, 0x9F, 0x43, + 0xE3, 0x83, 0xA0, 0x43, 0xE3, 0x83, 0xA1, 0x43, + 0xE3, 0x83, 0xA2, 0x43, 0xE3, 0x83, 0xA3, 0x43, + 0xE3, 0x83, 0xA4, 0x43, 0xE3, 0x83, 0xA5, 0x43, + 0xE3, 0x83, 0xA6, 0x43, 0xE3, 0x83, 0xA7, 0x43, + // Bytes 580 - 5bf + 0xE3, 0x83, 0xA8, 0x43, 0xE3, 0x83, 0xA9, 0x43, + 0xE3, 0x83, 0xAA, 0x43, 0xE3, 0x83, 0xAB, 0x43, + 0xE3, 0x83, 0xAC, 0x43, 0xE3, 0x83, 0xAD, 0x43, + 0xE3, 0x83, 0xAF, 0x43, 0xE3, 0x83, 0xB0, 0x43, + 0xE3, 0x83, 0xB1, 0x43, 0xE3, 0x83, 0xB2, 0x43, + 0xE3, 0x83, 0xB3, 0x43, 0xE3, 0x83, 0xBB, 0x43, + 0xE3, 0x83, 0xBC, 0x43, 0xE3, 0x92, 0x9E, 0x43, + 0xE3, 0x92, 0xB9, 0x43, 0xE3, 0x92, 0xBB, 0x43, + // Bytes 5c0 - 5ff + 0xE3, 0x93, 0x9F, 0x43, 0xE3, 0x94, 0x95, 0x43, + 0xE3, 0x9B, 0xAE, 0x43, 0xE3, 0x9B, 0xBC, 0x43, + 0xE3, 0x9E, 0x81, 0x43, 0xE3, 0xA0, 0xAF, 0x43, + 0xE3, 0xA1, 0xA2, 0x43, 0xE3, 0xA1, 0xBC, 0x43, + 0xE3, 0xA3, 0x87, 0x43, 0xE3, 0xA3, 0xA3, 0x43, + 0xE3, 0xA4, 0x9C, 0x43, 0xE3, 0xA4, 0xBA, 0x43, + 0xE3, 0xA8, 0xAE, 0x43, 0xE3, 0xA9, 0xAC, 0x43, + 0xE3, 0xAB, 0xA4, 0x43, 0xE3, 0xAC, 0x88, 0x43, + // Bytes 600 - 63f + 0xE3, 0xAC, 0x99, 0x43, 0xE3, 0xAD, 0x89, 0x43, + 0xE3, 0xAE, 0x9D, 0x43, 0xE3, 0xB0, 0x98, 0x43, + 0xE3, 0xB1, 0x8E, 0x43, 0xE3, 0xB4, 0xB3, 0x43, + 0xE3, 0xB6, 0x96, 0x43, 0xE3, 0xBA, 0xAC, 0x43, + 0xE3, 0xBA, 0xB8, 0x43, 0xE3, 0xBC, 0x9B, 0x43, + 0xE3, 0xBF, 0xBC, 0x43, 0xE4, 0x80, 0x88, 0x43, + 0xE4, 0x80, 0x98, 0x43, 0xE4, 0x80, 0xB9, 0x43, + 0xE4, 0x81, 0x86, 0x43, 0xE4, 0x82, 0x96, 0x43, + // Bytes 640 - 67f + 0xE4, 0x83, 0xA3, 0x43, 0xE4, 0x84, 0xAF, 0x43, + 0xE4, 0x88, 0x82, 0x43, 0xE4, 0x88, 0xA7, 0x43, + 0xE4, 0x8A, 0xA0, 0x43, 0xE4, 0x8C, 0x81, 0x43, + 0xE4, 0x8C, 0xB4, 0x43, 0xE4, 0x8D, 0x99, 0x43, + 0xE4, 0x8F, 0x95, 0x43, 0xE4, 0x8F, 0x99, 0x43, + 0xE4, 0x90, 0x8B, 0x43, 0xE4, 0x91, 0xAB, 0x43, + 0xE4, 0x94, 0xAB, 0x43, 0xE4, 0x95, 0x9D, 0x43, + 0xE4, 0x95, 0xA1, 0x43, 0xE4, 0x95, 0xAB, 0x43, + // Bytes 680 - 6bf + 0xE4, 0x97, 0x97, 0x43, 0xE4, 0x97, 0xB9, 0x43, + 0xE4, 0x98, 0xB5, 0x43, 0xE4, 0x9A, 0xBE, 0x43, + 0xE4, 0x9B, 0x87, 0x43, 0xE4, 0xA6, 0x95, 0x43, + 0xE4, 0xA7, 0xA6, 0x43, 0xE4, 0xA9, 0xAE, 0x43, + 0xE4, 0xA9, 0xB6, 0x43, 0xE4, 0xAA, 0xB2, 0x43, + 0xE4, 0xAC, 0xB3, 0x43, 0xE4, 0xAF, 0x8E, 0x43, + 0xE4, 0xB3, 0x8E, 0x43, 0xE4, 0xB3, 0xAD, 0x43, + 0xE4, 0xB3, 0xB8, 0x43, 0xE4, 0xB5, 0x96, 0x43, + // Bytes 6c0 - 6ff + 0xE4, 0xB8, 0x80, 0x43, 0xE4, 0xB8, 0x81, 0x43, + 0xE4, 0xB8, 0x83, 0x43, 0xE4, 0xB8, 0x89, 0x43, + 0xE4, 0xB8, 0x8A, 0x43, 0xE4, 0xB8, 0x8B, 0x43, + 0xE4, 0xB8, 0x8D, 0x43, 0xE4, 0xB8, 0x99, 0x43, + 0xE4, 0xB8, 0xA6, 0x43, 0xE4, 0xB8, 0xA8, 0x43, + 0xE4, 0xB8, 0xAD, 0x43, 0xE4, 0xB8, 0xB2, 0x43, + 0xE4, 0xB8, 0xB6, 0x43, 0xE4, 0xB8, 0xB8, 0x43, + 0xE4, 0xB8, 0xB9, 0x43, 0xE4, 0xB8, 0xBD, 0x43, + // Bytes 700 - 73f + 0xE4, 0xB8, 0xBF, 0x43, 0xE4, 0xB9, 0x81, 0x43, + 0xE4, 0xB9, 0x99, 0x43, 0xE4, 0xB9, 0x9D, 0x43, + 0xE4, 0xBA, 0x82, 0x43, 0xE4, 0xBA, 0x85, 0x43, + 0xE4, 0xBA, 0x86, 0x43, 0xE4, 0xBA, 0x8C, 0x43, + 0xE4, 0xBA, 0x94, 0x43, 0xE4, 0xBA, 0xA0, 0x43, + 0xE4, 0xBA, 0xA4, 0x43, 0xE4, 0xBA, 0xAE, 0x43, + 0xE4, 0xBA, 0xBA, 0x43, 0xE4, 0xBB, 0x80, 0x43, + 0xE4, 0xBB, 0x8C, 0x43, 0xE4, 0xBB, 0xA4, 0x43, + // Bytes 740 - 77f + 0xE4, 0xBC, 0x81, 0x43, 0xE4, 0xBC, 0x91, 0x43, + 0xE4, 0xBD, 0xA0, 0x43, 0xE4, 0xBE, 0x80, 0x43, + 0xE4, 0xBE, 0x86, 0x43, 0xE4, 0xBE, 0x8B, 0x43, + 0xE4, 0xBE, 0xAE, 0x43, 0xE4, 0xBE, 0xBB, 0x43, + 0xE4, 0xBE, 0xBF, 0x43, 0xE5, 0x80, 0x82, 0x43, + 0xE5, 0x80, 0xAB, 0x43, 0xE5, 0x81, 0xBA, 0x43, + 0xE5, 0x82, 0x99, 0x43, 0xE5, 0x83, 0x8F, 0x43, + 0xE5, 0x83, 0x9A, 0x43, 0xE5, 0x83, 0xA7, 0x43, + // Bytes 780 - 7bf + 0xE5, 0x84, 0xAA, 0x43, 0xE5, 0x84, 0xBF, 0x43, + 0xE5, 0x85, 0x80, 0x43, 0xE5, 0x85, 0x85, 0x43, + 0xE5, 0x85, 0x8D, 0x43, 0xE5, 0x85, 0x94, 0x43, + 0xE5, 0x85, 0xA4, 0x43, 0xE5, 0x85, 0xA5, 0x43, + 0xE5, 0x85, 0xA7, 0x43, 0xE5, 0x85, 0xA8, 0x43, + 0xE5, 0x85, 0xA9, 0x43, 0xE5, 0x85, 0xAB, 0x43, + 0xE5, 0x85, 0xAD, 0x43, 0xE5, 0x85, 0xB7, 0x43, + 0xE5, 0x86, 0x80, 0x43, 0xE5, 0x86, 0x82, 0x43, + // Bytes 7c0 - 7ff + 0xE5, 0x86, 0x8D, 0x43, 0xE5, 0x86, 0x92, 0x43, + 0xE5, 0x86, 0x95, 0x43, 0xE5, 0x86, 0x96, 0x43, + 0xE5, 0x86, 0x97, 0x43, 0xE5, 0x86, 0x99, 0x43, + 0xE5, 0x86, 0xA4, 0x43, 0xE5, 0x86, 0xAB, 0x43, + 0xE5, 0x86, 0xAC, 0x43, 0xE5, 0x86, 0xB5, 0x43, + 0xE5, 0x86, 0xB7, 0x43, 0xE5, 0x87, 0x89, 0x43, + 0xE5, 0x87, 0x8C, 0x43, 0xE5, 0x87, 0x9C, 0x43, + 0xE5, 0x87, 0x9E, 0x43, 0xE5, 0x87, 0xA0, 0x43, + // Bytes 800 - 83f + 0xE5, 0x87, 0xB5, 0x43, 0xE5, 0x88, 0x80, 0x43, + 0xE5, 0x88, 0x83, 0x43, 0xE5, 0x88, 0x87, 0x43, + 0xE5, 0x88, 0x97, 0x43, 0xE5, 0x88, 0x9D, 0x43, + 0xE5, 0x88, 0xA9, 0x43, 0xE5, 0x88, 0xBA, 0x43, + 0xE5, 0x88, 0xBB, 0x43, 0xE5, 0x89, 0x86, 0x43, + 0xE5, 0x89, 0x8D, 0x43, 0xE5, 0x89, 0xB2, 0x43, + 0xE5, 0x89, 0xB7, 0x43, 0xE5, 0x8A, 0x89, 0x43, + 0xE5, 0x8A, 0x9B, 0x43, 0xE5, 0x8A, 0xA3, 0x43, + // Bytes 840 - 87f + 0xE5, 0x8A, 0xB3, 0x43, 0xE5, 0x8A, 0xB4, 0x43, + 0xE5, 0x8B, 0x87, 0x43, 0xE5, 0x8B, 0x89, 0x43, + 0xE5, 0x8B, 0x92, 0x43, 0xE5, 0x8B, 0x9E, 0x43, + 0xE5, 0x8B, 0xA4, 0x43, 0xE5, 0x8B, 0xB5, 0x43, + 0xE5, 0x8B, 0xB9, 0x43, 0xE5, 0x8B, 0xBA, 0x43, + 0xE5, 0x8C, 0x85, 0x43, 0xE5, 0x8C, 0x86, 0x43, + 0xE5, 0x8C, 0x95, 0x43, 0xE5, 0x8C, 0x97, 0x43, + 0xE5, 0x8C, 0x9A, 0x43, 0xE5, 0x8C, 0xB8, 0x43, + // Bytes 880 - 8bf + 0xE5, 0x8C, 0xBB, 0x43, 0xE5, 0x8C, 0xBF, 0x43, + 0xE5, 0x8D, 0x81, 0x43, 0xE5, 0x8D, 0x84, 0x43, + 0xE5, 0x8D, 0x85, 0x43, 0xE5, 0x8D, 0x89, 0x43, + 0xE5, 0x8D, 0x91, 0x43, 0xE5, 0x8D, 0x94, 0x43, + 0xE5, 0x8D, 0x9A, 0x43, 0xE5, 0x8D, 0x9C, 0x43, + 0xE5, 0x8D, 0xA9, 0x43, 0xE5, 0x8D, 0xB0, 0x43, + 0xE5, 0x8D, 0xB3, 0x43, 0xE5, 0x8D, 0xB5, 0x43, + 0xE5, 0x8D, 0xBD, 0x43, 0xE5, 0x8D, 0xBF, 0x43, + // Bytes 8c0 - 8ff + 0xE5, 0x8E, 0x82, 0x43, 0xE5, 0x8E, 0xB6, 0x43, + 0xE5, 0x8F, 0x83, 0x43, 0xE5, 0x8F, 0x88, 0x43, + 0xE5, 0x8F, 0x8A, 0x43, 0xE5, 0x8F, 0x8C, 0x43, + 0xE5, 0x8F, 0x9F, 0x43, 0xE5, 0x8F, 0xA3, 0x43, + 0xE5, 0x8F, 0xA5, 0x43, 0xE5, 0x8F, 0xAB, 0x43, + 0xE5, 0x8F, 0xAF, 0x43, 0xE5, 0x8F, 0xB1, 0x43, + 0xE5, 0x8F, 0xB3, 0x43, 0xE5, 0x90, 0x86, 0x43, + 0xE5, 0x90, 0x88, 0x43, 0xE5, 0x90, 0x8D, 0x43, + // Bytes 900 - 93f + 0xE5, 0x90, 0x8F, 0x43, 0xE5, 0x90, 0x9D, 0x43, + 0xE5, 0x90, 0xB8, 0x43, 0xE5, 0x90, 0xB9, 0x43, + 0xE5, 0x91, 0x82, 0x43, 0xE5, 0x91, 0x88, 0x43, + 0xE5, 0x91, 0xA8, 0x43, 0xE5, 0x92, 0x9E, 0x43, + 0xE5, 0x92, 0xA2, 0x43, 0xE5, 0x92, 0xBD, 0x43, + 0xE5, 0x93, 0xB6, 0x43, 0xE5, 0x94, 0x90, 0x43, + 0xE5, 0x95, 0x8F, 0x43, 0xE5, 0x95, 0x93, 0x43, + 0xE5, 0x95, 0x95, 0x43, 0xE5, 0x95, 0xA3, 0x43, + // Bytes 940 - 97f + 0xE5, 0x96, 0x84, 0x43, 0xE5, 0x96, 0x87, 0x43, + 0xE5, 0x96, 0x99, 0x43, 0xE5, 0x96, 0x9D, 0x43, + 0xE5, 0x96, 0xAB, 0x43, 0xE5, 0x96, 0xB3, 0x43, + 0xE5, 0x96, 0xB6, 0x43, 0xE5, 0x97, 0x80, 0x43, + 0xE5, 0x97, 0x82, 0x43, 0xE5, 0x97, 0xA2, 0x43, + 0xE5, 0x98, 0x86, 0x43, 0xE5, 0x99, 0x91, 0x43, + 0xE5, 0x99, 0xA8, 0x43, 0xE5, 0x99, 0xB4, 0x43, + 0xE5, 0x9B, 0x97, 0x43, 0xE5, 0x9B, 0x9B, 0x43, + // Bytes 980 - 9bf + 0xE5, 0x9B, 0xB9, 0x43, 0xE5, 0x9C, 0x96, 0x43, + 0xE5, 0x9C, 0x97, 0x43, 0xE5, 0x9C, 0x9F, 0x43, + 0xE5, 0x9C, 0xB0, 0x43, 0xE5, 0x9E, 0x8B, 0x43, + 0xE5, 0x9F, 0x8E, 0x43, 0xE5, 0x9F, 0xB4, 0x43, + 0xE5, 0xA0, 0x8D, 0x43, 0xE5, 0xA0, 0xB1, 0x43, + 0xE5, 0xA0, 0xB2, 0x43, 0xE5, 0xA1, 0x80, 0x43, + 0xE5, 0xA1, 0x9A, 0x43, 0xE5, 0xA1, 0x9E, 0x43, + 0xE5, 0xA2, 0xA8, 0x43, 0xE5, 0xA2, 0xAC, 0x43, + // Bytes 9c0 - 9ff + 0xE5, 0xA2, 0xB3, 0x43, 0xE5, 0xA3, 0x98, 0x43, + 0xE5, 0xA3, 0x9F, 0x43, 0xE5, 0xA3, 0xAB, 0x43, + 0xE5, 0xA3, 0xAE, 0x43, 0xE5, 0xA3, 0xB0, 0x43, + 0xE5, 0xA3, 0xB2, 0x43, 0xE5, 0xA3, 0xB7, 0x43, + 0xE5, 0xA4, 0x82, 0x43, 0xE5, 0xA4, 0x86, 0x43, + 0xE5, 0xA4, 0x8A, 0x43, 0xE5, 0xA4, 0x95, 0x43, + 0xE5, 0xA4, 0x9A, 0x43, 0xE5, 0xA4, 0x9C, 0x43, + 0xE5, 0xA4, 0xA2, 0x43, 0xE5, 0xA4, 0xA7, 0x43, + // Bytes a00 - a3f + 0xE5, 0xA4, 0xA9, 0x43, 0xE5, 0xA5, 0x84, 0x43, + 0xE5, 0xA5, 0x88, 0x43, 0xE5, 0xA5, 0x91, 0x43, + 0xE5, 0xA5, 0x94, 0x43, 0xE5, 0xA5, 0xA2, 0x43, + 0xE5, 0xA5, 0xB3, 0x43, 0xE5, 0xA7, 0x98, 0x43, + 0xE5, 0xA7, 0xAC, 0x43, 0xE5, 0xA8, 0x9B, 0x43, + 0xE5, 0xA8, 0xA7, 0x43, 0xE5, 0xA9, 0xA2, 0x43, + 0xE5, 0xA9, 0xA6, 0x43, 0xE5, 0xAA, 0xB5, 0x43, + 0xE5, 0xAC, 0x88, 0x43, 0xE5, 0xAC, 0xA8, 0x43, + // Bytes a40 - a7f + 0xE5, 0xAC, 0xBE, 0x43, 0xE5, 0xAD, 0x90, 0x43, + 0xE5, 0xAD, 0x97, 0x43, 0xE5, 0xAD, 0xA6, 0x43, + 0xE5, 0xAE, 0x80, 0x43, 0xE5, 0xAE, 0x85, 0x43, + 0xE5, 0xAE, 0x97, 0x43, 0xE5, 0xAF, 0x83, 0x43, + 0xE5, 0xAF, 0x98, 0x43, 0xE5, 0xAF, 0xA7, 0x43, + 0xE5, 0xAF, 0xAE, 0x43, 0xE5, 0xAF, 0xB3, 0x43, + 0xE5, 0xAF, 0xB8, 0x43, 0xE5, 0xAF, 0xBF, 0x43, + 0xE5, 0xB0, 0x86, 0x43, 0xE5, 0xB0, 0x8F, 0x43, + // Bytes a80 - abf + 0xE5, 0xB0, 0xA2, 0x43, 0xE5, 0xB0, 0xB8, 0x43, + 0xE5, 0xB0, 0xBF, 0x43, 0xE5, 0xB1, 0xA0, 0x43, + 0xE5, 0xB1, 0xA2, 0x43, 0xE5, 0xB1, 0xA4, 0x43, + 0xE5, 0xB1, 0xA5, 0x43, 0xE5, 0xB1, 0xAE, 0x43, + 0xE5, 0xB1, 0xB1, 0x43, 0xE5, 0xB2, 0x8D, 0x43, + 0xE5, 0xB3, 0x80, 0x43, 0xE5, 0xB4, 0x99, 0x43, + 0xE5, 0xB5, 0x83, 0x43, 0xE5, 0xB5, 0x90, 0x43, + 0xE5, 0xB5, 0xAB, 0x43, 0xE5, 0xB5, 0xAE, 0x43, + // Bytes ac0 - aff + 0xE5, 0xB5, 0xBC, 0x43, 0xE5, 0xB6, 0xB2, 0x43, + 0xE5, 0xB6, 0xBA, 0x43, 0xE5, 0xB7, 0x9B, 0x43, + 0xE5, 0xB7, 0xA1, 0x43, 0xE5, 0xB7, 0xA2, 0x43, + 0xE5, 0xB7, 0xA5, 0x43, 0xE5, 0xB7, 0xA6, 0x43, + 0xE5, 0xB7, 0xB1, 0x43, 0xE5, 0xB7, 0xBD, 0x43, + 0xE5, 0xB7, 0xBE, 0x43, 0xE5, 0xB8, 0xA8, 0x43, + 0xE5, 0xB8, 0xBD, 0x43, 0xE5, 0xB9, 0xA9, 0x43, + 0xE5, 0xB9, 0xB2, 0x43, 0xE5, 0xB9, 0xB4, 0x43, + // Bytes b00 - b3f + 0xE5, 0xB9, 0xBA, 0x43, 0xE5, 0xB9, 0xBC, 0x43, + 0xE5, 0xB9, 0xBF, 0x43, 0xE5, 0xBA, 0xA6, 0x43, + 0xE5, 0xBA, 0xB0, 0x43, 0xE5, 0xBA, 0xB3, 0x43, + 0xE5, 0xBA, 0xB6, 0x43, 0xE5, 0xBB, 0x89, 0x43, + 0xE5, 0xBB, 0x8A, 0x43, 0xE5, 0xBB, 0x92, 0x43, + 0xE5, 0xBB, 0x93, 0x43, 0xE5, 0xBB, 0x99, 0x43, + 0xE5, 0xBB, 0xAC, 0x43, 0xE5, 0xBB, 0xB4, 0x43, + 0xE5, 0xBB, 0xBE, 0x43, 0xE5, 0xBC, 0x84, 0x43, + // Bytes b40 - b7f + 0xE5, 0xBC, 0x8B, 0x43, 0xE5, 0xBC, 0x93, 0x43, + 0xE5, 0xBC, 0xA2, 0x43, 0xE5, 0xBD, 0x90, 0x43, + 0xE5, 0xBD, 0x93, 0x43, 0xE5, 0xBD, 0xA1, 0x43, + 0xE5, 0xBD, 0xA2, 0x43, 0xE5, 0xBD, 0xA9, 0x43, + 0xE5, 0xBD, 0xAB, 0x43, 0xE5, 0xBD, 0xB3, 0x43, + 0xE5, 0xBE, 0x8B, 0x43, 0xE5, 0xBE, 0x8C, 0x43, + 0xE5, 0xBE, 0x97, 0x43, 0xE5, 0xBE, 0x9A, 0x43, + 0xE5, 0xBE, 0xA9, 0x43, 0xE5, 0xBE, 0xAD, 0x43, + // Bytes b80 - bbf + 0xE5, 0xBF, 0x83, 0x43, 0xE5, 0xBF, 0x8D, 0x43, + 0xE5, 0xBF, 0x97, 0x43, 0xE5, 0xBF, 0xB5, 0x43, + 0xE5, 0xBF, 0xB9, 0x43, 0xE6, 0x80, 0x92, 0x43, + 0xE6, 0x80, 0x9C, 0x43, 0xE6, 0x81, 0xB5, 0x43, + 0xE6, 0x82, 0x81, 0x43, 0xE6, 0x82, 0x94, 0x43, + 0xE6, 0x83, 0x87, 0x43, 0xE6, 0x83, 0x98, 0x43, + 0xE6, 0x83, 0xA1, 0x43, 0xE6, 0x84, 0x88, 0x43, + 0xE6, 0x85, 0x84, 0x43, 0xE6, 0x85, 0x88, 0x43, + // Bytes bc0 - bff + 0xE6, 0x85, 0x8C, 0x43, 0xE6, 0x85, 0x8E, 0x43, + 0xE6, 0x85, 0xA0, 0x43, 0xE6, 0x85, 0xA8, 0x43, + 0xE6, 0x85, 0xBA, 0x43, 0xE6, 0x86, 0x8E, 0x43, + 0xE6, 0x86, 0x90, 0x43, 0xE6, 0x86, 0xA4, 0x43, + 0xE6, 0x86, 0xAF, 0x43, 0xE6, 0x86, 0xB2, 0x43, + 0xE6, 0x87, 0x9E, 0x43, 0xE6, 0x87, 0xB2, 0x43, + 0xE6, 0x87, 0xB6, 0x43, 0xE6, 0x88, 0x80, 0x43, + 0xE6, 0x88, 0x88, 0x43, 0xE6, 0x88, 0x90, 0x43, + // Bytes c00 - c3f + 0xE6, 0x88, 0x9B, 0x43, 0xE6, 0x88, 0xAE, 0x43, + 0xE6, 0x88, 0xB4, 0x43, 0xE6, 0x88, 0xB6, 0x43, + 0xE6, 0x89, 0x8B, 0x43, 0xE6, 0x89, 0x93, 0x43, + 0xE6, 0x89, 0x9D, 0x43, 0xE6, 0x8A, 0x95, 0x43, + 0xE6, 0x8A, 0xB1, 0x43, 0xE6, 0x8B, 0x89, 0x43, + 0xE6, 0x8B, 0x8F, 0x43, 0xE6, 0x8B, 0x93, 0x43, + 0xE6, 0x8B, 0x94, 0x43, 0xE6, 0x8B, 0xBC, 0x43, + 0xE6, 0x8B, 0xBE, 0x43, 0xE6, 0x8C, 0x87, 0x43, + // Bytes c40 - c7f + 0xE6, 0x8C, 0xBD, 0x43, 0xE6, 0x8D, 0x90, 0x43, + 0xE6, 0x8D, 0x95, 0x43, 0xE6, 0x8D, 0xA8, 0x43, + 0xE6, 0x8D, 0xBB, 0x43, 0xE6, 0x8E, 0x83, 0x43, + 0xE6, 0x8E, 0xA0, 0x43, 0xE6, 0x8E, 0xA9, 0x43, + 0xE6, 0x8F, 0x84, 0x43, 0xE6, 0x8F, 0x85, 0x43, + 0xE6, 0x8F, 0xA4, 0x43, 0xE6, 0x90, 0x9C, 0x43, + 0xE6, 0x90, 0xA2, 0x43, 0xE6, 0x91, 0x92, 0x43, + 0xE6, 0x91, 0xA9, 0x43, 0xE6, 0x91, 0xB7, 0x43, + // Bytes c80 - cbf + 0xE6, 0x91, 0xBE, 0x43, 0xE6, 0x92, 0x9A, 0x43, + 0xE6, 0x92, 0x9D, 0x43, 0xE6, 0x93, 0x84, 0x43, + 0xE6, 0x94, 0xAF, 0x43, 0xE6, 0x94, 0xB4, 0x43, + 0xE6, 0x95, 0x8F, 0x43, 0xE6, 0x95, 0x96, 0x43, + 0xE6, 0x95, 0xAC, 0x43, 0xE6, 0x95, 0xB8, 0x43, + 0xE6, 0x96, 0x87, 0x43, 0xE6, 0x96, 0x97, 0x43, + 0xE6, 0x96, 0x99, 0x43, 0xE6, 0x96, 0xA4, 0x43, + 0xE6, 0x96, 0xB0, 0x43, 0xE6, 0x96, 0xB9, 0x43, + // Bytes cc0 - cff + 0xE6, 0x97, 0x85, 0x43, 0xE6, 0x97, 0xA0, 0x43, + 0xE6, 0x97, 0xA2, 0x43, 0xE6, 0x97, 0xA3, 0x43, + 0xE6, 0x97, 0xA5, 0x43, 0xE6, 0x98, 0x93, 0x43, + 0xE6, 0x98, 0xA0, 0x43, 0xE6, 0x99, 0x89, 0x43, + 0xE6, 0x99, 0xB4, 0x43, 0xE6, 0x9A, 0x88, 0x43, + 0xE6, 0x9A, 0x91, 0x43, 0xE6, 0x9A, 0x9C, 0x43, + 0xE6, 0x9A, 0xB4, 0x43, 0xE6, 0x9B, 0x86, 0x43, + 0xE6, 0x9B, 0xB0, 0x43, 0xE6, 0x9B, 0xB4, 0x43, + // Bytes d00 - d3f + 0xE6, 0x9B, 0xB8, 0x43, 0xE6, 0x9C, 0x80, 0x43, + 0xE6, 0x9C, 0x88, 0x43, 0xE6, 0x9C, 0x89, 0x43, + 0xE6, 0x9C, 0x97, 0x43, 0xE6, 0x9C, 0x9B, 0x43, + 0xE6, 0x9C, 0xA1, 0x43, 0xE6, 0x9C, 0xA8, 0x43, + 0xE6, 0x9D, 0x8E, 0x43, 0xE6, 0x9D, 0x93, 0x43, + 0xE6, 0x9D, 0x96, 0x43, 0xE6, 0x9D, 0x9E, 0x43, + 0xE6, 0x9D, 0xBB, 0x43, 0xE6, 0x9E, 0x85, 0x43, + 0xE6, 0x9E, 0x97, 0x43, 0xE6, 0x9F, 0xB3, 0x43, + // Bytes d40 - d7f + 0xE6, 0x9F, 0xBA, 0x43, 0xE6, 0xA0, 0x97, 0x43, + 0xE6, 0xA0, 0x9F, 0x43, 0xE6, 0xA0, 0xAA, 0x43, + 0xE6, 0xA1, 0x92, 0x43, 0xE6, 0xA2, 0x81, 0x43, + 0xE6, 0xA2, 0x85, 0x43, 0xE6, 0xA2, 0x8E, 0x43, + 0xE6, 0xA2, 0xA8, 0x43, 0xE6, 0xA4, 0x94, 0x43, + 0xE6, 0xA5, 0x82, 0x43, 0xE6, 0xA6, 0xA3, 0x43, + 0xE6, 0xA7, 0xAA, 0x43, 0xE6, 0xA8, 0x82, 0x43, + 0xE6, 0xA8, 0x93, 0x43, 0xE6, 0xAA, 0xA8, 0x43, + // Bytes d80 - dbf + 0xE6, 0xAB, 0x93, 0x43, 0xE6, 0xAB, 0x9B, 0x43, + 0xE6, 0xAC, 0x84, 0x43, 0xE6, 0xAC, 0xA0, 0x43, + 0xE6, 0xAC, 0xA1, 0x43, 0xE6, 0xAD, 0x94, 0x43, + 0xE6, 0xAD, 0xA2, 0x43, 0xE6, 0xAD, 0xA3, 0x43, + 0xE6, 0xAD, 0xB2, 0x43, 0xE6, 0xAD, 0xB7, 0x43, + 0xE6, 0xAD, 0xB9, 0x43, 0xE6, 0xAE, 0x9F, 0x43, + 0xE6, 0xAE, 0xAE, 0x43, 0xE6, 0xAE, 0xB3, 0x43, + 0xE6, 0xAE, 0xBA, 0x43, 0xE6, 0xAE, 0xBB, 0x43, + // Bytes dc0 - dff + 0xE6, 0xAF, 0x8B, 0x43, 0xE6, 0xAF, 0x8D, 0x43, + 0xE6, 0xAF, 0x94, 0x43, 0xE6, 0xAF, 0x9B, 0x43, + 0xE6, 0xB0, 0x8F, 0x43, 0xE6, 0xB0, 0x94, 0x43, + 0xE6, 0xB0, 0xB4, 0x43, 0xE6, 0xB1, 0x8E, 0x43, + 0xE6, 0xB1, 0xA7, 0x43, 0xE6, 0xB2, 0x88, 0x43, + 0xE6, 0xB2, 0xBF, 0x43, 0xE6, 0xB3, 0x8C, 0x43, + 0xE6, 0xB3, 0x8D, 0x43, 0xE6, 0xB3, 0xA5, 0x43, + 0xE6, 0xB3, 0xA8, 0x43, 0xE6, 0xB4, 0x96, 0x43, + // Bytes e00 - e3f + 0xE6, 0xB4, 0x9B, 0x43, 0xE6, 0xB4, 0x9E, 0x43, + 0xE6, 0xB4, 0xB4, 0x43, 0xE6, 0xB4, 0xBE, 0x43, + 0xE6, 0xB5, 0x81, 0x43, 0xE6, 0xB5, 0xA9, 0x43, + 0xE6, 0xB5, 0xAA, 0x43, 0xE6, 0xB5, 0xB7, 0x43, + 0xE6, 0xB5, 0xB8, 0x43, 0xE6, 0xB6, 0x85, 0x43, + 0xE6, 0xB7, 0x8B, 0x43, 0xE6, 0xB7, 0x9A, 0x43, + 0xE6, 0xB7, 0xAA, 0x43, 0xE6, 0xB7, 0xB9, 0x43, + 0xE6, 0xB8, 0x9A, 0x43, 0xE6, 0xB8, 0xAF, 0x43, + // Bytes e40 - e7f + 0xE6, 0xB9, 0xAE, 0x43, 0xE6, 0xBA, 0x80, 0x43, + 0xE6, 0xBA, 0x9C, 0x43, 0xE6, 0xBA, 0xBA, 0x43, + 0xE6, 0xBB, 0x87, 0x43, 0xE6, 0xBB, 0x8B, 0x43, + 0xE6, 0xBB, 0x91, 0x43, 0xE6, 0xBB, 0x9B, 0x43, + 0xE6, 0xBC, 0x8F, 0x43, 0xE6, 0xBC, 0x94, 0x43, + 0xE6, 0xBC, 0xA2, 0x43, 0xE6, 0xBC, 0xA3, 0x43, + 0xE6, 0xBD, 0xAE, 0x43, 0xE6, 0xBF, 0x86, 0x43, + 0xE6, 0xBF, 0xAB, 0x43, 0xE6, 0xBF, 0xBE, 0x43, + // Bytes e80 - ebf + 0xE7, 0x80, 0x9B, 0x43, 0xE7, 0x80, 0x9E, 0x43, + 0xE7, 0x80, 0xB9, 0x43, 0xE7, 0x81, 0x8A, 0x43, + 0xE7, 0x81, 0xAB, 0x43, 0xE7, 0x81, 0xB0, 0x43, + 0xE7, 0x81, 0xB7, 0x43, 0xE7, 0x81, 0xBD, 0x43, + 0xE7, 0x82, 0x99, 0x43, 0xE7, 0x82, 0xAD, 0x43, + 0xE7, 0x83, 0x88, 0x43, 0xE7, 0x83, 0x99, 0x43, + 0xE7, 0x84, 0xA1, 0x43, 0xE7, 0x85, 0x85, 0x43, + 0xE7, 0x85, 0x89, 0x43, 0xE7, 0x85, 0xAE, 0x43, + // Bytes ec0 - eff + 0xE7, 0x86, 0x9C, 0x43, 0xE7, 0x87, 0x8E, 0x43, + 0xE7, 0x87, 0x90, 0x43, 0xE7, 0x88, 0x90, 0x43, + 0xE7, 0x88, 0x9B, 0x43, 0xE7, 0x88, 0xA8, 0x43, + 0xE7, 0x88, 0xAA, 0x43, 0xE7, 0x88, 0xAB, 0x43, + 0xE7, 0x88, 0xB5, 0x43, 0xE7, 0x88, 0xB6, 0x43, + 0xE7, 0x88, 0xBB, 0x43, 0xE7, 0x88, 0xBF, 0x43, + 0xE7, 0x89, 0x87, 0x43, 0xE7, 0x89, 0x90, 0x43, + 0xE7, 0x89, 0x99, 0x43, 0xE7, 0x89, 0x9B, 0x43, + // Bytes f00 - f3f + 0xE7, 0x89, 0xA2, 0x43, 0xE7, 0x89, 0xB9, 0x43, + 0xE7, 0x8A, 0x80, 0x43, 0xE7, 0x8A, 0x95, 0x43, + 0xE7, 0x8A, 0xAC, 0x43, 0xE7, 0x8A, 0xAF, 0x43, + 0xE7, 0x8B, 0x80, 0x43, 0xE7, 0x8B, 0xBC, 0x43, + 0xE7, 0x8C, 0xAA, 0x43, 0xE7, 0x8D, 0xB5, 0x43, + 0xE7, 0x8D, 0xBA, 0x43, 0xE7, 0x8E, 0x84, 0x43, + 0xE7, 0x8E, 0x87, 0x43, 0xE7, 0x8E, 0x89, 0x43, + 0xE7, 0x8E, 0x8B, 0x43, 0xE7, 0x8E, 0xA5, 0x43, + // Bytes f40 - f7f + 0xE7, 0x8E, 0xB2, 0x43, 0xE7, 0x8F, 0x9E, 0x43, + 0xE7, 0x90, 0x86, 0x43, 0xE7, 0x90, 0x89, 0x43, + 0xE7, 0x90, 0xA2, 0x43, 0xE7, 0x91, 0x87, 0x43, + 0xE7, 0x91, 0x9C, 0x43, 0xE7, 0x91, 0xA9, 0x43, + 0xE7, 0x91, 0xB1, 0x43, 0xE7, 0x92, 0x85, 0x43, + 0xE7, 0x92, 0x89, 0x43, 0xE7, 0x92, 0x98, 0x43, + 0xE7, 0x93, 0x8A, 0x43, 0xE7, 0x93, 0x9C, 0x43, + 0xE7, 0x93, 0xA6, 0x43, 0xE7, 0x94, 0x86, 0x43, + // Bytes f80 - fbf + 0xE7, 0x94, 0x98, 0x43, 0xE7, 0x94, 0x9F, 0x43, + 0xE7, 0x94, 0xA4, 0x43, 0xE7, 0x94, 0xA8, 0x43, + 0xE7, 0x94, 0xB0, 0x43, 0xE7, 0x94, 0xB2, 0x43, + 0xE7, 0x94, 0xB3, 0x43, 0xE7, 0x94, 0xB7, 0x43, + 0xE7, 0x94, 0xBB, 0x43, 0xE7, 0x94, 0xBE, 0x43, + 0xE7, 0x95, 0x99, 0x43, 0xE7, 0x95, 0xA5, 0x43, + 0xE7, 0x95, 0xB0, 0x43, 0xE7, 0x96, 0x8B, 0x43, + 0xE7, 0x96, 0x92, 0x43, 0xE7, 0x97, 0xA2, 0x43, + // Bytes fc0 - fff + 0xE7, 0x98, 0x90, 0x43, 0xE7, 0x98, 0x9D, 0x43, + 0xE7, 0x98, 0x9F, 0x43, 0xE7, 0x99, 0x82, 0x43, + 0xE7, 0x99, 0xA9, 0x43, 0xE7, 0x99, 0xB6, 0x43, + 0xE7, 0x99, 0xBD, 0x43, 0xE7, 0x9A, 0xAE, 0x43, + 0xE7, 0x9A, 0xBF, 0x43, 0xE7, 0x9B, 0x8A, 0x43, + 0xE7, 0x9B, 0x9B, 0x43, 0xE7, 0x9B, 0xA3, 0x43, + 0xE7, 0x9B, 0xA7, 0x43, 0xE7, 0x9B, 0xAE, 0x43, + 0xE7, 0x9B, 0xB4, 0x43, 0xE7, 0x9C, 0x81, 0x43, + // Bytes 1000 - 103f + 0xE7, 0x9C, 0x9E, 0x43, 0xE7, 0x9C, 0x9F, 0x43, + 0xE7, 0x9D, 0x80, 0x43, 0xE7, 0x9D, 0x8A, 0x43, + 0xE7, 0x9E, 0x8B, 0x43, 0xE7, 0x9E, 0xA7, 0x43, + 0xE7, 0x9F, 0x9B, 0x43, 0xE7, 0x9F, 0xA2, 0x43, + 0xE7, 0x9F, 0xB3, 0x43, 0xE7, 0xA1, 0x8E, 0x43, + 0xE7, 0xA1, 0xAB, 0x43, 0xE7, 0xA2, 0x8C, 0x43, + 0xE7, 0xA2, 0x91, 0x43, 0xE7, 0xA3, 0x8A, 0x43, + 0xE7, 0xA3, 0x8C, 0x43, 0xE7, 0xA3, 0xBB, 0x43, + // Bytes 1040 - 107f + 0xE7, 0xA4, 0xAA, 0x43, 0xE7, 0xA4, 0xBA, 0x43, + 0xE7, 0xA4, 0xBC, 0x43, 0xE7, 0xA4, 0xBE, 0x43, + 0xE7, 0xA5, 0x88, 0x43, 0xE7, 0xA5, 0x89, 0x43, + 0xE7, 0xA5, 0x90, 0x43, 0xE7, 0xA5, 0x96, 0x43, + 0xE7, 0xA5, 0x9D, 0x43, 0xE7, 0xA5, 0x9E, 0x43, + 0xE7, 0xA5, 0xA5, 0x43, 0xE7, 0xA5, 0xBF, 0x43, + 0xE7, 0xA6, 0x81, 0x43, 0xE7, 0xA6, 0x8D, 0x43, + 0xE7, 0xA6, 0x8E, 0x43, 0xE7, 0xA6, 0x8F, 0x43, + // Bytes 1080 - 10bf + 0xE7, 0xA6, 0xAE, 0x43, 0xE7, 0xA6, 0xB8, 0x43, + 0xE7, 0xA6, 0xBE, 0x43, 0xE7, 0xA7, 0x8A, 0x43, + 0xE7, 0xA7, 0x98, 0x43, 0xE7, 0xA7, 0xAB, 0x43, + 0xE7, 0xA8, 0x9C, 0x43, 0xE7, 0xA9, 0x80, 0x43, + 0xE7, 0xA9, 0x8A, 0x43, 0xE7, 0xA9, 0x8F, 0x43, + 0xE7, 0xA9, 0xB4, 0x43, 0xE7, 0xA9, 0xBA, 0x43, + 0xE7, 0xAA, 0x81, 0x43, 0xE7, 0xAA, 0xB1, 0x43, + 0xE7, 0xAB, 0x8B, 0x43, 0xE7, 0xAB, 0xAE, 0x43, + // Bytes 10c0 - 10ff + 0xE7, 0xAB, 0xB9, 0x43, 0xE7, 0xAC, 0xA0, 0x43, + 0xE7, 0xAE, 0x8F, 0x43, 0xE7, 0xAF, 0x80, 0x43, + 0xE7, 0xAF, 0x86, 0x43, 0xE7, 0xAF, 0x89, 0x43, + 0xE7, 0xB0, 0xBE, 0x43, 0xE7, 0xB1, 0xA0, 0x43, + 0xE7, 0xB1, 0xB3, 0x43, 0xE7, 0xB1, 0xBB, 0x43, + 0xE7, 0xB2, 0x92, 0x43, 0xE7, 0xB2, 0xBE, 0x43, + 0xE7, 0xB3, 0x92, 0x43, 0xE7, 0xB3, 0x96, 0x43, + 0xE7, 0xB3, 0xA3, 0x43, 0xE7, 0xB3, 0xA7, 0x43, + // Bytes 1100 - 113f + 0xE7, 0xB3, 0xA8, 0x43, 0xE7, 0xB3, 0xB8, 0x43, + 0xE7, 0xB4, 0x80, 0x43, 0xE7, 0xB4, 0x90, 0x43, + 0xE7, 0xB4, 0xA2, 0x43, 0xE7, 0xB4, 0xAF, 0x43, + 0xE7, 0xB5, 0x82, 0x43, 0xE7, 0xB5, 0x9B, 0x43, + 0xE7, 0xB5, 0xA3, 0x43, 0xE7, 0xB6, 0xA0, 0x43, + 0xE7, 0xB6, 0xBE, 0x43, 0xE7, 0xB7, 0x87, 0x43, + 0xE7, 0xB7, 0xB4, 0x43, 0xE7, 0xB8, 0x82, 0x43, + 0xE7, 0xB8, 0x89, 0x43, 0xE7, 0xB8, 0xB7, 0x43, + // Bytes 1140 - 117f + 0xE7, 0xB9, 0x81, 0x43, 0xE7, 0xB9, 0x85, 0x43, + 0xE7, 0xBC, 0xB6, 0x43, 0xE7, 0xBC, 0xBE, 0x43, + 0xE7, 0xBD, 0x91, 0x43, 0xE7, 0xBD, 0xB2, 0x43, + 0xE7, 0xBD, 0xB9, 0x43, 0xE7, 0xBD, 0xBA, 0x43, + 0xE7, 0xBE, 0x85, 0x43, 0xE7, 0xBE, 0x8A, 0x43, + 0xE7, 0xBE, 0x95, 0x43, 0xE7, 0xBE, 0x9A, 0x43, + 0xE7, 0xBE, 0xBD, 0x43, 0xE7, 0xBF, 0xBA, 0x43, + 0xE8, 0x80, 0x81, 0x43, 0xE8, 0x80, 0x85, 0x43, + // Bytes 1180 - 11bf + 0xE8, 0x80, 0x8C, 0x43, 0xE8, 0x80, 0x92, 0x43, + 0xE8, 0x80, 0xB3, 0x43, 0xE8, 0x81, 0x86, 0x43, + 0xE8, 0x81, 0xA0, 0x43, 0xE8, 0x81, 0xAF, 0x43, + 0xE8, 0x81, 0xB0, 0x43, 0xE8, 0x81, 0xBE, 0x43, + 0xE8, 0x81, 0xBF, 0x43, 0xE8, 0x82, 0x89, 0x43, + 0xE8, 0x82, 0x8B, 0x43, 0xE8, 0x82, 0xAD, 0x43, + 0xE8, 0x82, 0xB2, 0x43, 0xE8, 0x84, 0x83, 0x43, + 0xE8, 0x84, 0xBE, 0x43, 0xE8, 0x87, 0x98, 0x43, + // Bytes 11c0 - 11ff + 0xE8, 0x87, 0xA3, 0x43, 0xE8, 0x87, 0xA8, 0x43, + 0xE8, 0x87, 0xAA, 0x43, 0xE8, 0x87, 0xAD, 0x43, + 0xE8, 0x87, 0xB3, 0x43, 0xE8, 0x87, 0xBC, 0x43, + 0xE8, 0x88, 0x81, 0x43, 0xE8, 0x88, 0x84, 0x43, + 0xE8, 0x88, 0x8C, 0x43, 0xE8, 0x88, 0x98, 0x43, + 0xE8, 0x88, 0x9B, 0x43, 0xE8, 0x88, 0x9F, 0x43, + 0xE8, 0x89, 0xAE, 0x43, 0xE8, 0x89, 0xAF, 0x43, + 0xE8, 0x89, 0xB2, 0x43, 0xE8, 0x89, 0xB8, 0x43, + // Bytes 1200 - 123f + 0xE8, 0x89, 0xB9, 0x43, 0xE8, 0x8A, 0x8B, 0x43, + 0xE8, 0x8A, 0x91, 0x43, 0xE8, 0x8A, 0x9D, 0x43, + 0xE8, 0x8A, 0xB1, 0x43, 0xE8, 0x8A, 0xB3, 0x43, + 0xE8, 0x8A, 0xBD, 0x43, 0xE8, 0x8B, 0xA5, 0x43, + 0xE8, 0x8B, 0xA6, 0x43, 0xE8, 0x8C, 0x9D, 0x43, + 0xE8, 0x8C, 0xA3, 0x43, 0xE8, 0x8C, 0xB6, 0x43, + 0xE8, 0x8D, 0x92, 0x43, 0xE8, 0x8D, 0x93, 0x43, + 0xE8, 0x8D, 0xA3, 0x43, 0xE8, 0x8E, 0xAD, 0x43, + // Bytes 1240 - 127f + 0xE8, 0x8E, 0xBD, 0x43, 0xE8, 0x8F, 0x89, 0x43, + 0xE8, 0x8F, 0x8A, 0x43, 0xE8, 0x8F, 0x8C, 0x43, + 0xE8, 0x8F, 0x9C, 0x43, 0xE8, 0x8F, 0xA7, 0x43, + 0xE8, 0x8F, 0xAF, 0x43, 0xE8, 0x8F, 0xB1, 0x43, + 0xE8, 0x90, 0xBD, 0x43, 0xE8, 0x91, 0x89, 0x43, + 0xE8, 0x91, 0x97, 0x43, 0xE8, 0x93, 0xAE, 0x43, + 0xE8, 0x93, 0xB1, 0x43, 0xE8, 0x93, 0xB3, 0x43, + 0xE8, 0x93, 0xBC, 0x43, 0xE8, 0x94, 0x96, 0x43, + // Bytes 1280 - 12bf + 0xE8, 0x95, 0xA4, 0x43, 0xE8, 0x97, 0x8D, 0x43, + 0xE8, 0x97, 0xBA, 0x43, 0xE8, 0x98, 0x86, 0x43, + 0xE8, 0x98, 0x92, 0x43, 0xE8, 0x98, 0xAD, 0x43, + 0xE8, 0x98, 0xBF, 0x43, 0xE8, 0x99, 0x8D, 0x43, + 0xE8, 0x99, 0x90, 0x43, 0xE8, 0x99, 0x9C, 0x43, + 0xE8, 0x99, 0xA7, 0x43, 0xE8, 0x99, 0xA9, 0x43, + 0xE8, 0x99, 0xAB, 0x43, 0xE8, 0x9A, 0x88, 0x43, + 0xE8, 0x9A, 0xA9, 0x43, 0xE8, 0x9B, 0xA2, 0x43, + // Bytes 12c0 - 12ff + 0xE8, 0x9C, 0x8E, 0x43, 0xE8, 0x9C, 0xA8, 0x43, + 0xE8, 0x9D, 0xAB, 0x43, 0xE8, 0x9D, 0xB9, 0x43, + 0xE8, 0x9E, 0x86, 0x43, 0xE8, 0x9E, 0xBA, 0x43, + 0xE8, 0x9F, 0xA1, 0x43, 0xE8, 0xA0, 0x81, 0x43, + 0xE8, 0xA0, 0x9F, 0x43, 0xE8, 0xA1, 0x80, 0x43, + 0xE8, 0xA1, 0x8C, 0x43, 0xE8, 0xA1, 0xA0, 0x43, + 0xE8, 0xA1, 0xA3, 0x43, 0xE8, 0xA3, 0x82, 0x43, + 0xE8, 0xA3, 0x8F, 0x43, 0xE8, 0xA3, 0x97, 0x43, + // Bytes 1300 - 133f + 0xE8, 0xA3, 0x9E, 0x43, 0xE8, 0xA3, 0xA1, 0x43, + 0xE8, 0xA3, 0xB8, 0x43, 0xE8, 0xA3, 0xBA, 0x43, + 0xE8, 0xA4, 0x90, 0x43, 0xE8, 0xA5, 0x81, 0x43, + 0xE8, 0xA5, 0xA4, 0x43, 0xE8, 0xA5, 0xBE, 0x43, + 0xE8, 0xA6, 0x86, 0x43, 0xE8, 0xA6, 0x8B, 0x43, + 0xE8, 0xA6, 0x96, 0x43, 0xE8, 0xA7, 0x92, 0x43, + 0xE8, 0xA7, 0xA3, 0x43, 0xE8, 0xA8, 0x80, 0x43, + 0xE8, 0xAA, 0xA0, 0x43, 0xE8, 0xAA, 0xAA, 0x43, + // Bytes 1340 - 137f + 0xE8, 0xAA, 0xBF, 0x43, 0xE8, 0xAB, 0x8B, 0x43, + 0xE8, 0xAB, 0x92, 0x43, 0xE8, 0xAB, 0x96, 0x43, + 0xE8, 0xAB, 0xAD, 0x43, 0xE8, 0xAB, 0xB8, 0x43, + 0xE8, 0xAB, 0xBE, 0x43, 0xE8, 0xAC, 0x81, 0x43, + 0xE8, 0xAC, 0xB9, 0x43, 0xE8, 0xAD, 0x98, 0x43, + 0xE8, 0xAE, 0x80, 0x43, 0xE8, 0xAE, 0x8A, 0x43, + 0xE8, 0xB0, 0xB7, 0x43, 0xE8, 0xB1, 0x86, 0x43, + 0xE8, 0xB1, 0x88, 0x43, 0xE8, 0xB1, 0x95, 0x43, + // Bytes 1380 - 13bf + 0xE8, 0xB1, 0xB8, 0x43, 0xE8, 0xB2, 0x9D, 0x43, + 0xE8, 0xB2, 0xA1, 0x43, 0xE8, 0xB2, 0xA9, 0x43, + 0xE8, 0xB2, 0xAB, 0x43, 0xE8, 0xB3, 0x81, 0x43, + 0xE8, 0xB3, 0x82, 0x43, 0xE8, 0xB3, 0x87, 0x43, + 0xE8, 0xB3, 0x88, 0x43, 0xE8, 0xB3, 0x93, 0x43, + 0xE8, 0xB4, 0x88, 0x43, 0xE8, 0xB4, 0x9B, 0x43, + 0xE8, 0xB5, 0xA4, 0x43, 0xE8, 0xB5, 0xB0, 0x43, + 0xE8, 0xB5, 0xB7, 0x43, 0xE8, 0xB6, 0xB3, 0x43, + // Bytes 13c0 - 13ff + 0xE8, 0xB6, 0xBC, 0x43, 0xE8, 0xB7, 0x8B, 0x43, + 0xE8, 0xB7, 0xAF, 0x43, 0xE8, 0xB7, 0xB0, 0x43, + 0xE8, 0xBA, 0xAB, 0x43, 0xE8, 0xBB, 0x8A, 0x43, + 0xE8, 0xBB, 0x94, 0x43, 0xE8, 0xBC, 0xA6, 0x43, + 0xE8, 0xBC, 0xAA, 0x43, 0xE8, 0xBC, 0xB8, 0x43, + 0xE8, 0xBC, 0xBB, 0x43, 0xE8, 0xBD, 0xA2, 0x43, + 0xE8, 0xBE, 0x9B, 0x43, 0xE8, 0xBE, 0x9E, 0x43, + 0xE8, 0xBE, 0xB0, 0x43, 0xE8, 0xBE, 0xB5, 0x43, + // Bytes 1400 - 143f + 0xE8, 0xBE, 0xB6, 0x43, 0xE9, 0x80, 0xA3, 0x43, + 0xE9, 0x80, 0xB8, 0x43, 0xE9, 0x81, 0x8A, 0x43, + 0xE9, 0x81, 0xA9, 0x43, 0xE9, 0x81, 0xB2, 0x43, + 0xE9, 0x81, 0xBC, 0x43, 0xE9, 0x82, 0x8F, 0x43, + 0xE9, 0x82, 0x91, 0x43, 0xE9, 0x82, 0x94, 0x43, + 0xE9, 0x83, 0x8E, 0x43, 0xE9, 0x83, 0x9E, 0x43, + 0xE9, 0x83, 0xB1, 0x43, 0xE9, 0x83, 0xBD, 0x43, + 0xE9, 0x84, 0x91, 0x43, 0xE9, 0x84, 0x9B, 0x43, + // Bytes 1440 - 147f + 0xE9, 0x85, 0x89, 0x43, 0xE9, 0x85, 0x8D, 0x43, + 0xE9, 0x85, 0xAA, 0x43, 0xE9, 0x86, 0x99, 0x43, + 0xE9, 0x86, 0xB4, 0x43, 0xE9, 0x87, 0x86, 0x43, + 0xE9, 0x87, 0x8C, 0x43, 0xE9, 0x87, 0x8F, 0x43, + 0xE9, 0x87, 0x91, 0x43, 0xE9, 0x88, 0xB4, 0x43, + 0xE9, 0x88, 0xB8, 0x43, 0xE9, 0x89, 0xB6, 0x43, + 0xE9, 0x89, 0xBC, 0x43, 0xE9, 0x8B, 0x97, 0x43, + 0xE9, 0x8B, 0x98, 0x43, 0xE9, 0x8C, 0x84, 0x43, + // Bytes 1480 - 14bf + 0xE9, 0x8D, 0x8A, 0x43, 0xE9, 0x8F, 0xB9, 0x43, + 0xE9, 0x90, 0x95, 0x43, 0xE9, 0x95, 0xB7, 0x43, + 0xE9, 0x96, 0x80, 0x43, 0xE9, 0x96, 0x8B, 0x43, + 0xE9, 0x96, 0xAD, 0x43, 0xE9, 0x96, 0xB7, 0x43, + 0xE9, 0x98, 0x9C, 0x43, 0xE9, 0x98, 0xAE, 0x43, + 0xE9, 0x99, 0x8B, 0x43, 0xE9, 0x99, 0x8D, 0x43, + 0xE9, 0x99, 0xB5, 0x43, 0xE9, 0x99, 0xB8, 0x43, + 0xE9, 0x99, 0xBC, 0x43, 0xE9, 0x9A, 0x86, 0x43, + // Bytes 14c0 - 14ff + 0xE9, 0x9A, 0xA3, 0x43, 0xE9, 0x9A, 0xB6, 0x43, + 0xE9, 0x9A, 0xB7, 0x43, 0xE9, 0x9A, 0xB8, 0x43, + 0xE9, 0x9A, 0xB9, 0x43, 0xE9, 0x9B, 0x83, 0x43, + 0xE9, 0x9B, 0xA2, 0x43, 0xE9, 0x9B, 0xA3, 0x43, + 0xE9, 0x9B, 0xA8, 0x43, 0xE9, 0x9B, 0xB6, 0x43, + 0xE9, 0x9B, 0xB7, 0x43, 0xE9, 0x9C, 0xA3, 0x43, + 0xE9, 0x9C, 0xB2, 0x43, 0xE9, 0x9D, 0x88, 0x43, + 0xE9, 0x9D, 0x91, 0x43, 0xE9, 0x9D, 0x96, 0x43, + // Bytes 1500 - 153f + 0xE9, 0x9D, 0x9E, 0x43, 0xE9, 0x9D, 0xA2, 0x43, + 0xE9, 0x9D, 0xA9, 0x43, 0xE9, 0x9F, 0x8B, 0x43, + 0xE9, 0x9F, 0x9B, 0x43, 0xE9, 0x9F, 0xA0, 0x43, + 0xE9, 0x9F, 0xAD, 0x43, 0xE9, 0x9F, 0xB3, 0x43, + 0xE9, 0x9F, 0xBF, 0x43, 0xE9, 0xA0, 0x81, 0x43, + 0xE9, 0xA0, 0x85, 0x43, 0xE9, 0xA0, 0x8B, 0x43, + 0xE9, 0xA0, 0x98, 0x43, 0xE9, 0xA0, 0xA9, 0x43, + 0xE9, 0xA0, 0xBB, 0x43, 0xE9, 0xA1, 0x9E, 0x43, + // Bytes 1540 - 157f + 0xE9, 0xA2, 0xA8, 0x43, 0xE9, 0xA3, 0x9B, 0x43, + 0xE9, 0xA3, 0x9F, 0x43, 0xE9, 0xA3, 0xA2, 0x43, + 0xE9, 0xA3, 0xAF, 0x43, 0xE9, 0xA3, 0xBC, 0x43, + 0xE9, 0xA4, 0xA8, 0x43, 0xE9, 0xA4, 0xA9, 0x43, + 0xE9, 0xA6, 0x96, 0x43, 0xE9, 0xA6, 0x99, 0x43, + 0xE9, 0xA6, 0xA7, 0x43, 0xE9, 0xA6, 0xAC, 0x43, + 0xE9, 0xA7, 0x82, 0x43, 0xE9, 0xA7, 0xB1, 0x43, + 0xE9, 0xA7, 0xBE, 0x43, 0xE9, 0xA9, 0xAA, 0x43, + // Bytes 1580 - 15bf + 0xE9, 0xAA, 0xA8, 0x43, 0xE9, 0xAB, 0x98, 0x43, + 0xE9, 0xAB, 0x9F, 0x43, 0xE9, 0xAC, 0x92, 0x43, + 0xE9, 0xAC, 0xA5, 0x43, 0xE9, 0xAC, 0xAF, 0x43, + 0xE9, 0xAC, 0xB2, 0x43, 0xE9, 0xAC, 0xBC, 0x43, + 0xE9, 0xAD, 0x9A, 0x43, 0xE9, 0xAD, 0xAF, 0x43, + 0xE9, 0xB1, 0x80, 0x43, 0xE9, 0xB1, 0x97, 0x43, + 0xE9, 0xB3, 0xA5, 0x43, 0xE9, 0xB3, 0xBD, 0x43, + 0xE9, 0xB5, 0xA7, 0x43, 0xE9, 0xB6, 0xB4, 0x43, + // Bytes 15c0 - 15ff + 0xE9, 0xB7, 0xBA, 0x43, 0xE9, 0xB8, 0x9E, 0x43, + 0xE9, 0xB9, 0xB5, 0x43, 0xE9, 0xB9, 0xBF, 0x43, + 0xE9, 0xBA, 0x97, 0x43, 0xE9, 0xBA, 0x9F, 0x43, + 0xE9, 0xBA, 0xA5, 0x43, 0xE9, 0xBA, 0xBB, 0x43, + 0xE9, 0xBB, 0x83, 0x43, 0xE9, 0xBB, 0x8D, 0x43, + 0xE9, 0xBB, 0x8E, 0x43, 0xE9, 0xBB, 0x91, 0x43, + 0xE9, 0xBB, 0xB9, 0x43, 0xE9, 0xBB, 0xBD, 0x43, + 0xE9, 0xBB, 0xBE, 0x43, 0xE9, 0xBC, 0x85, 0x43, + // Bytes 1600 - 163f + 0xE9, 0xBC, 0x8E, 0x43, 0xE9, 0xBC, 0x8F, 0x43, + 0xE9, 0xBC, 0x93, 0x43, 0xE9, 0xBC, 0x96, 0x43, + 0xE9, 0xBC, 0xA0, 0x43, 0xE9, 0xBC, 0xBB, 0x43, + 0xE9, 0xBD, 0x83, 0x43, 0xE9, 0xBD, 0x8A, 0x43, + 0xE9, 0xBD, 0x92, 0x43, 0xE9, 0xBE, 0x8D, 0x43, + 0xE9, 0xBE, 0x8E, 0x43, 0xE9, 0xBE, 0x9C, 0x43, + 0xE9, 0xBE, 0x9F, 0x43, 0xE9, 0xBE, 0xA0, 0x43, + 0xEA, 0x9C, 0xA7, 0x43, 0xEA, 0x9D, 0xAF, 0x43, + // Bytes 1640 - 167f + 0xEA, 0xAC, 0xB7, 0x43, 0xEA, 0xAD, 0x92, 0x44, + 0xF0, 0xA0, 0x84, 0xA2, 0x44, 0xF0, 0xA0, 0x94, + 0x9C, 0x44, 0xF0, 0xA0, 0x94, 0xA5, 0x44, 0xF0, + 0xA0, 0x95, 0x8B, 0x44, 0xF0, 0xA0, 0x98, 0xBA, + 0x44, 0xF0, 0xA0, 0xA0, 0x84, 0x44, 0xF0, 0xA0, + 0xA3, 0x9E, 0x44, 0xF0, 0xA0, 0xA8, 0xAC, 0x44, + 0xF0, 0xA0, 0xAD, 0xA3, 0x44, 0xF0, 0xA1, 0x93, + 0xA4, 0x44, 0xF0, 0xA1, 0x9A, 0xA8, 0x44, 0xF0, + // Bytes 1680 - 16bf + 0xA1, 0x9B, 0xAA, 0x44, 0xF0, 0xA1, 0xA7, 0x88, + 0x44, 0xF0, 0xA1, 0xAC, 0x98, 0x44, 0xF0, 0xA1, + 0xB4, 0x8B, 0x44, 0xF0, 0xA1, 0xB7, 0xA4, 0x44, + 0xF0, 0xA1, 0xB7, 0xA6, 0x44, 0xF0, 0xA2, 0x86, + 0x83, 0x44, 0xF0, 0xA2, 0x86, 0x9F, 0x44, 0xF0, + 0xA2, 0x8C, 0xB1, 0x44, 0xF0, 0xA2, 0x9B, 0x94, + 0x44, 0xF0, 0xA2, 0xA1, 0x84, 0x44, 0xF0, 0xA2, + 0xA1, 0x8A, 0x44, 0xF0, 0xA2, 0xAC, 0x8C, 0x44, + // Bytes 16c0 - 16ff + 0xF0, 0xA2, 0xAF, 0xB1, 0x44, 0xF0, 0xA3, 0x80, + 0x8A, 0x44, 0xF0, 0xA3, 0x8A, 0xB8, 0x44, 0xF0, + 0xA3, 0x8D, 0x9F, 0x44, 0xF0, 0xA3, 0x8E, 0x93, + 0x44, 0xF0, 0xA3, 0x8E, 0x9C, 0x44, 0xF0, 0xA3, + 0x8F, 0x83, 0x44, 0xF0, 0xA3, 0x8F, 0x95, 0x44, + 0xF0, 0xA3, 0x91, 0xAD, 0x44, 0xF0, 0xA3, 0x9A, + 0xA3, 0x44, 0xF0, 0xA3, 0xA2, 0xA7, 0x44, 0xF0, + 0xA3, 0xAA, 0x8D, 0x44, 0xF0, 0xA3, 0xAB, 0xBA, + // Bytes 1700 - 173f + 0x44, 0xF0, 0xA3, 0xB2, 0xBC, 0x44, 0xF0, 0xA3, + 0xB4, 0x9E, 0x44, 0xF0, 0xA3, 0xBB, 0x91, 0x44, + 0xF0, 0xA3, 0xBD, 0x9E, 0x44, 0xF0, 0xA3, 0xBE, + 0x8E, 0x44, 0xF0, 0xA4, 0x89, 0xA3, 0x44, 0xF0, + 0xA4, 0x8B, 0xAE, 0x44, 0xF0, 0xA4, 0x8E, 0xAB, + 0x44, 0xF0, 0xA4, 0x98, 0x88, 0x44, 0xF0, 0xA4, + 0x9C, 0xB5, 0x44, 0xF0, 0xA4, 0xA0, 0x94, 0x44, + 0xF0, 0xA4, 0xB0, 0xB6, 0x44, 0xF0, 0xA4, 0xB2, + // Bytes 1740 - 177f + 0x92, 0x44, 0xF0, 0xA4, 0xBE, 0xA1, 0x44, 0xF0, + 0xA4, 0xBE, 0xB8, 0x44, 0xF0, 0xA5, 0x81, 0x84, + 0x44, 0xF0, 0xA5, 0x83, 0xB2, 0x44, 0xF0, 0xA5, + 0x83, 0xB3, 0x44, 0xF0, 0xA5, 0x84, 0x99, 0x44, + 0xF0, 0xA5, 0x84, 0xB3, 0x44, 0xF0, 0xA5, 0x89, + 0x89, 0x44, 0xF0, 0xA5, 0x90, 0x9D, 0x44, 0xF0, + 0xA5, 0x98, 0xA6, 0x44, 0xF0, 0xA5, 0x9A, 0x9A, + 0x44, 0xF0, 0xA5, 0x9B, 0x85, 0x44, 0xF0, 0xA5, + // Bytes 1780 - 17bf + 0xA5, 0xBC, 0x44, 0xF0, 0xA5, 0xAA, 0xA7, 0x44, + 0xF0, 0xA5, 0xAE, 0xAB, 0x44, 0xF0, 0xA5, 0xB2, + 0x80, 0x44, 0xF0, 0xA5, 0xB3, 0x90, 0x44, 0xF0, + 0xA5, 0xBE, 0x86, 0x44, 0xF0, 0xA6, 0x87, 0x9A, + 0x44, 0xF0, 0xA6, 0x88, 0xA8, 0x44, 0xF0, 0xA6, + 0x89, 0x87, 0x44, 0xF0, 0xA6, 0x8B, 0x99, 0x44, + 0xF0, 0xA6, 0x8C, 0xBE, 0x44, 0xF0, 0xA6, 0x93, + 0x9A, 0x44, 0xF0, 0xA6, 0x94, 0xA3, 0x44, 0xF0, + // Bytes 17c0 - 17ff + 0xA6, 0x96, 0xA8, 0x44, 0xF0, 0xA6, 0x9E, 0xA7, + 0x44, 0xF0, 0xA6, 0x9E, 0xB5, 0x44, 0xF0, 0xA6, + 0xAC, 0xBC, 0x44, 0xF0, 0xA6, 0xB0, 0xB6, 0x44, + 0xF0, 0xA6, 0xB3, 0x95, 0x44, 0xF0, 0xA6, 0xB5, + 0xAB, 0x44, 0xF0, 0xA6, 0xBC, 0xAC, 0x44, 0xF0, + 0xA6, 0xBE, 0xB1, 0x44, 0xF0, 0xA7, 0x83, 0x92, + 0x44, 0xF0, 0xA7, 0x8F, 0x8A, 0x44, 0xF0, 0xA7, + 0x99, 0xA7, 0x44, 0xF0, 0xA7, 0xA2, 0xAE, 0x44, + // Bytes 1800 - 183f + 0xF0, 0xA7, 0xA5, 0xA6, 0x44, 0xF0, 0xA7, 0xB2, + 0xA8, 0x44, 0xF0, 0xA7, 0xBB, 0x93, 0x44, 0xF0, + 0xA7, 0xBC, 0xAF, 0x44, 0xF0, 0xA8, 0x97, 0x92, + 0x44, 0xF0, 0xA8, 0x97, 0xAD, 0x44, 0xF0, 0xA8, + 0x9C, 0xAE, 0x44, 0xF0, 0xA8, 0xAF, 0xBA, 0x44, + 0xF0, 0xA8, 0xB5, 0xB7, 0x44, 0xF0, 0xA9, 0x85, + 0x85, 0x44, 0xF0, 0xA9, 0x87, 0x9F, 0x44, 0xF0, + 0xA9, 0x88, 0x9A, 0x44, 0xF0, 0xA9, 0x90, 0x8A, + // Bytes 1840 - 187f + 0x44, 0xF0, 0xA9, 0x92, 0x96, 0x44, 0xF0, 0xA9, + 0x96, 0xB6, 0x44, 0xF0, 0xA9, 0xAC, 0xB0, 0x44, + 0xF0, 0xAA, 0x83, 0x8E, 0x44, 0xF0, 0xAA, 0x84, + 0x85, 0x44, 0xF0, 0xAA, 0x88, 0x8E, 0x44, 0xF0, + 0xAA, 0x8A, 0x91, 0x44, 0xF0, 0xAA, 0x8E, 0x92, + 0x44, 0xF0, 0xAA, 0x98, 0x80, 0x42, 0x21, 0x21, + 0x42, 0x21, 0x3F, 0x42, 0x2E, 0x2E, 0x42, 0x30, + 0x2C, 0x42, 0x30, 0x2E, 0x42, 0x31, 0x2C, 0x42, + // Bytes 1880 - 18bf + 0x31, 0x2E, 0x42, 0x31, 0x30, 0x42, 0x31, 0x31, + 0x42, 0x31, 0x32, 0x42, 0x31, 0x33, 0x42, 0x31, + 0x34, 0x42, 0x31, 0x35, 0x42, 0x31, 0x36, 0x42, + 0x31, 0x37, 0x42, 0x31, 0x38, 0x42, 0x31, 0x39, + 0x42, 0x32, 0x2C, 0x42, 0x32, 0x2E, 0x42, 0x32, + 0x30, 0x42, 0x32, 0x31, 0x42, 0x32, 0x32, 0x42, + 0x32, 0x33, 0x42, 0x32, 0x34, 0x42, 0x32, 0x35, + 0x42, 0x32, 0x36, 0x42, 0x32, 0x37, 0x42, 0x32, + // Bytes 18c0 - 18ff + 0x38, 0x42, 0x32, 0x39, 0x42, 0x33, 0x2C, 0x42, + 0x33, 0x2E, 0x42, 0x33, 0x30, 0x42, 0x33, 0x31, + 0x42, 0x33, 0x32, 0x42, 0x33, 0x33, 0x42, 0x33, + 0x34, 0x42, 0x33, 0x35, 0x42, 0x33, 0x36, 0x42, + 0x33, 0x37, 0x42, 0x33, 0x38, 0x42, 0x33, 0x39, + 0x42, 0x34, 0x2C, 0x42, 0x34, 0x2E, 0x42, 0x34, + 0x30, 0x42, 0x34, 0x31, 0x42, 0x34, 0x32, 0x42, + 0x34, 0x33, 0x42, 0x34, 0x34, 0x42, 0x34, 0x35, + // Bytes 1900 - 193f + 0x42, 0x34, 0x36, 0x42, 0x34, 0x37, 0x42, 0x34, + 0x38, 0x42, 0x34, 0x39, 0x42, 0x35, 0x2C, 0x42, + 0x35, 0x2E, 0x42, 0x35, 0x30, 0x42, 0x36, 0x2C, + 0x42, 0x36, 0x2E, 0x42, 0x37, 0x2C, 0x42, 0x37, + 0x2E, 0x42, 0x38, 0x2C, 0x42, 0x38, 0x2E, 0x42, + 0x39, 0x2C, 0x42, 0x39, 0x2E, 0x42, 0x3D, 0x3D, + 0x42, 0x3F, 0x21, 0x42, 0x3F, 0x3F, 0x42, 0x41, + 0x55, 0x42, 0x42, 0x71, 0x42, 0x43, 0x44, 0x42, + // Bytes 1940 - 197f + 0x44, 0x4A, 0x42, 0x44, 0x5A, 0x42, 0x44, 0x7A, + 0x42, 0x47, 0x42, 0x42, 0x47, 0x79, 0x42, 0x48, + 0x50, 0x42, 0x48, 0x56, 0x42, 0x48, 0x67, 0x42, + 0x48, 0x7A, 0x42, 0x49, 0x49, 0x42, 0x49, 0x4A, + 0x42, 0x49, 0x55, 0x42, 0x49, 0x56, 0x42, 0x49, + 0x58, 0x42, 0x4B, 0x42, 0x42, 0x4B, 0x4B, 0x42, + 0x4B, 0x4D, 0x42, 0x4C, 0x4A, 0x42, 0x4C, 0x6A, + 0x42, 0x4D, 0x42, 0x42, 0x4D, 0x43, 0x42, 0x4D, + // Bytes 1980 - 19bf + 0x44, 0x42, 0x4D, 0x52, 0x42, 0x4D, 0x56, 0x42, + 0x4D, 0x57, 0x42, 0x4E, 0x4A, 0x42, 0x4E, 0x6A, + 0x42, 0x4E, 0x6F, 0x42, 0x50, 0x48, 0x42, 0x50, + 0x52, 0x42, 0x50, 0x61, 0x42, 0x52, 0x73, 0x42, + 0x53, 0x44, 0x42, 0x53, 0x4D, 0x42, 0x53, 0x53, + 0x42, 0x53, 0x76, 0x42, 0x54, 0x4D, 0x42, 0x56, + 0x49, 0x42, 0x57, 0x43, 0x42, 0x57, 0x5A, 0x42, + 0x57, 0x62, 0x42, 0x58, 0x49, 0x42, 0x63, 0x63, + // Bytes 19c0 - 19ff + 0x42, 0x63, 0x64, 0x42, 0x63, 0x6D, 0x42, 0x64, + 0x42, 0x42, 0x64, 0x61, 0x42, 0x64, 0x6C, 0x42, + 0x64, 0x6D, 0x42, 0x64, 0x7A, 0x42, 0x65, 0x56, + 0x42, 0x66, 0x66, 0x42, 0x66, 0x69, 0x42, 0x66, + 0x6C, 0x42, 0x66, 0x6D, 0x42, 0x68, 0x61, 0x42, + 0x69, 0x69, 0x42, 0x69, 0x6A, 0x42, 0x69, 0x6E, + 0x42, 0x69, 0x76, 0x42, 0x69, 0x78, 0x42, 0x6B, + 0x41, 0x42, 0x6B, 0x56, 0x42, 0x6B, 0x57, 0x42, + // Bytes 1a00 - 1a3f + 0x6B, 0x67, 0x42, 0x6B, 0x6C, 0x42, 0x6B, 0x6D, + 0x42, 0x6B, 0x74, 0x42, 0x6C, 0x6A, 0x42, 0x6C, + 0x6D, 0x42, 0x6C, 0x6E, 0x42, 0x6C, 0x78, 0x42, + 0x6D, 0x32, 0x42, 0x6D, 0x33, 0x42, 0x6D, 0x41, + 0x42, 0x6D, 0x56, 0x42, 0x6D, 0x57, 0x42, 0x6D, + 0x62, 0x42, 0x6D, 0x67, 0x42, 0x6D, 0x6C, 0x42, + 0x6D, 0x6D, 0x42, 0x6D, 0x73, 0x42, 0x6E, 0x41, + 0x42, 0x6E, 0x46, 0x42, 0x6E, 0x56, 0x42, 0x6E, + // Bytes 1a40 - 1a7f + 0x57, 0x42, 0x6E, 0x6A, 0x42, 0x6E, 0x6D, 0x42, + 0x6E, 0x73, 0x42, 0x6F, 0x56, 0x42, 0x70, 0x41, + 0x42, 0x70, 0x46, 0x42, 0x70, 0x56, 0x42, 0x70, + 0x57, 0x42, 0x70, 0x63, 0x42, 0x70, 0x73, 0x42, + 0x73, 0x72, 0x42, 0x73, 0x74, 0x42, 0x76, 0x69, + 0x42, 0x78, 0x69, 0x43, 0x28, 0x31, 0x29, 0x43, + 0x28, 0x32, 0x29, 0x43, 0x28, 0x33, 0x29, 0x43, + 0x28, 0x34, 0x29, 0x43, 0x28, 0x35, 0x29, 0x43, + // Bytes 1a80 - 1abf + 0x28, 0x36, 0x29, 0x43, 0x28, 0x37, 0x29, 0x43, + 0x28, 0x38, 0x29, 0x43, 0x28, 0x39, 0x29, 0x43, + 0x28, 0x41, 0x29, 0x43, 0x28, 0x42, 0x29, 0x43, + 0x28, 0x43, 0x29, 0x43, 0x28, 0x44, 0x29, 0x43, + 0x28, 0x45, 0x29, 0x43, 0x28, 0x46, 0x29, 0x43, + 0x28, 0x47, 0x29, 0x43, 0x28, 0x48, 0x29, 0x43, + 0x28, 0x49, 0x29, 0x43, 0x28, 0x4A, 0x29, 0x43, + 0x28, 0x4B, 0x29, 0x43, 0x28, 0x4C, 0x29, 0x43, + // Bytes 1ac0 - 1aff + 0x28, 0x4D, 0x29, 0x43, 0x28, 0x4E, 0x29, 0x43, + 0x28, 0x4F, 0x29, 0x43, 0x28, 0x50, 0x29, 0x43, + 0x28, 0x51, 0x29, 0x43, 0x28, 0x52, 0x29, 0x43, + 0x28, 0x53, 0x29, 0x43, 0x28, 0x54, 0x29, 0x43, + 0x28, 0x55, 0x29, 0x43, 0x28, 0x56, 0x29, 0x43, + 0x28, 0x57, 0x29, 0x43, 0x28, 0x58, 0x29, 0x43, + 0x28, 0x59, 0x29, 0x43, 0x28, 0x5A, 0x29, 0x43, + 0x28, 0x61, 0x29, 0x43, 0x28, 0x62, 0x29, 0x43, + // Bytes 1b00 - 1b3f + 0x28, 0x63, 0x29, 0x43, 0x28, 0x64, 0x29, 0x43, + 0x28, 0x65, 0x29, 0x43, 0x28, 0x66, 0x29, 0x43, + 0x28, 0x67, 0x29, 0x43, 0x28, 0x68, 0x29, 0x43, + 0x28, 0x69, 0x29, 0x43, 0x28, 0x6A, 0x29, 0x43, + 0x28, 0x6B, 0x29, 0x43, 0x28, 0x6C, 0x29, 0x43, + 0x28, 0x6D, 0x29, 0x43, 0x28, 0x6E, 0x29, 0x43, + 0x28, 0x6F, 0x29, 0x43, 0x28, 0x70, 0x29, 0x43, + 0x28, 0x71, 0x29, 0x43, 0x28, 0x72, 0x29, 0x43, + // Bytes 1b40 - 1b7f + 0x28, 0x73, 0x29, 0x43, 0x28, 0x74, 0x29, 0x43, + 0x28, 0x75, 0x29, 0x43, 0x28, 0x76, 0x29, 0x43, + 0x28, 0x77, 0x29, 0x43, 0x28, 0x78, 0x29, 0x43, + 0x28, 0x79, 0x29, 0x43, 0x28, 0x7A, 0x29, 0x43, + 0x2E, 0x2E, 0x2E, 0x43, 0x31, 0x30, 0x2E, 0x43, + 0x31, 0x31, 0x2E, 0x43, 0x31, 0x32, 0x2E, 0x43, + 0x31, 0x33, 0x2E, 0x43, 0x31, 0x34, 0x2E, 0x43, + 0x31, 0x35, 0x2E, 0x43, 0x31, 0x36, 0x2E, 0x43, + // Bytes 1b80 - 1bbf + 0x31, 0x37, 0x2E, 0x43, 0x31, 0x38, 0x2E, 0x43, + 0x31, 0x39, 0x2E, 0x43, 0x32, 0x30, 0x2E, 0x43, + 0x3A, 0x3A, 0x3D, 0x43, 0x3D, 0x3D, 0x3D, 0x43, + 0x43, 0x6F, 0x2E, 0x43, 0x46, 0x41, 0x58, 0x43, + 0x47, 0x48, 0x7A, 0x43, 0x47, 0x50, 0x61, 0x43, + 0x49, 0x49, 0x49, 0x43, 0x4C, 0x54, 0x44, 0x43, + 0x4C, 0xC2, 0xB7, 0x43, 0x4D, 0x48, 0x7A, 0x43, + 0x4D, 0x50, 0x61, 0x43, 0x4D, 0xCE, 0xA9, 0x43, + // Bytes 1bc0 - 1bff + 0x50, 0x50, 0x4D, 0x43, 0x50, 0x50, 0x56, 0x43, + 0x50, 0x54, 0x45, 0x43, 0x54, 0x45, 0x4C, 0x43, + 0x54, 0x48, 0x7A, 0x43, 0x56, 0x49, 0x49, 0x43, + 0x58, 0x49, 0x49, 0x43, 0x61, 0x2F, 0x63, 0x43, + 0x61, 0x2F, 0x73, 0x43, 0x61, 0xCA, 0xBE, 0x43, + 0x62, 0x61, 0x72, 0x43, 0x63, 0x2F, 0x6F, 0x43, + 0x63, 0x2F, 0x75, 0x43, 0x63, 0x61, 0x6C, 0x43, + 0x63, 0x6D, 0x32, 0x43, 0x63, 0x6D, 0x33, 0x43, + // Bytes 1c00 - 1c3f + 0x64, 0x6D, 0x32, 0x43, 0x64, 0x6D, 0x33, 0x43, + 0x65, 0x72, 0x67, 0x43, 0x66, 0x66, 0x69, 0x43, + 0x66, 0x66, 0x6C, 0x43, 0x67, 0x61, 0x6C, 0x43, + 0x68, 0x50, 0x61, 0x43, 0x69, 0x69, 0x69, 0x43, + 0x6B, 0x48, 0x7A, 0x43, 0x6B, 0x50, 0x61, 0x43, + 0x6B, 0x6D, 0x32, 0x43, 0x6B, 0x6D, 0x33, 0x43, + 0x6B, 0xCE, 0xA9, 0x43, 0x6C, 0x6F, 0x67, 0x43, + 0x6C, 0xC2, 0xB7, 0x43, 0x6D, 0x69, 0x6C, 0x43, + // Bytes 1c40 - 1c7f + 0x6D, 0x6D, 0x32, 0x43, 0x6D, 0x6D, 0x33, 0x43, + 0x6D, 0x6F, 0x6C, 0x43, 0x72, 0x61, 0x64, 0x43, + 0x76, 0x69, 0x69, 0x43, 0x78, 0x69, 0x69, 0x43, + 0xC2, 0xB0, 0x43, 0x43, 0xC2, 0xB0, 0x46, 0x43, + 0xCA, 0xBC, 0x6E, 0x43, 0xCE, 0xBC, 0x41, 0x43, + 0xCE, 0xBC, 0x46, 0x43, 0xCE, 0xBC, 0x56, 0x43, + 0xCE, 0xBC, 0x57, 0x43, 0xCE, 0xBC, 0x67, 0x43, + 0xCE, 0xBC, 0x6C, 0x43, 0xCE, 0xBC, 0x6D, 0x43, + // Bytes 1c80 - 1cbf + 0xCE, 0xBC, 0x73, 0x44, 0x28, 0x31, 0x30, 0x29, + 0x44, 0x28, 0x31, 0x31, 0x29, 0x44, 0x28, 0x31, + 0x32, 0x29, 0x44, 0x28, 0x31, 0x33, 0x29, 0x44, + 0x28, 0x31, 0x34, 0x29, 0x44, 0x28, 0x31, 0x35, + 0x29, 0x44, 0x28, 0x31, 0x36, 0x29, 0x44, 0x28, + 0x31, 0x37, 0x29, 0x44, 0x28, 0x31, 0x38, 0x29, + 0x44, 0x28, 0x31, 0x39, 0x29, 0x44, 0x28, 0x32, + 0x30, 0x29, 0x44, 0x30, 0xE7, 0x82, 0xB9, 0x44, + // Bytes 1cc0 - 1cff + 0x31, 0xE2, 0x81, 0x84, 0x44, 0x31, 0xE6, 0x97, + 0xA5, 0x44, 0x31, 0xE6, 0x9C, 0x88, 0x44, 0x31, + 0xE7, 0x82, 0xB9, 0x44, 0x32, 0xE6, 0x97, 0xA5, + 0x44, 0x32, 0xE6, 0x9C, 0x88, 0x44, 0x32, 0xE7, + 0x82, 0xB9, 0x44, 0x33, 0xE6, 0x97, 0xA5, 0x44, + 0x33, 0xE6, 0x9C, 0x88, 0x44, 0x33, 0xE7, 0x82, + 0xB9, 0x44, 0x34, 0xE6, 0x97, 0xA5, 0x44, 0x34, + 0xE6, 0x9C, 0x88, 0x44, 0x34, 0xE7, 0x82, 0xB9, + // Bytes 1d00 - 1d3f + 0x44, 0x35, 0xE6, 0x97, 0xA5, 0x44, 0x35, 0xE6, + 0x9C, 0x88, 0x44, 0x35, 0xE7, 0x82, 0xB9, 0x44, + 0x36, 0xE6, 0x97, 0xA5, 0x44, 0x36, 0xE6, 0x9C, + 0x88, 0x44, 0x36, 0xE7, 0x82, 0xB9, 0x44, 0x37, + 0xE6, 0x97, 0xA5, 0x44, 0x37, 0xE6, 0x9C, 0x88, + 0x44, 0x37, 0xE7, 0x82, 0xB9, 0x44, 0x38, 0xE6, + 0x97, 0xA5, 0x44, 0x38, 0xE6, 0x9C, 0x88, 0x44, + 0x38, 0xE7, 0x82, 0xB9, 0x44, 0x39, 0xE6, 0x97, + // Bytes 1d40 - 1d7f + 0xA5, 0x44, 0x39, 0xE6, 0x9C, 0x88, 0x44, 0x39, + 0xE7, 0x82, 0xB9, 0x44, 0x56, 0x49, 0x49, 0x49, + 0x44, 0x61, 0x2E, 0x6D, 0x2E, 0x44, 0x6B, 0x63, + 0x61, 0x6C, 0x44, 0x70, 0x2E, 0x6D, 0x2E, 0x44, + 0x76, 0x69, 0x69, 0x69, 0x44, 0xD5, 0xA5, 0xD6, + 0x82, 0x44, 0xD5, 0xB4, 0xD5, 0xA5, 0x44, 0xD5, + 0xB4, 0xD5, 0xAB, 0x44, 0xD5, 0xB4, 0xD5, 0xAD, + 0x44, 0xD5, 0xB4, 0xD5, 0xB6, 0x44, 0xD5, 0xBE, + // Bytes 1d80 - 1dbf + 0xD5, 0xB6, 0x44, 0xD7, 0x90, 0xD7, 0x9C, 0x44, + 0xD8, 0xA7, 0xD9, 0xB4, 0x44, 0xD8, 0xA8, 0xD8, + 0xAC, 0x44, 0xD8, 0xA8, 0xD8, 0xAD, 0x44, 0xD8, + 0xA8, 0xD8, 0xAE, 0x44, 0xD8, 0xA8, 0xD8, 0xB1, + 0x44, 0xD8, 0xA8, 0xD8, 0xB2, 0x44, 0xD8, 0xA8, + 0xD9, 0x85, 0x44, 0xD8, 0xA8, 0xD9, 0x86, 0x44, + 0xD8, 0xA8, 0xD9, 0x87, 0x44, 0xD8, 0xA8, 0xD9, + 0x89, 0x44, 0xD8, 0xA8, 0xD9, 0x8A, 0x44, 0xD8, + // Bytes 1dc0 - 1dff + 0xAA, 0xD8, 0xAC, 0x44, 0xD8, 0xAA, 0xD8, 0xAD, + 0x44, 0xD8, 0xAA, 0xD8, 0xAE, 0x44, 0xD8, 0xAA, + 0xD8, 0xB1, 0x44, 0xD8, 0xAA, 0xD8, 0xB2, 0x44, + 0xD8, 0xAA, 0xD9, 0x85, 0x44, 0xD8, 0xAA, 0xD9, + 0x86, 0x44, 0xD8, 0xAA, 0xD9, 0x87, 0x44, 0xD8, + 0xAA, 0xD9, 0x89, 0x44, 0xD8, 0xAA, 0xD9, 0x8A, + 0x44, 0xD8, 0xAB, 0xD8, 0xAC, 0x44, 0xD8, 0xAB, + 0xD8, 0xB1, 0x44, 0xD8, 0xAB, 0xD8, 0xB2, 0x44, + // Bytes 1e00 - 1e3f + 0xD8, 0xAB, 0xD9, 0x85, 0x44, 0xD8, 0xAB, 0xD9, + 0x86, 0x44, 0xD8, 0xAB, 0xD9, 0x87, 0x44, 0xD8, + 0xAB, 0xD9, 0x89, 0x44, 0xD8, 0xAB, 0xD9, 0x8A, + 0x44, 0xD8, 0xAC, 0xD8, 0xAD, 0x44, 0xD8, 0xAC, + 0xD9, 0x85, 0x44, 0xD8, 0xAC, 0xD9, 0x89, 0x44, + 0xD8, 0xAC, 0xD9, 0x8A, 0x44, 0xD8, 0xAD, 0xD8, + 0xAC, 0x44, 0xD8, 0xAD, 0xD9, 0x85, 0x44, 0xD8, + 0xAD, 0xD9, 0x89, 0x44, 0xD8, 0xAD, 0xD9, 0x8A, + // Bytes 1e40 - 1e7f + 0x44, 0xD8, 0xAE, 0xD8, 0xAC, 0x44, 0xD8, 0xAE, + 0xD8, 0xAD, 0x44, 0xD8, 0xAE, 0xD9, 0x85, 0x44, + 0xD8, 0xAE, 0xD9, 0x89, 0x44, 0xD8, 0xAE, 0xD9, + 0x8A, 0x44, 0xD8, 0xB3, 0xD8, 0xAC, 0x44, 0xD8, + 0xB3, 0xD8, 0xAD, 0x44, 0xD8, 0xB3, 0xD8, 0xAE, + 0x44, 0xD8, 0xB3, 0xD8, 0xB1, 0x44, 0xD8, 0xB3, + 0xD9, 0x85, 0x44, 0xD8, 0xB3, 0xD9, 0x87, 0x44, + 0xD8, 0xB3, 0xD9, 0x89, 0x44, 0xD8, 0xB3, 0xD9, + // Bytes 1e80 - 1ebf + 0x8A, 0x44, 0xD8, 0xB4, 0xD8, 0xAC, 0x44, 0xD8, + 0xB4, 0xD8, 0xAD, 0x44, 0xD8, 0xB4, 0xD8, 0xAE, + 0x44, 0xD8, 0xB4, 0xD8, 0xB1, 0x44, 0xD8, 0xB4, + 0xD9, 0x85, 0x44, 0xD8, 0xB4, 0xD9, 0x87, 0x44, + 0xD8, 0xB4, 0xD9, 0x89, 0x44, 0xD8, 0xB4, 0xD9, + 0x8A, 0x44, 0xD8, 0xB5, 0xD8, 0xAD, 0x44, 0xD8, + 0xB5, 0xD8, 0xAE, 0x44, 0xD8, 0xB5, 0xD8, 0xB1, + 0x44, 0xD8, 0xB5, 0xD9, 0x85, 0x44, 0xD8, 0xB5, + // Bytes 1ec0 - 1eff + 0xD9, 0x89, 0x44, 0xD8, 0xB5, 0xD9, 0x8A, 0x44, + 0xD8, 0xB6, 0xD8, 0xAC, 0x44, 0xD8, 0xB6, 0xD8, + 0xAD, 0x44, 0xD8, 0xB6, 0xD8, 0xAE, 0x44, 0xD8, + 0xB6, 0xD8, 0xB1, 0x44, 0xD8, 0xB6, 0xD9, 0x85, + 0x44, 0xD8, 0xB6, 0xD9, 0x89, 0x44, 0xD8, 0xB6, + 0xD9, 0x8A, 0x44, 0xD8, 0xB7, 0xD8, 0xAD, 0x44, + 0xD8, 0xB7, 0xD9, 0x85, 0x44, 0xD8, 0xB7, 0xD9, + 0x89, 0x44, 0xD8, 0xB7, 0xD9, 0x8A, 0x44, 0xD8, + // Bytes 1f00 - 1f3f + 0xB8, 0xD9, 0x85, 0x44, 0xD8, 0xB9, 0xD8, 0xAC, + 0x44, 0xD8, 0xB9, 0xD9, 0x85, 0x44, 0xD8, 0xB9, + 0xD9, 0x89, 0x44, 0xD8, 0xB9, 0xD9, 0x8A, 0x44, + 0xD8, 0xBA, 0xD8, 0xAC, 0x44, 0xD8, 0xBA, 0xD9, + 0x85, 0x44, 0xD8, 0xBA, 0xD9, 0x89, 0x44, 0xD8, + 0xBA, 0xD9, 0x8A, 0x44, 0xD9, 0x81, 0xD8, 0xAC, + 0x44, 0xD9, 0x81, 0xD8, 0xAD, 0x44, 0xD9, 0x81, + 0xD8, 0xAE, 0x44, 0xD9, 0x81, 0xD9, 0x85, 0x44, + // Bytes 1f40 - 1f7f + 0xD9, 0x81, 0xD9, 0x89, 0x44, 0xD9, 0x81, 0xD9, + 0x8A, 0x44, 0xD9, 0x82, 0xD8, 0xAD, 0x44, 0xD9, + 0x82, 0xD9, 0x85, 0x44, 0xD9, 0x82, 0xD9, 0x89, + 0x44, 0xD9, 0x82, 0xD9, 0x8A, 0x44, 0xD9, 0x83, + 0xD8, 0xA7, 0x44, 0xD9, 0x83, 0xD8, 0xAC, 0x44, + 0xD9, 0x83, 0xD8, 0xAD, 0x44, 0xD9, 0x83, 0xD8, + 0xAE, 0x44, 0xD9, 0x83, 0xD9, 0x84, 0x44, 0xD9, + 0x83, 0xD9, 0x85, 0x44, 0xD9, 0x83, 0xD9, 0x89, + // Bytes 1f80 - 1fbf + 0x44, 0xD9, 0x83, 0xD9, 0x8A, 0x44, 0xD9, 0x84, + 0xD8, 0xA7, 0x44, 0xD9, 0x84, 0xD8, 0xAC, 0x44, + 0xD9, 0x84, 0xD8, 0xAD, 0x44, 0xD9, 0x84, 0xD8, + 0xAE, 0x44, 0xD9, 0x84, 0xD9, 0x85, 0x44, 0xD9, + 0x84, 0xD9, 0x87, 0x44, 0xD9, 0x84, 0xD9, 0x89, + 0x44, 0xD9, 0x84, 0xD9, 0x8A, 0x44, 0xD9, 0x85, + 0xD8, 0xA7, 0x44, 0xD9, 0x85, 0xD8, 0xAC, 0x44, + 0xD9, 0x85, 0xD8, 0xAD, 0x44, 0xD9, 0x85, 0xD8, + // Bytes 1fc0 - 1fff + 0xAE, 0x44, 0xD9, 0x85, 0xD9, 0x85, 0x44, 0xD9, + 0x85, 0xD9, 0x89, 0x44, 0xD9, 0x85, 0xD9, 0x8A, + 0x44, 0xD9, 0x86, 0xD8, 0xAC, 0x44, 0xD9, 0x86, + 0xD8, 0xAD, 0x44, 0xD9, 0x86, 0xD8, 0xAE, 0x44, + 0xD9, 0x86, 0xD8, 0xB1, 0x44, 0xD9, 0x86, 0xD8, + 0xB2, 0x44, 0xD9, 0x86, 0xD9, 0x85, 0x44, 0xD9, + 0x86, 0xD9, 0x86, 0x44, 0xD9, 0x86, 0xD9, 0x87, + 0x44, 0xD9, 0x86, 0xD9, 0x89, 0x44, 0xD9, 0x86, + // Bytes 2000 - 203f + 0xD9, 0x8A, 0x44, 0xD9, 0x87, 0xD8, 0xAC, 0x44, + 0xD9, 0x87, 0xD9, 0x85, 0x44, 0xD9, 0x87, 0xD9, + 0x89, 0x44, 0xD9, 0x87, 0xD9, 0x8A, 0x44, 0xD9, + 0x88, 0xD9, 0xB4, 0x44, 0xD9, 0x8A, 0xD8, 0xAC, + 0x44, 0xD9, 0x8A, 0xD8, 0xAD, 0x44, 0xD9, 0x8A, + 0xD8, 0xAE, 0x44, 0xD9, 0x8A, 0xD8, 0xB1, 0x44, + 0xD9, 0x8A, 0xD8, 0xB2, 0x44, 0xD9, 0x8A, 0xD9, + 0x85, 0x44, 0xD9, 0x8A, 0xD9, 0x86, 0x44, 0xD9, + // Bytes 2040 - 207f + 0x8A, 0xD9, 0x87, 0x44, 0xD9, 0x8A, 0xD9, 0x89, + 0x44, 0xD9, 0x8A, 0xD9, 0x8A, 0x44, 0xD9, 0x8A, + 0xD9, 0xB4, 0x44, 0xDB, 0x87, 0xD9, 0xB4, 0x45, + 0x28, 0xE1, 0x84, 0x80, 0x29, 0x45, 0x28, 0xE1, + 0x84, 0x82, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x83, + 0x29, 0x45, 0x28, 0xE1, 0x84, 0x85, 0x29, 0x45, + 0x28, 0xE1, 0x84, 0x86, 0x29, 0x45, 0x28, 0xE1, + 0x84, 0x87, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x89, + // Bytes 2080 - 20bf + 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8B, 0x29, 0x45, + 0x28, 0xE1, 0x84, 0x8C, 0x29, 0x45, 0x28, 0xE1, + 0x84, 0x8E, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8F, + 0x29, 0x45, 0x28, 0xE1, 0x84, 0x90, 0x29, 0x45, + 0x28, 0xE1, 0x84, 0x91, 0x29, 0x45, 0x28, 0xE1, + 0x84, 0x92, 0x29, 0x45, 0x28, 0xE4, 0xB8, 0x80, + 0x29, 0x45, 0x28, 0xE4, 0xB8, 0x83, 0x29, 0x45, + 0x28, 0xE4, 0xB8, 0x89, 0x29, 0x45, 0x28, 0xE4, + // Bytes 20c0 - 20ff + 0xB9, 0x9D, 0x29, 0x45, 0x28, 0xE4, 0xBA, 0x8C, + 0x29, 0x45, 0x28, 0xE4, 0xBA, 0x94, 0x29, 0x45, + 0x28, 0xE4, 0xBB, 0xA3, 0x29, 0x45, 0x28, 0xE4, + 0xBC, 0x81, 0x29, 0x45, 0x28, 0xE4, 0xBC, 0x91, + 0x29, 0x45, 0x28, 0xE5, 0x85, 0xAB, 0x29, 0x45, + 0x28, 0xE5, 0x85, 0xAD, 0x29, 0x45, 0x28, 0xE5, + 0x8A, 0xB4, 0x29, 0x45, 0x28, 0xE5, 0x8D, 0x81, + 0x29, 0x45, 0x28, 0xE5, 0x8D, 0x94, 0x29, 0x45, + // Bytes 2100 - 213f + 0x28, 0xE5, 0x90, 0x8D, 0x29, 0x45, 0x28, 0xE5, + 0x91, 0xBC, 0x29, 0x45, 0x28, 0xE5, 0x9B, 0x9B, + 0x29, 0x45, 0x28, 0xE5, 0x9C, 0x9F, 0x29, 0x45, + 0x28, 0xE5, 0xAD, 0xA6, 0x29, 0x45, 0x28, 0xE6, + 0x97, 0xA5, 0x29, 0x45, 0x28, 0xE6, 0x9C, 0x88, + 0x29, 0x45, 0x28, 0xE6, 0x9C, 0x89, 0x29, 0x45, + 0x28, 0xE6, 0x9C, 0xA8, 0x29, 0x45, 0x28, 0xE6, + 0xA0, 0xAA, 0x29, 0x45, 0x28, 0xE6, 0xB0, 0xB4, + // Bytes 2140 - 217f + 0x29, 0x45, 0x28, 0xE7, 0x81, 0xAB, 0x29, 0x45, + 0x28, 0xE7, 0x89, 0xB9, 0x29, 0x45, 0x28, 0xE7, + 0x9B, 0xA3, 0x29, 0x45, 0x28, 0xE7, 0xA4, 0xBE, + 0x29, 0x45, 0x28, 0xE7, 0xA5, 0x9D, 0x29, 0x45, + 0x28, 0xE7, 0xA5, 0xAD, 0x29, 0x45, 0x28, 0xE8, + 0x87, 0xAA, 0x29, 0x45, 0x28, 0xE8, 0x87, 0xB3, + 0x29, 0x45, 0x28, 0xE8, 0xB2, 0xA1, 0x29, 0x45, + 0x28, 0xE8, 0xB3, 0x87, 0x29, 0x45, 0x28, 0xE9, + // Bytes 2180 - 21bf + 0x87, 0x91, 0x29, 0x45, 0x30, 0xE2, 0x81, 0x84, + 0x33, 0x45, 0x31, 0x30, 0xE6, 0x97, 0xA5, 0x45, + 0x31, 0x30, 0xE6, 0x9C, 0x88, 0x45, 0x31, 0x30, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x31, 0xE6, 0x97, + 0xA5, 0x45, 0x31, 0x31, 0xE6, 0x9C, 0x88, 0x45, + 0x31, 0x31, 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x32, + 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x32, 0xE6, 0x9C, + 0x88, 0x45, 0x31, 0x32, 0xE7, 0x82, 0xB9, 0x45, + // Bytes 21c0 - 21ff + 0x31, 0x33, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x33, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x34, 0xE6, 0x97, + 0xA5, 0x45, 0x31, 0x34, 0xE7, 0x82, 0xB9, 0x45, + 0x31, 0x35, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x35, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x36, 0xE6, 0x97, + 0xA5, 0x45, 0x31, 0x36, 0xE7, 0x82, 0xB9, 0x45, + 0x31, 0x37, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x37, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0x38, 0xE6, 0x97, + // Bytes 2200 - 223f + 0xA5, 0x45, 0x31, 0x38, 0xE7, 0x82, 0xB9, 0x45, + 0x31, 0x39, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x39, + 0xE7, 0x82, 0xB9, 0x45, 0x31, 0xE2, 0x81, 0x84, + 0x32, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x33, 0x45, + 0x31, 0xE2, 0x81, 0x84, 0x34, 0x45, 0x31, 0xE2, + 0x81, 0x84, 0x35, 0x45, 0x31, 0xE2, 0x81, 0x84, + 0x36, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x37, 0x45, + 0x31, 0xE2, 0x81, 0x84, 0x38, 0x45, 0x31, 0xE2, + // Bytes 2240 - 227f + 0x81, 0x84, 0x39, 0x45, 0x32, 0x30, 0xE6, 0x97, + 0xA5, 0x45, 0x32, 0x30, 0xE7, 0x82, 0xB9, 0x45, + 0x32, 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x31, + 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x32, 0xE6, 0x97, + 0xA5, 0x45, 0x32, 0x32, 0xE7, 0x82, 0xB9, 0x45, + 0x32, 0x33, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x33, + 0xE7, 0x82, 0xB9, 0x45, 0x32, 0x34, 0xE6, 0x97, + 0xA5, 0x45, 0x32, 0x34, 0xE7, 0x82, 0xB9, 0x45, + // Bytes 2280 - 22bf + 0x32, 0x35, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x36, + 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x37, 0xE6, 0x97, + 0xA5, 0x45, 0x32, 0x38, 0xE6, 0x97, 0xA5, 0x45, + 0x32, 0x39, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0xE2, + 0x81, 0x84, 0x33, 0x45, 0x32, 0xE2, 0x81, 0x84, + 0x35, 0x45, 0x33, 0x30, 0xE6, 0x97, 0xA5, 0x45, + 0x33, 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x33, 0xE2, + 0x81, 0x84, 0x34, 0x45, 0x33, 0xE2, 0x81, 0x84, + // Bytes 22c0 - 22ff + 0x35, 0x45, 0x33, 0xE2, 0x81, 0x84, 0x38, 0x45, + 0x34, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x35, 0xE2, + 0x81, 0x84, 0x36, 0x45, 0x35, 0xE2, 0x81, 0x84, + 0x38, 0x45, 0x37, 0xE2, 0x81, 0x84, 0x38, 0x45, + 0x41, 0xE2, 0x88, 0x95, 0x6D, 0x45, 0x56, 0xE2, + 0x88, 0x95, 0x6D, 0x45, 0x6D, 0xE2, 0x88, 0x95, + 0x73, 0x46, 0x31, 0xE2, 0x81, 0x84, 0x31, 0x30, + 0x46, 0x43, 0xE2, 0x88, 0x95, 0x6B, 0x67, 0x46, + // Bytes 2300 - 233f + 0x6D, 0xE2, 0x88, 0x95, 0x73, 0x32, 0x46, 0xD8, + 0xA8, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xA8, + 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD8, 0xAA, 0xD8, + 0xAC, 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAC, + 0xD9, 0x89, 0x46, 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, + 0x8A, 0x46, 0xD8, 0xAA, 0xD8, 0xAD, 0xD8, 0xAC, + 0x46, 0xD8, 0xAA, 0xD8, 0xAD, 0xD9, 0x85, 0x46, + 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD8, + // Bytes 2340 - 237f + 0xAA, 0xD8, 0xAE, 0xD9, 0x89, 0x46, 0xD8, 0xAA, + 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD8, 0xAA, 0xD9, + 0x85, 0xD8, 0xAC, 0x46, 0xD8, 0xAA, 0xD9, 0x85, + 0xD8, 0xAD, 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD8, + 0xAE, 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x89, + 0x46, 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD8, + 0xAC, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xAC, + // Bytes 2380 - 23bf + 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xAC, 0xD9, + 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAC, 0xD9, 0x85, + 0xD9, 0x8A, 0x46, 0xD8, 0xAD, 0xD8, 0xAC, 0xD9, + 0x8A, 0x46, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x89, + 0x46, 0xD8, 0xAD, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD8, 0xB3, 0xD8, 0xAC, 0xD8, 0xAD, 0x46, 0xD8, + 0xB3, 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD8, 0xB3, + 0xD8, 0xAD, 0xD8, 0xAC, 0x46, 0xD8, 0xB3, 0xD8, + // Bytes 23c0 - 23ff + 0xAE, 0xD9, 0x89, 0x46, 0xD8, 0xB3, 0xD8, 0xAE, + 0xD9, 0x8A, 0x46, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, + 0xAC, 0x46, 0xD8, 0xB3, 0xD9, 0x85, 0xD8, 0xAD, + 0x46, 0xD8, 0xB3, 0xD9, 0x85, 0xD9, 0x85, 0x46, + 0xD8, 0xB4, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, + 0xB4, 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD8, 0xB4, + 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB4, 0xD9, + 0x85, 0xD8, 0xAE, 0x46, 0xD8, 0xB4, 0xD9, 0x85, + // Bytes 2400 - 243f + 0xD9, 0x85, 0x46, 0xD8, 0xB5, 0xD8, 0xAD, 0xD8, + 0xAD, 0x46, 0xD8, 0xB5, 0xD8, 0xAD, 0xD9, 0x8A, + 0x46, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89, 0x46, + 0xD8, 0xB5, 0xD9, 0x84, 0xDB, 0x92, 0x46, 0xD8, + 0xB5, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB6, + 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD8, 0xB6, 0xD8, + 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB6, 0xD8, 0xAE, + 0xD9, 0x85, 0x46, 0xD8, 0xB7, 0xD9, 0x85, 0xD8, + // Bytes 2440 - 247f + 0xAD, 0x46, 0xD8, 0xB7, 0xD9, 0x85, 0xD9, 0x85, + 0x46, 0xD8, 0xB7, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD8, 0xB9, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD8, + 0xB9, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB9, + 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xB9, 0xD9, + 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xBA, 0xD9, 0x85, + 0xD9, 0x85, 0x46, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, + 0x89, 0x46, 0xD8, 0xBA, 0xD9, 0x85, 0xD9, 0x8A, + // Bytes 2480 - 24bf + 0x46, 0xD9, 0x81, 0xD8, 0xAE, 0xD9, 0x85, 0x46, + 0xD9, 0x81, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, + 0x82, 0xD9, 0x84, 0xDB, 0x92, 0x46, 0xD9, 0x82, + 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD9, 0x82, 0xD9, + 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x82, 0xD9, 0x85, + 0xD9, 0x8A, 0x46, 0xD9, 0x83, 0xD9, 0x85, 0xD9, + 0x85, 0x46, 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x8A, + 0x46, 0xD9, 0x84, 0xD8, 0xAC, 0xD8, 0xAC, 0x46, + // Bytes 24c0 - 24ff + 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD9, + 0x84, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x84, + 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, 0x84, 0xD8, + 0xAD, 0xD9, 0x89, 0x46, 0xD9, 0x84, 0xD8, 0xAD, + 0xD9, 0x8A, 0x46, 0xD9, 0x84, 0xD8, 0xAE, 0xD9, + 0x85, 0x46, 0xD9, 0x84, 0xD9, 0x85, 0xD8, 0xAD, + 0x46, 0xD9, 0x84, 0xD9, 0x85, 0xD9, 0x8A, 0x46, + 0xD9, 0x85, 0xD8, 0xAC, 0xD8, 0xAD, 0x46, 0xD9, + // Bytes 2500 - 253f + 0x85, 0xD8, 0xAC, 0xD8, 0xAE, 0x46, 0xD9, 0x85, + 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD9, 0x85, 0xD8, + 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, 0xAD, + 0xD8, 0xAC, 0x46, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, + 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x8A, + 0x46, 0xD9, 0x85, 0xD8, 0xAE, 0xD8, 0xAC, 0x46, + 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, + 0x85, 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD9, 0x85, + // Bytes 2540 - 257f + 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x86, 0xD8, + 0xAC, 0xD8, 0xAD, 0x46, 0xD9, 0x86, 0xD8, 0xAC, + 0xD9, 0x85, 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, + 0x89, 0x46, 0xD9, 0x86, 0xD8, 0xAC, 0xD9, 0x8A, + 0x46, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x85, 0x46, + 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD9, + 0x86, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x86, + 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD9, 0x86, 0xD9, + // Bytes 2580 - 25bf + 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x87, 0xD9, 0x85, + 0xD8, 0xAC, 0x46, 0xD9, 0x87, 0xD9, 0x85, 0xD9, + 0x85, 0x46, 0xD9, 0x8A, 0xD8, 0xAC, 0xD9, 0x8A, + 0x46, 0xD9, 0x8A, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, + 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, + 0x8A, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xD8, 0xA7, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xD8, 0xAC, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + // Bytes 25c0 - 25ff + 0xD8, 0xAD, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, + 0xAE, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xB1, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xB2, 0x46, + 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x85, 0x46, 0xD9, + 0x8A, 0xD9, 0x94, 0xD9, 0x86, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xD9, 0x87, 0x46, 0xD9, 0x8A, 0xD9, + 0x94, 0xD9, 0x88, 0x46, 0xD9, 0x8A, 0xD9, 0x94, + 0xD9, 0x89, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, + // Bytes 2600 - 263f + 0x8A, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x86, + 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x87, 0x46, + 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x88, 0x46, 0xD9, + 0x8A, 0xD9, 0x94, 0xDB, 0x90, 0x46, 0xD9, 0x8A, + 0xD9, 0x94, 0xDB, 0x95, 0x46, 0xE0, 0xB9, 0x8D, + 0xE0, 0xB8, 0xB2, 0x46, 0xE0, 0xBA, 0xAB, 0xE0, + 0xBA, 0x99, 0x46, 0xE0, 0xBA, 0xAB, 0xE0, 0xBA, + 0xA1, 0x46, 0xE0, 0xBB, 0x8D, 0xE0, 0xBA, 0xB2, + // Bytes 2640 - 267f + 0x46, 0xE0, 0xBD, 0x80, 0xE0, 0xBE, 0xB5, 0x46, + 0xE0, 0xBD, 0x82, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, + 0xBD, 0x8C, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, + 0x91, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x96, + 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBD, 0x9B, 0xE0, + 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0x90, 0xE0, 0xBE, + 0xB5, 0x46, 0xE0, 0xBE, 0x92, 0xE0, 0xBE, 0xB7, + 0x46, 0xE0, 0xBE, 0x9C, 0xE0, 0xBE, 0xB7, 0x46, + // Bytes 2680 - 26bf + 0xE0, 0xBE, 0xA1, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, + 0xBE, 0xA6, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, + 0xAB, 0xE0, 0xBE, 0xB7, 0x46, 0xE2, 0x80, 0xB2, + 0xE2, 0x80, 0xB2, 0x46, 0xE2, 0x80, 0xB5, 0xE2, + 0x80, 0xB5, 0x46, 0xE2, 0x88, 0xAB, 0xE2, 0x88, + 0xAB, 0x46, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, + 0x46, 0xE3, 0x81, 0xBB, 0xE3, 0x81, 0x8B, 0x46, + 0xE3, 0x82, 0x88, 0xE3, 0x82, 0x8A, 0x46, 0xE3, + // Bytes 26c0 - 26ff + 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0x46, 0xE3, 0x82, + 0xB3, 0xE3, 0x82, 0xB3, 0x46, 0xE3, 0x82, 0xB3, + 0xE3, 0x83, 0x88, 0x46, 0xE3, 0x83, 0x88, 0xE3, + 0x83, 0xB3, 0x46, 0xE3, 0x83, 0x8A, 0xE3, 0x83, + 0x8E, 0x46, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xB3, + 0x46, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, 0x46, + 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xA9, 0x46, 0xE3, + 0x83, 0xAC, 0xE3, 0x83, 0xA0, 0x46, 0xE5, 0xA4, + // Bytes 2700 - 273f + 0xA7, 0xE6, 0xAD, 0xA3, 0x46, 0xE5, 0xB9, 0xB3, + 0xE6, 0x88, 0x90, 0x46, 0xE6, 0x98, 0x8E, 0xE6, + 0xB2, 0xBB, 0x46, 0xE6, 0x98, 0xAD, 0xE5, 0x92, + 0x8C, 0x47, 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, + 0x73, 0x47, 0xE3, 0x80, 0x94, 0x53, 0xE3, 0x80, + 0x95, 0x48, 0x28, 0xE1, 0x84, 0x80, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x82, 0xE1, + 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x83, + // Bytes 2740 - 277f + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x85, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, + 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, + 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x89, 0xE1, 0x85, 0xA1, 0x29, + 0x48, 0x28, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA1, + 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8C, 0xE1, 0x85, + 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8C, 0xE1, + // Bytes 2780 - 27bf + 0x85, 0xAE, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8E, + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, + 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, + 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x29, 0x48, + 0x28, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0x29, + 0x48, 0x72, 0x61, 0x64, 0xE2, 0x88, 0x95, 0x73, + 0x32, 0x48, 0xD8, 0xA7, 0xD9, 0x83, 0xD8, 0xA8, + // Bytes 27c0 - 27ff + 0xD8, 0xB1, 0x48, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, + 0x84, 0xD9, 0x87, 0x48, 0xD8, 0xB1, 0xD8, 0xB3, + 0xD9, 0x88, 0xD9, 0x84, 0x48, 0xD8, 0xB1, 0xDB, + 0x8C, 0xD8, 0xA7, 0xD9, 0x84, 0x48, 0xD8, 0xB5, + 0xD9, 0x84, 0xD8, 0xB9, 0xD9, 0x85, 0x48, 0xD8, + 0xB9, 0xD9, 0x84, 0xD9, 0x8A, 0xD9, 0x87, 0x48, + 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85, 0xD8, 0xAF, + 0x48, 0xD9, 0x88, 0xD8, 0xB3, 0xD9, 0x84, 0xD9, + // Bytes 2800 - 283f + 0x85, 0x49, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0xE2, 0x80, 0xB2, 0x49, 0xE2, 0x80, 0xB5, 0xE2, + 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x49, 0xE2, 0x88, + 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x49, + 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE, 0xE2, 0x88, + 0xAE, 0x49, 0xE3, 0x80, 0x94, 0xE4, 0xB8, 0x89, + 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE4, + 0xBA, 0x8C, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, + // Bytes 2840 - 287f + 0x94, 0xE5, 0x8B, 0x9D, 0xE3, 0x80, 0x95, 0x49, + 0xE3, 0x80, 0x94, 0xE5, 0xAE, 0x89, 0xE3, 0x80, + 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6, 0x89, 0x93, + 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6, + 0x95, 0x97, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, + 0x94, 0xE6, 0x9C, 0xAC, 0xE3, 0x80, 0x95, 0x49, + 0xE3, 0x80, 0x94, 0xE7, 0x82, 0xB9, 0xE3, 0x80, + 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7, 0x9B, 0x97, + // Bytes 2880 - 28bf + 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x82, 0xA2, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x49, + 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0xA9, 0xE3, 0x83, + 0xB3, 0x49, 0xE3, 0x82, 0xAA, 0xE3, 0x83, 0xB3, + 0xE3, 0x82, 0xB9, 0x49, 0xE3, 0x82, 0xAA, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x49, 0xE3, 0x82, + 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAA, 0x49, + // Bytes 28c0 - 28ff + 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC, 0xE3, 0x82, + 0xB9, 0x49, 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0xAB, + 0xE3, 0x83, 0x8A, 0x49, 0xE3, 0x82, 0xBB, 0xE3, + 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x49, 0xE3, 0x82, + 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0x49, + 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0xE3, 0x82, + 0xB7, 0x49, 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, + 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x8E, 0xE3, + // Bytes 2900 - 293f + 0x83, 0x83, 0xE3, 0x83, 0x88, 0x49, 0xE3, 0x83, + 0x8F, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x84, 0x49, + 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xAB, 0x49, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, + 0xE3, 0x82, 0xB3, 0x49, 0xE3, 0x83, 0x95, 0xE3, + 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0x49, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xBD, 0x49, + 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB, 0xE3, 0x83, + // Bytes 2940 - 297f + 0x84, 0x49, 0xE3, 0x83, 0x9B, 0xE3, 0x83, 0xBC, + 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x9B, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0xB3, 0x49, 0xE3, 0x83, + 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAB, 0x49, + 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x8F, 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0xAB, + 0xE3, 0x82, 0xAF, 0x49, 0xE3, 0x83, 0xA4, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, + // Bytes 2980 - 29bf + 0xA6, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3, 0x49, + 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x88, 0x4C, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, + 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x4C, 0xE2, + 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, + 0xE2, 0x88, 0xAB, 0x4C, 0xE3, 0x82, 0xA2, 0xE3, + 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA1, + 0x4C, 0xE3, 0x82, 0xA8, 0xE3, 0x83, 0xBC, 0xE3, + // Bytes 29c0 - 29ff + 0x82, 0xAB, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, + 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAD, 0xE3, + 0x83, 0xB3, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x9E, 0x4C, + 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xA9, 0xE3, 0x83, + 0x83, 0xE3, 0x83, 0x88, 0x4C, 0xE3, 0x82, 0xAB, + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAA, 0xE3, 0x83, + 0xBC, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, + // Bytes 2a00 - 2a3f + 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, + 0x82, 0xAD, 0xE3, 0x83, 0xA5, 0xE3, 0x83, 0xAA, + 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAF, 0xE3, + 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, + 0x4C, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0xE3, + 0x83, 0xBC, 0xE3, 0x83, 0x8D, 0x4C, 0xE3, 0x82, + 0xB5, 0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, + 0x83, 0xAB, 0x4C, 0xE3, 0x82, 0xBF, 0xE3, 0x82, + // Bytes 2a40 - 2a7f + 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB9, 0x4C, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0x84, 0x4C, 0xE3, 0x83, 0x92, + 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xAF, 0xE3, 0x83, + 0xAB, 0x4C, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA3, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0x4C, 0xE3, + 0x83, 0x98, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, + 0xE3, 0x82, 0xBF, 0x4C, 0xE3, 0x83, 0x98, 0xE3, + // Bytes 2a80 - 2abf + 0x82, 0x9A, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0x92, + 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, + 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x4C, 0xE3, 0x83, + 0x9B, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, + 0x83, 0x88, 0x4C, 0xE3, 0x83, 0x9E, 0xE3, 0x82, + 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAD, 0x4C, + 0xE3, 0x83, 0x9F, 0xE3, 0x82, 0xAF, 0xE3, 0x83, + 0xAD, 0xE3, 0x83, 0xB3, 0x4C, 0xE3, 0x83, 0xA1, + // Bytes 2ac0 - 2aff + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x83, + 0xAB, 0x4C, 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0x83, + 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, + 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, + 0xE3, 0x83, 0xBC, 0x4C, 0xE6, 0xA0, 0xAA, 0xE5, + 0xBC, 0x8F, 0xE4, 0xBC, 0x9A, 0xE7, 0xA4, 0xBE, + 0x4E, 0x28, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA9, + 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xAE, 0x29, 0x4F, + // Bytes 2b00 - 2b3f + 0xD8, 0xAC, 0xD9, 0x84, 0x20, 0xD8, 0xAC, 0xD9, + 0x84, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x87, 0x4F, + 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0x8F, 0xE3, 0x82, + 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0x4F, + 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0x4F, + 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, + 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x4F, + // Bytes 2b40 - 2b7f + 0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3, 0xE3, 0x83, + 0x81, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x4F, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xAB, 0x4F, + 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF, 0xE3, 0x82, + 0xBF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x4F, + 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x82, + 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0x4F, + // Bytes 2b80 - 2bbf + 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0xB3, 0xE3, 0x82, + 0xB7, 0xE3, 0x83, 0xA7, 0xE3, 0x83, 0xB3, 0x4F, + 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x4F, + 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xBC, 0xE3, 0x83, + 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x51, + 0x28, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA9, 0xE1, + 0x84, 0x8C, 0xE1, 0x85, 0xA5, 0xE1, 0x86, 0xAB, + // Bytes 2bc0 - 2bff + 0x29, 0x52, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, + 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBF, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xBC, 0x52, 0xE3, 0x82, 0xAD, + 0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xAF, 0xE3, 0x82, + 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0x52, + 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x83, + 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, + 0x83, 0xAB, 0x52, 0xE3, 0x82, 0xAF, 0xE3, 0x82, + // Bytes 2c00 - 2c3f + 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xA0, 0xE3, + 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x52, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBB, 0xE3, + 0x82, 0x99, 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xAD, + 0x52, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0xE3, + 0x83, 0xBC, 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, + 0xE3, 0x83, 0x88, 0x52, 0xE3, 0x83, 0x92, 0xE3, + 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0xE3, 0x82, 0xB9, + // Bytes 2c40 - 2c7f + 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB, 0x52, 0xE3, + 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x83, + 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xA7, 0xE3, 0x83, + 0xAB, 0x52, 0xE3, 0x83, 0x9F, 0xE3, 0x83, 0xAA, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xBC, 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x83, 0xAC, + 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, 0x82, + 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, 0x61, + // Bytes 2c80 - 2cbf + 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89, 0x20, 0xD8, + 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9, 0x87, 0x20, + 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A, 0xD9, 0x87, + 0x20, 0xD9, 0x88, 0xD8, 0xB3, 0xD9, 0x84, 0xD9, + 0x85, 0x06, 0xE0, 0xA7, 0x87, 0xE0, 0xA6, 0xBE, + 0x01, 0x06, 0xE0, 0xA7, 0x87, 0xE0, 0xA7, 0x97, + 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0, 0xAC, 0xBE, + 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0, 0xAD, 0x96, + // Bytes 2cc0 - 2cff + 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0, 0xAD, 0x97, + 0x01, 0x06, 0xE0, 0xAE, 0x92, 0xE0, 0xAF, 0x97, + 0x01, 0x06, 0xE0, 0xAF, 0x86, 0xE0, 0xAE, 0xBE, + 0x01, 0x06, 0xE0, 0xAF, 0x86, 0xE0, 0xAF, 0x97, + 0x01, 0x06, 0xE0, 0xAF, 0x87, 0xE0, 0xAE, 0xBE, + 0x01, 0x06, 0xE0, 0xB2, 0xBF, 0xE0, 0xB3, 0x95, + 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x95, + 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x96, + // Bytes 2d00 - 2d3f + 0x01, 0x06, 0xE0, 0xB5, 0x86, 0xE0, 0xB4, 0xBE, + 0x01, 0x06, 0xE0, 0xB5, 0x86, 0xE0, 0xB5, 0x97, + 0x01, 0x06, 0xE0, 0xB5, 0x87, 0xE0, 0xB4, 0xBE, + 0x01, 0x06, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x9F, + 0x01, 0x06, 0xE1, 0x80, 0xA5, 0xE1, 0x80, 0xAE, + 0x01, 0x06, 0xE1, 0xAC, 0x85, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAC, 0x87, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAC, 0x89, 0xE1, 0xAC, 0xB5, + // Bytes 2d40 - 2d7f + 0x01, 0x06, 0xE1, 0xAC, 0x8B, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAC, 0x8D, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAC, 0x91, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAC, 0xBA, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAC, 0xBC, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAC, 0xBE, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAC, 0xBF, 0xE1, 0xAC, 0xB5, + 0x01, 0x06, 0xE1, 0xAD, 0x82, 0xE1, 0xAC, 0xB5, + // Bytes 2d80 - 2dbf + 0x01, 0x08, 0xF0, 0x91, 0x84, 0xB1, 0xF0, 0x91, + 0x84, 0xA7, 0x01, 0x08, 0xF0, 0x91, 0x84, 0xB2, + 0xF0, 0x91, 0x84, 0xA7, 0x01, 0x08, 0xF0, 0x91, + 0x8D, 0x87, 0xF0, 0x91, 0x8C, 0xBE, 0x01, 0x08, + 0xF0, 0x91, 0x8D, 0x87, 0xF0, 0x91, 0x8D, 0x97, + 0x01, 0x08, 0xF0, 0x91, 0x92, 0xB9, 0xF0, 0x91, + 0x92, 0xB0, 0x01, 0x08, 0xF0, 0x91, 0x92, 0xB9, + 0xF0, 0x91, 0x92, 0xBA, 0x01, 0x08, 0xF0, 0x91, + // Bytes 2dc0 - 2dff + 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xBD, 0x01, 0x08, + 0xF0, 0x91, 0x96, 0xB8, 0xF0, 0x91, 0x96, 0xAF, + 0x01, 0x08, 0xF0, 0x91, 0x96, 0xB9, 0xF0, 0x91, + 0x96, 0xAF, 0x01, 0x09, 0xE0, 0xB3, 0x86, 0xE0, + 0xB3, 0x82, 0xE0, 0xB3, 0x95, 0x02, 0x09, 0xE0, + 0xB7, 0x99, 0xE0, 0xB7, 0x8F, 0xE0, 0xB7, 0x8A, + 0x12, 0x44, 0x44, 0x5A, 0xCC, 0x8C, 0xC9, 0x44, + 0x44, 0x7A, 0xCC, 0x8C, 0xC9, 0x44, 0x64, 0x7A, + // Bytes 2e00 - 2e3f + 0xCC, 0x8C, 0xC9, 0x46, 0xD9, 0x84, 0xD8, 0xA7, + 0xD9, 0x93, 0xC9, 0x46, 0xD9, 0x84, 0xD8, 0xA7, + 0xD9, 0x94, 0xC9, 0x46, 0xD9, 0x84, 0xD8, 0xA7, + 0xD9, 0x95, 0xB5, 0x46, 0xE1, 0x84, 0x80, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x82, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x83, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x85, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x86, 0xE1, + // Bytes 2e40 - 2e7f + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x87, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x89, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x8B, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x8B, 0xE1, + 0x85, 0xAE, 0x01, 0x46, 0xE1, 0x84, 0x8C, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x8E, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x8F, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x90, 0xE1, + // Bytes 2e80 - 2ebf + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x91, 0xE1, + 0x85, 0xA1, 0x01, 0x46, 0xE1, 0x84, 0x92, 0xE1, + 0x85, 0xA1, 0x01, 0x49, 0xE3, 0x83, 0xA1, 0xE3, + 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x0D, 0x4C, 0xE1, + 0x84, 0x8C, 0xE1, 0x85, 0xAE, 0xE1, 0x84, 0x8B, + 0xE1, 0x85, 0xB4, 0x01, 0x4C, 0xE3, 0x82, 0xAD, + 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xAB, 0xE3, 0x82, + 0x99, 0x0D, 0x4C, 0xE3, 0x82, 0xB3, 0xE3, 0x83, + // Bytes 2ec0 - 2eff + 0xBC, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x0D, + 0x4C, 0xE3, 0x83, 0xA4, 0xE3, 0x83, 0xBC, 0xE3, + 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, 0x4F, 0xE1, + 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0xE1, 0x86, 0xB7, + 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA9, 0x01, 0x4F, + 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0x8B, 0xE3, 0x83, + 0xB3, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x0D, + 0x4F, 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xAA, 0xE3, + // Bytes 2f00 - 2f3f + 0x83, 0xB3, 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, + 0x0D, 0x4F, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, + 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xB7, 0xE3, 0x82, + 0x99, 0x0D, 0x4F, 0xE3, 0x83, 0x9B, 0xE3, 0x82, + 0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88, 0xE3, + 0x82, 0x99, 0x0D, 0x52, 0xE3, 0x82, 0xA8, 0xE3, + 0x82, 0xB9, 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xBC, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x0D, 0x52, + // Bytes 2f40 - 2f7f + 0xE3, 0x83, 0x95, 0xE3, 0x82, 0xA1, 0xE3, 0x83, + 0xA9, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, + 0x82, 0x99, 0x0D, 0x86, 0xE0, 0xB3, 0x86, 0xE0, + 0xB3, 0x82, 0x01, 0x86, 0xE0, 0xB7, 0x99, 0xE0, + 0xB7, 0x8F, 0x01, 0x03, 0x3C, 0xCC, 0xB8, 0x05, + 0x03, 0x3D, 0xCC, 0xB8, 0x05, 0x03, 0x3E, 0xCC, + 0xB8, 0x05, 0x03, 0x41, 0xCC, 0x80, 0xC9, 0x03, + 0x41, 0xCC, 0x81, 0xC9, 0x03, 0x41, 0xCC, 0x83, + // Bytes 2f80 - 2fbf + 0xC9, 0x03, 0x41, 0xCC, 0x84, 0xC9, 0x03, 0x41, + 0xCC, 0x89, 0xC9, 0x03, 0x41, 0xCC, 0x8C, 0xC9, + 0x03, 0x41, 0xCC, 0x8F, 0xC9, 0x03, 0x41, 0xCC, + 0x91, 0xC9, 0x03, 0x41, 0xCC, 0xA5, 0xB5, 0x03, + 0x41, 0xCC, 0xA8, 0xA5, 0x03, 0x42, 0xCC, 0x87, + 0xC9, 0x03, 0x42, 0xCC, 0xA3, 0xB5, 0x03, 0x42, + 0xCC, 0xB1, 0xB5, 0x03, 0x43, 0xCC, 0x81, 0xC9, + 0x03, 0x43, 0xCC, 0x82, 0xC9, 0x03, 0x43, 0xCC, + // Bytes 2fc0 - 2fff + 0x87, 0xC9, 0x03, 0x43, 0xCC, 0x8C, 0xC9, 0x03, + 0x44, 0xCC, 0x87, 0xC9, 0x03, 0x44, 0xCC, 0x8C, + 0xC9, 0x03, 0x44, 0xCC, 0xA3, 0xB5, 0x03, 0x44, + 0xCC, 0xA7, 0xA5, 0x03, 0x44, 0xCC, 0xAD, 0xB5, + 0x03, 0x44, 0xCC, 0xB1, 0xB5, 0x03, 0x45, 0xCC, + 0x80, 0xC9, 0x03, 0x45, 0xCC, 0x81, 0xC9, 0x03, + 0x45, 0xCC, 0x83, 0xC9, 0x03, 0x45, 0xCC, 0x86, + 0xC9, 0x03, 0x45, 0xCC, 0x87, 0xC9, 0x03, 0x45, + // Bytes 3000 - 303f + 0xCC, 0x88, 0xC9, 0x03, 0x45, 0xCC, 0x89, 0xC9, + 0x03, 0x45, 0xCC, 0x8C, 0xC9, 0x03, 0x45, 0xCC, + 0x8F, 0xC9, 0x03, 0x45, 0xCC, 0x91, 0xC9, 0x03, + 0x45, 0xCC, 0xA8, 0xA5, 0x03, 0x45, 0xCC, 0xAD, + 0xB5, 0x03, 0x45, 0xCC, 0xB0, 0xB5, 0x03, 0x46, + 0xCC, 0x87, 0xC9, 0x03, 0x47, 0xCC, 0x81, 0xC9, + 0x03, 0x47, 0xCC, 0x82, 0xC9, 0x03, 0x47, 0xCC, + 0x84, 0xC9, 0x03, 0x47, 0xCC, 0x86, 0xC9, 0x03, + // Bytes 3040 - 307f + 0x47, 0xCC, 0x87, 0xC9, 0x03, 0x47, 0xCC, 0x8C, + 0xC9, 0x03, 0x47, 0xCC, 0xA7, 0xA5, 0x03, 0x48, + 0xCC, 0x82, 0xC9, 0x03, 0x48, 0xCC, 0x87, 0xC9, + 0x03, 0x48, 0xCC, 0x88, 0xC9, 0x03, 0x48, 0xCC, + 0x8C, 0xC9, 0x03, 0x48, 0xCC, 0xA3, 0xB5, 0x03, + 0x48, 0xCC, 0xA7, 0xA5, 0x03, 0x48, 0xCC, 0xAE, + 0xB5, 0x03, 0x49, 0xCC, 0x80, 0xC9, 0x03, 0x49, + 0xCC, 0x81, 0xC9, 0x03, 0x49, 0xCC, 0x82, 0xC9, + // Bytes 3080 - 30bf + 0x03, 0x49, 0xCC, 0x83, 0xC9, 0x03, 0x49, 0xCC, + 0x84, 0xC9, 0x03, 0x49, 0xCC, 0x86, 0xC9, 0x03, + 0x49, 0xCC, 0x87, 0xC9, 0x03, 0x49, 0xCC, 0x89, + 0xC9, 0x03, 0x49, 0xCC, 0x8C, 0xC9, 0x03, 0x49, + 0xCC, 0x8F, 0xC9, 0x03, 0x49, 0xCC, 0x91, 0xC9, + 0x03, 0x49, 0xCC, 0xA3, 0xB5, 0x03, 0x49, 0xCC, + 0xA8, 0xA5, 0x03, 0x49, 0xCC, 0xB0, 0xB5, 0x03, + 0x4A, 0xCC, 0x82, 0xC9, 0x03, 0x4B, 0xCC, 0x81, + // Bytes 30c0 - 30ff + 0xC9, 0x03, 0x4B, 0xCC, 0x8C, 0xC9, 0x03, 0x4B, + 0xCC, 0xA3, 0xB5, 0x03, 0x4B, 0xCC, 0xA7, 0xA5, + 0x03, 0x4B, 0xCC, 0xB1, 0xB5, 0x03, 0x4C, 0xCC, + 0x81, 0xC9, 0x03, 0x4C, 0xCC, 0x8C, 0xC9, 0x03, + 0x4C, 0xCC, 0xA7, 0xA5, 0x03, 0x4C, 0xCC, 0xAD, + 0xB5, 0x03, 0x4C, 0xCC, 0xB1, 0xB5, 0x03, 0x4D, + 0xCC, 0x81, 0xC9, 0x03, 0x4D, 0xCC, 0x87, 0xC9, + 0x03, 0x4D, 0xCC, 0xA3, 0xB5, 0x03, 0x4E, 0xCC, + // Bytes 3100 - 313f + 0x80, 0xC9, 0x03, 0x4E, 0xCC, 0x81, 0xC9, 0x03, + 0x4E, 0xCC, 0x83, 0xC9, 0x03, 0x4E, 0xCC, 0x87, + 0xC9, 0x03, 0x4E, 0xCC, 0x8C, 0xC9, 0x03, 0x4E, + 0xCC, 0xA3, 0xB5, 0x03, 0x4E, 0xCC, 0xA7, 0xA5, + 0x03, 0x4E, 0xCC, 0xAD, 0xB5, 0x03, 0x4E, 0xCC, + 0xB1, 0xB5, 0x03, 0x4F, 0xCC, 0x80, 0xC9, 0x03, + 0x4F, 0xCC, 0x81, 0xC9, 0x03, 0x4F, 0xCC, 0x86, + 0xC9, 0x03, 0x4F, 0xCC, 0x89, 0xC9, 0x03, 0x4F, + // Bytes 3140 - 317f + 0xCC, 0x8B, 0xC9, 0x03, 0x4F, 0xCC, 0x8C, 0xC9, + 0x03, 0x4F, 0xCC, 0x8F, 0xC9, 0x03, 0x4F, 0xCC, + 0x91, 0xC9, 0x03, 0x50, 0xCC, 0x81, 0xC9, 0x03, + 0x50, 0xCC, 0x87, 0xC9, 0x03, 0x52, 0xCC, 0x81, + 0xC9, 0x03, 0x52, 0xCC, 0x87, 0xC9, 0x03, 0x52, + 0xCC, 0x8C, 0xC9, 0x03, 0x52, 0xCC, 0x8F, 0xC9, + 0x03, 0x52, 0xCC, 0x91, 0xC9, 0x03, 0x52, 0xCC, + 0xA7, 0xA5, 0x03, 0x52, 0xCC, 0xB1, 0xB5, 0x03, + // Bytes 3180 - 31bf + 0x53, 0xCC, 0x82, 0xC9, 0x03, 0x53, 0xCC, 0x87, + 0xC9, 0x03, 0x53, 0xCC, 0xA6, 0xB5, 0x03, 0x53, + 0xCC, 0xA7, 0xA5, 0x03, 0x54, 0xCC, 0x87, 0xC9, + 0x03, 0x54, 0xCC, 0x8C, 0xC9, 0x03, 0x54, 0xCC, + 0xA3, 0xB5, 0x03, 0x54, 0xCC, 0xA6, 0xB5, 0x03, + 0x54, 0xCC, 0xA7, 0xA5, 0x03, 0x54, 0xCC, 0xAD, + 0xB5, 0x03, 0x54, 0xCC, 0xB1, 0xB5, 0x03, 0x55, + 0xCC, 0x80, 0xC9, 0x03, 0x55, 0xCC, 0x81, 0xC9, + // Bytes 31c0 - 31ff + 0x03, 0x55, 0xCC, 0x82, 0xC9, 0x03, 0x55, 0xCC, + 0x86, 0xC9, 0x03, 0x55, 0xCC, 0x89, 0xC9, 0x03, + 0x55, 0xCC, 0x8A, 0xC9, 0x03, 0x55, 0xCC, 0x8B, + 0xC9, 0x03, 0x55, 0xCC, 0x8C, 0xC9, 0x03, 0x55, + 0xCC, 0x8F, 0xC9, 0x03, 0x55, 0xCC, 0x91, 0xC9, + 0x03, 0x55, 0xCC, 0xA3, 0xB5, 0x03, 0x55, 0xCC, + 0xA4, 0xB5, 0x03, 0x55, 0xCC, 0xA8, 0xA5, 0x03, + 0x55, 0xCC, 0xAD, 0xB5, 0x03, 0x55, 0xCC, 0xB0, + // Bytes 3200 - 323f + 0xB5, 0x03, 0x56, 0xCC, 0x83, 0xC9, 0x03, 0x56, + 0xCC, 0xA3, 0xB5, 0x03, 0x57, 0xCC, 0x80, 0xC9, + 0x03, 0x57, 0xCC, 0x81, 0xC9, 0x03, 0x57, 0xCC, + 0x82, 0xC9, 0x03, 0x57, 0xCC, 0x87, 0xC9, 0x03, + 0x57, 0xCC, 0x88, 0xC9, 0x03, 0x57, 0xCC, 0xA3, + 0xB5, 0x03, 0x58, 0xCC, 0x87, 0xC9, 0x03, 0x58, + 0xCC, 0x88, 0xC9, 0x03, 0x59, 0xCC, 0x80, 0xC9, + 0x03, 0x59, 0xCC, 0x81, 0xC9, 0x03, 0x59, 0xCC, + // Bytes 3240 - 327f + 0x82, 0xC9, 0x03, 0x59, 0xCC, 0x83, 0xC9, 0x03, + 0x59, 0xCC, 0x84, 0xC9, 0x03, 0x59, 0xCC, 0x87, + 0xC9, 0x03, 0x59, 0xCC, 0x88, 0xC9, 0x03, 0x59, + 0xCC, 0x89, 0xC9, 0x03, 0x59, 0xCC, 0xA3, 0xB5, + 0x03, 0x5A, 0xCC, 0x81, 0xC9, 0x03, 0x5A, 0xCC, + 0x82, 0xC9, 0x03, 0x5A, 0xCC, 0x87, 0xC9, 0x03, + 0x5A, 0xCC, 0x8C, 0xC9, 0x03, 0x5A, 0xCC, 0xA3, + 0xB5, 0x03, 0x5A, 0xCC, 0xB1, 0xB5, 0x03, 0x61, + // Bytes 3280 - 32bf + 0xCC, 0x80, 0xC9, 0x03, 0x61, 0xCC, 0x81, 0xC9, + 0x03, 0x61, 0xCC, 0x83, 0xC9, 0x03, 0x61, 0xCC, + 0x84, 0xC9, 0x03, 0x61, 0xCC, 0x89, 0xC9, 0x03, + 0x61, 0xCC, 0x8C, 0xC9, 0x03, 0x61, 0xCC, 0x8F, + 0xC9, 0x03, 0x61, 0xCC, 0x91, 0xC9, 0x03, 0x61, + 0xCC, 0xA5, 0xB5, 0x03, 0x61, 0xCC, 0xA8, 0xA5, + 0x03, 0x62, 0xCC, 0x87, 0xC9, 0x03, 0x62, 0xCC, + 0xA3, 0xB5, 0x03, 0x62, 0xCC, 0xB1, 0xB5, 0x03, + // Bytes 32c0 - 32ff + 0x63, 0xCC, 0x81, 0xC9, 0x03, 0x63, 0xCC, 0x82, + 0xC9, 0x03, 0x63, 0xCC, 0x87, 0xC9, 0x03, 0x63, + 0xCC, 0x8C, 0xC9, 0x03, 0x64, 0xCC, 0x87, 0xC9, + 0x03, 0x64, 0xCC, 0x8C, 0xC9, 0x03, 0x64, 0xCC, + 0xA3, 0xB5, 0x03, 0x64, 0xCC, 0xA7, 0xA5, 0x03, + 0x64, 0xCC, 0xAD, 0xB5, 0x03, 0x64, 0xCC, 0xB1, + 0xB5, 0x03, 0x65, 0xCC, 0x80, 0xC9, 0x03, 0x65, + 0xCC, 0x81, 0xC9, 0x03, 0x65, 0xCC, 0x83, 0xC9, + // Bytes 3300 - 333f + 0x03, 0x65, 0xCC, 0x86, 0xC9, 0x03, 0x65, 0xCC, + 0x87, 0xC9, 0x03, 0x65, 0xCC, 0x88, 0xC9, 0x03, + 0x65, 0xCC, 0x89, 0xC9, 0x03, 0x65, 0xCC, 0x8C, + 0xC9, 0x03, 0x65, 0xCC, 0x8F, 0xC9, 0x03, 0x65, + 0xCC, 0x91, 0xC9, 0x03, 0x65, 0xCC, 0xA8, 0xA5, + 0x03, 0x65, 0xCC, 0xAD, 0xB5, 0x03, 0x65, 0xCC, + 0xB0, 0xB5, 0x03, 0x66, 0xCC, 0x87, 0xC9, 0x03, + 0x67, 0xCC, 0x81, 0xC9, 0x03, 0x67, 0xCC, 0x82, + // Bytes 3340 - 337f + 0xC9, 0x03, 0x67, 0xCC, 0x84, 0xC9, 0x03, 0x67, + 0xCC, 0x86, 0xC9, 0x03, 0x67, 0xCC, 0x87, 0xC9, + 0x03, 0x67, 0xCC, 0x8C, 0xC9, 0x03, 0x67, 0xCC, + 0xA7, 0xA5, 0x03, 0x68, 0xCC, 0x82, 0xC9, 0x03, + 0x68, 0xCC, 0x87, 0xC9, 0x03, 0x68, 0xCC, 0x88, + 0xC9, 0x03, 0x68, 0xCC, 0x8C, 0xC9, 0x03, 0x68, + 0xCC, 0xA3, 0xB5, 0x03, 0x68, 0xCC, 0xA7, 0xA5, + 0x03, 0x68, 0xCC, 0xAE, 0xB5, 0x03, 0x68, 0xCC, + // Bytes 3380 - 33bf + 0xB1, 0xB5, 0x03, 0x69, 0xCC, 0x80, 0xC9, 0x03, + 0x69, 0xCC, 0x81, 0xC9, 0x03, 0x69, 0xCC, 0x82, + 0xC9, 0x03, 0x69, 0xCC, 0x83, 0xC9, 0x03, 0x69, + 0xCC, 0x84, 0xC9, 0x03, 0x69, 0xCC, 0x86, 0xC9, + 0x03, 0x69, 0xCC, 0x89, 0xC9, 0x03, 0x69, 0xCC, + 0x8C, 0xC9, 0x03, 0x69, 0xCC, 0x8F, 0xC9, 0x03, + 0x69, 0xCC, 0x91, 0xC9, 0x03, 0x69, 0xCC, 0xA3, + 0xB5, 0x03, 0x69, 0xCC, 0xA8, 0xA5, 0x03, 0x69, + // Bytes 33c0 - 33ff + 0xCC, 0xB0, 0xB5, 0x03, 0x6A, 0xCC, 0x82, 0xC9, + 0x03, 0x6A, 0xCC, 0x8C, 0xC9, 0x03, 0x6B, 0xCC, + 0x81, 0xC9, 0x03, 0x6B, 0xCC, 0x8C, 0xC9, 0x03, + 0x6B, 0xCC, 0xA3, 0xB5, 0x03, 0x6B, 0xCC, 0xA7, + 0xA5, 0x03, 0x6B, 0xCC, 0xB1, 0xB5, 0x03, 0x6C, + 0xCC, 0x81, 0xC9, 0x03, 0x6C, 0xCC, 0x8C, 0xC9, + 0x03, 0x6C, 0xCC, 0xA7, 0xA5, 0x03, 0x6C, 0xCC, + 0xAD, 0xB5, 0x03, 0x6C, 0xCC, 0xB1, 0xB5, 0x03, + // Bytes 3400 - 343f + 0x6D, 0xCC, 0x81, 0xC9, 0x03, 0x6D, 0xCC, 0x87, + 0xC9, 0x03, 0x6D, 0xCC, 0xA3, 0xB5, 0x03, 0x6E, + 0xCC, 0x80, 0xC9, 0x03, 0x6E, 0xCC, 0x81, 0xC9, + 0x03, 0x6E, 0xCC, 0x83, 0xC9, 0x03, 0x6E, 0xCC, + 0x87, 0xC9, 0x03, 0x6E, 0xCC, 0x8C, 0xC9, 0x03, + 0x6E, 0xCC, 0xA3, 0xB5, 0x03, 0x6E, 0xCC, 0xA7, + 0xA5, 0x03, 0x6E, 0xCC, 0xAD, 0xB5, 0x03, 0x6E, + 0xCC, 0xB1, 0xB5, 0x03, 0x6F, 0xCC, 0x80, 0xC9, + // Bytes 3440 - 347f + 0x03, 0x6F, 0xCC, 0x81, 0xC9, 0x03, 0x6F, 0xCC, + 0x86, 0xC9, 0x03, 0x6F, 0xCC, 0x89, 0xC9, 0x03, + 0x6F, 0xCC, 0x8B, 0xC9, 0x03, 0x6F, 0xCC, 0x8C, + 0xC9, 0x03, 0x6F, 0xCC, 0x8F, 0xC9, 0x03, 0x6F, + 0xCC, 0x91, 0xC9, 0x03, 0x70, 0xCC, 0x81, 0xC9, + 0x03, 0x70, 0xCC, 0x87, 0xC9, 0x03, 0x72, 0xCC, + 0x81, 0xC9, 0x03, 0x72, 0xCC, 0x87, 0xC9, 0x03, + 0x72, 0xCC, 0x8C, 0xC9, 0x03, 0x72, 0xCC, 0x8F, + // Bytes 3480 - 34bf + 0xC9, 0x03, 0x72, 0xCC, 0x91, 0xC9, 0x03, 0x72, + 0xCC, 0xA7, 0xA5, 0x03, 0x72, 0xCC, 0xB1, 0xB5, + 0x03, 0x73, 0xCC, 0x82, 0xC9, 0x03, 0x73, 0xCC, + 0x87, 0xC9, 0x03, 0x73, 0xCC, 0xA6, 0xB5, 0x03, + 0x73, 0xCC, 0xA7, 0xA5, 0x03, 0x74, 0xCC, 0x87, + 0xC9, 0x03, 0x74, 0xCC, 0x88, 0xC9, 0x03, 0x74, + 0xCC, 0x8C, 0xC9, 0x03, 0x74, 0xCC, 0xA3, 0xB5, + 0x03, 0x74, 0xCC, 0xA6, 0xB5, 0x03, 0x74, 0xCC, + // Bytes 34c0 - 34ff + 0xA7, 0xA5, 0x03, 0x74, 0xCC, 0xAD, 0xB5, 0x03, + 0x74, 0xCC, 0xB1, 0xB5, 0x03, 0x75, 0xCC, 0x80, + 0xC9, 0x03, 0x75, 0xCC, 0x81, 0xC9, 0x03, 0x75, + 0xCC, 0x82, 0xC9, 0x03, 0x75, 0xCC, 0x86, 0xC9, + 0x03, 0x75, 0xCC, 0x89, 0xC9, 0x03, 0x75, 0xCC, + 0x8A, 0xC9, 0x03, 0x75, 0xCC, 0x8B, 0xC9, 0x03, + 0x75, 0xCC, 0x8C, 0xC9, 0x03, 0x75, 0xCC, 0x8F, + 0xC9, 0x03, 0x75, 0xCC, 0x91, 0xC9, 0x03, 0x75, + // Bytes 3500 - 353f + 0xCC, 0xA3, 0xB5, 0x03, 0x75, 0xCC, 0xA4, 0xB5, + 0x03, 0x75, 0xCC, 0xA8, 0xA5, 0x03, 0x75, 0xCC, + 0xAD, 0xB5, 0x03, 0x75, 0xCC, 0xB0, 0xB5, 0x03, + 0x76, 0xCC, 0x83, 0xC9, 0x03, 0x76, 0xCC, 0xA3, + 0xB5, 0x03, 0x77, 0xCC, 0x80, 0xC9, 0x03, 0x77, + 0xCC, 0x81, 0xC9, 0x03, 0x77, 0xCC, 0x82, 0xC9, + 0x03, 0x77, 0xCC, 0x87, 0xC9, 0x03, 0x77, 0xCC, + 0x88, 0xC9, 0x03, 0x77, 0xCC, 0x8A, 0xC9, 0x03, + // Bytes 3540 - 357f + 0x77, 0xCC, 0xA3, 0xB5, 0x03, 0x78, 0xCC, 0x87, + 0xC9, 0x03, 0x78, 0xCC, 0x88, 0xC9, 0x03, 0x79, + 0xCC, 0x80, 0xC9, 0x03, 0x79, 0xCC, 0x81, 0xC9, + 0x03, 0x79, 0xCC, 0x82, 0xC9, 0x03, 0x79, 0xCC, + 0x83, 0xC9, 0x03, 0x79, 0xCC, 0x84, 0xC9, 0x03, + 0x79, 0xCC, 0x87, 0xC9, 0x03, 0x79, 0xCC, 0x88, + 0xC9, 0x03, 0x79, 0xCC, 0x89, 0xC9, 0x03, 0x79, + 0xCC, 0x8A, 0xC9, 0x03, 0x79, 0xCC, 0xA3, 0xB5, + // Bytes 3580 - 35bf + 0x03, 0x7A, 0xCC, 0x81, 0xC9, 0x03, 0x7A, 0xCC, + 0x82, 0xC9, 0x03, 0x7A, 0xCC, 0x87, 0xC9, 0x03, + 0x7A, 0xCC, 0x8C, 0xC9, 0x03, 0x7A, 0xCC, 0xA3, + 0xB5, 0x03, 0x7A, 0xCC, 0xB1, 0xB5, 0x04, 0xC2, + 0xA8, 0xCC, 0x80, 0xCA, 0x04, 0xC2, 0xA8, 0xCC, + 0x81, 0xCA, 0x04, 0xC2, 0xA8, 0xCD, 0x82, 0xCA, + 0x04, 0xC3, 0x86, 0xCC, 0x81, 0xC9, 0x04, 0xC3, + 0x86, 0xCC, 0x84, 0xC9, 0x04, 0xC3, 0x98, 0xCC, + // Bytes 35c0 - 35ff + 0x81, 0xC9, 0x04, 0xC3, 0xA6, 0xCC, 0x81, 0xC9, + 0x04, 0xC3, 0xA6, 0xCC, 0x84, 0xC9, 0x04, 0xC3, + 0xB8, 0xCC, 0x81, 0xC9, 0x04, 0xC5, 0xBF, 0xCC, + 0x87, 0xC9, 0x04, 0xC6, 0xB7, 0xCC, 0x8C, 0xC9, + 0x04, 0xCA, 0x92, 0xCC, 0x8C, 0xC9, 0x04, 0xCE, + 0x91, 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0x91, 0xCC, + 0x81, 0xC9, 0x04, 0xCE, 0x91, 0xCC, 0x84, 0xC9, + 0x04, 0xCE, 0x91, 0xCC, 0x86, 0xC9, 0x04, 0xCE, + // Bytes 3600 - 363f + 0x91, 0xCD, 0x85, 0xD9, 0x04, 0xCE, 0x95, 0xCC, + 0x80, 0xC9, 0x04, 0xCE, 0x95, 0xCC, 0x81, 0xC9, + 0x04, 0xCE, 0x97, 0xCC, 0x80, 0xC9, 0x04, 0xCE, + 0x97, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0x97, 0xCD, + 0x85, 0xD9, 0x04, 0xCE, 0x99, 0xCC, 0x80, 0xC9, + 0x04, 0xCE, 0x99, 0xCC, 0x81, 0xC9, 0x04, 0xCE, + 0x99, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0x99, 0xCC, + 0x86, 0xC9, 0x04, 0xCE, 0x99, 0xCC, 0x88, 0xC9, + // Bytes 3640 - 367f + 0x04, 0xCE, 0x9F, 0xCC, 0x80, 0xC9, 0x04, 0xCE, + 0x9F, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0xA1, 0xCC, + 0x94, 0xC9, 0x04, 0xCE, 0xA5, 0xCC, 0x80, 0xC9, + 0x04, 0xCE, 0xA5, 0xCC, 0x81, 0xC9, 0x04, 0xCE, + 0xA5, 0xCC, 0x84, 0xC9, 0x04, 0xCE, 0xA5, 0xCC, + 0x86, 0xC9, 0x04, 0xCE, 0xA5, 0xCC, 0x88, 0xC9, + 0x04, 0xCE, 0xA9, 0xCC, 0x80, 0xC9, 0x04, 0xCE, + 0xA9, 0xCC, 0x81, 0xC9, 0x04, 0xCE, 0xA9, 0xCD, + // Bytes 3680 - 36bf + 0x85, 0xD9, 0x04, 0xCE, 0xB1, 0xCC, 0x84, 0xC9, + 0x04, 0xCE, 0xB1, 0xCC, 0x86, 0xC9, 0x04, 0xCE, + 0xB1, 0xCD, 0x85, 0xD9, 0x04, 0xCE, 0xB5, 0xCC, + 0x80, 0xC9, 0x04, 0xCE, 0xB5, 0xCC, 0x81, 0xC9, + 0x04, 0xCE, 0xB7, 0xCD, 0x85, 0xD9, 0x04, 0xCE, + 0xB9, 0xCC, 0x80, 0xC9, 0x04, 0xCE, 0xB9, 0xCC, + 0x81, 0xC9, 0x04, 0xCE, 0xB9, 0xCC, 0x84, 0xC9, + 0x04, 0xCE, 0xB9, 0xCC, 0x86, 0xC9, 0x04, 0xCE, + // Bytes 36c0 - 36ff + 0xB9, 0xCD, 0x82, 0xC9, 0x04, 0xCE, 0xBF, 0xCC, + 0x80, 0xC9, 0x04, 0xCE, 0xBF, 0xCC, 0x81, 0xC9, + 0x04, 0xCF, 0x81, 0xCC, 0x93, 0xC9, 0x04, 0xCF, + 0x81, 0xCC, 0x94, 0xC9, 0x04, 0xCF, 0x85, 0xCC, + 0x80, 0xC9, 0x04, 0xCF, 0x85, 0xCC, 0x81, 0xC9, + 0x04, 0xCF, 0x85, 0xCC, 0x84, 0xC9, 0x04, 0xCF, + 0x85, 0xCC, 0x86, 0xC9, 0x04, 0xCF, 0x85, 0xCD, + 0x82, 0xC9, 0x04, 0xCF, 0x89, 0xCD, 0x85, 0xD9, + // Bytes 3700 - 373f + 0x04, 0xCF, 0x92, 0xCC, 0x81, 0xC9, 0x04, 0xCF, + 0x92, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0x86, 0xCC, + 0x88, 0xC9, 0x04, 0xD0, 0x90, 0xCC, 0x86, 0xC9, + 0x04, 0xD0, 0x90, 0xCC, 0x88, 0xC9, 0x04, 0xD0, + 0x93, 0xCC, 0x81, 0xC9, 0x04, 0xD0, 0x95, 0xCC, + 0x80, 0xC9, 0x04, 0xD0, 0x95, 0xCC, 0x86, 0xC9, + 0x04, 0xD0, 0x95, 0xCC, 0x88, 0xC9, 0x04, 0xD0, + 0x96, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0x96, 0xCC, + // Bytes 3740 - 377f + 0x88, 0xC9, 0x04, 0xD0, 0x97, 0xCC, 0x88, 0xC9, + 0x04, 0xD0, 0x98, 0xCC, 0x80, 0xC9, 0x04, 0xD0, + 0x98, 0xCC, 0x84, 0xC9, 0x04, 0xD0, 0x98, 0xCC, + 0x86, 0xC9, 0x04, 0xD0, 0x98, 0xCC, 0x88, 0xC9, + 0x04, 0xD0, 0x9A, 0xCC, 0x81, 0xC9, 0x04, 0xD0, + 0x9E, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xA3, 0xCC, + 0x84, 0xC9, 0x04, 0xD0, 0xA3, 0xCC, 0x86, 0xC9, + 0x04, 0xD0, 0xA3, 0xCC, 0x88, 0xC9, 0x04, 0xD0, + // Bytes 3780 - 37bf + 0xA3, 0xCC, 0x8B, 0xC9, 0x04, 0xD0, 0xA7, 0xCC, + 0x88, 0xC9, 0x04, 0xD0, 0xAB, 0xCC, 0x88, 0xC9, + 0x04, 0xD0, 0xAD, 0xCC, 0x88, 0xC9, 0x04, 0xD0, + 0xB0, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xB0, 0xCC, + 0x88, 0xC9, 0x04, 0xD0, 0xB3, 0xCC, 0x81, 0xC9, + 0x04, 0xD0, 0xB5, 0xCC, 0x80, 0xC9, 0x04, 0xD0, + 0xB5, 0xCC, 0x86, 0xC9, 0x04, 0xD0, 0xB5, 0xCC, + 0x88, 0xC9, 0x04, 0xD0, 0xB6, 0xCC, 0x86, 0xC9, + // Bytes 37c0 - 37ff + 0x04, 0xD0, 0xB6, 0xCC, 0x88, 0xC9, 0x04, 0xD0, + 0xB7, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xB8, 0xCC, + 0x80, 0xC9, 0x04, 0xD0, 0xB8, 0xCC, 0x84, 0xC9, + 0x04, 0xD0, 0xB8, 0xCC, 0x86, 0xC9, 0x04, 0xD0, + 0xB8, 0xCC, 0x88, 0xC9, 0x04, 0xD0, 0xBA, 0xCC, + 0x81, 0xC9, 0x04, 0xD0, 0xBE, 0xCC, 0x88, 0xC9, + 0x04, 0xD1, 0x83, 0xCC, 0x84, 0xC9, 0x04, 0xD1, + 0x83, 0xCC, 0x86, 0xC9, 0x04, 0xD1, 0x83, 0xCC, + // Bytes 3800 - 383f + 0x88, 0xC9, 0x04, 0xD1, 0x83, 0xCC, 0x8B, 0xC9, + 0x04, 0xD1, 0x87, 0xCC, 0x88, 0xC9, 0x04, 0xD1, + 0x8B, 0xCC, 0x88, 0xC9, 0x04, 0xD1, 0x8D, 0xCC, + 0x88, 0xC9, 0x04, 0xD1, 0x96, 0xCC, 0x88, 0xC9, + 0x04, 0xD1, 0xB4, 0xCC, 0x8F, 0xC9, 0x04, 0xD1, + 0xB5, 0xCC, 0x8F, 0xC9, 0x04, 0xD3, 0x98, 0xCC, + 0x88, 0xC9, 0x04, 0xD3, 0x99, 0xCC, 0x88, 0xC9, + 0x04, 0xD3, 0xA8, 0xCC, 0x88, 0xC9, 0x04, 0xD3, + // Bytes 3840 - 387f + 0xA9, 0xCC, 0x88, 0xC9, 0x04, 0xD8, 0xA7, 0xD9, + 0x93, 0xC9, 0x04, 0xD8, 0xA7, 0xD9, 0x94, 0xC9, + 0x04, 0xD8, 0xA7, 0xD9, 0x95, 0xB5, 0x04, 0xD9, + 0x88, 0xD9, 0x94, 0xC9, 0x04, 0xD9, 0x8A, 0xD9, + 0x94, 0xC9, 0x04, 0xDB, 0x81, 0xD9, 0x94, 0xC9, + 0x04, 0xDB, 0x92, 0xD9, 0x94, 0xC9, 0x04, 0xDB, + 0x95, 0xD9, 0x94, 0xC9, 0x05, 0x41, 0xCC, 0x82, + 0xCC, 0x80, 0xCA, 0x05, 0x41, 0xCC, 0x82, 0xCC, + // Bytes 3880 - 38bf + 0x81, 0xCA, 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x83, + 0xCA, 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x89, 0xCA, + 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x80, 0xCA, 0x05, + 0x41, 0xCC, 0x86, 0xCC, 0x81, 0xCA, 0x05, 0x41, + 0xCC, 0x86, 0xCC, 0x83, 0xCA, 0x05, 0x41, 0xCC, + 0x86, 0xCC, 0x89, 0xCA, 0x05, 0x41, 0xCC, 0x87, + 0xCC, 0x84, 0xCA, 0x05, 0x41, 0xCC, 0x88, 0xCC, + 0x84, 0xCA, 0x05, 0x41, 0xCC, 0x8A, 0xCC, 0x81, + // Bytes 38c0 - 38ff + 0xCA, 0x05, 0x41, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, + 0x05, 0x41, 0xCC, 0xA3, 0xCC, 0x86, 0xCA, 0x05, + 0x43, 0xCC, 0xA7, 0xCC, 0x81, 0xCA, 0x05, 0x45, + 0xCC, 0x82, 0xCC, 0x80, 0xCA, 0x05, 0x45, 0xCC, + 0x82, 0xCC, 0x81, 0xCA, 0x05, 0x45, 0xCC, 0x82, + 0xCC, 0x83, 0xCA, 0x05, 0x45, 0xCC, 0x82, 0xCC, + 0x89, 0xCA, 0x05, 0x45, 0xCC, 0x84, 0xCC, 0x80, + 0xCA, 0x05, 0x45, 0xCC, 0x84, 0xCC, 0x81, 0xCA, + // Bytes 3900 - 393f + 0x05, 0x45, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, + 0x45, 0xCC, 0xA7, 0xCC, 0x86, 0xCA, 0x05, 0x49, + 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x05, 0x4C, 0xCC, + 0xA3, 0xCC, 0x84, 0xCA, 0x05, 0x4F, 0xCC, 0x82, + 0xCC, 0x80, 0xCA, 0x05, 0x4F, 0xCC, 0x82, 0xCC, + 0x81, 0xCA, 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x83, + 0xCA, 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x89, 0xCA, + 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x81, 0xCA, 0x05, + // Bytes 3940 - 397f + 0x4F, 0xCC, 0x83, 0xCC, 0x84, 0xCA, 0x05, 0x4F, + 0xCC, 0x83, 0xCC, 0x88, 0xCA, 0x05, 0x4F, 0xCC, + 0x84, 0xCC, 0x80, 0xCA, 0x05, 0x4F, 0xCC, 0x84, + 0xCC, 0x81, 0xCA, 0x05, 0x4F, 0xCC, 0x87, 0xCC, + 0x84, 0xCA, 0x05, 0x4F, 0xCC, 0x88, 0xCC, 0x84, + 0xCA, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x80, 0xCA, + 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x81, 0xCA, 0x05, + 0x4F, 0xCC, 0x9B, 0xCC, 0x83, 0xCA, 0x05, 0x4F, + // Bytes 3980 - 39bf + 0xCC, 0x9B, 0xCC, 0x89, 0xCA, 0x05, 0x4F, 0xCC, + 0x9B, 0xCC, 0xA3, 0xB6, 0x05, 0x4F, 0xCC, 0xA3, + 0xCC, 0x82, 0xCA, 0x05, 0x4F, 0xCC, 0xA8, 0xCC, + 0x84, 0xCA, 0x05, 0x52, 0xCC, 0xA3, 0xCC, 0x84, + 0xCA, 0x05, 0x53, 0xCC, 0x81, 0xCC, 0x87, 0xCA, + 0x05, 0x53, 0xCC, 0x8C, 0xCC, 0x87, 0xCA, 0x05, + 0x53, 0xCC, 0xA3, 0xCC, 0x87, 0xCA, 0x05, 0x55, + 0xCC, 0x83, 0xCC, 0x81, 0xCA, 0x05, 0x55, 0xCC, + // Bytes 39c0 - 39ff + 0x84, 0xCC, 0x88, 0xCA, 0x05, 0x55, 0xCC, 0x88, + 0xCC, 0x80, 0xCA, 0x05, 0x55, 0xCC, 0x88, 0xCC, + 0x81, 0xCA, 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x84, + 0xCA, 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x8C, 0xCA, + 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x80, 0xCA, 0x05, + 0x55, 0xCC, 0x9B, 0xCC, 0x81, 0xCA, 0x05, 0x55, + 0xCC, 0x9B, 0xCC, 0x83, 0xCA, 0x05, 0x55, 0xCC, + 0x9B, 0xCC, 0x89, 0xCA, 0x05, 0x55, 0xCC, 0x9B, + // Bytes 3a00 - 3a3f + 0xCC, 0xA3, 0xB6, 0x05, 0x61, 0xCC, 0x82, 0xCC, + 0x80, 0xCA, 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x81, + 0xCA, 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x83, 0xCA, + 0x05, 0x61, 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, + 0x61, 0xCC, 0x86, 0xCC, 0x80, 0xCA, 0x05, 0x61, + 0xCC, 0x86, 0xCC, 0x81, 0xCA, 0x05, 0x61, 0xCC, + 0x86, 0xCC, 0x83, 0xCA, 0x05, 0x61, 0xCC, 0x86, + 0xCC, 0x89, 0xCA, 0x05, 0x61, 0xCC, 0x87, 0xCC, + // Bytes 3a40 - 3a7f + 0x84, 0xCA, 0x05, 0x61, 0xCC, 0x88, 0xCC, 0x84, + 0xCA, 0x05, 0x61, 0xCC, 0x8A, 0xCC, 0x81, 0xCA, + 0x05, 0x61, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, + 0x61, 0xCC, 0xA3, 0xCC, 0x86, 0xCA, 0x05, 0x63, + 0xCC, 0xA7, 0xCC, 0x81, 0xCA, 0x05, 0x65, 0xCC, + 0x82, 0xCC, 0x80, 0xCA, 0x05, 0x65, 0xCC, 0x82, + 0xCC, 0x81, 0xCA, 0x05, 0x65, 0xCC, 0x82, 0xCC, + 0x83, 0xCA, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x89, + // Bytes 3a80 - 3abf + 0xCA, 0x05, 0x65, 0xCC, 0x84, 0xCC, 0x80, 0xCA, + 0x05, 0x65, 0xCC, 0x84, 0xCC, 0x81, 0xCA, 0x05, + 0x65, 0xCC, 0xA3, 0xCC, 0x82, 0xCA, 0x05, 0x65, + 0xCC, 0xA7, 0xCC, 0x86, 0xCA, 0x05, 0x69, 0xCC, + 0x88, 0xCC, 0x81, 0xCA, 0x05, 0x6C, 0xCC, 0xA3, + 0xCC, 0x84, 0xCA, 0x05, 0x6F, 0xCC, 0x82, 0xCC, + 0x80, 0xCA, 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x81, + 0xCA, 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x83, 0xCA, + // Bytes 3ac0 - 3aff + 0x05, 0x6F, 0xCC, 0x82, 0xCC, 0x89, 0xCA, 0x05, + 0x6F, 0xCC, 0x83, 0xCC, 0x81, 0xCA, 0x05, 0x6F, + 0xCC, 0x83, 0xCC, 0x84, 0xCA, 0x05, 0x6F, 0xCC, + 0x83, 0xCC, 0x88, 0xCA, 0x05, 0x6F, 0xCC, 0x84, + 0xCC, 0x80, 0xCA, 0x05, 0x6F, 0xCC, 0x84, 0xCC, + 0x81, 0xCA, 0x05, 0x6F, 0xCC, 0x87, 0xCC, 0x84, + 0xCA, 0x05, 0x6F, 0xCC, 0x88, 0xCC, 0x84, 0xCA, + 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x80, 0xCA, 0x05, + // Bytes 3b00 - 3b3f + 0x6F, 0xCC, 0x9B, 0xCC, 0x81, 0xCA, 0x05, 0x6F, + 0xCC, 0x9B, 0xCC, 0x83, 0xCA, 0x05, 0x6F, 0xCC, + 0x9B, 0xCC, 0x89, 0xCA, 0x05, 0x6F, 0xCC, 0x9B, + 0xCC, 0xA3, 0xB6, 0x05, 0x6F, 0xCC, 0xA3, 0xCC, + 0x82, 0xCA, 0x05, 0x6F, 0xCC, 0xA8, 0xCC, 0x84, + 0xCA, 0x05, 0x72, 0xCC, 0xA3, 0xCC, 0x84, 0xCA, + 0x05, 0x73, 0xCC, 0x81, 0xCC, 0x87, 0xCA, 0x05, + 0x73, 0xCC, 0x8C, 0xCC, 0x87, 0xCA, 0x05, 0x73, + // Bytes 3b40 - 3b7f + 0xCC, 0xA3, 0xCC, 0x87, 0xCA, 0x05, 0x75, 0xCC, + 0x83, 0xCC, 0x81, 0xCA, 0x05, 0x75, 0xCC, 0x84, + 0xCC, 0x88, 0xCA, 0x05, 0x75, 0xCC, 0x88, 0xCC, + 0x80, 0xCA, 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x81, + 0xCA, 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x84, 0xCA, + 0x05, 0x75, 0xCC, 0x88, 0xCC, 0x8C, 0xCA, 0x05, + 0x75, 0xCC, 0x9B, 0xCC, 0x80, 0xCA, 0x05, 0x75, + 0xCC, 0x9B, 0xCC, 0x81, 0xCA, 0x05, 0x75, 0xCC, + // Bytes 3b80 - 3bbf + 0x9B, 0xCC, 0x83, 0xCA, 0x05, 0x75, 0xCC, 0x9B, + 0xCC, 0x89, 0xCA, 0x05, 0x75, 0xCC, 0x9B, 0xCC, + 0xA3, 0xB6, 0x05, 0xE1, 0xBE, 0xBF, 0xCC, 0x80, + 0xCA, 0x05, 0xE1, 0xBE, 0xBF, 0xCC, 0x81, 0xCA, + 0x05, 0xE1, 0xBE, 0xBF, 0xCD, 0x82, 0xCA, 0x05, + 0xE1, 0xBF, 0xBE, 0xCC, 0x80, 0xCA, 0x05, 0xE1, + 0xBF, 0xBE, 0xCC, 0x81, 0xCA, 0x05, 0xE1, 0xBF, + 0xBE, 0xCD, 0x82, 0xCA, 0x05, 0xE2, 0x86, 0x90, + // Bytes 3bc0 - 3bff + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x86, 0x92, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x86, 0x94, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x87, 0x90, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x87, 0x92, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x87, 0x94, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x88, 0x83, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88, + 0x88, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x8B, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88, 0xA3, 0xCC, + // Bytes 3c00 - 3c3f + 0xB8, 0x05, 0x05, 0xE2, 0x88, 0xA5, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x88, 0xBC, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x89, 0x83, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0x85, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x89, 0x88, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, + 0x8D, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xA1, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xA4, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xA5, 0xCC, 0xB8, + // Bytes 3c40 - 3c7f + 0x05, 0x05, 0xE2, 0x89, 0xB2, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x89, 0xB3, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0xB6, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x89, 0xB7, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, + 0xBA, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xBB, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xBC, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xBD, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x8A, 0x82, 0xCC, 0xB8, 0x05, + // Bytes 3c80 - 3cbf + 0x05, 0xE2, 0x8A, 0x83, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x8A, 0x86, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x8A, 0x87, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + 0x91, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x92, + 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xA2, 0xCC, + 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xA8, 0xCC, 0xB8, + 0x05, 0x05, 0xE2, 0x8A, 0xA9, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x8A, 0xAB, 0xCC, 0xB8, 0x05, 0x05, + // Bytes 3cc0 - 3cff + 0xE2, 0x8A, 0xB2, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x8A, 0xB3, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + 0xB4, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB5, + 0xCC, 0xB8, 0x05, 0x06, 0xCE, 0x91, 0xCC, 0x93, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0x91, 0xCC, 0x94, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0x95, 0xCC, 0x93, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0x95, 0xCC, 0x93, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0x95, 0xCC, 0x94, + // Bytes 3d00 - 3d3f + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0x95, 0xCC, 0x94, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0x97, 0xCC, 0x93, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0x97, 0xCC, 0x94, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0x99, 0xCC, 0x93, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0x99, 0xCC, 0x93, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0x99, 0xCC, 0x93, + 0xCD, 0x82, 0xCA, 0x06, 0xCE, 0x99, 0xCC, 0x94, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0x99, 0xCC, 0x94, + // Bytes 3d40 - 3d7f + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0x99, 0xCC, 0x94, + 0xCD, 0x82, 0xCA, 0x06, 0xCE, 0x9F, 0xCC, 0x93, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0x9F, 0xCC, 0x93, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0x9F, 0xCC, 0x94, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0x9F, 0xCC, 0x94, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0xA5, 0xCC, 0x94, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0xA5, 0xCC, 0x94, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0xA5, 0xCC, 0x94, + // Bytes 3d80 - 3dbf + 0xCD, 0x82, 0xCA, 0x06, 0xCE, 0xA9, 0xCC, 0x93, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xA9, 0xCC, 0x94, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB1, 0xCC, 0x80, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB1, 0xCC, 0x81, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB1, 0xCC, 0x93, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB1, 0xCC, 0x94, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB1, 0xCD, 0x82, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB5, 0xCC, 0x93, + // Bytes 3dc0 - 3dff + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0xB5, 0xCC, 0x93, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0xB5, 0xCC, 0x94, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0xB5, 0xCC, 0x94, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0xB7, 0xCC, 0x80, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB7, 0xCC, 0x81, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB7, 0xCC, 0x93, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB7, 0xCC, 0x94, + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB7, 0xCD, 0x82, + // Bytes 3e00 - 3e3f + 0xCD, 0x85, 0xDA, 0x06, 0xCE, 0xB9, 0xCC, 0x88, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0xB9, 0xCC, 0x88, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0xB9, 0xCC, 0x88, + 0xCD, 0x82, 0xCA, 0x06, 0xCE, 0xB9, 0xCC, 0x93, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0xB9, 0xCC, 0x93, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0xB9, 0xCC, 0x93, + 0xCD, 0x82, 0xCA, 0x06, 0xCE, 0xB9, 0xCC, 0x94, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0xB9, 0xCC, 0x94, + // Bytes 3e40 - 3e7f + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0xB9, 0xCC, 0x94, + 0xCD, 0x82, 0xCA, 0x06, 0xCE, 0xBF, 0xCC, 0x93, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0xBF, 0xCC, 0x93, + 0xCC, 0x81, 0xCA, 0x06, 0xCE, 0xBF, 0xCC, 0x94, + 0xCC, 0x80, 0xCA, 0x06, 0xCE, 0xBF, 0xCC, 0x94, + 0xCC, 0x81, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x88, + 0xCC, 0x80, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x88, + 0xCC, 0x81, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x88, + // Bytes 3e80 - 3ebf + 0xCD, 0x82, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x93, + 0xCC, 0x80, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x93, + 0xCC, 0x81, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x93, + 0xCD, 0x82, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x94, + 0xCC, 0x80, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x94, + 0xCC, 0x81, 0xCA, 0x06, 0xCF, 0x85, 0xCC, 0x94, + 0xCD, 0x82, 0xCA, 0x06, 0xCF, 0x89, 0xCC, 0x80, + 0xCD, 0x85, 0xDA, 0x06, 0xCF, 0x89, 0xCC, 0x81, + // Bytes 3ec0 - 3eff + 0xCD, 0x85, 0xDA, 0x06, 0xCF, 0x89, 0xCC, 0x93, + 0xCD, 0x85, 0xDA, 0x06, 0xCF, 0x89, 0xCC, 0x94, + 0xCD, 0x85, 0xDA, 0x06, 0xCF, 0x89, 0xCD, 0x82, + 0xCD, 0x85, 0xDA, 0x06, 0xE0, 0xA4, 0xA8, 0xE0, + 0xA4, 0xBC, 0x09, 0x06, 0xE0, 0xA4, 0xB0, 0xE0, + 0xA4, 0xBC, 0x09, 0x06, 0xE0, 0xA4, 0xB3, 0xE0, + 0xA4, 0xBC, 0x09, 0x06, 0xE0, 0xB1, 0x86, 0xE0, + 0xB1, 0x96, 0x85, 0x06, 0xE0, 0xB7, 0x99, 0xE0, + // Bytes 3f00 - 3f3f + 0xB7, 0x8A, 0x11, 0x06, 0xE3, 0x81, 0x86, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x8B, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x8D, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x8F, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x91, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x93, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x95, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x97, 0xE3, + // Bytes 3f40 - 3f7f + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x99, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x9B, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x9D, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0x9F, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xA1, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xA4, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xA6, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xA8, 0xE3, + // Bytes 3f80 - 3fbf + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xAF, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xAF, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x81, 0xB2, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xB2, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x81, 0xB5, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xB5, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x81, 0xB8, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xB8, 0xE3, + // Bytes 3fc0 - 3fff + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x81, 0xBB, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x81, 0xBB, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x82, 0x9D, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xA6, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xAB, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xAD, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xAF, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xB1, 0xE3, + // Bytes 4000 - 403f + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xB3, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xB5, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xB7, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xB9, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xBB, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xBD, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x82, 0xBF, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x81, 0xE3, + // Bytes 4040 - 407f + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x84, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x86, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x88, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x8F, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x8F, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x83, 0x92, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x92, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x83, 0x95, 0xE3, + // Bytes 4080 - 40bf + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x95, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x83, 0x98, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x98, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x83, 0x9B, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0x9B, 0xE3, + 0x82, 0x9A, 0x0D, 0x06, 0xE3, 0x83, 0xAF, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0xB0, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0xB1, 0xE3, + // Bytes 40c0 - 40ff + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0xB2, 0xE3, + 0x82, 0x99, 0x0D, 0x06, 0xE3, 0x83, 0xBD, 0xE3, + 0x82, 0x99, 0x0D, 0x08, 0xCE, 0x91, 0xCC, 0x93, + 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x91, + 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, + 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, + 0xDB, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, + 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x91, 0xCC, 0x94, + // Bytes 4100 - 413f + 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x91, + 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, + 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, + 0xDB, 0x08, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x81, + 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x97, 0xCC, 0x93, + 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0x97, + 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, + 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, + // Bytes 4140 - 417f + 0xDB, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x82, + 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x93, + 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xA9, + 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, + 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, + 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x80, + 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xA9, 0xCC, 0x94, + 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xA9, + // Bytes 4180 - 41bf + 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, + 0xCE, 0xB1, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, + 0xDB, 0x08, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, 0x81, + 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB1, 0xCC, 0x93, + 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB1, + 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, + 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, + 0xDB, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, + // Bytes 41c0 - 41ff + 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x93, + 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB7, + 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, + 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, + 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x80, + 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB7, 0xCC, 0x94, + 0xCC, 0x81, 0xCD, 0x85, 0xDB, 0x08, 0xCE, 0xB7, + 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, + // Bytes 4200 - 423f + 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, + 0xDB, 0x08, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x81, + 0xCD, 0x85, 0xDB, 0x08, 0xCF, 0x89, 0xCC, 0x93, + 0xCD, 0x82, 0xCD, 0x85, 0xDB, 0x08, 0xCF, 0x89, + 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDB, 0x08, + 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, + 0xDB, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82, + 0xCD, 0x85, 0xDB, 0x08, 0xF0, 0x91, 0x82, 0x99, + // Bytes 4240 - 427f + 0xF0, 0x91, 0x82, 0xBA, 0x09, 0x08, 0xF0, 0x91, + 0x82, 0x9B, 0xF0, 0x91, 0x82, 0xBA, 0x09, 0x08, + 0xF0, 0x91, 0x82, 0xA5, 0xF0, 0x91, 0x82, 0xBA, + 0x09, 0x42, 0xC2, 0xB4, 0x01, 0x43, 0x20, 0xCC, + 0x81, 0xC9, 0x43, 0x20, 0xCC, 0x83, 0xC9, 0x43, + 0x20, 0xCC, 0x84, 0xC9, 0x43, 0x20, 0xCC, 0x85, + 0xC9, 0x43, 0x20, 0xCC, 0x86, 0xC9, 0x43, 0x20, + 0xCC, 0x87, 0xC9, 0x43, 0x20, 0xCC, 0x88, 0xC9, + // Bytes 4280 - 42bf + 0x43, 0x20, 0xCC, 0x8A, 0xC9, 0x43, 0x20, 0xCC, + 0x8B, 0xC9, 0x43, 0x20, 0xCC, 0x93, 0xC9, 0x43, + 0x20, 0xCC, 0x94, 0xC9, 0x43, 0x20, 0xCC, 0xA7, + 0xA5, 0x43, 0x20, 0xCC, 0xA8, 0xA5, 0x43, 0x20, + 0xCC, 0xB3, 0xB5, 0x43, 0x20, 0xCD, 0x82, 0xC9, + 0x43, 0x20, 0xCD, 0x85, 0xD9, 0x43, 0x20, 0xD9, + 0x8B, 0x59, 0x43, 0x20, 0xD9, 0x8C, 0x5D, 0x43, + 0x20, 0xD9, 0x8D, 0x61, 0x43, 0x20, 0xD9, 0x8E, + // Bytes 42c0 - 42ff + 0x65, 0x43, 0x20, 0xD9, 0x8F, 0x69, 0x43, 0x20, + 0xD9, 0x90, 0x6D, 0x43, 0x20, 0xD9, 0x91, 0x71, + 0x43, 0x20, 0xD9, 0x92, 0x75, 0x43, 0x41, 0xCC, + 0x8A, 0xC9, 0x43, 0x73, 0xCC, 0x87, 0xC9, 0x44, + 0x20, 0xE3, 0x82, 0x99, 0x0D, 0x44, 0x20, 0xE3, + 0x82, 0x9A, 0x0D, 0x44, 0xC2, 0xA8, 0xCC, 0x81, + 0xCA, 0x44, 0xCE, 0x91, 0xCC, 0x81, 0xC9, 0x44, + 0xCE, 0x95, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0x97, + // Bytes 4300 - 433f + 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0x99, 0xCC, 0x81, + 0xC9, 0x44, 0xCE, 0x9F, 0xCC, 0x81, 0xC9, 0x44, + 0xCE, 0xA5, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xA5, + 0xCC, 0x88, 0xC9, 0x44, 0xCE, 0xA9, 0xCC, 0x81, + 0xC9, 0x44, 0xCE, 0xB1, 0xCC, 0x81, 0xC9, 0x44, + 0xCE, 0xB5, 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xB7, + 0xCC, 0x81, 0xC9, 0x44, 0xCE, 0xB9, 0xCC, 0x81, + 0xC9, 0x44, 0xCE, 0xBF, 0xCC, 0x81, 0xC9, 0x44, + // Bytes 4340 - 437f + 0xCF, 0x85, 0xCC, 0x81, 0xC9, 0x44, 0xCF, 0x89, + 0xCC, 0x81, 0xC9, 0x44, 0xD7, 0x90, 0xD6, 0xB7, + 0x31, 0x44, 0xD7, 0x90, 0xD6, 0xB8, 0x35, 0x44, + 0xD7, 0x90, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x91, + 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x91, 0xD6, 0xBF, + 0x49, 0x44, 0xD7, 0x92, 0xD6, 0xBC, 0x41, 0x44, + 0xD7, 0x93, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x94, + 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x95, 0xD6, 0xB9, + // Bytes 4380 - 43bf + 0x39, 0x44, 0xD7, 0x95, 0xD6, 0xBC, 0x41, 0x44, + 0xD7, 0x96, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x98, + 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x99, 0xD6, 0xB4, + 0x25, 0x44, 0xD7, 0x99, 0xD6, 0xBC, 0x41, 0x44, + 0xD7, 0x9A, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x9B, + 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0x9B, 0xD6, 0xBF, + 0x49, 0x44, 0xD7, 0x9C, 0xD6, 0xBC, 0x41, 0x44, + 0xD7, 0x9E, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA0, + // Bytes 43c0 - 43ff + 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA1, 0xD6, 0xBC, + 0x41, 0x44, 0xD7, 0xA3, 0xD6, 0xBC, 0x41, 0x44, + 0xD7, 0xA4, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA4, + 0xD6, 0xBF, 0x49, 0x44, 0xD7, 0xA6, 0xD6, 0xBC, + 0x41, 0x44, 0xD7, 0xA7, 0xD6, 0xBC, 0x41, 0x44, + 0xD7, 0xA8, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA9, + 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xA9, 0xD7, 0x81, + 0x4D, 0x44, 0xD7, 0xA9, 0xD7, 0x82, 0x51, 0x44, + // Bytes 4400 - 443f + 0xD7, 0xAA, 0xD6, 0xBC, 0x41, 0x44, 0xD7, 0xB2, + 0xD6, 0xB7, 0x31, 0x44, 0xD8, 0xA7, 0xD9, 0x8B, + 0x59, 0x44, 0xD8, 0xA7, 0xD9, 0x93, 0xC9, 0x44, + 0xD8, 0xA7, 0xD9, 0x94, 0xC9, 0x44, 0xD8, 0xA7, + 0xD9, 0x95, 0xB5, 0x44, 0xD8, 0xB0, 0xD9, 0xB0, + 0x79, 0x44, 0xD8, 0xB1, 0xD9, 0xB0, 0x79, 0x44, + 0xD9, 0x80, 0xD9, 0x8B, 0x59, 0x44, 0xD9, 0x80, + 0xD9, 0x8E, 0x65, 0x44, 0xD9, 0x80, 0xD9, 0x8F, + // Bytes 4440 - 447f + 0x69, 0x44, 0xD9, 0x80, 0xD9, 0x90, 0x6D, 0x44, + 0xD9, 0x80, 0xD9, 0x91, 0x71, 0x44, 0xD9, 0x80, + 0xD9, 0x92, 0x75, 0x44, 0xD9, 0x87, 0xD9, 0xB0, + 0x79, 0x44, 0xD9, 0x88, 0xD9, 0x94, 0xC9, 0x44, + 0xD9, 0x89, 0xD9, 0xB0, 0x79, 0x44, 0xD9, 0x8A, + 0xD9, 0x94, 0xC9, 0x44, 0xDB, 0x92, 0xD9, 0x94, + 0xC9, 0x44, 0xDB, 0x95, 0xD9, 0x94, 0xC9, 0x45, + 0x20, 0xCC, 0x88, 0xCC, 0x80, 0xCA, 0x45, 0x20, + // Bytes 4480 - 44bf + 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x45, 0x20, 0xCC, + 0x88, 0xCD, 0x82, 0xCA, 0x45, 0x20, 0xCC, 0x93, + 0xCC, 0x80, 0xCA, 0x45, 0x20, 0xCC, 0x93, 0xCC, + 0x81, 0xCA, 0x45, 0x20, 0xCC, 0x93, 0xCD, 0x82, + 0xCA, 0x45, 0x20, 0xCC, 0x94, 0xCC, 0x80, 0xCA, + 0x45, 0x20, 0xCC, 0x94, 0xCC, 0x81, 0xCA, 0x45, + 0x20, 0xCC, 0x94, 0xCD, 0x82, 0xCA, 0x45, 0x20, + 0xD9, 0x8C, 0xD9, 0x91, 0x72, 0x45, 0x20, 0xD9, + // Bytes 44c0 - 44ff + 0x8D, 0xD9, 0x91, 0x72, 0x45, 0x20, 0xD9, 0x8E, + 0xD9, 0x91, 0x72, 0x45, 0x20, 0xD9, 0x8F, 0xD9, + 0x91, 0x72, 0x45, 0x20, 0xD9, 0x90, 0xD9, 0x91, + 0x72, 0x45, 0x20, 0xD9, 0x91, 0xD9, 0xB0, 0x7A, + 0x45, 0xE2, 0xAB, 0x9D, 0xCC, 0xB8, 0x05, 0x46, + 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x46, + 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xCA, 0x46, + 0xD7, 0xA9, 0xD6, 0xBC, 0xD7, 0x81, 0x4E, 0x46, + // Bytes 4500 - 453f + 0xD7, 0xA9, 0xD6, 0xBC, 0xD7, 0x82, 0x52, 0x46, + 0xD9, 0x80, 0xD9, 0x8E, 0xD9, 0x91, 0x72, 0x46, + 0xD9, 0x80, 0xD9, 0x8F, 0xD9, 0x91, 0x72, 0x46, + 0xD9, 0x80, 0xD9, 0x90, 0xD9, 0x91, 0x72, 0x46, + 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBC, 0x09, 0x46, + 0xE0, 0xA4, 0x96, 0xE0, 0xA4, 0xBC, 0x09, 0x46, + 0xE0, 0xA4, 0x97, 0xE0, 0xA4, 0xBC, 0x09, 0x46, + 0xE0, 0xA4, 0x9C, 0xE0, 0xA4, 0xBC, 0x09, 0x46, + // Bytes 4540 - 457f + 0xE0, 0xA4, 0xA1, 0xE0, 0xA4, 0xBC, 0x09, 0x46, + 0xE0, 0xA4, 0xA2, 0xE0, 0xA4, 0xBC, 0x09, 0x46, + 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xBC, 0x09, 0x46, + 0xE0, 0xA4, 0xAF, 0xE0, 0xA4, 0xBC, 0x09, 0x46, + 0xE0, 0xA6, 0xA1, 0xE0, 0xA6, 0xBC, 0x09, 0x46, + 0xE0, 0xA6, 0xA2, 0xE0, 0xA6, 0xBC, 0x09, 0x46, + 0xE0, 0xA6, 0xAF, 0xE0, 0xA6, 0xBC, 0x09, 0x46, + 0xE0, 0xA8, 0x96, 0xE0, 0xA8, 0xBC, 0x09, 0x46, + // Bytes 4580 - 45bf + 0xE0, 0xA8, 0x97, 0xE0, 0xA8, 0xBC, 0x09, 0x46, + 0xE0, 0xA8, 0x9C, 0xE0, 0xA8, 0xBC, 0x09, 0x46, + 0xE0, 0xA8, 0xAB, 0xE0, 0xA8, 0xBC, 0x09, 0x46, + 0xE0, 0xA8, 0xB2, 0xE0, 0xA8, 0xBC, 0x09, 0x46, + 0xE0, 0xA8, 0xB8, 0xE0, 0xA8, 0xBC, 0x09, 0x46, + 0xE0, 0xAC, 0xA1, 0xE0, 0xAC, 0xBC, 0x09, 0x46, + 0xE0, 0xAC, 0xA2, 0xE0, 0xAC, 0xBC, 0x09, 0x46, + 0xE0, 0xBE, 0xB2, 0xE0, 0xBE, 0x80, 0x9D, 0x46, + // Bytes 45c0 - 45ff + 0xE0, 0xBE, 0xB3, 0xE0, 0xBE, 0x80, 0x9D, 0x46, + 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0x0D, 0x48, + 0xF0, 0x9D, 0x85, 0x97, 0xF0, 0x9D, 0x85, 0xA5, + 0xAD, 0x48, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, + 0x85, 0xA5, 0xAD, 0x48, 0xF0, 0x9D, 0x86, 0xB9, + 0xF0, 0x9D, 0x85, 0xA5, 0xAD, 0x48, 0xF0, 0x9D, + 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xAD, 0x49, + 0xE0, 0xBE, 0xB2, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, + // Bytes 4600 - 463f + 0x80, 0x9E, 0x49, 0xE0, 0xBE, 0xB3, 0xE0, 0xBD, + 0xB1, 0xE0, 0xBE, 0x80, 0x9E, 0x4C, 0xF0, 0x9D, + 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xAE, 0xAE, 0x4C, 0xF0, 0x9D, 0x85, 0x98, + 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, + 0xAE, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, + 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB0, 0xAE, 0x4C, + 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, + // Bytes 4640 - 467f + 0xF0, 0x9D, 0x85, 0xB1, 0xAE, 0x4C, 0xF0, 0x9D, + 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xB2, 0xAE, 0x4C, 0xF0, 0x9D, 0x86, 0xB9, + 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, + 0xAE, 0x4C, 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, + 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xAE, 0x4C, + 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, + 0xF0, 0x9D, 0x85, 0xAE, 0xAE, 0x4C, 0xF0, 0x9D, + // Bytes 4680 - 46bf + 0x86, 0xBA, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xAF, 0xAE, 0x83, 0x41, 0xCC, 0x82, 0xC9, + 0x83, 0x41, 0xCC, 0x86, 0xC9, 0x83, 0x41, 0xCC, + 0x87, 0xC9, 0x83, 0x41, 0xCC, 0x88, 0xC9, 0x83, + 0x41, 0xCC, 0x8A, 0xC9, 0x83, 0x41, 0xCC, 0xA3, + 0xB5, 0x83, 0x43, 0xCC, 0xA7, 0xA5, 0x83, 0x45, + 0xCC, 0x82, 0xC9, 0x83, 0x45, 0xCC, 0x84, 0xC9, + 0x83, 0x45, 0xCC, 0xA3, 0xB5, 0x83, 0x45, 0xCC, + // Bytes 46c0 - 46ff + 0xA7, 0xA5, 0x83, 0x49, 0xCC, 0x88, 0xC9, 0x83, + 0x4C, 0xCC, 0xA3, 0xB5, 0x83, 0x4F, 0xCC, 0x82, + 0xC9, 0x83, 0x4F, 0xCC, 0x83, 0xC9, 0x83, 0x4F, + 0xCC, 0x84, 0xC9, 0x83, 0x4F, 0xCC, 0x87, 0xC9, + 0x83, 0x4F, 0xCC, 0x88, 0xC9, 0x83, 0x4F, 0xCC, + 0x9B, 0xAD, 0x83, 0x4F, 0xCC, 0xA3, 0xB5, 0x83, + 0x4F, 0xCC, 0xA8, 0xA5, 0x83, 0x52, 0xCC, 0xA3, + 0xB5, 0x83, 0x53, 0xCC, 0x81, 0xC9, 0x83, 0x53, + // Bytes 4700 - 473f + 0xCC, 0x8C, 0xC9, 0x83, 0x53, 0xCC, 0xA3, 0xB5, + 0x83, 0x55, 0xCC, 0x83, 0xC9, 0x83, 0x55, 0xCC, + 0x84, 0xC9, 0x83, 0x55, 0xCC, 0x88, 0xC9, 0x83, + 0x55, 0xCC, 0x9B, 0xAD, 0x83, 0x61, 0xCC, 0x82, + 0xC9, 0x83, 0x61, 0xCC, 0x86, 0xC9, 0x83, 0x61, + 0xCC, 0x87, 0xC9, 0x83, 0x61, 0xCC, 0x88, 0xC9, + 0x83, 0x61, 0xCC, 0x8A, 0xC9, 0x83, 0x61, 0xCC, + 0xA3, 0xB5, 0x83, 0x63, 0xCC, 0xA7, 0xA5, 0x83, + // Bytes 4740 - 477f + 0x65, 0xCC, 0x82, 0xC9, 0x83, 0x65, 0xCC, 0x84, + 0xC9, 0x83, 0x65, 0xCC, 0xA3, 0xB5, 0x83, 0x65, + 0xCC, 0xA7, 0xA5, 0x83, 0x69, 0xCC, 0x88, 0xC9, + 0x83, 0x6C, 0xCC, 0xA3, 0xB5, 0x83, 0x6F, 0xCC, + 0x82, 0xC9, 0x83, 0x6F, 0xCC, 0x83, 0xC9, 0x83, + 0x6F, 0xCC, 0x84, 0xC9, 0x83, 0x6F, 0xCC, 0x87, + 0xC9, 0x83, 0x6F, 0xCC, 0x88, 0xC9, 0x83, 0x6F, + 0xCC, 0x9B, 0xAD, 0x83, 0x6F, 0xCC, 0xA3, 0xB5, + // Bytes 4780 - 47bf + 0x83, 0x6F, 0xCC, 0xA8, 0xA5, 0x83, 0x72, 0xCC, + 0xA3, 0xB5, 0x83, 0x73, 0xCC, 0x81, 0xC9, 0x83, + 0x73, 0xCC, 0x8C, 0xC9, 0x83, 0x73, 0xCC, 0xA3, + 0xB5, 0x83, 0x75, 0xCC, 0x83, 0xC9, 0x83, 0x75, + 0xCC, 0x84, 0xC9, 0x83, 0x75, 0xCC, 0x88, 0xC9, + 0x83, 0x75, 0xCC, 0x9B, 0xAD, 0x84, 0xCE, 0x91, + 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x91, 0xCC, 0x94, + 0xC9, 0x84, 0xCE, 0x95, 0xCC, 0x93, 0xC9, 0x84, + // Bytes 47c0 - 47ff + 0xCE, 0x95, 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0x97, + 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x97, 0xCC, 0x94, + 0xC9, 0x84, 0xCE, 0x99, 0xCC, 0x93, 0xC9, 0x84, + 0xCE, 0x99, 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0x9F, + 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0x9F, 0xCC, 0x94, + 0xC9, 0x84, 0xCE, 0xA5, 0xCC, 0x94, 0xC9, 0x84, + 0xCE, 0xA9, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xA9, + 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0xB1, 0xCC, 0x80, + // Bytes 4800 - 483f + 0xC9, 0x84, 0xCE, 0xB1, 0xCC, 0x81, 0xC9, 0x84, + 0xCE, 0xB1, 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xB1, + 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0xB1, 0xCD, 0x82, + 0xC9, 0x84, 0xCE, 0xB5, 0xCC, 0x93, 0xC9, 0x84, + 0xCE, 0xB5, 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0xB7, + 0xCC, 0x80, 0xC9, 0x84, 0xCE, 0xB7, 0xCC, 0x81, + 0xC9, 0x84, 0xCE, 0xB7, 0xCC, 0x93, 0xC9, 0x84, + 0xCE, 0xB7, 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0xB7, + // Bytes 4840 - 487f + 0xCD, 0x82, 0xC9, 0x84, 0xCE, 0xB9, 0xCC, 0x88, + 0xC9, 0x84, 0xCE, 0xB9, 0xCC, 0x93, 0xC9, 0x84, + 0xCE, 0xB9, 0xCC, 0x94, 0xC9, 0x84, 0xCE, 0xBF, + 0xCC, 0x93, 0xC9, 0x84, 0xCE, 0xBF, 0xCC, 0x94, + 0xC9, 0x84, 0xCF, 0x85, 0xCC, 0x88, 0xC9, 0x84, + 0xCF, 0x85, 0xCC, 0x93, 0xC9, 0x84, 0xCF, 0x85, + 0xCC, 0x94, 0xC9, 0x84, 0xCF, 0x89, 0xCC, 0x80, + 0xC9, 0x84, 0xCF, 0x89, 0xCC, 0x81, 0xC9, 0x84, + // Bytes 4880 - 48bf + 0xCF, 0x89, 0xCC, 0x93, 0xC9, 0x84, 0xCF, 0x89, + 0xCC, 0x94, 0xC9, 0x84, 0xCF, 0x89, 0xCD, 0x82, + 0xC9, 0x86, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x82, + 0xCA, 0x86, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x82, + // Bytes 48c0 - 48ff + 0xCA, 0x86, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0x97, 0xCC, 0x93, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, + 0xCA, 0x86, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x82, + 0xCA, 0x86, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81, + // Bytes 4900 - 493f + 0xCA, 0x86, 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x82, + 0xCA, 0x86, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82, + 0xCA, 0x86, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0xB1, 0xCC, 0x93, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, + 0xCA, 0x86, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x80, + // Bytes 4940 - 497f + 0xCA, 0x86, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x82, + 0xCA, 0x86, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x82, + 0xCA, 0x86, 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x80, + 0xCA, 0x86, 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, + 0xCA, 0x86, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82, + // Bytes 4980 - 49bf + 0xCA, 0x86, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x80, + 0xCA, 0x86, 0xCF, 0x89, 0xCC, 0x93, 0xCC, 0x81, + 0xCA, 0x86, 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, + 0xCA, 0x86, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80, + 0xCA, 0x86, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x81, + 0xCA, 0x86, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x82, + 0xCA, 0x42, 0xCC, 0x80, 0xC9, 0x32, 0x42, 0xCC, + 0x81, 0xC9, 0x32, 0x42, 0xCC, 0x93, 0xC9, 0x32, + // Bytes 49c0 - 49ff + 0x43, 0xE1, 0x85, 0xA1, 0x01, 0x00, 0x43, 0xE1, + 0x85, 0xA2, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA3, + 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA4, 0x01, 0x00, + 0x43, 0xE1, 0x85, 0xA5, 0x01, 0x00, 0x43, 0xE1, + 0x85, 0xA6, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA7, + 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA8, 0x01, 0x00, + 0x43, 0xE1, 0x85, 0xA9, 0x01, 0x00, 0x43, 0xE1, + 0x85, 0xAA, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAB, + // Bytes 4a00 - 4a3f + 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAC, 0x01, 0x00, + 0x43, 0xE1, 0x85, 0xAD, 0x01, 0x00, 0x43, 0xE1, + 0x85, 0xAE, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAF, + 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB0, 0x01, 0x00, + 0x43, 0xE1, 0x85, 0xB1, 0x01, 0x00, 0x43, 0xE1, + 0x85, 0xB2, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB3, + 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB4, 0x01, 0x00, + 0x43, 0xE1, 0x85, 0xB5, 0x01, 0x00, 0x43, 0xE1, + // Bytes 4a40 - 4a7f + 0x86, 0xAA, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xAC, + 0x01, 0x00, 0x43, 0xE1, 0x86, 0xAD, 0x01, 0x00, + 0x43, 0xE1, 0x86, 0xB0, 0x01, 0x00, 0x43, 0xE1, + 0x86, 0xB1, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB2, + 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB3, 0x01, 0x00, + 0x43, 0xE1, 0x86, 0xB4, 0x01, 0x00, 0x43, 0xE1, + 0x86, 0xB5, 0x01, 0x00, 0x44, 0xCC, 0x88, 0xCC, + 0x81, 0xCA, 0x32, 0x43, 0xE3, 0x82, 0x99, 0x0D, + // Bytes 4a80 - 4abf + 0x03, 0x43, 0xE3, 0x82, 0x9A, 0x0D, 0x03, 0x46, + 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB2, 0x9E, 0x26, + 0x46, 0xE0, 0xBD, 0xB1, 0xE0, 0xBD, 0xB4, 0xA2, + 0x26, 0x46, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, + 0x9E, 0x26, 0x00, 0x01, +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfcTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfcTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfcValues[c0] + } + i := nfcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfcTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfcTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfcValues[c0] + } + i := nfcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// nfcTrie. Total size: 10610 bytes (10.36 KiB). Checksum: 95e8869a9f81e5e6. +type nfcTrie struct{} + +func newNfcTrie(i int) *nfcTrie { + return &nfcTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *nfcTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 46: + return uint16(nfcValues[n<<6+uint32(b)]) + default: + n -= 46 + return uint16(nfcSparse.lookup(n, b)) + } +} + +// nfcValues: 48 blocks, 3072 entries, 6144 bytes +// The third block is the zero block. +var nfcValues = [3072]uint16{ + // Block 0x0, offset 0x0 + 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000, + // Block 0x1, offset 0x40 + 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000, + 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000, + 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000, + 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000, + 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000, + 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000, + 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000, + 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000, + 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000, + 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x2f72, 0xc1: 0x2f77, 0xc2: 0x468b, 0xc3: 0x2f7c, 0xc4: 0x469a, 0xc5: 0x469f, + 0xc6: 0xa000, 0xc7: 0x46a9, 0xc8: 0x2fe5, 0xc9: 0x2fea, 0xca: 0x46ae, 0xcb: 0x2ffe, + 0xcc: 0x3071, 0xcd: 0x3076, 0xce: 0x307b, 0xcf: 0x46c2, 0xd1: 0x3107, + 0xd2: 0x312a, 0xd3: 0x312f, 0xd4: 0x46cc, 0xd5: 0x46d1, 0xd6: 0x46e0, + 0xd8: 0xa000, 0xd9: 0x31b6, 0xda: 0x31bb, 0xdb: 0x31c0, 0xdc: 0x4712, 0xdd: 0x3238, + 0xe0: 0x327e, 0xe1: 0x3283, 0xe2: 0x471c, 0xe3: 0x3288, + 0xe4: 0x472b, 0xe5: 0x4730, 0xe6: 0xa000, 0xe7: 0x473a, 0xe8: 0x32f1, 0xe9: 0x32f6, + 0xea: 0x473f, 0xeb: 0x330a, 0xec: 0x3382, 0xed: 0x3387, 0xee: 0x338c, 0xef: 0x4753, + 0xf1: 0x3418, 0xf2: 0x343b, 0xf3: 0x3440, 0xf4: 0x475d, 0xf5: 0x4762, + 0xf6: 0x4771, 0xf8: 0xa000, 0xf9: 0x34cc, 0xfa: 0x34d1, 0xfb: 0x34d6, + 0xfc: 0x47a3, 0xfd: 0x3553, 0xff: 0x356c, + // Block 0x4, offset 0x100 + 0x100: 0x2f81, 0x101: 0x328d, 0x102: 0x4690, 0x103: 0x4721, 0x104: 0x2f9f, 0x105: 0x32ab, + 0x106: 0x2fb3, 0x107: 0x32bf, 0x108: 0x2fb8, 0x109: 0x32c4, 0x10a: 0x2fbd, 0x10b: 0x32c9, + 0x10c: 0x2fc2, 0x10d: 0x32ce, 0x10e: 0x2fcc, 0x10f: 0x32d8, + 0x112: 0x46b3, 0x113: 0x4744, 0x114: 0x2ff4, 0x115: 0x3300, 0x116: 0x2ff9, 0x117: 0x3305, + 0x118: 0x3017, 0x119: 0x3323, 0x11a: 0x3008, 0x11b: 0x3314, 0x11c: 0x3030, 0x11d: 0x333c, + 0x11e: 0x303a, 0x11f: 0x3346, 0x120: 0x303f, 0x121: 0x334b, 0x122: 0x3049, 0x123: 0x3355, + 0x124: 0x304e, 0x125: 0x335a, 0x128: 0x3080, 0x129: 0x3391, + 0x12a: 0x3085, 0x12b: 0x3396, 0x12c: 0x308a, 0x12d: 0x339b, 0x12e: 0x30ad, 0x12f: 0x33b9, + 0x130: 0x308f, 0x134: 0x30b7, 0x135: 0x33c3, + 0x136: 0x30cb, 0x137: 0x33dc, 0x139: 0x30d5, 0x13a: 0x33e6, 0x13b: 0x30df, + 0x13c: 0x33f0, 0x13d: 0x30da, 0x13e: 0x33eb, + // Block 0x5, offset 0x140 + 0x143: 0x3102, 0x144: 0x3413, 0x145: 0x311b, + 0x146: 0x342c, 0x147: 0x3111, 0x148: 0x3422, + 0x14c: 0x46d6, 0x14d: 0x4767, 0x14e: 0x3134, 0x14f: 0x3445, 0x150: 0x313e, 0x151: 0x344f, + 0x154: 0x315c, 0x155: 0x346d, 0x156: 0x3175, 0x157: 0x3486, + 0x158: 0x3166, 0x159: 0x3477, 0x15a: 0x46f9, 0x15b: 0x478a, 0x15c: 0x317f, 0x15d: 0x3490, + 0x15e: 0x318e, 0x15f: 0x349f, 0x160: 0x46fe, 0x161: 0x478f, 0x162: 0x31a7, 0x163: 0x34bd, + 0x164: 0x3198, 0x165: 0x34ae, 0x168: 0x4708, 0x169: 0x4799, + 0x16a: 0x470d, 0x16b: 0x479e, 0x16c: 0x31c5, 0x16d: 0x34db, 0x16e: 0x31cf, 0x16f: 0x34e5, + 0x170: 0x31d4, 0x171: 0x34ea, 0x172: 0x31f2, 0x173: 0x3508, 0x174: 0x3215, 0x175: 0x352b, + 0x176: 0x323d, 0x177: 0x3558, 0x178: 0x3251, 0x179: 0x3260, 0x17a: 0x3580, 0x17b: 0x326a, + 0x17c: 0x358a, 0x17d: 0x326f, 0x17e: 0x358f, 0x17f: 0xa000, + // Block 0x6, offset 0x180 + 0x184: 0x8100, 0x185: 0x8100, + 0x186: 0x8100, + 0x18d: 0x2f8b, 0x18e: 0x3297, 0x18f: 0x3099, 0x190: 0x33a5, 0x191: 0x3143, + 0x192: 0x3454, 0x193: 0x31d9, 0x194: 0x34ef, 0x195: 0x39d2, 0x196: 0x3b61, 0x197: 0x39cb, + 0x198: 0x3b5a, 0x199: 0x39d9, 0x19a: 0x3b68, 0x19b: 0x39c4, 0x19c: 0x3b53, + 0x19e: 0x38b3, 0x19f: 0x3a42, 0x1a0: 0x38ac, 0x1a1: 0x3a3b, 0x1a2: 0x35b6, 0x1a3: 0x35c8, + 0x1a6: 0x3044, 0x1a7: 0x3350, 0x1a8: 0x30c1, 0x1a9: 0x33d2, + 0x1aa: 0x46ef, 0x1ab: 0x4780, 0x1ac: 0x3993, 0x1ad: 0x3b22, 0x1ae: 0x35da, 0x1af: 0x35e0, + 0x1b0: 0x33c8, 0x1b4: 0x302b, 0x1b5: 0x3337, + 0x1b8: 0x30fd, 0x1b9: 0x340e, 0x1ba: 0x38ba, 0x1bb: 0x3a49, + 0x1bc: 0x35b0, 0x1bd: 0x35c2, 0x1be: 0x35bc, 0x1bf: 0x35ce, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2f90, 0x1c1: 0x329c, 0x1c2: 0x2f95, 0x1c3: 0x32a1, 0x1c4: 0x300d, 0x1c5: 0x3319, + 0x1c6: 0x3012, 0x1c7: 0x331e, 0x1c8: 0x309e, 0x1c9: 0x33aa, 0x1ca: 0x30a3, 0x1cb: 0x33af, + 0x1cc: 0x3148, 0x1cd: 0x3459, 0x1ce: 0x314d, 0x1cf: 0x345e, 0x1d0: 0x316b, 0x1d1: 0x347c, + 0x1d2: 0x3170, 0x1d3: 0x3481, 0x1d4: 0x31de, 0x1d5: 0x34f4, 0x1d6: 0x31e3, 0x1d7: 0x34f9, + 0x1d8: 0x3189, 0x1d9: 0x349a, 0x1da: 0x31a2, 0x1db: 0x34b8, + 0x1de: 0x305d, 0x1df: 0x3369, + 0x1e6: 0x4695, 0x1e7: 0x4726, 0x1e8: 0x46bd, 0x1e9: 0x474e, + 0x1ea: 0x3962, 0x1eb: 0x3af1, 0x1ec: 0x393f, 0x1ed: 0x3ace, 0x1ee: 0x46db, 0x1ef: 0x476c, + 0x1f0: 0x395b, 0x1f1: 0x3aea, 0x1f2: 0x3247, 0x1f3: 0x3562, + // Block 0x8, offset 0x200 + 0x200: 0x9932, 0x201: 0x9932, 0x202: 0x9932, 0x203: 0x9932, 0x204: 0x9932, 0x205: 0x8132, + 0x206: 0x9932, 0x207: 0x9932, 0x208: 0x9932, 0x209: 0x9932, 0x20a: 0x9932, 0x20b: 0x9932, + 0x20c: 0x9932, 0x20d: 0x8132, 0x20e: 0x8132, 0x20f: 0x9932, 0x210: 0x8132, 0x211: 0x9932, + 0x212: 0x8132, 0x213: 0x9932, 0x214: 0x9932, 0x215: 0x8133, 0x216: 0x812d, 0x217: 0x812d, + 0x218: 0x812d, 0x219: 0x812d, 0x21a: 0x8133, 0x21b: 0x992b, 0x21c: 0x812d, 0x21d: 0x812d, + 0x21e: 0x812d, 0x21f: 0x812d, 0x220: 0x812d, 0x221: 0x8129, 0x222: 0x8129, 0x223: 0x992d, + 0x224: 0x992d, 0x225: 0x992d, 0x226: 0x992d, 0x227: 0x9929, 0x228: 0x9929, 0x229: 0x812d, + 0x22a: 0x812d, 0x22b: 0x812d, 0x22c: 0x812d, 0x22d: 0x992d, 0x22e: 0x992d, 0x22f: 0x812d, + 0x230: 0x992d, 0x231: 0x992d, 0x232: 0x812d, 0x233: 0x812d, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812d, 0x23a: 0x812d, 0x23b: 0x812d, + 0x23c: 0x812d, 0x23d: 0x8132, 0x23e: 0x8132, 0x23f: 0x8132, + // Block 0x9, offset 0x240 + 0x240: 0x49b1, 0x241: 0x49b6, 0x242: 0x9932, 0x243: 0x49bb, 0x244: 0x4a74, 0x245: 0x9936, + 0x246: 0x8132, 0x247: 0x812d, 0x248: 0x812d, 0x249: 0x812d, 0x24a: 0x8132, 0x24b: 0x8132, + 0x24c: 0x8132, 0x24d: 0x812d, 0x24e: 0x812d, 0x250: 0x8132, 0x251: 0x8132, + 0x252: 0x8132, 0x253: 0x812d, 0x254: 0x812d, 0x255: 0x812d, 0x256: 0x812d, 0x257: 0x8132, + 0x258: 0x8133, 0x259: 0x812d, 0x25a: 0x812d, 0x25b: 0x8132, 0x25c: 0x8134, 0x25d: 0x8135, + 0x25e: 0x8135, 0x25f: 0x8134, 0x260: 0x8135, 0x261: 0x8135, 0x262: 0x8134, 0x263: 0x8132, + 0x264: 0x8132, 0x265: 0x8132, 0x266: 0x8132, 0x267: 0x8132, 0x268: 0x8132, 0x269: 0x8132, + 0x26a: 0x8132, 0x26b: 0x8132, 0x26c: 0x8132, 0x26d: 0x8132, 0x26e: 0x8132, 0x26f: 0x8132, + 0x274: 0x0170, + 0x27a: 0x8100, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x8100, 0x285: 0x35a4, + 0x286: 0x35ec, 0x287: 0x00ce, 0x288: 0x360a, 0x289: 0x3616, 0x28a: 0x3628, + 0x28c: 0x3646, 0x28e: 0x3658, 0x28f: 0x3676, 0x290: 0x3e0b, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x363a, 0x2ab: 0x366a, 0x2ac: 0x4801, 0x2ad: 0x369a, 0x2ae: 0x482b, 0x2af: 0x36ac, + 0x2b0: 0x3e73, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x3724, 0x2c1: 0x3730, 0x2c3: 0x371e, + 0x2c6: 0xa000, 0x2c7: 0x370c, + 0x2cc: 0x3760, 0x2cd: 0x3748, 0x2ce: 0x3772, 0x2d0: 0xa000, + 0x2d3: 0xa000, 0x2d5: 0xa000, 0x2d6: 0xa000, 0x2d7: 0xa000, + 0x2d8: 0xa000, 0x2d9: 0x3754, 0x2da: 0xa000, + 0x2de: 0xa000, 0x2e3: 0xa000, + 0x2e7: 0xa000, + 0x2eb: 0xa000, 0x2ed: 0xa000, + 0x2f0: 0xa000, 0x2f3: 0xa000, 0x2f5: 0xa000, + 0x2f6: 0xa000, 0x2f7: 0xa000, 0x2f8: 0xa000, 0x2f9: 0x37d8, 0x2fa: 0xa000, + 0x2fe: 0xa000, + // Block 0xc, offset 0x300 + 0x301: 0x3736, 0x302: 0x37ba, + 0x310: 0x3712, 0x311: 0x3796, + 0x312: 0x3718, 0x313: 0x379c, 0x316: 0x372a, 0x317: 0x37ae, + 0x318: 0xa000, 0x319: 0xa000, 0x31a: 0x382c, 0x31b: 0x3832, 0x31c: 0x373c, 0x31d: 0x37c0, + 0x31e: 0x3742, 0x31f: 0x37c6, 0x322: 0x374e, 0x323: 0x37d2, + 0x324: 0x375a, 0x325: 0x37de, 0x326: 0x3766, 0x327: 0x37ea, 0x328: 0xa000, 0x329: 0xa000, + 0x32a: 0x3838, 0x32b: 0x383e, 0x32c: 0x3790, 0x32d: 0x3814, 0x32e: 0x376c, 0x32f: 0x37f0, + 0x330: 0x3778, 0x331: 0x37fc, 0x332: 0x377e, 0x333: 0x3802, 0x334: 0x3784, 0x335: 0x3808, + 0x338: 0x378a, 0x339: 0x380e, + // Block 0xd, offset 0x340 + 0x351: 0x812d, + 0x352: 0x8132, 0x353: 0x8132, 0x354: 0x8132, 0x355: 0x8132, 0x356: 0x812d, 0x357: 0x8132, + 0x358: 0x8132, 0x359: 0x8132, 0x35a: 0x812e, 0x35b: 0x812d, 0x35c: 0x8132, 0x35d: 0x8132, + 0x35e: 0x8132, 0x35f: 0x8132, 0x360: 0x8132, 0x361: 0x8132, 0x362: 0x812d, 0x363: 0x812d, + 0x364: 0x812d, 0x365: 0x812d, 0x366: 0x812d, 0x367: 0x812d, 0x368: 0x8132, 0x369: 0x8132, + 0x36a: 0x812d, 0x36b: 0x8132, 0x36c: 0x8132, 0x36d: 0x812e, 0x36e: 0x8131, 0x36f: 0x8132, + 0x370: 0x8105, 0x371: 0x8106, 0x372: 0x8107, 0x373: 0x8108, 0x374: 0x8109, 0x375: 0x810a, + 0x376: 0x810b, 0x377: 0x810c, 0x378: 0x810d, 0x379: 0x810e, 0x37a: 0x810e, 0x37b: 0x810f, + 0x37c: 0x8110, 0x37d: 0x8111, 0x37f: 0x8112, + // Block 0xe, offset 0x380 + 0x388: 0xa000, 0x38a: 0xa000, 0x38b: 0x8116, + 0x38c: 0x8117, 0x38d: 0x8118, 0x38e: 0x8119, 0x38f: 0x811a, 0x390: 0x811b, 0x391: 0x811c, + 0x392: 0x811d, 0x393: 0x9932, 0x394: 0x9932, 0x395: 0x992d, 0x396: 0x812d, 0x397: 0x8132, + 0x398: 0x8132, 0x399: 0x8132, 0x39a: 0x8132, 0x39b: 0x8132, 0x39c: 0x812d, 0x39d: 0x8132, + 0x39e: 0x8132, 0x39f: 0x812d, + 0x3b0: 0x811e, + // Block 0xf, offset 0x3c0 + 0x3d3: 0x812d, 0x3d4: 0x8132, 0x3d5: 0x8132, 0x3d6: 0x8132, 0x3d7: 0x8132, + 0x3d8: 0x8132, 0x3d9: 0x8132, 0x3da: 0x8132, 0x3db: 0x8132, 0x3dc: 0x8132, 0x3dd: 0x8132, + 0x3de: 0x8132, 0x3df: 0x8132, 0x3e0: 0x8132, 0x3e1: 0x8132, 0x3e3: 0x812d, + 0x3e4: 0x8132, 0x3e5: 0x8132, 0x3e6: 0x812d, 0x3e7: 0x8132, 0x3e8: 0x8132, 0x3e9: 0x812d, + 0x3ea: 0x8132, 0x3eb: 0x8132, 0x3ec: 0x8132, 0x3ed: 0x812d, 0x3ee: 0x812d, 0x3ef: 0x812d, + 0x3f0: 0x8116, 0x3f1: 0x8117, 0x3f2: 0x8118, 0x3f3: 0x8132, 0x3f4: 0x8132, 0x3f5: 0x8132, + 0x3f6: 0x812d, 0x3f7: 0x8132, 0x3f8: 0x8132, 0x3f9: 0x812d, 0x3fa: 0x812d, 0x3fb: 0x8132, + 0x3fc: 0x8132, 0x3fd: 0x8132, 0x3fe: 0x8132, 0x3ff: 0x8132, + // Block 0x10, offset 0x400 + 0x405: 0xa000, + 0x406: 0x2d29, 0x407: 0xa000, 0x408: 0x2d31, 0x409: 0xa000, 0x40a: 0x2d39, 0x40b: 0xa000, + 0x40c: 0x2d41, 0x40d: 0xa000, 0x40e: 0x2d49, 0x411: 0xa000, + 0x412: 0x2d51, + 0x434: 0x8102, 0x435: 0x9900, + 0x43a: 0xa000, 0x43b: 0x2d59, + 0x43c: 0xa000, 0x43d: 0x2d61, 0x43e: 0xa000, 0x43f: 0xa000, + // Block 0x11, offset 0x440 + 0x440: 0x8132, 0x441: 0x8132, 0x442: 0x812d, 0x443: 0x8132, 0x444: 0x8132, 0x445: 0x8132, + 0x446: 0x8132, 0x447: 0x8132, 0x448: 0x8132, 0x449: 0x8132, 0x44a: 0x812d, 0x44b: 0x8132, + 0x44c: 0x8132, 0x44d: 0x8135, 0x44e: 0x812a, 0x44f: 0x812d, 0x450: 0x8129, 0x451: 0x8132, + 0x452: 0x8132, 0x453: 0x8132, 0x454: 0x8132, 0x455: 0x8132, 0x456: 0x8132, 0x457: 0x8132, + 0x458: 0x8132, 0x459: 0x8132, 0x45a: 0x8132, 0x45b: 0x8132, 0x45c: 0x8132, 0x45d: 0x8132, + 0x45e: 0x8132, 0x45f: 0x8132, 0x460: 0x8132, 0x461: 0x8132, 0x462: 0x8132, 0x463: 0x8132, + 0x464: 0x8132, 0x465: 0x8132, 0x466: 0x8132, 0x467: 0x8132, 0x468: 0x8132, 0x469: 0x8132, + 0x46a: 0x8132, 0x46b: 0x8132, 0x46c: 0x8132, 0x46d: 0x8132, 0x46e: 0x8132, 0x46f: 0x8132, + 0x470: 0x8132, 0x471: 0x8132, 0x472: 0x8132, 0x473: 0x8132, 0x474: 0x8132, 0x475: 0x8132, + 0x476: 0x8133, 0x477: 0x8131, 0x478: 0x8131, 0x479: 0x812d, 0x47b: 0x8132, + 0x47c: 0x8134, 0x47d: 0x812d, 0x47e: 0x8132, 0x47f: 0x812d, + // Block 0x12, offset 0x480 + 0x480: 0x2f9a, 0x481: 0x32a6, 0x482: 0x2fa4, 0x483: 0x32b0, 0x484: 0x2fa9, 0x485: 0x32b5, + 0x486: 0x2fae, 0x487: 0x32ba, 0x488: 0x38cf, 0x489: 0x3a5e, 0x48a: 0x2fc7, 0x48b: 0x32d3, + 0x48c: 0x2fd1, 0x48d: 0x32dd, 0x48e: 0x2fe0, 0x48f: 0x32ec, 0x490: 0x2fd6, 0x491: 0x32e2, + 0x492: 0x2fdb, 0x493: 0x32e7, 0x494: 0x38f2, 0x495: 0x3a81, 0x496: 0x38f9, 0x497: 0x3a88, + 0x498: 0x301c, 0x499: 0x3328, 0x49a: 0x3021, 0x49b: 0x332d, 0x49c: 0x3907, 0x49d: 0x3a96, + 0x49e: 0x3026, 0x49f: 0x3332, 0x4a0: 0x3035, 0x4a1: 0x3341, 0x4a2: 0x3053, 0x4a3: 0x335f, + 0x4a4: 0x3062, 0x4a5: 0x336e, 0x4a6: 0x3058, 0x4a7: 0x3364, 0x4a8: 0x3067, 0x4a9: 0x3373, + 0x4aa: 0x306c, 0x4ab: 0x3378, 0x4ac: 0x30b2, 0x4ad: 0x33be, 0x4ae: 0x390e, 0x4af: 0x3a9d, + 0x4b0: 0x30bc, 0x4b1: 0x33cd, 0x4b2: 0x30c6, 0x4b3: 0x33d7, 0x4b4: 0x30d0, 0x4b5: 0x33e1, + 0x4b6: 0x46c7, 0x4b7: 0x4758, 0x4b8: 0x3915, 0x4b9: 0x3aa4, 0x4ba: 0x30e9, 0x4bb: 0x33fa, + 0x4bc: 0x30e4, 0x4bd: 0x33f5, 0x4be: 0x30ee, 0x4bf: 0x33ff, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x30f3, 0x4c1: 0x3404, 0x4c2: 0x30f8, 0x4c3: 0x3409, 0x4c4: 0x310c, 0x4c5: 0x341d, + 0x4c6: 0x3116, 0x4c7: 0x3427, 0x4c8: 0x3125, 0x4c9: 0x3436, 0x4ca: 0x3120, 0x4cb: 0x3431, + 0x4cc: 0x3938, 0x4cd: 0x3ac7, 0x4ce: 0x3946, 0x4cf: 0x3ad5, 0x4d0: 0x394d, 0x4d1: 0x3adc, + 0x4d2: 0x3954, 0x4d3: 0x3ae3, 0x4d4: 0x3152, 0x4d5: 0x3463, 0x4d6: 0x3157, 0x4d7: 0x3468, + 0x4d8: 0x3161, 0x4d9: 0x3472, 0x4da: 0x46f4, 0x4db: 0x4785, 0x4dc: 0x399a, 0x4dd: 0x3b29, + 0x4de: 0x317a, 0x4df: 0x348b, 0x4e0: 0x3184, 0x4e1: 0x3495, 0x4e2: 0x4703, 0x4e3: 0x4794, + 0x4e4: 0x39a1, 0x4e5: 0x3b30, 0x4e6: 0x39a8, 0x4e7: 0x3b37, 0x4e8: 0x39af, 0x4e9: 0x3b3e, + 0x4ea: 0x3193, 0x4eb: 0x34a4, 0x4ec: 0x319d, 0x4ed: 0x34b3, 0x4ee: 0x31b1, 0x4ef: 0x34c7, + 0x4f0: 0x31ac, 0x4f1: 0x34c2, 0x4f2: 0x31ed, 0x4f3: 0x3503, 0x4f4: 0x31fc, 0x4f5: 0x3512, + 0x4f6: 0x31f7, 0x4f7: 0x350d, 0x4f8: 0x39b6, 0x4f9: 0x3b45, 0x4fa: 0x39bd, 0x4fb: 0x3b4c, + 0x4fc: 0x3201, 0x4fd: 0x3517, 0x4fe: 0x3206, 0x4ff: 0x351c, + // Block 0x14, offset 0x500 + 0x500: 0x320b, 0x501: 0x3521, 0x502: 0x3210, 0x503: 0x3526, 0x504: 0x321f, 0x505: 0x3535, + 0x506: 0x321a, 0x507: 0x3530, 0x508: 0x3224, 0x509: 0x353f, 0x50a: 0x3229, 0x50b: 0x3544, + 0x50c: 0x322e, 0x50d: 0x3549, 0x50e: 0x324c, 0x50f: 0x3567, 0x510: 0x3265, 0x511: 0x3585, + 0x512: 0x3274, 0x513: 0x3594, 0x514: 0x3279, 0x515: 0x3599, 0x516: 0x337d, 0x517: 0x34a9, + 0x518: 0x353a, 0x519: 0x3576, 0x51b: 0x35d4, + 0x520: 0x46a4, 0x521: 0x4735, 0x522: 0x2f86, 0x523: 0x3292, + 0x524: 0x387b, 0x525: 0x3a0a, 0x526: 0x3874, 0x527: 0x3a03, 0x528: 0x3889, 0x529: 0x3a18, + 0x52a: 0x3882, 0x52b: 0x3a11, 0x52c: 0x38c1, 0x52d: 0x3a50, 0x52e: 0x3897, 0x52f: 0x3a26, + 0x530: 0x3890, 0x531: 0x3a1f, 0x532: 0x38a5, 0x533: 0x3a34, 0x534: 0x389e, 0x535: 0x3a2d, + 0x536: 0x38c8, 0x537: 0x3a57, 0x538: 0x46b8, 0x539: 0x4749, 0x53a: 0x3003, 0x53b: 0x330f, + 0x53c: 0x2fef, 0x53d: 0x32fb, 0x53e: 0x38dd, 0x53f: 0x3a6c, + // Block 0x15, offset 0x540 + 0x540: 0x38d6, 0x541: 0x3a65, 0x542: 0x38eb, 0x543: 0x3a7a, 0x544: 0x38e4, 0x545: 0x3a73, + 0x546: 0x3900, 0x547: 0x3a8f, 0x548: 0x3094, 0x549: 0x33a0, 0x54a: 0x30a8, 0x54b: 0x33b4, + 0x54c: 0x46ea, 0x54d: 0x477b, 0x54e: 0x3139, 0x54f: 0x344a, 0x550: 0x3923, 0x551: 0x3ab2, + 0x552: 0x391c, 0x553: 0x3aab, 0x554: 0x3931, 0x555: 0x3ac0, 0x556: 0x392a, 0x557: 0x3ab9, + 0x558: 0x398c, 0x559: 0x3b1b, 0x55a: 0x3970, 0x55b: 0x3aff, 0x55c: 0x3969, 0x55d: 0x3af8, + 0x55e: 0x397e, 0x55f: 0x3b0d, 0x560: 0x3977, 0x561: 0x3b06, 0x562: 0x3985, 0x563: 0x3b14, + 0x564: 0x31e8, 0x565: 0x34fe, 0x566: 0x31ca, 0x567: 0x34e0, 0x568: 0x39e7, 0x569: 0x3b76, + 0x56a: 0x39e0, 0x56b: 0x3b6f, 0x56c: 0x39f5, 0x56d: 0x3b84, 0x56e: 0x39ee, 0x56f: 0x3b7d, + 0x570: 0x39fc, 0x571: 0x3b8b, 0x572: 0x3233, 0x573: 0x354e, 0x574: 0x325b, 0x575: 0x357b, + 0x576: 0x3256, 0x577: 0x3571, 0x578: 0x3242, 0x579: 0x355d, + // Block 0x16, offset 0x580 + 0x580: 0x4807, 0x581: 0x480d, 0x582: 0x4921, 0x583: 0x4939, 0x584: 0x4929, 0x585: 0x4941, + 0x586: 0x4931, 0x587: 0x4949, 0x588: 0x47ad, 0x589: 0x47b3, 0x58a: 0x4891, 0x58b: 0x48a9, + 0x58c: 0x4899, 0x58d: 0x48b1, 0x58e: 0x48a1, 0x58f: 0x48b9, 0x590: 0x4819, 0x591: 0x481f, + 0x592: 0x3dbb, 0x593: 0x3dcb, 0x594: 0x3dc3, 0x595: 0x3dd3, + 0x598: 0x47b9, 0x599: 0x47bf, 0x59a: 0x3ceb, 0x59b: 0x3cfb, 0x59c: 0x3cf3, 0x59d: 0x3d03, + 0x5a0: 0x4831, 0x5a1: 0x4837, 0x5a2: 0x4951, 0x5a3: 0x4969, + 0x5a4: 0x4959, 0x5a5: 0x4971, 0x5a6: 0x4961, 0x5a7: 0x4979, 0x5a8: 0x47c5, 0x5a9: 0x47cb, + 0x5aa: 0x48c1, 0x5ab: 0x48d9, 0x5ac: 0x48c9, 0x5ad: 0x48e1, 0x5ae: 0x48d1, 0x5af: 0x48e9, + 0x5b0: 0x4849, 0x5b1: 0x484f, 0x5b2: 0x3e1b, 0x5b3: 0x3e33, 0x5b4: 0x3e23, 0x5b5: 0x3e3b, + 0x5b6: 0x3e2b, 0x5b7: 0x3e43, 0x5b8: 0x47d1, 0x5b9: 0x47d7, 0x5ba: 0x3d1b, 0x5bb: 0x3d33, + 0x5bc: 0x3d23, 0x5bd: 0x3d3b, 0x5be: 0x3d2b, 0x5bf: 0x3d43, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x4855, 0x5c1: 0x485b, 0x5c2: 0x3e4b, 0x5c3: 0x3e5b, 0x5c4: 0x3e53, 0x5c5: 0x3e63, + 0x5c8: 0x47dd, 0x5c9: 0x47e3, 0x5ca: 0x3d4b, 0x5cb: 0x3d5b, + 0x5cc: 0x3d53, 0x5cd: 0x3d63, 0x5d0: 0x4867, 0x5d1: 0x486d, + 0x5d2: 0x3e83, 0x5d3: 0x3e9b, 0x5d4: 0x3e8b, 0x5d5: 0x3ea3, 0x5d6: 0x3e93, 0x5d7: 0x3eab, + 0x5d9: 0x47e9, 0x5db: 0x3d6b, 0x5dd: 0x3d73, + 0x5df: 0x3d7b, 0x5e0: 0x487f, 0x5e1: 0x4885, 0x5e2: 0x4981, 0x5e3: 0x4999, + 0x5e4: 0x4989, 0x5e5: 0x49a1, 0x5e6: 0x4991, 0x5e7: 0x49a9, 0x5e8: 0x47ef, 0x5e9: 0x47f5, + 0x5ea: 0x48f1, 0x5eb: 0x4909, 0x5ec: 0x48f9, 0x5ed: 0x4911, 0x5ee: 0x4901, 0x5ef: 0x4919, + 0x5f0: 0x47fb, 0x5f1: 0x4321, 0x5f2: 0x3694, 0x5f3: 0x4327, 0x5f4: 0x4825, 0x5f5: 0x432d, + 0x5f6: 0x36a6, 0x5f7: 0x4333, 0x5f8: 0x36c4, 0x5f9: 0x4339, 0x5fa: 0x36dc, 0x5fb: 0x433f, + 0x5fc: 0x4873, 0x5fd: 0x4345, + // Block 0x18, offset 0x600 + 0x600: 0x3da3, 0x601: 0x3dab, 0x602: 0x4187, 0x603: 0x41a5, 0x604: 0x4191, 0x605: 0x41af, + 0x606: 0x419b, 0x607: 0x41b9, 0x608: 0x3cdb, 0x609: 0x3ce3, 0x60a: 0x40d3, 0x60b: 0x40f1, + 0x60c: 0x40dd, 0x60d: 0x40fb, 0x60e: 0x40e7, 0x60f: 0x4105, 0x610: 0x3deb, 0x611: 0x3df3, + 0x612: 0x41c3, 0x613: 0x41e1, 0x614: 0x41cd, 0x615: 0x41eb, 0x616: 0x41d7, 0x617: 0x41f5, + 0x618: 0x3d0b, 0x619: 0x3d13, 0x61a: 0x410f, 0x61b: 0x412d, 0x61c: 0x4119, 0x61d: 0x4137, + 0x61e: 0x4123, 0x61f: 0x4141, 0x620: 0x3ec3, 0x621: 0x3ecb, 0x622: 0x41ff, 0x623: 0x421d, + 0x624: 0x4209, 0x625: 0x4227, 0x626: 0x4213, 0x627: 0x4231, 0x628: 0x3d83, 0x629: 0x3d8b, + 0x62a: 0x414b, 0x62b: 0x4169, 0x62c: 0x4155, 0x62d: 0x4173, 0x62e: 0x415f, 0x62f: 0x417d, + 0x630: 0x3688, 0x631: 0x3682, 0x632: 0x3d93, 0x633: 0x368e, 0x634: 0x3d9b, + 0x636: 0x4813, 0x637: 0x3db3, 0x638: 0x35f8, 0x639: 0x35f2, 0x63a: 0x35e6, 0x63b: 0x42f1, + 0x63c: 0x35fe, 0x63d: 0x8100, 0x63e: 0x01d3, 0x63f: 0xa100, + // Block 0x19, offset 0x640 + 0x640: 0x8100, 0x641: 0x35aa, 0x642: 0x3ddb, 0x643: 0x36a0, 0x644: 0x3de3, + 0x646: 0x483d, 0x647: 0x3dfb, 0x648: 0x3604, 0x649: 0x42f7, 0x64a: 0x3610, 0x64b: 0x42fd, + 0x64c: 0x361c, 0x64d: 0x3b92, 0x64e: 0x3b99, 0x64f: 0x3ba0, 0x650: 0x36b8, 0x651: 0x36b2, + 0x652: 0x3e03, 0x653: 0x44e7, 0x656: 0x36be, 0x657: 0x3e13, + 0x658: 0x3634, 0x659: 0x362e, 0x65a: 0x3622, 0x65b: 0x4303, 0x65d: 0x3ba7, + 0x65e: 0x3bae, 0x65f: 0x3bb5, 0x660: 0x36ee, 0x661: 0x36e8, 0x662: 0x3e6b, 0x663: 0x44ef, + 0x664: 0x36d0, 0x665: 0x36d6, 0x666: 0x36f4, 0x667: 0x3e7b, 0x668: 0x3664, 0x669: 0x365e, + 0x66a: 0x3652, 0x66b: 0x430f, 0x66c: 0x364c, 0x66d: 0x359e, 0x66e: 0x42eb, 0x66f: 0x0081, + 0x672: 0x3eb3, 0x673: 0x36fa, 0x674: 0x3ebb, + 0x676: 0x488b, 0x677: 0x3ed3, 0x678: 0x3640, 0x679: 0x4309, 0x67a: 0x3670, 0x67b: 0x431b, + 0x67c: 0x367c, 0x67d: 0x4259, 0x67e: 0xa100, + // Block 0x1a, offset 0x680 + 0x681: 0x3c09, 0x683: 0xa000, 0x684: 0x3c10, 0x685: 0xa000, + 0x687: 0x3c17, 0x688: 0xa000, 0x689: 0x3c1e, + 0x68d: 0xa000, + 0x6a0: 0x2f68, 0x6a1: 0xa000, 0x6a2: 0x3c2c, + 0x6a4: 0xa000, 0x6a5: 0xa000, + 0x6ad: 0x3c25, 0x6ae: 0x2f63, 0x6af: 0x2f6d, + 0x6b0: 0x3c33, 0x6b1: 0x3c3a, 0x6b2: 0xa000, 0x6b3: 0xa000, 0x6b4: 0x3c41, 0x6b5: 0x3c48, + 0x6b6: 0xa000, 0x6b7: 0xa000, 0x6b8: 0x3c4f, 0x6b9: 0x3c56, 0x6ba: 0xa000, 0x6bb: 0xa000, + 0x6bc: 0xa000, 0x6bd: 0xa000, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x3c5d, 0x6c1: 0x3c64, 0x6c2: 0xa000, 0x6c3: 0xa000, 0x6c4: 0x3c79, 0x6c5: 0x3c80, + 0x6c6: 0xa000, 0x6c7: 0xa000, 0x6c8: 0x3c87, 0x6c9: 0x3c8e, + 0x6d1: 0xa000, + 0x6d2: 0xa000, + 0x6e2: 0xa000, + 0x6e8: 0xa000, 0x6e9: 0xa000, + 0x6eb: 0xa000, 0x6ec: 0x3ca3, 0x6ed: 0x3caa, 0x6ee: 0x3cb1, 0x6ef: 0x3cb8, + 0x6f2: 0xa000, 0x6f3: 0xa000, 0x6f4: 0xa000, 0x6f5: 0xa000, + // Block 0x1c, offset 0x700 + 0x706: 0xa000, 0x70b: 0xa000, + 0x70c: 0x3f0b, 0x70d: 0xa000, 0x70e: 0x3f13, 0x70f: 0xa000, 0x710: 0x3f1b, 0x711: 0xa000, + 0x712: 0x3f23, 0x713: 0xa000, 0x714: 0x3f2b, 0x715: 0xa000, 0x716: 0x3f33, 0x717: 0xa000, + 0x718: 0x3f3b, 0x719: 0xa000, 0x71a: 0x3f43, 0x71b: 0xa000, 0x71c: 0x3f4b, 0x71d: 0xa000, + 0x71e: 0x3f53, 0x71f: 0xa000, 0x720: 0x3f5b, 0x721: 0xa000, 0x722: 0x3f63, + 0x724: 0xa000, 0x725: 0x3f6b, 0x726: 0xa000, 0x727: 0x3f73, 0x728: 0xa000, 0x729: 0x3f7b, + 0x72f: 0xa000, + 0x730: 0x3f83, 0x731: 0x3f8b, 0x732: 0xa000, 0x733: 0x3f93, 0x734: 0x3f9b, 0x735: 0xa000, + 0x736: 0x3fa3, 0x737: 0x3fab, 0x738: 0xa000, 0x739: 0x3fb3, 0x73a: 0x3fbb, 0x73b: 0xa000, + 0x73c: 0x3fc3, 0x73d: 0x3fcb, + // Block 0x1d, offset 0x740 + 0x754: 0x3f03, + 0x759: 0x9903, 0x75a: 0x9903, 0x75b: 0x8100, 0x75c: 0x8100, 0x75d: 0xa000, + 0x75e: 0x3fd3, + 0x766: 0xa000, + 0x76b: 0xa000, 0x76c: 0x3fe3, 0x76d: 0xa000, 0x76e: 0x3feb, 0x76f: 0xa000, + 0x770: 0x3ff3, 0x771: 0xa000, 0x772: 0x3ffb, 0x773: 0xa000, 0x774: 0x4003, 0x775: 0xa000, + 0x776: 0x400b, 0x777: 0xa000, 0x778: 0x4013, 0x779: 0xa000, 0x77a: 0x401b, 0x77b: 0xa000, + 0x77c: 0x4023, 0x77d: 0xa000, 0x77e: 0x402b, 0x77f: 0xa000, + // Block 0x1e, offset 0x780 + 0x780: 0x4033, 0x781: 0xa000, 0x782: 0x403b, 0x784: 0xa000, 0x785: 0x4043, + 0x786: 0xa000, 0x787: 0x404b, 0x788: 0xa000, 0x789: 0x4053, + 0x78f: 0xa000, 0x790: 0x405b, 0x791: 0x4063, + 0x792: 0xa000, 0x793: 0x406b, 0x794: 0x4073, 0x795: 0xa000, 0x796: 0x407b, 0x797: 0x4083, + 0x798: 0xa000, 0x799: 0x408b, 0x79a: 0x4093, 0x79b: 0xa000, 0x79c: 0x409b, 0x79d: 0x40a3, + 0x7af: 0xa000, + 0x7b0: 0xa000, 0x7b1: 0xa000, 0x7b2: 0xa000, 0x7b4: 0x3fdb, + 0x7b7: 0x40ab, 0x7b8: 0x40b3, 0x7b9: 0x40bb, 0x7ba: 0x40c3, + 0x7bd: 0xa000, 0x7be: 0x40cb, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x1377, 0x7c1: 0x0cfb, 0x7c2: 0x13d3, 0x7c3: 0x139f, 0x7c4: 0x0e57, 0x7c5: 0x06eb, + 0x7c6: 0x08df, 0x7c7: 0x162b, 0x7c8: 0x162b, 0x7c9: 0x0a0b, 0x7ca: 0x145f, 0x7cb: 0x0943, + 0x7cc: 0x0a07, 0x7cd: 0x0bef, 0x7ce: 0x0fcf, 0x7cf: 0x115f, 0x7d0: 0x1297, 0x7d1: 0x12d3, + 0x7d2: 0x1307, 0x7d3: 0x141b, 0x7d4: 0x0d73, 0x7d5: 0x0dff, 0x7d6: 0x0eab, 0x7d7: 0x0f43, + 0x7d8: 0x125f, 0x7d9: 0x1447, 0x7da: 0x1573, 0x7db: 0x070f, 0x7dc: 0x08b3, 0x7dd: 0x0d87, + 0x7de: 0x0ecf, 0x7df: 0x1293, 0x7e0: 0x15c3, 0x7e1: 0x0ab3, 0x7e2: 0x0e77, 0x7e3: 0x1283, + 0x7e4: 0x1317, 0x7e5: 0x0c23, 0x7e6: 0x11bb, 0x7e7: 0x12df, 0x7e8: 0x0b1f, 0x7e9: 0x0d0f, + 0x7ea: 0x0e17, 0x7eb: 0x0f1b, 0x7ec: 0x1427, 0x7ed: 0x074f, 0x7ee: 0x07e7, 0x7ef: 0x0853, + 0x7f0: 0x0c8b, 0x7f1: 0x0d7f, 0x7f2: 0x0ecb, 0x7f3: 0x0fef, 0x7f4: 0x1177, 0x7f5: 0x128b, + 0x7f6: 0x12a3, 0x7f7: 0x13c7, 0x7f8: 0x14ef, 0x7f9: 0x15a3, 0x7fa: 0x15bf, 0x7fb: 0x102b, + 0x7fc: 0x106b, 0x7fd: 0x1123, 0x7fe: 0x1243, 0x7ff: 0x147b, + // Block 0x20, offset 0x800 + 0x800: 0x15cb, 0x801: 0x134b, 0x802: 0x09c7, 0x803: 0x0b3b, 0x804: 0x10db, 0x805: 0x119b, + 0x806: 0x0eff, 0x807: 0x1033, 0x808: 0x1397, 0x809: 0x14e7, 0x80a: 0x09c3, 0x80b: 0x0a8f, + 0x80c: 0x0d77, 0x80d: 0x0e2b, 0x80e: 0x0e5f, 0x80f: 0x1113, 0x810: 0x113b, 0x811: 0x14a7, + 0x812: 0x084f, 0x813: 0x11a7, 0x814: 0x07f3, 0x815: 0x07ef, 0x816: 0x1097, 0x817: 0x1127, + 0x818: 0x125b, 0x819: 0x14af, 0x81a: 0x1367, 0x81b: 0x0c27, 0x81c: 0x0d73, 0x81d: 0x1357, + 0x81e: 0x06f7, 0x81f: 0x0a63, 0x820: 0x0b93, 0x821: 0x0f2f, 0x822: 0x0faf, 0x823: 0x0873, + 0x824: 0x103b, 0x825: 0x075f, 0x826: 0x0b77, 0x827: 0x06d7, 0x828: 0x0deb, 0x829: 0x0ca3, + 0x82a: 0x110f, 0x82b: 0x08c7, 0x82c: 0x09b3, 0x82d: 0x0ffb, 0x82e: 0x1263, 0x82f: 0x133b, + 0x830: 0x0db7, 0x831: 0x13f7, 0x832: 0x0de3, 0x833: 0x0c37, 0x834: 0x121b, 0x835: 0x0c57, + 0x836: 0x0fab, 0x837: 0x072b, 0x838: 0x07a7, 0x839: 0x07eb, 0x83a: 0x0d53, 0x83b: 0x10fb, + 0x83c: 0x11f3, 0x83d: 0x1347, 0x83e: 0x145b, 0x83f: 0x085b, + // Block 0x21, offset 0x840 + 0x840: 0x090f, 0x841: 0x0a17, 0x842: 0x0b2f, 0x843: 0x0cbf, 0x844: 0x0e7b, 0x845: 0x103f, + 0x846: 0x1497, 0x847: 0x157b, 0x848: 0x15cf, 0x849: 0x15e7, 0x84a: 0x0837, 0x84b: 0x0cf3, + 0x84c: 0x0da3, 0x84d: 0x13eb, 0x84e: 0x0afb, 0x84f: 0x0bd7, 0x850: 0x0bf3, 0x851: 0x0c83, + 0x852: 0x0e6b, 0x853: 0x0eb7, 0x854: 0x0f67, 0x855: 0x108b, 0x856: 0x112f, 0x857: 0x1193, + 0x858: 0x13db, 0x859: 0x126b, 0x85a: 0x1403, 0x85b: 0x147f, 0x85c: 0x080f, 0x85d: 0x083b, + 0x85e: 0x0923, 0x85f: 0x0ea7, 0x860: 0x12f3, 0x861: 0x133b, 0x862: 0x0b1b, 0x863: 0x0b8b, + 0x864: 0x0c4f, 0x865: 0x0daf, 0x866: 0x10d7, 0x867: 0x0f23, 0x868: 0x073b, 0x869: 0x097f, + 0x86a: 0x0a63, 0x86b: 0x0ac7, 0x86c: 0x0b97, 0x86d: 0x0f3f, 0x86e: 0x0f5b, 0x86f: 0x116b, + 0x870: 0x118b, 0x871: 0x1463, 0x872: 0x14e3, 0x873: 0x14f3, 0x874: 0x152f, 0x875: 0x0753, + 0x876: 0x107f, 0x877: 0x144f, 0x878: 0x14cb, 0x879: 0x0baf, 0x87a: 0x0717, 0x87b: 0x0777, + 0x87c: 0x0a67, 0x87d: 0x0a87, 0x87e: 0x0caf, 0x87f: 0x0d73, + // Block 0x22, offset 0x880 + 0x880: 0x0ec3, 0x881: 0x0fcb, 0x882: 0x1277, 0x883: 0x1417, 0x884: 0x1623, 0x885: 0x0ce3, + 0x886: 0x14a3, 0x887: 0x0833, 0x888: 0x0d2f, 0x889: 0x0d3b, 0x88a: 0x0e0f, 0x88b: 0x0e47, + 0x88c: 0x0f4b, 0x88d: 0x0fa7, 0x88e: 0x1027, 0x88f: 0x110b, 0x890: 0x153b, 0x891: 0x07af, + 0x892: 0x0c03, 0x893: 0x14b3, 0x894: 0x0767, 0x895: 0x0aab, 0x896: 0x0e2f, 0x897: 0x13df, + 0x898: 0x0b67, 0x899: 0x0bb7, 0x89a: 0x0d43, 0x89b: 0x0f2f, 0x89c: 0x14bb, 0x89d: 0x0817, + 0x89e: 0x08ff, 0x89f: 0x0a97, 0x8a0: 0x0cd3, 0x8a1: 0x0d1f, 0x8a2: 0x0d5f, 0x8a3: 0x0df3, + 0x8a4: 0x0f47, 0x8a5: 0x0fbb, 0x8a6: 0x1157, 0x8a7: 0x12f7, 0x8a8: 0x1303, 0x8a9: 0x1457, + 0x8aa: 0x14d7, 0x8ab: 0x0883, 0x8ac: 0x0e4b, 0x8ad: 0x0903, 0x8ae: 0x0ec7, 0x8af: 0x0f6b, + 0x8b0: 0x1287, 0x8b1: 0x14bf, 0x8b2: 0x15ab, 0x8b3: 0x15d3, 0x8b4: 0x0d37, 0x8b5: 0x0e27, + 0x8b6: 0x11c3, 0x8b7: 0x10b7, 0x8b8: 0x10c3, 0x8b9: 0x10e7, 0x8ba: 0x0f17, 0x8bb: 0x0e9f, + 0x8bc: 0x1363, 0x8bd: 0x0733, 0x8be: 0x122b, 0x8bf: 0x081b, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x080b, 0x8c1: 0x0b0b, 0x8c2: 0x0c2b, 0x8c3: 0x10f3, 0x8c4: 0x0a53, 0x8c5: 0x0e03, + 0x8c6: 0x0cef, 0x8c7: 0x13e7, 0x8c8: 0x12e7, 0x8c9: 0x14ab, 0x8ca: 0x1323, 0x8cb: 0x0b27, + 0x8cc: 0x0787, 0x8cd: 0x095b, 0x8d0: 0x09af, + 0x8d2: 0x0cdf, 0x8d5: 0x07f7, 0x8d6: 0x0f1f, 0x8d7: 0x0fe3, + 0x8d8: 0x1047, 0x8d9: 0x1063, 0x8da: 0x1067, 0x8db: 0x107b, 0x8dc: 0x14fb, 0x8dd: 0x10eb, + 0x8de: 0x116f, 0x8e0: 0x128f, 0x8e2: 0x1353, + 0x8e5: 0x1407, 0x8e6: 0x1433, + 0x8ea: 0x154f, 0x8eb: 0x1553, 0x8ec: 0x1557, 0x8ed: 0x15bb, 0x8ee: 0x142b, 0x8ef: 0x14c7, + 0x8f0: 0x0757, 0x8f1: 0x077b, 0x8f2: 0x078f, 0x8f3: 0x084b, 0x8f4: 0x0857, 0x8f5: 0x0897, + 0x8f6: 0x094b, 0x8f7: 0x0967, 0x8f8: 0x096f, 0x8f9: 0x09ab, 0x8fa: 0x09b7, 0x8fb: 0x0a93, + 0x8fc: 0x0a9b, 0x8fd: 0x0ba3, 0x8fe: 0x0bcb, 0x8ff: 0x0bd3, + // Block 0x24, offset 0x900 + 0x900: 0x0beb, 0x901: 0x0c97, 0x902: 0x0cc7, 0x903: 0x0ce7, 0x904: 0x0d57, 0x905: 0x0e1b, + 0x906: 0x0e37, 0x907: 0x0e67, 0x908: 0x0ebb, 0x909: 0x0edb, 0x90a: 0x0f4f, 0x90b: 0x102f, + 0x90c: 0x104b, 0x90d: 0x1053, 0x90e: 0x104f, 0x90f: 0x1057, 0x910: 0x105b, 0x911: 0x105f, + 0x912: 0x1073, 0x913: 0x1077, 0x914: 0x109b, 0x915: 0x10af, 0x916: 0x10cb, 0x917: 0x112f, + 0x918: 0x1137, 0x919: 0x113f, 0x91a: 0x1153, 0x91b: 0x117b, 0x91c: 0x11cb, 0x91d: 0x11ff, + 0x91e: 0x11ff, 0x91f: 0x1267, 0x920: 0x130f, 0x921: 0x1327, 0x922: 0x135b, 0x923: 0x135f, + 0x924: 0x13a3, 0x925: 0x13a7, 0x926: 0x13ff, 0x927: 0x1407, 0x928: 0x14db, 0x929: 0x151f, + 0x92a: 0x1537, 0x92b: 0x0b9b, 0x92c: 0x171e, 0x92d: 0x11e3, + 0x930: 0x06df, 0x931: 0x07e3, 0x932: 0x07a3, 0x933: 0x074b, 0x934: 0x078b, 0x935: 0x07b7, + 0x936: 0x0847, 0x937: 0x0863, 0x938: 0x094b, 0x939: 0x0937, 0x93a: 0x0947, 0x93b: 0x0963, + 0x93c: 0x09af, 0x93d: 0x09bf, 0x93e: 0x0a03, 0x93f: 0x0a0f, + // Block 0x25, offset 0x940 + 0x940: 0x0a2b, 0x941: 0x0a3b, 0x942: 0x0b23, 0x943: 0x0b2b, 0x944: 0x0b5b, 0x945: 0x0b7b, + 0x946: 0x0bab, 0x947: 0x0bc3, 0x948: 0x0bb3, 0x949: 0x0bd3, 0x94a: 0x0bc7, 0x94b: 0x0beb, + 0x94c: 0x0c07, 0x94d: 0x0c5f, 0x94e: 0x0c6b, 0x94f: 0x0c73, 0x950: 0x0c9b, 0x951: 0x0cdf, + 0x952: 0x0d0f, 0x953: 0x0d13, 0x954: 0x0d27, 0x955: 0x0da7, 0x956: 0x0db7, 0x957: 0x0e0f, + 0x958: 0x0e5b, 0x959: 0x0e53, 0x95a: 0x0e67, 0x95b: 0x0e83, 0x95c: 0x0ebb, 0x95d: 0x1013, + 0x95e: 0x0edf, 0x95f: 0x0f13, 0x960: 0x0f1f, 0x961: 0x0f5f, 0x962: 0x0f7b, 0x963: 0x0f9f, + 0x964: 0x0fc3, 0x965: 0x0fc7, 0x966: 0x0fe3, 0x967: 0x0fe7, 0x968: 0x0ff7, 0x969: 0x100b, + 0x96a: 0x1007, 0x96b: 0x1037, 0x96c: 0x10b3, 0x96d: 0x10cb, 0x96e: 0x10e3, 0x96f: 0x111b, + 0x970: 0x112f, 0x971: 0x114b, 0x972: 0x117b, 0x973: 0x122f, 0x974: 0x1257, 0x975: 0x12cb, + 0x976: 0x1313, 0x977: 0x131f, 0x978: 0x1327, 0x979: 0x133f, 0x97a: 0x1353, 0x97b: 0x1343, + 0x97c: 0x135b, 0x97d: 0x1357, 0x97e: 0x134f, 0x97f: 0x135f, + // Block 0x26, offset 0x980 + 0x980: 0x136b, 0x981: 0x13a7, 0x982: 0x13e3, 0x983: 0x1413, 0x984: 0x144b, 0x985: 0x146b, + 0x986: 0x14b7, 0x987: 0x14db, 0x988: 0x14fb, 0x989: 0x150f, 0x98a: 0x151f, 0x98b: 0x152b, + 0x98c: 0x1537, 0x98d: 0x158b, 0x98e: 0x162b, 0x98f: 0x16b5, 0x990: 0x16b0, 0x991: 0x16e2, + 0x992: 0x0607, 0x993: 0x062f, 0x994: 0x0633, 0x995: 0x1764, 0x996: 0x1791, 0x997: 0x1809, + 0x998: 0x1617, 0x999: 0x1627, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x06fb, 0x9c1: 0x06f3, 0x9c2: 0x0703, 0x9c3: 0x1647, 0x9c4: 0x0747, 0x9c5: 0x0757, + 0x9c6: 0x075b, 0x9c7: 0x0763, 0x9c8: 0x076b, 0x9c9: 0x076f, 0x9ca: 0x077b, 0x9cb: 0x0773, + 0x9cc: 0x05b3, 0x9cd: 0x165b, 0x9ce: 0x078f, 0x9cf: 0x0793, 0x9d0: 0x0797, 0x9d1: 0x07b3, + 0x9d2: 0x164c, 0x9d3: 0x05b7, 0x9d4: 0x079f, 0x9d5: 0x07bf, 0x9d6: 0x1656, 0x9d7: 0x07cf, + 0x9d8: 0x07d7, 0x9d9: 0x0737, 0x9da: 0x07df, 0x9db: 0x07e3, 0x9dc: 0x1831, 0x9dd: 0x07ff, + 0x9de: 0x0807, 0x9df: 0x05bf, 0x9e0: 0x081f, 0x9e1: 0x0823, 0x9e2: 0x082b, 0x9e3: 0x082f, + 0x9e4: 0x05c3, 0x9e5: 0x0847, 0x9e6: 0x084b, 0x9e7: 0x0857, 0x9e8: 0x0863, 0x9e9: 0x0867, + 0x9ea: 0x086b, 0x9eb: 0x0873, 0x9ec: 0x0893, 0x9ed: 0x0897, 0x9ee: 0x089f, 0x9ef: 0x08af, + 0x9f0: 0x08b7, 0x9f1: 0x08bb, 0x9f2: 0x08bb, 0x9f3: 0x08bb, 0x9f4: 0x166a, 0x9f5: 0x0e93, + 0x9f6: 0x08cf, 0x9f7: 0x08d7, 0x9f8: 0x166f, 0x9f9: 0x08e3, 0x9fa: 0x08eb, 0x9fb: 0x08f3, + 0x9fc: 0x091b, 0x9fd: 0x0907, 0x9fe: 0x0913, 0x9ff: 0x0917, + // Block 0x28, offset 0xa00 + 0xa00: 0x091f, 0xa01: 0x0927, 0xa02: 0x092b, 0xa03: 0x0933, 0xa04: 0x093b, 0xa05: 0x093f, + 0xa06: 0x093f, 0xa07: 0x0947, 0xa08: 0x094f, 0xa09: 0x0953, 0xa0a: 0x095f, 0xa0b: 0x0983, + 0xa0c: 0x0967, 0xa0d: 0x0987, 0xa0e: 0x096b, 0xa0f: 0x0973, 0xa10: 0x080b, 0xa11: 0x09cf, + 0xa12: 0x0997, 0xa13: 0x099b, 0xa14: 0x099f, 0xa15: 0x0993, 0xa16: 0x09a7, 0xa17: 0x09a3, + 0xa18: 0x09bb, 0xa19: 0x1674, 0xa1a: 0x09d7, 0xa1b: 0x09db, 0xa1c: 0x09e3, 0xa1d: 0x09ef, + 0xa1e: 0x09f7, 0xa1f: 0x0a13, 0xa20: 0x1679, 0xa21: 0x167e, 0xa22: 0x0a1f, 0xa23: 0x0a23, + 0xa24: 0x0a27, 0xa25: 0x0a1b, 0xa26: 0x0a2f, 0xa27: 0x05c7, 0xa28: 0x05cb, 0xa29: 0x0a37, + 0xa2a: 0x0a3f, 0xa2b: 0x0a3f, 0xa2c: 0x1683, 0xa2d: 0x0a5b, 0xa2e: 0x0a5f, 0xa2f: 0x0a63, + 0xa30: 0x0a6b, 0xa31: 0x1688, 0xa32: 0x0a73, 0xa33: 0x0a77, 0xa34: 0x0b4f, 0xa35: 0x0a7f, + 0xa36: 0x05cf, 0xa37: 0x0a8b, 0xa38: 0x0a9b, 0xa39: 0x0aa7, 0xa3a: 0x0aa3, 0xa3b: 0x1692, + 0xa3c: 0x0aaf, 0xa3d: 0x1697, 0xa3e: 0x0abb, 0xa3f: 0x0ab7, + // Block 0x29, offset 0xa40 + 0xa40: 0x0abf, 0xa41: 0x0acf, 0xa42: 0x0ad3, 0xa43: 0x05d3, 0xa44: 0x0ae3, 0xa45: 0x0aeb, + 0xa46: 0x0aef, 0xa47: 0x0af3, 0xa48: 0x05d7, 0xa49: 0x169c, 0xa4a: 0x05db, 0xa4b: 0x0b0f, + 0xa4c: 0x0b13, 0xa4d: 0x0b17, 0xa4e: 0x0b1f, 0xa4f: 0x1863, 0xa50: 0x0b37, 0xa51: 0x16a6, + 0xa52: 0x16a6, 0xa53: 0x11d7, 0xa54: 0x0b47, 0xa55: 0x0b47, 0xa56: 0x05df, 0xa57: 0x16c9, + 0xa58: 0x179b, 0xa59: 0x0b57, 0xa5a: 0x0b5f, 0xa5b: 0x05e3, 0xa5c: 0x0b73, 0xa5d: 0x0b83, + 0xa5e: 0x0b87, 0xa5f: 0x0b8f, 0xa60: 0x0b9f, 0xa61: 0x05eb, 0xa62: 0x05e7, 0xa63: 0x0ba3, + 0xa64: 0x16ab, 0xa65: 0x0ba7, 0xa66: 0x0bbb, 0xa67: 0x0bbf, 0xa68: 0x0bc3, 0xa69: 0x0bbf, + 0xa6a: 0x0bcf, 0xa6b: 0x0bd3, 0xa6c: 0x0be3, 0xa6d: 0x0bdb, 0xa6e: 0x0bdf, 0xa6f: 0x0be7, + 0xa70: 0x0beb, 0xa71: 0x0bef, 0xa72: 0x0bfb, 0xa73: 0x0bff, 0xa74: 0x0c17, 0xa75: 0x0c1f, + 0xa76: 0x0c2f, 0xa77: 0x0c43, 0xa78: 0x16ba, 0xa79: 0x0c3f, 0xa7a: 0x0c33, 0xa7b: 0x0c4b, + 0xa7c: 0x0c53, 0xa7d: 0x0c67, 0xa7e: 0x16bf, 0xa7f: 0x0c6f, + // Block 0x2a, offset 0xa80 + 0xa80: 0x0c63, 0xa81: 0x0c5b, 0xa82: 0x05ef, 0xa83: 0x0c77, 0xa84: 0x0c7f, 0xa85: 0x0c87, + 0xa86: 0x0c7b, 0xa87: 0x05f3, 0xa88: 0x0c97, 0xa89: 0x0c9f, 0xa8a: 0x16c4, 0xa8b: 0x0ccb, + 0xa8c: 0x0cff, 0xa8d: 0x0cdb, 0xa8e: 0x05ff, 0xa8f: 0x0ce7, 0xa90: 0x05fb, 0xa91: 0x05f7, + 0xa92: 0x07c3, 0xa93: 0x07c7, 0xa94: 0x0d03, 0xa95: 0x0ceb, 0xa96: 0x11ab, 0xa97: 0x0663, + 0xa98: 0x0d0f, 0xa99: 0x0d13, 0xa9a: 0x0d17, 0xa9b: 0x0d2b, 0xa9c: 0x0d23, 0xa9d: 0x16dd, + 0xa9e: 0x0603, 0xa9f: 0x0d3f, 0xaa0: 0x0d33, 0xaa1: 0x0d4f, 0xaa2: 0x0d57, 0xaa3: 0x16e7, + 0xaa4: 0x0d5b, 0xaa5: 0x0d47, 0xaa6: 0x0d63, 0xaa7: 0x0607, 0xaa8: 0x0d67, 0xaa9: 0x0d6b, + 0xaaa: 0x0d6f, 0xaab: 0x0d7b, 0xaac: 0x16ec, 0xaad: 0x0d83, 0xaae: 0x060b, 0xaaf: 0x0d8f, + 0xab0: 0x16f1, 0xab1: 0x0d93, 0xab2: 0x060f, 0xab3: 0x0d9f, 0xab4: 0x0dab, 0xab5: 0x0db7, + 0xab6: 0x0dbb, 0xab7: 0x16f6, 0xab8: 0x168d, 0xab9: 0x16fb, 0xaba: 0x0ddb, 0xabb: 0x1700, + 0xabc: 0x0de7, 0xabd: 0x0def, 0xabe: 0x0ddf, 0xabf: 0x0dfb, + // Block 0x2b, offset 0xac0 + 0xac0: 0x0e0b, 0xac1: 0x0e1b, 0xac2: 0x0e0f, 0xac3: 0x0e13, 0xac4: 0x0e1f, 0xac5: 0x0e23, + 0xac6: 0x1705, 0xac7: 0x0e07, 0xac8: 0x0e3b, 0xac9: 0x0e3f, 0xaca: 0x0613, 0xacb: 0x0e53, + 0xacc: 0x0e4f, 0xacd: 0x170a, 0xace: 0x0e33, 0xacf: 0x0e6f, 0xad0: 0x170f, 0xad1: 0x1714, + 0xad2: 0x0e73, 0xad3: 0x0e87, 0xad4: 0x0e83, 0xad5: 0x0e7f, 0xad6: 0x0617, 0xad7: 0x0e8b, + 0xad8: 0x0e9b, 0xad9: 0x0e97, 0xada: 0x0ea3, 0xadb: 0x1651, 0xadc: 0x0eb3, 0xadd: 0x1719, + 0xade: 0x0ebf, 0xadf: 0x1723, 0xae0: 0x0ed3, 0xae1: 0x0edf, 0xae2: 0x0ef3, 0xae3: 0x1728, + 0xae4: 0x0f07, 0xae5: 0x0f0b, 0xae6: 0x172d, 0xae7: 0x1732, 0xae8: 0x0f27, 0xae9: 0x0f37, + 0xaea: 0x061b, 0xaeb: 0x0f3b, 0xaec: 0x061f, 0xaed: 0x061f, 0xaee: 0x0f53, 0xaef: 0x0f57, + 0xaf0: 0x0f5f, 0xaf1: 0x0f63, 0xaf2: 0x0f6f, 0xaf3: 0x0623, 0xaf4: 0x0f87, 0xaf5: 0x1737, + 0xaf6: 0x0fa3, 0xaf7: 0x173c, 0xaf8: 0x0faf, 0xaf9: 0x16a1, 0xafa: 0x0fbf, 0xafb: 0x1741, + 0xafc: 0x1746, 0xafd: 0x174b, 0xafe: 0x0627, 0xaff: 0x062b, + // Block 0x2c, offset 0xb00 + 0xb00: 0x0ff7, 0xb01: 0x1755, 0xb02: 0x1750, 0xb03: 0x175a, 0xb04: 0x175f, 0xb05: 0x0fff, + 0xb06: 0x1003, 0xb07: 0x1003, 0xb08: 0x100b, 0xb09: 0x0633, 0xb0a: 0x100f, 0xb0b: 0x0637, + 0xb0c: 0x063b, 0xb0d: 0x1769, 0xb0e: 0x1023, 0xb0f: 0x102b, 0xb10: 0x1037, 0xb11: 0x063f, + 0xb12: 0x176e, 0xb13: 0x105b, 0xb14: 0x1773, 0xb15: 0x1778, 0xb16: 0x107b, 0xb17: 0x1093, + 0xb18: 0x0643, 0xb19: 0x109b, 0xb1a: 0x109f, 0xb1b: 0x10a3, 0xb1c: 0x177d, 0xb1d: 0x1782, + 0xb1e: 0x1782, 0xb1f: 0x10bb, 0xb20: 0x0647, 0xb21: 0x1787, 0xb22: 0x10cf, 0xb23: 0x10d3, + 0xb24: 0x064b, 0xb25: 0x178c, 0xb26: 0x10ef, 0xb27: 0x064f, 0xb28: 0x10ff, 0xb29: 0x10f7, + 0xb2a: 0x1107, 0xb2b: 0x1796, 0xb2c: 0x111f, 0xb2d: 0x0653, 0xb2e: 0x112b, 0xb2f: 0x1133, + 0xb30: 0x1143, 0xb31: 0x0657, 0xb32: 0x17a0, 0xb33: 0x17a5, 0xb34: 0x065b, 0xb35: 0x17aa, + 0xb36: 0x115b, 0xb37: 0x17af, 0xb38: 0x1167, 0xb39: 0x1173, 0xb3a: 0x117b, 0xb3b: 0x17b4, + 0xb3c: 0x17b9, 0xb3d: 0x118f, 0xb3e: 0x17be, 0xb3f: 0x1197, + // Block 0x2d, offset 0xb40 + 0xb40: 0x16ce, 0xb41: 0x065f, 0xb42: 0x11af, 0xb43: 0x11b3, 0xb44: 0x0667, 0xb45: 0x11b7, + 0xb46: 0x0a33, 0xb47: 0x17c3, 0xb48: 0x17c8, 0xb49: 0x16d3, 0xb4a: 0x16d8, 0xb4b: 0x11d7, + 0xb4c: 0x11db, 0xb4d: 0x13f3, 0xb4e: 0x066b, 0xb4f: 0x1207, 0xb50: 0x1203, 0xb51: 0x120b, + 0xb52: 0x083f, 0xb53: 0x120f, 0xb54: 0x1213, 0xb55: 0x1217, 0xb56: 0x121f, 0xb57: 0x17cd, + 0xb58: 0x121b, 0xb59: 0x1223, 0xb5a: 0x1237, 0xb5b: 0x123b, 0xb5c: 0x1227, 0xb5d: 0x123f, + 0xb5e: 0x1253, 0xb5f: 0x1267, 0xb60: 0x1233, 0xb61: 0x1247, 0xb62: 0x124b, 0xb63: 0x124f, + 0xb64: 0x17d2, 0xb65: 0x17dc, 0xb66: 0x17d7, 0xb67: 0x066f, 0xb68: 0x126f, 0xb69: 0x1273, + 0xb6a: 0x127b, 0xb6b: 0x17f0, 0xb6c: 0x127f, 0xb6d: 0x17e1, 0xb6e: 0x0673, 0xb6f: 0x0677, + 0xb70: 0x17e6, 0xb71: 0x17eb, 0xb72: 0x067b, 0xb73: 0x129f, 0xb74: 0x12a3, 0xb75: 0x12a7, + 0xb76: 0x12ab, 0xb77: 0x12b7, 0xb78: 0x12b3, 0xb79: 0x12bf, 0xb7a: 0x12bb, 0xb7b: 0x12cb, + 0xb7c: 0x12c3, 0xb7d: 0x12c7, 0xb7e: 0x12cf, 0xb7f: 0x067f, + // Block 0x2e, offset 0xb80 + 0xb80: 0x12d7, 0xb81: 0x12db, 0xb82: 0x0683, 0xb83: 0x12eb, 0xb84: 0x12ef, 0xb85: 0x17f5, + 0xb86: 0x12fb, 0xb87: 0x12ff, 0xb88: 0x0687, 0xb89: 0x130b, 0xb8a: 0x05bb, 0xb8b: 0x17fa, + 0xb8c: 0x17ff, 0xb8d: 0x068b, 0xb8e: 0x068f, 0xb8f: 0x1337, 0xb90: 0x134f, 0xb91: 0x136b, + 0xb92: 0x137b, 0xb93: 0x1804, 0xb94: 0x138f, 0xb95: 0x1393, 0xb96: 0x13ab, 0xb97: 0x13b7, + 0xb98: 0x180e, 0xb99: 0x1660, 0xb9a: 0x13c3, 0xb9b: 0x13bf, 0xb9c: 0x13cb, 0xb9d: 0x1665, + 0xb9e: 0x13d7, 0xb9f: 0x13e3, 0xba0: 0x1813, 0xba1: 0x1818, 0xba2: 0x1423, 0xba3: 0x142f, + 0xba4: 0x1437, 0xba5: 0x181d, 0xba6: 0x143b, 0xba7: 0x1467, 0xba8: 0x1473, 0xba9: 0x1477, + 0xbaa: 0x146f, 0xbab: 0x1483, 0xbac: 0x1487, 0xbad: 0x1822, 0xbae: 0x1493, 0xbaf: 0x0693, + 0xbb0: 0x149b, 0xbb1: 0x1827, 0xbb2: 0x0697, 0xbb3: 0x14d3, 0xbb4: 0x0ac3, 0xbb5: 0x14eb, + 0xbb6: 0x182c, 0xbb7: 0x1836, 0xbb8: 0x069b, 0xbb9: 0x069f, 0xbba: 0x1513, 0xbbb: 0x183b, + 0xbbc: 0x06a3, 0xbbd: 0x1840, 0xbbe: 0x152b, 0xbbf: 0x152b, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x1533, 0xbc1: 0x1845, 0xbc2: 0x154b, 0xbc3: 0x06a7, 0xbc4: 0x155b, 0xbc5: 0x1567, + 0xbc6: 0x156f, 0xbc7: 0x1577, 0xbc8: 0x06ab, 0xbc9: 0x184a, 0xbca: 0x158b, 0xbcb: 0x15a7, + 0xbcc: 0x15b3, 0xbcd: 0x06af, 0xbce: 0x06b3, 0xbcf: 0x15b7, 0xbd0: 0x184f, 0xbd1: 0x06b7, + 0xbd2: 0x1854, 0xbd3: 0x1859, 0xbd4: 0x185e, 0xbd5: 0x15db, 0xbd6: 0x06bb, 0xbd7: 0x15ef, + 0xbd8: 0x15f7, 0xbd9: 0x15fb, 0xbda: 0x1603, 0xbdb: 0x160b, 0xbdc: 0x1613, 0xbdd: 0x1868, +} + +// nfcIndex: 22 blocks, 1408 entries, 1408 bytes +// Block 0 is the zero block. +var nfcIndex = [1408]uint8{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x2e, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2f, 0xc7: 0x04, + 0xc8: 0x05, 0xca: 0x30, 0xcb: 0x31, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x32, + 0xd0: 0x09, 0xd1: 0x33, 0xd2: 0x34, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x35, + 0xd8: 0x36, 0xd9: 0x0c, 0xdb: 0x37, 0xdc: 0x38, 0xdd: 0x39, 0xdf: 0x3a, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, + 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a, + 0xf0: 0x13, + // Block 0x4, offset 0x100 + 0x120: 0x3b, 0x121: 0x3c, 0x123: 0x0d, 0x124: 0x3d, 0x125: 0x3e, 0x126: 0x3f, 0x127: 0x40, + 0x128: 0x41, 0x129: 0x42, 0x12a: 0x43, 0x12b: 0x44, 0x12c: 0x3f, 0x12d: 0x45, 0x12e: 0x46, 0x12f: 0x47, + 0x131: 0x48, 0x132: 0x49, 0x133: 0x4a, 0x134: 0x4b, 0x135: 0x4c, 0x137: 0x4d, + 0x138: 0x4e, 0x139: 0x4f, 0x13a: 0x50, 0x13b: 0x51, 0x13c: 0x52, 0x13d: 0x53, 0x13e: 0x54, 0x13f: 0x55, + // Block 0x5, offset 0x140 + 0x140: 0x56, 0x142: 0x57, 0x144: 0x58, 0x145: 0x59, 0x146: 0x5a, 0x147: 0x5b, + 0x14d: 0x5c, + 0x15c: 0x5d, 0x15f: 0x5e, + 0x162: 0x5f, 0x164: 0x60, + 0x168: 0x61, 0x169: 0x62, 0x16a: 0x63, 0x16c: 0x0e, 0x16d: 0x64, 0x16e: 0x65, 0x16f: 0x66, + 0x170: 0x67, 0x173: 0x68, 0x177: 0x0f, + 0x178: 0x10, 0x179: 0x11, 0x17a: 0x12, 0x17b: 0x13, 0x17c: 0x14, 0x17d: 0x15, 0x17e: 0x16, 0x17f: 0x17, + // Block 0x6, offset 0x180 + 0x180: 0x69, 0x183: 0x6a, 0x184: 0x6b, 0x186: 0x6c, 0x187: 0x6d, + 0x188: 0x6e, 0x189: 0x18, 0x18a: 0x19, 0x18b: 0x6f, 0x18c: 0x70, + 0x1ab: 0x71, + 0x1b3: 0x72, 0x1b5: 0x73, 0x1b7: 0x74, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x75, 0x1c1: 0x1a, 0x1c2: 0x1b, 0x1c3: 0x1c, 0x1c4: 0x76, 0x1c5: 0x77, + 0x1c9: 0x78, 0x1cc: 0x79, 0x1cd: 0x7a, + // Block 0x8, offset 0x200 + 0x219: 0x7b, 0x21a: 0x7c, 0x21b: 0x7d, + 0x220: 0x7e, 0x223: 0x7f, 0x224: 0x80, 0x225: 0x81, 0x226: 0x82, 0x227: 0x83, + 0x22a: 0x84, 0x22b: 0x85, 0x22f: 0x86, + 0x230: 0x87, 0x231: 0x88, 0x232: 0x89, 0x233: 0x8a, 0x234: 0x8b, 0x235: 0x8c, 0x236: 0x8d, 0x237: 0x87, + 0x238: 0x88, 0x239: 0x89, 0x23a: 0x8a, 0x23b: 0x8b, 0x23c: 0x8c, 0x23d: 0x8d, 0x23e: 0x87, 0x23f: 0x88, + // Block 0x9, offset 0x240 + 0x240: 0x89, 0x241: 0x8a, 0x242: 0x8b, 0x243: 0x8c, 0x244: 0x8d, 0x245: 0x87, 0x246: 0x88, 0x247: 0x89, + 0x248: 0x8a, 0x249: 0x8b, 0x24a: 0x8c, 0x24b: 0x8d, 0x24c: 0x87, 0x24d: 0x88, 0x24e: 0x89, 0x24f: 0x8a, + 0x250: 0x8b, 0x251: 0x8c, 0x252: 0x8d, 0x253: 0x87, 0x254: 0x88, 0x255: 0x89, 0x256: 0x8a, 0x257: 0x8b, + 0x258: 0x8c, 0x259: 0x8d, 0x25a: 0x87, 0x25b: 0x88, 0x25c: 0x89, 0x25d: 0x8a, 0x25e: 0x8b, 0x25f: 0x8c, + 0x260: 0x8d, 0x261: 0x87, 0x262: 0x88, 0x263: 0x89, 0x264: 0x8a, 0x265: 0x8b, 0x266: 0x8c, 0x267: 0x8d, + 0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26c: 0x8b, 0x26d: 0x8c, 0x26e: 0x8d, 0x26f: 0x87, + 0x270: 0x88, 0x271: 0x89, 0x272: 0x8a, 0x273: 0x8b, 0x274: 0x8c, 0x275: 0x8d, 0x276: 0x87, 0x277: 0x88, + 0x278: 0x89, 0x279: 0x8a, 0x27a: 0x8b, 0x27b: 0x8c, 0x27c: 0x8d, 0x27d: 0x87, 0x27e: 0x88, 0x27f: 0x89, + // Block 0xa, offset 0x280 + 0x280: 0x8a, 0x281: 0x8b, 0x282: 0x8c, 0x283: 0x8d, 0x284: 0x87, 0x285: 0x88, 0x286: 0x89, 0x287: 0x8a, + 0x288: 0x8b, 0x289: 0x8c, 0x28a: 0x8d, 0x28b: 0x87, 0x28c: 0x88, 0x28d: 0x89, 0x28e: 0x8a, 0x28f: 0x8b, + 0x290: 0x8c, 0x291: 0x8d, 0x292: 0x87, 0x293: 0x88, 0x294: 0x89, 0x295: 0x8a, 0x296: 0x8b, 0x297: 0x8c, + 0x298: 0x8d, 0x299: 0x87, 0x29a: 0x88, 0x29b: 0x89, 0x29c: 0x8a, 0x29d: 0x8b, 0x29e: 0x8c, 0x29f: 0x8d, + 0x2a0: 0x87, 0x2a1: 0x88, 0x2a2: 0x89, 0x2a3: 0x8a, 0x2a4: 0x8b, 0x2a5: 0x8c, 0x2a6: 0x8d, 0x2a7: 0x87, + 0x2a8: 0x88, 0x2a9: 0x89, 0x2aa: 0x8a, 0x2ab: 0x8b, 0x2ac: 0x8c, 0x2ad: 0x8d, 0x2ae: 0x87, 0x2af: 0x88, + 0x2b0: 0x89, 0x2b1: 0x8a, 0x2b2: 0x8b, 0x2b3: 0x8c, 0x2b4: 0x8d, 0x2b5: 0x87, 0x2b6: 0x88, 0x2b7: 0x89, + 0x2b8: 0x8a, 0x2b9: 0x8b, 0x2ba: 0x8c, 0x2bb: 0x8d, 0x2bc: 0x87, 0x2bd: 0x88, 0x2be: 0x89, 0x2bf: 0x8a, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x8b, 0x2c1: 0x8c, 0x2c2: 0x8d, 0x2c3: 0x87, 0x2c4: 0x88, 0x2c5: 0x89, 0x2c6: 0x8a, 0x2c7: 0x8b, + 0x2c8: 0x8c, 0x2c9: 0x8d, 0x2ca: 0x87, 0x2cb: 0x88, 0x2cc: 0x89, 0x2cd: 0x8a, 0x2ce: 0x8b, 0x2cf: 0x8c, + 0x2d0: 0x8d, 0x2d1: 0x87, 0x2d2: 0x88, 0x2d3: 0x89, 0x2d4: 0x8a, 0x2d5: 0x8b, 0x2d6: 0x8c, 0x2d7: 0x8d, + 0x2d8: 0x87, 0x2d9: 0x88, 0x2da: 0x89, 0x2db: 0x8a, 0x2dc: 0x8b, 0x2dd: 0x8c, 0x2de: 0x8e, + // Block 0xc, offset 0x300 + 0x324: 0x1d, 0x325: 0x1e, 0x326: 0x1f, 0x327: 0x20, + 0x328: 0x21, 0x329: 0x22, 0x32a: 0x23, 0x32b: 0x24, 0x32c: 0x8f, 0x32d: 0x90, 0x32e: 0x91, + 0x331: 0x92, 0x332: 0x93, 0x333: 0x94, 0x334: 0x95, + 0x338: 0x96, 0x339: 0x97, 0x33a: 0x98, 0x33b: 0x99, 0x33e: 0x9a, 0x33f: 0x9b, + // Block 0xd, offset 0x340 + 0x347: 0x9c, + 0x34b: 0x9d, 0x34d: 0x9e, + 0x368: 0x9f, 0x36b: 0xa0, + 0x374: 0xa1, + 0x37d: 0xa2, + // Block 0xe, offset 0x380 + 0x381: 0xa3, 0x382: 0xa4, 0x384: 0xa5, 0x385: 0x82, 0x387: 0xa6, + 0x388: 0xa7, 0x38b: 0xa8, 0x38c: 0xa9, 0x38d: 0xaa, + 0x391: 0xab, 0x392: 0xac, 0x393: 0xad, 0x396: 0xae, 0x397: 0xaf, + 0x398: 0x73, 0x39a: 0xb0, 0x39c: 0xb1, + 0x3a0: 0xb2, 0x3a7: 0xb3, + 0x3a8: 0xb4, 0x3a9: 0xb5, 0x3aa: 0xb6, + 0x3b0: 0x73, 0x3b5: 0xb7, 0x3b6: 0xb8, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xb9, 0x3ec: 0xba, + // Block 0x10, offset 0x400 + 0x432: 0xbb, + // Block 0x11, offset 0x440 + 0x445: 0xbc, 0x446: 0xbd, 0x447: 0xbe, + 0x449: 0xbf, + // Block 0x12, offset 0x480 + 0x480: 0xc0, 0x484: 0xba, + 0x48b: 0xc1, + 0x4a3: 0xc2, 0x4a5: 0xc3, + // Block 0x13, offset 0x4c0 + 0x4c8: 0xc4, + // Block 0x14, offset 0x500 + 0x520: 0x25, 0x521: 0x26, 0x522: 0x27, 0x523: 0x28, 0x524: 0x29, 0x525: 0x2a, 0x526: 0x2b, 0x527: 0x2c, + 0x528: 0x2d, + // Block 0x15, offset 0x540 + 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d, + 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11, + 0x56f: 0x12, +} + +// nfcSparseOffset: 151 entries, 302 bytes +var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x63, 0x68, 0x6a, 0x72, 0x79, 0x7c, 0x84, 0x88, 0x8c, 0x8e, 0x90, 0x99, 0x9d, 0xa4, 0xa9, 0xac, 0xb6, 0xb9, 0xc0, 0xc8, 0xcb, 0xcd, 0xd0, 0xd2, 0xd7, 0xe8, 0xf4, 0xf6, 0xfc, 0xfe, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10b, 0x10e, 0x110, 0x113, 0x116, 0x11a, 0x11f, 0x128, 0x12a, 0x12d, 0x12f, 0x13a, 0x13e, 0x14c, 0x14f, 0x155, 0x15b, 0x166, 0x16a, 0x16c, 0x16e, 0x170, 0x172, 0x174, 0x17a, 0x17e, 0x180, 0x182, 0x18a, 0x18e, 0x191, 0x193, 0x195, 0x197, 0x19a, 0x19c, 0x19e, 0x1a0, 0x1a2, 0x1a8, 0x1ab, 0x1ad, 0x1b4, 0x1ba, 0x1c0, 0x1c8, 0x1ce, 0x1d4, 0x1da, 0x1de, 0x1ec, 0x1f5, 0x1f8, 0x1fb, 0x1fd, 0x200, 0x202, 0x206, 0x20b, 0x20d, 0x20f, 0x214, 0x21a, 0x21c, 0x21e, 0x220, 0x226, 0x229, 0x22b, 0x231, 0x234, 0x23c, 0x243, 0x246, 0x249, 0x24b, 0x24e, 0x256, 0x25a, 0x261, 0x264, 0x26a, 0x26c, 0x26f, 0x271, 0x274, 0x276, 0x278, 0x27a, 0x27c, 0x27f, 0x281, 0x283, 0x285, 0x287, 0x294, 0x29e, 0x2a0, 0x2a2, 0x2a8, 0x2aa, 0x2ac, 0x2af} + +// nfcSparseValues: 689 entries, 2756 bytes +var nfcSparseValues = [689]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0000, lo: 0x04}, + {value: 0xa100, lo: 0xa8, hi: 0xa8}, + {value: 0x8100, lo: 0xaf, hi: 0xaf}, + {value: 0x8100, lo: 0xb4, hi: 0xb4}, + {value: 0x8100, lo: 0xb8, hi: 0xb8}, + // Block 0x1, offset 0x5 + {value: 0x0091, lo: 0x03}, + {value: 0x46e5, lo: 0xa0, hi: 0xa1}, + {value: 0x4717, lo: 0xaf, hi: 0xb0}, + {value: 0xa000, lo: 0xb7, hi: 0xb7}, + // Block 0x2, offset 0x9 + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + // Block 0x3, offset 0xb + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x98, hi: 0x9d}, + // Block 0x4, offset 0xd + {value: 0x0006, lo: 0x0a}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x85, hi: 0x85}, + {value: 0xa000, lo: 0x89, hi: 0x89}, + {value: 0x4843, lo: 0x8a, hi: 0x8a}, + {value: 0x4861, lo: 0x8b, hi: 0x8b}, + {value: 0x36ca, lo: 0x8c, hi: 0x8c}, + {value: 0x36e2, lo: 0x8d, hi: 0x8d}, + {value: 0x4879, lo: 0x8e, hi: 0x8e}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3700, lo: 0x93, hi: 0x94}, + // Block 0x5, offset 0x18 + {value: 0x0000, lo: 0x0f}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0xa000, lo: 0x8d, hi: 0x8d}, + {value: 0x37a8, lo: 0x90, hi: 0x90}, + {value: 0x37b4, lo: 0x91, hi: 0x91}, + {value: 0x37a2, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x381a, lo: 0x97, hi: 0x97}, + {value: 0x37e4, lo: 0x9c, hi: 0x9c}, + {value: 0x37cc, lo: 0x9d, hi: 0x9d}, + {value: 0x37f6, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x3820, lo: 0xb6, hi: 0xb6}, + {value: 0x3826, lo: 0xb7, hi: 0xb7}, + // Block 0x6, offset 0x28 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x83, hi: 0x87}, + // Block 0x7, offset 0x2a + {value: 0x0001, lo: 0x04}, + {value: 0x8113, lo: 0x81, hi: 0x82}, + {value: 0x8132, lo: 0x84, hi: 0x84}, + {value: 0x812d, lo: 0x85, hi: 0x85}, + {value: 0x810d, lo: 0x87, hi: 0x87}, + // Block 0x8, offset 0x2f + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x97}, + {value: 0x8119, lo: 0x98, hi: 0x98}, + {value: 0x811a, lo: 0x99, hi: 0x99}, + {value: 0x811b, lo: 0x9a, hi: 0x9a}, + {value: 0x3844, lo: 0xa2, hi: 0xa2}, + {value: 0x384a, lo: 0xa3, hi: 0xa3}, + {value: 0x3856, lo: 0xa4, hi: 0xa4}, + {value: 0x3850, lo: 0xa5, hi: 0xa5}, + {value: 0x385c, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x9, offset 0x3a + {value: 0x0000, lo: 0x0e}, + {value: 0x386e, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x3862, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3868, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8132, lo: 0x96, hi: 0x9c}, + {value: 0x8132, lo: 0x9f, hi: 0xa2}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa4}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + // Block 0xa, offset 0x49 + {value: 0x0000, lo: 0x0c}, + {value: 0x811f, lo: 0x91, hi: 0x91}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x812d, lo: 0xb1, hi: 0xb1}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb5, hi: 0xb6}, + {value: 0x812d, lo: 0xb7, hi: 0xb9}, + {value: 0x8132, lo: 0xba, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbc}, + {value: 0x8132, lo: 0xbd, hi: 0xbd}, + {value: 0x812d, lo: 0xbe, hi: 0xbe}, + {value: 0x8132, lo: 0xbf, hi: 0xbf}, + // Block 0xb, offset 0x56 + {value: 0x0005, lo: 0x07}, + {value: 0x8132, lo: 0x80, hi: 0x80}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x83}, + {value: 0x812d, lo: 0x84, hi: 0x85}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x812d, lo: 0x88, hi: 0x89}, + {value: 0x8132, lo: 0x8a, hi: 0x8a}, + // Block 0xc, offset 0x5e + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xab, hi: 0xb1}, + {value: 0x812d, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb3}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0xd, offset 0x63 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0x96, hi: 0x99}, + {value: 0x8132, lo: 0x9b, hi: 0xa3}, + {value: 0x8132, lo: 0xa5, hi: 0xa7}, + {value: 0x8132, lo: 0xa9, hi: 0xad}, + // Block 0xe, offset 0x68 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x99, hi: 0x9b}, + // Block 0xf, offset 0x6a + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3edb, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ee3, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3eeb, lo: 0xb4, hi: 0xb4}, + {value: 0x9902, lo: 0xbc, hi: 0xbc}, + // Block 0x10, offset 0x72 + {value: 0x0008, lo: 0x06}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x91, hi: 0x91}, + {value: 0x812d, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x93, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x94}, + {value: 0x451f, lo: 0x98, hi: 0x9f}, + // Block 0x11, offset 0x79 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x12, offset 0x7c + {value: 0x0008, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2ca1, lo: 0x8b, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x455f, lo: 0x9c, hi: 0x9d}, + {value: 0x456f, lo: 0x9f, hi: 0x9f}, + {value: 0x8132, lo: 0xbe, hi: 0xbe}, + // Block 0x13, offset 0x84 + {value: 0x0000, lo: 0x03}, + {value: 0x4597, lo: 0xb3, hi: 0xb3}, + {value: 0x459f, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x14, offset 0x88 + {value: 0x0008, lo: 0x03}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x4577, lo: 0x99, hi: 0x9b}, + {value: 0x458f, lo: 0x9e, hi: 0x9e}, + // Block 0x15, offset 0x8c + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x16, offset 0x8e + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + // Block 0x17, offset 0x90 + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cb9, lo: 0x88, hi: 0x88}, + {value: 0x2cb1, lo: 0x8b, hi: 0x8b}, + {value: 0x2cc1, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45a7, lo: 0x9c, hi: 0x9c}, + {value: 0x45af, lo: 0x9d, hi: 0x9d}, + // Block 0x18, offset 0x99 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cc9, lo: 0x94, hi: 0x94}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x19, offset 0x9d + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cd1, lo: 0x8a, hi: 0x8a}, + {value: 0x2ce1, lo: 0x8b, hi: 0x8b}, + {value: 0x2cd9, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1a, offset 0xa4 + {value: 0x1801, lo: 0x04}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x3ef3, lo: 0x88, hi: 0x88}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8120, lo: 0x95, hi: 0x96}, + // Block 0x1b, offset 0xa9 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1c, offset 0xac + {value: 0x0000, lo: 0x09}, + {value: 0x2ce9, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cf1, lo: 0x87, hi: 0x87}, + {value: 0x2cf9, lo: 0x88, hi: 0x88}, + {value: 0x2f53, lo: 0x8a, hi: 0x8a}, + {value: 0x2ddb, lo: 0x8b, hi: 0x8b}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1d, offset 0xb6 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1e, offset 0xb9 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2d01, lo: 0x8a, hi: 0x8a}, + {value: 0x2d11, lo: 0x8b, hi: 0x8b}, + {value: 0x2d09, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1f, offset 0xc0 + {value: 0x6be7, lo: 0x07}, + {value: 0x9904, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3efb, lo: 0x9a, hi: 0x9a}, + {value: 0x2f5b, lo: 0x9c, hi: 0x9c}, + {value: 0x2de6, lo: 0x9d, hi: 0x9d}, + {value: 0x2d19, lo: 0x9e, hi: 0x9f}, + // Block 0x20, offset 0xc8 + {value: 0x0000, lo: 0x02}, + {value: 0x8122, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x21, offset 0xcb + {value: 0x0000, lo: 0x01}, + {value: 0x8123, lo: 0x88, hi: 0x8b}, + // Block 0x22, offset 0xcd + {value: 0x0000, lo: 0x02}, + {value: 0x8124, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x23, offset 0xd0 + {value: 0x0000, lo: 0x01}, + {value: 0x8125, lo: 0x88, hi: 0x8b}, + // Block 0x24, offset 0xd2 + {value: 0x0000, lo: 0x04}, + {value: 0x812d, lo: 0x98, hi: 0x99}, + {value: 0x812d, lo: 0xb5, hi: 0xb5}, + {value: 0x812d, lo: 0xb7, hi: 0xb7}, + {value: 0x812b, lo: 0xb9, hi: 0xb9}, + // Block 0x25, offset 0xd7 + {value: 0x0000, lo: 0x10}, + {value: 0x2647, lo: 0x83, hi: 0x83}, + {value: 0x264e, lo: 0x8d, hi: 0x8d}, + {value: 0x2655, lo: 0x92, hi: 0x92}, + {value: 0x265c, lo: 0x97, hi: 0x97}, + {value: 0x2663, lo: 0x9c, hi: 0x9c}, + {value: 0x2640, lo: 0xa9, hi: 0xa9}, + {value: 0x8126, lo: 0xb1, hi: 0xb1}, + {value: 0x8127, lo: 0xb2, hi: 0xb2}, + {value: 0x4a87, lo: 0xb3, hi: 0xb3}, + {value: 0x8128, lo: 0xb4, hi: 0xb4}, + {value: 0x4a90, lo: 0xb5, hi: 0xb5}, + {value: 0x45b7, lo: 0xb6, hi: 0xb6}, + {value: 0x8200, lo: 0xb7, hi: 0xb7}, + {value: 0x45bf, lo: 0xb8, hi: 0xb8}, + {value: 0x8200, lo: 0xb9, hi: 0xb9}, + {value: 0x8127, lo: 0xba, hi: 0xbd}, + // Block 0x26, offset 0xe8 + {value: 0x0000, lo: 0x0b}, + {value: 0x8127, lo: 0x80, hi: 0x80}, + {value: 0x4a99, lo: 0x81, hi: 0x81}, + {value: 0x8132, lo: 0x82, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0x86, hi: 0x87}, + {value: 0x2671, lo: 0x93, hi: 0x93}, + {value: 0x2678, lo: 0x9d, hi: 0x9d}, + {value: 0x267f, lo: 0xa2, hi: 0xa2}, + {value: 0x2686, lo: 0xa7, hi: 0xa7}, + {value: 0x268d, lo: 0xac, hi: 0xac}, + {value: 0x266a, lo: 0xb9, hi: 0xb9}, + // Block 0x27, offset 0xf4 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x86, hi: 0x86}, + // Block 0x28, offset 0xf6 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d21, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x29, offset 0xfc + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + // Block 0x2a, offset 0xfe + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x80, hi: 0x92}, + // Block 0x2b, offset 0x100 + {value: 0x0000, lo: 0x01}, + {value: 0xb900, lo: 0xa1, hi: 0xb5}, + // Block 0x2c, offset 0x102 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xa8, hi: 0xbf}, + // Block 0x2d, offset 0x104 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0x80, hi: 0x82}, + // Block 0x2e, offset 0x106 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9d, hi: 0x9f}, + // Block 0x2f, offset 0x108 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x94, hi: 0x94}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x30, offset 0x10b + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x9d, hi: 0x9d}, + // Block 0x31, offset 0x10e + {value: 0x0000, lo: 0x01}, + {value: 0x8131, lo: 0xa9, hi: 0xa9}, + // Block 0x32, offset 0x110 + {value: 0x0004, lo: 0x02}, + {value: 0x812e, lo: 0xb9, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbb}, + // Block 0x33, offset 0x113 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x97, hi: 0x97}, + {value: 0x812d, lo: 0x98, hi: 0x98}, + // Block 0x34, offset 0x116 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + {value: 0x8132, lo: 0xb5, hi: 0xbc}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x35, offset 0x11a + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + {value: 0x812d, lo: 0xb5, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x36, offset 0x11f + {value: 0x0000, lo: 0x08}, + {value: 0x2d69, lo: 0x80, hi: 0x80}, + {value: 0x2d71, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d79, lo: 0x83, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xac}, + {value: 0x8132, lo: 0xad, hi: 0xb3}, + // Block 0x37, offset 0x128 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xaa, hi: 0xab}, + // Block 0x38, offset 0x12a + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xa6, hi: 0xa6}, + {value: 0x8104, lo: 0xb2, hi: 0xb3}, + // Block 0x39, offset 0x12d + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x3a, offset 0x12f + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812d, lo: 0x95, hi: 0x99}, + {value: 0x8132, lo: 0x9a, hi: 0x9b}, + {value: 0x812d, lo: 0x9c, hi: 0x9f}, + {value: 0x8132, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + {value: 0x8132, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb8, hi: 0xb9}, + // Block 0x3b, offset 0x13a + {value: 0x0004, lo: 0x03}, + {value: 0x0433, lo: 0x80, hi: 0x81}, + {value: 0x8100, lo: 0x97, hi: 0x97}, + {value: 0x8100, lo: 0xbe, hi: 0xbe}, + // Block 0x3c, offset 0x13e + {value: 0x0000, lo: 0x0d}, + {value: 0x8132, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8132, lo: 0x9b, hi: 0x9c}, + {value: 0x8132, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa7}, + {value: 0x812d, lo: 0xa8, hi: 0xa8}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xaf}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + // Block 0x3d, offset 0x14c + {value: 0x427e, lo: 0x02}, + {value: 0x01b8, lo: 0xa6, hi: 0xa6}, + {value: 0x0057, lo: 0xaa, hi: 0xab}, + // Block 0x3e, offset 0x14f + {value: 0x0007, lo: 0x05}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bbc, lo: 0x9a, hi: 0x9b}, + {value: 0x3bca, lo: 0xae, hi: 0xae}, + // Block 0x3f, offset 0x155 + {value: 0x000e, lo: 0x05}, + {value: 0x3bd1, lo: 0x8d, hi: 0x8e}, + {value: 0x3bd8, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x40, offset 0x15b + {value: 0x6405, lo: 0x0a}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3be6, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3bed, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3bf4, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3bfb, lo: 0xa4, hi: 0xa5}, + {value: 0x3c02, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x41, offset 0x166 + {value: 0x0007, lo: 0x03}, + {value: 0x3c6b, lo: 0xa0, hi: 0xa1}, + {value: 0x3c95, lo: 0xa2, hi: 0xa3}, + {value: 0x3cbf, lo: 0xaa, hi: 0xad}, + // Block 0x42, offset 0x16a + {value: 0x0004, lo: 0x01}, + {value: 0x048b, lo: 0xa9, hi: 0xaa}, + // Block 0x43, offset 0x16c + {value: 0x0000, lo: 0x01}, + {value: 0x44e0, lo: 0x9c, hi: 0x9c}, + // Block 0x44, offset 0x16e + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xaf, hi: 0xb1}, + // Block 0x45, offset 0x170 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x46, offset 0x172 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa0, hi: 0xbf}, + // Block 0x47, offset 0x174 + {value: 0x0000, lo: 0x05}, + {value: 0x812c, lo: 0xaa, hi: 0xaa}, + {value: 0x8131, lo: 0xab, hi: 0xab}, + {value: 0x8133, lo: 0xac, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x812f, lo: 0xae, hi: 0xaf}, + // Block 0x48, offset 0x17a + {value: 0x0000, lo: 0x03}, + {value: 0x4aa2, lo: 0xb3, hi: 0xb3}, + {value: 0x4aa2, lo: 0xb5, hi: 0xb6}, + {value: 0x4aa2, lo: 0xba, hi: 0xbf}, + // Block 0x49, offset 0x17e + {value: 0x0000, lo: 0x01}, + {value: 0x4aa2, lo: 0x8f, hi: 0xa3}, + // Block 0x4a, offset 0x180 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xae, hi: 0xbe}, + // Block 0x4b, offset 0x182 + {value: 0x0000, lo: 0x07}, + {value: 0x8100, lo: 0x84, hi: 0x84}, + {value: 0x8100, lo: 0x87, hi: 0x87}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + {value: 0x8100, lo: 0x9e, hi: 0x9e}, + {value: 0x8100, lo: 0xa1, hi: 0xa1}, + {value: 0x8100, lo: 0xb2, hi: 0xb2}, + {value: 0x8100, lo: 0xbb, hi: 0xbb}, + // Block 0x4c, offset 0x18a + {value: 0x0000, lo: 0x03}, + {value: 0x8100, lo: 0x80, hi: 0x80}, + {value: 0x8100, lo: 0x8b, hi: 0x8b}, + {value: 0x8100, lo: 0x8e, hi: 0x8e}, + // Block 0x4d, offset 0x18e + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xaf, hi: 0xaf}, + {value: 0x8132, lo: 0xb4, hi: 0xbd}, + // Block 0x4e, offset 0x191 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9e, hi: 0x9f}, + // Block 0x4f, offset 0x193 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb1}, + // Block 0x50, offset 0x195 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + // Block 0x51, offset 0x197 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xa0, hi: 0xb1}, + // Block 0x52, offset 0x19a + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xab, hi: 0xad}, + // Block 0x53, offset 0x19c + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x93, hi: 0x93}, + // Block 0x54, offset 0x19e + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb3, hi: 0xb3}, + // Block 0x55, offset 0x1a0 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + // Block 0x56, offset 0x1a2 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x8132, lo: 0xbe, hi: 0xbf}, + // Block 0x57, offset 0x1a8 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + // Block 0x58, offset 0x1ab + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xad, hi: 0xad}, + // Block 0x59, offset 0x1ad + {value: 0x0000, lo: 0x06}, + {value: 0xe500, lo: 0x80, hi: 0x80}, + {value: 0xc600, lo: 0x81, hi: 0x9b}, + {value: 0xe500, lo: 0x9c, hi: 0x9c}, + {value: 0xc600, lo: 0x9d, hi: 0xb7}, + {value: 0xe500, lo: 0xb8, hi: 0xb8}, + {value: 0xc600, lo: 0xb9, hi: 0xbf}, + // Block 0x5a, offset 0x1b4 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x93}, + {value: 0xe500, lo: 0x94, hi: 0x94}, + {value: 0xc600, lo: 0x95, hi: 0xaf}, + {value: 0xe500, lo: 0xb0, hi: 0xb0}, + {value: 0xc600, lo: 0xb1, hi: 0xbf}, + // Block 0x5b, offset 0x1ba + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8b}, + {value: 0xe500, lo: 0x8c, hi: 0x8c}, + {value: 0xc600, lo: 0x8d, hi: 0xa7}, + {value: 0xe500, lo: 0xa8, hi: 0xa8}, + {value: 0xc600, lo: 0xa9, hi: 0xbf}, + // Block 0x5c, offset 0x1c0 + {value: 0x0000, lo: 0x07}, + {value: 0xc600, lo: 0x80, hi: 0x83}, + {value: 0xe500, lo: 0x84, hi: 0x84}, + {value: 0xc600, lo: 0x85, hi: 0x9f}, + {value: 0xe500, lo: 0xa0, hi: 0xa0}, + {value: 0xc600, lo: 0xa1, hi: 0xbb}, + {value: 0xe500, lo: 0xbc, hi: 0xbc}, + {value: 0xc600, lo: 0xbd, hi: 0xbf}, + // Block 0x5d, offset 0x1c8 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x97}, + {value: 0xe500, lo: 0x98, hi: 0x98}, + {value: 0xc600, lo: 0x99, hi: 0xb3}, + {value: 0xe500, lo: 0xb4, hi: 0xb4}, + {value: 0xc600, lo: 0xb5, hi: 0xbf}, + // Block 0x5e, offset 0x1ce + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8f}, + {value: 0xe500, lo: 0x90, hi: 0x90}, + {value: 0xc600, lo: 0x91, hi: 0xab}, + {value: 0xe500, lo: 0xac, hi: 0xac}, + {value: 0xc600, lo: 0xad, hi: 0xbf}, + // Block 0x5f, offset 0x1d4 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + {value: 0xe500, lo: 0xa4, hi: 0xa4}, + {value: 0xc600, lo: 0xa5, hi: 0xbf}, + // Block 0x60, offset 0x1da + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x61, offset 0x1de + {value: 0x0006, lo: 0x0d}, + {value: 0x4393, lo: 0x9d, hi: 0x9d}, + {value: 0x8115, lo: 0x9e, hi: 0x9e}, + {value: 0x4405, lo: 0x9f, hi: 0x9f}, + {value: 0x43f3, lo: 0xaa, hi: 0xab}, + {value: 0x44f7, lo: 0xac, hi: 0xac}, + {value: 0x44ff, lo: 0xad, hi: 0xad}, + {value: 0x434b, lo: 0xae, hi: 0xb1}, + {value: 0x4369, lo: 0xb2, hi: 0xb4}, + {value: 0x4381, lo: 0xb5, hi: 0xb6}, + {value: 0x438d, lo: 0xb8, hi: 0xb8}, + {value: 0x4399, lo: 0xb9, hi: 0xbb}, + {value: 0x43b1, lo: 0xbc, hi: 0xbc}, + {value: 0x43b7, lo: 0xbe, hi: 0xbe}, + // Block 0x62, offset 0x1ec + {value: 0x0006, lo: 0x08}, + {value: 0x43bd, lo: 0x80, hi: 0x81}, + {value: 0x43c9, lo: 0x83, hi: 0x84}, + {value: 0x43db, lo: 0x86, hi: 0x89}, + {value: 0x43ff, lo: 0x8a, hi: 0x8a}, + {value: 0x437b, lo: 0x8b, hi: 0x8b}, + {value: 0x4363, lo: 0x8c, hi: 0x8c}, + {value: 0x43ab, lo: 0x8d, hi: 0x8d}, + {value: 0x43d5, lo: 0x8e, hi: 0x8e}, + // Block 0x63, offset 0x1f5 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0xa4, hi: 0xa5}, + {value: 0x8100, lo: 0xb0, hi: 0xb1}, + // Block 0x64, offset 0x1f8 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x9b, hi: 0x9d}, + {value: 0x8200, lo: 0x9e, hi: 0xa3}, + // Block 0x65, offset 0x1fb + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + // Block 0x66, offset 0x1fd + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x99, hi: 0x99}, + {value: 0x8200, lo: 0xb2, hi: 0xb4}, + // Block 0x67, offset 0x200 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xbc, hi: 0xbd}, + // Block 0x68, offset 0x202 + {value: 0x0000, lo: 0x03}, + {value: 0x8132, lo: 0xa0, hi: 0xa6}, + {value: 0x812d, lo: 0xa7, hi: 0xad}, + {value: 0x8132, lo: 0xae, hi: 0xaf}, + // Block 0x69, offset 0x206 + {value: 0x0000, lo: 0x04}, + {value: 0x8100, lo: 0x89, hi: 0x8c}, + {value: 0x8100, lo: 0xb0, hi: 0xb2}, + {value: 0x8100, lo: 0xb4, hi: 0xb4}, + {value: 0x8100, lo: 0xb6, hi: 0xbf}, + // Block 0x6a, offset 0x20b + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x81, hi: 0x8c}, + // Block 0x6b, offset 0x20d + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xb5, hi: 0xba}, + // Block 0x6c, offset 0x20f + {value: 0x0000, lo: 0x04}, + {value: 0x4aa2, lo: 0x9e, hi: 0x9f}, + {value: 0x4aa2, lo: 0xa3, hi: 0xa3}, + {value: 0x4aa2, lo: 0xa5, hi: 0xa6}, + {value: 0x4aa2, lo: 0xaa, hi: 0xaf}, + // Block 0x6d, offset 0x214 + {value: 0x0000, lo: 0x05}, + {value: 0x4aa2, lo: 0x82, hi: 0x87}, + {value: 0x4aa2, lo: 0x8a, hi: 0x8f}, + {value: 0x4aa2, lo: 0x92, hi: 0x97}, + {value: 0x4aa2, lo: 0x9a, hi: 0x9c}, + {value: 0x8100, lo: 0xa3, hi: 0xa3}, + // Block 0x6e, offset 0x21a + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x6f, offset 0x21c + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xa0, hi: 0xa0}, + // Block 0x70, offset 0x21e + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb6, hi: 0xba}, + // Block 0x71, offset 0x220 + {value: 0x002c, lo: 0x05}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x8f, hi: 0x8f}, + {value: 0x8132, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x72, offset 0x226 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xa5, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + // Block 0x73, offset 0x229 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa4, hi: 0xa7}, + // Block 0x74, offset 0x22b + {value: 0x0000, lo: 0x05}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x8132, lo: 0x88, hi: 0x8a}, + {value: 0x812d, lo: 0x8b, hi: 0x8b}, + {value: 0x8132, lo: 0x8c, hi: 0x8c}, + {value: 0x812d, lo: 0x8d, hi: 0x90}, + // Block 0x75, offset 0x231 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x76, offset 0x234 + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x423b, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4245, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x424f, lo: 0xab, hi: 0xab}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x77, offset 0x23c + {value: 0x0000, lo: 0x06}, + {value: 0x8132, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d81, lo: 0xae, hi: 0xae}, + {value: 0x2d8b, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8104, lo: 0xb3, hi: 0xb4}, + // Block 0x78, offset 0x243 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x79, offset 0x246 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb5, hi: 0xb5}, + {value: 0x8102, lo: 0xb6, hi: 0xb6}, + // Block 0x7a, offset 0x249 + {value: 0x0002, lo: 0x01}, + {value: 0x8102, lo: 0xa9, hi: 0xaa}, + // Block 0x7b, offset 0x24b + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x7c, offset 0x24e + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d95, lo: 0x8b, hi: 0x8b}, + {value: 0x2d9f, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8132, lo: 0xa6, hi: 0xac}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + // Block 0x7d, offset 0x256 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x86, hi: 0x86}, + {value: 0x8132, lo: 0x9e, hi: 0x9e}, + // Block 0x7e, offset 0x25a + {value: 0x6b57, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2db3, lo: 0xbb, hi: 0xbb}, + {value: 0x2da9, lo: 0xbc, hi: 0xbd}, + {value: 0x2dbd, lo: 0xbe, hi: 0xbe}, + // Block 0x7f, offset 0x261 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x83, hi: 0x83}, + // Block 0x80, offset 0x264 + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dc7, lo: 0xba, hi: 0xba}, + {value: 0x2dd1, lo: 0xbb, hi: 0xbb}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x81, offset 0x26a + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0x80, hi: 0x80}, + // Block 0x82, offset 0x26c + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x83, offset 0x26f + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xab, hi: 0xab}, + // Block 0x84, offset 0x271 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb9, hi: 0xb9}, + {value: 0x8102, lo: 0xba, hi: 0xba}, + // Block 0x85, offset 0x274 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + // Block 0x86, offset 0x276 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x87, offset 0x278 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x87, hi: 0x87}, + // Block 0x88, offset 0x27a + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x99, hi: 0x99}, + // Block 0x89, offset 0x27c + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0x82, hi: 0x82}, + {value: 0x8104, lo: 0x84, hi: 0x85}, + // Block 0x8a, offset 0x27f + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x97, hi: 0x97}, + // Block 0x8b, offset 0x281 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x8c, offset 0x283 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb6}, + // Block 0x8d, offset 0x285 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x8e, offset 0x287 + {value: 0x0000, lo: 0x0c}, + {value: 0x45cf, lo: 0x9e, hi: 0x9e}, + {value: 0x45d9, lo: 0x9f, hi: 0x9f}, + {value: 0x460d, lo: 0xa0, hi: 0xa0}, + {value: 0x461b, lo: 0xa1, hi: 0xa1}, + {value: 0x4629, lo: 0xa2, hi: 0xa2}, + {value: 0x4637, lo: 0xa3, hi: 0xa3}, + {value: 0x4645, lo: 0xa4, hi: 0xa4}, + {value: 0x812b, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8130, lo: 0xad, hi: 0xad}, + {value: 0x812b, lo: 0xae, hi: 0xb2}, + {value: 0x812d, lo: 0xbb, hi: 0xbf}, + // Block 0x8f, offset 0x294 + {value: 0x0000, lo: 0x09}, + {value: 0x812d, lo: 0x80, hi: 0x82}, + {value: 0x8132, lo: 0x85, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8b}, + {value: 0x8132, lo: 0xaa, hi: 0xad}, + {value: 0x45e3, lo: 0xbb, hi: 0xbb}, + {value: 0x45ed, lo: 0xbc, hi: 0xbc}, + {value: 0x4653, lo: 0xbd, hi: 0xbd}, + {value: 0x466f, lo: 0xbe, hi: 0xbe}, + {value: 0x4661, lo: 0xbf, hi: 0xbf}, + // Block 0x90, offset 0x29e + {value: 0x0000, lo: 0x01}, + {value: 0x467d, lo: 0x80, hi: 0x80}, + // Block 0x91, offset 0x2a0 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x82, hi: 0x84}, + // Block 0x92, offset 0x2a2 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0x80, hi: 0x86}, + {value: 0x8132, lo: 0x88, hi: 0x98}, + {value: 0x8132, lo: 0x9b, hi: 0xa1}, + {value: 0x8132, lo: 0xa3, hi: 0xa4}, + {value: 0x8132, lo: 0xa6, hi: 0xaa}, + // Block 0x93, offset 0x2a8 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xac, hi: 0xaf}, + // Block 0x94, offset 0x2aa + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x90, hi: 0x96}, + // Block 0x95, offset 0x2ac + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x84, hi: 0x89}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x96, offset 0x2af + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x93, hi: 0x93}, +} + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfkcTrie) lookup(s []byte) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfkcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfkcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfkcTrie) lookupUnsafe(s []byte) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfkcValues[c0] + } + i := nfkcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *nfkcTrie) lookupString(s string) (v uint16, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return nfkcValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := nfkcIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = nfkcIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = nfkcIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *nfkcTrie) lookupStringUnsafe(s string) uint16 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return nfkcValues[c0] + } + i := nfkcIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = nfkcIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// nfkcTrie. Total size: 18684 bytes (18.25 KiB). Checksum: 113e23c477adfabd. +type nfkcTrie struct{} + +func newNfkcTrie(i int) *nfkcTrie { + return &nfkcTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *nfkcTrie) lookupValue(n uint32, b byte) uint16 { + switch { + case n < 92: + return uint16(nfkcValues[n<<6+uint32(b)]) + default: + n -= 92 + return uint16(nfkcSparse.lookup(n, b)) + } +} + +// nfkcValues: 94 blocks, 6016 entries, 12032 bytes +// The third block is the zero block. +var nfkcValues = [6016]uint16{ + // Block 0x0, offset 0x0 + 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000, + // Block 0x1, offset 0x40 + 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000, + 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000, + 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000, + 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000, + 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000, + 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000, + 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000, + 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000, + 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000, + 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x2f72, 0xc1: 0x2f77, 0xc2: 0x468b, 0xc3: 0x2f7c, 0xc4: 0x469a, 0xc5: 0x469f, + 0xc6: 0xa000, 0xc7: 0x46a9, 0xc8: 0x2fe5, 0xc9: 0x2fea, 0xca: 0x46ae, 0xcb: 0x2ffe, + 0xcc: 0x3071, 0xcd: 0x3076, 0xce: 0x307b, 0xcf: 0x46c2, 0xd1: 0x3107, + 0xd2: 0x312a, 0xd3: 0x312f, 0xd4: 0x46cc, 0xd5: 0x46d1, 0xd6: 0x46e0, + 0xd8: 0xa000, 0xd9: 0x31b6, 0xda: 0x31bb, 0xdb: 0x31c0, 0xdc: 0x4712, 0xdd: 0x3238, + 0xe0: 0x327e, 0xe1: 0x3283, 0xe2: 0x471c, 0xe3: 0x3288, + 0xe4: 0x472b, 0xe5: 0x4730, 0xe6: 0xa000, 0xe7: 0x473a, 0xe8: 0x32f1, 0xe9: 0x32f6, + 0xea: 0x473f, 0xeb: 0x330a, 0xec: 0x3382, 0xed: 0x3387, 0xee: 0x338c, 0xef: 0x4753, + 0xf1: 0x3418, 0xf2: 0x343b, 0xf3: 0x3440, 0xf4: 0x475d, 0xf5: 0x4762, + 0xf6: 0x4771, 0xf8: 0xa000, 0xf9: 0x34cc, 0xfa: 0x34d1, 0xfb: 0x34d6, + 0xfc: 0x47a3, 0xfd: 0x3553, 0xff: 0x356c, + // Block 0x4, offset 0x100 + 0x100: 0x2f81, 0x101: 0x328d, 0x102: 0x4690, 0x103: 0x4721, 0x104: 0x2f9f, 0x105: 0x32ab, + 0x106: 0x2fb3, 0x107: 0x32bf, 0x108: 0x2fb8, 0x109: 0x32c4, 0x10a: 0x2fbd, 0x10b: 0x32c9, + 0x10c: 0x2fc2, 0x10d: 0x32ce, 0x10e: 0x2fcc, 0x10f: 0x32d8, + 0x112: 0x46b3, 0x113: 0x4744, 0x114: 0x2ff4, 0x115: 0x3300, 0x116: 0x2ff9, 0x117: 0x3305, + 0x118: 0x3017, 0x119: 0x3323, 0x11a: 0x3008, 0x11b: 0x3314, 0x11c: 0x3030, 0x11d: 0x333c, + 0x11e: 0x303a, 0x11f: 0x3346, 0x120: 0x303f, 0x121: 0x334b, 0x122: 0x3049, 0x123: 0x3355, + 0x124: 0x304e, 0x125: 0x335a, 0x128: 0x3080, 0x129: 0x3391, + 0x12a: 0x3085, 0x12b: 0x3396, 0x12c: 0x308a, 0x12d: 0x339b, 0x12e: 0x30ad, 0x12f: 0x33b9, + 0x130: 0x308f, 0x132: 0x195d, 0x133: 0x19ea, 0x134: 0x30b7, 0x135: 0x33c3, + 0x136: 0x30cb, 0x137: 0x33dc, 0x139: 0x30d5, 0x13a: 0x33e6, 0x13b: 0x30df, + 0x13c: 0x33f0, 0x13d: 0x30da, 0x13e: 0x33eb, 0x13f: 0x1baf, + // Block 0x5, offset 0x140 + 0x140: 0x1c37, 0x143: 0x3102, 0x144: 0x3413, 0x145: 0x311b, + 0x146: 0x342c, 0x147: 0x3111, 0x148: 0x3422, 0x149: 0x1c5f, + 0x14c: 0x46d6, 0x14d: 0x4767, 0x14e: 0x3134, 0x14f: 0x3445, 0x150: 0x313e, 0x151: 0x344f, + 0x154: 0x315c, 0x155: 0x346d, 0x156: 0x3175, 0x157: 0x3486, + 0x158: 0x3166, 0x159: 0x3477, 0x15a: 0x46f9, 0x15b: 0x478a, 0x15c: 0x317f, 0x15d: 0x3490, + 0x15e: 0x318e, 0x15f: 0x349f, 0x160: 0x46fe, 0x161: 0x478f, 0x162: 0x31a7, 0x163: 0x34bd, + 0x164: 0x3198, 0x165: 0x34ae, 0x168: 0x4708, 0x169: 0x4799, + 0x16a: 0x470d, 0x16b: 0x479e, 0x16c: 0x31c5, 0x16d: 0x34db, 0x16e: 0x31cf, 0x16f: 0x34e5, + 0x170: 0x31d4, 0x171: 0x34ea, 0x172: 0x31f2, 0x173: 0x3508, 0x174: 0x3215, 0x175: 0x352b, + 0x176: 0x323d, 0x177: 0x3558, 0x178: 0x3251, 0x179: 0x3260, 0x17a: 0x3580, 0x17b: 0x326a, + 0x17c: 0x358a, 0x17d: 0x326f, 0x17e: 0x358f, 0x17f: 0x00a7, + // Block 0x6, offset 0x180 + 0x184: 0x2df1, 0x185: 0x2df7, + 0x186: 0x2dfd, 0x187: 0x1972, 0x188: 0x1975, 0x189: 0x1a0b, 0x18a: 0x198a, 0x18b: 0x198d, + 0x18c: 0x1a41, 0x18d: 0x2f8b, 0x18e: 0x3297, 0x18f: 0x3099, 0x190: 0x33a5, 0x191: 0x3143, + 0x192: 0x3454, 0x193: 0x31d9, 0x194: 0x34ef, 0x195: 0x39d2, 0x196: 0x3b61, 0x197: 0x39cb, + 0x198: 0x3b5a, 0x199: 0x39d9, 0x19a: 0x3b68, 0x19b: 0x39c4, 0x19c: 0x3b53, + 0x19e: 0x38b3, 0x19f: 0x3a42, 0x1a0: 0x38ac, 0x1a1: 0x3a3b, 0x1a2: 0x35b6, 0x1a3: 0x35c8, + 0x1a6: 0x3044, 0x1a7: 0x3350, 0x1a8: 0x30c1, 0x1a9: 0x33d2, + 0x1aa: 0x46ef, 0x1ab: 0x4780, 0x1ac: 0x3993, 0x1ad: 0x3b22, 0x1ae: 0x35da, 0x1af: 0x35e0, + 0x1b0: 0x33c8, 0x1b1: 0x1942, 0x1b2: 0x1945, 0x1b3: 0x19d2, 0x1b4: 0x302b, 0x1b5: 0x3337, + 0x1b8: 0x30fd, 0x1b9: 0x340e, 0x1ba: 0x38ba, 0x1bb: 0x3a49, + 0x1bc: 0x35b0, 0x1bd: 0x35c2, 0x1be: 0x35bc, 0x1bf: 0x35ce, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2f90, 0x1c1: 0x329c, 0x1c2: 0x2f95, 0x1c3: 0x32a1, 0x1c4: 0x300d, 0x1c5: 0x3319, + 0x1c6: 0x3012, 0x1c7: 0x331e, 0x1c8: 0x309e, 0x1c9: 0x33aa, 0x1ca: 0x30a3, 0x1cb: 0x33af, + 0x1cc: 0x3148, 0x1cd: 0x3459, 0x1ce: 0x314d, 0x1cf: 0x345e, 0x1d0: 0x316b, 0x1d1: 0x347c, + 0x1d2: 0x3170, 0x1d3: 0x3481, 0x1d4: 0x31de, 0x1d5: 0x34f4, 0x1d6: 0x31e3, 0x1d7: 0x34f9, + 0x1d8: 0x3189, 0x1d9: 0x349a, 0x1da: 0x31a2, 0x1db: 0x34b8, + 0x1de: 0x305d, 0x1df: 0x3369, + 0x1e6: 0x4695, 0x1e7: 0x4726, 0x1e8: 0x46bd, 0x1e9: 0x474e, + 0x1ea: 0x3962, 0x1eb: 0x3af1, 0x1ec: 0x393f, 0x1ed: 0x3ace, 0x1ee: 0x46db, 0x1ef: 0x476c, + 0x1f0: 0x395b, 0x1f1: 0x3aea, 0x1f2: 0x3247, 0x1f3: 0x3562, + // Block 0x8, offset 0x200 + 0x200: 0x9932, 0x201: 0x9932, 0x202: 0x9932, 0x203: 0x9932, 0x204: 0x9932, 0x205: 0x8132, + 0x206: 0x9932, 0x207: 0x9932, 0x208: 0x9932, 0x209: 0x9932, 0x20a: 0x9932, 0x20b: 0x9932, + 0x20c: 0x9932, 0x20d: 0x8132, 0x20e: 0x8132, 0x20f: 0x9932, 0x210: 0x8132, 0x211: 0x9932, + 0x212: 0x8132, 0x213: 0x9932, 0x214: 0x9932, 0x215: 0x8133, 0x216: 0x812d, 0x217: 0x812d, + 0x218: 0x812d, 0x219: 0x812d, 0x21a: 0x8133, 0x21b: 0x992b, 0x21c: 0x812d, 0x21d: 0x812d, + 0x21e: 0x812d, 0x21f: 0x812d, 0x220: 0x812d, 0x221: 0x8129, 0x222: 0x8129, 0x223: 0x992d, + 0x224: 0x992d, 0x225: 0x992d, 0x226: 0x992d, 0x227: 0x9929, 0x228: 0x9929, 0x229: 0x812d, + 0x22a: 0x812d, 0x22b: 0x812d, 0x22c: 0x812d, 0x22d: 0x992d, 0x22e: 0x992d, 0x22f: 0x812d, + 0x230: 0x992d, 0x231: 0x992d, 0x232: 0x812d, 0x233: 0x812d, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812d, 0x23a: 0x812d, 0x23b: 0x812d, + 0x23c: 0x812d, 0x23d: 0x8132, 0x23e: 0x8132, 0x23f: 0x8132, + // Block 0x9, offset 0x240 + 0x240: 0x49b1, 0x241: 0x49b6, 0x242: 0x9932, 0x243: 0x49bb, 0x244: 0x4a74, 0x245: 0x9936, + 0x246: 0x8132, 0x247: 0x812d, 0x248: 0x812d, 0x249: 0x812d, 0x24a: 0x8132, 0x24b: 0x8132, + 0x24c: 0x8132, 0x24d: 0x812d, 0x24e: 0x812d, 0x250: 0x8132, 0x251: 0x8132, + 0x252: 0x8132, 0x253: 0x812d, 0x254: 0x812d, 0x255: 0x812d, 0x256: 0x812d, 0x257: 0x8132, + 0x258: 0x8133, 0x259: 0x812d, 0x25a: 0x812d, 0x25b: 0x8132, 0x25c: 0x8134, 0x25d: 0x8135, + 0x25e: 0x8135, 0x25f: 0x8134, 0x260: 0x8135, 0x261: 0x8135, 0x262: 0x8134, 0x263: 0x8132, + 0x264: 0x8132, 0x265: 0x8132, 0x266: 0x8132, 0x267: 0x8132, 0x268: 0x8132, 0x269: 0x8132, + 0x26a: 0x8132, 0x26b: 0x8132, 0x26c: 0x8132, 0x26d: 0x8132, 0x26e: 0x8132, 0x26f: 0x8132, + 0x274: 0x0170, + 0x27a: 0x42a8, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x425d, 0x285: 0x447e, + 0x286: 0x35ec, 0x287: 0x00ce, 0x288: 0x360a, 0x289: 0x3616, 0x28a: 0x3628, + 0x28c: 0x3646, 0x28e: 0x3658, 0x28f: 0x3676, 0x290: 0x3e0b, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x363a, 0x2ab: 0x366a, 0x2ac: 0x4801, 0x2ad: 0x369a, 0x2ae: 0x482b, 0x2af: 0x36ac, + 0x2b0: 0x3e73, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c1: 0xa000, 0x2c5: 0xa000, + 0x2c9: 0xa000, 0x2ca: 0x4843, 0x2cb: 0x4861, + 0x2cc: 0x36ca, 0x2cd: 0x36e2, 0x2ce: 0x4879, 0x2d0: 0x01be, 0x2d1: 0x01d0, + 0x2d2: 0x01ac, 0x2d3: 0x430f, 0x2d4: 0x4315, 0x2d5: 0x01fa, 0x2d6: 0x01e8, + 0x2f0: 0x01d6, 0x2f1: 0x01eb, 0x2f2: 0x01ee, 0x2f4: 0x0188, 0x2f5: 0x01c7, + 0x2f9: 0x01a6, + // Block 0xc, offset 0x300 + 0x300: 0x3724, 0x301: 0x3730, 0x303: 0x371e, + 0x306: 0xa000, 0x307: 0x370c, + 0x30c: 0x3760, 0x30d: 0x3748, 0x30e: 0x3772, 0x310: 0xa000, + 0x313: 0xa000, 0x315: 0xa000, 0x316: 0xa000, 0x317: 0xa000, + 0x318: 0xa000, 0x319: 0x3754, 0x31a: 0xa000, + 0x31e: 0xa000, 0x323: 0xa000, + 0x327: 0xa000, + 0x32b: 0xa000, 0x32d: 0xa000, + 0x330: 0xa000, 0x333: 0xa000, 0x335: 0xa000, + 0x336: 0xa000, 0x337: 0xa000, 0x338: 0xa000, 0x339: 0x37d8, 0x33a: 0xa000, + 0x33e: 0xa000, + // Block 0xd, offset 0x340 + 0x341: 0x3736, 0x342: 0x37ba, + 0x350: 0x3712, 0x351: 0x3796, + 0x352: 0x3718, 0x353: 0x379c, 0x356: 0x372a, 0x357: 0x37ae, + 0x358: 0xa000, 0x359: 0xa000, 0x35a: 0x382c, 0x35b: 0x3832, 0x35c: 0x373c, 0x35d: 0x37c0, + 0x35e: 0x3742, 0x35f: 0x37c6, 0x362: 0x374e, 0x363: 0x37d2, + 0x364: 0x375a, 0x365: 0x37de, 0x366: 0x3766, 0x367: 0x37ea, 0x368: 0xa000, 0x369: 0xa000, + 0x36a: 0x3838, 0x36b: 0x383e, 0x36c: 0x3790, 0x36d: 0x3814, 0x36e: 0x376c, 0x36f: 0x37f0, + 0x370: 0x3778, 0x371: 0x37fc, 0x372: 0x377e, 0x373: 0x3802, 0x374: 0x3784, 0x375: 0x3808, + 0x378: 0x378a, 0x379: 0x380e, + // Block 0xe, offset 0x380 + 0x387: 0x1d64, + 0x391: 0x812d, + 0x392: 0x8132, 0x393: 0x8132, 0x394: 0x8132, 0x395: 0x8132, 0x396: 0x812d, 0x397: 0x8132, + 0x398: 0x8132, 0x399: 0x8132, 0x39a: 0x812e, 0x39b: 0x812d, 0x39c: 0x8132, 0x39d: 0x8132, + 0x39e: 0x8132, 0x39f: 0x8132, 0x3a0: 0x8132, 0x3a1: 0x8132, 0x3a2: 0x812d, 0x3a3: 0x812d, + 0x3a4: 0x812d, 0x3a5: 0x812d, 0x3a6: 0x812d, 0x3a7: 0x812d, 0x3a8: 0x8132, 0x3a9: 0x8132, + 0x3aa: 0x812d, 0x3ab: 0x8132, 0x3ac: 0x8132, 0x3ad: 0x812e, 0x3ae: 0x8131, 0x3af: 0x8132, + 0x3b0: 0x8105, 0x3b1: 0x8106, 0x3b2: 0x8107, 0x3b3: 0x8108, 0x3b4: 0x8109, 0x3b5: 0x810a, + 0x3b6: 0x810b, 0x3b7: 0x810c, 0x3b8: 0x810d, 0x3b9: 0x810e, 0x3ba: 0x810e, 0x3bb: 0x810f, + 0x3bc: 0x8110, 0x3bd: 0x8111, 0x3bf: 0x8112, + // Block 0xf, offset 0x3c0 + 0x3c8: 0xa000, 0x3ca: 0xa000, 0x3cb: 0x8116, + 0x3cc: 0x8117, 0x3cd: 0x8118, 0x3ce: 0x8119, 0x3cf: 0x811a, 0x3d0: 0x811b, 0x3d1: 0x811c, + 0x3d2: 0x811d, 0x3d3: 0x9932, 0x3d4: 0x9932, 0x3d5: 0x992d, 0x3d6: 0x812d, 0x3d7: 0x8132, + 0x3d8: 0x8132, 0x3d9: 0x8132, 0x3da: 0x8132, 0x3db: 0x8132, 0x3dc: 0x812d, 0x3dd: 0x8132, + 0x3de: 0x8132, 0x3df: 0x812d, + 0x3f0: 0x811e, 0x3f5: 0x1d87, + 0x3f6: 0x2016, 0x3f7: 0x2052, 0x3f8: 0x204d, + // Block 0x10, offset 0x400 + 0x413: 0x812d, 0x414: 0x8132, 0x415: 0x8132, 0x416: 0x8132, 0x417: 0x8132, + 0x418: 0x8132, 0x419: 0x8132, 0x41a: 0x8132, 0x41b: 0x8132, 0x41c: 0x8132, 0x41d: 0x8132, + 0x41e: 0x8132, 0x41f: 0x8132, 0x420: 0x8132, 0x421: 0x8132, 0x423: 0x812d, + 0x424: 0x8132, 0x425: 0x8132, 0x426: 0x812d, 0x427: 0x8132, 0x428: 0x8132, 0x429: 0x812d, + 0x42a: 0x8132, 0x42b: 0x8132, 0x42c: 0x8132, 0x42d: 0x812d, 0x42e: 0x812d, 0x42f: 0x812d, + 0x430: 0x8116, 0x431: 0x8117, 0x432: 0x8118, 0x433: 0x8132, 0x434: 0x8132, 0x435: 0x8132, + 0x436: 0x812d, 0x437: 0x8132, 0x438: 0x8132, 0x439: 0x812d, 0x43a: 0x812d, 0x43b: 0x8132, + 0x43c: 0x8132, 0x43d: 0x8132, 0x43e: 0x8132, 0x43f: 0x8132, + // Block 0x11, offset 0x440 + 0x445: 0xa000, + 0x446: 0x2d29, 0x447: 0xa000, 0x448: 0x2d31, 0x449: 0xa000, 0x44a: 0x2d39, 0x44b: 0xa000, + 0x44c: 0x2d41, 0x44d: 0xa000, 0x44e: 0x2d49, 0x451: 0xa000, + 0x452: 0x2d51, + 0x474: 0x8102, 0x475: 0x9900, + 0x47a: 0xa000, 0x47b: 0x2d59, + 0x47c: 0xa000, 0x47d: 0x2d61, 0x47e: 0xa000, 0x47f: 0xa000, + // Block 0x12, offset 0x480 + 0x480: 0x0069, 0x481: 0x006b, 0x482: 0x006f, 0x483: 0x0083, 0x484: 0x00f5, 0x485: 0x00f8, + 0x486: 0x0413, 0x487: 0x0085, 0x488: 0x0089, 0x489: 0x008b, 0x48a: 0x0104, 0x48b: 0x0107, + 0x48c: 0x010a, 0x48d: 0x008f, 0x48f: 0x0097, 0x490: 0x009b, 0x491: 0x00e0, + 0x492: 0x009f, 0x493: 0x00fe, 0x494: 0x0417, 0x495: 0x041b, 0x496: 0x00a1, 0x497: 0x00a9, + 0x498: 0x00ab, 0x499: 0x0423, 0x49a: 0x012b, 0x49b: 0x00ad, 0x49c: 0x0427, 0x49d: 0x01be, + 0x49e: 0x01c1, 0x49f: 0x01c4, 0x4a0: 0x01fa, 0x4a1: 0x01fd, 0x4a2: 0x0093, 0x4a3: 0x00a5, + 0x4a4: 0x00ab, 0x4a5: 0x00ad, 0x4a6: 0x01be, 0x4a7: 0x01c1, 0x4a8: 0x01eb, 0x4a9: 0x01fa, + 0x4aa: 0x01fd, + 0x4b8: 0x020c, + // Block 0x13, offset 0x4c0 + 0x4db: 0x00fb, 0x4dc: 0x0087, 0x4dd: 0x0101, + 0x4de: 0x00d4, 0x4df: 0x010a, 0x4e0: 0x008d, 0x4e1: 0x010d, 0x4e2: 0x0110, 0x4e3: 0x0116, + 0x4e4: 0x011c, 0x4e5: 0x011f, 0x4e6: 0x0122, 0x4e7: 0x042b, 0x4e8: 0x016a, 0x4e9: 0x0128, + 0x4ea: 0x042f, 0x4eb: 0x016d, 0x4ec: 0x0131, 0x4ed: 0x012e, 0x4ee: 0x0134, 0x4ef: 0x0137, + 0x4f0: 0x013a, 0x4f1: 0x013d, 0x4f2: 0x0140, 0x4f3: 0x014c, 0x4f4: 0x014f, 0x4f5: 0x00ec, + 0x4f6: 0x0152, 0x4f7: 0x0155, 0x4f8: 0x041f, 0x4f9: 0x0158, 0x4fa: 0x015b, 0x4fb: 0x00b5, + 0x4fc: 0x015e, 0x4fd: 0x0161, 0x4fe: 0x0164, 0x4ff: 0x01d0, + // Block 0x14, offset 0x500 + 0x500: 0x8132, 0x501: 0x8132, 0x502: 0x812d, 0x503: 0x8132, 0x504: 0x8132, 0x505: 0x8132, + 0x506: 0x8132, 0x507: 0x8132, 0x508: 0x8132, 0x509: 0x8132, 0x50a: 0x812d, 0x50b: 0x8132, + 0x50c: 0x8132, 0x50d: 0x8135, 0x50e: 0x812a, 0x50f: 0x812d, 0x510: 0x8129, 0x511: 0x8132, + 0x512: 0x8132, 0x513: 0x8132, 0x514: 0x8132, 0x515: 0x8132, 0x516: 0x8132, 0x517: 0x8132, + 0x518: 0x8132, 0x519: 0x8132, 0x51a: 0x8132, 0x51b: 0x8132, 0x51c: 0x8132, 0x51d: 0x8132, + 0x51e: 0x8132, 0x51f: 0x8132, 0x520: 0x8132, 0x521: 0x8132, 0x522: 0x8132, 0x523: 0x8132, + 0x524: 0x8132, 0x525: 0x8132, 0x526: 0x8132, 0x527: 0x8132, 0x528: 0x8132, 0x529: 0x8132, + 0x52a: 0x8132, 0x52b: 0x8132, 0x52c: 0x8132, 0x52d: 0x8132, 0x52e: 0x8132, 0x52f: 0x8132, + 0x530: 0x8132, 0x531: 0x8132, 0x532: 0x8132, 0x533: 0x8132, 0x534: 0x8132, 0x535: 0x8132, + 0x536: 0x8133, 0x537: 0x8131, 0x538: 0x8131, 0x539: 0x812d, 0x53b: 0x8132, + 0x53c: 0x8134, 0x53d: 0x812d, 0x53e: 0x8132, 0x53f: 0x812d, + // Block 0x15, offset 0x540 + 0x540: 0x2f9a, 0x541: 0x32a6, 0x542: 0x2fa4, 0x543: 0x32b0, 0x544: 0x2fa9, 0x545: 0x32b5, + 0x546: 0x2fae, 0x547: 0x32ba, 0x548: 0x38cf, 0x549: 0x3a5e, 0x54a: 0x2fc7, 0x54b: 0x32d3, + 0x54c: 0x2fd1, 0x54d: 0x32dd, 0x54e: 0x2fe0, 0x54f: 0x32ec, 0x550: 0x2fd6, 0x551: 0x32e2, + 0x552: 0x2fdb, 0x553: 0x32e7, 0x554: 0x38f2, 0x555: 0x3a81, 0x556: 0x38f9, 0x557: 0x3a88, + 0x558: 0x301c, 0x559: 0x3328, 0x55a: 0x3021, 0x55b: 0x332d, 0x55c: 0x3907, 0x55d: 0x3a96, + 0x55e: 0x3026, 0x55f: 0x3332, 0x560: 0x3035, 0x561: 0x3341, 0x562: 0x3053, 0x563: 0x335f, + 0x564: 0x3062, 0x565: 0x336e, 0x566: 0x3058, 0x567: 0x3364, 0x568: 0x3067, 0x569: 0x3373, + 0x56a: 0x306c, 0x56b: 0x3378, 0x56c: 0x30b2, 0x56d: 0x33be, 0x56e: 0x390e, 0x56f: 0x3a9d, + 0x570: 0x30bc, 0x571: 0x33cd, 0x572: 0x30c6, 0x573: 0x33d7, 0x574: 0x30d0, 0x575: 0x33e1, + 0x576: 0x46c7, 0x577: 0x4758, 0x578: 0x3915, 0x579: 0x3aa4, 0x57a: 0x30e9, 0x57b: 0x33fa, + 0x57c: 0x30e4, 0x57d: 0x33f5, 0x57e: 0x30ee, 0x57f: 0x33ff, + // Block 0x16, offset 0x580 + 0x580: 0x30f3, 0x581: 0x3404, 0x582: 0x30f8, 0x583: 0x3409, 0x584: 0x310c, 0x585: 0x341d, + 0x586: 0x3116, 0x587: 0x3427, 0x588: 0x3125, 0x589: 0x3436, 0x58a: 0x3120, 0x58b: 0x3431, + 0x58c: 0x3938, 0x58d: 0x3ac7, 0x58e: 0x3946, 0x58f: 0x3ad5, 0x590: 0x394d, 0x591: 0x3adc, + 0x592: 0x3954, 0x593: 0x3ae3, 0x594: 0x3152, 0x595: 0x3463, 0x596: 0x3157, 0x597: 0x3468, + 0x598: 0x3161, 0x599: 0x3472, 0x59a: 0x46f4, 0x59b: 0x4785, 0x59c: 0x399a, 0x59d: 0x3b29, + 0x59e: 0x317a, 0x59f: 0x348b, 0x5a0: 0x3184, 0x5a1: 0x3495, 0x5a2: 0x4703, 0x5a3: 0x4794, + 0x5a4: 0x39a1, 0x5a5: 0x3b30, 0x5a6: 0x39a8, 0x5a7: 0x3b37, 0x5a8: 0x39af, 0x5a9: 0x3b3e, + 0x5aa: 0x3193, 0x5ab: 0x34a4, 0x5ac: 0x319d, 0x5ad: 0x34b3, 0x5ae: 0x31b1, 0x5af: 0x34c7, + 0x5b0: 0x31ac, 0x5b1: 0x34c2, 0x5b2: 0x31ed, 0x5b3: 0x3503, 0x5b4: 0x31fc, 0x5b5: 0x3512, + 0x5b6: 0x31f7, 0x5b7: 0x350d, 0x5b8: 0x39b6, 0x5b9: 0x3b45, 0x5ba: 0x39bd, 0x5bb: 0x3b4c, + 0x5bc: 0x3201, 0x5bd: 0x3517, 0x5be: 0x3206, 0x5bf: 0x351c, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x320b, 0x5c1: 0x3521, 0x5c2: 0x3210, 0x5c3: 0x3526, 0x5c4: 0x321f, 0x5c5: 0x3535, + 0x5c6: 0x321a, 0x5c7: 0x3530, 0x5c8: 0x3224, 0x5c9: 0x353f, 0x5ca: 0x3229, 0x5cb: 0x3544, + 0x5cc: 0x322e, 0x5cd: 0x3549, 0x5ce: 0x324c, 0x5cf: 0x3567, 0x5d0: 0x3265, 0x5d1: 0x3585, + 0x5d2: 0x3274, 0x5d3: 0x3594, 0x5d4: 0x3279, 0x5d5: 0x3599, 0x5d6: 0x337d, 0x5d7: 0x34a9, + 0x5d8: 0x353a, 0x5d9: 0x3576, 0x5da: 0x1be3, 0x5db: 0x42da, + 0x5e0: 0x46a4, 0x5e1: 0x4735, 0x5e2: 0x2f86, 0x5e3: 0x3292, + 0x5e4: 0x387b, 0x5e5: 0x3a0a, 0x5e6: 0x3874, 0x5e7: 0x3a03, 0x5e8: 0x3889, 0x5e9: 0x3a18, + 0x5ea: 0x3882, 0x5eb: 0x3a11, 0x5ec: 0x38c1, 0x5ed: 0x3a50, 0x5ee: 0x3897, 0x5ef: 0x3a26, + 0x5f0: 0x3890, 0x5f1: 0x3a1f, 0x5f2: 0x38a5, 0x5f3: 0x3a34, 0x5f4: 0x389e, 0x5f5: 0x3a2d, + 0x5f6: 0x38c8, 0x5f7: 0x3a57, 0x5f8: 0x46b8, 0x5f9: 0x4749, 0x5fa: 0x3003, 0x5fb: 0x330f, + 0x5fc: 0x2fef, 0x5fd: 0x32fb, 0x5fe: 0x38dd, 0x5ff: 0x3a6c, + // Block 0x18, offset 0x600 + 0x600: 0x38d6, 0x601: 0x3a65, 0x602: 0x38eb, 0x603: 0x3a7a, 0x604: 0x38e4, 0x605: 0x3a73, + 0x606: 0x3900, 0x607: 0x3a8f, 0x608: 0x3094, 0x609: 0x33a0, 0x60a: 0x30a8, 0x60b: 0x33b4, + 0x60c: 0x46ea, 0x60d: 0x477b, 0x60e: 0x3139, 0x60f: 0x344a, 0x610: 0x3923, 0x611: 0x3ab2, + 0x612: 0x391c, 0x613: 0x3aab, 0x614: 0x3931, 0x615: 0x3ac0, 0x616: 0x392a, 0x617: 0x3ab9, + 0x618: 0x398c, 0x619: 0x3b1b, 0x61a: 0x3970, 0x61b: 0x3aff, 0x61c: 0x3969, 0x61d: 0x3af8, + 0x61e: 0x397e, 0x61f: 0x3b0d, 0x620: 0x3977, 0x621: 0x3b06, 0x622: 0x3985, 0x623: 0x3b14, + 0x624: 0x31e8, 0x625: 0x34fe, 0x626: 0x31ca, 0x627: 0x34e0, 0x628: 0x39e7, 0x629: 0x3b76, + 0x62a: 0x39e0, 0x62b: 0x3b6f, 0x62c: 0x39f5, 0x62d: 0x3b84, 0x62e: 0x39ee, 0x62f: 0x3b7d, + 0x630: 0x39fc, 0x631: 0x3b8b, 0x632: 0x3233, 0x633: 0x354e, 0x634: 0x325b, 0x635: 0x357b, + 0x636: 0x3256, 0x637: 0x3571, 0x638: 0x3242, 0x639: 0x355d, + // Block 0x19, offset 0x640 + 0x640: 0x4807, 0x641: 0x480d, 0x642: 0x4921, 0x643: 0x4939, 0x644: 0x4929, 0x645: 0x4941, + 0x646: 0x4931, 0x647: 0x4949, 0x648: 0x47ad, 0x649: 0x47b3, 0x64a: 0x4891, 0x64b: 0x48a9, + 0x64c: 0x4899, 0x64d: 0x48b1, 0x64e: 0x48a1, 0x64f: 0x48b9, 0x650: 0x4819, 0x651: 0x481f, + 0x652: 0x3dbb, 0x653: 0x3dcb, 0x654: 0x3dc3, 0x655: 0x3dd3, + 0x658: 0x47b9, 0x659: 0x47bf, 0x65a: 0x3ceb, 0x65b: 0x3cfb, 0x65c: 0x3cf3, 0x65d: 0x3d03, + 0x660: 0x4831, 0x661: 0x4837, 0x662: 0x4951, 0x663: 0x4969, + 0x664: 0x4959, 0x665: 0x4971, 0x666: 0x4961, 0x667: 0x4979, 0x668: 0x47c5, 0x669: 0x47cb, + 0x66a: 0x48c1, 0x66b: 0x48d9, 0x66c: 0x48c9, 0x66d: 0x48e1, 0x66e: 0x48d1, 0x66f: 0x48e9, + 0x670: 0x4849, 0x671: 0x484f, 0x672: 0x3e1b, 0x673: 0x3e33, 0x674: 0x3e23, 0x675: 0x3e3b, + 0x676: 0x3e2b, 0x677: 0x3e43, 0x678: 0x47d1, 0x679: 0x47d7, 0x67a: 0x3d1b, 0x67b: 0x3d33, + 0x67c: 0x3d23, 0x67d: 0x3d3b, 0x67e: 0x3d2b, 0x67f: 0x3d43, + // Block 0x1a, offset 0x680 + 0x680: 0x4855, 0x681: 0x485b, 0x682: 0x3e4b, 0x683: 0x3e5b, 0x684: 0x3e53, 0x685: 0x3e63, + 0x688: 0x47dd, 0x689: 0x47e3, 0x68a: 0x3d4b, 0x68b: 0x3d5b, + 0x68c: 0x3d53, 0x68d: 0x3d63, 0x690: 0x4867, 0x691: 0x486d, + 0x692: 0x3e83, 0x693: 0x3e9b, 0x694: 0x3e8b, 0x695: 0x3ea3, 0x696: 0x3e93, 0x697: 0x3eab, + 0x699: 0x47e9, 0x69b: 0x3d6b, 0x69d: 0x3d73, + 0x69f: 0x3d7b, 0x6a0: 0x487f, 0x6a1: 0x4885, 0x6a2: 0x4981, 0x6a3: 0x4999, + 0x6a4: 0x4989, 0x6a5: 0x49a1, 0x6a6: 0x4991, 0x6a7: 0x49a9, 0x6a8: 0x47ef, 0x6a9: 0x47f5, + 0x6aa: 0x48f1, 0x6ab: 0x4909, 0x6ac: 0x48f9, 0x6ad: 0x4911, 0x6ae: 0x4901, 0x6af: 0x4919, + 0x6b0: 0x47fb, 0x6b1: 0x4321, 0x6b2: 0x3694, 0x6b3: 0x4327, 0x6b4: 0x4825, 0x6b5: 0x432d, + 0x6b6: 0x36a6, 0x6b7: 0x4333, 0x6b8: 0x36c4, 0x6b9: 0x4339, 0x6ba: 0x36dc, 0x6bb: 0x433f, + 0x6bc: 0x4873, 0x6bd: 0x4345, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x3da3, 0x6c1: 0x3dab, 0x6c2: 0x4187, 0x6c3: 0x41a5, 0x6c4: 0x4191, 0x6c5: 0x41af, + 0x6c6: 0x419b, 0x6c7: 0x41b9, 0x6c8: 0x3cdb, 0x6c9: 0x3ce3, 0x6ca: 0x40d3, 0x6cb: 0x40f1, + 0x6cc: 0x40dd, 0x6cd: 0x40fb, 0x6ce: 0x40e7, 0x6cf: 0x4105, 0x6d0: 0x3deb, 0x6d1: 0x3df3, + 0x6d2: 0x41c3, 0x6d3: 0x41e1, 0x6d4: 0x41cd, 0x6d5: 0x41eb, 0x6d6: 0x41d7, 0x6d7: 0x41f5, + 0x6d8: 0x3d0b, 0x6d9: 0x3d13, 0x6da: 0x410f, 0x6db: 0x412d, 0x6dc: 0x4119, 0x6dd: 0x4137, + 0x6de: 0x4123, 0x6df: 0x4141, 0x6e0: 0x3ec3, 0x6e1: 0x3ecb, 0x6e2: 0x41ff, 0x6e3: 0x421d, + 0x6e4: 0x4209, 0x6e5: 0x4227, 0x6e6: 0x4213, 0x6e7: 0x4231, 0x6e8: 0x3d83, 0x6e9: 0x3d8b, + 0x6ea: 0x414b, 0x6eb: 0x4169, 0x6ec: 0x4155, 0x6ed: 0x4173, 0x6ee: 0x415f, 0x6ef: 0x417d, + 0x6f0: 0x3688, 0x6f1: 0x3682, 0x6f2: 0x3d93, 0x6f3: 0x368e, 0x6f4: 0x3d9b, + 0x6f6: 0x4813, 0x6f7: 0x3db3, 0x6f8: 0x35f8, 0x6f9: 0x35f2, 0x6fa: 0x35e6, 0x6fb: 0x42f1, + 0x6fc: 0x35fe, 0x6fd: 0x428a, 0x6fe: 0x01d3, 0x6ff: 0x428a, + // Block 0x1c, offset 0x700 + 0x700: 0x42a3, 0x701: 0x4485, 0x702: 0x3ddb, 0x703: 0x36a0, 0x704: 0x3de3, + 0x706: 0x483d, 0x707: 0x3dfb, 0x708: 0x3604, 0x709: 0x42f7, 0x70a: 0x3610, 0x70b: 0x42fd, + 0x70c: 0x361c, 0x70d: 0x448c, 0x70e: 0x4493, 0x70f: 0x449a, 0x710: 0x36b8, 0x711: 0x36b2, + 0x712: 0x3e03, 0x713: 0x44e7, 0x716: 0x36be, 0x717: 0x3e13, + 0x718: 0x3634, 0x719: 0x362e, 0x71a: 0x3622, 0x71b: 0x4303, 0x71d: 0x44a1, + 0x71e: 0x44a8, 0x71f: 0x44af, 0x720: 0x36ee, 0x721: 0x36e8, 0x722: 0x3e6b, 0x723: 0x44ef, + 0x724: 0x36d0, 0x725: 0x36d6, 0x726: 0x36f4, 0x727: 0x3e7b, 0x728: 0x3664, 0x729: 0x365e, + 0x72a: 0x3652, 0x72b: 0x430f, 0x72c: 0x364c, 0x72d: 0x4477, 0x72e: 0x447e, 0x72f: 0x0081, + 0x732: 0x3eb3, 0x733: 0x36fa, 0x734: 0x3ebb, + 0x736: 0x488b, 0x737: 0x3ed3, 0x738: 0x3640, 0x739: 0x4309, 0x73a: 0x3670, 0x73b: 0x431b, + 0x73c: 0x367c, 0x73d: 0x425d, 0x73e: 0x428f, + // Block 0x1d, offset 0x740 + 0x740: 0x1bdb, 0x741: 0x1bdf, 0x742: 0x0047, 0x743: 0x1c57, 0x745: 0x1beb, + 0x746: 0x1bef, 0x747: 0x00e9, 0x749: 0x1c5b, 0x74a: 0x008f, 0x74b: 0x0051, + 0x74c: 0x0051, 0x74d: 0x0051, 0x74e: 0x0091, 0x74f: 0x00da, 0x750: 0x0053, 0x751: 0x0053, + 0x752: 0x0059, 0x753: 0x0099, 0x755: 0x005d, 0x756: 0x1990, + 0x759: 0x0061, 0x75a: 0x0063, 0x75b: 0x0065, 0x75c: 0x0065, 0x75d: 0x0065, + 0x760: 0x19a2, 0x761: 0x1bcb, 0x762: 0x19ab, + 0x764: 0x0075, 0x766: 0x01b8, 0x768: 0x0075, + 0x76a: 0x0057, 0x76b: 0x42d5, 0x76c: 0x0045, 0x76d: 0x0047, 0x76f: 0x008b, + 0x770: 0x004b, 0x771: 0x004d, 0x773: 0x005b, 0x774: 0x009f, 0x775: 0x0215, + 0x776: 0x0218, 0x777: 0x021b, 0x778: 0x021e, 0x779: 0x0093, 0x77b: 0x1b9b, + 0x77c: 0x01e8, 0x77d: 0x01c1, 0x77e: 0x0179, 0x77f: 0x01a0, + // Block 0x1e, offset 0x780 + 0x780: 0x0463, 0x785: 0x0049, + 0x786: 0x0089, 0x787: 0x008b, 0x788: 0x0093, 0x789: 0x0095, + 0x790: 0x2231, 0x791: 0x223d, + 0x792: 0x22f1, 0x793: 0x2219, 0x794: 0x229d, 0x795: 0x2225, 0x796: 0x22a3, 0x797: 0x22bb, + 0x798: 0x22c7, 0x799: 0x222b, 0x79a: 0x22cd, 0x79b: 0x2237, 0x79c: 0x22c1, 0x79d: 0x22d3, + 0x79e: 0x22d9, 0x79f: 0x1cbf, 0x7a0: 0x0053, 0x7a1: 0x195a, 0x7a2: 0x1ba7, 0x7a3: 0x1963, + 0x7a4: 0x006d, 0x7a5: 0x19ae, 0x7a6: 0x1bd3, 0x7a7: 0x1d4b, 0x7a8: 0x1966, 0x7a9: 0x0071, + 0x7aa: 0x19ba, 0x7ab: 0x1bd7, 0x7ac: 0x0059, 0x7ad: 0x0047, 0x7ae: 0x0049, 0x7af: 0x005b, + 0x7b0: 0x0093, 0x7b1: 0x19e7, 0x7b2: 0x1c1b, 0x7b3: 0x19f0, 0x7b4: 0x00ad, 0x7b5: 0x1a65, + 0x7b6: 0x1c4f, 0x7b7: 0x1d5f, 0x7b8: 0x19f3, 0x7b9: 0x00b1, 0x7ba: 0x1a68, 0x7bb: 0x1c53, + 0x7bc: 0x0099, 0x7bd: 0x0087, 0x7be: 0x0089, 0x7bf: 0x009b, + // Block 0x1f, offset 0x7c0 + 0x7c1: 0x3c09, 0x7c3: 0xa000, 0x7c4: 0x3c10, 0x7c5: 0xa000, + 0x7c7: 0x3c17, 0x7c8: 0xa000, 0x7c9: 0x3c1e, + 0x7cd: 0xa000, + 0x7e0: 0x2f68, 0x7e1: 0xa000, 0x7e2: 0x3c2c, + 0x7e4: 0xa000, 0x7e5: 0xa000, + 0x7ed: 0x3c25, 0x7ee: 0x2f63, 0x7ef: 0x2f6d, + 0x7f0: 0x3c33, 0x7f1: 0x3c3a, 0x7f2: 0xa000, 0x7f3: 0xa000, 0x7f4: 0x3c41, 0x7f5: 0x3c48, + 0x7f6: 0xa000, 0x7f7: 0xa000, 0x7f8: 0x3c4f, 0x7f9: 0x3c56, 0x7fa: 0xa000, 0x7fb: 0xa000, + 0x7fc: 0xa000, 0x7fd: 0xa000, + // Block 0x20, offset 0x800 + 0x800: 0x3c5d, 0x801: 0x3c64, 0x802: 0xa000, 0x803: 0xa000, 0x804: 0x3c79, 0x805: 0x3c80, + 0x806: 0xa000, 0x807: 0xa000, 0x808: 0x3c87, 0x809: 0x3c8e, + 0x811: 0xa000, + 0x812: 0xa000, + 0x822: 0xa000, + 0x828: 0xa000, 0x829: 0xa000, + 0x82b: 0xa000, 0x82c: 0x3ca3, 0x82d: 0x3caa, 0x82e: 0x3cb1, 0x82f: 0x3cb8, + 0x832: 0xa000, 0x833: 0xa000, 0x834: 0xa000, 0x835: 0xa000, + // Block 0x21, offset 0x840 + 0x860: 0x0023, 0x861: 0x0025, 0x862: 0x0027, 0x863: 0x0029, + 0x864: 0x002b, 0x865: 0x002d, 0x866: 0x002f, 0x867: 0x0031, 0x868: 0x0033, 0x869: 0x1882, + 0x86a: 0x1885, 0x86b: 0x1888, 0x86c: 0x188b, 0x86d: 0x188e, 0x86e: 0x1891, 0x86f: 0x1894, + 0x870: 0x1897, 0x871: 0x189a, 0x872: 0x189d, 0x873: 0x18a6, 0x874: 0x1a6b, 0x875: 0x1a6f, + 0x876: 0x1a73, 0x877: 0x1a77, 0x878: 0x1a7b, 0x879: 0x1a7f, 0x87a: 0x1a83, 0x87b: 0x1a87, + 0x87c: 0x1a8b, 0x87d: 0x1c83, 0x87e: 0x1c88, 0x87f: 0x1c8d, + // Block 0x22, offset 0x880 + 0x880: 0x1c92, 0x881: 0x1c97, 0x882: 0x1c9c, 0x883: 0x1ca1, 0x884: 0x1ca6, 0x885: 0x1cab, + 0x886: 0x1cb0, 0x887: 0x1cb5, 0x888: 0x187f, 0x889: 0x18a3, 0x88a: 0x18c7, 0x88b: 0x18eb, + 0x88c: 0x190f, 0x88d: 0x1918, 0x88e: 0x191e, 0x88f: 0x1924, 0x890: 0x192a, 0x891: 0x1b63, + 0x892: 0x1b67, 0x893: 0x1b6b, 0x894: 0x1b6f, 0x895: 0x1b73, 0x896: 0x1b77, 0x897: 0x1b7b, + 0x898: 0x1b7f, 0x899: 0x1b83, 0x89a: 0x1b87, 0x89b: 0x1b8b, 0x89c: 0x1af7, 0x89d: 0x1afb, + 0x89e: 0x1aff, 0x89f: 0x1b03, 0x8a0: 0x1b07, 0x8a1: 0x1b0b, 0x8a2: 0x1b0f, 0x8a3: 0x1b13, + 0x8a4: 0x1b17, 0x8a5: 0x1b1b, 0x8a6: 0x1b1f, 0x8a7: 0x1b23, 0x8a8: 0x1b27, 0x8a9: 0x1b2b, + 0x8aa: 0x1b2f, 0x8ab: 0x1b33, 0x8ac: 0x1b37, 0x8ad: 0x1b3b, 0x8ae: 0x1b3f, 0x8af: 0x1b43, + 0x8b0: 0x1b47, 0x8b1: 0x1b4b, 0x8b2: 0x1b4f, 0x8b3: 0x1b53, 0x8b4: 0x1b57, 0x8b5: 0x1b5b, + 0x8b6: 0x0043, 0x8b7: 0x0045, 0x8b8: 0x0047, 0x8b9: 0x0049, 0x8ba: 0x004b, 0x8bb: 0x004d, + 0x8bc: 0x004f, 0x8bd: 0x0051, 0x8be: 0x0053, 0x8bf: 0x0055, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x06bf, 0x8c1: 0x06e3, 0x8c2: 0x06ef, 0x8c3: 0x06ff, 0x8c4: 0x0707, 0x8c5: 0x0713, + 0x8c6: 0x071b, 0x8c7: 0x0723, 0x8c8: 0x072f, 0x8c9: 0x0783, 0x8ca: 0x079b, 0x8cb: 0x07ab, + 0x8cc: 0x07bb, 0x8cd: 0x07cb, 0x8ce: 0x07db, 0x8cf: 0x07fb, 0x8d0: 0x07ff, 0x8d1: 0x0803, + 0x8d2: 0x0837, 0x8d3: 0x085f, 0x8d4: 0x086f, 0x8d5: 0x0877, 0x8d6: 0x087b, 0x8d7: 0x0887, + 0x8d8: 0x08a3, 0x8d9: 0x08a7, 0x8da: 0x08bf, 0x8db: 0x08c3, 0x8dc: 0x08cb, 0x8dd: 0x08db, + 0x8de: 0x0977, 0x8df: 0x098b, 0x8e0: 0x09cb, 0x8e1: 0x09df, 0x8e2: 0x09e7, 0x8e3: 0x09eb, + 0x8e4: 0x09fb, 0x8e5: 0x0a17, 0x8e6: 0x0a43, 0x8e7: 0x0a4f, 0x8e8: 0x0a6f, 0x8e9: 0x0a7b, + 0x8ea: 0x0a7f, 0x8eb: 0x0a83, 0x8ec: 0x0a9b, 0x8ed: 0x0a9f, 0x8ee: 0x0acb, 0x8ef: 0x0ad7, + 0x8f0: 0x0adf, 0x8f1: 0x0ae7, 0x8f2: 0x0af7, 0x8f3: 0x0aff, 0x8f4: 0x0b07, 0x8f5: 0x0b33, + 0x8f6: 0x0b37, 0x8f7: 0x0b3f, 0x8f8: 0x0b43, 0x8f9: 0x0b4b, 0x8fa: 0x0b53, 0x8fb: 0x0b63, + 0x8fc: 0x0b7f, 0x8fd: 0x0bf7, 0x8fe: 0x0c0b, 0x8ff: 0x0c0f, + // Block 0x24, offset 0x900 + 0x900: 0x0c8f, 0x901: 0x0c93, 0x902: 0x0ca7, 0x903: 0x0cab, 0x904: 0x0cb3, 0x905: 0x0cbb, + 0x906: 0x0cc3, 0x907: 0x0ccf, 0x908: 0x0cf7, 0x909: 0x0d07, 0x90a: 0x0d1b, 0x90b: 0x0d8b, + 0x90c: 0x0d97, 0x90d: 0x0da7, 0x90e: 0x0db3, 0x90f: 0x0dbf, 0x910: 0x0dc7, 0x911: 0x0dcb, + 0x912: 0x0dcf, 0x913: 0x0dd3, 0x914: 0x0dd7, 0x915: 0x0e8f, 0x916: 0x0ed7, 0x917: 0x0ee3, + 0x918: 0x0ee7, 0x919: 0x0eeb, 0x91a: 0x0eef, 0x91b: 0x0ef7, 0x91c: 0x0efb, 0x91d: 0x0f0f, + 0x91e: 0x0f2b, 0x91f: 0x0f33, 0x920: 0x0f73, 0x921: 0x0f77, 0x922: 0x0f7f, 0x923: 0x0f83, + 0x924: 0x0f8b, 0x925: 0x0f8f, 0x926: 0x0fb3, 0x927: 0x0fb7, 0x928: 0x0fd3, 0x929: 0x0fd7, + 0x92a: 0x0fdb, 0x92b: 0x0fdf, 0x92c: 0x0ff3, 0x92d: 0x1017, 0x92e: 0x101b, 0x92f: 0x101f, + 0x930: 0x1043, 0x931: 0x1083, 0x932: 0x1087, 0x933: 0x10a7, 0x934: 0x10b7, 0x935: 0x10bf, + 0x936: 0x10df, 0x937: 0x1103, 0x938: 0x1147, 0x939: 0x114f, 0x93a: 0x1163, 0x93b: 0x116f, + 0x93c: 0x1177, 0x93d: 0x117f, 0x93e: 0x1183, 0x93f: 0x1187, + // Block 0x25, offset 0x940 + 0x940: 0x119f, 0x941: 0x11a3, 0x942: 0x11bf, 0x943: 0x11c7, 0x944: 0x11cf, 0x945: 0x11d3, + 0x946: 0x11df, 0x947: 0x11e7, 0x948: 0x11eb, 0x949: 0x11ef, 0x94a: 0x11f7, 0x94b: 0x11fb, + 0x94c: 0x129b, 0x94d: 0x12af, 0x94e: 0x12e3, 0x94f: 0x12e7, 0x950: 0x12ef, 0x951: 0x131b, + 0x952: 0x1323, 0x953: 0x132b, 0x954: 0x1333, 0x955: 0x136f, 0x956: 0x1373, 0x957: 0x137b, + 0x958: 0x137f, 0x959: 0x1383, 0x95a: 0x13af, 0x95b: 0x13b3, 0x95c: 0x13bb, 0x95d: 0x13cf, + 0x95e: 0x13d3, 0x95f: 0x13ef, 0x960: 0x13f7, 0x961: 0x13fb, 0x962: 0x141f, 0x963: 0x143f, + 0x964: 0x1453, 0x965: 0x1457, 0x966: 0x145f, 0x967: 0x148b, 0x968: 0x148f, 0x969: 0x149f, + 0x96a: 0x14c3, 0x96b: 0x14cf, 0x96c: 0x14df, 0x96d: 0x14f7, 0x96e: 0x14ff, 0x96f: 0x1503, + 0x970: 0x1507, 0x971: 0x150b, 0x972: 0x1517, 0x973: 0x151b, 0x974: 0x1523, 0x975: 0x153f, + 0x976: 0x1543, 0x977: 0x1547, 0x978: 0x155f, 0x979: 0x1563, 0x97a: 0x156b, 0x97b: 0x157f, + 0x97c: 0x1583, 0x97d: 0x1587, 0x97e: 0x158f, 0x97f: 0x1593, + // Block 0x26, offset 0x980 + 0x986: 0xa000, 0x98b: 0xa000, + 0x98c: 0x3f0b, 0x98d: 0xa000, 0x98e: 0x3f13, 0x98f: 0xa000, 0x990: 0x3f1b, 0x991: 0xa000, + 0x992: 0x3f23, 0x993: 0xa000, 0x994: 0x3f2b, 0x995: 0xa000, 0x996: 0x3f33, 0x997: 0xa000, + 0x998: 0x3f3b, 0x999: 0xa000, 0x99a: 0x3f43, 0x99b: 0xa000, 0x99c: 0x3f4b, 0x99d: 0xa000, + 0x99e: 0x3f53, 0x99f: 0xa000, 0x9a0: 0x3f5b, 0x9a1: 0xa000, 0x9a2: 0x3f63, + 0x9a4: 0xa000, 0x9a5: 0x3f6b, 0x9a6: 0xa000, 0x9a7: 0x3f73, 0x9a8: 0xa000, 0x9a9: 0x3f7b, + 0x9af: 0xa000, + 0x9b0: 0x3f83, 0x9b1: 0x3f8b, 0x9b2: 0xa000, 0x9b3: 0x3f93, 0x9b4: 0x3f9b, 0x9b5: 0xa000, + 0x9b6: 0x3fa3, 0x9b7: 0x3fab, 0x9b8: 0xa000, 0x9b9: 0x3fb3, 0x9ba: 0x3fbb, 0x9bb: 0xa000, + 0x9bc: 0x3fc3, 0x9bd: 0x3fcb, + // Block 0x27, offset 0x9c0 + 0x9d4: 0x3f03, + 0x9d9: 0x9903, 0x9da: 0x9903, 0x9db: 0x42df, 0x9dc: 0x42e5, 0x9dd: 0xa000, + 0x9de: 0x3fd3, 0x9df: 0x26b7, + 0x9e6: 0xa000, + 0x9eb: 0xa000, 0x9ec: 0x3fe3, 0x9ed: 0xa000, 0x9ee: 0x3feb, 0x9ef: 0xa000, + 0x9f0: 0x3ff3, 0x9f1: 0xa000, 0x9f2: 0x3ffb, 0x9f3: 0xa000, 0x9f4: 0x4003, 0x9f5: 0xa000, + 0x9f6: 0x400b, 0x9f7: 0xa000, 0x9f8: 0x4013, 0x9f9: 0xa000, 0x9fa: 0x401b, 0x9fb: 0xa000, + 0x9fc: 0x4023, 0x9fd: 0xa000, 0x9fe: 0x402b, 0x9ff: 0xa000, + // Block 0x28, offset 0xa00 + 0xa00: 0x4033, 0xa01: 0xa000, 0xa02: 0x403b, 0xa04: 0xa000, 0xa05: 0x4043, + 0xa06: 0xa000, 0xa07: 0x404b, 0xa08: 0xa000, 0xa09: 0x4053, + 0xa0f: 0xa000, 0xa10: 0x405b, 0xa11: 0x4063, + 0xa12: 0xa000, 0xa13: 0x406b, 0xa14: 0x4073, 0xa15: 0xa000, 0xa16: 0x407b, 0xa17: 0x4083, + 0xa18: 0xa000, 0xa19: 0x408b, 0xa1a: 0x4093, 0xa1b: 0xa000, 0xa1c: 0x409b, 0xa1d: 0x40a3, + 0xa2f: 0xa000, + 0xa30: 0xa000, 0xa31: 0xa000, 0xa32: 0xa000, 0xa34: 0x3fdb, + 0xa37: 0x40ab, 0xa38: 0x40b3, 0xa39: 0x40bb, 0xa3a: 0x40c3, + 0xa3d: 0xa000, 0xa3e: 0x40cb, 0xa3f: 0x26cc, + // Block 0x29, offset 0xa40 + 0xa40: 0x0367, 0xa41: 0x032b, 0xa42: 0x032f, 0xa43: 0x0333, 0xa44: 0x037b, 0xa45: 0x0337, + 0xa46: 0x033b, 0xa47: 0x033f, 0xa48: 0x0343, 0xa49: 0x0347, 0xa4a: 0x034b, 0xa4b: 0x034f, + 0xa4c: 0x0353, 0xa4d: 0x0357, 0xa4e: 0x035b, 0xa4f: 0x49c0, 0xa50: 0x49c6, 0xa51: 0x49cc, + 0xa52: 0x49d2, 0xa53: 0x49d8, 0xa54: 0x49de, 0xa55: 0x49e4, 0xa56: 0x49ea, 0xa57: 0x49f0, + 0xa58: 0x49f6, 0xa59: 0x49fc, 0xa5a: 0x4a02, 0xa5b: 0x4a08, 0xa5c: 0x4a0e, 0xa5d: 0x4a14, + 0xa5e: 0x4a1a, 0xa5f: 0x4a20, 0xa60: 0x4a26, 0xa61: 0x4a2c, 0xa62: 0x4a32, 0xa63: 0x4a38, + 0xa64: 0x03c3, 0xa65: 0x035f, 0xa66: 0x0363, 0xa67: 0x03e7, 0xa68: 0x03eb, 0xa69: 0x03ef, + 0xa6a: 0x03f3, 0xa6b: 0x03f7, 0xa6c: 0x03fb, 0xa6d: 0x03ff, 0xa6e: 0x036b, 0xa6f: 0x0403, + 0xa70: 0x0407, 0xa71: 0x036f, 0xa72: 0x0373, 0xa73: 0x0377, 0xa74: 0x037f, 0xa75: 0x0383, + 0xa76: 0x0387, 0xa77: 0x038b, 0xa78: 0x038f, 0xa79: 0x0393, 0xa7a: 0x0397, 0xa7b: 0x039b, + 0xa7c: 0x039f, 0xa7d: 0x03a3, 0xa7e: 0x03a7, 0xa7f: 0x03ab, + // Block 0x2a, offset 0xa80 + 0xa80: 0x03af, 0xa81: 0x03b3, 0xa82: 0x040b, 0xa83: 0x040f, 0xa84: 0x03b7, 0xa85: 0x03bb, + 0xa86: 0x03bf, 0xa87: 0x03c7, 0xa88: 0x03cb, 0xa89: 0x03cf, 0xa8a: 0x03d3, 0xa8b: 0x03d7, + 0xa8c: 0x03db, 0xa8d: 0x03df, 0xa8e: 0x03e3, + 0xa92: 0x06bf, 0xa93: 0x071b, 0xa94: 0x06cb, 0xa95: 0x097b, 0xa96: 0x06cf, 0xa97: 0x06e7, + 0xa98: 0x06d3, 0xa99: 0x0f93, 0xa9a: 0x0707, 0xa9b: 0x06db, 0xa9c: 0x06c3, 0xa9d: 0x09ff, + 0xa9e: 0x098f, 0xa9f: 0x072f, + // Block 0x2b, offset 0xac0 + 0xac0: 0x2057, 0xac1: 0x205d, 0xac2: 0x2063, 0xac3: 0x2069, 0xac4: 0x206f, 0xac5: 0x2075, + 0xac6: 0x207b, 0xac7: 0x2081, 0xac8: 0x2087, 0xac9: 0x208d, 0xaca: 0x2093, 0xacb: 0x2099, + 0xacc: 0x209f, 0xacd: 0x20a5, 0xace: 0x2729, 0xacf: 0x2732, 0xad0: 0x273b, 0xad1: 0x2744, + 0xad2: 0x274d, 0xad3: 0x2756, 0xad4: 0x275f, 0xad5: 0x2768, 0xad6: 0x2771, 0xad7: 0x2783, + 0xad8: 0x278c, 0xad9: 0x2795, 0xada: 0x279e, 0xadb: 0x27a7, 0xadc: 0x277a, 0xadd: 0x2baf, + 0xade: 0x2af0, 0xae0: 0x20ab, 0xae1: 0x20c3, 0xae2: 0x20b7, 0xae3: 0x210b, + 0xae4: 0x20c9, 0xae5: 0x20e7, 0xae6: 0x20b1, 0xae7: 0x20e1, 0xae8: 0x20bd, 0xae9: 0x20f3, + 0xaea: 0x2123, 0xaeb: 0x2141, 0xaec: 0x213b, 0xaed: 0x212f, 0xaee: 0x217d, 0xaef: 0x2111, + 0xaf0: 0x211d, 0xaf1: 0x2135, 0xaf2: 0x2129, 0xaf3: 0x2153, 0xaf4: 0x20ff, 0xaf5: 0x2147, + 0xaf6: 0x2171, 0xaf7: 0x2159, 0xaf8: 0x20ed, 0xaf9: 0x20cf, 0xafa: 0x2105, 0xafb: 0x2117, + 0xafc: 0x214d, 0xafd: 0x20d5, 0xafe: 0x2177, 0xaff: 0x20f9, + // Block 0x2c, offset 0xb00 + 0xb00: 0x215f, 0xb01: 0x20db, 0xb02: 0x2165, 0xb03: 0x216b, 0xb04: 0x092f, 0xb05: 0x0b03, + 0xb06: 0x0ca7, 0xb07: 0x10c7, + 0xb10: 0x1bc7, 0xb11: 0x18a9, + 0xb12: 0x18ac, 0xb13: 0x18af, 0xb14: 0x18b2, 0xb15: 0x18b5, 0xb16: 0x18b8, 0xb17: 0x18bb, + 0xb18: 0x18be, 0xb19: 0x18c1, 0xb1a: 0x18ca, 0xb1b: 0x18cd, 0xb1c: 0x18d0, 0xb1d: 0x18d3, + 0xb1e: 0x18d6, 0xb1f: 0x18d9, 0xb20: 0x0313, 0xb21: 0x031b, 0xb22: 0x031f, 0xb23: 0x0327, + 0xb24: 0x032b, 0xb25: 0x032f, 0xb26: 0x0337, 0xb27: 0x033f, 0xb28: 0x0343, 0xb29: 0x034b, + 0xb2a: 0x034f, 0xb2b: 0x0353, 0xb2c: 0x0357, 0xb2d: 0x035b, 0xb2e: 0x2e1b, 0xb2f: 0x2e23, + 0xb30: 0x2e2b, 0xb31: 0x2e33, 0xb32: 0x2e3b, 0xb33: 0x2e43, 0xb34: 0x2e4b, 0xb35: 0x2e53, + 0xb36: 0x2e63, 0xb37: 0x2e6b, 0xb38: 0x2e73, 0xb39: 0x2e7b, 0xb3a: 0x2e83, 0xb3b: 0x2e8b, + 0xb3c: 0x2ed6, 0xb3d: 0x2e9e, 0xb3e: 0x2e5b, + // Block 0x2d, offset 0xb40 + 0xb40: 0x06bf, 0xb41: 0x071b, 0xb42: 0x06cb, 0xb43: 0x097b, 0xb44: 0x071f, 0xb45: 0x07af, + 0xb46: 0x06c7, 0xb47: 0x07ab, 0xb48: 0x070b, 0xb49: 0x0887, 0xb4a: 0x0d07, 0xb4b: 0x0e8f, + 0xb4c: 0x0dd7, 0xb4d: 0x0d1b, 0xb4e: 0x145f, 0xb4f: 0x098b, 0xb50: 0x0ccf, 0xb51: 0x0d4b, + 0xb52: 0x0d0b, 0xb53: 0x104b, 0xb54: 0x08fb, 0xb55: 0x0f03, 0xb56: 0x1387, 0xb57: 0x105f, + 0xb58: 0x0843, 0xb59: 0x108f, 0xb5a: 0x0f9b, 0xb5b: 0x0a17, 0xb5c: 0x140f, 0xb5d: 0x077f, + 0xb5e: 0x08ab, 0xb5f: 0x0df7, 0xb60: 0x1527, 0xb61: 0x0743, 0xb62: 0x07d3, 0xb63: 0x0d9b, + 0xb64: 0x06cf, 0xb65: 0x06e7, 0xb66: 0x06d3, 0xb67: 0x0adb, 0xb68: 0x08ef, 0xb69: 0x087f, + 0xb6a: 0x0a57, 0xb6b: 0x0a4b, 0xb6c: 0x0feb, 0xb6d: 0x073f, 0xb6e: 0x139b, 0xb6f: 0x089b, + 0xb70: 0x09f3, 0xb71: 0x18dc, 0xb72: 0x18df, 0xb73: 0x18e2, 0xb74: 0x18e5, 0xb75: 0x18ee, + 0xb76: 0x18f1, 0xb77: 0x18f4, 0xb78: 0x18f7, 0xb79: 0x18fa, 0xb7a: 0x18fd, 0xb7b: 0x1900, + 0xb7c: 0x1903, 0xb7d: 0x1906, 0xb7e: 0x1909, 0xb7f: 0x1912, + // Block 0x2e, offset 0xb80 + 0xb80: 0x1cc9, 0xb81: 0x1cd8, 0xb82: 0x1ce7, 0xb83: 0x1cf6, 0xb84: 0x1d05, 0xb85: 0x1d14, + 0xb86: 0x1d23, 0xb87: 0x1d32, 0xb88: 0x1d41, 0xb89: 0x218f, 0xb8a: 0x21a1, 0xb8b: 0x21b3, + 0xb8c: 0x1954, 0xb8d: 0x1c07, 0xb8e: 0x19d5, 0xb8f: 0x1bab, 0xb90: 0x04cb, 0xb91: 0x04d3, + 0xb92: 0x04db, 0xb93: 0x04e3, 0xb94: 0x04eb, 0xb95: 0x04ef, 0xb96: 0x04f3, 0xb97: 0x04f7, + 0xb98: 0x04fb, 0xb99: 0x04ff, 0xb9a: 0x0503, 0xb9b: 0x0507, 0xb9c: 0x050b, 0xb9d: 0x050f, + 0xb9e: 0x0513, 0xb9f: 0x0517, 0xba0: 0x051b, 0xba1: 0x0523, 0xba2: 0x0527, 0xba3: 0x052b, + 0xba4: 0x052f, 0xba5: 0x0533, 0xba6: 0x0537, 0xba7: 0x053b, 0xba8: 0x053f, 0xba9: 0x0543, + 0xbaa: 0x0547, 0xbab: 0x054b, 0xbac: 0x054f, 0xbad: 0x0553, 0xbae: 0x0557, 0xbaf: 0x055b, + 0xbb0: 0x055f, 0xbb1: 0x0563, 0xbb2: 0x0567, 0xbb3: 0x056f, 0xbb4: 0x0577, 0xbb5: 0x057f, + 0xbb6: 0x0583, 0xbb7: 0x0587, 0xbb8: 0x058b, 0xbb9: 0x058f, 0xbba: 0x0593, 0xbbb: 0x0597, + 0xbbc: 0x059b, 0xbbd: 0x059f, 0xbbe: 0x05a3, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x2b0f, 0xbc1: 0x29ab, 0xbc2: 0x2b1f, 0xbc3: 0x2883, 0xbc4: 0x2ee7, 0xbc5: 0x288d, + 0xbc6: 0x2897, 0xbc7: 0x2f2b, 0xbc8: 0x29b8, 0xbc9: 0x28a1, 0xbca: 0x28ab, 0xbcb: 0x28b5, + 0xbcc: 0x29df, 0xbcd: 0x29ec, 0xbce: 0x29c5, 0xbcf: 0x29d2, 0xbd0: 0x2eac, 0xbd1: 0x29f9, + 0xbd2: 0x2a06, 0xbd3: 0x2bc1, 0xbd4: 0x26be, 0xbd5: 0x2bd4, 0xbd6: 0x2be7, 0xbd7: 0x2b2f, + 0xbd8: 0x2a13, 0xbd9: 0x2bfa, 0xbda: 0x2c0d, 0xbdb: 0x2a20, 0xbdc: 0x28bf, 0xbdd: 0x28c9, + 0xbde: 0x2eba, 0xbdf: 0x2a2d, 0xbe0: 0x2b3f, 0xbe1: 0x2ef8, 0xbe2: 0x28d3, 0xbe3: 0x28dd, + 0xbe4: 0x2a3a, 0xbe5: 0x28e7, 0xbe6: 0x28f1, 0xbe7: 0x26d3, 0xbe8: 0x26da, 0xbe9: 0x28fb, + 0xbea: 0x2905, 0xbeb: 0x2c20, 0xbec: 0x2a47, 0xbed: 0x2b4f, 0xbee: 0x2c33, 0xbef: 0x2a54, + 0xbf0: 0x2919, 0xbf1: 0x290f, 0xbf2: 0x2f3f, 0xbf3: 0x2a61, 0xbf4: 0x2c46, 0xbf5: 0x2923, + 0xbf6: 0x2b5f, 0xbf7: 0x292d, 0xbf8: 0x2a7b, 0xbf9: 0x2937, 0xbfa: 0x2a88, 0xbfb: 0x2f09, + 0xbfc: 0x2a6e, 0xbfd: 0x2b6f, 0xbfe: 0x2a95, 0xbff: 0x26e1, + // Block 0x30, offset 0xc00 + 0xc00: 0x2f1a, 0xc01: 0x2941, 0xc02: 0x294b, 0xc03: 0x2aa2, 0xc04: 0x2955, 0xc05: 0x295f, + 0xc06: 0x2969, 0xc07: 0x2b7f, 0xc08: 0x2aaf, 0xc09: 0x26e8, 0xc0a: 0x2c59, 0xc0b: 0x2e93, + 0xc0c: 0x2b8f, 0xc0d: 0x2abc, 0xc0e: 0x2ec8, 0xc0f: 0x2973, 0xc10: 0x297d, 0xc11: 0x2ac9, + 0xc12: 0x26ef, 0xc13: 0x2ad6, 0xc14: 0x2b9f, 0xc15: 0x26f6, 0xc16: 0x2c6c, 0xc17: 0x2987, + 0xc18: 0x1cba, 0xc19: 0x1cce, 0xc1a: 0x1cdd, 0xc1b: 0x1cec, 0xc1c: 0x1cfb, 0xc1d: 0x1d0a, + 0xc1e: 0x1d19, 0xc1f: 0x1d28, 0xc20: 0x1d37, 0xc21: 0x1d46, 0xc22: 0x2195, 0xc23: 0x21a7, + 0xc24: 0x21b9, 0xc25: 0x21c5, 0xc26: 0x21d1, 0xc27: 0x21dd, 0xc28: 0x21e9, 0xc29: 0x21f5, + 0xc2a: 0x2201, 0xc2b: 0x220d, 0xc2c: 0x2249, 0xc2d: 0x2255, 0xc2e: 0x2261, 0xc2f: 0x226d, + 0xc30: 0x2279, 0xc31: 0x1c17, 0xc32: 0x19c9, 0xc33: 0x1936, 0xc34: 0x1be7, 0xc35: 0x1a4a, + 0xc36: 0x1a59, 0xc37: 0x19cf, 0xc38: 0x1bff, 0xc39: 0x1c03, 0xc3a: 0x1960, 0xc3b: 0x2704, + 0xc3c: 0x2712, 0xc3d: 0x26fd, 0xc3e: 0x270b, 0xc3f: 0x2ae3, + // Block 0x31, offset 0xc40 + 0xc40: 0x1a4d, 0xc41: 0x1a35, 0xc42: 0x1c63, 0xc43: 0x1a1d, 0xc44: 0x19f6, 0xc45: 0x1969, + 0xc46: 0x1978, 0xc47: 0x1948, 0xc48: 0x1bf3, 0xc49: 0x1d55, 0xc4a: 0x1a50, 0xc4b: 0x1a38, + 0xc4c: 0x1c67, 0xc4d: 0x1c73, 0xc4e: 0x1a29, 0xc4f: 0x19ff, 0xc50: 0x1957, 0xc51: 0x1c1f, + 0xc52: 0x1bb3, 0xc53: 0x1b9f, 0xc54: 0x1bcf, 0xc55: 0x1c77, 0xc56: 0x1a2c, 0xc57: 0x19cc, + 0xc58: 0x1a02, 0xc59: 0x19e1, 0xc5a: 0x1a44, 0xc5b: 0x1c7b, 0xc5c: 0x1a2f, 0xc5d: 0x19c3, + 0xc5e: 0x1a05, 0xc5f: 0x1c3f, 0xc60: 0x1bf7, 0xc61: 0x1a17, 0xc62: 0x1c27, 0xc63: 0x1c43, + 0xc64: 0x1bfb, 0xc65: 0x1a1a, 0xc66: 0x1c2b, 0xc67: 0x22eb, 0xc68: 0x22ff, 0xc69: 0x1999, + 0xc6a: 0x1c23, 0xc6b: 0x1bb7, 0xc6c: 0x1ba3, 0xc6d: 0x1c4b, 0xc6e: 0x2719, 0xc6f: 0x27b0, + 0xc70: 0x1a5c, 0xc71: 0x1a47, 0xc72: 0x1c7f, 0xc73: 0x1a32, 0xc74: 0x1a53, 0xc75: 0x1a3b, + 0xc76: 0x1c6b, 0xc77: 0x1a20, 0xc78: 0x19f9, 0xc79: 0x1984, 0xc7a: 0x1a56, 0xc7b: 0x1a3e, + 0xc7c: 0x1c6f, 0xc7d: 0x1a23, 0xc7e: 0x19fc, 0xc7f: 0x1987, + // Block 0x32, offset 0xc80 + 0xc80: 0x1c2f, 0xc81: 0x1bbb, 0xc82: 0x1d50, 0xc83: 0x1939, 0xc84: 0x19bd, 0xc85: 0x19c0, + 0xc86: 0x22f8, 0xc87: 0x1b97, 0xc88: 0x19c6, 0xc89: 0x194b, 0xc8a: 0x19e4, 0xc8b: 0x194e, + 0xc8c: 0x19ed, 0xc8d: 0x196c, 0xc8e: 0x196f, 0xc8f: 0x1a08, 0xc90: 0x1a0e, 0xc91: 0x1a11, + 0xc92: 0x1c33, 0xc93: 0x1a14, 0xc94: 0x1a26, 0xc95: 0x1c3b, 0xc96: 0x1c47, 0xc97: 0x1993, + 0xc98: 0x1d5a, 0xc99: 0x1bbf, 0xc9a: 0x1996, 0xc9b: 0x1a5f, 0xc9c: 0x19a8, 0xc9d: 0x19b7, + 0xc9e: 0x22e5, 0xc9f: 0x22df, 0xca0: 0x1cc4, 0xca1: 0x1cd3, 0xca2: 0x1ce2, 0xca3: 0x1cf1, + 0xca4: 0x1d00, 0xca5: 0x1d0f, 0xca6: 0x1d1e, 0xca7: 0x1d2d, 0xca8: 0x1d3c, 0xca9: 0x2189, + 0xcaa: 0x219b, 0xcab: 0x21ad, 0xcac: 0x21bf, 0xcad: 0x21cb, 0xcae: 0x21d7, 0xcaf: 0x21e3, + 0xcb0: 0x21ef, 0xcb1: 0x21fb, 0xcb2: 0x2207, 0xcb3: 0x2243, 0xcb4: 0x224f, 0xcb5: 0x225b, + 0xcb6: 0x2267, 0xcb7: 0x2273, 0xcb8: 0x227f, 0xcb9: 0x2285, 0xcba: 0x228b, 0xcbb: 0x2291, + 0xcbc: 0x2297, 0xcbd: 0x22a9, 0xcbe: 0x22af, 0xcbf: 0x1c13, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x1377, 0xcc1: 0x0cfb, 0xcc2: 0x13d3, 0xcc3: 0x139f, 0xcc4: 0x0e57, 0xcc5: 0x06eb, + 0xcc6: 0x08df, 0xcc7: 0x162b, 0xcc8: 0x162b, 0xcc9: 0x0a0b, 0xcca: 0x145f, 0xccb: 0x0943, + 0xccc: 0x0a07, 0xccd: 0x0bef, 0xcce: 0x0fcf, 0xccf: 0x115f, 0xcd0: 0x1297, 0xcd1: 0x12d3, + 0xcd2: 0x1307, 0xcd3: 0x141b, 0xcd4: 0x0d73, 0xcd5: 0x0dff, 0xcd6: 0x0eab, 0xcd7: 0x0f43, + 0xcd8: 0x125f, 0xcd9: 0x1447, 0xcda: 0x1573, 0xcdb: 0x070f, 0xcdc: 0x08b3, 0xcdd: 0x0d87, + 0xcde: 0x0ecf, 0xcdf: 0x1293, 0xce0: 0x15c3, 0xce1: 0x0ab3, 0xce2: 0x0e77, 0xce3: 0x1283, + 0xce4: 0x1317, 0xce5: 0x0c23, 0xce6: 0x11bb, 0xce7: 0x12df, 0xce8: 0x0b1f, 0xce9: 0x0d0f, + 0xcea: 0x0e17, 0xceb: 0x0f1b, 0xcec: 0x1427, 0xced: 0x074f, 0xcee: 0x07e7, 0xcef: 0x0853, + 0xcf0: 0x0c8b, 0xcf1: 0x0d7f, 0xcf2: 0x0ecb, 0xcf3: 0x0fef, 0xcf4: 0x1177, 0xcf5: 0x128b, + 0xcf6: 0x12a3, 0xcf7: 0x13c7, 0xcf8: 0x14ef, 0xcf9: 0x15a3, 0xcfa: 0x15bf, 0xcfb: 0x102b, + 0xcfc: 0x106b, 0xcfd: 0x1123, 0xcfe: 0x1243, 0xcff: 0x147b, + // Block 0x34, offset 0xd00 + 0xd00: 0x15cb, 0xd01: 0x134b, 0xd02: 0x09c7, 0xd03: 0x0b3b, 0xd04: 0x10db, 0xd05: 0x119b, + 0xd06: 0x0eff, 0xd07: 0x1033, 0xd08: 0x1397, 0xd09: 0x14e7, 0xd0a: 0x09c3, 0xd0b: 0x0a8f, + 0xd0c: 0x0d77, 0xd0d: 0x0e2b, 0xd0e: 0x0e5f, 0xd0f: 0x1113, 0xd10: 0x113b, 0xd11: 0x14a7, + 0xd12: 0x084f, 0xd13: 0x11a7, 0xd14: 0x07f3, 0xd15: 0x07ef, 0xd16: 0x1097, 0xd17: 0x1127, + 0xd18: 0x125b, 0xd19: 0x14af, 0xd1a: 0x1367, 0xd1b: 0x0c27, 0xd1c: 0x0d73, 0xd1d: 0x1357, + 0xd1e: 0x06f7, 0xd1f: 0x0a63, 0xd20: 0x0b93, 0xd21: 0x0f2f, 0xd22: 0x0faf, 0xd23: 0x0873, + 0xd24: 0x103b, 0xd25: 0x075f, 0xd26: 0x0b77, 0xd27: 0x06d7, 0xd28: 0x0deb, 0xd29: 0x0ca3, + 0xd2a: 0x110f, 0xd2b: 0x08c7, 0xd2c: 0x09b3, 0xd2d: 0x0ffb, 0xd2e: 0x1263, 0xd2f: 0x133b, + 0xd30: 0x0db7, 0xd31: 0x13f7, 0xd32: 0x0de3, 0xd33: 0x0c37, 0xd34: 0x121b, 0xd35: 0x0c57, + 0xd36: 0x0fab, 0xd37: 0x072b, 0xd38: 0x07a7, 0xd39: 0x07eb, 0xd3a: 0x0d53, 0xd3b: 0x10fb, + 0xd3c: 0x11f3, 0xd3d: 0x1347, 0xd3e: 0x145b, 0xd3f: 0x085b, + // Block 0x35, offset 0xd40 + 0xd40: 0x090f, 0xd41: 0x0a17, 0xd42: 0x0b2f, 0xd43: 0x0cbf, 0xd44: 0x0e7b, 0xd45: 0x103f, + 0xd46: 0x1497, 0xd47: 0x157b, 0xd48: 0x15cf, 0xd49: 0x15e7, 0xd4a: 0x0837, 0xd4b: 0x0cf3, + 0xd4c: 0x0da3, 0xd4d: 0x13eb, 0xd4e: 0x0afb, 0xd4f: 0x0bd7, 0xd50: 0x0bf3, 0xd51: 0x0c83, + 0xd52: 0x0e6b, 0xd53: 0x0eb7, 0xd54: 0x0f67, 0xd55: 0x108b, 0xd56: 0x112f, 0xd57: 0x1193, + 0xd58: 0x13db, 0xd59: 0x126b, 0xd5a: 0x1403, 0xd5b: 0x147f, 0xd5c: 0x080f, 0xd5d: 0x083b, + 0xd5e: 0x0923, 0xd5f: 0x0ea7, 0xd60: 0x12f3, 0xd61: 0x133b, 0xd62: 0x0b1b, 0xd63: 0x0b8b, + 0xd64: 0x0c4f, 0xd65: 0x0daf, 0xd66: 0x10d7, 0xd67: 0x0f23, 0xd68: 0x073b, 0xd69: 0x097f, + 0xd6a: 0x0a63, 0xd6b: 0x0ac7, 0xd6c: 0x0b97, 0xd6d: 0x0f3f, 0xd6e: 0x0f5b, 0xd6f: 0x116b, + 0xd70: 0x118b, 0xd71: 0x1463, 0xd72: 0x14e3, 0xd73: 0x14f3, 0xd74: 0x152f, 0xd75: 0x0753, + 0xd76: 0x107f, 0xd77: 0x144f, 0xd78: 0x14cb, 0xd79: 0x0baf, 0xd7a: 0x0717, 0xd7b: 0x0777, + 0xd7c: 0x0a67, 0xd7d: 0x0a87, 0xd7e: 0x0caf, 0xd7f: 0x0d73, + // Block 0x36, offset 0xd80 + 0xd80: 0x0ec3, 0xd81: 0x0fcb, 0xd82: 0x1277, 0xd83: 0x1417, 0xd84: 0x1623, 0xd85: 0x0ce3, + 0xd86: 0x14a3, 0xd87: 0x0833, 0xd88: 0x0d2f, 0xd89: 0x0d3b, 0xd8a: 0x0e0f, 0xd8b: 0x0e47, + 0xd8c: 0x0f4b, 0xd8d: 0x0fa7, 0xd8e: 0x1027, 0xd8f: 0x110b, 0xd90: 0x153b, 0xd91: 0x07af, + 0xd92: 0x0c03, 0xd93: 0x14b3, 0xd94: 0x0767, 0xd95: 0x0aab, 0xd96: 0x0e2f, 0xd97: 0x13df, + 0xd98: 0x0b67, 0xd99: 0x0bb7, 0xd9a: 0x0d43, 0xd9b: 0x0f2f, 0xd9c: 0x14bb, 0xd9d: 0x0817, + 0xd9e: 0x08ff, 0xd9f: 0x0a97, 0xda0: 0x0cd3, 0xda1: 0x0d1f, 0xda2: 0x0d5f, 0xda3: 0x0df3, + 0xda4: 0x0f47, 0xda5: 0x0fbb, 0xda6: 0x1157, 0xda7: 0x12f7, 0xda8: 0x1303, 0xda9: 0x1457, + 0xdaa: 0x14d7, 0xdab: 0x0883, 0xdac: 0x0e4b, 0xdad: 0x0903, 0xdae: 0x0ec7, 0xdaf: 0x0f6b, + 0xdb0: 0x1287, 0xdb1: 0x14bf, 0xdb2: 0x15ab, 0xdb3: 0x15d3, 0xdb4: 0x0d37, 0xdb5: 0x0e27, + 0xdb6: 0x11c3, 0xdb7: 0x10b7, 0xdb8: 0x10c3, 0xdb9: 0x10e7, 0xdba: 0x0f17, 0xdbb: 0x0e9f, + 0xdbc: 0x1363, 0xdbd: 0x0733, 0xdbe: 0x122b, 0xdbf: 0x081b, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x080b, 0xdc1: 0x0b0b, 0xdc2: 0x0c2b, 0xdc3: 0x10f3, 0xdc4: 0x0a53, 0xdc5: 0x0e03, + 0xdc6: 0x0cef, 0xdc7: 0x13e7, 0xdc8: 0x12e7, 0xdc9: 0x14ab, 0xdca: 0x1323, 0xdcb: 0x0b27, + 0xdcc: 0x0787, 0xdcd: 0x095b, 0xdd0: 0x09af, + 0xdd2: 0x0cdf, 0xdd5: 0x07f7, 0xdd6: 0x0f1f, 0xdd7: 0x0fe3, + 0xdd8: 0x1047, 0xdd9: 0x1063, 0xdda: 0x1067, 0xddb: 0x107b, 0xddc: 0x14fb, 0xddd: 0x10eb, + 0xdde: 0x116f, 0xde0: 0x128f, 0xde2: 0x1353, + 0xde5: 0x1407, 0xde6: 0x1433, + 0xdea: 0x154f, 0xdeb: 0x1553, 0xdec: 0x1557, 0xded: 0x15bb, 0xdee: 0x142b, 0xdef: 0x14c7, + 0xdf0: 0x0757, 0xdf1: 0x077b, 0xdf2: 0x078f, 0xdf3: 0x084b, 0xdf4: 0x0857, 0xdf5: 0x0897, + 0xdf6: 0x094b, 0xdf7: 0x0967, 0xdf8: 0x096f, 0xdf9: 0x09ab, 0xdfa: 0x09b7, 0xdfb: 0x0a93, + 0xdfc: 0x0a9b, 0xdfd: 0x0ba3, 0xdfe: 0x0bcb, 0xdff: 0x0bd3, + // Block 0x38, offset 0xe00 + 0xe00: 0x0beb, 0xe01: 0x0c97, 0xe02: 0x0cc7, 0xe03: 0x0ce7, 0xe04: 0x0d57, 0xe05: 0x0e1b, + 0xe06: 0x0e37, 0xe07: 0x0e67, 0xe08: 0x0ebb, 0xe09: 0x0edb, 0xe0a: 0x0f4f, 0xe0b: 0x102f, + 0xe0c: 0x104b, 0xe0d: 0x1053, 0xe0e: 0x104f, 0xe0f: 0x1057, 0xe10: 0x105b, 0xe11: 0x105f, + 0xe12: 0x1073, 0xe13: 0x1077, 0xe14: 0x109b, 0xe15: 0x10af, 0xe16: 0x10cb, 0xe17: 0x112f, + 0xe18: 0x1137, 0xe19: 0x113f, 0xe1a: 0x1153, 0xe1b: 0x117b, 0xe1c: 0x11cb, 0xe1d: 0x11ff, + 0xe1e: 0x11ff, 0xe1f: 0x1267, 0xe20: 0x130f, 0xe21: 0x1327, 0xe22: 0x135b, 0xe23: 0x135f, + 0xe24: 0x13a3, 0xe25: 0x13a7, 0xe26: 0x13ff, 0xe27: 0x1407, 0xe28: 0x14db, 0xe29: 0x151f, + 0xe2a: 0x1537, 0xe2b: 0x0b9b, 0xe2c: 0x171e, 0xe2d: 0x11e3, + 0xe30: 0x06df, 0xe31: 0x07e3, 0xe32: 0x07a3, 0xe33: 0x074b, 0xe34: 0x078b, 0xe35: 0x07b7, + 0xe36: 0x0847, 0xe37: 0x0863, 0xe38: 0x094b, 0xe39: 0x0937, 0xe3a: 0x0947, 0xe3b: 0x0963, + 0xe3c: 0x09af, 0xe3d: 0x09bf, 0xe3e: 0x0a03, 0xe3f: 0x0a0f, + // Block 0x39, offset 0xe40 + 0xe40: 0x0a2b, 0xe41: 0x0a3b, 0xe42: 0x0b23, 0xe43: 0x0b2b, 0xe44: 0x0b5b, 0xe45: 0x0b7b, + 0xe46: 0x0bab, 0xe47: 0x0bc3, 0xe48: 0x0bb3, 0xe49: 0x0bd3, 0xe4a: 0x0bc7, 0xe4b: 0x0beb, + 0xe4c: 0x0c07, 0xe4d: 0x0c5f, 0xe4e: 0x0c6b, 0xe4f: 0x0c73, 0xe50: 0x0c9b, 0xe51: 0x0cdf, + 0xe52: 0x0d0f, 0xe53: 0x0d13, 0xe54: 0x0d27, 0xe55: 0x0da7, 0xe56: 0x0db7, 0xe57: 0x0e0f, + 0xe58: 0x0e5b, 0xe59: 0x0e53, 0xe5a: 0x0e67, 0xe5b: 0x0e83, 0xe5c: 0x0ebb, 0xe5d: 0x1013, + 0xe5e: 0x0edf, 0xe5f: 0x0f13, 0xe60: 0x0f1f, 0xe61: 0x0f5f, 0xe62: 0x0f7b, 0xe63: 0x0f9f, + 0xe64: 0x0fc3, 0xe65: 0x0fc7, 0xe66: 0x0fe3, 0xe67: 0x0fe7, 0xe68: 0x0ff7, 0xe69: 0x100b, + 0xe6a: 0x1007, 0xe6b: 0x1037, 0xe6c: 0x10b3, 0xe6d: 0x10cb, 0xe6e: 0x10e3, 0xe6f: 0x111b, + 0xe70: 0x112f, 0xe71: 0x114b, 0xe72: 0x117b, 0xe73: 0x122f, 0xe74: 0x1257, 0xe75: 0x12cb, + 0xe76: 0x1313, 0xe77: 0x131f, 0xe78: 0x1327, 0xe79: 0x133f, 0xe7a: 0x1353, 0xe7b: 0x1343, + 0xe7c: 0x135b, 0xe7d: 0x1357, 0xe7e: 0x134f, 0xe7f: 0x135f, + // Block 0x3a, offset 0xe80 + 0xe80: 0x136b, 0xe81: 0x13a7, 0xe82: 0x13e3, 0xe83: 0x1413, 0xe84: 0x144b, 0xe85: 0x146b, + 0xe86: 0x14b7, 0xe87: 0x14db, 0xe88: 0x14fb, 0xe89: 0x150f, 0xe8a: 0x151f, 0xe8b: 0x152b, + 0xe8c: 0x1537, 0xe8d: 0x158b, 0xe8e: 0x162b, 0xe8f: 0x16b5, 0xe90: 0x16b0, 0xe91: 0x16e2, + 0xe92: 0x0607, 0xe93: 0x062f, 0xe94: 0x0633, 0xe95: 0x1764, 0xe96: 0x1791, 0xe97: 0x1809, + 0xe98: 0x1617, 0xe99: 0x1627, + // Block 0x3b, offset 0xec0 + 0xec0: 0x19d8, 0xec1: 0x19db, 0xec2: 0x19de, 0xec3: 0x1c0b, 0xec4: 0x1c0f, 0xec5: 0x1a62, + 0xec6: 0x1a62, + 0xed3: 0x1d78, 0xed4: 0x1d69, 0xed5: 0x1d6e, 0xed6: 0x1d7d, 0xed7: 0x1d73, + 0xedd: 0x4393, + 0xede: 0x8115, 0xedf: 0x4405, 0xee0: 0x022d, 0xee1: 0x0215, 0xee2: 0x021e, 0xee3: 0x0221, + 0xee4: 0x0224, 0xee5: 0x0227, 0xee6: 0x022a, 0xee7: 0x0230, 0xee8: 0x0233, 0xee9: 0x0017, + 0xeea: 0x43f3, 0xeeb: 0x43f9, 0xeec: 0x44f7, 0xeed: 0x44ff, 0xeee: 0x434b, 0xeef: 0x4351, + 0xef0: 0x4357, 0xef1: 0x435d, 0xef2: 0x4369, 0xef3: 0x436f, 0xef4: 0x4375, 0xef5: 0x4381, + 0xef6: 0x4387, 0xef8: 0x438d, 0xef9: 0x4399, 0xefa: 0x439f, 0xefb: 0x43a5, + 0xefc: 0x43b1, 0xefe: 0x43b7, + // Block 0x3c, offset 0xf00 + 0xf00: 0x43bd, 0xf01: 0x43c3, 0xf03: 0x43c9, 0xf04: 0x43cf, + 0xf06: 0x43db, 0xf07: 0x43e1, 0xf08: 0x43e7, 0xf09: 0x43ed, 0xf0a: 0x43ff, 0xf0b: 0x437b, + 0xf0c: 0x4363, 0xf0d: 0x43ab, 0xf0e: 0x43d5, 0xf0f: 0x1d82, 0xf10: 0x0299, 0xf11: 0x0299, + 0xf12: 0x02a2, 0xf13: 0x02a2, 0xf14: 0x02a2, 0xf15: 0x02a2, 0xf16: 0x02a5, 0xf17: 0x02a5, + 0xf18: 0x02a5, 0xf19: 0x02a5, 0xf1a: 0x02ab, 0xf1b: 0x02ab, 0xf1c: 0x02ab, 0xf1d: 0x02ab, + 0xf1e: 0x029f, 0xf1f: 0x029f, 0xf20: 0x029f, 0xf21: 0x029f, 0xf22: 0x02a8, 0xf23: 0x02a8, + 0xf24: 0x02a8, 0xf25: 0x02a8, 0xf26: 0x029c, 0xf27: 0x029c, 0xf28: 0x029c, 0xf29: 0x029c, + 0xf2a: 0x02cf, 0xf2b: 0x02cf, 0xf2c: 0x02cf, 0xf2d: 0x02cf, 0xf2e: 0x02d2, 0xf2f: 0x02d2, + 0xf30: 0x02d2, 0xf31: 0x02d2, 0xf32: 0x02b1, 0xf33: 0x02b1, 0xf34: 0x02b1, 0xf35: 0x02b1, + 0xf36: 0x02ae, 0xf37: 0x02ae, 0xf38: 0x02ae, 0xf39: 0x02ae, 0xf3a: 0x02b4, 0xf3b: 0x02b4, + 0xf3c: 0x02b4, 0xf3d: 0x02b4, 0xf3e: 0x02b7, 0xf3f: 0x02b7, + // Block 0x3d, offset 0xf40 + 0xf40: 0x02b7, 0xf41: 0x02b7, 0xf42: 0x02c0, 0xf43: 0x02c0, 0xf44: 0x02bd, 0xf45: 0x02bd, + 0xf46: 0x02c3, 0xf47: 0x02c3, 0xf48: 0x02ba, 0xf49: 0x02ba, 0xf4a: 0x02c9, 0xf4b: 0x02c9, + 0xf4c: 0x02c6, 0xf4d: 0x02c6, 0xf4e: 0x02d5, 0xf4f: 0x02d5, 0xf50: 0x02d5, 0xf51: 0x02d5, + 0xf52: 0x02db, 0xf53: 0x02db, 0xf54: 0x02db, 0xf55: 0x02db, 0xf56: 0x02e1, 0xf57: 0x02e1, + 0xf58: 0x02e1, 0xf59: 0x02e1, 0xf5a: 0x02de, 0xf5b: 0x02de, 0xf5c: 0x02de, 0xf5d: 0x02de, + 0xf5e: 0x02e4, 0xf5f: 0x02e4, 0xf60: 0x02e7, 0xf61: 0x02e7, 0xf62: 0x02e7, 0xf63: 0x02e7, + 0xf64: 0x4471, 0xf65: 0x4471, 0xf66: 0x02ed, 0xf67: 0x02ed, 0xf68: 0x02ed, 0xf69: 0x02ed, + 0xf6a: 0x02ea, 0xf6b: 0x02ea, 0xf6c: 0x02ea, 0xf6d: 0x02ea, 0xf6e: 0x0308, 0xf6f: 0x0308, + 0xf70: 0x446b, 0xf71: 0x446b, + // Block 0x3e, offset 0xf80 + 0xf93: 0x02d8, 0xf94: 0x02d8, 0xf95: 0x02d8, 0xf96: 0x02d8, 0xf97: 0x02f6, + 0xf98: 0x02f6, 0xf99: 0x02f3, 0xf9a: 0x02f3, 0xf9b: 0x02f9, 0xf9c: 0x02f9, 0xf9d: 0x2052, + 0xf9e: 0x02ff, 0xf9f: 0x02ff, 0xfa0: 0x02f0, 0xfa1: 0x02f0, 0xfa2: 0x02fc, 0xfa3: 0x02fc, + 0xfa4: 0x0305, 0xfa5: 0x0305, 0xfa6: 0x0305, 0xfa7: 0x0305, 0xfa8: 0x028d, 0xfa9: 0x028d, + 0xfaa: 0x25ad, 0xfab: 0x25ad, 0xfac: 0x261d, 0xfad: 0x261d, 0xfae: 0x25ec, 0xfaf: 0x25ec, + 0xfb0: 0x2608, 0xfb1: 0x2608, 0xfb2: 0x2601, 0xfb3: 0x2601, 0xfb4: 0x260f, 0xfb5: 0x260f, + 0xfb6: 0x2616, 0xfb7: 0x2616, 0xfb8: 0x2616, 0xfb9: 0x25f3, 0xfba: 0x25f3, 0xfbb: 0x25f3, + 0xfbc: 0x0302, 0xfbd: 0x0302, 0xfbe: 0x0302, 0xfbf: 0x0302, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x25b4, 0xfc1: 0x25bb, 0xfc2: 0x25d7, 0xfc3: 0x25f3, 0xfc4: 0x25fa, 0xfc5: 0x1d8c, + 0xfc6: 0x1d91, 0xfc7: 0x1d96, 0xfc8: 0x1da5, 0xfc9: 0x1db4, 0xfca: 0x1db9, 0xfcb: 0x1dbe, + 0xfcc: 0x1dc3, 0xfcd: 0x1dc8, 0xfce: 0x1dd7, 0xfcf: 0x1de6, 0xfd0: 0x1deb, 0xfd1: 0x1df0, + 0xfd2: 0x1dff, 0xfd3: 0x1e0e, 0xfd4: 0x1e13, 0xfd5: 0x1e18, 0xfd6: 0x1e1d, 0xfd7: 0x1e2c, + 0xfd8: 0x1e31, 0xfd9: 0x1e40, 0xfda: 0x1e45, 0xfdb: 0x1e4a, 0xfdc: 0x1e59, 0xfdd: 0x1e5e, + 0xfde: 0x1e63, 0xfdf: 0x1e6d, 0xfe0: 0x1ea9, 0xfe1: 0x1eb8, 0xfe2: 0x1ec7, 0xfe3: 0x1ecc, + 0xfe4: 0x1ed1, 0xfe5: 0x1edb, 0xfe6: 0x1eea, 0xfe7: 0x1eef, 0xfe8: 0x1efe, 0xfe9: 0x1f03, + 0xfea: 0x1f08, 0xfeb: 0x1f17, 0xfec: 0x1f1c, 0xfed: 0x1f2b, 0xfee: 0x1f30, 0xfef: 0x1f35, + 0xff0: 0x1f3a, 0xff1: 0x1f3f, 0xff2: 0x1f44, 0xff3: 0x1f49, 0xff4: 0x1f4e, 0xff5: 0x1f53, + 0xff6: 0x1f58, 0xff7: 0x1f5d, 0xff8: 0x1f62, 0xff9: 0x1f67, 0xffa: 0x1f6c, 0xffb: 0x1f71, + 0xffc: 0x1f76, 0xffd: 0x1f7b, 0xffe: 0x1f80, 0xfff: 0x1f8a, + // Block 0x40, offset 0x1000 + 0x1000: 0x1f8f, 0x1001: 0x1f94, 0x1002: 0x1f99, 0x1003: 0x1fa3, 0x1004: 0x1fa8, 0x1005: 0x1fb2, + 0x1006: 0x1fb7, 0x1007: 0x1fbc, 0x1008: 0x1fc1, 0x1009: 0x1fc6, 0x100a: 0x1fcb, 0x100b: 0x1fd0, + 0x100c: 0x1fd5, 0x100d: 0x1fda, 0x100e: 0x1fe9, 0x100f: 0x1ff8, 0x1010: 0x1ffd, 0x1011: 0x2002, + 0x1012: 0x2007, 0x1013: 0x200c, 0x1014: 0x2011, 0x1015: 0x201b, 0x1016: 0x2020, 0x1017: 0x2025, + 0x1018: 0x2034, 0x1019: 0x2043, 0x101a: 0x2048, 0x101b: 0x4423, 0x101c: 0x4429, 0x101d: 0x445f, + 0x101e: 0x44b6, 0x101f: 0x44bd, 0x1020: 0x44c4, 0x1021: 0x44cb, 0x1022: 0x44d2, 0x1023: 0x44d9, + 0x1024: 0x25c9, 0x1025: 0x25d0, 0x1026: 0x25d7, 0x1027: 0x25de, 0x1028: 0x25f3, 0x1029: 0x25fa, + 0x102a: 0x1d9b, 0x102b: 0x1da0, 0x102c: 0x1da5, 0x102d: 0x1daa, 0x102e: 0x1db4, 0x102f: 0x1db9, + 0x1030: 0x1dcd, 0x1031: 0x1dd2, 0x1032: 0x1dd7, 0x1033: 0x1ddc, 0x1034: 0x1de6, 0x1035: 0x1deb, + 0x1036: 0x1df5, 0x1037: 0x1dfa, 0x1038: 0x1dff, 0x1039: 0x1e04, 0x103a: 0x1e0e, 0x103b: 0x1e13, + 0x103c: 0x1f3f, 0x103d: 0x1f44, 0x103e: 0x1f53, 0x103f: 0x1f58, + // Block 0x41, offset 0x1040 + 0x1040: 0x1f5d, 0x1041: 0x1f71, 0x1042: 0x1f76, 0x1043: 0x1f7b, 0x1044: 0x1f80, 0x1045: 0x1f99, + 0x1046: 0x1fa3, 0x1047: 0x1fa8, 0x1048: 0x1fad, 0x1049: 0x1fc1, 0x104a: 0x1fdf, 0x104b: 0x1fe4, + 0x104c: 0x1fe9, 0x104d: 0x1fee, 0x104e: 0x1ff8, 0x104f: 0x1ffd, 0x1050: 0x445f, 0x1051: 0x202a, + 0x1052: 0x202f, 0x1053: 0x2034, 0x1054: 0x2039, 0x1055: 0x2043, 0x1056: 0x2048, 0x1057: 0x25b4, + 0x1058: 0x25bb, 0x1059: 0x25c2, 0x105a: 0x25d7, 0x105b: 0x25e5, 0x105c: 0x1d8c, 0x105d: 0x1d91, + 0x105e: 0x1d96, 0x105f: 0x1da5, 0x1060: 0x1daf, 0x1061: 0x1dbe, 0x1062: 0x1dc3, 0x1063: 0x1dc8, + 0x1064: 0x1dd7, 0x1065: 0x1de1, 0x1066: 0x1dff, 0x1067: 0x1e18, 0x1068: 0x1e1d, 0x1069: 0x1e2c, + 0x106a: 0x1e31, 0x106b: 0x1e40, 0x106c: 0x1e4a, 0x106d: 0x1e59, 0x106e: 0x1e5e, 0x106f: 0x1e63, + 0x1070: 0x1e6d, 0x1071: 0x1ea9, 0x1072: 0x1eae, 0x1073: 0x1eb8, 0x1074: 0x1ec7, 0x1075: 0x1ecc, + 0x1076: 0x1ed1, 0x1077: 0x1edb, 0x1078: 0x1eea, 0x1079: 0x1efe, 0x107a: 0x1f03, 0x107b: 0x1f08, + 0x107c: 0x1f17, 0x107d: 0x1f1c, 0x107e: 0x1f2b, 0x107f: 0x1f30, + // Block 0x42, offset 0x1080 + 0x1080: 0x1f35, 0x1081: 0x1f3a, 0x1082: 0x1f49, 0x1083: 0x1f4e, 0x1084: 0x1f62, 0x1085: 0x1f67, + 0x1086: 0x1f6c, 0x1087: 0x1f71, 0x1088: 0x1f76, 0x1089: 0x1f8a, 0x108a: 0x1f8f, 0x108b: 0x1f94, + 0x108c: 0x1f99, 0x108d: 0x1f9e, 0x108e: 0x1fb2, 0x108f: 0x1fb7, 0x1090: 0x1fbc, 0x1091: 0x1fc1, + 0x1092: 0x1fd0, 0x1093: 0x1fd5, 0x1094: 0x1fda, 0x1095: 0x1fe9, 0x1096: 0x1ff3, 0x1097: 0x2002, + 0x1098: 0x2007, 0x1099: 0x4453, 0x109a: 0x201b, 0x109b: 0x2020, 0x109c: 0x2025, 0x109d: 0x2034, + 0x109e: 0x203e, 0x109f: 0x25d7, 0x10a0: 0x25e5, 0x10a1: 0x1da5, 0x10a2: 0x1daf, 0x10a3: 0x1dd7, + 0x10a4: 0x1de1, 0x10a5: 0x1dff, 0x10a6: 0x1e09, 0x10a7: 0x1e6d, 0x10a8: 0x1e72, 0x10a9: 0x1e95, + 0x10aa: 0x1e9a, 0x10ab: 0x1f71, 0x10ac: 0x1f76, 0x10ad: 0x1f99, 0x10ae: 0x1fe9, 0x10af: 0x1ff3, + 0x10b0: 0x2034, 0x10b1: 0x203e, 0x10b2: 0x4507, 0x10b3: 0x450f, 0x10b4: 0x4517, 0x10b5: 0x1ef4, + 0x10b6: 0x1ef9, 0x10b7: 0x1f0d, 0x10b8: 0x1f12, 0x10b9: 0x1f21, 0x10ba: 0x1f26, 0x10bb: 0x1e77, + 0x10bc: 0x1e7c, 0x10bd: 0x1e9f, 0x10be: 0x1ea4, 0x10bf: 0x1e36, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x1e3b, 0x10c1: 0x1e22, 0x10c2: 0x1e27, 0x10c3: 0x1e4f, 0x10c4: 0x1e54, 0x10c5: 0x1ebd, + 0x10c6: 0x1ec2, 0x10c7: 0x1ee0, 0x10c8: 0x1ee5, 0x10c9: 0x1e81, 0x10ca: 0x1e86, 0x10cb: 0x1e8b, + 0x10cc: 0x1e95, 0x10cd: 0x1e90, 0x10ce: 0x1e68, 0x10cf: 0x1eb3, 0x10d0: 0x1ed6, 0x10d1: 0x1ef4, + 0x10d2: 0x1ef9, 0x10d3: 0x1f0d, 0x10d4: 0x1f12, 0x10d5: 0x1f21, 0x10d6: 0x1f26, 0x10d7: 0x1e77, + 0x10d8: 0x1e7c, 0x10d9: 0x1e9f, 0x10da: 0x1ea4, 0x10db: 0x1e36, 0x10dc: 0x1e3b, 0x10dd: 0x1e22, + 0x10de: 0x1e27, 0x10df: 0x1e4f, 0x10e0: 0x1e54, 0x10e1: 0x1ebd, 0x10e2: 0x1ec2, 0x10e3: 0x1ee0, + 0x10e4: 0x1ee5, 0x10e5: 0x1e81, 0x10e6: 0x1e86, 0x10e7: 0x1e8b, 0x10e8: 0x1e95, 0x10e9: 0x1e90, + 0x10ea: 0x1e68, 0x10eb: 0x1eb3, 0x10ec: 0x1ed6, 0x10ed: 0x1e81, 0x10ee: 0x1e86, 0x10ef: 0x1e8b, + 0x10f0: 0x1e95, 0x10f1: 0x1e72, 0x10f2: 0x1e9a, 0x10f3: 0x1eef, 0x10f4: 0x1e59, 0x10f5: 0x1e5e, + 0x10f6: 0x1e63, 0x10f7: 0x1e81, 0x10f8: 0x1e86, 0x10f9: 0x1e8b, 0x10fa: 0x1eef, 0x10fb: 0x1efe, + 0x10fc: 0x440b, 0x10fd: 0x440b, + // Block 0x44, offset 0x1100 + 0x1110: 0x2314, 0x1111: 0x2329, + 0x1112: 0x2329, 0x1113: 0x2330, 0x1114: 0x2337, 0x1115: 0x234c, 0x1116: 0x2353, 0x1117: 0x235a, + 0x1118: 0x237d, 0x1119: 0x237d, 0x111a: 0x23a0, 0x111b: 0x2399, 0x111c: 0x23b5, 0x111d: 0x23a7, + 0x111e: 0x23ae, 0x111f: 0x23d1, 0x1120: 0x23d1, 0x1121: 0x23ca, 0x1122: 0x23d8, 0x1123: 0x23d8, + 0x1124: 0x2402, 0x1125: 0x2402, 0x1126: 0x241e, 0x1127: 0x23e6, 0x1128: 0x23e6, 0x1129: 0x23df, + 0x112a: 0x23f4, 0x112b: 0x23f4, 0x112c: 0x23fb, 0x112d: 0x23fb, 0x112e: 0x2425, 0x112f: 0x2433, + 0x1130: 0x2433, 0x1131: 0x243a, 0x1132: 0x243a, 0x1133: 0x2441, 0x1134: 0x2448, 0x1135: 0x244f, + 0x1136: 0x2456, 0x1137: 0x2456, 0x1138: 0x245d, 0x1139: 0x246b, 0x113a: 0x2479, 0x113b: 0x2472, + 0x113c: 0x2480, 0x113d: 0x2480, 0x113e: 0x2495, 0x113f: 0x249c, + // Block 0x45, offset 0x1140 + 0x1140: 0x24cd, 0x1141: 0x24db, 0x1142: 0x24d4, 0x1143: 0x24b8, 0x1144: 0x24b8, 0x1145: 0x24e2, + 0x1146: 0x24e2, 0x1147: 0x24e9, 0x1148: 0x24e9, 0x1149: 0x2513, 0x114a: 0x251a, 0x114b: 0x2521, + 0x114c: 0x24f7, 0x114d: 0x2505, 0x114e: 0x2528, 0x114f: 0x252f, + 0x1152: 0x24fe, 0x1153: 0x2583, 0x1154: 0x258a, 0x1155: 0x2560, 0x1156: 0x2567, 0x1157: 0x254b, + 0x1158: 0x254b, 0x1159: 0x2552, 0x115a: 0x257c, 0x115b: 0x2575, 0x115c: 0x259f, 0x115d: 0x259f, + 0x115e: 0x230d, 0x115f: 0x2322, 0x1160: 0x231b, 0x1161: 0x2345, 0x1162: 0x233e, 0x1163: 0x2368, + 0x1164: 0x2361, 0x1165: 0x238b, 0x1166: 0x236f, 0x1167: 0x2384, 0x1168: 0x23bc, 0x1169: 0x2409, + 0x116a: 0x23ed, 0x116b: 0x242c, 0x116c: 0x24c6, 0x116d: 0x24f0, 0x116e: 0x2598, 0x116f: 0x2591, + 0x1170: 0x25a6, 0x1171: 0x253d, 0x1172: 0x24a3, 0x1173: 0x256e, 0x1174: 0x2495, 0x1175: 0x24cd, + 0x1176: 0x2464, 0x1177: 0x24b1, 0x1178: 0x2544, 0x1179: 0x2536, 0x117a: 0x24bf, 0x117b: 0x24aa, + 0x117c: 0x24bf, 0x117d: 0x2544, 0x117e: 0x2376, 0x117f: 0x2392, + // Block 0x46, offset 0x1180 + 0x1180: 0x250c, 0x1181: 0x2487, 0x1182: 0x2306, 0x1183: 0x24aa, 0x1184: 0x244f, 0x1185: 0x241e, + 0x1186: 0x23c3, 0x1187: 0x2559, + 0x11b0: 0x2417, 0x11b1: 0x248e, 0x11b2: 0x27c2, 0x11b3: 0x27b9, 0x11b4: 0x27ef, 0x11b5: 0x27dd, + 0x11b6: 0x27cb, 0x11b7: 0x27e6, 0x11b8: 0x27f8, 0x11b9: 0x2410, 0x11ba: 0x2c7f, 0x11bb: 0x2aff, + 0x11bc: 0x27d4, + // Block 0x47, offset 0x11c0 + 0x11d0: 0x0019, 0x11d1: 0x0483, + 0x11d2: 0x0487, 0x11d3: 0x0035, 0x11d4: 0x0037, 0x11d5: 0x0003, 0x11d6: 0x003f, 0x11d7: 0x04bf, + 0x11d8: 0x04c3, 0x11d9: 0x1b5f, + 0x11e0: 0x8132, 0x11e1: 0x8132, 0x11e2: 0x8132, 0x11e3: 0x8132, + 0x11e4: 0x8132, 0x11e5: 0x8132, 0x11e6: 0x8132, 0x11e7: 0x812d, 0x11e8: 0x812d, 0x11e9: 0x812d, + 0x11ea: 0x812d, 0x11eb: 0x812d, 0x11ec: 0x812d, 0x11ed: 0x812d, 0x11ee: 0x8132, 0x11ef: 0x8132, + 0x11f0: 0x1873, 0x11f1: 0x0443, 0x11f2: 0x043f, 0x11f3: 0x007f, 0x11f4: 0x007f, 0x11f5: 0x0011, + 0x11f6: 0x0013, 0x11f7: 0x00b7, 0x11f8: 0x00bb, 0x11f9: 0x04b7, 0x11fa: 0x04bb, 0x11fb: 0x04ab, + 0x11fc: 0x04af, 0x11fd: 0x0493, 0x11fe: 0x0497, 0x11ff: 0x048b, + // Block 0x48, offset 0x1200 + 0x1200: 0x048f, 0x1201: 0x049b, 0x1202: 0x049f, 0x1203: 0x04a3, 0x1204: 0x04a7, + 0x1207: 0x0077, 0x1208: 0x007b, 0x1209: 0x426c, 0x120a: 0x426c, 0x120b: 0x426c, + 0x120c: 0x426c, 0x120d: 0x007f, 0x120e: 0x007f, 0x120f: 0x007f, 0x1210: 0x0019, 0x1211: 0x0483, + 0x1212: 0x001d, 0x1214: 0x0037, 0x1215: 0x0035, 0x1216: 0x003f, 0x1217: 0x0003, + 0x1218: 0x0443, 0x1219: 0x0011, 0x121a: 0x0013, 0x121b: 0x00b7, 0x121c: 0x00bb, 0x121d: 0x04b7, + 0x121e: 0x04bb, 0x121f: 0x0007, 0x1220: 0x000d, 0x1221: 0x0015, 0x1222: 0x0017, 0x1223: 0x001b, + 0x1224: 0x0039, 0x1225: 0x003d, 0x1226: 0x003b, 0x1228: 0x0079, 0x1229: 0x0009, + 0x122a: 0x000b, 0x122b: 0x0041, + 0x1230: 0x42ad, 0x1231: 0x442f, 0x1232: 0x42b2, 0x1234: 0x42b7, + 0x1236: 0x42bc, 0x1237: 0x4435, 0x1238: 0x42c1, 0x1239: 0x443b, 0x123a: 0x42c6, 0x123b: 0x4441, + 0x123c: 0x42cb, 0x123d: 0x4447, 0x123e: 0x42d0, 0x123f: 0x444d, + // Block 0x49, offset 0x1240 + 0x1240: 0x0236, 0x1241: 0x4411, 0x1242: 0x4411, 0x1243: 0x4417, 0x1244: 0x4417, 0x1245: 0x4459, + 0x1246: 0x4459, 0x1247: 0x441d, 0x1248: 0x441d, 0x1249: 0x4465, 0x124a: 0x4465, 0x124b: 0x4465, + 0x124c: 0x4465, 0x124d: 0x0239, 0x124e: 0x0239, 0x124f: 0x023c, 0x1250: 0x023c, 0x1251: 0x023c, + 0x1252: 0x023c, 0x1253: 0x023f, 0x1254: 0x023f, 0x1255: 0x0242, 0x1256: 0x0242, 0x1257: 0x0242, + 0x1258: 0x0242, 0x1259: 0x0245, 0x125a: 0x0245, 0x125b: 0x0245, 0x125c: 0x0245, 0x125d: 0x0248, + 0x125e: 0x0248, 0x125f: 0x0248, 0x1260: 0x0248, 0x1261: 0x024b, 0x1262: 0x024b, 0x1263: 0x024b, + 0x1264: 0x024b, 0x1265: 0x024e, 0x1266: 0x024e, 0x1267: 0x024e, 0x1268: 0x024e, 0x1269: 0x0251, + 0x126a: 0x0251, 0x126b: 0x0254, 0x126c: 0x0254, 0x126d: 0x0257, 0x126e: 0x0257, 0x126f: 0x025a, + 0x1270: 0x025a, 0x1271: 0x025d, 0x1272: 0x025d, 0x1273: 0x025d, 0x1274: 0x025d, 0x1275: 0x0260, + 0x1276: 0x0260, 0x1277: 0x0260, 0x1278: 0x0260, 0x1279: 0x0263, 0x127a: 0x0263, 0x127b: 0x0263, + 0x127c: 0x0263, 0x127d: 0x0266, 0x127e: 0x0266, 0x127f: 0x0266, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0266, 0x1281: 0x0269, 0x1282: 0x0269, 0x1283: 0x0269, 0x1284: 0x0269, 0x1285: 0x026c, + 0x1286: 0x026c, 0x1287: 0x026c, 0x1288: 0x026c, 0x1289: 0x026f, 0x128a: 0x026f, 0x128b: 0x026f, + 0x128c: 0x026f, 0x128d: 0x0272, 0x128e: 0x0272, 0x128f: 0x0272, 0x1290: 0x0272, 0x1291: 0x0275, + 0x1292: 0x0275, 0x1293: 0x0275, 0x1294: 0x0275, 0x1295: 0x0278, 0x1296: 0x0278, 0x1297: 0x0278, + 0x1298: 0x0278, 0x1299: 0x027b, 0x129a: 0x027b, 0x129b: 0x027b, 0x129c: 0x027b, 0x129d: 0x027e, + 0x129e: 0x027e, 0x129f: 0x027e, 0x12a0: 0x027e, 0x12a1: 0x0281, 0x12a2: 0x0281, 0x12a3: 0x0281, + 0x12a4: 0x0281, 0x12a5: 0x0284, 0x12a6: 0x0284, 0x12a7: 0x0284, 0x12a8: 0x0284, 0x12a9: 0x0287, + 0x12aa: 0x0287, 0x12ab: 0x0287, 0x12ac: 0x0287, 0x12ad: 0x028a, 0x12ae: 0x028a, 0x12af: 0x028d, + 0x12b0: 0x028d, 0x12b1: 0x0290, 0x12b2: 0x0290, 0x12b3: 0x0290, 0x12b4: 0x0290, 0x12b5: 0x2e03, + 0x12b6: 0x2e03, 0x12b7: 0x2e0b, 0x12b8: 0x2e0b, 0x12b9: 0x2e13, 0x12ba: 0x2e13, 0x12bb: 0x1f85, + 0x12bc: 0x1f85, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x0081, 0x12c1: 0x0083, 0x12c2: 0x0085, 0x12c3: 0x0087, 0x12c4: 0x0089, 0x12c5: 0x008b, + 0x12c6: 0x008d, 0x12c7: 0x008f, 0x12c8: 0x0091, 0x12c9: 0x0093, 0x12ca: 0x0095, 0x12cb: 0x0097, + 0x12cc: 0x0099, 0x12cd: 0x009b, 0x12ce: 0x009d, 0x12cf: 0x009f, 0x12d0: 0x00a1, 0x12d1: 0x00a3, + 0x12d2: 0x00a5, 0x12d3: 0x00a7, 0x12d4: 0x00a9, 0x12d5: 0x00ab, 0x12d6: 0x00ad, 0x12d7: 0x00af, + 0x12d8: 0x00b1, 0x12d9: 0x00b3, 0x12da: 0x00b5, 0x12db: 0x00b7, 0x12dc: 0x00b9, 0x12dd: 0x00bb, + 0x12de: 0x00bd, 0x12df: 0x0477, 0x12e0: 0x047b, 0x12e1: 0x0487, 0x12e2: 0x049b, 0x12e3: 0x049f, + 0x12e4: 0x0483, 0x12e5: 0x05ab, 0x12e6: 0x05a3, 0x12e7: 0x04c7, 0x12e8: 0x04cf, 0x12e9: 0x04d7, + 0x12ea: 0x04df, 0x12eb: 0x04e7, 0x12ec: 0x056b, 0x12ed: 0x0573, 0x12ee: 0x057b, 0x12ef: 0x051f, + 0x12f0: 0x05af, 0x12f1: 0x04cb, 0x12f2: 0x04d3, 0x12f3: 0x04db, 0x12f4: 0x04e3, 0x12f5: 0x04eb, + 0x12f6: 0x04ef, 0x12f7: 0x04f3, 0x12f8: 0x04f7, 0x12f9: 0x04fb, 0x12fa: 0x04ff, 0x12fb: 0x0503, + 0x12fc: 0x0507, 0x12fd: 0x050b, 0x12fe: 0x050f, 0x12ff: 0x0513, + // Block 0x4c, offset 0x1300 + 0x1300: 0x0517, 0x1301: 0x051b, 0x1302: 0x0523, 0x1303: 0x0527, 0x1304: 0x052b, 0x1305: 0x052f, + 0x1306: 0x0533, 0x1307: 0x0537, 0x1308: 0x053b, 0x1309: 0x053f, 0x130a: 0x0543, 0x130b: 0x0547, + 0x130c: 0x054b, 0x130d: 0x054f, 0x130e: 0x0553, 0x130f: 0x0557, 0x1310: 0x055b, 0x1311: 0x055f, + 0x1312: 0x0563, 0x1313: 0x0567, 0x1314: 0x056f, 0x1315: 0x0577, 0x1316: 0x057f, 0x1317: 0x0583, + 0x1318: 0x0587, 0x1319: 0x058b, 0x131a: 0x058f, 0x131b: 0x0593, 0x131c: 0x0597, 0x131d: 0x05a7, + 0x131e: 0x4a7b, 0x131f: 0x4a81, 0x1320: 0x03c3, 0x1321: 0x0313, 0x1322: 0x0317, 0x1323: 0x4a3e, + 0x1324: 0x031b, 0x1325: 0x4a44, 0x1326: 0x4a4a, 0x1327: 0x031f, 0x1328: 0x0323, 0x1329: 0x0327, + 0x132a: 0x4a50, 0x132b: 0x4a56, 0x132c: 0x4a5c, 0x132d: 0x4a62, 0x132e: 0x4a68, 0x132f: 0x4a6e, + 0x1330: 0x0367, 0x1331: 0x032b, 0x1332: 0x032f, 0x1333: 0x0333, 0x1334: 0x037b, 0x1335: 0x0337, + 0x1336: 0x033b, 0x1337: 0x033f, 0x1338: 0x0343, 0x1339: 0x0347, 0x133a: 0x034b, 0x133b: 0x034f, + 0x133c: 0x0353, 0x133d: 0x0357, 0x133e: 0x035b, + // Block 0x4d, offset 0x1340 + 0x1342: 0x49c0, 0x1343: 0x49c6, 0x1344: 0x49cc, 0x1345: 0x49d2, + 0x1346: 0x49d8, 0x1347: 0x49de, 0x134a: 0x49e4, 0x134b: 0x49ea, + 0x134c: 0x49f0, 0x134d: 0x49f6, 0x134e: 0x49fc, 0x134f: 0x4a02, + 0x1352: 0x4a08, 0x1353: 0x4a0e, 0x1354: 0x4a14, 0x1355: 0x4a1a, 0x1356: 0x4a20, 0x1357: 0x4a26, + 0x135a: 0x4a2c, 0x135b: 0x4a32, 0x135c: 0x4a38, + 0x1360: 0x00bf, 0x1361: 0x00c2, 0x1362: 0x00cb, 0x1363: 0x4267, + 0x1364: 0x00c8, 0x1365: 0x00c5, 0x1366: 0x0447, 0x1368: 0x046b, 0x1369: 0x044b, + 0x136a: 0x044f, 0x136b: 0x0453, 0x136c: 0x0457, 0x136d: 0x046f, 0x136e: 0x0473, + // Block 0x4e, offset 0x1380 + 0x1380: 0x0063, 0x1381: 0x0065, 0x1382: 0x0067, 0x1383: 0x0069, 0x1384: 0x006b, 0x1385: 0x006d, + 0x1386: 0x006f, 0x1387: 0x0071, 0x1388: 0x0073, 0x1389: 0x0075, 0x138a: 0x0083, 0x138b: 0x0085, + 0x138c: 0x0087, 0x138d: 0x0089, 0x138e: 0x008b, 0x138f: 0x008d, 0x1390: 0x008f, 0x1391: 0x0091, + 0x1392: 0x0093, 0x1393: 0x0095, 0x1394: 0x0097, 0x1395: 0x0099, 0x1396: 0x009b, 0x1397: 0x009d, + 0x1398: 0x009f, 0x1399: 0x00a1, 0x139a: 0x00a3, 0x139b: 0x00a5, 0x139c: 0x00a7, 0x139d: 0x00a9, + 0x139e: 0x00ab, 0x139f: 0x00ad, 0x13a0: 0x00af, 0x13a1: 0x00b1, 0x13a2: 0x00b3, 0x13a3: 0x00b5, + 0x13a4: 0x00dd, 0x13a5: 0x00f2, 0x13a8: 0x0173, 0x13a9: 0x0176, + 0x13aa: 0x0179, 0x13ab: 0x017c, 0x13ac: 0x017f, 0x13ad: 0x0182, 0x13ae: 0x0185, 0x13af: 0x0188, + 0x13b0: 0x018b, 0x13b1: 0x018e, 0x13b2: 0x0191, 0x13b3: 0x0194, 0x13b4: 0x0197, 0x13b5: 0x019a, + 0x13b6: 0x019d, 0x13b7: 0x01a0, 0x13b8: 0x01a3, 0x13b9: 0x0188, 0x13ba: 0x01a6, 0x13bb: 0x01a9, + 0x13bc: 0x01ac, 0x13bd: 0x01af, 0x13be: 0x01b2, 0x13bf: 0x01b5, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x01fd, 0x13c1: 0x0200, 0x13c2: 0x0203, 0x13c3: 0x045b, 0x13c4: 0x01c7, 0x13c5: 0x01d0, + 0x13c6: 0x01d6, 0x13c7: 0x01fa, 0x13c8: 0x01eb, 0x13c9: 0x01e8, 0x13ca: 0x0206, 0x13cb: 0x0209, + 0x13ce: 0x0021, 0x13cf: 0x0023, 0x13d0: 0x0025, 0x13d1: 0x0027, + 0x13d2: 0x0029, 0x13d3: 0x002b, 0x13d4: 0x002d, 0x13d5: 0x002f, 0x13d6: 0x0031, 0x13d7: 0x0033, + 0x13d8: 0x0021, 0x13d9: 0x0023, 0x13da: 0x0025, 0x13db: 0x0027, 0x13dc: 0x0029, 0x13dd: 0x002b, + 0x13de: 0x002d, 0x13df: 0x002f, 0x13e0: 0x0031, 0x13e1: 0x0033, 0x13e2: 0x0021, 0x13e3: 0x0023, + 0x13e4: 0x0025, 0x13e5: 0x0027, 0x13e6: 0x0029, 0x13e7: 0x002b, 0x13e8: 0x002d, 0x13e9: 0x002f, + 0x13ea: 0x0031, 0x13eb: 0x0033, 0x13ec: 0x0021, 0x13ed: 0x0023, 0x13ee: 0x0025, 0x13ef: 0x0027, + 0x13f0: 0x0029, 0x13f1: 0x002b, 0x13f2: 0x002d, 0x13f3: 0x002f, 0x13f4: 0x0031, 0x13f5: 0x0033, + 0x13f6: 0x0021, 0x13f7: 0x0023, 0x13f8: 0x0025, 0x13f9: 0x0027, 0x13fa: 0x0029, 0x13fb: 0x002b, + 0x13fc: 0x002d, 0x13fd: 0x002f, 0x13fe: 0x0031, 0x13ff: 0x0033, + // Block 0x50, offset 0x1400 + 0x1400: 0x0239, 0x1401: 0x023c, 0x1402: 0x0248, 0x1403: 0x0251, 0x1405: 0x028a, + 0x1406: 0x025a, 0x1407: 0x024b, 0x1408: 0x0269, 0x1409: 0x0290, 0x140a: 0x027b, 0x140b: 0x027e, + 0x140c: 0x0281, 0x140d: 0x0284, 0x140e: 0x025d, 0x140f: 0x026f, 0x1410: 0x0275, 0x1411: 0x0263, + 0x1412: 0x0278, 0x1413: 0x0257, 0x1414: 0x0260, 0x1415: 0x0242, 0x1416: 0x0245, 0x1417: 0x024e, + 0x1418: 0x0254, 0x1419: 0x0266, 0x141a: 0x026c, 0x141b: 0x0272, 0x141c: 0x0293, 0x141d: 0x02e4, + 0x141e: 0x02cc, 0x141f: 0x0296, 0x1421: 0x023c, 0x1422: 0x0248, + 0x1424: 0x0287, 0x1427: 0x024b, 0x1429: 0x0290, + 0x142a: 0x027b, 0x142b: 0x027e, 0x142c: 0x0281, 0x142d: 0x0284, 0x142e: 0x025d, 0x142f: 0x026f, + 0x1430: 0x0275, 0x1431: 0x0263, 0x1432: 0x0278, 0x1434: 0x0260, 0x1435: 0x0242, + 0x1436: 0x0245, 0x1437: 0x024e, 0x1439: 0x0266, 0x143b: 0x0272, + // Block 0x51, offset 0x1440 + 0x1442: 0x0248, + 0x1447: 0x024b, 0x1449: 0x0290, 0x144b: 0x027e, + 0x144d: 0x0284, 0x144e: 0x025d, 0x144f: 0x026f, 0x1451: 0x0263, + 0x1452: 0x0278, 0x1454: 0x0260, 0x1457: 0x024e, + 0x1459: 0x0266, 0x145b: 0x0272, 0x145d: 0x02e4, + 0x145f: 0x0296, 0x1461: 0x023c, 0x1462: 0x0248, + 0x1464: 0x0287, 0x1467: 0x024b, 0x1468: 0x0269, 0x1469: 0x0290, + 0x146a: 0x027b, 0x146c: 0x0281, 0x146d: 0x0284, 0x146e: 0x025d, 0x146f: 0x026f, + 0x1470: 0x0275, 0x1471: 0x0263, 0x1472: 0x0278, 0x1474: 0x0260, 0x1475: 0x0242, + 0x1476: 0x0245, 0x1477: 0x024e, 0x1479: 0x0266, 0x147a: 0x026c, 0x147b: 0x0272, + 0x147c: 0x0293, 0x147e: 0x02cc, + // Block 0x52, offset 0x1480 + 0x1480: 0x0239, 0x1481: 0x023c, 0x1482: 0x0248, 0x1483: 0x0251, 0x1484: 0x0287, 0x1485: 0x028a, + 0x1486: 0x025a, 0x1487: 0x024b, 0x1488: 0x0269, 0x1489: 0x0290, 0x148b: 0x027e, + 0x148c: 0x0281, 0x148d: 0x0284, 0x148e: 0x025d, 0x148f: 0x026f, 0x1490: 0x0275, 0x1491: 0x0263, + 0x1492: 0x0278, 0x1493: 0x0257, 0x1494: 0x0260, 0x1495: 0x0242, 0x1496: 0x0245, 0x1497: 0x024e, + 0x1498: 0x0254, 0x1499: 0x0266, 0x149a: 0x026c, 0x149b: 0x0272, + 0x14a1: 0x023c, 0x14a2: 0x0248, 0x14a3: 0x0251, + 0x14a5: 0x028a, 0x14a6: 0x025a, 0x14a7: 0x024b, 0x14a8: 0x0269, 0x14a9: 0x0290, + 0x14ab: 0x027e, 0x14ac: 0x0281, 0x14ad: 0x0284, 0x14ae: 0x025d, 0x14af: 0x026f, + 0x14b0: 0x0275, 0x14b1: 0x0263, 0x14b2: 0x0278, 0x14b3: 0x0257, 0x14b4: 0x0260, 0x14b5: 0x0242, + 0x14b6: 0x0245, 0x14b7: 0x024e, 0x14b8: 0x0254, 0x14b9: 0x0266, 0x14ba: 0x026c, 0x14bb: 0x0272, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x1879, 0x14c1: 0x1876, 0x14c2: 0x187c, 0x14c3: 0x18a0, 0x14c4: 0x18c4, 0x14c5: 0x18e8, + 0x14c6: 0x190c, 0x14c7: 0x1915, 0x14c8: 0x191b, 0x14c9: 0x1921, 0x14ca: 0x1927, + 0x14d0: 0x1a8f, 0x14d1: 0x1a93, + 0x14d2: 0x1a97, 0x14d3: 0x1a9b, 0x14d4: 0x1a9f, 0x14d5: 0x1aa3, 0x14d6: 0x1aa7, 0x14d7: 0x1aab, + 0x14d8: 0x1aaf, 0x14d9: 0x1ab3, 0x14da: 0x1ab7, 0x14db: 0x1abb, 0x14dc: 0x1abf, 0x14dd: 0x1ac3, + 0x14de: 0x1ac7, 0x14df: 0x1acb, 0x14e0: 0x1acf, 0x14e1: 0x1ad3, 0x14e2: 0x1ad7, 0x14e3: 0x1adb, + 0x14e4: 0x1adf, 0x14e5: 0x1ae3, 0x14e6: 0x1ae7, 0x14e7: 0x1aeb, 0x14e8: 0x1aef, 0x14e9: 0x1af3, + 0x14ea: 0x2721, 0x14eb: 0x0047, 0x14ec: 0x0065, 0x14ed: 0x193c, 0x14ee: 0x19b4, + 0x14f0: 0x0043, 0x14f1: 0x0045, 0x14f2: 0x0047, 0x14f3: 0x0049, 0x14f4: 0x004b, 0x14f5: 0x004d, + 0x14f6: 0x004f, 0x14f7: 0x0051, 0x14f8: 0x0053, 0x14f9: 0x0055, 0x14fa: 0x0057, 0x14fb: 0x0059, + 0x14fc: 0x005b, 0x14fd: 0x005d, 0x14fe: 0x005f, 0x14ff: 0x0061, + // Block 0x54, offset 0x1500 + 0x1500: 0x26b0, 0x1501: 0x26c5, 0x1502: 0x0503, + 0x1510: 0x0c0f, 0x1511: 0x0a47, + 0x1512: 0x08d3, 0x1513: 0x45c7, 0x1514: 0x071b, 0x1515: 0x09ef, 0x1516: 0x132f, 0x1517: 0x09ff, + 0x1518: 0x0727, 0x1519: 0x0cd7, 0x151a: 0x0eaf, 0x151b: 0x0caf, 0x151c: 0x0827, 0x151d: 0x0b6b, + 0x151e: 0x07bf, 0x151f: 0x0cb7, 0x1520: 0x0813, 0x1521: 0x1117, 0x1522: 0x0f83, 0x1523: 0x138b, + 0x1524: 0x09d3, 0x1525: 0x090b, 0x1526: 0x0e63, 0x1527: 0x0c1b, 0x1528: 0x0c47, 0x1529: 0x06bf, + 0x152a: 0x06cb, 0x152b: 0x140b, 0x152c: 0x0adb, 0x152d: 0x06e7, 0x152e: 0x08ef, 0x152f: 0x0c3b, + 0x1530: 0x13b3, 0x1531: 0x0c13, 0x1532: 0x106f, 0x1533: 0x10ab, 0x1534: 0x08f7, 0x1535: 0x0e43, + 0x1536: 0x0d0b, 0x1537: 0x0d07, 0x1538: 0x0f97, 0x1539: 0x082b, 0x153a: 0x0957, 0x153b: 0x1443, + // Block 0x55, offset 0x1540 + 0x1540: 0x06fb, 0x1541: 0x06f3, 0x1542: 0x0703, 0x1543: 0x1647, 0x1544: 0x0747, 0x1545: 0x0757, + 0x1546: 0x075b, 0x1547: 0x0763, 0x1548: 0x076b, 0x1549: 0x076f, 0x154a: 0x077b, 0x154b: 0x0773, + 0x154c: 0x05b3, 0x154d: 0x165b, 0x154e: 0x078f, 0x154f: 0x0793, 0x1550: 0x0797, 0x1551: 0x07b3, + 0x1552: 0x164c, 0x1553: 0x05b7, 0x1554: 0x079f, 0x1555: 0x07bf, 0x1556: 0x1656, 0x1557: 0x07cf, + 0x1558: 0x07d7, 0x1559: 0x0737, 0x155a: 0x07df, 0x155b: 0x07e3, 0x155c: 0x1831, 0x155d: 0x07ff, + 0x155e: 0x0807, 0x155f: 0x05bf, 0x1560: 0x081f, 0x1561: 0x0823, 0x1562: 0x082b, 0x1563: 0x082f, + 0x1564: 0x05c3, 0x1565: 0x0847, 0x1566: 0x084b, 0x1567: 0x0857, 0x1568: 0x0863, 0x1569: 0x0867, + 0x156a: 0x086b, 0x156b: 0x0873, 0x156c: 0x0893, 0x156d: 0x0897, 0x156e: 0x089f, 0x156f: 0x08af, + 0x1570: 0x08b7, 0x1571: 0x08bb, 0x1572: 0x08bb, 0x1573: 0x08bb, 0x1574: 0x166a, 0x1575: 0x0e93, + 0x1576: 0x08cf, 0x1577: 0x08d7, 0x1578: 0x166f, 0x1579: 0x08e3, 0x157a: 0x08eb, 0x157b: 0x08f3, + 0x157c: 0x091b, 0x157d: 0x0907, 0x157e: 0x0913, 0x157f: 0x0917, + // Block 0x56, offset 0x1580 + 0x1580: 0x091f, 0x1581: 0x0927, 0x1582: 0x092b, 0x1583: 0x0933, 0x1584: 0x093b, 0x1585: 0x093f, + 0x1586: 0x093f, 0x1587: 0x0947, 0x1588: 0x094f, 0x1589: 0x0953, 0x158a: 0x095f, 0x158b: 0x0983, + 0x158c: 0x0967, 0x158d: 0x0987, 0x158e: 0x096b, 0x158f: 0x0973, 0x1590: 0x080b, 0x1591: 0x09cf, + 0x1592: 0x0997, 0x1593: 0x099b, 0x1594: 0x099f, 0x1595: 0x0993, 0x1596: 0x09a7, 0x1597: 0x09a3, + 0x1598: 0x09bb, 0x1599: 0x1674, 0x159a: 0x09d7, 0x159b: 0x09db, 0x159c: 0x09e3, 0x159d: 0x09ef, + 0x159e: 0x09f7, 0x159f: 0x0a13, 0x15a0: 0x1679, 0x15a1: 0x167e, 0x15a2: 0x0a1f, 0x15a3: 0x0a23, + 0x15a4: 0x0a27, 0x15a5: 0x0a1b, 0x15a6: 0x0a2f, 0x15a7: 0x05c7, 0x15a8: 0x05cb, 0x15a9: 0x0a37, + 0x15aa: 0x0a3f, 0x15ab: 0x0a3f, 0x15ac: 0x1683, 0x15ad: 0x0a5b, 0x15ae: 0x0a5f, 0x15af: 0x0a63, + 0x15b0: 0x0a6b, 0x15b1: 0x1688, 0x15b2: 0x0a73, 0x15b3: 0x0a77, 0x15b4: 0x0b4f, 0x15b5: 0x0a7f, + 0x15b6: 0x05cf, 0x15b7: 0x0a8b, 0x15b8: 0x0a9b, 0x15b9: 0x0aa7, 0x15ba: 0x0aa3, 0x15bb: 0x1692, + 0x15bc: 0x0aaf, 0x15bd: 0x1697, 0x15be: 0x0abb, 0x15bf: 0x0ab7, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x0abf, 0x15c1: 0x0acf, 0x15c2: 0x0ad3, 0x15c3: 0x05d3, 0x15c4: 0x0ae3, 0x15c5: 0x0aeb, + 0x15c6: 0x0aef, 0x15c7: 0x0af3, 0x15c8: 0x05d7, 0x15c9: 0x169c, 0x15ca: 0x05db, 0x15cb: 0x0b0f, + 0x15cc: 0x0b13, 0x15cd: 0x0b17, 0x15ce: 0x0b1f, 0x15cf: 0x1863, 0x15d0: 0x0b37, 0x15d1: 0x16a6, + 0x15d2: 0x16a6, 0x15d3: 0x11d7, 0x15d4: 0x0b47, 0x15d5: 0x0b47, 0x15d6: 0x05df, 0x15d7: 0x16c9, + 0x15d8: 0x179b, 0x15d9: 0x0b57, 0x15da: 0x0b5f, 0x15db: 0x05e3, 0x15dc: 0x0b73, 0x15dd: 0x0b83, + 0x15de: 0x0b87, 0x15df: 0x0b8f, 0x15e0: 0x0b9f, 0x15e1: 0x05eb, 0x15e2: 0x05e7, 0x15e3: 0x0ba3, + 0x15e4: 0x16ab, 0x15e5: 0x0ba7, 0x15e6: 0x0bbb, 0x15e7: 0x0bbf, 0x15e8: 0x0bc3, 0x15e9: 0x0bbf, + 0x15ea: 0x0bcf, 0x15eb: 0x0bd3, 0x15ec: 0x0be3, 0x15ed: 0x0bdb, 0x15ee: 0x0bdf, 0x15ef: 0x0be7, + 0x15f0: 0x0beb, 0x15f1: 0x0bef, 0x15f2: 0x0bfb, 0x15f3: 0x0bff, 0x15f4: 0x0c17, 0x15f5: 0x0c1f, + 0x15f6: 0x0c2f, 0x15f7: 0x0c43, 0x15f8: 0x16ba, 0x15f9: 0x0c3f, 0x15fa: 0x0c33, 0x15fb: 0x0c4b, + 0x15fc: 0x0c53, 0x15fd: 0x0c67, 0x15fe: 0x16bf, 0x15ff: 0x0c6f, + // Block 0x58, offset 0x1600 + 0x1600: 0x0c63, 0x1601: 0x0c5b, 0x1602: 0x05ef, 0x1603: 0x0c77, 0x1604: 0x0c7f, 0x1605: 0x0c87, + 0x1606: 0x0c7b, 0x1607: 0x05f3, 0x1608: 0x0c97, 0x1609: 0x0c9f, 0x160a: 0x16c4, 0x160b: 0x0ccb, + 0x160c: 0x0cff, 0x160d: 0x0cdb, 0x160e: 0x05ff, 0x160f: 0x0ce7, 0x1610: 0x05fb, 0x1611: 0x05f7, + 0x1612: 0x07c3, 0x1613: 0x07c7, 0x1614: 0x0d03, 0x1615: 0x0ceb, 0x1616: 0x11ab, 0x1617: 0x0663, + 0x1618: 0x0d0f, 0x1619: 0x0d13, 0x161a: 0x0d17, 0x161b: 0x0d2b, 0x161c: 0x0d23, 0x161d: 0x16dd, + 0x161e: 0x0603, 0x161f: 0x0d3f, 0x1620: 0x0d33, 0x1621: 0x0d4f, 0x1622: 0x0d57, 0x1623: 0x16e7, + 0x1624: 0x0d5b, 0x1625: 0x0d47, 0x1626: 0x0d63, 0x1627: 0x0607, 0x1628: 0x0d67, 0x1629: 0x0d6b, + 0x162a: 0x0d6f, 0x162b: 0x0d7b, 0x162c: 0x16ec, 0x162d: 0x0d83, 0x162e: 0x060b, 0x162f: 0x0d8f, + 0x1630: 0x16f1, 0x1631: 0x0d93, 0x1632: 0x060f, 0x1633: 0x0d9f, 0x1634: 0x0dab, 0x1635: 0x0db7, + 0x1636: 0x0dbb, 0x1637: 0x16f6, 0x1638: 0x168d, 0x1639: 0x16fb, 0x163a: 0x0ddb, 0x163b: 0x1700, + 0x163c: 0x0de7, 0x163d: 0x0def, 0x163e: 0x0ddf, 0x163f: 0x0dfb, + // Block 0x59, offset 0x1640 + 0x1640: 0x0e0b, 0x1641: 0x0e1b, 0x1642: 0x0e0f, 0x1643: 0x0e13, 0x1644: 0x0e1f, 0x1645: 0x0e23, + 0x1646: 0x1705, 0x1647: 0x0e07, 0x1648: 0x0e3b, 0x1649: 0x0e3f, 0x164a: 0x0613, 0x164b: 0x0e53, + 0x164c: 0x0e4f, 0x164d: 0x170a, 0x164e: 0x0e33, 0x164f: 0x0e6f, 0x1650: 0x170f, 0x1651: 0x1714, + 0x1652: 0x0e73, 0x1653: 0x0e87, 0x1654: 0x0e83, 0x1655: 0x0e7f, 0x1656: 0x0617, 0x1657: 0x0e8b, + 0x1658: 0x0e9b, 0x1659: 0x0e97, 0x165a: 0x0ea3, 0x165b: 0x1651, 0x165c: 0x0eb3, 0x165d: 0x1719, + 0x165e: 0x0ebf, 0x165f: 0x1723, 0x1660: 0x0ed3, 0x1661: 0x0edf, 0x1662: 0x0ef3, 0x1663: 0x1728, + 0x1664: 0x0f07, 0x1665: 0x0f0b, 0x1666: 0x172d, 0x1667: 0x1732, 0x1668: 0x0f27, 0x1669: 0x0f37, + 0x166a: 0x061b, 0x166b: 0x0f3b, 0x166c: 0x061f, 0x166d: 0x061f, 0x166e: 0x0f53, 0x166f: 0x0f57, + 0x1670: 0x0f5f, 0x1671: 0x0f63, 0x1672: 0x0f6f, 0x1673: 0x0623, 0x1674: 0x0f87, 0x1675: 0x1737, + 0x1676: 0x0fa3, 0x1677: 0x173c, 0x1678: 0x0faf, 0x1679: 0x16a1, 0x167a: 0x0fbf, 0x167b: 0x1741, + 0x167c: 0x1746, 0x167d: 0x174b, 0x167e: 0x0627, 0x167f: 0x062b, + // Block 0x5a, offset 0x1680 + 0x1680: 0x0ff7, 0x1681: 0x1755, 0x1682: 0x1750, 0x1683: 0x175a, 0x1684: 0x175f, 0x1685: 0x0fff, + 0x1686: 0x1003, 0x1687: 0x1003, 0x1688: 0x100b, 0x1689: 0x0633, 0x168a: 0x100f, 0x168b: 0x0637, + 0x168c: 0x063b, 0x168d: 0x1769, 0x168e: 0x1023, 0x168f: 0x102b, 0x1690: 0x1037, 0x1691: 0x063f, + 0x1692: 0x176e, 0x1693: 0x105b, 0x1694: 0x1773, 0x1695: 0x1778, 0x1696: 0x107b, 0x1697: 0x1093, + 0x1698: 0x0643, 0x1699: 0x109b, 0x169a: 0x109f, 0x169b: 0x10a3, 0x169c: 0x177d, 0x169d: 0x1782, + 0x169e: 0x1782, 0x169f: 0x10bb, 0x16a0: 0x0647, 0x16a1: 0x1787, 0x16a2: 0x10cf, 0x16a3: 0x10d3, + 0x16a4: 0x064b, 0x16a5: 0x178c, 0x16a6: 0x10ef, 0x16a7: 0x064f, 0x16a8: 0x10ff, 0x16a9: 0x10f7, + 0x16aa: 0x1107, 0x16ab: 0x1796, 0x16ac: 0x111f, 0x16ad: 0x0653, 0x16ae: 0x112b, 0x16af: 0x1133, + 0x16b0: 0x1143, 0x16b1: 0x0657, 0x16b2: 0x17a0, 0x16b3: 0x17a5, 0x16b4: 0x065b, 0x16b5: 0x17aa, + 0x16b6: 0x115b, 0x16b7: 0x17af, 0x16b8: 0x1167, 0x16b9: 0x1173, 0x16ba: 0x117b, 0x16bb: 0x17b4, + 0x16bc: 0x17b9, 0x16bd: 0x118f, 0x16be: 0x17be, 0x16bf: 0x1197, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x16ce, 0x16c1: 0x065f, 0x16c2: 0x11af, 0x16c3: 0x11b3, 0x16c4: 0x0667, 0x16c5: 0x11b7, + 0x16c6: 0x0a33, 0x16c7: 0x17c3, 0x16c8: 0x17c8, 0x16c9: 0x16d3, 0x16ca: 0x16d8, 0x16cb: 0x11d7, + 0x16cc: 0x11db, 0x16cd: 0x13f3, 0x16ce: 0x066b, 0x16cf: 0x1207, 0x16d0: 0x1203, 0x16d1: 0x120b, + 0x16d2: 0x083f, 0x16d3: 0x120f, 0x16d4: 0x1213, 0x16d5: 0x1217, 0x16d6: 0x121f, 0x16d7: 0x17cd, + 0x16d8: 0x121b, 0x16d9: 0x1223, 0x16da: 0x1237, 0x16db: 0x123b, 0x16dc: 0x1227, 0x16dd: 0x123f, + 0x16de: 0x1253, 0x16df: 0x1267, 0x16e0: 0x1233, 0x16e1: 0x1247, 0x16e2: 0x124b, 0x16e3: 0x124f, + 0x16e4: 0x17d2, 0x16e5: 0x17dc, 0x16e6: 0x17d7, 0x16e7: 0x066f, 0x16e8: 0x126f, 0x16e9: 0x1273, + 0x16ea: 0x127b, 0x16eb: 0x17f0, 0x16ec: 0x127f, 0x16ed: 0x17e1, 0x16ee: 0x0673, 0x16ef: 0x0677, + 0x16f0: 0x17e6, 0x16f1: 0x17eb, 0x16f2: 0x067b, 0x16f3: 0x129f, 0x16f4: 0x12a3, 0x16f5: 0x12a7, + 0x16f6: 0x12ab, 0x16f7: 0x12b7, 0x16f8: 0x12b3, 0x16f9: 0x12bf, 0x16fa: 0x12bb, 0x16fb: 0x12cb, + 0x16fc: 0x12c3, 0x16fd: 0x12c7, 0x16fe: 0x12cf, 0x16ff: 0x067f, + // Block 0x5c, offset 0x1700 + 0x1700: 0x12d7, 0x1701: 0x12db, 0x1702: 0x0683, 0x1703: 0x12eb, 0x1704: 0x12ef, 0x1705: 0x17f5, + 0x1706: 0x12fb, 0x1707: 0x12ff, 0x1708: 0x0687, 0x1709: 0x130b, 0x170a: 0x05bb, 0x170b: 0x17fa, + 0x170c: 0x17ff, 0x170d: 0x068b, 0x170e: 0x068f, 0x170f: 0x1337, 0x1710: 0x134f, 0x1711: 0x136b, + 0x1712: 0x137b, 0x1713: 0x1804, 0x1714: 0x138f, 0x1715: 0x1393, 0x1716: 0x13ab, 0x1717: 0x13b7, + 0x1718: 0x180e, 0x1719: 0x1660, 0x171a: 0x13c3, 0x171b: 0x13bf, 0x171c: 0x13cb, 0x171d: 0x1665, + 0x171e: 0x13d7, 0x171f: 0x13e3, 0x1720: 0x1813, 0x1721: 0x1818, 0x1722: 0x1423, 0x1723: 0x142f, + 0x1724: 0x1437, 0x1725: 0x181d, 0x1726: 0x143b, 0x1727: 0x1467, 0x1728: 0x1473, 0x1729: 0x1477, + 0x172a: 0x146f, 0x172b: 0x1483, 0x172c: 0x1487, 0x172d: 0x1822, 0x172e: 0x1493, 0x172f: 0x0693, + 0x1730: 0x149b, 0x1731: 0x1827, 0x1732: 0x0697, 0x1733: 0x14d3, 0x1734: 0x0ac3, 0x1735: 0x14eb, + 0x1736: 0x182c, 0x1737: 0x1836, 0x1738: 0x069b, 0x1739: 0x069f, 0x173a: 0x1513, 0x173b: 0x183b, + 0x173c: 0x06a3, 0x173d: 0x1840, 0x173e: 0x152b, 0x173f: 0x152b, + // Block 0x5d, offset 0x1740 + 0x1740: 0x1533, 0x1741: 0x1845, 0x1742: 0x154b, 0x1743: 0x06a7, 0x1744: 0x155b, 0x1745: 0x1567, + 0x1746: 0x156f, 0x1747: 0x1577, 0x1748: 0x06ab, 0x1749: 0x184a, 0x174a: 0x158b, 0x174b: 0x15a7, + 0x174c: 0x15b3, 0x174d: 0x06af, 0x174e: 0x06b3, 0x174f: 0x15b7, 0x1750: 0x184f, 0x1751: 0x06b7, + 0x1752: 0x1854, 0x1753: 0x1859, 0x1754: 0x185e, 0x1755: 0x15db, 0x1756: 0x06bb, 0x1757: 0x15ef, + 0x1758: 0x15f7, 0x1759: 0x15fb, 0x175a: 0x1603, 0x175b: 0x160b, 0x175c: 0x1613, 0x175d: 0x1868, +} + +// nfkcIndex: 22 blocks, 1408 entries, 2816 bytes +// Block 0 is the zero block. +var nfkcIndex = [1408]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x5c, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5d, 0xc7: 0x04, + 0xc8: 0x05, 0xca: 0x5e, 0xcb: 0x5f, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09, + 0xd0: 0x0a, 0xd1: 0x60, 0xd2: 0x61, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x62, + 0xd8: 0x63, 0xd9: 0x0d, 0xdb: 0x64, 0xdc: 0x65, 0xdd: 0x66, 0xdf: 0x67, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, + 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a, + 0xf0: 0x13, + // Block 0x4, offset 0x100 + 0x120: 0x68, 0x121: 0x69, 0x123: 0x0e, 0x124: 0x6a, 0x125: 0x6b, 0x126: 0x6c, 0x127: 0x6d, + 0x128: 0x6e, 0x129: 0x6f, 0x12a: 0x70, 0x12b: 0x71, 0x12c: 0x6c, 0x12d: 0x72, 0x12e: 0x73, 0x12f: 0x74, + 0x131: 0x75, 0x132: 0x76, 0x133: 0x77, 0x134: 0x78, 0x135: 0x79, 0x137: 0x7a, + 0x138: 0x7b, 0x139: 0x7c, 0x13a: 0x7d, 0x13b: 0x7e, 0x13c: 0x7f, 0x13d: 0x80, 0x13e: 0x81, 0x13f: 0x82, + // Block 0x5, offset 0x140 + 0x140: 0x83, 0x142: 0x84, 0x143: 0x85, 0x144: 0x86, 0x145: 0x87, 0x146: 0x88, 0x147: 0x89, + 0x14d: 0x8a, + 0x15c: 0x8b, 0x15f: 0x8c, + 0x162: 0x8d, 0x164: 0x8e, + 0x168: 0x8f, 0x169: 0x90, 0x16a: 0x91, 0x16c: 0x0f, 0x16d: 0x92, 0x16e: 0x93, 0x16f: 0x94, + 0x170: 0x95, 0x173: 0x96, 0x174: 0x97, 0x175: 0x10, 0x176: 0x11, 0x177: 0x12, + 0x178: 0x13, 0x179: 0x14, 0x17a: 0x15, 0x17b: 0x16, 0x17c: 0x17, 0x17d: 0x18, 0x17e: 0x19, 0x17f: 0x1a, + // Block 0x6, offset 0x180 + 0x180: 0x98, 0x181: 0x99, 0x182: 0x9a, 0x183: 0x9b, 0x184: 0x1b, 0x185: 0x1c, 0x186: 0x9c, 0x187: 0x9d, + 0x188: 0x9e, 0x189: 0x1d, 0x18a: 0x1e, 0x18b: 0x9f, 0x18c: 0xa0, + 0x191: 0x1f, 0x192: 0x20, 0x193: 0xa1, + 0x1a8: 0xa2, 0x1a9: 0xa3, 0x1ab: 0xa4, + 0x1b1: 0xa5, 0x1b3: 0xa6, 0x1b5: 0xa7, 0x1b7: 0xa8, + 0x1ba: 0xa9, 0x1bb: 0xaa, 0x1bc: 0x21, 0x1bd: 0x22, 0x1be: 0x23, 0x1bf: 0xab, + // Block 0x7, offset 0x1c0 + 0x1c0: 0xac, 0x1c1: 0x24, 0x1c2: 0x25, 0x1c3: 0x26, 0x1c4: 0xad, 0x1c5: 0x27, 0x1c6: 0x28, + 0x1c8: 0x29, 0x1c9: 0x2a, 0x1ca: 0x2b, 0x1cb: 0x2c, 0x1cc: 0x2d, 0x1cd: 0x2e, 0x1ce: 0x2f, 0x1cf: 0x30, + // Block 0x8, offset 0x200 + 0x219: 0xae, 0x21a: 0xaf, 0x21b: 0xb0, 0x21d: 0xb1, 0x21f: 0xb2, + 0x220: 0xb3, 0x223: 0xb4, 0x224: 0xb5, 0x225: 0xb6, 0x226: 0xb7, 0x227: 0xb8, + 0x22a: 0xb9, 0x22b: 0xba, 0x22d: 0xbb, 0x22f: 0xbc, + 0x230: 0xbd, 0x231: 0xbe, 0x232: 0xbf, 0x233: 0xc0, 0x234: 0xc1, 0x235: 0xc2, 0x236: 0xc3, 0x237: 0xbd, + 0x238: 0xbe, 0x239: 0xbf, 0x23a: 0xc0, 0x23b: 0xc1, 0x23c: 0xc2, 0x23d: 0xc3, 0x23e: 0xbd, 0x23f: 0xbe, + // Block 0x9, offset 0x240 + 0x240: 0xbf, 0x241: 0xc0, 0x242: 0xc1, 0x243: 0xc2, 0x244: 0xc3, 0x245: 0xbd, 0x246: 0xbe, 0x247: 0xbf, + 0x248: 0xc0, 0x249: 0xc1, 0x24a: 0xc2, 0x24b: 0xc3, 0x24c: 0xbd, 0x24d: 0xbe, 0x24e: 0xbf, 0x24f: 0xc0, + 0x250: 0xc1, 0x251: 0xc2, 0x252: 0xc3, 0x253: 0xbd, 0x254: 0xbe, 0x255: 0xbf, 0x256: 0xc0, 0x257: 0xc1, + 0x258: 0xc2, 0x259: 0xc3, 0x25a: 0xbd, 0x25b: 0xbe, 0x25c: 0xbf, 0x25d: 0xc0, 0x25e: 0xc1, 0x25f: 0xc2, + 0x260: 0xc3, 0x261: 0xbd, 0x262: 0xbe, 0x263: 0xbf, 0x264: 0xc0, 0x265: 0xc1, 0x266: 0xc2, 0x267: 0xc3, + 0x268: 0xbd, 0x269: 0xbe, 0x26a: 0xbf, 0x26b: 0xc0, 0x26c: 0xc1, 0x26d: 0xc2, 0x26e: 0xc3, 0x26f: 0xbd, + 0x270: 0xbe, 0x271: 0xbf, 0x272: 0xc0, 0x273: 0xc1, 0x274: 0xc2, 0x275: 0xc3, 0x276: 0xbd, 0x277: 0xbe, + 0x278: 0xbf, 0x279: 0xc0, 0x27a: 0xc1, 0x27b: 0xc2, 0x27c: 0xc3, 0x27d: 0xbd, 0x27e: 0xbe, 0x27f: 0xbf, + // Block 0xa, offset 0x280 + 0x280: 0xc0, 0x281: 0xc1, 0x282: 0xc2, 0x283: 0xc3, 0x284: 0xbd, 0x285: 0xbe, 0x286: 0xbf, 0x287: 0xc0, + 0x288: 0xc1, 0x289: 0xc2, 0x28a: 0xc3, 0x28b: 0xbd, 0x28c: 0xbe, 0x28d: 0xbf, 0x28e: 0xc0, 0x28f: 0xc1, + 0x290: 0xc2, 0x291: 0xc3, 0x292: 0xbd, 0x293: 0xbe, 0x294: 0xbf, 0x295: 0xc0, 0x296: 0xc1, 0x297: 0xc2, + 0x298: 0xc3, 0x299: 0xbd, 0x29a: 0xbe, 0x29b: 0xbf, 0x29c: 0xc0, 0x29d: 0xc1, 0x29e: 0xc2, 0x29f: 0xc3, + 0x2a0: 0xbd, 0x2a1: 0xbe, 0x2a2: 0xbf, 0x2a3: 0xc0, 0x2a4: 0xc1, 0x2a5: 0xc2, 0x2a6: 0xc3, 0x2a7: 0xbd, + 0x2a8: 0xbe, 0x2a9: 0xbf, 0x2aa: 0xc0, 0x2ab: 0xc1, 0x2ac: 0xc2, 0x2ad: 0xc3, 0x2ae: 0xbd, 0x2af: 0xbe, + 0x2b0: 0xbf, 0x2b1: 0xc0, 0x2b2: 0xc1, 0x2b3: 0xc2, 0x2b4: 0xc3, 0x2b5: 0xbd, 0x2b6: 0xbe, 0x2b7: 0xbf, + 0x2b8: 0xc0, 0x2b9: 0xc1, 0x2ba: 0xc2, 0x2bb: 0xc3, 0x2bc: 0xbd, 0x2bd: 0xbe, 0x2be: 0xbf, 0x2bf: 0xc0, + // Block 0xb, offset 0x2c0 + 0x2c0: 0xc1, 0x2c1: 0xc2, 0x2c2: 0xc3, 0x2c3: 0xbd, 0x2c4: 0xbe, 0x2c5: 0xbf, 0x2c6: 0xc0, 0x2c7: 0xc1, + 0x2c8: 0xc2, 0x2c9: 0xc3, 0x2ca: 0xbd, 0x2cb: 0xbe, 0x2cc: 0xbf, 0x2cd: 0xc0, 0x2ce: 0xc1, 0x2cf: 0xc2, + 0x2d0: 0xc3, 0x2d1: 0xbd, 0x2d2: 0xbe, 0x2d3: 0xbf, 0x2d4: 0xc0, 0x2d5: 0xc1, 0x2d6: 0xc2, 0x2d7: 0xc3, + 0x2d8: 0xbd, 0x2d9: 0xbe, 0x2da: 0xbf, 0x2db: 0xc0, 0x2dc: 0xc1, 0x2dd: 0xc2, 0x2de: 0xc4, + // Block 0xc, offset 0x300 + 0x324: 0x31, 0x325: 0x32, 0x326: 0x33, 0x327: 0x34, + 0x328: 0x35, 0x329: 0x36, 0x32a: 0x37, 0x32b: 0x38, 0x32c: 0x39, 0x32d: 0x3a, 0x32e: 0x3b, 0x32f: 0x3c, + 0x330: 0x3d, 0x331: 0x3e, 0x332: 0x3f, 0x333: 0x40, 0x334: 0x41, 0x335: 0x42, 0x336: 0x43, 0x337: 0x44, + 0x338: 0x45, 0x339: 0x46, 0x33a: 0x47, 0x33b: 0x48, 0x33c: 0xc5, 0x33d: 0x49, 0x33e: 0x4a, 0x33f: 0x4b, + // Block 0xd, offset 0x340 + 0x347: 0xc6, + 0x34b: 0xc7, 0x34d: 0xc8, + 0x368: 0xc9, 0x36b: 0xca, + 0x374: 0xcb, + 0x37d: 0xcc, + // Block 0xe, offset 0x380 + 0x381: 0xcd, 0x382: 0xce, 0x384: 0xcf, 0x385: 0xb7, 0x387: 0xd0, + 0x388: 0xd1, 0x38b: 0xd2, 0x38c: 0xd3, 0x38d: 0xd4, + 0x391: 0xd5, 0x392: 0xd6, 0x393: 0xd7, 0x396: 0xd8, 0x397: 0xd9, + 0x398: 0xda, 0x39a: 0xdb, 0x39c: 0xdc, + 0x3a0: 0xdd, 0x3a7: 0xde, + 0x3a8: 0xdf, 0x3a9: 0xe0, 0x3aa: 0xe1, + 0x3b0: 0xda, 0x3b5: 0xe2, 0x3b6: 0xe3, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xe4, 0x3ec: 0xe5, + // Block 0x10, offset 0x400 + 0x432: 0xe6, + // Block 0x11, offset 0x440 + 0x445: 0xe7, 0x446: 0xe8, 0x447: 0xe9, + 0x449: 0xea, + 0x450: 0xeb, 0x451: 0xec, 0x452: 0xed, 0x453: 0xee, 0x454: 0xef, 0x455: 0xf0, 0x456: 0xf1, 0x457: 0xf2, + 0x458: 0xf3, 0x459: 0xf4, 0x45a: 0x4c, 0x45b: 0xf5, 0x45c: 0xf6, 0x45d: 0xf7, 0x45e: 0xf8, 0x45f: 0x4d, + // Block 0x12, offset 0x480 + 0x480: 0xf9, 0x484: 0xe5, + 0x48b: 0xfa, + 0x4a3: 0xfb, 0x4a5: 0xfc, + 0x4b8: 0x4e, 0x4b9: 0x4f, 0x4ba: 0x50, + // Block 0x13, offset 0x4c0 + 0x4c4: 0x51, 0x4c5: 0xfd, 0x4c6: 0xfe, + 0x4c8: 0x52, 0x4c9: 0xff, + // Block 0x14, offset 0x500 + 0x520: 0x53, 0x521: 0x54, 0x522: 0x55, 0x523: 0x56, 0x524: 0x57, 0x525: 0x58, 0x526: 0x59, 0x527: 0x5a, + 0x528: 0x5b, + // Block 0x15, offset 0x540 + 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d, + 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11, + 0x56f: 0x12, +} + +// nfkcSparseOffset: 164 entries, 328 bytes +var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x70, 0x75, 0x77, 0x7f, 0x86, 0x89, 0x91, 0x95, 0x99, 0x9b, 0x9d, 0xa6, 0xaa, 0xb1, 0xb6, 0xb9, 0xc3, 0xc6, 0xcd, 0xd5, 0xd9, 0xdb, 0xdf, 0xe3, 0xe9, 0xfa, 0x106, 0x108, 0x10e, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11f, 0x122, 0x124, 0x127, 0x12a, 0x12e, 0x133, 0x13c, 0x13e, 0x141, 0x143, 0x14e, 0x159, 0x167, 0x175, 0x185, 0x193, 0x19a, 0x1a0, 0x1af, 0x1b3, 0x1b5, 0x1b9, 0x1bb, 0x1be, 0x1c0, 0x1c3, 0x1c5, 0x1c8, 0x1ca, 0x1cc, 0x1ce, 0x1da, 0x1e4, 0x1ee, 0x1f1, 0x1f5, 0x1f7, 0x1f9, 0x1fb, 0x1fd, 0x200, 0x202, 0x204, 0x206, 0x208, 0x20e, 0x211, 0x215, 0x217, 0x21e, 0x224, 0x22a, 0x232, 0x238, 0x23e, 0x244, 0x248, 0x24a, 0x24c, 0x24e, 0x250, 0x256, 0x259, 0x25b, 0x261, 0x264, 0x26c, 0x273, 0x276, 0x279, 0x27b, 0x27e, 0x286, 0x28a, 0x291, 0x294, 0x29a, 0x29c, 0x29e, 0x2a1, 0x2a3, 0x2a6, 0x2a8, 0x2aa, 0x2ac, 0x2ae, 0x2b1, 0x2b3, 0x2b5, 0x2b7, 0x2b9, 0x2c6, 0x2d0, 0x2d2, 0x2d4, 0x2d8, 0x2dd, 0x2e9, 0x2ee, 0x2f7, 0x2fd, 0x302, 0x306, 0x30b, 0x30f, 0x31f, 0x32d, 0x33b, 0x349, 0x34f, 0x351, 0x353, 0x356, 0x361, 0x363} + +// nfkcSparseValues: 877 entries, 3508 bytes +var nfkcSparseValues = [877]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0002, lo: 0x0d}, + {value: 0x0001, lo: 0xa0, hi: 0xa0}, + {value: 0x427b, lo: 0xa8, hi: 0xa8}, + {value: 0x0083, lo: 0xaa, hi: 0xaa}, + {value: 0x4267, lo: 0xaf, hi: 0xaf}, + {value: 0x0025, lo: 0xb2, hi: 0xb3}, + {value: 0x425d, lo: 0xb4, hi: 0xb4}, + {value: 0x01dc, lo: 0xb5, hi: 0xb5}, + {value: 0x4294, lo: 0xb8, hi: 0xb8}, + {value: 0x0023, lo: 0xb9, hi: 0xb9}, + {value: 0x009f, lo: 0xba, hi: 0xba}, + {value: 0x221f, lo: 0xbc, hi: 0xbc}, + {value: 0x2213, lo: 0xbd, hi: 0xbd}, + {value: 0x22b5, lo: 0xbe, hi: 0xbe}, + // Block 0x1, offset 0xe + {value: 0x0091, lo: 0x03}, + {value: 0x46e5, lo: 0xa0, hi: 0xa1}, + {value: 0x4717, lo: 0xaf, hi: 0xb0}, + {value: 0xa000, lo: 0xb7, hi: 0xb7}, + // Block 0x2, offset 0x12 + {value: 0x0003, lo: 0x08}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x0091, lo: 0xb0, hi: 0xb0}, + {value: 0x0119, lo: 0xb1, hi: 0xb1}, + {value: 0x0095, lo: 0xb2, hi: 0xb2}, + {value: 0x00a5, lo: 0xb3, hi: 0xb3}, + {value: 0x0143, lo: 0xb4, hi: 0xb6}, + {value: 0x00af, lo: 0xb7, hi: 0xb7}, + {value: 0x00b3, lo: 0xb8, hi: 0xb8}, + // Block 0x3, offset 0x1b + {value: 0x000a, lo: 0x09}, + {value: 0x4271, lo: 0x98, hi: 0x98}, + {value: 0x4276, lo: 0x99, hi: 0x9a}, + {value: 0x4299, lo: 0x9b, hi: 0x9b}, + {value: 0x4262, lo: 0x9c, hi: 0x9c}, + {value: 0x4285, lo: 0x9d, hi: 0x9d}, + {value: 0x0113, lo: 0xa0, hi: 0xa0}, + {value: 0x0099, lo: 0xa1, hi: 0xa1}, + {value: 0x00a7, lo: 0xa2, hi: 0xa3}, + {value: 0x0167, lo: 0xa4, hi: 0xa4}, + // Block 0x4, offset 0x25 + {value: 0x0000, lo: 0x0f}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0xa000, lo: 0x8d, hi: 0x8d}, + {value: 0x37a8, lo: 0x90, hi: 0x90}, + {value: 0x37b4, lo: 0x91, hi: 0x91}, + {value: 0x37a2, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x381a, lo: 0x97, hi: 0x97}, + {value: 0x37e4, lo: 0x9c, hi: 0x9c}, + {value: 0x37cc, lo: 0x9d, hi: 0x9d}, + {value: 0x37f6, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x3820, lo: 0xb6, hi: 0xb6}, + {value: 0x3826, lo: 0xb7, hi: 0xb7}, + // Block 0x5, offset 0x35 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x83, hi: 0x87}, + // Block 0x6, offset 0x37 + {value: 0x0001, lo: 0x04}, + {value: 0x8113, lo: 0x81, hi: 0x82}, + {value: 0x8132, lo: 0x84, hi: 0x84}, + {value: 0x812d, lo: 0x85, hi: 0x85}, + {value: 0x810d, lo: 0x87, hi: 0x87}, + // Block 0x7, offset 0x3c + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x97}, + {value: 0x8119, lo: 0x98, hi: 0x98}, + {value: 0x811a, lo: 0x99, hi: 0x99}, + {value: 0x811b, lo: 0x9a, hi: 0x9a}, + {value: 0x3844, lo: 0xa2, hi: 0xa2}, + {value: 0x384a, lo: 0xa3, hi: 0xa3}, + {value: 0x3856, lo: 0xa4, hi: 0xa4}, + {value: 0x3850, lo: 0xa5, hi: 0xa5}, + {value: 0x385c, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x8, offset 0x47 + {value: 0x0000, lo: 0x0e}, + {value: 0x386e, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x3862, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3868, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8132, lo: 0x96, hi: 0x9c}, + {value: 0x8132, lo: 0x9f, hi: 0xa2}, + {value: 0x812d, lo: 0xa3, hi: 0xa3}, + {value: 0x8132, lo: 0xa4, hi: 0xa4}, + {value: 0x8132, lo: 0xa7, hi: 0xa8}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xac}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + // Block 0x9, offset 0x56 + {value: 0x0000, lo: 0x0c}, + {value: 0x811f, lo: 0x91, hi: 0x91}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x812d, lo: 0xb1, hi: 0xb1}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb5, hi: 0xb6}, + {value: 0x812d, lo: 0xb7, hi: 0xb9}, + {value: 0x8132, lo: 0xba, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbc}, + {value: 0x8132, lo: 0xbd, hi: 0xbd}, + {value: 0x812d, lo: 0xbe, hi: 0xbe}, + {value: 0x8132, lo: 0xbf, hi: 0xbf}, + // Block 0xa, offset 0x63 + {value: 0x0005, lo: 0x07}, + {value: 0x8132, lo: 0x80, hi: 0x80}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x812d, lo: 0x82, hi: 0x83}, + {value: 0x812d, lo: 0x84, hi: 0x85}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x812d, lo: 0x88, hi: 0x89}, + {value: 0x8132, lo: 0x8a, hi: 0x8a}, + // Block 0xb, offset 0x6b + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xab, hi: 0xb1}, + {value: 0x812d, lo: 0xb2, hi: 0xb2}, + {value: 0x8132, lo: 0xb3, hi: 0xb3}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0xc, offset 0x70 + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0x96, hi: 0x99}, + {value: 0x8132, lo: 0x9b, hi: 0xa3}, + {value: 0x8132, lo: 0xa5, hi: 0xa7}, + {value: 0x8132, lo: 0xa9, hi: 0xad}, + // Block 0xd, offset 0x75 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x99, hi: 0x9b}, + // Block 0xe, offset 0x77 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3edb, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ee3, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3eeb, lo: 0xb4, hi: 0xb4}, + {value: 0x9902, lo: 0xbc, hi: 0xbc}, + // Block 0xf, offset 0x7f + {value: 0x0008, lo: 0x06}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x91, hi: 0x91}, + {value: 0x812d, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x93, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x94}, + {value: 0x451f, lo: 0x98, hi: 0x9f}, + // Block 0x10, offset 0x86 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x11, offset 0x89 + {value: 0x0008, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2ca1, lo: 0x8b, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x455f, lo: 0x9c, hi: 0x9d}, + {value: 0x456f, lo: 0x9f, hi: 0x9f}, + {value: 0x8132, lo: 0xbe, hi: 0xbe}, + // Block 0x12, offset 0x91 + {value: 0x0000, lo: 0x03}, + {value: 0x4597, lo: 0xb3, hi: 0xb3}, + {value: 0x459f, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x13, offset 0x95 + {value: 0x0008, lo: 0x03}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x4577, lo: 0x99, hi: 0x9b}, + {value: 0x458f, lo: 0x9e, hi: 0x9e}, + // Block 0x14, offset 0x99 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + // Block 0x15, offset 0x9b + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + // Block 0x16, offset 0x9d + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cb9, lo: 0x88, hi: 0x88}, + {value: 0x2cb1, lo: 0x8b, hi: 0x8b}, + {value: 0x2cc1, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45a7, lo: 0x9c, hi: 0x9c}, + {value: 0x45af, lo: 0x9d, hi: 0x9d}, + // Block 0x17, offset 0xa6 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cc9, lo: 0x94, hi: 0x94}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x18, offset 0xaa + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2cd1, lo: 0x8a, hi: 0x8a}, + {value: 0x2ce1, lo: 0x8b, hi: 0x8b}, + {value: 0x2cd9, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x19, offset 0xb1 + {value: 0x1801, lo: 0x04}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x3ef3, lo: 0x88, hi: 0x88}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x8120, lo: 0x95, hi: 0x96}, + // Block 0x1a, offset 0xb6 + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1b, offset 0xb9 + {value: 0x0000, lo: 0x09}, + {value: 0x2ce9, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cf1, lo: 0x87, hi: 0x87}, + {value: 0x2cf9, lo: 0x88, hi: 0x88}, + {value: 0x2f53, lo: 0x8a, hi: 0x8a}, + {value: 0x2ddb, lo: 0x8b, hi: 0x8b}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1c, offset 0xc3 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x1d, offset 0xc6 + {value: 0x0000, lo: 0x06}, + {value: 0xa000, lo: 0x86, hi: 0x87}, + {value: 0x2d01, lo: 0x8a, hi: 0x8a}, + {value: 0x2d11, lo: 0x8b, hi: 0x8b}, + {value: 0x2d09, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1e, offset 0xcd + {value: 0x6be7, lo: 0x07}, + {value: 0x9904, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3efb, lo: 0x9a, hi: 0x9a}, + {value: 0x2f5b, lo: 0x9c, hi: 0x9c}, + {value: 0x2de6, lo: 0x9d, hi: 0x9d}, + {value: 0x2d19, lo: 0x9e, hi: 0x9f}, + // Block 0x1f, offset 0xd5 + {value: 0x0000, lo: 0x03}, + {value: 0x2624, lo: 0xb3, hi: 0xb3}, + {value: 0x8122, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x20, offset 0xd9 + {value: 0x0000, lo: 0x01}, + {value: 0x8123, lo: 0x88, hi: 0x8b}, + // Block 0x21, offset 0xdb + {value: 0x0000, lo: 0x03}, + {value: 0x2639, lo: 0xb3, hi: 0xb3}, + {value: 0x8124, lo: 0xb8, hi: 0xb9}, + {value: 0x8104, lo: 0xba, hi: 0xba}, + // Block 0x22, offset 0xdf + {value: 0x0000, lo: 0x03}, + {value: 0x8125, lo: 0x88, hi: 0x8b}, + {value: 0x262b, lo: 0x9c, hi: 0x9c}, + {value: 0x2632, lo: 0x9d, hi: 0x9d}, + // Block 0x23, offset 0xe3 + {value: 0x0000, lo: 0x05}, + {value: 0x030b, lo: 0x8c, hi: 0x8c}, + {value: 0x812d, lo: 0x98, hi: 0x99}, + {value: 0x812d, lo: 0xb5, hi: 0xb5}, + {value: 0x812d, lo: 0xb7, hi: 0xb7}, + {value: 0x812b, lo: 0xb9, hi: 0xb9}, + // Block 0x24, offset 0xe9 + {value: 0x0000, lo: 0x10}, + {value: 0x2647, lo: 0x83, hi: 0x83}, + {value: 0x264e, lo: 0x8d, hi: 0x8d}, + {value: 0x2655, lo: 0x92, hi: 0x92}, + {value: 0x265c, lo: 0x97, hi: 0x97}, + {value: 0x2663, lo: 0x9c, hi: 0x9c}, + {value: 0x2640, lo: 0xa9, hi: 0xa9}, + {value: 0x8126, lo: 0xb1, hi: 0xb1}, + {value: 0x8127, lo: 0xb2, hi: 0xb2}, + {value: 0x4a87, lo: 0xb3, hi: 0xb3}, + {value: 0x8128, lo: 0xb4, hi: 0xb4}, + {value: 0x4a90, lo: 0xb5, hi: 0xb5}, + {value: 0x45b7, lo: 0xb6, hi: 0xb6}, + {value: 0x45f7, lo: 0xb7, hi: 0xb7}, + {value: 0x45bf, lo: 0xb8, hi: 0xb8}, + {value: 0x4602, lo: 0xb9, hi: 0xb9}, + {value: 0x8127, lo: 0xba, hi: 0xbd}, + // Block 0x25, offset 0xfa + {value: 0x0000, lo: 0x0b}, + {value: 0x8127, lo: 0x80, hi: 0x80}, + {value: 0x4a99, lo: 0x81, hi: 0x81}, + {value: 0x8132, lo: 0x82, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0x86, hi: 0x87}, + {value: 0x2671, lo: 0x93, hi: 0x93}, + {value: 0x2678, lo: 0x9d, hi: 0x9d}, + {value: 0x267f, lo: 0xa2, hi: 0xa2}, + {value: 0x2686, lo: 0xa7, hi: 0xa7}, + {value: 0x268d, lo: 0xac, hi: 0xac}, + {value: 0x266a, lo: 0xb9, hi: 0xb9}, + // Block 0x26, offset 0x106 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x86, hi: 0x86}, + // Block 0x27, offset 0x108 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d21, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x28, offset 0x10e + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + // Block 0x29, offset 0x110 + {value: 0x0000, lo: 0x01}, + {value: 0x030f, lo: 0xbc, hi: 0xbc}, + // Block 0x2a, offset 0x112 + {value: 0x0000, lo: 0x01}, + {value: 0xa000, lo: 0x80, hi: 0x92}, + // Block 0x2b, offset 0x114 + {value: 0x0000, lo: 0x01}, + {value: 0xb900, lo: 0xa1, hi: 0xb5}, + // Block 0x2c, offset 0x116 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0xa8, hi: 0xbf}, + // Block 0x2d, offset 0x118 + {value: 0x0000, lo: 0x01}, + {value: 0x9900, lo: 0x80, hi: 0x82}, + // Block 0x2e, offset 0x11a + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x9d, hi: 0x9f}, + // Block 0x2f, offset 0x11c + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x94, hi: 0x94}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x30, offset 0x11f + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x92, hi: 0x92}, + {value: 0x8132, lo: 0x9d, hi: 0x9d}, + // Block 0x31, offset 0x122 + {value: 0x0000, lo: 0x01}, + {value: 0x8131, lo: 0xa9, hi: 0xa9}, + // Block 0x32, offset 0x124 + {value: 0x0004, lo: 0x02}, + {value: 0x812e, lo: 0xb9, hi: 0xba}, + {value: 0x812d, lo: 0xbb, hi: 0xbb}, + // Block 0x33, offset 0x127 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x97, hi: 0x97}, + {value: 0x812d, lo: 0x98, hi: 0x98}, + // Block 0x34, offset 0x12a + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + {value: 0x8132, lo: 0xb5, hi: 0xbc}, + {value: 0x812d, lo: 0xbf, hi: 0xbf}, + // Block 0x35, offset 0x12e + {value: 0x0000, lo: 0x04}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + {value: 0x812d, lo: 0xb5, hi: 0xba}, + {value: 0x8132, lo: 0xbb, hi: 0xbc}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x36, offset 0x133 + {value: 0x0000, lo: 0x08}, + {value: 0x2d69, lo: 0x80, hi: 0x80}, + {value: 0x2d71, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d79, lo: 0x83, hi: 0x83}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xac}, + {value: 0x8132, lo: 0xad, hi: 0xb3}, + // Block 0x37, offset 0x13c + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xaa, hi: 0xab}, + // Block 0x38, offset 0x13e + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xa6, hi: 0xa6}, + {value: 0x8104, lo: 0xb2, hi: 0xb3}, + // Block 0x39, offset 0x141 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x3a, offset 0x143 + {value: 0x0000, lo: 0x0a}, + {value: 0x8132, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812d, lo: 0x95, hi: 0x99}, + {value: 0x8132, lo: 0x9a, hi: 0x9b}, + {value: 0x812d, lo: 0x9c, hi: 0x9f}, + {value: 0x8132, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812d, lo: 0xad, hi: 0xad}, + {value: 0x8132, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb8, hi: 0xb9}, + // Block 0x3b, offset 0x14e + {value: 0x0002, lo: 0x0a}, + {value: 0x0043, lo: 0xac, hi: 0xac}, + {value: 0x00d1, lo: 0xad, hi: 0xad}, + {value: 0x0045, lo: 0xae, hi: 0xae}, + {value: 0x0049, lo: 0xb0, hi: 0xb1}, + {value: 0x00e6, lo: 0xb2, hi: 0xb2}, + {value: 0x004f, lo: 0xb3, hi: 0xba}, + {value: 0x005f, lo: 0xbc, hi: 0xbc}, + {value: 0x00ef, lo: 0xbd, hi: 0xbd}, + {value: 0x0061, lo: 0xbe, hi: 0xbe}, + {value: 0x0065, lo: 0xbf, hi: 0xbf}, + // Block 0x3c, offset 0x159 + {value: 0x0000, lo: 0x0d}, + {value: 0x0001, lo: 0x80, hi: 0x8a}, + {value: 0x043b, lo: 0x91, hi: 0x91}, + {value: 0x429e, lo: 0x97, hi: 0x97}, + {value: 0x001d, lo: 0xa4, hi: 0xa4}, + {value: 0x1873, lo: 0xa5, hi: 0xa5}, + {value: 0x1b5f, lo: 0xa6, hi: 0xa6}, + {value: 0x0001, lo: 0xaf, hi: 0xaf}, + {value: 0x2694, lo: 0xb3, hi: 0xb3}, + {value: 0x2801, lo: 0xb4, hi: 0xb4}, + {value: 0x269b, lo: 0xb6, hi: 0xb6}, + {value: 0x280b, lo: 0xb7, hi: 0xb7}, + {value: 0x186d, lo: 0xbc, hi: 0xbc}, + {value: 0x426c, lo: 0xbe, hi: 0xbe}, + // Block 0x3d, offset 0x167 + {value: 0x0002, lo: 0x0d}, + {value: 0x1933, lo: 0x87, hi: 0x87}, + {value: 0x1930, lo: 0x88, hi: 0x88}, + {value: 0x1870, lo: 0x89, hi: 0x89}, + {value: 0x2991, lo: 0x97, hi: 0x97}, + {value: 0x0001, lo: 0x9f, hi: 0x9f}, + {value: 0x0021, lo: 0xb0, hi: 0xb0}, + {value: 0x0093, lo: 0xb1, hi: 0xb1}, + {value: 0x0029, lo: 0xb4, hi: 0xb9}, + {value: 0x0017, lo: 0xba, hi: 0xba}, + {value: 0x0467, lo: 0xbb, hi: 0xbb}, + {value: 0x003b, lo: 0xbc, hi: 0xbc}, + {value: 0x0011, lo: 0xbd, hi: 0xbe}, + {value: 0x009d, lo: 0xbf, hi: 0xbf}, + // Block 0x3e, offset 0x175 + {value: 0x0002, lo: 0x0f}, + {value: 0x0021, lo: 0x80, hi: 0x89}, + {value: 0x0017, lo: 0x8a, hi: 0x8a}, + {value: 0x0467, lo: 0x8b, hi: 0x8b}, + {value: 0x003b, lo: 0x8c, hi: 0x8c}, + {value: 0x0011, lo: 0x8d, hi: 0x8e}, + {value: 0x0083, lo: 0x90, hi: 0x90}, + {value: 0x008b, lo: 0x91, hi: 0x91}, + {value: 0x009f, lo: 0x92, hi: 0x92}, + {value: 0x00b1, lo: 0x93, hi: 0x93}, + {value: 0x0104, lo: 0x94, hi: 0x94}, + {value: 0x0091, lo: 0x95, hi: 0x95}, + {value: 0x0097, lo: 0x96, hi: 0x99}, + {value: 0x00a1, lo: 0x9a, hi: 0x9a}, + {value: 0x00a7, lo: 0x9b, hi: 0x9c}, + {value: 0x199c, lo: 0xa8, hi: 0xa8}, + // Block 0x3f, offset 0x185 + {value: 0x0000, lo: 0x0d}, + {value: 0x8132, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8132, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8132, lo: 0x9b, hi: 0x9c}, + {value: 0x8132, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8132, lo: 0xa7, hi: 0xa7}, + {value: 0x812d, lo: 0xa8, hi: 0xa8}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812d, lo: 0xac, hi: 0xaf}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + // Block 0x40, offset 0x193 + {value: 0x0007, lo: 0x06}, + {value: 0x2183, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bbc, lo: 0x9a, hi: 0x9b}, + {value: 0x3bca, lo: 0xae, hi: 0xae}, + // Block 0x41, offset 0x19a + {value: 0x000e, lo: 0x05}, + {value: 0x3bd1, lo: 0x8d, hi: 0x8e}, + {value: 0x3bd8, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x42, offset 0x1a0 + {value: 0x0173, lo: 0x0e}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3be6, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3bed, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3bf4, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3bfb, lo: 0xa4, hi: 0xa4}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x3c02, lo: 0xa6, hi: 0xa6}, + {value: 0x26a2, lo: 0xac, hi: 0xad}, + {value: 0x26a9, lo: 0xaf, hi: 0xaf}, + {value: 0x281f, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x43, offset 0x1af + {value: 0x0007, lo: 0x03}, + {value: 0x3c6b, lo: 0xa0, hi: 0xa1}, + {value: 0x3c95, lo: 0xa2, hi: 0xa3}, + {value: 0x3cbf, lo: 0xaa, hi: 0xad}, + // Block 0x44, offset 0x1b3 + {value: 0x0004, lo: 0x01}, + {value: 0x048b, lo: 0xa9, hi: 0xaa}, + // Block 0x45, offset 0x1b5 + {value: 0x0002, lo: 0x03}, + {value: 0x0057, lo: 0x80, hi: 0x8f}, + {value: 0x0083, lo: 0x90, hi: 0xa9}, + {value: 0x0021, lo: 0xaa, hi: 0xaa}, + // Block 0x46, offset 0x1b9 + {value: 0x0000, lo: 0x01}, + {value: 0x299e, lo: 0x8c, hi: 0x8c}, + // Block 0x47, offset 0x1bb + {value: 0x0266, lo: 0x02}, + {value: 0x1b8f, lo: 0xb4, hi: 0xb4}, + {value: 0x192d, lo: 0xb5, hi: 0xb6}, + // Block 0x48, offset 0x1be + {value: 0x0000, lo: 0x01}, + {value: 0x44e0, lo: 0x9c, hi: 0x9c}, + // Block 0x49, offset 0x1c0 + {value: 0x0000, lo: 0x02}, + {value: 0x0095, lo: 0xbc, hi: 0xbc}, + {value: 0x006d, lo: 0xbd, hi: 0xbd}, + // Block 0x4a, offset 0x1c3 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xaf, hi: 0xb1}, + // Block 0x4b, offset 0x1c5 + {value: 0x0000, lo: 0x02}, + {value: 0x047f, lo: 0xaf, hi: 0xaf}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x4c, offset 0x1c8 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa0, hi: 0xbf}, + // Block 0x4d, offset 0x1ca + {value: 0x0000, lo: 0x01}, + {value: 0x0dc3, lo: 0x9f, hi: 0x9f}, + // Block 0x4e, offset 0x1cc + {value: 0x0000, lo: 0x01}, + {value: 0x162f, lo: 0xb3, hi: 0xb3}, + // Block 0x4f, offset 0x1ce + {value: 0x0004, lo: 0x0b}, + {value: 0x1597, lo: 0x80, hi: 0x82}, + {value: 0x15af, lo: 0x83, hi: 0x83}, + {value: 0x15c7, lo: 0x84, hi: 0x85}, + {value: 0x15d7, lo: 0x86, hi: 0x89}, + {value: 0x15eb, lo: 0x8a, hi: 0x8c}, + {value: 0x15ff, lo: 0x8d, hi: 0x8d}, + {value: 0x1607, lo: 0x8e, hi: 0x8e}, + {value: 0x160f, lo: 0x8f, hi: 0x90}, + {value: 0x161b, lo: 0x91, hi: 0x93}, + {value: 0x162b, lo: 0x94, hi: 0x94}, + {value: 0x1633, lo: 0x95, hi: 0x95}, + // Block 0x50, offset 0x1da + {value: 0x0004, lo: 0x09}, + {value: 0x0001, lo: 0x80, hi: 0x80}, + {value: 0x812c, lo: 0xaa, hi: 0xaa}, + {value: 0x8131, lo: 0xab, hi: 0xab}, + {value: 0x8133, lo: 0xac, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x812f, lo: 0xae, hi: 0xae}, + {value: 0x812f, lo: 0xaf, hi: 0xaf}, + {value: 0x04b3, lo: 0xb6, hi: 0xb6}, + {value: 0x0887, lo: 0xb8, hi: 0xba}, + // Block 0x51, offset 0x1e4 + {value: 0x0006, lo: 0x09}, + {value: 0x0313, lo: 0xb1, hi: 0xb1}, + {value: 0x0317, lo: 0xb2, hi: 0xb2}, + {value: 0x4a3e, lo: 0xb3, hi: 0xb3}, + {value: 0x031b, lo: 0xb4, hi: 0xb4}, + {value: 0x4a44, lo: 0xb5, hi: 0xb6}, + {value: 0x031f, lo: 0xb7, hi: 0xb7}, + {value: 0x0323, lo: 0xb8, hi: 0xb8}, + {value: 0x0327, lo: 0xb9, hi: 0xb9}, + {value: 0x4a50, lo: 0xba, hi: 0xbf}, + // Block 0x52, offset 0x1ee + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xaf, hi: 0xaf}, + {value: 0x8132, lo: 0xb4, hi: 0xbd}, + // Block 0x53, offset 0x1f1 + {value: 0x0000, lo: 0x03}, + {value: 0x020f, lo: 0x9c, hi: 0x9c}, + {value: 0x0212, lo: 0x9d, hi: 0x9d}, + {value: 0x8132, lo: 0x9e, hi: 0x9f}, + // Block 0x54, offset 0x1f5 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb1}, + // Block 0x55, offset 0x1f7 + {value: 0x0000, lo: 0x01}, + {value: 0x163b, lo: 0xb0, hi: 0xb0}, + // Block 0x56, offset 0x1f9 + {value: 0x000c, lo: 0x01}, + {value: 0x00d7, lo: 0xb8, hi: 0xb9}, + // Block 0x57, offset 0x1fb + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + // Block 0x58, offset 0x1fd + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x84, hi: 0x84}, + {value: 0x8132, lo: 0xa0, hi: 0xb1}, + // Block 0x59, offset 0x200 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xab, hi: 0xad}, + // Block 0x5a, offset 0x202 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x93, hi: 0x93}, + // Block 0x5b, offset 0x204 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb3, hi: 0xb3}, + // Block 0x5c, offset 0x206 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + // Block 0x5d, offset 0x208 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0xb0, hi: 0xb0}, + {value: 0x8132, lo: 0xb2, hi: 0xb3}, + {value: 0x812d, lo: 0xb4, hi: 0xb4}, + {value: 0x8132, lo: 0xb7, hi: 0xb8}, + {value: 0x8132, lo: 0xbe, hi: 0xbf}, + // Block 0x5e, offset 0x20e + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x81, hi: 0x81}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + // Block 0x5f, offset 0x211 + {value: 0x0008, lo: 0x03}, + {value: 0x1637, lo: 0x9c, hi: 0x9d}, + {value: 0x0125, lo: 0x9e, hi: 0x9e}, + {value: 0x1643, lo: 0x9f, hi: 0x9f}, + // Block 0x60, offset 0x215 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xad, hi: 0xad}, + // Block 0x61, offset 0x217 + {value: 0x0000, lo: 0x06}, + {value: 0xe500, lo: 0x80, hi: 0x80}, + {value: 0xc600, lo: 0x81, hi: 0x9b}, + {value: 0xe500, lo: 0x9c, hi: 0x9c}, + {value: 0xc600, lo: 0x9d, hi: 0xb7}, + {value: 0xe500, lo: 0xb8, hi: 0xb8}, + {value: 0xc600, lo: 0xb9, hi: 0xbf}, + // Block 0x62, offset 0x21e + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x93}, + {value: 0xe500, lo: 0x94, hi: 0x94}, + {value: 0xc600, lo: 0x95, hi: 0xaf}, + {value: 0xe500, lo: 0xb0, hi: 0xb0}, + {value: 0xc600, lo: 0xb1, hi: 0xbf}, + // Block 0x63, offset 0x224 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8b}, + {value: 0xe500, lo: 0x8c, hi: 0x8c}, + {value: 0xc600, lo: 0x8d, hi: 0xa7}, + {value: 0xe500, lo: 0xa8, hi: 0xa8}, + {value: 0xc600, lo: 0xa9, hi: 0xbf}, + // Block 0x64, offset 0x22a + {value: 0x0000, lo: 0x07}, + {value: 0xc600, lo: 0x80, hi: 0x83}, + {value: 0xe500, lo: 0x84, hi: 0x84}, + {value: 0xc600, lo: 0x85, hi: 0x9f}, + {value: 0xe500, lo: 0xa0, hi: 0xa0}, + {value: 0xc600, lo: 0xa1, hi: 0xbb}, + {value: 0xe500, lo: 0xbc, hi: 0xbc}, + {value: 0xc600, lo: 0xbd, hi: 0xbf}, + // Block 0x65, offset 0x232 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x97}, + {value: 0xe500, lo: 0x98, hi: 0x98}, + {value: 0xc600, lo: 0x99, hi: 0xb3}, + {value: 0xe500, lo: 0xb4, hi: 0xb4}, + {value: 0xc600, lo: 0xb5, hi: 0xbf}, + // Block 0x66, offset 0x238 + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x8f}, + {value: 0xe500, lo: 0x90, hi: 0x90}, + {value: 0xc600, lo: 0x91, hi: 0xab}, + {value: 0xe500, lo: 0xac, hi: 0xac}, + {value: 0xc600, lo: 0xad, hi: 0xbf}, + // Block 0x67, offset 0x23e + {value: 0x0000, lo: 0x05}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + {value: 0xe500, lo: 0xa4, hi: 0xa4}, + {value: 0xc600, lo: 0xa5, hi: 0xbf}, + // Block 0x68, offset 0x244 + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x69, offset 0x248 + {value: 0x0002, lo: 0x01}, + {value: 0x0003, lo: 0x81, hi: 0xbf}, + // Block 0x6a, offset 0x24a + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xbd, hi: 0xbd}, + // Block 0x6b, offset 0x24c + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0xa0, hi: 0xa0}, + // Block 0x6c, offset 0x24e + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb6, hi: 0xba}, + // Block 0x6d, offset 0x250 + {value: 0x002c, lo: 0x05}, + {value: 0x812d, lo: 0x8d, hi: 0x8d}, + {value: 0x8132, lo: 0x8f, hi: 0x8f}, + {value: 0x8132, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x6e, offset 0x256 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0xa5, hi: 0xa5}, + {value: 0x812d, lo: 0xa6, hi: 0xa6}, + // Block 0x6f, offset 0x259 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa4, hi: 0xa7}, + // Block 0x70, offset 0x25b + {value: 0x0000, lo: 0x05}, + {value: 0x812d, lo: 0x86, hi: 0x87}, + {value: 0x8132, lo: 0x88, hi: 0x8a}, + {value: 0x812d, lo: 0x8b, hi: 0x8b}, + {value: 0x8132, lo: 0x8c, hi: 0x8c}, + {value: 0x812d, lo: 0x8d, hi: 0x90}, + // Block 0x71, offset 0x261 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x86, hi: 0x86}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x72, offset 0x264 + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x423b, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4245, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x424f, lo: 0xab, hi: 0xab}, + {value: 0x8104, lo: 0xb9, hi: 0xba}, + // Block 0x73, offset 0x26c + {value: 0x0000, lo: 0x06}, + {value: 0x8132, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d81, lo: 0xae, hi: 0xae}, + {value: 0x2d8b, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8104, lo: 0xb3, hi: 0xb4}, + // Block 0x74, offset 0x273 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x80, hi: 0x80}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0x75, offset 0x276 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb5, hi: 0xb5}, + {value: 0x8102, lo: 0xb6, hi: 0xb6}, + // Block 0x76, offset 0x279 + {value: 0x0002, lo: 0x01}, + {value: 0x8102, lo: 0xa9, hi: 0xaa}, + // Block 0x77, offset 0x27b + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x78, offset 0x27e + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d95, lo: 0x8b, hi: 0x8b}, + {value: 0x2d9f, lo: 0x8c, hi: 0x8c}, + {value: 0x8104, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8132, lo: 0xa6, hi: 0xac}, + {value: 0x8132, lo: 0xb0, hi: 0xb4}, + // Block 0x79, offset 0x286 + {value: 0x0000, lo: 0x03}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x86, hi: 0x86}, + {value: 0x8132, lo: 0x9e, hi: 0x9e}, + // Block 0x7a, offset 0x28a + {value: 0x6b57, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2db3, lo: 0xbb, hi: 0xbb}, + {value: 0x2da9, lo: 0xbc, hi: 0xbd}, + {value: 0x2dbd, lo: 0xbe, hi: 0xbe}, + // Block 0x7b, offset 0x291 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0x82, hi: 0x82}, + {value: 0x8102, lo: 0x83, hi: 0x83}, + // Block 0x7c, offset 0x294 + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dc7, lo: 0xba, hi: 0xba}, + {value: 0x2dd1, lo: 0xbb, hi: 0xbb}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7d, offset 0x29a + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0x80, hi: 0x80}, + // Block 0x7e, offset 0x29c + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xbf, hi: 0xbf}, + // Block 0x7f, offset 0x29e + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb6, hi: 0xb6}, + {value: 0x8102, lo: 0xb7, hi: 0xb7}, + // Block 0x80, offset 0x2a1 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xab, hi: 0xab}, + // Block 0x81, offset 0x2a3 + {value: 0x0000, lo: 0x02}, + {value: 0x8104, lo: 0xb9, hi: 0xb9}, + {value: 0x8102, lo: 0xba, hi: 0xba}, + // Block 0x82, offset 0x2a6 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xa0, hi: 0xa0}, + // Block 0x83, offset 0x2a8 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0xb4, hi: 0xb4}, + // Block 0x84, offset 0x2aa + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x87, hi: 0x87}, + // Block 0x85, offset 0x2ac + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x99, hi: 0x99}, + // Block 0x86, offset 0x2ae + {value: 0x0000, lo: 0x02}, + {value: 0x8102, lo: 0x82, hi: 0x82}, + {value: 0x8104, lo: 0x84, hi: 0x85}, + // Block 0x87, offset 0x2b1 + {value: 0x0000, lo: 0x01}, + {value: 0x8104, lo: 0x97, hi: 0x97}, + // Block 0x88, offset 0x2b3 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x89, offset 0x2b5 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xb0, hi: 0xb6}, + // Block 0x8a, offset 0x2b7 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x8b, offset 0x2b9 + {value: 0x0000, lo: 0x0c}, + {value: 0x45cf, lo: 0x9e, hi: 0x9e}, + {value: 0x45d9, lo: 0x9f, hi: 0x9f}, + {value: 0x460d, lo: 0xa0, hi: 0xa0}, + {value: 0x461b, lo: 0xa1, hi: 0xa1}, + {value: 0x4629, lo: 0xa2, hi: 0xa2}, + {value: 0x4637, lo: 0xa3, hi: 0xa3}, + {value: 0x4645, lo: 0xa4, hi: 0xa4}, + {value: 0x812b, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8130, lo: 0xad, hi: 0xad}, + {value: 0x812b, lo: 0xae, hi: 0xb2}, + {value: 0x812d, lo: 0xbb, hi: 0xbf}, + // Block 0x8c, offset 0x2c6 + {value: 0x0000, lo: 0x09}, + {value: 0x812d, lo: 0x80, hi: 0x82}, + {value: 0x8132, lo: 0x85, hi: 0x89}, + {value: 0x812d, lo: 0x8a, hi: 0x8b}, + {value: 0x8132, lo: 0xaa, hi: 0xad}, + {value: 0x45e3, lo: 0xbb, hi: 0xbb}, + {value: 0x45ed, lo: 0xbc, hi: 0xbc}, + {value: 0x4653, lo: 0xbd, hi: 0xbd}, + {value: 0x466f, lo: 0xbe, hi: 0xbe}, + {value: 0x4661, lo: 0xbf, hi: 0xbf}, + // Block 0x8d, offset 0x2d0 + {value: 0x0000, lo: 0x01}, + {value: 0x467d, lo: 0x80, hi: 0x80}, + // Block 0x8e, offset 0x2d2 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0x82, hi: 0x84}, + // Block 0x8f, offset 0x2d4 + {value: 0x0002, lo: 0x03}, + {value: 0x0043, lo: 0x80, hi: 0x99}, + {value: 0x0083, lo: 0x9a, hi: 0xb3}, + {value: 0x0043, lo: 0xb4, hi: 0xbf}, + // Block 0x90, offset 0x2d8 + {value: 0x0002, lo: 0x04}, + {value: 0x005b, lo: 0x80, hi: 0x8d}, + {value: 0x0083, lo: 0x8e, hi: 0x94}, + {value: 0x0093, lo: 0x96, hi: 0xa7}, + {value: 0x0043, lo: 0xa8, hi: 0xbf}, + // Block 0x91, offset 0x2dd + {value: 0x0002, lo: 0x0b}, + {value: 0x0073, lo: 0x80, hi: 0x81}, + {value: 0x0083, lo: 0x82, hi: 0x9b}, + {value: 0x0043, lo: 0x9c, hi: 0x9c}, + {value: 0x0047, lo: 0x9e, hi: 0x9f}, + {value: 0x004f, lo: 0xa2, hi: 0xa2}, + {value: 0x0055, lo: 0xa5, hi: 0xa6}, + {value: 0x005d, lo: 0xa9, hi: 0xac}, + {value: 0x0067, lo: 0xae, hi: 0xb5}, + {value: 0x0083, lo: 0xb6, hi: 0xb9}, + {value: 0x008d, lo: 0xbb, hi: 0xbb}, + {value: 0x0091, lo: 0xbd, hi: 0xbf}, + // Block 0x92, offset 0x2e9 + {value: 0x0002, lo: 0x04}, + {value: 0x0097, lo: 0x80, hi: 0x83}, + {value: 0x00a1, lo: 0x85, hi: 0x8f}, + {value: 0x0043, lo: 0x90, hi: 0xa9}, + {value: 0x0083, lo: 0xaa, hi: 0xbf}, + // Block 0x93, offset 0x2ee + {value: 0x0002, lo: 0x08}, + {value: 0x00af, lo: 0x80, hi: 0x83}, + {value: 0x0043, lo: 0x84, hi: 0x85}, + {value: 0x0049, lo: 0x87, hi: 0x8a}, + {value: 0x0055, lo: 0x8d, hi: 0x94}, + {value: 0x0067, lo: 0x96, hi: 0x9c}, + {value: 0x0083, lo: 0x9e, hi: 0xb7}, + {value: 0x0043, lo: 0xb8, hi: 0xb9}, + {value: 0x0049, lo: 0xbb, hi: 0xbe}, + // Block 0x94, offset 0x2f7 + {value: 0x0002, lo: 0x05}, + {value: 0x0053, lo: 0x80, hi: 0x84}, + {value: 0x005f, lo: 0x86, hi: 0x86}, + {value: 0x0067, lo: 0x8a, hi: 0x90}, + {value: 0x0083, lo: 0x92, hi: 0xab}, + {value: 0x0043, lo: 0xac, hi: 0xbf}, + // Block 0x95, offset 0x2fd + {value: 0x0002, lo: 0x04}, + {value: 0x006b, lo: 0x80, hi: 0x85}, + {value: 0x0083, lo: 0x86, hi: 0x9f}, + {value: 0x0043, lo: 0xa0, hi: 0xb9}, + {value: 0x0083, lo: 0xba, hi: 0xbf}, + // Block 0x96, offset 0x302 + {value: 0x0002, lo: 0x03}, + {value: 0x008f, lo: 0x80, hi: 0x93}, + {value: 0x0043, lo: 0x94, hi: 0xad}, + {value: 0x0083, lo: 0xae, hi: 0xbf}, + // Block 0x97, offset 0x306 + {value: 0x0002, lo: 0x04}, + {value: 0x00a7, lo: 0x80, hi: 0x87}, + {value: 0x0043, lo: 0x88, hi: 0xa1}, + {value: 0x0083, lo: 0xa2, hi: 0xbb}, + {value: 0x0043, lo: 0xbc, hi: 0xbf}, + // Block 0x98, offset 0x30b + {value: 0x0002, lo: 0x03}, + {value: 0x004b, lo: 0x80, hi: 0x95}, + {value: 0x0083, lo: 0x96, hi: 0xaf}, + {value: 0x0043, lo: 0xb0, hi: 0xbf}, + // Block 0x99, offset 0x30f + {value: 0x0003, lo: 0x0f}, + {value: 0x01b8, lo: 0x80, hi: 0x80}, + {value: 0x045f, lo: 0x81, hi: 0x81}, + {value: 0x01bb, lo: 0x82, hi: 0x9a}, + {value: 0x045b, lo: 0x9b, hi: 0x9b}, + {value: 0x01c7, lo: 0x9c, hi: 0x9c}, + {value: 0x01d0, lo: 0x9d, hi: 0x9d}, + {value: 0x01d6, lo: 0x9e, hi: 0x9e}, + {value: 0x01fa, lo: 0x9f, hi: 0x9f}, + {value: 0x01eb, lo: 0xa0, hi: 0xa0}, + {value: 0x01e8, lo: 0xa1, hi: 0xa1}, + {value: 0x0173, lo: 0xa2, hi: 0xb2}, + {value: 0x0188, lo: 0xb3, hi: 0xb3}, + {value: 0x01a6, lo: 0xb4, hi: 0xba}, + {value: 0x045f, lo: 0xbb, hi: 0xbb}, + {value: 0x01bb, lo: 0xbc, hi: 0xbf}, + // Block 0x9a, offset 0x31f + {value: 0x0003, lo: 0x0d}, + {value: 0x01c7, lo: 0x80, hi: 0x94}, + {value: 0x045b, lo: 0x95, hi: 0x95}, + {value: 0x01c7, lo: 0x96, hi: 0x96}, + {value: 0x01d0, lo: 0x97, hi: 0x97}, + {value: 0x01d6, lo: 0x98, hi: 0x98}, + {value: 0x01fa, lo: 0x99, hi: 0x99}, + {value: 0x01eb, lo: 0x9a, hi: 0x9a}, + {value: 0x01e8, lo: 0x9b, hi: 0x9b}, + {value: 0x0173, lo: 0x9c, hi: 0xac}, + {value: 0x0188, lo: 0xad, hi: 0xad}, + {value: 0x01a6, lo: 0xae, hi: 0xb4}, + {value: 0x045f, lo: 0xb5, hi: 0xb5}, + {value: 0x01bb, lo: 0xb6, hi: 0xbf}, + // Block 0x9b, offset 0x32d + {value: 0x0003, lo: 0x0d}, + {value: 0x01d9, lo: 0x80, hi: 0x8e}, + {value: 0x045b, lo: 0x8f, hi: 0x8f}, + {value: 0x01c7, lo: 0x90, hi: 0x90}, + {value: 0x01d0, lo: 0x91, hi: 0x91}, + {value: 0x01d6, lo: 0x92, hi: 0x92}, + {value: 0x01fa, lo: 0x93, hi: 0x93}, + {value: 0x01eb, lo: 0x94, hi: 0x94}, + {value: 0x01e8, lo: 0x95, hi: 0x95}, + {value: 0x0173, lo: 0x96, hi: 0xa6}, + {value: 0x0188, lo: 0xa7, hi: 0xa7}, + {value: 0x01a6, lo: 0xa8, hi: 0xae}, + {value: 0x045f, lo: 0xaf, hi: 0xaf}, + {value: 0x01bb, lo: 0xb0, hi: 0xbf}, + // Block 0x9c, offset 0x33b + {value: 0x0003, lo: 0x0d}, + {value: 0x01eb, lo: 0x80, hi: 0x88}, + {value: 0x045b, lo: 0x89, hi: 0x89}, + {value: 0x01c7, lo: 0x8a, hi: 0x8a}, + {value: 0x01d0, lo: 0x8b, hi: 0x8b}, + {value: 0x01d6, lo: 0x8c, hi: 0x8c}, + {value: 0x01fa, lo: 0x8d, hi: 0x8d}, + {value: 0x01eb, lo: 0x8e, hi: 0x8e}, + {value: 0x01e8, lo: 0x8f, hi: 0x8f}, + {value: 0x0173, lo: 0x90, hi: 0xa0}, + {value: 0x0188, lo: 0xa1, hi: 0xa1}, + {value: 0x01a6, lo: 0xa2, hi: 0xa8}, + {value: 0x045f, lo: 0xa9, hi: 0xa9}, + {value: 0x01bb, lo: 0xaa, hi: 0xbf}, + // Block 0x9d, offset 0x349 + {value: 0x0000, lo: 0x05}, + {value: 0x8132, lo: 0x80, hi: 0x86}, + {value: 0x8132, lo: 0x88, hi: 0x98}, + {value: 0x8132, lo: 0x9b, hi: 0xa1}, + {value: 0x8132, lo: 0xa3, hi: 0xa4}, + {value: 0x8132, lo: 0xa6, hi: 0xaa}, + // Block 0x9e, offset 0x34f + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xac, hi: 0xaf}, + // Block 0x9f, offset 0x351 + {value: 0x0000, lo: 0x01}, + {value: 0x812d, lo: 0x90, hi: 0x96}, + // Block 0xa0, offset 0x353 + {value: 0x0000, lo: 0x02}, + {value: 0x8132, lo: 0x84, hi: 0x89}, + {value: 0x8102, lo: 0x8a, hi: 0x8a}, + // Block 0xa1, offset 0x356 + {value: 0x0002, lo: 0x0a}, + {value: 0x0063, lo: 0x80, hi: 0x89}, + {value: 0x1951, lo: 0x8a, hi: 0x8a}, + {value: 0x1984, lo: 0x8b, hi: 0x8b}, + {value: 0x199f, lo: 0x8c, hi: 0x8c}, + {value: 0x19a5, lo: 0x8d, hi: 0x8d}, + {value: 0x1bc3, lo: 0x8e, hi: 0x8e}, + {value: 0x19b1, lo: 0x8f, hi: 0x8f}, + {value: 0x197b, lo: 0xaa, hi: 0xaa}, + {value: 0x197e, lo: 0xab, hi: 0xab}, + {value: 0x1981, lo: 0xac, hi: 0xac}, + // Block 0xa2, offset 0x361 + {value: 0x0000, lo: 0x01}, + {value: 0x193f, lo: 0x90, hi: 0x90}, + // Block 0xa3, offset 0x363 + {value: 0x0028, lo: 0x09}, + {value: 0x2865, lo: 0x80, hi: 0x80}, + {value: 0x2829, lo: 0x81, hi: 0x81}, + {value: 0x2833, lo: 0x82, hi: 0x82}, + {value: 0x2847, lo: 0x83, hi: 0x84}, + {value: 0x2851, lo: 0x85, hi: 0x86}, + {value: 0x283d, lo: 0x87, hi: 0x87}, + {value: 0x285b, lo: 0x88, hi: 0x88}, + {value: 0x0b6f, lo: 0x90, hi: 0x90}, + {value: 0x08e7, lo: 0x91, hi: 0x91}, +} + +// recompMap: 7520 bytes (entries only) +var recompMap map[uint32]rune +var recompMapOnce sync.Once + +const recompMapPacked = "" + + "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0 + "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1 + "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2 + "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3 + "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4 + "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5 + "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7 + "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8 + "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9 + "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA + "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB + "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC + "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD + "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE + "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF + "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1 + "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2 + "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3 + "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4 + "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5 + "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6 + "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9 + "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA + "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB + "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC + "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD + "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0 + "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1 + "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2 + "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3 + "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4 + "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5 + "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7 + "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8 + "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9 + "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA + "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB + "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC + "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED + "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE + "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF + "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1 + "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2 + "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3 + "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4 + "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5 + "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6 + "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9 + "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA + "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB + "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC + "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD + "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF + "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100 + "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101 + "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102 + "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103 + "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104 + "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105 + "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106 + "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107 + "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108 + "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109 + "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A + "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B + "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C + "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D + "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E + "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F + "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112 + "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113 + "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114 + "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115 + "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116 + "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117 + "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118 + "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119 + "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A + "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B + "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C + "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D + "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E + "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F + "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120 + "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121 + "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122 + "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123 + "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124 + "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125 + "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128 + "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129 + "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A + "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B + "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C + "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D + "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E + "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F + "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130 + "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134 + "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135 + "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136 + "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137 + "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139 + "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A + "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B + "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C + "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D + "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E + "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143 + "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144 + "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145 + "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146 + "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147 + "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148 + "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C + "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D + "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E + "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F + "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150 + "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151 + "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154 + "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155 + "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156 + "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157 + "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158 + "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159 + "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A + "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B + "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C + "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D + "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E + "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F + "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160 + "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161 + "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162 + "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163 + "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164 + "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165 + "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168 + "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169 + "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A + "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B + "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C + "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D + "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E + "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F + "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170 + "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171 + "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172 + "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173 + "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174 + "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175 + "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176 + "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177 + "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178 + "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179 + "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A + "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B + "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C + "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D + "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E + "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0 + "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1 + "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF + "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0 + "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD + "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE + "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF + "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0 + "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1 + "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2 + "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3 + "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4 + "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5 + "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6 + "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7 + "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8 + "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9 + "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA + "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB + "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC + "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE + "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF + "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0 + "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1 + "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2 + "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3 + "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6 + "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7 + "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8 + "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9 + "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA + "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB + "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC + "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED + "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE + "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF + "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0 + "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4 + "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5 + "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8 + "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9 + "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA + "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB + "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC + "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD + "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE + "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF + "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200 + "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201 + "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202 + "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203 + "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204 + "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205 + "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206 + "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207 + "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208 + "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209 + "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A + "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B + "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C + "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D + "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E + "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F + "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210 + "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211 + "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212 + "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213 + "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214 + "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215 + "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216 + "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217 + "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218 + "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219 + "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A + "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B + "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E + "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F + "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226 + "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227 + "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228 + "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229 + "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A + "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B + "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C + "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D + "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E + "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F + "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230 + "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231 + "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232 + "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233 + "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385 + "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386 + "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388 + "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389 + "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A + "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C + "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E + "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F + "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390 + "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA + "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB + "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC + "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD + "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE + "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF + "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0 + "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA + "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB + "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC + "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD + "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE + "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3 + "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4 + "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400 + "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401 + "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403 + "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407 + "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C + "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D + "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E + "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419 + "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439 + "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450 + "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451 + "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453 + "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457 + "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C + "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D + "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E + "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476 + "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477 + "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1 + "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2 + "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0 + "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1 + "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2 + "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3 + "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6 + "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7 + "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA + "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB + "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC + "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD + "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE + "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF + "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2 + "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3 + "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4 + "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5 + "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6 + "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7 + "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA + "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB + "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC + "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED + "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE + "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF + "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0 + "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1 + "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2 + "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3 + "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4 + "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5 + "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8 + "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9 + "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622 + "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623 + "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624 + "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625 + "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626 + "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0 + "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2 + "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3 + "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929 + "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931 + "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934 + "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB + "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC + "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48 + "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B + "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C + "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94 + "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA + "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB + "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC + "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48 + "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0 + "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7 + "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8 + "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA + "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB + "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A + "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B + "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C + "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA + "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC + "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD + "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE + "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026 + "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06 + "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08 + "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A + "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C + "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E + "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12 + "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B + "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D + "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40 + "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41 + "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43 + "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00 + "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01 + "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02 + "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03 + "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04 + "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05 + "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06 + "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07 + "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08 + "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09 + "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A + "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B + "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C + "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D + "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E + "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F + "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10 + "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11 + "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12 + "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13 + "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14 + "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15 + "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16 + "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17 + "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18 + "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19 + "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A + "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B + "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C + "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D + "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E + "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F + "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20 + "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21 + "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22 + "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23 + "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24 + "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25 + "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26 + "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27 + "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28 + "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29 + "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A + "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B + "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C + "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D + "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E + "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F + "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30 + "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31 + "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32 + "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33 + "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34 + "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35 + "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36 + "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37 + "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38 + "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39 + "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A + "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B + "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C + "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D + "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E + "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F + "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40 + "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41 + "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42 + "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43 + "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44 + "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45 + "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46 + "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47 + "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48 + "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49 + "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A + "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B + "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C + "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D + "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E + "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F + "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50 + "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51 + "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52 + "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53 + "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54 + "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55 + "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56 + "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57 + "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58 + "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59 + "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A + "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B + "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C + "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D + "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E + "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F + "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60 + "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61 + "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62 + "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63 + "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64 + "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65 + "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66 + "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67 + "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68 + "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69 + "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A + "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B + "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C + "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D + "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E + "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F + "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70 + "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71 + "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72 + "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73 + "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74 + "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75 + "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76 + "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77 + "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78 + "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79 + "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A + "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B + "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C + "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D + "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E + "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F + "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 + "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 + "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 + "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83 + "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84 + "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85 + "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86 + "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87 + "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88 + "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89 + "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A + "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B + "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C + "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D + "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E + "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F + "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90 + "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91 + "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92 + "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93 + "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94 + "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95 + "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96 + "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 + "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 + "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 + "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B + "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 + "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 + "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 + "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3 + "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4 + "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5 + "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6 + "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7 + "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8 + "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9 + "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA + "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB + "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC + "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD + "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE + "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF + "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0 + "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1 + "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2 + "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3 + "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4 + "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5 + "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6 + "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7 + "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8 + "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9 + "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA + "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB + "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC + "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD + "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE + "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF + "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0 + "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1 + "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2 + "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3 + "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4 + "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5 + "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6 + "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7 + "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8 + "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9 + "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA + "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB + "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC + "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD + "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE + "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF + "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0 + "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1 + "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2 + "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3 + "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4 + "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5 + "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6 + "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7 + "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8 + "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9 + "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA + "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB + "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC + "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD + "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE + "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF + "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0 + "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1 + "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2 + "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3 + "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4 + "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5 + "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6 + "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7 + "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8 + "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9 + "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA + "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB + "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC + "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED + "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE + "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF + "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0 + "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1 + "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2 + "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3 + "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4 + "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5 + "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6 + "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7 + "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8 + "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9 + "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00 + "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01 + "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02 + "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03 + "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04 + "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05 + "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06 + "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07 + "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08 + "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09 + "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A + "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B + "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C + "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D + "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E + "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F + "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10 + "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11 + "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12 + "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13 + "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14 + "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15 + "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18 + "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19 + "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A + "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B + "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C + "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D + "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20 + "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21 + "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22 + "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23 + "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24 + "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25 + "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26 + "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27 + "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28 + "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29 + "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A + "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B + "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C + "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D + "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E + "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F + "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30 + "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31 + "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32 + "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33 + "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34 + "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35 + "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36 + "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37 + "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38 + "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39 + "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A + "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B + "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C + "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D + "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E + "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F + "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40 + "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41 + "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42 + "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43 + "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44 + "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45 + "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48 + "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49 + "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A + "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B + "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C + "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D + "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50 + "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51 + "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52 + "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53 + "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54 + "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55 + "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56 + "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57 + "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59 + "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B + "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D + "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F + "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60 + "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61 + "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62 + "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63 + "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64 + "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65 + "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66 + "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67 + "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68 + "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69 + "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A + "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B + "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C + "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D + "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E + "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F + "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70 + "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72 + "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74 + "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76 + "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78 + "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A + "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C + "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80 + "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81 + "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82 + "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83 + "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84 + "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85 + "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86 + "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87 + "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88 + "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89 + "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A + "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B + "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C + "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D + "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E + "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F + "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90 + "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91 + "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92 + "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93 + "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94 + "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95 + "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96 + "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97 + "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98 + "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99 + "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A + "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B + "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C + "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D + "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E + "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F + "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0 + "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1 + "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2 + "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3 + "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4 + "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5 + "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6 + "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7 + "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8 + "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9 + "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA + "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB + "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC + "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD + "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE + "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF + "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0 + "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1 + "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2 + "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3 + "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4 + "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6 + "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7 + "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8 + "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9 + "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA + "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC + "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1 + "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2 + "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3 + "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4 + "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6 + "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7 + "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8 + "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA + "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC + "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD + "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE + "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF + "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0 + "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1 + "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2 + "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6 + "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7 + "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8 + "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9 + "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA + "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD + "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE + "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF + "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0 + "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1 + "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2 + "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4 + "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5 + "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6 + "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7 + "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8 + "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9 + "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA + "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC + "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED + "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2 + "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3 + "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4 + "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6 + "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7 + "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8 + "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA + "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC + "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A + "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B + "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE + "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD + "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE + "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF + "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204 + "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209 + "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C + "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224 + "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226 + "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241 + "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244 + "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247 + "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249 + "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260 + "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262 + "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D + "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E + "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F + "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270 + "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271 + "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274 + "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275 + "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278 + "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279 + "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280 + "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281 + "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284 + "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285 + "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288 + "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289 + "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC + "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD + "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE + "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF + "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0 + "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1 + "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2 + "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3 + "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA + "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB + "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC + "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED + "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C + "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E + "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050 + "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052 + "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054 + "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056 + "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058 + "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A + "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C + "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E + "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060 + "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062 + "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065 + "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067 + "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069 + "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070 + "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071 + "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073 + "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074 + "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076 + "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077 + "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079 + "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A + "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C + "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D + "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094 + "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E + "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC + "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE + "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0 + "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2 + "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4 + "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6 + "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8 + "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA + "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC + "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE + "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0 + "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2 + "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5 + "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7 + "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9 + "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0 + "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1 + "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3 + "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4 + "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6 + "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7 + "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9 + "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA + "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC + "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD + "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4 + "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7 + "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8 + "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9 + "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA + "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE + "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A + "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C + "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB + "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E + "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F + "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B + "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C + "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB + "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC + "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE + "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA + "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB + "" + // Total size of tables: 55KB (55977 bytes) diff --git a/libgo/go/golang.org/x/tools/go/analysis/analysis.go b/libgo/go/golang.org/x/tools/go/analysis/analysis.go index 19e1e421a38..ea605f4fd46 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/analysis.go +++ b/libgo/go/golang.org/x/tools/go/analysis/analysis.go @@ -128,11 +128,13 @@ type Pass struct { // See comments for ExportObjectFact. ExportPackageFact func(fact Fact) - // AllPackageFacts returns a new slice containing all package facts in unspecified order. + // AllPackageFacts returns a new slice containing all package facts of the analysis's FactTypes + // in unspecified order. // WARNING: This is an experimental API and may change in the future. AllPackageFacts func() []PackageFact - // AllObjectFacts returns a new slice containing all object facts in unspecified order. + // AllObjectFacts returns a new slice containing all object facts of the analysis's FactTypes + // in unspecified order. // WARNING: This is an experimental API and may change in the future. AllObjectFacts func() []ObjectFact @@ -161,13 +163,19 @@ func (pass *Pass) Reportf(pos token.Pos, format string, args ...interface{}) { pass.Report(Diagnostic{Pos: pos, Message: msg}) } -// reportNodef is a helper function that reports a Diagnostic using the -// range denoted by the AST node. -// -// WARNING: This is an experimental API and may change in the future. -func (pass *Pass) reportNodef(node ast.Node, format string, args ...interface{}) { +// The Range interface provides a range. It's equivalent to and satisfied by +// ast.Node. +type Range interface { + Pos() token.Pos // position of first character belonging to the node + End() token.Pos // position of first character immediately after the node +} + +// ReportRangef is a helper function that reports a Diagnostic using the +// range provided. ast.Node values can be passed in as the range because +// they satisfy the Range interface. +func (pass *Pass) ReportRangef(rng Range, format string, args ...interface{}) { msg := fmt.Sprintf(format, args...) - pass.Report(Diagnostic{Pos: node.Pos(), End: node.End(), Message: msg}) + pass.Report(Diagnostic{Pos: rng.Pos(), End: rng.End(), Message: msg}) } func (pass *Pass) String() string { @@ -211,18 +219,3 @@ func (pass *Pass) String() string { type Fact interface { AFact() // dummy method to avoid type errors } - -// A Diagnostic is a message associated with a source location or range. -// -// An Analyzer may return a variety of diagnostics; the optional Category, -// which should be a constant, may be used to classify them. -// It is primarily intended to make it easy to look up documentation. -// -// If End is provided, the diagnostic is specified to apply to the range between -// Pos and End. -type Diagnostic struct { - Pos token.Pos - End token.Pos // optional - Category string // optional - Message string -} diff --git a/libgo/go/golang.org/x/tools/go/analysis/diagnostic.go b/libgo/go/golang.org/x/tools/go/analysis/diagnostic.go new file mode 100644 index 00000000000..57eaf6faa2a --- /dev/null +++ b/libgo/go/golang.org/x/tools/go/analysis/diagnostic.go @@ -0,0 +1,61 @@ +package analysis + +import "go/token" + +// A Diagnostic is a message associated with a source location or range. +// +// An Analyzer may return a variety of diagnostics; the optional Category, +// which should be a constant, may be used to classify them. +// It is primarily intended to make it easy to look up documentation. +// +// If End is provided, the diagnostic is specified to apply to the range between +// Pos and End. +type Diagnostic struct { + Pos token.Pos + End token.Pos // optional + Category string // optional + Message string + + // SuggestedFixes contains suggested fixes for a diagnostic which can be used to perform + // edits to a file that address the diagnostic. + // TODO(matloob): Should multiple SuggestedFixes be allowed for a diagnostic? + // Diagnostics should not contain SuggestedFixes that overlap. + // Experimental: This API is experimental and may change in the future. + SuggestedFixes []SuggestedFix // optional + + // Experimental: This API is experimental and may change in the future. + Related []RelatedInformation // optional +} + +// RelatedInformation contains information related to a diagnostic. +// For example, a diagnostic that flags duplicated declarations of a +// variable may include one RelatedInformation per existing +// declaration. +type RelatedInformation struct { + Pos token.Pos + End token.Pos + Message string +} + +// A SuggestedFix is a code change associated with a Diagnostic that a user can choose +// to apply to their code. Usually the SuggestedFix is meant to fix the issue flagged +// by the diagnostic. +// TextEdits for a SuggestedFix should not overlap. TextEdits for a SuggestedFix +// should not contain edits for other packages. +// Experimental: This API is experimental and may change in the future. +type SuggestedFix struct { + // A description for this suggested fix to be shown to a user deciding + // whether to accept it. + Message string + TextEdits []TextEdit +} + +// A TextEdit represents the replacement of the code between Pos and End with the new text. +// Each TextEdit should apply to a single file. End should not be earlier in the file than Pos. +// Experimental: This API is experimental and may change in the future. +type TextEdit struct { + // For a pure insertion, End can either be set to Pos or token.NoPos. + Pos token.Pos + End token.Pos + NewText []byte +} diff --git a/libgo/go/golang.org/x/tools/go/analysis/doc.go b/libgo/go/golang.org/x/tools/go/analysis/doc.go index 2d44b0458a9..a2353fc88b9 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/doc.go +++ b/libgo/go/golang.org/x/tools/go/analysis/doc.go @@ -67,7 +67,7 @@ To add a new Analyzer to an existing driver, add another item to the list: } A driver may use the name, flags, and documentation to provide on-line -help that describes the analyses its performs. +help that describes the analyses it performs. The doc comment contains a brief one-line summary, optionally followed by paragraphs of explanation. The vet command, shown below, is an example of a driver that runs @@ -169,7 +169,7 @@ type information, and source positions for a single package of Go code. The OtherFiles field provides the names, but not the contents, of non-Go files such as assembly that are part of this package. See the "asmdecl" -or "buildtags" analyzers for examples of loading non-Go files and report +or "buildtags" analyzers for examples of loading non-Go files and reporting diagnostics against them. The ResultOf field provides the results computed by the analyzers @@ -231,7 +231,7 @@ understood as alternative or non-standard type systems. For example, vet's printf checker infers whether a function has the "printf wrapper" type, and it applies stricter checks to calls of such functions. In addition, it records which functions are printf wrappers for use by -later analysis units to identify other printf wrappers by induction. +later analysis passes to identify other printf wrappers by induction. A result such as “f is a printf wrapper” that is not interesting by itself but serves as a stepping stone to an interesting result (such as a diagnostic) is called a "fact". @@ -252,9 +252,9 @@ An Analyzer that uses facts must declare their types: type isWrapper struct{} // => *types.Func f “is a printf wrapper” -A driver program ensures that facts for a pass’s dependencies are -generated before analyzing the pass and are responsible for propagating -facts between from one pass to another, possibly across address spaces. +The driver program ensures that facts for a pass’s dependencies are +generated before analyzing the package and is responsible for propagating +facts from one package to another, possibly across address spaces. Consequently, Facts must be serializable. The API requires that drivers use the gob encoding, an efficient, robust, self-describing binary protocol. A fact type may implement the GobEncoder/GobDecoder interfaces @@ -288,10 +288,10 @@ not currently apply analyzers to packages of the standard library. Therefore, for best results, analyzer authors should not rely on analysis facts being available for standard packages. For example, although the printf checker is capable of deducing during -analysis of the log package that log.Printf is a printf-wrapper, +analysis of the log package that log.Printf is a printf wrapper, this fact is built in to the analyzer so that it correctly checks calls to log.Printf even when run in a driver that does not apply -it to standard packages. We plan to remove this limitation in future. +it to standard packages. We would like to remove this limitation in future. Testing an Analyzer diff --git a/libgo/go/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go b/libgo/go/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go index a3c2f096300..0778f422074 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go +++ b/libgo/go/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go @@ -168,10 +168,10 @@ func printFlags() { var flags []jsonFlag = nil flag.VisitAll(func(f *flag.Flag) { // Don't report {single,multi}checker debugging - // flags as these have no effect on unitchecker + // flags or fix as these have no effect on unitchecker // (as invoked by 'go vet'). switch f.Name { - case "debug", "cpuprofile", "memprofile", "trace": + case "debug", "cpuprofile", "memprofile", "trace", "fix": return } @@ -209,7 +209,7 @@ func (versionFlag) Set(s string) error { log.Fatalf("unsupported flag value: -V=%s", s) } - // This replicates the miminal subset of + // This replicates the minimal subset of // cmd/internal/objabi.AddVersionFlag, which is private to the // go tool yet forms part of our command-line interface. // TODO(adonovan): clarify the contract. diff --git a/libgo/go/golang.org/x/tools/go/analysis/internal/facts/facts.go b/libgo/go/golang.org/x/tools/go/analysis/internal/facts/facts.go index 468f148900f..1fb69c61591 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/internal/facts/facts.go +++ b/libgo/go/golang.org/x/tools/go/analysis/internal/facts/facts.go @@ -29,7 +29,7 @@ // The notion of "exportedness" that matters here is that of the // compiler. According to the language spec, a method pkg.T.f is // unexported simply because its name starts with lowercase. But the -// compiler must nonethless export f so that downstream compilations can +// compiler must nonetheless export f so that downstream compilations can // accurately ascertain whether pkg.T implements an interface pkg.I // defined as interface{f()}. Exported thus means "described in export // data". @@ -99,6 +99,18 @@ func (s *Set) ExportObjectFact(obj types.Object, fact analysis.Fact) { s.mu.Unlock() } +func (s *Set) AllObjectFacts(filter map[reflect.Type]bool) []analysis.ObjectFact { + var facts []analysis.ObjectFact + s.mu.Lock() + for k, v := range s.m { + if k.obj != nil && filter[k.t] { + facts = append(facts, analysis.ObjectFact{Object: k.obj, Fact: v}) + } + } + s.mu.Unlock() + return facts +} + // ImportPackageFact implements analysis.Pass.ImportPackageFact. func (s *Set) ImportPackageFact(pkg *types.Package, ptr analysis.Fact) bool { if pkg == nil { @@ -122,6 +134,18 @@ func (s *Set) ExportPackageFact(fact analysis.Fact) { s.mu.Unlock() } +func (s *Set) AllPackageFacts(filter map[reflect.Type]bool) []analysis.PackageFact { + var facts []analysis.PackageFact + s.mu.Lock() + for k, v := range s.m { + if k.obj == nil && filter[k.t] { + facts = append(facts, analysis.PackageFact{Package: k.pkg, Fact: v}) + } + } + s.mu.Unlock() + return facts +} + // gobFact is the Gob declaration of a serialized fact. type gobFact struct { PkgPath string // path of package diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go b/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go index d41c4e97e32..5c93a4f7030 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/asmdecl/asmdecl.go @@ -22,9 +22,11 @@ import ( "golang.org/x/tools/go/analysis/passes/internal/analysisutil" ) +const Doc = "report mismatches between assembly files and Go declarations" + var Analyzer = &analysis.Analyzer{ Name: "asmdecl", - Doc: "report mismatches between assembly files and Go declarations", + Doc: Doc, Run: run, } @@ -79,7 +81,6 @@ var ( asmArchArm = asmArch{name: "arm", bigEndian: false, stack: "R13", lr: true} asmArchArm64 = asmArch{name: "arm64", bigEndian: false, stack: "RSP", lr: true} asmArchAmd64 = asmArch{name: "amd64", bigEndian: false, stack: "SP", lr: false} - asmArchAmd64p32 = asmArch{name: "amd64p32", bigEndian: false, stack: "SP", lr: false} asmArchMips = asmArch{name: "mips", bigEndian: true, stack: "R29", lr: true} asmArchMipsLE = asmArch{name: "mipsle", bigEndian: false, stack: "R29", lr: true} asmArchMips64 = asmArch{name: "mips64", bigEndian: true, stack: "R29", lr: true} @@ -94,7 +95,6 @@ var ( &asmArchArm, &asmArchArm64, &asmArchAmd64, - &asmArchAmd64p32, &asmArchMips, &asmArchMipsLE, &asmArchMips64, @@ -635,9 +635,6 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri case "amd64.LEAQ": dst = 8 addr = true - case "amd64p32.LEAL": - dst = 4 - addr = true default: switch fn.arch.name { case "386", "amd64": @@ -666,6 +663,10 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri src = 4 break } + if op == "MOVO" || op == "MOVOU" { + src = 16 + break + } if strings.HasPrefix(op, "SET") { // SETEQ, etc src = 1 @@ -741,6 +742,11 @@ func asmCheckVar(badf func(string, ...interface{}), fn *asmFunc, line, expr stri vk = v.inner[0].kind vs = v.inner[0].size vt = v.inner[0].typ + case asmComplex: + // Allow a single instruction to load both parts of a complex. + if int(kind) == vs { + kind = asmComplex + } } if addr { vk = asmKind(archDef.ptrSize) diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/assign/assign.go b/libgo/go/golang.org/x/tools/go/analysis/passes/assign/assign.go index 4dff2908c32..3586638efc0 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/assign/assign.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/assign/assign.go @@ -9,6 +9,7 @@ package assign // methods that are on T instead of *T. import ( + "fmt" "go/ast" "go/token" "reflect" @@ -59,7 +60,14 @@ func run(pass *analysis.Pass) (interface{}, error) { le := analysisutil.Format(pass.Fset, lhs) re := analysisutil.Format(pass.Fset, rhs) if le == re { - pass.Reportf(stmt.Pos(), "self-assignment of %s to %s", re, le) + pass.Report(analysis.Diagnostic{ + Pos: stmt.Pos(), Message: fmt.Sprintf("self-assignment of %s to %s", re, le), + SuggestedFixes: []analysis.SuggestedFix{ + {Message: "Remove", TextEdits: []analysis.TextEdit{ + {Pos: stmt.Pos(), End: stmt.End(), NewText: []byte{}}, + }}, + }, + }) } } }) diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/atomic/atomic.go b/libgo/go/golang.org/x/tools/go/analysis/passes/atomic/atomic.go index 45243d6f8c0..9261db7e4e5 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/atomic/atomic.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/atomic/atomic.go @@ -91,6 +91,6 @@ func checkAtomicAddAssignment(pass *analysis.Pass, left ast.Expr, call *ast.Call } if broken { - pass.Reportf(left.Pos(), "direct assignment to atomic value") + pass.ReportRangef(left, "direct assignment to atomic value") } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/bools/bools.go b/libgo/go/golang.org/x/tools/go/analysis/passes/bools/bools.go index c82d3675b95..5ae47d8948f 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/bools/bools.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/bools/bools.go @@ -17,9 +17,11 @@ import ( "golang.org/x/tools/go/ast/inspector" ) +const Doc = "check for common mistakes involving boolean operators" + var Analyzer = &analysis.Analyzer{ Name: "bools", - Doc: "check for common mistakes involving boolean operators", + Doc: Doc, Requires: []*analysis.Analyzer{inspect.Analyzer}, Run: run, } @@ -100,7 +102,7 @@ func (op boolOp) checkRedundant(pass *analysis.Pass, exprs []ast.Expr) { for _, e := range exprs { efmt := analysisutil.Format(pass.Fset, e) if seen[efmt] { - pass.Reportf(e.Pos(), "redundant %s: %s %s %s", op.name, efmt, op.tok, efmt) + pass.ReportRangef(e, "redundant %s: %s %s %s", op.name, efmt, op.tok, efmt) } else { seen[efmt] = true } @@ -147,7 +149,7 @@ func (op boolOp) checkSuspect(pass *analysis.Pass, exprs []ast.Expr) { if prev, found := seen[xfmt]; found { // checkRedundant handles the case in which efmt == prev. if efmt != prev { - pass.Reportf(e.Pos(), "suspect %s: %s %s %s", op.name, efmt, op.tok, prev) + pass.ReportRangef(e, "suspect %s: %s %s %s", op.name, efmt, op.tok, prev) } } else { seen[xfmt] = efmt diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go b/libgo/go/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go index 5a441e609b6..78176f10114 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/buildtag/buildtag.go @@ -16,9 +16,11 @@ import ( "golang.org/x/tools/go/analysis/passes/internal/analysisutil" ) +const Doc = "check that +build tags are well-formed and correctly located" + var Analyzer = &analysis.Analyzer{ Name: "buildtag", - Doc: "check that +build tags are well-formed and correctly located", + Doc: Doc, Run: runBuildTag, } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go b/libgo/go/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go index 42a690dbab6..7f7ca088b25 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/cgocall/cgocall.go @@ -24,7 +24,7 @@ import ( const debug = false -const doc = `detect some violations of the cgo pointer passing rules +const Doc = `detect some violations of the cgo pointer passing rules Check for invalid cgo pointer passing. This looks for code that uses cgo to call C code passing values @@ -35,7 +35,7 @@ or slice to C, either directly, or via a pointer, array, or struct.` var Analyzer = &analysis.Analyzer{ Name: "cgocall", - Doc: doc, + Doc: Doc, RunDespiteErrors: true, Run: run, } @@ -108,7 +108,7 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t // cgo files of a package (those that import "C"). Such files are not // Go, so there may be gaps in type information around C.f references. // -// This checker was initially written in vet to inpect raw cgo source +// This checker was initially written in vet to inspect raw cgo source // files using partial type information. However, Analyzers in the new // analysis API are presented with the type-checked, "cooked" Go ASTs // resulting from cgo-processing files, so we must choose between @@ -134,7 +134,7 @@ func checkCgo(fset *token.FileSet, f *ast.File, info *types.Info, reportf func(t // func (T) f(int) string { ... } // // we synthesize a new ast.File, shown below, that dot-imports the -// orginal "cooked" package using a special name ("·this·"), so that all +// original "cooked" package using a special name ("·this·"), so that all // references to package members resolve correctly. (References to // unexported names cause an "unexported" error, which we ignore.) // diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/composite/composite.go b/libgo/go/golang.org/x/tools/go/analysis/passes/composite/composite.go index 2abe7c6d51e..4c3ac6647f6 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/composite/composite.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/composite/composite.go @@ -97,7 +97,7 @@ func run(pass *analysis.Pass) (interface{}, error) { return } - pass.Reportf(cl.Pos(), "%s composite literal uses unkeyed fields", typeName) + pass.ReportRangef(cl, "%s composite literal uses unkeyed fields", typeName) }) return nil, nil } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/composite/whitelist.go b/libgo/go/golang.org/x/tools/go/analysis/passes/composite/whitelist.go index ab609f279bc..1e5f5fd20b5 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/composite/whitelist.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/composite/whitelist.go @@ -24,6 +24,7 @@ var unkeyedLiteral = map[string]bool{ "image.Uniform": true, "unicode.Range16": true, + "unicode.Range32": true, // These three structs are used in generated test main files, // but the generator can be trusted. diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/copylock/copylock.go b/libgo/go/golang.org/x/tools/go/analysis/passes/copylock/copylock.go index 067aed57df3..c4ebf785710 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/copylock/copylock.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/copylock/copylock.go @@ -74,7 +74,7 @@ func run(pass *analysis.Pass) (interface{}, error) { func checkCopyLocksAssign(pass *analysis.Pass, as *ast.AssignStmt) { for i, x := range as.Rhs { if path := lockPathRhs(pass, x); path != nil { - pass.Reportf(x.Pos(), "assignment copies lock value to %v: %v", analysisutil.Format(pass.Fset, as.Lhs[i]), path) + pass.ReportRangef(x, "assignment copies lock value to %v: %v", analysisutil.Format(pass.Fset, as.Lhs[i]), path) } } } @@ -89,7 +89,7 @@ func checkCopyLocksGenDecl(pass *analysis.Pass, gd *ast.GenDecl) { valueSpec := spec.(*ast.ValueSpec) for i, x := range valueSpec.Values { if path := lockPathRhs(pass, x); path != nil { - pass.Reportf(x.Pos(), "variable declaration copies lock value to %v: %v", valueSpec.Names[i].Name, path) + pass.ReportRangef(x, "variable declaration copies lock value to %v: %v", valueSpec.Names[i].Name, path) } } } @@ -102,7 +102,7 @@ func checkCopyLocksCompositeLit(pass *analysis.Pass, cl *ast.CompositeLit) { x = node.Value } if path := lockPathRhs(pass, x); path != nil { - pass.Reportf(x.Pos(), "literal copies lock value from %v: %v", analysisutil.Format(pass.Fset, x), path) + pass.ReportRangef(x, "literal copies lock value from %v: %v", analysisutil.Format(pass.Fset, x), path) } } } @@ -111,7 +111,7 @@ func checkCopyLocksCompositeLit(pass *analysis.Pass, cl *ast.CompositeLit) { func checkCopyLocksReturnStmt(pass *analysis.Pass, rs *ast.ReturnStmt) { for _, x := range rs.Results { if path := lockPathRhs(pass, x); path != nil { - pass.Reportf(x.Pos(), "return copies lock value: %v", path) + pass.ReportRangef(x, "return copies lock value: %v", path) } } } @@ -133,7 +133,7 @@ func checkCopyLocksCallExpr(pass *analysis.Pass, ce *ast.CallExpr) { } for _, x := range ce.Args { if path := lockPathRhs(pass, x); path != nil { - pass.Reportf(x.Pos(), "call of %s copies lock value: %v", analysisutil.Format(pass.Fset, ce.Fun), path) + pass.ReportRangef(x, "call of %s copies lock value: %v", analysisutil.Format(pass.Fset, ce.Fun), path) } } } @@ -146,7 +146,7 @@ func checkCopyLocksFunc(pass *analysis.Pass, name string, recv *ast.FieldList, t if recv != nil && len(recv.List) > 0 { expr := recv.List[0].Type if path := lockPath(pass.Pkg, pass.TypesInfo.Types[expr].Type); path != nil { - pass.Reportf(expr.Pos(), "%s passes lock by value: %v", name, path) + pass.ReportRangef(expr, "%s passes lock by value: %v", name, path) } } @@ -154,7 +154,7 @@ func checkCopyLocksFunc(pass *analysis.Pass, name string, recv *ast.FieldList, t for _, field := range typ.Params.List { expr := field.Type if path := lockPath(pass.Pkg, pass.TypesInfo.Types[expr].Type); path != nil { - pass.Reportf(expr.Pos(), "%s passes lock by value: %v", name, path) + pass.ReportRangef(expr, "%s passes lock by value: %v", name, path) } } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/ctrlflow/ctrlflow.go b/libgo/go/golang.org/x/tools/go/analysis/passes/ctrlflow/ctrlflow.go index 75655c5bad4..51600ffc7eb 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/ctrlflow/ctrlflow.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/ctrlflow/ctrlflow.go @@ -102,10 +102,11 @@ func run(pass *analysis.Pass) (interface{}, error) { inspect.Preorder(nodeFilter, func(n ast.Node) { switch n := n.(type) { case *ast.FuncDecl: - fn := pass.TypesInfo.Defs[n.Name].(*types.Func) - funcDecls[fn] = &declInfo{decl: n} - decls = append(decls, fn) - + // Type information may be incomplete. + if fn, ok := pass.TypesInfo.Defs[n.Name].(*types.Func); ok { + funcDecls[fn] = &declInfo{decl: n} + decls = append(decls, fn) + } case *ast.FuncLit: funcLits[n] = new(litInfo) lits = append(lits, n) diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go b/libgo/go/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go index c411466c28e..b80271afb95 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/errorsas/errorsas.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// The errorsas package defines an Analyzer that checks that the second arugment to +// The errorsas package defines an Analyzer that checks that the second argument to // errors.As is a pointer to a type implementing error. package errorsas @@ -16,14 +16,14 @@ import ( "golang.org/x/tools/go/types/typeutil" ) -const doc = `report passing non-pointer or non-error values to errors.As +const Doc = `report passing non-pointer or non-error values to errors.As The errorsas analysis reports calls to errors.As where the type of the second argument is not a pointer to a type implementing error.` var Analyzer = &analysis.Analyzer{ Name: "errorsas", - Doc: doc, + Doc: Doc, Requires: []*analysis.Analyzer{inspect.Analyzer}, Run: run, } @@ -51,7 +51,7 @@ func run(pass *analysis.Pass) (interface{}, error) { return // not enough arguments, e.g. called with return values of another function } if fn.FullName() == "errors.As" && !pointerToInterfaceOrError(pass, call.Args[1]) { - pass.Reportf(call.Pos(), "second argument to errors.As must be a pointer to an interface or a type implementing error") + pass.ReportRangef(call, "second argument to errors.As must be a pointer to an interface or a type implementing error") } }) return nil, nil diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go b/libgo/go/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go index 0cf21b8cd1e..ec335d35061 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/httpresponse/httpresponse.go @@ -85,7 +85,7 @@ func run(pass *analysis.Pass) (interface{}, error) { } if resp.Obj == root.Obj { - pass.Reportf(root.Pos(), "using %s before checking for errors", resp.Name) + pass.ReportRangef(root, "using %s before checking for errors", resp.Name) } return true }) diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/inspect/inspect.go b/libgo/go/golang.org/x/tools/go/analysis/passes/inspect/inspect.go index 8213f633135..2856df137c5 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/inspect/inspect.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/inspect/inspect.go @@ -16,7 +16,7 @@ // // var Analyzer = &analysis.Analyzer{ // ... -// Requires: reflect.TypeOf(new(inspect.Analyzer)), +// Requires: []*analysis.Analyzer{inspect.Analyzer}, // } // // func run(pass *analysis.Pass) (interface{}, error) { diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go b/libgo/go/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go index da0714069f7..a14e7eb55d0 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/loopclosure/loopclosure.go @@ -119,7 +119,7 @@ func run(pass *analysis.Pass) (interface{}, error) { } for _, v := range vars { if v.Obj == id.Obj { - pass.Reportf(id.Pos(), "loop variable %s captured by func literal", + pass.ReportRangef(id, "loop variable %s captured by func literal", id.Name) } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/lostcancel/lostcancel.go b/libgo/go/golang.org/x/tools/go/analysis/passes/lostcancel/lostcancel.go index e88cf57d8f7..de6f840f685 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/lostcancel/lostcancel.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/lostcancel/lostcancel.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Package lostcancel defines an Analyzer that checks for failure to -// call a context cancelation function. +// call a context cancellation function. package lostcancel import ( @@ -20,7 +20,7 @@ import ( const Doc = `check cancel func returned by context.WithCancel is called -The cancelation function returned by context.WithCancel, WithTimeout, +The cancellation function returned by context.WithCancel, WithTimeout, and WithDeadline must be called or the new context will remain live until its parent context is cancelled. (The background context is never cancelled.)` @@ -121,7 +121,7 @@ func runFunc(pass *analysis.Pass, node ast.Node) { } if id != nil { if id.Name == "_" { - pass.Reportf(id.Pos(), + pass.ReportRangef(id, "the cancel function returned by context.%s should be called, not discarded, to avoid a context leak", n.(*ast.SelectorExpr).Sel.Name) } else if v, ok := pass.TypesInfo.Uses[id].(*types.Var); ok { @@ -174,8 +174,8 @@ func runFunc(pass *analysis.Pass, node ast.Node) { for v, stmt := range cancelvars { if ret := lostCancelPath(pass, g, v, stmt, sig); ret != nil { lineno := pass.Fset.Position(stmt.Pos()).Line - pass.Reportf(stmt.Pos(), "the %s function is not used on all paths (possible context leak)", v.Name()) - pass.Reportf(ret.Pos(), "this return statement may be reached without using the %s var defined on line %d", v.Name(), lineno) + pass.ReportRangef(stmt, "the %s function is not used on all paths (possible context leak)", v.Name()) + pass.ReportRangef(ret, "this return statement may be reached without using the %s var defined on line %d", v.Name(), lineno) } } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/nilfunc/nilfunc.go b/libgo/go/golang.org/x/tools/go/analysis/passes/nilfunc/nilfunc.go index 9c2d4df20a0..cd42c9897f2 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/nilfunc/nilfunc.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/nilfunc/nilfunc.go @@ -68,7 +68,7 @@ func run(pass *analysis.Pass) (interface{}, error) { return } - pass.Reportf(e.Pos(), "comparison of function %v %v nil is always %v", obj.Name(), e.Op, e.Op == token.NEQ) + pass.ReportRangef(e, "comparison of function %v %v nil is always %v", obj.Name(), e.Op, e.Op == token.NEQ) }) return nil, nil } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/printf/printf.go b/libgo/go/golang.org/x/tools/go/analysis/passes/printf/printf.go index f59e95dc219..a81dba91251 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/printf/printf.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/printf/printf.go @@ -13,6 +13,7 @@ import ( "go/constant" "go/token" "go/types" + "reflect" "regexp" "sort" "strconv" @@ -31,14 +32,15 @@ func init() { } var Analyzer = &analysis.Analyzer{ - Name: "printf", - Doc: doc, - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Run: run, - FactTypes: []analysis.Fact{new(isWrapper)}, + Name: "printf", + Doc: Doc, + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, + ResultType: reflect.TypeOf((*Result)(nil)), + FactTypes: []analysis.Fact{new(isWrapper)}, } -const doc = `check consistency of Printf format strings and arguments +const Doc = `check consistency of Printf format strings and arguments The check applies to known functions (for example, those in package fmt) as well as any detected wrappers of known functions. @@ -66,23 +68,77 @@ argument list. Otherwise it is assumed to be Print-like, taking a list of arguments with no format string. ` +// Kind is a kind of fmt function behavior. +type Kind int + +const ( + KindNone Kind = iota // not a fmt wrapper function + KindPrint // function behaves like fmt.Print + KindPrintf // function behaves like fmt.Printf + KindErrorf // function behaves like fmt.Errorf +) + +func (kind Kind) String() string { + switch kind { + case KindPrint: + return "print" + case KindPrintf: + return "printf" + case KindErrorf: + return "errorf" + } + return "" +} + +// Result is the printf analyzer's result type. Clients may query the result +// to learn whether a function behaves like fmt.Print or fmt.Printf. +type Result struct { + funcs map[*types.Func]Kind +} + +// Kind reports whether fn behaves like fmt.Print or fmt.Printf. +func (r *Result) Kind(fn *types.Func) Kind { + _, ok := isPrint[fn.FullName()] + if !ok { + // Next look up just "printf", for use with -printf.funcs. + _, ok = isPrint[strings.ToLower(fn.Name())] + } + if ok { + if strings.HasSuffix(fn.Name(), "f") { + return KindPrintf + } else { + return KindPrint + } + } + + return r.funcs[fn] +} + // isWrapper is a fact indicating that a function is a print or printf wrapper. -type isWrapper struct{ Printf bool } +type isWrapper struct{ Kind Kind } func (f *isWrapper) AFact() {} func (f *isWrapper) String() string { - if f.Printf { + switch f.Kind { + case KindPrintf: return "printfWrapper" - } else { + case KindPrint: return "printWrapper" + case KindErrorf: + return "errorfWrapper" + default: + return "unknownWrapper" } } func run(pass *analysis.Pass) (interface{}, error) { - findPrintfLike(pass) + res := &Result{ + funcs: make(map[*types.Func]Kind), + } + findPrintfLike(pass, res) checkCall(pass) - return nil, nil + return res, nil } type printfWrapper struct { @@ -112,7 +168,11 @@ func maybePrintfWrapper(info *types.Info, decl ast.Decl) *printfWrapper { if !ok || fdecl.Body == nil { return nil } - fn := info.Defs[fdecl.Name].(*types.Func) + fn, ok := info.Defs[fdecl.Name].(*types.Func) + // Type information may be incomplete. + if !ok { + return nil + } sig := fn.Type().(*types.Signature) if !sig.Variadic() { @@ -145,7 +205,7 @@ func maybePrintfWrapper(info *types.Info, decl ast.Decl) *printfWrapper { } // findPrintfLike scans the entire package to find printf-like functions. -func findPrintfLike(pass *analysis.Pass) (interface{}, error) { +func findPrintfLike(pass *analysis.Pass, res *Result) (interface{}, error) { // Gather potential wrappers and call graph between them. byObj := make(map[*types.Func]*printfWrapper) var wrappers []*printfWrapper @@ -200,7 +260,7 @@ func findPrintfLike(pass *analysis.Pass) (interface{}, error) { fn, kind := printfNameAndKind(pass, call) if kind != 0 { - checkPrintfFwd(pass, w, call, kind) + checkPrintfFwd(pass, w, call, kind, res) return true } @@ -223,16 +283,11 @@ func match(info *types.Info, arg ast.Expr, param *types.Var) bool { return ok && info.ObjectOf(id) == param } -const ( - kindPrintf = 1 - kindPrint = 2 -) - // checkPrintfFwd checks that a printf-forwarding wrapper is forwarding correctly. // It diagnoses writing fmt.Printf(format, args) instead of fmt.Printf(format, args...). -func checkPrintfFwd(pass *analysis.Pass, w *printfWrapper, call *ast.CallExpr, kind int) { - matched := kind == kindPrint || - kind == kindPrintf && len(call.Args) >= 2 && match(pass.TypesInfo, call.Args[len(call.Args)-2], w.format) +func checkPrintfFwd(pass *analysis.Pass, w *printfWrapper, call *ast.CallExpr, kind Kind, res *Result) { + matched := kind == KindPrint || + kind != KindNone && len(call.Args) >= 2 && match(pass.TypesInfo, call.Args[len(call.Args)-2], w.format) if !matched { return } @@ -253,19 +308,20 @@ func checkPrintfFwd(pass *analysis.Pass, w *printfWrapper, call *ast.CallExpr, k return } desc := "printf" - if kind == kindPrint { + if kind == KindPrint { desc = "print" } - pass.Reportf(call.Pos(), "missing ... in args forwarded to %s-like function", desc) + pass.ReportRangef(call, "missing ... in args forwarded to %s-like function", desc) return } fn := w.obj var fact isWrapper if !pass.ImportObjectFact(fn, &fact) { - fact.Printf = kind == kindPrintf + fact.Kind = kind pass.ExportObjectFact(fn, &fact) + res.funcs[fn] = kind for _, caller := range w.callers { - checkPrintfFwd(pass, caller.w, caller.call, kind) + checkPrintfFwd(pass, caller.w, caller.call, kind, res) } } } @@ -414,42 +470,42 @@ func checkCall(pass *analysis.Pass) { call := n.(*ast.CallExpr) fn, kind := printfNameAndKind(pass, call) switch kind { - case kindPrintf: - checkPrintf(pass, call, fn) - case kindPrint: + case KindPrintf, KindErrorf: + checkPrintf(pass, kind, call, fn) + case KindPrint: checkPrint(pass, call, fn) } }) } -func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func, kind int) { +func printfNameAndKind(pass *analysis.Pass, call *ast.CallExpr) (fn *types.Func, kind Kind) { fn, _ = typeutil.Callee(pass.TypesInfo, call).(*types.Func) if fn == nil { return nil, 0 } - var fact isWrapper - if pass.ImportObjectFact(fn, &fact) { - if fact.Printf { - return fn, kindPrintf - } else { - return fn, kindPrint - } - } - _, ok := isPrint[fn.FullName()] if !ok { // Next look up just "printf", for use with -printf.funcs. _, ok = isPrint[strings.ToLower(fn.Name())] } if ok { - if strings.HasSuffix(fn.Name(), "f") { - kind = kindPrintf + if fn.Name() == "Errorf" { + kind = KindErrorf + } else if strings.HasSuffix(fn.Name(), "f") { + kind = KindPrintf } else { - kind = kindPrint + kind = KindPrint } + return fn, kind } - return fn, kind + + var fact isWrapper + if pass.ImportObjectFact(fn, &fact) { + return fn, fact.Kind + } + + return fn, KindNone } // isFormatter reports whether t satisfies fmt.Formatter. @@ -491,7 +547,7 @@ type formatState struct { } // checkPrintf checks a call to a formatted print routine such as Printf. -func checkPrintf(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) { +func checkPrintf(pass *analysis.Pass, kind Kind, call *ast.CallExpr, fn *types.Func) { format, idx := formatString(pass, call) if idx < 0 { if false { @@ -511,6 +567,7 @@ func checkPrintf(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) { argNum := firstArg maxArgNum := firstArg anyIndex := false + anyW := false for i, w := 0, 0; i < len(format); i += w { w = 1 if format[i] != '%' { @@ -527,6 +584,17 @@ func checkPrintf(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) { if state.hasIndex { anyIndex = true } + if state.verb == 'w' { + if kind != KindErrorf { + pass.Reportf(call.Pos(), "%s call has error-wrapping directive %%w", state.name) + return + } + if anyW { + pass.Reportf(call.Pos(), "%s call has more than one error-wrapping directive %%w", state.name) + return + } + anyW = true + } if len(state.argNums) > 0 { // Continue with the next sequential argument. argNum = state.argNums[len(state.argNums)-1] + 1 @@ -549,7 +617,7 @@ func checkPrintf(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) { if maxArgNum != len(call.Args) { expect := maxArgNum - firstArg numArgs := len(call.Args) - firstArg - pass.Reportf(call.Pos(), "%s call needs %v but has %v", fn.Name(), count(expect, "arg"), count(numArgs, "arg")) + pass.ReportRangef(call, "%s call needs %v but has %v", fn.Name(), count(expect, "arg"), count(numArgs, "arg")) } } @@ -590,13 +658,13 @@ func (s *formatState) parseIndex() bool { ok = false s.nbytes = strings.Index(s.format, "]") if s.nbytes < 0 { - s.pass.Reportf(s.call.Pos(), "%s format %s is missing closing ]", s.name, s.format) + s.pass.ReportRangef(s.call, "%s format %s is missing closing ]", s.name, s.format) return false } } arg32, err := strconv.ParseInt(s.format[start:s.nbytes], 10, 32) if err != nil || !ok || arg32 <= 0 || arg32 > int64(len(s.call.Args)-s.firstArg) { - s.pass.Reportf(s.call.Pos(), "%s format has invalid argument index [%s]", s.name, s.format[start:s.nbytes]) + s.pass.ReportRangef(s.call, "%s format has invalid argument index [%s]", s.name, s.format[start:s.nbytes]) return false } s.nbytes++ // skip ']' @@ -673,7 +741,7 @@ func parsePrintfVerb(pass *analysis.Pass, call *ast.CallExpr, name, format strin return nil } if state.nbytes == len(state.format) { - pass.Reportf(call.Pos(), "%s format %s is missing verb at end of string", name, state.format) + pass.ReportRangef(call.Fun, "%s format %s is missing verb at end of string", name, state.format) return nil } verb, w := utf8.DecodeRuneInString(state.format[state.nbytes:]) @@ -697,6 +765,7 @@ const ( argFloat argComplex argPointer + argError anyType printfArgType = ^0 ) @@ -722,7 +791,7 @@ var printVerbs = []printVerb{ // '#' is alternate format for several verbs. // ' ' is spacer for numbers {'%', noFlag, 0}, - {'b', numFlag, argInt | argFloat | argComplex | argPointer}, + {'b', sharpNumFlag, argInt | argFloat | argComplex | argPointer}, {'c', "-", argRune | argInt}, {'d', numFlag, argInt | argPointer}, {'e', sharpNumFlag, argFloat | argComplex}, @@ -739,9 +808,9 @@ var printVerbs = []printVerb{ {'T', "-", anyType}, {'U', "-#", argRune | argInt}, {'v', allFlags, anyType}, - {'w', noFlag, anyType}, - {'x', sharpNumFlag, argRune | argInt | argString | argPointer}, - {'X', sharpNumFlag, argRune | argInt | argString | argPointer}, + {'w', allFlags, argError}, + {'x', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex}, + {'X', sharpNumFlag, argRune | argInt | argString | argPointer | argFloat | argComplex}, } // okPrintfArg compares the formatState to the arguments actually present, @@ -768,7 +837,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o if !formatter { if !found { - pass.Reportf(call.Pos(), "%s format %s has unknown verb %c", state.name, state.format, state.verb) + pass.ReportRangef(call, "%s format %s has unknown verb %c", state.name, state.format, state.verb) return false } for _, flag := range state.flags { @@ -778,7 +847,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o continue } if !strings.ContainsRune(v.flags, rune(flag)) { - pass.Reportf(call.Pos(), "%s format %s has unrecognized flag %c", state.name, state.format, flag) + pass.ReportRangef(call, "%s format %s has unrecognized flag %c", state.name, state.format, flag) return false } } @@ -797,7 +866,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o } arg := call.Args[argNum] if !matchArgType(pass, argInt, nil, arg) { - pass.Reportf(call.Pos(), "%s format %s uses non-int %s as argument of *", state.name, state.format, analysisutil.Format(pass.Fset, arg)) + pass.ReportRangef(call, "%s format %s uses non-int %s as argument of *", state.name, state.format, analysisutil.Format(pass.Fset, arg)) return false } } @@ -811,7 +880,7 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o } arg := call.Args[argNum] if isFunctionValue(pass, arg) && state.verb != 'p' && state.verb != 'T' { - pass.Reportf(call.Pos(), "%s format %s arg %s is a func value, not called", state.name, state.format, analysisutil.Format(pass.Fset, arg)) + pass.ReportRangef(call, "%s format %s arg %s is a func value, not called", state.name, state.format, analysisutil.Format(pass.Fset, arg)) return false } if !matchArgType(pass, v.typ, nil, arg) { @@ -819,11 +888,11 @@ func okPrintfArg(pass *analysis.Pass, call *ast.CallExpr, state *formatState) (o if typ := pass.TypesInfo.Types[arg].Type; typ != nil { typeString = typ.String() } - pass.Reportf(call.Pos(), "%s format %s has arg %s of wrong type %s", state.name, state.format, analysisutil.Format(pass.Fset, arg), typeString) + pass.ReportRangef(call, "%s format %s has arg %s of wrong type %s", state.name, state.format, analysisutil.Format(pass.Fset, arg), typeString) return false } if v.typ&argString != 0 && v.verb != 'T' && !bytes.Contains(state.flags, []byte{'#'}) && recursiveStringer(pass, arg) { - pass.Reportf(call.Pos(), "%s format %s with arg %s causes recursive String method call", state.name, state.format, analysisutil.Format(pass.Fset, arg)) + pass.ReportRangef(call, "%s format %s with arg %s causes recursive String method call", state.name, state.format, analysisutil.Format(pass.Fset, arg)) return false } return true @@ -909,7 +978,7 @@ func argCanBeChecked(pass *analysis.Pass, call *ast.CallExpr, formatArg int, sta // There are bad indexes in the format or there are fewer arguments than the format needs. // This is the argument number relative to the format: Printf("%s", "hi") will give 1 for the "hi". arg := argNum - state.firstArg + 1 // People think of arguments as 1-indexed. - pass.Reportf(call.Pos(), "%s format %s reads arg #%d, but call has %v", state.name, state.format, arg, count(len(call.Args)-state.firstArg, "arg")) + pass.ReportRangef(call, "%s format %s reads arg #%d, but call has %v", state.name, state.format, arg, count(len(call.Args)-state.firstArg, "arg")) return false } @@ -960,7 +1029,7 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) { if sel, ok := call.Args[0].(*ast.SelectorExpr); ok { if x, ok := sel.X.(*ast.Ident); ok { if x.Name == "os" && strings.HasPrefix(sel.Sel.Name, "Std") { - pass.Reportf(call.Pos(), "%s does not take io.Writer but has first arg %s", fn.Name(), analysisutil.Format(pass.Fset, call.Args[0])) + pass.ReportRangef(call, "%s does not take io.Writer but has first arg %s", fn.Name(), analysisutil.Format(pass.Fset, call.Args[0])) } } } @@ -974,7 +1043,7 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) { if strings.Contains(s, "%") { m := printFormatRE.FindStringSubmatch(s) if m != nil { - pass.Reportf(call.Pos(), "%s call has possible formatting directive %s", fn.Name(), m[0]) + pass.ReportRangef(call, "%s call has possible formatting directive %s", fn.Name(), m[0]) } } } @@ -984,16 +1053,16 @@ func checkPrint(pass *analysis.Pass, call *ast.CallExpr, fn *types.Func) { if lit, ok := arg.(*ast.BasicLit); ok && lit.Kind == token.STRING { str, _ := strconv.Unquote(lit.Value) if strings.HasSuffix(str, "\n") { - pass.Reportf(call.Pos(), "%s arg list ends with redundant newline", fn.Name()) + pass.ReportRangef(call, "%s arg list ends with redundant newline", fn.Name()) } } } for _, arg := range args { if isFunctionValue(pass, arg) { - pass.Reportf(call.Pos(), "%s arg %s is a func value, not called", fn.Name(), analysisutil.Format(pass.Fset, arg)) + pass.ReportRangef(call, "%s arg %s is a func value, not called", fn.Name(), analysisutil.Format(pass.Fset, arg)) } if recursiveStringer(pass, arg) { - pass.Reportf(call.Pos(), "%s arg %s causes recursive call to String method", fn.Name(), analysisutil.Format(pass.Fset, arg)) + pass.ReportRangef(call, "%s arg %s causes recursive call to String method", fn.Name(), analysisutil.Format(pass.Fset, arg)) } } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/printf/types.go b/libgo/go/golang.org/x/tools/go/analysis/passes/printf/types.go index 12286fd5df5..bd8a594ef57 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/printf/types.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/printf/types.go @@ -37,6 +37,12 @@ func matchArgTypeInternal(pass *analysis.Pass, t printfArgType, typ types.Type, return true // probably a type check problem } } + + // %w accepts only errors. + if t == argError { + return types.ConvertibleTo(typ, errorType) + } + // If the type implements fmt.Formatter, we have nothing to check. if isFormatter(typ) { return true @@ -228,7 +234,7 @@ func matchStructArgType(pass *analysis.Pass, t printfArgType, typ *types.Struct, return false } if t&argString != 0 && !typf.Exported() && isConvertibleToString(pass, typf.Type()) { - // Issue #17798: unexported Stringer or error cannot be properly fomatted. + // Issue #17798: unexported Stringer or error cannot be properly formatted. return false } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/shift/shift.go b/libgo/go/golang.org/x/tools/go/analysis/passes/shift/shift.go index 39f54573c9f..1f3df07ccd1 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/shift/shift.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/shift/shift.go @@ -21,9 +21,11 @@ import ( "golang.org/x/tools/go/ast/inspector" ) +const Doc = "check for shifts that equal or exceed the width of the integer" + var Analyzer = &analysis.Analyzer{ Name: "shift", - Doc: "check for shifts that equal or exceed the width of the integer", + Doc: Doc, Requires: []*analysis.Analyzer{inspect.Analyzer}, Run: run, } @@ -94,6 +96,6 @@ func checkLongShift(pass *analysis.Pass, node ast.Node, x, y ast.Expr) { size := 8 * pass.TypesSizes.Sizeof(t) if amt >= size { ident := analysisutil.Format(pass.Fset, x) - pass.Reportf(node.Pos(), "%s (%d bits) too small for shift of %d", ident, size, amt) + pass.ReportRangef(node, "%s (%d bits) too small for shift of %d", ident, size, amt) } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go b/libgo/go/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go index bc1db7e4c2e..856c6ae0d81 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/stdmethods/stdmethods.go @@ -141,7 +141,7 @@ func canonicalMethod(pass *analysis.Pass, id *ast.Ident) { actual = strings.TrimPrefix(actual, "func") actual = id.Name + actual - pass.Reportf(id.Pos(), "method %s should have signature %s", actual, expectFmt) + pass.ReportRangef(id, "method %s should have signature %s", actual, expectFmt) } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/structtag/structtag.go b/libgo/go/golang.org/x/tools/go/analysis/passes/structtag/structtag.go index acc6e6c770d..e09160379f6 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/structtag/structtag.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/structtag/structtag.go @@ -40,7 +40,11 @@ func run(pass *analysis.Pass) (interface{}, error) { (*ast.StructType)(nil), } inspect.Preorder(nodeFilter, func(n ast.Node) { - styp := pass.TypesInfo.Types[n.(*ast.StructType)].Type.(*types.Struct) + styp, ok := pass.TypesInfo.Types[n.(*ast.StructType)].Type.(*types.Struct) + // Type information may be incomplete. + if !ok { + return + } var seen namesSeen for i := 0; i < styp.NumFields(); i++ { field := styp.Field(i) diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go b/libgo/go/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go index d019ecef15a..f9cc993cbb4 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/unmarshal/unmarshal.go @@ -16,14 +16,14 @@ import ( "golang.org/x/tools/go/types/typeutil" ) -const doc = `report passing non-pointer or non-interface values to unmarshal +const Doc = `report passing non-pointer or non-interface values to unmarshal The unmarshal analysis reports calls to functions such as json.Unmarshal in which the argument type is not a pointer or an interface.` var Analyzer = &analysis.Analyzer{ Name: "unmarshal", - Doc: doc, + Doc: Doc, Requires: []*analysis.Analyzer{inspect.Analyzer}, Run: run, } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go b/libgo/go/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go index 19bc9c2db98..089c064838d 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/unreachable/unreachable.go @@ -189,7 +189,7 @@ func (d *deadState) findDead(stmt ast.Stmt) { case *ast.EmptyStmt: // do not warn about unreachable empty statements default: - d.pass.Reportf(stmt.Pos(), "unreachable code") + d.pass.ReportRangef(stmt, "unreachable code") d.reachable = true // silence error about next statement } } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go b/libgo/go/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go index 308bfc69cb4..d5bafb859d2 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/unsafeptr/unsafeptr.go @@ -45,7 +45,7 @@ func run(pass *analysis.Pass) (interface{}, error) { if hasBasicType(pass.TypesInfo, x.Fun, types.UnsafePointer) && hasBasicType(pass.TypesInfo, x.Args[0], types.Uintptr) && !isSafeUintptr(pass.TypesInfo, x.Args[0]) { - pass.Reportf(x.Pos(), "possible misuse of unsafe.Pointer") + pass.ReportRangef(x, "possible misuse of unsafe.Pointer") } }) return nil, nil diff --git a/libgo/go/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go b/libgo/go/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go index b4fda19ecaa..ed5f43c2601 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go +++ b/libgo/go/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go @@ -42,6 +42,7 @@ import ( "log" "os" "path/filepath" + "reflect" "sort" "strings" "sync" @@ -322,6 +323,11 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re return } + factFilter := make(map[reflect.Type]bool) + for _, f := range a.FactTypes { + factFilter[reflect.TypeOf(f)] = true + } + pass := &analysis.Pass{ Analyzer: a, Fset: fset, @@ -334,8 +340,10 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) }, ImportObjectFact: facts.ImportObjectFact, ExportObjectFact: facts.ExportObjectFact, + AllObjectFacts: func() []analysis.ObjectFact { return facts.AllObjectFacts(factFilter) }, ImportPackageFact: facts.ImportPackageFact, ExportPackageFact: facts.ExportPackageFact, + AllPackageFacts: func() []analysis.PackageFact { return facts.AllPackageFacts(factFilter) }, } t0 := time.Now() diff --git a/libgo/go/golang.org/x/tools/go/analysis/validate.go b/libgo/go/golang.org/x/tools/go/analysis/validate.go index 6e6cf4984fe..be98143461e 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/validate.go +++ b/libgo/go/golang.org/x/tools/go/analysis/validate.go @@ -9,13 +9,10 @@ import ( // Validate reports an error if any of the analyzers are misconfigured. // Checks include: // that the name is a valid identifier; -// that analyzer names are unique; -// that the Requires graph is acylic; +// that the Requires graph is acyclic; // that analyzer fact types are unique; // that each fact type is a pointer. func Validate(analyzers []*Analyzer) error { - names := make(map[string]bool) - // Map each fact type to its sole generating analyzer. factTypes := make(map[reflect.Type]*Analyzer) @@ -39,10 +36,6 @@ func Validate(analyzers []*Analyzer) error { if !validIdent(a.Name) { return fmt.Errorf("invalid analyzer name %q", a) } - if names[a.Name] { - return fmt.Errorf("duplicate analyzer name %q", a) - } - names[a.Name] = true if a.Doc == "" { return fmt.Errorf("analyzer %q is undocumented", a) diff --git a/libgo/go/golang.org/x/tools/go/cfg/builder.go b/libgo/go/golang.org/x/tools/go/cfg/builder.go index 24e1aba0339..7f95a2961a9 100644 --- a/libgo/go/golang.org/x/tools/go/cfg/builder.go +++ b/libgo/go/golang.org/x/tools/go/cfg/builder.go @@ -149,7 +149,7 @@ func (b *builder) branchStmt(s *ast.BranchStmt) { } case token.FALLTHROUGH: - for t := b.targets; t != nil; t = t.tail { + for t := b.targets; t != nil && block == nil; t = t.tail { block = t._fallthrough } diff --git a/libgo/go/golang.org/x/tools/go/types/objectpath/objectpath.go b/libgo/go/golang.org/x/tools/go/types/objectpath/objectpath.go index 0d85488efb6..882e3b3d8a9 100644 --- a/libgo/go/golang.org/x/tools/go/types/objectpath/objectpath.go +++ b/libgo/go/golang.org/x/tools/go/types/objectpath/objectpath.go @@ -376,7 +376,7 @@ func Object(pkg *types.Package, p Path) (types.Object, error) { return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj) } - // abtraction of *types.{Pointer,Slice,Array,Chan,Map} + // abstraction of *types.{Pointer,Slice,Array,Chan,Map} type hasElem interface { Elem() types.Type } diff --git a/libgo/go/golang.org/x/xerrors/LICENSE b/libgo/go/golang.org/x/xerrors/LICENSE new file mode 100644 index 00000000000..e4a47e17f14 --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2019 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libgo/go/golang.org/x/xerrors/PATENTS b/libgo/go/golang.org/x/xerrors/PATENTS new file mode 100644 index 00000000000..733099041f8 --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/libgo/go/golang.org/x/xerrors/README b/libgo/go/golang.org/x/xerrors/README new file mode 100644 index 00000000000..aac7867a560 --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/README @@ -0,0 +1,2 @@ +This repository holds the transition packages for the new Go 1.13 error values. +See golang.org/design/29934-error-values. diff --git a/libgo/go/golang.org/x/xerrors/adaptor.go b/libgo/go/golang.org/x/xerrors/adaptor.go new file mode 100644 index 00000000000..4317f248331 --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/adaptor.go @@ -0,0 +1,193 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strconv" +) + +// FormatError calls the FormatError method of f with an errors.Printer +// configured according to s and verb, and writes the result to s. +func FormatError(f Formatter, s fmt.State, verb rune) { + // Assuming this function is only called from the Format method, and given + // that FormatError takes precedence over Format, it cannot be called from + // any package that supports errors.Formatter. It is therefore safe to + // disregard that State may be a specific printer implementation and use one + // of our choice instead. + + // limitations: does not support printing error as Go struct. + + var ( + sep = " " // separator before next error + p = &state{State: s} + direct = true + ) + + var err error = f + + switch verb { + // Note that this switch must match the preference order + // for ordinary string printing (%#v before %+v, and so on). + + case 'v': + if s.Flag('#') { + if stringer, ok := err.(fmt.GoStringer); ok { + io.WriteString(&p.buf, stringer.GoString()) + goto exit + } + // proceed as if it were %v + } else if s.Flag('+') { + p.printDetail = true + sep = "\n - " + } + case 's': + case 'q', 'x', 'X': + // Use an intermediate buffer in the rare cases that precision, + // truncation, or one of the alternative verbs (q, x, and X) are + // specified. + direct = false + + default: + p.buf.WriteString("%!") + p.buf.WriteRune(verb) + p.buf.WriteByte('(') + switch { + case err != nil: + p.buf.WriteString(reflect.TypeOf(f).String()) + default: + p.buf.WriteString("") + } + p.buf.WriteByte(')') + io.Copy(s, &p.buf) + return + } + +loop: + for { + switch v := err.(type) { + case Formatter: + err = v.FormatError((*printer)(p)) + case fmt.Formatter: + v.Format(p, 'v') + break loop + default: + io.WriteString(&p.buf, v.Error()) + break loop + } + if err == nil { + break + } + if p.needColon || !p.printDetail { + p.buf.WriteByte(':') + p.needColon = false + } + p.buf.WriteString(sep) + p.inDetail = false + p.needNewline = false + } + +exit: + width, okW := s.Width() + prec, okP := s.Precision() + + if !direct || (okW && width > 0) || okP { + // Construct format string from State s. + format := []byte{'%'} + if s.Flag('-') { + format = append(format, '-') + } + if s.Flag('+') { + format = append(format, '+') + } + if s.Flag(' ') { + format = append(format, ' ') + } + if okW { + format = strconv.AppendInt(format, int64(width), 10) + } + if okP { + format = append(format, '.') + format = strconv.AppendInt(format, int64(prec), 10) + } + format = append(format, string(verb)...) + fmt.Fprintf(s, string(format), p.buf.String()) + } else { + io.Copy(s, &p.buf) + } +} + +var detailSep = []byte("\n ") + +// state tracks error printing state. It implements fmt.State. +type state struct { + fmt.State + buf bytes.Buffer + + printDetail bool + inDetail bool + needColon bool + needNewline bool +} + +func (s *state) Write(b []byte) (n int, err error) { + if s.printDetail { + if len(b) == 0 { + return 0, nil + } + if s.inDetail && s.needColon { + s.needNewline = true + if b[0] == '\n' { + b = b[1:] + } + } + k := 0 + for i, c := range b { + if s.needNewline { + if s.inDetail && s.needColon { + s.buf.WriteByte(':') + s.needColon = false + } + s.buf.Write(detailSep) + s.needNewline = false + } + if c == '\n' { + s.buf.Write(b[k:i]) + k = i + 1 + s.needNewline = true + } + } + s.buf.Write(b[k:]) + if !s.inDetail { + s.needColon = true + } + } else if !s.inDetail { + s.buf.Write(b) + } + return len(b), nil +} + +// printer wraps a state to implement an xerrors.Printer. +type printer state + +func (s *printer) Print(args ...interface{}) { + if !s.inDetail || s.printDetail { + fmt.Fprint((*state)(s), args...) + } +} + +func (s *printer) Printf(format string, args ...interface{}) { + if !s.inDetail || s.printDetail { + fmt.Fprintf((*state)(s), format, args...) + } +} + +func (s *printer) Detail() bool { + s.inDetail = true + return s.printDetail +} diff --git a/libgo/go/golang.org/x/xerrors/codereview.cfg b/libgo/go/golang.org/x/xerrors/codereview.cfg new file mode 100644 index 00000000000..3f8b14b64e8 --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/codereview.cfg @@ -0,0 +1 @@ +issuerepo: golang/go diff --git a/libgo/go/golang.org/x/xerrors/doc.go b/libgo/go/golang.org/x/xerrors/doc.go new file mode 100644 index 00000000000..eef99d9d54d --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/doc.go @@ -0,0 +1,22 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package xerrors implements functions to manipulate errors. +// +// This package is based on the Go 2 proposal for error values: +// https://golang.org/design/29934-error-values +// +// These functions were incorporated into the standard library's errors package +// in Go 1.13: +// - Is +// - As +// - Unwrap +// +// Also, Errorf's %w verb was incorporated into fmt.Errorf. +// +// Use this package to get equivalent behavior in all supported Go versions. +// +// No other features of this package were included in Go 1.13, and at present +// there are no plans to include any of them. +package xerrors // import "golang.org/x/xerrors" diff --git a/libgo/go/golang.org/x/xerrors/errors.go b/libgo/go/golang.org/x/xerrors/errors.go new file mode 100644 index 00000000000..e88d3772d86 --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/errors.go @@ -0,0 +1,33 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import "fmt" + +// errorString is a trivial implementation of error. +type errorString struct { + s string + frame Frame +} + +// New returns an error that formats as the given text. +// +// The returned error contains a Frame set to the caller's location and +// implements Formatter to show this information when printed with details. +func New(text string) error { + return &errorString{text, Caller(1)} +} + +func (e *errorString) Error() string { + return e.s +} + +func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *errorString) FormatError(p Printer) (next error) { + p.Print(e.s) + e.frame.Format(p) + return nil +} diff --git a/libgo/go/golang.org/x/xerrors/fmt.go b/libgo/go/golang.org/x/xerrors/fmt.go new file mode 100644 index 00000000000..74c1c93ec9c --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/fmt.go @@ -0,0 +1,109 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "fmt" + "strings" + + "golang.org/x/xerrors/internal" +) + +// Errorf formats according to a format specifier and returns the string as a +// value that satisfies error. +// +// The returned error includes the file and line number of the caller when +// formatted with additional detail enabled. If the last argument is an error +// the returned error's Format method will return it if the format string ends +// with ": %s", ": %v", or ": %w". If the last argument is an error and the +// format string ends with ": %w", the returned error implements Wrapper +// with an Unwrap method returning it. +func Errorf(format string, a ...interface{}) error { + err, wrap := lastError(format, a) + format = formatPlusW(format) + if err == nil { + return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)} + } + + // TODO: this is not entirely correct. The error value could be + // printed elsewhere in format if it mixes numbered with unnumbered + // substitutions. With relatively small changes to doPrintf we can + // have it optionally ignore extra arguments and pass the argument + // list in its entirety. + msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...) + frame := Frame{} + if internal.EnableTrace { + frame = Caller(1) + } + if wrap { + return &wrapError{msg, err, frame} + } + return &noWrapError{msg, err, frame} +} + +// formatPlusW is used to avoid the vet check that will barf at %w. +func formatPlusW(s string) string { + return s +} + +func lastError(format string, a []interface{}) (err error, wrap bool) { + wrap = strings.HasSuffix(format, ": %w") + if !wrap && + !strings.HasSuffix(format, ": %s") && + !strings.HasSuffix(format, ": %v") { + return nil, false + } + + if len(a) == 0 { + return nil, false + } + + err, ok := a[len(a)-1].(error) + if !ok { + return nil, false + } + + return err, wrap +} + +type noWrapError struct { + msg string + err error + frame Frame +} + +func (e *noWrapError) Error() string { + return fmt.Sprint(e) +} + +func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *noWrapError) FormatError(p Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +type wrapError struct { + msg string + err error + frame Frame +} + +func (e *wrapError) Error() string { + return fmt.Sprint(e) +} + +func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) } + +func (e *wrapError) FormatError(p Printer) (next error) { + p.Print(e.msg) + e.frame.Format(p) + return e.err +} + +func (e *wrapError) Unwrap() error { + return e.err +} diff --git a/libgo/go/golang.org/x/xerrors/format.go b/libgo/go/golang.org/x/xerrors/format.go new file mode 100644 index 00000000000..1bc9c26b97f --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/format.go @@ -0,0 +1,34 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +// A Formatter formats error messages. +type Formatter interface { + error + + // FormatError prints the receiver's first error and returns the next error in + // the error chain, if any. + FormatError(p Printer) (next error) +} + +// A Printer formats error messages. +// +// The most common implementation of Printer is the one provided by package fmt +// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message +// typically provide their own implementations. +type Printer interface { + // Print appends args to the message output. + Print(args ...interface{}) + + // Printf writes a formatted string. + Printf(format string, args ...interface{}) + + // Detail reports whether error detail is requested. + // After the first call to Detail, all text written to the Printer + // is formatted as additional detail, or ignored when + // detail has not been requested. + // If Detail returns false, the caller can avoid printing the detail at all. + Detail() bool +} diff --git a/libgo/go/golang.org/x/xerrors/frame.go b/libgo/go/golang.org/x/xerrors/frame.go new file mode 100644 index 00000000000..0de628ec501 --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/frame.go @@ -0,0 +1,56 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "runtime" +) + +// A Frame contains part of a call stack. +type Frame struct { + // Make room for three PCs: the one we were asked for, what it called, + // and possibly a PC for skipPleaseUseCallersFrames. See: + // https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169 + frames [3]uintptr +} + +// Caller returns a Frame that describes a frame on the caller's stack. +// The argument skip is the number of frames to skip over. +// Caller(0) returns the frame for the caller of Caller. +func Caller(skip int) Frame { + var s Frame + runtime.Callers(skip+1, s.frames[:]) + return s +} + +// location reports the file, line, and function of a frame. +// +// The returned function may be "" even if file and line are not. +func (f Frame) location() (function, file string, line int) { + frames := runtime.CallersFrames(f.frames[:]) + if _, ok := frames.Next(); !ok { + return "", "", 0 + } + fr, ok := frames.Next() + if !ok { + return "", "", 0 + } + return fr.Function, fr.File, fr.Line +} + +// Format prints the stack as error detail. +// It should be called from an error's Format implementation +// after printing any other error detail. +func (f Frame) Format(p Printer) { + if p.Detail() { + function, file, line := f.location() + if function != "" { + p.Printf("%s\n ", function) + } + if file != "" { + p.Printf("%s:%d\n", file, line) + } + } +} diff --git a/libgo/go/golang.org/x/xerrors/go.mod b/libgo/go/golang.org/x/xerrors/go.mod new file mode 100644 index 00000000000..870d4f612db --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/go.mod @@ -0,0 +1,3 @@ +module golang.org/x/xerrors + +go 1.11 diff --git a/libgo/go/golang.org/x/xerrors/internal/internal.go b/libgo/go/golang.org/x/xerrors/internal/internal.go new file mode 100644 index 00000000000..89f4eca5df7 --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/internal/internal.go @@ -0,0 +1,8 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal + +// EnableTrace indicates whether stack information should be recorded in errors. +var EnableTrace = true diff --git a/libgo/go/golang.org/x/xerrors/wrap.go b/libgo/go/golang.org/x/xerrors/wrap.go new file mode 100644 index 00000000000..9a3b510374e --- /dev/null +++ b/libgo/go/golang.org/x/xerrors/wrap.go @@ -0,0 +1,106 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xerrors + +import ( + "reflect" +) + +// A Wrapper provides context around another error. +type Wrapper interface { + // Unwrap returns the next error in the error chain. + // If there is no next error, Unwrap returns nil. + Unwrap() error +} + +// Opaque returns an error with the same error formatting as err +// but that does not match err and cannot be unwrapped. +func Opaque(err error) error { + return noWrapper{err} +} + +type noWrapper struct { + error +} + +func (e noWrapper) FormatError(p Printer) (next error) { + if f, ok := e.error.(Formatter); ok { + return f.FormatError(p) + } + p.Print(e.error) + return nil +} + +// Unwrap returns the result of calling the Unwrap method on err, if err implements +// Unwrap. Otherwise, Unwrap returns nil. +func Unwrap(err error) error { + u, ok := err.(Wrapper) + if !ok { + return nil + } + return u.Unwrap() +} + +// Is reports whether any error in err's chain matches target. +// +// An error is considered to match a target if it is equal to that target or if +// it implements a method Is(error) bool such that Is(target) returns true. +func Is(err, target error) bool { + if target == nil { + return err == target + } + + isComparable := reflect.TypeOf(target).Comparable() + for { + if isComparable && err == target { + return true + } + if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) { + return true + } + // TODO: consider supporing target.Is(err). This would allow + // user-definable predicates, but also may allow for coping with sloppy + // APIs, thereby making it easier to get away with them. + if err = Unwrap(err); err == nil { + return false + } + } +} + +// As finds the first error in err's chain that matches the type to which target +// points, and if so, sets the target to its value and returns true. An error +// matches a type if it is assignable to the target type, or if it has a method +// As(interface{}) bool such that As(target) returns true. As will panic if target +// is not a non-nil pointer to a type which implements error or is of interface type. +// +// The As method should set the target to its value and return true if err +// matches the type to which target points. +func As(err error, target interface{}) bool { + if target == nil { + panic("errors: target cannot be nil") + } + val := reflect.ValueOf(target) + typ := val.Type() + if typ.Kind() != reflect.Ptr || val.IsNil() { + panic("errors: target must be a non-nil pointer") + } + if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) { + panic("errors: *target must be interface or implement error") + } + targetType := typ.Elem() + for err != nil { + if reflect.TypeOf(err).AssignableTo(targetType) { + val.Elem().Set(reflect.ValueOf(err)) + return true + } + if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) { + return true + } + err = Unwrap(err) + } + return false +} + +var errorType = reflect.TypeOf((*error)(nil)).Elem() diff --git a/libgo/go/hash/crc32/crc32_amd64p32.go b/libgo/go/hash/crc32/crc32_amd64p32.go deleted file mode 100644 index f61b801b418..00000000000 --- a/libgo/go/hash/crc32/crc32_amd64p32.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build ignore - -package crc32 - -import "internal/cpu" - -// This file contains the code to call the SSE 4.2 version of the Castagnoli -// CRC. - -// castagnoliSSE42 is defined in crc32_amd64p32.s and uses the SSE4.2 CRC32 -// instruction. -//go:noescape -func castagnoliSSE42(crc uint32, p []byte) uint32 - -func archAvailableCastagnoli() bool { - return cpu.X86.HasSSE42 -} - -func archInitCastagnoli() { - if !cpu.X86.HasSSE42 { - panic("not available") - } - // No initialization necessary. -} - -func archUpdateCastagnoli(crc uint32, p []byte) uint32 { - if !cpu.X86.HasSSE42 { - panic("not available") - } - return castagnoliSSE42(crc, p) -} - -func archAvailableIEEE() bool { return false } -func archInitIEEE() { panic("not available") } -func archUpdateIEEE(crc uint32, p []byte) uint32 { panic("not available") } diff --git a/libgo/go/hash/crc32/crc32_otherarch.go b/libgo/go/hash/crc32/crc32_otherarch.go index c3acd254182..86f9fd9229c 100644 --- a/libgo/go/hash/crc32/crc32_otherarch.go +++ b/libgo/go/hash/crc32/crc32_otherarch.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// -build !amd64,!amd64p32,!s390x,!ppc64le,!arm64 +// -build !amd64,!s390x,!ppc64le,!arm64 package crc32 diff --git a/libgo/go/hash/maphash/maphash.go b/libgo/go/hash/maphash/maphash.go new file mode 100644 index 00000000000..3f406e9db63 --- /dev/null +++ b/libgo/go/hash/maphash/maphash.go @@ -0,0 +1,219 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package maphash provides hash functions on byte sequences. +// These hash functions are intended to be used to implement hash tables or +// other data structures that need to map arbitrary strings or byte +// sequences to a uniform distribution of integers. +// +// The hash functions are collision-resistant but not cryptographically secure. +// (See crypto/sha256 and crypto/sha512 for cryptographic use.) +package maphash + +import "unsafe" + +// A Seed is a random value that selects the specific hash function +// computed by a Hash. If two Hashes use the same Seeds, they +// will compute the same hash values for any given input. +// If two Hashes use different Seeds, they are very likely to compute +// distinct hash values for any given input. +// +// A Seed must be initialized by calling MakeSeed. +// The zero seed is uninitialized and not valid for use with Hash's SetSeed method. +// +// Each Seed value is local to a single process and cannot be serialized +// or otherwise recreated in a different process. +type Seed struct { + s uint64 +} + +// A Hash computes a seeded hash of a byte sequence. +// +// The zero Hash is a valid Hash ready to use. +// A zero Hash chooses a random seed for itself during +// the first call to a Reset, Write, Seed, Sum64, or Seed method. +// For control over the seed, use SetSeed. +// +// The computed hash values depend only on the initial seed and +// the sequence of bytes provided to the Hash object, not on the way +// in which the bytes are provided. For example, the three sequences +// +// h.Write([]byte{'f','o','o'}) +// h.WriteByte('f'); h.WriteByte('o'); h.WriteByte('o') +// h.WriteString("foo") +// +// all have the same effect. +// +// Hashes are intended to be collision-resistant, even for situations +// where an adversary controls the byte sequences being hashed. +// +// A Hash is not safe for concurrent use by multiple goroutines, but a Seed is. +// If multiple goroutines must compute the same seeded hash, +// each can declare its own Hash and call SetSeed with a common Seed. +type Hash struct { + _ [0]func() // not comparable + seed Seed // initial seed used for this hash + state Seed // current hash of all flushed bytes + buf [64]byte // unflushed byte buffer + n int // number of unflushed bytes +} + +// initSeed seeds the hash if necessary. +// initSeed is called lazily before any operation that actually uses h.seed/h.state. +// Note that this does not include Write/WriteByte/WriteString in the case +// where they only add to h.buf. (If they write too much, they call h.flush, +// which does call h.initSeed.) +func (h *Hash) initSeed() { + if h.seed.s == 0 { + h.SetSeed(MakeSeed()) + } +} + +// WriteByte adds b to the sequence of bytes hashed by h. +// It never fails; the error result is for implementing io.ByteWriter. +func (h *Hash) WriteByte(b byte) error { + if h.n == len(h.buf) { + h.flush() + } + h.buf[h.n] = b + h.n++ + return nil +} + +// Write adds b to the sequence of bytes hashed by h. +// It always writes all of b and never fails; the count and error result are for implementing io.Writer. +func (h *Hash) Write(b []byte) (int, error) { + size := len(b) + for h.n+len(b) > len(h.buf) { + k := copy(h.buf[h.n:], b) + h.n = len(h.buf) + b = b[k:] + h.flush() + } + h.n += copy(h.buf[h.n:], b) + return size, nil +} + +// WriteString adds the bytes of s to the sequence of bytes hashed by h. +// It always writes all of s and never fails; the count and error result are for implementing io.StringWriter. +func (h *Hash) WriteString(s string) (int, error) { + size := len(s) + for h.n+len(s) > len(h.buf) { + k := copy(h.buf[h.n:], s) + h.n = len(h.buf) + s = s[k:] + h.flush() + } + h.n += copy(h.buf[h.n:], s) + return size, nil +} + +// Seed returns h's seed value. +func (h *Hash) Seed() Seed { + h.initSeed() + return h.seed +} + +// SetSeed sets h to use seed, which must have been returned by MakeSeed +// or by another Hash's Seed method. +// Two Hash objects with the same seed behave identically. +// Two Hash objects with different seeds will very likely behave differently. +// Any bytes added to h before this call will be discarded. +func (h *Hash) SetSeed(seed Seed) { + if seed.s == 0 { + panic("maphash: use of uninitialized Seed") + } + h.seed = seed + h.state = seed + h.n = 0 +} + +// Reset discards all bytes added to h. +// (The seed remains the same.) +func (h *Hash) Reset() { + h.initSeed() + h.state = h.seed + h.n = 0 +} + +// precondition: buffer is full. +func (h *Hash) flush() { + if h.n != len(h.buf) { + panic("maphash: flush of partially full buffer") + } + h.initSeed() + h.state.s = rthash(h.buf[:], h.state.s) + h.n = 0 +} + +// Sum64 returns h's current 64-bit value, which depends on +// h's seed and the sequence of bytes added to h since the +// last call to Reset or SetSeed. +// +// All bits of the Sum64 result are close to uniformly and +// independently distributed, so it can be safely reduced +// by using bit masking, shifting, or modular arithmetic. +func (h *Hash) Sum64() uint64 { + h.initSeed() + return rthash(h.buf[:h.n], h.state.s) +} + +// MakeSeed returns a new random seed. +func MakeSeed() Seed { + var s1, s2 uint64 + for { + s1 = uint64(runtime_fastrand()) + s2 = uint64(runtime_fastrand()) + // We use seed 0 to indicate an uninitialized seed/hash, + // so keep trying until we get a non-zero seed. + if s1|s2 != 0 { + break + } + } + return Seed{s: s1<<32 + s2} +} + +//go:linkname runtime_fastrand runtime.fastrand +func runtime_fastrand() uint32 + +func rthash(b []byte, seed uint64) uint64 { + if len(b) == 0 { + return seed + } + // The runtime hasher only works on uintptr. For 64-bit + // architectures, we use the hasher directly. Otherwise, + // we use two parallel hashers on the lower and upper 32 bits. + if unsafe.Sizeof(uintptr(0)) == 8 { + return uint64(runtime_memhash(unsafe.Pointer(&b[0]), uintptr(seed), uintptr(len(b)))) + } + lo := runtime_memhash(unsafe.Pointer(&b[0]), uintptr(seed), uintptr(len(b))) + hi := runtime_memhash(unsafe.Pointer(&b[0]), uintptr(seed>>32), uintptr(len(b))) + return uint64(hi)<<32 | uint64(lo) +} + +//go:linkname runtime_memhash runtime.memhash +//go:noescape +func runtime_memhash(p unsafe.Pointer, seed, s uintptr) uintptr + +// Sum appends the hash's current 64-bit value to b. +// It exists for implementing hash.Hash. +// For direct calls, it is more efficient to use Sum64. +func (h *Hash) Sum(b []byte) []byte { + x := h.Sum64() + return append(b, + byte(x>>0), + byte(x>>8), + byte(x>>16), + byte(x>>24), + byte(x>>32), + byte(x>>40), + byte(x>>48), + byte(x>>56)) +} + +// Size returns h's hash value size, 8 bytes. +func (h *Hash) Size() int { return 8 } + +// BlockSize returns h's block size. +func (h *Hash) BlockSize() int { return len(h.buf) } diff --git a/libgo/go/hash/maphash/maphash_test.go b/libgo/go/hash/maphash/maphash_test.go new file mode 100644 index 00000000000..31d84a3b50a --- /dev/null +++ b/libgo/go/hash/maphash/maphash_test.go @@ -0,0 +1,88 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package maphash + +import ( + "hash" + "testing" +) + +func TestUnseededHash(t *testing.T) { + m := map[uint64]struct{}{} + for i := 0; i < 1000; i++ { + h := new(Hash) + m[h.Sum64()] = struct{}{} + } + if len(m) < 900 { + t.Errorf("empty hash not sufficiently random: got %d, want 1000", len(m)) + } +} + +func TestSeededHash(t *testing.T) { + s := MakeSeed() + m := map[uint64]struct{}{} + for i := 0; i < 1000; i++ { + h := new(Hash) + h.SetSeed(s) + m[h.Sum64()] = struct{}{} + } + if len(m) != 1 { + t.Errorf("seeded hash is random: got %d, want 1", len(m)) + } +} + +func TestHashGrouping(t *testing.T) { + b := []byte("foo") + h1 := new(Hash) + h2 := new(Hash) + h2.SetSeed(h1.Seed()) + h1.Write(b) + for _, x := range b { + err := h2.WriteByte(x) + if err != nil { + t.Fatalf("WriteByte: %v", err) + } + } + if h1.Sum64() != h2.Sum64() { + t.Errorf("hash of \"foo\" and \"f\",\"o\",\"o\" not identical") + } +} + +func TestHashBytesVsString(t *testing.T) { + s := "foo" + b := []byte(s) + h1 := new(Hash) + h2 := new(Hash) + h2.SetSeed(h1.Seed()) + n1, err1 := h1.WriteString(s) + if n1 != len(s) || err1 != nil { + t.Fatalf("WriteString(s) = %d, %v, want %d, nil", n1, err1, len(s)) + } + n2, err2 := h2.Write(b) + if n2 != len(b) || err2 != nil { + t.Fatalf("Write(b) = %d, %v, want %d, nil", n2, err2, len(b)) + } + if h1.Sum64() != h2.Sum64() { + t.Errorf("hash of string and bytes not identical") + } +} + +func TestHashHighBytes(t *testing.T) { + // See issue 34925. + const N = 10 + m := map[uint64]struct{}{} + for i := 0; i < N; i++ { + h := new(Hash) + h.WriteString("foo") + m[h.Sum64()>>32] = struct{}{} + } + if len(m) < N/2 { + t.Errorf("from %d seeds, wanted at least %d different hashes; got %d", N, N/2, len(m)) + } +} + +// Make sure a Hash implements the hash.Hash and hash.Hash64 interfaces. +var _ hash.Hash = &Hash{} +var _ hash.Hash64 = &Hash{} diff --git a/libgo/go/hash/maphash/smhasher_test.go b/libgo/go/hash/maphash/smhasher_test.go new file mode 100644 index 00000000000..6e6f2983a21 --- /dev/null +++ b/libgo/go/hash/maphash/smhasher_test.go @@ -0,0 +1,469 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package maphash + +import ( + "fmt" + "math" + "math/rand" + "runtime" + "strings" + "testing" + "unsafe" +) + +// Smhasher is a torture test for hash functions. +// https://code.google.com/p/smhasher/ +// This code is a port of some of the Smhasher tests to Go. + +var fixedSeed = MakeSeed() + +// Sanity checks. +// hash should not depend on values outside key. +// hash should not depend on alignment. +func TestSmhasherSanity(t *testing.T) { + r := rand.New(rand.NewSource(1234)) + const REP = 10 + const KEYMAX = 128 + const PAD = 16 + const OFFMAX = 16 + for k := 0; k < REP; k++ { + for n := 0; n < KEYMAX; n++ { + for i := 0; i < OFFMAX; i++ { + var b [KEYMAX + OFFMAX + 2*PAD]byte + var c [KEYMAX + OFFMAX + 2*PAD]byte + randBytes(r, b[:]) + randBytes(r, c[:]) + copy(c[PAD+i:PAD+i+n], b[PAD:PAD+n]) + if bytesHash(b[PAD:PAD+n]) != bytesHash(c[PAD+i:PAD+i+n]) { + t.Errorf("hash depends on bytes outside key") + } + } + } + } +} + +func bytesHash(b []byte) uint64 { + var h Hash + h.SetSeed(fixedSeed) + h.Write(b) + return h.Sum64() +} +func stringHash(s string) uint64 { + var h Hash + h.SetSeed(fixedSeed) + h.WriteString(s) + return h.Sum64() +} + +const hashSize = 64 + +func randBytes(r *rand.Rand, b []byte) { + r.Read(b) // can't fail +} + +// A hashSet measures the frequency of hash collisions. +type hashSet struct { + m map[uint64]struct{} // set of hashes added + n int // number of hashes added +} + +func newHashSet() *hashSet { + return &hashSet{make(map[uint64]struct{}), 0} +} +func (s *hashSet) add(h uint64) { + s.m[h] = struct{}{} + s.n++ +} +func (s *hashSet) addS(x string) { + s.add(stringHash(x)) +} +func (s *hashSet) addB(x []byte) { + s.add(bytesHash(x)) +} +func (s *hashSet) addS_seed(x string, seed Seed) { + var h Hash + h.SetSeed(seed) + h.WriteString(x) + s.add(h.Sum64()) +} +func (s *hashSet) check(t *testing.T) { + const SLOP = 10.0 + collisions := s.n - len(s.m) + pairs := int64(s.n) * int64(s.n-1) / 2 + expected := float64(pairs) / math.Pow(2.0, float64(hashSize)) + stddev := math.Sqrt(expected) + if float64(collisions) > expected+SLOP*(3*stddev+1) { + t.Errorf("unexpected number of collisions: got=%d mean=%f stddev=%f", collisions, expected, stddev) + } +} + +// a string plus adding zeros must make distinct hashes +func TestSmhasherAppendedZeros(t *testing.T) { + s := "hello" + strings.Repeat("\x00", 256) + h := newHashSet() + for i := 0; i <= len(s); i++ { + h.addS(s[:i]) + } + h.check(t) +} + +// All 0-3 byte strings have distinct hashes. +func TestSmhasherSmallKeys(t *testing.T) { + h := newHashSet() + var b [3]byte + for i := 0; i < 256; i++ { + b[0] = byte(i) + h.addB(b[:1]) + for j := 0; j < 256; j++ { + b[1] = byte(j) + h.addB(b[:2]) + if !testing.Short() { + for k := 0; k < 256; k++ { + b[2] = byte(k) + h.addB(b[:3]) + } + } + } + } + h.check(t) +} + +// Different length strings of all zeros have distinct hashes. +func TestSmhasherZeros(t *testing.T) { + N := 256 * 1024 + if testing.Short() { + N = 1024 + } + h := newHashSet() + b := make([]byte, N) + for i := 0; i <= N; i++ { + h.addB(b[:i]) + } + h.check(t) +} + +// Strings with up to two nonzero bytes all have distinct hashes. +func TestSmhasherTwoNonzero(t *testing.T) { + if runtime.GOARCH == "wasm" { + t.Skip("Too slow on wasm") + } + if testing.Short() { + t.Skip("Skipping in short mode") + } + h := newHashSet() + for n := 2; n <= 16; n++ { + twoNonZero(h, n) + } + h.check(t) +} +func twoNonZero(h *hashSet, n int) { + b := make([]byte, n) + + // all zero + h.addB(b) + + // one non-zero byte + for i := 0; i < n; i++ { + for x := 1; x < 256; x++ { + b[i] = byte(x) + h.addB(b) + b[i] = 0 + } + } + + // two non-zero bytes + for i := 0; i < n; i++ { + for x := 1; x < 256; x++ { + b[i] = byte(x) + for j := i + 1; j < n; j++ { + for y := 1; y < 256; y++ { + b[j] = byte(y) + h.addB(b) + b[j] = 0 + } + } + b[i] = 0 + } + } +} + +// Test strings with repeats, like "abcdabcdabcdabcd..." +func TestSmhasherCyclic(t *testing.T) { + if testing.Short() { + t.Skip("Skipping in short mode") + } + r := rand.New(rand.NewSource(1234)) + const REPEAT = 8 + const N = 1000000 + for n := 4; n <= 12; n++ { + h := newHashSet() + b := make([]byte, REPEAT*n) + for i := 0; i < N; i++ { + b[0] = byte(i * 79 % 97) + b[1] = byte(i * 43 % 137) + b[2] = byte(i * 151 % 197) + b[3] = byte(i * 199 % 251) + randBytes(r, b[4:n]) + for j := n; j < n*REPEAT; j++ { + b[j] = b[j-n] + } + h.addB(b) + } + h.check(t) + } +} + +// Test strings with only a few bits set +func TestSmhasherSparse(t *testing.T) { + if runtime.GOARCH == "wasm" { + t.Skip("Too slow on wasm") + } + if testing.Short() { + t.Skip("Skipping in short mode") + } + sparse(t, 32, 6) + sparse(t, 40, 6) + sparse(t, 48, 5) + sparse(t, 56, 5) + sparse(t, 64, 5) + sparse(t, 96, 4) + sparse(t, 256, 3) + sparse(t, 2048, 2) +} +func sparse(t *testing.T, n int, k int) { + b := make([]byte, n/8) + h := newHashSet() + setbits(h, b, 0, k) + h.check(t) +} + +// set up to k bits at index i and greater +func setbits(h *hashSet, b []byte, i int, k int) { + h.addB(b) + if k == 0 { + return + } + for j := i; j < len(b)*8; j++ { + b[j/8] |= byte(1 << uint(j&7)) + setbits(h, b, j+1, k-1) + b[j/8] &= byte(^(1 << uint(j&7))) + } +} + +// Test all possible combinations of n blocks from the set s. +// "permutation" is a bad name here, but it is what Smhasher uses. +func TestSmhasherPermutation(t *testing.T) { + if runtime.GOARCH == "wasm" { + t.Skip("Too slow on wasm") + } + if testing.Short() { + t.Skip("Skipping in short mode") + } + permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7}, 8) + permutation(t, []uint32{0, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 8) + permutation(t, []uint32{0, 1}, 20) + permutation(t, []uint32{0, 1 << 31}, 20) + permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 6) +} +func permutation(t *testing.T, s []uint32, n int) { + b := make([]byte, n*4) + h := newHashSet() + genPerm(h, b, s, 0) + h.check(t) +} +func genPerm(h *hashSet, b []byte, s []uint32, n int) { + h.addB(b[:n]) + if n == len(b) { + return + } + for _, v := range s { + b[n] = byte(v) + b[n+1] = byte(v >> 8) + b[n+2] = byte(v >> 16) + b[n+3] = byte(v >> 24) + genPerm(h, b, s, n+4) + } +} + +type key interface { + clear() // set bits all to 0 + random(r *rand.Rand) // set key to something random + bits() int // how many bits key has + flipBit(i int) // flip bit i of the key + hash() uint64 // hash the key + name() string // for error reporting +} + +type bytesKey struct { + b []byte +} + +func (k *bytesKey) clear() { + for i := range k.b { + k.b[i] = 0 + } +} +func (k *bytesKey) random(r *rand.Rand) { + randBytes(r, k.b) +} +func (k *bytesKey) bits() int { + return len(k.b) * 8 +} +func (k *bytesKey) flipBit(i int) { + k.b[i>>3] ^= byte(1 << uint(i&7)) +} +func (k *bytesKey) hash() uint64 { + return bytesHash(k.b) +} +func (k *bytesKey) name() string { + return fmt.Sprintf("bytes%d", len(k.b)) +} + +// Flipping a single bit of a key should flip each output bit with 50% probability. +func TestSmhasherAvalanche(t *testing.T) { + if runtime.GOARCH == "wasm" { + t.Skip("Too slow on wasm") + } + if testing.Short() { + t.Skip("Skipping in short mode") + } + avalancheTest1(t, &bytesKey{make([]byte, 2)}) + avalancheTest1(t, &bytesKey{make([]byte, 4)}) + avalancheTest1(t, &bytesKey{make([]byte, 8)}) + avalancheTest1(t, &bytesKey{make([]byte, 16)}) + avalancheTest1(t, &bytesKey{make([]byte, 32)}) + avalancheTest1(t, &bytesKey{make([]byte, 200)}) +} +func avalancheTest1(t *testing.T, k key) { + const REP = 100000 + r := rand.New(rand.NewSource(1234)) + n := k.bits() + + // grid[i][j] is a count of whether flipping + // input bit i affects output bit j. + grid := make([][hashSize]int, n) + + for z := 0; z < REP; z++ { + // pick a random key, hash it + k.random(r) + h := k.hash() + + // flip each bit, hash & compare the results + for i := 0; i < n; i++ { + k.flipBit(i) + d := h ^ k.hash() + k.flipBit(i) + + // record the effects of that bit flip + g := &grid[i] + for j := 0; j < hashSize; j++ { + g[j] += int(d & 1) + d >>= 1 + } + } + } + + // Each entry in the grid should be about REP/2. + // More precisely, we did N = k.bits() * hashSize experiments where + // each is the sum of REP coin flips. We want to find bounds on the + // sum of coin flips such that a truly random experiment would have + // all sums inside those bounds with 99% probability. + N := n * hashSize + var c float64 + // find c such that Prob(mean-c*stddev < x < mean+c*stddev)^N > .9999 + for c = 0.0; math.Pow(math.Erf(c/math.Sqrt(2)), float64(N)) < .9999; c += .1 { + } + c *= 4.0 // allowed slack - we don't need to be perfectly random + mean := .5 * REP + stddev := .5 * math.Sqrt(REP) + low := int(mean - c*stddev) + high := int(mean + c*stddev) + for i := 0; i < n; i++ { + for j := 0; j < hashSize; j++ { + x := grid[i][j] + if x < low || x > high { + t.Errorf("bad bias for %s bit %d -> bit %d: %d/%d\n", k.name(), i, j, x, REP) + } + } + } +} + +// All bit rotations of a set of distinct keys +func TestSmhasherWindowed(t *testing.T) { + windowed(t, &bytesKey{make([]byte, 128)}) +} +func windowed(t *testing.T, k key) { + if runtime.GOARCH == "wasm" { + t.Skip("Too slow on wasm") + } + if testing.Short() { + t.Skip("Skipping in short mode") + } + const BITS = 16 + + for r := 0; r < k.bits(); r++ { + h := newHashSet() + for i := 0; i < 1<>uint(j)&1 != 0 { + k.flipBit((j + r) % k.bits()) + } + } + h.add(k.hash()) + } + h.check(t) + } +} + +// All keys of the form prefix + [A-Za-z0-9]*N + suffix. +func TestSmhasherText(t *testing.T) { + if testing.Short() { + t.Skip("Skipping in short mode") + } + text(t, "Foo", "Bar") + text(t, "FooBar", "") + text(t, "", "FooBar") +} +func text(t *testing.T, prefix, suffix string) { + const N = 4 + const S = "ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst0123456789" + const L = len(S) + b := make([]byte, len(prefix)+N+len(suffix)) + copy(b, prefix) + copy(b[len(prefix)+N:], suffix) + h := newHashSet() + c := b[len(prefix):] + for i := 0; i < L; i++ { + c[0] = S[i] + for j := 0; j < L; j++ { + c[1] = S[j] + for k := 0; k < L; k++ { + c[2] = S[k] + for x := 0; x < L; x++ { + c[3] = S[x] + h.addB(b) + } + } + } + } + h.check(t) +} + +// Make sure different seed values generate different hashes. +func TestSmhasherSeed(t *testing.T) { + if unsafe.Sizeof(uintptr(0)) == 4 { + t.Skip("32-bit platforms don't have ideal seed-input distributions (see issue 33988)") + } + h := newHashSet() + const N = 100000 + s := "hello" + for i := 0; i < N; i++ { + h.addS_seed(s, Seed{s: uint64(i + 1)}) + h.addS_seed(s, Seed{s: uint64(i+1) << 32}) // make sure high bits are used + } + h.check(t) +} diff --git a/libgo/go/html/template/doc.go b/libgo/go/html/template/doc.go index 290ec81b967..650e7147a36 100644 --- a/libgo/go/html/template/doc.go +++ b/libgo/go/html/template/doc.go @@ -73,6 +73,51 @@ functions. For these internal escaping functions, if an action pipeline evaluates to a nil interface value, it is treated as though it were an empty string. +Namespaced and data- attributes + +Attributes with a namespace are treated as if they had no namespace. +Given the excerpt + + + +At parse time the attribute will be treated as if it were just "href". +So at parse time the template becomes: + + + +Similarly to attributes with namespaces, attributes with a "data-" prefix are +treated as if they had no "data-" prefix. So given + + + +At parse time this becomes + + + +If an attribute has both a namespace and a "data-" prefix, only the namespace +will be removed when determining the context. For example + + + +This is handled as if "my:data-href" was just "data-href" and not "href" as +it would be if the "data-" prefix were to be ignored too. Thus at parse +time this becomes just + + + +As a special case, attributes with the namespace "xmlns" are always treated +as containing URLs. Given the excerpts + + + + + +At parse time they become: + + + + + Errors See the documentation of ErrorCode for details. diff --git a/libgo/go/html/template/example_test.go b/libgo/go/html/template/example_test.go index 533c0dd9616..9d965f1943c 100644 --- a/libgo/go/html/template/example_test.go +++ b/libgo/go/html/template/example_test.go @@ -116,9 +116,9 @@ func Example_escape() { // "Fran & Freddie's Diner" <tasty@example.com> // "Fran & Freddie's Diner" <tasty@example.com> // "Fran & Freddie's Diner"32<tasty@example.com> - // \"Fran & Freddie\'s Diner\" \x3Ctasty@example.com\x3E - // \"Fran & Freddie\'s Diner\" \x3Ctasty@example.com\x3E - // \"Fran & Freddie\'s Diner\"32\x3Ctasty@example.com\x3E + // \"Fran \x26 Freddie\'s Diner\" \x3Ctasty@example.com\x3E + // \"Fran \x26 Freddie\'s Diner\" \x3Ctasty@example.com\x3E + // \"Fran \x26 Freddie\'s Diner\"32\x3Ctasty@example.com\x3E // %22Fran+%26+Freddie%27s+Diner%2232%3Ctasty%40example.com%3E } diff --git a/libgo/go/html/template/js.go b/libgo/go/html/template/js.go index 7025c1cfaac..0e91458d19c 100644 --- a/libgo/go/html/template/js.go +++ b/libgo/go/html/template/js.go @@ -383,11 +383,11 @@ func isJSType(mimeType string) bool { // https://tools.ietf.org/html/rfc7231#section-3.1.1 // https://tools.ietf.org/html/rfc4329#section-3 // https://www.ietf.org/rfc/rfc4627.txt - mimeType = strings.ToLower(mimeType) // discard parameters if i := strings.Index(mimeType, ";"); i >= 0 { mimeType = mimeType[:i] } + mimeType = strings.ToLower(mimeType) mimeType = strings.TrimSpace(mimeType) switch mimeType { case diff --git a/libgo/go/image/gif/writer_test.go b/libgo/go/image/gif/writer_test.go index 0bc24d1beec..b619961787d 100644 --- a/libgo/go/image/gif/writer_test.go +++ b/libgo/go/image/gif/writer_test.go @@ -52,7 +52,7 @@ func averageDelta(m0, m1 image.Image) int64 { } // averageDeltaBounds returns the average delta in RGB space. The average delta is -// calulated in the specified bounds. +// calculated in the specified bounds. func averageDeltaBound(m0, m1 image.Image, b0, b1 image.Rectangle) int64 { var sum, n int64 for y := b0.Min.Y; y < b0.Max.Y; y++ { diff --git a/libgo/go/image/png/writer.go b/libgo/go/image/png/writer.go index 2bd4fde692c..53adc1633c0 100644 --- a/libgo/go/image/png/writer.go +++ b/libgo/go/image/png/writer.go @@ -426,10 +426,11 @@ func (e *encoder) writeImage(w io.Writer, m image.Image, cb int, level int) erro var a uint8 var c int + pixelsPerByte := 8 / bitsPerPixel for x := b.Min.X; x < b.Max.X; x++ { a = a<> 32) + if n <= 0 { // We don't know the size of the file so infer it. + // Find the number of bytes offset from curpos until the end of the file. + n, err = syscall.Seek(o.handle, -curpos, io.SeekEnd) + if err != nil { + return + } + // Now seek back to the original position. + if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil { + return + } + } + + // TransmitFile can be invoked in one call with at most + // 2,147,483,646 bytes: the maximum value for a 32-bit integer minus 1. + // See https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile + const maxChunkSizePerCall = int64(0x7fffffff - 1) + + for n > 0 { + chunkSize := maxChunkSizePerCall + if chunkSize > n { + chunkSize = n + } + + o.qty = uint32(chunkSize) + o.o.Offset = uint32(curpos) + o.o.OffsetHigh = uint32(curpos >> 32) + + nw, err := wsrv.ExecIO(o, func(o *operation) error { + return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND) + }) + if err != nil { + return written, err + } + + curpos += int64(nw) - done, err := wsrv.ExecIO(o, func(o *operation) error { - return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND) - }) - if err == nil { // Some versions of Windows (Windows 10 1803) do not set // file position after TransmitFile completes. // So just use Seek to set file position. - _, err = syscall.Seek(o.handle, curpos+int64(done), 0) + if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil { + return written, err + } + + n -= int64(nw) + written += int64(nw) } - return int64(done), err + + return } diff --git a/libgo/go/internal/poll/sys_cloexec.go b/libgo/go/internal/poll/sys_cloexec.go index 64e46127d45..7b87f136dfe 100644 --- a/libgo/go/internal/poll/sys_cloexec.go +++ b/libgo/go/internal/poll/sys_cloexec.go @@ -5,7 +5,7 @@ // This file implements sysSocket and accept for platforms that do not // provide a fast path for setting SetNonblock and CloseOnExec. -// +build aix darwin js,wasm nacl solaris +// +build aix darwin js,wasm solaris package poll diff --git a/libgo/go/internal/reflectlite/reflect_mirror_test.go b/libgo/go/internal/reflectlite/reflect_mirror_test.go new file mode 100644 index 00000000000..fbb6fb397ef --- /dev/null +++ b/libgo/go/internal/reflectlite/reflect_mirror_test.go @@ -0,0 +1,131 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package reflectlite_test + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" + "os" + "path/filepath" + "runtime" + "strings" + "sync" + "testing" +) + +var typeNames = []string{ + "rtype", + "uncommonType", + "arrayType", + "chanType", + "funcType", + "interfaceType", + "mapType", + "ptrType", + "sliceType", + "structType", +} + +type visitor struct { + m map[string]map[string]bool +} + +func newVisitor() visitor { + v := visitor{} + v.m = make(map[string]map[string]bool) + + return v +} +func (v visitor) filter(name string) bool { + for _, typeName := range typeNames { + if typeName == name { + return true + } + } + return false +} + +func (v visitor) Visit(n ast.Node) ast.Visitor { + switch x := n.(type) { + case *ast.TypeSpec: + if v.filter(x.Name.String()) { + if st, ok := x.Type.(*ast.StructType); ok { + v.m[x.Name.String()] = make(map[string]bool) + for _, field := range st.Fields.List { + k := fmt.Sprintf("%s", field.Type) + if len(field.Names) > 0 { + k = field.Names[0].Name + } + v.m[x.Name.String()][k] = true + } + } + } + } + return v +} + +func loadTypes(path, pkgName string, v visitor) { + fset := token.NewFileSet() + + filter := func(fi os.FileInfo) bool { + return strings.HasSuffix(fi.Name(), ".go") + } + pkgs, err := parser.ParseDir(fset, path, filter, 0) + if err != nil { + panic(err) + } + + pkg := pkgs[pkgName] + + for _, f := range pkg.Files { + ast.Walk(v, f) + } +} + +func TestMirrorWithReflect(t *testing.T) { + reflectDir := filepath.Join(runtime.GOROOT(), "src", "reflect") + if _, err := os.Stat(reflectDir); os.IsNotExist(err) { + // On some mobile builders, the test binary executes on a machine without a + // complete GOROOT source tree. + t.Skipf("GOROOT source not present") + } + + var wg sync.WaitGroup + rl, r := newVisitor(), newVisitor() + + for _, tc := range []struct { + path, pkg string + v visitor + }{ + {".", "reflectlite", rl}, + {reflectDir, "reflect", r}, + } { + tc := tc + wg.Add(1) + go func() { + defer wg.Done() + loadTypes(tc.path, tc.pkg, tc.v) + }() + } + wg.Wait() + + if len(rl.m) != len(r.m) { + t.Fatalf("number of types mismatch, reflect: %d, reflectlite: %d", len(r.m), len(rl.m)) + } + + for typName := range r.m { + if len(r.m[typName]) != len(rl.m[typName]) { + t.Errorf("type %s number of fields mismatch, reflect: %d, reflectlite: %d", typName, len(r.m[typName]), len(rl.m[typName])) + continue + } + for field := range r.m[typName] { + if _, ok := rl.m[typName][field]; !ok { + t.Errorf(`Field mismatch, reflect have "%s", relectlite does not.`, field) + } + } + } +} diff --git a/libgo/go/internal/reflectlite/set_test.go b/libgo/go/internal/reflectlite/set_test.go index 817e4beae1b..a610499d084 100644 --- a/libgo/go/internal/reflectlite/set_test.go +++ b/libgo/go/internal/reflectlite/set_test.go @@ -39,6 +39,8 @@ var implementsTests = []struct { {new(notASTExpr), new(ast.Expr), false}, {new(ast.Expr), new(notASTExpr), false}, {new(*notAnExpr), new(notASTExpr), true}, + {new(mapError), new(error), true}, + {new(*mapError), new(error), true}, } type notAnExpr struct{} @@ -53,6 +55,13 @@ type notASTExpr interface { exprNode() } +type mapError map[string]string + +func (mapError) Error() string { return "mapError" } + +var _ error = mapError{} +var _ error = new(mapError) + func TestImplements(t *testing.T) { for _, tt := range implementsTests { xv := TypeOf(tt.x).Elem() diff --git a/libgo/go/internal/reflectlite/type.go b/libgo/go/internal/reflectlite/type.go index 35cf1a4fefe..e700a554e41 100644 --- a/libgo/go/internal/reflectlite/type.go +++ b/libgo/go/internal/reflectlite/type.go @@ -351,6 +351,10 @@ func (t *rtype) PkgPath() string { return t.uncommonType.PkgPath() } +func (t *rtype) hasName() bool { + return t.uncommonType != nil && t.uncommonType.name != nil +} + func (t *rtype) Name() string { return t.uncommonType.Name() } @@ -574,7 +578,7 @@ func directlyAssignable(T, V *rtype) bool { // Otherwise at least one of T and V must not be defined // and they must have the same kind. - if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() { + if T.hasName() && V.hasName() || T.Kind() != V.Kind() { return false } diff --git a/libgo/go/internal/reflectlite/value.go b/libgo/go/internal/reflectlite/value.go index bfc321f35cd..9a14d18ba2f 100644 --- a/libgo/go/internal/reflectlite/value.go +++ b/libgo/go/internal/reflectlite/value.go @@ -180,16 +180,6 @@ type emptyInterface struct { word unsafe.Pointer } -// nonEmptyInterface is the header for an interface value with methods. -type nonEmptyInterface struct { - // see ../runtime/iface.go:/Itab - itab *struct { - typ *rtype // dynamic concrete type - fun [100000]unsafe.Pointer // method table - } - word unsafe.Pointer -} - // mustBeExported panics if f records that the value was obtained using // an unexported field. func (f flag) mustBeExported() { @@ -316,7 +306,7 @@ func (v Value) IsNil() bool { // IsValid reports whether v represents a value. // It returns false if v is the zero Value. // If IsValid returns false, all other methods except String panic. -// Most functions and methods never return an invalid value. +// Most functions and methods never return an invalid Value. // If one does, its documentation states the conditions explicitly. func (v Value) IsValid() bool { return v.flag != 0 diff --git a/libgo/go/internal/singleflight/singleflight_test.go b/libgo/go/internal/singleflight/singleflight_test.go index 5e6f1b328e0..6404a1775a0 100644 --- a/libgo/go/internal/singleflight/singleflight_test.go +++ b/libgo/go/internal/singleflight/singleflight_test.go @@ -28,7 +28,7 @@ func TestDo(t *testing.T) { func TestDoErr(t *testing.T) { var g Group - someErr := errors.New("Some error") + someErr := errors.New("some error") v, err, _ := g.Do("key", func() (interface{}, error) { return nil, someErr }) diff --git a/libgo/go/internal/syscall/unix/getrandom_linux_generic.go b/libgo/go/internal/syscall/unix/getrandom_linux_generic.go index f70ada31a98..95748d5ebad 100644 --- a/libgo/go/internal/syscall/unix/getrandom_linux_generic.go +++ b/libgo/go/internal/syscall/unix/getrandom_linux_generic.go @@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build linux,arm64 linux,nios2 linux,riscv64 +// +build linux +// +build arm64 nios2 riscv64 package unix // Linux getrandom system call number. // See GetRandom in getrandom_linux.go. // -// This file is named "generic" because at a certain point Linux -// started standardizing on system call numbers across -// architectures. So far this means only arm64 uses the standard -// numbers. +// This file is named "generic" because at a certain point Linux started +// standardizing on system call numbers across architectures. So far this means +// only arm64 and riscv64 use the standard numbers. const randomTrap uintptr = 278 diff --git a/libgo/go/internal/syscall/unix/nonblocking_nacl.go b/libgo/go/internal/syscall/unix/nonblocking_nacl.go deleted file mode 100644 index ff67c75e81a..00000000000 --- a/libgo/go/internal/syscall/unix/nonblocking_nacl.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package unix - -func IsNonblock(fd int) (nonblocking bool, err error) { - return false, nil -} diff --git a/libgo/go/internal/syscall/windows/mksyscall.go b/libgo/go/internal/syscall/windows/mksyscall.go index 0bf87dc95c2..95e36f7aa3c 100644 --- a/libgo/go/internal/syscall/windows/mksyscall.go +++ b/libgo/go/internal/syscall/windows/mksyscall.go @@ -6,4 +6,4 @@ package windows -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go security_windows.go psapi_windows.go symlink_windows.go +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall_windows.go security_windows.go psapi_windows.go symlink_windows.go diff --git a/libgo/go/internal/syscall/windows/registry/mksyscall.go b/libgo/go/internal/syscall/windows/registry/mksyscall.go index fa8e27e8ff6..cb4906a7b26 100644 --- a/libgo/go/internal/syscall/windows/registry/mksyscall.go +++ b/libgo/go/internal/syscall/windows/registry/mksyscall.go @@ -6,4 +6,4 @@ package registry -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall.go diff --git a/libgo/go/internal/syscall/windows/registry/registry_test.go b/libgo/go/internal/syscall/windows/registry/registry_test.go index c77329cb1e4..8227232c703 100644 --- a/libgo/go/internal/syscall/windows/registry/registry_test.go +++ b/libgo/go/internal/syscall/windows/registry/registry_test.go @@ -522,86 +522,6 @@ func TestValues(t *testing.T) { deleteValues(t, k) } -func walkKey(t *testing.T, k registry.Key, kname string) { - names, err := k.ReadValueNames(-1) - if err != nil { - t.Fatalf("reading value names of %s failed: %v", kname, err) - } - for _, name := range names { - _, valtype, err := k.GetValue(name, nil) - if err != nil { - t.Fatalf("reading value type of %s of %s failed: %v", name, kname, err) - } - switch valtype { - case registry.NONE: - case registry.SZ: - _, _, err := k.GetStringValue(name) - if err != nil { - t.Error(err) - } - case registry.EXPAND_SZ: - s, _, err := k.GetStringValue(name) - if err != nil { - t.Error(err) - } - _, err = registry.ExpandString(s) - if err != nil { - t.Error(err) - } - case registry.DWORD, registry.QWORD: - _, _, err := k.GetIntegerValue(name) - if err != nil { - t.Error(err) - } - case registry.BINARY: - _, _, err := k.GetBinaryValue(name) - if err != nil { - t.Error(err) - } - case registry.MULTI_SZ: - _, _, err := k.GetStringsValue(name) - if err != nil { - t.Error(err) - } - case registry.FULL_RESOURCE_DESCRIPTOR, registry.RESOURCE_LIST, registry.RESOURCE_REQUIREMENTS_LIST: - // TODO: not implemented - default: - t.Fatalf("value type %d of %s of %s failed: %v", valtype, name, kname, err) - } - } - - names, err = k.ReadSubKeyNames(-1) - if err != nil { - t.Fatalf("reading sub-keys of %s failed: %v", kname, err) - } - for _, name := range names { - func() { - subk, err := registry.OpenKey(k, name, registry.ENUMERATE_SUB_KEYS|registry.QUERY_VALUE) - if err != nil { - if err == syscall.ERROR_ACCESS_DENIED { - // ignore error, if we are not allowed to access this key - return - } - t.Fatalf("opening sub-keys %s of %s failed: %v", name, kname, err) - } - defer subk.Close() - - walkKey(t, subk, kname+`\`+name) - }() - } -} - -func TestWalkFullRegistry(t *testing.T) { - if testing.Short() { - t.Skip("skipping long running test in short mode") - } - walkKey(t, registry.CLASSES_ROOT, "CLASSES_ROOT") - walkKey(t, registry.CURRENT_USER, "CURRENT_USER") - walkKey(t, registry.LOCAL_MACHINE, "LOCAL_MACHINE") - walkKey(t, registry.USERS, "USERS") - walkKey(t, registry.CURRENT_CONFIG, "CURRENT_CONFIG") -} - func TestExpandString(t *testing.T) { got, err := registry.ExpandString("%PATH%") if err != nil { diff --git a/libgo/go/internal/syscall/windows/registry/value.go b/libgo/go/internal/syscall/windows/registry/value.go index 71d4e15bab1..bf8ab007590 100644 --- a/libgo/go/internal/syscall/windows/registry/value.go +++ b/libgo/go/internal/syscall/windows/registry/value.go @@ -108,7 +108,7 @@ func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) if len(data) == 0 { return "", typ, nil } - u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:] + u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[: len(data)/2 : len(data)/2] return syscall.UTF16ToString(u), typ, nil } @@ -185,8 +185,7 @@ func ExpandString(value string) (string, error) { return "", err } if n <= uint32(len(r)) { - u := (*[1 << 29]uint16)(unsafe.Pointer(&r[0]))[:] - return syscall.UTF16ToString(u), nil + return syscall.UTF16ToString(r[:n]), nil } r = make([]uint16, n) } @@ -208,7 +207,7 @@ func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err err if len(data) == 0 { return nil, typ, nil } - p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2] + p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[: len(data)/2 : len(data)/2] if len(p) == 0 { return nil, typ, nil } @@ -296,7 +295,7 @@ func (k Key) setStringValue(name string, valtype uint32, value string) error { if err != nil { return err } - buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2] + buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[: len(v)*2 : len(v)*2] return k.setValue(name, valtype, buf) } @@ -326,7 +325,7 @@ func (k Key) SetStringsValue(name string, value []string) error { ss += s + "\x00" } v := utf16.Encode([]rune(ss + "\x00")) - buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2] + buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[: len(v)*2 : len(v)*2] return k.setValue(name, MULTI_SZ, buf) } diff --git a/libgo/go/internal/syscall/windows/reparse_windows.go b/libgo/go/internal/syscall/windows/reparse_windows.go index 610b733c4a9..6e111392f09 100644 --- a/libgo/go/internal/syscall/windows/reparse_windows.go +++ b/libgo/go/internal/syscall/windows/reparse_windows.go @@ -60,8 +60,9 @@ type SymbolicLinkReparseBuffer struct { // Path returns path stored in rb. func (rb *SymbolicLinkReparseBuffer) Path() string { - p := (*[0xffff]uint16)(unsafe.Pointer(&rb.PathBuffer[0])) - return syscall.UTF16ToString(p[rb.SubstituteNameOffset/2 : (rb.SubstituteNameOffset+rb.SubstituteNameLength)/2]) + n1 := rb.SubstituteNameOffset / 2 + n2 := (rb.SubstituteNameOffset + rb.SubstituteNameLength) / 2 + return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(&rb.PathBuffer[0]))[n1:n2:n2]) } type MountPointReparseBuffer struct { @@ -83,6 +84,7 @@ type MountPointReparseBuffer struct { // Path returns path stored in rb. func (rb *MountPointReparseBuffer) Path() string { - p := (*[0xffff]uint16)(unsafe.Pointer(&rb.PathBuffer[0])) - return syscall.UTF16ToString(p[rb.SubstituteNameOffset/2 : (rb.SubstituteNameOffset+rb.SubstituteNameLength)/2]) + n1 := rb.SubstituteNameOffset / 2 + n2 := (rb.SubstituteNameOffset + rb.SubstituteNameLength) / 2 + return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(&rb.PathBuffer[0]))[n1:n2:n2]) } diff --git a/libgo/go/internal/syscall/windows/syscall_windows.go b/libgo/go/internal/syscall/windows/syscall_windows.go index 099e91ed68c..dc641116bae 100644 --- a/libgo/go/internal/syscall/windows/syscall_windows.go +++ b/libgo/go/internal/syscall/windows/syscall_windows.go @@ -7,9 +7,29 @@ package windows import ( "sync" "syscall" + "unicode/utf16" "unsafe" ) +// UTF16PtrToString is like UTF16ToString, but takes *uint16 +// as a parameter instead of []uint16. +// max is how many times p can be advanced looking for the null terminator. +// If max is hit, the string is truncated at that point. +func UTF16PtrToString(p *uint16, max int) string { + if p == nil { + return "" + } + // Find NUL terminator. + end := unsafe.Pointer(p) + n := 0 + for *(*uint16)(end) != 0 && n < max { + end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) + n++ + } + s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n] + return string(utf16.Decode(s)) +} + const ( ERROR_SHARING_VIOLATION syscall.Errno = 32 ERROR_LOCK_VIOLATION syscall.Errno = 33 diff --git a/libgo/go/internal/testenv/testenv.go b/libgo/go/internal/testenv/testenv.go index 3460054a676..c2e9d98f03c 100644 --- a/libgo/go/internal/testenv/testenv.go +++ b/libgo/go/internal/testenv/testenv.go @@ -50,7 +50,7 @@ func HasGoBuild() bool { return false } switch runtime.GOOS { - case "android", "nacl", "js": + case "android", "js": return false case "darwin": if strings.HasPrefix(runtime.GOARCH, "arm") { @@ -136,7 +136,7 @@ func GoTool() (string, error) { // using os.StartProcess or (more commonly) exec.Command. func HasExec() bool { switch runtime.GOOS { - case "nacl", "js": + case "js": return false case "darwin": if strings.HasPrefix(runtime.GOARCH, "arm") { @@ -149,8 +149,6 @@ func HasExec() bool { // HasSrc reports whether the entire source tree is available under GOROOT. func HasSrc() bool { switch runtime.GOOS { - case "nacl": - return false case "darwin": if strings.HasPrefix(runtime.GOARCH, "arm") { return false @@ -192,14 +190,14 @@ func MustHaveExecPath(t testing.TB, path string) { // HasExternalNetwork reports whether the current system can use // external (non-localhost) networks. func HasExternalNetwork() bool { - return !testing.Short() && runtime.GOOS != "nacl" && runtime.GOOS != "js" + return !testing.Short() && runtime.GOOS != "js" } // MustHaveExternalNetwork checks that the current system can use // external (non-localhost) networks. // If not, MustHaveExternalNetwork calls t.Skip with an explanation. func MustHaveExternalNetwork(t testing.TB) { - if runtime.GOOS == "nacl" || runtime.GOOS == "js" { + if runtime.GOOS == "js" { t.Skipf("skipping test: no external network on %s", runtime.GOOS) } if testing.Short() { diff --git a/libgo/go/internal/testenv/testenv_notwin.go b/libgo/go/internal/testenv/testenv_notwin.go index d8ce6cd3853..ccb5d5585f6 100644 --- a/libgo/go/internal/testenv/testenv_notwin.go +++ b/libgo/go/internal/testenv/testenv_notwin.go @@ -12,7 +12,7 @@ import ( func hasSymlink() (ok bool, reason string) { switch runtime.GOOS { - case "android", "nacl", "plan9": + case "android", "plan9": return false, "" } diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go index 2010770e6a4..9cc3086c19b 100644 --- a/libgo/go/io/io.go +++ b/libgo/go/io/io.go @@ -368,6 +368,9 @@ func Copy(dst Writer, src Reader) (written int64, err error) { // provided buffer (if one is required) rather than allocating a // temporary one. If buf is nil, one is allocated; otherwise if it has // zero length, CopyBuffer panics. +// +// If either src implements WriterTo or dst implements ReaderFrom, +// buf will not be used to perform the copy. func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) { if buf != nil && len(buf) == 0 { panic("empty buffer in io.CopyBuffer") diff --git a/libgo/go/io/io_test.go b/libgo/go/io/io_test.go index 0e4ce612400..ca90403c59c 100644 --- a/libgo/go/io/io_test.go +++ b/libgo/go/io/io_test.go @@ -13,7 +13,7 @@ import ( "testing" ) -// An version of bytes.Buffer without ReadFrom and WriteTo +// A version of bytes.Buffer without ReadFrom and WriteTo type Buffer struct { bytes.Buffer ReaderFrom // conflicts with and hides bytes.Buffer's ReaderFrom. diff --git a/libgo/go/io/ioutil/example_test.go b/libgo/go/io/ioutil/example_test.go index a7d340b77fa..bc2b6fba736 100644 --- a/libgo/go/io/ioutil/example_test.go +++ b/libgo/go/io/ioutil/example_test.go @@ -53,6 +53,29 @@ func ExampleTempDir() { } } +func ExampleTempDir_suffix() { + parentDir := os.TempDir() + logsDir, err := ioutil.TempDir(parentDir, "*-logs") + if err != nil { + log.Fatal(err) + } + defer os.RemoveAll(logsDir) // clean up + + // Logs can be cleaned out earlier if needed by searching + // for all directories whose suffix ends in *-logs. + globPattern := filepath.Join(parentDir, "*-logs") + matches, err := filepath.Glob(globPattern) + if err != nil { + log.Fatalf("Failed to match %q: %v", globPattern, err) + } + + for _, match := range matches { + if err := os.RemoveAll(match); err != nil { + log.Printf("Failed to remove %q: %v", match, err) + } + } +} + func ExampleTempFile() { content := []byte("temporary file's content") tmpfile, err := ioutil.TempFile("", "example") diff --git a/libgo/go/io/ioutil/ioutil.go b/libgo/go/io/ioutil/ioutil.go index 674b2701db1..b1cb841468f 100644 --- a/libgo/go/io/ioutil/ioutil.go +++ b/libgo/go/io/ioutil/ioutil.go @@ -74,17 +74,14 @@ func ReadFile(filename string) ([]byte, error) { } // WriteFile writes data to a file named by filename. -// If the file does not exist, WriteFile creates it with permissions perm; -// otherwise WriteFile truncates it before writing. +// If the file does not exist, WriteFile creates it with permissions perm +// (before umask); otherwise WriteFile truncates it before writing. func WriteFile(filename string, data []byte, perm os.FileMode) error { f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) if err != nil { return err } - n, err := f.Write(data) - if err == nil && n < len(data) { - err = io.ErrShortWrite - } + _, err = f.Write(data) if err1 := f.Close(); err == nil { err = err1 } diff --git a/libgo/go/io/ioutil/ioutil_test.go b/libgo/go/io/ioutil/ioutil_test.go index 81fc602cdb4..1fc4c8b7949 100644 --- a/libgo/go/io/ioutil/ioutil_test.go +++ b/libgo/go/io/ioutil/ioutil_test.go @@ -5,7 +5,9 @@ package ioutil import ( + "bytes" "os" + "path/filepath" "testing" ) @@ -63,6 +65,38 @@ func TestWriteFile(t *testing.T) { os.Remove(filename) // ignore error } +func TestReadOnlyWriteFile(t *testing.T) { + if os.Getuid() == 0 { + t.Skipf("Root can write to read-only files anyway, so skip the read-only test.") + } + + // We don't want to use TempFile directly, since that opens a file for us as 0600. + tempDir, err := TempDir("", t.Name()) + if err != nil { + t.Fatalf("TempDir %s: %v", t.Name(), err) + } + defer os.RemoveAll(tempDir) + filename := filepath.Join(tempDir, "blurp.txt") + + shmorp := []byte("shmorp") + florp := []byte("florp") + err = WriteFile(filename, shmorp, 0444) + if err != nil { + t.Fatalf("WriteFile %s: %v", filename, err) + } + err = WriteFile(filename, florp, 0444) + if err == nil { + t.Fatalf("Expected an error when writing to read-only file %s", filename) + } + got, err := ReadFile(filename) + if err != nil { + t.Fatalf("ReadFile %s: %v", filename, err) + } + if !bytes.Equal(got, shmorp) { + t.Fatalf("want %s, got %s", shmorp, got) + } +} + func TestReadDir(t *testing.T) { dirname := "rumpelstilzchen" _, err := ReadDir(dirname) diff --git a/libgo/go/io/ioutil/tempfile.go b/libgo/go/io/ioutil/tempfile.go index ba8783b9a0d..3aa23c5f017 100644 --- a/libgo/go/io/ioutil/tempfile.go +++ b/libgo/go/io/ioutil/tempfile.go @@ -52,12 +52,7 @@ func TempFile(dir, pattern string) (f *os.File, err error) { dir = os.TempDir() } - var prefix, suffix string - if pos := strings.LastIndex(pattern, "*"); pos != -1 { - prefix, suffix = pattern[:pos], pattern[pos+1:] - } else { - prefix = pattern - } + prefix, suffix := prefixAndSuffix(pattern) nconflict := 0 for i := 0; i < 10000; i++ { @@ -76,21 +71,36 @@ func TempFile(dir, pattern string) (f *os.File, err error) { return } -// TempDir creates a new temporary directory in the directory dir -// with a name beginning with prefix and returns the path of the -// new directory. If dir is the empty string, TempDir uses the +// prefixAndSuffix splits pattern by the last wildcard "*", if applicable, +// returning prefix as the part before "*" and suffix as the part after "*". +func prefixAndSuffix(pattern string) (prefix, suffix string) { + if pos := strings.LastIndex(pattern, "*"); pos != -1 { + prefix, suffix = pattern[:pos], pattern[pos+1:] + } else { + prefix = pattern + } + return +} + +// TempDir creates a new temporary directory in the directory dir. +// The directory name is generated by taking pattern and applying a +// random string to the end. If pattern includes a "*", the random string +// replaces the last "*". TempDir returns the name of the new directory. +// If dir is the empty string, TempDir uses the // default directory for temporary files (see os.TempDir). // Multiple programs calling TempDir simultaneously // will not choose the same directory. It is the caller's responsibility // to remove the directory when no longer needed. -func TempDir(dir, prefix string) (name string, err error) { +func TempDir(dir, pattern string) (name string, err error) { if dir == "" { dir = os.TempDir() } + prefix, suffix := prefixAndSuffix(pattern) + nconflict := 0 for i := 0; i < 10000; i++ { - try := filepath.Join(dir, prefix+nextRandom()) + try := filepath.Join(dir, prefix+nextRandom()+suffix) err = os.Mkdir(try, 0700) if os.IsExist(err) { if nconflict++; nconflict > 10 { diff --git a/libgo/go/io/ioutil/tempfile_test.go b/libgo/go/io/ioutil/tempfile_test.go index 0758890b699..698ebabee9e 100644 --- a/libgo/go/io/ioutil/tempfile_test.go +++ b/libgo/go/io/ioutil/tempfile_test.go @@ -54,18 +54,47 @@ func TestTempDir(t *testing.T) { t.Errorf("TempDir(`/_not_exists_`, `foo`) = %v, %v", name, err) } - dir := os.TempDir() - name, err = TempDir(dir, "ioutil_test") - if name == "" || err != nil { - t.Errorf("TempDir(dir, `ioutil_test`) = %v, %v", name, err) + tests := []struct { + pattern string + wantPrefix, wantSuffix string + }{ + {"ioutil_test", "ioutil_test", ""}, + {"ioutil_test*", "ioutil_test", ""}, + {"ioutil_test*xyz", "ioutil_test", "xyz"}, } - if name != "" { - os.Remove(name) - re := regexp.MustCompile("^" + regexp.QuoteMeta(filepath.Join(dir, "ioutil_test")) + "[0-9]+$") + + dir := os.TempDir() + + runTestTempDir := func(t *testing.T, pattern, wantRePat string) { + name, err := TempDir(dir, pattern) + if name == "" || err != nil { + t.Fatalf("TempDir(dir, `ioutil_test`) = %v, %v", name, err) + } + defer os.Remove(name) + + re := regexp.MustCompile(wantRePat) if !re.MatchString(name) { - t.Errorf("TempDir(`"+dir+"`, `ioutil_test`) created bad name %s", name) + t.Errorf("TempDir(%q, %q) created bad name\n\t%q\ndid not match pattern\n\t%q", dir, pattern, name, wantRePat) } } + + for _, tt := range tests { + t.Run(tt.pattern, func(t *testing.T) { + wantRePat := "^" + regexp.QuoteMeta(filepath.Join(dir, tt.wantPrefix)) + "[0-9]+" + regexp.QuoteMeta(tt.wantSuffix) + "$" + runTestTempDir(t, tt.pattern, wantRePat) + }) + } + + // Separately testing "*xyz" (which has no prefix). That is when constructing the + // pattern to assert on, as in the previous loop, using filepath.Join for an empty + // prefix filepath.Join(dir, ""), produces the pattern: + // ^[0-9]+xyz$ + // yet we just want to match + // "^/[0-9]+xyz" + t.Run("*xyz", func(t *testing.T) { + wantRePat := "^" + regexp.QuoteMeta(filepath.Join(dir)) + regexp.QuoteMeta(string(filepath.Separator)) + "[0-9]+xyz$" + runTestTempDir(t, "*xyz", wantRePat) + }) } // test that we return a nice error message if the dir argument to TempDir doesn't diff --git a/libgo/go/io/multi_test.go b/libgo/go/io/multi_test.go index 9aad95454c6..bc6b0ab7546 100644 --- a/libgo/go/io/multi_test.go +++ b/libgo/go/io/multi_test.go @@ -287,7 +287,7 @@ func TestMultiReaderSingleByteWithEOF(t *testing.T) { } } -// Test that a reader returning (n, EOF) at the end of an MultiReader +// Test that a reader returning (n, EOF) at the end of a MultiReader // chain continues to return EOF on its final read, rather than // yielding a (0, EOF). func TestMultiReaderFinalEOF(t *testing.T) { diff --git a/libgo/go/io/pipe.go b/libgo/go/io/pipe.go index 4efaf2f8e48..b5343bb6b73 100644 --- a/libgo/go/io/pipe.go +++ b/libgo/go/io/pipe.go @@ -10,19 +10,26 @@ package io import ( "errors" "sync" - "sync/atomic" ) -// atomicError is a type-safe atomic value for errors. -// We use a struct{ error } to ensure consistent use of a concrete type. -type atomicError struct{ v atomic.Value } +// onceError is an object that will only store an error once. +type onceError struct { + sync.Mutex // guards following + err error +} -func (a *atomicError) Store(err error) { - a.v.Store(struct{ error }{err}) +func (a *onceError) Store(err error) { + a.Lock() + defer a.Unlock() + if a.err != nil { + return + } + a.err = err } -func (a *atomicError) Load() error { - err, _ := a.v.Load().(struct{ error }) - return err.error +func (a *onceError) Load() error { + a.Lock() + defer a.Unlock() + return a.err } // ErrClosedPipe is the error used for read or write operations on a closed pipe. @@ -36,8 +43,8 @@ type pipe struct { once sync.Once // Protects closing done done chan struct{} - rerr atomicError - werr atomicError + rerr onceError + werr onceError } func (p *pipe) Read(b []byte) (n int, err error) { @@ -135,6 +142,9 @@ func (r *PipeReader) Close() error { // CloseWithError closes the reader; subsequent writes // to the write half of the pipe will return the error err. +// +// CloseWithError never overwrites the previous error if it exists +// and always returns nil. func (r *PipeReader) CloseWithError(err error) error { return r.p.CloseRead(err) } @@ -163,7 +173,8 @@ func (w *PipeWriter) Close() error { // read half of the pipe will return no bytes and the error err, // or EOF if err is nil. // -// CloseWithError always returns nil. +// CloseWithError never overwrites the previous error if it exists +// and always returns nil. func (w *PipeWriter) CloseWithError(err error) error { return w.p.CloseWrite(err) } diff --git a/libgo/go/io/pipe_test.go b/libgo/go/io/pipe_test.go index f18b1c45f8b..89733607401 100644 --- a/libgo/go/io/pipe_test.go +++ b/libgo/go/io/pipe_test.go @@ -326,8 +326,8 @@ func TestPipeCloseError(t *testing.T) { t.Errorf("Write error: got %T, want testError1", err) } r.CloseWithError(testError2{}) - if _, err := w.Write(nil); err != (testError2{}) { - t.Errorf("Write error: got %T, want testError2", err) + if _, err := w.Write(nil); err != (testError1{}) { + t.Errorf("Write error: got %T, want testError1", err) } r, w = Pipe() @@ -336,8 +336,8 @@ func TestPipeCloseError(t *testing.T) { t.Errorf("Read error: got %T, want testError1", err) } w.CloseWithError(testError2{}) - if _, err := r.Read(nil); err != (testError2{}) { - t.Errorf("Read error: got %T, want testError2", err) + if _, err := r.Read(nil); err != (testError1{}) { + t.Errorf("Read error: got %T, want testError1", err) } } diff --git a/libgo/go/log/log.go b/libgo/go/log/log.go index 12a9e7b8ce2..216cfe03222 100644 --- a/libgo/go/log/log.go +++ b/libgo/go/log/log.go @@ -25,8 +25,9 @@ import ( // These flags define which text to prefix to each log entry generated by the Logger. // Bits are or'ed together to control what's printed. -// There is no control over the order they appear (the order listed -// here) or the format they present (as described in the comments). +// With the exception of the Lmsgprefix flag, there is no +// control over the order they appear (the order listed here) +// or the format they present (as described in the comments). // The prefix is followed by a colon only when Llongfile or Lshortfile // is specified. // For example, flags Ldate | Ltime (or LstdFlags) produce, @@ -40,6 +41,7 @@ const ( Llongfile // full file name and line number: /a/b/c/d.go:23 Lshortfile // final file name element and line number: d.go:23. overrides Llongfile LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone + Lmsgprefix // move the "prefix" from the beginning of the line to before the message LstdFlags = Ldate | Ltime // initial values for the standard logger ) @@ -49,7 +51,7 @@ const ( // multiple goroutines; it guarantees to serialize access to the Writer. type Logger struct { mu sync.Mutex // ensures atomic writes; protects the following fields - prefix string // prefix to write at beginning of each line + prefix string // prefix on each line to identify the logger (but see Lmsgprefix) flag int // properties out io.Writer // destination for output buf []byte // for accumulating text to write @@ -57,7 +59,8 @@ type Logger struct { // New creates a new Logger. The out variable sets the // destination to which log data will be written. -// The prefix appears at the beginning of each generated log line. +// The prefix appears at the beginning of each generated log line, or +// after the log header if the Lmsgprefix flag is provided. // The flag argument defines the logging properties. func New(out io.Writer, prefix string, flag int) *Logger { return &Logger{out: out, prefix: prefix, flag: flag} @@ -90,11 +93,14 @@ func itoa(buf *[]byte, i int, wid int) { } // formatHeader writes log header to buf in following order: -// * l.prefix (if it's not blank), +// * l.prefix (if it's not blank and Lmsgprefix is unset), // * date and/or time (if corresponding flags are provided), -// * file and line number (if corresponding flags are provided). +// * file and line number (if corresponding flags are provided), +// * l.prefix (if it's not blank and Lmsgprefix is set). func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) { - *buf = append(*buf, l.prefix...) + if l.flag&Lmsgprefix == 0 { + *buf = append(*buf, l.prefix...) + } if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 { if l.flag&LUTC != 0 { t = t.UTC() @@ -138,6 +144,9 @@ func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) { itoa(buf, line, -1) *buf = append(*buf, ": "...) } + if l.flag&Lmsgprefix != 0 { + *buf = append(*buf, l.prefix...) + } } // Output writes the output for a logging event. The string s contains @@ -227,6 +236,7 @@ func (l *Logger) Panicln(v ...interface{}) { } // Flags returns the output flags for the logger. +// The flag bits are Ldate, Ltime, and so on. func (l *Logger) Flags() int { l.mu.Lock() defer l.mu.Unlock() @@ -234,6 +244,7 @@ func (l *Logger) Flags() int { } // SetFlags sets the output flags for the logger. +// The flag bits are Ldate, Ltime, and so on. func (l *Logger) SetFlags(flag int) { l.mu.Lock() defer l.mu.Unlock() @@ -269,11 +280,13 @@ func SetOutput(w io.Writer) { } // Flags returns the output flags for the standard logger. +// The flag bits are Ldate, Ltime, and so on. func Flags() int { return std.Flags() } // SetFlags sets the output flags for the standard logger. +// The flag bits are Ldate, Ltime, and so on. func SetFlags(flag int) { std.SetFlags(flag) } diff --git a/libgo/go/log/log_test.go b/libgo/go/log/log_test.go index b79251877e9..cdccbc554d8 100644 --- a/libgo/go/log/log_test.go +++ b/libgo/go/log/log_test.go @@ -20,7 +20,7 @@ const ( Rdate = `[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9]` Rtime = `[0-9][0-9]:[0-9][0-9]:[0-9][0-9]` Rmicroseconds = `\.[0-9][0-9][0-9][0-9][0-9][0-9]` - Rline = `(57|59):` // must update if the calls to l.Printf / l.Print below move + Rline = `(60|62):` // must update if the calls to l.Printf / l.Print below move Rlongfile = `.*/[A-Za-z0-9_\-]+\.go:` + Rline Rshortfile = `[A-Za-z0-9_\-]+\.go:` + Rline ) @@ -37,6 +37,7 @@ var tests = []tester{ {0, "XXX", "XXX"}, {Ldate, "", Rdate + " "}, {Ltime, "", Rtime + " "}, + {Ltime | Lmsgprefix, "XXX", Rtime + " XXX"}, {Ltime | Lmicroseconds, "", Rtime + Rmicroseconds + " "}, {Lmicroseconds, "", Rtime + Rmicroseconds + " "}, // microsec implies time {Llongfile, "", Rlongfile + " "}, @@ -45,6 +46,8 @@ var tests = []tester{ // everything at once: {Ldate | Ltime | Lmicroseconds | Llongfile, "XXX", "XXX" + Rdate + " " + Rtime + Rmicroseconds + " " + Rlongfile + " "}, {Ldate | Ltime | Lmicroseconds | Lshortfile, "XXX", "XXX" + Rdate + " " + Rtime + Rmicroseconds + " " + Rshortfile + " "}, + {Ldate | Ltime | Lmicroseconds | Llongfile | Lmsgprefix, "XXX", Rdate + " " + Rtime + Rmicroseconds + " " + Rlongfile + " XXX"}, + {Ldate | Ltime | Lmicroseconds | Lshortfile | Lmsgprefix, "XXX", Rdate + " " + Rtime + Rmicroseconds + " " + Rshortfile + " XXX"}, } // Test using Println("hello", 23, "world") or using Printf("hello %d world", 23) diff --git a/libgo/go/log/syslog/doc.go b/libgo/go/log/syslog/doc.go index 54585232498..bd12bea581f 100644 --- a/libgo/go/log/syslog/doc.go +++ b/libgo/go/log/syslog/doc.go @@ -22,5 +22,3 @@ package syslog // see https://golang.org/issue/1108. // BUG(akumar): This package is not implemented on Plan 9. - -// BUG(minux): This package is not implemented on NaCl (Native Client). diff --git a/libgo/go/log/syslog/example_test.go b/libgo/go/log/syslog/example_test.go index 3d5b76d219c..4288d37dee0 100644 --- a/libgo/go/log/syslog/example_test.go +++ b/libgo/go/log/syslog/example_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !windows,!nacl,!plan9 +// +build !windows,!plan9 package syslog_test diff --git a/libgo/go/log/syslog/syslog.go b/libgo/go/log/syslog/syslog.go index dfd0028e5c1..82dd4e7dd6d 100644 --- a/libgo/go/log/syslog/syslog.go +++ b/libgo/go/log/syslog/syslog.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !windows,!nacl,!plan9 +// +build !windows,!plan9 package syslog diff --git a/libgo/go/log/syslog/syslog_test.go b/libgo/go/log/syslog/syslog_test.go index 447654a8749..8df8ebbf585 100644 --- a/libgo/go/log/syslog/syslog_test.go +++ b/libgo/go/log/syslog/syslog_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !windows,!nacl,!plan9,!js +// +build !windows,!plan9,!js package syslog diff --git a/libgo/go/log/syslog/syslog_unix.go b/libgo/go/log/syslog/syslog_unix.go index 53cbf502436..940e92e5e66 100644 --- a/libgo/go/log/syslog/syslog_unix.go +++ b/libgo/go/log/syslog/syslog_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !windows,!nacl,!plan9,!solaris,!irix +// +build !windows,!plan9,!solaris,!irix package syslog diff --git a/libgo/go/math/all_test.go b/libgo/go/math/all_test.go index 208c8233e0d..1ac9d71a251 100644 --- a/libgo/go/math/all_test.go +++ b/libgo/go/math/all_test.go @@ -2005,6 +2005,64 @@ var logbBC = []float64{ 1023, } +// Test cases were generated with Berkeley TestFloat-3e/testfloat_gen. +// http://www.jhauser.us/arithmetic/TestFloat.html. +// The default rounding mode is selected (nearest/even), and exception flags are ignored. +var fmaC = []struct{ x, y, z, want float64 }{ + // Large exponent spread + {-3.999999999999087, -1.1123914289620494e-16, -7.999877929687506, -7.999877929687505}, + {-262112.0000004768, -0.06251525855623184, 1.1102230248837136e-16, 16385.99945072085}, + {-6.462348523533467e-27, -2.3763644720331857e-211, 4.000000000931324, 4.000000000931324}, + + // Effective addition + {-2.0000000037252907, 6.7904383376e-313, -3.3951933161e-313, -1.697607001654e-312}, + {-0.12499999999999999, 512.007568359375, -1.4193627164960366e-16, -64.00094604492188}, + {-2.7550648847397148e-39, -3.4028301595800694e+38, 0.9960937495343386, 1.9335955376735676}, + {5.723369164769208e+24, 3.8149300927159385e-06, 1.84489958778182e+19, 4.028324913621874e+19}, + {-0.4843749999990904, -3.6893487872543293e+19, 9.223653786709391e+18, 2.7093936974938993e+19}, + {-3.8146972665201165e-06, 4.2949672959999385e+09, -2.2204460489938386e-16, -16384.000003844263}, + {6.98156394130982e-309, -1.1072962560000002e+09, -4.4414561548793455e-308, -7.73065965765153e-300}, + + // Effective subtraction + {5e-324, 4.5, -2e-323, 0}, + {5e-324, 7, -3.5e-323, 0}, + {5e-324, 0.5000000000000001, -5e-324, Copysign(0, -1)}, + {-2.1240680525e-314, -1.233647078189316e+308, -0.25781249999954525, -0.25780987964919844}, + {8.579992955364441e-308, 0.6037391876780558, -4.4501307410480706e-308, 7.29947236107098e-309}, + {-4.450143471986689e-308, -0.9960937499927239, -4.450419332475649e-308, -1.7659233458788e-310}, + {1.4932076393918112, -2.2248022430460833e-308, 4.449875571054211e-308, 1.127783865601762e-308}, + + // Overflow + {-2.288020632214759e+38, -8.98846570988901e+307, 1.7696041796300924e+308, Inf(0)}, + {1.4888652783208255e+308, -9.007199254742012e+15, -6.807282911929205e+38, Inf(-1)}, + {9.142703268902826e+192, -1.3504889569802838e+296, -1.9082200803806996e-89, Inf(-1)}, + + // Finite x and y, but non-finite z. + {31.99218749627471, -1.7976930544991702e+308, Inf(0), Inf(0)}, + {-1.7976931281784667e+308, -2.0009765625002265, Inf(-1), Inf(-1)}, + + // Special + {0, 0, 0, 0}, + {-1.1754226043408471e-38, NaN(), Inf(0), NaN()}, + {0, 0, 2.22507385643494e-308, 2.22507385643494e-308}, + {-8.65697792e+09, NaN(), -7.516192799999999e+09, NaN()}, + {-0.00012207403779029757, 3.221225471996093e+09, NaN(), NaN()}, + {Inf(-1), 0.1252441407414153, -1.387184532981584e-76, Inf(-1)}, + {Inf(0), 1.525878907671432e-05, -9.214364835452549e+18, Inf(0)}, + + // Random + {0.1777916152213626, -32.000015266239636, -2.2204459148334633e-16, -5.689334401293007}, + {-2.0816681711722314e-16, -0.4997558592585846, -0.9465627129124969, -0.9465627129124968}, + {-1.9999997615814211, 1.8518819259933516e+19, 16.874999999999996, -3.703763410463646e+19}, + {-0.12499994039717421, 32767.99999976135, -2.0752587082923246e+19, -2.075258708292325e+19}, + {7.705600568510257e-34, -1.801432979000528e+16, -0.17224197722973714, -0.17224197722973716}, + {3.8988133103758913e-308, -0.9848632812499999, 3.893879244098556e-308, 5.40811742605814e-310}, + {-0.012651981190687427, 6.911985574912436e+38, 6.669240527007144e+18, -8.745031148409496e+36}, + {4.612811918325842e+18, 1.4901161193847641e-08, 2.6077032311277997e-08, 6.873625395187494e+10}, + {-9.094947033611148e-13, 4.450691014249257e-308, 2.086006742350485e-308, 2.086006742346437e-308}, + {-7.751454006381804e-05, 5.588653777189071e-308, -2.2207280111272877e-308, -2.2211612130544025e-308}, +} + func tolerance(a, b, e float64) bool { // Multiplying by e here can underflow denormal values to zero. // Check a==b so that at least if a and b are small and identical @@ -2995,6 +3053,21 @@ func TestYn(t *testing.T) { } } +var PortableFMA = FMA // hide call from compiler intrinsic; falls back to portable code + +func TestFMA(t *testing.T) { + for _, c := range fmaC { + got := FMA(c.x, c.y, c.z) + if !alike(got, c.want) { + t.Errorf("FMA(%g,%g,%g) == %g; want %g", c.x, c.y, c.z, got, c.want) + } + got = PortableFMA(c.x, c.y, c.z) + if !alike(got, c.want) { + t.Errorf("PortableFMA(%g,%g,%g) == %g; want %g", c.x, c.y, c.z, got, c.want) + } + } +} + // Check that math functions of high angle values // return accurate results. [Since (vf[i] + large) - large != vf[i], // testing for Trig(vf[i] + large) == Trig(vf[i]), where large is @@ -3725,3 +3798,11 @@ func BenchmarkFloat32frombits(b *testing.B) { } GlobalF = float64(x) } + +func BenchmarkFMA(b *testing.B) { + x := 0.0 + for i := 0; i < b.N; i++ { + x = FMA(E, Pi, x) + } + GlobalF = x +} diff --git a/libgo/go/math/big/floatconv_test.go b/libgo/go/math/big/floatconv_test.go index c6c6ba63e58..3aa68341436 100644 --- a/libgo/go/math/big/floatconv_test.go +++ b/libgo/go/math/big/floatconv_test.go @@ -536,6 +536,10 @@ func TestFloatText(t *testing.T) { {"-8191.53125", ToNegativeInf, 53, 'x', 4, "-0x1.fff9p+12"}, {"8191.53125", ToPositiveInf, 53, 'x', 4, "0x1.fff9p+12"}, {"-8191.53125", ToPositiveInf, 53, 'x', 4, "-0x1.fff8p+12"}, + + // issue 34343 + {"0x.8p-2147483648", ToNearestEven, 4, 'p', -1, "0x.8p-2147483648"}, + {"0x.8p-2147483648", ToNearestEven, 4, 'x', -1, "0x1p-2147483649"}, } { f, _, err := ParseFloat(test.x, 0, test.prec, ToNearestEven) if err != nil { diff --git a/libgo/go/math/big/ftoa.go b/libgo/go/math/big/ftoa.go index 6cae63ed097..5506e6e4257 100644 --- a/libgo/go/math/big/ftoa.go +++ b/libgo/go/math/big/ftoa.go @@ -384,7 +384,7 @@ func (x *Float) fmtX(buf []byte, prec int) []byte { case w > n: m = nat(nil).shr(m, w-n) } - exp := x.exp - 1 + exp64 := int64(x.exp) - 1 // avoid wrap-around hm := m.utoa(16) if debugFloat && hm[0] != '1' { @@ -397,7 +397,6 @@ func (x *Float) fmtX(buf []byte, prec int) []byte { } buf = append(buf, 'p') - exp64 := int64(exp) if exp64 >= 0 { buf = append(buf, '+') } else { diff --git a/libgo/go/math/big/int.go b/libgo/go/math/big/int.go index 8e52f0ab27b..bf1fa73cce3 100644 --- a/libgo/go/math/big/int.go +++ b/libgo/go/math/big/int.go @@ -323,6 +323,8 @@ func (x *Int) Cmp(y *Int) (r int) { // (-x) cmp y == y // (-x) cmp (-y) == -(x cmp y) switch { + case x == y: + // nothing to do case x.neg == y.neg: r = x.abs.cmp(y.abs) if x.neg { @@ -466,7 +468,7 @@ func (x *Int) TrailingZeroBits() uint { // If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. If m > 0, y < 0, // and x and n are not relatively prime, z is unchanged and nil is returned. // -// Modular exponentation of inputs of a particular size is not a +// Modular exponentiation of inputs of a particular size is not a // cryptographically constant-time operation. func (z *Int) Exp(x, y, m *Int) *Int { // See Knuth, volume 2, section 4.6.3. @@ -500,18 +502,36 @@ func (z *Int) Exp(x, y, m *Int) *Int { return z } -// GCD sets z to the greatest common divisor of a and b, which both must -// be > 0, and returns z. +// GCD sets z to the greatest common divisor of a and b and returns z. // If x or y are not nil, GCD sets their value such that z = a*x + b*y. -// If either a or b is <= 0, GCD sets z = x = y = 0. +// Regardless of the signs of a and b, z is always >= 0. +// If a == b == 0, GCD sets z = x = y = 0. +// If a == 0 and b != 0, GCD sets z = |b|, x = 0, y = sign(b) * 1. +// If a != 0 and b == 0, GCD sets z = |a|, x = sign(a) * 1, y = 0. func (z *Int) GCD(x, y, a, b *Int) *Int { - if a.Sign() <= 0 || b.Sign() <= 0 { - z.SetInt64(0) + if len(a.abs) == 0 || len(b.abs) == 0 { + lenA, lenB, negA, negB := len(a.abs), len(b.abs), a.neg, b.neg + if lenA == 0 { + z.Set(b) + } else { + z.Set(a) + } + z.neg = false if x != nil { - x.SetInt64(0) + if lenA == 0 { + x.SetUint64(0) + } else { + x.SetUint64(1) + x.neg = negA + } } if y != nil { - y.SetInt64(0) + if lenB == 0 { + y.SetUint64(0) + } else { + y.SetUint64(1) + y.neg = negB + } } return z } @@ -619,7 +639,7 @@ func euclidUpdate(A, B, Ua, Ub, q, r, s, t *Int, extended bool) { } // lehmerGCD sets z to the greatest common divisor of a and b, -// which both must be > 0, and returns z. +// which both must be != 0, and returns z. // If x or y are not nil, their values are set such that z = a*x + b*y. // See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm L. // This implementation uses the improved condition by Collins requiring only one @@ -631,8 +651,8 @@ func euclidUpdate(A, B, Ua, Ub, q, r, s, t *Int, extended bool) { func (z *Int) lehmerGCD(x, y, a, b *Int) *Int { var A, B, Ua, Ub *Int - A = new(Int).Set(a) - B = new(Int).Set(b) + A = new(Int).Abs(a) + B = new(Int).Abs(b) extended := x != nil || y != nil @@ -718,7 +738,7 @@ func (z *Int) lehmerGCD(x, y, a, b *Int) *Int { A.abs[0] = aWord } } - + negA := a.neg if y != nil { // avoid aliasing b needed in the division below if y == b { @@ -728,12 +748,18 @@ func (z *Int) lehmerGCD(x, y, a, b *Int) *Int { } // y = (z - a*x)/b y.Mul(a, Ua) // y can safely alias a + if negA { + y.neg = !y.neg + } y.Sub(A, y) y.Div(y, B) } if x != nil { *x = *Ua + if negA { + x.neg = !x.neg + } } *z = *A diff --git a/libgo/go/math/big/int_test.go b/libgo/go/math/big/int_test.go index ade973b2074..e3a1587b3f0 100644 --- a/libgo/go/math/big/int_test.go +++ b/libgo/go/math/big/int_test.go @@ -757,11 +757,13 @@ var gcdTests = []struct { }{ // a <= 0 || b <= 0 {"0", "0", "0", "0", "0"}, - {"0", "0", "0", "0", "7"}, - {"0", "0", "0", "11", "0"}, - {"0", "0", "0", "-77", "35"}, - {"0", "0", "0", "64515", "-24310"}, - {"0", "0", "0", "-64515", "-24310"}, + {"7", "0", "1", "0", "7"}, + {"7", "0", "-1", "0", "-7"}, + {"11", "1", "0", "11", "0"}, + {"7", "-1", "-2", "-77", "35"}, + {"935", "-3", "8", "64515", "24310"}, + {"935", "-3", "-8", "64515", "-24310"}, + {"935", "3", "-8", "-64515", "-24310"}, {"1", "-9", "47", "120", "23"}, {"7", "1", "-2", "77", "35"}, @@ -1071,6 +1073,20 @@ func TestCmpAbs(t *testing.T) { } } +func TestIntCmpSelf(t *testing.T) { + for _, s := range cmpAbsTests { + x, ok := new(Int).SetString(s, 0) + if !ok { + t.Fatalf("SetString(%s, 0) failed", s) + } + got := x.Cmp(x) + want := 0 + if got != want { + t.Errorf("x = %s: x.Cmp(x): got %d; want %d", x, got, want) + } + } +} + var int64Tests = []string{ // int64 "0", @@ -1813,8 +1829,11 @@ func benchmarkDiv(b *testing.B, aSize, bSize int) { } func BenchmarkDiv(b *testing.B) { - min, max, step := 10, 100000, 10 - for i := min; i <= max; i *= step { + sizes := []int{ + 10, 20, 50, 100, 200, 500, 1000, + 1e4, 1e5, 1e6, 1e7, + } + for _, i := range sizes { j := 2 * i b.Run(fmt.Sprintf("%d/%d", j, i), func(b *testing.B) { benchmarkDiv(b, j, i) diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go index 22d7a6cac06..1b771ca7c63 100644 --- a/libgo/go/math/big/nat.go +++ b/libgo/go/math/big/nat.go @@ -463,7 +463,8 @@ func (z nat) mul(x, y nat) nat { // be a larger valid threshold contradicting the assumption about k. // if k < n || m != n { - var t nat + tp := getNat(3 * k) + t := *tp // add x0*y1*b x0 := x0.norm() @@ -484,6 +485,8 @@ func (z nat) mul(x, y nat) nat { t = t.mul(xi, y1) addAt(z, t, i+k) } + + putNat(tp) } return z.norm() @@ -495,7 +498,9 @@ func (z nat) mul(x, y nat) nat { // The (non-normalized) result is placed in z. func basicSqr(z, x nat) { n := len(x) - t := make(nat, 2*n) // temporary variable to hold the products + tp := getNat(2 * n) + t := *tp // temporary variable to hold the products + t.clear() z[1], z[0] = mulWW(x[0], x[0]) // the initial square for i := 1; i < n; i++ { d := x[i] @@ -506,6 +511,7 @@ func basicSqr(z, x nat) { } t[2*n-1] = shlVU(t[1:2*n-1], t[1:2*n-1], 1) // double the j < i products addVV(z, z, t) // combine the result + putNat(tp) } // karatsubaSqr squares x and leaves the result in z. @@ -592,7 +598,8 @@ func (z nat) sqr(x nat) nat { z[2*k:].clear() if k < n { - var t nat + tp := getNat(2 * k) + t := *tp x0 := x0.norm() x1 := x[k:] t = t.mul(x0, x1) @@ -600,6 +607,7 @@ func (z nat) sqr(x nat) nat { addAt(z, t, k) // z = 2*x1*x0*b + x0^2 t = t.sqr(x1) addAt(z, t, 2*k) // z = x1^2*b^2 + 2*x1*x0*b + x0^2 + putNat(tp) } return z.norm() @@ -685,7 +693,7 @@ func putNat(x *nat) { var natPool sync.Pool -// q = (uIn-r)/vIn, with 0 <= r < y +// q = (uIn-r)/vIn, with 0 <= r < vIn // Uses z as storage for q, and u as storage for r if possible. // See Knuth, Volume 2, section 4.3.1, Algorithm D. // Preconditions: @@ -713,6 +721,30 @@ func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) { } q = z.make(m + 1) + if n < divRecursiveThreshold { + q.divBasic(u, v) + } else { + q.divRecursive(u, v) + } + putNat(vp) + + q = q.norm() + shrVU(u, u, shift) + r = u.norm() + + return q, r +} + +// divBasic performs word-by-word division of u by v. +// The quotient is written in pre-allocated q. +// The remainder overwrites input u. +// +// Precondition: +// - len(q) >= len(u)-len(v) +func (q nat) divBasic(u, v nat) { + n := len(v) + m := len(u) - n + qhatvp := getNat(n + 1) qhatv := *qhatvp @@ -721,7 +753,11 @@ func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) { for j := m; j >= 0; j-- { // D3. qhat := Word(_M) - if ujn := u[j+n]; ujn != vn1 { + var ujn Word + if j+n < len(u) { + ujn = u[j+n] + } + if ujn != vn1 { var rhat Word qhat, rhat = divWW(ujn, u[j+n-1], vn1) @@ -744,25 +780,175 @@ func (z nat) divLarge(u, uIn, vIn nat) (q, r nat) { // D4. qhatv[n] = mulAddVWW(qhatv[0:n], v, qhat, 0) - - c := subVV(u[j:j+len(qhatv)], u[j:], qhatv) + qhl := len(qhatv) + if j+qhl > len(u) && qhatv[n] == 0 { + qhl-- + } + c := subVV(u[j:j+qhl], u[j:], qhatv) if c != 0 { c := addVV(u[j:j+n], u[j:], v) u[j+n] += c qhat-- } + if j == m && m == len(q) && qhat == 0 { + continue + } q[j] = qhat } - putNat(vp) putNat(qhatvp) +} - q = q.norm() - shrVU(u, u, shift) - r = u.norm() +const divRecursiveThreshold = 100 - return q, r +// divRecursive performs word-by-word division of u by v. +// The quotient is written in pre-allocated z. +// The remainder overwrites input u. +// +// Precondition: +// - len(z) >= len(u)-len(v) +// +// See Burnikel, Ziegler, "Fast Recursive Division", Algorithm 1 and 2. +func (z nat) divRecursive(u, v nat) { + // Recursion depth is less than 2 log2(len(v)) + // Allocate a slice of temporaries to be reused across recursion. + recDepth := 2 * bits.Len(uint(len(v))) + // large enough to perform Karatsuba on operands as large as v + tmp := getNat(3 * len(v)) + temps := make([]*nat, recDepth) + z.clear() + z.divRecursiveStep(u, v, 0, tmp, temps) + for _, n := range temps { + if n != nil { + putNat(n) + } + } + putNat(tmp) +} + +func (z nat) divRecursiveStep(u, v nat, depth int, tmp *nat, temps []*nat) { + u = u.norm() + v = v.norm() + + if len(u) == 0 { + z.clear() + return + } + n := len(v) + if n < divRecursiveThreshold { + z.divBasic(u, v) + return + } + m := len(u) - n + if m < 0 { + return + } + + // Produce the quotient by blocks of B words. + // Division by v (length n) is done using a length n/2 division + // and a length n/2 multiplication for each block. The final + // complexity is driven by multiplication complexity. + B := n / 2 + + // Allocate a nat for qhat below. + if temps[depth] == nil { + temps[depth] = getNat(n) + } else { + *temps[depth] = temps[depth].make(B + 1) + } + + j := m + for j > B { + // Divide u[j-B:j+n] by vIn. Keep remainder in u + // for next block. + // + // The following property will be used (Lemma 2): + // if u = u1 << s + u0 + // v = v1 << s + v0 + // then floor(u1/v1) >= floor(u/v) + // + // Moreover, the difference is at most 2 if len(v1) >= len(u/v) + // We choose s = B-1 since len(v)-B >= B+1 >= len(u/v) + s := (B - 1) + // Except for the first step, the top bits are always + // a division remainder, so the quotient length is <= n. + uu := u[j-B:] + + qhat := *temps[depth] + qhat.clear() + qhat.divRecursiveStep(uu[s:B+n], v[s:], depth+1, tmp, temps) + qhat = qhat.norm() + // Adjust the quotient: + // u = u_h << s + u_l + // v = v_h << s + v_l + // u_h = q̂ v_h + rh + // u = q̂ (v - v_l) + rh << s + u_l + // After the above step, u contains a remainder: + // u = rh << s + u_l + // and we need to subtract q̂ v_l + // + // But it may be a bit too large, in which case q̂ needs to be smaller. + qhatv := tmp.make(3 * n) + qhatv.clear() + qhatv = qhatv.mul(qhat, v[:s]) + for i := 0; i < 2; i++ { + e := qhatv.cmp(uu.norm()) + if e <= 0 { + break + } + subVW(qhat, qhat, 1) + c := subVV(qhatv[:s], qhatv[:s], v[:s]) + if len(qhatv) > s { + subVW(qhatv[s:], qhatv[s:], c) + } + addAt(uu[s:], v[s:], 0) + } + if qhatv.cmp(uu.norm()) > 0 { + panic("impossible") + } + c := subVV(uu[:len(qhatv)], uu[:len(qhatv)], qhatv) + if c > 0 { + subVW(uu[len(qhatv):], uu[len(qhatv):], c) + } + addAt(z, qhat, j-B) + j -= B + } + + // Now u < (v< 0 { + subVW(qhat, qhat, 1) + c := subVV(qhatv[:s], qhatv[:s], v[:s]) + if len(qhatv) > s { + subVW(qhatv[s:], qhatv[s:], c) + } + addAt(u[s:], v[s:], 0) + } + } + if qhatv.cmp(u.norm()) > 0 { + panic("impossible") + } + c := subVV(u[0:len(qhatv)], u[0:len(qhatv)], qhatv) + if c > 0 { + c = subVW(u[len(qhatv):], u[len(qhatv):], c) + } + if c > 0 { + panic("impossible") + } + + // Done! + addAt(z, qhat.norm(), 0) } // Length of x in bits. x must be normalized. diff --git a/libgo/go/math/big/nat_test.go b/libgo/go/math/big/nat_test.go index 3c794954dc3..32f29e38769 100644 --- a/libgo/go/math/big/nat_test.go +++ b/libgo/go/math/big/nat_test.go @@ -192,10 +192,22 @@ func TestMulUnbalanced(t *testing.T) { } } +// rndNat returns a random nat value >= 0 of (usually) n words in length. +// In extremely unlikely cases it may be smaller than n words if the top- +// most words are 0. func rndNat(n int) nat { return nat(rndV(n)).norm() } +// rndNat1 is like rndNat but the result is guaranteed to be > 0. +func rndNat1(n int) nat { + x := nat(rndV(n)).norm() + if len(x) == 0 { + x.setWord(1) + } + return x +} + func BenchmarkMul(b *testing.B) { mulx := rndNat(1e4) muly := rndNat(1e4) @@ -206,6 +218,29 @@ func BenchmarkMul(b *testing.B) { } } +func benchmarkNatMul(b *testing.B, nwords int) { + x := rndNat(nwords) + y := rndNat(nwords) + var z nat + b.ResetTimer() + for i := 0; i < b.N; i++ { + z.mul(x, y) + } +} + +var mulBenchSizes = []int{10, 100, 1000, 10000, 100000} + +func BenchmarkNatMul(b *testing.B) { + for _, n := range mulBenchSizes { + if isRaceBuilder && n > 1e3 { + continue + } + b.Run(fmt.Sprintf("%d", n), func(b *testing.B) { + benchmarkNatMul(b, n) + }) + } +} + func TestNLZ(t *testing.T) { var x Word = _B >> 1 for i := 0; i <= _W; i++ { @@ -681,7 +716,11 @@ func benchmarkNatSqr(b *testing.B, nwords int) { } } -var sqrBenchSizes = []int{1, 2, 3, 5, 8, 10, 20, 30, 50, 80, 100, 200, 300, 500, 800, 1000} +var sqrBenchSizes = []int{ + 1, 2, 3, 5, 8, 10, 20, 30, 50, 80, + 100, 200, 300, 500, 800, + 1000, 10000, 100000, +} func BenchmarkNatSqr(b *testing.B) { for _, n := range sqrBenchSizes { @@ -712,3 +751,38 @@ func BenchmarkNatSetBytes(b *testing.B) { }) } } + +func TestNatDiv(t *testing.T) { + sizes := []int{ + 1, 2, 5, 8, 15, 25, 40, 65, 100, + 200, 500, 800, 1500, 2500, 4000, 6500, 10000, + } + for _, i := range sizes { + for _, j := range sizes { + a := rndNat1(i) + b := rndNat1(j) + // the test requires b >= 2 + if len(b) == 1 && b[0] == 1 { + b[0] = 2 + } + // choose a remainder c < b + c := rndNat1(len(b)) + if len(c) == len(b) && c[len(c)-1] >= b[len(b)-1] { + c[len(c)-1] = 0 + c = c.norm() + } + // compute x = a*b+c + x := nat(nil).mul(a, b) + x = x.add(x, c) + + var q, r nat + q, r = q.div(r, x, b) + if q.cmp(a) != 0 { + t.Fatalf("wrong quotient: got %s; want %s for %s/%s", q.utoa(10), a.utoa(10), x.utoa(10), b.utoa(10)) + } + if r.cmp(c) != 0 { + t.Fatalf("wrong remainder: got %s; want %s for %s/%s", r.utoa(10), c.utoa(10), x.utoa(10), b.utoa(10)) + } + } + } +} diff --git a/libgo/go/math/big/rat.go b/libgo/go/math/big/rat.go index c8bf698b184..d35cd4cbd10 100644 --- a/libgo/go/math/big/rat.go +++ b/libgo/go/math/big/rat.go @@ -22,7 +22,9 @@ import ( // of Rats are not supported and may lead to errors. type Rat struct { // To make zero values for Rat work w/o initialization, - // a zero value of b (len(b) == 0) acts like b == 1. + // a zero value of b (len(b) == 0) acts like b == 1. At + // the earliest opportunity (when an assignment to the Rat + // is made), such uninitialized denominators are set to 1. // a.neg determines the sign of the Rat, b.neg is ignored. a, b Int } @@ -271,7 +273,7 @@ func quotToFloat64(a, b nat) (f float64, exact bool) { func (x *Rat) Float32() (f float32, exact bool) { b := x.b.abs if len(b) == 0 { - b = b.set(natOne) // materialize denominator + b = natOne } f, exact = quotToFloat32(x.a.abs, b) if x.a.neg { @@ -287,7 +289,7 @@ func (x *Rat) Float32() (f float32, exact bool) { func (x *Rat) Float64() (f float64, exact bool) { b := x.b.abs if len(b) == 0 { - b = b.set(natOne) // materialize denominator + b = natOne } f, exact = quotToFloat64(x.a.abs, b) if x.a.neg { @@ -297,6 +299,7 @@ func (x *Rat) Float64() (f float64, exact bool) { } // SetFrac sets z to a/b and returns z. +// If b == 0, SetFrac panics. func (z *Rat) SetFrac(a, b *Int) *Rat { z.a.neg = a.neg != b.neg babs := b.abs @@ -312,11 +315,12 @@ func (z *Rat) SetFrac(a, b *Int) *Rat { } // SetFrac64 sets z to a/b and returns z. +// If b == 0, SetFrac64 panics. func (z *Rat) SetFrac64(a, b int64) *Rat { - z.a.SetInt64(a) if b == 0 { panic("division by zero") } + z.a.SetInt64(a) if b < 0 { b = -b z.a.neg = !z.a.neg @@ -328,21 +332,21 @@ func (z *Rat) SetFrac64(a, b int64) *Rat { // SetInt sets z to x (by making a copy of x) and returns z. func (z *Rat) SetInt(x *Int) *Rat { z.a.Set(x) - z.b.abs = z.b.abs[:0] + z.b.abs = z.b.abs.setWord(1) return z } // SetInt64 sets z to x and returns z. func (z *Rat) SetInt64(x int64) *Rat { z.a.SetInt64(x) - z.b.abs = z.b.abs[:0] + z.b.abs = z.b.abs.setWord(1) return z } // SetUint64 sets z to x and returns z. func (z *Rat) SetUint64(x uint64) *Rat { z.a.SetUint64(x) - z.b.abs = z.b.abs[:0] + z.b.abs = z.b.abs.setWord(1) return z } @@ -352,6 +356,9 @@ func (z *Rat) Set(x *Rat) *Rat { z.a.Set(&x.a) z.b.Set(&x.b) } + if len(z.b.abs) == 0 { + z.b.abs = z.b.abs.setWord(1) + } return z } @@ -370,20 +377,13 @@ func (z *Rat) Neg(x *Rat) *Rat { } // Inv sets z to 1/x and returns z. +// If x == 0, Inv panics. func (z *Rat) Inv(x *Rat) *Rat { if len(x.a.abs) == 0 { panic("division by zero") } z.Set(x) - a := z.b.abs - if len(a) == 0 { - a = a.set(natOne) // materialize numerator - } - b := z.a.abs - if b.cmp(natOne) == 0 { - b = b[:0] // normalize denominator - } - z.a.abs, z.b.abs = a, b // sign doesn't change + z.a.abs, z.b.abs = z.b.abs, z.a.abs return z } @@ -411,12 +411,19 @@ func (x *Rat) Num() *Int { } // Denom returns the denominator of x; it is always > 0. -// The result is a reference to x's denominator; it +// The result is a reference to x's denominator, unless +// x is an uninitialized (zero value) Rat, in which case +// the result is a new Int of value 1. (To initialize x, +// any operation that sets x will do, including x.Set(x).) +// If the result is a reference to x's denominator it // may change if a new value is assigned to x, and vice versa. func (x *Rat) Denom() *Int { x.b.neg = false // the result is always >= 0 if len(x.b.abs) == 0 { - x.b.abs = x.b.abs.set(natOne) // materialize denominator + // Note: If this proves problematic, we could + // panic instead and require the Rat to + // be explicitly initialized. + return &Int{abs: nat{1}} } return &x.b } @@ -424,25 +431,20 @@ func (x *Rat) Denom() *Int { func (z *Rat) norm() *Rat { switch { case len(z.a.abs) == 0: - // z == 0 - normalize sign and denominator + // z == 0; normalize sign and denominator z.a.neg = false - z.b.abs = z.b.abs[:0] + fallthrough case len(z.b.abs) == 0: - // z is normalized int - nothing to do - case z.b.abs.cmp(natOne) == 0: - // z is int - normalize denominator - z.b.abs = z.b.abs[:0] + // z is integer; normalize denominator + z.b.abs = z.b.abs.setWord(1) default: + // z is fraction; normalize numerator and denominator neg := z.a.neg z.a.neg = false z.b.neg = false if f := NewInt(0).lehmerGCD(nil, nil, &z.a, &z.b); f.Cmp(intOne) != 0 { z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f.abs) z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs) - if z.b.abs.cmp(natOne) == 0 { - // z is int - normalize denominator - z.b.abs = z.b.abs[:0] - } } z.a.neg = neg } @@ -454,6 +456,8 @@ func (z *Rat) norm() *Rat { // returns z. func mulDenom(z, x, y nat) nat { switch { + case len(x) == 0 && len(y) == 0: + return z.setWord(1) case len(x) == 0: return z.set(y) case len(y) == 0: @@ -509,10 +513,14 @@ func (z *Rat) Sub(x, y *Rat) *Rat { // Mul sets z to the product x*y and returns z. func (z *Rat) Mul(x, y *Rat) *Rat { if x == y { - // a squared Rat is positive and can't be reduced + // a squared Rat is positive and can't be reduced (no need to call norm()) z.a.neg = false z.a.abs = z.a.abs.sqr(x.a.abs) - z.b.abs = z.b.abs.sqr(x.b.abs) + if len(x.b.abs) == 0 { + z.b.abs = z.b.abs.setWord(1) + } else { + z.b.abs = z.b.abs.sqr(x.b.abs) + } return z } z.a.Mul(&x.a, &y.a) @@ -521,7 +529,7 @@ func (z *Rat) Mul(x, y *Rat) *Rat { } // Quo sets z to the quotient x/y and returns z. -// If y == 0, a division-by-zero run-time panic occurs. +// If y == 0, Quo panics. func (z *Rat) Quo(x, y *Rat) *Rat { if len(y.a.abs) == 0 { panic("division by zero") diff --git a/libgo/go/math/big/rat_test.go b/libgo/go/math/big/rat_test.go index 83c5d5cfea1..02569c1b16a 100644 --- a/libgo/go/math/big/rat_test.go +++ b/libgo/go/math/big/rat_test.go @@ -329,18 +329,40 @@ func TestIssue3521(t *testing.T) { t.Errorf("0) got %s want %s", zero.Denom(), one) } - // 1a) a zero value remains zero independent of denominator + // 1a) the denominator of an (uninitialized) zero value is not shared with the value + s := &zero.b + d := zero.Denom() + if d == s { + t.Errorf("1a) got %s (%p) == %s (%p) want different *Int values", d, d, s, s) + } + + // 1b) the denominator of an (uninitialized) value is a new 1 each time + d1 := zero.Denom() + d2 := zero.Denom() + if d1 == d2 { + t.Errorf("1b) got %s (%p) == %s (%p) want different *Int values", d1, d1, d2, d2) + } + + // 1c) the denominator of an initialized zero value is shared with the value x := new(Rat) + x.Set(x) // initialize x (any operation that sets x explicitly will do) + s = &x.b + d = x.Denom() + if d != s { + t.Errorf("1c) got %s (%p) != %s (%p) want identical *Int values", d, d, s, s) + } + + // 1d) a zero value remains zero independent of denominator x.Denom().Set(new(Int).Neg(b)) if x.Cmp(zero) != 0 { - t.Errorf("1a) got %s want %s", x, zero) + t.Errorf("1d) got %s want %s", x, zero) } - // 1b) a zero value may have a denominator != 0 and != 1 + // 1e) a zero value may have a denominator != 0 and != 1 x.Num().Set(a) qab := new(Rat).SetFrac(a, b) if x.Cmp(qab) != 0 { - t.Errorf("1b) got %s want %s", x, qab) + t.Errorf("1e) got %s want %s", x, qab) } // 2a) an integral value becomes a fraction depending on denominator @@ -678,3 +700,29 @@ func BenchmarkRatCmp(b *testing.B) { x.Cmp(y) } } + +// TestIssue34919 verifies that a Rat's denominator is not modified +// when simply accessing the Rat value. +func TestIssue34919(t *testing.T) { + for _, acc := range []struct { + name string + f func(*Rat) + }{ + {"Float32", func(x *Rat) { x.Float32() }}, + {"Float64", func(x *Rat) { x.Float64() }}, + {"Inv", func(x *Rat) { new(Rat).Inv(x) }}, + {"Sign", func(x *Rat) { x.Sign() }}, + {"IsInt", func(x *Rat) { x.IsInt() }}, + {"Num", func(x *Rat) { x.Num() }}, + // {"Denom", func(x *Rat) { x.Denom() }}, TODO(gri) should we change the API? See issue #33792. + } { + // A denominator of length 0 is interpreted as 1. Make sure that + // "materialization" of the denominator doesn't lead to setting + // the underlying array element 0 to 1. + r := &Rat{Int{abs: nat{991}}, Int{abs: make(nat, 0, 1)}} + acc.f(r) + if d := r.b.abs[:1][0]; d != 0 { + t.Errorf("%s modified denominator: got %d, want 0", acc.name, d) + } + } +} diff --git a/libgo/go/math/big/ratconv.go b/libgo/go/math/big/ratconv.go index f29ec98cdcb..941139e72d1 100644 --- a/libgo/go/math/big/ratconv.go +++ b/libgo/go/math/big/ratconv.go @@ -123,7 +123,7 @@ func (z *Rat) SetString(s string) (*Rat, bool) { // Multiplications are commutative, so we can apply them in any // order. We only have powers of 2 and 10, and we split powers // of 10 into the product of the same powers of 2 and 5. This - // may reduce the the size of shift/multiplication factors or + // may reduce the size of shift/multiplication factors or // divisors required to create the final fraction, depending // on the actual floating-point value. diff --git a/libgo/go/math/bits/bits.go b/libgo/go/math/bits/bits.go index 3114c14030b..0bfe90c4552 100644 --- a/libgo/go/math/bits/bits.go +++ b/libgo/go/math/bits/bits.go @@ -555,3 +555,34 @@ func Div64(hi, lo, y uint64) (quo, rem uint64) { return q1*two32 + q0, (un21*two32 + un0 - q0*y) >> s } + +// Rem returns the remainder of (hi, lo) divided by y. Rem panics for +// y == 0 (division by zero) but, unlike Div, it doesn't panic on a +// quotient overflow. +func Rem(hi, lo, y uint) uint { + if UintSize == 32 { + return uint(Rem32(uint32(hi), uint32(lo), uint32(y))) + } + return uint(Rem64(uint64(hi), uint64(lo), uint64(y))) +} + +// Rem32 returns the remainder of (hi, lo) divided by y. Rem32 panics +// for y == 0 (division by zero) but, unlike Div32, it doesn't panic +// on a quotient overflow. +func Rem32(hi, lo, y uint32) uint32 { + return uint32((uint64(hi)<<32 | uint64(lo)) % uint64(y)) +} + +// Rem64 returns the remainder of (hi, lo) divided by y. Rem64 panics +// for y == 0 (division by zero) but, unlike Div64, it doesn't panic +// on a quotient overflow. +func Rem64(hi, lo, y uint64) uint64 { + // We scale down hi so that hi < y, then use Div64 to compute the + // rem with the guarantee that it won't panic on quotient overflow. + // Given that + // hi ≡ hi%y (mod y) + // we have + // hi<<64 + lo ≡ (hi%y)<<64 + lo (mod y) + _, rem := Div64(hi%y, lo, y) + return rem +} diff --git a/libgo/go/math/bits/bits_test.go b/libgo/go/math/bits/bits_test.go index afdfd393bb3..c0f43093d9b 100644 --- a/libgo/go/math/bits/bits_test.go +++ b/libgo/go/math/bits/bits_test.go @@ -984,6 +984,76 @@ func TestDiv64PanicZero(t *testing.T) { t.Errorf("undefined q, r = %v, %v calculated when Div64 should have panicked", q, r) } +func TestRem32(t *testing.T) { + // Sanity check: for non-oveflowing dividends, the result is the + // same as the rem returned by Div32 + hi, lo, y := uint32(510510), uint32(9699690), uint32(510510+1) // ensure hi < y + for i := 0; i < 1000; i++ { + r := Rem32(hi, lo, y) + _, r2 := Div32(hi, lo, y) + if r != r2 { + t.Errorf("Rem32(%v, %v, %v) returned %v, but Div32 returned rem %v", hi, lo, y, r, r2) + } + y += 13 + } +} + +func TestRem32Overflow(t *testing.T) { + // To trigger a quotient overflow, we need y <= hi + hi, lo, y := uint32(510510), uint32(9699690), uint32(7) + for i := 0; i < 1000; i++ { + r := Rem32(hi, lo, y) + _, r2 := Div64(0, uint64(hi)<<32|uint64(lo), uint64(y)) + if r != uint32(r2) { + t.Errorf("Rem32(%v, %v, %v) returned %v, but Div64 returned rem %v", hi, lo, y, r, r2) + } + y += 13 + } +} + +func TestRem64(t *testing.T) { + // Sanity check: for non-oveflowing dividends, the result is the + // same as the rem returned by Div64 + hi, lo, y := uint64(510510), uint64(9699690), uint64(510510+1) // ensure hi < y + for i := 0; i < 1000; i++ { + r := Rem64(hi, lo, y) + _, r2 := Div64(hi, lo, y) + if r != r2 { + t.Errorf("Rem64(%v, %v, %v) returned %v, but Div64 returned rem %v", hi, lo, y, r, r2) + } + y += 13 + } +} + +func TestRem64Overflow(t *testing.T) { + Rem64Tests := []struct { + hi, lo, y uint64 + rem uint64 + }{ + // Testcases computed using Python 3, as: + // >>> hi = 42; lo = 1119; y = 42 + // >>> ((hi<<64)+lo) % y + {42, 1119, 42, 27}, + {42, 1119, 38, 9}, + {42, 1119, 26, 23}, + {469, 0, 467, 271}, + {469, 0, 113, 58}, + {111111, 111111, 1171, 803}, + {3968194946088682615, 3192705705065114702, 1000037, 56067}, + } + + for _, rt := range Rem64Tests { + if rt.hi < rt.y { + t.Fatalf("Rem64(%v, %v, %v) is not a test with quo overflow", rt.hi, rt.lo, rt.y) + } + rem := Rem64(rt.hi, rt.lo, rt.y) + if rem != rt.rem { + t.Errorf("Rem64(%v, %v, %v) returned %v, wanted %v", + rt.hi, rt.lo, rt.y, rem, rt.rem) + } + } +} + func BenchmarkAdd(b *testing.B) { var z, c uint for i := 0; i < b.N; i++ { diff --git a/libgo/go/math/example_test.go b/libgo/go/math/example_test.go index 364891324a0..50c74269792 100644 --- a/libgo/go/math/example_test.go +++ b/libgo/go/math/example_test.go @@ -44,6 +44,11 @@ func ExampleAtanh() { // Output: 0.00 } +func ExampleCopysign() { + fmt.Printf("%.2f", math.Copysign(3.2, -1)) + // Output: -3.20 +} + func ExampleCos() { fmt.Printf("%.2f", math.Cos(math.Pi/2)) // Output: 0.00 @@ -173,3 +178,44 @@ func ExampleAbs() { // 2.0 // 2.0 } +func ExampleDim() { + fmt.Printf("%.2f\n", math.Dim(4, -2)) + fmt.Printf("%.2f\n", math.Dim(-4, 2)) + // Output: + // 6.00 + // 0.00 +} + +func ExampleExp() { + fmt.Printf("%.2f\n", math.Exp(1)) + fmt.Printf("%.2f\n", math.Exp(2)) + fmt.Printf("%.2f\n", math.Exp(-1)) + // Output: + // 2.72 + // 7.39 + // 0.37 +} + +func ExampleExp2() { + fmt.Printf("%.2f\n", math.Exp2(1)) + fmt.Printf("%.2f\n", math.Exp2(-3)) + // Output: + // 2.00 + // 0.12 +} + +func ExampleExpm1() { + fmt.Printf("%.6f\n", math.Expm1(0.01)) + fmt.Printf("%.6f\n", math.Expm1(-1)) + // Output: + // 0.010050 + // -0.632121 +} + +func ExampleTrunc() { + fmt.Printf("%.2f\n", math.Trunc(math.Pi)) + fmt.Printf("%.2f\n", math.Trunc(-1.2345)) + // Output: + // 3.00 + // -1.00 +} diff --git a/libgo/go/math/exp_asm.go b/libgo/go/math/exp_asm.go index 298420faeaf..11e0a611cdd 100644 --- a/libgo/go/math/exp_asm.go +++ b/libgo/go/math/exp_asm.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build amd64 amd64p32 +// +build amd64 // +build ignore package math diff --git a/libgo/go/math/fma.go b/libgo/go/math/fma.go new file mode 100644 index 00000000000..db78dfa5e15 --- /dev/null +++ b/libgo/go/math/fma.go @@ -0,0 +1,170 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package math + +import "math/bits" + +func zero(x uint64) uint64 { + if x == 0 { + return 1 + } + return 0 + // branchless: + // return ((x>>1 | x&1) - 1) >> 63 +} + +func nonzero(x uint64) uint64 { + if x != 0 { + return 1 + } + return 0 + // branchless: + // return 1 - ((x>>1|x&1)-1)>>63 +} + +func shl(u1, u2 uint64, n uint) (r1, r2 uint64) { + r1 = u1<>(64-n) | u2<<(n-64) + r2 = u2 << n + return +} + +func shr(u1, u2 uint64, n uint) (r1, r2 uint64) { + r2 = u2>>n | u1<<(64-n) | u1>>(n-64) + r1 = u1 >> n + return +} + +// shrcompress compresses the bottom n+1 bits of the two-word +// value into a single bit. the result is equal to the value +// shifted to the right by n, except the result's 0th bit is +// set to the bitwise OR of the bottom n+1 bits. +func shrcompress(u1, u2 uint64, n uint) (r1, r2 uint64) { + // TODO: Performance here is really sensitive to the + // order/placement of these branches. n == 0 is common + // enough to be in the fast path. Perhaps more measurement + // needs to be done to find the optimal order/placement? + switch { + case n == 0: + return u1, u2 + case n == 64: + return 0, u1 | nonzero(u2) + case n >= 128: + return 0, nonzero(u1 | u2) + case n < 64: + r1, r2 = shr(u1, u2, n) + r2 |= nonzero(u2 & (1<> 63) + exp = int32(b>>52) & mask + mantissa = b & fracMask + + if exp == 0 { + // Normalize value if subnormal. + shift := uint(bits.LeadingZeros64(mantissa) - 11) + mantissa <<= shift + exp = 1 - int32(shift) + } else { + // Add implicit 1 bit + mantissa |= 1 << 52 + } + return +} + +// FMA returns x * y + z, computed with only one rounding. +// (That is, FMA returns the fused multiply-add of x, y, and z.) +func FMA(x, y, z float64) float64 { + bx, by, bz := Float64bits(x), Float64bits(y), Float64bits(z) + + // Inf or NaN or zero involved. At most one rounding will occur. + if x == 0.0 || y == 0.0 || z == 0.0 || bx&uvinf == uvinf || by&uvinf == uvinf { + return x*y + z + } + // Handle non-finite z separately. Evaluating x*y+z where + // x and y are finite, but z is infinite, should always result in z. + if bz&uvinf == uvinf { + return z + } + + // Inputs are (sub)normal. + // Split x, y, z into sign, exponent, mantissa. + xs, xe, xm := split(bx) + ys, ye, ym := split(by) + zs, ze, zm := split(bz) + + // Compute product p = x*y as sign, exponent, two-word mantissa. + // Start with exponent. "is normal" bit isn't subtracted yet. + pe := xe + ye - bias + 1 + + // pm1:pm2 is the double-word mantissa for the product p. + // Shift left to leave top bit in product. Effectively + // shifts the 106-bit product to the left by 21. + pm1, pm2 := bits.Mul64(xm<<10, ym<<11) + zm1, zm2 := zm<<10, uint64(0) + ps := xs ^ ys // product sign + + // normalize to 62nd bit + is62zero := uint((^pm1 >> 62) & 1) + pm1, pm2 = shl(pm1, pm2, is62zero) + pe -= int32(is62zero) + + // Swap addition operands so |p| >= |z| + if pe < ze || (pe == ze && (pm1 < zm1 || (pm1 == zm1 && pm2 < zm2))) { + ps, pe, pm1, pm2, zs, ze, zm1, zm2 = zs, ze, zm1, zm2, ps, pe, pm1, pm2 + } + + // Align significands + zm1, zm2 = shrcompress(zm1, zm2, uint(pe-ze)) + + // Compute resulting significands, normalizing if necessary. + var m, c uint64 + if ps == zs { + // Adding (pm1:pm2) + (zm1:zm2) + pm2, c = bits.Add64(pm2, zm2, 0) + pm1, _ = bits.Add64(pm1, zm1, c) + pe -= int32(^pm1 >> 63) + pm1, m = shrcompress(pm1, pm2, uint(64+pm1>>63)) + } else { + // Subtracting (pm1:pm2) - (zm1:zm2) + // TODO: should we special-case cancellation? + pm2, c = bits.Sub64(pm2, zm2, 0) + pm1, _ = bits.Sub64(pm1, zm1, c) + nz := lz(pm1, pm2) + pe -= nz + m, pm2 = shl(pm1, pm2, uint(nz-1)) + m |= nonzero(pm2) + } + + // Round and break ties to even + if pe > 1022+bias || pe == 1022+bias && (m+1<<9)>>63 == 1 { + // rounded value overflows exponent range + return Float64frombits(uint64(ps)<<63 | uvinf) + } + if pe < 0 { + n := uint(-pe) + m = m>>n | nonzero(m&(1<> 10) & ^zero((m&(1<<10-1))^1<<9) + pe &= -int32(nonzero(m)) + return Float64frombits(uint64(ps)<<63 + uint64(pe)<<52 + m) +} diff --git a/libgo/go/math/rand/rand.go b/libgo/go/math/rand/rand.go index 04382e62088..d6422c914d8 100644 --- a/libgo/go/math/rand/rand.go +++ b/libgo/go/math/rand/rand.go @@ -261,15 +261,20 @@ func (r *Rand) Read(p []byte) (n int, err error) { if lk, ok := r.src.(*lockedSource); ok { return lk.read(p, &r.readVal, &r.readPos) } - return read(p, r.Int63, &r.readVal, &r.readPos) + return read(p, r.src, &r.readVal, &r.readPos) } -func read(p []byte, int63 func() int64, readVal *int64, readPos *int8) (n int, err error) { +func read(p []byte, src Source, readVal *int64, readPos *int8) (n int, err error) { pos := *readPos val := *readVal + rng, _ := src.(*rngSource) for n = 0; n < len(p); n++ { if pos == 0 { - val = int63() + if rng != nil { + val = rng.Int63() + } else { + val = src.Int63() + } pos = 7 } p[n] = byte(val) @@ -285,12 +290,15 @@ func read(p []byte, int63 func() int64, readVal *int64, readPos *int8) (n int, e * Top-level convenience functions */ -var globalRand = New(&lockedSource{src: NewSource(1).(Source64)}) +var globalRand = New(&lockedSource{src: NewSource(1).(*rngSource)}) + +// Type assert that globalRand's source is a lockedSource whose src is a *rngSource. +var _ *rngSource = globalRand.src.(*lockedSource).src // Seed uses the provided seed value to initialize the default Source to a // deterministic state. If Seed is not called, the generator behaves as // if seeded by Seed(1). Seed values that have the same remainder when -// divided by 2^31-1 generate the same pseudo-random sequence. +// divided by 2³¹-1 generate the same pseudo-random sequence. // Seed, unlike the Rand.Seed method, is safe for concurrent use. func Seed(seed int64) { globalRand.Seed(seed) } @@ -373,7 +381,7 @@ func ExpFloat64() float64 { return globalRand.ExpFloat64() } type lockedSource struct { lk sync.Mutex - src Source64 + src *rngSource } func (r *lockedSource) Int63() (n int64) { @@ -407,7 +415,7 @@ func (r *lockedSource) seedPos(seed int64, readPos *int8) { // read implements Read for a lockedSource without a race condition. func (r *lockedSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) { r.lk.Lock() - n, err = read(p, r.src.Int63, readVal, readPos) + n, err = read(p, r.src, readVal, readPos) r.lk.Unlock() return } diff --git a/libgo/go/math/rand/rand_test.go b/libgo/go/math/rand/rand_test.go index ee9c8f8e84b..e037aaed0ea 100644 --- a/libgo/go/math/rand/rand_test.go +++ b/libgo/go/math/rand/rand_test.go @@ -565,6 +565,14 @@ func BenchmarkInt63Threadsafe(b *testing.B) { } } +func BenchmarkInt63ThreadsafeParallel(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + Int63() + } + }) +} + func BenchmarkInt63Unthreadsafe(b *testing.B) { r := New(NewSource(1)) for n := b.N; n > 0; n-- { diff --git a/libgo/go/mime/multipart/multipart.go b/libgo/go/mime/multipart/multipart.go index a222409d3ce..1750300fb53 100644 --- a/libgo/go/mime/multipart/multipart.go +++ b/libgo/go/mime/multipart/multipart.go @@ -36,11 +36,6 @@ type Part struct { // The headers of the body, if any, with the keys canonicalized // in the same fashion that the Go http.Request headers are. // For example, "foo-bar" changes case to "Foo-Bar" - // - // As a special case, if the "Content-Transfer-Encoding" header - // has a value of "quoted-printable", that header is instead - // hidden from this map and the body is transparently decoded - // during Read calls. Header textproto.MIMEHeader mr *Reader @@ -126,7 +121,7 @@ func (r *stickyErrorReader) Read(p []byte) (n int, _ error) { return n, r.err } -func newPart(mr *Reader) (*Part, error) { +func newPart(mr *Reader, rawPart bool) (*Part, error) { bp := &Part{ Header: make(map[string][]string), mr: mr, @@ -135,10 +130,14 @@ func newPart(mr *Reader) (*Part, error) { return nil, err } bp.r = partReader{bp} - const cte = "Content-Transfer-Encoding" - if strings.EqualFold(bp.Header.Get(cte), "quoted-printable") { - bp.Header.Del(cte) - bp.r = quotedprintable.NewReader(bp.r) + + // rawPart is used to switch between Part.NextPart and Part.NextRawPart. + if !rawPart { + const cte = "Content-Transfer-Encoding" + if strings.EqualFold(bp.Header.Get(cte), "quoted-printable") { + bp.Header.Del(cte) + bp.r = quotedprintable.NewReader(bp.r) + } } return bp, nil } @@ -300,7 +299,24 @@ type Reader struct { // NextPart returns the next part in the multipart or an error. // When there are no more parts, the error io.EOF is returned. +// +// As a special case, if the "Content-Transfer-Encoding" header +// has a value of "quoted-printable", that header is instead +// hidden and the body is transparently decoded during Read calls. func (r *Reader) NextPart() (*Part, error) { + return r.nextPart(false) +} + +// NextRawPart returns the next part in the multipart or an error. +// When there are no more parts, the error io.EOF is returned. +// +// Unlike NextPart, it does not have special handling for +// "Content-Transfer-Encoding: quoted-printable". +func (r *Reader) NextRawPart() (*Part, error) { + return r.nextPart(true) +} + +func (r *Reader) nextPart(rawPart bool) (*Part, error) { if r.currentPart != nil { r.currentPart.Close() } @@ -325,7 +341,7 @@ func (r *Reader) NextPart() (*Part, error) { if r.isBoundaryDelimiterLine(line) { r.partsRead++ - bp, err := newPart(r) + bp, err := newPart(r, rawPart) if err != nil { return nil, err } diff --git a/libgo/go/mime/multipart/multipart_test.go b/libgo/go/mime/multipart/multipart_test.go index 5dc74b5ffe1..b60c54a2042 100644 --- a/libgo/go/mime/multipart/multipart_test.go +++ b/libgo/go/mime/multipart/multipart_test.go @@ -449,6 +449,66 @@ func testQuotedPrintableEncoding(t *testing.T, cte string) { } } +func TestRawPart(t *testing.T) { + // https://github.com/golang/go/issues/29090 + + body := strings.Replace(`--0016e68ee29c5d515f04cedf6733 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: quoted-printable + +
Hello World.
+--0016e68ee29c5d515f04cedf6733 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: quoted-printable + +
Hello World.
+--0016e68ee29c5d515f04cedf6733--`, "\n", "\r\n", -1) + + r := NewReader(strings.NewReader(body), "0016e68ee29c5d515f04cedf6733") + + // This part is expected to be raw, bypassing the automatic handling + // of quoted-printable. + part, err := r.NextRawPart() + if err != nil { + t.Fatal(err) + } + if _, ok := part.Header["Content-Transfer-Encoding"]; !ok { + t.Errorf("missing Content-Transfer-Encoding") + } + var buf bytes.Buffer + _, err = io.Copy(&buf, part) + if err != nil { + t.Error(err) + } + got := buf.String() + // Data is still quoted-printable. + want := `
Hello World.
` + if got != want { + t.Errorf("wrong part value:\n got: %q\nwant: %q", got, want) + } + + // This part is expected to have automatic decoding of quoted-printable. + part, err = r.NextPart() + if err != nil { + t.Fatal(err) + } + if te, ok := part.Header["Content-Transfer-Encoding"]; ok { + t.Errorf("unexpected Content-Transfer-Encoding of %q", te) + } + + buf.Reset() + _, err = io.Copy(&buf, part) + if err != nil { + t.Error(err) + } + got = buf.String() + // QP data has been decoded. + want = `
Hello World.
` + if got != want { + t.Errorf("wrong part value:\n got: %q\nwant: %q", got, want) + } +} + // Test parsing an image attachment from gmail, which previously failed. func TestNested(t *testing.T) { // nested-mime is the body part of a multipart/mixed email diff --git a/libgo/go/mime/type.go b/libgo/go/mime/type.go index ad763133e69..aa05077e221 100644 --- a/libgo/go/mime/type.go +++ b/libgo/go/mime/type.go @@ -63,8 +63,8 @@ var builtinTypesLower = map[string]string{ ".html": "text/html; charset=utf-8", ".jpeg": "image/jpeg", ".jpg": "image/jpeg", - ".js": "application/javascript", - ".mjs": "application/javascript", + ".js": "text/javascript; charset=utf-8", + ".mjs": "text/javascript; charset=utf-8", ".pdf": "application/pdf", ".png": "image/png", ".svg": "image/svg+xml", diff --git a/libgo/go/mime/type_unix.go b/libgo/go/mime/type_unix.go index 46ae5969cf3..5db1b68ee53 100644 --- a/libgo/go/mime/type_unix.go +++ b/libgo/go/mime/type_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package mime diff --git a/libgo/go/net/dial.go b/libgo/go/net/dial.go index 4d55a95ddf6..d8be1c222d0 100644 --- a/libgo/go/net/dial.go +++ b/libgo/go/net/dial.go @@ -23,6 +23,8 @@ const ( // The zero value for each field is equivalent to dialing // without that option. Dialing with the zero value of Dialer // is therefore equivalent to just calling the Dial function. +// +// It is safe to call Dialer's methods concurrently. type Dialer struct { // Timeout is the maximum amount of time a dial will wait for // a connect to complete. If Deadline is also set, it may fail @@ -527,20 +529,21 @@ func (sd *sysDialer) dialSerial(ctx context.Context, ras addrList) (Conn, error) default: } - deadline, _ := ctx.Deadline() - partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i) - if err != nil { - // Ran out of time. - if firstErr == nil { - firstErr = &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: err} - } - break - } dialCtx := ctx - if partialDeadline.Before(deadline) { - var cancel context.CancelFunc - dialCtx, cancel = context.WithDeadline(ctx, partialDeadline) - defer cancel() + if deadline, hasDeadline := ctx.Deadline(); hasDeadline { + partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i) + if err != nil { + // Ran out of time. + if firstErr == nil { + firstErr = &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: err} + } + break + } + if partialDeadline.Before(deadline) { + var cancel context.CancelFunc + dialCtx, cancel = context.WithDeadline(ctx, partialDeadline) + defer cancel() + } } c, err := sd.dialSingle(dialCtx, ra) diff --git a/libgo/go/net/dial_test.go b/libgo/go/net/dial_test.go index 1bf96fd3ce3..ae40079f853 100644 --- a/libgo/go/net/dial_test.go +++ b/libgo/go/net/dial_test.go @@ -14,6 +14,7 @@ import ( "io" "os" "runtime" + "strings" "sync" "testing" "time" @@ -154,7 +155,7 @@ func slowDialTCP(ctx context.Context, network string, laddr, raddr *TCPAddr) (*T return c, err } -func dialClosedPort() (actual, expected time.Duration) { +func dialClosedPort(t *testing.T) (actual, expected time.Duration) { // Estimate the expected time for this platform. // On Windows, dialing a closed port takes roughly 1 second, // but other platforms should be instantaneous. @@ -168,6 +169,7 @@ func dialClosedPort() (actual, expected time.Duration) { l, err := Listen("tcp", "127.0.0.1:0") if err != nil { + t.Logf("dialClosedPort: Listen failed: %v", err) return 999 * time.Hour, expected } addr := l.Addr().String() @@ -183,6 +185,7 @@ func dialClosedPort() (actual, expected time.Duration) { } elapsed := time.Now().Sub(startTime) if i == 2 { + t.Logf("dialClosedPort: measured delay %v", elapsed) return elapsed, expected } } @@ -195,7 +198,7 @@ func TestDialParallel(t *testing.T) { t.Skip("both IPv4 and IPv6 are required") } - closedPortDelay, expectClosedPortDelay := dialClosedPort() + closedPortDelay, expectClosedPortDelay := dialClosedPort(t) if closedPortDelay > expectClosedPortDelay { t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay) } @@ -316,8 +319,14 @@ func TestDialParallel(t *testing.T) { t.Errorf("#%d: got nil; want non-nil", i) } - expectElapsedMin := tt.expectElapsed - 95*time.Millisecond - expectElapsedMax := tt.expectElapsed + 95*time.Millisecond + // We used to always use 95 milliseconds as the slop, + // but that was flaky on Windows. See issue 35616. + slop := 95 * time.Millisecond + if fifth := tt.expectElapsed / 5; fifth > slop { + slop = fifth + } + expectElapsedMin := tt.expectElapsed - slop + expectElapsedMax := tt.expectElapsed + slop if elapsed < expectElapsedMin { t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectElapsedMin) } else if elapsed > expectElapsedMax { @@ -639,9 +648,11 @@ func TestDialerLocalAddr(t *testing.T) { } c, err := d.Dial(tt.network, addr) if err == nil && tt.error != nil || err != nil && tt.error == nil { - // On Darwin this occasionally times out. - // We don't know why. Issue #22019. - if runtime.GOOS == "darwin" && tt.error == nil && os.IsTimeout(err) { + // A suspected kernel bug in macOS 10.12 occasionally results in + // timeout errors when dialing address ::1. The errors have not + // been observed on newer versions of the OS, so we don't plan to work + // around them. See https://golang.org/issue/22019. + if tt.raddr == "::1" && os.Getenv("GO_BUILDER_NAME") == "darwin-amd64-10_12" && os.IsTimeout(err) { t.Logf("ignoring timeout error on Darwin; see https://golang.org/issue/22019") } else { t.Errorf("%s %v->%s: got %v; want %v", tt.network, tt.laddr, tt.raddr, err, tt.error) @@ -664,7 +675,7 @@ func TestDialerDualStack(t *testing.T) { t.Skip("both IPv4 and IPv6 are required") } - closedPortDelay, expectClosedPortDelay := dialClosedPort() + closedPortDelay, expectClosedPortDelay := dialClosedPort(t) if closedPortDelay > expectClosedPortDelay { t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay) } @@ -757,17 +768,8 @@ func TestDialerKeepAlive(t *testing.T) { } func TestDialCancel(t *testing.T) { - switch testenv.Builder() { - case "linux-arm64-buildlet": - t.Skip("skipping on linux-arm64-buildlet; incompatible network config? issue 15191") - } mustHaveExternalNetwork(t) - if runtime.GOOS == "nacl" { - // nacl doesn't have external network access. - t.Skipf("skipping on %s", runtime.GOOS) - } - blackholeIPPort := JoinHostPort(slowDst4, "1234") if !supportsIPv4() { blackholeIPPort = JoinHostPort(slowDst6, "1234") @@ -810,6 +812,11 @@ func TestDialCancel(t *testing.T) { t.Error(perr) } if ticks < cancelTick { + // Using strings.Contains is ugly but + // may work on plan9 and windows. + if strings.Contains(err.Error(), "connection refused") { + t.Skipf("connection to %v failed fast with %v", blackholeIPPort, err) + } t.Fatalf("dial error after %d ticks (%d before cancel sent): %v", ticks, cancelTick-ticks, err) } @@ -923,7 +930,7 @@ func TestDialListenerAddr(t *testing.T) { func TestDialerControl(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } @@ -981,3 +988,32 @@ func mustHaveExternalNetwork(t *testing.T) { testenv.MustHaveExternalNetwork(t) } } + +type contextWithNonZeroDeadline struct { + context.Context +} + +func (contextWithNonZeroDeadline) Deadline() (time.Time, bool) { + // Return non-zero time.Time value with false indicating that no deadline is set. + return time.Unix(0, 0), false +} + +func TestDialWithNonZeroDeadline(t *testing.T) { + ln, err := newLocalListener("tcp") + if err != nil { + t.Fatal(err) + } + defer ln.Close() + _, port, err := SplitHostPort(ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + + ctx := contextWithNonZeroDeadline{Context: context.Background()} + var dialer Dialer + c, err := dialer.DialContext(ctx, "tcp", JoinHostPort("", port)) + if err != nil { + t.Fatal(err) + } + c.Close() +} diff --git a/libgo/go/net/dnsclient_unix.go b/libgo/go/net/dnsclient_unix.go index b3284b8cd76..da6baf34b57 100644 --- a/libgo/go/net/dnsclient_unix.go +++ b/libgo/go/net/dnsclient_unix.go @@ -765,6 +765,14 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string) ([]string, erro } } if h.Type != dnsmessage.TypePTR { + err := p.SkipAnswer() + if err != nil { + return nil, &DNSError{ + Err: "cannot marshal DNS message", + Name: addr, + Server: server, + } + } continue } ptr, err := p.PTRResource() diff --git a/libgo/go/net/dnsclient_unix_test.go b/libgo/go/net/dnsclient_unix_test.go index b51d60861f8..6d72817ec60 100644 --- a/libgo/go/net/dnsclient_unix_test.go +++ b/libgo/go/net/dnsclient_unix_test.go @@ -1753,3 +1753,50 @@ func TestDNSUseTCP(t *testing.T) { t.Fatal("exchange failed:", err) } } + +// Issue 34660: PTR response with non-PTR answers should ignore non-PTR +func TestPTRandNonPTR(t *testing.T) { + fake := fakeDNSServer{ + rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + r := dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.Header.ID, + Response: true, + RCode: dnsmessage.RCodeSuccess, + }, + Questions: q.Questions, + Answers: []dnsmessage.Resource{ + { + Header: dnsmessage.ResourceHeader{ + Name: q.Questions[0].Name, + Type: dnsmessage.TypePTR, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.PTRResource{ + PTR: dnsmessage.MustNewName("golang.org."), + }, + }, + { + Header: dnsmessage.ResourceHeader{ + Name: q.Questions[0].Name, + Type: dnsmessage.TypeTXT, + Class: dnsmessage.ClassINET, + }, + Body: &dnsmessage.TXTResource{ + TXT: []string{"PTR 8 6 60 ..."}, // fake RRSIG + }, + }, + }, + } + return r, nil + }, + } + r := Resolver{PreferGo: true, Dial: fake.DialContext} + names, err := r.lookupAddr(context.Background(), "192.0.2.123") + if err != nil { + t.Fatalf("LookupAddr: %v", err) + } + if want := []string{"golang.org."}; !reflect.DeepEqual(names, want) { + t.Errorf("names = %q; want %q", names, want) + } +} diff --git a/libgo/go/net/error_nacl.go b/libgo/go/net/error_nacl.go deleted file mode 100644 index caad133b774..00000000000 --- a/libgo/go/net/error_nacl.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package net - -func isConnError(err error) bool { - return false -} diff --git a/libgo/go/net/error_posix.go b/libgo/go/net/error_posix.go index 0ea26e9708c..c13d5bcd313 100644 --- a/libgo/go/net/error_posix.go +++ b/libgo/go/net/error_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package net diff --git a/libgo/go/net/error_test.go b/libgo/go/net/error_test.go index c4fee5aa5e5..89dcc2e6e6e 100644 --- a/libgo/go/net/error_test.go +++ b/libgo/go/net/error_test.go @@ -185,7 +185,7 @@ func TestDialError(t *testing.T) { func TestProtocolDialError(t *testing.T) { switch runtime.GOOS { - case "nacl", "solaris", "illumos": + case "solaris", "illumos": t.Skipf("not supported on %s", runtime.GOOS) } @@ -214,7 +214,7 @@ func TestProtocolDialError(t *testing.T) { func TestDialAddrError(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv4() || !supportsIPv6() { @@ -376,7 +376,7 @@ func TestListenPacketError(t *testing.T) { func TestProtocolListenError(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/libgo/go/net/example_test.go b/libgo/go/net/example_test.go new file mode 100644 index 00000000000..ef8c38f9f4a --- /dev/null +++ b/libgo/go/net/example_test.go @@ -0,0 +1,160 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net_test + +import ( + "context" + "fmt" + "io" + "log" + "net" + "time" +) + +func ExampleListener() { + // Listen on TCP port 2000 on all available unicast and + // anycast IP addresses of the local system. + l, err := net.Listen("tcp", ":2000") + if err != nil { + log.Fatal(err) + } + defer l.Close() + for { + // Wait for a connection. + conn, err := l.Accept() + if err != nil { + log.Fatal(err) + } + // Handle the connection in a new goroutine. + // The loop then returns to accepting, so that + // multiple connections may be served concurrently. + go func(c net.Conn) { + // Echo all incoming data. + io.Copy(c, c) + // Shut down the connection. + c.Close() + }(conn) + } +} + +func ExampleDialer() { + var d net.Dialer + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + conn, err := d.DialContext(ctx, "tcp", "localhost:12345") + if err != nil { + log.Fatalf("Failed to dial: %v", err) + } + defer conn.Close() + + if _, err := conn.Write([]byte("Hello, World!")); err != nil { + log.Fatal(err) + } +} + +func ExampleIPv4() { + fmt.Println(net.IPv4(8, 8, 8, 8)) + + // Output: + // 8.8.8.8 +} + +func ExampleParseCIDR() { + ipv4Addr, ipv4Net, err := net.ParseCIDR("192.0.2.1/24") + if err != nil { + log.Fatal(err) + } + fmt.Println(ipv4Addr) + fmt.Println(ipv4Net) + + ipv6Addr, ipv6Net, err := net.ParseCIDR("2001:db8:a0b:12f0::1/32") + if err != nil { + log.Fatal(err) + } + fmt.Println(ipv6Addr) + fmt.Println(ipv6Net) + + // Output: + // 192.0.2.1 + // 192.0.2.0/24 + // 2001:db8:a0b:12f0::1 + // 2001:db8::/32 +} + +func ExampleParseIP() { + fmt.Println(net.ParseIP("192.0.2.1")) + fmt.Println(net.ParseIP("2001:db8::68")) + fmt.Println(net.ParseIP("192.0.2")) + + // Output: + // 192.0.2.1 + // 2001:db8::68 + // +} + +func ExampleIP_DefaultMask() { + ip := net.ParseIP("192.0.2.1") + fmt.Println(ip.DefaultMask()) + + // Output: + // ffffff00 +} + +func ExampleIP_Mask() { + ipv4Addr := net.ParseIP("192.0.2.1") + // This mask corresponds to a /24 subnet for IPv4. + ipv4Mask := net.CIDRMask(24, 32) + fmt.Println(ipv4Addr.Mask(ipv4Mask)) + + ipv6Addr := net.ParseIP("2001:db8:a0b:12f0::1") + // This mask corresponds to a /32 subnet for IPv6. + ipv6Mask := net.CIDRMask(32, 128) + fmt.Println(ipv6Addr.Mask(ipv6Mask)) + + // Output: + // 192.0.2.0 + // 2001:db8:: +} + +func ExampleCIDRMask() { + // This mask corresponds to a /31 subnet for IPv4. + fmt.Println(net.CIDRMask(31, 32)) + + // This mask corresponds to a /64 subnet for IPv6. + fmt.Println(net.CIDRMask(64, 128)) + + // Output: + // fffffffe + // ffffffffffffffff0000000000000000 +} + +func ExampleIPv4Mask() { + fmt.Println(net.IPv4Mask(255, 255, 255, 0)) + + // Output: + // ffffff00 +} + +func ExampleUDPConn_WriteTo() { + // Unlike Dial, ListenPacket creates a connection without any + // association with peers. + conn, err := net.ListenPacket("udp", ":0") + if err != nil { + log.Fatal(err) + } + defer conn.Close() + + dst, err := net.ResolveUDPAddr("udp", "192.0.2.1:2000") + if err != nil { + log.Fatal(err) + } + + // The connection can write data to the desired address. + _, err = conn.WriteTo([]byte("data"), dst) + if err != nil { + log.Fatal(err) + } +} diff --git a/libgo/go/net/fd_unix.go b/libgo/go/net/fd_unix.go index 286d3f1c92a..117f5a994fe 100644 --- a/libgo/go/net/fd_unix.go +++ b/libgo/go/net/fd_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris package net @@ -96,7 +96,7 @@ func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (rsa sysc if err := fd.pfd.Init(fd.net, true); err != nil { return nil, err } - if deadline, _ := ctx.Deadline(); !deadline.IsZero() { + if deadline, hasDeadline := ctx.Deadline(); hasDeadline { fd.pfd.SetWriteDeadline(deadline) defer fd.pfd.SetWriteDeadline(noDeadline) } @@ -248,7 +248,7 @@ func (fd *netFD) accept() (netfd *netFD, err error) { return nil, err } if err = netfd.init(); err != nil { - fd.Close() + netfd.Close() return nil, err } lsa, _ := syscall.Getsockname(netfd.pfd.Sysfd) diff --git a/libgo/go/net/file.go b/libgo/go/net/file.go index 81a44e1f3f3..c13332c188a 100644 --- a/libgo/go/net/file.go +++ b/libgo/go/net/file.go @@ -6,7 +6,7 @@ package net import "os" -// BUG(mikio): On JS, NaCl and Windows, the FileConn, FileListener and +// BUG(mikio): On JS and Windows, the FileConn, FileListener and // FilePacketConn functions are not implemented. type fileAddr string diff --git a/libgo/go/net/file_stub.go b/libgo/go/net/file_stub.go index 22566083658..bfb8100f53c 100644 --- a/libgo/go/net/file_stub.go +++ b/libgo/go/net/file_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build nacl js,wasm +// +build js,wasm package net diff --git a/libgo/go/net/file_test.go b/libgo/go/net/file_test.go index cd717747af6..8c09c0da1bd 100644 --- a/libgo/go/net/file_test.go +++ b/libgo/go/net/file_test.go @@ -31,7 +31,7 @@ var fileConnTests = []struct { func TestFileConn(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } @@ -138,7 +138,7 @@ var fileListenerTests = []struct { func TestFileListener(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } @@ -230,7 +230,7 @@ var filePacketConnTests = []struct { func TestFilePacketConn(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } @@ -297,7 +297,7 @@ func TestFilePacketConn(t *testing.T) { // Issue 24483. func TestFileCloseRace(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "plan9", "windows": t.Skipf("not supported on %s", runtime.GOOS) } if !testableNetwork("tcp") { diff --git a/libgo/go/net/hook_unix.go b/libgo/go/net/hook_unix.go index aaa692200d5..780b23caba3 100644 --- a/libgo/go/net/hook_unix.go +++ b/libgo/go/net/hook_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package net diff --git a/libgo/go/net/http/alpn_test.go b/libgo/go/net/http/alpn_test.go new file mode 100644 index 00000000000..618bdbe54a6 --- /dev/null +++ b/libgo/go/net/http/alpn_test.go @@ -0,0 +1,133 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package http_test + +import ( + "bufio" + "bytes" + "crypto/tls" + "crypto/x509" + "fmt" + "io" + "io/ioutil" + . "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestNextProtoUpgrade(t *testing.T) { + setParallel(t) + defer afterTest(t) + ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { + fmt.Fprintf(w, "path=%s,proto=", r.URL.Path) + if r.TLS != nil { + w.Write([]byte(r.TLS.NegotiatedProtocol)) + } + if r.RemoteAddr == "" { + t.Error("request with no RemoteAddr") + } + if r.Body == nil { + t.Errorf("request with nil Body") + } + })) + ts.TLS = &tls.Config{ + NextProtos: []string{"unhandled-proto", "tls-0.9"}, + } + ts.Config.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){ + "tls-0.9": handleTLSProtocol09, + } + ts.StartTLS() + defer ts.Close() + + // Normal request, without NPN. + { + c := ts.Client() + res, err := c.Get(ts.URL) + if err != nil { + t.Fatal(err) + } + body, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + if want := "path=/,proto="; string(body) != want { + t.Errorf("plain request = %q; want %q", body, want) + } + } + + // Request to an advertised but unhandled NPN protocol. + // Server will hang up. + { + certPool := x509.NewCertPool() + certPool.AddCert(ts.Certificate()) + tr := &Transport{ + TLSClientConfig: &tls.Config{ + RootCAs: certPool, + NextProtos: []string{"unhandled-proto"}, + }, + } + defer tr.CloseIdleConnections() + c := &Client{ + Transport: tr, + } + res, err := c.Get(ts.URL) + if err == nil { + defer res.Body.Close() + var buf bytes.Buffer + res.Write(&buf) + t.Errorf("expected error on unhandled-proto request; got: %s", buf.Bytes()) + } + } + + // Request using the "tls-0.9" protocol, which we register here. + // It is HTTP/0.9 over TLS. + { + c := ts.Client() + tlsConfig := c.Transport.(*Transport).TLSClientConfig + tlsConfig.NextProtos = []string{"tls-0.9"} + conn, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig) + if err != nil { + t.Fatal(err) + } + conn.Write([]byte("GET /foo\n")) + body, err := ioutil.ReadAll(conn) + if err != nil { + t.Fatal(err) + } + if want := "path=/foo,proto=tls-0.9"; string(body) != want { + t.Errorf("plain request = %q; want %q", body, want) + } + } +} + +// handleTLSProtocol09 implements the HTTP/0.9 protocol over TLS, for the +// TestNextProtoUpgrade test. +func handleTLSProtocol09(srv *Server, conn *tls.Conn, h Handler) { + br := bufio.NewReader(conn) + line, err := br.ReadString('\n') + if err != nil { + return + } + line = strings.TrimSpace(line) + path := strings.TrimPrefix(line, "GET ") + if path == line { + return + } + req, _ := NewRequest("GET", path, nil) + req.Proto = "HTTP/0.9" + req.ProtoMajor = 0 + req.ProtoMinor = 9 + rw := &http09Writer{conn, make(Header)} + h.ServeHTTP(rw, req) +} + +type http09Writer struct { + io.Writer + h Header +} + +func (w http09Writer) Header() Header { return w.h } +func (w http09Writer) WriteHeader(int) {} // no headers diff --git a/libgo/go/net/http/cgi/host_test.go b/libgo/go/net/http/cgi/host_test.go index 25882deed05..9f1716b2ecb 100644 --- a/libgo/go/net/http/cgi/host_test.go +++ b/libgo/go/net/http/cgi/host_test.go @@ -456,6 +456,23 @@ func TestDirUnix(t *testing.T) { runCgiTest(t, h, "GET /test.cgi HTTP/1.0\nHost: example.com\n\n", expectedMap) } +func findPerl(t *testing.T) string { + t.Helper() + perl, err := exec.LookPath("perl") + if err != nil { + t.Skip("Skipping test: perl not found.") + } + perl, _ = filepath.Abs(perl) + + cmd := exec.Command(perl, "-e", "print 123") + cmd.Env = []string{"PATH=/garbage"} + out, err := cmd.Output() + if err != nil || string(out) != "123" { + t.Skipf("Skipping test: %s is not functional", perl) + } + return perl +} + func TestDirWindows(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("Skipping windows specific test.") @@ -463,13 +480,7 @@ func TestDirWindows(t *testing.T) { cgifile, _ := filepath.Abs("testdata/test.cgi") - var perl string - var err error - perl, err = exec.LookPath("perl") - if err != nil { - t.Skip("Skipping test: perl not found.") - } - perl, _ = filepath.Abs(perl) + perl := findPerl(t) cwd, _ := os.Getwd() h := &Handler{ @@ -506,13 +517,7 @@ func TestEnvOverride(t *testing.T) { check(t) cgifile, _ := filepath.Abs("testdata/test.cgi") - var perl string - var err error - perl, err = exec.LookPath("perl") - if err != nil { - t.Skipf("Skipping test: perl not found.") - } - perl, _ = filepath.Abs(perl) + perl := findPerl(t) cwd, _ := os.Getwd() h := &Handler{ diff --git a/libgo/go/net/http/client.go b/libgo/go/net/http/client.go index 65a9d51cc6b..6a8c59a6702 100644 --- a/libgo/go/net/http/client.go +++ b/libgo/go/net/http/client.go @@ -10,6 +10,7 @@ package http import ( + "context" "crypto/tls" "encoding/base64" "errors" @@ -18,6 +19,7 @@ import ( "io/ioutil" "log" "net/url" + "reflect" "sort" "strings" "sync" @@ -238,7 +240,7 @@ func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, d username := u.Username() password, _ := u.Password() forkReq() - req.Header = ireq.Header.Clone() + req.Header = cloneOrMakeHeader(ireq.Header) req.Header.Set("Authorization", "Basic "+basicAuth(username, password)) } @@ -273,46 +275,95 @@ func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, d return resp, nil, nil } -// setRequestCancel sets the Cancel field of req, if deadline is -// non-zero. The RoundTripper's type is used to determine whether the legacy -// CancelRequest behavior should be used. +// timeBeforeContextDeadline reports whether the non-zero Time t is +// before ctx's deadline, if any. If ctx does not have a deadline, it +// always reports true (the deadline is considered infinite). +func timeBeforeContextDeadline(t time.Time, ctx context.Context) bool { + d, ok := ctx.Deadline() + if !ok { + return true + } + return t.Before(d) +} + +// knownRoundTripperImpl reports whether rt is a RoundTripper that's +// maintained by the Go team and known to implement the latest +// optional semantics (notably contexts). +func knownRoundTripperImpl(rt RoundTripper) bool { + switch rt.(type) { + case *Transport, *http2Transport: + return true + } + // There's a very minor chance of a false positive with this. + // Insted of detecting our golang.org/x/net/http2.Transport, + // it might detect a Transport type in a different http2 + // package. But I know of none, and the only problem would be + // some temporarily leaked goroutines if the transport didn't + // support contexts. So this is a good enough heuristic: + if reflect.TypeOf(rt).String() == "*http2.Transport" { + return true + } + return false +} + +// setRequestCancel sets req.Cancel and adds a deadline context to req +// if deadline is non-zero. The RoundTripper's type is used to +// determine whether the legacy CancelRequest behavior should be used. // // As background, there are three ways to cancel a request: // First was Transport.CancelRequest. (deprecated) -// Second was Request.Cancel (this mechanism). +// Second was Request.Cancel. // Third was Request.Context. +// This function populates the second and third, and uses the first if it really needs to. func setRequestCancel(req *Request, rt RoundTripper, deadline time.Time) (stopTimer func(), didTimeout func() bool) { if deadline.IsZero() { return nop, alwaysFalse } + knownTransport := knownRoundTripperImpl(rt) + oldCtx := req.Context() + if req.Cancel == nil && knownTransport { + // If they already had a Request.Context that's + // expiring sooner, do nothing: + if !timeBeforeContextDeadline(deadline, oldCtx) { + return nop, alwaysFalse + } + + var cancelCtx func() + req.ctx, cancelCtx = context.WithDeadline(oldCtx, deadline) + return cancelCtx, func() bool { return time.Now().After(deadline) } + } initialReqCancel := req.Cancel // the user's original Request.Cancel, if any + var cancelCtx func() + if oldCtx := req.Context(); timeBeforeContextDeadline(deadline, oldCtx) { + req.ctx, cancelCtx = context.WithDeadline(oldCtx, deadline) + } + cancel := make(chan struct{}) req.Cancel = cancel doCancel := func() { - // The newer way (the second way in the func comment): + // The second way in the func comment above: close(cancel) - - // The legacy compatibility way, used only - // for RoundTripper implementations written - // before Go 1.5 or Go 1.6. - type canceler interface { - CancelRequest(*Request) - } - switch v := rt.(type) { - case *Transport, *http2Transport: - // Do nothing. The net/http package's transports - // support the new Request.Cancel channel - case canceler: + // The first way, used only for RoundTripper + // implementations written before Go 1.5 or Go 1.6. + type canceler interface{ CancelRequest(*Request) } + if v, ok := rt.(canceler); ok { v.CancelRequest(req) } } stopTimerCh := make(chan struct{}) var once sync.Once - stopTimer = func() { once.Do(func() { close(stopTimerCh) }) } + stopTimer = func() { + once.Do(func() { + close(stopTimerCh) + if cancelCtx != nil { + cancelCtx() + } + }) + } timer := time.NewTimer(time.Until(deadline)) var timedOut atomicBool @@ -383,8 +434,8 @@ func Get(url string) (resp *Response, err error) { // An error is returned if the Client's CheckRedirect function fails // or if there was an HTTP protocol error. A non-2xx response doesn't // cause an error. Any returned error will be of type *url.Error. The -// url.Error value's Timeout method will report true if request timed -// out or was canceled. +// url.Error value's Timeout method will report true if the request +// timed out. // // When err is nil, resp always contains a non-nil resp.Body. // Caller should close resp.Body when done reading from it. @@ -668,7 +719,7 @@ func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) { // The headers to copy are from the very initial request. // We use a closured callback to keep a reference to these original headers. var ( - ireqhdr = ireq.Header.Clone() + ireqhdr = cloneOrMakeHeader(ireq.Header) icookies map[string][]*Cookie ) if c.Jar != nil && ireq.Header.Get("Cookie") != "" { @@ -870,8 +921,7 @@ func (b *cancelTimerBody) Read(p []byte) (n int, err error) { } if b.reqDidTimeout() { err = &httpError{ - // TODO: early in cycle: s/Client.Timeout exceeded/timeout or context cancellation/ - err: err.Error() + " (Client.Timeout exceeded while reading body)", + err: err.Error() + " (Client.Timeout or context cancellation while reading body)", timeout: true, } } diff --git a/libgo/go/net/http/client_test.go b/libgo/go/net/http/client_test.go index de490bc6074..2b4f53f802b 100644 --- a/libgo/go/net/http/client_test.go +++ b/libgo/go/net/http/client_test.go @@ -221,27 +221,27 @@ func TestClientRedirects(t *testing.T) { c := ts.Client() _, err := c.Get(ts.URL) - if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { + if e, g := `Get "/?n=10": stopped after 10 redirects`, fmt.Sprintf("%v", err); e != g { t.Errorf("with default client Get, expected error %q, got %q", e, g) } // HEAD request should also have the ability to follow redirects. _, err = c.Head(ts.URL) - if e, g := "Head /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { + if e, g := `Head "/?n=10": stopped after 10 redirects`, fmt.Sprintf("%v", err); e != g { t.Errorf("with default client Head, expected error %q, got %q", e, g) } // Do should also follow redirects. greq, _ := NewRequest("GET", ts.URL, nil) _, err = c.Do(greq) - if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { + if e, g := `Get "/?n=10": stopped after 10 redirects`, fmt.Sprintf("%v", err); e != g { t.Errorf("with default client Do, expected error %q, got %q", e, g) } // Requests with an empty Method should also redirect (Issue 12705) greq.Method = "" _, err = c.Do(greq) - if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g { + if e, g := `Get "/?n=10": stopped after 10 redirects`, fmt.Sprintf("%v", err); e != g { t.Errorf("with default client Do and empty Method, expected error %q, got %q", e, g) } @@ -1172,22 +1172,22 @@ func TestStripPasswordFromError(t *testing.T) { { desc: "Strip password from error message", in: "http://user:password@dummy.faketld/", - out: "Get http://user:***@dummy.faketld/: dummy impl", + out: `Get "http://user:***@dummy.faketld/": dummy impl`, }, { desc: "Don't Strip password from domain name", in: "http://user:password@password.faketld/", - out: "Get http://user:***@password.faketld/: dummy impl", + out: `Get "http://user:***@password.faketld/": dummy impl`, }, { desc: "Don't Strip password from path", in: "http://user:password@dummy.faketld/password", - out: "Get http://user:***@dummy.faketld/password: dummy impl", + out: `Get "http://user:***@dummy.faketld/password": dummy impl`, }, { desc: "Strip escaped password", in: "http://user:pa%2Fssword@dummy.faketld/", - out: "Get http://user:***@dummy.faketld/: dummy impl", + out: `Get "http://user:***@dummy.faketld/": dummy impl`, }, } for _, tC := range testCases { @@ -1274,7 +1274,7 @@ func testClientTimeout(t *testing.T, h2 bool) { } else if !ne.Timeout() { t.Errorf("net.Error.Timeout = false; want true") } - if got := ne.Error(); !strings.Contains(got, "Client.Timeout exceeded") { + if got := ne.Error(); !strings.Contains(got, "(Client.Timeout") { t.Errorf("error string = %q; missing timeout substring", got) } case <-time.After(failTime): @@ -1917,3 +1917,77 @@ func TestClientCloseIdleConnections(t *testing.T) { t.Error("not closed") } } + +func TestClientPropagatesTimeoutToContext(t *testing.T) { + errDial := errors.New("not actually dialing") + c := &Client{ + Timeout: 5 * time.Second, + Transport: &Transport{ + DialContext: func(ctx context.Context, netw, addr string) (net.Conn, error) { + deadline, ok := ctx.Deadline() + if !ok { + t.Error("no deadline") + } else { + t.Logf("deadline in %v", deadline.Sub(time.Now()).Round(time.Second/10)) + } + return nil, errDial + }, + }, + } + c.Get("https://example.tld/") +} + +func TestClientDoCanceledVsTimeout_h1(t *testing.T) { + testClientDoCanceledVsTimeout(t, h1Mode) +} + +func TestClientDoCanceledVsTimeout_h2(t *testing.T) { + testClientDoCanceledVsTimeout(t, h2Mode) +} + +// Issue 33545: lock-in the behavior promised by Client.Do's +// docs about request cancelation vs timing out. +func testClientDoCanceledVsTimeout(t *testing.T, h2 bool) { + defer afterTest(t) + cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { + w.Write([]byte("Hello, World!")) + })) + defer cst.close() + + cases := []string{"timeout", "canceled"} + + for _, name := range cases { + t.Run(name, func(t *testing.T) { + var ctx context.Context + var cancel func() + if name == "timeout" { + ctx, cancel = context.WithTimeout(context.Background(), -time.Nanosecond) + } else { + ctx, cancel = context.WithCancel(context.Background()) + cancel() + } + defer cancel() + + req, _ := NewRequestWithContext(ctx, "GET", cst.ts.URL, nil) + _, err := cst.c.Do(req) + if err == nil { + t.Fatal("Unexpectedly got a nil error") + } + + ue := err.(*url.Error) + + var wantIsTimeout bool + var wantErr error = context.Canceled + if name == "timeout" { + wantErr = context.DeadlineExceeded + wantIsTimeout = true + } + if g, w := ue.Timeout(), wantIsTimeout; g != w { + t.Fatalf("url.Timeout() = %t, want %t", g, w) + } + if g, w := ue.Err, wantErr; g != w { + t.Errorf("url.Error.Err = %v; want %v", g, w) + } + }) + } +} diff --git a/libgo/go/net/http/clientserver_test.go b/libgo/go/net/http/clientserver_test.go index ee48fb05ccd..70bcd0ec387 100644 --- a/libgo/go/net/http/clientserver_test.go +++ b/libgo/go/net/http/clientserver_test.go @@ -76,7 +76,16 @@ var optQuietLog = func(ts *httptest.Server) { ts.Config.ErrorLog = quietLog } +func optWithServerLog(lg *log.Logger) func(*httptest.Server) { + return func(ts *httptest.Server) { + ts.Config.ErrorLog = lg + } +} + func newClientServerTest(t *testing.T, h2 bool, h Handler, opts ...interface{}) *clientServerTest { + if h2 { + CondSkipHTTP2(t) + } cst := &clientServerTest{ t: t, h2: h2, diff --git a/libgo/go/net/http/clone.go b/libgo/go/net/http/clone.go index 5f2784d2808..3a3375bff71 100644 --- a/libgo/go/net/http/clone.go +++ b/libgo/go/net/http/clone.go @@ -62,3 +62,13 @@ func cloneMultipartFileHeader(fh *multipart.FileHeader) *multipart.FileHeader { fh2.Header = textproto.MIMEHeader(Header(fh.Header).Clone()) return fh2 } + +// cloneOrMakeHeader invokes Header.Clone but if the +// result is nil, it'll instead make and return a non-nil Header. +func cloneOrMakeHeader(hdr Header) Header { + clone := hdr.Clone() + if clone == nil { + clone = make(Header) + } + return clone +} diff --git a/libgo/go/net/http/cookie.go b/libgo/go/net/http/cookie.go index 91ff544e79f..5c572d6dc5a 100644 --- a/libgo/go/net/http/cookie.go +++ b/libgo/go/net/http/cookie.go @@ -353,6 +353,7 @@ func sanitizeCookieName(n string) string { return cookieNameSanitizer.Replace(n) } +// sanitizeCookieValue produces a suitable cookie-value from v. // https://tools.ietf.org/html/rfc6265#section-4.1.1 // cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) // cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E @@ -360,8 +361,8 @@ func sanitizeCookieName(n string) string { // ; whitespace DQUOTE, comma, semicolon, // ; and backslash // We loosen this as spaces and commas are common in cookie values -// but we produce a quoted cookie-value in when value starts or ends -// with a comma or space. +// but we produce a quoted cookie-value if and only if v contains +// commas or spaces. // See https://golang.org/issue/7243 for the discussion. func sanitizeCookieValue(v string) string { v = sanitizeOrWarn("Cookie.Value", validCookieValueByte, v) diff --git a/libgo/go/net/http/export_test.go b/libgo/go/net/http/export_test.go index d265cd3f726..657ff9dba49 100644 --- a/libgo/go/net/http/export_test.go +++ b/libgo/go/net/http/export_test.go @@ -60,6 +60,12 @@ func init() { } } +func CondSkipHTTP2(t *testing.T) { + if omitBundledHTTP2 { + t.Skip("skipping HTTP/2 test when nethttpomithttp2 build tag in use") + } +} + var ( SetEnterRoundTripHook = hookSetter(&testHookEnterRoundTrip) SetRoundTripRetried = hookSetter(&testHookRoundTripRetried) @@ -208,6 +214,30 @@ func (t *Transport) PutIdleTestConn(scheme, addr string) bool { }) == nil } +// PutIdleTestConnH2 reports whether it was able to insert a fresh +// HTTP/2 persistConn for scheme, addr into the idle connection pool. +func (t *Transport) PutIdleTestConnH2(scheme, addr string, alt RoundTripper) bool { + key := connectMethodKey{"", scheme, addr, false} + + if t.MaxConnsPerHost > 0 { + // Transport is tracking conns-per-host. + // Increment connection count to account + // for new persistConn created below. + t.connsPerHostMu.Lock() + if t.connsPerHost == nil { + t.connsPerHost = make(map[connectMethodKey]int) + } + t.connsPerHost[key]++ + t.connsPerHostMu.Unlock() + } + + return t.tryPutIdleConn(&persistConn{ + t: t, + alt: alt, + cacheKey: key, + }) == nil +} + // All test hooks must be non-nil so they can be called directly, // but the tests use nil to mean hook disabled. func unnilTestHook(f *func()) { diff --git a/libgo/go/net/http/fs.go b/libgo/go/net/http/fs.go index 41d46dced2a..d2144857e84 100644 --- a/libgo/go/net/http/fs.go +++ b/libgo/go/net/http/fs.go @@ -384,15 +384,18 @@ func checkIfUnmodifiedSince(r *Request, modtime time.Time) condResult { if ius == "" || isZeroTime(modtime) { return condNone } - if t, err := ParseTime(ius); err == nil { - // The Date-Modified header truncates sub-second precision, so - // use mtime < t+1s instead of mtime <= t to check for unmodified. - if modtime.Before(t.Add(1 * time.Second)) { - return condTrue - } - return condFalse + t, err := ParseTime(ius) + if err != nil { + return condNone } - return condNone + + // The Last-Modified header truncates sub-second precision so + // the modtime needs to be truncated too. + modtime = modtime.Truncate(time.Second) + if modtime.Before(t) || modtime.Equal(t) { + return condTrue + } + return condFalse } func checkIfNoneMatch(w ResponseWriter, r *Request) condResult { @@ -436,9 +439,10 @@ func checkIfModifiedSince(r *Request, modtime time.Time) condResult { if err != nil { return condNone } - // The Date-Modified header truncates sub-second precision, so - // use mtime < t+1s instead of mtime <= t to check for unmodified. - if modtime.Before(t.Add(1 * time.Second)) { + // The Last-Modified header truncates sub-second precision so + // the modtime needs to be truncated too. + modtime = modtime.Truncate(time.Second) + if modtime.Before(t) || modtime.Equal(t) { return condFalse } return condTrue @@ -582,17 +586,15 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec } } - // redirect if the directory name doesn't end in a slash if d.IsDir() { url := r.URL.Path - if url[len(url)-1] != '/' { + // redirect if the directory name doesn't end in a slash + if url == "" || url[len(url)-1] != '/' { localRedirect(w, r, path.Base(url)+"/") return } - } - // use contents of index.html for directory, if present - if d.IsDir() { + // use contents of index.html for directory, if present index := strings.TrimSuffix(name, "/") + indexPage ff, err := fs.Open(index) if err == nil { @@ -612,7 +614,7 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec writeNotModified(w) return } - w.Header().Set("Last-Modified", d.ModTime().UTC().Format(TimeFormat)) + setLastModified(w, d.ModTime()) dirList(w, r, f) return } diff --git a/libgo/go/net/http/fs_test.go b/libgo/go/net/http/fs_test.go index 82e13a464d7..435e34be3af 100644 --- a/libgo/go/net/http/fs_test.go +++ b/libgo/go/net/http/fs_test.go @@ -207,6 +207,18 @@ func TestServeFile_DotDot(t *testing.T) { } } +// Tests that this doesn't panic. (Issue 30165) +func TestServeFileDirPanicEmptyPath(t *testing.T) { + rec := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/", nil) + req.URL.Path = "" + ServeFile(rec, req, "testdata") + res := rec.Result() + if res.StatusCode != 301 { + t.Errorf("code = %v; want 301", res.Status) + } +} + var fsRedirectTestData = []struct { original, redirect string }{ @@ -1110,21 +1122,13 @@ func TestLinuxSendfile(t *testing.T) { } defer ln.Close() - syscalls := "sendfile,sendfile64" - switch runtime.GOARCH { - case "mips64", "mips64le", "s390x", "alpha": - // strace on the above platforms doesn't support sendfile64 - // and will error out if we specify that with `-e trace='. - syscalls = "sendfile" - } - // Attempt to run strace, and skip on failure - this test requires SYS_PTRACE. - if err := exec.Command("strace", "-f", "-q", "-e", "trace="+syscalls, os.Args[0], "-test.run=^$").Run(); err != nil { + if err := exec.Command("strace", "-f", "-q", os.Args[0], "-test.run=^$").Run(); err != nil { t.Skipf("skipping; failed to run strace: %v", err) } var buf bytes.Buffer - child := exec.Command("strace", "-f", "-q", "-e", "trace="+syscalls, os.Args[0], "-test.run=TestLinuxSendfileChild") + child := exec.Command("strace", "-f", "-q", os.Args[0], "-test.run=TestLinuxSendfileChild") child.ExtraFiles = append(child.ExtraFiles, lnf) child.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...) child.Stdout = &buf @@ -1147,7 +1151,7 @@ func TestLinuxSendfile(t *testing.T) { Post(fmt.Sprintf("http://%s/quit", ln.Addr()), "", nil) child.Wait() - rx := regexp.MustCompile(`sendfile(64)?\(`) + rx := regexp.MustCompile(`\b(n64:)?sendfile(64)?\(`) out := buf.String() if !rx.MatchString(out) { t.Errorf("no sendfile system call found in:\n%s", out) diff --git a/libgo/go/net/http/h2_bundle.go b/libgo/go/net/http/h2_bundle.go index 21921aba5fd..f03dbba729b 100644 --- a/libgo/go/net/http/h2_bundle.go +++ b/libgo/go/net/http/h2_bundle.go @@ -1,5 +1,7 @@ +// +build !nethttpomithttp2 + // Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. -//go:generate bundle -o h2_bundle.go -prefix http2 golang.org/x/net/http2 +// $ bundle -o=h2_bundle.go -prefix=http2 -tags=!nethttpomithttp2 golang.org/x/net/http2 // Package http2 implements the HTTP/2 protocol. // @@ -3465,6 +3467,7 @@ type http2pipe struct { mu sync.Mutex c sync.Cond // c.L lazily initialized to &p.mu b http2pipeBuffer // nil when done reading + unread int // bytes unread when done err error // read error once empty. non-nil means closed. breakErr error // immediate read error (caller doesn't see rest of b) donec chan struct{} // closed on error @@ -3481,7 +3484,7 @@ func (p *http2pipe) Len() int { p.mu.Lock() defer p.mu.Unlock() if p.b == nil { - return 0 + return p.unread } return p.b.Len() } @@ -3528,6 +3531,7 @@ func (p *http2pipe) Write(d []byte) (n int, err error) { return 0, http2errClosedPipeWrite } if p.breakErr != nil { + p.unread += len(d) return len(d), nil // discard when there is no reader } return p.b.Write(d) @@ -3565,6 +3569,9 @@ func (p *http2pipe) closeWithError(dst *error, err error, fn func()) { } p.readFn = fn if dst == &p.breakErr { + if p.b != nil { + p.unread += p.b.Len() + } p.b = nil } *dst = err @@ -3811,7 +3818,7 @@ func http2ConfigureServer(s *Server, conf *http2Server) error { } } if !haveRequired { - return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher.") + return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).") } } @@ -3881,7 +3888,7 @@ type http2ServeConnOpts struct { } func (o *http2ServeConnOpts) context() context.Context { - if o.Context != nil { + if o != nil && o.Context != nil { return o.Context } return context.Background() @@ -5979,7 +5986,11 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { clen = strconv.Itoa(len(p)) } _, hasContentType := rws.snapHeader["Content-Type"] - if !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 { + // If the Content-Encoding is non-blank, we shouldn't + // sniff the body. See Issue golang.org/issue/31753. + ce := rws.snapHeader.Get("Content-Encoding") + hasCE := len(ce) > 0 + if !hasCE && !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 { ctype = DetectContentType(p) } var date string @@ -6088,7 +6099,7 @@ const http2TrailerPrefix = "Trailer:" // trailers. That worked for a while, until we found the first major // user of Trailers in the wild: gRPC (using them only over http2), // and gRPC libraries permit setting trailers mid-stream without -// predeclarnig them. So: change of plans. We still permit the old +// predeclaring them. So: change of plans. We still permit the old // way, but we also permit this hack: if a Header() key begins with // "Trailer:", the suffix of that key is a Trailer. Because ':' is an // invalid token byte anyway, there is no ambiguity. (And it's already @@ -6388,7 +6399,7 @@ func (sc *http2serverConn) startPush(msg *http2startPushRequest) { // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that // is in either the "open" or "half-closed (remote)" state. if msg.parent.state != http2stateOpen && msg.parent.state != http2stateHalfClosedRemote { - // responseWriter.Push checks that the stream is peer-initiaed. + // responseWriter.Push checks that the stream is peer-initiated. msg.done <- http2errStreamClosed return } @@ -6715,6 +6726,7 @@ type http2ClientConn struct { br *bufio.Reader fr *http2Framer lastActive time.Time + lastIdle time.Time // time last idle // Settings from peer: (also guarded by mu) maxFrameSize uint32 maxConcurrentStreams uint32 @@ -7092,7 +7104,7 @@ func (t *http2Transport) expectContinueTimeout() time.Duration { } func (t *http2Transport) NewClientConn(c net.Conn) (*http2ClientConn, error) { - return t.newClientConn(c, false) + return t.newClientConn(c, t.disableKeepAlives()) } func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2ClientConn, error) { @@ -7225,7 +7237,8 @@ func (cc *http2ClientConn) idleStateLocked() (st http2clientConnIdleState) { } st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay && - int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 + int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 && + !cc.tooIdleLocked() st.freshConn = cc.nextStreamID == 1 && st.canTakeNewRequest return } @@ -7235,6 +7248,16 @@ func (cc *http2ClientConn) canTakeNewRequestLocked() bool { return st.canTakeNewRequest } +// tooIdleLocked reports whether this connection has been been sitting idle +// for too much wall time. +func (cc *http2ClientConn) tooIdleLocked() bool { + // The Round(0) strips the monontonic clock reading so the + // times are compared based on their wall time. We don't want + // to reuse a connection that's been sitting idle during + // VM/laptop suspend if monotonic time was also frozen. + return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout +} + // onIdleTimeout is called from a time.AfterFunc goroutine. It will // only be called when we're idle, but because we're coming from a new // goroutine, there could be a new request coming in at the same time, @@ -7654,6 +7677,7 @@ func (cc *http2ClientConn) awaitOpenSlotForRequest(req *Request) error { } return http2errClientConnUnusable } + cc.lastIdle = time.Time{} if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) { if waitingForConn != nil { close(waitingForConn) @@ -7720,6 +7744,8 @@ var ( // abort request body write, but send stream reset of cancel. http2errStopReqBodyWriteAndCancel = errors.New("http2: canceling request") + + http2errReqBodyTooLong = errors.New("http2: request body larger than specified content length") ) func (cs *http2clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) { @@ -7742,10 +7768,32 @@ func (cs *http2clientStream) writeRequestBody(body io.Reader, bodyCloser io.Clos req := cs.req hasTrailers := req.Trailer != nil + remainLen := http2actualContentLength(req) + hasContentLen := remainLen != -1 var sawEOF bool for !sawEOF { - n, err := body.Read(buf) + n, err := body.Read(buf[:len(buf)-1]) + if hasContentLen { + remainLen -= int64(n) + if remainLen == 0 && err == nil { + // The request body's Content-Length was predeclared and + // we just finished reading it all, but the underlying io.Reader + // returned the final chunk with a nil error (which is one of + // the two valid things a Reader can do at EOF). Because we'd prefer + // to send the END_STREAM bit early, double-check that we're actually + // at EOF. Subsequent reads should return (0, EOF) at this point. + // If either value is different, we return an error in one of two ways below. + var n1 int + n1, err = body.Read(buf[n:]) + remainLen -= int64(n1) + } + if remainLen < 0 { + err = http2errReqBodyTooLong + cc.writeStreamReset(cs.ID, http2ErrCodeCancel, err) + return err + } + } if err == io.EOF { sawEOF = true err = nil @@ -7958,7 +8006,29 @@ func (cc *http2ClientConn) encodeHeaders(req *Request, addGzipHeader bool, trail if vv[0] == "" { continue } - + } else if strings.EqualFold(k, "cookie") { + // Per 8.1.2.5 To allow for better compression efficiency, the + // Cookie header field MAY be split into separate header fields, + // each with one or more cookie-pairs. + for _, v := range vv { + for { + p := strings.IndexByte(v, ';') + if p < 0 { + break + } + f("cookie", v[:p]) + p++ + // strip space after semicolon if any. + for p+1 <= len(v) && v[p] == ' ' { + p++ + } + v = v[p:] + } + if len(v) > 0 { + f("cookie", v) + } + } + continue } for _, v := range vv { @@ -8096,6 +8166,7 @@ func (cc *http2ClientConn) streamByID(id uint32, andRemove bool) *http2clientStr delete(cc.streams, id) if len(cc.streams) == 0 && cc.idleTimer != nil { cc.idleTimer.Reset(cc.idleTimeout) + cc.lastIdle = time.Now() } close(cs.done) // Wake up checkResetOrDone via clientStream.awaitFlowControl and @@ -9846,7 +9917,7 @@ func (n *http2priorityNode) addBytes(b int64) { } // walkReadyInOrder iterates over the tree in priority order, calling f for each node -// with a non-empty write queue. When f returns true, this funcion returns true and the +// with a non-empty write queue. When f returns true, this function returns true and the // walk halts. tmp is used as scratch space for sorting. // // f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true @@ -10163,7 +10234,8 @@ type http2randomWriteScheduler struct { zero http2writeQueue // sq contains the stream-specific queues, keyed by stream ID. - // When a stream is idle or closed, it's deleted from the map. + // When a stream is idle, closed, or emptied, it's deleted + // from the map. sq map[uint32]*http2writeQueue // pool of empty queues for reuse. @@ -10207,8 +10279,12 @@ func (ws *http2randomWriteScheduler) Pop() (http2FrameWriteRequest, bool) { return ws.zero.shift(), true } // Iterate over all non-idle streams until finding one that can be consumed. - for _, q := range ws.sq { + for streamID, q := range ws.sq { if wr, ok := q.consume(math.MaxInt32); ok { + if q.empty() { + delete(ws.sq, streamID) + ws.queuePool.put(q) + } return wr, true } } diff --git a/libgo/go/net/http/header.go b/libgo/go/net/http/header.go index 230ca03d4f0..b9b53911f38 100644 --- a/libgo/go/net/http/header.go +++ b/libgo/go/net/http/header.go @@ -40,13 +40,21 @@ func (h Header) Set(key, value string) { // Get gets the first value associated with the given key. If // there are no values associated with the key, Get returns "". // It is case insensitive; textproto.CanonicalMIMEHeaderKey is -// used to canonicalize the provided key. To access multiple -// values of a key, or to use non-canonical keys, access the -// map directly. +// used to canonicalize the provided key. To use non-canonical keys, +// access the map directly. func (h Header) Get(key string) string { return textproto.MIMEHeader(h).Get(key) } +// Values returns all values associated with the given key. +// It is case insensitive; textproto.CanonicalMIMEHeaderKey is +// used to canonicalize the provided key. To use non-canonical +// keys, access the map directly. +// The returned slice is not a copy. +func (h Header) Values(key string) []string { + return textproto.MIMEHeader(h).Values(key) +} + // get is like Get, but key must already be in CanonicalHeaderKey form. func (h Header) get(key string) string { if v := h[key]; len(v) > 0 { @@ -170,6 +178,7 @@ func (h Header) sortedKeyValues(exclude map[string]bool) (kvs []keyValues, hs *h // WriteSubset writes a header in wire format. // If exclude is not nil, keys where exclude[key] == true are not written. +// Keys are not canonicalized before checking the exclude map. func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error { return h.writeSubset(w, exclude, nil) } diff --git a/libgo/go/net/http/header_test.go b/libgo/go/net/http/header_test.go index a82504afe32..ad8ab9b0554 100644 --- a/libgo/go/net/http/header_test.go +++ b/libgo/go/net/http/header_test.go @@ -7,6 +7,7 @@ package http import ( "bytes" "internal/race" + "reflect" "runtime" "testing" "time" @@ -220,3 +221,34 @@ func TestHeaderWriteSubsetAllocs(t *testing.T) { t.Errorf("allocs = %g; want 0", n) } } + +// Issue 34878: test that every call to +// cloneOrMakeHeader never returns a nil Header. +func TestCloneOrMakeHeader(t *testing.T) { + tests := []struct { + name string + in, want Header + }{ + {"nil", nil, Header{}}, + {"empty", Header{}, Header{}}, + { + name: "non-empty", + in: Header{"foo": {"bar"}}, + want: Header{"foo": {"bar"}}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := cloneOrMakeHeader(tt.in) + if got == nil { + t.Fatal("unexpected nil Header") + } + if !reflect.DeepEqual(got, tt.want) { + t.Fatalf("Got: %#v\nWant: %#v", got, tt.want) + } + got.Add("A", "B") + got.Get("A") + }) + } +} diff --git a/libgo/go/net/http/http.go b/libgo/go/net/http/http.go index 3510fe604d0..89e86d80e8e 100644 --- a/libgo/go/net/http/http.go +++ b/libgo/go/net/http/http.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:generate bundle -o=h2_bundle.go -prefix=http2 -tags=!nethttpomithttp2 golang.org/x/net/http2 + package http import ( @@ -22,6 +24,11 @@ const maxInt64 = 1<<63 - 1 // immediate cancellation of network operations. var aLongTimeAgo = time.Unix(1, 0) +// omitBundledHTTP2 is set by omithttp2.go when the nethttpomithttp2 +// build tag is set. That means h2_bundle.go isn't compiled in and we +// shouldn't try to use it. +var omitBundledHTTP2 bool + // TODO(bradfitz): move common stuff here. The other files have accumulated // generic http stuff in random places. diff --git a/libgo/go/net/http/http_test.go b/libgo/go/net/http/http_test.go index 8f466bb3668..f4ea52db3bc 100644 --- a/libgo/go/net/http/http_test.go +++ b/libgo/go/net/http/http_test.go @@ -9,6 +9,7 @@ package http import ( "bytes" "internal/testenv" + "net/url" "os/exec" "reflect" "testing" @@ -109,3 +110,54 @@ func TestCmdGoNoHTTPServer(t *testing.T) { } } } + +// Tests that the nethttpomithttp2 build tag doesn't rot too much, +// even if there's not a regular builder on it. +func TestOmitHTTP2(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + t.Parallel() + goTool := testenv.GoToolPath(t) + out, err := exec.Command(goTool, "test", "-short", "-tags=nethttpomithttp2", "net/http").CombinedOutput() + if err != nil { + t.Fatalf("go test -short failed: %v, %s", err, out) + } +} + +// Tests that the nethttpomithttp2 build tag at least type checks +// in short mode. +// The TestOmitHTTP2 test above actually runs tests (in long mode). +func TestOmitHTTP2Vet(t *testing.T) { + t.Parallel() + goTool := testenv.GoToolPath(t) + out, err := exec.Command(goTool, "vet", "-tags=nethttpomithttp2", "net/http").CombinedOutput() + if err != nil { + t.Fatalf("go vet failed: %v, %s", err, out) + } +} + +var valuesCount int + +func BenchmarkCopyValues(b *testing.B) { + b.ReportAllocs() + src := url.Values{ + "a": {"1", "2", "3", "4", "5"}, + "b": {"2", "2", "3", "4", "5"}, + "c": {"3", "2", "3", "4", "5"}, + "d": {"4", "2", "3", "4", "5"}, + "e": {"1", "1", "2", "3", "4", "5", "6", "7", "abcdef", "l", "a", "b", "c", "d", "z"}, + "j": {"1", "2"}, + "m": nil, + } + for i := 0; i < b.N; i++ { + dst := url.Values{"a": {"b"}, "b": {"2"}, "c": {"3"}, "d": {"4"}, "j": nil, "m": {"x"}} + copyValues(dst, src) + if valuesCount = len(dst["a"]); valuesCount != 6 { + b.Fatalf(`%d items in dst["a"] but expected 6`, valuesCount) + } + } + if valuesCount == 0 { + b.Fatal("Benchmark wasn't run") + } +} diff --git a/libgo/go/net/http/httptest/example_test.go b/libgo/go/net/http/httptest/example_test.go new file mode 100644 index 00000000000..54e77dbb84c --- /dev/null +++ b/libgo/go/net/http/httptest/example_test.go @@ -0,0 +1,100 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package httptest_test + +import ( + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "net/http/httptest" +) + +func ExampleResponseRecorder() { + handler := func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "Hello World!") + } + + req := httptest.NewRequest("GET", "http://example.com/foo", nil) + w := httptest.NewRecorder() + handler(w, req) + + resp := w.Result() + body, _ := ioutil.ReadAll(resp.Body) + + fmt.Println(resp.StatusCode) + fmt.Println(resp.Header.Get("Content-Type")) + fmt.Println(string(body)) + + // Output: + // 200 + // text/html; charset=utf-8 + // Hello World! +} + +func ExampleServer() { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello, client") + })) + defer ts.Close() + + res, err := http.Get(ts.URL) + if err != nil { + log.Fatal(err) + } + greeting, err := ioutil.ReadAll(res.Body) + res.Body.Close() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s", greeting) + // Output: Hello, client +} + +func ExampleServer_hTTP2() { + ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hello, %s", r.Proto) + })) + ts.EnableHTTP2 = true + ts.StartTLS() + defer ts.Close() + + res, err := ts.Client().Get(ts.URL) + if err != nil { + log.Fatal(err) + } + greeting, err := ioutil.ReadAll(res.Body) + res.Body.Close() + if err != nil { + log.Fatal(err) + } + fmt.Printf("%s", greeting) + + // Output: Hello, HTTP/2.0 +} + +func ExampleNewTLSServer() { + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "Hello, client") + })) + defer ts.Close() + + client := ts.Client() + res, err := client.Get(ts.URL) + if err != nil { + log.Fatal(err) + } + + greeting, err := ioutil.ReadAll(res.Body) + res.Body.Close() + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s", greeting) + // Output: Hello, client +} diff --git a/libgo/go/net/http/httptest/server.go b/libgo/go/net/http/httptest/server.go index 485a4a5797e..8ebf681f4b8 100644 --- a/libgo/go/net/http/httptest/server.go +++ b/libgo/go/net/http/httptest/server.go @@ -27,6 +27,11 @@ type Server struct { URL string // base URL of form http://ipaddr:port with no trailing slash Listener net.Listener + // EnableHTTP2 controls whether HTTP/2 is enabled + // on the server. It must be set between calling + // NewUnstartedServer and calling Server.StartTLS. + EnableHTTP2 bool + // TLS is the optional TLS configuration, populated with a new config // after TLS is started. If set on an unstarted server before StartTLS // is called, existing fields are copied into the new config. @@ -151,7 +156,11 @@ func (s *Server) StartTLS() { s.TLS = new(tls.Config) } if s.TLS.NextProtos == nil { - s.TLS.NextProtos = []string{"http/1.1"} + nextProtos := []string{"http/1.1"} + if s.EnableHTTP2 { + nextProtos = []string{"h2"} + } + s.TLS.NextProtos = nextProtos } if len(s.TLS.Certificates) == 0 { s.TLS.Certificates = []tls.Certificate{cert} @@ -166,6 +175,7 @@ func (s *Server) StartTLS() { TLSClientConfig: &tls.Config{ RootCAs: certpool, }, + ForceAttemptHTTP2: s.EnableHTTP2, } s.Listener = tls.NewListener(s.Listener, s.TLS) s.URL = "https://" + s.Listener.Addr().String() diff --git a/libgo/go/net/http/httptest/server_test.go b/libgo/go/net/http/httptest/server_test.go index 8ab50cdb0ab..0aad15c5ed2 100644 --- a/libgo/go/net/http/httptest/server_test.go +++ b/libgo/go/net/http/httptest/server_test.go @@ -202,3 +202,39 @@ func TestServerZeroValueClose(t *testing.T) { ts.Close() // tests that it doesn't panic } + +func TestTLSServerWithHTTP2(t *testing.T) { + modes := []struct { + name string + wantProto string + }{ + {"http1", "HTTP/1.1"}, + {"http2", "HTTP/2.0"}, + } + + for _, tt := range modes { + t.Run(tt.name, func(t *testing.T) { + cst := NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("X-Proto", r.Proto) + })) + + switch tt.name { + case "http2": + cst.EnableHTTP2 = true + cst.StartTLS() + default: + cst.Start() + } + + defer cst.Close() + + res, err := cst.Client().Get(cst.URL) + if err != nil { + t.Fatalf("Failed to make request: %v", err) + } + if g, w := res.Header.Get("X-Proto"), tt.wantProto; g != w { + t.Fatalf("X-Proto header mismatch:\n\tgot: %q\n\twant: %q", g, w) + } + }) + } +} diff --git a/libgo/go/net/http/httptrace/trace.go b/libgo/go/net/http/httptrace/trace.go index 8b377edee5d..6a5cbac9d89 100644 --- a/libgo/go/net/http/httptrace/trace.go +++ b/libgo/go/net/http/httptrace/trace.go @@ -133,8 +133,8 @@ type ClientTrace struct { ConnectDone func(network, addr string, err error) // TLSHandshakeStart is called when the TLS handshake is started. When - // connecting to a HTTPS site via a HTTP proxy, the handshake happens after - // the CONNECT request is processed by the proxy. + // connecting to an HTTPS site via an HTTP proxy, the handshake happens + // after the CONNECT request is processed by the proxy. TLSHandshakeStart func() // TLSHandshakeDone is called after the TLS handshake with either the diff --git a/libgo/go/net/http/httputil/dump.go b/libgo/go/net/http/httputil/dump.go index 7104c374545..c97be066d7d 100644 --- a/libgo/go/net/http/httputil/dump.go +++ b/libgo/go/net/http/httputil/dump.go @@ -24,7 +24,7 @@ import ( // It returns an error if the initial slurp of all bytes fails. It does not attempt // to make the returned ReadClosers have identical error-matching behavior. func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) { - if b == http.NoBody { + if b == nil || b == http.NoBody { // No copying needed. Preserve the magic sentinel meaning of NoBody. return http.NoBody, http.NoBody, nil } @@ -60,16 +60,28 @@ func (b neverEnding) Read(p []byte) (n int, err error) { return len(p), nil } +// outGoingLength is a copy of the unexported +// (*http.Request).outgoingLength method. +func outgoingLength(req *http.Request) int64 { + if req.Body == nil || req.Body == http.NoBody { + return 0 + } + if req.ContentLength != 0 { + return req.ContentLength + } + return -1 +} + // DumpRequestOut is like DumpRequest but for outgoing client requests. It // includes any headers that the standard http.Transport adds, such as // User-Agent. func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { save := req.Body dummyBody := false - if !body || req.Body == nil { - req.Body = nil - if req.ContentLength != 0 { - req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), req.ContentLength)) + if !body { + contentLength := outgoingLength(req) + if contentLength != 0 { + req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), contentLength)) dummyBody = true } } else { @@ -111,6 +123,10 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { } defer t.CloseIdleConnections() + // We need this channel to ensure that the reader + // goroutine exits if t.RoundTrip returns an error. + // See golang.org/issue/32571. + quitReadCh := make(chan struct{}) // Wait for the request before replying with a dummy response: go func() { req, err := http.ReadRequest(bufio.NewReader(pr)) @@ -120,13 +136,18 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) { io.Copy(ioutil.Discard, req.Body) req.Body.Close() } - dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n") + select { + case dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\nConnection: close\r\n\r\n"): + case <-quitReadCh: + } }() _, err := t.RoundTrip(reqSend) req.Body = save if err != nil { + pw.Close() + quitReadCh <- struct{}{} return nil, err } dump := buf.Bytes() diff --git a/libgo/go/net/http/httputil/dump_test.go b/libgo/go/net/http/httputil/dump_test.go index 97954ca88d0..ead56bc172b 100644 --- a/libgo/go/net/http/httputil/dump_test.go +++ b/libgo/go/net/http/httputil/dump_test.go @@ -17,6 +17,12 @@ import ( "testing" ) +type eofReader struct{} + +func (n eofReader) Close() error { return nil } + +func (n eofReader) Read([]byte) (int, error) { return 0, io.EOF } + type dumpTest struct { // Either Req or GetReq can be set/nil but not both. Req *http.Request @@ -26,6 +32,7 @@ type dumpTest struct { WantDump string WantDumpOut string + MustError bool // if true, the test is expected to throw an error NoBody bool // if true, set DumpRequest{,Out} body to false } @@ -203,9 +210,42 @@ var dumpTests = []dumpTest{ "Content-Length: 0\r\n" + "Accept-Encoding: gzip\r\n\r\n", }, + + // Issue 34504: a non-nil Body without ContentLength set should be chunked + { + Req: &http.Request{ + Method: "PUT", + URL: &url.URL{ + Scheme: "http", + Host: "post.tld", + Path: "/test", + }, + ContentLength: 0, + Proto: "HTTP/1.1", + ProtoMajor: 1, + ProtoMinor: 1, + Body: &eofReader{}, + }, + NoBody: true, + WantDumpOut: "PUT /test HTTP/1.1\r\n" + + "Host: post.tld\r\n" + + "User-Agent: Go-http-client/1.1\r\n" + + "Transfer-Encoding: chunked\r\n" + + "Accept-Encoding: gzip\r\n\r\n", + }, } func TestDumpRequest(t *testing.T) { + // Make a copy of dumpTests and add 10 new cases with an empty URL + // to test that no goroutines are leaked. See golang.org/issue/32571. + // 10 seems to be a decent number which always triggers the failure. + dumpTests := dumpTests[:] + for i := 0; i < 10; i++ { + dumpTests = append(dumpTests, dumpTest{ + Req: mustNewRequest("GET", "", nil), + MustError: true, + }) + } numg0 := runtime.NumGoroutine() for i, tt := range dumpTests { if tt.Req != nil && tt.GetReq != nil || tt.Req == nil && tt.GetReq == nil { @@ -250,6 +290,15 @@ func TestDumpRequest(t *testing.T) { } } + if tt.MustError { + req := freshReq(tt) + _, err := DumpRequestOut(req, !tt.NoBody) + if err == nil { + t.Errorf("DumpRequestOut #%d: expected an error, got nil", i) + } + continue + } + if tt.WantDumpOut != "" { req := freshReq(tt) dump, err := DumpRequestOut(req, !tt.NoBody) diff --git a/libgo/go/net/http/httputil/reverseproxy_test.go b/libgo/go/net/http/httputil/reverseproxy_test.go index 7f9dc0800f8..f58e08867f6 100644 --- a/libgo/go/net/http/httputil/reverseproxy_test.go +++ b/libgo/go/net/http/httputil/reverseproxy_test.go @@ -436,7 +436,7 @@ func TestReverseProxyCancelation(t *testing.T) { } if err == nil { // This should be an error like: - // Get http://127.0.0.1:58079: read tcp 127.0.0.1:58079: + // Get "http://127.0.0.1:58079": read tcp 127.0.0.1:58079: // use of closed network connection t.Error("Server.Client().Do() returned nil error; want non-nil error") } diff --git a/libgo/go/net/http/main_test.go b/libgo/go/net/http/main_test.go index 7936fb3044e..35cc80977c4 100644 --- a/libgo/go/net/http/main_test.go +++ b/libgo/go/net/http/main_test.go @@ -90,6 +90,9 @@ func goroutineLeaked() bool { // (all.bash), but as a serial test otherwise. Using t.Parallel isn't // compatible with the afterTest func in non-short mode. func setParallel(t *testing.T) { + if strings.Contains(t.Name(), "HTTP2") { + http.CondSkipHTTP2(t) + } if testing.Short() { t.Parallel() } @@ -122,7 +125,7 @@ func afterTest(t testing.TB) { ").noteClientGone(": "a closenotifier sender", } var stacks string - for i := 0; i < 4; i++ { + for i := 0; i < 10; i++ { bad = "" stacks = strings.Join(interestingGoroutines(), "\n\n") for substr, what := range badSubstring { diff --git a/libgo/go/net/http/npn_test.go b/libgo/go/net/http/npn_test.go deleted file mode 100644 index 618bdbe54a6..00000000000 --- a/libgo/go/net/http/npn_test.go +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http_test - -import ( - "bufio" - "bytes" - "crypto/tls" - "crypto/x509" - "fmt" - "io" - "io/ioutil" - . "net/http" - "net/http/httptest" - "strings" - "testing" -) - -func TestNextProtoUpgrade(t *testing.T) { - setParallel(t) - defer afterTest(t) - ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { - fmt.Fprintf(w, "path=%s,proto=", r.URL.Path) - if r.TLS != nil { - w.Write([]byte(r.TLS.NegotiatedProtocol)) - } - if r.RemoteAddr == "" { - t.Error("request with no RemoteAddr") - } - if r.Body == nil { - t.Errorf("request with nil Body") - } - })) - ts.TLS = &tls.Config{ - NextProtos: []string{"unhandled-proto", "tls-0.9"}, - } - ts.Config.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){ - "tls-0.9": handleTLSProtocol09, - } - ts.StartTLS() - defer ts.Close() - - // Normal request, without NPN. - { - c := ts.Client() - res, err := c.Get(ts.URL) - if err != nil { - t.Fatal(err) - } - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - if want := "path=/,proto="; string(body) != want { - t.Errorf("plain request = %q; want %q", body, want) - } - } - - // Request to an advertised but unhandled NPN protocol. - // Server will hang up. - { - certPool := x509.NewCertPool() - certPool.AddCert(ts.Certificate()) - tr := &Transport{ - TLSClientConfig: &tls.Config{ - RootCAs: certPool, - NextProtos: []string{"unhandled-proto"}, - }, - } - defer tr.CloseIdleConnections() - c := &Client{ - Transport: tr, - } - res, err := c.Get(ts.URL) - if err == nil { - defer res.Body.Close() - var buf bytes.Buffer - res.Write(&buf) - t.Errorf("expected error on unhandled-proto request; got: %s", buf.Bytes()) - } - } - - // Request using the "tls-0.9" protocol, which we register here. - // It is HTTP/0.9 over TLS. - { - c := ts.Client() - tlsConfig := c.Transport.(*Transport).TLSClientConfig - tlsConfig.NextProtos = []string{"tls-0.9"} - conn, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig) - if err != nil { - t.Fatal(err) - } - conn.Write([]byte("GET /foo\n")) - body, err := ioutil.ReadAll(conn) - if err != nil { - t.Fatal(err) - } - if want := "path=/foo,proto=tls-0.9"; string(body) != want { - t.Errorf("plain request = %q; want %q", body, want) - } - } -} - -// handleTLSProtocol09 implements the HTTP/0.9 protocol over TLS, for the -// TestNextProtoUpgrade test. -func handleTLSProtocol09(srv *Server, conn *tls.Conn, h Handler) { - br := bufio.NewReader(conn) - line, err := br.ReadString('\n') - if err != nil { - return - } - line = strings.TrimSpace(line) - path := strings.TrimPrefix(line, "GET ") - if path == line { - return - } - req, _ := NewRequest("GET", path, nil) - req.Proto = "HTTP/0.9" - req.ProtoMajor = 0 - req.ProtoMinor = 9 - rw := &http09Writer{conn, make(Header)} - h.ServeHTTP(rw, req) -} - -type http09Writer struct { - io.Writer - h Header -} - -func (w http09Writer) Header() Header { return w.h } -func (w http09Writer) WriteHeader(int) {} // no headers diff --git a/libgo/go/net/http/omithttp2.go b/libgo/go/net/http/omithttp2.go new file mode 100644 index 00000000000..a0b33e9aad1 --- /dev/null +++ b/libgo/go/net/http/omithttp2.go @@ -0,0 +1,71 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build nethttpomithttp2 + +package http + +import ( + "errors" + "sync" + "time" +) + +func init() { + omitBundledHTTP2 = true +} + +const noHTTP2 = "no bundled HTTP/2" // should never see this + +var http2errRequestCanceled = errors.New("net/http: request canceled") + +var http2goAwayTimeout = 1 * time.Second + +const http2NextProtoTLS = "h2" + +type http2Transport struct { + MaxHeaderListSize uint32 + ConnPool interface{} +} + +func (*http2Transport) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) } +func (*http2Transport) CloseIdleConnections() {} + +type http2erringRoundTripper struct{} + +func (http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) } + +type http2noDialClientConnPool struct { + http2clientConnPool http2clientConnPool +} + +type http2clientConnPool struct { + mu *sync.Mutex + conns map[string][]struct{} +} + +func http2configureTransport(*Transport) (*http2Transport, error) { panic(noHTTP2) } + +func http2isNoCachedConnError(err error) bool { + _, ok := err.(interface{ IsHTTP2NoCachedConnError() }) + return ok +} + +type http2Server struct { + NewWriteScheduler func() http2WriteScheduler +} + +type http2WriteScheduler interface{} + +func http2NewPriorityWriteScheduler(interface{}) http2WriteScheduler { panic(noHTTP2) } + +func http2ConfigureServer(s *Server, conf *http2Server) error { panic(noHTTP2) } + +var http2ErrNoCachedConn = http2noCachedConnError{} + +type http2noCachedConnError struct{} + +func (http2noCachedConnError) IsHTTP2NoCachedConnError() {} + +func (http2noCachedConnError) Error() string { return "http2: no cached connection was available" } diff --git a/libgo/go/net/http/pprof/pprof.go b/libgo/go/net/http/pprof/pprof.go index 35b3285a080..a237f58609c 100644 --- a/libgo/go/net/http/pprof/pprof.go +++ b/libgo/go/net/http/pprof/pprof.go @@ -20,6 +20,9 @@ // log.Println(http.ListenAndServe("localhost:6060", nil)) // }() // +// If you are not using DefaultServeMux, you will have to register handlers +// with the mux you are using. +// // Then use the pprof tool to look at the heap profile: // // go tool pprof http://localhost:6060/debug/pprof/heap diff --git a/libgo/go/net/http/readrequest_test.go b/libgo/go/net/http/readrequest_test.go index 517a8189e15..b227bb6d38b 100644 --- a/libgo/go/net/http/readrequest_test.go +++ b/libgo/go/net/http/readrequest_test.go @@ -133,7 +133,7 @@ var reqTests = []reqTest{ nil, noBodyStr, noTrailer, - "parse ../../../../etc/passwd: invalid URI for request", + `parse "../../../../etc/passwd": invalid URI for request`, }, // Tests missing URL: @@ -143,7 +143,7 @@ var reqTests = []reqTest{ nil, noBodyStr, noTrailer, - "parse : empty url", + `parse "": empty url`, }, // Tests chunked body with trailer: diff --git a/libgo/go/net/http/request.go b/libgo/go/net/http/request.go index 31d62083cb0..8dd9fe199f4 100644 --- a/libgo/go/net/http/request.go +++ b/libgo/go/net/http/request.go @@ -22,6 +22,7 @@ import ( "net/http/httptrace" "net/textproto" "net/url" + urlpkg "net/url" "strconv" "strings" "sync" @@ -217,9 +218,11 @@ type Request struct { // Transport.DisableKeepAlives were set. Close bool - // For server requests, Host specifies the host on which the URL - // is sought. Per RFC 7230, section 5.4, this is either the value - // of the "Host" header or the host name given in the URL itself. + // For server requests, Host specifies the host on which the + // URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this + // is either the value of the "Host" header or the host name + // given in the URL itself. For HTTP/2, it is the value of the + // ":authority" pseudo-header field. // It may be of the form "host:port". For international domain // names, Host may be in Punycode or Unicode form. Use // golang.org/x/net/idna to convert it to either format if @@ -347,8 +350,8 @@ func (r *Request) Context() context.Context { // sending the request, and reading the response headers and body. // // To create a new request with a context, use NewRequestWithContext. -// To change the context of a request (such as an incoming) you then -// also want to modify to send back out, use Request.Clone. Between +// To change the context of a request, such as an incoming request you +// want to modify before sending back out, use Request.Clone. Between // those two uses, it's rare to need WithContext. func (r *Request) WithContext(ctx context.Context) *Request { if ctx == nil { @@ -763,7 +766,7 @@ func removeZone(host string) string { return host[:j] + host[i:] } -// ParseHTTPVersion parses a HTTP version string. +// ParseHTTPVersion parses an HTTP version string. // "HTTP/1.0" returns (1, 0, true). func ParseHTTPVersion(vers string) (major, minor int, ok bool) { const Big = 1000000 // arbitrary upper bound @@ -848,7 +851,7 @@ func NewRequestWithContext(ctx context.Context, method, url string, body io.Read if ctx == nil { return nil, errors.New("net/http: nil Context") } - u, err := parseURL(url) // Just url.Parse (url is shadowed for godoc). + u, err := urlpkg.Parse(url) if err != nil { return nil, err } @@ -1165,9 +1168,7 @@ func (l *maxBytesReader) Close() error { func copyValues(dst, src url.Values) { for k, vs := range src { - for _, value := range vs { - dst.Add(k, value) - } + dst[k] = append(dst[k], vs...) } } diff --git a/libgo/go/net/http/request_test.go b/libgo/go/net/http/request_test.go index b072f958024..42c16d00ea8 100644 --- a/libgo/go/net/http/request_test.go +++ b/libgo/go/net/http/request_test.go @@ -85,35 +85,37 @@ func TestParseFormQueryMethods(t *testing.T) { } } -type stringMap map[string][]string -type parseContentTypeTest struct { - shouldError bool - contentType stringMap -} - -var parseContentTypeTests = []parseContentTypeTest{ - {false, stringMap{"Content-Type": {"text/plain"}}}, - // Empty content type is legal - may be treated as - // application/octet-stream (RFC 7231, section 3.1.1.5) - {false, stringMap{}}, - {true, stringMap{"Content-Type": {"text/plain; boundary="}}}, - {false, stringMap{"Content-Type": {"application/unknown"}}}, -} - func TestParseFormUnknownContentType(t *testing.T) { - for i, test := range parseContentTypeTests { - req := &Request{ - Method: "POST", - Header: Header(test.contentType), - Body: ioutil.NopCloser(strings.NewReader("body")), - } - err := req.ParseForm() - switch { - case err == nil && test.shouldError: - t.Errorf("test %d should have returned error", i) - case err != nil && !test.shouldError: - t.Errorf("test %d should not have returned error, got %v", i, err) - } + for _, test := range []struct { + name string + wantErr string + contentType Header + }{ + {"text", "", Header{"Content-Type": {"text/plain"}}}, + // Empty content type is legal - may be treated as + // application/octet-stream (RFC 7231, section 3.1.1.5) + {"empty", "", Header{}}, + {"boundary", "mime: invalid media parameter", Header{"Content-Type": {"text/plain; boundary="}}}, + {"unknown", "", Header{"Content-Type": {"application/unknown"}}}, + } { + t.Run(test.name, + func(t *testing.T) { + req := &Request{ + Method: "POST", + Header: test.contentType, + Body: ioutil.NopCloser(strings.NewReader("body")), + } + err := req.ParseForm() + switch { + case err == nil && test.wantErr != "": + t.Errorf("unexpected success; want error %q", test.wantErr) + case err != nil && test.wantErr == "": + t.Errorf("want success, got error: %v", err) + case test.wantErr != "" && test.wantErr != fmt.Sprint(err): + t.Errorf("got error %q; want %q", err, test.wantErr) + } + }, + ) } } @@ -826,6 +828,34 @@ func TestWithContextDeepCopiesURL(t *testing.T) { } } +func TestNoPanicOnRoundTripWithBasicAuth_h1(t *testing.T) { + testNoPanicWithBasicAuth(t, h1Mode) +} + +func TestNoPanicOnRoundTripWithBasicAuth_h2(t *testing.T) { + testNoPanicWithBasicAuth(t, h2Mode) +} + +// Issue 34878: verify we don't panic when including basic auth (Go 1.13 regression) +func testNoPanicWithBasicAuth(t *testing.T, h2 bool) { + defer afterTest(t) + cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {})) + defer cst.close() + + u, err := url.Parse(cst.ts.URL) + if err != nil { + t.Fatal(err) + } + u.User = url.UserPassword("foo", "bar") + req := &Request{ + URL: u, + Method: "GET", + } + if _, err := cst.c.Do(req); err != nil { + t.Fatalf("Unexpected error: %v", err) + } +} + // verify that NewRequest sets Request.GetBody and that it works func TestNewRequestGetBody(t *testing.T) { tests := []struct { diff --git a/libgo/go/net/http/response_test.go b/libgo/go/net/http/response_test.go index ee7f0d0b708..0c78df6f3fd 100644 --- a/libgo/go/net/http/response_test.go +++ b/libgo/go/net/http/response_test.go @@ -636,6 +636,11 @@ var readResponseCloseInMiddleTests = []struct { {true, true}, } +type readerAndCloser struct { + io.Reader + io.Closer +} + // TestReadResponseCloseInMiddle tests that closing a body after // reading only part of its contents advances the read to the end of // the request, right up until the next request. diff --git a/libgo/go/net/http/roundtrip_js.go b/libgo/go/net/http/roundtrip_js.go index 6331351a838..4dd99651a7b 100644 --- a/libgo/go/net/http/roundtrip_js.go +++ b/libgo/go/net/http/roundtrip_js.go @@ -41,7 +41,7 @@ const jsFetchCreds = "js.fetch:credentials" // Reference: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters const jsFetchRedirect = "js.fetch:redirect" -var useFakeNetwork = js.Global().Get("fetch") == js.Undefined() +var useFakeNetwork = js.Global().Get("fetch").IsUndefined() // RoundTrip implements the RoundTripper interface using the WHATWG Fetch API. func (t *Transport) RoundTrip(req *Request) (*Response, error) { @@ -50,7 +50,7 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { } ac := js.Global().Get("AbortController") - if ac != js.Undefined() { + if !ac.IsUndefined() { // Some browsers that support WASM don't necessarily support // the AbortController. See // https://developer.mozilla.org/en-US/docs/Web/API/AbortController#Browser_compatibility. @@ -74,7 +74,7 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { opt.Set("redirect", h) req.Header.Del(jsFetchRedirect) } - if ac != js.Undefined() { + if !ac.IsUndefined() { opt.Set("signal", ac.Get("signal")) } headers := js.Global().Get("Headers").New() @@ -132,7 +132,7 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { var body io.ReadCloser // The body is undefined when the browser does not support streaming response bodies (Firefox), // and null in certain error cases, i.e. when the request is blocked because of CORS settings. - if b != js.Undefined() && b != js.Null() { + if !b.IsUndefined() && !b.IsNull() { body = &streamReader{stream: b.Call("getReader")} } else { // Fall back to using ArrayBuffer @@ -168,7 +168,7 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { respPromise.Call("then", success, failure) select { case <-req.Context().Done(): - if ac != js.Undefined() { + if !ac.IsUndefined() { // Abort the Fetch request ac.Call("abort") } diff --git a/libgo/go/net/http/serve_test.go b/libgo/go/net/http/serve_test.go index 61adda2604c..29b937993e0 100644 --- a/libgo/go/net/http/serve_test.go +++ b/libgo/go/net/http/serve_test.go @@ -10,6 +10,7 @@ import ( "bufio" "bytes" "compress/gzip" + "compress/zlib" "context" "crypto/tls" "encoding/json" @@ -28,10 +29,11 @@ import ( "net/url" "os" "os/exec" + "path/filepath" "reflect" + "regexp" "runtime" "runtime/debug" - "sort" "strconv" "strings" "sync" @@ -1504,6 +1506,7 @@ func TestTLSServer(t *testing.T) { } func TestServeTLS(t *testing.T) { + CondSkipHTTP2(t) // Not parallel: uses global test hooks. defer afterTest(t) defer SetTestHookServerServe(nil) @@ -1654,6 +1657,7 @@ func TestAutomaticHTTP2_ListenAndServe_GetCertificate(t *testing.T) { } func testAutomaticHTTP2_ListenAndServe(t *testing.T, tlsConf *tls.Config) { + CondSkipHTTP2(t) // Not parallel: uses global test hooks. defer afterTest(t) defer SetTestHookServerServe(nil) @@ -2627,7 +2631,7 @@ func TestRedirect(t *testing.T) { // Test that Redirect sets Content-Type header for GET and HEAD requests // and writes a short HTML body, unless the request already has a Content-Type header. -func TestRedirect_contentTypeAndBody(t *testing.T) { +func TestRedirectContentTypeAndBody(t *testing.T) { type ctHeader struct { Values []string } @@ -2906,7 +2910,7 @@ func TestStripPrefix(t *testing.T) { } // https://golang.org/issue/18952. -func TestStripPrefix_notModifyRequest(t *testing.T) { +func TestStripPrefixNotModifyRequest(t *testing.T) { h := StripPrefix("/foo", NotFoundHandler()) req := httptest.NewRequest("GET", "/foo/bar", nil) h.ServeHTTP(httptest.NewRecorder(), req) @@ -4111,14 +4115,49 @@ func TestServerConnState(t *testing.T) { panic("intentional panic") }, } + + // A stateLog is a log of states over the lifetime of a connection. + type stateLog struct { + active net.Conn // The connection for which the log is recorded; set to the first connection seen in StateNew. + got []ConnState + want []ConnState + complete chan<- struct{} // If non-nil, closed when either 'got' is equal to 'want', or 'got' is no longer a prefix of 'want'. + } + activeLog := make(chan *stateLog, 1) + + // wantLog invokes doRequests, then waits for the resulting connection to + // either pass through the sequence of states in want or enter a state outside + // of that sequence. + wantLog := func(doRequests func(), want ...ConnState) { + t.Helper() + complete := make(chan struct{}) + activeLog <- &stateLog{want: want, complete: complete} + + doRequests() + + timer := time.NewTimer(5 * time.Second) + select { + case <-timer.C: + t.Errorf("Timed out waiting for connection to change state.") + case <-complete: + timer.Stop() + } + sl := <-activeLog + if !reflect.DeepEqual(sl.got, sl.want) { + t.Errorf("Request(s) produced unexpected state sequence.\nGot: %v\nWant: %v", sl.got, sl.want) + } + // Don't return sl to activeLog: we don't expect any further states after + // this point, and want to keep the ConnState callback blocked until the + // next call to wantLog. + } + ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) { handler[r.URL.Path](w, r) })) - defer ts.Close() - - var mu sync.Mutex // guard stateLog and connID - var stateLog = map[int][]ConnState{} - var connID = map[net.Conn]int{} + defer func() { + activeLog <- &stateLog{} // If the test failed, allow any remaining ConnState callbacks to complete. + ts.Close() + }() ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) ts.Config.ConnState = func(c net.Conn, state ConnState) { @@ -4126,20 +4165,27 @@ func TestServerConnState(t *testing.T) { t.Errorf("nil conn seen in state %s", state) return } - mu.Lock() - defer mu.Unlock() - id, ok := connID[c] - if !ok { - id = len(connID) + 1 - connID[c] = id + sl := <-activeLog + if sl.active == nil && state == StateNew { + sl.active = c + } else if sl.active != c { + t.Errorf("unexpected conn in state %s", state) + activeLog <- sl + return + } + sl.got = append(sl.got, state) + if sl.complete != nil && (len(sl.got) >= len(sl.want) || !reflect.DeepEqual(sl.got, sl.want[:len(sl.got)])) { + close(sl.complete) + sl.complete = nil } - stateLog[id] = append(stateLog[id], state) + activeLog <- sl } - ts.Start() + ts.Start() c := ts.Client() mustGet := func(url string, headers ...string) { + t.Helper() req, err := NewRequest("GET", url, nil) if err != nil { t.Fatal(err) @@ -4160,26 +4206,33 @@ func TestServerConnState(t *testing.T) { } } - mustGet(ts.URL + "/") - mustGet(ts.URL + "/close") + wantLog(func() { + mustGet(ts.URL + "/") + mustGet(ts.URL + "/close") + }, StateNew, StateActive, StateIdle, StateActive, StateClosed) - mustGet(ts.URL + "/") - mustGet(ts.URL+"/", "Connection", "close") + wantLog(func() { + mustGet(ts.URL + "/") + mustGet(ts.URL+"/", "Connection", "close") + }, StateNew, StateActive, StateIdle, StateActive, StateClosed) - mustGet(ts.URL + "/hijack") - mustGet(ts.URL + "/hijack-panic") + wantLog(func() { + mustGet(ts.URL + "/hijack") + }, StateNew, StateActive, StateHijacked) - // New->Closed - { + wantLog(func() { + mustGet(ts.URL + "/hijack-panic") + }, StateNew, StateActive, StateHijacked) + + wantLog(func() { c, err := net.Dial("tcp", ts.Listener.Addr().String()) if err != nil { t.Fatal(err) } c.Close() - } + }, StateNew, StateClosed) - // New->Active->Closed - { + wantLog(func() { c, err := net.Dial("tcp", ts.Listener.Addr().String()) if err != nil { t.Fatal(err) @@ -4189,10 +4242,9 @@ func TestServerConnState(t *testing.T) { } c.Read(make([]byte, 1)) // block until server hangs up on us c.Close() - } + }, StateNew, StateActive, StateClosed) - // New->Idle->Closed - { + wantLog(func() { c, err := net.Dial("tcp", ts.Listener.Addr().String()) if err != nil { t.Fatal(err) @@ -4208,47 +4260,7 @@ func TestServerConnState(t *testing.T) { t.Fatal(err) } c.Close() - } - - want := map[int][]ConnState{ - 1: {StateNew, StateActive, StateIdle, StateActive, StateClosed}, - 2: {StateNew, StateActive, StateIdle, StateActive, StateClosed}, - 3: {StateNew, StateActive, StateHijacked}, - 4: {StateNew, StateActive, StateHijacked}, - 5: {StateNew, StateClosed}, - 6: {StateNew, StateActive, StateClosed}, - 7: {StateNew, StateActive, StateIdle, StateClosed}, - } - logString := func(m map[int][]ConnState) string { - var b bytes.Buffer - var keys []int - for id := range m { - keys = append(keys, id) - } - sort.Ints(keys) - for _, id := range keys { - fmt.Fprintf(&b, "Conn %d: ", id) - for _, s := range m[id] { - fmt.Fprintf(&b, "%s ", s) - } - b.WriteString("\n") - } - return b.String() - } - - for i := 0; i < 5; i++ { - time.Sleep(time.Duration(i) * 50 * time.Millisecond) - mu.Lock() - match := reflect.DeepEqual(stateLog, want) - mu.Unlock() - if match { - return - } - } - - mu.Lock() - t.Errorf("Unexpected events.\nGot log:\n%s\n Want:\n%s\n", logString(stateLog), logString(want)) - mu.Unlock() + }, StateNew, StateActive, StateIdle, StateClosed) } func TestServerKeepAlivesEnabled(t *testing.T) { @@ -4347,7 +4359,7 @@ func TestCloseWrite(t *testing.T) { // This verifies that a handler can Flush and then Hijack. // -// An similar test crashed once during development, but it was only +// A similar test crashed once during development, but it was only // testing this tangentially and temporarily until another TODO was // fixed. // @@ -4755,6 +4767,10 @@ func TestServerValidatesHeaders(t *testing.T) { {"foo\xffbar: foo\r\n", 400}, // binary in header {"foo\x00bar: foo\r\n", 400}, // binary in header {"Foo: " + strings.Repeat("x", 1<<21) + "\r\n", 431}, // header too large + // Spaces between the header key and colon are not allowed. + // See RFC 7230, Section 3.2.4. + {"Foo : bar\r\n", 400}, + {"Foo\t: bar\r\n", 400}, {"foo: foo foo\r\n", 200}, // LWS space is okay {"foo: foo\tfoo\r\n", 200}, // LWS tab is okay @@ -6117,6 +6133,39 @@ func TestServerContextsHTTP2(t *testing.T) { } } +// Issue 35750: check ConnContext not modifying context for other connections +func TestConnContextNotModifyingAllContexts(t *testing.T) { + setParallel(t) + defer afterTest(t) + type connKey struct{} + ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) { + rw.Header().Set("Connection", "close") + })) + ts.Config.ConnContext = func(ctx context.Context, c net.Conn) context.Context { + if got := ctx.Value(connKey{}); got != nil { + t.Errorf("in ConnContext, unexpected context key = %#v", got) + } + return context.WithValue(ctx, connKey{}, "conn") + } + ts.Start() + defer ts.Close() + + var res *Response + var err error + + res, err = ts.Client().Get(ts.URL) + if err != nil { + t.Fatal(err) + } + res.Body.Close() + + res, err = ts.Client().Get(ts.URL) + if err != nil { + t.Fatal(err) + } + res.Body.Close() +} + // Issue 30710: ensure that as per the spec, a server responds // with 501 Not Implemented for unsupported transfer-encodings. func TestUnsupportedTransferEncodingsReturn501(t *testing.T) { @@ -6157,6 +6206,217 @@ func TestUnsupportedTransferEncodingsReturn501(t *testing.T) { } } +func TestContentEncodingNoSniffing_h1(t *testing.T) { + testContentEncodingNoSniffing(t, h1Mode) +} + +func TestContentEncodingNoSniffing_h2(t *testing.T) { + testContentEncodingNoSniffing(t, h2Mode) +} + +// Issue 31753: don't sniff when Content-Encoding is set +func testContentEncodingNoSniffing(t *testing.T, h2 bool) { + setParallel(t) + defer afterTest(t) + + type setting struct { + name string + body []byte + + // setting contentEncoding as an interface instead of a string + // directly, so as to differentiate between 3 states: + // unset, empty string "" and set string "foo/bar". + contentEncoding interface{} + wantContentType string + } + + settings := []*setting{ + { + name: "gzip content-encoding, gzipped", // don't sniff. + contentEncoding: "application/gzip", + wantContentType: "", + body: func() []byte { + buf := new(bytes.Buffer) + gzw := gzip.NewWriter(buf) + gzw.Write([]byte("doctype html>

Hello

")) + gzw.Close() + return buf.Bytes() + }(), + }, + { + name: "zlib content-encoding, zlibbed", // don't sniff. + contentEncoding: "application/zlib", + wantContentType: "", + body: func() []byte { + buf := new(bytes.Buffer) + zw := zlib.NewWriter(buf) + zw.Write([]byte("doctype html>

Hello

")) + zw.Close() + return buf.Bytes() + }(), + }, + { + name: "no content-encoding", // must sniff. + wantContentType: "application/x-gzip", + body: func() []byte { + buf := new(bytes.Buffer) + gzw := gzip.NewWriter(buf) + gzw.Write([]byte("doctype html>

Hello

")) + gzw.Close() + return buf.Bytes() + }(), + }, + { + name: "phony content-encoding", // don't sniff. + contentEncoding: "foo/bar", + body: []byte("doctype html>

Hello

"), + }, + { + name: "empty but set content-encoding", + contentEncoding: "", + wantContentType: "audio/mpeg", + body: []byte("ID3"), + }, + } + + for _, tt := range settings { + t.Run(tt.name, func(t *testing.T) { + cst := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, r *Request) { + if tt.contentEncoding != nil { + rw.Header().Set("Content-Encoding", tt.contentEncoding.(string)) + } + rw.Write(tt.body) + })) + defer cst.close() + + res, err := cst.c.Get(cst.ts.URL) + if err != nil { + t.Fatalf("Failed to fetch URL: %v", err) + } + defer res.Body.Close() + + if g, w := res.Header.Get("Content-Encoding"), tt.contentEncoding; g != w { + if w != nil { // The case where contentEncoding was set explicitly. + t.Errorf("Content-Encoding mismatch\n\tgot: %q\n\twant: %q", g, w) + } else if g != "" { // "" should be the equivalent when the contentEncoding is unset. + t.Errorf("Unexpected Content-Encoding %q", g) + } + } + + if g, w := res.Header.Get("Content-Type"), tt.wantContentType; g != w { + t.Errorf("Content-Type mismatch\n\tgot: %q\n\twant: %q", g, w) + } + }) + } +} + +// Issue 30803: ensure that TimeoutHandler logs spurious +// WriteHeader calls, for consistency with other Handlers. +func TestTimeoutHandlerSuperfluousLogs(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + + setParallel(t) + defer afterTest(t) + + pc, curFile, _, _ := runtime.Caller(0) + curFileBaseName := filepath.Base(curFile) + testFuncName := runtime.FuncForPC(pc).Name() + + timeoutMsg := "timed out here!" + + tests := []struct { + name string + mustTimeout bool + wantResp string + }{ + { + name: "return before timeout", + wantResp: "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n", + }, + { + name: "return after timeout", + mustTimeout: true, + wantResp: fmt.Sprintf("HTTP/1.1 503 Service Unavailable\r\nContent-Length: %d\r\n\r\n%s", + len(timeoutMsg), timeoutMsg), + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + exitHandler := make(chan bool, 1) + defer close(exitHandler) + lastLine := make(chan int, 1) + + sh := HandlerFunc(func(w ResponseWriter, r *Request) { + w.WriteHeader(404) + w.WriteHeader(404) + w.WriteHeader(404) + w.WriteHeader(404) + _, _, line, _ := runtime.Caller(0) + lastLine <- line + <-exitHandler + }) + + if !tt.mustTimeout { + exitHandler <- true + } + + logBuf := new(bytes.Buffer) + srvLog := log.New(logBuf, "", 0) + // When expecting to timeout, we'll keep the duration short. + dur := 20 * time.Millisecond + if !tt.mustTimeout { + // Otherwise, make it arbitrarily long to reduce the risk of flakes. + dur = 10 * time.Second + } + th := TimeoutHandler(sh, dur, timeoutMsg) + cst := newClientServerTest(t, h1Mode /* the test is protocol-agnostic */, th, optWithServerLog(srvLog)) + defer cst.close() + + res, err := cst.c.Get(cst.ts.URL) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // Deliberately removing the "Date" header since it is highly ephemeral + // and will cause failure if we try to match it exactly. + res.Header.Del("Date") + res.Header.Del("Content-Type") + + // Match the response. + blob, _ := httputil.DumpResponse(res, true) + if g, w := string(blob), tt.wantResp; g != w { + t.Errorf("Response mismatch\nGot\n%q\n\nWant\n%q", g, w) + } + + // Given 4 w.WriteHeader calls, only the first one is valid + // and the rest should be reported as the 3 spurious logs. + logEntries := strings.Split(strings.TrimSpace(logBuf.String()), "\n") + if g, w := len(logEntries), 3; g != w { + blob, _ := json.MarshalIndent(logEntries, "", " ") + t.Fatalf("Server logs count mismatch\ngot %d, want %d\n\nGot\n%s\n", g, w, blob) + } + + lastSpuriousLine := <-lastLine + firstSpuriousLine := lastSpuriousLine - 3 + // Now ensure that the regexes match exactly. + // "http: superfluous response.WriteHeader call from .func\d.\d (:lastSpuriousLine-[1, 3]" + for i, logEntry := range logEntries { + wantLine := firstSpuriousLine + i + pat := fmt.Sprintf("^http: superfluous response.WriteHeader call from %s.func\\d+.\\d+ \\(%s:%d\\)$", + testFuncName, curFileBaseName, wantLine) + re := regexp.MustCompile(pat) + if !re.MatchString(logEntry) { + t.Errorf("Log entry mismatch\n\t%s\ndoes not match\n\t%s", logEntry, pat) + } + } + }) + } +} + // fetchWireResponse is a helper for dialing to host, // sending http1ReqBody as the payload and retrieving // the response as it was sent on the wire. diff --git a/libgo/go/net/http/server.go b/libgo/go/net/http/server.go index aaf7b68eaff..77329b2708a 100644 --- a/libgo/go/net/http/server.go +++ b/libgo/go/net/http/server.go @@ -19,6 +19,7 @@ import ( "net" "net/textproto" "net/url" + urlpkg "net/url" "os" "path" "runtime" @@ -1384,7 +1385,12 @@ func (cw *chunkWriter) writeHeader(p []byte) { if bodyAllowedForStatus(code) { // If no content type, apply sniffing algorithm to body. _, haveType := header["Content-Type"] - if !haveType && !hasTE && len(p) > 0 { + + // If the Content-Encoding was set and is non-blank, + // we shouldn't sniff the body. See Issue 31753. + ce := header.Get("Content-Encoding") + hasCE := len(ce) > 0 + if !hasCE && !haveType && !hasTE && len(p) > 0 { setHeader.contentType = DetectContentType(p) } } else { @@ -1696,11 +1702,10 @@ func (c *conn) closeWriteAndWait() { time.Sleep(rstAvoidanceDelay) } -// validNPN reports whether the proto is not a blacklisted Next -// Protocol Negotiation protocol. Empty and built-in protocol types -// are blacklisted and can't be overridden with alternate -// implementations. -func validNPN(proto string) bool { +// validNextProto reports whether the proto is not a blacklisted ALPN +// protocol name. Empty and built-in protocol types are blacklisted +// and can't be overridden with alternate implementations. +func validNextProto(proto string) bool { switch proto { case "", "http/1.1", "http/1.0": return false @@ -1799,9 +1804,9 @@ func (c *conn) serve(ctx context.Context) { } c.tlsState = new(tls.ConnectionState) *c.tlsState = tlsConn.ConnectionState() - if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) { + if proto := c.tlsState.NegotiatedProtocol; validNextProto(proto) { if fn := c.server.TLSNextProto[proto]; fn != nil { - h := initNPNRequest{ctx, tlsConn, serverHandler{c.server}} + h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}} fn(c.server, tlsConn, h) } return @@ -2066,8 +2071,7 @@ func StripPrefix(prefix string, h Handler) Handler { // Setting the Content-Type header to any value, including nil, // disables that behavior. func Redirect(w ResponseWriter, r *Request, url string, code int) { - // parseURL is just url.Parse (url is shadowed for godoc). - if u, err := parseURL(url); err == nil { + if u, err := urlpkg.Parse(url); err == nil { // If url was relative, make its path absolute by // combining with request path. // The client would probably do this for us, @@ -2121,10 +2125,6 @@ func Redirect(w ResponseWriter, r *Request, url string, code int) { } } -// parseURL is just url.Parse. It exists only so that url.Parse can be called -// in places where url is shadowed for godoc. See https://golang.org/cl/49930. -var parseURL = url.Parse - var htmlReplacer = strings.NewReplacer( "&", "&", "<", "<", @@ -2493,7 +2493,12 @@ func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error { // A Server defines parameters for running an HTTP server. // The zero value for Server is a valid configuration. type Server struct { - Addr string // TCP address to listen on, ":http" if empty + // Addr optionally specifies the TCP address for the server to listen on, + // in the form "host:port". If empty, ":http" (port 80) is used. + // The service names are defined in RFC 6335 and assigned by IANA. + // See net.Dial for details of the address format. + Addr string + Handler Handler // handler to invoke, http.DefaultServeMux if nil // TLSConfig optionally provides a TLS configuration for use @@ -2542,7 +2547,7 @@ type Server struct { MaxHeaderBytes int // TLSNextProto optionally specifies a function to take over - // ownership of the provided TLS connection when an NPN/ALPN + // ownership of the provided TLS connection when an ALPN // protocol upgrade has occurred. The map key is the protocol // name negotiated. The Handler argument should be used to // handle HTTP requests and will initialize the Request's TLS @@ -2692,7 +2697,7 @@ func (srv *Server) Shutdown(ctx context.Context) error { // RegisterOnShutdown registers a function to call on Shutdown. // This can be used to gracefully shutdown connections that have -// undergone NPN/ALPN protocol upgrade or that have been hijacked. +// undergone ALPN protocol upgrade or that have been hijacked. // This function should start protocol-specific graceful shutdown, // but should not wait for shutdown to complete. func (srv *Server) RegisterOnShutdown(f func()) { @@ -2886,8 +2891,6 @@ func (srv *Server) Serve(l net.Listener) error { } defer srv.trackListener(&l, false) - var tempDelay time.Duration // how long to sleep on accept failure - baseCtx := context.Background() if srv.BaseContext != nil { baseCtx = srv.BaseContext(origListener) @@ -2896,16 +2899,18 @@ func (srv *Server) Serve(l net.Listener) error { } } + var tempDelay time.Duration // how long to sleep on accept failure + ctx := context.WithValue(baseCtx, ServerContextKey, srv) for { - rw, e := l.Accept() - if e != nil { + rw, err := l.Accept() + if err != nil { select { case <-srv.getDoneChan(): return ErrServerClosed default: } - if ne, ok := e.(net.Error); ok && ne.Temporary() { + if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { @@ -2914,22 +2919,23 @@ func (srv *Server) Serve(l net.Listener) error { if max := 1 * time.Second; tempDelay > max { tempDelay = max } - srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay) + srv.logf("http: Accept error: %v; retrying in %v", err, tempDelay) time.Sleep(tempDelay) continue } - return e + return err } + connCtx := ctx if cc := srv.ConnContext; cc != nil { - ctx = cc(ctx, rw) - if ctx == nil { + connCtx = cc(connCtx, rw) + if connCtx == nil { panic("ConnContext returned nil") } } tempDelay = 0 c := srv.newConn(rw) c.setState(c.rwc, StateNew) // before Serve can return - go c.serve(ctx) + go c.serve(connCtx) } } @@ -3160,7 +3166,7 @@ func (srv *Server) onceSetNextProtoDefaults_Serve() { // configured otherwise. (by setting srv.TLSNextProto non-nil) // It must only be called via srv.nextProtoOnce (use srv.setupHTTP2_*). func (srv *Server) onceSetNextProtoDefaults() { - if strings.Contains(os.Getenv("GODEBUG"), "http2server=0") { + if omitBundledHTTP2 || strings.Contains(os.Getenv("GODEBUG"), "http2server=0") { return } // Enable HTTP/2 by default if the user hasn't otherwise @@ -3182,8 +3188,8 @@ func (srv *Server) onceSetNextProtoDefaults() { // After such a timeout, writes by h to its ResponseWriter will return // ErrHandlerTimeout. // -// TimeoutHandler supports the Flusher and Pusher interfaces but does not -// support the Hijacker interface. +// TimeoutHandler supports the Pusher interface but does not support +// the Hijacker or Flusher interfaces. func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler { return &timeoutHandler{ handler: h, @@ -3223,8 +3229,9 @@ func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) { r = r.WithContext(ctx) done := make(chan struct{}) tw := &timeoutWriter{ - w: w, - h: make(Header), + w: w, + h: make(Header), + req: r, } panicChan := make(chan interface{}, 1) go func() { @@ -3264,6 +3271,7 @@ type timeoutWriter struct { w ResponseWriter h Header wbuf bytes.Buffer + req *Request mu sync.Mutex timedOut bool @@ -3272,7 +3280,6 @@ type timeoutWriter struct { } var _ Pusher = (*timeoutWriter)(nil) -var _ Flusher = (*timeoutWriter)(nil) // Push implements the Pusher interface. func (tw *timeoutWriter) Push(target string, opts *PushOptions) error { @@ -3282,14 +3289,6 @@ func (tw *timeoutWriter) Push(target string, opts *PushOptions) error { return ErrNotSupported } -// Flush implements the Flusher interface. -func (tw *timeoutWriter) Flush() { - f, ok := tw.w.(Flusher) - if ok { - f.Flush() - } -} - func (tw *timeoutWriter) Header() Header { return tw.h } func (tw *timeoutWriter) Write(p []byte) (int, error) { @@ -3299,24 +3298,32 @@ func (tw *timeoutWriter) Write(p []byte) (int, error) { return 0, ErrHandlerTimeout } if !tw.wroteHeader { - tw.writeHeader(StatusOK) + tw.writeHeaderLocked(StatusOK) } return tw.wbuf.Write(p) } -func (tw *timeoutWriter) WriteHeader(code int) { +func (tw *timeoutWriter) writeHeaderLocked(code int) { checkWriteHeaderCode(code) - tw.mu.Lock() - defer tw.mu.Unlock() - if tw.timedOut || tw.wroteHeader { + + switch { + case tw.timedOut: return + case tw.wroteHeader: + if tw.req != nil { + caller := relevantCaller() + logf(tw.req, "http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line) + } + default: + tw.wroteHeader = true + tw.code = code } - tw.writeHeader(code) } -func (tw *timeoutWriter) writeHeader(code int) { - tw.wroteHeader = true - tw.code = code +func (tw *timeoutWriter) WriteHeader(code int) { + tw.mu.Lock() + defer tw.mu.Unlock() + tw.writeHeaderLocked(code) } // onceCloseListener wraps a net.Listener, protecting it from @@ -3350,10 +3357,10 @@ func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) { } } -// initNPNRequest is an HTTP handler that initializes certain +// initALPNRequest is an HTTP handler that initializes certain // uninitialized fields in its *Request. Such partially-initialized -// Requests come from NPN protocol handlers. -type initNPNRequest struct { +// Requests come from ALPN protocol handlers. +type initALPNRequest struct { ctx context.Context c *tls.Conn h serverHandler @@ -3363,9 +3370,9 @@ type initNPNRequest struct { // recognized by x/net/http2 to pass down a context; the TLSNextProto // API predates context support so we shoehorn through the only // interface we have available. -func (h initNPNRequest) BaseContext() context.Context { return h.ctx } +func (h initALPNRequest) BaseContext() context.Context { return h.ctx } -func (h initNPNRequest) ServeHTTP(rw ResponseWriter, req *Request) { +func (h initALPNRequest) ServeHTTP(rw ResponseWriter, req *Request) { if req.TLS == nil { req.TLS = &tls.ConnectionState{} *req.TLS = h.c.ConnectionState() diff --git a/libgo/go/net/http/socks_bundle.go b/libgo/go/net/http/socks_bundle.go index d22d6363815..e4466695899 100644 --- a/libgo/go/net/http/socks_bundle.go +++ b/libgo/go/net/http/socks_bundle.go @@ -283,7 +283,7 @@ type socksDialer struct { // establishing the transport connection. ProxyDial func(context.Context, string, string) (net.Conn, error) - // AuthMethods specifies the list of request authention + // AuthMethods specifies the list of request authentication // methods. // If empty, SOCKS client requests only AuthMethodNotRequired. AuthMethods []socksAuthMethod diff --git a/libgo/go/net/http/transfer.go b/libgo/go/net/http/transfer.go index 2e01a07f84f..1d6a9875454 100644 --- a/libgo/go/net/http/transfer.go +++ b/libgo/go/net/http/transfer.go @@ -7,6 +7,7 @@ package http import ( "bufio" "bytes" + "compress/gzip" "errors" "fmt" "io" @@ -466,6 +467,34 @@ func suppressedHeaders(status int) []string { return nil } +// proxyingReadCloser is a composite type that accepts and proxies +// io.Read and io.Close calls to its respective Reader and Closer. +// +// It is composed of: +// a) a top-level reader e.g. the result of decompression +// b) a symbolic Closer e.g. the result of decompression, the +// original body and the connection itself. +type proxyingReadCloser struct { + io.Reader + io.Closer +} + +// multiCloser implements io.Closer and allows a bunch of io.Closer values +// to all be closed once. +// Example usage is with proxyingReadCloser if we are decompressing a response +// body on the fly and would like to close both *gzip.Reader and underlying body. +type multiCloser []io.Closer + +func (mc multiCloser) Close() error { + var err error + for _, c := range mc { + if err1 := c.Close(); err1 != nil && err == nil { + err = err1 + } + } + return err +} + // msg is *Request or *Response. func readTransfer(msg interface{}, r *bufio.Reader) (err error) { t := &transferReader{RequestMethod: "GET"} @@ -543,7 +572,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) { // Prepare body reader. ContentLength < 0 means chunked encoding // or close connection when finished, since multipart is not supported yet switch { - case chunked(t.TransferEncoding): + case chunked(t.TransferEncoding) || implicitlyChunked(t.TransferEncoding): if noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode) { t.Body = NoBody } else { @@ -564,6 +593,21 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) { } } + // Finally if "gzip" was one of the requested transfer-encodings, + // we'll unzip the concatenated body/payload of the request. + // TODO: As we support more transfer-encodings, extract + // this code and apply the un-codings in reverse. + if t.Body != NoBody && gzipped(t.TransferEncoding) { + zr, err := gzip.NewReader(t.Body) + if err != nil { + return fmt.Errorf("http: failed to gunzip body: %v", err) + } + t.Body = &proxyingReadCloser{ + Reader: zr, + Closer: multiCloser{zr, t.Body}, + } + } + // Unify output switch rr := msg.(type) { case *Request: @@ -583,8 +627,41 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) { return nil } -// Checks whether chunked is part of the encodings stack -func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" } +// Checks whether chunked is the last part of the encodings stack +func chunked(te []string) bool { return len(te) > 0 && te[len(te)-1] == "chunked" } + +// implicitlyChunked is a helper to check for implicity of chunked, because +// RFC 7230 Section 3.3.1 says that the sender MUST apply chunked as the final +// payload body to ensure that the message is framed for both the request +// and the body. Since "identity" is incompatible with any other transformational +// encoding cannot co-exist, the presence of "identity" will cause implicitlyChunked +// to return false. +func implicitlyChunked(te []string) bool { + if len(te) == 0 { // No transfer-encodings passed in, so not implicitly chunked. + return false + } + for _, tei := range te { + if tei == "identity" { + return false + } + } + return true +} + +func isGzipTransferEncoding(tei string) bool { + // RFC 7230 4.2.3 requests that "x-gzip" SHOULD be considered the same as "gzip". + return tei == "gzip" || tei == "x-gzip" +} + +// Checks where either of "gzip" or "x-gzip" are contained in transfer encodings. +func gzipped(te []string) bool { + for _, tei := range te { + if isGzipTransferEncoding(tei) { + return true + } + } + return false +} // Checks whether the encoding is explicitly "identity". func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" } @@ -620,25 +697,47 @@ func (t *transferReader) fixTransferEncoding() error { encodings := strings.Split(raw[0], ",") te := make([]string, 0, len(encodings)) - // TODO: Even though we only support "identity" and "chunked" - // encodings, the loop below is designed with foresight. One - // invariant that must be maintained is that, if present, - // chunked encoding must always come first. - for _, encoding := range encodings { + + // When adding new encodings, please maintain the invariant: + // if chunked encoding is present, it must always + // come last and it must be applied only once. + // See RFC 7230 Section 3.3.1 Transfer-Encoding. + for i, encoding := range encodings { encoding = strings.ToLower(strings.TrimSpace(encoding)) - // "identity" encoding is not recorded + if encoding == "identity" { + // "identity" should not be mixed with other transfer-encodings/compressions + // because it means "no compression, no transformation". + if len(encodings) != 1 { + return &badStringError{`"identity" when present must be the only transfer encoding`, strings.Join(encodings, ",")} + } + // "identity" is not recorded. break } - if encoding != "chunked" { + + switch { + case encoding == "chunked": + // "chunked" MUST ALWAYS be the last + // encoding as per the loop invariant. + // That is: + // Invalid: [chunked, gzip] + // Valid: [gzip, chunked] + if i+1 != len(encodings) { + return &badStringError{"chunked must be applied only once, as the last encoding", strings.Join(encodings, ",")} + } + // Supported otherwise. + + case isGzipTransferEncoding(encoding): + // Supported + + default: return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", encoding)} } + te = te[0 : len(te)+1] te[len(te)-1] = encoding } - if len(te) > 1 { - return &badStringError{"too many transfer encodings", strings.Join(te, ",")} - } + if len(te) > 0 { // RFC 7230 3.3.2 says "A sender MUST NOT send a // Content-Length header field in any message that diff --git a/libgo/go/net/http/transfer_test.go b/libgo/go/net/http/transfer_test.go index 65009ee8bf7..a8ce2d3709a 100644 --- a/libgo/go/net/http/transfer_test.go +++ b/libgo/go/net/http/transfer_test.go @@ -7,6 +7,7 @@ package http import ( "bufio" "bytes" + "compress/gzip" "crypto/rand" "fmt" "io" @@ -61,7 +62,6 @@ func TestFinalChunkedBodyReadEOF(t *testing.T) { buf := make([]byte, len(want)) n, err := res.Body.Read(buf) if n != len(want) || err != io.EOF { - t.Logf("body = %#v", res.Body) t.Errorf("Read = %v, %v; want %d, EOF", n, err, len(want)) } if string(buf) != want { @@ -290,7 +290,7 @@ func TestFixTransferEncoding(t *testing.T) { }, { hdr: Header{"Transfer-Encoding": {"chunked, chunked", "identity", "chunked"}}, - wantErr: &badStringError{"too many transfer encodings", "chunked,chunked"}, + wantErr: &badStringError{"chunked must be applied only once, as the last encoding", "chunked, chunked"}, }, { hdr: Header{"Transfer-Encoding": {"chunked"}}, @@ -310,3 +310,283 @@ func TestFixTransferEncoding(t *testing.T) { } } } + +func gzipIt(s string) string { + buf := new(bytes.Buffer) + gw := gzip.NewWriter(buf) + gw.Write([]byte(s)) + gw.Close() + return buf.String() +} + +func TestUnitTestProxyingReadCloserClosesBody(t *testing.T) { + var checker closeChecker + buf := new(bytes.Buffer) + buf.WriteString("Hello, Gophers!") + prc := &proxyingReadCloser{ + Reader: buf, + Closer: &checker, + } + prc.Close() + + read, err := ioutil.ReadAll(prc) + if err != nil { + t.Fatalf("Read error: %v", err) + } + if g, w := string(read), "Hello, Gophers!"; g != w { + t.Errorf("Read mismatch: got %q want %q", g, w) + } + + if checker.closed != true { + t.Fatal("closeChecker.Close was never invoked") + } +} + +func TestGzipTransferEncoding_request(t *testing.T) { + helloWorldGzipped := gzipIt("Hello, World!") + + tests := []struct { + payload string + wantErr string + wantBody string + }{ + + { + // The case of "chunked" properly applied as the last encoding + // and a gzipped request payload that is streamed in 3 parts. + payload: `POST / HTTP/1.1 +Host: golang.org +Transfer-Encoding: gzip, chunked +Content-Type: text/html; charset=UTF-8 + +` + fmt.Sprintf("%02x\r\n%s\r\n%02x\r\n%s\r\n%02x\r\n%s\r\n0\r\n\r\n", + 3, helloWorldGzipped[:3], + 5, helloWorldGzipped[3:8], + len(helloWorldGzipped)-8, helloWorldGzipped[8:]), + wantBody: `Hello, World!`, + }, + + { + // The request specifies "Transfer-Encoding: chunked" so its body must be left untouched. + payload: `PUT / HTTP/1.1 +Host: golang.org +Transfer-Encoding: chunked +Connection: close +Content-Type: text/html; charset=UTF-8 + +` + fmt.Sprintf("%0x\r\n%s\r\n0\r\n\r\n", len(helloWorldGzipped), helloWorldGzipped), + // We want that payload as it was sent. + wantBody: helloWorldGzipped, + }, + + { + // Valid request, the body doesn't have "Transfer-Encoding: chunked" but implicitly encoded + // for chunking as per the advisory from RFC 7230 3.3.1 which advises for cases where. + payload: `POST / HTTP/1.1 +Host: localhost +Transfer-Encoding: gzip +Content-Type: text/html; charset=UTF-8 + +` + fmt.Sprintf("%0x\r\n%s\r\n0\r\n\r\n", len(helloWorldGzipped), helloWorldGzipped), + wantBody: `Hello, World!`, + }, + + { + // Invalid request, the body isn't chunked nor is the connection terminated immediately + // hence invalid as per the advisory from RFC 7230 3.3.1 which advises for cases where + // a Transfer-Encoding that isn't finally chunked is provided. + payload: `PUT / HTTP/1.1 +Host: golang.org +Transfer-Encoding: gzip +Content-Length: 0 +Connection: close +Content-Type: text/html; charset=UTF-8 + +`, + wantErr: `EOF`, + }, + + { + // The case of chunked applied before another encoding. + payload: `PUT / HTTP/1.1 +Location: golang.org +Transfer-Encoding: chunked, gzip +Content-Length: 0 +Connection: close +Content-Type: text/html; charset=UTF-8 + +`, + wantErr: `chunked must be applied only once, as the last encoding "chunked, gzip"`, + }, + + { + // The case of chunked properly applied as the + // last encoding BUT with a bad "Content-Length". + payload: `POST / HTTP/1.1 +Host: golang.org +Transfer-Encoding: gzip, chunked +Content-Length: 10 +Connection: close +Content-Type: text/html; charset=UTF-8 + +` + "0\r\n\r\n", + wantErr: "EOF", + }, + } + + for i, tt := range tests { + req, err := ReadRequest(bufio.NewReader(strings.NewReader(tt.payload))) + if tt.wantErr != "" { + if err == nil || !strings.Contains(err.Error(), tt.wantErr) { + t.Errorf("test %d. Error mismatch\nGot: %v\nWant: %s", i, err, tt.wantErr) + } + continue + } + + if err != nil { + t.Errorf("test %d. Unexpected ReadRequest error: %v\nPayload:\n%s", i, err, tt.payload) + continue + } + + got, err := ioutil.ReadAll(req.Body) + req.Body.Close() + if err != nil { + t.Errorf("test %d. Failed to read response body: %v", i, err) + } + if g, w := string(got), tt.wantBody; g != w { + t.Errorf("test %d. Request body mimsatch\nGot:\n%s\n\nWant:\n%s", i, g, w) + } + } +} + +func TestGzipTransferEncoding_response(t *testing.T) { + helloWorldGzipped := gzipIt("Hello, World!") + + tests := []struct { + payload string + wantErr string + wantBody string + }{ + + { + // The case of "chunked" properly applied as the last encoding + // and a gzipped payload that is streamed in 3 parts. + payload: `HTTP/1.1 302 Found +Location: https://golang.org/ +Transfer-Encoding: gzip, chunked +Connection: close +Content-Type: text/html; charset=UTF-8 + +` + fmt.Sprintf("%02x\r\n%s\r\n%02x\r\n%s\r\n%02x\r\n%s\r\n0\r\n\r\n", + 3, helloWorldGzipped[:3], + 5, helloWorldGzipped[3:8], + len(helloWorldGzipped)-8, helloWorldGzipped[8:]), + wantBody: `Hello, World!`, + }, + + { + // The response specifies "Transfer-Encoding: chunked" so response body must be left untouched. + payload: `HTTP/1.1 302 Found +Location: https://golang.org/ +Transfer-Encoding: chunked +Connection: close +Content-Type: text/html; charset=UTF-8 + +` + fmt.Sprintf("%0x\r\n%s\r\n0\r\n\r\n", len(helloWorldGzipped), helloWorldGzipped), + // We want that payload as it was sent. + wantBody: helloWorldGzipped, + }, + + { + // Valid response, the body doesn't have "Transfer-Encoding: chunked" but implicitly encoded + // for chunking as per the advisory from RFC 7230 3.3.1 which advises for cases where. + payload: `HTTP/1.1 302 Found +Location: https://golang.org/ +Transfer-Encoding: gzip +Connection: close +Content-Type: text/html; charset=UTF-8 + +` + fmt.Sprintf("%0x\r\n%s\r\n0\r\n\r\n", len(helloWorldGzipped), helloWorldGzipped), + wantBody: `Hello, World!`, + }, + + { + // Invalid response, the body isn't chunked nor is the connection terminated immediately + // hence invalid as per the advisory from RFC 7230 3.3.1 which advises for cases where + // a Transfer-Encoding that isn't finally chunked is provided. + payload: `HTTP/1.1 302 Found +Location: https://golang.org/ +Transfer-Encoding: gzip +Content-Length: 0 +Connection: close +Content-Type: text/html; charset=UTF-8 + +`, + wantErr: `EOF`, + }, + + { + // The case of chunked applied before another encoding. + payload: `HTTP/1.1 302 Found +Location: https://golang.org/ +Transfer-Encoding: chunked, gzip +Content-Length: 0 +Connection: close +Content-Type: text/html; charset=UTF-8 + +`, + wantErr: `chunked must be applied only once, as the last encoding "chunked, gzip"`, + }, + + { + // The case of chunked properly applied as the + // last encoding BUT with a bad "Content-Length". + payload: `HTTP/1.1 302 Found +Location: https://golang.org/ +Transfer-Encoding: gzip, chunked +Content-Length: 10 +Connection: close +Content-Type: text/html; charset=UTF-8 + +` + "0\r\n\r\n", + wantErr: "EOF", + }, + + { + // Including "identity" more than once. + payload: `HTTP/1.1 200 OK +Location: https://golang.org/ +Transfer-Encoding: identity, identity +Content-Length: 0 +Connection: close +Content-Type: text/html; charset=UTF-8 + +` + "0\r\n\r\n", + wantErr: `"identity" when present must be the only transfer encoding "identity, identity"`, + }, + } + + for i, tt := range tests { + res, err := ReadResponse(bufio.NewReader(strings.NewReader(tt.payload)), nil) + if tt.wantErr != "" { + if err == nil || !strings.Contains(err.Error(), tt.wantErr) { + t.Errorf("test %d. Error mismatch\nGot: %v\nWant: %s", i, err, tt.wantErr) + } + continue + } + + if err != nil { + t.Errorf("test %d. Unexpected ReadResponse error: %v\nPayload:\n%s", i, err, tt.payload) + continue + } + + got, err := ioutil.ReadAll(res.Body) + res.Body.Close() + if err != nil { + t.Errorf("test %d. Failed to read response body: %v", i, err) + } + if g, w := string(got), tt.wantBody; g != w { + t.Errorf("test %d. Response body mimsatch\nGot:\n%s\n\nWant:\n%s", i, g, w) + } + } +} diff --git a/libgo/go/net/http/transport.go b/libgo/go/net/http/transport.go index ee279877e02..64d8510b959 100644 --- a/libgo/go/net/http/transport.go +++ b/libgo/go/net/http/transport.go @@ -89,7 +89,7 @@ const DefaultMaxIdleConnsPerHost = 2 // Request.GetBody defined. HTTP requests are considered idempotent if // they have HTTP methods GET, HEAD, OPTIONS, or TRACE; or if their // Header map contains an "Idempotency-Key" or "X-Idempotency-Key" -// entry. If the idempotency key value is an zero-length slice, the +// entry. If the idempotency key value is a zero-length slice, the // request is treated as idempotent but the header is not sent on the // wire. type Transport struct { @@ -142,15 +142,24 @@ type Transport struct { // If both are set, DialContext takes priority. Dial func(network, addr string) (net.Conn, error) - // DialTLS specifies an optional dial function for creating + // DialTLSContext specifies an optional dial function for creating // TLS connections for non-proxied HTTPS requests. // - // If DialTLS is nil, Dial and TLSClientConfig are used. + // If DialTLSContext is nil (and the deprecated DialTLS below is also nil), + // DialContext and TLSClientConfig are used. // - // If DialTLS is set, the Dial hook is not used for HTTPS + // If DialTLSContext is set, the Dial and DialContext hooks are not used for HTTPS // requests and the TLSClientConfig and TLSHandshakeTimeout // are ignored. The returned net.Conn is assumed to already be // past the TLS handshake. + DialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error) + + // DialTLS specifies an optional dial function for creating + // TLS connections for non-proxied HTTPS requests. + // + // Deprecated: Use DialTLSContext instead, which allows the transport + // to cancel dials as soon as they are no longer needed. + // If both are set, DialTLSContext takes priority. DialTLS func(network, addr string) (net.Conn, error) // TLSClientConfig specifies the TLS configuration to use with @@ -218,7 +227,7 @@ type Transport struct { ExpectContinueTimeout time.Duration // TLSNextProto specifies how the Transport switches to an - // alternate protocol (such as HTTP/2) after a TLS NPN/ALPN + // alternate protocol (such as HTTP/2) after a TLS ALPN // protocol negotiation. If Transport dials an TLS connection // with a non-empty protocol name and TLSNextProto contains a // map entry for that key (such as "h2"), then the func is @@ -286,7 +295,7 @@ func (t *Transport) Clone() *Transport { DialContext: t.DialContext, Dial: t.Dial, DialTLS: t.DialTLS, - TLSClientConfig: t.TLSClientConfig.Clone(), + DialTLSContext: t.DialTLSContext, TLSHandshakeTimeout: t.TLSHandshakeTimeout, DisableKeepAlives: t.DisableKeepAlives, DisableCompression: t.DisableCompression, @@ -302,6 +311,9 @@ func (t *Transport) Clone() *Transport { WriteBufferSize: t.WriteBufferSize, ReadBufferSize: t.ReadBufferSize, } + if t.TLSClientConfig != nil { + t2.TLSClientConfig = t.TLSClientConfig.Clone() + } if !t.tlsNextProtoWasNil { npm := map[string]func(authority string, c *tls.Conn) RoundTripper{} for k, v := range t.TLSNextProto { @@ -322,6 +334,10 @@ type h2Transport interface { CloseIdleConnections() } +func (t *Transport) hasCustomTLSDialer() bool { + return t.DialTLS != nil || t.DialTLSContext != nil +} + // onceSetNextProtoDefaults initializes TLSNextProto. // It must be called via t.nextProtoOnce.Do. func (t *Transport) onceSetNextProtoDefaults() { @@ -350,7 +366,7 @@ func (t *Transport) onceSetNextProtoDefaults() { // Transport. return } - if !t.ForceAttemptHTTP2 && (t.TLSClientConfig != nil || t.Dial != nil || t.DialTLS != nil || t.DialContext != nil) { + if !t.ForceAttemptHTTP2 && (t.TLSClientConfig != nil || t.Dial != nil || t.DialContext != nil || t.hasCustomTLSDialer()) { // Be conservative and don't automatically enable // http2 if they've specified a custom TLS config or // custom dialers. Let them opt-in themselves via @@ -359,6 +375,9 @@ func (t *Transport) onceSetNextProtoDefaults() { // However, if ForceAttemptHTTP2 is true, it overrides the above checks. return } + if omitBundledHTTP2 { + return + } t2, err := http2configureTransport(t) if err != nil { log.Printf("Error enabling Transport HTTP/2 support: %v", err) @@ -437,7 +456,7 @@ func (tr *transportRequest) setError(err error) { tr.mu.Unlock() } -// useRegisteredProtocol reports whether an alternate protocol (as reqistered +// useRegisteredProtocol reports whether an alternate protocol (as registered // with Transport.RegisterProtocol) should be respected for this request. func (t *Transport) useRegisteredProtocol(req *Request) bool { if req.URL.Scheme == "https" && req.requiresHTTP1() { @@ -469,10 +488,12 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) { if isHTTP { for k, vv := range req.Header { if !httpguts.ValidHeaderFieldName(k) { + req.closeBody() return nil, fmt.Errorf("net/http: invalid header field name %q", k) } for _, v := range vv { if !httpguts.ValidHeaderFieldValue(v) { + req.closeBody() return nil, fmt.Errorf("net/http: invalid header field value %q for key %v", v, k) } } @@ -492,6 +513,7 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) { return nil, &badStringError{"unsupported protocol scheme", scheme} } if req.Method != "" && !validMethod(req.Method) { + req.closeBody() return nil, fmt.Errorf("net/http: invalid method %q", req.Method) } if req.URL.Host == "" { @@ -537,9 +559,16 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) { if err == nil { return resp, nil } - if http2isNoCachedConnError(err) { - t.removeIdleConn(pconn) - } else if !pconn.shouldRetryRequest(req, err) { + + // Failed. Clean up and determine whether to retry. + + _, isH2DialError := pconn.alt.(http2erringRoundTripper) + if http2isNoCachedConnError(err) || isH2DialError { + if t.removeIdleConn(pconn) { + t.decConnsPerHost(pconn.cacheKey) + } + } + if !pconn.shouldRetryRequest(req, err) { // Issue 16465: return underlying net.Conn.Read error from peek, // as we've historically done. if e, ok := err.(transportReadFromServerError); ok { @@ -710,20 +739,10 @@ func resetProxyConfig() { } func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) { - // TODO: the validPort check is redundant after CL 189258, as url.URL.Port - // only returns valid ports now. golang.org/issue/33600 - if port := treq.URL.Port(); !validPort(port) { - return cm, fmt.Errorf("invalid URL port %q", port) - } cm.targetScheme = treq.URL.Scheme cm.targetAddr = canonicalAddr(treq.URL) if t.Proxy != nil { cm.proxyURL, err = t.Proxy(treq.Request) - if err == nil && cm.proxyURL != nil { - if port := cm.proxyURL.Port(); !validPort(port) { - return cm, fmt.Errorf("invalid proxy URL port %q", port) - } - } } cm.onlyH1 = treq.requiresHTTP1() return cm, err @@ -753,7 +772,6 @@ var ( errCloseIdleConns = errors.New("http: CloseIdleConnections called") errReadLoopExiting = errors.New("http: persistConn.readLoop exiting") errIdleConnTimeout = errors.New("http: idle connection timeout") - errNotCachingH2Conn = errors.New("http: not caching alternate protocol's connections") // errServerClosedIdle is not seen by users for idempotent requests, but may be // seen by a user if the server shuts down an idle connection and sends its FIN @@ -911,16 +929,37 @@ func (t *Transport) queueForIdleConn(w *wantConn) (delivered bool) { return false } + // If IdleConnTimeout is set, calculate the oldest + // persistConn.idleAt time we're willing to use a cached idle + // conn. + var oldTime time.Time + if t.IdleConnTimeout > 0 { + oldTime = time.Now().Add(-t.IdleConnTimeout) + } + // Look for most recently-used idle connection. if list, ok := t.idleConn[w.key]; ok { stop := false delivered := false for len(list) > 0 && !stop { pconn := list[len(list)-1] - if pconn.isBroken() { - // persistConn.readLoop has marked the connection broken, - // but Transport.removeIdleConn has not yet removed it from the idle list. - // Drop on floor on behalf of Transport.removeIdleConn. + + // See whether this connection has been idle too long, considering + // only the wall time (the Round(0)), in case this is a laptop or VM + // coming out of suspend with previously cached idle connections. + tooOld := !oldTime.IsZero() && pconn.idleAt.Round(0).Before(oldTime) + if tooOld { + // Async cleanup. Launch in its own goroutine (as if a + // time.AfterFunc called it); it acquires idleMu, which we're + // holding, and does a synchronous net.Conn.Close. + go pconn.closeConnIfStillIdle() + } + if pconn.isBroken() || tooOld { + // If either persistConn.readLoop has marked the connection + // broken, but Transport.removeIdleConn has not yet removed it + // from the idle list, or if this persistConn is too old (it was + // idle too long), then ignore it and look for another. In both + // cases it's already in the process of being closed. list = list[:len(list)-1] continue } @@ -960,26 +999,28 @@ func (t *Transport) queueForIdleConn(w *wantConn) (delivered bool) { } // removeIdleConn marks pconn as dead. -func (t *Transport) removeIdleConn(pconn *persistConn) { +func (t *Transport) removeIdleConn(pconn *persistConn) bool { t.idleMu.Lock() defer t.idleMu.Unlock() - t.removeIdleConnLocked(pconn) + return t.removeIdleConnLocked(pconn) } // t.idleMu must be held. -func (t *Transport) removeIdleConnLocked(pconn *persistConn) { +func (t *Transport) removeIdleConnLocked(pconn *persistConn) bool { if pconn.idleTimer != nil { pconn.idleTimer.Stop() } t.idleLRU.remove(pconn) key := pconn.cacheKey pconns := t.idleConn[key] + var removed bool switch len(pconns) { case 0: // Nothing case 1: if pconns[0] == pconn { delete(t.idleConn, key) + removed = true } default: for i, v := range pconns { @@ -990,9 +1031,11 @@ func (t *Transport) removeIdleConnLocked(pconn *persistConn) { // conns at the end. copy(pconns[i:], pconns[i+1:]) t.idleConn[key] = pconns[:len(pconns)-1] + removed = true break } } + return removed } func (t *Transport) setReqCanceler(r *Request, fn func(error)) { @@ -1177,6 +1220,18 @@ func (q *wantConnQueue) cleanFront() (cleaned bool) { } } +func (t *Transport) customDialTLS(ctx context.Context, network, addr string) (conn net.Conn, err error) { + if t.DialTLSContext != nil { + conn, err = t.DialTLSContext(ctx, network, addr) + } else { + conn, err = t.DialTLS(network, addr) + } + if conn == nil && err == nil { + err = errors.New("net/http: Transport.DialTLS or DialTLSContext returned (nil, nil)") + } + return +} + // getConn dials and creates a new persistConn to the target as // specified in the connectMethod. This includes doing a proxy CONNECT // and/or setting up TLS. If this doesn't return an error, the persistConn @@ -1206,7 +1261,9 @@ func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (pc *persi // Queue for idle connection. if delivered := t.queueForIdleConn(w); delivered { pc := w.pc - if trace != nil && trace.GotConn != nil { + // Trace only for HTTP/1. + // HTTP/2 calls trace.GotConn itself. + if pc.alt == nil && trace != nil && trace.GotConn != nil { trace.GotConn(pc.gotIdleConnTrace(pc.idleAt)) } // set request canceler to some non-nil function so we @@ -1360,19 +1417,6 @@ func (t *Transport) decConnsPerHost(key connectMethodKey) { } } -// The connect method and the transport can both specify a TLS -// Host name. The transport's name takes precedence if present. -func chooseTLSHost(cm connectMethod, t *Transport) string { - tlsHost := "" - if t.TLSClientConfig != nil { - tlsHost = t.TLSClientConfig.ServerName - } - if tlsHost == "" { - tlsHost = cm.tlsHost() - } - return tlsHost -} - // Add TLS to a persistent connection, i.e. negotiate a TLS session. If pconn is already a TLS // tunnel, this function establishes a nested TLS session inside the encrypted channel. // The remote endpoint's name may be overridden by TLSClientConfig.ServerName. @@ -1438,15 +1482,12 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers } return err } - if cm.scheme() == "https" && t.DialTLS != nil { + if cm.scheme() == "https" && t.hasCustomTLSDialer() { var err error - pconn.conn, err = t.DialTLS("tcp", cm.addr()) + pconn.conn, err = t.customDialTLS(ctx, "tcp", cm.addr()) if err != nil { return nil, wrapErr(err) } - if pconn.conn == nil { - return nil, wrapErr(errors.New("net/http: Transport.DialTLS returned (nil, nil)")) - } if tc, ok := pconn.conn.(*tls.Conn); ok { // Handshake here, in case DialTLS didn't. TLSNextProto below // depends on it for knowing the connection state. @@ -1527,13 +1568,44 @@ func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *pers if pa := cm.proxyAuth(); pa != "" { connectReq.Header.Set("Proxy-Authorization", pa) } - connectReq.Write(conn) - // Read response. - // Okay to use and discard buffered reader here, because - // TLS server will not speak until spoken to. - br := bufio.NewReader(conn) - resp, err := ReadResponse(br, connectReq) + // If there's no done channel (no deadline or cancellation + // from the caller possible), at least set some (long) + // timeout here. This will make sure we don't block forever + // and leak a goroutine if the connection stops replying + // after the TCP connect. + connectCtx := ctx + if ctx.Done() == nil { + newCtx, cancel := context.WithTimeout(ctx, 1*time.Minute) + defer cancel() + connectCtx = newCtx + } + + didReadResponse := make(chan struct{}) // closed after CONNECT write+read is done or fails + var ( + resp *Response + err error // write or read error + ) + // Write the CONNECT request & read the response. + go func() { + defer close(didReadResponse) + err = connectReq.Write(conn) + if err != nil { + return + } + // Okay to use and discard buffered reader here, because + // TLS server will not speak until spoken to. + br := bufio.NewReader(conn) + resp, err = ReadResponse(br, connectReq) + }() + select { + case <-connectCtx.Done(): + conn.Close() + <-didReadResponse + return nil, connectCtx.Err() + case <-didReadResponse: + // resp or err now set + } if err != nil { conn.Close() return nil, err @@ -1927,7 +1999,7 @@ func (pc *persistConn) readLoop() { } return } - pc.readLimit = maxInt64 // effictively no limit for response bodies + pc.readLimit = maxInt64 // effectively no limit for response bodies pc.mu.Lock() pc.numExpectedResponses-- @@ -2635,11 +2707,6 @@ func (gz *gzipReader) Close() error { return gz.body.Close() } -type readerAndCloser struct { - io.Reader - io.Closer -} - type tlsHandshakeTimeoutError struct{} func (tlsHandshakeTimeoutError) Timeout() bool { return true } @@ -2702,15 +2769,3 @@ func (cl *connLRU) remove(pc *persistConn) { func (cl *connLRU) len() int { return len(cl.m) } - -// validPort reports whether p (without the colon) is a valid port in -// a URL, per RFC 3986 Section 3.2.3, which says the port may be -// empty, or only contain digits. -func validPort(p string) bool { - for _, r := range []byte(p) { - if r < '0' || r > '9' { - return false - } - } - return true -} diff --git a/libgo/go/net/http/transport_test.go b/libgo/go/net/http/transport_test.go index f304a7bc0e4..22568136bc4 100644 --- a/libgo/go/net/http/transport_test.go +++ b/libgo/go/net/http/transport_test.go @@ -591,6 +591,7 @@ func TestTransportMaxConnsPerHostIncludeDialInProgress(t *testing.T) { func TestTransportMaxConnsPerHost(t *testing.T) { defer afterTest(t) + CondSkipHTTP2(t) h := HandlerFunc(func(w ResponseWriter, r *Request) { _, err := w.Write([]byte("foo")) @@ -1441,6 +1442,72 @@ func TestTransportProxy(t *testing.T) { } } +// Issue 28012: verify that the Transport closes its TCP connection to http proxies +// when they're slow to reply to HTTPS CONNECT responses. +func TestTransportProxyHTTPSConnectLeak(t *testing.T) { + setParallel(t) + defer afterTest(t) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ln := newLocalListener(t) + defer ln.Close() + listenerDone := make(chan struct{}) + go func() { + defer close(listenerDone) + c, err := ln.Accept() + if err != nil { + t.Errorf("Accept: %v", err) + return + } + defer c.Close() + // Read the CONNECT request + br := bufio.NewReader(c) + cr, err := ReadRequest(br) + if err != nil { + t.Errorf("proxy server failed to read CONNECT request") + return + } + if cr.Method != "CONNECT" { + t.Errorf("unexpected method %q", cr.Method) + return + } + + // Now hang and never write a response; instead, cancel the request and wait + // for the client to close. + // (Prior to Issue 28012 being fixed, we never closed.) + cancel() + var buf [1]byte + _, err = br.Read(buf[:]) + if err != io.EOF { + t.Errorf("proxy server Read err = %v; want EOF", err) + } + return + }() + + c := &Client{ + Transport: &Transport{ + Proxy: func(*Request) (*url.URL, error) { + return url.Parse("http://" + ln.Addr().String()) + }, + }, + } + req, err := NewRequestWithContext(ctx, "GET", "https://golang.fake.tld/", nil) + if err != nil { + t.Fatal(err) + } + _, err = c.Do(req) + if err == nil { + t.Errorf("unexpected Get success") + } + + // Wait unconditionally for the listener goroutine to exit: this should never + // hang, so if it does we want a full goroutine dump — and that's exactly what + // the testing package will give us when the test run times out. + <-listenerDone +} + // Issue 16997: test transport dial preserves typed errors func TestTransportDialPreservesNetOpProxyError(t *testing.T) { defer afterTest(t) @@ -2293,7 +2360,7 @@ func TestTransportCancelRequestInDial(t *testing.T) { got := logbuf.String() want := `dial: blocking canceling -Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection +Get = Get "http://something.no-network.tld/": net/http: request canceled while waiting for connection ` if got != want { t.Errorf("Got events:\n%s\nWant:\n%s", got, want) @@ -3509,6 +3576,90 @@ func TestTransportDialTLS(t *testing.T) { } } +func TestTransportDialContext(t *testing.T) { + setParallel(t) + defer afterTest(t) + var mu sync.Mutex // guards following + var gotReq bool + var receivedContext context.Context + + ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + mu.Lock() + gotReq = true + mu.Unlock() + })) + defer ts.Close() + c := ts.Client() + c.Transport.(*Transport).DialContext = func(ctx context.Context, netw, addr string) (net.Conn, error) { + mu.Lock() + receivedContext = ctx + mu.Unlock() + return net.Dial(netw, addr) + } + + req, err := NewRequest("GET", ts.URL, nil) + if err != nil { + t.Fatal(err) + } + ctx := context.WithValue(context.Background(), "some-key", "some-value") + res, err := c.Do(req.WithContext(ctx)) + if err != nil { + t.Fatal(err) + } + res.Body.Close() + mu.Lock() + if !gotReq { + t.Error("didn't get request") + } + if receivedContext != ctx { + t.Error("didn't receive correct context") + } +} + +func TestTransportDialTLSContext(t *testing.T) { + setParallel(t) + defer afterTest(t) + var mu sync.Mutex // guards following + var gotReq bool + var receivedContext context.Context + + ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) { + mu.Lock() + gotReq = true + mu.Unlock() + })) + defer ts.Close() + c := ts.Client() + c.Transport.(*Transport).DialTLSContext = func(ctx context.Context, netw, addr string) (net.Conn, error) { + mu.Lock() + receivedContext = ctx + mu.Unlock() + c, err := tls.Dial(netw, addr, c.Transport.(*Transport).TLSClientConfig) + if err != nil { + return nil, err + } + return c, c.Handshake() + } + + req, err := NewRequest("GET", ts.URL, nil) + if err != nil { + t.Fatal(err) + } + ctx := context.WithValue(context.Background(), "some-key", "some-value") + res, err := c.Do(req.WithContext(ctx)) + if err != nil { + t.Fatal(err) + } + res.Body.Close() + mu.Lock() + if !gotReq { + t.Error("didn't get request") + } + if receivedContext != ctx { + t.Error("didn't receive correct context") + } +} + // Test for issue 8755 // Ensure that if a proxy returns an error, it is exposed by RoundTrip func TestRoundTripReturnsProxyError(t *testing.T) { @@ -3566,7 +3717,77 @@ func TestTransportCloseIdleConnsThenReturn(t *testing.T) { wantIdle("after final put", 1) } -// This tests that an client requesting a content range won't also +// Test for issue 34282 +// Ensure that getConn doesn't call the GotConn trace hook on a HTTP/2 idle conn +func TestTransportTraceGotConnH2IdleConns(t *testing.T) { + tr := &Transport{} + wantIdle := func(when string, n int) bool { + got := tr.IdleConnCountForTesting("https", "example.com:443") // key used by PutIdleTestConnH2 + if got == n { + return true + } + t.Errorf("%s: idle conns = %d; want %d", when, got, n) + return false + } + wantIdle("start", 0) + alt := funcRoundTripper(func() {}) + if !tr.PutIdleTestConnH2("https", "example.com:443", alt) { + t.Fatal("put failed") + } + wantIdle("after put", 1) + ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{ + GotConn: func(httptrace.GotConnInfo) { + // tr.getConn should leave it for the HTTP/2 alt to call GotConn. + t.Error("GotConn called") + }, + }) + req, _ := NewRequestWithContext(ctx, MethodGet, "https://example.com", nil) + _, err := tr.RoundTrip(req) + if err != errFakeRoundTrip { + t.Errorf("got error: %v; want %q", err, errFakeRoundTrip) + } + wantIdle("after round trip", 1) +} + +func TestTransportRemovesH2ConnsAfterIdle(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode") + } + + trFunc := func(tr *Transport) { + tr.MaxConnsPerHost = 1 + tr.MaxIdleConnsPerHost = 1 + tr.IdleConnTimeout = 10 * time.Millisecond + } + cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), trFunc) + defer cst.close() + + if _, err := cst.c.Get(cst.ts.URL); err != nil { + t.Fatalf("got error: %s", err) + } + + time.Sleep(100 * time.Millisecond) + got := make(chan error) + go func() { + if _, err := cst.c.Get(cst.ts.URL); err != nil { + got <- err + } + close(got) + }() + + timeout := time.NewTimer(5 * time.Second) + defer timeout.Stop() + select { + case err := <-got: + if err != nil { + t.Fatalf("got error: %s", err) + } + case <-timeout.C: + t.Fatal("request never completed") + } +} + +// This tests that a client requesting a content range won't also // implicitly ask for gzip support. If they want that, they need to do it // on their own. // golang.org/issue/8923 @@ -3928,6 +4149,7 @@ func TestTransportAutomaticHTTP2_DialTLS(t *testing.T) { } func testTransportAutoHTTP(t *testing.T, tr *Transport, wantH2 bool) { + CondSkipHTTP2(t) _, err := tr.RoundTrip(new(Request)) if err == nil { t.Error("expected error from RoundTrip") @@ -5509,6 +5731,7 @@ func TestTransportClone(t *testing.T) { DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") }, Dial: func(network, addr string) (net.Conn, error) { panic("") }, DialTLS: func(network, addr string) (net.Conn, error) { panic("") }, + DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) { panic("") }, TLSClientConfig: new(tls.Config), TLSHandshakeTimeout: time.Second, DisableKeepAlives: true, @@ -5626,3 +5849,263 @@ func TestTransportIgnores408(t *testing.T) { } t.Fatalf("timeout after %v waiting for Transport connections to die off", time.Since(t0)) } + +func TestInvalidHeaderResponse(t *testing.T) { + setParallel(t) + defer afterTest(t) + cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) { + conn, buf, _ := w.(Hijacker).Hijack() + buf.Write([]byte("HTTP/1.1 200 OK\r\n" + + "Date: Wed, 30 Aug 2017 19:09:27 GMT\r\n" + + "Content-Type: text/html; charset=utf-8\r\n" + + "Content-Length: 0\r\n" + + "Foo : bar\r\n\r\n")) + buf.Flush() + conn.Close() + })) + defer cst.close() + res, err := cst.c.Get(cst.ts.URL) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + if v := res.Header.Get("Foo"); v != "" { + t.Errorf(`unexpected "Foo" header: %q`, v) + } + if v := res.Header.Get("Foo "); v != "bar" { + t.Errorf(`bad "Foo " header value: %q, want %q`, v, "bar") + } +} + +type bodyCloser bool + +func (bc *bodyCloser) Close() error { + *bc = true + return nil +} +func (bc *bodyCloser) Read(b []byte) (n int, err error) { + return 0, io.EOF +} + +// Issue 35015: ensure that Transport closes the body on any error +// with an invalid request, as promised by Client.Do docs. +func TestTransportClosesBodyOnInvalidRequests(t *testing.T) { + cst := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { + t.Errorf("Should not have been invoked") + })) + defer cst.Close() + + u, _ := url.Parse(cst.URL) + + tests := []struct { + name string + req *Request + wantErr string + }{ + { + name: "invalid method", + req: &Request{ + Method: " ", + URL: u, + }, + wantErr: "invalid method", + }, + { + name: "nil URL", + req: &Request{ + Method: "GET", + }, + wantErr: "nil Request.URL", + }, + { + name: "invalid header key", + req: &Request{ + Method: "GET", + Header: Header{"💡": {"emoji"}}, + URL: u, + }, + wantErr: "invalid header field name", + }, + { + name: "invalid header value", + req: &Request{ + Method: "POST", + Header: Header{"key": {"\x19"}}, + URL: u, + }, + wantErr: "invalid header field value", + }, + { + name: "non HTTP(s) scheme", + req: &Request{ + Method: "POST", + URL: &url.URL{Scheme: "faux"}, + }, + wantErr: "unsupported protocol scheme", + }, + { + name: "no Host in URL", + req: &Request{ + Method: "POST", + URL: &url.URL{Scheme: "http"}, + }, + wantErr: "no Host", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var bc bodyCloser + req := tt.req + req.Body = &bc + _, err := DefaultClient.Do(tt.req) + if err == nil { + t.Fatal("Expected an error") + } + if !bc { + t.Fatal("Expected body to have been closed") + } + if g, w := err.Error(), tt.wantErr; !strings.Contains(g, w) { + t.Fatalf("Error mismatch\n\t%q\ndoes not contain\n\t%q", g, w) + } + }) + } +} + +// breakableConn is a net.Conn wrapper with a Write method +// that will fail when its brokenState is true. +type breakableConn struct { + net.Conn + *brokenState +} + +type brokenState struct { + sync.Mutex + broken bool +} + +func (w *breakableConn) Write(b []byte) (n int, err error) { + w.Lock() + defer w.Unlock() + if w.broken { + return 0, errors.New("some write error") + } + return w.Conn.Write(b) +} + +// Issue 34978: don't cache a broken HTTP/2 connection +func TestDontCacheBrokenHTTP2Conn(t *testing.T) { + cst := newClientServerTest(t, h2Mode, HandlerFunc(func(w ResponseWriter, r *Request) {}), optQuietLog) + defer cst.close() + + var brokenState brokenState + + const numReqs = 5 + var numDials, gotConns uint32 // atomic + + cst.tr.Dial = func(netw, addr string) (net.Conn, error) { + atomic.AddUint32(&numDials, 1) + c, err := net.Dial(netw, addr) + if err != nil { + t.Errorf("unexpected Dial error: %v", err) + return nil, err + } + return &breakableConn{c, &brokenState}, err + } + + for i := 1; i <= numReqs; i++ { + brokenState.Lock() + brokenState.broken = false + brokenState.Unlock() + + // doBreak controls whether we break the TCP connection after the TLS + // handshake (before the HTTP/2 handshake). We test a few failures + // in a row followed by a final success. + doBreak := i != numReqs + + ctx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{ + GotConn: func(info httptrace.GotConnInfo) { + t.Logf("got conn: %v, reused=%v, wasIdle=%v, idleTime=%v", info.Conn.LocalAddr(), info.Reused, info.WasIdle, info.IdleTime) + atomic.AddUint32(&gotConns, 1) + }, + TLSHandshakeDone: func(cfg tls.ConnectionState, err error) { + brokenState.Lock() + defer brokenState.Unlock() + if doBreak { + brokenState.broken = true + } + }, + }) + req, err := NewRequestWithContext(ctx, "GET", cst.ts.URL, nil) + if err != nil { + t.Fatal(err) + } + _, err = cst.c.Do(req) + if doBreak != (err != nil) { + t.Errorf("for iteration %d, doBreak=%v; unexpected error %v", i, doBreak, err) + } + } + if got, want := atomic.LoadUint32(&gotConns), 1; int(got) != want { + t.Errorf("GotConn calls = %v; want %v", got, want) + } + if got, want := atomic.LoadUint32(&numDials), numReqs; int(got) != want { + t.Errorf("Dials = %v; want %v", got, want) + } +} + +// Issue 34941 +// When the client has too many concurrent requests on a single connection, +// http.http2noCachedConnError is reported on multiple requests. There should +// only be one decrement regardless of the number of failures. +func TestTransportDecrementConnWhenIdleConnRemoved(t *testing.T) { + defer afterTest(t) + CondSkipHTTP2(t) + + h := HandlerFunc(func(w ResponseWriter, r *Request) { + _, err := w.Write([]byte("foo")) + if err != nil { + t.Fatalf("Write: %v", err) + } + }) + + ts := httptest.NewUnstartedServer(h) + ts.EnableHTTP2 = true + ts.StartTLS() + defer ts.Close() + + c := ts.Client() + tr := c.Transport.(*Transport) + tr.MaxConnsPerHost = 1 + if err := ExportHttp2ConfigureTransport(tr); err != nil { + t.Fatalf("ExportHttp2ConfigureTransport: %v", err) + } + + errCh := make(chan error, 300) + doReq := func() { + resp, err := c.Get(ts.URL) + if err != nil { + errCh <- fmt.Errorf("request failed: %v", err) + return + } + defer resp.Body.Close() + _, err = ioutil.ReadAll(resp.Body) + if err != nil { + errCh <- fmt.Errorf("read body failed: %v", err) + } + } + + var wg sync.WaitGroup + for i := 0; i < 300; i++ { + wg.Add(1) + go func() { + defer wg.Done() + doReq() + }() + } + wg.Wait() + close(errCh) + + for err := range errCh { + t.Errorf("error occurred: %v", err) + } +} diff --git a/libgo/go/net/interface.go b/libgo/go/net/interface.go index 58248560a25..914aaa010f3 100644 --- a/libgo/go/net/interface.go +++ b/libgo/go/net/interface.go @@ -10,7 +10,7 @@ import ( "time" ) -// BUG(mikio): On JS and NaCl, methods and functions related to +// BUG(mikio): On JS, methods and functions related to // Interface are not implemented. // BUG(mikio): On AIX, DragonFly BSD, NetBSD, OpenBSD, Plan 9 and diff --git a/libgo/go/net/interface_bsd_test.go b/libgo/go/net/interface_bsd_test.go new file mode 100644 index 00000000000..947dde71e61 --- /dev/null +++ b/libgo/go/net/interface_bsd_test.go @@ -0,0 +1,60 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd netbsd openbsd + +package net + +import ( + "errors" + "fmt" + "os/exec" + "runtime" +) + +func (ti *testInterface) setBroadcast(vid int) error { + if runtime.GOOS == "openbsd" { + ti.name = fmt.Sprintf("vether%d", vid) + } else { + ti.name = fmt.Sprintf("vlan%d", vid) + } + xname, err := exec.LookPath("ifconfig") + if err != nil { + return err + } + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ifconfig", ti.name, "create"}, + }) + ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ifconfig", ti.name, "destroy"}, + }) + return nil +} + +func (ti *testInterface) setPointToPoint(suffix int) error { + ti.name = fmt.Sprintf("gif%d", suffix) + xname, err := exec.LookPath("ifconfig") + if err != nil { + return err + } + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ifconfig", ti.name, "create"}, + }) + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ifconfig", ti.name, "inet", ti.local, ti.remote}, + }) + ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ifconfig", ti.name, "destroy"}, + }) + return nil +} + +func (ti *testInterface) setLinkLocal(suffix int) error { + return errors.New("not yet implemented for BSD") +} diff --git a/libgo/go/net/interface_linux_test.go b/libgo/go/net/interface_linux_test.go new file mode 100644 index 00000000000..0699fec6368 --- /dev/null +++ b/libgo/go/net/interface_linux_test.go @@ -0,0 +1,133 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +import ( + "fmt" + "os/exec" + "testing" +) + +func (ti *testInterface) setBroadcast(suffix int) error { + ti.name = fmt.Sprintf("gotest%d", suffix) + xname, err := exec.LookPath("ip") + if err != nil { + return err + } + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "link", "add", ti.name, "type", "dummy"}, + }) + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "address", "add", ti.local, "peer", ti.remote, "dev", ti.name}, + }) + ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "address", "del", ti.local, "peer", ti.remote, "dev", ti.name}, + }) + ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "link", "delete", ti.name, "type", "dummy"}, + }) + return nil +} + +func (ti *testInterface) setLinkLocal(suffix int) error { + ti.name = fmt.Sprintf("gotest%d", suffix) + xname, err := exec.LookPath("ip") + if err != nil { + return err + } + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "link", "add", ti.name, "type", "dummy"}, + }) + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "address", "add", ti.local, "dev", ti.name}, + }) + ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "address", "del", ti.local, "dev", ti.name}, + }) + ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "link", "delete", ti.name, "type", "dummy"}, + }) + return nil +} + +func (ti *testInterface) setPointToPoint(suffix int) error { + ti.name = fmt.Sprintf("gotest%d", suffix) + xname, err := exec.LookPath("ip") + if err != nil { + return err + } + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "tunnel", "add", ti.name, "mode", "gre", "local", ti.local, "remote", ti.remote}, + }) + ti.setupCmds = append(ti.setupCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "address", "add", ti.local, "peer", ti.remote, "dev", ti.name}, + }) + ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "address", "del", ti.local, "peer", ti.remote, "dev", ti.name}, + }) + ti.teardownCmds = append(ti.teardownCmds, &exec.Cmd{ + Path: xname, + Args: []string{"ip", "tunnel", "del", ti.name, "mode", "gre", "local", ti.local, "remote", ti.remote}, + }) + return nil +} + +const ( + numOfTestIPv4MCAddrs = 14 + numOfTestIPv6MCAddrs = 18 +) + +var ( + igmpInterfaceTable = []Interface{ + {Name: "lo"}, + {Name: "eth0"}, {Name: "eth1"}, {Name: "eth2"}, + {Name: "eth0.100"}, {Name: "eth0.101"}, {Name: "eth0.102"}, {Name: "eth0.103"}, + {Name: "device1tap2"}, + } + igmp6InterfaceTable = []Interface{ + {Name: "lo"}, + {Name: "eth0"}, {Name: "eth1"}, {Name: "eth2"}, + {Name: "eth0.100"}, {Name: "eth0.101"}, {Name: "eth0.102"}, {Name: "eth0.103"}, + {Name: "device1tap2"}, + {Name: "pan0"}, + } +) + +func TestParseProcNet(t *testing.T) { + defer func() { + if p := recover(); p != nil { + t.Fatalf("panicked: %v", p) + } + }() + + var ifmat4 []Addr + for _, ifi := range igmpInterfaceTable { + ifmat := parseProcNetIGMP("testdata/igmp", &ifi) + ifmat4 = append(ifmat4, ifmat...) + } + if len(ifmat4) != numOfTestIPv4MCAddrs { + t.Fatalf("got %d; want %d", len(ifmat4), numOfTestIPv4MCAddrs) + } + + var ifmat6 []Addr + for _, ifi := range igmp6InterfaceTable { + ifmat := parseProcNetIGMP6("testdata/igmp6", &ifi) + ifmat6 = append(ifmat6, ifmat...) + } + if len(ifmat6) != numOfTestIPv6MCAddrs { + t.Fatalf("got %d; want %d", len(ifmat6), numOfTestIPv6MCAddrs) + } +} diff --git a/libgo/go/net/interface_plan9.go b/libgo/go/net/interface_plan9.go index 8fe91384064..1295017a1b9 100644 --- a/libgo/go/net/interface_plan9.go +++ b/libgo/go/net/interface_plan9.go @@ -143,8 +143,8 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) { ifcs = []Interface{*ifi} } - addrs := make([]Addr, len(ifcs)) - for i, ifc := range ifcs { + var addrs []Addr + for _, ifc := range ifcs { status := ifc.Name + "/status" statusf, err := open(status) if err != nil { @@ -157,39 +157,36 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) { if _, ok := statusf.readLine(); !ok { return nil, errors.New("cannot read header line for interface: " + status) } - line, ok := statusf.readLine() - if !ok { - return nil, errors.New("cannot read IP address for interface: " + status) - } - // This assumes only a single address for the interface. - fields := getFields(line) - if len(fields) < 1 { - return nil, errors.New("cannot parse IP address for interface: " + status) - } - addr := fields[0] - ip := ParseIP(addr) - if ip == nil { - return nil, errors.New("cannot parse IP address for interface: " + status) - } + for line, ok := statusf.readLine(); ok; line, ok = statusf.readLine() { + fields := getFields(line) + if len(fields) < 1 { + return nil, errors.New("cannot parse IP address for interface: " + status) + } + addr := fields[0] + ip := ParseIP(addr) + if ip == nil { + return nil, errors.New("cannot parse IP address for interface: " + status) + } - // The mask is represented as CIDR relative to the IPv6 address. - // Plan 9 internal representation is always IPv6. - maskfld := fields[1] - maskfld = maskfld[1:] - pfxlen, _, ok := dtoi(maskfld) - if !ok { - return nil, errors.New("cannot parse network mask for interface: " + status) - } - var mask IPMask - if ip.To4() != nil { // IPv4 or IPv6 IPv4-mapped address - mask = CIDRMask(pfxlen-8*len(v4InV6Prefix), 8*IPv4len) - } - if ip.To16() != nil && ip.To4() == nil { // IPv6 address - mask = CIDRMask(pfxlen, 8*IPv6len) - } + // The mask is represented as CIDR relative to the IPv6 address. + // Plan 9 internal representation is always IPv6. + maskfld := fields[1] + maskfld = maskfld[1:] + pfxlen, _, ok := dtoi(maskfld) + if !ok { + return nil, errors.New("cannot parse network mask for interface: " + status) + } + var mask IPMask + if ip.To4() != nil { // IPv4 or IPv6 IPv4-mapped address + mask = CIDRMask(pfxlen-8*len(v4InV6Prefix), 8*IPv4len) + } + if ip.To16() != nil && ip.To4() == nil { // IPv6 address + mask = CIDRMask(pfxlen, 8*IPv6len) + } - addrs[i] = &IPNet{IP: ip, Mask: mask} + addrs = append(addrs, &IPNet{IP: ip, Mask: mask}) + } } return addrs, nil diff --git a/libgo/go/net/interface_stub.go b/libgo/go/net/interface_stub.go index d8afd5e7519..437b9ebb189 100644 --- a/libgo/go/net/interface_stub.go +++ b/libgo/go/net/interface_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build nacl hurd js,wasm +// +build hurd js,wasm package net diff --git a/libgo/go/net/interface_test.go b/libgo/go/net/interface_test.go index fb6032fbc06..b2ef21e8ac2 100644 --- a/libgo/go/net/interface_test.go +++ b/libgo/go/net/interface_test.go @@ -278,7 +278,7 @@ func checkUnicastStats(ifStats *ifStats, uniStats *routeStats) error { func checkMulticastStats(ifStats *ifStats, uniStats, multiStats *routeStats) error { switch runtime.GOOS { - case "aix", "dragonfly", "nacl", "netbsd", "openbsd", "plan9", "solaris", "illumos": + case "aix", "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "illumos": default: // Test the existence of connected multicast route // clones for IPv4. Unlike IPv6, IPv4 multicast diff --git a/libgo/go/net/interface_unix_test.go b/libgo/go/net/interface_unix_test.go new file mode 100644 index 00000000000..6a2b7f1a88b --- /dev/null +++ b/libgo/go/net/interface_unix_test.go @@ -0,0 +1,212 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd + +package net + +import ( + "fmt" + "os" + "os/exec" + "runtime" + "strings" + "testing" + "time" +) + +type testInterface struct { + name string + local string + remote string + setupCmds []*exec.Cmd + teardownCmds []*exec.Cmd +} + +func (ti *testInterface) setup() error { + for _, cmd := range ti.setupCmds { + if out, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("args=%v out=%q err=%v", cmd.Args, string(out), err) + } + } + return nil +} + +func (ti *testInterface) teardown() error { + for _, cmd := range ti.teardownCmds { + if out, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("args=%v out=%q err=%v ", cmd.Args, string(out), err) + } + } + return nil +} + +func TestPointToPointInterface(t *testing.T) { + if testing.Short() { + t.Skip("avoid external network") + } + if runtime.GOOS == "darwin" { + t.Skipf("not supported on %s", runtime.GOOS) + } + if os.Getuid() != 0 { + t.Skip("must be root") + } + + // We suppose that using IPv4 link-local addresses doesn't + // harm anyone. + local, remote := "169.254.0.1", "169.254.0.254" + ip := ParseIP(remote) + for i := 0; i < 3; i++ { + ti := &testInterface{local: local, remote: remote} + if err := ti.setPointToPoint(5963 + i); err != nil { + t.Skipf("test requires external command: %v", err) + } + if err := ti.setup(); err != nil { + if e := err.Error(); strings.Contains(e, "No such device") && strings.Contains(e, "gre0") { + t.Skip("skipping test; no gre0 device. likely running in container?") + } + t.Fatal(err) + } else { + time.Sleep(3 * time.Millisecond) + } + ift, err := Interfaces() + if err != nil { + ti.teardown() + t.Fatal(err) + } + for _, ifi := range ift { + if ti.name != ifi.Name { + continue + } + ifat, err := ifi.Addrs() + if err != nil { + ti.teardown() + t.Fatal(err) + } + for _, ifa := range ifat { + if ip.Equal(ifa.(*IPNet).IP) { + ti.teardown() + t.Fatalf("got %v", ifa) + } + } + } + if err := ti.teardown(); err != nil { + t.Fatal(err) + } else { + time.Sleep(3 * time.Millisecond) + } + } +} + +func TestInterfaceArrivalAndDeparture(t *testing.T) { + if testing.Short() { + t.Skip("avoid external network") + } + if os.Getuid() != 0 { + t.Skip("must be root") + } + + // We suppose that using IPv4 link-local addresses and the + // dot1Q ID for Token Ring and FDDI doesn't harm anyone. + local, remote := "169.254.0.1", "169.254.0.254" + ip := ParseIP(remote) + for _, vid := range []int{1002, 1003, 1004, 1005} { + ift1, err := Interfaces() + if err != nil { + t.Fatal(err) + } + ti := &testInterface{local: local, remote: remote} + if err := ti.setBroadcast(vid); err != nil { + t.Skipf("test requires external command: %v", err) + } + if err := ti.setup(); err != nil { + t.Fatal(err) + } else { + time.Sleep(3 * time.Millisecond) + } + ift2, err := Interfaces() + if err != nil { + ti.teardown() + t.Fatal(err) + } + if len(ift2) <= len(ift1) { + for _, ifi := range ift1 { + t.Logf("before: %v", ifi) + } + for _, ifi := range ift2 { + t.Logf("after: %v", ifi) + } + ti.teardown() + t.Fatalf("got %v; want gt %v", len(ift2), len(ift1)) + } + for _, ifi := range ift2 { + if ti.name != ifi.Name { + continue + } + ifat, err := ifi.Addrs() + if err != nil { + ti.teardown() + t.Fatal(err) + } + for _, ifa := range ifat { + if ip.Equal(ifa.(*IPNet).IP) { + ti.teardown() + t.Fatalf("got %v", ifa) + } + } + } + if err := ti.teardown(); err != nil { + t.Fatal(err) + } else { + time.Sleep(3 * time.Millisecond) + } + ift3, err := Interfaces() + if err != nil { + t.Fatal(err) + } + if len(ift3) >= len(ift2) { + for _, ifi := range ift2 { + t.Logf("before: %v", ifi) + } + for _, ifi := range ift3 { + t.Logf("after: %v", ifi) + } + t.Fatalf("got %v; want lt %v", len(ift3), len(ift2)) + } + } +} + +func TestInterfaceArrivalAndDepartureZoneCache(t *testing.T) { + if testing.Short() { + t.Skip("avoid external network") + } + if os.Getuid() != 0 { + t.Skip("must be root") + } + + // Ensure zoneCache is filled: + _, _ = Listen("tcp", "[fe80::1%nonexistent]:0") + + ti := &testInterface{local: "fe80::1"} + if err := ti.setLinkLocal(0); err != nil { + t.Skipf("test requires external command: %v", err) + } + if err := ti.setup(); err != nil { + t.Fatal(err) + } + defer ti.teardown() + + time.Sleep(3 * time.Millisecond) + + // If Listen fails (on Linux with “bind: invalid argument”), zoneCache was + // not updated when encountering a nonexistent interface: + ln, err := Listen("tcp", "[fe80::1%"+ti.name+"]:0") + if err != nil { + t.Fatal(err) + } + ln.Close() + if err := ti.teardown(); err != nil { + t.Fatal(err) + } +} diff --git a/libgo/go/net/interface_windows.go b/libgo/go/net/interface_windows.go index 28b0a65f665..544943278dc 100644 --- a/libgo/go/net/interface_windows.go +++ b/libgo/go/net/interface_windows.go @@ -58,7 +58,7 @@ func interfaceTable(ifindex int) ([]Interface, error) { if ifindex == 0 || ifindex == int(index) { ifi := Interface{ Index: int(index), - Name: syscall.UTF16ToString((*(*[10000]uint16)(unsafe.Pointer(aa.FriendlyName)))[:]), + Name: windows.UTF16PtrToString(aa.FriendlyName, 10000), } if aa.OperStatus == windows.IfOperStatusUp { ifi.Flags |= FlagUp diff --git a/libgo/go/net/internal/socktest/switch_unix.go b/libgo/go/net/internal/socktest/switch_unix.go index 29959134b32..4c037baec0c 100644 --- a/libgo/go/net/internal/socktest/switch_unix.go +++ b/libgo/go/net/internal/socktest/switch_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package socktest diff --git a/libgo/go/net/internal/socktest/sys_unix.go b/libgo/go/net/internal/socktest/sys_unix.go index 81c7fb6711e..fbbffc6eaba 100644 --- a/libgo/go/net/internal/socktest/sys_unix.go +++ b/libgo/go/net/internal/socktest/sys_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package socktest diff --git a/libgo/go/net/ip.go b/libgo/go/net/ip.go index 1a1d0e7dba4..9d1223e705e 100644 --- a/libgo/go/net/ip.go +++ b/libgo/go/net/ip.go @@ -31,7 +31,10 @@ const ( // be an IPv4 address. type IP []byte -// An IP mask is an IP address. +// An IPMask is a bitmask that can be used to manipulate +// IP addresses for IP addressing and routing. +// +// See type IPNet and func ParseCIDR for details. type IPMask []byte // An IPNet represents an IP network. @@ -65,8 +68,8 @@ func IPv4Mask(a, b, c, d byte) IPMask { return p } -// CIDRMask returns an IPMask consisting of `ones' 1 bits -// followed by 0s up to a total length of `bits' bits. +// CIDRMask returns an IPMask consisting of 'ones' 1 bits +// followed by 0s up to a total length of 'bits' bits. // For a mask of this form, CIDRMask is the inverse of IPMask.Size. func CIDRMask(ones, bits int) IPMask { if bits != 8*IPv4len && bits != 8*IPv6len { diff --git a/libgo/go/net/iprawsock.go b/libgo/go/net/iprawsock.go index 8a9c26559bd..f18331a1fd5 100644 --- a/libgo/go/net/iprawsock.go +++ b/libgo/go/net/iprawsock.go @@ -21,7 +21,7 @@ import ( // change the behavior of these methods; use Read or ReadMsgIP // instead. -// BUG(mikio): On JS, NaCl and Plan 9, methods and functions related +// BUG(mikio): On JS and Plan 9, methods and functions related // to IPConn are not implemented. // BUG(mikio): On Windows, the File method of IPConn is not diff --git a/libgo/go/net/iprawsock_posix.go b/libgo/go/net/iprawsock_posix.go index a14c629c01d..fdb39135be9 100644 --- a/libgo/go/net/iprawsock_posix.go +++ b/libgo/go/net/iprawsock_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package net diff --git a/libgo/go/net/ipsock_plan9.go b/libgo/go/net/ipsock_plan9.go index d226585e086..93f0f4eec36 100644 --- a/libgo/go/net/ipsock_plan9.go +++ b/libgo/go/net/ipsock_plan9.go @@ -227,7 +227,7 @@ func listenPlan9(ctx context.Context, net string, laddr Addr) (fd *netFD, err er _, err = f.WriteString("announce " + dest) if err != nil { f.Close() - return nil, err + return nil, &OpError{Op: "announce", Net: net, Source: laddr, Addr: nil, Err: err} } laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local") if err != nil { diff --git a/libgo/go/net/ipsock_posix.go b/libgo/go/net/ipsock_posix.go index 5bf534276ad..84e72d52549 100644 --- a/libgo/go/net/ipsock_posix.go +++ b/libgo/go/net/ipsock_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package net @@ -134,7 +134,7 @@ func favoriteAddrFamily(network string, laddr, raddr sockaddr, mode string) (fam } func internetSocket(ctx context.Context, net string, laddr, raddr sockaddr, sotype, proto int, mode string, ctrlFn func(string, string, syscall.RawConn) error) (fd *netFD, err error) { - if (runtime.GOOS == "aix" || runtime.GOOS == "windows" || runtime.GOOS == "openbsd" || runtime.GOOS == "nacl") && mode == "dial" && raddr.isWildcard() { + if (runtime.GOOS == "aix" || runtime.GOOS == "windows" || runtime.GOOS == "openbsd") && mode == "dial" && raddr.isWildcard() { raddr = raddr.toLocal(net) } family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode) @@ -162,7 +162,7 @@ func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, e // of IP node. // // When the IP node supports IPv4-mapped IPv6 address, - // we allow an listener to listen to the wildcard + // we allow a listener to listen to the wildcard // address of both IP addressing spaces by specifying // IPv6 wildcard address. if len(ip) == 0 || ip.Equal(IPv4zero) { diff --git a/libgo/go/net/listen_test.go b/libgo/go/net/listen_test.go index fef2b6405fa..d8c72096ed1 100644 --- a/libgo/go/net/listen_test.go +++ b/libgo/go/net/listen_test.go @@ -224,7 +224,7 @@ var dualStackTCPListenerTests = []struct { // to be greater than or equal to 4.4. func TestDualStackTCPListener(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv4() || !supportsIPv6() { @@ -314,7 +314,7 @@ var dualStackUDPListenerTests = []struct { // to be greater than or equal to 4.4. func TestDualStackUDPListener(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } if !supportsIPv4() || !supportsIPv6() { @@ -532,7 +532,7 @@ func TestIPv4MulticastListener(t *testing.T) { testenv.MustHaveExternalNetwork(t) switch runtime.GOOS { - case "android", "nacl", "plan9": + case "android", "plan9": t.Skipf("not supported on %s", runtime.GOOS) case "solaris", "illumos": t.Skipf("not supported on solaris or illumos, see golang.org/issue/7399") @@ -733,7 +733,7 @@ func TestClosingListener(t *testing.T) { func TestListenConfigControl(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/libgo/go/net/lookup.go b/libgo/go/net/lookup.go index 24d0d25c3a2..9cebd10c87a 100644 --- a/libgo/go/net/lookup.go +++ b/libgo/go/net/lookup.go @@ -27,8 +27,7 @@ var protocols = map[string]int{ } // services contains minimal mappings between services names and port -// numbers for platforms that don't have a complete list of port numbers -// (some Solaris distros, nacl, etc). +// numbers for platforms that don't have a complete list of port numbers. // // See https://www.iana.org/assignments/service-names-port-numbers // diff --git a/libgo/go/net/lookup_fake.go b/libgo/go/net/lookup_fake.go index 6c8a151bcac..3b3c39bc7da 100644 --- a/libgo/go/net/lookup_fake.go +++ b/libgo/go/net/lookup_fake.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build nacl js,wasm +// +build js,wasm package net diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go index dd599c7c1c2..8a41510daf3 100644 --- a/libgo/go/net/lookup_test.go +++ b/libgo/go/net/lookup_test.go @@ -21,6 +21,10 @@ import ( "time" ) +func hasSuffixFold(s, suffix string) bool { + return strings.HasSuffix(strings.ToLower(s), strings.ToLower(suffix)) +} + func lookupLocalhost(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) { switch host { case "localhost": @@ -97,11 +101,11 @@ func TestLookupGoogleSRV(t *testing.T) { if len(srvs) == 0 { t.Error("got no record") } - if !strings.HasSuffix(cname, tt.cname) { + if !hasSuffixFold(cname, tt.cname) { t.Errorf("got %s; want %s", cname, tt.cname) } for _, srv := range srvs { - if !strings.HasSuffix(srv.Target, tt.target) { + if !hasSuffixFold(srv.Target, tt.target) { t.Errorf("got %v; want a record containing %s", srv, tt.target) } } @@ -147,7 +151,7 @@ func TestLookupGmailMX(t *testing.T) { t.Error("got no record") } for _, mx := range mxs { - if !strings.HasSuffix(mx.Host, tt.host) { + if !hasSuffixFold(mx.Host, tt.host) { t.Errorf("got %v; want a record containing %s", mx, tt.host) } } @@ -193,7 +197,7 @@ func TestLookupGmailNS(t *testing.T) { t.Error("got no record") } for _, ns := range nss { - if !strings.HasSuffix(ns.Host, tt.host) { + if !hasSuffixFold(ns.Host, tt.host) { t.Errorf("got %v; want a record containing %s", ns, tt.host) } } @@ -279,7 +283,7 @@ func TestLookupGooglePublicDNSAddr(t *testing.T) { t.Error("got no record") } for _, name := range names { - if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") { + if !hasSuffixFold(name, ".google.com.") && !hasSuffixFold(name, ".google.") { t.Errorf("got %q; want a record ending in .google.com. or .google.", name) } } @@ -371,7 +375,7 @@ func TestLookupCNAME(t *testing.T) { } t.Fatal(err) } - if !strings.HasSuffix(cname, tt.cname) { + if !hasSuffixFold(cname, tt.cname) { t.Errorf("got %s; want a record containing %s", cname, tt.cname) } } @@ -656,7 +660,7 @@ func testDots(t *testing.T, mode string) { t.Errorf("LookupAddr(8.8.8.8): %v (mode=%v)", err, mode) } else { for _, name := range names { - if !strings.HasSuffix(name, ".google.com.") && !strings.HasSuffix(name, ".google.") { + if !hasSuffixFold(name, ".google.com.") && !hasSuffixFold(name, ".google.") { t.Errorf("LookupAddr(8.8.8.8) = %v, want names ending in .google.com or .google with trailing dot (mode=%v)", names, mode) break } @@ -677,7 +681,7 @@ func testDots(t *testing.T, mode string) { t.Errorf("LookupMX(google.com): %v (mode=%v)", err, mode) } else { for _, mx := range mxs { - if !strings.HasSuffix(mx.Host, ".google.com.") { + if !hasSuffixFold(mx.Host, ".google.com.") { t.Errorf("LookupMX(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)", mxString(mxs), mode) break } @@ -690,7 +694,7 @@ func testDots(t *testing.T, mode string) { t.Errorf("LookupNS(google.com): %v (mode=%v)", err, mode) } else { for _, ns := range nss { - if !strings.HasSuffix(ns.Host, ".google.com.") { + if !hasSuffixFold(ns.Host, ".google.com.") { t.Errorf("LookupNS(google.com) = %v, want names ending in .google.com. with trailing dot (mode=%v)", nsString(nss), mode) break } @@ -702,11 +706,11 @@ func testDots(t *testing.T, mode string) { testenv.SkipFlakyNet(t) t.Errorf("LookupSRV(xmpp-server, tcp, google.com): %v (mode=%v)", err, mode) } else { - if !strings.HasSuffix(cname, ".google.com.") { + if !hasSuffixFold(cname, ".google.com.") { t.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned cname=%v, want name ending in .google.com. with trailing dot (mode=%v)", cname, mode) } for _, srv := range srvs { - if !strings.HasSuffix(srv.Target, ".google.com.") { + if !hasSuffixFold(srv.Target, ".google.com.") { t.Errorf("LookupSRV(xmpp-server, tcp, google.com) returned addrs=%v, want names ending in .google.com. with trailing dot (mode=%v)", srvString(srvs), mode) break } @@ -856,10 +860,6 @@ func TestLookupProtocol_Minimal(t *testing.T) { } func TestLookupNonLDH(t *testing.T) { - if runtime.GOOS == "nacl" { - t.Skip("skip on nacl") - } - defer dnsWaitGroup.Wait() if fixup := forceGoDNS(); fixup != nil { @@ -884,10 +884,6 @@ func TestLookupNonLDH(t *testing.T) { func TestLookupContextCancel(t *testing.T) { mustHaveExternalNetwork(t) - if runtime.GOOS == "nacl" { - t.Skip("skip on nacl") - } - defer dnsWaitGroup.Wait() ctx, ctxCancel := context.WithCancel(context.Background()) @@ -909,9 +905,6 @@ func TestLookupContextCancel(t *testing.T) { // crashes if nil is used. func TestNilResolverLookup(t *testing.T) { mustHaveExternalNetwork(t) - if runtime.GOOS == "nacl" { - t.Skip("skip on nacl") - } var r *Resolver = nil ctx := context.Background() @@ -931,10 +924,6 @@ func TestNilResolverLookup(t *testing.T) { // canceled lookups (see golang.org/issue/24178 for details). func TestLookupHostCancel(t *testing.T) { mustHaveExternalNetwork(t) - if runtime.GOOS == "nacl" { - t.Skip("skip on nacl") - } - const ( google = "www.google.com" invalidDomain = "invalid.invalid" // RFC 2606 reserves .invalid @@ -983,10 +972,11 @@ func (lcr *lookupCustomResolver) dial() func(ctx context.Context, network, addre // TestConcurrentPreferGoResolversDial tests that multiple resolvers with the // PreferGo option used concurrently are all dialed properly. func TestConcurrentPreferGoResolversDial(t *testing.T) { - // The windows implementation of the resolver does not use the Dial - // function. - if runtime.GOOS == "windows" { - t.Skip("skip on windows") + // The windows and plan9 implementation of the resolver does not use + // the Dial function. + switch runtime.GOOS { + case "windows", "plan9": + t.Skipf("skip on %v", runtime.GOOS) } testenv.MustHaveExternalNetwork(t) diff --git a/libgo/go/net/lookup_windows.go b/libgo/go/net/lookup_windows.go index d7b28f5e185..7d5c9419566 100644 --- a/libgo/go/net/lookup_windows.go +++ b/libgo/go/net/lookup_windows.go @@ -6,6 +6,7 @@ package net import ( "context" + "internal/syscall/windows" "os" "runtime" "syscall" @@ -233,7 +234,7 @@ func (*Resolver) lookupCNAME(ctx context.Context, name string) (string, error) { defer syscall.DnsRecordListFree(r, 1) resolved := resolveCNAME(syscall.StringToUTF16Ptr(name), r) - cname := syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(resolved))[:]) + cname := windows.UTF16PtrToString(resolved, 256) return absDomainName([]byte(cname)), nil } @@ -277,7 +278,7 @@ func (*Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) { mxs := make([]*MX, 0, 10) for _, p := range validRecs(r, syscall.DNS_TYPE_MX, name) { v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0])) - mxs = append(mxs, &MX{absDomainName([]byte(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.NameExchange))[:]))), v.Preference}) + mxs = append(mxs, &MX{absDomainName([]byte(windows.UTF16PtrToString(v.NameExchange, 256))), v.Preference}) } byPref(mxs).sort() return mxs, nil @@ -317,8 +318,8 @@ func (*Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) { for _, p := range validRecs(r, syscall.DNS_TYPE_TEXT, name) { d := (*syscall.DNSTXTData)(unsafe.Pointer(&p.Data[0])) s := "" - for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount] { - s += syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(v))[:]) + for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount:d.StringCount] { + s += windows.UTF16PtrToString(v, 1<<20) } txts = append(txts, s) } @@ -343,7 +344,7 @@ func (*Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) ptrs := make([]string, 0, 10) for _, p := range validRecs(r, syscall.DNS_TYPE_PTR, arpa) { v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0])) - ptrs = append(ptrs, absDomainName([]byte(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:])))) + ptrs = append(ptrs, absDomainName([]byte(windows.UTF16PtrToString(v.Host, 256)))) } return ptrs, nil } @@ -358,7 +359,8 @@ func validRecs(r *syscall.DNSRecord, dnstype uint16, name string) []*syscall.DNS } rec := make([]*syscall.DNSRecord, 0, 10) for p := r; p != nil; p = p.Next { - if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer { + // in case of a local machine, DNS records are returned with DNSREC_QUESTION flag instead of DNS_ANSWER + if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer && p.Dw&dnsSectionMask != syscall.DnsSectionQuestion { continue } if p.Type != dnstype { @@ -374,7 +376,7 @@ func validRecs(r *syscall.DNSRecord, dnstype uint16, name string) []*syscall.DNS // returns the last CNAME in chain func resolveCNAME(name *uint16, r *syscall.DNSRecord) *uint16 { - // limit cname resolving to 10 in case of a infinite CNAME loop + // limit cname resolving to 10 in case of an infinite CNAME loop Cname: for cnameloop := 0; cnameloop < 10; cnameloop++ { for p := r; p != nil; p = p.Next { diff --git a/libgo/go/net/lookup_windows_test.go b/libgo/go/net/lookup_windows_test.go new file mode 100644 index 00000000000..62b61ed6c2f --- /dev/null +++ b/libgo/go/net/lookup_windows_test.go @@ -0,0 +1,317 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "internal/testenv" + "os/exec" + "reflect" + "regexp" + "sort" + "strings" + "testing" +) + +var nslookupTestServers = []string{"mail.golang.com", "gmail.com"} +var lookupTestIPs = []string{"8.8.8.8", "1.1.1.1"} + +func toJson(v interface{}) string { + data, _ := json.Marshal(v) + return string(data) +} + +func TestNSLookupMX(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + for _, server := range nslookupTestServers { + mx, err := LookupMX(server) + if err != nil { + t.Error(err) + continue + } + if len(mx) == 0 { + t.Errorf("no results") + continue + } + expected, err := nslookupMX(server) + if err != nil { + t.Logf("skipping failed nslookup %s test: %s", server, err) + } + sort.Sort(byPrefAndHost(expected)) + sort.Sort(byPrefAndHost(mx)) + if !reflect.DeepEqual(expected, mx) { + t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(mx)) + } + } +} + +func TestNSLookupCNAME(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + for _, server := range nslookupTestServers { + cname, err := LookupCNAME(server) + if err != nil { + t.Errorf("failed %s: %s", server, err) + continue + } + if cname == "" { + t.Errorf("no result %s", server) + } + expected, err := nslookupCNAME(server) + if err != nil { + t.Logf("skipping failed nslookup %s test: %s", server, err) + continue + } + if expected != cname { + t.Errorf("different results %s:\texp:%v\tgot:%v", server, expected, cname) + } + } +} + +func TestNSLookupNS(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + for _, server := range nslookupTestServers { + ns, err := LookupNS(server) + if err != nil { + t.Errorf("failed %s: %s", server, err) + continue + } + if len(ns) == 0 { + t.Errorf("no results") + continue + } + expected, err := nslookupNS(server) + if err != nil { + t.Logf("skipping failed nslookup %s test: %s", server, err) + continue + } + sort.Sort(byHost(expected)) + sort.Sort(byHost(ns)) + if !reflect.DeepEqual(expected, ns) { + t.Errorf("different results %s:\texp:%v\tgot:%v", toJson(server), toJson(expected), ns) + } + } +} + +func TestNSLookupTXT(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + for _, server := range nslookupTestServers { + txt, err := LookupTXT(server) + if err != nil { + t.Errorf("failed %s: %s", server, err) + continue + } + if len(txt) == 0 { + t.Errorf("no results") + continue + } + expected, err := nslookupTXT(server) + if err != nil { + t.Logf("skipping failed nslookup %s test: %s", server, err) + continue + } + sort.Strings(expected) + sort.Strings(txt) + if !reflect.DeepEqual(expected, txt) { + t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(txt)) + } + } +} + +func TestLookupLocalPTR(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + addr, err := localIP() + if err != nil { + t.Errorf("failed to get local ip: %s", err) + } + names, err := LookupAddr(addr.String()) + if err != nil { + t.Errorf("failed %s: %s", addr, err) + } + if len(names) == 0 { + t.Errorf("no results") + } + expected, err := lookupPTR(addr.String()) + if err != nil { + t.Logf("skipping failed lookup %s test: %s", addr.String(), err) + } + sort.Strings(expected) + sort.Strings(names) + if !reflect.DeepEqual(expected, names) { + t.Errorf("different results %s:\texp:%v\tgot:%v", addr, toJson(expected), toJson(names)) + } +} + +func TestLookupPTR(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + for _, addr := range lookupTestIPs { + names, err := LookupAddr(addr) + if err != nil { + t.Errorf("failed %s: %s", addr, err) + } + if len(names) == 0 { + t.Errorf("no results") + } + expected, err := lookupPTR(addr) + if err != nil { + t.Logf("skipping failed lookup %s test: %s", addr, err) + } + sort.Strings(expected) + sort.Strings(names) + if !reflect.DeepEqual(expected, names) { + t.Errorf("different results %s:\texp:%v\tgot:%v", addr, toJson(expected), toJson(names)) + } + } +} + +type byPrefAndHost []*MX + +func (s byPrefAndHost) Len() int { return len(s) } +func (s byPrefAndHost) Less(i, j int) bool { + if s[i].Pref != s[j].Pref { + return s[i].Pref < s[j].Pref + } + return s[i].Host < s[j].Host +} +func (s byPrefAndHost) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +type byHost []*NS + +func (s byHost) Len() int { return len(s) } +func (s byHost) Less(i, j int) bool { return s[i].Host < s[j].Host } +func (s byHost) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func nslookup(qtype, name string) (string, error) { + var out bytes.Buffer + var err bytes.Buffer + cmd := exec.Command("nslookup", "-querytype="+qtype, name) + cmd.Stdout = &out + cmd.Stderr = &err + if err := cmd.Run(); err != nil { + return "", err + } + r := strings.ReplaceAll(out.String(), "\r\n", "\n") + // nslookup stderr output contains also debug information such as + // "Non-authoritative answer" and it doesn't return the correct errcode + if strings.Contains(err.String(), "can't find") { + return r, errors.New(err.String()) + } + return r, nil +} + +func nslookupMX(name string) (mx []*MX, err error) { + var r string + if r, err = nslookup("mx", name); err != nil { + return + } + mx = make([]*MX, 0, 10) + // linux nslookup syntax + // golang.org mail exchanger = 2 alt1.aspmx.l.google.com. + rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+mail exchanger\s*=\s*([0-9]+)\s*([a-z0-9.\-]+)$`) + for _, ans := range rx.FindAllStringSubmatch(r, -1) { + pref, _, _ := dtoi(ans[2]) + mx = append(mx, &MX{absDomainName([]byte(ans[3])), uint16(pref)}) + } + // windows nslookup syntax + // gmail.com MX preference = 30, mail exchanger = alt3.gmail-smtp-in.l.google.com + rx = regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+MX preference\s*=\s*([0-9]+)\s*,\s*mail exchanger\s*=\s*([a-z0-9.\-]+)$`) + for _, ans := range rx.FindAllStringSubmatch(r, -1) { + pref, _, _ := dtoi(ans[2]) + mx = append(mx, &MX{absDomainName([]byte(ans[3])), uint16(pref)}) + } + return +} + +func nslookupNS(name string) (ns []*NS, err error) { + var r string + if r, err = nslookup("ns", name); err != nil { + return + } + ns = make([]*NS, 0, 10) + // golang.org nameserver = ns1.google.com. + rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+nameserver\s*=\s*([a-z0-9.\-]+)$`) + for _, ans := range rx.FindAllStringSubmatch(r, -1) { + ns = append(ns, &NS{absDomainName([]byte(ans[2]))}) + } + return +} + +func nslookupCNAME(name string) (cname string, err error) { + var r string + if r, err = nslookup("cname", name); err != nil { + return + } + // mail.golang.com canonical name = golang.org. + rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+canonical name\s*=\s*([a-z0-9.\-]+)$`) + // assumes the last CNAME is the correct one + last := name + for _, ans := range rx.FindAllStringSubmatch(r, -1) { + last = ans[2] + } + return absDomainName([]byte(last)), nil +} + +func nslookupTXT(name string) (txt []string, err error) { + var r string + if r, err = nslookup("txt", name); err != nil { + return + } + txt = make([]string, 0, 10) + // linux + // golang.org text = "v=spf1 redirect=_spf.google.com" + + // windows + // golang.org text = + // + // "v=spf1 redirect=_spf.google.com" + rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+text\s*=\s*"(.*)"$`) + for _, ans := range rx.FindAllStringSubmatch(r, -1) { + txt = append(txt, ans[2]) + } + return +} + +func ping(name string) (string, error) { + cmd := exec.Command("ping", "-n", "1", "-a", name) + stdoutStderr, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("%v: %v", err, string(stdoutStderr)) + } + r := strings.ReplaceAll(string(stdoutStderr), "\r\n", "\n") + return r, nil +} + +func lookupPTR(name string) (ptr []string, err error) { + var r string + if r, err = ping(name); err != nil { + return + } + ptr = make([]string, 0, 10) + rx := regexp.MustCompile(`(?m)^Pinging\s+([a-zA-Z0-9.\-]+)\s+\[.*$`) + for _, ans := range rx.FindAllStringSubmatch(r, -1) { + ptr = append(ptr, ans[1]+".") + } + return +} + +func localIP() (ip IP, err error) { + conn, err := Dial("udp", "golang.org:80") + if err != nil { + return nil, err + } + defer conn.Close() + + localAddr := conn.LocalAddr().(*UDPAddr) + + return localAddr.IP, nil +} diff --git a/libgo/go/net/mail/message.go b/libgo/go/net/mail/message.go index 75207db4342..0781310ed3f 100644 --- a/libgo/go/net/mail/message.go +++ b/libgo/go/net/mail/message.go @@ -79,7 +79,7 @@ func buildDateLayouts() { years := [...]string{"2006", "06"} // year = 4*DIGIT / 2*DIGIT seconds := [...]string{":05", ""} // second // "-0700 (MST)" is not in RFC 5322, but is common. - zones := [...]string{"-0700", "MST", "-0700 (MST)"} // zone = (("+" / "-") 4DIGIT) / "GMT" / ... + zones := [...]string{"-0700", "MST"} // zone = (("+" / "-") 4DIGIT) / "GMT" / ... for _, dow := range dows { for _, day := range days { @@ -98,6 +98,29 @@ func buildDateLayouts() { // ParseDate parses an RFC 5322 date string. func ParseDate(date string) (time.Time, error) { dateLayoutsBuildOnce.Do(buildDateLayouts) + // CR and LF must match and are tolerated anywhere in the date field. + date = strings.ReplaceAll(date, "\r\n", "") + if strings.Index(date, "\r") != -1 { + return time.Time{}, errors.New("mail: header has a CR without LF") + } + // Re-using some addrParser methods which support obsolete text, i.e. non-printable ASCII + p := addrParser{date, nil} + p.skipSpace() + + // RFC 5322: zone = (FWS ( "+" / "-" ) 4DIGIT) / obs-zone + // zone length is always 5 chars unless obsolete (obs-zone) + if ind := strings.IndexAny(p.s, "+-"); ind != -1 && len(p.s) >= ind+5 { + date = p.s[:ind+5] + p.s = p.s[ind+5:] + } else if ind := strings.Index(p.s, "T"); ind != -1 && len(p.s) >= ind+1 { + // The last letter T of the obsolete time zone is checked when no standard time zone is found. + // If T is misplaced, the date to parse is garbage. + date = p.s[:ind+1] + p.s = p.s[ind+1:] + } + if !p.skipCFWS() { + return time.Time{}, errors.New("mail: misformatted parenthetical comment") + } for _, layout := range dateLayouts { t, err := time.Parse(layout, date) if err == nil { diff --git a/libgo/go/net/mail/message_test.go b/libgo/go/net/mail/message_test.go index 2950bc4de92..acab538e18b 100644 --- a/libgo/go/net/mail/message_test.go +++ b/libgo/go/net/mail/message_test.go @@ -124,6 +124,157 @@ func TestDateParsing(t *testing.T) { } } +func TestDateParsingCFWS(t *testing.T) { + tests := []struct { + dateStr string + exp time.Time + valid bool + }{ + // FWS-only. No date. + { + " ", + // nil is not allowed + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, + }, + // FWS is allowed before optional day of week. + { + " Fri, 21 Nov 1997 09:55:06 -0600", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + true, + }, + { + "21 Nov 1997 09:55:06 -0600", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + true, + }, + { + "Fri 21 Nov 1997 09:55:06 -0600", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, // missing , + }, + // FWS is allowed before day of month but HTAB fails. + { + "Fri, 21 Nov 1997 09:55:06 -0600", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + true, + }, + // FWS is allowed before and after year but HTAB fails. + { + "Fri, 21 Nov 1997 09:55:06 -0600", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + true, + }, + // FWS is allowed before zone but HTAB is not handled. Obsolete timezone is handled. + { + "Fri, 21 Nov 1997 09:55:06 CST", + time.Time{}, + true, + }, + // FWS is allowed after date and a CRLF is already replaced. + { + "Fri, 21 Nov 1997 09:55:06 CST (no leading FWS and a trailing CRLF) \r\n", + time.Time{}, + true, + }, + // CFWS is a reduced set of US-ASCII where space and accentuated are obsolete. No error. + { + "Fri, 21 Nov 1997 09:55:06 -0600 (MDT and non-US-ASCII signs éèç )", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + true, + }, + // CFWS is allowed after zone including a nested comment. + // Trailing FWS is allowed. + { + "Fri, 21 Nov 1997 09:55:06 -0600 \r\n (thisisa(valid)cfws) \t ", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + true, + }, + // CRLF is incomplete and misplaced. + { + "Fri, 21 Nov 1997 \r 09:55:06 -0600 \r\n (thisisa(valid)cfws) \t ", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, + }, + // CRLF is complete but misplaced. No error is returned. + { + "Fri, 21 Nov 199\r\n7 09:55:06 -0600 \r\n (thisisa(valid)cfws) \t ", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + true, // should be false in the strict interpretation of RFC 5322. + }, + // Invalid ASCII in date. + { + "Fri, 21 Nov 1997 ù 09:55:06 -0600 \r\n (thisisa(valid)cfws) \t ", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, + }, + // CFWS chars () in date. + { + "Fri, 21 Nov () 1997 09:55:06 -0600 \r\n (thisisa(valid)cfws) \t ", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, + }, + // Timezone is invalid but T is found in comment. + { + "Fri, 21 Nov 1997 09:55:06 -060 \r\n (Thisisa(valid)cfws) \t ", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, + }, + // Date has no month. + { + "Fri, 21 1997 09:55:06 -0600", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, + }, + // Invalid month : OCT iso Oct + { + "Fri, 21 OCT 1997 09:55:06 CST", + time.Time{}, + false, + }, + // A too short time zone. + { + "Fri, 21 Nov 1997 09:55:06 -060", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, + }, + // A too short obsolete time zone. + { + "Fri, 21 1997 09:55:06 GT", + time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)), + false, + }, + } + for _, test := range tests { + hdr := Header{ + "Date": []string{test.dateStr}, + } + date, err := hdr.Date() + if err != nil && test.valid { + t.Errorf("Header(Date: %s).Date(): %v", test.dateStr, err) + } else if err == nil && test.exp.IsZero() { + // OK. Used when exact result depends on the + // system's local zoneinfo. + } else if err == nil && !date.Equal(test.exp) && test.valid { + t.Errorf("Header(Date: %s).Date() = %+v, want %+v", test.dateStr, date, test.exp) + } else if err == nil && !test.valid { // an invalid expression was tested + t.Errorf("Header(Date: %s).Date() did not return an error but %v", test.dateStr, date) + } + + date, err = ParseDate(test.dateStr) + if err != nil && test.valid { + t.Errorf("ParseDate(%s): %v", test.dateStr, err) + } else if err == nil && test.exp.IsZero() { + // OK. Used when exact result depends on the + // system's local zoneinfo. + } else if err == nil && !test.valid { // an invalid expression was tested + t.Errorf("ParseDate(%s) did not return an error but %v", test.dateStr, date) + } else if err == nil && test.valid && !date.Equal(test.exp) { + t.Errorf("ParseDate(%s) = %+v, want %+v", test.dateStr, date, test.exp) + } + } +} + func TestAddressParsingError(t *testing.T) { mustErrTestCases := [...]struct { text string diff --git a/libgo/go/net/main_conf_test.go b/libgo/go/net/main_conf_test.go index b535046bda1..a92dff56c2a 100644 --- a/libgo/go/net/main_conf_test.go +++ b/libgo/go/net/main_conf_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !js,!nacl,!plan9,!windows +// +build !js,!plan9,!windows package net diff --git a/libgo/go/net/main_noconf_test.go b/libgo/go/net/main_noconf_test.go index 55e37708354..bac84aa3002 100644 --- a/libgo/go/net/main_noconf_test.go +++ b/libgo/go/net/main_noconf_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build js,wasm nacl plan9 windows +// +build js,wasm plan9 windows package net diff --git a/libgo/go/net/main_unix_test.go b/libgo/go/net/main_unix_test.go index af9f2d43726..ef7e915aa60 100644 --- a/libgo/go/net/main_unix_test.go +++ b/libgo/go/net/main_unix_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris package net diff --git a/libgo/go/net/net_test.go b/libgo/go/net/net_test.go index 463ae8856d2..a7406740f52 100644 --- a/libgo/go/net/net_test.go +++ b/libgo/go/net/net_test.go @@ -72,7 +72,7 @@ func TestCloseRead(t *testing.T) { func TestCloseWrite(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } @@ -285,7 +285,6 @@ func TestPacketConnClose(t *testing.T) { } } -// nacl was previous failing to reuse an address. func TestListenCloseListen(t *testing.T) { const maxTries = 10 for tries := 0; tries < maxTries; tries++ { @@ -302,7 +301,7 @@ func TestListenCloseListen(t *testing.T) { } ln, err = Listen("tcp", addr) if err == nil { - // Success. nacl couldn't do this before. + // Success. (This test didn't always make it here earlier.) ln.Close() return } @@ -541,7 +540,7 @@ func TestNotTemporaryRead(t *testing.T) { if err == nil { return errors.New("Read succeeded unexpectedly") } else if err == io.EOF { - // This happens on NaCl and Plan 9. + // This happens on Plan 9. return nil } else if ne, ok := err.(Error); !ok { return fmt.Errorf("unexpected error %v", err) diff --git a/libgo/go/net/platform_test.go b/libgo/go/net/platform_test.go index 10f55c971df..d35dfaade3e 100644 --- a/libgo/go/net/platform_test.go +++ b/libgo/go/net/platform_test.go @@ -37,13 +37,9 @@ func testableNetwork(network string) bool { ss := strings.Split(network, ":") switch ss[0] { case "ip+nopriv": - switch runtime.GOOS { - case "nacl": - return false - } case "ip", "ip4", "ip6": switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": return false default: if os.Getuid() != 0 { @@ -52,7 +48,7 @@ func testableNetwork(network string) bool { } case "unix", "unixgram": switch runtime.GOOS { - case "android", "nacl", "plan9", "windows": + case "android", "plan9", "windows": return false case "aix": return unixEnabledOnAIX @@ -63,7 +59,7 @@ func testableNetwork(network string) bool { } case "unixpacket": switch runtime.GOOS { - case "aix", "android", "darwin", "nacl", "plan9", "windows": + case "aix", "android", "darwin", "plan9", "windows": return false case "netbsd": // It passes on amd64 at least. 386 fails (Issue 22927). arm is unknown. diff --git a/libgo/go/net/port_unix.go b/libgo/go/net/port_unix.go index 6da6f5a84ab..a3b402fdcd5 100644 --- a/libgo/go/net/port_unix.go +++ b/libgo/go/net/port_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris nacl +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris // Read system port mappings from /etc/services diff --git a/libgo/go/net/rawconn.go b/libgo/go/net/rawconn.go index c40ea4a2e12..c7863545826 100644 --- a/libgo/go/net/rawconn.go +++ b/libgo/go/net/rawconn.go @@ -15,7 +15,7 @@ import ( // deadlines. If the user-provided callback returns false, the Write // method will fail immediately. -// BUG(mikio): On JS, NaCl and Plan 9, the Control, Read and Write +// BUG(mikio): On JS and Plan 9, the Control, Read and Write // methods of syscall.RawConn are not implemented. type rawConn struct { diff --git a/libgo/go/net/rawconn_stub_test.go b/libgo/go/net/rawconn_stub_test.go index 0a033c12fc5..cec977f75d9 100644 --- a/libgo/go/net/rawconn_stub_test.go +++ b/libgo/go/net/rawconn_stub_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build js,wasm nacl plan9 +// +build js,wasm plan9 package net diff --git a/libgo/go/net/rawconn_test.go b/libgo/go/net/rawconn_test.go index 11900dff8dd..9a82f8f78e0 100644 --- a/libgo/go/net/rawconn_test.go +++ b/libgo/go/net/rawconn_test.go @@ -15,7 +15,7 @@ import ( func TestRawConnReadWrite(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } @@ -175,7 +175,7 @@ func TestRawConnReadWrite(t *testing.T) { func TestRawConnControl(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/libgo/go/net/sendfile_stub.go b/libgo/go/net/sendfile_stub.go index 6d338da454f..53bc53af43b 100644 --- a/libgo/go/net/sendfile_stub.go +++ b/libgo/go/net/sendfile_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin js,wasm nacl netbsd openbsd +// +build aix darwin js,wasm netbsd openbsd package net diff --git a/libgo/go/net/sendfile_test.go b/libgo/go/net/sendfile_test.go index 911e6139c57..13842a1261f 100644 --- a/libgo/go/net/sendfile_test.go +++ b/libgo/go/net/sendfile_test.go @@ -218,7 +218,7 @@ func TestSendfileSeeked(t *testing.T) { // Test that sendfile doesn't put a pipe into blocking mode. func TestSendfilePipe(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9", "windows": + case "plan9", "windows": // These systems don't support deadlines on pipes. t.Skipf("skipping on %s", runtime.GOOS) } diff --git a/libgo/go/net/sendfile_windows.go b/libgo/go/net/sendfile_windows.go index bccd8b149f7..59b1b0d5c1d 100644 --- a/libgo/go/net/sendfile_windows.go +++ b/libgo/go/net/sendfile_windows.go @@ -18,10 +18,8 @@ import ( // non-EOF error. // // if handled == false, sendFile performed no work. -// -// Note that sendfile for windows does not support >2GB file. func sendFile(fd *netFD, r io.Reader) (written int64, err error, handled bool) { - var n int64 = 0 // by default, copy until EOF + var n int64 = 0 // by default, copy until EOF. lr, ok := r.(*io.LimitedReader) if ok { @@ -30,18 +28,20 @@ func sendFile(fd *netFD, r io.Reader) (written int64, err error, handled bool) { return 0, nil, true } } + f, ok := r.(*os.File) if !ok { return 0, nil, false } - done, err := poll.SendFile(&fd.pfd, syscall.Handle(f.Fd()), n) - + written, err = poll.SendFile(&fd.pfd, syscall.Handle(f.Fd()), n) if err != nil { - return 0, wrapSyscallError("transmitfile", err), false + err = wrapSyscallError("transmitfile", err) } - if lr != nil { - lr.N -= int64(done) - } - return int64(done), nil, true + + // If any byte was copied, regardless of any error + // encountered mid-way, handled must be set to true. + handled = written > 0 + + return } diff --git a/libgo/go/net/server_test.go b/libgo/go/net/server_test.go index 1608bebb00c..2673b87718c 100644 --- a/libgo/go/net/server_test.go +++ b/libgo/go/net/server_test.go @@ -56,71 +56,79 @@ func TestTCPServer(t *testing.T) { const N = 3 for i, tt := range tcpServerTests { - if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) { - t.Logf("skipping %s test", tt.snet+" "+tt.saddr+"<-"+tt.taddr) - continue - } - - ln, err := Listen(tt.snet, tt.saddr) - if err != nil { - if perr := parseDialError(err); perr != nil { - t.Error(perr) + t.Run(tt.snet+" "+tt.saddr+"<-"+tt.taddr, func(t *testing.T) { + if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) { + t.Skip("not testable") } - t.Fatal(err) - } - var lss []*localServer - var tpchs []chan error - defer func() { - for _, ls := range lss { - ls.teardown() - } - }() - for i := 0; i < N; i++ { - ls, err := (&streamListener{Listener: ln}).newLocalServer() + ln, err := Listen(tt.snet, tt.saddr) if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } t.Fatal(err) } - lss = append(lss, ls) - tpchs = append(tpchs, make(chan error, 1)) - } - for i := 0; i < N; i++ { - ch := tpchs[i] - handler := func(ls *localServer, ln Listener) { transponder(ln, ch) } - if err := lss[i].buildup(handler); err != nil { - t.Fatal(err) - } - } - var trchs []chan error - for i := 0; i < N; i++ { - _, port, err := SplitHostPort(lss[i].Listener.Addr().String()) - if err != nil { - t.Fatal(err) + var lss []*localServer + var tpchs []chan error + defer func() { + for _, ls := range lss { + ls.teardown() + } + }() + for i := 0; i < N; i++ { + ls, err := (&streamListener{Listener: ln}).newLocalServer() + if err != nil { + t.Fatal(err) + } + lss = append(lss, ls) + tpchs = append(tpchs, make(chan error, 1)) } - d := Dialer{Timeout: someTimeout} - c, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port)) - if err != nil { - if perr := parseDialError(err); perr != nil { - t.Error(perr) + for i := 0; i < N; i++ { + ch := tpchs[i] + handler := func(ls *localServer, ln Listener) { transponder(ln, ch) } + if err := lss[i].buildup(handler); err != nil { + t.Fatal(err) } - t.Fatal(err) } - defer c.Close() - trchs = append(trchs, make(chan error, 1)) - go transceiver(c, []byte("TCP SERVER TEST"), trchs[i]) - } - for _, ch := range trchs { - for err := range ch { - t.Errorf("#%d: %v", i, err) + var trchs []chan error + for i := 0; i < N; i++ { + _, port, err := SplitHostPort(lss[i].Listener.Addr().String()) + if err != nil { + t.Fatal(err) + } + d := Dialer{Timeout: someTimeout} + c, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port)) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + if tt.taddr == "::1" && os.Getenv("GO_BUILDER_NAME") == "darwin-amd64-10_12" && os.IsTimeout(err) { + // A suspected kernel bug in macOS 10.12 occasionally results in + // "i/o timeout" errors when dialing address ::1. The errors have not + // been observed on newer versions of the OS, so we don't plan to work + // around them. See https://golang.org/issue/32919. + t.Skipf("skipping due to error on known-flaky macOS 10.12 builder: %v", err) + } + t.Fatal(err) + } + defer c.Close() + trchs = append(trchs, make(chan error, 1)) + go transceiver(c, []byte("TCP SERVER TEST"), trchs[i]) } - } - for _, ch := range tpchs { - for err := range ch { - t.Errorf("#%d: %v", i, err) + + for _, ch := range trchs { + for err := range ch { + t.Errorf("#%d: %v", i, err) + } } - } + for _, ch := range tpchs { + for err := range ch { + t.Errorf("#%d: %v", i, err) + } + } + }) } } diff --git a/libgo/go/net/smtp/smtp_test.go b/libgo/go/net/smtp/smtp_test.go index 8195f91419e..cfda0790e96 100644 --- a/libgo/go/net/smtp/smtp_test.go +++ b/libgo/go/net/smtp/smtp_test.go @@ -9,13 +9,13 @@ import ( "bytes" "crypto/tls" "crypto/x509" + "fmt" "internal/testenv" "io" "net" "net/textproto" "runtime" "strings" - "sync" "testing" "time" ) @@ -642,13 +642,13 @@ func TestSendMailWithAuth(t *testing.T) { t.Fatalf("Unable to create listener: %v", err) } defer l.Close() - wg := sync.WaitGroup{} - var done = make(chan struct{}) + + errCh := make(chan error) go func() { - defer wg.Done() + defer close(errCh) conn, err := l.Accept() if err != nil { - t.Errorf("Accept error: %v", err) + errCh <- fmt.Errorf("Accept: %v", err) return } defer conn.Close() @@ -656,13 +656,21 @@ func TestSendMailWithAuth(t *testing.T) { tc := textproto.NewConn(conn) tc.PrintfLine("220 hello world") msg, err := tc.ReadLine() - if msg == "EHLO localhost" { - tc.PrintfLine("250 mx.google.com at your service") + if err != nil { + errCh <- fmt.Errorf("ReadLine error: %v", err) + return + } + const wantMsg = "EHLO localhost" + if msg != wantMsg { + errCh <- fmt.Errorf("unexpected response %q; want %q", msg, wantMsg) + return + } + err = tc.PrintfLine("250 mx.google.com at your service") + if err != nil { + errCh <- fmt.Errorf("PrintfLine: %v", err) + return } - // for this test case, there should have no more traffic - <-done }() - wg.Add(1) err = SendMail(l.Addr().String(), PlainAuth("", "user", "pass", "smtp.google.com"), "test@example.com", []string{"other@example.com"}, []byte(strings.Replace(`From: test@example.com To: other@example.com @@ -676,8 +684,10 @@ SendMail is working for me. if err.Error() != "smtp: server doesn't support AUTH" { t.Errorf("Expected: smtp: server doesn't support AUTH, got: %s", err) } - close(done) - wg.Wait() + err = <-errCh + if err != nil { + t.Fatalf("server error: %v", err) + } } func TestAuthFailed(t *testing.T) { diff --git a/libgo/go/net/sock_posix.go b/libgo/go/net/sock_posix.go index 8076cf1f84c..8fe9bc74871 100644 --- a/libgo/go/net/sock_posix.go +++ b/libgo/go/net/sock_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris windows package net diff --git a/libgo/go/net/sock_stub.go b/libgo/go/net/sock_stub.go index eca1f941139..6d44f43b898 100644 --- a/libgo/go/net/sock_stub.go +++ b/libgo/go/net/sock_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix hurd nacl js,wasm solaris +// +build aix hurd js,wasm solaris package net diff --git a/libgo/go/net/sockaddr_posix.go b/libgo/go/net/sockaddr_posix.go index 9f246509fff..470d04444da 100644 --- a/libgo/go/net/sockaddr_posix.go +++ b/libgo/go/net/sockaddr_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package net diff --git a/libgo/go/net/sockopt_stub.go b/libgo/go/net/sockopt_stub.go index bc0667504af..52624a35d81 100644 --- a/libgo/go/net/sockopt_stub.go +++ b/libgo/go/net/sockopt_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build nacl js,wasm +// +build js,wasm package net diff --git a/libgo/go/net/sockoptip_stub.go b/libgo/go/net/sockoptip_stub.go index 3297969314e..57cd2890405 100644 --- a/libgo/go/net/sockoptip_stub.go +++ b/libgo/go/net/sockoptip_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build nacl js,wasm +// +build js,wasm package net diff --git a/libgo/go/net/sys_cloexec.go b/libgo/go/net/sys_cloexec.go index e97fb21a1f4..89aad7066af 100644 --- a/libgo/go/net/sys_cloexec.go +++ b/libgo/go/net/sys_cloexec.go @@ -5,7 +5,7 @@ // This file implements sysSocket and accept for platforms that do not // provide a fast path for setting SetNonblock and CloseOnExec. -// +build aix darwin nacl solaris +// +build aix darwin solaris package net diff --git a/libgo/go/net/tcpsock.go b/libgo/go/net/tcpsock.go index 0daa2f6487a..9a9b03a1e89 100644 --- a/libgo/go/net/tcpsock.go +++ b/libgo/go/net/tcpsock.go @@ -12,7 +12,7 @@ import ( "time" ) -// BUG(mikio): On JS, NaCl and Windows, the File method of TCPConn and +// BUG(mikio): On JS and Windows, the File method of TCPConn and // TCPListener is not implemented. // TCPAddr represents the address of a TCP end point. @@ -337,3 +337,8 @@ func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) { } return ln, nil } + +// roundDurationUp rounds d to the next multiple of to. +func roundDurationUp(d time.Duration, to time.Duration) time.Duration { + return (d + to - 1) / to +} diff --git a/libgo/go/net/tcpsock_plan9.go b/libgo/go/net/tcpsock_plan9.go index e2e835957c0..768d03b06ce 100644 --- a/libgo/go/net/tcpsock_plan9.go +++ b/libgo/go/net/tcpsock_plan9.go @@ -23,7 +23,12 @@ func (sd *sysDialer) dialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPCo func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) { switch sd.network { - case "tcp", "tcp4", "tcp6": + case "tcp4": + // Plan 9 doesn't complain about [::]:0->127.0.0.1, so it's up to us. + if laddr != nil && len(laddr.IP) != 0 && laddr.IP.To4() == nil { + return nil, &AddrError{Err: "non-IPv4 local address", Addr: laddr.String()} + } + case "tcp", "tcp6": default: return nil, UnknownNetworkError(sd.network) } diff --git a/libgo/go/net/tcpsock_posix.go b/libgo/go/net/tcpsock_posix.go index 1ff0ec04616..2c359da3980 100644 --- a/libgo/go/net/tcpsock_posix.go +++ b/libgo/go/net/tcpsock_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package net diff --git a/libgo/go/net/tcpsock_test.go b/libgo/go/net/tcpsock_test.go index a89f6217196..920bf420fbb 100644 --- a/libgo/go/net/tcpsock_test.go +++ b/libgo/go/net/tcpsock_test.go @@ -480,10 +480,6 @@ func TestTCPReadWriteAllocs(t *testing.T) { // I/O on Plan 9 allocates memory. // See net/fd_io_plan9.go. t.Skipf("not supported on %s", runtime.GOOS) - case "nacl": - // NaCl needs to allocate pseudo file descriptor - // stuff. See syscall/fd_nacl.go. - t.Skipf("not supported on %s", runtime.GOOS) } ln, err := Listen("tcp", "127.0.0.1:0") diff --git a/libgo/go/net/tcpsockopt_darwin.go b/libgo/go/net/tcpsockopt_darwin.go index da0d173453e..53c6756e33e 100644 --- a/libgo/go/net/tcpsockopt_darwin.go +++ b/libgo/go/net/tcpsockopt_darwin.go @@ -15,8 +15,7 @@ const sysTCP_KEEPINTVL = 0x101 func setKeepAlivePeriod(fd *netFD, d time.Duration) error { // The kernel expects seconds so round to next highest second. - d += (time.Second - time.Nanosecond) - secs := int(d.Seconds()) + secs := int(roundDurationUp(d, time.Second)) if err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, sysTCP_KEEPINTVL, secs); err != nil { return wrapSyscallError("setsockopt", err) } diff --git a/libgo/go/net/tcpsockopt_dragonfly.go b/libgo/go/net/tcpsockopt_dragonfly.go index 2b018f2bb2b..b473c02b686 100644 --- a/libgo/go/net/tcpsockopt_dragonfly.go +++ b/libgo/go/net/tcpsockopt_dragonfly.go @@ -13,8 +13,7 @@ import ( func setKeepAlivePeriod(fd *netFD, d time.Duration) error { // The kernel expects milliseconds so round to next highest // millisecond. - d += (time.Millisecond - time.Nanosecond) - msecs := int(d / time.Millisecond) + msecs := int(roundDurationUp(d, time.Millisecond)) if err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, msecs); err != nil { return wrapSyscallError("setsockopt", err) } diff --git a/libgo/go/net/tcpsockopt_solaris.go b/libgo/go/net/tcpsockopt_solaris.go index aa86a29063e..f15e589dc05 100644 --- a/libgo/go/net/tcpsockopt_solaris.go +++ b/libgo/go/net/tcpsockopt_solaris.go @@ -11,11 +11,22 @@ import ( ) func setKeepAlivePeriod(fd *netFD, d time.Duration) error { - // The kernel expects seconds so round to next highest second. - d += (time.Second - time.Nanosecond) - secs := int(d.Seconds()) + // The kernel expects milliseconds so round to next highest + // millisecond. + msecs := int(roundDurationUp(d, time.Millisecond)) - err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, syscall.SO_KEEPALIVE, secs) + // Normally we'd do + // syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, secs) + // here, but we can't because Solaris does not have TCP_KEEPINTVL. + // Solaris has TCP_KEEPALIVE_ABORT_THRESHOLD, but it's not the same + // thing, it refers to the total time until aborting (not between + // probes), and it uses an exponential backoff algorithm instead of + // waiting the same time between probes. We can't hope for the best + // and do it anyway, like on Darwin, because Solaris might eventually + // allocate a constant with a different meaning for the value of + // TCP_KEEPINTVL on illumos. + + err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, syscall.TCP_KEEPALIVE_THRESHOLD, msecs) runtime.KeepAlive(fd) return wrapSyscallError("setsockopt", err) } diff --git a/libgo/go/net/tcpsockopt_stub.go b/libgo/go/net/tcpsockopt_stub.go index fd7f57923ba..d043da123d6 100644 --- a/libgo/go/net/tcpsockopt_stub.go +++ b/libgo/go/net/tcpsockopt_stub.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build nacl js,wasm +// +build js,wasm package net diff --git a/libgo/go/net/tcpsockopt_unix.go b/libgo/go/net/tcpsockopt_unix.go index 13cab6cc236..e05cb73783d 100644 --- a/libgo/go/net/tcpsockopt_unix.go +++ b/libgo/go/net/tcpsockopt_unix.go @@ -14,8 +14,7 @@ import ( func setKeepAlivePeriod(fd *netFD, d time.Duration) error { // The kernel expects seconds so round to next highest second. - d += (time.Second - time.Nanosecond) - secs := int(d.Seconds()) + secs := int(roundDurationUp(d, time.Second)) if err := fd.pfd.SetsockoptInt(syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, secs); err != nil { return wrapSyscallError("setsockopt", err) } diff --git a/libgo/go/net/tcpsockopt_windows.go b/libgo/go/net/tcpsockopt_windows.go index 73dead11d00..4a0b09465ee 100644 --- a/libgo/go/net/tcpsockopt_windows.go +++ b/libgo/go/net/tcpsockopt_windows.go @@ -15,8 +15,7 @@ import ( func setKeepAlivePeriod(fd *netFD, d time.Duration) error { // The kernel expects milliseconds so round to next highest // millisecond. - d += (time.Millisecond - time.Nanosecond) - msecs := uint32(d / time.Millisecond) + msecs := uint32(roundDurationUp(d, time.Millisecond)) ka := syscall.TCPKeepalive{ OnOff: 1, Time: msecs, diff --git a/libgo/go/net/textproto/header.go b/libgo/go/net/textproto/header.go index ed096d9a3cb..a58df7aebca 100644 --- a/libgo/go/net/textproto/header.go +++ b/libgo/go/net/textproto/header.go @@ -26,8 +26,7 @@ func (h MIMEHeader) Set(key, value string) { // It is case insensitive; CanonicalMIMEHeaderKey is used // to canonicalize the provided key. // If there are no values associated with the key, Get returns "". -// To access multiple values of a key, or to use non-canonical keys, -// access the map directly. +// To use non-canonical keys, access the map directly. func (h MIMEHeader) Get(key string) string { if h == nil { return "" @@ -39,6 +38,18 @@ func (h MIMEHeader) Get(key string) string { return v[0] } +// Values returns all values associated with the given key. +// It is case insensitive; CanonicalMIMEHeaderKey is +// used to canonicalize the provided key. To use non-canonical +// keys, access the map directly. +// The returned slice is not a copy. +func (h MIMEHeader) Values(key string) []string { + if h == nil { + return nil + } + return h[CanonicalMIMEHeaderKey(key)] +} + // Del deletes the values associated with key. func (h MIMEHeader) Del(key string) { delete(h, CanonicalMIMEHeaderKey(key)) diff --git a/libgo/go/net/textproto/header_test.go b/libgo/go/net/textproto/header_test.go new file mode 100644 index 00000000000..de9405ca868 --- /dev/null +++ b/libgo/go/net/textproto/header_test.go @@ -0,0 +1,54 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package textproto + +import "testing" + +type canonicalHeaderKeyTest struct { + in, out string +} + +var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{ + {"a-b-c", "A-B-C"}, + {"a-1-c", "A-1-C"}, + {"User-Agent", "User-Agent"}, + {"uSER-aGENT", "User-Agent"}, + {"user-agent", "User-Agent"}, + {"USER-AGENT", "User-Agent"}, + + // Other valid tchar bytes in tokens: + {"foo-bar_baz", "Foo-Bar_baz"}, + {"foo-bar$baz", "Foo-Bar$baz"}, + {"foo-bar~baz", "Foo-Bar~baz"}, + {"foo-bar*baz", "Foo-Bar*baz"}, + + // Non-ASCII or anything with spaces or non-token chars is unchanged: + {"üser-agenT", "üser-agenT"}, + {"a B", "a B"}, + + // This caused a panic due to mishandling of a space: + {"C Ontent-Transfer-Encoding", "C Ontent-Transfer-Encoding"}, + {"foo bar", "foo bar"}, +} + +func TestCanonicalMIMEHeaderKey(t *testing.T) { + for _, tt := range canonicalHeaderKeyTests { + if s := CanonicalMIMEHeaderKey(tt.in); s != tt.out { + t.Errorf("CanonicalMIMEHeaderKey(%q) = %q, want %q", tt.in, s, tt.out) + } + } +} + +// Issue #34799 add a Header method to get multiple values []string, with canonicalized key +func TestMIMEHeaderMultipleValues(t *testing.T) { + testHeader := MIMEHeader{ + "Set-Cookie": {"cookie 1", "cookie 2"}, + } + values := testHeader.Values("set-cookie") + n := len(values) + if n != 2 { + t.Errorf("count: %d; want 2", n) + } +} diff --git a/libgo/go/net/textproto/reader.go b/libgo/go/net/textproto/reader.go index a5cab993b29..a505da985c2 100644 --- a/libgo/go/net/textproto/reader.go +++ b/libgo/go/net/textproto/reader.go @@ -7,6 +7,7 @@ package textproto import ( "bufio" "bytes" + "fmt" "io" "io/ioutil" "strconv" @@ -90,7 +91,7 @@ func (r *Reader) readLineSlice() ([]byte, error) { // A line consisting of only white space is never continued. // func (r *Reader) ReadContinuedLine() (string, error) { - line, err := r.readContinuedLineSlice() + line, err := r.readContinuedLineSlice(noValidation) return string(line), err } @@ -111,7 +112,7 @@ func trim(s []byte) []byte { // ReadContinuedLineBytes is like ReadContinuedLine but // returns a []byte instead of a string. func (r *Reader) ReadContinuedLineBytes() ([]byte, error) { - line, err := r.readContinuedLineSlice() + line, err := r.readContinuedLineSlice(noValidation) if line != nil { buf := make([]byte, len(line)) copy(buf, line) @@ -120,7 +121,15 @@ func (r *Reader) ReadContinuedLineBytes() ([]byte, error) { return line, err } -func (r *Reader) readContinuedLineSlice() ([]byte, error) { +// readContinuedLineSlice reads continued lines from the reader buffer, +// returning a byte slice with all lines. The validateFirstLine function +// is run on the first read line, and if it returns an error then this +// error is returned from readContinuedLineSlice. +func (r *Reader) readContinuedLineSlice(validateFirstLine func([]byte) error) ([]byte, error) { + if validateFirstLine == nil { + return nil, fmt.Errorf("missing validateFirstLine func") + } + // Read the first line. line, err := r.readLineSlice() if err != nil { @@ -130,6 +139,10 @@ func (r *Reader) readContinuedLineSlice() ([]byte, error) { return line, nil } + if err := validateFirstLine(line); err != nil { + return nil, err + } + // Optimistically assume that we have started to buffer the next line // and it starts with an ASCII letter (the next header key), or a blank // line, so we can avoid copying that buffered data around in memory @@ -490,23 +503,17 @@ func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) { } for { - kv, err := r.readContinuedLineSlice() + kv, err := r.readContinuedLineSlice(mustHaveFieldNameColon) if len(kv) == 0 { return m, err } - // Key ends at first colon; should not have trailing spaces - // but they appear in the wild, violating specs, so we remove - // them if present. + // Key ends at first colon. i := bytes.IndexByte(kv, ':') if i < 0 { return m, ProtocolError("malformed MIME header line: " + string(kv)) } - endKey := i - for endKey > 0 && kv[endKey-1] == ' ' { - endKey-- - } - key := canonicalMIMEHeaderKey(kv[:endKey]) + key := canonicalMIMEHeaderKey(kv[:i]) // As per RFC 7230 field-name is a token, tokens consist of one or more chars. // We could return a ProtocolError here, but better to be liberal in what we @@ -541,6 +548,20 @@ func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) { } } +// noValidation is a no-op validation func for readContinuedLineSlice +// that permits any lines. +func noValidation(_ []byte) error { return nil } + +// mustHaveFieldNameColon ensures that, per RFC 7230, the +// field-name is on a single line, so the first line must +// contain a colon. +func mustHaveFieldNameColon(line []byte) error { + if bytes.IndexByte(line, ':') < 0 { + return ProtocolError(fmt.Sprintf("malformed MIME header: missing colon: %q" + string(line))) + } + return nil +} + // upcomingHeaderNewlines returns an approximation of the number of newlines // that will be in this header. If it gets confused, it returns 0. func (r *Reader) upcomingHeaderNewlines() (n int) { diff --git a/libgo/go/net/textproto/reader_test.go b/libgo/go/net/textproto/reader_test.go index e9ae04d37de..e0e9adbfb35 100644 --- a/libgo/go/net/textproto/reader_test.go +++ b/libgo/go/net/textproto/reader_test.go @@ -13,41 +13,6 @@ import ( "testing" ) -type canonicalHeaderKeyTest struct { - in, out string -} - -var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{ - {"a-b-c", "A-B-C"}, - {"a-1-c", "A-1-C"}, - {"User-Agent", "User-Agent"}, - {"uSER-aGENT", "User-Agent"}, - {"user-agent", "User-Agent"}, - {"USER-AGENT", "User-Agent"}, - - // Other valid tchar bytes in tokens: - {"foo-bar_baz", "Foo-Bar_baz"}, - {"foo-bar$baz", "Foo-Bar$baz"}, - {"foo-bar~baz", "Foo-Bar~baz"}, - {"foo-bar*baz", "Foo-Bar*baz"}, - - // Non-ASCII or anything with spaces or non-token chars is unchanged: - {"üser-agenT", "üser-agenT"}, - {"a B", "a B"}, - - // This caused a panic due to mishandling of a space: - {"C Ontent-Transfer-Encoding", "C Ontent-Transfer-Encoding"}, - {"foo bar", "foo bar"}, -} - -func TestCanonicalMIMEHeaderKey(t *testing.T) { - for _, tt := range canonicalHeaderKeyTests { - if s := CanonicalMIMEHeaderKey(tt.in); s != tt.out { - t.Errorf("CanonicalMIMEHeaderKey(%q) = %q, want %q", tt.in, s, tt.out) - } - } -} - func reader(s string) *Reader { return NewReader(bufio.NewReader(strings.NewReader(s))) } @@ -188,11 +153,10 @@ func TestLargeReadMIMEHeader(t *testing.T) { } } -// Test that we read slightly-bogus MIME headers seen in the wild, -// with spaces before colons, and spaces in keys. +// TestReadMIMEHeaderNonCompliant checks that we don't normalize headers +// with spaces before colons, and accept spaces in keys. func TestReadMIMEHeaderNonCompliant(t *testing.T) { - // Invalid HTTP response header as sent by an Axis security - // camera: (this is handled by IE, Firefox, Chrome, curl, etc.) + // These invalid headers will be rejected by net/http according to RFC 7230. r := reader("Foo: bar\r\n" + "Content-Language: en\r\n" + "SID : 0\r\n" + @@ -202,9 +166,9 @@ func TestReadMIMEHeaderNonCompliant(t *testing.T) { want := MIMEHeader{ "Foo": {"bar"}, "Content-Language": {"en"}, - "Sid": {"0"}, - "Audio Mode": {"None"}, - "Privilege": {"127"}, + "SID ": {"0"}, + "Audio Mode ": {"None"}, + "Privilege ": {"127"}, } if !reflect.DeepEqual(m, want) || err != nil { t.Fatalf("ReadMIMEHeader =\n%v, %v; want:\n%v", m, err, want) @@ -219,6 +183,10 @@ func TestReadMIMEHeaderMalformed(t *testing.T) { " First: line with leading space\r\nFoo: foo\r\n\r\n", "\tFirst: line with leading tab\r\nFoo: foo\r\n\r\n", "Foo: foo\r\nNo colon second line\r\n\r\n", + "Foo-\n\tBar: foo\r\n\r\n", + "Foo-\r\n\tBar: foo\r\n\r\n", + "Foo\r\n\t: foo\r\n\r\n", + "Foo-\n\tBar", } for _, input := range inputs { diff --git a/libgo/go/net/timeout_test.go b/libgo/go/net/timeout_test.go index b4fc2c01981..f54c9564f9e 100644 --- a/libgo/go/net/timeout_test.go +++ b/libgo/go/net/timeout_test.go @@ -411,9 +411,6 @@ func TestReadTimeoutMustNotReturn(t *testing.T) { if perr := parseReadError(err); perr != nil { t.Error(perr) } - if err == io.EOF && runtime.GOOS == "nacl" { // see golang.org/issue/8044 - return - } if nerr, ok := err.(Error); !ok || nerr.Timeout() || nerr.Temporary() { t.Fatal(err) } @@ -432,11 +429,6 @@ var readFromTimeoutTests = []struct { } func TestReadFromTimeout(t *testing.T) { - switch runtime.GOOS { - case "nacl": - t.Skipf("not supported on %s", runtime.GOOS) // see golang.org/issue/8916 - } - ch := make(chan Addr) defer close(ch) handler := func(ls *localPacketServer, c PacketConn) { @@ -621,11 +613,6 @@ var writeToTimeoutTests = []struct { func TestWriteToTimeout(t *testing.T) { t.Parallel() - switch runtime.GOOS { - case "nacl": - t.Skipf("not supported on %s", runtime.GOOS) - } - c1, err := newLocalPacketListener("udp") if err != nil { t.Fatal(err) @@ -991,11 +978,6 @@ func TestReadWriteProlongedTimeout(t *testing.T) { func TestReadWriteDeadlineRace(t *testing.T) { t.Parallel() - switch runtime.GOOS { - case "nacl": - t.Skipf("not supported on %s", runtime.GOOS) - } - N := 1000 if testing.Short() { N = 50 @@ -1051,3 +1033,43 @@ func TestReadWriteDeadlineRace(t *testing.T) { }() wg.Wait() // wait for tester goroutine to stop } + +// Issue 35367. +func TestConcurrentSetDeadline(t *testing.T) { + ln, err := newLocalListener("tcp") + if err != nil { + t.Fatal(err) + } + defer ln.Close() + + const goroutines = 8 + const conns = 10 + const tries = 100 + + var c [conns]Conn + for i := 0; i < conns; i++ { + c[i], err = Dial(ln.Addr().Network(), ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + defer c[i].Close() + } + + var wg sync.WaitGroup + wg.Add(goroutines) + now := time.Now() + for i := 0; i < goroutines; i++ { + go func(i int) { + defer wg.Done() + // Make the deadlines steadily earlier, + // to trigger runtime adjusttimers calls. + for j := tries; j > 0; j-- { + for k := 0; k < conns; k++ { + c[k].SetReadDeadline(now.Add(2*time.Hour + time.Duration(i*j*k)*time.Second)) + c[k].SetWriteDeadline(now.Add(1*time.Hour + time.Duration(i*j*k)*time.Second)) + } + } + }(i) + } + wg.Wait() +} diff --git a/libgo/go/net/udpsock.go b/libgo/go/net/udpsock.go index b234ed89abf..ec2bcfa607b 100644 --- a/libgo/go/net/udpsock.go +++ b/libgo/go/net/udpsock.go @@ -9,15 +9,12 @@ import ( "syscall" ) -// BUG(mikio): On NaCl and Plan 9, the ReadMsgUDP and +// BUG(mikio): On Plan 9, the ReadMsgUDP and // WriteMsgUDP methods of UDPConn are not implemented. // BUG(mikio): On Windows, the File method of UDPConn is not // implemented. -// BUG(mikio): On NaCl, the ListenMulticastUDP function is not -// implemented. - // BUG(mikio): On JS, methods and functions related to UDPConn are not // implemented. diff --git a/libgo/go/net/udpsock_plan9.go b/libgo/go/net/udpsock_plan9.go index 563d943507e..79986ce4da2 100644 --- a/libgo/go/net/udpsock_plan9.go +++ b/libgo/go/net/udpsock_plan9.go @@ -109,7 +109,9 @@ func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn, } func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) { - l, err := listenPlan9(ctx, sl.network, gaddr) + // Plan 9 does not like announce command with a multicast address, + // so do not specify an IP address when listening. + l, err := listenPlan9(ctx, sl.network, &UDPAddr{IP: nil, Port: gaddr.Port, Zone: gaddr.Zone}) if err != nil { return nil, err } @@ -129,11 +131,13 @@ func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, g return nil, err } } + + have4 := gaddr.IP.To4() != nil for _, addr := range addrs { - if ipnet, ok := addr.(*IPNet); ok { + if ipnet, ok := addr.(*IPNet); ok && (ipnet.IP.To4() != nil) == have4 { _, err = l.ctl.WriteString("addmulti " + ipnet.IP.String() + " " + gaddr.IP.String()) if err != nil { - return nil, err + return nil, &OpError{Op: "addmulti", Net: "", Source: nil, Addr: ipnet, Err: err} } } } diff --git a/libgo/go/net/udpsock_plan9_test.go b/libgo/go/net/udpsock_plan9_test.go index 09f5a5dc654..3febfcc0741 100644 --- a/libgo/go/net/udpsock_plan9_test.go +++ b/libgo/go/net/udpsock_plan9_test.go @@ -36,7 +36,7 @@ func TestListenMulticastUDP(t *testing.T) { c1, err := ListenMulticastUDP("udp4", mifc, &UDPAddr{IP: ParseIP("224.0.0.254")}) if err != nil { - t.Fatalf("multicast not working on %s", runtime.GOOS) + t.Fatalf("multicast not working on %s: %v", runtime.GOOS, err) } c1addr := c1.LocalAddr().(*UDPAddr) if err != nil { diff --git a/libgo/go/net/udpsock_posix.go b/libgo/go/net/udpsock_posix.go index 1d4cde176ae..858a3efe2f9 100644 --- a/libgo/go/net/udpsock_posix.go +++ b/libgo/go/net/udpsock_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package net diff --git a/libgo/go/net/udpsock_test.go b/libgo/go/net/udpsock_test.go index 397b6649cda..947381a57b0 100644 --- a/libgo/go/net/udpsock_test.go +++ b/libgo/go/net/udpsock_test.go @@ -162,13 +162,8 @@ func testWriteToConn(t *testing.T, raddr string) { t.Fatalf("should fail as ErrWriteToConnected: %v", err) } _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, nil) - switch runtime.GOOS { - case "nacl": // see golang.org/issue/9252 - t.Skipf("not implemented yet on %s", runtime.GOOS) - default: - if err != nil { - t.Fatal(err) - } + if err != nil { + t.Fatal(err) } } @@ -205,13 +200,8 @@ func testWriteToPacketConn(t *testing.T, raddr string) { t.Fatalf("should fail as errMissingAddress: %v", err) } _, _, err = c.(*UDPConn).WriteMsgUDP(b, nil, ra) - switch runtime.GOOS { - case "nacl": // see golang.org/issue/9252 - t.Skipf("not implemented yet on %s", runtime.GOOS) - default: - if err != nil { - t.Fatal(err) - } + if err != nil { + t.Fatal(err) } } @@ -335,7 +325,7 @@ func TestIPv6LinkLocalUnicastUDP(t *testing.T) { func TestUDPZeroBytePayload(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) case "darwin": testenv.SkipFlaky(t, 29225) @@ -373,7 +363,7 @@ func TestUDPZeroBytePayload(t *testing.T) { func TestUDPZeroByteBuffer(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } @@ -410,7 +400,7 @@ func TestUDPZeroByteBuffer(t *testing.T) { func TestUDPReadSizeError(t *testing.T) { switch runtime.GOOS { - case "nacl", "plan9": + case "plan9": t.Skipf("not supported on %s", runtime.GOOS) } diff --git a/libgo/go/net/unixsock.go b/libgo/go/net/unixsock.go index ae912a46ddb..b38438c11a8 100644 --- a/libgo/go/net/unixsock.go +++ b/libgo/go/net/unixsock.go @@ -12,7 +12,7 @@ import ( "time" ) -// BUG(mikio): On JS, NaCl and Plan 9, methods and functions related +// BUG(mikio): On JS and Plan 9, methods and functions related // to UnixConn and UnixListener are not implemented. // BUG(mikio): On Windows, methods and functions related to UnixConn diff --git a/libgo/go/net/unixsock_posix.go b/libgo/go/net/unixsock_posix.go index 68887b4cabe..37214854dac 100644 --- a/libgo/go/net/unixsock_posix.go +++ b/libgo/go/net/unixsock_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package net diff --git a/libgo/go/net/unixsock_test.go b/libgo/go/net/unixsock_test.go index 48289903107..80cccf21e3d 100644 --- a/libgo/go/net/unixsock_test.go +++ b/libgo/go/net/unixsock_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !js,!nacl,!plan9,!windows +// +build !js,!plan9,!windows package net diff --git a/libgo/go/net/url/url.go b/libgo/go/net/url/url.go index 12ea35f0f9e..2880e820c30 100644 --- a/libgo/go/net/url/url.go +++ b/libgo/go/net/url/url.go @@ -26,7 +26,7 @@ type Error struct { } func (e *Error) Unwrap() error { return e.Err } -func (e *Error) Error() string { return e.Op + " " + e.URL + ": " + e.Err.Error() } +func (e *Error) Error() string { return fmt.Sprintf("%s %q: %s", e.Op, e.URL, e.Err) } func (e *Error) Timeout() bool { t, ok := e.Err.(interface { @@ -42,6 +42,8 @@ func (e *Error) Temporary() bool { return ok && t.Temporary() } +const upperhex = "0123456789ABCDEF" + func ishex(c byte) bool { switch { case '0' <= c && c <= '9': @@ -324,8 +326,8 @@ func escape(s string, mode encoding) string { j++ case shouldEscape(c, mode): t[j] = '%' - t[j+1] = "0123456789ABCDEF"[c>>4] - t[j+2] = "0123456789ABCDEF"[c&15] + t[j+1] = upperhex[c>>4] + t[j+2] = upperhex[c&15] j += 3 default: t[j] = s[i] @@ -449,16 +451,16 @@ func getscheme(rawurl string) (scheme, path string, err error) { return "", rawurl, nil } -// Maybe s is of the form t c u. -// If so, return t, c u (or t, u if cutc == true). -// If not, return s, "". -func split(s string, c string, cutc bool) (string, string) { - i := strings.Index(s, c) +// split slices s into two substrings separated by the first occurrence of +// sep. If cutc is true then sep is excluded from the second substring. +// If sep does not occur in s then s and the empty string is returned. +func split(s string, sep byte, cutc bool) (string, string) { + i := strings.IndexByte(s, sep) if i < 0 { return s, "" } if cutc { - return s[:i], s[i+len(c):] + return s[:i], s[i+1:] } return s[:i], s[i:] } @@ -471,7 +473,7 @@ func split(s string, c string, cutc bool) (string, string) { // error, due to parsing ambiguities. func Parse(rawurl string) (*URL, error) { // Cut off #frag - u, frag := split(rawurl, "#", true) + u, frag := split(rawurl, '#', true) url, err := parse(u, false) if err != nil { return nil, &Error{"parse", u, err} @@ -531,7 +533,7 @@ func parse(rawurl string, viaRequest bool) (*URL, error) { url.ForceQuery = true rest = rest[:len(rest)-1] } else { - rest, url.RawQuery = split(rest, "?", true) + rest, url.RawQuery = split(rest, '?', true) } if !strings.HasPrefix(rest, "/") { @@ -560,7 +562,7 @@ func parse(rawurl string, viaRequest bool) (*URL, error) { if (url.Scheme != "" || !viaRequest && !strings.HasPrefix(rest, "///")) && strings.HasPrefix(rest, "//") { var authority string - authority, rest = split(rest[2:], "/", false) + authority, rest = split(rest[2:], '/', false) url.User, url.Host, err = parseAuthority(authority) if err != nil { return nil, err @@ -599,7 +601,7 @@ func parseAuthority(authority string) (user *Userinfo, host string, err error) { } user = User(userinfo) } else { - username, password := split(userinfo, ":", true) + username, password := split(userinfo, ':', true) if username, err = unescape(username, encodeUserPassword); err != nil { return nil, "", err } @@ -948,8 +950,8 @@ func resolvePath(base, ref string) string { if full == "" { return "" } - var dst []string src := strings.Split(full, "/") + dst := make([]string, 0, len(src)) for _, elem := range src { switch elem { case ".": diff --git a/libgo/go/net/url/url_test.go b/libgo/go/net/url/url_test.go index e83c86c4243..79fd3d5c79f 100644 --- a/libgo/go/net/url/url_test.go +++ b/libgo/go/net/url/url_test.go @@ -668,6 +668,7 @@ var parseRequestURLTests = []struct { {"foo.html", false}, {"../dir/", false}, + {" http://foo.com", false}, {"http://192.168.0.%31/", false}, {"http://192.168.0.%31:8080/", false}, {"http://[fe80::%31]/", false}, @@ -1429,16 +1430,21 @@ func TestParseErrors(t *testing.T) { {"http://[::1]/", false}, {"http://[::1]a", true}, {"http://[::1]%23", true}, - {"http://[::1%25en0]", false}, // valid zone id - {"http://[::1]:", false}, // colon, but no port OK - {"http://x:", false}, // colon, but no port OK - {"http://[::1]:%38%30", true}, // not allowed: % encoding only for non-ASCII - {"http://[::1%25%41]", false}, // RFC 6874 allows over-escaping in zone - {"http://[%10::1]", true}, // no %xx escapes in IP address - {"http://[::1]/%48", false}, // %xx in path is fine - {"http://%41:8080/", true}, // not allowed: % encoding only for non-ASCII - {"mysql://x@y(z:123)/foo", false}, // golang.org/issue/12023 - {"mysql://x@y(1.2.3.4:123)/foo", false}, + {"http://[::1%25en0]", false}, // valid zone id + {"http://[::1]:", false}, // colon, but no port OK + {"http://x:", false}, // colon, but no port OK + {"http://[::1]:%38%30", true}, // not allowed: % encoding only for non-ASCII + {"http://[::1%25%41]", false}, // RFC 6874 allows over-escaping in zone + {"http://[%10::1]", true}, // no %xx escapes in IP address + {"http://[::1]/%48", false}, // %xx in path is fine + {"http://%41:8080/", true}, // not allowed: % encoding only for non-ASCII + {"mysql://x@y(z:123)/foo", true}, // not well-formed per RFC 3986, golang.org/issue/33646 + {"mysql://x@y(1.2.3.4:123)/foo", true}, + + {" http://foo.com", true}, // invalid character in schema + {"ht tp://foo.com", true}, // invalid character in schema + {"ahttp://foo.com", false}, // valid schema characters + {"1http://foo.com", true}, // invalid character in schema {"http://[]%20%48%54%54%50%2f%31%2e%31%0a%4d%79%48%65%61%64%65%72%3a%20%31%32%33%0a%0a/", true}, // golang.org/issue/11208 {"http://a b.com/", true}, // no space in host name please @@ -1456,7 +1462,7 @@ func TestParseErrors(t *testing.T) { continue } if err != nil { - t.Logf("Parse(%q) = %v; want no error", tt.in, err) + t.Errorf("Parse(%q) = %v; want no error", tt.in, err) } } } @@ -1874,3 +1880,12 @@ func BenchmarkPathUnescape(b *testing.B) { }) } } + +var sink string + +func BenchmarkSplit(b *testing.B) { + url := "http://www.google.com/?q=go+language#foo%26bar" + for i := 0; i < b.N; i++ { + sink, sink = split(url, '#', true) + } +} diff --git a/libgo/go/os/dir_gccgo.go b/libgo/go/os/dir_gccgo.go index ad77a406840..171dde5097b 100644 --- a/libgo/go/os/dir_gccgo.go +++ b/libgo/go/os/dir_gccgo.go @@ -14,7 +14,10 @@ import ( // FIXME: pathconf returns long, not int. //extern pathconf -func libc_pathconf(*byte, int) int +func libc_pathconf(*byte, int32) int + +//extern dup +func libc_dup(int32) int32 func clen(n []byte) int { for i := 0; i < len(n); i++ { @@ -48,9 +51,17 @@ func (file *File) readdirnames(n int) (names []string, err error) { } syscall.Entersyscall() - r := libc_fdopendir(int32(file.pfd.Sysfd)) + fd := libc_dup(int32(file.pfd.Sysfd)) errno := syscall.GetErrno() syscall.Exitsyscall() + if fd < 0 { + return nil, &PathError{"dup", file.name, errno} + } + + syscall.Entersyscall() + r := libc_fdopendir(fd) + errno = syscall.GetErrno() + syscall.Exitsyscall() if r == nil { return nil, &PathError{"fdopendir", file.name, errno} } @@ -100,3 +111,12 @@ func (file *File) readdirnames(n int) (names []string, err error) { } return names, nil } + +func (f *File) seekInvalidate() { + if f.file.dirinfo != nil { + syscall.Entersyscall() + libc_closedir(f.file.dirinfo.dir) + syscall.Exitsyscall() + f.file.dirinfo = nil + } +} diff --git a/libgo/go/os/env_windows.go b/libgo/go/os/env_windows.go index e8f647e7ac7..b1b1ee4b3e6 100644 --- a/libgo/go/os/env_windows.go +++ b/libgo/go/os/env_windows.go @@ -23,16 +23,20 @@ func environForSysProcAttr(sys *syscall.SysProcAttr) (env []string, err error) { defer windows.DestroyEnvironmentBlock(block) blockp := uintptr(unsafe.Pointer(block)) for { - entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:] - for i, v := range entry { - if v == 0 { - entry = entry[:i] - break - } + + // find NUL terminator + end := unsafe.Pointer(blockp) + for *(*uint16)(end) != 0 { + end = unsafe.Pointer(uintptr(end) + 2) } - if len(entry) == 0 { + + n := (uintptr(end) - uintptr(unsafe.Pointer(blockp))) / 2 + if n == 0 { + // environment block ends with empty string break } + + entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:n:n] env = append(env, string(utf16.Decode(entry))) blockp += 2 * (uintptr(len(entry)) + 1) } diff --git a/libgo/go/os/error.go b/libgo/go/os/error.go index 0e8e2d47f8f..26bfe4cab53 100644 --- a/libgo/go/os/error.go +++ b/libgo/go/os/error.go @@ -110,7 +110,7 @@ func IsTimeout(err error) bool { func underlyingErrorIs(err, target error) bool { // Note that this function is not errors.Is: // underlyingError only unwraps the specific error-wrapping types - // that it historically did, not all errors.Wrapper implementations. + // that it historically did, not all errors implementing Unwrap(). err = underlyingError(err) if err == target { return true diff --git a/libgo/go/os/error_posix.go b/libgo/go/os/error_posix.go index 401e6f7acb5..7d5a19caa56 100644 --- a/libgo/go/os/error_posix.go +++ b/libgo/go/os/error_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package os diff --git a/libgo/go/os/error_unix_test.go b/libgo/go/os/error_unix_test.go index faf18ee308d..a01916e88d5 100644 --- a/libgo/go/os/error_unix_test.go +++ b/libgo/go/os/error_unix_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package os_test diff --git a/libgo/go/os/exec/exec.go b/libgo/go/os/exec/exec.go index 17ef003eca0..3474ae0ca49 100644 --- a/libgo/go/os/exec/exec.go +++ b/libgo/go/os/exec/exec.go @@ -238,7 +238,6 @@ func (c *Cmd) argv() []string { // skipStdinCopyError optionally specifies a function which reports // whether the provided stdin copy error should be ignored. -// It is non-nil everywhere but Plan 9, which lacks EPIPE. See exec_posix.go. var skipStdinCopyError func(error) bool func (c *Cmd) stdin() (f *os.File, err error) { @@ -369,6 +368,8 @@ func lookExtensions(path, dir string) (string, error) { // Start starts the specified command but does not wait for it to complete. // +// If Start returns successfully, the c.Process field will be set. +// // The Wait method will return the exit code and release associated resources // once the command exits. func (c *Cmd) Start() error { @@ -606,8 +607,8 @@ func (c *closeOnce) close() { // standard output when the command starts. // // Wait will close the pipe after seeing the command exit, so most callers -// need not close the pipe themselves; however, an implication is that -// it is incorrect to call Wait before all reads from the pipe have completed. +// need not close the pipe themselves. It is thus incorrect to call Wait +// before all reads from the pipe have completed. // For the same reason, it is incorrect to call Run when using StdoutPipe. // See the example for idiomatic usage. func (c *Cmd) StdoutPipe() (io.ReadCloser, error) { @@ -631,8 +632,8 @@ func (c *Cmd) StdoutPipe() (io.ReadCloser, error) { // standard error when the command starts. // // Wait will close the pipe after seeing the command exit, so most callers -// need not close the pipe themselves; however, an implication is that -// it is incorrect to call Wait before all reads from the pipe have completed. +// need not close the pipe themselves. It is thus incorrect to call Wait +// before all reads from the pipe have completed. // For the same reason, it is incorrect to use Run when using StderrPipe. // See the StdoutPipe example for idiomatic usage. func (c *Cmd) StderrPipe() (io.ReadCloser, error) { diff --git a/libgo/go/os/exec/exec_plan9.go b/libgo/go/os/exec/exec_plan9.go new file mode 100644 index 00000000000..d90bd043991 --- /dev/null +++ b/libgo/go/os/exec/exec_plan9.go @@ -0,0 +1,19 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package exec + +import "os" + +func init() { + skipStdinCopyError = func(err error) bool { + // Ignore hungup errors copying to stdin if the program + // completed successfully otherwise. + // See Issue 35753. + pe, ok := err.(*os.PathError) + return ok && + pe.Op == "write" && pe.Path == "|1" && + pe.Err.Error() == "i/o on hungup channel" + } +} diff --git a/libgo/go/os/exec/exec_test.go b/libgo/go/os/exec/exec_test.go index cfbb87a68f3..dce66c5c2e1 100644 --- a/libgo/go/os/exec/exec_test.go +++ b/libgo/go/os/exec/exec_test.go @@ -30,6 +30,45 @@ import ( "time" ) +// haveUnexpectedFDs is set at init time to report whether any +// file descriptors were open at program start. +var haveUnexpectedFDs bool + +// unfinalizedFiles holds files that should not be finalized, +// because that would close the associated file descriptor, +// which we don't want to do. +var unfinalizedFiles []*os.File + +func init() { + if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { + return + } + if runtime.GOOS == "windows" { + return + } + for fd := uintptr(3); fd <= 100; fd++ { + if poll.IsPollDescriptor(fd) { + continue + } + // We have no good portable way to check whether an FD is open. + // We use NewFile to create a *os.File, which lets us + // know whether it is open, but then we have to cope with + // the finalizer on the *os.File. + f := os.NewFile(fd, "") + if _, err := f.Stat(); err != nil { + // Close the file to clear the finalizer. + // We expect the Close to fail. + f.Close() + } else { + fmt.Printf("fd %d open at test start\n", fd) + haveUnexpectedFDs = true + // Use a global variable to avoid running + // the finalizer, which would close the FD. + unfinalizedFiles = append(unfinalizedFiles, f) + } + } +} + func helperCommandContext(t *testing.T, ctx context.Context, s ...string) (cmd *exec.Cmd) { testenv.MustHaveExec(t) @@ -40,11 +79,7 @@ func helperCommandContext(t *testing.T, ctx context.Context, s ...string) (cmd * } else { cmd = exec.Command(os.Args[0], cs...) } - cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"} - path := os.Getenv("LD_LIBRARY_PATH") - if path != "" { - cmd.Env = append(cmd.Env, "LD_LIBRARY_PATH="+path) - } + cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1") return cmd } @@ -453,17 +488,15 @@ func numOpenFDsAndroid(t *testing.T) (n int, lsof []byte) { return bytes.Count(lsof, []byte("\n")), lsof } -var testedAlreadyLeaked = false - // basefds returns the number of expected file descriptors // to be present in a process at start. -// stdin, stdout, stderr, epoll/kqueue, maybe testlog +// stdin, stdout, stderr, epoll/kqueue, epoll/kqueue pipe, maybe testlog func basefds() uintptr { n := os.Stderr.Fd() + 1 // The poll (epoll/kqueue) descriptor can be numerically // either between stderr and the testlog-fd, or after // testlog-fd. - if poll.IsPollDescriptor(n) { + for poll.IsPollDescriptor(n) { n++ } for _, arg := range os.Args { @@ -474,29 +507,9 @@ func basefds() uintptr { return n } -func closeUnexpectedFds(t *testing.T, m string) { - for fd := basefds(); fd <= 101; fd++ { - if poll.IsPollDescriptor(fd) { - continue - } - err := os.NewFile(fd, "").Close() - if err == nil { - t.Logf("%s: Something already leaked - closed fd %d", m, fd) - } - } -} - func TestExtraFilesFDShuffle(t *testing.T) { t.Skip("flaky test; see https://golang.org/issue/5780") switch runtime.GOOS { - case "darwin": - // TODO(cnicolaou): https://golang.org/issue/2603 - // leads to leaked file descriptors in this test when it's - // run from a builder. - closeUnexpectedFds(t, "TestExtraFilesFDShuffle") - case "netbsd": - // https://golang.org/issue/3955 - closeUnexpectedFds(t, "TestExtraFilesFDShuffle") case "windows": t.Skip("no operating system support; skipping") } @@ -591,19 +604,29 @@ func TestExtraFilesFDShuffle(t *testing.T) { } func TestExtraFiles(t *testing.T) { + if haveUnexpectedFDs { + // The point of this test is to make sure that any + // descriptors we open are marked close-on-exec. + // If haveUnexpectedFDs is true then there were other + // descriptors open when we started the test, + // so those descriptors are clearly not close-on-exec, + // and they will confuse the test. We could modify + // the test to expect those descriptors to remain open, + // but since we don't know where they came from or what + // they are doing, that seems fragile. For example, + // perhaps they are from the startup code on this + // system for some reason. Also, this test is not + // system-specific; as long as most systems do not skip + // the test, we will still be testing what we care about. + t.Skip("skipping test because test was run with FDs open") + } + testenv.MustHaveExec(t) if runtime.GOOS == "windows" { t.Skipf("skipping test on %q", runtime.GOOS) } - // Ensure that file descriptors have not already been leaked into - // our environment. - if !testedAlreadyLeaked { - testedAlreadyLeaked = true - closeUnexpectedFds(t, "TestExtraFiles") - } - // Force network usage, to verify the epoll (or whatever) fd // doesn't leak to the child, ln, err := net.Listen("tcp", "127.0.0.1:0") @@ -660,7 +683,7 @@ func TestExtraFiles(t *testing.T) { c.ExtraFiles = []*os.File{tf} err = c.Run() if err != nil { - t.Fatalf("Run: %v; stdout %q, stderr %q", err, stdout.Bytes(), stderr.Bytes()) + t.Fatalf("Run: %v\n--- stdout:\n%s--- stderr:\n%s", err, stdout.Bytes(), stderr.Bytes()) } if stdout.String() != text { t.Errorf("got stdout %q, stderr %q; want %q on stdout", stdout.String(), stderr.String(), text) @@ -825,55 +848,40 @@ func TestHelperProcess(*testing.T) { fmt.Printf("ReadAll from fd 3: %v", err) os.Exit(1) } - switch runtime.GOOS { - case "dragonfly": - // TODO(jsing): Determine why DragonFly is leaking - // file descriptors... - case "darwin": - // TODO(bradfitz): broken? Sometimes. - // https://golang.org/issue/2603 - // Skip this additional part of the test for now. - case "netbsd": - // TODO(jsing): This currently fails on NetBSD due to - // the cloned file descriptors that result from opening - // /dev/urandom. - // https://golang.org/issue/3955 - case "illumos", "solaris": - // TODO(aram): This fails on Solaris because libc opens - // its own files, as it sees fit. Darwin does the same, - // see: https://golang.org/issue/2603 - default: - // Now verify that there are no other open fds. - var files []*os.File - for wantfd := basefds() + 1; wantfd <= 100; wantfd++ { - if poll.IsPollDescriptor(wantfd) { - continue + // Now verify that there are no other open fds. + var files []*os.File + for wantfd := basefds() + 1; wantfd <= 100; wantfd++ { + if poll.IsPollDescriptor(wantfd) { + continue + } + f, err := os.Open(os.Args[0]) + if err != nil { + fmt.Printf("error opening file with expected fd %d: %v", wantfd, err) + os.Exit(1) + } + if got := f.Fd(); got != wantfd { + fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd) + var args []string + switch runtime.GOOS { + case "plan9": + args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())} + case "aix": + args = []string{fmt.Sprint(os.Getpid())} + default: + args = []string{"-p", fmt.Sprint(os.Getpid())} } - f, err := os.Open(os.Args[0]) + cmd := exec.Command(ofcmd, args...) + out, err := cmd.CombinedOutput() if err != nil { - fmt.Printf("error opening file with expected fd %d: %v", wantfd, err) - os.Exit(1) - } - if got := f.Fd(); got != wantfd { - fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd) - var args []string - switch runtime.GOOS { - case "plan9": - args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())} - case "aix": - args = []string{fmt.Sprint(os.Getpid())} - default: - args = []string{"-p", fmt.Sprint(os.Getpid())} - } - out, _ := exec.Command(ofcmd, args...).CombinedOutput() - fmt.Print(string(out)) - os.Exit(1) + fmt.Fprintf(os.Stderr, "%s failed: %v\n", strings.Join(cmd.Args, " "), err) } - files = append(files, f) - } - for _, f := range files { - f.Close() + fmt.Printf("%s", out) + os.Exit(1) } + files = append(files, f) + } + for _, f := range files { + f.Close() } // Referring to fd3 here ensures that it is not // garbage collected, and therefore closed, while @@ -966,11 +974,6 @@ func (delayedInfiniteReader) Read(b []byte) (int, error) { func TestIgnorePipeErrorOnSuccess(t *testing.T) { testenv.MustHaveExec(t) - // We really only care about testing this on Unixy and Windowsy things. - if runtime.GOOS == "plan9" { - t.Skipf("skipping test on %q", runtime.GOOS) - } - testWith := func(r io.Reader) func(*testing.T) { return func(t *testing.T) { cmd := helperCommand(t, "echo", "foo") diff --git a/libgo/go/os/exec/lp_unix.go b/libgo/go/os/exec/lp_unix.go index d3f174feea8..6a5e877f760 100644 --- a/libgo/go/os/exec/lp_unix.go +++ b/libgo/go/os/exec/lp_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris package exec diff --git a/libgo/go/os/exec_posix.go b/libgo/go/os/exec_posix.go index bb47e8330c7..a944e4e0350 100644 --- a/libgo/go/os/exec_posix.go +++ b/libgo/go/os/exec_posix.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package os import ( + "runtime" "syscall" ) @@ -49,9 +50,14 @@ func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err e } pid, h, e := syscall.StartProcess(name, argv, sysattr) + + // Make sure we don't run the finalizers of attr.Files. + runtime.KeepAlive(attr) + if e != nil { return nil, &PathError{"fork/exec", name, e} } + return newProcess(pid, h), nil } diff --git a/libgo/go/os/exec_unix.go b/libgo/go/os/exec_unix.go index 1cb8ebc6bd0..238d7555c7a 100644 --- a/libgo/go/os/exec_unix.go +++ b/libgo/go/os/exec_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package os diff --git a/libgo/go/os/exec_windows.go b/libgo/go/os/exec_windows.go index 38293a0d285..10503c595ff 100644 --- a/libgo/go/os/exec_windows.go +++ b/libgo/go/os/exec_windows.go @@ -6,11 +6,11 @@ package os import ( "errors" + "internal/syscall/windows" "runtime" "sync/atomic" "syscall" "time" - "unsafe" ) func (p *Process) wait() (ps *ProcessState, err error) { @@ -98,8 +98,7 @@ func findProcess(pid int) (p *Process, err error) { } func init() { - p := syscall.GetCommandLine() - cmd := syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(p))[:]) + cmd := windows.UTF16PtrToString(syscall.GetCommandLine(), 0xffff) if len(cmd) == 0 { arg0, _ := Executable() Args = []string{arg0} diff --git a/libgo/go/os/executable.go b/libgo/go/os/executable.go index 17eed10bc9f..cc3134af1c1 100644 --- a/libgo/go/os/executable.go +++ b/libgo/go/os/executable.go @@ -15,8 +15,6 @@ package os // // The main use case is finding resources located relative to an // executable. -// -// Executable is not supported on nacl. func Executable() (string, error) { return executable() } diff --git a/libgo/go/os/executable_procfs.go b/libgo/go/os/executable_procfs.go index e690103b0ad..d2d2e5a66df 100644 --- a/libgo/go/os/executable_procfs.go +++ b/libgo/go/os/executable_procfs.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build hurd linux netbsd dragonfly nacl js,wasm +// +build hurd linux netbsd dragonfly js,wasm package os diff --git a/libgo/go/os/executable_test.go b/libgo/go/os/executable_test.go index d513c8760ee..f25ee0c95a1 100644 --- a/libgo/go/os/executable_test.go +++ b/libgo/go/os/executable_test.go @@ -17,7 +17,7 @@ import ( const executable_EnvVar = "OSTEST_OUTPUT_EXECPATH" func TestExecutable(t *testing.T) { - testenv.MustHaveExec(t) // will also exclude nacl, which doesn't support Executable anyway + testenv.MustHaveExec(t) ep, err := os.Executable() if err != nil { t.Fatalf("Executable failed: %v", err) diff --git a/libgo/go/os/export_test.go b/libgo/go/os/export_test.go index d17d5e62308..812432cee48 100644 --- a/libgo/go/os/export_test.go +++ b/libgo/go/os/export_test.go @@ -9,4 +9,3 @@ package os var Atime = atime var LstatP = &lstat var ErrWriteAtInAppendMode = errWriteAtInAppendMode -var RemoveAllTestHook = &removeAllTestHook diff --git a/libgo/go/os/export_unix_test.go b/libgo/go/os/export_unix_test.go index 3a15aad2158..f4d399dfad4 100644 --- a/libgo/go/os/export_unix_test.go +++ b/libgo/go/os/export_unix_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package os diff --git a/libgo/go/os/file.go b/libgo/go/os/file.go index c13babe5f7f..7995de79bfc 100644 --- a/libgo/go/os/file.go +++ b/libgo/go/os/file.go @@ -228,6 +228,9 @@ func (f *File) WriteString(s string) (n int, err error) { // bits (before umask). // If there is an error, it will be of type *PathError. func Mkdir(name string, perm FileMode) error { + if runtime.GOOS == "windows" && isWindowsNulName(name) { + return &PathError{"mkdir", name, syscall.ENOTDIR} + } e := syscall.Mkdir(fixLongPath(name), syscallMode(perm)) if e != nil { @@ -247,7 +250,7 @@ func Mkdir(name string, perm FileMode) error { return nil } -// setStickyBit adds ModeSticky to the permision bits of path, non atomic. +// setStickyBit adds ModeSticky to the permission bits of path, non atomic. func setStickyBit(name string) error { fi, err := Stat(name) if err != nil { @@ -408,7 +411,7 @@ func UserCacheDir() (string, error) { // subdirectory within this one and use that. // // On Unix systems, it returns $XDG_CONFIG_HOME as specified by -// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html if +// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if // non-empty, else $HOME/.config. // On Darwin, it returns $HOME/Library/Application Support. // On Windows, it returns %AppData%. @@ -472,8 +475,6 @@ func UserHomeDir() (string, error) { } // On some geese the home directory is not always defined. switch runtime.GOOS { - case "nacl": - return "/", nil case "android": return "/sdcard", nil case "darwin": @@ -560,3 +561,21 @@ func (f *File) SyscallConn() (syscall.RawConn, error) { } return newRawConn(f) } + +// isWindowsNulName reports whether name is os.DevNull ('NUL') on Windows. +// True is returned if name is 'NUL' whatever the case. +func isWindowsNulName(name string) bool { + if len(name) != 3 { + return false + } + if name[0] != 'n' && name[0] != 'N' { + return false + } + if name[1] != 'u' && name[1] != 'U' { + return false + } + if name[2] != 'l' && name[2] != 'L' { + return false + } + return true +} diff --git a/libgo/go/os/file_plan9.go b/libgo/go/os/file_plan9.go index e0a3826a34c..48bf5f5076a 100644 --- a/libgo/go/os/file_plan9.go +++ b/libgo/go/os/file_plan9.go @@ -111,7 +111,7 @@ func openFileNolog(name string, flag int, perm FileMode) (*File, error) { fd, e = syscall.Create(name, flag, syscallMode(perm)) } else { fd, e = syscall.Open(name, flag) - if e != nil && create { + if IsNotExist(e) && create { var e1 error fd, e1 = syscall.Create(name, flag, syscallMode(perm)) if e1 == nil { diff --git a/libgo/go/os/file_posix.go b/libgo/go/os/file_posix.go index 2220a442f0d..f59d1378fc1 100644 --- a/libgo/go/os/file_posix.go +++ b/libgo/go/os/file_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package os diff --git a/libgo/go/os/file_unix.go b/libgo/go/os/file_unix.go index 750771fa47a..2fc63188e48 100644 --- a/libgo/go/os/file_unix.go +++ b/libgo/go/os/file_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package os @@ -27,13 +27,17 @@ func rename(oldname, newname string) error { // At this point we've determined the newname is bad. // But just in case oldname is also bad, prioritize returning // the oldname error because that's what we did historically. - if _, err := Lstat(oldname); err != nil { + // However, if the old name and new name are not the same, yet + // they refer to the same file, it implies a case-only + // rename on a case-insensitive filesystem, which is ok. + if ofi, err := Lstat(oldname); err != nil { if pe, ok := err.(*PathError); ok { err = pe.Err } return &LinkError{"rename", oldname, newname, err} + } else if newname == oldname || !SameFile(fi, ofi) { + return &LinkError{"rename", oldname, newname, syscall.EEXIST} } - return &LinkError{"rename", oldname, newname, syscall.EEXIST} } err = syscall.Rename(oldname, newname) if err != nil { @@ -253,13 +257,12 @@ func (file *file) close() error { if i < 0 && errno != 0 { err = &PathError{"closedir", file.name, errno} } - } else { - if e := file.pfd.Close(); e != nil { - if e == poll.ErrFileClosing { - e = ErrClosed - } - err = &PathError{"close", file.name, e} + } + if e := file.pfd.Close(); e != nil { + if e == poll.ErrFileClosing { + e = ErrClosed } + err = &PathError{"close", file.name, e} } // no need for a finalizer anymore @@ -305,6 +308,7 @@ func (f *File) pwrite(b []byte, off int64) (n int, err error) { // relative to the current offset, and 2 means relative to the end. // It returns the new offset and an error, if any. func (f *File) seek(offset int64, whence int) (ret int64, err error) { + f.seekInvalidate() ret, err = f.pfd.Seek(offset, whence) runtime.KeepAlive(f) return ret, err diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go index c27432f9ab4..a19b46d2964 100644 --- a/libgo/go/os/os_test.go +++ b/libgo/go/os/os_test.go @@ -971,6 +971,67 @@ func TestRenameToDirFailed(t *testing.T) { } } +func TestRenameCaseDifference(pt *testing.T) { + from, to := "renameFROM", "RENAMEfrom" + tests := []struct { + name string + create func() error + }{ + {"dir", func() error { + return Mkdir(from, 0777) + }}, + {"file", func() error { + fd, err := Create(from) + if err != nil { + return err + } + return fd.Close() + }}, + } + + for _, test := range tests { + pt.Run(test.name, func(t *testing.T) { + defer chtmpdir(t)() + + if err := test.create(); err != nil { + t.Fatalf("failed to create test file: %s", err) + } + + if _, err := Stat(to); err != nil { + // Sanity check that the underlying filesystem is not case sensitive. + if IsNotExist(err) { + t.Skipf("case sensitive filesystem") + } + t.Fatalf("stat %q, got: %q", to, err) + } + + if err := Rename(from, to); err != nil { + t.Fatalf("unexpected error when renaming from %q to %q: %s", from, to, err) + } + + fd, err := Open(".") + if err != nil { + t.Fatalf("Open .: %s", err) + } + + // Stat does not return the real case of the file (it returns what the called asked for) + // So we have to use readdir to get the real name of the file. + dirNames, err := fd.Readdirnames(-1) + if err != nil { + t.Fatalf("readdirnames: %s", err) + } + + if dirNamesLen := len(dirNames); dirNamesLen != 1 { + t.Fatalf("unexpected dirNames len, got %q, want %q", dirNamesLen, 1) + } + + if dirNames[0] != to { + t.Errorf("unexpected name, got %q, want %q", dirNames[0], to) + } + }) + } +} + func exec(t *testing.T, dir, cmd string, args []string, expect string) { r, w, err := Pipe() if err != nil { @@ -1157,9 +1218,7 @@ func testChtimes(t *testing.T, name string) { pmt := postStat.ModTime() if !pat.Before(at) { switch runtime.GOOS { - case "plan9", "nacl": - // Ignore. - // Plan 9, NaCl: + case "plan9": // Mtime is the time of the last change of // content. Similarly, atime is set whenever // the contents are accessed; also, it is set @@ -1349,10 +1408,6 @@ func TestSeek(t *testing.T) { {0, io.SeekCurrent, 2<<32 - 1}, } for i, tt := range tests { - if runtime.GOOS == "nacl" && tt.out > 1<<30 { - t.Logf("skipping test case #%d on nacl; https://golang.org/issue/21728", i) - continue - } if runtime.GOOS == "hurd" && tt.out > 1<<32 { t.Logf("skipping test case #%d on Hurd: file too large", i) continue @@ -1373,7 +1428,7 @@ func TestSeek(t *testing.T) { func TestSeekError(t *testing.T) { switch runtime.GOOS { - case "js", "nacl", "plan9": + case "js", "plan9": t.Skipf("skipping test on %v", runtime.GOOS) } @@ -2253,8 +2308,6 @@ func TestPipeThreads(t *testing.T) { t.Skip("skipping on Plan 9; does not support runtime poller") case "js": t.Skip("skipping on js; no support for os.Pipe") - case "darwin": - t.Skip("skipping on Darwin; issue 33953") } threads := 100 @@ -2355,3 +2408,45 @@ func TestUserHomeDir(t *testing.T) { t.Fatalf("dir %s is not directory; type = %v", dir, fi.Mode()) } } + +func TestDirSeek(t *testing.T) { + if runtime.GOOS == "windows" { + testenv.SkipFlaky(t, 36019) + } + wd, err := Getwd() + if err != nil { + t.Fatal(err) + } + f, err := Open(wd) + if err != nil { + t.Fatal(err) + } + dirnames1, err := f.Readdirnames(0) + if err != nil { + t.Fatal(err) + } + + ret, err := f.Seek(0, 0) + if err != nil { + t.Fatal(err) + } + if ret != 0 { + t.Fatalf("seek result not zero: %d", ret) + } + + dirnames2, err := f.Readdirnames(0) + if err != nil { + t.Fatal(err) + return + } + + if len(dirnames1) != len(dirnames2) { + t.Fatalf("listings have different lengths: %d and %d\n", len(dirnames1), len(dirnames2)) + } + for i, n1 := range dirnames1 { + n2 := dirnames2[i] + if n1 != n2 { + t.Fatalf("different name i=%d n1=%s n2=%s\n", i, n1, n2) + } + } +} diff --git a/libgo/go/os/os_windows_test.go b/libgo/go/os/os_windows_test.go new file mode 100644 index 00000000000..8c141031434 --- /dev/null +++ b/libgo/go/os/os_windows_test.go @@ -0,0 +1,1188 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package os_test + +import ( + "errors" + "fmt" + "internal/poll" + "internal/syscall/windows" + "internal/syscall/windows/registry" + "internal/testenv" + "io" + "io/ioutil" + "os" + osexec "os/exec" + "path/filepath" + "reflect" + "runtime" + "sort" + "strings" + "syscall" + "testing" + "unicode/utf16" + "unsafe" +) + +// For TestRawConnReadWrite. +type syscallDescriptor = syscall.Handle + +func TestSameWindowsFile(t *testing.T) { + temp, err := ioutil.TempDir("", "TestSameWindowsFile") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(temp) + + wd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + err = os.Chdir(temp) + if err != nil { + t.Fatal(err) + } + defer os.Chdir(wd) + + f, err := os.Create("a") + if err != nil { + t.Fatal(err) + } + f.Close() + + ia1, err := os.Stat("a") + if err != nil { + t.Fatal(err) + } + + path, err := filepath.Abs("a") + if err != nil { + t.Fatal(err) + } + ia2, err := os.Stat(path) + if err != nil { + t.Fatal(err) + } + if !os.SameFile(ia1, ia2) { + t.Errorf("files should be same") + } + + p := filepath.VolumeName(path) + filepath.Base(path) + if err != nil { + t.Fatal(err) + } + ia3, err := os.Stat(p) + if err != nil { + t.Fatal(err) + } + if !os.SameFile(ia1, ia3) { + t.Errorf("files should be same") + } +} + +type dirLinkTest struct { + name string + mklink func(link, target string) error + issueNo int // correspondent issue number (for broken tests) +} + +func testDirLinks(t *testing.T, tests []dirLinkTest) { + tmpdir, err := ioutil.TempDir("", "testDirLinks") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + oldwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + err = os.Chdir(tmpdir) + if err != nil { + t.Fatal(err) + } + defer os.Chdir(oldwd) + + dir := filepath.Join(tmpdir, "dir") + err = os.Mkdir(dir, 0777) + if err != nil { + t.Fatal(err) + } + fi, err := os.Stat(dir) + if err != nil { + t.Fatal(err) + } + err = ioutil.WriteFile(filepath.Join(dir, "abc"), []byte("abc"), 0644) + if err != nil { + t.Fatal(err) + } + for _, test := range tests { + link := filepath.Join(tmpdir, test.name+"_link") + err := test.mklink(link, dir) + if err != nil { + t.Errorf("creating link for %q test failed: %v", test.name, err) + continue + } + + data, err := ioutil.ReadFile(filepath.Join(link, "abc")) + if err != nil { + t.Errorf("failed to read abc file: %v", err) + continue + } + if string(data) != "abc" { + t.Errorf(`abc file is expected to have "abc" in it, but has %v`, data) + continue + } + + if test.issueNo > 0 { + t.Logf("skipping broken %q test: see issue %d", test.name, test.issueNo) + continue + } + + fi1, err := os.Stat(link) + if err != nil { + t.Errorf("failed to stat link %v: %v", link, err) + continue + } + if !fi1.IsDir() { + t.Errorf("%q should be a directory", link) + continue + } + if fi1.Name() != filepath.Base(link) { + t.Errorf("Stat(%q).Name() = %q, want %q", link, fi1.Name(), filepath.Base(link)) + continue + } + if !os.SameFile(fi, fi1) { + t.Errorf("%q should point to %q", link, dir) + continue + } + + fi2, err := os.Lstat(link) + if err != nil { + t.Errorf("failed to lstat link %v: %v", link, err) + continue + } + if m := fi2.Mode(); m&os.ModeSymlink == 0 { + t.Errorf("%q should be a link, but is not (mode=0x%x)", link, uint32(m)) + continue + } + if m := fi2.Mode(); m&os.ModeDir != 0 { + t.Errorf("%q should be a link, not a directory (mode=0x%x)", link, uint32(m)) + continue + } + } +} + +// reparseData is used to build reparse buffer data required for tests. +type reparseData struct { + substituteName namePosition + printName namePosition + pathBuf []uint16 +} + +type namePosition struct { + offset uint16 + length uint16 +} + +func (rd *reparseData) addUTF16s(s []uint16) (offset uint16) { + off := len(rd.pathBuf) * 2 + rd.pathBuf = append(rd.pathBuf, s...) + return uint16(off) +} + +func (rd *reparseData) addString(s string) (offset, length uint16) { + p := syscall.StringToUTF16(s) + return rd.addUTF16s(p), uint16(len(p)-1) * 2 // do not include terminating NUL in the length (as per PrintNameLength and SubstituteNameLength documentation) +} + +func (rd *reparseData) addSubstituteName(name string) { + rd.substituteName.offset, rd.substituteName.length = rd.addString(name) +} + +func (rd *reparseData) addPrintName(name string) { + rd.printName.offset, rd.printName.length = rd.addString(name) +} + +func (rd *reparseData) addStringNoNUL(s string) (offset, length uint16) { + p := syscall.StringToUTF16(s) + p = p[:len(p)-1] + return rd.addUTF16s(p), uint16(len(p)) * 2 +} + +func (rd *reparseData) addSubstituteNameNoNUL(name string) { + rd.substituteName.offset, rd.substituteName.length = rd.addStringNoNUL(name) +} + +func (rd *reparseData) addPrintNameNoNUL(name string) { + rd.printName.offset, rd.printName.length = rd.addStringNoNUL(name) +} + +// pathBuffeLen returns length of rd pathBuf in bytes. +func (rd *reparseData) pathBuffeLen() uint16 { + return uint16(len(rd.pathBuf)) * 2 +} + +// Windows REPARSE_DATA_BUFFER contains union member, and cannot be +// translated into Go directly. _REPARSE_DATA_BUFFER type is to help +// construct alternative versions of Windows REPARSE_DATA_BUFFER with +// union part of SymbolicLinkReparseBuffer or MountPointReparseBuffer type. +type _REPARSE_DATA_BUFFER struct { + header windows.REPARSE_DATA_BUFFER_HEADER + detail [syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE]byte +} + +func createDirLink(link string, rdb *_REPARSE_DATA_BUFFER) error { + err := os.Mkdir(link, 0777) + if err != nil { + return err + } + + linkp := syscall.StringToUTF16(link) + fd, err := syscall.CreateFile(&linkp[0], syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, + syscall.FILE_FLAG_OPEN_REPARSE_POINT|syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) + if err != nil { + return err + } + defer syscall.CloseHandle(fd) + + buflen := uint32(rdb.header.ReparseDataLength) + uint32(unsafe.Sizeof(rdb.header)) + var bytesReturned uint32 + return syscall.DeviceIoControl(fd, windows.FSCTL_SET_REPARSE_POINT, + (*byte)(unsafe.Pointer(&rdb.header)), buflen, nil, 0, &bytesReturned, nil) +} + +func createMountPoint(link string, target *reparseData) error { + var buf *windows.MountPointReparseBuffer + buflen := uint16(unsafe.Offsetof(buf.PathBuffer)) + target.pathBuffeLen() // see ReparseDataLength documentation + byteblob := make([]byte, buflen) + buf = (*windows.MountPointReparseBuffer)(unsafe.Pointer(&byteblob[0])) + buf.SubstituteNameOffset = target.substituteName.offset + buf.SubstituteNameLength = target.substituteName.length + buf.PrintNameOffset = target.printName.offset + buf.PrintNameLength = target.printName.length + pbuflen := len(target.pathBuf) + copy((*[2048]uint16)(unsafe.Pointer(&buf.PathBuffer[0]))[:pbuflen:pbuflen], target.pathBuf) + + var rdb _REPARSE_DATA_BUFFER + rdb.header.ReparseTag = windows.IO_REPARSE_TAG_MOUNT_POINT + rdb.header.ReparseDataLength = buflen + copy(rdb.detail[:], byteblob) + + return createDirLink(link, &rdb) +} + +func TestDirectoryJunction(t *testing.T) { + var tests = []dirLinkTest{ + { + // Create link similar to what mklink does, by inserting \??\ at the front of absolute target. + name: "standard", + mklink: func(link, target string) error { + var t reparseData + t.addSubstituteName(`\??\` + target) + t.addPrintName(target) + return createMountPoint(link, &t) + }, + }, + { + // Do as junction utility https://technet.microsoft.com/en-au/sysinternals/bb896768.aspx does - set PrintNameLength to 0. + name: "have_blank_print_name", + mklink: func(link, target string) error { + var t reparseData + t.addSubstituteName(`\??\` + target) + t.addPrintName("") + return createMountPoint(link, &t) + }, + }, + } + output, _ := osexec.Command("cmd", "/c", "mklink", "/?").Output() + mklinkSupportsJunctionLinks := strings.Contains(string(output), " /J ") + if mklinkSupportsJunctionLinks { + tests = append(tests, + dirLinkTest{ + name: "use_mklink_cmd", + mklink: func(link, target string) error { + output, err := osexec.Command("cmd", "/c", "mklink", "/J", link, target).CombinedOutput() + if err != nil { + t.Errorf("failed to run mklink %v %v: %v %q", link, target, err, output) + } + return nil + }, + }, + ) + } else { + t.Log(`skipping "use_mklink_cmd" test, mklink does not supports directory junctions`) + } + testDirLinks(t, tests) +} + +func enableCurrentThreadPrivilege(privilegeName string) error { + ct, err := windows.GetCurrentThread() + if err != nil { + return err + } + var t syscall.Token + err = windows.OpenThreadToken(ct, syscall.TOKEN_QUERY|windows.TOKEN_ADJUST_PRIVILEGES, false, &t) + if err != nil { + return err + } + defer syscall.CloseHandle(syscall.Handle(t)) + + var tp windows.TOKEN_PRIVILEGES + + privStr, err := syscall.UTF16PtrFromString(privilegeName) + if err != nil { + return err + } + err = windows.LookupPrivilegeValue(nil, privStr, &tp.Privileges[0].Luid) + if err != nil { + return err + } + tp.PrivilegeCount = 1 + tp.Privileges[0].Attributes = windows.SE_PRIVILEGE_ENABLED + return windows.AdjustTokenPrivileges(t, false, &tp, 0, nil, nil) +} + +func createSymbolicLink(link string, target *reparseData, isrelative bool) error { + var buf *windows.SymbolicLinkReparseBuffer + buflen := uint16(unsafe.Offsetof(buf.PathBuffer)) + target.pathBuffeLen() // see ReparseDataLength documentation + byteblob := make([]byte, buflen) + buf = (*windows.SymbolicLinkReparseBuffer)(unsafe.Pointer(&byteblob[0])) + buf.SubstituteNameOffset = target.substituteName.offset + buf.SubstituteNameLength = target.substituteName.length + buf.PrintNameOffset = target.printName.offset + buf.PrintNameLength = target.printName.length + if isrelative { + buf.Flags = windows.SYMLINK_FLAG_RELATIVE + } + pbuflen := len(target.pathBuf) + copy((*[2048]uint16)(unsafe.Pointer(&buf.PathBuffer[0]))[:pbuflen:pbuflen], target.pathBuf) + + var rdb _REPARSE_DATA_BUFFER + rdb.header.ReparseTag = syscall.IO_REPARSE_TAG_SYMLINK + rdb.header.ReparseDataLength = buflen + copy(rdb.detail[:], byteblob) + + return createDirLink(link, &rdb) +} + +func TestDirectorySymbolicLink(t *testing.T) { + var tests []dirLinkTest + output, _ := osexec.Command("cmd", "/c", "mklink", "/?").Output() + mklinkSupportsDirectorySymbolicLinks := strings.Contains(string(output), " /D ") + if mklinkSupportsDirectorySymbolicLinks { + tests = append(tests, + dirLinkTest{ + name: "use_mklink_cmd", + mklink: func(link, target string) error { + output, err := osexec.Command("cmd", "/c", "mklink", "/D", link, target).CombinedOutput() + if err != nil { + t.Errorf("failed to run mklink %v %v: %v %q", link, target, err, output) + } + return nil + }, + }, + ) + } else { + t.Log(`skipping "use_mklink_cmd" test, mklink does not supports directory symbolic links`) + } + + // The rest of these test requires SeCreateSymbolicLinkPrivilege to be held. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + err := windows.ImpersonateSelf(windows.SecurityImpersonation) + if err != nil { + t.Fatal(err) + } + defer windows.RevertToSelf() + + err = enableCurrentThreadPrivilege("SeCreateSymbolicLinkPrivilege") + if err != nil { + t.Skipf(`skipping some tests, could not enable "SeCreateSymbolicLinkPrivilege": %v`, err) + } + tests = append(tests, + dirLinkTest{ + name: "use_os_pkg", + mklink: func(link, target string) error { + return os.Symlink(target, link) + }, + }, + dirLinkTest{ + // Create link similar to what mklink does, by inserting \??\ at the front of absolute target. + name: "standard", + mklink: func(link, target string) error { + var t reparseData + t.addPrintName(target) + t.addSubstituteName(`\??\` + target) + return createSymbolicLink(link, &t, false) + }, + }, + dirLinkTest{ + name: "relative", + mklink: func(link, target string) error { + var t reparseData + t.addSubstituteNameNoNUL(filepath.Base(target)) + t.addPrintNameNoNUL(filepath.Base(target)) + return createSymbolicLink(link, &t, true) + }, + }, + ) + testDirLinks(t, tests) +} + +func TestNetworkSymbolicLink(t *testing.T) { + testenv.MustHaveSymlink(t) + + const _NERR_ServerNotStarted = syscall.Errno(2114) + + dir, err := ioutil.TempDir("", "TestNetworkSymbolicLink") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(dir) + + oldwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + err = os.Chdir(dir) + if err != nil { + t.Fatal(err) + } + defer os.Chdir(oldwd) + + shareName := "GoSymbolicLinkTestShare" // hope no conflictions + sharePath := filepath.Join(dir, shareName) + testDir := "TestDir" + + err = os.MkdirAll(filepath.Join(sharePath, testDir), 0777) + if err != nil { + t.Fatal(err) + } + + wShareName, err := syscall.UTF16PtrFromString(shareName) + if err != nil { + t.Fatal(err) + } + wSharePath, err := syscall.UTF16PtrFromString(sharePath) + if err != nil { + t.Fatal(err) + } + + p := windows.SHARE_INFO_2{ + Netname: wShareName, + Type: windows.STYPE_DISKTREE, + Remark: nil, + Permissions: 0, + MaxUses: 1, + CurrentUses: 0, + Path: wSharePath, + Passwd: nil, + } + + err = windows.NetShareAdd(nil, 2, (*byte)(unsafe.Pointer(&p)), nil) + if err != nil { + if err == syscall.ERROR_ACCESS_DENIED { + t.Skip("you don't have enough privileges to add network share") + } + if err == _NERR_ServerNotStarted { + t.Skip(_NERR_ServerNotStarted.Error()) + } + t.Fatal(err) + } + defer func() { + err := windows.NetShareDel(nil, wShareName, 0) + if err != nil { + t.Fatal(err) + } + }() + + UNCPath := `\\localhost\` + shareName + `\` + + fi1, err := os.Stat(sharePath) + if err != nil { + t.Fatal(err) + } + fi2, err := os.Stat(UNCPath) + if err != nil { + t.Fatal(err) + } + if !os.SameFile(fi1, fi2) { + t.Fatalf("%q and %q should be the same directory, but not", sharePath, UNCPath) + } + + target := filepath.Join(UNCPath, testDir) + link := "link" + + err = os.Symlink(target, link) + if err != nil { + t.Fatal(err) + } + defer os.Remove(link) + + got, err := os.Readlink(link) + if err != nil { + t.Fatal(err) + } + if got != target { + t.Errorf(`os.Readlink("%s"): got %v, want %v`, link, got, target) + } + + got, err = filepath.EvalSymlinks(link) + if err != nil { + t.Fatal(err) + } + if got != target { + t.Errorf(`filepath.EvalSymlinks("%s"): got %v, want %v`, link, got, target) + } +} + +func TestStartProcessAttr(t *testing.T) { + p, err := os.StartProcess(os.Getenv("COMSPEC"), []string{"/c", "cd"}, new(os.ProcAttr)) + if err != nil { + return + } + defer p.Wait() + t.Fatalf("StartProcess expected to fail, but succeeded.") +} + +func TestShareNotExistError(t *testing.T) { + if testing.Short() { + t.Skip("slow test that uses network; skipping") + } + _, err := os.Stat(`\\no_such_server\no_such_share\no_such_file`) + if err == nil { + t.Fatal("stat succeeded, but expected to fail") + } + if !os.IsNotExist(err) { + t.Fatalf("os.Stat failed with %q, but os.IsNotExist(err) is false", err) + } +} + +func TestBadNetPathError(t *testing.T) { + const ERROR_BAD_NETPATH = syscall.Errno(53) + if !os.IsNotExist(ERROR_BAD_NETPATH) { + t.Fatal("os.IsNotExist(syscall.Errno(53)) is false, but want true") + } +} + +func TestStatDir(t *testing.T) { + defer chtmpdir(t)() + + f, err := os.Open(".") + if err != nil { + t.Fatal(err) + } + defer f.Close() + + fi, err := f.Stat() + if err != nil { + t.Fatal(err) + } + + err = os.Chdir("..") + if err != nil { + t.Fatal(err) + } + + fi2, err := f.Stat() + if err != nil { + t.Fatal(err) + } + + if !os.SameFile(fi, fi2) { + t.Fatal("race condition occurred") + } +} + +func TestOpenVolumeName(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "TestOpenVolumeName") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + wd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + err = os.Chdir(tmpdir) + if err != nil { + t.Fatal(err) + } + defer os.Chdir(wd) + + want := []string{"file1", "file2", "file3", "gopher.txt"} + sort.Strings(want) + for _, name := range want { + err := ioutil.WriteFile(filepath.Join(tmpdir, name), nil, 0777) + if err != nil { + t.Fatal(err) + } + } + + f, err := os.Open(filepath.VolumeName(tmpdir)) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + have, err := f.Readdirnames(-1) + if err != nil { + t.Fatal(err) + } + sort.Strings(have) + + if strings.Join(want, "/") != strings.Join(have, "/") { + t.Fatalf("unexpected file list %q, want %q", have, want) + } +} + +func TestDeleteReadOnly(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "TestDeleteReadOnly") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + p := filepath.Join(tmpdir, "a") + // This sets FILE_ATTRIBUTE_READONLY. + f, err := os.OpenFile(p, os.O_CREATE, 0400) + if err != nil { + t.Fatal(err) + } + f.Close() + + if err = os.Chmod(p, 0400); err != nil { + t.Fatal(err) + } + if err = os.Remove(p); err != nil { + t.Fatal(err) + } +} + +func TestStatSymlinkLoop(t *testing.T) { + testenv.MustHaveSymlink(t) + + defer chtmpdir(t)() + + err := os.Symlink("x", "y") + if err != nil { + t.Fatal(err) + } + defer os.Remove("y") + + err = os.Symlink("y", "x") + if err != nil { + t.Fatal(err) + } + defer os.Remove("x") + + _, err = os.Stat("x") + if _, ok := err.(*os.PathError); !ok { + t.Errorf("expected *PathError, got %T: %v\n", err, err) + } +} + +func TestReadStdin(t *testing.T) { + old := poll.ReadConsole + defer func() { + poll.ReadConsole = old + }() + + testConsole := os.NewConsoleFile(syscall.Stdin, "test") + + var tests = []string{ + "abc", + "äöü", + "\u3042", + "“hi”™", + "hello\x1aworld", + "\U0001F648\U0001F649\U0001F64A", + } + + for _, consoleSize := range []int{1, 2, 3, 10, 16, 100, 1000} { + for _, readSize := range []int{1, 2, 3, 4, 5, 8, 10, 16, 20, 50, 100} { + for _, s := range tests { + t.Run(fmt.Sprintf("c%d/r%d/%s", consoleSize, readSize, s), func(t *testing.T) { + s16 := utf16.Encode([]rune(s)) + poll.ReadConsole = func(h syscall.Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) error { + if inputControl != nil { + t.Fatalf("inputControl not nil") + } + n := int(toread) + if n > consoleSize { + n = consoleSize + } + n = copy((*[10000]uint16)(unsafe.Pointer(buf))[:n:n], s16) + s16 = s16[n:] + *read = uint32(n) + t.Logf("read %d -> %d", toread, *read) + return nil + } + + var all []string + var buf []byte + chunk := make([]byte, readSize) + for { + n, err := testConsole.Read(chunk) + buf = append(buf, chunk[:n]...) + if err == io.EOF { + all = append(all, string(buf)) + if len(all) >= 5 { + break + } + buf = buf[:0] + } else if err != nil { + t.Fatalf("reading %q: error: %v", s, err) + } + if len(buf) >= 2000 { + t.Fatalf("reading %q: stuck in loop: %q", s, buf) + } + } + + want := strings.Split(s, "\x1a") + for len(want) < 5 { + want = append(want, "") + } + if !reflect.DeepEqual(all, want) { + t.Errorf("reading %q:\nhave %x\nwant %x", s, all, want) + } + }) + } + } + } +} + +func TestStatPagefile(t *testing.T) { + fi, err := os.Stat(`c:\pagefile.sys`) + if err == nil { + if fi.Name() == "" { + t.Fatal(`FileInfo of c:\pagefile.sys has empty name`) + } + return + } + if os.IsNotExist(err) { + t.Skip(`skipping because c:\pagefile.sys is not found`) + } + t.Fatal(err) +} + +// syscallCommandLineToArgv calls syscall.CommandLineToArgv +// and converts returned result into []string. +func syscallCommandLineToArgv(cmd string) ([]string, error) { + var argc int32 + argv, err := syscall.CommandLineToArgv(&syscall.StringToUTF16(cmd)[0], &argc) + if err != nil { + return nil, err + } + defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv)))) + + var args []string + for _, v := range (*argv)[:argc] { + args = append(args, syscall.UTF16ToString((*v)[:])) + } + return args, nil +} + +// compareCommandLineToArgvWithSyscall ensures that +// os.CommandLineToArgv(cmd) and syscall.CommandLineToArgv(cmd) +// return the same result. +func compareCommandLineToArgvWithSyscall(t *testing.T, cmd string) { + syscallArgs, err := syscallCommandLineToArgv(cmd) + if err != nil { + t.Fatal(err) + } + args := os.CommandLineToArgv(cmd) + if want, have := fmt.Sprintf("%q", syscallArgs), fmt.Sprintf("%q", args); want != have { + t.Errorf("testing os.commandLineToArgv(%q) failed: have %q want %q", cmd, args, syscallArgs) + return + } +} + +func TestCmdArgs(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "TestCmdArgs") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + const prog = ` +package main + +import ( + "fmt" + "os" +) + +func main() { + fmt.Printf("%q", os.Args) +} +` + src := filepath.Join(tmpdir, "main.go") + err = ioutil.WriteFile(src, []byte(prog), 0666) + if err != nil { + t.Fatal(err) + } + + exe := filepath.Join(tmpdir, "main.exe") + cmd := osexec.Command(testenv.GoToolPath(t), "build", "-o", exe, src) + cmd.Dir = tmpdir + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("building main.exe failed: %v\n%s", err, out) + } + + var cmds = []string{ + ``, + ` a b c`, + ` "`, + ` ""`, + ` """`, + ` "" a`, + ` "123"`, + ` \"123\"`, + ` \"123 456\"`, + ` \\"`, + ` \\\"`, + ` \\\\\"`, + ` \\\"x`, + ` """"\""\\\"`, + ` abc`, + ` \\\\\""x"""y z`, + "\tb\t\"x\ty\"", + ` "Брад" d e`, + // examples from https://msdn.microsoft.com/en-us/library/17w5ykft.aspx + ` "abc" d e`, + ` a\\b d"e f"g h`, + ` a\\\"b c d`, + ` a\\\\"b c" d e`, + // http://daviddeley.com/autohotkey/parameters/parameters.htm#WINARGV + // from 5.4 Examples + ` CallMeIshmael`, + ` "Call Me Ishmael"`, + ` Cal"l Me I"shmael`, + ` CallMe\"Ishmael`, + ` "CallMe\"Ishmael"`, + ` "Call Me Ishmael\\"`, + ` "CallMe\\\"Ishmael"`, + ` a\\\b`, + ` "a\\\b"`, + // from 5.5 Some Common Tasks + ` "\"Call Me Ishmael\""`, + ` "C:\TEST A\\"`, + ` "\"C:\TEST A\\\""`, + // from 5.6 The Microsoft Examples Explained + ` "a b c" d e`, + ` "ab\"c" "\\" d`, + ` a\\\b d"e f"g h`, + ` a\\\"b c d`, + ` a\\\\"b c" d e`, + // from 5.7 Double Double Quote Examples (pre 2008) + ` "a b c""`, + ` """CallMeIshmael""" b c`, + ` """Call Me Ishmael"""`, + ` """"Call Me Ishmael"" b c`, + } + for _, cmd := range cmds { + compareCommandLineToArgvWithSyscall(t, "test"+cmd) + compareCommandLineToArgvWithSyscall(t, `"cmd line"`+cmd) + compareCommandLineToArgvWithSyscall(t, exe+cmd) + + // test both syscall.EscapeArg and os.commandLineToArgv + args := os.CommandLineToArgv(exe + cmd) + out, err := osexec.Command(args[0], args[1:]...).CombinedOutput() + if err != nil { + t.Fatalf("running %q failed: %v\n%v", args, err, string(out)) + } + if want, have := fmt.Sprintf("%q", args), string(out); want != have { + t.Errorf("wrong output of executing %q: have %q want %q", args, have, want) + continue + } + } +} + +func findOneDriveDir() (string, error) { + // as per https://stackoverflow.com/questions/42519624/how-to-determine-location-of-onedrive-on-windows-7-and-8-in-c + const onedrivekey = `SOFTWARE\Microsoft\OneDrive` + k, err := registry.OpenKey(registry.CURRENT_USER, onedrivekey, registry.READ) + if err != nil { + return "", fmt.Errorf("OpenKey(%q) failed: %v", onedrivekey, err) + } + defer k.Close() + + path, _, err := k.GetStringValue("UserFolder") + if err != nil { + return "", fmt.Errorf("reading UserFolder failed: %v", err) + } + return path, nil +} + +// TestOneDrive verifies that OneDrive folder is a directory and not a symlink. +func TestOneDrive(t *testing.T) { + dir, err := findOneDriveDir() + if err != nil { + t.Skipf("Skipping, because we did not find OneDrive directory: %v", err) + } + testDirStats(t, dir) +} + +func TestWindowsDevNullFile(t *testing.T) { + testDevNullFile(t, "NUL", true) + testDevNullFile(t, "nul", true) + testDevNullFile(t, "Nul", true) + + f1, err := os.Open("NUL") + if err != nil { + t.Fatal(err) + } + defer f1.Close() + + fi1, err := f1.Stat() + if err != nil { + t.Fatal(err) + } + + f2, err := os.Open("nul") + if err != nil { + t.Fatal(err) + } + defer f2.Close() + + fi2, err := f2.Stat() + if err != nil { + t.Fatal(err) + } + + if !os.SameFile(fi1, fi2) { + t.Errorf(`"NUL" and "nul" are not the same file`) + } +} + +// TestSymlinkCreation verifies that creating a symbolic link +// works on Windows when developer mode is active. +// This is supported starting Windows 10 (1703, v10.0.14972). +func TestSymlinkCreation(t *testing.T) { + if !isWindowsDeveloperModeActive() { + t.Skip("Windows developer mode is not active") + } + + temp, err := ioutil.TempDir("", "TestSymlinkCreation") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(temp) + + dummyFile := filepath.Join(temp, "file") + err = ioutil.WriteFile(dummyFile, []byte(""), 0644) + if err != nil { + t.Fatal(err) + } + + linkFile := filepath.Join(temp, "link") + err = os.Symlink(dummyFile, linkFile) + if err != nil { + t.Fatal(err) + } +} + +// isWindowsDeveloperModeActive checks whether or not the developer mode is active on Windows 10. +// Returns false for prior Windows versions. +// see https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development +func isWindowsDeveloperModeActive() bool { + key, err := registry.OpenKey(registry.LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\AppModelUnlock", registry.READ) + if err != nil { + return false + } + + val, _, err := key.GetIntegerValue("AllowDevelopmentWithoutDevLicense") + if err != nil { + return false + } + + return val != 0 +} + +// TestStatOfInvalidName is regression test for issue #24999. +func TestStatOfInvalidName(t *testing.T) { + _, err := os.Stat("*.go") + if err == nil { + t.Fatal(`os.Stat("*.go") unexpectedly succeeded`) + } +} + +// findUnusedDriveLetter searches mounted drive list on the system +// (starting from Z: and ending at D:) for unused drive letter. +// It returns path to the found drive root directory (like Z:\) or error. +func findUnusedDriveLetter() (string, error) { + // Do not use A: and B:, because they are reserved for floppy drive. + // Do not use C:, because it is normally used for main drive. + for l := 'Z'; l >= 'D'; l-- { + p := string(l) + `:\` + _, err := os.Stat(p) + if os.IsNotExist(err) { + return p, nil + } + } + return "", errors.New("Could not find unused drive letter.") +} + +func TestRootDirAsTemp(t *testing.T) { + testenv.MustHaveExec(t) + + if os.Getenv("GO_WANT_HELPER_PROCESS") == "1" { + fmt.Print(os.TempDir()) + os.Exit(0) + } + + newtmp, err := findUnusedDriveLetter() + if err != nil { + t.Fatal(err) + } + + cmd := osexec.Command(os.Args[0], "-test.run=TestRootDirAsTemp") + cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, "GO_WANT_HELPER_PROCESS=1") + cmd.Env = append(cmd.Env, "TMP="+newtmp) + cmd.Env = append(cmd.Env, "TEMP="+newtmp) + output, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("Failed to spawn child process: %v %q", err, string(output)) + } + if want, have := newtmp, string(output); have != want { + t.Fatalf("unexpected child process output %q, want %q", have, want) + } +} + +func testReadlink(t *testing.T, path, want string) { + got, err := os.Readlink(path) + if err != nil { + t.Error(err) + return + } + if got != want { + t.Errorf(`Readlink(%q): got %q, want %q`, path, got, want) + } +} + +func mklink(t *testing.T, link, target string) { + output, err := osexec.Command("cmd", "/c", "mklink", link, target).CombinedOutput() + if err != nil { + t.Fatalf("failed to run mklink %v %v: %v %q", link, target, err, output) + } +} + +func mklinkj(t *testing.T, link, target string) { + output, err := osexec.Command("cmd", "/c", "mklink", "/J", link, target).CombinedOutput() + if err != nil { + t.Fatalf("failed to run mklink %v %v: %v %q", link, target, err, output) + } +} + +func mklinkd(t *testing.T, link, target string) { + output, err := osexec.Command("cmd", "/c", "mklink", "/D", link, target).CombinedOutput() + if err != nil { + t.Fatalf("failed to run mklink %v %v: %v %q", link, target, err, output) + } +} + +func TestWindowsReadlink(t *testing.T) { + tmpdir, err := ioutil.TempDir("", "TestWindowsReadlink") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + // Make sure tmpdir is not a symlink, otherwise tests will fail. + tmpdir, err = filepath.EvalSymlinks(tmpdir) + if err != nil { + t.Fatal(err) + } + + wd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + err = os.Chdir(tmpdir) + if err != nil { + t.Fatal(err) + } + defer os.Chdir(wd) + + vol := filepath.VolumeName(tmpdir) + output, err := osexec.Command("cmd", "/c", "mountvol", vol, "/L").CombinedOutput() + if err != nil { + t.Fatalf("failed to run mountvol %v /L: %v %q", vol, err, output) + } + ntvol := strings.Trim(string(output), " \n\r") + + dir := filepath.Join(tmpdir, "dir") + err = os.MkdirAll(dir, 0777) + if err != nil { + t.Fatal(err) + } + + absdirjlink := filepath.Join(tmpdir, "absdirjlink") + mklinkj(t, absdirjlink, dir) + testReadlink(t, absdirjlink, dir) + + ntdirjlink := filepath.Join(tmpdir, "ntdirjlink") + mklinkj(t, ntdirjlink, ntvol+absdirjlink[len(filepath.VolumeName(absdirjlink)):]) + testReadlink(t, ntdirjlink, absdirjlink) + + ntdirjlinktolink := filepath.Join(tmpdir, "ntdirjlinktolink") + mklinkj(t, ntdirjlinktolink, ntvol+absdirjlink[len(filepath.VolumeName(absdirjlink)):]) + testReadlink(t, ntdirjlinktolink, absdirjlink) + + mklinkj(t, "reldirjlink", "dir") + testReadlink(t, "reldirjlink", dir) // relative directory junction resolves to absolute path + + // Make sure we have sufficient privilege to run mklink command. + testenv.MustHaveSymlink(t) + + absdirlink := filepath.Join(tmpdir, "absdirlink") + mklinkd(t, absdirlink, dir) + testReadlink(t, absdirlink, dir) + + ntdirlink := filepath.Join(tmpdir, "ntdirlink") + mklinkd(t, ntdirlink, ntvol+absdirlink[len(filepath.VolumeName(absdirlink)):]) + testReadlink(t, ntdirlink, absdirlink) + + mklinkd(t, "reldirlink", "dir") + testReadlink(t, "reldirlink", "dir") + + file := filepath.Join(tmpdir, "file") + err = ioutil.WriteFile(file, []byte(""), 0666) + if err != nil { + t.Fatal(err) + } + + filelink := filepath.Join(tmpdir, "filelink") + mklink(t, filelink, file) + testReadlink(t, filelink, file) + + linktofilelink := filepath.Join(tmpdir, "linktofilelink") + mklink(t, linktofilelink, ntvol+filelink[len(filepath.VolumeName(filelink)):]) + testReadlink(t, linktofilelink, filelink) + + mklink(t, "relfilelink", "file") + testReadlink(t, "relfilelink", "file") +} + +// os.Mkdir(os.DevNull) fails. +func TestMkdirDevNull(t *testing.T) { + err := os.Mkdir(os.DevNull, 777) + oserr, ok := err.(*os.PathError) + if !ok { + t.Fatalf("error (%T) is not *os.PathError", err) + } + errno, ok := oserr.Err.(syscall.Errno) + if !ok { + t.Fatalf("error (%T) is not syscall.Errno", oserr) + } + if errno != syscall.ENOTDIR { + t.Fatalf("error %d is not syscall.ENOTDIR", errno) + } +} diff --git a/libgo/go/os/path.go b/libgo/go/os/path.go index 9d7ecad7929..ba43ea35254 100644 --- a/libgo/go/os/path.go +++ b/libgo/go/os/path.go @@ -58,9 +58,6 @@ func MkdirAll(path string, perm FileMode) error { return nil } -// removeAllTestHook is a hook for testing. -var removeAllTestHook = func(err error) error { return err } - // RemoveAll removes path and any children it contains. // It removes everything it can but returns the first error // it encounters. If the path does not exist, RemoveAll diff --git a/libgo/go/os/path_unix.go b/libgo/go/os/path_unix.go index 4c97f39c960..6ef6560dd40 100644 --- a/libgo/go/os/path_unix.go +++ b/libgo/go/os/path_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package os diff --git a/libgo/go/os/path_windows_test.go b/libgo/go/os/path_windows_test.go index f1745ad132e..862b4043624 100644 --- a/libgo/go/os/path_windows_test.go +++ b/libgo/go/os/path_windows_test.go @@ -74,3 +74,18 @@ func TestMkdirAllExtendedLength(t *testing.T) { t.Fatalf("MkdirAll(%q) should have failed, but did not", path) } } + +func TestOpenRootSlash(t *testing.T) { + tests := []string{ + `/`, + `\`, + } + + for _, test := range tests { + dir, err := os.Open(test) + if err != nil { + t.Fatalf("Open(%q) failed: %v", test, err) + } + dir.Close() + } +} diff --git a/libgo/go/os/pipe_bsd.go b/libgo/go/os/pipe_bsd.go index dc4c951a286..0d2d82feb95 100644 --- a/libgo/go/os/pipe_bsd.go +++ b/libgo/go/os/pipe_bsd.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly js,wasm nacl solaris +// +build aix darwin dragonfly js,wasm solaris package os diff --git a/libgo/go/os/pipe_test.go b/libgo/go/os/pipe_test.go index 4c53bc985d2..2e93e3946af 100644 --- a/libgo/go/os/pipe_test.go +++ b/libgo/go/os/pipe_test.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Test broken pipes on Unix systems. -// +build !plan9,!nacl,!js +// +build !plan9,!js package os_test @@ -428,7 +428,7 @@ func TestFdReadRace(t *testing.T) { go func() { defer wg.Done() var buf [10]byte - r.SetReadDeadline(time.Now().Add(time.Second)) + r.SetReadDeadline(time.Now().Add(time.Minute)) c <- true if _, err := r.Read(buf[:]); os.IsTimeout(err) { t.Error("read timed out") diff --git a/libgo/go/os/rawconn_test.go b/libgo/go/os/rawconn_test.go index 820150d959b..2554f5b0878 100644 --- a/libgo/go/os/rawconn_test.go +++ b/libgo/go/os/rawconn_test.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Test use of raw connections. -// +build !plan9,!nacl,!js +// +build !plan9,!js package os_test diff --git a/libgo/go/os/removeall_at.go b/libgo/go/os/removeall_at.go index 377aa49c91e..afee01d7935 100644 --- a/libgo/go/os/removeall_at.go +++ b/libgo/go/os/removeall_at.go @@ -153,7 +153,6 @@ func removeAllFrom(parent *File, base string) error { // Remove the directory itself. unlinkError := unix.Unlinkat(parentFd, base, unix.AT_REMOVEDIR) - unlinkError = removeAllTestHook(unlinkError) if unlinkError == nil || IsNotExist(unlinkError) { return nil } diff --git a/libgo/go/os/removeall_noat.go b/libgo/go/os/removeall_noat.go index cf26bdb2161..fb9b45f7f1d 100644 --- a/libgo/go/os/removeall_noat.go +++ b/libgo/go/os/removeall_noat.go @@ -8,6 +8,7 @@ package os import ( "io" + "runtime" "syscall" ) @@ -124,10 +125,16 @@ func removeAll(path string) error { // Remove directory. err1 := Remove(path) - err1 = removeAllTestHook(err1) if err1 == nil || IsNotExist(err1) { return nil } + if runtime.GOOS == "windows" && IsPermission(err1) { + if fs, err := Stat(path); err == nil { + if err = Chmod(path, FileMode(0200|int(fs.Mode()))); err == nil { + err1 = Remove(path) + } + } + } if err == nil { err = err1 } diff --git a/libgo/go/os/removeall_test.go b/libgo/go/os/removeall_test.go index 4d556f977e4..8a71f687ed0 100644 --- a/libgo/go/os/removeall_test.go +++ b/libgo/go/os/removeall_test.go @@ -5,7 +5,6 @@ package os_test import ( - "errors" "fmt" "io/ioutil" . "os" @@ -289,7 +288,7 @@ func TestRemoveReadOnlyDir(t *testing.T) { // Issue #29983. func TestRemoveAllButReadOnlyAndPathError(t *testing.T) { switch runtime.GOOS { - case "nacl", "js", "windows": + case "js", "windows": t.Skipf("skipping test on %s", runtime.GOOS) } @@ -379,7 +378,7 @@ func TestRemoveAllButReadOnlyAndPathError(t *testing.T) { func TestRemoveUnreadableDir(t *testing.T) { switch runtime.GOOS { - case "nacl", "js", "windows": + case "js": t.Skipf("skipping test on %s", runtime.GOOS) } @@ -413,14 +412,6 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) { t.Skip("skipping in short mode") } - defer func(oldHook func(error) error) { - *RemoveAllTestHook = oldHook - }(*RemoveAllTestHook) - - *RemoveAllTestHook = func(err error) error { - return errors.New("error from RemoveAllTestHook") - } - tmpDir, err := ioutil.TempDir("", "TestRemoveAll-") if err != nil { t.Fatal(err) @@ -429,7 +420,7 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) { path := filepath.Join(tmpDir, "_TestRemoveAllWithMoreErrorThanReqSize_") - // Make directory with 1025 files and remove. + // Make directory with 1025 read-only files. if err := MkdirAll(path, 0777); err != nil { t.Fatalf("MkdirAll %q: %s", path, err) } @@ -442,13 +433,38 @@ func TestRemoveAllWithMoreErrorThanReqSize(t *testing.T) { fd.Close() } - // This call should not hang - if err := RemoveAll(path); err == nil { - t.Fatal("Want error from RemoveAllTestHook, got nil") + // Make the parent directory read-only. On some platforms, this is what + // prevents os.Remove from removing the files within that directory. + if err := Chmod(path, 0555); err != nil { + t.Fatal(err) } + defer Chmod(path, 0755) - // We hook to inject error, but the actual files must be deleted - if _, err := Lstat(path); err == nil { - t.Fatal("directory must be deleted even with removeAllTetHook run") + // This call should not hang, even on a platform that disallows file deletion + // from read-only directories. + err = RemoveAll(path) + + if Getuid() == 0 { + // On many platforms, root can remove files from read-only directories. + return + } + if err == nil { + if runtime.GOOS == "windows" { + // Marking a directory as read-only in Windows does not prevent the RemoveAll + // from creating or removing files within it. + return + } + t.Fatal("RemoveAll() = nil; want error") + } + + dir, err := Open(path) + if err != nil { + t.Fatal(err) + } + defer dir.Close() + + names, _ := dir.Readdirnames(1025) + if len(names) < 1025 { + t.Fatalf("RemoveAll() unexpectedly removed %d read-only files from that directory", 1025-len(names)) } } diff --git a/libgo/go/os/signal/doc.go b/libgo/go/os/signal/doc.go index 16f49c7ab8b..2229d36954f 100644 --- a/libgo/go/os/signal/doc.go +++ b/libgo/go/os/signal/doc.go @@ -211,6 +211,14 @@ will cause os.Interrupt to be sent on the channel, and the program will not exit. If Reset is called, or Stop is called on all channels passed to Notify, then the default behavior will be restored. +Additionally, if Notify is called, and Windows sends CTRL_CLOSE_EVENT, +CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT to the process, Notify will +return syscall.SIGTERM. Unlike Control-C and Control-Break, Notify does +not change process behavior when either CTRL_CLOSE_EVENT, +CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT is received - the process will +still get terminated unless it exits. But receiving syscall.SIGTERM will +give the process an opportunity to clean up before termination. + Plan 9 On Plan 9, signals have type syscall.Note, which is a string. Calling diff --git a/libgo/go/os/signal/signal.go b/libgo/go/os/signal/signal.go index a0eba0d50fb..136dd9cc97f 100644 --- a/libgo/go/os/signal/signal.go +++ b/libgo/go/os/signal/signal.go @@ -92,6 +92,15 @@ func Ignored(sig os.Signal) bool { return sn >= 0 && signalIgnored(sn) } +var ( + // watchSignalLoopOnce guards calling the conditionally + // initialized watchSignalLoop. If watchSignalLoop is non-nil, + // it will be run in a goroutine lazily once Notify is invoked. + // See Issue 21576. + watchSignalLoopOnce sync.Once + watchSignalLoop func() +) + // Notify causes package signal to relay incoming signals to c. // If no signals are provided, all incoming signals will be relayed to c. // Otherwise, just the provided signals will. @@ -113,6 +122,12 @@ func Notify(c chan<- os.Signal, sig ...os.Signal) { panic("os/signal: Notify using nil channel") } + watchSignalLoopOnce.Do(func() { + if watchSignalLoop != nil { + go watchSignalLoop() + } + }) + handlers.Lock() defer handlers.Unlock() diff --git a/libgo/go/os/signal/signal_plan9.go b/libgo/go/os/signal/signal_plan9.go index a1eb68855ed..8408607c7fa 100644 --- a/libgo/go/os/signal/signal_plan9.go +++ b/libgo/go/os/signal/signal_plan9.go @@ -20,7 +20,8 @@ func signal_recv() string func init() { signal_enable(0) // first call - initialize - go loop() + + watchSignalLoop = loop } func loop() { diff --git a/libgo/go/os/signal/signal_test.go b/libgo/go/os/signal/signal_test.go index fe5893e5a3c..0708d4c188a 100644 --- a/libgo/go/os/signal/signal_test.go +++ b/libgo/go/os/signal/signal_test.go @@ -22,15 +22,51 @@ import ( "time" ) +var testDeadline time.Time + +func TestMain(m *testing.M) { + flag.Parse() + + // TODO(golang.org/issue/28135): Remove this setup and use t.Deadline instead. + timeoutFlag := flag.Lookup("test.timeout") + if timeoutFlag != nil { + if d := timeoutFlag.Value.(flag.Getter).Get().(time.Duration); d != 0 { + testDeadline = time.Now().Add(d) + } + } + + os.Exit(m.Run()) +} + func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) { - select { - case s := <-c: - if s != sig { - t.Fatalf("signal was %v, want %v", s, sig) + waitSig1(t, c, sig, false) +} +func waitSigAll(t *testing.T, c <-chan os.Signal, sig os.Signal) { + waitSig1(t, c, sig, true) +} + +func waitSig1(t *testing.T, c <-chan os.Signal, sig os.Signal, all bool) { + // Sleep multiple times to give the kernel more tries to + // deliver the signal. + for i := 0; i < 10; i++ { + select { + case s := <-c: + // If the caller notified for all signals on + // c, filter out SIGURG, which is used for + // runtime preemption and can come at + // unpredictable times. + if all && s == syscall.SIGURG { + continue + } + if s != sig { + t.Fatalf("signal was %v, want %v", s, sig) + } + return + + case <-time.After(100 * time.Millisecond): } - case <-time.After(1 * time.Second): - t.Fatalf("timeout waiting for %v", sig) } + t.Fatalf("timeout waiting for %v", sig) } // Test that basic signal handling works. @@ -45,24 +81,26 @@ func TestSignal(t *testing.T) { syscall.Kill(syscall.Getpid(), syscall.SIGHUP) waitSig(t, c, syscall.SIGHUP) - // Ask for everything we can get. - c1 := make(chan os.Signal, 1) + // Ask for everything we can get. The buffer size has to be + // more than 1, since the runtime might send SIGURG signals. + // Using 10 is arbitrary. + c1 := make(chan os.Signal, 10) Notify(c1) // Send this process a SIGWINCH t.Logf("sigwinch...") syscall.Kill(syscall.Getpid(), syscall.SIGWINCH) - waitSig(t, c1, syscall.SIGWINCH) + waitSigAll(t, c1, syscall.SIGWINCH) // Send two more SIGHUPs, to make sure that // they get delivered on c1 and that not reading // from c does not block everything. t.Logf("sighup...") syscall.Kill(syscall.Getpid(), syscall.SIGHUP) - waitSig(t, c1, syscall.SIGHUP) + waitSigAll(t, c1, syscall.SIGHUP) t.Logf("sighup...") syscall.Kill(syscall.Getpid(), syscall.SIGHUP) - waitSig(t, c1, syscall.SIGHUP) + waitSigAll(t, c1, syscall.SIGHUP) // The first SIGHUP should be waiting for us on c. waitSig(t, c, syscall.SIGHUP) @@ -268,7 +306,15 @@ func TestStop(t *testing.T) { if sig == syscall.SIGWINCH || (sig == syscall.SIGHUP && *sendUncaughtSighup == 1) { syscall.Kill(syscall.Getpid(), sig) } - time.Sleep(100 * time.Millisecond) + + // The kernel will deliver a signal as a thread returns + // from a syscall. If the only active thread is sleeping, + // and the system is busy, the kernel may not get around + // to waking up a thread to catch the signal. + // We try splitting up the sleep to give the kernel + // another chance to deliver the signal. + time.Sleep(50 * time.Millisecond) + time.Sleep(50 * time.Millisecond) // Ask for signal c := make(chan os.Signal, 1) @@ -280,10 +326,11 @@ func TestStop(t *testing.T) { waitSig(t, c, sig) Stop(c) + time.Sleep(50 * time.Millisecond) select { case s := <-c: t.Fatalf("unexpected signal %v", s) - case <-time.After(100 * time.Millisecond): + case <-time.After(50 * time.Millisecond): // nothing to read - good } @@ -294,10 +341,11 @@ func TestStop(t *testing.T) { syscall.Kill(syscall.Getpid(), sig) } + time.Sleep(50 * time.Millisecond) select { case s := <-c: t.Fatalf("unexpected signal %v", s) - case <-time.After(100 * time.Millisecond): + case <-time.After(50 * time.Millisecond): // nothing to read - good } } @@ -374,9 +422,26 @@ func TestAtomicStop(t *testing.T) { testenv.MustHaveExec(t) + // Call Notify for SIGINT before starting the child process. + // That ensures that SIGINT is not ignored for the child. + // This is necessary because if SIGINT is ignored when a + // Go program starts, then it remains ignored, and closing + // the last notification channel for SIGINT will switch it + // back to being ignored. In that case the assumption of + // atomicStopTestProgram, that it will either die from SIGINT + // or have it be reported, breaks down, as there is a third + // option: SIGINT might be ignored. + cs := make(chan os.Signal, 1) + Notify(cs, syscall.SIGINT) + defer Stop(cs) + const execs = 10 for i := 0; i < execs; i++ { - cmd := exec.Command(os.Args[0], "-test.run=TestAtomicStop") + timeout := "0" + if !testDeadline.IsZero() { + timeout = testDeadline.Sub(time.Now()).String() + } + cmd := exec.Command(os.Args[0], "-test.run=TestAtomicStop", "-test.timeout="+timeout) cmd.Env = append(os.Environ(), "GO_TEST_ATOMIC_STOP=1") out, err := cmd.CombinedOutput() if err == nil { @@ -414,7 +479,21 @@ func TestAtomicStop(t *testing.T) { // It tries to trigger a signal delivery race. This function should // either catch a signal or die from it. func atomicStopTestProgram() { + // This test won't work if SIGINT is ignored here. + if Ignored(syscall.SIGINT) { + fmt.Println("SIGINT is ignored") + os.Exit(1) + } + const tries = 10 + + timeout := 2 * time.Second + if !testDeadline.IsZero() { + // Give each try an equal slice of the deadline, with one slice to spare for + // cleanup. + timeout = testDeadline.Sub(time.Now()) / (tries + 1) + } + pid := syscall.Getpid() printed := false for i := 0; i < tries; i++ { @@ -437,7 +516,7 @@ func atomicStopTestProgram() { select { case <-cs: - case <-time.After(2 * time.Second): + case <-time.After(timeout): if !printed { fmt.Print("lost signal on tries:") printed = true @@ -453,3 +532,52 @@ func atomicStopTestProgram() { os.Exit(0) } + +func TestTime(t *testing.T) { + // Test that signal works fine when we are in a call to get time, + // which on some platforms is using VDSO. See issue #34391. + dur := 3 * time.Second + if testing.Short() { + dur = 100 * time.Millisecond + } + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) + done := make(chan bool) + finished := make(chan bool) + go func() { + sig := make(chan os.Signal, 1) + Notify(sig, syscall.SIGUSR1) + defer Stop(sig) + Loop: + for { + select { + case <-sig: + case <-done: + break Loop + } + } + finished <- true + }() + go func() { + Loop: + for { + select { + case <-done: + break Loop + default: + syscall.Kill(syscall.Getpid(), syscall.SIGUSR1) + runtime.Gosched() + } + } + finished <- true + }() + t0 := time.Now() + for t1 := t0; t1.Sub(t0) < dur; t1 = time.Now() { + } // hammering on getting time + close(done) + <-finished + <-finished + // When run with 'go test -cpu=1,2,4' SIGUSR1 from this test can slip + // into subsequent TestSignal() causing failure. + // Sleep for a while to reduce the possibility of the failure. + time.Sleep(10 * time.Millisecond) +} diff --git a/libgo/go/os/signal/signal_unix.go b/libgo/go/os/signal/signal_unix.go index 8ed0cde0759..532c0b586cb 100644 --- a/libgo/go/os/signal/signal_unix.go +++ b/libgo/go/os/signal/signal_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package signal @@ -26,7 +26,8 @@ func loop() { func init() { signal_enable(0) // first call - initialize - go loop() + + watchSignalLoop = loop } const ( diff --git a/libgo/go/os/stat_js.go b/libgo/go/os/stat_js.go new file mode 100644 index 00000000000..8d20ccddfcc --- /dev/null +++ b/libgo/go/os/stat_js.go @@ -0,0 +1,54 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build js,wasm + +package os + +import ( + "syscall" + "time" +) + +func fillFileStatFromSys(fs *fileStat, name string) { + fs.name = basename(name) + 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 { + case syscall.S_IFBLK: + fs.mode |= ModeDevice + case syscall.S_IFCHR: + fs.mode |= ModeDevice | ModeCharDevice + case syscall.S_IFDIR: + fs.mode |= ModeDir + case syscall.S_IFIFO: + fs.mode |= ModeNamedPipe + case syscall.S_IFLNK: + fs.mode |= ModeSymlink + case syscall.S_IFREG: + // nothing to do + case syscall.S_IFSOCK: + fs.mode |= ModeSocket + } + if fs.sys.Mode&syscall.S_ISGID != 0 { + fs.mode |= ModeSetgid + } + if fs.sys.Mode&syscall.S_ISUID != 0 { + fs.mode |= ModeSetuid + } + if fs.sys.Mode&syscall.S_ISVTX != 0 { + fs.mode |= ModeSticky + } +} + +func timespecToTime(sec, nsec int64) time.Time { + return time.Unix(sec, nsec) +} + +// For testing. +func atime(fi FileInfo) time.Time { + st := fi.Sys().(*syscall.Stat_t) + return timespecToTime(st.Atime, st.AtimeNsec) +} diff --git a/libgo/go/os/stat_nacljs.go b/libgo/go/os/stat_nacljs.go deleted file mode 100644 index f14add8674a..00000000000 --- a/libgo/go/os/stat_nacljs.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build js,wasm nacl - -package os - -import ( - "syscall" - "time" -) - -func fillFileStatFromSys(fs *fileStat, name string) { - fs.name = basename(name) - 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 { - case syscall.S_IFBLK: - fs.mode |= ModeDevice - case syscall.S_IFCHR: - fs.mode |= ModeDevice | ModeCharDevice - case syscall.S_IFDIR: - fs.mode |= ModeDir - case syscall.S_IFIFO: - fs.mode |= ModeNamedPipe - case syscall.S_IFLNK: - fs.mode |= ModeSymlink - case syscall.S_IFREG: - // nothing to do - case syscall.S_IFSOCK: - fs.mode |= ModeSocket - } - if fs.sys.Mode&syscall.S_ISGID != 0 { - fs.mode |= ModeSetgid - } - if fs.sys.Mode&syscall.S_ISUID != 0 { - fs.mode |= ModeSetuid - } - if fs.sys.Mode&syscall.S_ISVTX != 0 { - fs.mode |= ModeSticky - } -} - -func timespecToTime(sec, nsec int64) time.Time { - return time.Unix(sec, nsec) -} - -// For testing. -func atime(fi FileInfo) time.Time { - st := fi.Sys().(*syscall.Stat_t) - return timespecToTime(st.Atime, st.AtimeNsec) -} diff --git a/libgo/go/os/stat_unix.go b/libgo/go/os/stat_unix.go index 2bdbc4e2357..d489ad18f15 100644 --- a/libgo/go/os/stat_unix.go +++ b/libgo/go/os/stat_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package os diff --git a/libgo/go/os/sys_bsd.go b/libgo/go/os/sys_bsd.go index d820be2ab67..b1698f5d4c7 100644 --- a/libgo/go/os/sys_bsd.go +++ b/libgo/go/os/sys_bsd.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin dragonfly freebsd js,wasm nacl netbsd openbsd +// +build darwin dragonfly freebsd js,wasm netbsd openbsd package os diff --git a/libgo/go/os/sys_nacl.go b/libgo/go/os/sys_nacl.go deleted file mode 100644 index 07907c84771..00000000000 --- a/libgo/go/os/sys_nacl.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package os - -// supportsCloseOnExec reports whether the platform supports the -// O_CLOEXEC flag. -const supportsCloseOnExec = false diff --git a/libgo/go/os/timeout_test.go b/libgo/go/os/timeout_test.go index 5d7ea7ea29c..0fe03fa517f 100644 --- a/libgo/go/os/timeout_test.go +++ b/libgo/go/os/timeout_test.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !nacl // +build !js // +build !plan9 // +build !windows diff --git a/libgo/go/os/user/cgo_lookup_unix.go b/libgo/go/os/user/cgo_lookup_unix.go index 5872d1165a4..eb6ab505ce8 100644 --- a/libgo/go/os/user/cgo_lookup_unix.go +++ b/libgo/go/os/user/cgo_lookup_unix.go @@ -118,10 +118,6 @@ func buildUser(pwd *syscall.Passwd) *User { return u } -func currentGroup() (*Group, error) { - return lookupUnixGid(syscall.Getgid()) -} - func lookupGroup(groupname string) (*Group, error) { var grp syscall.Group var result *syscall.Group diff --git a/libgo/go/os/user/lookup_stubs.go b/libgo/go/os/user/lookup_stubs.go index d3acbddd180..178d814dda0 100644 --- a/libgo/go/os/user/lookup_stubs.go +++ b/libgo/go/os/user/lookup_stubs.go @@ -35,15 +35,8 @@ func current() (*User, error) { Name: "", // ignored HomeDir: homeDir, } - // On NaCL and Android, return a dummy user instead of failing. + // On Android, return a dummy user instead of failing. switch runtime.GOOS { - case "nacl": - if u.Uid == "" { - u.Uid = "1" - } - if u.Username == "" { - u.Username = "nacl" - } case "android": if u.Uid == "" { u.Uid = "1" @@ -72,7 +65,7 @@ func current() (*User, error) { func listGroups(*User) ([]string, error) { if runtime.GOOS == "android" || runtime.GOOS == "aix" { - return nil, errors.New(fmt.Sprintf("user: GroupIds not implemented on %s", runtime.GOOS)) + return nil, fmt.Errorf("user: GroupIds not implemented on %s", runtime.GOOS) } return nil, errors.New("user: GroupIds requires cgo") } diff --git a/libgo/go/os/user/lookup_unix.go b/libgo/go/os/user/lookup_unix.go index ba914f65900..0f5e82d86f8 100644 --- a/libgo/go/os/user/lookup_unix.go +++ b/libgo/go/os/user/lookup_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm !android,linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm !android,linux netbsd openbsd solaris // +build !cgo osusergo package user diff --git a/libgo/go/os/user/lookup_unix_test.go b/libgo/go/os/user/lookup_unix_test.go index 65fe0656de6..72d3b475344 100644 --- a/libgo/go/os/user/lookup_unix_test.go +++ b/libgo/go/os/user/lookup_unix_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd !android,linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd !android,linux netbsd openbsd solaris // +build !cgo package user diff --git a/libgo/go/os/user/lookup_windows.go b/libgo/go/os/user/lookup_windows.go index 7499f6a470b..faaddd2341f 100644 --- a/libgo/go/os/user/lookup_windows.go +++ b/libgo/go/os/user/lookup_windows.go @@ -44,11 +44,7 @@ func lookupFullNameServer(servername, username string) (string, error) { } defer syscall.NetApiBufferFree(p) i := (*syscall.UserInfo10)(unsafe.Pointer(p)) - if i.FullName == nil { - return "", nil - } - name := syscall.UTF16ToString((*[1024]uint16)(unsafe.Pointer(i.FullName))[:]) - return name, nil + return windows.UTF16PtrToString(i.FullName, 1024), nil } func lookupFullName(domain, username, domainAndUser string) (string, error) { @@ -165,14 +161,13 @@ func listGroupsForUsernameAndDomain(username, domain string) ([]string, error) { if entriesRead == 0 { return nil, fmt.Errorf("listGroupsForUsernameAndDomain: NetUserGetLocalGroups() returned an empty list for domain: %s, username: %s", domain, username) } - entries := (*[1024]windows.LocalGroupUserInfo0)(unsafe.Pointer(p0))[:entriesRead] + entries := (*[1024]windows.LocalGroupUserInfo0)(unsafe.Pointer(p0))[:entriesRead:entriesRead] var sids []string for _, entry := range entries { if entry.Name == nil { continue } - name := syscall.UTF16ToString((*[1024]uint16)(unsafe.Pointer(entry.Name))[:]) - sid, err := lookupGroupName(name) + sid, err := lookupGroupName(windows.UTF16PtrToString(entry.Name, 1024)) if err != nil { return nil, err } diff --git a/libgo/go/os/wait_unimp.go b/libgo/go/os/wait_unimp.go index 2551f21f388..cb875abdbb4 100644 --- a/libgo/go/os/wait_unimp.go +++ b/libgo/go/os/wait_unimp.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly hurd js,wasm nacl netbsd openbsd solaris +// +build aix darwin dragonfly hurd js,wasm netbsd openbsd solaris package os diff --git a/libgo/go/path/example_test.go b/libgo/go/path/example_test.go index 77fbfa99b73..30777292262 100644 --- a/libgo/go/path/example_test.go +++ b/libgo/go/path/example_test.go @@ -104,11 +104,15 @@ func ExampleMatch() { } func ExampleSplit() { - fmt.Println(path.Split("static/myfile.css")) - fmt.Println(path.Split("myfile.css")) - fmt.Println(path.Split("")) + split := func(s string) { + dir, file := path.Split(s) + fmt.Printf("path.Split(%q) = dir: %q, file: %q\n", s, dir, file) + } + split("static/myfile.css") + split("myfile.css") + split("") // Output: - // static/ myfile.css - // myfile.css - // + // path.Split("static/myfile.css") = dir: "static/", file: "myfile.css" + // path.Split("myfile.css") = dir: "", file: "myfile.css" + // path.Split("") = dir: "", file: "" } diff --git a/libgo/go/path/filepath/path.go b/libgo/go/path/filepath/path.go index aba1717e7d5..26f18331892 100644 --- a/libgo/go/path/filepath/path.go +++ b/libgo/go/path/filepath/path.go @@ -201,11 +201,13 @@ func Split(path string) (dir, file string) { return path[:i+1], path[i+1:] } -// Join joins any number of path elements into a single path, adding -// a Separator if necessary. Join calls Clean on the result; in particular, -// all empty strings are ignored. -// On Windows, the result is a UNC path if and only if the first path -// element is a UNC path. +// Join joins any number of path elements into a single path, +// separating them with an OS specific Separator. Empty elements +// are ignored. The result is Cleaned. However, if the argument +// list is empty or all its elements are empty, Join returns +// an empty string. +// On Windows, the result will only be a UNC path if the first +// non-empty element is a UNC path. func Join(elem ...string) string { return join(elem) } diff --git a/libgo/go/path/filepath/path_unix.go b/libgo/go/path/filepath/path_unix.go index fa0e40d1f09..57341ed7d90 100644 --- a/libgo/go/path/filepath/path_unix.go +++ b/libgo/go/path/filepath/path_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package filepath diff --git a/libgo/go/path/path.go b/libgo/go/path/path.go index 5c905110a1b..c513114b4d7 100644 --- a/libgo/go/path/path.go +++ b/libgo/go/path/path.go @@ -149,9 +149,11 @@ func Split(path string) (dir, file string) { return path[:i+1], path[i+1:] } -// Join joins any number of path elements into a single path, adding a -// separating slash if necessary. The result is Cleaned; in particular, -// all empty strings are ignored. +// Join joins any number of path elements into a single path, +// separating them with slashes. Empty elements are ignored. +// The result is Cleaned. However, if the argument list is +// empty or all its elements are empty, Join returns +// an empty string. func Join(elem ...string) string { for i, e := range elem { if e != "" { diff --git a/libgo/go/plugin/plugin.go b/libgo/go/plugin/plugin.go index 5506e956925..4a524bfa3f0 100644 --- a/libgo/go/plugin/plugin.go +++ b/libgo/go/plugin/plugin.go @@ -13,7 +13,7 @@ // already part of the program are called. The main function is not run. // A plugin is only initialized once, and cannot be closed. // -// Currently plugins are only supported on Linux and macOS. +// Currently plugins are only supported on Linux, FreeBSD, and macOS. // Please report any issues. package plugin diff --git a/libgo/go/plugin/plugin_dlopen.go b/libgo/go/plugin/plugin_dlopen.go index 3abfb607493..8342267a66b 100644 --- a/libgo/go/plugin/plugin_dlopen.go +++ b/libgo/go/plugin/plugin_dlopen.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build linux,cgo darwin,cgo hurd,cgo +// +build linux,cgo darwin,cgo freebsd,cgo hurd,cgo package plugin diff --git a/libgo/go/plugin/plugin_stubs.go b/libgo/go/plugin/plugin_stubs.go index 412d103c14f..0f9adb77b84 100644 --- a/libgo/go/plugin/plugin_stubs.go +++ b/libgo/go/plugin/plugin_stubs.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !hurd !linux,!darwin !cgo +// +build !hurd,!linux,!freebsd,!darwin !cgo package plugin diff --git a/libgo/go/plugin/plugin_test.go b/libgo/go/plugin/plugin_test.go index b334c5cf0ec..30b79edaad7 100644 --- a/libgo/go/plugin/plugin_test.go +++ b/libgo/go/plugin/plugin_test.go @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !nacl // +build !linux linux,!arm64 package plugin_test diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index 6e06485f018..c9ed0a9e52d 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -787,6 +787,7 @@ type Loopy interface{} var loop1, loop2 Loop var loopy1, loopy2 Loopy +var cycleMap1, cycleMap2, cycleMap3 map[string]interface{} func init() { loop1 = &loop2 @@ -794,6 +795,13 @@ func init() { loopy1 = &loopy2 loopy2 = &loopy1 + + cycleMap1 = map[string]interface{}{} + cycleMap1["cycle"] = cycleMap1 + cycleMap2 = map[string]interface{}{} + cycleMap2["cycle"] = cycleMap2 + cycleMap3 = map[string]interface{}{} + cycleMap3["different"] = cycleMap3 } var deepEqualTests = []DeepEqualTest{ @@ -860,6 +868,8 @@ var deepEqualTests = []DeepEqualTest{ {&loop1, &loop2, true}, {&loopy1, &loopy1, true}, {&loopy1, &loopy2, true}, + {&cycleMap1, &cycleMap2, true}, + {&cycleMap1, &cycleMap3, false}, } func TestDeepEqual(t *testing.T) { @@ -868,7 +878,7 @@ func TestDeepEqual(t *testing.T) { test.b = test.a } if r := DeepEqual(test.a, test.b); r != test.eq { - t.Errorf("DeepEqual(%v, %v) = %v, want %v", test.a, test.b, r, test.eq) + t.Errorf("DeepEqual(%#v, %#v) = %v, want %v", test.a, test.b, r, test.eq) } } } @@ -3634,6 +3644,13 @@ type MyRunes []int32 type MyFunc func() type MyByte byte +type IntChan chan int +type IntChanRecv <-chan int +type IntChanSend chan<- int +type BytesChan chan []byte +type BytesChanRecv <-chan []byte +type BytesChanSend chan<- []byte + var convertTests = []struct { in Value out Value @@ -3995,10 +4012,6 @@ var convertTests = []struct { {V((***byte)(nil)), V((***byte)(nil))}, {V((***int32)(nil)), V((***int32)(nil))}, {V((***int64)(nil)), V((***int64)(nil))}, - {V((chan int)(nil)), V((<-chan int)(nil))}, - {V((chan int)(nil)), V((chan<- int)(nil))}, - {V((chan string)(nil)), V((<-chan string)(nil))}, - {V((chan string)(nil)), V((chan<- string)(nil))}, {V((chan byte)(nil)), V((chan byte)(nil))}, {V((chan MyByte)(nil)), V((chan MyByte)(nil))}, {V((map[int]bool)(nil)), V((map[int]bool)(nil))}, @@ -4010,6 +4023,40 @@ var convertTests = []struct { {V(new(io.Reader)), V(new(io.Reader))}, {V(new(io.Writer)), V(new(io.Writer))}, + // channels + {V(IntChan(nil)), V((chan<- int)(nil))}, + {V(IntChan(nil)), V((<-chan int)(nil))}, + {V((chan int)(nil)), V(IntChanRecv(nil))}, + {V((chan int)(nil)), V(IntChanSend(nil))}, + {V(IntChanRecv(nil)), V((<-chan int)(nil))}, + {V((<-chan int)(nil)), V(IntChanRecv(nil))}, + {V(IntChanSend(nil)), V((chan<- int)(nil))}, + {V((chan<- int)(nil)), V(IntChanSend(nil))}, + {V(IntChan(nil)), V((chan int)(nil))}, + {V((chan int)(nil)), V(IntChan(nil))}, + {V((chan int)(nil)), V((<-chan int)(nil))}, + {V((chan int)(nil)), V((chan<- int)(nil))}, + {V(BytesChan(nil)), V((chan<- []byte)(nil))}, + {V(BytesChan(nil)), V((<-chan []byte)(nil))}, + {V((chan []byte)(nil)), V(BytesChanRecv(nil))}, + {V((chan []byte)(nil)), V(BytesChanSend(nil))}, + {V(BytesChanRecv(nil)), V((<-chan []byte)(nil))}, + {V((<-chan []byte)(nil)), V(BytesChanRecv(nil))}, + {V(BytesChanSend(nil)), V((chan<- []byte)(nil))}, + {V((chan<- []byte)(nil)), V(BytesChanSend(nil))}, + {V(BytesChan(nil)), V((chan []byte)(nil))}, + {V((chan []byte)(nil)), V(BytesChan(nil))}, + {V((chan []byte)(nil)), V((<-chan []byte)(nil))}, + {V((chan []byte)(nil)), V((chan<- []byte)(nil))}, + + // cannot convert other instances (channels) + {V(IntChan(nil)), V(IntChan(nil))}, + {V(IntChanRecv(nil)), V(IntChanRecv(nil))}, + {V(IntChanSend(nil)), V(IntChanSend(nil))}, + {V(BytesChan(nil)), V(BytesChan(nil))}, + {V(BytesChanRecv(nil)), V(BytesChanRecv(nil))}, + {V(BytesChanSend(nil)), V(BytesChanSend(nil))}, + // interfaces {V(int(1)), EmptyInterfaceV(int(1))}, {V(string("hello")), EmptyInterfaceV(string("hello"))}, @@ -4734,17 +4781,14 @@ func TestStructOfExportRules(t *testing.T) { mustPanic: true, }, { - field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"}, - mustPanic: true, + field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"}, }, { - field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"}, - mustPanic: true, + field: StructField{Name: "s2", Type: TypeOf(int(0)), PkgPath: "other/pkg"}, }, { - field: StructField{Name: "S", Type: TypeOf(S1{})}, - mustPanic: false, - exported: true, + field: StructField{Name: "S", Type: TypeOf(S1{})}, + exported: true, }, { field: StructField{Name: "S", Type: TypeOf((*S1)(nil))}, @@ -4775,20 +4819,16 @@ func TestStructOfExportRules(t *testing.T) { mustPanic: true, }, { - field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"}, - mustPanic: true, // TODO(sbinet): creating a name with a package path + field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"}, }, { - field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"}, - mustPanic: true, // TODO(sbinet): creating a name with a package path + field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"}, }, { - field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"}, - mustPanic: true, // TODO(sbinet): creating a name with a package path + field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"}, }, { - field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"}, - mustPanic: true, // TODO(sbinet): creating a name with a package path + field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"}, }, { field: StructField{Name: "", Type: TypeOf(ΦType{})}, @@ -6120,9 +6160,6 @@ var funcLayoutTests []funcLayoutTest func init() { var argAlign uintptr = PtrSize - if runtime.GOARCH == "amd64p32" { - argAlign = 2 * PtrSize - } roundup := func(x uintptr, a uintptr) uintptr { return (x + a - 1) / a * a } @@ -6435,7 +6472,7 @@ func TestGCBits(t *testing.T) { join(hdr, rep(8, lit(0, 1)), rep(8, lit(1)), lit(1))) verifyMapBucket(t, Tint64, Tptr, map[int64]Xptr(nil), - join(hdr, rep(8, rep(8/PtrSize, lit(0))), rep(8, lit(1)), naclpad(), lit(1))) + join(hdr, rep(8, rep(8/PtrSize, lit(0))), rep(8, lit(1)), lit(1))) verifyMapBucket(t, Tscalar, Tscalar, map[Xscalar]Xscalar(nil), @@ -6462,13 +6499,6 @@ func TestGCBits(t *testing.T) { join(hdr, rep(8, lit(1)), rep(8, lit(1)), lit(1))) } -func naclpad() []byte { - if runtime.GOARCH == "amd64p32" { - return lit(0) - } - return nil -} - func rep(n int, b []byte) []byte { return bytes.Repeat(b, n) } func join(b ...[]byte) []byte { return bytes.Join(b, nil) } func lit(x ...byte) []byte { return x } diff --git a/libgo/go/reflect/deepequal.go b/libgo/go/reflect/deepequal.go index 5b6694d3f0b..f2d46165b50 100644 --- a/libgo/go/reflect/deepequal.go +++ b/libgo/go/reflect/deepequal.go @@ -33,18 +33,20 @@ func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool { // We want to avoid putting more in the visited map than we need to. // For any possible reference cycle that might be encountered, - // hard(t) needs to return true for at least one of the types in the cycle. - hard := func(k Kind) bool { - switch k { + // hard(v1, v2) needs to return true for at least one of the types in the cycle, + // and it's safe and valid to get Value's internal pointer. + hard := func(v1, v2 Value) bool { + switch v1.Kind() { case Map, Slice, Ptr, Interface: - return true + // Nil pointers cannot be cyclic. Avoid putting them in the visited map. + return !v1.IsNil() && !v2.IsNil() } return false } - if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) { - addr1 := unsafe.Pointer(v1.UnsafeAddr()) - addr2 := unsafe.Pointer(v2.UnsafeAddr()) + if hard(v1, v2) { + addr1 := v1.ptr + addr2 := v2.ptr if uintptr(addr1) > uintptr(addr2) { // Canonicalize order to reduce number of entries in visited. // Assumes non-moving garbage collector. diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go index 41ed383fc8e..a3506748a25 100644 --- a/libgo/go/reflect/type.go +++ b/libgo/go/reflect/type.go @@ -633,13 +633,17 @@ func (t *rtype) PkgPath() string { return t.uncommonType.PkgPath() } +func (t *rtype) hasName() bool { + return t.uncommonType != nil && t.uncommonType.name != nil +} + func (t *rtype) Name() string { return t.uncommonType.Name() } func (t *rtype) ChanDir() ChanDir { if t.Kind() != Chan { - panic("reflect: ChanDir of non-chan type") + panic("reflect: ChanDir of non-chan type " + t.String()) } tt := (*chanType)(unsafe.Pointer(t)) return ChanDir(tt.dir) @@ -647,7 +651,7 @@ func (t *rtype) ChanDir() ChanDir { func (t *rtype) IsVariadic() bool { if t.Kind() != Func { - panic("reflect: IsVariadic of non-func type") + panic("reflect: IsVariadic of non-func type " + t.String()) } tt := (*funcType)(unsafe.Pointer(t)) return tt.dotdotdot @@ -671,12 +675,12 @@ func (t *rtype) Elem() Type { tt := (*sliceType)(unsafe.Pointer(t)) return toType(tt.elem) } - panic("reflect: Elem of invalid type") + panic("reflect: Elem of invalid type " + t.String()) } func (t *rtype) Field(i int) StructField { if t.Kind() != Struct { - panic("reflect: Field of non-struct type") + panic("reflect: Field of non-struct type " + t.String()) } tt := (*structType)(unsafe.Pointer(t)) return tt.Field(i) @@ -684,7 +688,7 @@ func (t *rtype) Field(i int) StructField { func (t *rtype) FieldByIndex(index []int) StructField { if t.Kind() != Struct { - panic("reflect: FieldByIndex of non-struct type") + panic("reflect: FieldByIndex of non-struct type " + t.String()) } tt := (*structType)(unsafe.Pointer(t)) return tt.FieldByIndex(index) @@ -692,7 +696,7 @@ func (t *rtype) FieldByIndex(index []int) StructField { func (t *rtype) FieldByName(name string) (StructField, bool) { if t.Kind() != Struct { - panic("reflect: FieldByName of non-struct type") + panic("reflect: FieldByName of non-struct type " + t.String()) } tt := (*structType)(unsafe.Pointer(t)) return tt.FieldByName(name) @@ -700,7 +704,7 @@ func (t *rtype) FieldByName(name string) (StructField, bool) { func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) { if t.Kind() != Struct { - panic("reflect: FieldByNameFunc of non-struct type") + panic("reflect: FieldByNameFunc of non-struct type " + t.String()) } tt := (*structType)(unsafe.Pointer(t)) return tt.FieldByNameFunc(match) @@ -708,7 +712,7 @@ func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) { func (t *rtype) In(i int) Type { if t.Kind() != Func { - panic("reflect: In of non-func type") + panic("reflect: In of non-func type " + t.String()) } tt := (*funcType)(unsafe.Pointer(t)) return toType(tt.in[i]) @@ -716,7 +720,7 @@ func (t *rtype) In(i int) Type { func (t *rtype) Key() Type { if t.Kind() != Map { - panic("reflect: Key of non-map type") + panic("reflect: Key of non-map type " + t.String()) } tt := (*mapType)(unsafe.Pointer(t)) return toType(tt.key) @@ -724,7 +728,7 @@ func (t *rtype) Key() Type { func (t *rtype) Len() int { if t.Kind() != Array { - panic("reflect: Len of non-array type") + panic("reflect: Len of non-array type " + t.String()) } tt := (*arrayType)(unsafe.Pointer(t)) return int(tt.len) @@ -732,7 +736,7 @@ func (t *rtype) Len() int { func (t *rtype) NumField() int { if t.Kind() != Struct { - panic("reflect: NumField of non-struct type") + panic("reflect: NumField of non-struct type " + t.String()) } tt := (*structType)(unsafe.Pointer(t)) return len(tt.fields) @@ -740,7 +744,7 @@ func (t *rtype) NumField() int { func (t *rtype) NumIn() int { if t.Kind() != Func { - panic("reflect: NumIn of non-func type") + panic("reflect: NumIn of non-func type " + t.String()) } tt := (*funcType)(unsafe.Pointer(t)) return len(tt.in) @@ -748,7 +752,7 @@ func (t *rtype) NumIn() int { func (t *rtype) NumOut() int { if t.Kind() != Func { - panic("reflect: NumOut of non-func type") + panic("reflect: NumOut of non-func type " + t.String()) } tt := (*funcType)(unsafe.Pointer(t)) return len(tt.out) @@ -756,7 +760,7 @@ func (t *rtype) NumOut() int { func (t *rtype) Out(i int) Type { if t.Kind() != Func { - panic("reflect: Out of non-func type") + panic("reflect: Out of non-func type " + t.String()) } tt := (*funcType)(unsafe.Pointer(t)) return toType(tt.out[i]) @@ -1250,6 +1254,18 @@ func implements(T, V *rtype) bool { return false } +// specialChannelAssignability reports whether a value x of channel type V +// can be directly assigned (using memmove) to another channel type T. +// https://golang.org/doc/go_spec.html#Assignability +// T and V must be both of Chan kind. +func specialChannelAssignability(T, V *rtype) bool { + // Special case: + // x is a bidirectional channel value, T is a channel type, + // x's type V and T have identical element types, + // and at least one of V or T is not a defined type. + return V.ChanDir() == BothDir && (T.Name() == "" || V.Name() == "") && haveIdenticalType(T.Elem(), V.Elem(), true) +} + // directlyAssignable reports whether a value x of type V can be directly // assigned (using memmove) to a value of type T. // https://golang.org/doc/go_spec.html#Assignability @@ -1263,11 +1279,15 @@ func directlyAssignable(T, V *rtype) bool { // Otherwise at least one of T and V must not be defined // and they must have the same kind. - if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() { + if T.hasName() && V.hasName() || T.Kind() != V.Kind() { return false } - // x's type T and V must have identical underlying types. + if T.Kind() == Chan && specialChannelAssignability(T, V) { + return true + } + + // x's type T and V must have identical underlying types. return haveIdenticalUnderlyingType(T, V, true) } @@ -1305,14 +1325,6 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool { return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) case Chan: - // Special case: - // x is a bidirectional channel value, T is a channel type, - // and x's type V and T have identical element types. - if V.ChanDir() == BothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) { - return true - } - - // Otherwise continue test for identical underlying type. return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) case Func: @@ -1800,36 +1812,14 @@ func bucketOf(ktyp, etyp *rtype) *rtype { base := psize / ptrSize if ktyp.ptrdata != 0 { - if ktyp.kind&kindGCProg != 0 { - panic("reflect: unexpected GC program in MapOf") - } - kmask := (*[16]byte)(unsafe.Pointer(ktyp.gcdata)) - for i := uintptr(0); i < ktyp.ptrdata/ptrSize; i++ { - if (kmask[i/8]>>(i%8))&1 != 0 { - for j := uintptr(0); j < bucketSize; j++ { - word := base + j*ktyp.size/ptrSize + i - mask[word/8] |= 1 << (word % 8) - } - } - } + emitGCMask(mask, base, ktyp, bucketSize) } psize += bucketSize * ktyp.size psize = align(psize, uintptr(etyp.fieldAlign)) base = psize / ptrSize if etyp.ptrdata != 0 { - if etyp.kind&kindGCProg != 0 { - panic("reflect: unexpected GC program in MapOf") - } - emask := (*[16]byte)(unsafe.Pointer(etyp.gcdata)) - for i := uintptr(0); i < etyp.ptrdata/ptrSize; i++ { - if (emask[i/8]>>(i%8))&1 != 0 { - for j := uintptr(0); j < bucketSize; j++ { - word := base + j*etyp.size/ptrSize + i - mask[word/8] |= 1 << (word % 8) - } - } - } + emitGCMask(mask, base, etyp, bucketSize) } word := ovoff / ptrSize @@ -1856,6 +1846,55 @@ func bucketOf(ktyp, etyp *rtype) *rtype { return b } +func (t *rtype) gcSlice(begin, end uintptr) []byte { + return (*[1 << 30]byte)(unsafe.Pointer(t.gcdata))[begin:end:end] +} + +// emitGCMask writes the GC mask for [n]typ into out, starting at bit +// offset base. +func emitGCMask(out []byte, base uintptr, typ *rtype, n uintptr) { + if typ.kind&kindGCProg != 0 { + panic("reflect: unexpected GC program") + } + ptrs := typ.ptrdata / ptrSize + words := typ.size / ptrSize + mask := typ.gcSlice(0, (ptrs+7)/8) + for j := uintptr(0); j < ptrs; j++ { + if (mask[j/8]>>(j%8))&1 != 0 { + for i := uintptr(0); i < n; i++ { + k := base + i*words + j + out[k/8] |= 1 << (k % 8) + } + } + } +} + +// appendGCProg appends the GC program for the first ptrdata bytes of +// typ to dst and returns the extended slice. +func appendGCProg(dst []byte, typ *rtype) []byte { + if typ.kind&kindGCProg != 0 { + // Element has GC program; emit one element. + n := uintptr(*(*uint32)(unsafe.Pointer(typ.gcdata))) + prog := typ.gcSlice(4, 4+n-1) + return append(dst, prog...) + } + + // Element is small with pointer mask; use as literal bits. + ptrs := typ.ptrdata / ptrSize + mask := typ.gcSlice(0, (ptrs+7)/8) + + // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes). + for ; ptrs > 120; ptrs -= 120 { + dst = append(dst, 120) + dst = append(dst, mask[:15]...) + mask = mask[15:] + } + + dst = append(dst, byte(ptrs)) + dst = append(dst, mask...) + return dst +} + // SliceOf returns the slice type with element type t. // For example, if t represents int, SliceOf(t) represents []int. func SliceOf(t Type) Type { @@ -2146,25 +2185,7 @@ func StructOf(fields []StructField) Type { off = ft.offset() } - elemGC := (*[1 << 30]byte)(unsafe.Pointer(ft.typ.gcdata))[:] - elemPtrs := ft.typ.ptrdata / ptrSize - if ft.typ.kind&kindGCProg == 0 { - // Element is small with pointer mask; use as literal bits. - mask := elemGC - // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes). - var n uintptr - for n = elemPtrs; n > 120; n -= 120 { - prog = append(prog, 120) - prog = append(prog, mask[:15]...) - mask = mask[15:] - } - prog = append(prog, byte(n)) - prog = append(prog, mask[:(n+7)/8]...) - } else { - // Element has GC program; emit one element. - elemProg := elemGC[4 : 4+*(*uint32)(unsafe.Pointer(&elemGC[0]))-1] - prog = append(prog, elemProg...) - } + prog = appendGCProg(prog, ft.typ) off += ft.typ.ptrdata } prog = append(prog, 0) @@ -2209,15 +2230,18 @@ func StructOf(fields []StructField) Type { } func runtimeStructField(field StructField) structField { - if field.PkgPath != "" { - panic("reflect.StructOf: StructOf does not allow unexported fields") + if field.Anonymous && field.PkgPath != "" { + panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set") } - // Best-effort check for misuse. - // Since PkgPath is empty, not much harm done if Unicode lowercase slips through. - c := field.Name[0] - if 'a' <= c && c <= 'z' || c == '_' { - panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath") + exported := field.PkgPath == "" + if exported { + // Best-effort check for misuse. + // Since this field will be treated as exported, not much harm done if Unicode lowercase slips through. + c := field.Name[0] + if 'a' <= c && c <= 'z' || c == '_' { + panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath") + } } offsetEmbed := uintptr(0) @@ -2234,9 +2258,14 @@ func runtimeStructField(field StructField) structField { tag = &st } + var pkgPath *string + if field.PkgPath != "" { + s := field.PkgPath + pkgPath = &s + } return structField{ name: name, - pkgPath: nil, + pkgPath: pkgPath, typ: field.Type.common(), tag: tag, offsetEmbed: offsetEmbed, @@ -2346,42 +2375,16 @@ func ArrayOf(count int, elem Type) Type { // Create direct pointer mask by turning each 1 bit in elem // into count 1 bits in larger mask. mask := make([]byte, (array.ptrdata/ptrSize+7)/8) - elemMask := (*[1 << 30]byte)(unsafe.Pointer(typ.gcdata))[:] - elemWords := typ.size / ptrSize - for j := uintptr(0); j < typ.ptrdata/ptrSize; j++ { - if (elemMask[j/8]>>(j%8))&1 != 0 { - for i := uintptr(0); i < array.len; i++ { - k := i*elemWords + j - mask[k/8] |= 1 << (k % 8) - } - } - } + emitGCMask(mask, 0, typ, array.len) array.gcdata = &mask[0] default: // Create program that emits one element // and then repeats to make the array. prog := []byte{0, 0, 0, 0} // will be length of prog - elemGC := (*[1 << 30]byte)(unsafe.Pointer(typ.gcdata))[:] - elemPtrs := typ.ptrdata / ptrSize - if typ.kind&kindGCProg == 0 { - // Element is small with pointer mask; use as literal bits. - mask := elemGC - // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes). - var n uintptr - for n = elemPtrs; n > 120; n -= 120 { - prog = append(prog, 120) - prog = append(prog, mask[:15]...) - mask = mask[15:] - } - prog = append(prog, byte(n)) - prog = append(prog, mask[:(n+7)/8]...) - } else { - // Element has GC program; emit one element. - elemProg := elemGC[4 : 4+*(*uint32)(unsafe.Pointer(&elemGC[0]))-1] - prog = append(prog, elemProg...) - } + prog = appendGCProg(prog, typ) // Pad from ptrdata to size. + elemPtrs := typ.ptrdata / ptrSize elemWords := typ.size / ptrSize if elemPtrs < elemWords { // Emit literal 0 bit, then repeat as needed. @@ -2462,7 +2465,6 @@ func ifaceIndir(t *rtype) bool { return t.kind&kindDirectIface == 0 } -// Layout matches runtime.gobitvector (well enough). type bitVector struct { n uint32 // number of bits data []byte diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index 15a502465f7..147a9c47298 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -884,7 +884,7 @@ func (v Value) IsNil() bool { // IsValid reports whether v represents a value. // It returns false if v is the zero Value. // If IsValid returns false, all other methods except String panic. -// Most functions and methods never return an invalid value. +// Most functions and methods never return an invalid Value. // If one does, its documentation states the conditions explicitly. func (v Value) IsValid() bool { return v.flag != 0 @@ -1225,6 +1225,11 @@ func (v Value) OverflowUint(x uint64) bool { panic(&ValueError{"reflect.Value.OverflowUint", v.kind()}) } +//go:nocheckptr +// This prevents inlining Value.Pointer when -d=checkptr is enabled, +// which ensures cmd/compile can recognize unsafe.Pointer(v.Pointer()) +// and make an exception. + // Pointer returns v's value as a uintptr. // It returns uintptr instead of unsafe.Pointer so that // code using reflect cannot obtain unsafe.Pointers @@ -1722,6 +1727,11 @@ func (v Value) Uint() uint64 { panic(&ValueError{"reflect.Value.Uint", v.kind()}) } +//go:nocheckptr +// This prevents inlining Value.UnsafeAddr when -d=checkptr is enabled, +// which ensures cmd/compile can recognize unsafe.Pointer(v.UnsafeAddr()) +// and make an exception. + // UnsafeAddr returns a pointer to v's data. // It is for advanced clients that also import the "unsafe" package. // It panics if v is not addressable. @@ -2274,6 +2284,11 @@ func convertOp(dst, src *rtype) func(Value, Type) Value { return cvtRunesString } } + + case Chan: + if dst.Kind() == Chan && specialChannelAssignability(dst, src) { + return cvtDirect + } } // dst and src have same underlying type. diff --git a/libgo/go/regexp/backtrack.go b/libgo/go/regexp/backtrack.go index 9fb7d1e4937..41ae59bcaa2 100644 --- a/libgo/go/regexp/backtrack.go +++ b/libgo/go/regexp/backtrack.go @@ -247,7 +247,7 @@ func (re *Regexp) tryBacktrack(b *bitState, i input, pc uint32, pos int) bool { b.cap[inst.Arg] = pos continue } else { - if 0 <= inst.Arg && inst.Arg < uint32(len(b.cap)) { + if inst.Arg < uint32(len(b.cap)) { // Capture pos to register, but save old value. b.push(re, pc, b.cap[inst.Arg], true) // come back when we're done. b.cap[inst.Arg] = pos diff --git a/libgo/go/regexp/example_test.go b/libgo/go/regexp/example_test.go new file mode 100644 index 00000000000..ea35a2e5918 --- /dev/null +++ b/libgo/go/regexp/example_test.go @@ -0,0 +1,420 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package regexp_test + +import ( + "fmt" + "regexp" + "strings" +) + +func Example() { + // Compile the expression once, usually at init time. + // Use raw strings to avoid having to quote the backslashes. + var validID = regexp.MustCompile(`^[a-z]+\[[0-9]+\]$`) + + fmt.Println(validID.MatchString("adam[23]")) + fmt.Println(validID.MatchString("eve[7]")) + fmt.Println(validID.MatchString("Job[48]")) + fmt.Println(validID.MatchString("snakey")) + // Output: + // true + // true + // false + // false +} + +func ExampleMatch() { + matched, err := regexp.Match(`foo.*`, []byte(`seafood`)) + fmt.Println(matched, err) + matched, err = regexp.Match(`bar.*`, []byte(`seafood`)) + fmt.Println(matched, err) + matched, err = regexp.Match(`a(b`, []byte(`seafood`)) + fmt.Println(matched, err) + + // Output: + // true + // false + // false error parsing regexp: missing closing ): `a(b` +} + +func ExampleMatchString() { + matched, err := regexp.MatchString(`foo.*`, "seafood") + fmt.Println(matched, err) + matched, err = regexp.MatchString(`bar.*`, "seafood") + fmt.Println(matched, err) + matched, err = regexp.MatchString(`a(b`, "seafood") + fmt.Println(matched, err) + // Output: + // true + // false + // false error parsing regexp: missing closing ): `a(b` +} + +func ExampleQuoteMeta() { + fmt.Println(regexp.QuoteMeta(`Escaping symbols like: .+*?()|[]{}^$`)) + // Output: + // Escaping symbols like: \.\+\*\?\(\)\|\[\]\{\}\^\$ +} + +func ExampleRegexp_Find() { + re := regexp.MustCompile(`foo.?`) + fmt.Printf("%q\n", re.Find([]byte(`seafood fool`))) + + // Output: + // "food" +} + +func ExampleRegexp_FindAll() { + re := regexp.MustCompile(`foo.?`) + fmt.Printf("%q\n", re.FindAll([]byte(`seafood fool`), -1)) + + // Output: + // ["food" "fool"] +} + +func ExampleRegexp_FindAllSubmatch() { + re := regexp.MustCompile(`foo(.?)`) + fmt.Printf("%q\n", re.FindAllSubmatch([]byte(`seafood fool`), -1)) + + // Output: + // [["food" "d"] ["fool" "l"]] +} + +func ExampleRegexp_FindSubmatch() { + re := regexp.MustCompile(`foo(.?)`) + fmt.Printf("%q\n", re.FindSubmatch([]byte(`seafood fool`))) + + // Output: + // ["food" "d"] +} + +func ExampleRegexp_Match() { + re := regexp.MustCompile(`foo.?`) + fmt.Println(re.Match([]byte(`seafood fool`))) + fmt.Println(re.Match([]byte(`something else`))) + + // Output: + // true + // false +} + +func ExampleRegexp_FindString() { + re := regexp.MustCompile(`foo.?`) + fmt.Printf("%q\n", re.FindString("seafood fool")) + fmt.Printf("%q\n", re.FindString("meat")) + // Output: + // "food" + // "" +} + +func ExampleRegexp_FindStringIndex() { + re := regexp.MustCompile(`ab?`) + fmt.Println(re.FindStringIndex("tablett")) + fmt.Println(re.FindStringIndex("foo") == nil) + // Output: + // [1 3] + // true +} + +func ExampleRegexp_FindStringSubmatch() { + re := regexp.MustCompile(`a(x*)b(y|z)c`) + fmt.Printf("%q\n", re.FindStringSubmatch("-axxxbyc-")) + fmt.Printf("%q\n", re.FindStringSubmatch("-abzc-")) + // Output: + // ["axxxbyc" "xxx" "y"] + // ["abzc" "" "z"] +} + +func ExampleRegexp_FindAllString() { + re := regexp.MustCompile(`a.`) + fmt.Println(re.FindAllString("paranormal", -1)) + fmt.Println(re.FindAllString("paranormal", 2)) + fmt.Println(re.FindAllString("graal", -1)) + fmt.Println(re.FindAllString("none", -1)) + // Output: + // [ar an al] + // [ar an] + // [aa] + // [] +} + +func ExampleRegexp_FindAllStringSubmatch() { + re := regexp.MustCompile(`a(x*)b`) + fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-", -1)) + fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-", -1)) + fmt.Printf("%q\n", re.FindAllStringSubmatch("-ab-axb-", -1)) + fmt.Printf("%q\n", re.FindAllStringSubmatch("-axxb-ab-", -1)) + // Output: + // [["ab" ""]] + // [["axxb" "xx"]] + // [["ab" ""] ["axb" "x"]] + // [["axxb" "xx"] ["ab" ""]] +} + +func ExampleRegexp_FindAllStringSubmatchIndex() { + re := regexp.MustCompile(`a(x*)b`) + // Indices: + // 01234567 012345678 + // -ab-axb- -axxb-ab- + fmt.Println(re.FindAllStringSubmatchIndex("-ab-", -1)) + fmt.Println(re.FindAllStringSubmatchIndex("-axxb-", -1)) + fmt.Println(re.FindAllStringSubmatchIndex("-ab-axb-", -1)) + fmt.Println(re.FindAllStringSubmatchIndex("-axxb-ab-", -1)) + fmt.Println(re.FindAllStringSubmatchIndex("-foo-", -1)) + // Output: + // [[1 3 2 2]] + // [[1 5 2 4]] + // [[1 3 2 2] [4 7 5 6]] + // [[1 5 2 4] [6 8 7 7]] + // [] +} + +func ExampleRegexp_FindSubmatchIndex() { + re := regexp.MustCompile(`a(x*)b`) + // Indices: + // 01234567 012345678 + // -ab-axb- -axxb-ab- + fmt.Println(re.FindSubmatchIndex([]byte("-ab-"))) + fmt.Println(re.FindSubmatchIndex([]byte("-axxb-"))) + fmt.Println(re.FindSubmatchIndex([]byte("-ab-axb-"))) + fmt.Println(re.FindSubmatchIndex([]byte("-axxb-ab-"))) + fmt.Println(re.FindSubmatchIndex([]byte("-foo-"))) + // Output: + // [1 3 2 2] + // [1 5 2 4] + // [1 3 2 2] + // [1 5 2 4] + // [] +} + +func ExampleRegexp_Longest() { + re := regexp.MustCompile(`a(|b)`) + fmt.Println(re.FindString("ab")) + re.Longest() + fmt.Println(re.FindString("ab")) + // Output: + // a + // ab +} + +func ExampleRegexp_MatchString() { + re := regexp.MustCompile(`(gopher){2}`) + fmt.Println(re.MatchString("gopher")) + fmt.Println(re.MatchString("gophergopher")) + fmt.Println(re.MatchString("gophergophergopher")) + // Output: + // false + // true + // true +} + +func ExampleRegexp_NumSubexp() { + re0 := regexp.MustCompile(`a.`) + fmt.Printf("%d\n", re0.NumSubexp()) + + re := regexp.MustCompile(`(.*)((a)b)(.*)a`) + fmt.Println(re.NumSubexp()) + // Output: + // 0 + // 4 +} + +func ExampleRegexp_ReplaceAll() { + re := regexp.MustCompile(`a(x*)b`) + fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("T"))) + fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("$1"))) + fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("$1W"))) + fmt.Printf("%s\n", re.ReplaceAll([]byte("-ab-axxb-"), []byte("${1}W"))) + // Output: + // -T-T- + // --xx- + // --- + // -W-xxW- +} + +func ExampleRegexp_ReplaceAllLiteralString() { + re := regexp.MustCompile(`a(x*)b`) + fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "T")) + fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "$1")) + fmt.Println(re.ReplaceAllLiteralString("-ab-axxb-", "${1}")) + // Output: + // -T-T- + // -$1-$1- + // -${1}-${1}- +} + +func ExampleRegexp_ReplaceAllString() { + re := regexp.MustCompile(`a(x*)b`) + fmt.Println(re.ReplaceAllString("-ab-axxb-", "T")) + fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1")) + fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W")) + fmt.Println(re.ReplaceAllString("-ab-axxb-", "${1}W")) + // Output: + // -T-T- + // --xx- + // --- + // -W-xxW- +} + +func ExampleRegexp_ReplaceAllStringFunc() { + re := regexp.MustCompile(`[^aeiou]`) + fmt.Println(re.ReplaceAllStringFunc("seafood fool", strings.ToUpper)) + // Output: + // SeaFooD FooL +} + +func ExampleRegexp_SubexpNames() { + re := regexp.MustCompile(`(?P[a-zA-Z]+) (?P[a-zA-Z]+)`) + fmt.Println(re.MatchString("Alan Turing")) + fmt.Printf("%q\n", re.SubexpNames()) + reversed := fmt.Sprintf("${%s} ${%s}", re.SubexpNames()[2], re.SubexpNames()[1]) + fmt.Println(reversed) + fmt.Println(re.ReplaceAllString("Alan Turing", reversed)) + // Output: + // true + // ["" "first" "last"] + // ${last} ${first} + // Turing Alan +} + +func ExampleRegexp_Split() { + a := regexp.MustCompile(`a`) + fmt.Println(a.Split("banana", -1)) + fmt.Println(a.Split("banana", 0)) + fmt.Println(a.Split("banana", 1)) + fmt.Println(a.Split("banana", 2)) + zp := regexp.MustCompile(`z+`) + fmt.Println(zp.Split("pizza", -1)) + fmt.Println(zp.Split("pizza", 0)) + fmt.Println(zp.Split("pizza", 1)) + fmt.Println(zp.Split("pizza", 2)) + // Output: + // [b n n ] + // [] + // [banana] + // [b nana] + // [pi a] + // [] + // [pizza] + // [pi a] +} + +func ExampleRegexp_Expand() { + content := []byte(` + # comment line + option1: value1 + option2: value2 + + # another comment line + option3: value3 +`) + + // Regex pattern captures "key: value" pair from the content. + pattern := regexp.MustCompile(`(?m)(?P\w+):\s+(?P\w+)$`) + + // Template to convert "key: value" to "key=value" by + // referencing the values captured by the regex pattern. + template := []byte("$key=$value\n") + + result := []byte{} + + // For each match of the regex in the content. + for _, submatches := range pattern.FindAllSubmatchIndex(content, -1) { + // Apply the captured submatches to the template and append the output + // to the result. + result = pattern.Expand(result, template, content, submatches) + } + fmt.Println(string(result)) + // Output: + // option1=value1 + // option2=value2 + // option3=value3 +} + +func ExampleRegexp_ExpandString() { + content := ` + # comment line + option1: value1 + option2: value2 + + # another comment line + option3: value3 +` + + // Regex pattern captures "key: value" pair from the content. + pattern := regexp.MustCompile(`(?m)(?P\w+):\s+(?P\w+)$`) + + // Template to convert "key: value" to "key=value" by + // referencing the values captured by the regex pattern. + template := "$key=$value\n" + + result := []byte{} + + // For each match of the regex in the content. + for _, submatches := range pattern.FindAllStringSubmatchIndex(content, -1) { + // Apply the captured submatches to the template and append the output + // to the result. + result = pattern.ExpandString(result, template, content, submatches) + } + fmt.Println(string(result)) + // Output: + // option1=value1 + // option2=value2 + // option3=value3 +} + +func ExampleRegexp_FindIndex() { + content := []byte(` + # comment line + option1: value1 + option2: value2 +`) + // Regex pattern captures "key: value" pair from the content. + pattern := regexp.MustCompile(`(?m)(?P\w+):\s+(?P\w+)$`) + + loc := pattern.FindIndex(content) + fmt.Println(loc) + fmt.Println(string(content[loc[0]:loc[1]])) + // Output: + // [18 33] + // option1: value1 +} + +func ExampleRegexp_FindAllSubmatchIndex() { + content := []byte(` + # comment line + option1: value1 + option2: value2 +`) + // Regex pattern captures "key: value" pair from the content. + pattern := regexp.MustCompile(`(?m)(?P\w+):\s+(?P\w+)$`) + allIndexes := pattern.FindAllSubmatchIndex(content, -1) + for _, loc := range allIndexes { + fmt.Println(loc) + fmt.Println(string(content[loc[0]:loc[1]])) + fmt.Println(string(content[loc[2]:loc[3]])) + fmt.Println(string(content[loc[4]:loc[5]])) + } + // Output: + // [18 33 18 25 27 33] + // option1: value1 + // option1 + // value1 + // [35 50 35 42 44 50] + // option2: value2 + // option2 + // value2 +} + +func ExampleRegexp_FindAllIndex() { + content := []byte("London") + re := regexp.MustCompile(`o.`) + fmt.Println(re.FindAllIndex(content, 1)) + fmt.Println(re.FindAllIndex(content, -1)) + // Output: + // [[1 3]] + // [[1 3] [4 6]] +} diff --git a/libgo/go/regexp/exec_test.go b/libgo/go/regexp/exec_test.go index 1e8795525d0..1f9a7a96e0c 100644 --- a/libgo/go/regexp/exec_test.go +++ b/libgo/go/regexp/exec_test.go @@ -665,7 +665,7 @@ func BenchmarkMatch(b *testing.B) { for _, data := range benchData { r := MustCompile(data.re) for _, size := range benchSizes { - if isRaceBuilder && size.n > 1<<10 { + if (isRaceBuilder || testing.Short()) && size.n > 1<<10 { continue } t := makeText(size.n) @@ -688,7 +688,7 @@ func BenchmarkMatch_onepass_regex(b *testing.B) { b.Fatalf("want onepass regex, but %q is not onepass", r) } for _, size := range benchSizes { - if isRaceBuilder && size.n > 1<<10 { + if (isRaceBuilder || testing.Short()) && size.n > 1<<10 { continue } t := makeText(size.n) diff --git a/libgo/go/runtime/alg.go b/libgo/go/runtime/alg.go index e802fdd7024..101402ca49c 100644 --- a/libgo/go/runtime/alg.go +++ b/libgo/go/runtime/alg.go @@ -281,6 +281,7 @@ func efaceeq(x, y eface) bool { } return eq(x.data, y.data) } + func ifaceeq(x, y iface) bool { xtab := x.tab if xtab == nil && y.tab == nil { @@ -463,7 +464,6 @@ var hashkey [4]uintptr func alginit() { // Install AES hash algorithms if the instructions needed are present. if (GOARCH == "386" || GOARCH == "amd64") && - GOOS != "nacl" && support_aes && cpu.X86.HasAES && // AESENC cpu.X86.HasSSSE3 && // PSHUFB @@ -488,7 +488,7 @@ func initAlgAES() { getRandomData(aeskeysched[:]) } -// Note: These routines perform the read with an native endianness. +// Note: These routines perform the read with a native endianness. func readUnaligned32(p unsafe.Pointer) uint32 { q := (*[4]byte)(p) if sys.BigEndian { diff --git a/libgo/go/runtime/callers_test.go b/libgo/go/runtime/callers_test.go index ad83f9969c4..26a6f3a73fc 100644 --- a/libgo/go/runtime/callers_test.go +++ b/libgo/go/runtime/callers_test.go @@ -5,25 +5,26 @@ package runtime_test import ( + "reflect" "runtime" "strings" "testing" ) func f1(pan bool) []uintptr { - return f2(pan) // line 14 + return f2(pan) // line 15 } func f2(pan bool) []uintptr { - return f3(pan) // line 18 + return f3(pan) // line 19 } func f3(pan bool) []uintptr { if pan { - panic("f3") // line 23 + panic("f3") // line 24 } ret := make([]uintptr, 20) - return ret[:runtime.Callers(0, ret)] // line 26 + return ret[:runtime.Callers(0, ret)] // line 27 } func testCallers(t *testing.T, pcs []uintptr, pan bool) { @@ -47,16 +48,16 @@ func testCallers(t *testing.T, pcs []uintptr, pan bool) { var f3Line int if pan { - f3Line = 23 + f3Line = 24 } else { - f3Line = 26 + f3Line = 27 } want := []struct { name string line int }{ - {"f1", 14}, - {"f2", 18}, + {"f1", 15}, + {"f2", 19}, {"f3", f3Line}, } for _, w := range want { @@ -66,11 +67,38 @@ func testCallers(t *testing.T, pcs []uintptr, pan bool) { } } +func testCallersEqual(t *testing.T, pcs []uintptr, want []string) { + got := make([]string, 0, len(want)) + + frames := runtime.CallersFrames(pcs) + for { + frame, more := frames.Next() + if !more || len(got) >= len(want) { + break + } + got = append(got, frame.Function) + } + if !reflect.DeepEqual(want, got) { + t.Fatalf("wanted %v, got %v", want, got) + } +} + func TestCallers(t *testing.T) { testCallers(t, f1(false), false) } func TestCallersPanic(t *testing.T) { + // Make sure we don't have any extra frames on the stack (due to + // open-coded defer processing) + want := []string{"runtime.Callers", "runtime_test.TestCallersPanic.func1", + "runtime.gopanic", "runtime_test.f3", "runtime_test.f2", "runtime_test.f1", + "runtime_test.TestCallersPanic"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersPanic..func1", + "runtime.gopanic", "runtime_test.f3", "runtime_test.f2", "runtime_test.f1", + "runtime_test.TestCallersPanic"} + } + defer func() { if r := recover(); r == nil { t.Fatal("did not panic") @@ -78,6 +106,240 @@ func TestCallersPanic(t *testing.T) { pcs := make([]uintptr, 20) pcs = pcs[:runtime.Callers(0, pcs)] testCallers(t, pcs, true) + testCallersEqual(t, pcs, want) }() f1(true) } + +func TestCallersDoublePanic(t *testing.T) { + // Make sure we don't have any extra frames on the stack (due to + // open-coded defer processing) + want := []string{"runtime.Callers", "runtime_test.TestCallersDoublePanic.func1.1", + "runtime.gopanic", "runtime_test.TestCallersDoublePanic.func1", "runtime.gopanic", "runtime_test.TestCallersDoublePanic"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersDoublePanic..func2", + "runtime.gopanic", "runtime_test.TestCallersDoublePanic..func1", "runtime.gopanic", "runtime_test.TestCallersDoublePanic"} + } + + defer func() { + defer func() { + pcs := make([]uintptr, 20) + pcs = pcs[:runtime.Callers(0, pcs)] + if recover() == nil { + t.Fatal("did not panic") + } + testCallersEqual(t, pcs, want) + }() + if recover() == nil { + t.Fatal("did not panic") + } + panic(2) + }() + panic(1) +} + +// Test that a defer after a successful recovery looks like it is called directly +// from the function with the defers. +func TestCallersAfterRecovery(t *testing.T) { + want := []string{"runtime.Callers", "runtime_test.TestCallersAfterRecovery.func1", "runtime_test.TestCallersAfterRecovery"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersAfterRecovery..func1", "runtime_test.TestCallersAfterRecovery"} + } + + defer func() { + pcs := make([]uintptr, 20) + pcs = pcs[:runtime.Callers(0, pcs)] + testCallersEqual(t, pcs, want) + }() + defer func() { + if recover() == nil { + t.Fatal("did not recover from panic") + } + }() + panic(1) +} + +func TestCallersAbortedPanic(t *testing.T) { + want := []string{"runtime.Callers", "runtime_test.TestCallersAbortedPanic.func2", "runtime_test.TestCallersAbortedPanic"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersAbortedPanic..func2", "runtime_test.TestCallersAbortedPanic"} + } + + defer func() { + r := recover() + if r != nil { + t.Fatalf("should be no panic remaining to recover") + } + }() + + defer func() { + // panic2 was aborted/replaced by panic1, so when panic2 was + // recovered, there is no remaining panic on the stack. + pcs := make([]uintptr, 20) + pcs = pcs[:runtime.Callers(0, pcs)] + testCallersEqual(t, pcs, want) + }() + defer func() { + r := recover() + if r != "panic2" { + t.Fatalf("got %v, wanted %v", r, "panic2") + } + }() + defer func() { + // panic2 aborts/replaces panic1, because it is a recursive panic + // that is not recovered within the defer function called by + // panic1 panicking sequence + panic("panic2") + }() + panic("panic1") +} + +func TestCallersAbortedPanic2(t *testing.T) { + want := []string{"runtime.Callers", "runtime_test.TestCallersAbortedPanic2.func2", "runtime_test.TestCallersAbortedPanic2"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersAbortedPanic2..func2", "runtime_test.TestCallersAbortedPanic2"} + } + defer func() { + r := recover() + if r != nil { + t.Fatalf("should be no panic remaining to recover") + } + }() + defer func() { + pcs := make([]uintptr, 20) + pcs = pcs[:runtime.Callers(0, pcs)] + testCallersEqual(t, pcs, want) + }() + func() { + defer func() { + r := recover() + if r != "panic2" { + t.Fatalf("got %v, wanted %v", r, "panic2") + } + }() + func() { + defer func() { + // Again, panic2 aborts/replaces panic1 + panic("panic2") + }() + panic("panic1") + }() + }() +} + +func TestCallersNilPointerPanic(t *testing.T) { + // Make sure we don't have any extra frames on the stack (due to + // open-coded defer processing) + want := []string{"runtime.Callers", "runtime_test.TestCallersNilPointerPanic.func1", + "runtime.gopanic", "runtime.panicmem", "runtime.sigpanic", + "runtime_test.TestCallersNilPointerPanic"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersNilPointerPanic..func1", + "runtime.gopanic", "runtime.panicmem", "runtime.sigpanic", + "runtime_test.TestCallersNilPointerPanic"} + } + + defer func() { + if r := recover(); r == nil { + t.Fatal("did not panic") + } + pcs := make([]uintptr, 20) + pcs = pcs[:runtime.Callers(0, pcs)] + testCallersEqual(t, pcs, want) + }() + var p *int + if *p == 3 { + t.Fatal("did not see nil pointer panic") + } +} + +func TestCallersDivZeroPanic(t *testing.T) { + // Make sure we don't have any extra frames on the stack (due to + // open-coded defer processing) + want := []string{"runtime.Callers", "runtime_test.TestCallersDivZeroPanic.func1", + "runtime.gopanic", "runtime.panicdivide", + "runtime_test.TestCallersDivZeroPanic"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersDivZeroPanic..func1", + "runtime.gopanic", "runtime.panicdivide", + "runtime_test.TestCallersDivZeroPanic"} + } + + defer func() { + if r := recover(); r == nil { + t.Fatal("did not panic") + } + pcs := make([]uintptr, 20) + pcs = pcs[:runtime.Callers(0, pcs)] + testCallersEqual(t, pcs, want) + }() + var n int + if 5/n == 1 { + t.Fatal("did not see divide-by-sizer panic") + } +} + +func TestCallersDeferNilFuncPanic(t *testing.T) { + // Make sure we don't have any extra frames on the stack. We cut off the check + // at runtime.sigpanic, because non-open-coded defers (which may be used in + // non-opt or race checker mode) include an extra 'deferreturn' frame (which is + // where the nil pointer deref happens). + state := 1 + want := []string{"runtime.Callers", "runtime_test.TestCallersDeferNilFuncPanic.func1", + "runtime.gopanic", "runtime.panicmem", "runtime.sigpanic"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersDeferNilFuncPanic..func1", + "runtime.gopanic", "runtime.panicmem", "runtime.sigpanic"} + } + + defer func() { + if r := recover(); r == nil { + t.Fatal("did not panic") + } + pcs := make([]uintptr, 20) + pcs = pcs[:runtime.Callers(0, pcs)] + testCallersEqual(t, pcs, want) + if state == 1 { + t.Fatal("nil defer func panicked at defer time rather than function exit time") + } + + }() + var f func() + defer f() + // Use the value of 'state' to make sure nil defer func f causes panic at + // function exit, rather than at the defer statement. + state = 2 +} + +// Same test, but forcing non-open-coded defer by putting the defer in a loop. See +// issue #36050 +func TestCallersDeferNilFuncPanicWithLoop(t *testing.T) { + state := 1 + want := []string{"runtime.Callers", "runtime_test.TestCallersDeferNilFuncPanicWithLoop.func1", + "runtime.gopanic", "runtime.panicmem", "runtime.sigpanic", "runtime.deferreturn", "runtime_test.TestCallersDeferNilFuncPanicWithLoop"} + if runtime.Compiler == "gccgo" { + want = []string{"runtime.Callers", "runtime_test.TestCallersDeferNilFuncPanicWithLoop..func1", + "runtime.gopanic", "runtime.panicmem", "runtime.sigpanic", "runtime_test.TestCallersDeferNilFuncPanicWithLoop"} + } + + defer func() { + if r := recover(); r == nil { + t.Fatal("did not panic") + } + pcs := make([]uintptr, 20) + pcs = pcs[:runtime.Callers(0, pcs)] + testCallersEqual(t, pcs, want) + if state == 1 { + t.Fatal("nil defer func panicked at defer time rather than function exit time") + } + + }() + + for i := 0; i < 1; i++ { + var f func() + defer f() + } + // Use the value of 'state' to make sure nil defer func f causes panic at + // function exit, rather than at the defer statement. + state = 2 +} diff --git a/libgo/go/runtime/cgocall.go b/libgo/go/runtime/cgocall.go index 587001cb977..efd0e24a218 100644 --- a/libgo/go/runtime/cgocall.go +++ b/libgo/go/runtime/cgocall.go @@ -47,24 +47,24 @@ import ( // cgoCheckPointer checks if the argument contains a Go pointer that // points to a Go pointer, and panics if it does. -func cgoCheckPointer(ptr interface{}, args ...interface{}) { +func cgoCheckPointer(ptr interface{}, arg interface{}) { if debug.cgocheck == 0 { return } - ep := (*eface)(unsafe.Pointer(&ptr)) + ep := efaceOf(&ptr) t := ep._type top := true - if len(args) > 0 && (t.kind&kindMask == kindPtr || t.kind&kindMask == kindUnsafePointer) { + if arg != nil && (t.kind&kindMask == kindPtr || t.kind&kindMask == kindUnsafePointer) { p := ep.data if t.kind&kindDirectIface == 0 { p = *(*unsafe.Pointer)(p) } - if !cgoIsGoPointer(p) { + if p == nil || !cgoIsGoPointer(p) { return } - aep := (*eface)(unsafe.Pointer(&args[0])) + aep := efaceOf(&arg) switch aep._type.kind & kindMask { case kindBool: if t.kind&kindMask == kindUnsafePointer { @@ -101,7 +101,7 @@ const cgoResultFail = "cgo result has Go pointer" // depending on indir. The top parameter is whether we are at the top // level, where Go pointers are allowed. func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) { - if t.ptrdata == 0 { + if t.ptrdata == 0 || p == nil { // If the type has no pointers there is nothing to do. return } @@ -158,7 +158,7 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) { st := (*slicetype)(unsafe.Pointer(t)) s := (*slice)(p) p = s.array - if !cgoIsGoPointer(p) { + if p == nil || !cgoIsGoPointer(p) { return } if !top { @@ -189,11 +189,17 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) { return } for _, f := range st.fields { + if f.typ.ptrdata == 0 { + continue + } cgoCheckArg(f.typ, add(p, f.offset()), true, top, msg) } case kindPtr, kindUnsafePointer: if indir { p = *(*unsafe.Pointer)(p) + if p == nil { + return + } } if !cgoIsGoPointer(p) { @@ -298,7 +304,7 @@ func cgoCheckResult(val interface{}) { return } - ep := (*eface)(unsafe.Pointer(&val)) + ep := efaceOf(&val) t := ep._type cgoCheckArg(t, ep.data, t.kind&kindDirectIface == 0, false, cgoResultFail) } diff --git a/libgo/go/runtime/cgocheck.go b/libgo/go/runtime/cgocheck.go index 130db295acf..c03bafe424c 100644 --- a/libgo/go/runtime/cgocheck.go +++ b/libgo/go/runtime/cgocheck.go @@ -134,7 +134,7 @@ func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) { } s := spanOfUnchecked(uintptr(src)) - if s.state == mSpanManual { + if s.state.get() == mSpanManual { // There are no heap bits for value stored on the stack. // For a channel receive src might be on the stack of some // other goroutine, so we can't unwind the stack even if diff --git a/libgo/go/runtime/chan.go b/libgo/go/runtime/chan.go index 291fe0013d1..549e56620b6 100644 --- a/libgo/go/runtime/chan.go +++ b/libgo/go/runtime/chan.go @@ -133,6 +133,21 @@ func chanbuf(c *hchan, i uint) unsafe.Pointer { return add(c.buf, uintptr(i)*uintptr(c.elemsize)) } +// full reports whether a send on c would block (that is, the channel is full). +// It uses a single word-sized read of mutable state, so although +// the answer is instantaneously true, the correct answer may have changed +// by the time the calling function receives the return value. +func full(c *hchan) bool { + // c.dataqsiz is immutable (never written after the channel is created) + // so it is safe to read at any time during channel operation. + if c.dataqsiz == 0 { + // Assumes that a pointer read is relaxed-atomic. + return c.recvq.first == nil + } + // Assumes that a uint read is relaxed-atomic. + return c.qcount == c.dataqsiz +} + // entry point for c <- x from compiled code //go:nosplit func chansend1(c *hchan, elem unsafe.Pointer) { @@ -177,7 +192,7 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { // // After observing that the channel is not closed, we observe that the channel is // not ready for sending. Each of these observations is a single word-sized read - // (first c.closed and second c.recvq.first or c.qcount depending on kind of channel). + // (first c.closed and second full()). // Because a closed channel cannot transition from 'ready for sending' to // 'not ready for sending', even if the channel is closed between the two observations, // they imply a moment between the two when the channel was both not yet closed @@ -186,9 +201,10 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { // // It is okay if the reads are reordered here: if we observe that the channel is not // ready for sending and then observe that it is not closed, that implies that the - // channel wasn't closed during the first observation. - if !block && c.closed == 0 && ((c.dataqsiz == 0 && c.recvq.first == nil) || - (c.dataqsiz > 0 && c.qcount == c.dataqsiz)) { + // channel wasn't closed during the first observation. However, nothing here + // guarantees forward progress. We rely on the side effects of lock release in + // chanrecv() and closechan() to update this thread's view of c.closed and full(). + if !block && c.closed == 0 && full(c) { return false } @@ -250,7 +266,7 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { gp.waiting = mysg gp.param = nil c.sendq.enqueue(mysg) - goparkunlock(&c.lock, waitReasonChanSend, traceEvGoBlockSend, 3) + gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanSend, traceEvGoBlockSend, 2) // Ensure the value being sent is kept alive until the // receiver copies it out. The sudog has a pointer to the // stack object, but sudogs aren't considered as roots of the @@ -262,6 +278,7 @@ func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool { throw("G waiting list is corrupted") } gp.waiting = nil + gp.activeStackChans = false if gp.param == nil { if c.closed == 0 { throw("chansend: spurious wakeup") @@ -417,6 +434,16 @@ func closechan(c *hchan) { } } +// empty reports whether a read from c would block (that is, the channel is +// empty). It uses a single atomic read of mutable state. +func empty(c *hchan) bool { + // c.dataqsiz is immutable. + if c.dataqsiz == 0 { + return atomic.Loadp(unsafe.Pointer(&c.sendq.first)) == nil + } + return atomic.Loaduint(&c.qcount) == 0 +} + // entry points for <- c from compiled code //go:nosplit func chanrecv1(c *hchan, elem unsafe.Pointer) { @@ -457,21 +484,33 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) } // Fast path: check for failed non-blocking operation without acquiring the lock. - // - // After observing that the channel is not ready for receiving, we observe that the - // channel is not closed. Each of these observations is a single word-sized read - // (first c.sendq.first or c.qcount, and second c.closed). - // Because a channel cannot be reopened, the later observation of the channel - // being not closed implies that it was also not closed at the moment of the - // first observation. We behave as if we observed the channel at that moment - // and report that the receive cannot proceed. - // - // The order of operations is important here: reversing the operations can lead to - // incorrect behavior when racing with a close. - if !block && (c.dataqsiz == 0 && c.sendq.first == nil || - c.dataqsiz > 0 && atomic.Loaduint(&c.qcount) == 0) && - atomic.Load(&c.closed) == 0 { - return + if !block && empty(c) { + // After observing that the channel is not ready for receiving, we observe whether the + // channel is closed. + // + // Reordering of these checks could lead to incorrect behavior when racing with a close. + // For example, if the channel was open and not empty, was closed, and then drained, + // reordered reads could incorrectly indicate "open and empty". To prevent reordering, + // we use atomic loads for both checks, and rely on emptying and closing to happen in + // separate critical sections under the same lock. This assumption fails when closing + // an unbuffered channel with a blocked send, but that is an error condition anyway. + if atomic.Load(&c.closed) == 0 { + // Because a channel cannot be reopened, the later observation of the channel + // being not closed implies that it was also not closed at the moment of the + // first observation. We behave as if we observed the channel at that moment + // and report that the receive cannot proceed. + return + } + // The channel is irreversibly closed. Re-check whether the channel has any pending data + // to receive, which could have arrived between the empty and closed checks above. + // Sequential consistency is also required here, when racing with such a send. + if empty(c) { + // The channel is irreversibly closed and empty. + if ep != nil { + typedmemclr(c.elemtype, ep) + } + return true, false + } } var t0 int64 @@ -543,13 +582,14 @@ func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) mysg.c = c gp.param = nil c.recvq.enqueue(mysg) - goparkunlock(&c.lock, waitReasonChanReceive, traceEvGoBlockRecv, 3) + gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanReceive, traceEvGoBlockRecv, 2) // someone woke us up if mysg != gp.waiting { throw("G waiting list is corrupted") } gp.waiting = nil + gp.activeStackChans = false if mysg.releasetime > 0 { blockevent(mysg.releasetime-t0, 2) } @@ -616,6 +656,14 @@ func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) { goready(gp, skip+1) } +func chanparkcommit(gp *g, chanLock unsafe.Pointer) bool { + // There are unlocked sudogs that point into gp's stack. Stack + // copying must lock the channels of those sudogs. + gp.activeStackChans = true + unlock((*mutex)(chanLock)) + return true +} + // compiler implements // // select { diff --git a/libgo/go/runtime/chan_test.go b/libgo/go/runtime/chan_test.go index 29fb321c926..ac81d409bda 100644 --- a/libgo/go/runtime/chan_test.go +++ b/libgo/go/runtime/chan_test.go @@ -485,11 +485,11 @@ func TestSelectFairness(t *testing.T) { // If the select in the goroutine is fair, // cnt1 and cnt2 should be about the same value. // With 10,000 trials, the expected margin of error at - // a confidence level of five nines is 4.4172 / (2 * Sqrt(10000)). + // a confidence level of six nines is 4.891676 / (2 * Sqrt(10000)). r := float64(cnt1) / trials e := math.Abs(r - 0.5) t.Log(cnt1, cnt2, r, e) - if e > 4.4172/(2*math.Sqrt(trials)) { + if e > 4.891676/(2*math.Sqrt(trials)) { t.Errorf("unfair select: in %d trials, results were %d, %d", trials, cnt1, cnt2) } close(done) @@ -724,6 +724,7 @@ func TestSelectStackAdjust(t *testing.T) { if after.NumGC-before.NumGC >= 2 { goto done } + runtime.Gosched() } t.Fatal("failed to trigger concurrent GC") done: @@ -1131,6 +1132,20 @@ func BenchmarkChanPopular(b *testing.B) { wg.Wait() } +func BenchmarkChanClosed(b *testing.B) { + c := make(chan struct{}) + close(c) + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + select { + case <-c: + default: + b.Error("Unreachable") + } + } + }) +} + var ( alwaysFalse = false workSink = 0 diff --git a/libgo/go/runtime/checkptr.go b/libgo/go/runtime/checkptr.go new file mode 100644 index 00000000000..f478dddcf81 --- /dev/null +++ b/libgo/go/runtime/checkptr.go @@ -0,0 +1,106 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +package runtime + +import "unsafe" + +type ptrAlignError struct { + ptr unsafe.Pointer + elem *_type + n uintptr +} + +func (e ptrAlignError) RuntimeError() {} + +func (e ptrAlignError) Error() string { + return "runtime error: unsafe pointer conversion" +} + +func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) { + // Check that (*[n]elem)(p) is appropriately aligned. + // TODO(mdempsky): What about fieldAlign? + if uintptr(p)&(uintptr(elem.align)-1) != 0 { + panic(ptrAlignError{p, elem, n}) + } + + // Check that (*[n]elem)(p) doesn't straddle multiple heap objects. + if size := n * elem.size; size > 1 && checkptrBase(p) != checkptrBase(add(p, size-1)) { + panic(ptrAlignError{p, elem, n}) + } +} + +type ptrArithError struct { + ptr unsafe.Pointer + originals []unsafe.Pointer +} + +func (e ptrArithError) RuntimeError() {} + +func (e ptrArithError) Error() string { + return "runtime error: unsafe pointer arithmetic" +} + +func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) { + if 0 < uintptr(p) && uintptr(p) < minLegalPointer { + panic(ptrArithError{p, originals}) + } + + // Check that if the computed pointer p points into a heap + // object, then one of the original pointers must have pointed + // into the same object. + base := checkptrBase(p) + if base == 0 { + return + } + + for _, original := range originals { + if base == checkptrBase(original) { + return + } + } + + panic(ptrArithError{p, originals}) +} + +// checkptrBase returns the base address for the allocation containing +// the address p. +// +// Importantly, if p1 and p2 point into the same variable, then +// checkptrBase(p1) == checkptrBase(p2). However, the converse/inverse +// is not necessarily true as allocations can have trailing padding, +// and multiple variables may be packed into a single allocation. +func checkptrBase(p unsafe.Pointer) uintptr { + // stack + if gp := getg(); gp.stack.lo <= uintptr(p) && uintptr(p) < gp.stack.hi { + // TODO(mdempsky): Walk the stack to identify the + // specific stack frame or even stack object that p + // points into. + // + // In the mean time, use "1" as a pseudo-address to + // represent the stack. This is an invalid address on + // all platforms, so it's guaranteed to be distinct + // from any of the addresses we might return below. + return 1 + } + + // heap (must check after stack because of #35068) + if base, _, _ := findObject(uintptr(p), 0, 0); base != 0 { + return base + } + + // data or bss + for _, datap := range activeModules() { + if datap.data <= uintptr(p) && uintptr(p) < datap.edata { + return datap.data + } + if datap.bss <= uintptr(p) && uintptr(p) < datap.ebss { + return datap.bss + } + } + + return 0 +} diff --git a/libgo/go/runtime/crash_nonunix_test.go b/libgo/go/runtime/crash_nonunix_test.go index bf349a5d89d..06c197ec2b2 100644 --- a/libgo/go/runtime/crash_nonunix_test.go +++ b/libgo/go/runtime/crash_nonunix_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build windows plan9 nacl js,wasm +// +build windows plan9 js,wasm package runtime_test diff --git a/libgo/go/runtime/crash_test.go b/libgo/go/runtime/crash_test.go index 6343e8ef75f..6268f2ed726 100644 --- a/libgo/go/runtime/crash_test.go +++ b/libgo/go/runtime/crash_test.go @@ -104,8 +104,6 @@ func buildTestProg(t *testing.T, binary string, flags ...string) (string, error) t.Skip("-quick") } - checkStaleRuntime(t) - testprog.Lock() defer testprog.Unlock() if testprog.dir == "" { @@ -143,34 +141,12 @@ func buildTestProg(t *testing.T, binary string, flags ...string) (string, error) return exe, nil } -var ( - staleRuntimeOnce sync.Once // guards init of staleRuntimeErr - staleRuntimeErr error -) - -func checkStaleRuntime(t *testing.T) { - staleRuntimeOnce.Do(func() { - if runtime.Compiler == "gccgo" { - return - } - // 'go run' uses the installed copy of runtime.a, which may be out of date. - out, err := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "list", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "-f", "{{.Stale}}", "runtime")).CombinedOutput() - if err != nil { - staleRuntimeErr = fmt.Errorf("failed to execute 'go list': %v\n%v", err, string(out)) - return - } - if string(out) != "false\n" { - t.Logf("go list -f {{.Stale}} runtime:\n%s", out) - out, err := testenv.CleanCmdEnv(exec.Command(testenv.GoToolPath(t), "list", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "-f", "{{.StaleReason}}", "runtime")).CombinedOutput() - if err != nil { - t.Logf("go list -f {{.StaleReason}} failed: %v", err) - } - t.Logf("go list -f {{.StaleReason}} runtime:\n%s", out) - staleRuntimeErr = fmt.Errorf("Stale runtime.a. Run 'go install runtime'.") - } - }) - if staleRuntimeErr != nil { - t.Fatal(staleRuntimeErr) +func TestVDSO(t *testing.T) { + t.Parallel() + output := runTestProg(t, "testprog", "SignalInVDSO") + want := "success\n" + if output != want { + t.Fatalf("output:\n%s\n\nwanted:\n%s", output, want) } } @@ -231,9 +207,23 @@ func TestStackOverflow(t *testing.T) { t.Skip("gccgo does not do stack overflow checking") } output := runTestProg(t, "testprog", "StackOverflow") - want := "runtime: goroutine stack exceeds 1474560-byte limit\nfatal error: stack overflow" - if !strings.HasPrefix(output, want) { - t.Fatalf("output does not start with %q:\n%s", want, output) + want := []string{ + "runtime: goroutine stack exceeds 1474560-byte limit\n", + "fatal error: stack overflow", + // information about the current SP and stack bounds + "runtime: sp=", + "stack=[", + } + if !strings.HasPrefix(output, want[0]) { + t.Errorf("output does not start with %q", want[0]) + } + for _, s := range want[1:] { + if !strings.Contains(output, s) { + t.Errorf("output does not contain %q", s) + } + } + if t.Failed() { + t.Logf("output:\n%s", output) } } @@ -257,6 +247,41 @@ panic: again } +func TestRecursivePanic2(t *testing.T) { + output := runTestProg(t, "testprog", "RecursivePanic2") + want := `first panic +second panic +panic: third panic + +` + if !strings.HasPrefix(output, want) { + t.Fatalf("output does not start with %q:\n%s", want, output) + } + +} + +func TestRecursivePanic3(t *testing.T) { + output := runTestProg(t, "testprog", "RecursivePanic3") + want := `panic: first panic + +` + if !strings.HasPrefix(output, want) { + t.Fatalf("output does not start with %q:\n%s", want, output) + } + +} + +func TestRecursivePanic4(t *testing.T) { + output := runTestProg(t, "testprog", "RecursivePanic4") + want := `panic: first panic [recovered] + panic: second panic +` + if !strings.HasPrefix(output, want) { + t.Fatalf("output does not start with %q:\n%s", want, output) + } + +} + func TestGoexitCrash(t *testing.T) { output := runTestProg(t, "testprog", "GoexitExit") want := "no goroutines (main called runtime.Goexit) - deadlock!" @@ -389,26 +414,32 @@ func TestRecoveredPanicAfterGoexit(t *testing.T) { } func TestRecoverBeforePanicAfterGoexit(t *testing.T) { - // 1. defer a function that recovers - // 2. defer a function that panics - // 3. call goexit - // Goexit should run the #2 defer. Its panic - // should be caught by the #1 defer, and execution - // should resume in the caller. Like the Goexit - // never happened! - defer func() { - r := recover() - if r == nil { - panic("bad recover") - } - }() - defer func() { - panic("hello") - }() - runtime.Goexit() + t.Parallel() + output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit") + want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!" + if !strings.HasPrefix(output, want) { + t.Fatalf("output does not start with %q:\n%s", want, output) + } +} + +func TestRecoverBeforePanicAfterGoexit2(t *testing.T) { + t.Parallel() + output := runTestProg(t, "testprog", "RecoverBeforePanicAfterGoexit2") + want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!" + if !strings.HasPrefix(output, want) { + t.Fatalf("output does not start with %q:\n%s", want, output) + } } func TestNetpollDeadlock(t *testing.T) { + if os.Getenv("GO_BUILDER_NAME") == "darwin-amd64-10_12" { + // A suspected kernel bug in macOS 10.12 occasionally results in + // an apparent deadlock when dialing localhost. The errors have not + // been observed on newer versions of the OS, so we don't plan to work + // around them. See https://golang.org/issue/22019. + testenv.SkipFlaky(t, 22019) + } + t.Parallel() output := runTestProg(t, "testprognet", "NetpollDeadlock") want := "done\n" @@ -420,7 +451,7 @@ func TestNetpollDeadlock(t *testing.T) { func TestPanicTraceback(t *testing.T) { t.Parallel() output := runTestProg(t, "testprog", "PanicTraceback") - want := "panic: hello" + want := "panic: hello\n\tpanic: panic pt2\n\tpanic: panic pt1\n" if !strings.HasPrefix(output, want) { t.Fatalf("output does not start with %q:\n%s", want, output) } diff --git a/libgo/go/runtime/crash_unix_test.go b/libgo/go/runtime/crash_unix_test.go index b4b015e09de..7ce5bb207d1 100644 --- a/libgo/go/runtime/crash_unix_test.go +++ b/libgo/go/runtime/crash_unix_test.go @@ -15,9 +15,11 @@ import ( "os/exec" "path/filepath" "runtime" - "strings" + "sync" "syscall" "testing" + "time" + "unsafe" ) // sigquit is the signal to send to kill a hanging testdata program. @@ -33,6 +35,29 @@ func init() { } } +func TestBadOpen(t *testing.T) { + // make sure we get the correct error code if open fails. Same for + // read/write/close on the resulting -1 fd. See issue 10052. + nonfile := []byte("/notreallyafile") + fd := runtime.Open(&nonfile[0], 0, 0) + if fd != -1 { + t.Errorf("open(%q)=%d, want -1", nonfile, fd) + } + var buf [32]byte + r := runtime.Read(-1, unsafe.Pointer(&buf[0]), int32(len(buf))) + if got, want := r, -int32(syscall.EBADF); got != want { + t.Errorf("read()=%d, want %d", got, want) + } + w := runtime.Write(^uintptr(0), unsafe.Pointer(&buf[0]), int32(len(buf))) + if got, want := w, -int32(syscall.EBADF); got != want { + t.Errorf("write()=%d, want %d", got, want) + } + c := runtime.Close(-1) + if c != -1 { + t.Errorf("close()=%d, want -1", c) + } +} + func TestCrashDumpsAllThreads(t *testing.T) { if *flagQuick { t.Skip("-quick") @@ -53,8 +78,6 @@ func TestCrashDumpsAllThreads(t *testing.T) { testenv.MustHaveGoBuild(t) - checkStaleRuntime(t) - t.Parallel() dir, err := ioutil.TempDir("", "go-build") @@ -76,18 +99,17 @@ func TestCrashDumpsAllThreads(t *testing.T) { cmd = exec.Command(filepath.Join(dir, "a.exe")) cmd = testenv.CleanCmdEnv(cmd) - cmd.Env = append(cmd.Env, "GOTRACEBACK=crash") - - // Set GOGC=off. Because of golang.org/issue/10958, the tight - // loops in the test program are not preemptible. If GC kicks - // in, it may lock up and prevent main from saying it's ready. - newEnv := []string{} - for _, s := range cmd.Env { - if !strings.HasPrefix(s, "GOGC=") { - newEnv = append(newEnv, s) - } - } - cmd.Env = append(newEnv, "GOGC=off") + cmd.Env = append(cmd.Env, + "GOTRACEBACK=crash", + // Set GOGC=off. Because of golang.org/issue/10958, the tight + // loops in the test program are not preemptible. If GC kicks + // in, it may lock up and prevent main from saying it's ready. + "GOGC=off", + // Set GODEBUG=asyncpreemptoff=1. If a thread is preempted + // when it receives SIGQUIT, it won't show the expected + // stack trace. See issue 35356. + "GODEBUG=asyncpreemptoff=1", + ) var outbuf bytes.Buffer cmd.Stdout = &outbuf @@ -288,3 +310,51 @@ func TestSignalDuringExec(t *testing.T) { t.Fatalf("want %s, got %s\n", want, output) } } + +func TestSignalM(t *testing.T) { + if runtime.Compiler == "gccgo" { + t.Skip("no signalM for gccgo") + } + + r, w, errno := runtime.Pipe() + if errno != 0 { + t.Fatal(syscall.Errno(errno)) + } + defer func() { + runtime.Close(r) + runtime.Close(w) + }() + runtime.Closeonexec(r) + runtime.Closeonexec(w) + + var want, got int64 + var wg sync.WaitGroup + ready := make(chan *runtime.M) + wg.Add(1) + go func() { + runtime.LockOSThread() + want, got = runtime.WaitForSigusr1(r, w, func(mp *runtime.M) { + ready <- mp + }) + runtime.UnlockOSThread() + wg.Done() + }() + waitingM := <-ready + runtime.SendSigusr1(waitingM) + + timer := time.AfterFunc(time.Second, func() { + // Write 1 to tell WaitForSigusr1 that we timed out. + bw := byte(1) + if n := runtime.Write(uintptr(w), unsafe.Pointer(&bw), 1); n != 1 { + t.Errorf("pipe write failed: %d", n) + } + }) + defer timer.Stop() + + wg.Wait() + if got == -1 { + t.Fatal("signalM signal not received") + } else if want != got { + t.Fatalf("signal sent to M %d, but received on M %d", want, got) + } +} diff --git a/libgo/go/runtime/debug.go b/libgo/go/runtime/debug.go index e480466b4d5..1202e362a5a 100644 --- a/libgo/go/runtime/debug.go +++ b/libgo/go/runtime/debug.go @@ -26,12 +26,12 @@ func GOMAXPROCS(n int) int { return ret } - stopTheWorld("GOMAXPROCS") + stopTheWorldGC("GOMAXPROCS") // newprocs will be processed by startTheWorld newprocs = int32(n) - startTheWorld() + startTheWorldGC() return ret } diff --git a/libgo/go/runtime/debug/heapdump_test.go b/libgo/go/runtime/debug/heapdump_test.go index c986efcb325..de1ec27d21e 100644 --- a/libgo/go/runtime/debug/heapdump_test.go +++ b/libgo/go/runtime/debug/heapdump_test.go @@ -13,7 +13,7 @@ import ( ) func TestWriteHeapDumpNonempty(t *testing.T) { - if runtime.GOOS == "nacl" || runtime.GOOS == "js" { + if runtime.GOOS == "js" { t.Skipf("WriteHeapDump is not available on %s.", runtime.GOOS) } f, err := ioutil.TempFile("", "heapdumptest") @@ -42,7 +42,7 @@ func objfin(x *Obj) { } func TestWriteHeapDumpFinalizers(t *testing.T) { - if runtime.GOOS == "nacl" || runtime.GOOS == "js" { + if runtime.GOOS == "js" { t.Skipf("WriteHeapDump is not available on %s.", runtime.GOOS) } f, err := ioutil.TempFile("", "heapdumptest") diff --git a/libgo/go/runtime/debug/mod.go b/libgo/go/runtime/debug/mod.go index 58c6ae019af..c283928ff99 100644 --- a/libgo/go/runtime/debug/mod.go +++ b/libgo/go/runtime/debug/mod.go @@ -23,7 +23,7 @@ func ReadBuildInfo() (info *BuildInfo, ok bool) { // the running binary. type BuildInfo struct { Path string // The main package path - Main Module // The main module information + Main Module // The module containing the main package Deps []*Module // Module dependencies } diff --git a/libgo/go/runtime/debug_test.go b/libgo/go/runtime/debug_test.go index 12d93de3047..967477dd8c2 100644 --- a/libgo/go/runtime/debug_test.go +++ b/libgo/go/runtime/debug_test.go @@ -127,7 +127,7 @@ func TestDebugCall(t *testing.T) { return x + 1 } args.x = 42 - if _, err := runtime.InjectDebugCall(g, fn, &args, debugCallTKill); err != nil { + if _, err := runtime.InjectDebugCall(g, fn, &args, debugCallTKill, false); err != nil { t.Fatal(err) } if args.yRet != 43 { @@ -156,7 +156,7 @@ func TestDebugCallLarge(t *testing.T) { args.in[i] = i want[i] = i + 1 } - if _, err := runtime.InjectDebugCall(g, fn, &args, debugCallTKill); err != nil { + if _, err := runtime.InjectDebugCall(g, fn, &args, debugCallTKill, false); err != nil { t.Fatal(err) } if want != args.out { @@ -169,7 +169,7 @@ func TestDebugCallGC(t *testing.T) { defer after() // Inject a call that performs a GC. - if _, err := runtime.InjectDebugCall(g, runtime.GC, nil, debugCallTKill); err != nil { + if _, err := runtime.InjectDebugCall(g, runtime.GC, nil, debugCallTKill, false); err != nil { t.Fatal(err) } } @@ -180,7 +180,7 @@ func TestDebugCallGrowStack(t *testing.T) { // Inject a call that grows the stack. debugCallWorker checks // for stack pointer breakage. - if _, err := runtime.InjectDebugCall(g, func() { growStack(nil) }, nil, debugCallTKill); err != nil { + if _, err := runtime.InjectDebugCall(g, func() { growStack(nil) }, nil, debugCallTKill, false); err != nil { t.Fatal(err) } } @@ -216,7 +216,7 @@ func TestDebugCallUnsafePoint(t *testing.T) { runtime.Gosched() } - _, err := runtime.InjectDebugCall(g, func() {}, nil, debugCallTKill) + _, err := runtime.InjectDebugCall(g, func() {}, nil, debugCallTKill, true) if msg := "call not at safe point"; err == nil || err.Error() != msg { t.Fatalf("want %q, got %s", msg, err) } @@ -240,7 +240,7 @@ func TestDebugCallPanic(t *testing.T) { }() g := <-ready - p, err := runtime.InjectDebugCall(g, func() { panic("test") }, nil, debugCallTKill) + p, err := runtime.InjectDebugCall(g, func() { panic("test") }, nil, debugCallTKill, false) if err != nil { t.Fatal(err) } diff --git a/libgo/go/runtime/debuglog.go b/libgo/go/runtime/debuglog.go index 4f4109f71a6..404d0570a0b 100644 --- a/libgo/go/runtime/debuglog.go +++ b/libgo/go/runtime/debuglog.go @@ -803,7 +803,7 @@ func printDebugLog() { func printDebugLogPC(pc uintptr) { print(hex(pc)) - name, file, line, _ := funcfileline(pc, -1) + name, file, line, _ := funcfileline(pc, -1, false) if name == "" { print(" [unknown PC]") } else { diff --git a/libgo/go/runtime/defer_test.go b/libgo/go/runtime/defer_test.go new file mode 100644 index 00000000000..3d8f81277f3 --- /dev/null +++ b/libgo/go/runtime/defer_test.go @@ -0,0 +1,283 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "fmt" + "reflect" + "runtime" + "testing" +) + +// Make sure open-coded defer exit code is not lost, even when there is an +// unconditional panic (hence no return from the function) +func TestUnconditionalPanic(t *testing.T) { + defer func() { + if recover() != "testUnconditional" { + t.Fatal("expected unconditional panic") + } + }() + panic("testUnconditional") +} + +var glob int = 3 + +// Test an open-coded defer and non-open-coded defer - make sure both defers run +// and call recover() +func TestOpenAndNonOpenDefers(t *testing.T) { + for { + // Non-open defer because in a loop + defer func(n int) { + if recover() != "testNonOpenDefer" { + t.Fatal("expected testNonOpen panic") + } + }(3) + if glob > 2 { + break + } + } + testOpen(t, 47) + panic("testNonOpenDefer") +} + +//go:noinline +func testOpen(t *testing.T, arg int) { + defer func(n int) { + if recover() != "testOpenDefer" { + t.Fatal("expected testOpen panic") + } + }(4) + if arg > 2 { + panic("testOpenDefer") + } +} + +// Test a non-open-coded defer and an open-coded defer - make sure both defers run +// and call recover() +func TestNonOpenAndOpenDefers(t *testing.T) { + testOpen(t, 47) + for { + // Non-open defer because in a loop + defer func(n int) { + if recover() != "testNonOpenDefer" { + t.Fatal("expected testNonOpen panic") + } + }(3) + if glob > 2 { + break + } + } + panic("testNonOpenDefer") +} + +var list []int + +// Make sure that conditional open-coded defers are activated correctly and run in +// the correct order. +func TestConditionalDefers(t *testing.T) { + list = make([]int, 0, 10) + + defer func() { + if recover() != "testConditional" { + t.Fatal("expected panic") + } + want := []int{4, 2, 1} + if !reflect.DeepEqual(want, list) { + t.Fatal(fmt.Sprintf("wanted %v, got %v", want, list)) + } + + }() + testConditionalDefers(8) +} + +func testConditionalDefers(n int) { + doappend := func(i int) { + list = append(list, i) + } + + defer doappend(1) + if n > 5 { + defer doappend(2) + if n > 8 { + defer doappend(3) + } else { + defer doappend(4) + } + } + panic("testConditional") +} + +// Test that there is no compile-time or run-time error if an open-coded defer +// call is removed by constant propagation and dead-code elimination. +func TestDisappearingDefer(t *testing.T) { + switch runtime.GOOS { + case "invalidOS": + defer func() { + t.Fatal("Defer shouldn't run") + }() + } +} + +// This tests an extra recursive panic behavior that is only specified in the +// code. Suppose a first panic P1 happens and starts processing defer calls. If a +// second panic P2 happens while processing defer call D in frame F, then defer +// call processing is restarted (with some potentially new defer calls created by +// D or its callees). If the defer processing reaches the started defer call D +// again in the defer stack, then the original panic P1 is aborted and cannot +// continue panic processing or be recovered. If the panic P2 does a recover at +// some point, it will naturally remove the original panic P1 from the stack +// (since the original panic had to be in frame F or a descendant of F). +func TestAbortedPanic(t *testing.T) { + defer func() { + r := recover() + if r != nil { + t.Fatal(fmt.Sprintf("wanted nil recover, got %v", r)) + } + }() + defer func() { + r := recover() + if r != "panic2" { + t.Fatal(fmt.Sprintf("wanted %v, got %v", "panic2", r)) + } + }() + defer func() { + panic("panic2") + }() + panic("panic1") +} + +// This tests that recover() does not succeed unless it is called directly from a +// defer function that is directly called by the panic. Here, we first call it +// from a defer function that is created by the defer function called directly by +// the panic. In +func TestRecoverMatching(t *testing.T) { + defer func() { + r := recover() + if r != "panic1" { + t.Fatal(fmt.Sprintf("wanted %v, got %v", "panic1", r)) + } + }() + defer func() { + defer func() { + // Shouldn't succeed, even though it is called directly + // from a defer function, since this defer function was + // not directly called by the panic. + r := recover() + if r != nil { + t.Fatal(fmt.Sprintf("wanted nil recover, got %v", r)) + } + }() + }() + panic("panic1") +} + +type nonSSAable [128]byte + +type bigStruct struct { + x, y, z, w, p, q int64 +} + +type containsBigStruct struct { + element bigStruct +} + +func mknonSSAable() nonSSAable { + globint1++ + return nonSSAable{0, 0, 0, 0, 5} +} + +var globint1, globint2, globint3 int + +//go:noinline +func sideeffect(n int64) int64 { + globint2++ + return n +} + +func sideeffect2(in containsBigStruct) containsBigStruct { + globint3++ + return in +} + +// Test that nonSSAable arguments to defer are handled correctly and only evaluated once. +func TestNonSSAableArgs(t *testing.T) { + globint1 = 0 + globint2 = 0 + globint3 = 0 + var save1 byte + var save2 int64 + var save3 int64 + var save4 int64 + + defer func() { + if globint1 != 1 { + t.Fatal(fmt.Sprintf("globint1: wanted: 1, got %v", globint1)) + } + if save1 != 5 { + t.Fatal(fmt.Sprintf("save1: wanted: 5, got %v", save1)) + } + if globint2 != 1 { + t.Fatal(fmt.Sprintf("globint2: wanted: 1, got %v", globint2)) + } + if save2 != 2 { + t.Fatal(fmt.Sprintf("save2: wanted: 2, got %v", save2)) + } + if save3 != 4 { + t.Fatal(fmt.Sprintf("save3: wanted: 4, got %v", save3)) + } + if globint3 != 1 { + t.Fatal(fmt.Sprintf("globint3: wanted: 1, got %v", globint3)) + } + if save4 != 4 { + t.Fatal(fmt.Sprintf("save1: wanted: 4, got %v", save4)) + } + }() + + // Test function returning a non-SSAable arg + defer func(n nonSSAable) { + save1 = n[4] + }(mknonSSAable()) + // Test composite literal that is not SSAable + defer func(b bigStruct) { + save2 = b.y + }(bigStruct{1, 2, 3, 4, 5, sideeffect(6)}) + + // Test struct field reference that is non-SSAable + foo := containsBigStruct{} + foo.element.z = 4 + defer func(element bigStruct) { + save3 = element.z + }(foo.element) + defer func(element bigStruct) { + save4 = element.z + }(sideeffect2(foo).element) +} + +//go:noinline +func doPanic() { + panic("Test panic") +} + +func TestDeferForFuncWithNoExit(t *testing.T) { + cond := 1 + defer func() { + if cond != 2 { + t.Fatal(fmt.Sprintf("cond: wanted 2, got %v", cond)) + } + if recover() != "Test panic" { + t.Fatal("Didn't find expected panic") + } + }() + x := 0 + // Force a stack copy, to make sure that the &cond pointer passed to defer + // function is properly updated. + growStackIter(&x, 1000) + cond = 2 + doPanic() + + // This function has no exit/return, since it ends with an infinite loop + for { + } +} diff --git a/libgo/go/runtime/env_posix.go b/libgo/go/runtime/env_posix.go index c725bd93673..bf8996cd50d 100644 --- a/libgo/go/runtime/env_posix.go +++ b/libgo/go/runtime/env_posix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package runtime diff --git a/libgo/go/runtime/error.go b/libgo/go/runtime/error.go index 0c7f6319884..6cc46bfc3ee 100644 --- a/libgo/go/runtime/error.go +++ b/libgo/go/runtime/error.go @@ -129,7 +129,7 @@ func (e plainError) Error() string { return string(e) } -// An boundsError represents a an indexing or slicing operation gone wrong. +// A boundsError represents an indexing or slicing operation gone wrong. type boundsError struct { x int64 y int diff --git a/libgo/go/runtime/export_debug_test.go b/libgo/go/runtime/export_debug_test.go index 608d7567808..769ad55c588 100644 --- a/libgo/go/runtime/export_debug_test.go +++ b/libgo/go/runtime/export_debug_test.go @@ -21,7 +21,7 @@ import ( // // On success, InjectDebugCall returns the panic value of fn or nil. // If fn did not panic, its results will be available in args. -func InjectDebugCall(gp *g, fn, args interface{}, tkill func(tid int) error) (interface{}, error) { +func InjectDebugCall(gp *g, fn, args interface{}, tkill func(tid int) error, returnOnUnsafePoint bool) (interface{}, error) { if gp.lockedm == 0 { return nil, plainError("goroutine not locked to thread") } @@ -65,9 +65,16 @@ func InjectDebugCall(gp *g, fn, args interface{}, tkill func(tid int) error) (in notetsleepg(&h.done, -1) if h.err != "" { switch h.err { - case "retry _Grunnable", "executing on Go runtime stack": + case "call not at safe point": + if returnOnUnsafePoint { + // This is for TestDebugCallUnsafePoint. + return nil, h.err + } + fallthrough + case "retry _Grunnable", "executing on Go runtime stack", "call from within the Go runtime": // These are transient states. Try to get out of them. if i < 100 { + usleep(100) Gosched() continue } diff --git a/libgo/go/runtime/export_linux_test.go b/libgo/go/runtime/export_linux_test.go index 96ff1c73159..1f8e6336ead 100644 --- a/libgo/go/runtime/export_linux_test.go +++ b/libgo/go/runtime/export_linux_test.go @@ -10,6 +10,9 @@ import "unsafe" // var NewOSProc0 = newosproc0 // var Mincore = mincore +var Add = add + +type EpollEvent epollevent func Epollctl(epfd, op, fd int32, ev unsafe.Pointer) int32 { return epollctl(epfd, op, fd, (*epollevent)(ev)) diff --git a/libgo/go/runtime/export_mmap_test.go b/libgo/go/runtime/export_mmap_test.go index 5f3e99af2cc..000948b78c3 100644 --- a/libgo/go/runtime/export_mmap_test.go +++ b/libgo/go/runtime/export_mmap_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris // Export guts for testing. diff --git a/libgo/go/runtime/export_test.go b/libgo/go/runtime/export_test.go index 10890d35a65..9a977d829b3 100644 --- a/libgo/go/runtime/export_test.go +++ b/libgo/go/runtime/export_test.go @@ -35,9 +35,18 @@ var Atoi = atoi var Atoi32 = atoi32 var Nanotime = nanotime +var NetpollBreak = netpollBreak +var Usleep = usleep +var PhysPageSize = physPageSize var PhysHugePageSize = physHugePageSize +var NetpollGenericInit = netpollGenericInit + +var ParseRelease = parseRelease + +const PreemptMSupported = preemptMSupported + type LFNode struct { Next uint64 Pushcnt uintptr @@ -51,6 +60,12 @@ func LFStackPop(head *uint64) *LFNode { return (*LFNode)(unsafe.Pointer((*lfstack)(head).pop())) } +func Netpoll(delta int64) { + systemstack(func() { + netpoll(delta) + }) +} + func GCMask(x interface{}) (ret []byte) { return nil } @@ -241,7 +256,7 @@ func CountPagesInUse() (pagesInUse, counted uintptr) { pagesInUse = uintptr(mheap_.pagesInUse) for _, s := range mheap_.allspans { - if s.state == mSpanInUse { + if s.state.get() == mSpanInUse { counted += s.npages } } @@ -303,7 +318,7 @@ func ReadMemStatsSlow() (base, slow MemStats) { // Add up current allocations in spans. for _, s := range mheap_.allspans { - if s.state != mSpanInUse { + if s.state.get() != mSpanInUse { continue } if sizeclass := s.spanclass.sizeclass(); sizeclass == 0 { @@ -336,10 +351,18 @@ func ReadMemStatsSlow() (base, slow MemStats) { slow.BySize[i].Frees = bySize[i].Frees } - for i := mheap_.free.start(0, 0); i.valid(); i = i.next() { - slow.HeapReleased += uint64(i.span().released()) + for i := mheap_.pages.start; i < mheap_.pages.end; i++ { + pg := mheap_.pages.chunkOf(i).scavenged.popcntRange(0, pallocChunkPages) + slow.HeapReleased += uint64(pg) * pageSize + } + for _, p := range allp { + pg := sys.OnesCount64(p.pcache.scav) + slow.HeapReleased += uint64(pg) * pageSize } + // Unused space in the current arena also counts as released space. + slow.HeapReleased += uint64(mheap_.curArena.end - mheap_.curArena.base) + getg().m.mallocing-- }) @@ -512,200 +535,410 @@ func MapTombstoneCheck(m map[int]int) { } } -// UnscavHugePagesSlow returns the value of mheap_.freeHugePages -// and the number of unscavenged huge pages calculated by -// scanning the heap. -func UnscavHugePagesSlow() (uintptr, uintptr) { - var base, slow uintptr - // Run on the system stack to avoid deadlock from stack growth - // trying to acquire the heap lock. - systemstack(func() { - lock(&mheap_.lock) - base = mheap_.free.unscavHugePages - for _, s := range mheap_.allspans { - if s.state == mSpanFree && !s.scavenged { - slow += s.hugePages() - } - } - unlock(&mheap_.lock) - }) - return base, slow -} +func RunGetgThreadSwitchTest() { + // Test that getg works correctly with thread switch. + // With gccgo, if we generate getg inlined, the backend + // may cache the address of the TLS variable, which + // will become invalid after a thread switch. This test + // checks that the bad caching doesn't happen. -// Span is a safe wrapper around an mspan, whose memory -// is managed manually. -type Span struct { - *mspan + ch := make(chan int) + go func(ch chan int) { + ch <- 5 + LockOSThread() + }(ch) + + g1 := getg() + + // Block on a receive. This is likely to get us a thread + // switch. If we yield to the sender goroutine, it will + // lock the thread, forcing us to resume on a different + // thread. + <-ch + + g2 := getg() + if g1 != g2 { + panic("g1 != g2") + } + + // Also test getg after some control flow, as the + // backend is sensitive to control flow. + g3 := getg() + if g1 != g3 { + panic("g1 != g3") + } } -func AllocSpan(base, npages uintptr, scavenged bool) Span { - var s *mspan - systemstack(func() { - lock(&mheap_.lock) - s = (*mspan)(mheap_.spanalloc.alloc()) - unlock(&mheap_.lock) - }) - s.init(base, npages) - s.scavenged = scavenged - return Span{s} +const ( + PageSize = pageSize + PallocChunkPages = pallocChunkPages + PageAlloc64Bit = pageAlloc64Bit +) + +// Expose pallocSum for testing. +type PallocSum pallocSum + +func PackPallocSum(start, max, end uint) PallocSum { return PallocSum(packPallocSum(start, max, end)) } +func (m PallocSum) Start() uint { return pallocSum(m).start() } +func (m PallocSum) Max() uint { return pallocSum(m).max() } +func (m PallocSum) End() uint { return pallocSum(m).end() } + +// Expose pallocBits for testing. +type PallocBits pallocBits + +func (b *PallocBits) Find(npages uintptr, searchIdx uint) (uint, uint) { + return (*pallocBits)(b).find(npages, searchIdx) } +func (b *PallocBits) AllocRange(i, n uint) { (*pallocBits)(b).allocRange(i, n) } +func (b *PallocBits) Free(i, n uint) { (*pallocBits)(b).free(i, n) } +func (b *PallocBits) Summarize() PallocSum { return PallocSum((*pallocBits)(b).summarize()) } +func (b *PallocBits) PopcntRange(i, n uint) uint { return (*pageBits)(b).popcntRange(i, n) } -func (s *Span) Free() { - systemstack(func() { - lock(&mheap_.lock) - mheap_.spanalloc.free(unsafe.Pointer(s.mspan)) - unlock(&mheap_.lock) - }) - s.mspan = nil +// SummarizeSlow is a slow but more obviously correct implementation +// of (*pallocBits).summarize. Used for testing. +func SummarizeSlow(b *PallocBits) PallocSum { + var start, max, end uint + + const N = uint(len(b)) * 64 + for start < N && (*pageBits)(b).get(start) == 0 { + start++ + } + for end < N && (*pageBits)(b).get(N-end-1) == 0 { + end++ + } + run := uint(0) + for i := uint(0); i < N; i++ { + if (*pageBits)(b).get(i) == 0 { + run++ + } else { + run = 0 + } + if run > max { + max = run + } + } + return PackPallocSum(start, max, end) } -func (s Span) Base() uintptr { - return s.mspan.base() +// Expose non-trivial helpers for testing. +func FindBitRange64(c uint64, n uint) uint { return findBitRange64(c, n) } + +// Given two PallocBits, returns a set of bit ranges where +// they differ. +func DiffPallocBits(a, b *PallocBits) []BitRange { + ba := (*pageBits)(a) + bb := (*pageBits)(b) + + var d []BitRange + base, size := uint(0), uint(0) + for i := uint(0); i < uint(len(ba))*64; i++ { + if ba.get(i) != bb.get(i) { + if size == 0 { + base = i + } + size++ + } else { + if size != 0 { + d = append(d, BitRange{base, size}) + } + size = 0 + } + } + if size != 0 { + d = append(d, BitRange{base, size}) + } + return d +} + +// StringifyPallocBits gets the bits in the bit range r from b, +// and returns a string containing the bits as ASCII 0 and 1 +// characters. +func StringifyPallocBits(b *PallocBits, r BitRange) string { + str := "" + for j := r.I; j < r.I+r.N; j++ { + if (*pageBits)(b).get(j) != 0 { + str += "1" + } else { + str += "0" + } + } + return str } -func (s Span) Pages() uintptr { - return s.mspan.npages +// Expose pallocData for testing. +type PallocData pallocData + +func (d *PallocData) FindScavengeCandidate(searchIdx uint, min, max uintptr) (uint, uint) { + return (*pallocData)(d).findScavengeCandidate(searchIdx, min, max) +} +func (d *PallocData) AllocRange(i, n uint) { (*pallocData)(d).allocRange(i, n) } +func (d *PallocData) ScavengedSetRange(i, n uint) { + (*pallocData)(d).scavenged.setRange(i, n) +} +func (d *PallocData) PallocBits() *PallocBits { + return (*PallocBits)(&(*pallocData)(d).pallocBits) +} +func (d *PallocData) Scavenged() *PallocBits { + return (*PallocBits)(&(*pallocData)(d).scavenged) } -type TreapIterType treapIterType +// Expose fillAligned for testing. +func FillAligned(x uint64, m uint) uint64 { return fillAligned(x, m) } -const ( - TreapIterScav TreapIterType = TreapIterType(treapIterScav) - TreapIterHuge = TreapIterType(treapIterHuge) - TreapIterBits = treapIterBits -) +// Expose pageCache for testing. +type PageCache pageCache -type TreapIterFilter treapIterFilter +const PageCachePages = pageCachePages -func TreapFilter(mask, match TreapIterType) TreapIterFilter { - return TreapIterFilter(treapFilter(treapIterType(mask), treapIterType(match))) +func NewPageCache(base uintptr, cache, scav uint64) PageCache { + return PageCache(pageCache{base: base, cache: cache, scav: scav}) } - -func (s Span) MatchesIter(mask, match TreapIterType) bool { - return treapFilter(treapIterType(mask), treapIterType(match)).matches(s.treapFilter()) +func (c *PageCache) Empty() bool { return (*pageCache)(c).empty() } +func (c *PageCache) Base() uintptr { return (*pageCache)(c).base } +func (c *PageCache) Cache() uint64 { return (*pageCache)(c).cache } +func (c *PageCache) Scav() uint64 { return (*pageCache)(c).scav } +func (c *PageCache) Alloc(npages uintptr) (uintptr, uintptr) { + return (*pageCache)(c).alloc(npages) } - -type TreapIter struct { - treapIter +func (c *PageCache) Flush(s *PageAlloc) { + (*pageCache)(c).flush((*pageAlloc)(s)) } -func (t TreapIter) Span() Span { - return Span{t.span()} +// Expose chunk index type. +type ChunkIdx chunkIdx + +// Expose pageAlloc for testing. Note that because pageAlloc is +// not in the heap, so is PageAlloc. +type PageAlloc pageAlloc + +func (p *PageAlloc) Alloc(npages uintptr) (uintptr, uintptr) { + return (*pageAlloc)(p).alloc(npages) +} +func (p *PageAlloc) AllocToCache() PageCache { + return PageCache((*pageAlloc)(p).allocToCache()) +} +func (p *PageAlloc) Free(base, npages uintptr) { + (*pageAlloc)(p).free(base, npages) +} +func (p *PageAlloc) Bounds() (ChunkIdx, ChunkIdx) { + return ChunkIdx((*pageAlloc)(p).start), ChunkIdx((*pageAlloc)(p).end) +} +func (p *PageAlloc) Scavenge(nbytes uintptr, locked bool) (r uintptr) { + systemstack(func() { + r = (*pageAlloc)(p).scavenge(nbytes, locked) + }) + return +} +func (p *PageAlloc) InUse() []AddrRange { + ranges := make([]AddrRange, 0, len(p.inUse.ranges)) + for _, r := range p.inUse.ranges { + ranges = append(ranges, AddrRange{ + Base: r.base, + Limit: r.limit, + }) + } + return ranges } -func (t TreapIter) Valid() bool { - return t.valid() +// Returns nil if the PallocData's L2 is missing. +func (p *PageAlloc) PallocData(i ChunkIdx) *PallocData { + ci := chunkIdx(i) + l2 := (*pageAlloc)(p).chunks[ci.l1()] + if l2 == nil { + return nil + } + return (*PallocData)(&l2[ci.l2()]) } -func (t TreapIter) Next() TreapIter { - return TreapIter{t.next()} +// AddrRange represents a range over addresses. +// Specifically, it represents the range [Base, Limit). +type AddrRange struct { + Base, Limit uintptr } -func (t TreapIter) Prev() TreapIter { - return TreapIter{t.prev()} +// BitRange represents a range over a bitmap. +type BitRange struct { + I, N uint // bit index and length in bits } -// Treap is a safe wrapper around mTreap for testing. +// NewPageAlloc creates a new page allocator for testing and +// initializes it with the scav and chunks maps. Each key in these maps +// represents a chunk index and each value is a series of bit ranges to +// set within each bitmap's chunk. // -// It must never be heap-allocated because mTreap is -// notinheap. +// The initialization of the pageAlloc preserves the invariant that if a +// scavenged bit is set the alloc bit is necessarily unset, so some +// of the bits described by scav may be cleared in the final bitmap if +// ranges in chunks overlap with them. // -//go:notinheap -type Treap struct { - mTreap -} +// scav is optional, and if nil, the scavenged bitmap will be cleared +// (as opposed to all 1s, which it usually is). Furthermore, every +// chunk index in scav must appear in chunks; ones that do not are +// ignored. +func NewPageAlloc(chunks, scav map[ChunkIdx][]BitRange) *PageAlloc { + p := new(pageAlloc) + + // We've got an entry, so initialize the pageAlloc. + p.init(new(mutex), nil) + p.test = true + + for i, init := range chunks { + addr := chunkBase(chunkIdx(i)) + + // Mark the chunk's existence in the pageAlloc. + p.grow(addr, pallocChunkBytes) + + // Initialize the bitmap and update pageAlloc metadata. + chunk := p.chunkOf(chunkIndex(addr)) + + // Clear all the scavenged bits which grow set. + chunk.scavenged.clearRange(0, pallocChunkPages) + + // Apply scavenge state if applicable. + if scav != nil { + if scvg, ok := scav[i]; ok { + for _, s := range scvg { + // Ignore the case of s.N == 0. setRange doesn't handle + // it and it's a no-op anyway. + if s.N != 0 { + chunk.scavenged.setRange(s.I, s.N) + } + } + } + } + p.resetScavengeAddr() + + // Apply alloc state. + for _, s := range init { + // Ignore the case of s.N == 0. allocRange doesn't handle + // it and it's a no-op anyway. + if s.N != 0 { + chunk.allocRange(s.I, s.N) + } + } -func (t *Treap) Start(mask, match TreapIterType) TreapIter { - return TreapIter{t.start(treapIterType(mask), treapIterType(match))} + // Update heap metadata for the allocRange calls above. + p.update(addr, pallocChunkPages, false, false) + } + return (*PageAlloc)(p) } -func (t *Treap) End(mask, match TreapIterType) TreapIter { - return TreapIter{t.end(treapIterType(mask), treapIterType(match))} -} +// FreePageAlloc releases hard OS resources owned by the pageAlloc. Once this +// is called the pageAlloc may no longer be used. The object itself will be +// collected by the garbage collector once it is no longer live. +func FreePageAlloc(pp *PageAlloc) { + p := (*pageAlloc)(pp) -func (t *Treap) Insert(s Span) { - // mTreap uses a fixalloc in mheap_ for treapNode - // allocation which requires the mheap_ lock to manipulate. - // Locking here is safe because the treap itself never allocs - // or otherwise ends up grabbing this lock. - systemstack(func() { - lock(&mheap_.lock) - t.insert(s.mspan) - unlock(&mheap_.lock) - }) - t.CheckInvariants() + // Free all the mapped space for the summary levels. + if pageAlloc64Bit != 0 { + for l := 0; l < summaryLevels; l++ { + sysFree(unsafe.Pointer(&p.summary[l][0]), uintptr(cap(p.summary[l]))*pallocSumBytes, nil) + } + } else { + resSize := uintptr(0) + for _, s := range p.summary { + resSize += uintptr(cap(s)) * pallocSumBytes + } + sysFree(unsafe.Pointer(&p.summary[0][0]), alignUp(resSize, physPageSize), nil) + } + + // Free the mapped space for chunks. + for i := range p.chunks { + if x := p.chunks[i]; x != nil { + p.chunks[i] = nil + // This memory comes from sysAlloc and will always be page-aligned. + sysFree(unsafe.Pointer(x), unsafe.Sizeof(*p.chunks[0]), nil) + } + } } -func (t *Treap) Find(npages uintptr) TreapIter { - return TreapIter{t.find(npages)} +// BaseChunkIdx is a convenient chunkIdx value which works on both +// 64 bit and 32 bit platforms, allowing the tests to share code +// between the two. +// +// On AIX, the arenaBaseOffset is 0x0a00000000000000. However, this +// constant can't be used here because it is negative and will cause +// a constant overflow. +// +// This should not be higher than 0x100*pallocChunkBytes to support +// mips and mipsle, which only have 31-bit address spaces. +var BaseChunkIdx = ChunkIdx(chunkIndex(((0xc000*pageAlloc64Bit + 0x100*pageAlloc32Bit) * pallocChunkBytes) + 0x0a00000000000000*sys.GoosAix)) + +// PageBase returns an address given a chunk index and a page index +// relative to that chunk. +func PageBase(c ChunkIdx, pageIdx uint) uintptr { + return chunkBase(chunkIdx(c)) + uintptr(pageIdx)*pageSize } -func (t *Treap) Erase(i TreapIter) { - // mTreap uses a fixalloc in mheap_ for treapNode - // freeing which requires the mheap_ lock to manipulate. - // Locking here is safe because the treap itself never allocs - // or otherwise ends up grabbing this lock. - systemstack(func() { - lock(&mheap_.lock) - t.erase(i.treapIter) - unlock(&mheap_.lock) - }) - t.CheckInvariants() +type BitsMismatch struct { + Base uintptr + Got, Want uint64 } -func (t *Treap) RemoveSpan(s Span) { - // See Erase about locking. +func CheckScavengedBitsCleared(mismatches []BitsMismatch) (n int, ok bool) { + ok = true + + // Run on the system stack to avoid stack growth allocation. systemstack(func() { + getg().m.mallocing++ + + // Lock so that we can safely access the bitmap. lock(&mheap_.lock) - t.removeSpan(s.mspan) + chunkLoop: + for i := mheap_.pages.start; i < mheap_.pages.end; i++ { + chunk := mheap_.pages.chunkOf(i) + for j := 0; j < pallocChunkPages/64; j++ { + // Run over each 64-bit bitmap section and ensure + // scavenged is being cleared properly on allocation. + // If a used bit and scavenged bit are both set, that's + // an error, and could indicate a larger problem, or + // an accounting problem. + want := chunk.scavenged[j] &^ chunk.pallocBits[j] + got := chunk.scavenged[j] + if want != got { + ok = false + if n >= len(mismatches) { + break chunkLoop + } + mismatches[n] = BitsMismatch{ + Base: chunkBase(i) + uintptr(j)*64*pageSize, + Got: got, + Want: want, + } + n++ + } + } + } unlock(&mheap_.lock) - }) - t.CheckInvariants() -} -func (t *Treap) Size() int { - i := 0 - t.mTreap.treap.walkTreap(func(t *treapNode) { - i++ + getg().m.mallocing-- }) - return i + return } -func (t *Treap) CheckInvariants() { - t.mTreap.treap.walkTreap(checkTreapNode) - t.mTreap.treap.validateInvariants() -} +func PageCachePagesLeaked() (leaked uintptr) { + stopTheWorld("PageCachePagesLeaked") -func RunGetgThreadSwitchTest() { - // Test that getg works correctly with thread switch. - // With gccgo, if we generate getg inlined, the backend - // may cache the address of the TLS variable, which - // will become invalid after a thread switch. This test - // checks that the bad caching doesn't happen. - - ch := make(chan int) - go func(ch chan int) { - ch <- 5 - LockOSThread() - }(ch) - - g1 := getg() + // Walk over destroyed Ps and look for unflushed caches. + deadp := allp[len(allp):cap(allp)] + for _, p := range deadp { + // Since we're going past len(allp) we may see nil Ps. + // Just ignore them. + if p != nil { + leaked += uintptr(sys.OnesCount64(p.pcache.cache)) + } + } - // Block on a receive. This is likely to get us a thread - // switch. If we yield to the sender goroutine, it will - // lock the thread, forcing us to resume on a different - // thread. - <-ch + startTheWorld() + return +} - g2 := getg() - if g1 != g2 { - panic("g1 != g2") - } +var Semacquire = semacquire +var Semrelease1 = semrelease1 - // Also test getg after some control flow, as the - // backend is sensitive to control flow. - g3 := getg() - if g1 != g3 { - panic("g1 != g3") - } +func SemNwait(addr *uint32) uint32 { + root := semroot(addr) + return atomic.Load(&root.nwait) } + +var Pusestackmaps = &usestackmaps diff --git a/libgo/go/runtime/export_unix_test.go b/libgo/go/runtime/export_unix_test.go index 064d2b22124..9d0f0d8edc7 100644 --- a/libgo/go/runtime/export_unix_test.go +++ b/libgo/go/runtime/export_unix_test.go @@ -6,6 +6,13 @@ package runtime +import "unsafe" + +var NonblockingPipe = nonblockingPipe +var Pipe = pipe +var SetNonblock = setNonblock +var Closeonexec = closeonexec + func sigismember(mask *sigset, i int) bool { clear := *mask sigdelset(&clear, i) @@ -17,3 +24,71 @@ func Sigisblocked(i int) bool { sigprocmask(_SIG_SETMASK, nil, &sigmask) return sigismember(&sigmask, i) } + +type M = m + +var waitForSigusr1 struct { + rdpipe int32 + wrpipe int32 + mID int64 +} + +// WaitForSigusr1 blocks until a SIGUSR1 is received. It calls ready +// when it is set up to receive SIGUSR1. The ready function should +// cause a SIGUSR1 to be sent. The r and w arguments are a pipe that +// the signal handler can use to report when the signal is received. +// +// Once SIGUSR1 is received, it returns the ID of the current M and +// the ID of the M the SIGUSR1 was received on. If the caller writes +// a non-zero byte to w, WaitForSigusr1 returns immediately with -1, -1. +func WaitForSigusr1(r, w int32, ready func(mp *M)) (int64, int64) { + lockOSThread() + // Make sure we can receive SIGUSR1. + unblocksig(_SIGUSR1) + + waitForSigusr1.rdpipe = r + waitForSigusr1.wrpipe = w + + mp := getg().m + testSigusr1 = waitForSigusr1Callback + ready(mp) + + // Wait for the signal. We use a pipe rather than a note + // because write is always async-signal-safe. + entersyscallblock() + var b byte + read(waitForSigusr1.rdpipe, noescape(unsafe.Pointer(&b)), 1) + exitsyscall() + + gotM := waitForSigusr1.mID + testSigusr1 = nil + + unlockOSThread() + + if b != 0 { + // timeout signal from caller + return -1, -1 + } + return mp.id, gotM +} + +// waitForSigusr1Callback is called from the signal handler during +// WaitForSigusr1. It must not have write barriers because there may +// not be a P. +// +//go:nowritebarrierrec +func waitForSigusr1Callback(gp *g) bool { + if gp == nil || gp.m == nil { + waitForSigusr1.mID = -1 + } else { + waitForSigusr1.mID = gp.m.id + } + b := byte(0) + write(uintptr(waitForSigusr1.wrpipe), noescape(unsafe.Pointer(&b)), 1) + return true +} + +// SendSigusr1 sends SIGUSR1 to mp. +func SendSigusr1(mp *M) { + panic("SendSigusr1") +} diff --git a/libgo/go/runtime/extern.go b/libgo/go/runtime/extern.go index 9dbf057b17d..e2e601f9b40 100644 --- a/libgo/go/runtime/extern.go +++ b/libgo/go/runtime/extern.go @@ -125,6 +125,13 @@ It is a comma-separated list of name=val pairs setting these named variables: IDs will refer to the ID of the goroutine at the time of creation; it's possible for this ID to be reused for another goroutine. Setting N to 0 will report no ancestry information. + asyncpreemptoff: asyncpreemptoff=1 disables signal-based + asynchronous goroutine preemption. This makes some loops + non-preemptible for long periods, which may delay GC and + goroutine scheduling. This is useful for debugging GC issues + because it also disables the conservative stack scanning used + for asynchronously preempted goroutines. + The net, net/http, and crypto/tls packages also refer to debugging variables in GODEBUG. See the documentation for those packages for details. diff --git a/libgo/go/runtime/gc_test.go b/libgo/go/runtime/gc_test.go index 3eb01bf4729..8f14bf9e51f 100644 --- a/libgo/go/runtime/gc_test.go +++ b/libgo/go/runtime/gc_test.go @@ -22,12 +22,6 @@ func TestGcSys(t *testing.T) { if os.Getenv("GOGC") == "off" { t.Skip("skipping test; GOGC=off in environment") } - if runtime.GOOS == "windows" { - t.Skip("skipping test; GOOS=windows http://golang.org/issue/27156") - } - if runtime.GOOS == "linux" && runtime.GOARCH == "arm64" { - t.Skip("skipping test; GOOS=linux GOARCH=arm64 https://github.com/golang/go/issues/27636") - } got := runTestProg(t, "testprog", "GCSys") want := "OK\n" if got != want { @@ -473,25 +467,6 @@ func TestReadMemStats(t *testing.T) { } } -func TestUnscavHugePages(t *testing.T) { - // Allocate 20 MiB and immediately free it a few times to increase - // the chance that unscavHugePages isn't zero and that some kind of - // accounting had to happen in the runtime. - for j := 0; j < 3; j++ { - var large [][]byte - for i := 0; i < 5; i++ { - large = append(large, make([]byte, runtime.PhysHugePageSize)) - } - runtime.KeepAlive(large) - runtime.GC() - } - base, slow := runtime.UnscavHugePagesSlow() - if base != slow { - logDiff(t, "unscavHugePages", reflect.ValueOf(base), reflect.ValueOf(slow)) - t.Fatal("unscavHugePages mismatch") - } -} - func logDiff(t *testing.T, prefix string, got, want reflect.Value) { typ := got.Type() switch typ.Kind() { diff --git a/libgo/go/runtime/gcinfo_test.go b/libgo/go/runtime/gcinfo_test.go index 89144d520e3..fc24f04bf84 100644 --- a/libgo/go/runtime/gcinfo_test.go +++ b/libgo/go/runtime/gcinfo_test.go @@ -173,14 +173,6 @@ func infoBigStruct() []byte { typeScalar, typeScalar, typeScalar, // t int; y uint16; u uint64 typePointer, typeScalar, // i string } - case "amd64p32": - return []byte{ - typePointer, // q *int - typeScalar, typeScalar, typeScalar, typeScalar, typeScalar, // w byte; e [17]byte - typePointer, typeScalar, typeScalar, // r []byte - typeScalar, typeScalar, typeScalar, typeScalar, typeScalar, // t int; y uint16; u uint64 - typePointer, typeScalar, // i string - } default: panic("unknown arch") } diff --git a/libgo/go/runtime/hash64.go b/libgo/go/runtime/hash64.go index 3f94256ad33..cff663a1ccb 100644 --- a/libgo/go/runtime/hash64.go +++ b/libgo/go/runtime/hash64.go @@ -25,8 +25,7 @@ const ( ) func memhash(p unsafe.Pointer, seed, s uintptr) uintptr { - if (GOARCH == "amd64" || GOARCH == "arm64") && - GOOS != "nacl" && useAeshash { + if (GOARCH == "amd64" || GOARCH == "arm64") && useAeshash { return aeshash(p, seed, s) } h := uint64(seed + s*hashkey[0]) diff --git a/libgo/go/runtime/heapdump.go b/libgo/go/runtime/heapdump.go index c968ab36d9e..e8f16e90fe6 100644 --- a/libgo/go/runtime/heapdump.go +++ b/libgo/go/runtime/heapdump.go @@ -313,7 +313,7 @@ func finq_callback(fn *funcval, obj unsafe.Pointer, ft *functype, ot *ptrtype) { func dumproots() { // MSpan.types for _, s := range mheap_.allspans { - if s.state == mSpanInUse { + if s.state.get() == mSpanInUse { // Finalizers for sp := s.specials; sp != nil; sp = sp.next { if sp.kind != _KindSpecialFinalizer { @@ -336,7 +336,7 @@ var freemark [_PageSize / 8]bool func dumpobjs() { for _, s := range mheap_.allspans { - if s.state != mSpanInUse { + if s.state.get() != mSpanInUse { continue } p := s.base() @@ -445,7 +445,7 @@ func dumpmemprof_callback(b *bucket, nstk uintptr, pstk *uintptr, size, allocs, dumpint(uint64(nstk)) for i := uintptr(0); i < nstk; i++ { pc := stk[i] - fn, file, line, _ := funcfileline(pc, -1) + fn, file, line, _ := funcfileline(pc, -1, false) if fn == "" { var buf [64]byte n := len(buf) @@ -483,7 +483,7 @@ func dumpmemprof_callback(b *bucket, nstk uintptr, pstk *uintptr, size, allocs, func dumpmemprof() { iterate_memprof(dumpmemprof_callback) for _, s := range mheap_.allspans { - if s.state != mSpanInUse { + if s.state.get() != mSpanInUse { continue } for sp := s.specials; sp != nil; sp = sp.next { @@ -504,7 +504,7 @@ var dumphdr = []byte("go1.7 heap dump\n") func mdump() { // make sure we're done sweeping for _, s := range mheap_.allspans { - if s.state == mSpanInUse { + if s.state.get() == mSpanInUse { s.ensureSwept() } } diff --git a/libgo/go/runtime/internal/atomic/atomic.c b/libgo/go/runtime/internal/atomic/atomic.c index 17c83a28c1c..8ae4d7b619d 100644 --- a/libgo/go/runtime/internal/atomic/atomic.c +++ b/libgo/go/runtime/internal/atomic/atomic.c @@ -26,6 +26,16 @@ Loadp (void *ptr) return __atomic_load_n ((void **) ptr, __ATOMIC_SEQ_CST); } +uint8_t Load8 (uint8_t *ptr) + __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load8") + __attribute__ ((no_split_stack)); + +uint8_t +Load8 (uint8_t *ptr) +{ + return __atomic_load_n (ptr, __ATOMIC_SEQ_CST); +} + uint64_t Load64 (uint64_t *ptr) __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Load64") __attribute__ ((no_split_stack)); @@ -238,6 +248,16 @@ Store (uint32_t *ptr, uint32_t val) __atomic_store_n (ptr, val, __ATOMIC_SEQ_CST); } +void Store8 (uint8_t *ptr, uint8_t val) + __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store8") + __attribute__ ((no_split_stack)); + +void +Store8 (uint8_t *ptr, uint8_t val) +{ + __atomic_store_n (ptr, val, __ATOMIC_SEQ_CST); +} + void Store64 (uint64_t *ptr, uint64_t val) __asm__ (GOSYM_PREFIX "runtime..z2finternal..z2fatomic.Store64") __attribute__ ((no_split_stack)); diff --git a/libgo/go/runtime/internal/atomic/atomic_test.go b/libgo/go/runtime/internal/atomic/atomic_test.go index 0ba75447e8c..0c1125c5583 100644 --- a/libgo/go/runtime/internal/atomic/atomic_test.go +++ b/libgo/go/runtime/internal/atomic/atomic_test.go @@ -86,14 +86,8 @@ func TestUnaligned64(t *testing.T) { // a continual source of pain. Test that on 32-bit systems they crash // instead of failing silently. - switch runtime.GOARCH { - default: - if unsafe.Sizeof(int(0)) != 4 { - t.Skip("test only runs on 32-bit systems") - } - case "amd64p32": - // amd64p32 can handle unaligned atomics. - t.Skipf("test not needed on %v", runtime.GOARCH) + if unsafe.Sizeof(int(0)) != 4 { + t.Skip("test only runs on 32-bit systems") } x := make([]uint32, 4) @@ -109,3 +103,120 @@ func TestUnaligned64(t *testing.T) { shouldPanic(t, "Xchg64", func() { atomic.Xchg64(up64, 1) }) shouldPanic(t, "Cas64", func() { atomic.Cas64(up64, 1, 2) }) } + +func TestAnd8(t *testing.T) { + // Basic sanity check. + x := uint8(0xff) + for i := uint8(0); i < 8; i++ { + atomic.And8(&x, ^(1 << i)) + if r := uint8(0xff) << (i + 1); x != r { + t.Fatalf("clearing bit %#x: want %#x, got %#x", uint8(1<= 1<<32 { + x >>= 32 + n = 32 + } + if x >= 1<<16 { + x >>= 16 + n += 16 + } + if x >= 1<<8 { + x >>= 8 + n += 8 + } + return n + int(len8tab[x]) +} + +// --- OnesCount --- + +const m0 = 0x5555555555555555 // 01010101 ... +const m1 = 0x3333333333333333 // 00110011 ... +const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ... + +// OnesCount64 returns the number of one bits ("population count") in x. +func OnesCount64(x uint64) int { + // Implementation: Parallel summing of adjacent bits. + // See "Hacker's Delight", Chap. 5: Counting Bits. + // The following pattern shows the general approach: + // + // x = x>>1&(m0&m) + x&(m0&m) + // x = x>>2&(m1&m) + x&(m1&m) + // x = x>>4&(m2&m) + x&(m2&m) + // x = x>>8&(m3&m) + x&(m3&m) + // x = x>>16&(m4&m) + x&(m4&m) + // x = x>>32&(m5&m) + x&(m5&m) + // return int(x) + // + // Masking (& operations) can be left away when there's no + // danger that a field's sum will carry over into the next + // field: Since the result cannot be > 64, 8 bits is enough + // and we can ignore the masks for the shifts by 8 and up. + // Per "Hacker's Delight", the first line can be simplified + // more, but it saves at best one instruction, so we leave + // it alone for clarity. + const m = 1<<64 - 1 + x = x>>1&(m0&m) + x&(m0&m) + x = x>>2&(m1&m) + x&(m1&m) + x = (x>>4 + x) & (m2 & m) + x += x >> 8 + x += x >> 16 + x += x >> 32 + return int(x) & (1<<7 - 1) +} + +var deBruijn64tab = [64]byte{ + 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, + 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, + 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11, + 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6, +} + +const deBruijn64 = 0x03f79d71b4ca8b09 + +// TrailingZeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0. +func TrailingZeros64(x uint64) int { + if x == 0 { + return 64 + } + // If popcount is fast, replace code below with return popcount(^x & (x - 1)). + // + // x & -x leaves only the right-most bit set in the word. Let k be the + // index of that bit. Since only a single bit is set, the value is two + // to the power of k. Multiplying by a power of two is equivalent to + // left shifting, in this case by k bits. The de Bruijn (64 bit) constant + // is such that all six bit, consecutive substrings are distinct. + // Therefore, if we have a left shifted version of this constant we can + // find by how many bits it was shifted by looking at which six bit + // substring ended up at the top of the word. + // (Knuth, volume 4, section 7.3.1) + return int(deBruijn64tab[(x&-x)*deBruijn64>>(64-6)]) +} + +// LeadingZeros64 returns the number of leading zero bits in x; the result is 64 for x == 0. +func LeadingZeros64(x uint64) int { return 64 - Len64(x) } + +// LeadingZeros8 returns the number of leading zero bits in x; the result is 8 for x == 0. +func LeadingZeros8(x uint8) int { return 8 - Len8(x) } + +// TrailingZeros8 returns the number of trailing zero bits in x; the result is 8 for x == 0. +func TrailingZeros8(x uint8) int { + return int(ntz8tab[x]) +} + +// Len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0. +func Len8(x uint8) int { + return int(len8tab[x]) +} diff --git a/libgo/go/runtime/lfstack_32bit.go b/libgo/go/runtime/lfstack_32bit.go index f50c50895b4..6da037e3f36 100644 --- a/libgo/go/runtime/lfstack_32bit.go +++ b/libgo/go/runtime/lfstack_32bit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build 386 amd64p32 arm nacl armbe m68k mips mipsle mips64p32 mips64p32le nios2 ppc s390 sh shbe sparc +// +build 386 amd64p32 arm armbe m68k mips mipsle mips64p32 mips64p32le nios2 ppc s390 sh shbe sparc package runtime diff --git a/libgo/go/runtime/libfuzzer.go b/libgo/go/runtime/libfuzzer.go new file mode 100644 index 00000000000..0161955f09f --- /dev/null +++ b/libgo/go/runtime/libfuzzer.go @@ -0,0 +1,75 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build libfuzzer + +package runtime + +import _ "unsafe" // for go:linkname + +func libfuzzerCall(fn *byte, arg0, arg1 uintptr) + +func libfuzzerTraceCmp1(arg0, arg1 uint8) { + libfuzzerCall(&__sanitizer_cov_trace_cmp1, uintptr(arg0), uintptr(arg1)) +} + +func libfuzzerTraceCmp2(arg0, arg1 uint16) { + libfuzzerCall(&__sanitizer_cov_trace_cmp2, uintptr(arg0), uintptr(arg1)) +} + +func libfuzzerTraceCmp4(arg0, arg1 uint32) { + libfuzzerCall(&__sanitizer_cov_trace_cmp4, uintptr(arg0), uintptr(arg1)) +} + +func libfuzzerTraceCmp8(arg0, arg1 uint64) { + libfuzzerCall(&__sanitizer_cov_trace_cmp8, uintptr(arg0), uintptr(arg1)) +} + +func libfuzzerTraceConstCmp1(arg0, arg1 uint8) { + libfuzzerCall(&__sanitizer_cov_trace_const_cmp1, uintptr(arg0), uintptr(arg1)) +} + +func libfuzzerTraceConstCmp2(arg0, arg1 uint16) { + libfuzzerCall(&__sanitizer_cov_trace_const_cmp2, uintptr(arg0), uintptr(arg1)) +} + +func libfuzzerTraceConstCmp4(arg0, arg1 uint32) { + libfuzzerCall(&__sanitizer_cov_trace_const_cmp4, uintptr(arg0), uintptr(arg1)) +} + +func libfuzzerTraceConstCmp8(arg0, arg1 uint64) { + libfuzzerCall(&__sanitizer_cov_trace_const_cmp8, uintptr(arg0), uintptr(arg1)) +} + +//go:linkname __sanitizer_cov_trace_cmp1 __sanitizer_cov_trace_cmp1 +//go:cgo_import_static __sanitizer_cov_trace_cmp1 +var __sanitizer_cov_trace_cmp1 byte + +//go:linkname __sanitizer_cov_trace_cmp2 __sanitizer_cov_trace_cmp2 +//go:cgo_import_static __sanitizer_cov_trace_cmp2 +var __sanitizer_cov_trace_cmp2 byte + +//go:linkname __sanitizer_cov_trace_cmp4 __sanitizer_cov_trace_cmp4 +//go:cgo_import_static __sanitizer_cov_trace_cmp4 +var __sanitizer_cov_trace_cmp4 byte + +//go:linkname __sanitizer_cov_trace_cmp8 __sanitizer_cov_trace_cmp8 +//go:cgo_import_static __sanitizer_cov_trace_cmp8 +var __sanitizer_cov_trace_cmp8 byte + +//go:linkname __sanitizer_cov_trace_const_cmp1 __sanitizer_cov_trace_const_cmp1 +//go:cgo_import_static __sanitizer_cov_trace_const_cmp1 +var __sanitizer_cov_trace_const_cmp1 byte + +//go:linkname __sanitizer_cov_trace_const_cmp2 __sanitizer_cov_trace_const_cmp2 +//go:cgo_import_static __sanitizer_cov_trace_const_cmp2 +var __sanitizer_cov_trace_const_cmp2 byte + +//go:linkname __sanitizer_cov_trace_const_cmp4 __sanitizer_cov_trace_const_cmp4 +//go:cgo_import_static __sanitizer_cov_trace_const_cmp4 +var __sanitizer_cov_trace_const_cmp4 byte + +//go:linkname __sanitizer_cov_trace_const_cmp8 __sanitizer_cov_trace_const_cmp8 +//go:cgo_import_static __sanitizer_cov_trace_const_cmp8 +var __sanitizer_cov_trace_const_cmp8 byte diff --git a/libgo/go/runtime/lock_futex.go b/libgo/go/runtime/lock_futex.go index 6f86e91264b..f672efdc74c 100644 --- a/libgo/go/runtime/lock_futex.go +++ b/libgo/go/runtime/lock_futex.go @@ -241,7 +241,7 @@ func notetsleepg(n *note, ns int64) bool { return ok } -func beforeIdle() bool { +func beforeIdle(int64) bool { return false } diff --git a/libgo/go/runtime/lock_js.go b/libgo/go/runtime/lock_js.go index c038499f2a9..3168c86d8a0 100644 --- a/libgo/go/runtime/lock_js.go +++ b/libgo/go/runtime/lock_js.go @@ -111,6 +111,8 @@ func notetsleepg(n *note, ns int64) bool { gopark(nil, nil, waitReasonSleep, traceEvNone, 1) clearTimeoutEvent(id) // note might have woken early, clear timeout + clearIdleID() + mp = acquirem() delete(notes, n) delete(notesWithTimeout, n) @@ -144,33 +146,65 @@ func checkTimeouts() { } } -var returnedEventHandler *g +// events is a stack of calls from JavaScript into Go. +var events []*event + +type event struct { + // g was the active goroutine when the call from JavaScript occurred. + // It needs to be active when returning to JavaScript. + gp *g + // returned reports whether the event handler has returned. + // When all goroutines are idle and the event handler has returned, + // then g gets resumed and returns the execution to JavaScript. + returned bool +} -func init() { - // At the toplevel we need an extra goroutine that handles asynchronous events. - initg := getg() - go func() { - returnedEventHandler = getg() - goready(initg, 1) +// The timeout event started by beforeIdle. +var idleID int32 - gopark(nil, nil, waitReasonZero, traceEvNone, 1) - returnedEventHandler = nil +// beforeIdle gets called by the scheduler if no goroutine is awake. +// If we are not already handling an event, then we pause for an async event. +// If an event handler returned, we resume it and it will pause the execution. +func beforeIdle(delay int64) bool { + if delay > 0 { + clearIdleID() + if delay < 1e6 { + delay = 1 + } else if delay < 1e15 { + delay = delay / 1e6 + } else { + // An arbitrary cap on how long to wait for a timer. + // 1e9 ms == ~11.5 days. + delay = 1e9 + } + idleID = scheduleTimeoutEvent(delay) + } - pause(getcallersp() - 16) - }() - gopark(nil, nil, waitReasonZero, traceEvNone, 1) -} + if len(events) == 0 { + go handleAsyncEvent() + return true + } -// beforeIdle gets called by the scheduler if no goroutine is awake. -// We resume the event handler (if available) which will pause the execution. -func beforeIdle() bool { - if returnedEventHandler != nil { - goready(returnedEventHandler, 1) + e := events[len(events)-1] + if e.returned { + goready(e.gp, 1) return true } return false } +func handleAsyncEvent() { + pause(getcallersp() - 16) +} + +// clearIdleID clears our record of the timeout started by beforeIdle. +func clearIdleID() { + if idleID != 0 { + clearTimeoutEvent(idleID) + idleID = 0 + } +} + // pause sets SP to newsp and pauses the execution of Go's WebAssembly code until an event is triggered. func pause(newsp uintptr) @@ -181,18 +215,29 @@ func scheduleTimeoutEvent(ms int64) int32 // clearTimeoutEvent clears a timeout event scheduled by scheduleTimeoutEvent. func clearTimeoutEvent(id int32) +// handleEvent gets invoked on a call from JavaScript into Go. It calls the event handler of the syscall/js package +// and then parks the handler goroutine to allow other goroutines to run before giving execution back to JavaScript. +// When no other goroutine is awake any more, beforeIdle resumes the handler goroutine. Now that the same goroutine +// is running as was running when the call came in from JavaScript, execution can be safely passed back to JavaScript. func handleEvent() { - prevReturnedEventHandler := returnedEventHandler - returnedEventHandler = nil + e := &event{ + gp: getg(), + returned: false, + } + events = append(events, e) - checkTimeouts() eventHandler() - returnedEventHandler = getg() + clearIdleID() + + // wait until all goroutines are idle + e.returned = true gopark(nil, nil, waitReasonZero, traceEvNone, 1) - returnedEventHandler = prevReturnedEventHandler + events[len(events)-1] = nil + events = events[:len(events)-1] + // return execution to JavaScript pause(getcallersp() - 16) } diff --git a/libgo/go/runtime/lock_sema.go b/libgo/go/runtime/lock_sema.go index 5cf24061795..63a60149db3 100644 --- a/libgo/go/runtime/lock_sema.go +++ b/libgo/go/runtime/lock_sema.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin hurd nacl netbsd openbsd plan9 solaris windows +// +build aix darwin hurd netbsd openbsd plan9 solaris windows package runtime @@ -300,7 +300,7 @@ func notetsleepg(n *note, ns int64) bool { return ok } -func beforeIdle() bool { +func beforeIdle(int64) bool { return false } diff --git a/libgo/go/runtime/malloc.go b/libgo/go/runtime/malloc.go index 0eee55ef97e..fda22735818 100644 --- a/libgo/go/runtime/malloc.go +++ b/libgo/go/runtime/malloc.go @@ -19,7 +19,7 @@ // fixalloc: a free-list allocator for fixed-size off-heap objects, // used to manage storage used by the allocator. // mheap: the malloc heap, managed at page (8192-byte) granularity. -// mspan: a run of pages managed by the mheap. +// mspan: a run of in-use pages managed by the mheap. // mcentral: collects all spans of a given size class. // mcache: a per-P cache of mspans with free space. // mstats: allocation statistics. @@ -56,13 +56,8 @@ // it is placed on the mcentral free list for the mspan's size // class. // -// 3. Otherwise, if all objects in the mspan are free, the mspan -// is now "idle", so it is returned to the mheap and no longer -// has a size class. -// This may coalesce it with adjacent idle mspans. -// -// 4. If an mspan remains idle for long enough, return its pages -// to the operating system. +// 3. Otherwise, if all objects in the mspan are free, the mspan's +// pages are returned to the mheap and the mspan is now dead. // // Allocating and freeing a large object uses the mheap // directly, bypassing the mcache and mcentral. @@ -207,17 +202,21 @@ const ( // exceed Go's 48 bit limit, it's extremely unlikely in // practice. // - // On aix/ppc64, the limits is increased to 1<<60 to accept addresses - // returned by mmap syscall. These are in range: - // 0x0a00000000000000 - 0x0afffffffffffff - // // On 32-bit platforms, we accept the full 32-bit address // space because doing so is cheap. // mips32 only has access to the low 2GB of virtual memory, so // we further limit it to 31 bits. // + // On darwin/arm64, although 64-bit pointers are presumably + // available, pointers are truncated to 33 bits. Furthermore, + // only the top 4 GiB of the address space are actually available + // to the application, but we allow the whole 33 bits anyway for + // simplicity. + // TODO(mknyszek): Consider limiting it to 32 bits and using + // arenaBaseOffset to offset into the top 4 GiB. + // // WebAssembly currently has a limit of 4GB linear memory. - heapAddrBits = (_64bit*(1-sys.GoarchWasm)*(1-sys.GoosAix))*48 + (1-_64bit+sys.GoarchWasm)*(32-(sys.GoarchMips+sys.GoarchMipsle)) + 60*(sys.GoosAix*_64bit) + heapAddrBits = (_64bit*(1-sys.GoarchWasm)*(1-sys.GoosDarwin*sys.GoarchArm64))*48 + (1-_64bit+sys.GoarchWasm)*(32-(sys.GoarchMips+sys.GoarchMipsle)) + 33*sys.GoosDarwin*sys.GoarchArm64 // maxAlloc is the maximum size of an allocation. On 64-bit, // it's theoretically possible to allocate 1< maxPhysPageSize { + print("system page size (", physPageSize, ") is larger than maximum page size (", maxPhysPageSize, ")\n") + throw("bad system page size") + } if physPageSize < minPhysPageSize { print("system page size (", physPageSize, ") is smaller than minimum page size (", minPhysPageSize, ")\n") throw("bad system page size") @@ -456,6 +461,13 @@ func mallocinit() { print("system huge page size (", physHugePageSize, ") must be a power of 2\n") throw("bad system huge page size") } + if physHugePageSize > maxPhysHugePageSize { + // physHugePageSize is greater than the maximum supported huge page size. + // Don't throw here, like in the other cases, since a system configured + // in this way isn't wrong, we just don't have the code to support them. + // Instead, silently set the huge page size to zero. + physHugePageSize = 0 + } if physHugePageSize != 0 { // Since physHugePageSize is a power of 2, it suffices to increase // physHugePageShift until 1< persistentChunkSize || persistent.base == nil { persistent.base = (*notInHeap)(sysAlloc(persistentChunkSize, &memstats.other_sys)) if persistent.base == nil { @@ -1356,7 +1368,7 @@ func persistentalloc1(size, align uintptr, sysStat *uint64) *notInHeap { break } } - persistent.off = round(sys.PtrSize, align) + persistent.off = alignUp(sys.PtrSize, align) } p := persistent.base.add(persistent.off) persistent.off += size @@ -1402,12 +1414,12 @@ func (l *linearAlloc) init(base, size uintptr) { } func (l *linearAlloc) alloc(size, align uintptr, sysStat *uint64) unsafe.Pointer { - p := round(l.next, align) + p := alignUp(l.next, align) if p+size > l.end { return nil } l.next = p + size - if pEnd := round(l.next-1, physPageSize); pEnd > l.mapped { + if pEnd := alignUp(l.next-1, physPageSize); pEnd > l.mapped { // Transition from Reserved to Prepared to Ready. sysMap(unsafe.Pointer(l.mapped), pEnd-l.mapped, sysStat) sysUsed(unsafe.Pointer(l.mapped), pEnd-l.mapped) diff --git a/libgo/go/runtime/malloc_test.go b/libgo/go/runtime/malloc_test.go index c9282bae55e..bd30bc18d28 100644 --- a/libgo/go/runtime/malloc_test.go +++ b/libgo/go/runtime/malloc_test.go @@ -170,6 +170,14 @@ func TestTinyAlloc(t *testing.T) { } } +func TestPageCacheLeak(t *testing.T) { + defer GOMAXPROCS(GOMAXPROCS(1)) + leaked := PageCachePagesLeaked() + if leaked != 0 { + t.Fatalf("found %d leaked pages in page caches", leaked) + } +} + func TestPhysicalMemoryUtilization(t *testing.T) { got := runTestProg(t, "testprog", "GCPhys") want := "OK\n" @@ -178,6 +186,19 @@ func TestPhysicalMemoryUtilization(t *testing.T) { } } +func TestScavengedBitsCleared(t *testing.T) { + var mismatches [128]BitsMismatch + if n, ok := CheckScavengedBitsCleared(mismatches[:]); !ok { + t.Errorf("uncleared scavenged bits") + for _, m := range mismatches[:n] { + t.Logf("\t@ address 0x%x", m.Base) + t.Logf("\t| got: %064b", m.Got) + t.Logf("\t| want: %064b", m.Want) + } + t.FailNow() + } +} + type acLink struct { x [1 << 20]byte } diff --git a/libgo/go/runtime/map.go b/libgo/go/runtime/map.go index 36729087ce6..6667fe7cfe5 100644 --- a/libgo/go/runtime/map.go +++ b/libgo/go/runtime/map.go @@ -1429,5 +1429,5 @@ func reflectlite_maplen(h *hmap) int { return h.count } -const maxZero = 1024 // must match value in cmd/compile/internal/gc/walk.go +const maxZero = 1024 // must match value in cmd/compile/internal/gc/walk.go:zeroValSize var zeroVal [maxZero]byte diff --git a/libgo/go/runtime/map_benchmark_test.go b/libgo/go/runtime/map_benchmark_test.go index cf04ead1156..bae1aa0dbd6 100644 --- a/libgo/go/runtime/map_benchmark_test.go +++ b/libgo/go/runtime/map_benchmark_test.go @@ -251,7 +251,7 @@ func BenchmarkMapLast(b *testing.B) { } func BenchmarkMapCycle(b *testing.B) { - // Arrange map entries to be a permuation, so that + // Arrange map entries to be a permutation, so that // we hit all entries, and one lookup is data dependent // on the previous lookup. const N = 3127 diff --git a/libgo/go/runtime/mbitmap.go b/libgo/go/runtime/mbitmap.go index b84fe0fc6c4..457da13687a 100644 --- a/libgo/go/runtime/mbitmap.go +++ b/libgo/go/runtime/mbitmap.go @@ -243,6 +243,10 @@ func (s *mspan) nextFreeIndex() uintptr { } // isFree reports whether the index'th object in s is unallocated. +// +// The caller must ensure s.state is mSpanInUse, and there must have +// been no preemption points since ensuring this (which could allow a +// GC transition, which would allow the state to change). func (s *mspan) isFree(index uintptr) bool { if index < s.freeindex { return false @@ -349,6 +353,33 @@ func heapBitsForAddr(addr uintptr) (h heapBits) { return } +// badPointer throws bad pointer in heap panic. +func badPointer(s *mspan, p, refBase, refOff uintptr) { + // Typically this indicates an incorrect use + // of unsafe or cgo to store a bad pointer in + // the Go heap. It may also indicate a runtime + // bug. + // + // TODO(austin): We could be more aggressive + // and detect pointers to unallocated objects + // in allocated spans. + printlock() + print("runtime: pointer ", hex(p)) + state := s.state.get() + if state != mSpanInUse { + print(" to unallocated span") + } else { + print(" to unused region of span") + } + print(" span.base()=", hex(s.base()), " span.limit=", hex(s.limit), " span.state=", state, "\n") + if refBase != 0 { + print("runtime: found in object at *(", hex(refBase), "+", hex(refOff), ")\n") + gcDumpObject("object", refBase, refOff) + } + getg().m.traceback = 2 + throw("found bad pointer in Go heap (incorrect use of unsafe or cgo?)") +} + // findObject returns the base address for the heap object containing // the address p, the object's span, and the index of the object in s. // If p does not point into a heap object, it returns base == 0. @@ -362,42 +393,30 @@ func heapBitsForAddr(addr uintptr) (h heapBits) { // refBase and refOff optionally give the base address of the object // in which the pointer p was found and the byte offset at which it // was found. These are used for error reporting. +// +// It is nosplit so it is safe for p to be a pointer to the current goroutine's stack. +// Since p is a uintptr, it would not be adjusted if the stack were to move. +//go:nosplit func findObject(p, refBase, refOff uintptr, forStack bool) (base uintptr, s *mspan, objIndex uintptr) { s = spanOf(p) + // If s is nil, the virtual address has never been part of the heap. + // This pointer may be to some mmap'd region, so we allow it. + if s == nil { + return + } // If p is a bad pointer, it may not be in s's bounds. - if s == nil || p < s.base() || p >= s.limit || s.state != mSpanInUse { - if s == nil || s.state == mSpanManual || forStack { - // If s is nil, the virtual address has never been part of the heap. - // This pointer may be to some mmap'd region, so we allow it. - // Pointers into stacks are also ok, the runtime manages these explicitly. + // + // Check s.state to synchronize with span initialization + // before checking other fields. See also spanOfHeap. + if state := s.state.get(); state != mSpanInUse || p < s.base() || p >= s.limit { + // Pointers into stacks are also ok, the runtime manages these explicitly. + if state == mSpanManual || forStack { return } - // The following ensures that we are rigorous about what data // structures hold valid pointers. if debug.invalidptr != 0 { - // Typically this indicates an incorrect use - // of unsafe or cgo to store a bad pointer in - // the Go heap. It may also indicate a runtime - // bug. - // - // TODO(austin): We could be more aggressive - // and detect pointers to unallocated objects - // in allocated spans. - printlock() - print("runtime: pointer ", hex(p)) - if s.state != mSpanInUse { - print(" to unallocated span") - } else { - print(" to unused region of span") - } - print(" span.base()=", hex(s.base()), " span.limit=", hex(s.limit), " span.state=", s.state, "\n") - if refBase != 0 { - print("runtime: found in object at *(", hex(refBase), "+", hex(refOff), ")\n") - gcDumpObject("object", refBase, refOff) - } - getg().m.traceback = 2 - throw("found bad pointer in Go heap (incorrect use of unsafe or cgo?)") + badPointer(s, p, refBase, refOff) } return } @@ -629,7 +648,7 @@ func bulkBarrierPreWrite(dst, src, size uintptr) { } } return - } else if s.state != mSpanInUse || dst < s.base() || s.limit <= dst { + } else if s.state.get() != mSpanInUse || dst < s.base() || s.limit <= dst { // dst was heap memory at some point, but isn't now. // It can't be a global. It must be either our stack, // or in the case of direct channel sends, it could be @@ -801,29 +820,19 @@ func typeBitsBulkBarrier(typ *_type, dst, src, size uintptr) { // words to pointer/scan. // Otherwise, it initializes all words to scalar/dead. func (h heapBits) initSpan(s *mspan) { - size, n, total := s.layout() - - // Init the markbit structures - s.freeindex = 0 - s.allocCache = ^uint64(0) // all 1s indicating all free. - s.nelems = n - s.allocBits = nil - s.gcmarkBits = nil - s.gcmarkBits = newMarkBits(s.nelems) - s.allocBits = newAllocBits(s.nelems) - // Clear bits corresponding to objects. - nw := total / sys.PtrSize + nw := (s.npages << _PageShift) / sys.PtrSize if nw%wordsPerBitmapByte != 0 { throw("initSpan: unaligned length") } if h.shift != 0 { throw("initSpan: unaligned base") } + isPtrs := sys.PtrSize == 8 && s.elemsize == sys.PtrSize for nw > 0 { hNext, anw := h.forwardOrBoundary(nw) nbyte := anw / wordsPerBitmapByte - if sys.PtrSize == 8 && size == sys.PtrSize { + if isPtrs { bitp := h.bitp for i := uintptr(0); i < nbyte; i++ { *bitp = bitPointerAll | bitScanAll diff --git a/libgo/go/runtime/mcentral.go b/libgo/go/runtime/mcentral.go index cd5901054ae..78a3ae6ac19 100644 --- a/libgo/go/runtime/mcentral.go +++ b/libgo/go/runtime/mcentral.go @@ -243,7 +243,7 @@ func (c *mcentral) freeSpan(s *mspan, preserve bool, wasempty bool) bool { c.nonempty.remove(s) unlock(&c.lock) - mheap_.freeSpan(s, false) + mheap_.freeSpan(s) return true } @@ -252,7 +252,7 @@ func (c *mcentral) grow() *mspan { npages := uintptr(class_to_allocnpages[c.spanclass.sizeclass()]) size := uintptr(class_to_size[c.spanclass.sizeclass()]) - s := mheap_.alloc(npages, c.spanclass, false, true) + s := mheap_.alloc(npages, c.spanclass, true) if s == nil { return nil } diff --git a/libgo/go/runtime/mgc.go b/libgo/go/runtime/mgc.go index 46b7334e910..b0040f96554 100644 --- a/libgo/go/runtime/mgc.go +++ b/libgo/go/runtime/mgc.go @@ -139,6 +139,10 @@ const ( _ConcurrentSweep = true _FinBlockSize = 4 * 1024 + // debugScanConservative enables debug logging for stack + // frames that are scanned conservatively. + debugScanConservative = false + // sweepMinHeapDistance is a lower bound on the heap distance // (in bytes) reserved for concurrent sweeping between GC // cycles. @@ -231,6 +235,8 @@ func setGCPercent(in int32) (out int32) { gcSetTriggerRatio(memstats.triggerRatio) unlock(&mheap_.lock) }) + // Pacing changed, so the scavenger should be awoken. + wakeScavenger() // If we just disabled GC, wait for any concurrent GC mark to // finish so we always return with no GC running. @@ -490,25 +496,25 @@ func (c *gcControllerState) revise() { } live := atomic.Load64(&memstats.heap_live) - var heapGoal, scanWorkExpected int64 - if live <= memstats.next_gc { - // We're under the soft goal. Pace GC to complete at - // next_gc assuming the heap is in steady-state. - heapGoal = int64(memstats.next_gc) + // Assume we're under the soft goal. Pace GC to complete at + // next_gc assuming the heap is in steady-state. + heapGoal := int64(memstats.next_gc) - // Compute the expected scan work remaining. - // - // This is estimated based on the expected - // steady-state scannable heap. For example, with - // GOGC=100, only half of the scannable heap is - // expected to be live, so that's what we target. - // - // (This is a float calculation to avoid overflowing on - // 100*heap_scan.) - scanWorkExpected = int64(float64(memstats.heap_scan) * 100 / float64(100+gcpercent)) - } else { - // We're past the soft goal. Pace GC so that in the - // worst case it will complete by the hard goal. + // Compute the expected scan work remaining. + // + // This is estimated based on the expected + // steady-state scannable heap. For example, with + // GOGC=100, only half of the scannable heap is + // expected to be live, so that's what we target. + // + // (This is a float calculation to avoid overflowing on + // 100*heap_scan.) + scanWorkExpected := int64(float64(memstats.heap_scan) * 100 / float64(100+gcpercent)) + + if live > memstats.next_gc || c.scanWork > scanWorkExpected { + // We're past the soft goal, or we've already done more scan + // work than we expected. Pace GC so that in the worst case it + // will complete by the hard goal. const maxOvershoot = 1.1 heapGoal = int64(float64(memstats.next_gc) * maxOvershoot) @@ -520,7 +526,7 @@ func (c *gcControllerState) revise() { // // Note that we currently count allocations during GC as both // scannable heap (heap_scan) and scan work completed - // (scanWork), so allocation will change this difference will + // (scanWork), so allocation will change this difference // slowly in the soft regime and not at all in the hard // regime. scanWorkRemaining := scanWorkExpected - c.scanWork @@ -765,11 +771,25 @@ func gcSetTriggerRatio(triggerRatio float64) { goal = memstats.heap_marked + memstats.heap_marked*uint64(gcpercent)/100 } + // If we let triggerRatio go too low, then if the application + // is allocating very rapidly we might end up in a situation + // where we're allocating black during a nearly always-on GC. + // The result of this is a growing heap and ultimately an + // increase in RSS. By capping us at a point >0, we're essentially + // saying that we're OK using more CPU during the GC to prevent + // this growth in RSS. + // + // The current constant was chosen empirically: given a sufficiently + // fast/scalable allocator with 48 Ps that could drive the trigger ratio + // to <0.05, this constant causes applications to retain the same peak + // RSS compared to not having this allocator. + const minTriggerRatio = 0.6 + // Set the trigger ratio, capped to reasonable bounds. - if triggerRatio < 0 { + if triggerRatio < minTriggerRatio { // This can happen if the mutator is allocating very // quickly or the GC is scanning very slowly. - triggerRatio = 0 + triggerRatio = minTriggerRatio } else if gcpercent >= 0 { // Ensure there's always a little margin so that the // mutator assist ratio isn't infinity. @@ -847,7 +867,8 @@ func gcSetTriggerRatio(triggerRatio float64) { heapDistance = _PageSize } pagesSwept := atomic.Load64(&mheap_.pagesSwept) - sweepDistancePages := int64(mheap_.pagesInUse) - int64(pagesSwept) + pagesInUse := atomic.Load64(&mheap_.pagesInUse) + sweepDistancePages := int64(pagesInUse) - int64(pagesSwept) if sweepDistancePages <= 0 { mheap_.sweepPagesPerByte = 0 } else { @@ -1250,6 +1271,7 @@ func gcStart(trigger gcTrigger) { } // Ok, we're doing it! Stop everybody else + semacquire(&gcsema) semacquire(&worldsema) if trace.enabled { @@ -1348,6 +1370,13 @@ func gcStart(trigger gcTrigger) { work.pauseNS += now - work.pauseStart work.tMark = now }) + + // Release the world sema before Gosched() in STW mode + // because we will need to reacquire it later but before + // this goroutine becomes runnable again, and we could + // self-deadlock otherwise. + semrelease(&worldsema) + // In STW mode, we could block the instant systemstack // returns, so don't do anything important here. Make sure we // block rather than returning to user code. @@ -1417,6 +1446,10 @@ top: return } + // forEachP needs worldsema to execute, and we'll need it to + // stop the world later, so acquire worldsema now. + semacquire(&worldsema) + // Flush all local buffers and collect flushedWork flags. gcMarkDoneFlushed = 0 systemstack(func() { @@ -1477,6 +1510,7 @@ top: // work to do. Keep going. It's possible the // transition condition became true again during the // ragged barrier, so re-check it. + semrelease(&worldsema) goto top } @@ -1553,6 +1587,7 @@ top: now := startTheWorldWithSema(true) work.pauseNS += now - work.pauseStart }) + semrelease(&worldsema) goto top } } @@ -1651,9 +1686,16 @@ func gcMarkTermination(nextTriggerRatio float64) { throw("gc done but gcphase != _GCoff") } + // Record next_gc and heap_inuse for scavenger. + memstats.last_next_gc = memstats.next_gc + memstats.last_heap_inuse = memstats.heap_inuse + // Update GC trigger and pacing for the next cycle. gcSetTriggerRatio(nextTriggerRatio) + // Pacing changed, so the scavenger should be awoken. + wakeScavenger() + // Update timing memstats now := nanotime() sec, nsec, _ := time_now() @@ -1760,6 +1802,7 @@ func gcMarkTermination(nextTriggerRatio float64) { } semrelease(&worldsema) + semrelease(&gcsema) // Careful: another GC cycle may start now. releasem(mp) @@ -2152,8 +2195,7 @@ func gcResetMarkState() { // allgs doesn't change. lock(&allglock) for _, gp := range allgs { - gp.gcscandone = false // set to true in gcphasework - gp.gcscanvalid = false // stack has not been scanned + gp.gcscandone = false // set to true in gcphasework gp.gcAssistBytes = 0 } unlock(&allglock) diff --git a/libgo/go/runtime/mgc_gccgo.go b/libgo/go/runtime/mgc_gccgo.go index d7ae26090f5..21539eb9e9c 100644 --- a/libgo/go/runtime/mgc_gccgo.go +++ b/libgo/go/runtime/mgc_gccgo.go @@ -145,40 +145,15 @@ func registerGCRoots(r *gcRootList) { // and carries on. func checkPreempt() { gp := getg() - if !gp.preempt || gp != gp.m.curg || gp.m.locks != 0 || gp.m.mallocing != 0 || gp.m.preemptoff != "" || gp.m.incgo { + if !gp.preempt || gp != gp.m.curg || !canPreemptM(gp.m) { return } - // Synchronize with scang. - gp.scanningself = true - casgstatus(gp, _Grunning, _Gwaiting) - if gp.preemptscan { - for !castogscanstatus(gp, _Gwaiting, _Gscanwaiting) { - // Likely to be racing with the GC as - // it sees a _Gwaiting and does the - // stack scan. If so, gcworkdone will - // be set and gcphasework will simply - // return. - } - if !gp.gcscandone { - mp := acquirem() - gcw := &gp.m.p.ptr().gcw - scanstack(gp, gcw) - releasem(mp) - gp.gcscandone = true - } - gp.preemptscan = false - gp.preempt = false - casfrom_Gscanstatus(gp, _Gscanwaiting, _Gwaiting) - // This clears gcscanvalid. - casgstatus(gp, _Gwaiting, _Grunning) - gp.scanningself = false - return + if gp.preemptStop { + mcall(preemptPark) } // Act like goroutine called runtime.Gosched. - casgstatus(gp, _Gwaiting, _Grunning) - gp.scanningself = false mcall(gopreempt_m) } diff --git a/libgo/go/runtime/mgclarge.go b/libgo/go/runtime/mgclarge.go deleted file mode 100644 index 414db100192..00000000000 --- a/libgo/go/runtime/mgclarge.go +++ /dev/null @@ -1,657 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Page heap. -// -// See malloc.go for the general overview. -// -// Allocation policy is the subject of this file. All free spans live in -// a treap for most of their time being free. See -// https://en.wikipedia.org/wiki/Treap or -// https://faculty.washington.edu/aragon/pubs/rst89.pdf for an overview. -// sema.go also holds an implementation of a treap. -// -// Each treapNode holds a single span. The treap is sorted by base address -// and each span necessarily has a unique base address. -// Spans are returned based on a first-fit algorithm, acquiring the span -// with the lowest base address which still satisfies the request. -// -// The first-fit algorithm is possible due to an augmentation of each -// treapNode to maintain the size of the largest span in the subtree rooted -// at that treapNode. Below we refer to this invariant as the maxPages -// invariant. -// -// The primary routines are -// insert: adds a span to the treap -// remove: removes the span from that treap that best fits the required size -// removeSpan: which removes a specific span from the treap -// -// Whenever a pointer to a span which is owned by the treap is acquired, that -// span must not be mutated. To mutate a span in the treap, remove it first. -// -// mheap_.lock must be held when manipulating this data structure. - -package runtime - -import ( - "unsafe" -) - -//go:notinheap -type mTreap struct { - treap *treapNode - unscavHugePages uintptr // number of unscavenged huge pages in the treap -} - -//go:notinheap -type treapNode struct { - right *treapNode // all treapNodes > this treap node - left *treapNode // all treapNodes < this treap node - parent *treapNode // direct parent of this node, nil if root - key uintptr // base address of the span, used as primary sort key - span *mspan // span at base address key - maxPages uintptr // the maximum size of any span in this subtree, including the root - priority uint32 // random number used by treap algorithm to keep tree probabilistically balanced - types treapIterFilter // the types of spans available in this subtree -} - -// updateInvariants is a helper method which has a node recompute its own -// maxPages and types values by looking at its own span as well as the -// values of its direct children. -// -// Returns true if anything changed. -func (t *treapNode) updateInvariants() bool { - m, i := t.maxPages, t.types - t.maxPages = t.span.npages - t.types = t.span.treapFilter() - if t.left != nil { - t.types |= t.left.types - if t.maxPages < t.left.maxPages { - t.maxPages = t.left.maxPages - } - } - if t.right != nil { - t.types |= t.right.types - if t.maxPages < t.right.maxPages { - t.maxPages = t.right.maxPages - } - } - return m != t.maxPages || i != t.types -} - -// findMinimal finds the minimal (lowest base addressed) node in the treap -// which matches the criteria set out by the filter f and returns nil if -// none exists. -// -// This algorithm is functionally the same as (*mTreap).find, so see that -// method for more details. -func (t *treapNode) findMinimal(f treapIterFilter) *treapNode { - if t == nil || !f.matches(t.types) { - return nil - } - for t != nil { - if t.left != nil && f.matches(t.left.types) { - t = t.left - } else if f.matches(t.span.treapFilter()) { - break - } else if t.right != nil && f.matches(t.right.types) { - t = t.right - } else { - println("runtime: f=", f) - throw("failed to find minimal node matching filter") - } - } - return t -} - -// findMaximal finds the maximal (highest base addressed) node in the treap -// which matches the criteria set out by the filter f and returns nil if -// none exists. -// -// This algorithm is the logical inversion of findMinimal and just changes -// the order of the left and right tests. -func (t *treapNode) findMaximal(f treapIterFilter) *treapNode { - if t == nil || !f.matches(t.types) { - return nil - } - for t != nil { - if t.right != nil && f.matches(t.right.types) { - t = t.right - } else if f.matches(t.span.treapFilter()) { - break - } else if t.left != nil && f.matches(t.left.types) { - t = t.left - } else { - println("runtime: f=", f) - throw("failed to find minimal node matching filter") - } - } - return t -} - -// pred returns the predecessor of t in the treap subject to the criteria -// specified by the filter f. Returns nil if no such predecessor exists. -func (t *treapNode) pred(f treapIterFilter) *treapNode { - if t.left != nil && f.matches(t.left.types) { - // The node has a left subtree which contains at least one matching - // node, find the maximal matching node in that subtree. - return t.left.findMaximal(f) - } - // Lacking a left subtree, look to the parents. - p := t // previous node - t = t.parent - for t != nil { - // Walk up the tree until we find a node that has a left subtree - // that we haven't already visited. - if t.right == p { - if f.matches(t.span.treapFilter()) { - // If this node matches, then it's guaranteed to be the - // predecessor since everything to its left is strictly - // greater. - return t - } else if t.left != nil && f.matches(t.left.types) { - // Failing the root of this subtree, if its left subtree has - // something, that's where we'll find our predecessor. - return t.left.findMaximal(f) - } - } - p = t - t = t.parent - } - // If the parent is nil, then we've hit the root without finding - // a suitable left subtree containing the node (and the predecessor - // wasn't on the path). Thus, there's no predecessor, so just return - // nil. - return nil -} - -// succ returns the successor of t in the treap subject to the criteria -// specified by the filter f. Returns nil if no such successor exists. -func (t *treapNode) succ(f treapIterFilter) *treapNode { - // See pred. This method is just the logical inversion of it. - if t.right != nil && f.matches(t.right.types) { - return t.right.findMinimal(f) - } - p := t - t = t.parent - for t != nil { - if t.left == p { - if f.matches(t.span.treapFilter()) { - return t - } else if t.right != nil && f.matches(t.right.types) { - return t.right.findMinimal(f) - } - } - p = t - t = t.parent - } - return nil -} - -// isSpanInTreap is handy for debugging. One should hold the heap lock, usually -// mheap_.lock(). -func (t *treapNode) isSpanInTreap(s *mspan) bool { - if t == nil { - return false - } - return t.span == s || t.left.isSpanInTreap(s) || t.right.isSpanInTreap(s) -} - -// walkTreap is handy for debugging and testing. -// Starting at some treapnode t, for example the root, do a depth first preorder walk of -// the tree executing fn at each treap node. One should hold the heap lock, usually -// mheap_.lock(). -func (t *treapNode) walkTreap(fn func(tn *treapNode)) { - if t == nil { - return - } - fn(t) - t.left.walkTreap(fn) - t.right.walkTreap(fn) -} - -// checkTreapNode when used in conjunction with walkTreap can usually detect a -// poorly formed treap. -func checkTreapNode(t *treapNode) { - if t == nil { - return - } - if t.span.next != nil || t.span.prev != nil || t.span.list != nil { - throw("span may be on an mSpanList while simultaneously in the treap") - } - if t.span.base() != t.key { - println("runtime: checkTreapNode treapNode t=", t, " t.key=", t.key, - "t.span.base()=", t.span.base()) - throw("why does span.base() and treap.key do not match?") - } - if t.left != nil && t.key < t.left.key { - throw("found out-of-order spans in treap (left child has greater base address)") - } - if t.right != nil && t.key > t.right.key { - throw("found out-of-order spans in treap (right child has lesser base address)") - } -} - -// validateInvariants is handy for debugging and testing. -// It ensures that the various invariants on each treap node are -// appropriately maintained throughout the treap by walking the -// treap in a post-order manner. -func (t *treapNode) validateInvariants() (uintptr, treapIterFilter) { - if t == nil { - return 0, 0 - } - leftMax, leftTypes := t.left.validateInvariants() - rightMax, rightTypes := t.right.validateInvariants() - max := t.span.npages - if leftMax > max { - max = leftMax - } - if rightMax > max { - max = rightMax - } - if max != t.maxPages { - println("runtime: t.maxPages=", t.maxPages, "want=", max) - throw("maxPages invariant violated in treap") - } - typ := t.span.treapFilter() | leftTypes | rightTypes - if typ != t.types { - println("runtime: t.types=", t.types, "want=", typ) - throw("types invariant violated in treap") - } - return max, typ -} - -// treapIterType represents the type of iteration to perform -// over the treap. Each different flag is represented by a bit -// in the type, and types may be combined together by a bitwise -// or operation. -// -// Note that only 5 bits are available for treapIterType, do not -// use the 3 higher-order bits. This constraint is to allow for -// expansion into a treapIterFilter, which is a uint32. -type treapIterType uint8 - -const ( - treapIterScav treapIterType = 1 << iota // scavenged spans - treapIterHuge // spans containing at least one huge page - treapIterBits = iota -) - -// treapIterFilter is a bitwise filter of different spans by binary -// properties. Each bit of a treapIterFilter represents a unique -// combination of bits set in a treapIterType, in other words, it -// represents the power set of a treapIterType. -// -// The purpose of this representation is to allow the existence of -// a specific span type to bubble up in the treap (see the types -// field on treapNode). -// -// More specifically, any treapIterType may be transformed into a -// treapIterFilter for a specific combination of flags via the -// following operation: 1 << (0x1f&treapIterType). -type treapIterFilter uint32 - -// treapFilterAll represents the filter which allows all spans. -const treapFilterAll = ^treapIterFilter(0) - -// treapFilter creates a new treapIterFilter from two treapIterTypes. -// mask represents a bitmask for which flags we should check against -// and match for the expected result after applying the mask. -func treapFilter(mask, match treapIterType) treapIterFilter { - allow := treapIterFilter(0) - for i := treapIterType(0); i < 1< 0 { - have |= treapIterHuge - } - return treapIterFilter(uint32(1) << (0x1f & have)) -} - -// treapIter is a bidirectional iterator type which may be used to iterate over a -// an mTreap in-order forwards (increasing order) or backwards (decreasing order). -// Its purpose is to hide details about the treap from users when trying to iterate -// over it. -// -// To create iterators over the treap, call start or end on an mTreap. -type treapIter struct { - f treapIterFilter - t *treapNode -} - -// span returns the span at the current position in the treap. -// If the treap is not valid, span will panic. -func (i *treapIter) span() *mspan { - return i.t.span -} - -// valid returns whether the iterator represents a valid position -// in the mTreap. -func (i *treapIter) valid() bool { - return i.t != nil -} - -// next moves the iterator forward by one. Once the iterator -// ceases to be valid, calling next will panic. -func (i treapIter) next() treapIter { - i.t = i.t.succ(i.f) - return i -} - -// prev moves the iterator backwards by one. Once the iterator -// ceases to be valid, calling prev will panic. -func (i treapIter) prev() treapIter { - i.t = i.t.pred(i.f) - return i -} - -// start returns an iterator which points to the start of the treap (the -// left-most node in the treap) subject to mask and match constraints. -func (root *mTreap) start(mask, match treapIterType) treapIter { - f := treapFilter(mask, match) - return treapIter{f, root.treap.findMinimal(f)} -} - -// end returns an iterator which points to the end of the treap (the -// right-most node in the treap) subject to mask and match constraints. -func (root *mTreap) end(mask, match treapIterType) treapIter { - f := treapFilter(mask, match) - return treapIter{f, root.treap.findMaximal(f)} -} - -// mutate allows one to mutate the span without removing it from the treap via a -// callback. The span's base and size are allowed to change as long as the span -// remains in the same order relative to its predecessor and successor. -// -// Note however that any operation that causes a treap rebalancing inside of fn -// is strictly forbidden, as that may cause treap node metadata to go -// out-of-sync. -func (root *mTreap) mutate(i treapIter, fn func(span *mspan)) { - s := i.span() - // Save some state about the span for later inspection. - hpages := s.hugePages() - scavenged := s.scavenged - // Call the mutator. - fn(s) - // Update unscavHugePages appropriately. - if !scavenged { - mheap_.free.unscavHugePages -= hpages - } - if !s.scavenged { - mheap_.free.unscavHugePages += s.hugePages() - } - // Update the key in case the base changed. - i.t.key = s.base() - // Updating invariants up the tree needs to happen if - // anything changed at all, so just go ahead and do it - // unconditionally. - // - // If it turns out nothing changed, it'll exit quickly. - t := i.t - for t != nil && t.updateInvariants() { - t = t.parent - } -} - -// insert adds span to the large span treap. -func (root *mTreap) insert(span *mspan) { - if !span.scavenged { - root.unscavHugePages += span.hugePages() - } - base := span.base() - var last *treapNode - pt := &root.treap - for t := *pt; t != nil; t = *pt { - last = t - if t.key < base { - pt = &t.right - } else if t.key > base { - pt = &t.left - } else { - throw("inserting span already in treap") - } - } - - // Add t as new leaf in tree of span size and unique addrs. - // The balanced tree is a treap using priority as the random heap priority. - // That is, it is a binary tree ordered according to the key, - // but then among the space of possible binary trees respecting those - // keys, it is kept balanced on average by maintaining a heap ordering - // on the priority: s.priority <= both s.right.priority and s.right.priority. - // https://en.wikipedia.org/wiki/Treap - // https://faculty.washington.edu/aragon/pubs/rst89.pdf - - t := (*treapNode)(mheap_.treapalloc.alloc()) - t.key = span.base() - t.priority = fastrand() - t.span = span - t.maxPages = span.npages - t.types = span.treapFilter() - t.parent = last - *pt = t // t now at a leaf. - - // Update the tree to maintain the various invariants. - i := t - for i.parent != nil && i.parent.updateInvariants() { - i = i.parent - } - - // Rotate up into tree according to priority. - for t.parent != nil && t.parent.priority > t.priority { - if t != nil && t.span.base() != t.key { - println("runtime: insert t=", t, "t.key=", t.key) - println("runtime: t.span=", t.span, "t.span.base()=", t.span.base()) - throw("span and treap node base addresses do not match") - } - if t.parent.left == t { - root.rotateRight(t.parent) - } else { - if t.parent.right != t { - throw("treap insert finds a broken treap") - } - root.rotateLeft(t.parent) - } - } -} - -func (root *mTreap) removeNode(t *treapNode) { - if !t.span.scavenged { - root.unscavHugePages -= t.span.hugePages() - } - if t.span.base() != t.key { - throw("span and treap node base addresses do not match") - } - // Rotate t down to be leaf of tree for removal, respecting priorities. - for t.right != nil || t.left != nil { - if t.right == nil || t.left != nil && t.left.priority < t.right.priority { - root.rotateRight(t) - } else { - root.rotateLeft(t) - } - } - // Remove t, now a leaf. - if t.parent != nil { - p := t.parent - if p.left == t { - p.left = nil - } else { - p.right = nil - } - // Walk up the tree updating invariants until no updates occur. - for p != nil && p.updateInvariants() { - p = p.parent - } - } else { - root.treap = nil - } - // Return the found treapNode's span after freeing the treapNode. - mheap_.treapalloc.free(unsafe.Pointer(t)) -} - -// find searches for, finds, and returns the treap iterator over all spans -// representing the position of the span with the smallest base address which is -// at least npages in size. If no span has at least npages it returns an invalid -// iterator. -// -// This algorithm is as follows: -// * If there's a left child and its subtree can satisfy this allocation, -// continue down that subtree. -// * If there's no such left child, check if the root of this subtree can -// satisfy the allocation. If so, we're done. -// * If the root cannot satisfy the allocation either, continue down the -// right subtree if able. -// * Else, break and report that we cannot satisfy the allocation. -// -// The preference for left, then current, then right, results in us getting -// the left-most node which will contain the span with the lowest base -// address. -// -// Note that if a request cannot be satisfied the fourth case will be -// reached immediately at the root, since neither the left subtree nor -// the right subtree will have a sufficient maxPages, whilst the root -// node is also unable to satisfy it. -func (root *mTreap) find(npages uintptr) treapIter { - t := root.treap - for t != nil { - if t.span == nil { - throw("treap node with nil span found") - } - // Iterate over the treap trying to go as far left - // as possible while simultaneously ensuring that the - // subtrees we choose always have a span which can - // satisfy the allocation. - if t.left != nil && t.left.maxPages >= npages { - t = t.left - } else if t.span.npages >= npages { - // Before going right, if this span can satisfy the - // request, stop here. - break - } else if t.right != nil && t.right.maxPages >= npages { - t = t.right - } else { - t = nil - } - } - return treapIter{treapFilterAll, t} -} - -// removeSpan searches for, finds, deletes span along with -// the associated treap node. If the span is not in the treap -// then t will eventually be set to nil and the t.span -// will throw. -func (root *mTreap) removeSpan(span *mspan) { - base := span.base() - t := root.treap - for t.span != span { - if t.key < base { - t = t.right - } else if t.key > base { - t = t.left - } - } - root.removeNode(t) -} - -// erase removes the element referred to by the current position of the -// iterator. This operation consumes the given iterator, so it should no -// longer be used. It is up to the caller to get the next or previous -// iterator before calling erase, if need be. -func (root *mTreap) erase(i treapIter) { - root.removeNode(i.t) -} - -// rotateLeft rotates the tree rooted at node x. -// turning (x a (y b c)) into (y (x a b) c). -func (root *mTreap) rotateLeft(x *treapNode) { - // p -> (x a (y b c)) - p := x.parent - a, y := x.left, x.right - b, c := y.left, y.right - - y.left = x - x.parent = y - y.right = c - if c != nil { - c.parent = y - } - x.left = a - if a != nil { - a.parent = x - } - x.right = b - if b != nil { - b.parent = x - } - - y.parent = p - if p == nil { - root.treap = y - } else if p.left == x { - p.left = y - } else { - if p.right != x { - throw("large span treap rotateLeft") - } - p.right = y - } - - x.updateInvariants() - y.updateInvariants() -} - -// rotateRight rotates the tree rooted at node y. -// turning (y (x a b) c) into (x a (y b c)). -func (root *mTreap) rotateRight(y *treapNode) { - // p -> (y (x a b) c) - p := y.parent - x, c := y.left, y.right - a, b := x.left, x.right - - x.left = a - if a != nil { - a.parent = x - } - x.right = y - y.parent = x - y.left = b - if b != nil { - b.parent = y - } - y.right = c - if c != nil { - c.parent = y - } - - x.parent = p - if p == nil { - root.treap = x - } else if p.left == y { - p.left = x - } else { - if p.right != y { - throw("large span treap rotateRight") - } - p.right = x - } - - y.updateInvariants() - x.updateInvariants() -} diff --git a/libgo/go/runtime/mgcmark.go b/libgo/go/runtime/mgcmark.go index b6b69ddd2e1..a5af5d2446c 100644 --- a/libgo/go/runtime/mgcmark.go +++ b/libgo/go/runtime/mgcmark.go @@ -46,8 +46,6 @@ const ( // gcMarkRootPrepare queues root scanning jobs (stacks, globals, and // some miscellany) and initializes scanning-related state. // -// The caller must have call gcCopySpans(). -// // The world must be stopped. // //go:nowritebarrier @@ -111,8 +109,7 @@ func gcMarkRootCheck() { fail: println("gp", gp, "goid", gp.goid, "status", readgstatus(gp), - "gcscandone", gp.gcscandone, - "gcscanvalid", gp.gcscanvalid) + "gcscandone", gp.gcscandone) unlock(&allglock) // Avoid self-deadlock with traceback. throw("scan missed a g") } @@ -182,7 +179,7 @@ func markroot(gcw *gcWork, i uint32) { gp.waitsince = work.tstart } - // scang must be done on the system stack in case + // scanstack must be done on the system stack in case // we're trying to scan our own stack. systemstack(func() { // If this is a self-scan, put the user G in @@ -196,14 +193,24 @@ func markroot(gcw *gcWork, i uint32) { userG.waitreason = waitReasonGarbageCollectionScan } - // TODO: scang blocks until gp's stack has - // been scanned, which may take a while for + // TODO: suspendG blocks (and spins) until gp + // stops, which may take a while for // running goroutines. Consider doing this in // two phases where the first is non-blocking: // we scan the stacks we can and ask running // goroutines to scan themselves; and the // second blocks. - scang(gp, gcw) + stopped := suspendG(gp) + if stopped.dead { + gp.gcscandone = true + return + } + if gp.gcscandone { + throw("g already scanned") + } + scanstack(gp, gcw) + gp.gcscandone = true + resumeG(stopped) if selfScan { casgstatus(userG, _Gwaiting, _Grunning) @@ -242,13 +249,21 @@ func markrootSpans(gcw *gcWork, shard int) { sg := mheap_.sweepgen spans := mheap_.sweepSpans[mheap_.sweepgen/2%2].block(shard) // Note that work.spans may not include spans that were - // allocated between entering the scan phase and now. This is - // okay because any objects with finalizers in those spans - // must have been allocated and given finalizers after we - // entered the scan phase, so addfinalizer will have ensured - // the above invariants for them. - for _, s := range spans { - if s.state != mSpanInUse { + // allocated between entering the scan phase and now. We may + // also race with spans being added into sweepSpans when they're + // just created, and as a result we may see nil pointers in the + // spans slice. This is okay because any objects with finalizers + // in those spans must have been allocated and given finalizers + // after we entered the scan phase, so addfinalizer will have + // ensured the above invariants for them. + for i := 0; i < len(spans); i++ { + // sweepBuf.block requires that we read pointers from the block atomically. + // It also requires that we ignore nil pointers. + s := (*mspan)(atomic.Loadp(unsafe.Pointer(&spans[i]))) + + // This is racing with spans being initialized, so + // check the state carefully. + if s == nil || s.state.get() != mSpanInUse { continue } // Check that this span was swept (it may be cached or uncached). @@ -600,16 +615,16 @@ func doscanstackswitch(*g, *g) // scanstack scans gp's stack, greying all pointers found on the stack. // +// scanstack will also shrink the stack if it is safe to do so. If it +// is not, it schedules a stack shrink for the next synchronous safe +// point. +// // scanstack is marked go:systemstack because it must not be preempted // while using a workbuf. // //go:nowritebarrier //go:systemstack func scanstack(gp *g, gcw *gcWork) { - if gp.gcscanvalid { - return - } - if readgstatus(gp)&_Gscan == 0 { print("runtime:scanstack: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", hex(readgstatus(gp)), "\n") throw("scanstack - bad status") @@ -622,17 +637,9 @@ func scanstack(gp *g, gcw *gcWork) { case _Gdead: return case _Grunning: - // ok for gccgo, though not for gc. - if usestackmaps { - print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n") - throw("scanstack: goroutine not stopped") - } - case _Gsyscall: - if usestackmaps { - print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n") - throw("scanstack: goroutine in syscall") - } - case _Grunnable, _Gwaiting: + print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n") + throw("scanstack: goroutine not stopped") + case _Grunnable, _Gsyscall, _Gwaiting: // ok } @@ -644,6 +651,8 @@ func scanstack(gp *g, gcw *gcWork) { doscanstack(gp, gcw) } else if gp.entry != nil { // This is a newly created g that hasn't run. No stack to scan. + } else if readgstatus(gp)&^_Gscan == _Gsyscall { + scanSyscallStack(gp, gcw) } else { // Scanning another g's stack. We need to switch to that g // to unwind its stack. And switch back after scan. @@ -661,8 +670,6 @@ func scanstack(gp *g, gcw *gcWork) { // This is necessary as it uses stack objects (a.k.a. stack tracing). // We don't (yet) do stack objects, and regular stack/heap scan // will take care of defer records just fine. - - gp.gcscanvalid = true } // scanstackswitch scans gp's stack by switching (gogo) to gp and @@ -700,6 +707,38 @@ func scanstackswitch(gp *g, gcw *gcWork) { releasem(mp) } +// scanSyscallStack scans the stack of a goroutine blocked in a +// syscall by waking it up and asking it to scan its own stack. +func scanSyscallStack(gp *g, gcw *gcWork) { + if gp.scanningself { + // We've suspended the goroutine by setting the _Gscan bit, + // so this shouldn't be possible. + throw("scanSyscallStack: scanningself") + } + if gp.gcscandone { + // We've suspended the goroutine by setting the _Gscan bit, + // so this shouldn't be possible. + + throw("scanSyscallStack: gcscandone") + } + + gp.gcScannedSyscallStack = false + for { + mp := gp.m + noteclear(&mp.scannote) + gp.scangcw = uintptr(unsafe.Pointer(gcw)) + tgkill(getpid(), _pid_t(mp.procid), _SIGURG) + // Wait for gp to scan its own stack. + notesleep(&mp.scannote) + if gp.gcScannedSyscallStack { + return + } + + // The signal was delivered at a bad time. Try again. + osyield() + } +} + type gcDrainFlags int const ( @@ -1087,10 +1126,10 @@ func scanstackblockwithmap(pc, b0, n0 uintptr, ptrmask *uint8, gcw *gcWork) { if obj != 0 { o, span, objIndex := findObject(obj, b, i, false) if obj < minPhysPageSize || - span != nil && span.state != mSpanManual && - (obj < span.base() || obj >= span.limit || span.state != mSpanInUse) { + span != nil && span.state.get() != mSpanManual && + (obj < span.base() || obj >= span.limit || span.state.get() != mSpanInUse) { print("runtime: found in object at *(", hex(b), "+", hex(i), ") = ", hex(obj), ", pc=", hex(pc), "\n") - name, file, line, _ := funcfileline(pc, -1) + name, file, line, _ := funcfileline(pc, -1, false) print(name, "\n", file, ":", line, "\n") //gcDumpObject("object", b, i) throw("found bad pointer in Go stack (incorrect use of unsafe or cgo?)") @@ -1218,15 +1257,15 @@ func gcDumpObject(label string, obj, off uintptr) { return } print(" s.base()=", hex(s.base()), " s.limit=", hex(s.limit), " s.spanclass=", s.spanclass, " s.elemsize=", s.elemsize, " s.state=") - if 0 <= s.state && int(s.state) < len(mSpanStateNames) { - print(mSpanStateNames[s.state], "\n") + if state := s.state.get(); 0 <= state && int(state) < len(mSpanStateNames) { + print(mSpanStateNames[state], "\n") } else { - print("unknown(", s.state, ")\n") + print("unknown(", state, ")\n") } skipped := false size := s.elemsize - if s.state == mSpanManual && size == 0 { + if s.state.get() == mSpanManual && size == 0 { // We're printing something from a stack frame. We // don't know how big it is, so just show up to an // including off. @@ -1314,7 +1353,7 @@ var useCheckmark = false func initCheckmarks() { useCheckmark = true for _, s := range mheap_.allspans { - if s.state == mSpanInUse { + if s.state.get() == mSpanInUse { heapBitsForAddr(s.base()).initCheckmarkSpan(s.layout()) } } @@ -1323,7 +1362,7 @@ func initCheckmarks() { func clearCheckmarks() { useCheckmark = false for _, s := range mheap_.allspans { - if s.state == mSpanInUse { + if s.state.get() == mSpanInUse { heapBitsForAddr(s.base()).clearCheckmarkSpan(s.layout()) } } diff --git a/libgo/go/runtime/mgcscavenge.go b/libgo/go/runtime/mgcscavenge.go index 9f8c4725f08..f3856dbe8c0 100644 --- a/libgo/go/runtime/mgcscavenge.go +++ b/libgo/go/runtime/mgcscavenge.go @@ -17,7 +17,29 @@ // scavenger's primary goal is to bring the estimated heap RSS of the // application down to a goal. // -// That goal is defined as (retainExtraPercent+100) / 100 * next_gc. +// That goal is defined as: +// (retainExtraPercent+100) / 100 * (next_gc / last_next_gc) * last_heap_inuse +// +// Essentially, we wish to have the application's RSS track the heap goal, but +// the heap goal is defined in terms of bytes of objects, rather than pages like +// RSS. As a result, we need to take into account for fragmentation internal to +// spans. next_gc / last_next_gc defines the ratio between the current heap goal +// and the last heap goal, which tells us by how much the heap is growing and +// shrinking. We estimate what the heap will grow to in terms of pages by taking +// this ratio and multiplying it by heap_inuse at the end of the last GC, which +// allows us to account for this additional fragmentation. Note that this +// procedure makes the assumption that the degree of fragmentation won't change +// dramatically over the next GC cycle. Overestimating the amount of +// fragmentation simply results in higher memory use, which will be accounted +// for by the next pacing up date. Underestimating the fragmentation however +// could lead to performance degradation. Handling this case is not within the +// scope of the scavenger. Situations where the amount of fragmentation balloons +// over the course of a single GC cycle should be considered pathologies, +// flagged as bugs, and fixed appropriately. +// +// An additional factor of retainExtraPercent is added as a buffer to help ensure +// that there's more unscavenged memory to allocate out of, since each allocation +// out of scavenged memory incurs a potentially expensive page fault. // // The goal is updated after each GC and the scavenger's pacing parameters // (which live in mheap_) are updated to match. The pacing parameters work much @@ -33,25 +55,18 @@ package runtime +import ( + "runtime/internal/atomic" + "runtime/internal/sys" + "unsafe" +) + const ( // The background scavenger is paced according to these parameters. // // scavengePercent represents the portion of mutator time we're willing // to spend on scavenging in percent. - // - // scavengePageLatency is a worst-case estimate (order-of-magnitude) of - // the time it takes to scavenge one (regular-sized) page of memory. - // scavengeHugePageLatency is the same but for huge pages. - // - // scavengePagePeriod is derived from scavengePercent and scavengePageLatency, - // and represents the average time between scavenging one page that we're - // aiming for. scavengeHugePagePeriod is the same but for huge pages. - // These constants are core to the scavenge pacing algorithm. - scavengePercent = 1 // 1% - scavengePageLatency = 10e3 // 10µs - scavengeHugePageLatency = 10e3 // 10µs - scavengePagePeriod = scavengePageLatency / (scavengePercent / 100.0) - scavengeHugePagePeriod = scavengePageLatency / (scavengePercent / 100.0) + scavengePercent = 1 // 1% // retainExtraPercent represents the amount of memory over the heap goal // that the scavenger should keep as a buffer space for the allocator. @@ -61,34 +76,46 @@ const ( // incurs an additional cost), to account for heap fragmentation and // the ever-changing layout of the heap. retainExtraPercent = 10 + + // maxPagesPerPhysPage is the maximum number of supported runtime pages per + // physical page, based on maxPhysPageSize. + maxPagesPerPhysPage = maxPhysPageSize / pageSize ) // heapRetained returns an estimate of the current heap RSS. -// -// mheap_.lock must be held or the world must be stopped. func heapRetained() uint64 { - return memstats.heap_sys - memstats.heap_released + return atomic.Load64(&memstats.heap_sys) - atomic.Load64(&memstats.heap_released) } // gcPaceScavenger updates the scavenger's pacing, particularly // its rate and RSS goal. // // The RSS goal is based on the current heap goal with a small overhead -// to accomodate non-determinism in the allocator. +// to accommodate non-determinism in the allocator. // // The pacing is based on scavengePageRate, which applies to both regular and // huge pages. See that constant for more information. // // mheap_.lock must be held or the world must be stopped. func gcPaceScavenger() { - // Compute our scavenging goal and align it to a physical page boundary - // to make the following calculations more exact. - retainedGoal := memstats.next_gc + // If we're called before the first GC completed, disable scavenging. + // We never scavenge before the 2nd GC cycle anyway (we don't have enough + // information about the heap yet) so this is fine, and avoids a fault + // or garbage data later. + if memstats.last_next_gc == 0 { + mheap_.scavengeGoal = ^uint64(0) + return + } + // Compute our scavenging goal. + goalRatio := float64(memstats.next_gc) / float64(memstats.last_next_gc) + retainedGoal := uint64(float64(memstats.last_heap_inuse) * goalRatio) // Add retainExtraPercent overhead to retainedGoal. This calculation // looks strange but the purpose is to arrive at an integer division // (e.g. if retainExtraPercent = 12.5, then we get a divisor of 8) // that also avoids the overflow from a multiplication. retainedGoal += retainedGoal / (1.0 / (retainExtraPercent / 100.0)) + // Align it to a physical page boundary to make the following calculations + // a bit more exact. retainedGoal = (retainedGoal + uint64(physPageSize) - 1) &^ (uint64(physPageSize) - 1) // Represents where we are now in the heap's contribution to RSS in bytes. @@ -104,86 +131,31 @@ func gcPaceScavenger() { // physical page. retainedNow := heapRetained() - // If we're already below our goal, publish the goal in case it changed - // then disable the background scavenger. - if retainedNow <= retainedGoal { - mheap_.scavengeRetainedGoal = retainedGoal - mheap_.scavengeBytesPerNS = 0 + // If we're already below our goal, or within one page of our goal, then disable + // the background scavenger. We disable the background scavenger if there's + // less than one physical page of work to do because it's not worth it. + if retainedNow <= retainedGoal || retainedNow-retainedGoal < uint64(physPageSize) { + mheap_.scavengeGoal = ^uint64(0) return } - - // Now we start to compute the total amount of work necessary and the total - // amount of time we're willing to give the scavenger to complete this work. - // This will involve calculating how much of the work consists of huge pages - // and how much consists of regular pages since the former can let us scavenge - // more memory in the same time. - totalWork := retainedNow - retainedGoal - - // On systems without huge page support, all work is regular work. - regularWork := totalWork - hugeTime := uint64(0) - - // On systems where we have huge pages, we want to do as much of the - // scavenging work as possible on huge pages, because the costs are the - // same per page, but we can give back more more memory in a shorter - // period of time. - if physHugePageSize != 0 { - // Start by computing the amount of free memory we have in huge pages - // in total. Trivially, this is all the huge page work we need to do. - hugeWork := uint64(mheap_.free.unscavHugePages) << physHugePageShift - - // ...but it could turn out that there's more huge work to do than - // total work, so cap it at total work. This might happen for very large - // heaps where the additional factor of retainExtraPercent can make it so - // that there are free chunks of memory larger than a huge page that we don't want - // to scavenge. - if hugeWork >= totalWork { - hugePages := totalWork >> physHugePageShift - hugeWork = hugePages << physHugePageShift - } - // Everything that's not huge work is regular work. At this point we - // know huge work so we can calculate how much time that will take - // based on scavengePageRate (which applies to pages of any size). - regularWork = totalWork - hugeWork - hugeTime = (hugeWork >> physHugePageShift) * scavengeHugePagePeriod - } - // Finally, we can compute how much time it'll take to do the regular work - // and the total time to do all the work. - regularTime := regularWork / uint64(physPageSize) * scavengePagePeriod - totalTime := hugeTime + regularTime - - now := nanotime() - - lock(&scavenge.lock) - - // Update all the pacing parameters in mheap with scavenge.lock held, - // so that scavenge.gen is kept in sync with the updated values. - mheap_.scavengeRetainedGoal = retainedGoal - mheap_.scavengeRetainedBasis = retainedNow - mheap_.scavengeTimeBasis = now - mheap_.scavengeBytesPerNS = float64(totalWork) / float64(totalTime) - scavenge.gen++ // increase scavenge generation - - // Wake up background scavenger if needed, since the pacing was just updated. - wakeScavengerLocked() - - unlock(&scavenge.lock) + mheap_.scavengeGoal = retainedGoal + mheap_.pages.resetScavengeAddr() } -// State of the background scavenger. +// Sleep/wait state of the background scavenger. var scavenge struct { lock mutex g *g parked bool timer *timer - gen uint32 // read with either lock or mheap_.lock, write with both } -// wakeScavengerLocked unparks the scavenger if necessary. It must be called +// wakeScavenger unparks the scavenger if necessary. It must be called // after any pacing update. // -// scavenge.lock must be held. -func wakeScavengerLocked() { +// mheap_.lock and scavenge.lock must not be held. +func wakeScavenger() { + lock(&scavenge.lock) if scavenge.parked { // Try to stop the timer but we don't really care if we succeed. // It's possible that either a timer was never started, or that @@ -194,45 +166,44 @@ func wakeScavengerLocked() { stopTimer(scavenge.timer) // Unpark the goroutine and tell it that there may have been a pacing - // change. + // change. Note that we skip the scheduler's runnext slot because we + // want to avoid having the scavenger interfere with the fair + // scheduling of user goroutines. In effect, this schedules the + // scavenger at a "lower priority" but that's OK because it'll + // catch up on the work it missed when it does get scheduled. scavenge.parked = false - ready(scavenge.g, 0, true) + systemstack(func() { + ready(scavenge.g, 0, false) + }) } + unlock(&scavenge.lock) } // scavengeSleep attempts to put the scavenger to sleep for ns. -// It also checks to see if gen != scavenge.gen before going to sleep, -// and aborts if true (meaning an update had occurred). // // Note that this function should only be called by the scavenger. // // The scavenger may be woken up earlier by a pacing change, and it may not go // to sleep at all if there's a pending pacing change. // -// Returns false if awoken early (i.e. true means a complete sleep). -func scavengeSleep(gen uint32, ns int64) bool { +// Returns the amount of time actually slept. +func scavengeSleep(ns int64) int64 { lock(&scavenge.lock) - // If there was an update, just abort the sleep. - if scavenge.gen != gen { - unlock(&scavenge.lock) - return false - } - // Set the timer. - now := nanotime() - scavenge.timer.when = now + ns - startTimer(scavenge.timer) - - // Park the goroutine. It's fine that we don't publish the - // fact that the timer was set; even if the timer wakes up - // and fire scavengeReady before we park, it'll block on - // scavenge.lock. + // + // This must happen here instead of inside gopark + // because we can't close over any variables without + // failing escape analysis. + start := nanotime() + resetTimer(scavenge.timer, start+ns) + + // Mark ourself as asleep and go to sleep. scavenge.parked = true goparkunlock(&scavenge.lock, waitReasonSleep, traceEvGoSleep, 2) - // Return true if we completed the full sleep. - return (nanotime() - now) >= ns + // Return how long we actually slept for. + return nanotime() - start } // Background scavenger. @@ -250,118 +221,543 @@ func bgscavenge(c chan int) { scavenge.timer = new(timer) scavenge.timer.f = func(_ interface{}, _ uintptr) { - lock(&scavenge.lock) - wakeScavengerLocked() - unlock(&scavenge.lock) + wakeScavenger() } c <- 1 goparkunlock(&scavenge.lock, waitReasonGCScavengeWait, traceEvGoBlock, 1) - // Parameters for sleeping. - // - // If we end up doing more work than we need, we should avoid spinning - // until we have more work to do: instead, we know exactly how much time - // until more work will need to be done, so we sleep. - // - // We should avoid sleeping for less than minSleepNS because Gosched() - // overheads among other things will work out better in that case. + // Exponentially-weighted moving average of the fraction of time this + // goroutine spends scavenging (that is, percent of a single CPU). + // It represents a measure of scheduling overheads which might extend + // the sleep or the critical time beyond what's expected. Assume no + // overhead to begin with. // - // There's no reason to set a maximum on sleep time because we'll always - // get woken up earlier if there's any kind of update that could change - // the scavenger's pacing. - // - // retryDelayNS tracks how much to sleep next time we fail to do any - // useful work. - const minSleepNS = int64(100 * 1000) // 100 µs - - retryDelayNS := minSleepNS + // TODO(mknyszek): Consider making this based on total CPU time of the + // application (i.e. scavengePercent * GOMAXPROCS). This isn't really + // feasible now because the scavenger acquires the heap lock over the + // scavenging operation, which means scavenging effectively blocks + // allocators and isn't scalable. However, given a scalable allocator, + // it makes sense to also make the scavenger scale with it; if you're + // allocating more frequently, then presumably you're also generating + // more work for the scavenger. + const idealFraction = scavengePercent / 100.0 + scavengeEWMA := float64(idealFraction) for { released := uintptr(0) - park := false - ttnext := int64(0) - gen := uint32(0) + + // Time in scavenging critical section. + crit := int64(0) // Run on the system stack since we grab the heap lock, // and a stack growth with the heap lock means a deadlock. systemstack(func() { lock(&mheap_.lock) - gen = scavenge.gen - // If background scavenging is disabled or if there's no work to do just park. - retained := heapRetained() - if mheap_.scavengeBytesPerNS == 0 || retained <= mheap_.scavengeRetainedGoal { + retained, goal := heapRetained(), mheap_.scavengeGoal + if retained <= goal { unlock(&mheap_.lock) - park = true return } - - // Calculate how big we want the retained heap to be - // at this point in time. - // - // The formula is for that of a line, y = b - mx - // We want y (want), - // m = scavengeBytesPerNS (> 0) - // x = time between scavengeTimeBasis and now - // b = scavengeRetainedBasis - rate := mheap_.scavengeBytesPerNS - tdist := nanotime() - mheap_.scavengeTimeBasis - rdist := uint64(rate * float64(tdist)) - want := mheap_.scavengeRetainedBasis - rdist - - // If we're above the line, scavenge to get below the - // line. - if retained > want { - released = mheap_.scavengeLocked(uintptr(retained - want)) - } unlock(&mheap_.lock) - // If we over-scavenged a bit, calculate how much time it'll - // take at the current rate for us to make that up. We definitely - // won't have any work to do until at least that amount of time - // passes. - if released > uintptr(retained-want) { - extra := released - uintptr(retained-want) - ttnext = int64(float64(extra) / rate) - } + // Scavenge one page, and measure the amount of time spent scavenging. + start := nanotime() + released = mheap_.pages.scavengeOne(physPageSize, false) + crit = nanotime() - start }) - if park { + if debug.gctrace > 0 { + if released > 0 { + print("scvg: ", released>>10, " KB released\n") + } + print("scvg: inuse: ", memstats.heap_inuse>>20, ", idle: ", memstats.heap_idle>>20, ", sys: ", memstats.heap_sys>>20, ", released: ", memstats.heap_released>>20, ", consumed: ", (memstats.heap_sys-memstats.heap_released)>>20, " (MB)\n") + } + + if released == 0 { lock(&scavenge.lock) scavenge.parked = true goparkunlock(&scavenge.lock, waitReasonGCScavengeWait, traceEvGoBlock, 1) continue } - if debug.gctrace > 0 { - if released > 0 { - print("scvg: ", released>>20, " MB released\n") - } - print("scvg: inuse: ", memstats.heap_inuse>>20, ", idle: ", memstats.heap_idle>>20, ", sys: ", memstats.heap_sys>>20, ", released: ", memstats.heap_released>>20, ", consumed: ", (memstats.heap_sys-memstats.heap_released)>>20, " (MB)\n") + // If we spent more than 10 ms (for example, if the OS scheduled us away, or someone + // put their machine to sleep) in the critical section, bound the time we use to + // calculate at 10 ms to avoid letting the sleep time get arbitrarily high. + const maxCrit = 10e6 + if crit > maxCrit { + crit = maxCrit } - if released == 0 { - // If we were unable to release anything this may be because there's - // no free memory available to scavenge. Go to sleep and try again. - if scavengeSleep(gen, retryDelayNS) { - // If we successfully slept through the delay, back off exponentially. - retryDelayNS *= 2 + // Compute the amount of time to sleep, assuming we want to use at most + // scavengePercent of CPU time. Take into account scheduling overheads + // that may extend the length of our sleep by multiplying by how far + // off we are from the ideal ratio. For example, if we're sleeping too + // much, then scavengeEMWA < idealFraction, so we'll adjust the sleep time + // down. + adjust := scavengeEWMA / idealFraction + sleepTime := int64(adjust * float64(crit) / (scavengePercent / 100.0)) + + // Go to sleep. + slept := scavengeSleep(sleepTime) + + // Compute the new ratio. + fraction := float64(crit) / float64(crit+slept) + + // Set a lower bound on the fraction. + // Due to OS-related anomalies we may "sleep" for an inordinate amount + // of time. Let's avoid letting the ratio get out of hand by bounding + // the sleep time we use in our EWMA. + const minFraction = 1 / 1000 + if fraction < minFraction { + fraction = minFraction + } + + // Update scavengeEWMA by merging in the new crit/slept ratio. + const alpha = 0.5 + scavengeEWMA = alpha*fraction + (1-alpha)*scavengeEWMA + } +} + +// scavenge scavenges nbytes worth of free pages, starting with the +// highest address first. Successive calls continue from where it left +// off until the heap is exhausted. Call resetScavengeAddr to bring it +// back to the top of the heap. +// +// Returns the amount of memory scavenged in bytes. +// +// If locked == false, s.mheapLock must not be locked. If locked == true, +// s.mheapLock must be locked. +// +// Must run on the system stack because scavengeOne must run on the +// system stack. +// +//go:systemstack +func (s *pageAlloc) scavenge(nbytes uintptr, locked bool) uintptr { + released := uintptr(0) + for released < nbytes { + r := s.scavengeOne(nbytes-released, locked) + if r == 0 { + // Nothing left to scavenge! Give up. + break + } + released += r + } + return released +} + +// resetScavengeAddr sets the scavenge start address to the top of the heap's +// address space. This should be called each time the scavenger's pacing +// changes. +// +// s.mheapLock must be held. +func (s *pageAlloc) resetScavengeAddr() { + s.scavAddr = chunkBase(s.end) - 1 +} + +// scavengeOne starts from s.scavAddr and walks down the heap until it finds +// a contiguous run of pages to scavenge. It will try to scavenge at most +// max bytes at once, but may scavenge more to avoid breaking huge pages. Once +// it scavenges some memory it returns how much it scavenged and updates s.scavAddr +// appropriately. s.scavAddr must be reset manually and externally. +// +// Should it exhaust the heap, it will return 0 and set s.scavAddr to minScavAddr. +// +// If locked == false, s.mheapLock must not be locked. +// If locked == true, s.mheapLock must be locked. +// +// Must be run on the system stack because it either acquires the heap lock +// or executes with the heap lock acquired. +// +//go:systemstack +func (s *pageAlloc) scavengeOne(max uintptr, locked bool) uintptr { + // Calculate the maximum number of pages to scavenge. + // + // This should be alignUp(max, pageSize) / pageSize but max can and will + // be ^uintptr(0), so we need to be very careful not to overflow here. + // Rather than use alignUp, calculate the number of pages rounded down + // first, then add back one if necessary. + maxPages := max / pageSize + if max%pageSize != 0 { + maxPages++ + } + + // Calculate the minimum number of pages we can scavenge. + // + // Because we can only scavenge whole physical pages, we must + // ensure that we scavenge at least minPages each time, aligned + // to minPages*pageSize. + minPages := physPageSize / pageSize + if minPages < 1 { + minPages = 1 + } + + // Helpers for locking and unlocking only if locked == false. + lockHeap := func() { + if !locked { + lock(s.mheapLock) + } + } + unlockHeap := func() { + if !locked { + unlock(s.mheapLock) + } + } + + lockHeap() + ci := chunkIndex(s.scavAddr) + if ci < s.start { + unlockHeap() + return 0 + } + + // Check the chunk containing the scav addr, starting at the addr + // and see if there are any free and unscavenged pages. + if s.summary[len(s.summary)-1][ci].max() >= uint(minPages) { + // We only bother looking for a candidate if there at least + // minPages free pages at all. It's important that we only + // continue if the summary says we can because that's how + // we can tell if parts of the address space are unused. + // See the comment on s.chunks in mpagealloc.go. + base, npages := s.chunkOf(ci).findScavengeCandidate(chunkPageIndex(s.scavAddr), minPages, maxPages) + + // If we found something, scavenge it and return! + if npages != 0 { + s.scavengeRangeLocked(ci, base, npages) + unlockHeap() + return uintptr(npages) * pageSize + } + } + + // getInUseRange returns the highest range in the + // intersection of [0, addr] and s.inUse. + // + // s.mheapLock must be held. + getInUseRange := func(addr uintptr) addrRange { + top := s.inUse.findSucc(addr) + if top == 0 { + return addrRange{} + } + r := s.inUse.ranges[top-1] + // addr is inclusive, so treat it as such when + // updating the limit, which is exclusive. + if r.limit > addr+1 { + r.limit = addr + 1 + } + return r + } + + // Slow path: iterate optimistically over the in-use address space + // looking for any free and unscavenged page. If we think we see something, + // lock and verify it! + // + // We iterate over the address space by taking ranges from inUse. +newRange: + for { + r := getInUseRange(s.scavAddr) + if r.size() == 0 { + break + } + unlockHeap() + + // Iterate over all of the chunks described by r. + // Note that r.limit is the exclusive upper bound, but what + // we want is the top chunk instead, inclusive, so subtract 1. + bot, top := chunkIndex(r.base), chunkIndex(r.limit-1) + for i := top; i >= bot; i-- { + // If this chunk is totally in-use or has no unscavenged pages, don't bother + // doing a more sophisticated check. + // + // Note we're accessing the summary and the chunks without a lock, but + // that's fine. We're being optimistic anyway. + + // Check quickly if there are enough free pages at all. + if s.summary[len(s.summary)-1][i].max() < uint(minPages) { + continue } - continue + + // Run over the chunk looking harder for a candidate. Again, we could + // race with a lot of different pieces of code, but we're just being + // optimistic. Make sure we load the l2 pointer atomically though, to + // avoid races with heap growth. It may or may not be possible to also + // see a nil pointer in this case if we do race with heap growth, but + // just defensively ignore the nils. This operation is optimistic anyway. + l2 := (*[1 << pallocChunksL2Bits]pallocData)(atomic.Loadp(unsafe.Pointer(&s.chunks[i.l1()]))) + if l2 == nil || !l2[i.l2()].hasScavengeCandidate(minPages) { + continue + } + + // We found a candidate, so let's lock and verify it. + lockHeap() + + // Find, verify, and scavenge if we can. + chunk := s.chunkOf(i) + base, npages := chunk.findScavengeCandidate(pallocChunkPages-1, minPages, maxPages) + if npages > 0 { + // We found memory to scavenge! Mark the bits and report that up. + // scavengeRangeLocked will update scavAddr for us, also. + s.scavengeRangeLocked(i, base, npages) + unlockHeap() + return uintptr(npages) * pageSize + } + + // We were fooled, let's take this opportunity to move the scavAddr + // all the way down to where we searched as scavenged for future calls + // and keep iterating. Then, go get a new range. + s.scavAddr = chunkBase(i-1) + pallocChunkPages*pageSize - 1 + continue newRange } - retryDelayNS = minSleepNS + lockHeap() + + // Move the scavenger down the heap, past everything we just searched. + // Since we don't check if scavAddr moved while twe let go of the heap lock, + // it's possible that it moved down and we're moving it up here. This + // raciness could result in us searching parts of the heap unnecessarily. + // TODO(mknyszek): Remove this racy behavior through explicit address + // space reservations, which are difficult to do with just scavAddr. + s.scavAddr = r.base - 1 + } + // We reached the end of the in-use address space and couldn't find anything, + // so signal that there's nothing left to scavenge. + s.scavAddr = minScavAddr + unlockHeap() - if ttnext > 0 && ttnext > minSleepNS { - // If there's an appreciable amount of time until the next scavenging - // goal, just sleep. We'll get woken up if anything changes and this - // way we avoid spinning. - scavengeSleep(gen, ttnext) - continue + return 0 +} + +// scavengeRangeLocked scavenges the given region of memory. +// +// s.mheapLock must be held. +func (s *pageAlloc) scavengeRangeLocked(ci chunkIdx, base, npages uint) { + s.chunkOf(ci).scavenged.setRange(base, npages) + + // Compute the full address for the start of the range. + addr := chunkBase(ci) + uintptr(base)*pageSize + + // Update the scav pointer. + s.scavAddr = addr - 1 + + // Only perform the actual scavenging if we're not in a test. + // It's dangerous to do so otherwise. + if s.test { + return + } + sysUnused(unsafe.Pointer(addr), uintptr(npages)*pageSize) + + // Update global accounting only when not in test, otherwise + // the runtime's accounting will be wrong. + mSysStatInc(&memstats.heap_released, uintptr(npages)*pageSize) +} + +// fillAligned returns x but with all zeroes in m-aligned +// groups of m bits set to 1 if any bit in the group is non-zero. +// +// For example, fillAligned(0x0100a3, 8) == 0xff00ff. +// +// Note that if m == 1, this is a no-op. +// +// m must be a power of 2 <= maxPagesPerPhysPage. +func fillAligned(x uint64, m uint) uint64 { + apply := func(x uint64, c uint64) uint64 { + // The technique used it here is derived from + // https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord + // and extended for more than just bytes (like nibbles + // and uint16s) by using an appropriate constant. + // + // To summarize the technique, quoting from that page: + // "[It] works by first zeroing the high bits of the [8] + // bytes in the word. Subsequently, it adds a number that + // will result in an overflow to the high bit of a byte if + // any of the low bits were initially set. Next the high + // bits of the original word are ORed with these values; + // thus, the high bit of a byte is set iff any bit in the + // byte was set. Finally, we determine if any of these high + // bits are zero by ORing with ones everywhere except the + // high bits and inverting the result." + return ^((((x & c) + c) | x) | c) + } + // Transform x to contain a 1 bit at the top of each m-aligned + // group of m zero bits. + switch m { + case 1: + return x + case 2: + x = apply(x, 0x5555555555555555) + case 4: + x = apply(x, 0x7777777777777777) + case 8: + x = apply(x, 0x7f7f7f7f7f7f7f7f) + case 16: + x = apply(x, 0x7fff7fff7fff7fff) + case 32: + x = apply(x, 0x7fffffff7fffffff) + case 64: // == maxPagesPerPhysPage + x = apply(x, 0x7fffffffffffffff) + default: + throw("bad m value") + } + // Now, the top bit of each m-aligned group in x is set + // that group was all zero in the original x. + + // From each group of m bits subtract 1. + // Because we know only the top bits of each + // m-aligned group are set, we know this will + // set each group to have all the bits set except + // the top bit, so just OR with the original + // result to set all the bits. + return ^((x - (x >> (m - 1))) | x) +} + +// hasScavengeCandidate returns true if there's any min-page-aligned groups of +// min pages of free-and-unscavenged memory in the region represented by this +// pallocData. +// +// min must be a non-zero power of 2 <= maxPagesPerPhysPage. +func (m *pallocData) hasScavengeCandidate(min uintptr) bool { + if min&(min-1) != 0 || min == 0 { + print("runtime: min = ", min, "\n") + throw("min must be a non-zero power of 2") + } else if min > maxPagesPerPhysPage { + print("runtime: min = ", min, "\n") + throw("min too large") + } + + // The goal of this search is to see if the chunk contains any free and unscavenged memory. + for i := len(m.scavenged) - 1; i >= 0; i-- { + // 1s are scavenged OR non-free => 0s are unscavenged AND free + // + // TODO(mknyszek): Consider splitting up fillAligned into two + // functions, since here we technically could get by with just + // the first half of its computation. It'll save a few instructions + // but adds some additional code complexity. + x := fillAligned(m.scavenged[i]|m.pallocBits[i], uint(min)) + + // Quickly skip over chunks of non-free or scavenged pages. + if x != ^uint64(0) { + return true + } + } + return false +} + +// findScavengeCandidate returns a start index and a size for this pallocData +// segment which represents a contiguous region of free and unscavenged memory. +// +// searchIdx indicates the page index within this chunk to start the search, but +// note that findScavengeCandidate searches backwards through the pallocData. As a +// a result, it will return the highest scavenge candidate in address order. +// +// min indicates a hard minimum size and alignment for runs of pages. That is, +// findScavengeCandidate will not return a region smaller than min pages in size, +// or that is min pages or greater in size but not aligned to min. min must be +// a non-zero power of 2 <= maxPagesPerPhysPage. +// +// max is a hint for how big of a region is desired. If max >= pallocChunkPages, then +// findScavengeCandidate effectively returns entire free and unscavenged regions. +// If max < pallocChunkPages, it may truncate the returned region such that size is +// max. However, findScavengeCandidate may still return a larger region if, for +// example, it chooses to preserve huge pages, or if max is not aligned to min (it +// will round up). That is, even if max is small, the returned size is not guaranteed +// to be equal to max. max is allowed to be less than min, in which case it is as if +// max == min. +func (m *pallocData) findScavengeCandidate(searchIdx uint, min, max uintptr) (uint, uint) { + if min&(min-1) != 0 || min == 0 { + print("runtime: min = ", min, "\n") + throw("min must be a non-zero power of 2") + } else if min > maxPagesPerPhysPage { + print("runtime: min = ", min, "\n") + throw("min too large") + } + // max may not be min-aligned, so we might accidentally truncate to + // a max value which causes us to return a non-min-aligned value. + // To prevent this, align max up to a multiple of min (which is always + // a power of 2). This also prevents max from ever being less than + // min, unless it's zero, so handle that explicitly. + if max == 0 { + max = min + } else { + max = alignUp(max, min) + } + + i := int(searchIdx / 64) + // Start by quickly skipping over blocks of non-free or scavenged pages. + for ; i >= 0; i-- { + // 1s are scavenged OR non-free => 0s are unscavenged AND free + x := fillAligned(m.scavenged[i]|m.pallocBits[i], uint(min)) + if x != ^uint64(0) { + break + } + } + if i < 0 { + // Failed to find any free/unscavenged pages. + return 0, 0 + } + // We have something in the 64-bit chunk at i, but it could + // extend further. Loop until we find the extent of it. + + // 1s are scavenged OR non-free => 0s are unscavenged AND free + x := fillAligned(m.scavenged[i]|m.pallocBits[i], uint(min)) + z1 := uint(sys.LeadingZeros64(^x)) + run, end := uint(0), uint(i)*64+(64-z1) + if x<= 0; j-- { + x := fillAligned(m.scavenged[j]|m.pallocBits[j], uint(min)) + run += uint(sys.LeadingZeros64(x)) + if x != 0 { + // The run stopped in this word. + break + } } + } - // Give something else a chance to run, no locks are held. - Gosched() + // Split the run we found if it's larger than max but hold on to + // our original length, since we may need it later. + size := run + if size > uint(max) { + size = uint(max) + } + start := end - size + + // Each huge page is guaranteed to fit in a single palloc chunk. + // + // TODO(mknyszek): Support larger huge page sizes. + // TODO(mknyszek): Consider taking pages-per-huge-page as a parameter + // so we can write tests for this. + if physHugePageSize > pageSize && physHugePageSize > physPageSize { + // We have huge pages, so let's ensure we don't break one by scavenging + // over a huge page boundary. If the range [start, start+size) overlaps with + // a free-and-unscavenged huge page, we want to grow the region we scavenge + // to include that huge page. + + // Compute the huge page boundary above our candidate. + pagesPerHugePage := uintptr(physHugePageSize / pageSize) + hugePageAbove := uint(alignUp(uintptr(start), pagesPerHugePage)) + + // If that boundary is within our current candidate, then we may be breaking + // a huge page. + if hugePageAbove <= end { + // Compute the huge page boundary below our candidate. + hugePageBelow := uint(alignDown(uintptr(start), pagesPerHugePage)) + + if hugePageBelow >= end-run { + // We're in danger of breaking apart a huge page since start+size crosses + // a huge page boundary and rounding down start to the nearest huge + // page boundary is included in the full run we found. Include the entire + // huge page in the bound by rounding down to the huge page size. + size = size + (start - hugePageBelow) + start = hugePageBelow + } + } } + return start, size } diff --git a/libgo/go/runtime/mgcscavenge_test.go b/libgo/go/runtime/mgcscavenge_test.go new file mode 100644 index 00000000000..518d5ab27ae --- /dev/null +++ b/libgo/go/runtime/mgcscavenge_test.go @@ -0,0 +1,419 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "fmt" + "math/rand" + . "runtime" + "testing" +) + +// makePallocData produces an initialized PallocData by setting +// the ranges of described in alloc and scavenge. +func makePallocData(alloc, scavenged []BitRange) *PallocData { + b := new(PallocData) + for _, v := range alloc { + if v.N == 0 { + // Skip N==0. It's harmless and allocRange doesn't + // handle this case. + continue + } + b.AllocRange(v.I, v.N) + } + for _, v := range scavenged { + if v.N == 0 { + // See the previous loop. + continue + } + b.ScavengedSetRange(v.I, v.N) + } + return b +} + +func TestFillAligned(t *testing.T) { + fillAlignedSlow := func(x uint64, m uint) uint64 { + if m == 1 { + return x + } + out := uint64(0) + for i := uint(0); i < 64; i += m { + for j := uint(0); j < m; j++ { + if x&(uint64(1)<<(i+j)) != 0 { + out |= ((uint64(1) << m) - 1) << i + break + } + } + } + return out + } + check := func(x uint64, m uint) { + want := fillAlignedSlow(x, m) + if got := FillAligned(x, m); got != want { + t.Logf("got: %064b", got) + t.Logf("want: %064b", want) + t.Errorf("bad fillAligned(%016x, %d)", x, m) + } + } + for m := uint(1); m <= 64; m *= 2 { + tests := []uint64{ + 0x0000000000000000, + 0x00000000ffffffff, + 0xffffffff00000000, + 0x8000000000000001, + 0xf00000000000000f, + 0xf00000010050000f, + 0xffffffffffffffff, + 0x0000000000000001, + 0x0000000000000002, + 0x0000000000000008, + uint64(1) << (m - 1), + uint64(1) << m, + // Try a few fixed arbitrary examples. + 0xb02b9effcf137016, + 0x3975a076a9fbff18, + 0x0f8c88ec3b81506e, + 0x60f14d80ef2fa0e6, + } + for _, test := range tests { + check(test, m) + } + for i := 0; i < 1000; i++ { + // Try a pseudo-random numbers. + check(rand.Uint64(), m) + + if m > 1 { + // For m != 1, let's construct a slightly more interesting + // random test. Generate a bitmap which is either 0 or + // randomly set bits for each m-aligned group of m bits. + val := uint64(0) + for n := uint(0); n < 64; n += m { + // For each group of m bits, flip a coin: + // * Leave them as zero. + // * Set them randomly. + if rand.Uint64()%2 == 0 { + val |= (rand.Uint64() & ((1 << m) - 1)) << n + } + } + check(val, m) + } + } + } +} + +func TestPallocDataFindScavengeCandidate(t *testing.T) { + type test struct { + alloc, scavenged []BitRange + min, max uintptr + want BitRange + } + tests := map[string]test{ + "MixedMin1": { + alloc: []BitRange{{0, 40}, {42, PallocChunkPages - 42}}, + scavenged: []BitRange{{0, 41}, {42, PallocChunkPages - 42}}, + min: 1, + max: PallocChunkPages, + want: BitRange{41, 1}, + }, + "MultiMin1": { + alloc: []BitRange{{0, 63}, {65, 20}, {87, PallocChunkPages - 87}}, + scavenged: []BitRange{{86, 1}}, + min: 1, + max: PallocChunkPages, + want: BitRange{85, 1}, + }, + } + // Try out different page minimums. + for m := uintptr(1); m <= 64; m *= 2 { + suffix := fmt.Sprintf("Min%d", m) + tests["AllFree"+suffix] = test{ + min: m, + max: PallocChunkPages, + want: BitRange{0, PallocChunkPages}, + } + tests["AllScavenged"+suffix] = test{ + scavenged: []BitRange{{0, PallocChunkPages}}, + min: m, + max: PallocChunkPages, + want: BitRange{0, 0}, + } + tests["NoneFree"+suffix] = test{ + alloc: []BitRange{{0, PallocChunkPages}}, + scavenged: []BitRange{{PallocChunkPages / 2, PallocChunkPages / 2}}, + min: m, + max: PallocChunkPages, + want: BitRange{0, 0}, + } + tests["StartFree"+suffix] = test{ + alloc: []BitRange{{uint(m), PallocChunkPages - uint(m)}}, + min: m, + max: PallocChunkPages, + want: BitRange{0, uint(m)}, + } + tests["StartFree"+suffix] = test{ + alloc: []BitRange{{uint(m), PallocChunkPages - uint(m)}}, + min: m, + max: PallocChunkPages, + want: BitRange{0, uint(m)}, + } + tests["EndFree"+suffix] = test{ + alloc: []BitRange{{0, PallocChunkPages - uint(m)}}, + min: m, + max: PallocChunkPages, + want: BitRange{PallocChunkPages - uint(m), uint(m)}, + } + tests["Straddle64"+suffix] = test{ + alloc: []BitRange{{0, 64 - uint(m)}, {64 + uint(m), PallocChunkPages - (64 + uint(m))}}, + min: m, + max: 2 * m, + want: BitRange{64 - uint(m), 2 * uint(m)}, + } + tests["BottomEdge64WithFull"+suffix] = test{ + alloc: []BitRange{{64, 64}, {128 + 3*uint(m), PallocChunkPages - (128 + 3*uint(m))}}, + scavenged: []BitRange{{1, 10}}, + min: m, + max: 3 * m, + want: BitRange{128, 3 * uint(m)}, + } + tests["BottomEdge64WithPocket"+suffix] = test{ + alloc: []BitRange{{64, 62}, {127, 1}, {128 + 3*uint(m), PallocChunkPages - (128 + 3*uint(m))}}, + scavenged: []BitRange{{1, 10}}, + min: m, + max: 3 * m, + want: BitRange{128, 3 * uint(m)}, + } + tests["Max0"+suffix] = test{ + scavenged: []BitRange{{0, PallocChunkPages - uint(m)}}, + min: m, + max: 0, + want: BitRange{PallocChunkPages - uint(m), uint(m)}, + } + if m <= 8 { + tests["OneFree"] = test{ + alloc: []BitRange{{0, 40}, {40 + uint(m), PallocChunkPages - (40 + uint(m))}}, + min: m, + max: PallocChunkPages, + want: BitRange{40, uint(m)}, + } + tests["OneScavenged"] = test{ + alloc: []BitRange{{0, 40}, {40 + uint(m), PallocChunkPages - (40 + uint(m))}}, + scavenged: []BitRange{{40, 1}}, + min: m, + max: PallocChunkPages, + want: BitRange{0, 0}, + } + } + if m > 1 { + tests["MaxUnaligned"+suffix] = test{ + scavenged: []BitRange{{0, PallocChunkPages - uint(m*2-1)}}, + min: m, + max: m - 2, + want: BitRange{PallocChunkPages - uint(m), uint(m)}, + } + tests["SkipSmall"+suffix] = test{ + alloc: []BitRange{{0, 64 - uint(m)}, {64, 5}, {70, 11}, {82, PallocChunkPages - 82}}, + min: m, + max: m, + want: BitRange{64 - uint(m), uint(m)}, + } + tests["SkipMisaligned"+suffix] = test{ + alloc: []BitRange{{0, 64 - uint(m)}, {64, 63}, {127 + uint(m), PallocChunkPages - (127 + uint(m))}}, + min: m, + max: m, + want: BitRange{64 - uint(m), uint(m)}, + } + tests["MaxLessThan"+suffix] = test{ + scavenged: []BitRange{{0, PallocChunkPages - uint(m)}}, + min: m, + max: 1, + want: BitRange{PallocChunkPages - uint(m), uint(m)}, + } + } + } + if PhysHugePageSize > uintptr(PageSize) { + // Check hugepage preserving behavior. + bits := uint(PhysHugePageSize / uintptr(PageSize)) + tests["PreserveHugePageBottom"] = test{ + alloc: []BitRange{{bits + 2, PallocChunkPages - (bits + 2)}}, + min: 1, + max: 3, // Make it so that max would have us try to break the huge page. + want: BitRange{0, bits + 2}, + } + if 3*bits < PallocChunkPages { + // We need at least 3 huge pages in a chunk for this test to make sense. + tests["PreserveHugePageMiddle"] = test{ + alloc: []BitRange{{0, bits - 10}, {2*bits + 10, PallocChunkPages - (2*bits + 10)}}, + min: 1, + max: 12, // Make it so that max would have us try to break the huge page. + want: BitRange{bits, bits + 10}, + } + } + tests["PreserveHugePageTop"] = test{ + alloc: []BitRange{{0, PallocChunkPages - bits}}, + min: 1, + max: 1, // Even one page would break a huge page in this case. + want: BitRange{PallocChunkPages - bits, bits}, + } + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + b := makePallocData(v.alloc, v.scavenged) + start, size := b.FindScavengeCandidate(PallocChunkPages-1, v.min, v.max) + got := BitRange{start, size} + if !(got.N == 0 && v.want.N == 0) && got != v.want { + t.Fatalf("candidate mismatch: got %v, want %v", got, v.want) + } + }) + } +} + +// Tests end-to-end scavenging on a pageAlloc. +func TestPageAllocScavenge(t *testing.T) { + type test struct { + request, expect uintptr + } + minPages := PhysPageSize / PageSize + if minPages < 1 { + minPages = 1 + } + tests := map[string]struct { + beforeAlloc map[ChunkIdx][]BitRange + beforeScav map[ChunkIdx][]BitRange + expect []test + afterScav map[ChunkIdx][]BitRange + }{ + "AllFreeUnscavExhaust": { + beforeAlloc: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {}, + }, + beforeScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {}, + }, + expect: []test{ + {^uintptr(0), 3 * PallocChunkPages * PageSize}, + }, + afterScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + }, + }, + "NoneFreeUnscavExhaust": { + beforeAlloc: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + }, + beforeScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {}, + }, + expect: []test{ + {^uintptr(0), 0}, + }, + afterScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {}, + }, + }, + "ScavHighestPageFirst": { + beforeAlloc: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + beforeScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{uint(minPages), PallocChunkPages - uint(2*minPages)}}, + }, + expect: []test{ + {1, minPages * PageSize}, + }, + afterScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{uint(minPages), PallocChunkPages - uint(minPages)}}, + }, + }, + "ScavMultiple": { + beforeAlloc: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + beforeScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{uint(minPages), PallocChunkPages - uint(2*minPages)}}, + }, + expect: []test{ + {minPages * PageSize, minPages * PageSize}, + {minPages * PageSize, minPages * PageSize}, + }, + afterScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + }, + "ScavMultiple2": { + beforeAlloc: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + }, + beforeScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{uint(minPages), PallocChunkPages - uint(2*minPages)}}, + BaseChunkIdx + 1: {{0, PallocChunkPages - uint(2*minPages)}}, + }, + expect: []test{ + {2 * minPages * PageSize, 2 * minPages * PageSize}, + {minPages * PageSize, minPages * PageSize}, + {minPages * PageSize, minPages * PageSize}, + }, + afterScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + }, + }, + "ScavDiscontiguous": { + beforeAlloc: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 0xe: {}, + }, + beforeScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{uint(minPages), PallocChunkPages - uint(2*minPages)}}, + BaseChunkIdx + 0xe: {{uint(2 * minPages), PallocChunkPages - uint(2*minPages)}}, + }, + expect: []test{ + {2 * minPages * PageSize, 2 * minPages * PageSize}, + {^uintptr(0), 2 * minPages * PageSize}, + {^uintptr(0), 0}, + }, + afterScav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 0xe: {{0, PallocChunkPages}}, + }, + }, + } + for name, v := range tests { + v := v + runTest := func(t *testing.T, locked bool) { + b := NewPageAlloc(v.beforeAlloc, v.beforeScav) + defer FreePageAlloc(b) + + for iter, h := range v.expect { + if got := b.Scavenge(h.request, locked); got != h.expect { + t.Fatalf("bad scavenge #%d: want %d, got %d", iter+1, h.expect, got) + } + } + want := NewPageAlloc(v.beforeAlloc, v.afterScav) + defer FreePageAlloc(want) + + checkPageAlloc(t, want, b) + } + t.Run(name, func(t *testing.T) { + runTest(t, false) + }) + t.Run(name+"Locked", func(t *testing.T) { + runTest(t, true) + }) + } +} diff --git a/libgo/go/runtime/mgcsweep.go b/libgo/go/runtime/mgcsweep.go index c1c6e654c6e..1e959a4ad2d 100644 --- a/libgo/go/runtime/mgcsweep.go +++ b/libgo/go/runtime/mgcsweep.go @@ -116,12 +116,12 @@ func sweepone() uintptr { atomic.Store(&mheap_.sweepdone, 1) break } - if s.state != mSpanInUse { + if state := s.state.get(); state != mSpanInUse { // This can happen if direct sweeping already // swept this span, but in that case the sweep // generation should always be up-to-date. if !(s.sweepgen == sg || s.sweepgen == sg+3) { - print("runtime: bad span s.state=", s.state, " s.sweepgen=", s.sweepgen, " sweepgen=", sg, "\n") + print("runtime: bad span s.state=", state, " s.sweepgen=", s.sweepgen, " sweepgen=", sg, "\n") throw("non in-use span in unswept list") } continue @@ -213,8 +213,8 @@ func (s *mspan) sweep(preserve bool) bool { throw("mspan.sweep: m is not locked") } sweepgen := mheap_.sweepgen - if s.state != mSpanInUse || s.sweepgen != sweepgen-1 { - print("mspan.sweep: state=", s.state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n") + if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 { + print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n") throw("mspan.sweep: bad span state") } @@ -353,8 +353,8 @@ func (s *mspan) sweep(preserve bool) bool { if freeToHeap || nfreed == 0 { // The span must be in our exclusive ownership until we update sweepgen, // check for potential races. - if s.state != mSpanInUse || s.sweepgen != sweepgen-1 { - print("mspan.sweep: state=", s.state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n") + if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 { + print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n") throw("mspan.sweep: bad span state after sweep") } // Serialization point. @@ -388,7 +388,7 @@ func (s *mspan) sweep(preserve bool) bool { s.limit = 0 // prevent mlookup from finding this span sysFault(unsafe.Pointer(s.base()), size) } else { - mheap_.freeSpan(s, true) + mheap_.freeSpan(s) } c.local_nlargefree++ c.local_largefree += size diff --git a/libgo/go/runtime/mgcsweepbuf.go b/libgo/go/runtime/mgcsweepbuf.go index 0491f7ccf6c..78288229c83 100644 --- a/libgo/go/runtime/mgcsweepbuf.go +++ b/libgo/go/runtime/mgcsweepbuf.go @@ -111,8 +111,9 @@ retry: unlock(&b.spineLock) } - // We have a block. Insert the span. - block.spans[bottom] = s + // We have a block. Insert the span atomically, since there may be + // concurrent readers via the block API. + atomic.StorepNoWB(unsafe.Pointer(&block.spans[bottom]), unsafe.Pointer(s)) } // pop removes and returns a span from buffer b, or nil if b is empty. @@ -147,7 +148,9 @@ func (b *gcSweepBuf) numBlocks() int { } // block returns the spans in the i'th block of buffer b. block is -// safe to call concurrently with push. +// safe to call concurrently with push. The block may contain nil +// pointers that must be ignored, and each entry in the block must be +// loaded atomically. func (b *gcSweepBuf) block(i int) []*mspan { // Perform bounds check before loading spine address since // push ensures the allocated length is at least spineLen. @@ -169,11 +172,5 @@ func (b *gcSweepBuf) block(i int) []*mspan { } else { spans = block.spans[:bottom] } - - // push may have reserved a slot but not filled it yet, so - // trim away unused entries. - for len(spans) > 0 && spans[len(spans)-1] == nil { - spans = spans[:len(spans)-1] - } return spans } diff --git a/libgo/go/runtime/mgcwork.go b/libgo/go/runtime/mgcwork.go index 89d1e0e38e9..a1b61add9b5 100644 --- a/libgo/go/runtime/mgcwork.go +++ b/libgo/go/runtime/mgcwork.go @@ -126,12 +126,12 @@ func (w *gcWork) checkPut(ptr uintptr, ptrs []uintptr) { if debugCachedWork { alreadyFailed := w.putGen == w.pauseGen w.putGen = w.pauseGen - if m := getg().m; m.locks > 0 || m.mallocing != 0 || m.preemptoff != "" || m.p.ptr().status != _Prunning { + if !canPreemptM(getg().m) { // If we were to spin, the runtime may - // deadlock: the condition above prevents - // preemption (see newstack), which could - // prevent gcMarkDone from finishing the - // ragged barrier and releasing the spin. + // deadlock. Since we can't be preempted, the + // spin could prevent gcMarkDone from + // finishing the ragged barrier, which is what + // releases us from the spin. return } for atomic.Load(&gcWorkPauseGen) == w.pauseGen { diff --git a/libgo/go/runtime/mheap.go b/libgo/go/runtime/mheap.go index cd01b3f7570..f40589a5540 100644 --- a/libgo/go/runtime/mheap.go +++ b/libgo/go/runtime/mheap.go @@ -15,10 +15,19 @@ import ( "unsafe" ) -// minPhysPageSize is a lower-bound on the physical page size. The -// true physical page size may be larger than this. In contrast, -// sys.PhysPageSize is an upper-bound on the physical page size. -const minPhysPageSize = 4096 +const ( + // minPhysPageSize is a lower-bound on the physical page size. The + // true physical page size may be larger than this. In contrast, + // sys.PhysPageSize is an upper-bound on the physical page size. + minPhysPageSize = 4096 + + // maxPhysPageSize is the maximum page size the runtime supports. + maxPhysPageSize = 512 << 10 + + // maxPhysHugePageSize sets an upper-bound on the maximum huge page size + // that the runtime supports. + maxPhysHugePageSize = pallocChunkBytes +) // Main malloc heap. // The heap itself is the "free" and "scav" treaps, @@ -32,10 +41,10 @@ type mheap struct { // lock must only be acquired on the system stack, otherwise a g // could self-deadlock if its stack grows with the lock held. lock mutex - free mTreap // free spans - sweepgen uint32 // sweep generation, see comment in mspan - sweepdone uint32 // all spans are swept - sweepers uint32 // number of active sweepone calls + pages pageAlloc // page allocation data structure + sweepgen uint32 // sweep generation, see comment in mspan; written during STW + sweepdone uint32 // all spans are swept + sweepers uint32 // number of active sweepone calls // allspans is a slice of all mspans ever created. Each mspan // appears exactly once. @@ -81,7 +90,7 @@ type mheap struct { // accounting for current progress. If we could only adjust // the slope, it would create a discontinuity in debt if any // progress has already been made. - pagesInUse uint64 // pages of spans in stats mSpanInUse; R/W with mheap.lock + pagesInUse uint64 // pages of spans in stats mSpanInUse; updated atomically pagesSwept uint64 // pages swept this cycle; updated atomically pagesSweptBasis uint64 // pagesSwept to use as the origin of the sweep ratio; updated atomically sweepHeapLiveBasis uint64 // value of heap_live to use as the origin of sweep ratio; written with lock, read without @@ -89,24 +98,10 @@ type mheap struct { // TODO(austin): pagesInUse should be a uintptr, but the 386 // compiler can't 8-byte align fields. - // Scavenger pacing parameters - // - // The two basis parameters and the scavenge ratio parallel the proportional - // sweeping implementation, the primary differences being that: - // * Scavenging concerns itself with RSS, estimated as heapRetained() - // * Rather than pacing the scavenger to the GC, it is paced to a - // time-based rate computed in gcPaceScavenger. - // - // scavengeRetainedGoal represents our goal RSS. - // - // All fields must be accessed with lock. - // - // TODO(mknyszek): Consider abstracting the basis fields and the scavenge ratio - // into its own type so that this logic may be shared with proportional sweeping. - scavengeTimeBasis int64 - scavengeRetainedBasis uint64 - scavengeBytesPerNS float64 - scavengeRetainedGoal uint64 + // scavengeGoal is the amount of total retained heap memory (measured by + // heapRetained) that the runtime will try to maintain by returning memory + // to the OS. + scavengeGoal uint64 // Page reclaimer state @@ -185,6 +180,12 @@ type mheap struct { // simply blocking GC (by disabling preemption). sweepArenas []arenaIdx + // curArena is the arena that the heap is currently growing + // into. This should always be physPageSize-aligned. + curArena struct { + base, end uintptr + } + _ uint32 // ensure 64-bit alignment of central // central free lists for small size classes. @@ -199,7 +200,6 @@ type mheap struct { spanalloc fixalloc // allocator for span* cachealloc fixalloc // allocator for mcache* - treapalloc fixalloc // allocator for treapNodes* specialfinalizeralloc fixalloc // allocator for specialfinalizer* specialprofilealloc fixalloc // allocator for specialprofile* speciallock mutex // lock for special record allocators. @@ -213,10 +213,6 @@ var mheap_ mheap // A heapArena stores metadata for a heap arena. heapArenas are stored // outside of the Go heap and accessed via the mheap_.arenas index. // -// This gets allocated directly from the OS, so ideally it should be a -// multiple of the system page size. For example, avoid adding small -// fields. -// //go:notinheap type heapArena struct { // bitmap stores the pointer/scalar bitmap for the words in @@ -242,7 +238,7 @@ type heapArena struct { // but only the bit corresponding to the first page in each // span is used. // - // Writes are protected by mheap_.lock. + // Reads and writes are atomic. pageInUse [pagesPerArena / 8]uint8 // pageMarks is a bitmap that indicates which spans have any @@ -259,6 +255,18 @@ type heapArena struct { // faster scanning, but we don't have 64-bit atomic bit // operations. pageMarks [pagesPerArena / 8]uint8 + + // zeroedBase marks the first byte of the first page in this + // arena which hasn't been used yet and is therefore already + // zero. zeroedBase is relative to the arena base. + // Increases monotonically until it hits heapArenaBytes. + // + // This field is sufficient to determine if an allocation + // needs to be zeroed because the page allocator follows an + // address-ordered first-fit policy. + // + // Read atomically and written with an atomic CAS. + zeroedBase uintptr } // arenaHint is a hint for where to grow the heap arenas. See @@ -298,13 +306,20 @@ type arenaHint struct { // * During GC (gcphase != _GCoff), a span *must not* transition from // manual or in-use to free. Because concurrent GC may read a pointer // and then look up its span, the span state must be monotonic. +// +// Setting mspan.state to mSpanInUse or mSpanManual must be done +// atomically and only after all other span fields are valid. +// Likewise, if inspecting a span is contingent on it being +// mSpanInUse, the state should be loaded atomically and checked +// before depending on other fields. This allows the garbage collector +// to safely deal with potentially invalid pointers, since resolving +// such pointers may race with a span being allocated. type mSpanState uint8 const ( mSpanDead mSpanState = iota mSpanInUse // allocated for garbage collected heap mSpanManual // allocated for manual management (e.g., stack allocator) - mSpanFree ) // mSpanStateNames are the names of the span states, indexed by @@ -316,6 +331,21 @@ var mSpanStateNames = []string{ "mSpanFree", } +// mSpanStateBox holds an mSpanState and provides atomic operations on +// it. This is a separate type to disallow accidental comparison or +// assignment with mSpanState. +type mSpanStateBox struct { + s mSpanState +} + +func (b *mSpanStateBox) set(s mSpanState) { + atomic.Store8((*uint8)(&b.s), uint8(s)) +} + +func (b *mSpanStateBox) get() mSpanState { + return mSpanState(atomic.Load8((*uint8)(&b.s))) +} + // mSpanList heads a linked list of spans. // //go:notinheap @@ -397,19 +427,18 @@ type mspan struct { // h->sweepgen is incremented by 2 after every GC sweepgen uint32 - divMul uint16 // for divide by elemsize - divMagic.mul - baseMask uint16 // if non-0, elemsize is a power of 2, & this will get object allocation base - allocCount uint16 // number of allocated objects - spanclass spanClass // size class and noscan (uint8) - state mSpanState // mspaninuse etc - needzero uint8 // needs to be zeroed before allocation - divShift uint8 // for divide by elemsize - divMagic.shift - divShift2 uint8 // for divide by elemsize - divMagic.shift2 - scavenged bool // whether this span has had its pages released to the OS - elemsize uintptr // computed from sizeclass or from npages - limit uintptr // end of data in span - speciallock mutex // guards specials list - specials *special // linked list of special records sorted by offset. + divMul uint16 // for divide by elemsize - divMagic.mul + baseMask uint16 // if non-0, elemsize is a power of 2, & this will get object allocation base + allocCount uint16 // number of allocated objects + spanclass spanClass // size class and noscan (uint8) + state mSpanStateBox // mSpanInUse etc; accessed atomically (get/set methods) + needzero uint8 // needs to be zeroed before allocation + divShift uint8 // for divide by elemsize - divMagic.shift + divShift2 uint8 // for divide by elemsize - divMagic.shift2 + elemsize uintptr // computed from sizeclass or from npages + limit uintptr // end of data in span + speciallock mutex // guards specials list + specials *special // linked list of special records sorted by offset. } func (s *mspan) base() uintptr { @@ -425,181 +454,6 @@ func (s *mspan) layout() (size, n, total uintptr) { return } -// physPageBounds returns the start and end of the span -// rounded in to the physical page size. -func (s *mspan) physPageBounds() (uintptr, uintptr) { - start := s.base() - end := start + s.npages<<_PageShift - if physPageSize > _PageSize { - // Round start and end in. - start = (start + physPageSize - 1) &^ (physPageSize - 1) - end &^= physPageSize - 1 - } - return start, end -} - -func (h *mheap) coalesce(s *mspan) { - // merge is a helper which merges other into s, deletes references to other - // in heap metadata, and then discards it. other must be adjacent to s. - merge := func(a, b, other *mspan) { - // Caller must ensure a.startAddr < b.startAddr and that either a or - // b is s. a and b must be adjacent. other is whichever of the two is - // not s. - - if pageSize < physPageSize && a.scavenged && b.scavenged { - // If we're merging two scavenged spans on systems where - // pageSize < physPageSize, then their boundary should always be on - // a physical page boundary, due to the realignment that happens - // during coalescing. Throw if this case is no longer true, which - // means the implementation should probably be changed to scavenge - // along the boundary. - _, start := a.physPageBounds() - end, _ := b.physPageBounds() - if start != end { - println("runtime: a.base=", hex(a.base()), "a.npages=", a.npages) - println("runtime: b.base=", hex(b.base()), "b.npages=", b.npages) - println("runtime: physPageSize=", physPageSize, "pageSize=", pageSize) - throw("neighboring scavenged spans boundary is not a physical page boundary") - } - } - - // Adjust s via base and npages and also in heap metadata. - s.npages += other.npages - s.needzero |= other.needzero - if a == s { - h.setSpan(s.base()+s.npages*pageSize-1, s) - } else { - s.startAddr = other.startAddr - h.setSpan(s.base(), s) - } - - // The size is potentially changing so the treap needs to delete adjacent nodes and - // insert back as a combined node. - h.free.removeSpan(other) - other.state = mSpanDead - h.spanalloc.free(unsafe.Pointer(other)) - } - - // realign is a helper which shrinks other and grows s such that their - // boundary is on a physical page boundary. - realign := func(a, b, other *mspan) { - // Caller must ensure a.startAddr < b.startAddr and that either a or - // b is s. a and b must be adjacent. other is whichever of the two is - // not s. - - // If pageSize >= physPageSize then spans are always aligned - // to physical page boundaries, so just exit. - if pageSize >= physPageSize { - return - } - // Since we're resizing other, we must remove it from the treap. - h.free.removeSpan(other) - - // Round boundary to the nearest physical page size, toward the - // scavenged span. - boundary := b.startAddr - if a.scavenged { - boundary &^= (physPageSize - 1) - } else { - boundary = (boundary + physPageSize - 1) &^ (physPageSize - 1) - } - a.npages = (boundary - a.startAddr) / pageSize - b.npages = (b.startAddr + b.npages*pageSize - boundary) / pageSize - b.startAddr = boundary - - h.setSpan(boundary-1, a) - h.setSpan(boundary, b) - - // Re-insert other now that it has a new size. - h.free.insert(other) - } - - hpMiddle := s.hugePages() - - // Coalesce with earlier, later spans. - var hpBefore uintptr - if before := spanOf(s.base() - 1); before != nil && before.state == mSpanFree { - if s.scavenged == before.scavenged { - hpBefore = before.hugePages() - merge(before, s, before) - } else { - realign(before, s, before) - } - } - - // Now check to see if next (greater addresses) span is free and can be coalesced. - var hpAfter uintptr - if after := spanOf(s.base() + s.npages*pageSize); after != nil && after.state == mSpanFree { - if s.scavenged == after.scavenged { - hpAfter = after.hugePages() - merge(s, after, after) - } else { - realign(s, after, after) - } - } - if !s.scavenged && s.hugePages() > hpBefore+hpMiddle+hpAfter { - // If s has grown such that it now may contain more huge pages than it - // and its now-coalesced neighbors did before, then mark the whole region - // as huge-page-backable. - // - // Otherwise, on systems where we break up huge pages (like Linux) - // s may not be backed by huge pages because it could be made up of - // pieces which are broken up in the underlying VMA. The primary issue - // with this is that it can lead to a poor estimate of the amount of - // free memory backed by huge pages for determining the scavenging rate. - // - // TODO(mknyszek): Measure the performance characteristics of sysHugePage - // and determine whether it makes sense to only sysHugePage on the pages - // that matter, or if it's better to just mark the whole region. - sysHugePage(unsafe.Pointer(s.base()), s.npages*pageSize) - } -} - -// hugePages returns the number of aligned physical huge pages in the memory -// regioned owned by this mspan. -func (s *mspan) hugePages() uintptr { - if physHugePageSize == 0 || s.npages < physHugePageSize/pageSize { - return 0 - } - start := s.base() - end := start + s.npages*pageSize - if physHugePageSize > pageSize { - // Round start and end in. - start = (start + physHugePageSize - 1) &^ (physHugePageSize - 1) - end &^= physHugePageSize - 1 - } - if start < end { - return (end - start) >> physHugePageShift - } - return 0 -} - -func (s *mspan) scavenge() uintptr { - // start and end must be rounded in, otherwise madvise - // will round them *out* and release more memory - // than we want. - start, end := s.physPageBounds() - if end <= start { - // start and end don't span a whole physical page. - return 0 - } - released := end - start - memstats.heap_released += uint64(released) - s.scavenged = true - sysUnused(unsafe.Pointer(start), released) - return released -} - -// released returns the number of bytes in this span -// which were returned back to the OS. -func (s *mspan) released() uintptr { - if !s.scavenged { - return 0 - } - start, end := s.physPageBounds() - return end - start -} - // recordspan adds a newly allocated span to h.allspans. // // This only happens the first time a span is allocated from @@ -726,7 +580,7 @@ func inHeapOrStack(b uintptr) bool { if s == nil || b < s.base() { return false } - switch s.state { + switch s.state.get() { case mSpanInUse, mSpanManual: return b < s.limit default: @@ -793,9 +647,12 @@ func spanOfUnchecked(p uintptr) *mspan { //go:nosplit func spanOfHeap(p uintptr) *mspan { s := spanOf(p) - // If p is not allocated, it may point to a stale span, so we - // have to check the span's bounds and state. - if s == nil || p < s.base() || p >= s.limit || s.state != mSpanInUse { + // s is nil if it's never been allocated. Otherwise, we check + // its state first because we don't trust this pointer, so we + // have to synchronize with span initialization. Then, it's + // still possible we picked up a stale span pointer, so we + // have to check the span's bounds. + if s == nil || s.state.get() != mSpanInUse || p < s.base() || p >= s.limit { return nil } return s @@ -813,7 +670,6 @@ func pageIndexOf(p uintptr) (arena *heapArena, pageIdx uintptr, pageMask uint8) // Initialize the heap. func (h *mheap) init() { - h.treapalloc.init(unsafe.Sizeof(treapNode{}), nil, nil, &memstats.other_sys) h.spanalloc.init(unsafe.Sizeof(mspan{}), recordspan, unsafe.Pointer(h), &memstats.mspan_sys) h.cachealloc.init(unsafe.Sizeof(mcache{}), nil, nil, &memstats.mcache_sys) h.specialfinalizeralloc.init(unsafe.Sizeof(specialfinalizer{}), nil, nil, &memstats.other_sys) @@ -834,6 +690,8 @@ func (h *mheap) init() { for i := range h.central { h.central[i].mcentral.init(spanClass(i)) } + + h.pages.init(&h.lock, &memstats.gc_sys) } // reclaim sweeps and reclaims at least npage pages into the heap. @@ -954,7 +812,7 @@ func (h *mheap) reclaimChunk(arenas []arenaIdx, pageIdx, n uintptr) uintptr { // Scan this bitmap chunk for spans that are in-use // but have no marked objects on them. for i := range inUse { - inUseUnmarked := inUse[i] &^ marked[i] + inUseUnmarked := atomic.Load8(&inUse[i]) &^ marked[i] if inUseUnmarked == 0 { continue } @@ -973,7 +831,7 @@ func (h *mheap) reclaimChunk(arenas []arenaIdx, pageIdx, n uintptr) uintptr { // spans were freed when we dropped the // lock and we don't want to get stale // pointers from the spans array. - inUseUnmarked = inUse[i] &^ marked[i] + inUseUnmarked = atomic.Load8(&inUse[i]) &^ marked[i] } } } @@ -990,100 +848,23 @@ func (h *mheap) reclaimChunk(arenas []arenaIdx, pageIdx, n uintptr) uintptr { return nFreed } -// alloc_m is the internal implementation of mheap.alloc. -// -// alloc_m must run on the system stack because it locks the heap, so -// any stack growth during alloc_m would self-deadlock. -// -//go:systemstack -func (h *mheap) alloc_m(npage uintptr, spanclass spanClass, large bool) *mspan { - _g_ := getg() - - // To prevent excessive heap growth, before allocating n pages - // we need to sweep and reclaim at least n pages. - if h.sweepdone == 0 { - h.reclaim(npage) - } - - lock(&h.lock) - // transfer stats from cache to global - memstats.heap_scan += uint64(_g_.m.mcache.local_scan) - _g_.m.mcache.local_scan = 0 - memstats.tinyallocs += uint64(_g_.m.mcache.local_tinyallocs) - _g_.m.mcache.local_tinyallocs = 0 - - s := h.allocSpanLocked(npage, &memstats.heap_inuse) - if s != nil { - // Record span info, because gc needs to be - // able to map interior pointer to containing span. - atomic.Store(&s.sweepgen, h.sweepgen) - h.sweepSpans[h.sweepgen/2%2].push(s) // Add to swept in-use list. - s.state = mSpanInUse - s.allocCount = 0 - s.spanclass = spanclass - if sizeclass := spanclass.sizeclass(); sizeclass == 0 { - s.elemsize = s.npages << _PageShift - s.divShift = 0 - s.divMul = 0 - s.divShift2 = 0 - s.baseMask = 0 - } else { - s.elemsize = uintptr(class_to_size[sizeclass]) - m := &class_to_divmagic[sizeclass] - s.divShift = m.shift - s.divMul = m.mul - s.divShift2 = m.shift2 - s.baseMask = m.baseMask - } - - // Mark in-use span in arena page bitmap. - arena, pageIdx, pageMask := pageIndexOf(s.base()) - arena.pageInUse[pageIdx] |= pageMask - - // update stats, sweep lists - h.pagesInUse += uint64(npage) - if large { - memstats.heap_objects++ - mheap_.largealloc += uint64(s.elemsize) - mheap_.nlargealloc++ - atomic.Xadd64(&memstats.heap_live, int64(npage<<_PageShift)) - } - } - // heap_scan and heap_live were updated. - if gcBlackenEnabled != 0 { - gcController.revise() - } - - if trace.enabled { - traceHeapAlloc() - } - - // h.spans is accessed concurrently without synchronization - // from other threads. Hence, there must be a store/store - // barrier here to ensure the writes to h.spans above happen - // before the caller can publish a pointer p to an object - // allocated from s. As soon as this happens, the garbage - // collector running on another processor could read p and - // look up s in h.spans. The unlock acts as the barrier to - // order these writes. On the read side, the data dependency - // between p and the index in h.spans orders the reads. - unlock(&h.lock) - return s -} - // alloc allocates a new span of npage pages from the GC'd heap. // -// Either large must be true or spanclass must indicates the span's -// size class and scannability. +// spanclass indicates the span's size class and scannability. // // If needzero is true, the memory for the returned span will be zeroed. -func (h *mheap) alloc(npage uintptr, spanclass spanClass, large bool, needzero bool) *mspan { +func (h *mheap) alloc(npages uintptr, spanclass spanClass, needzero bool) *mspan { // Don't do any operations that lock the heap on the G stack. // It might trigger stack growth, and the stack growth code needs // to be able to allocate heap. var s *mspan systemstack(func() { - s = h.alloc_m(npage, spanclass, large) + // To prevent excessive heap growth, before allocating n pages + // we need to sweep and reclaim at least n pages. + if h.sweepdone == 0 { + h.reclaim(npages) + } + s = h.allocSpan(npages, false, spanclass, &memstats.heap_inuse) }) if s != nil { @@ -1105,35 +886,12 @@ func (h *mheap) alloc(npage uintptr, spanclass spanClass, large bool, needzero b // The memory backing the returned span may not be zeroed if // span.needzero is set. // -// allocManual must be called on the system stack because it acquires -// the heap lock. See mheap for details. +// allocManual must be called on the system stack because it may +// acquire the heap lock via allocSpan. See mheap for details. // //go:systemstack -func (h *mheap) allocManual(npage uintptr, stat *uint64) *mspan { - lock(&h.lock) - s := h.allocSpanLocked(npage, stat) - if s != nil { - s.state = mSpanManual - s.manualFreeList = 0 - s.allocCount = 0 - s.spanclass = 0 - s.nelems = 0 - s.elemsize = 0 - s.limit = s.base() + s.npages<<_PageShift - // Manually managed memory doesn't count toward heap_sys. - memstats.heap_sys -= uint64(s.npages << _PageShift) - } - - // This unlock acts as a release barrier. See mheap.alloc_m. - unlock(&h.lock) - - return s -} - -// setSpan modifies the span map so spanOf(base) is s. -func (h *mheap) setSpan(base uintptr, s *mspan) { - ai := arenaIndex(base) - h.arenas[ai.l1()][ai.l2()].spans[(base/pageSize)%pagesPerArena] = s +func (h *mheap) allocManual(npages uintptr, stat *uint64) *mspan { + return h.allocSpan(npages, true, 0, stat) } // setSpans modifies the span map so [spanOf(base), spanOf(base+npage*pageSize)) @@ -1152,93 +910,357 @@ func (h *mheap) setSpans(base, npage uintptr, s *mspan) { } } -// Allocates a span of the given size. h must be locked. -// The returned span has been removed from the -// free structures, but its state is still mSpanFree. -func (h *mheap) allocSpanLocked(npage uintptr, stat *uint64) *mspan { - t := h.free.find(npage) - if t.valid() { - goto HaveSpan +// allocNeedsZero checks if the region of address space [base, base+npage*pageSize), +// assumed to be allocated, needs to be zeroed, updating heap arena metadata for +// future allocations. +// +// This must be called each time pages are allocated from the heap, even if the page +// allocator can otherwise prove the memory it's allocating is already zero because +// they're fresh from the operating system. It updates heapArena metadata that is +// critical for future page allocations. +// +// There are no locking constraints on this method. +func (h *mheap) allocNeedsZero(base, npage uintptr) (needZero bool) { + for npage > 0 { + ai := arenaIndex(base) + ha := h.arenas[ai.l1()][ai.l2()] + + zeroedBase := atomic.Loaduintptr(&ha.zeroedBase) + arenaBase := base % heapArenaBytes + if arenaBase < zeroedBase { + // We extended into the non-zeroed part of the + // arena, so this region needs to be zeroed before use. + // + // zeroedBase is monotonically increasing, so if we see this now then + // we can be sure we need to zero this memory region. + // + // We still need to update zeroedBase for this arena, and + // potentially more arenas. + needZero = true + } + // We may observe arenaBase > zeroedBase if we're racing with one or more + // allocations which are acquiring memory directly before us in the address + // space. But, because we know no one else is acquiring *this* memory, it's + // still safe to not zero. + + // Compute how far into the arena we extend into, capped + // at heapArenaBytes. + arenaLimit := arenaBase + npage*pageSize + if arenaLimit > heapArenaBytes { + arenaLimit = heapArenaBytes + } + // Increase ha.zeroedBase so it's >= arenaLimit. + // We may be racing with other updates. + for arenaLimit > zeroedBase { + if atomic.Casuintptr(&ha.zeroedBase, zeroedBase, arenaLimit) { + break + } + zeroedBase = atomic.Loaduintptr(&ha.zeroedBase) + // Sanity check zeroedBase. + if zeroedBase <= arenaLimit && zeroedBase > arenaBase { + // The zeroedBase moved into the space we were trying to + // claim. That's very bad, and indicates someone allocated + // the same region we did. + throw("potentially overlapping in-use allocations detected") + } + } + + // Move base forward and subtract from npage to move into + // the next arena, or finish. + base += arenaLimit - arenaBase + npage -= (arenaLimit - arenaBase) / pageSize } - if !h.grow(npage) { + return +} + +// tryAllocMSpan attempts to allocate an mspan object from +// the P-local cache, but may fail. +// +// h need not be locked. +// +// This caller must ensure that its P won't change underneath +// it during this function. Currently to ensure that we enforce +// that the function is run on the system stack, because that's +// the only place it is used now. In the future, this requirement +// may be relaxed if its use is necessary elsewhere. +// +//go:systemstack +func (h *mheap) tryAllocMSpan() *mspan { + pp := getg().m.p.ptr() + // If we don't have a p or the cache is empty, we can't do + // anything here. + if pp == nil || pp.mspancache.len == 0 { return nil } - t = h.free.find(npage) - if t.valid() { - goto HaveSpan + // Pull off the last entry in the cache. + s := pp.mspancache.buf[pp.mspancache.len-1] + pp.mspancache.len-- + return s +} + +// allocMSpanLocked allocates an mspan object. +// +// h must be locked. +// +// allocMSpanLocked must be called on the system stack because +// its caller holds the heap lock. See mheap for details. +// Running on the system stack also ensures that we won't +// switch Ps during this function. See tryAllocMSpan for details. +// +//go:systemstack +func (h *mheap) allocMSpanLocked() *mspan { + pp := getg().m.p.ptr() + if pp == nil { + // We don't have a p so just do the normal thing. + return (*mspan)(h.spanalloc.alloc()) + } + // Refill the cache if necessary. + if pp.mspancache.len == 0 { + const refillCount = len(pp.mspancache.buf) / 2 + for i := 0; i < refillCount; i++ { + pp.mspancache.buf[i] = (*mspan)(h.spanalloc.alloc()) + } + pp.mspancache.len = refillCount } - throw("grew heap, but no adequate free span found") + // Pull off the last entry in the cache. + s := pp.mspancache.buf[pp.mspancache.len-1] + pp.mspancache.len-- + return s +} -HaveSpan: - s := t.span() - if s.state != mSpanFree { - throw("candidate mspan for allocation is not free") - } - - // First, subtract any memory that was released back to - // the OS from s. We will add back what's left if necessary. - memstats.heap_released -= uint64(s.released()) - - if s.npages == npage { - h.free.erase(t) - } else if s.npages > npage { - // Trim off the lower bits and make that our new span. - // Do this in-place since this operation does not - // affect the original span's location in the treap. - n := (*mspan)(h.spanalloc.alloc()) - h.free.mutate(t, func(s *mspan) { - n.init(s.base(), npage) - s.npages -= npage - s.startAddr = s.base() + npage*pageSize - h.setSpan(s.base()-1, n) - h.setSpan(s.base(), s) - h.setSpan(n.base(), n) - n.needzero = s.needzero - // n may not be big enough to actually be scavenged, but that's fine. - // We still want it to appear to be scavenged so that we can do the - // right bookkeeping later on in this function (i.e. sysUsed). - n.scavenged = s.scavenged - // Check if s is still scavenged. - if s.scavenged { - start, end := s.physPageBounds() - if start < end { - memstats.heap_released += uint64(end - start) - } else { - s.scavenged = false - } +// freeMSpanLocked free an mspan object. +// +// h must be locked. +// +// freeMSpanLocked must be called on the system stack because +// its caller holds the heap lock. See mheap for details. +// Running on the system stack also ensures that we won't +// switch Ps during this function. See tryAllocMSpan for details. +// +//go:systemstack +func (h *mheap) freeMSpanLocked(s *mspan) { + pp := getg().m.p.ptr() + // First try to free the mspan directly to the cache. + if pp != nil && pp.mspancache.len < len(pp.mspancache.buf) { + pp.mspancache.buf[pp.mspancache.len] = s + pp.mspancache.len++ + return + } + // Failing that (or if we don't have a p), just free it to + // the heap. + h.spanalloc.free(unsafe.Pointer(s)) +} + +// allocSpan allocates an mspan which owns npages worth of memory. +// +// If manual == false, allocSpan allocates a heap span of class spanclass +// and updates heap accounting. If manual == true, allocSpan allocates a +// manually-managed span (spanclass is ignored), and the caller is +// responsible for any accounting related to its use of the span. Either +// way, allocSpan will atomically add the bytes in the newly allocated +// span to *sysStat. +// +// The returned span is fully initialized. +// +// h must not be locked. +// +// allocSpan must be called on the system stack both because it acquires +// the heap lock and because it must block GC transitions. +// +//go:systemstack +func (h *mheap) allocSpan(npages uintptr, manual bool, spanclass spanClass, sysStat *uint64) (s *mspan) { + // Function-global state. + gp := getg() + base, scav := uintptr(0), uintptr(0) + + // If the allocation is small enough, try the page cache! + pp := gp.m.p.ptr() + if pp != nil && npages < pageCachePages/4 { + c := &pp.pcache + + // If the cache is empty, refill it. + if c.empty() { + lock(&h.lock) + *c = h.pages.allocToCache() + unlock(&h.lock) + } + + // Try to allocate from the cache. + base, scav = c.alloc(npages) + if base != 0 { + s = h.tryAllocMSpan() + + if s != nil && gcBlackenEnabled == 0 && (manual || spanclass.sizeclass() != 0) { + goto HaveSpan } - }) - s = n - } else { - throw("candidate mspan for allocation is too small") + // We're either running duing GC, failed to acquire a mspan, + // or the allocation is for a large object. This means we + // have to lock the heap and do a bunch of extra work, + // so go down the HaveBaseLocked path. + // + // We must do this during GC to avoid skew with heap_scan + // since we flush mcache stats whenever we lock. + // + // TODO(mknyszek): It would be nice to not have to + // lock the heap if it's a large allocation, but + // it's fine for now. The critical section here is + // short and large object allocations are relatively + // infrequent. + } } - // "Unscavenge" s only AFTER splitting so that - // we only sysUsed whatever we actually need. - if s.scavenged { + + // For one reason or another, we couldn't get the + // whole job done without the heap lock. + lock(&h.lock) + + if base == 0 { + // Try to acquire a base address. + base, scav = h.pages.alloc(npages) + if base == 0 { + if !h.grow(npages) { + unlock(&h.lock) + return nil + } + base, scav = h.pages.alloc(npages) + if base == 0 { + throw("grew heap, but no adequate free space found") + } + } + } + if s == nil { + // We failed to get an mspan earlier, so grab + // one now that we have the heap lock. + s = h.allocMSpanLocked() + } + if !manual { + // This is a heap span, so we should do some additional accounting + // which may only be done with the heap locked. + + // Transfer stats from mcache to global. + memstats.heap_scan += uint64(gp.m.mcache.local_scan) + gp.m.mcache.local_scan = 0 + memstats.tinyallocs += uint64(gp.m.mcache.local_tinyallocs) + gp.m.mcache.local_tinyallocs = 0 + + // Do some additional accounting if it's a large allocation. + if spanclass.sizeclass() == 0 { + mheap_.largealloc += uint64(npages * pageSize) + mheap_.nlargealloc++ + atomic.Xadd64(&memstats.heap_live, int64(npages*pageSize)) + } + + // Either heap_live or heap_scan could have been updated. + if gcBlackenEnabled != 0 { + gcController.revise() + } + } + unlock(&h.lock) + +HaveSpan: + // At this point, both s != nil and base != 0, and the heap + // lock is no longer held. Initialize the span. + s.init(base, npages) + if h.allocNeedsZero(base, npages) { + s.needzero = 1 + } + nbytes := npages * pageSize + if manual { + s.manualFreeList = 0 + s.nelems = 0 + s.limit = s.base() + s.npages*pageSize + // Manually managed memory doesn't count toward heap_sys. + mSysStatDec(&memstats.heap_sys, s.npages*pageSize) + s.state.set(mSpanManual) + } else { + // We must set span properties before the span is published anywhere + // since we're not holding the heap lock. + s.spanclass = spanclass + if sizeclass := spanclass.sizeclass(); sizeclass == 0 { + s.elemsize = nbytes + s.nelems = 1 + + s.divShift = 0 + s.divMul = 0 + s.divShift2 = 0 + s.baseMask = 0 + } else { + s.elemsize = uintptr(class_to_size[sizeclass]) + s.nelems = nbytes / s.elemsize + + m := &class_to_divmagic[sizeclass] + s.divShift = m.shift + s.divMul = m.mul + s.divShift2 = m.shift2 + s.baseMask = m.baseMask + } + + // Initialize mark and allocation structures. + s.freeindex = 0 + s.allocCache = ^uint64(0) // all 1s indicating all free. + s.gcmarkBits = newMarkBits(s.nelems) + s.allocBits = newAllocBits(s.nelems) + + // It's safe to access h.sweepgen without the heap lock because it's + // only ever updated with the world stopped and we run on the + // systemstack which blocks a STW transition. + atomic.Store(&s.sweepgen, h.sweepgen) + + // Now that the span is filled in, set its state. This + // is a publication barrier for the other fields in + // the span. While valid pointers into this span + // should never be visible until the span is returned, + // if the garbage collector finds an invalid pointer, + // access to the span may race with initialization of + // the span. We resolve this race by atomically + // setting the state after the span is fully + // initialized, and atomically checking the state in + // any situation where a pointer is suspect. + s.state.set(mSpanInUse) + } + + // Commit and account for any scavenged memory that the span now owns. + if scav != 0 { // sysUsed all the pages that are actually available - // in the span. Note that we don't need to decrement - // heap_released since we already did so earlier. - sysUsed(unsafe.Pointer(s.base()), s.npages<<_PageShift) - s.scavenged = false - - // Since we allocated out of a scavenged span, we just - // grew the RSS. Mitigate this by scavenging enough free - // space to make up for it but only if we need to. - // - // scavengeLocked may cause coalescing, so prevent - // coalescing with s by temporarily changing its state. - s.state = mSpanManual - h.scavengeIfNeededLocked(s.npages * pageSize) - s.state = mSpanFree + // in the span since some of them might be scavenged. + sysUsed(unsafe.Pointer(base), nbytes) + mSysStatDec(&memstats.heap_released, scav) } + // Update stats. + mSysStatInc(sysStat, nbytes) + mSysStatDec(&memstats.heap_idle, nbytes) - h.setSpans(s.base(), npage, s) + // Publish the span in various locations. - *stat += uint64(npage << _PageShift) - memstats.heap_idle -= uint64(npage << _PageShift) + // This is safe to call without the lock held because the slots + // related to this span will only every be read or modified by + // this thread until pointers into the span are published or + // pageInUse is updated. + h.setSpans(s.base(), npages, s) - if s.inList() { - throw("still in list") + if !manual { + // Add to swept in-use list. + // + // This publishes the span to root marking. + // + // h.sweepgen is guaranteed to only change during STW, + // and preemption is disabled in the page allocator. + h.sweepSpans[h.sweepgen/2%2].push(s) + + // Mark in-use span in arena page bitmap. + // + // This publishes the span to the page sweeper, so + // it's imperative that the span be completely initialized + // prior to this line. + arena, pageIdx, pageMask := pageIndexOf(s.base()) + atomic.Or8(&arena.pageInUse[pageIdx], pageMask) + + // Update related page sweeper stats. + atomic.Xadd64(&h.pagesInUse, int64(npages)) + + if trace.enabled { + // Trace that a heap alloc occurred. + traceHeapAlloc() + } } return s } @@ -1248,37 +1270,73 @@ HaveSpan: // // h must be locked. func (h *mheap) grow(npage uintptr) bool { - ask := npage << _PageShift - v, size := h.sysAlloc(ask) - if v == nil { - print("runtime: out of memory: cannot allocate ", ask, "-byte block (", memstats.heap_sys, " in use)\n") - return false - } + // We must grow the heap in whole palloc chunks. + ask := alignUp(npage, pallocChunkPages) * pageSize + + totalGrowth := uintptr(0) + nBase := alignUp(h.curArena.base+ask, physPageSize) + if nBase > h.curArena.end { + // Not enough room in the current arena. Allocate more + // arena space. This may not be contiguous with the + // current arena, so we have to request the full ask. + av, asize := h.sysAlloc(ask) + if av == nil { + print("runtime: out of memory: cannot allocate ", ask, "-byte block (", memstats.heap_sys, " in use)\n") + return false + } + + if uintptr(av) == h.curArena.end { + // The new space is contiguous with the old + // space, so just extend the current space. + h.curArena.end = uintptr(av) + asize + } else { + // The new space is discontiguous. Track what + // remains of the current space and switch to + // the new space. This should be rare. + if size := h.curArena.end - h.curArena.base; size != 0 { + h.pages.grow(h.curArena.base, size) + totalGrowth += size + } + // Switch to the new space. + h.curArena.base = uintptr(av) + h.curArena.end = uintptr(av) + asize + } - // Create a fake "in use" span and free it, so that the - // right accounting and coalescing happens. - s := (*mspan)(h.spanalloc.alloc()) - s.init(uintptr(v), size/pageSize) - h.setSpans(s.base(), s.npages, s) - s.state = mSpanFree - memstats.heap_idle += uint64(size) - // (*mheap).sysAlloc returns untouched/uncommitted memory. - s.scavenged = true - // s is always aligned to the heap arena size which is always > physPageSize, - // so its totally safe to just add directly to heap_released. Coalescing, - // if possible, will also always be correct in terms of accounting, because - // s.base() must be a physical page boundary. - memstats.heap_released += uint64(size) - h.coalesce(s) - h.free.insert(s) + // The memory just allocated counts as both released + // and idle, even though it's not yet backed by spans. + // + // The allocation is always aligned to the heap arena + // size which is always > physPageSize, so its safe to + // just add directly to heap_released. + mSysStatInc(&memstats.heap_released, asize) + mSysStatInc(&memstats.heap_idle, asize) + + // Recalculate nBase + nBase = alignUp(h.curArena.base+ask, physPageSize) + } + + // Grow into the current arena. + v := h.curArena.base + h.curArena.base = nBase + h.pages.grow(v, nBase-v) + totalGrowth += nBase - v + + // We just caused a heap growth, so scavenge down what will soon be used. + // By scavenging inline we deal with the failure to allocate out of + // memory fragments by scavenging the memory fragments that are least + // likely to be re-used. + if retained := heapRetained(); retained+uint64(totalGrowth) > h.scavengeGoal { + todo := totalGrowth + if overage := uintptr(retained + uint64(totalGrowth) - h.scavengeGoal); todo > overage { + todo = overage + } + h.pages.scavenge(todo, true) + } return true } // Free the span back into the heap. -// -// large must match the value of large passed to mheap.alloc. This is -// used for accounting. -func (h *mheap) freeSpan(s *mspan, large bool) { +func (h *mheap) freeSpan(s *mspan) { systemstack(func() { mp := getg().m lock(&h.lock) @@ -1292,10 +1350,6 @@ func (h *mheap) freeSpan(s *mspan, large bool) { bytes := s.npages << _PageShift msanfree(base, bytes) } - if large { - // Match accounting done in mheap.alloc. - memstats.heap_objects-- - } if gcBlackenEnabled != 0 { // heap_scan changed. gcController.revise() @@ -1319,14 +1373,14 @@ func (h *mheap) freeSpan(s *mspan, large bool) { func (h *mheap) freeManual(s *mspan, stat *uint64) { s.needzero = 1 lock(&h.lock) - *stat -= uint64(s.npages << _PageShift) - memstats.heap_sys += uint64(s.npages << _PageShift) + mSysStatDec(stat, s.npages*pageSize) + mSysStatInc(&memstats.heap_sys, s.npages*pageSize) h.freeSpanLocked(s, false, true) unlock(&h.lock) } func (h *mheap) freeSpanLocked(s *mspan, acctinuse, acctidle bool) { - switch s.state { + switch s.state.get() { case mSpanManual: if s.allocCount != 0 { throw("mheap.freeSpanLocked - invalid stack free") @@ -1336,140 +1390,28 @@ func (h *mheap) freeSpanLocked(s *mspan, acctinuse, acctidle bool) { print("mheap.freeSpanLocked - span ", s, " ptr ", hex(s.base()), " allocCount ", s.allocCount, " sweepgen ", s.sweepgen, "/", h.sweepgen, "\n") throw("mheap.freeSpanLocked - invalid free") } - h.pagesInUse -= uint64(s.npages) + atomic.Xadd64(&h.pagesInUse, -int64(s.npages)) // Clear in-use bit in arena page bitmap. arena, pageIdx, pageMask := pageIndexOf(s.base()) - arena.pageInUse[pageIdx] &^= pageMask + atomic.And8(&arena.pageInUse[pageIdx], ^pageMask) default: throw("mheap.freeSpanLocked - invalid span state") } if acctinuse { - memstats.heap_inuse -= uint64(s.npages << _PageShift) + mSysStatDec(&memstats.heap_inuse, s.npages*pageSize) } if acctidle { - memstats.heap_idle += uint64(s.npages << _PageShift) + mSysStatInc(&memstats.heap_idle, s.npages*pageSize) } - s.state = mSpanFree - - // Coalesce span with neighbors. - h.coalesce(s) - // Insert s into the treap. - h.free.insert(s) -} + // Mark the space as free. + h.pages.free(s.base(), s.npages) -// scavengeSplit takes t.span() and attempts to split off a span containing size -// (in bytes) worth of physical pages from the back. -// -// The split point is only approximately defined by size since the split point -// is aligned to physPageSize and pageSize every time. If physHugePageSize is -// non-zero and the split point would break apart a huge page in the span, then -// the split point is also aligned to physHugePageSize. -// -// If the desired split point ends up at the base of s, or if size is obviously -// much larger than s, then a split is not possible and this method returns nil. -// Otherwise if a split occurred it returns the newly-created span. -func (h *mheap) scavengeSplit(t treapIter, size uintptr) *mspan { - s := t.span() - start, end := s.physPageBounds() - if end <= start || end-start <= size { - // Size covers the whole span. - return nil - } - // The span is bigger than what we need, so compute the base for the new - // span if we decide to split. - base := end - size - // Round down to the next physical or logical page, whichever is bigger. - base &^= (physPageSize - 1) | (pageSize - 1) - if base <= start { - return nil - } - if physHugePageSize > pageSize && base&^(physHugePageSize-1) >= start { - // We're in danger of breaking apart a huge page, so include the entire - // huge page in the bound by rounding down to the huge page size. - // base should still be aligned to pageSize. - base &^= physHugePageSize - 1 - } - if base == start { - // After all that we rounded base down to s.base(), so no need to split. - return nil - } - if base < start { - print("runtime: base=", base, ", s.npages=", s.npages, ", s.base()=", s.base(), ", size=", size, "\n") - print("runtime: physPageSize=", physPageSize, ", physHugePageSize=", physHugePageSize, "\n") - throw("bad span split base") - } - - // Split s in-place, removing from the back. - n := (*mspan)(h.spanalloc.alloc()) - nbytes := s.base() + s.npages*pageSize - base - h.free.mutate(t, func(s *mspan) { - n.init(base, nbytes/pageSize) - s.npages -= nbytes / pageSize - h.setSpan(n.base()-1, s) - h.setSpan(n.base(), n) - h.setSpan(n.base()+nbytes-1, n) - n.needzero = s.needzero - n.state = s.state - }) - return n -} - -// scavengeLocked scavenges nbytes worth of spans in the free treap by -// starting from the span with the highest base address and working down. -// It then takes those spans and places them in scav. -// -// Returns the amount of memory scavenged in bytes. h must be locked. -func (h *mheap) scavengeLocked(nbytes uintptr) uintptr { - released := uintptr(0) - // Iterate over spans with huge pages first, then spans without. - const mask = treapIterScav | treapIterHuge - for _, match := range []treapIterType{treapIterHuge, 0} { - // Iterate over the treap backwards (from highest address to lowest address) - // scavenging spans until we've reached our quota of nbytes. - for t := h.free.end(mask, match); released < nbytes && t.valid(); { - s := t.span() - start, end := s.physPageBounds() - if start >= end { - // This span doesn't cover at least one physical page, so skip it. - t = t.prev() - continue - } - n := t.prev() - if span := h.scavengeSplit(t, nbytes-released); span != nil { - s = span - } else { - h.free.erase(t) - } - released += s.scavenge() - // Now that s is scavenged, we must eagerly coalesce it - // with its neighbors to prevent having two spans with - // the same scavenged state adjacent to each other. - h.coalesce(s) - t = n - h.free.insert(s) - } - } - return released -} - -// scavengeIfNeededLocked calls scavengeLocked if we're currently above the -// scavenge goal in order to prevent the mutator from out-running the -// the scavenger. -// -// h must be locked. -func (h *mheap) scavengeIfNeededLocked(size uintptr) { - if r := heapRetained(); r+uint64(size) > h.scavengeRetainedGoal { - todo := uint64(size) - // If we're only going to go a little bit over, just request what - // we actually need done. - if overage := r + uint64(size) - h.scavengeRetainedGoal; overage < todo { - todo = overage - } - h.scavengeLocked(uintptr(todo)) - } + // Free the span structure. We no longer have a use for it. + s.state.set(mSpanDead) + h.freeMSpanLocked(s) } // scavengeAll visits each node in the free treap and scavenges the @@ -1477,12 +1419,14 @@ func (h *mheap) scavengeIfNeededLocked(size uintptr) { // unscav and adds it into scav before continuing. func (h *mheap) scavengeAll() { // Disallow malloc or panic while holding the heap lock. We do - // this here because this is an non-mallocgc entry-point to + // this here because this is a non-mallocgc entry-point to // the mheap API. gp := getg() gp.m.mallocing++ lock(&h.lock) - released := h.scavengeLocked(^uintptr(0)) + // Reset the scavenger address so we have access to the whole heap. + h.pages.resetScavengeAddr() + released := h.pages.scavenge(^uintptr(0), true) unlock(&h.lock) gp.m.mallocing-- @@ -1511,14 +1455,13 @@ func (span *mspan) init(base uintptr, npages uintptr) { span.allocCount = 0 span.spanclass = 0 span.elemsize = 0 - span.state = mSpanDead - span.scavenged = false span.speciallock.key = 0 span.specials = nil span.needzero = 0 span.freeindex = 0 span.allocBits = nil span.gcmarkBits = nil + span.state.set(mSpanDead) } func (span *mspan) inList() bool { diff --git a/libgo/go/runtime/mkpreempt.go b/libgo/go/runtime/mkpreempt.go new file mode 100644 index 00000000000..615ec1868ca --- /dev/null +++ b/libgo/go/runtime/mkpreempt.go @@ -0,0 +1,522 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// mkpreempt generates the asyncPreempt functions for each +// architecture. +package main + +import ( + "flag" + "fmt" + "io" + "log" + "os" + "strings" +) + +// Copied from cmd/compile/internal/ssa/gen/*Ops.go + +var regNames386 = []string{ + "AX", + "CX", + "DX", + "BX", + "SP", + "BP", + "SI", + "DI", + "X0", + "X1", + "X2", + "X3", + "X4", + "X5", + "X6", + "X7", +} + +var regNamesAMD64 = []string{ + "AX", + "CX", + "DX", + "BX", + "SP", + "BP", + "SI", + "DI", + "R8", + "R9", + "R10", + "R11", + "R12", + "R13", + "R14", + "R15", + "X0", + "X1", + "X2", + "X3", + "X4", + "X5", + "X6", + "X7", + "X8", + "X9", + "X10", + "X11", + "X12", + "X13", + "X14", + "X15", +} + +var out io.Writer + +var arches = map[string]func(){ + "386": gen386, + "amd64": genAMD64, + "arm": genARM, + "arm64": genARM64, + "mips64x": func() { genMIPS(true) }, + "mipsx": func() { genMIPS(false) }, + "ppc64x": genPPC64, + "s390x": genS390X, + "wasm": genWasm, +} +var beLe = map[string]bool{"mips64x": true, "mipsx": true, "ppc64x": true} + +func main() { + flag.Parse() + if flag.NArg() > 0 { + out = os.Stdout + for _, arch := range flag.Args() { + gen, ok := arches[arch] + if !ok { + log.Fatalf("unknown arch %s", arch) + } + header(arch) + gen() + } + return + } + + for arch, gen := range arches { + f, err := os.Create(fmt.Sprintf("preempt_%s.s", arch)) + if err != nil { + log.Fatal(err) + } + out = f + header(arch) + gen() + if err := f.Close(); err != nil { + log.Fatal(err) + } + } +} + +func header(arch string) { + fmt.Fprintf(out, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n") + if beLe[arch] { + base := arch[:len(arch)-1] + fmt.Fprintf(out, "// +build %s %sle\n\n", base, base) + } + fmt.Fprintf(out, "#include \"go_asm.h\"\n") + fmt.Fprintf(out, "#include \"textflag.h\"\n\n") + fmt.Fprintf(out, "TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0\n") +} + +func p(f string, args ...interface{}) { + fmted := fmt.Sprintf(f, args...) + fmt.Fprintf(out, "\t%s\n", strings.Replace(fmted, "\n", "\n\t", -1)) +} + +func label(l string) { + fmt.Fprintf(out, "%s\n", l) +} + +type layout struct { + stack int + regs []regPos + sp string // stack pointer register +} + +type regPos struct { + pos int + + op string + reg string + + // If this register requires special save and restore, these + // give those operations with a %d placeholder for the stack + // offset. + save, restore string +} + +func (l *layout) add(op, reg string, size int) { + l.regs = append(l.regs, regPos{op: op, reg: reg, pos: l.stack}) + l.stack += size +} + +func (l *layout) addSpecial(save, restore string, size int) { + l.regs = append(l.regs, regPos{save: save, restore: restore, pos: l.stack}) + l.stack += size +} + +func (l *layout) save() { + for _, reg := range l.regs { + if reg.save != "" { + p(reg.save, reg.pos) + } else { + p("%s %s, %d(%s)", reg.op, reg.reg, reg.pos, l.sp) + } + } +} + +func (l *layout) restore() { + for i := len(l.regs) - 1; i >= 0; i-- { + reg := l.regs[i] + if reg.restore != "" { + p(reg.restore, reg.pos) + } else { + p("%s %d(%s), %s", reg.op, reg.pos, l.sp, reg.reg) + } + } +} + +func gen386() { + p("PUSHFL") + + // Save general purpose registers. + var l = layout{sp: "SP"} + for _, reg := range regNames386 { + if reg == "SP" || strings.HasPrefix(reg, "X") { + continue + } + l.add("MOVL", reg, 4) + } + + // Save the 387 state. + l.addSpecial( + "FSAVE %d(SP)\nFLDCW runtime·controlWord64(SB)", + "FRSTOR %d(SP)", + 108) + + // Save SSE state only if supported. + lSSE := layout{stack: l.stack, sp: "SP"} + for i := 0; i < 8; i++ { + lSSE.add("MOVUPS", fmt.Sprintf("X%d", i), 16) + } + + p("ADJSP $%d", lSSE.stack) + p("NOP SP") + l.save() + p("CMPB internal∕cpu·X86+const_offsetX86HasSSE2(SB), $1\nJNE nosse") + lSSE.save() + label("nosse:") + p("CALL ·asyncPreempt2(SB)") + p("CMPB internal∕cpu·X86+const_offsetX86HasSSE2(SB), $1\nJNE nosse2") + lSSE.restore() + label("nosse2:") + l.restore() + p("ADJSP $%d", -lSSE.stack) + + p("POPFL") + p("RET") +} + +func genAMD64() { + // Assign stack offsets. + var l = layout{sp: "SP"} + for _, reg := range regNamesAMD64 { + if reg == "SP" || reg == "BP" { + continue + } + if strings.HasPrefix(reg, "X") { + l.add("MOVUPS", reg, 16) + } else { + l.add("MOVQ", reg, 8) + } + } + + // TODO: MXCSR register? + + p("PUSHQ BP") + p("MOVQ SP, BP") + p("// Save flags before clobbering them") + p("PUSHFQ") + p("// obj doesn't understand ADD/SUB on SP, but does understand ADJSP") + p("ADJSP $%d", l.stack) + p("// But vet doesn't know ADJSP, so suppress vet stack checking") + p("NOP SP") + l.save() + p("CALL ·asyncPreempt2(SB)") + l.restore() + p("ADJSP $%d", -l.stack) + p("POPFQ") + p("POPQ BP") + p("RET") +} + +func genARM() { + // Add integer registers R0-R12. + // R13 (SP), R14 (LR), R15 (PC) are special and not saved here. + var l = layout{sp: "R13", stack: 4} // add LR slot + for i := 0; i <= 12; i++ { + reg := fmt.Sprintf("R%d", i) + if i == 10 { + continue // R10 is g register, no need to save/restore + } + l.add("MOVW", reg, 4) + } + // Add flag register. + l.addSpecial( + "MOVW CPSR, R0\nMOVW R0, %d(R13)", + "MOVW %d(R13), R0\nMOVW R0, CPSR", + 4) + + // Add floating point registers F0-F15 and flag register. + var lfp = layout{stack: l.stack, sp: "R13"} + lfp.addSpecial( + "MOVW FPCR, R0\nMOVW R0, %d(R13)", + "MOVW %d(R13), R0\nMOVW R0, FPCR", + 4) + for i := 0; i <= 15; i++ { + reg := fmt.Sprintf("F%d", i) + lfp.add("MOVD", reg, 8) + } + + p("MOVW.W R14, -%d(R13)", lfp.stack) // allocate frame, save LR + l.save() + p("MOVB ·goarm(SB), R0\nCMP $6, R0\nBLT nofp") // test goarm, and skip FP registers if goarm=5. + lfp.save() + label("nofp:") + p("CALL ·asyncPreempt2(SB)") + p("MOVB ·goarm(SB), R0\nCMP $6, R0\nBLT nofp2") // test goarm, and skip FP registers if goarm=5. + lfp.restore() + label("nofp2:") + l.restore() + + p("MOVW %d(R13), R14", lfp.stack) // sigctxt.pushCall pushes LR on stack, restore it + p("MOVW.P %d(R13), R15", lfp.stack+4) // load PC, pop frame (including the space pushed by sigctxt.pushCall) + p("UNDEF") // shouldn't get here +} + +func genARM64() { + // Add integer registers R0-R26 + // R27 (REGTMP), R28 (g), R29 (FP), R30 (LR), R31 (SP) are special + // and not saved here. + var l = layout{sp: "RSP", stack: 8} // add slot to save PC of interrupted instruction + for i := 0; i <= 26; i++ { + if i == 18 { + continue // R18 is not used, skip + } + reg := fmt.Sprintf("R%d", i) + l.add("MOVD", reg, 8) + } + // Add flag registers. + l.addSpecial( + "MOVD NZCV, R0\nMOVD R0, %d(RSP)", + "MOVD %d(RSP), R0\nMOVD R0, NZCV", + 8) + l.addSpecial( + "MOVD FPSR, R0\nMOVD R0, %d(RSP)", + "MOVD %d(RSP), R0\nMOVD R0, FPSR", + 8) + // TODO: FPCR? I don't think we'll change it, so no need to save. + // Add floating point registers F0-F31. + for i := 0; i <= 31; i++ { + reg := fmt.Sprintf("F%d", i) + l.add("FMOVD", reg, 8) + } + if l.stack%16 != 0 { + l.stack += 8 // SP needs 16-byte alignment + } + + // allocate frame, save PC of interrupted instruction (in LR) + p("MOVD R30, %d(RSP)", -l.stack) + p("SUB $%d, RSP", l.stack) + p("#ifdef GOOS_linux") + p("MOVD R29, -8(RSP)") // save frame pointer (only used on Linux) + p("SUB $8, RSP, R29") // set up new frame pointer + p("#endif") + // On darwin, save the LR again after decrementing SP. We run the + // signal handler on the G stack (as it doesn't support SA_ONSTACK), + // so any writes below SP may be clobbered. + p("#ifdef GOOS_darwin") + p("MOVD R30, (RSP)") + p("#endif") + + l.save() + p("CALL ·asyncPreempt2(SB)") + l.restore() + + p("MOVD %d(RSP), R30", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it + p("#ifdef GOOS_linux") + p("MOVD -8(RSP), R29") // restore frame pointer + p("#endif") + p("MOVD (RSP), R27") // load PC to REGTMP + p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall) + p("JMP (R27)") +} + +func genMIPS(_64bit bool) { + mov := "MOVW" + movf := "MOVF" + add := "ADD" + sub := "SUB" + r28 := "R28" + regsize := 4 + if _64bit { + mov = "MOVV" + movf = "MOVD" + add = "ADDV" + sub = "SUBV" + r28 = "RSB" + regsize = 8 + } + + // Add integer registers R1-R22, R24-R25, R28 + // R0 (zero), R23 (REGTMP), R29 (SP), R30 (g), R31 (LR) are special, + // and not saved here. R26 and R27 are reserved by kernel and not used. + var l = layout{sp: "R29", stack: regsize} // add slot to save PC of interrupted instruction (in LR) + for i := 1; i <= 25; i++ { + if i == 23 { + continue // R23 is REGTMP + } + reg := fmt.Sprintf("R%d", i) + l.add(mov, reg, regsize) + } + l.add(mov, r28, regsize) + l.addSpecial( + mov+" HI, R1\n"+mov+" R1, %d(R29)", + mov+" %d(R29), R1\n"+mov+" R1, HI", + regsize) + l.addSpecial( + mov+" LO, R1\n"+mov+" R1, %d(R29)", + mov+" %d(R29), R1\n"+mov+" R1, LO", + regsize) + // Add floating point control/status register FCR31 (FCR0-FCR30 are irrelevant) + l.addSpecial( + mov+" FCR31, R1\n"+mov+" R1, %d(R29)", + mov+" %d(R29), R1\n"+mov+" R1, FCR31", + regsize) + // Add floating point registers F0-F31. + for i := 0; i <= 31; i++ { + reg := fmt.Sprintf("F%d", i) + l.add(movf, reg, regsize) + } + + // allocate frame, save PC of interrupted instruction (in LR) + p(mov+" R31, -%d(R29)", l.stack) + p(sub+" $%d, R29", l.stack) + + l.save() + p("CALL ·asyncPreempt2(SB)") + l.restore() + + p(mov+" %d(R29), R31", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it + p(mov + " (R29), R23") // load PC to REGTMP + p(add+" $%d, R29", l.stack+regsize) // pop frame (including the space pushed by sigctxt.pushCall) + p("JMP (R23)") +} + +func genPPC64() { + // Add integer registers R3-R29 + // R0 (zero), R1 (SP), R30 (g) are special and not saved here. + // R2 (TOC pointer in PIC mode), R12 (function entry address in PIC mode) have been saved in sigctxt.pushCall. + // R31 (REGTMP) will be saved manually. + var l = layout{sp: "R1", stack: 32 + 8} // MinFrameSize on PPC64, plus one word for saving R31 + for i := 3; i <= 29; i++ { + if i == 12 || i == 13 { + // R12 has been saved in sigctxt.pushCall. + // R13 is TLS pointer, not used by Go code. we must NOT + // restore it, otherwise if we parked and resumed on a + // different thread we'll mess up TLS addresses. + continue + } + reg := fmt.Sprintf("R%d", i) + l.add("MOVD", reg, 8) + } + l.addSpecial( + "MOVW CR, R31\nMOVW R31, %d(R1)", + "MOVW %d(R1), R31\nMOVFL R31, $0xff", // this is MOVW R31, CR + 8) // CR is 4-byte wide, but just keep the alignment + l.addSpecial( + "MOVD XER, R31\nMOVD R31, %d(R1)", + "MOVD %d(R1), R31\nMOVD R31, XER", + 8) + // Add floating point registers F0-F31. + for i := 0; i <= 31; i++ { + reg := fmt.Sprintf("F%d", i) + l.add("FMOVD", reg, 8) + } + // Add floating point control/status register FPSCR. + l.addSpecial( + "MOVFL FPSCR, F0\nFMOVD F0, %d(R1)", + "FMOVD %d(R1), F0\nMOVFL F0, FPSCR", + 8) + + p("MOVD R31, -%d(R1)", l.stack-32) // save R31 first, we'll use R31 for saving LR + p("MOVD LR, R31") + p("MOVDU R31, -%d(R1)", l.stack) // allocate frame, save PC of interrupted instruction (in LR) + + l.save() + p("CALL ·asyncPreempt2(SB)") + l.restore() + + p("MOVD %d(R1), R31", l.stack) // sigctxt.pushCall has pushed LR, R2, R12 (at interrupt) on stack, restore them + p("MOVD R31, LR") + p("MOVD %d(R1), R2", l.stack+8) + p("MOVD %d(R1), R12", l.stack+16) + p("MOVD (R1), R31") // load PC to CTR + p("MOVD R31, CTR") + p("MOVD 32(R1), R31") // restore R31 + p("ADD $%d, R1", l.stack+32) // pop frame (including the space pushed by sigctxt.pushCall) + p("JMP (CTR)") +} + +func genS390X() { + // Add integer registers R0-R12 + // R13 (g), R14 (LR), R15 (SP) are special, and not saved here. + // Saving R10 (REGTMP) is not necessary, but it is saved anyway. + var l = layout{sp: "R15", stack: 16} // add slot to save PC of interrupted instruction and flags + l.addSpecial( + "STMG R0, R12, %d(R15)", + "LMG %d(R15), R0, R12", + 13*8) + // Add floating point registers F0-F31. + for i := 0; i <= 15; i++ { + reg := fmt.Sprintf("F%d", i) + l.add("FMOVD", reg, 8) + } + + // allocate frame, save PC of interrupted instruction (in LR) and flags (condition code) + p("IPM R10") // save flags upfront, as ADD will clobber flags + p("MOVD R14, -%d(R15)", l.stack) + p("ADD $-%d, R15", l.stack) + p("MOVW R10, 8(R15)") // save flags + + l.save() + p("CALL ·asyncPreempt2(SB)") + l.restore() + + p("MOVD %d(R15), R14", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it + p("ADD $%d, R15", l.stack+8) // pop frame (including the space pushed by sigctxt.pushCall) + p("MOVWZ -%d(R15), R10", l.stack) // load flags to REGTMP + p("TMLH R10, $(3<<12)") // restore flags + p("MOVD -%d(R15), R10", l.stack+8) // load PC to REGTMP + p("JMP (R10)") +} + +func genWasm() { + p("// No async preemption on wasm") + p("UNDEF") +} + +func notImplemented() { + p("// Not implemented yet") + p("JMP ·abort(SB)") +} diff --git a/libgo/go/runtime/mpagealloc.go b/libgo/go/runtime/mpagealloc.go new file mode 100644 index 00000000000..572e6a9bc5b --- /dev/null +++ b/libgo/go/runtime/mpagealloc.go @@ -0,0 +1,938 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Page allocator. +// +// The page allocator manages mapped pages (defined by pageSize, NOT +// physPageSize) for allocation and re-use. It is embedded into mheap. +// +// Pages are managed using a bitmap that is sharded into chunks. +// In the bitmap, 1 means in-use, and 0 means free. The bitmap spans the +// process's address space. Chunks are managed in a sparse-array-style structure +// similar to mheap.arenas, since the bitmap may be large on some systems. +// +// The bitmap is efficiently searched by using a radix tree in combination +// with fast bit-wise intrinsics. Allocation is performed using an address-ordered +// first-fit approach. +// +// Each entry in the radix tree is a summary that describes three properties of +// a particular region of the address space: the number of contiguous free pages +// at the start and end of the region it represents, and the maximum number of +// contiguous free pages found anywhere in that region. +// +// Each level of the radix tree is stored as one contiguous array, which represents +// a different granularity of subdivision of the processes' address space. Thus, this +// radix tree is actually implicit in these large arrays, as opposed to having explicit +// dynamically-allocated pointer-based node structures. Naturally, these arrays may be +// quite large for system with large address spaces, so in these cases they are mapped +// into memory as needed. The leaf summaries of the tree correspond to a bitmap chunk. +// +// The root level (referred to as L0 and index 0 in pageAlloc.summary) has each +// summary represent the largest section of address space (16 GiB on 64-bit systems), +// with each subsequent level representing successively smaller subsections until we +// reach the finest granularity at the leaves, a chunk. +// +// More specifically, each summary in each level (except for leaf summaries) +// represents some number of entries in the following level. For example, each +// summary in the root level may represent a 16 GiB region of address space, +// and in the next level there could be 8 corresponding entries which represent 2 +// GiB subsections of that 16 GiB region, each of which could correspond to 8 +// entries in the next level which each represent 256 MiB regions, and so on. +// +// Thus, this design only scales to heaps so large, but can always be extended to +// larger heaps by simply adding levels to the radix tree, which mostly costs +// additional virtual address space. The choice of managing large arrays also means +// that a large amount of virtual address space may be reserved by the runtime. + +package runtime + +import ( + "runtime/internal/atomic" + "unsafe" +) + +const ( + // The size of a bitmap chunk, i.e. the amount of bits (that is, pages) to consider + // in the bitmap at once. + pallocChunkPages = 1 << logPallocChunkPages + pallocChunkBytes = pallocChunkPages * pageSize + logPallocChunkPages = 9 + logPallocChunkBytes = logPallocChunkPages + pageShift + + // The number of radix bits for each level. + // + // The value of 3 is chosen such that the block of summaries we need to scan at + // each level fits in 64 bytes (2^3 summaries * 8 bytes per summary), which is + // close to the L1 cache line width on many systems. Also, a value of 3 fits 4 tree + // levels perfectly into the 21-bit pallocBits summary field at the root level. + // + // The following equation explains how each of the constants relate: + // summaryL0Bits + (summaryLevels-1)*summaryLevelBits + logPallocChunkBytes = heapAddrBits + // + // summaryLevels is an architecture-dependent value defined in mpagealloc_*.go. + summaryLevelBits = 3 + summaryL0Bits = heapAddrBits - logPallocChunkBytes - (summaryLevels-1)*summaryLevelBits + + // pallocChunksL2Bits is the number of bits of the chunk index number + // covered by the second level of the chunks map. + // + // See (*pageAlloc).chunks for more details. Update the documentation + // there should this change. + pallocChunksL2Bits = heapAddrBits - logPallocChunkBytes - pallocChunksL1Bits + pallocChunksL1Shift = pallocChunksL2Bits + + // Maximum searchAddr value, which indicates that the heap has no free space. + // + // We subtract arenaBaseOffset because we want this to represent the maximum + // value in the shifted address space, but searchAddr is stored as a regular + // memory address. See arenaBaseOffset for details. + maxSearchAddr = ^uintptr(0) - arenaBaseOffset + + // Minimum scavAddr value, which indicates that the scavenger is done. + // + // minScavAddr + arenaBaseOffset == 0 + minScavAddr = (^arenaBaseOffset + 1) & uintptrMask +) + +// Global chunk index. +// +// Represents an index into the leaf level of the radix tree. +// Similar to arenaIndex, except instead of arenas, it divides the address +// space into chunks. +type chunkIdx uint + +// chunkIndex returns the global index of the palloc chunk containing the +// pointer p. +func chunkIndex(p uintptr) chunkIdx { + return chunkIdx((p + arenaBaseOffset) / pallocChunkBytes) +} + +// chunkIndex returns the base address of the palloc chunk at index ci. +func chunkBase(ci chunkIdx) uintptr { + return uintptr(ci)*pallocChunkBytes - arenaBaseOffset +} + +// chunkPageIndex computes the index of the page that contains p, +// relative to the chunk which contains p. +func chunkPageIndex(p uintptr) uint { + return uint(p % pallocChunkBytes / pageSize) +} + +// l1 returns the index into the first level of (*pageAlloc).chunks. +func (i chunkIdx) l1() uint { + if pallocChunksL1Bits == 0 { + // Let the compiler optimize this away if there's no + // L1 map. + return 0 + } else { + return uint(i) >> pallocChunksL1Shift + } +} + +// l2 returns the index into the second level of (*pageAlloc).chunks. +func (i chunkIdx) l2() uint { + if pallocChunksL1Bits == 0 { + return uint(i) + } else { + return uint(i) & (1<> levelShift[level]) + hi = int(((limit-1)+arenaBaseOffset)>>levelShift[level]) + 1 + return +} + +// blockAlignSummaryRange aligns indices into the given level to that +// level's block width (1 << levelBits[level]). It assumes lo is inclusive +// and hi is exclusive, and so aligns them down and up respectively. +func blockAlignSummaryRange(level int, lo, hi int) (int, int) { + e := uintptr(1) << levelBits[level] + return int(alignDown(uintptr(lo), e)), int(alignUp(uintptr(hi), e)) +} + +type pageAlloc struct { + // Radix tree of summaries. + // + // Each slice's cap represents the whole memory reservation. + // Each slice's len reflects the allocator's maximum known + // mapped heap address for that level. + // + // The backing store of each summary level is reserved in init + // and may or may not be committed in grow (small address spaces + // may commit all the memory in init). + // + // The purpose of keeping len <= cap is to enforce bounds checks + // on the top end of the slice so that instead of an unknown + // runtime segmentation fault, we get a much friendlier out-of-bounds + // error. + // + // To iterate over a summary level, use inUse to determine which ranges + // are currently available. Otherwise one might try to access + // memory which is only Reserved which may result in a hard fault. + // + // We may still get segmentation faults < len since some of that + // memory may not be committed yet. + summary [summaryLevels][]pallocSum + + // chunks is a slice of bitmap chunks. + // + // The total size of chunks is quite large on most 64-bit platforms + // (O(GiB) or more) if flattened, so rather than making one large mapping + // (which has problems on some platforms, even when PROT_NONE) we use a + // two-level sparse array approach similar to the arena index in mheap. + // + // To find the chunk containing a memory address `a`, do: + // chunkOf(chunkIndex(a)) + // + // Below is a table describing the configuration for chunks for various + // heapAddrBits supported by the runtime. + // + // heapAddrBits | L1 Bits | L2 Bits | L2 Entry Size + // ------------------------------------------------ + // 32 | 0 | 10 | 128 KiB + // 33 (iOS) | 0 | 11 | 256 KiB + // 48 | 13 | 13 | 1 MiB + // + // There's no reason to use the L1 part of chunks on 32-bit, the + // address space is small so the L2 is small. For platforms with a + // 48-bit address space, we pick the L1 such that the L2 is 1 MiB + // in size, which is a good balance between low granularity without + // making the impact on BSS too high (note the L1 is stored directly + // in pageAlloc). + // + // To iterate over the bitmap, use inUse to determine which ranges + // are currently available. Otherwise one might iterate over unused + // ranges. + // + // TODO(mknyszek): Consider changing the definition of the bitmap + // such that 1 means free and 0 means in-use so that summaries and + // the bitmaps align better on zero-values. + chunks [1 << pallocChunksL1Bits]*[1 << pallocChunksL2Bits]pallocData + + // The address to start an allocation search with. + // + // When added with arenaBaseOffset, we guarantee that + // all valid heap addresses (when also added with + // arenaBaseOffset) below this value are allocated and + // not worth searching. + // + // Note that adding in arenaBaseOffset transforms addresses + // to a new address space with a linear view of the full address + // space on architectures with segmented address spaces. + searchAddr uintptr + + // The address to start a scavenge candidate search with. + scavAddr uintptr + + // start and end represent the chunk indices + // which pageAlloc knows about. It assumes + // chunks in the range [start, end) are + // currently ready to use. + start, end chunkIdx + + // inUse is a slice of ranges of address space which are + // known by the page allocator to be currently in-use (passed + // to grow). + // + // This field is currently unused on 32-bit architectures but + // is harmless to track. We care much more about having a + // contiguous heap in these cases and take additional measures + // to ensure that, so in nearly all cases this should have just + // 1 element. + // + // All access is protected by the mheapLock. + inUse addrRanges + + // mheap_.lock. This level of indirection makes it possible + // to test pageAlloc indepedently of the runtime allocator. + mheapLock *mutex + + // sysStat is the runtime memstat to update when new system + // memory is committed by the pageAlloc for allocation metadata. + sysStat *uint64 + + // Whether or not this struct is being used in tests. + test bool +} + +func (s *pageAlloc) init(mheapLock *mutex, sysStat *uint64) { + if levelLogPages[0] > logMaxPackedValue { + // We can't represent 1< 0 if addr is greater than s.searchAddr in the linearized address space. +// Returns 0 if addr and s.searchAddr are equal. +func (s *pageAlloc) compareSearchAddrTo(addr uintptr) int { + // Compare with arenaBaseOffset added because it gives us a linear, contiguous view + // of the heap on architectures with signed address spaces. + lAddr := addr + arenaBaseOffset + lSearchAddr := s.searchAddr + arenaBaseOffset + if lAddr < lSearchAddr { + return -1 + } else if lAddr > lSearchAddr { + return 1 + } + return 0 +} + +// chunkOf returns the chunk at the given chunk index. +func (s *pageAlloc) chunkOf(ci chunkIdx) *pallocData { + return &s.chunks[ci.l1()][ci.l2()] +} + +// grow sets up the metadata for the address range [base, base+size). +// It may allocate metadata, in which case *s.sysStat will be updated. +// +// s.mheapLock must be held. +func (s *pageAlloc) grow(base, size uintptr) { + // Round up to chunks, since we can't deal with increments smaller + // than chunks. Also, sysGrow expects aligned values. + limit := alignUp(base+size, pallocChunkBytes) + base = alignDown(base, pallocChunkBytes) + + // Grow the summary levels in a system-dependent manner. + // We just update a bunch of additional metadata here. + s.sysGrow(base, limit) + + // Update s.start and s.end. + // If no growth happened yet, start == 0. This is generally + // safe since the zero page is unmapped. + firstGrowth := s.start == 0 + start, end := chunkIndex(base), chunkIndex(limit) + if firstGrowth || start < s.start { + s.start = start + } + if end > s.end { + s.end = end + } + // Note that [base, limit) will never overlap with any existing + // range inUse because grow only ever adds never-used memory + // regions to the page allocator. + s.inUse.add(addrRange{base, limit}) + + // A grow operation is a lot like a free operation, so if our + // chunk ends up below the (linearized) s.searchAddr, update + // s.searchAddr to the new address, just like in free. + if s.compareSearchAddrTo(base) < 0 { + s.searchAddr = base + } + + // Add entries into chunks, which is sparse, if needed. Then, + // initialize the bitmap. + // + // Newly-grown memory is always considered scavenged. + // Set all the bits in the scavenged bitmaps high. + for c := chunkIndex(base); c < chunkIndex(limit); c++ { + if s.chunks[c.l1()] == nil { + // Create the necessary l2 entry. + // + // Store it atomically to avoid races with readers which + // don't acquire the heap lock. + r := sysAlloc(unsafe.Sizeof(*s.chunks[0]), s.sysStat) + atomic.StorepNoWB(unsafe.Pointer(&s.chunks[c.l1()]), r) + } + s.chunkOf(c).scavenged.setRange(0, pallocChunkPages) + } + + // Update summaries accordingly. The grow acts like a free, so + // we need to ensure this newly-free memory is visible in the + // summaries. + s.update(base, size/pageSize, true, false) +} + +// update updates heap metadata. It must be called each time the bitmap +// is updated. +// +// If contig is true, update does some optimizations assuming that there was +// a contiguous allocation or free between addr and addr+npages. alloc indicates +// whether the operation performed was an allocation or a free. +// +// s.mheapLock must be held. +func (s *pageAlloc) update(base, npages uintptr, contig, alloc bool) { + // base, limit, start, and end are inclusive. + limit := base + npages*pageSize - 1 + sc, ec := chunkIndex(base), chunkIndex(limit) + + // Handle updating the lowest level first. + if sc == ec { + // Fast path: the allocation doesn't span more than one chunk, + // so update this one and if the summary didn't change, return. + x := s.summary[len(s.summary)-1][sc] + y := s.chunkOf(sc).summarize() + if x == y { + return + } + s.summary[len(s.summary)-1][sc] = y + } else if contig { + // Slow contiguous path: the allocation spans more than one chunk + // and at least one summary is guaranteed to change. + summary := s.summary[len(s.summary)-1] + + // Update the summary for chunk sc. + summary[sc] = s.chunkOf(sc).summarize() + + // Update the summaries for chunks in between, which are + // either totally allocated or freed. + whole := s.summary[len(s.summary)-1][sc+1 : ec] + if alloc { + // Should optimize into a memclr. + for i := range whole { + whole[i] = 0 + } + } else { + for i := range whole { + whole[i] = freeChunkSum + } + } + + // Update the summary for chunk ec. + summary[ec] = s.chunkOf(ec).summarize() + } else { + // Slow general path: the allocation spans more than one chunk + // and at least one summary is guaranteed to change. + // + // We can't assume a contiguous allocation happened, so walk over + // every chunk in the range and manually recompute the summary. + summary := s.summary[len(s.summary)-1] + for c := sc; c <= ec; c++ { + summary[c] = s.chunkOf(c).summarize() + } + } + + // Walk up the radix tree and update the summaries appropriately. + changed := true + for l := len(s.summary) - 2; l >= 0 && changed; l-- { + // Update summaries at level l from summaries at level l+1. + changed = false + + // "Constants" for the previous level which we + // need to compute the summary from that level. + logEntriesPerBlock := levelBits[l+1] + logMaxPages := levelLogPages[l+1] + + // lo and hi describe all the parts of the level we need to look at. + lo, hi := addrsToSummaryRange(l, base, limit+1) + + // Iterate over each block, updating the corresponding summary in the less-granular level. + for i := lo; i < hi; i++ { + children := s.summary[l+1][i< firstFree.bound) { + // This range only partially overlaps with the firstFree range, + // so throw. + print("runtime: addr = ", hex(addr), ", size = ", size, "\n") + print("runtime: base = ", hex(firstFree.base), ", bound = ", hex(firstFree.bound), "\n") + throw("range partially overlaps") + } + } + + // lastSum is the summary which we saw on the previous level that made us + // move on to the next level. Used to print additional information in the + // case of a catastrophic failure. + // lastSumIdx is that summary's index in the previous level. + lastSum := packPallocSum(0, 0, 0) + lastSumIdx := -1 + +nextLevel: + for l := 0; l < len(s.summary); l++ { + // For the root level, entriesPerBlock is the whole level. + entriesPerBlock := 1 << levelBits[l] + logMaxPages := levelLogPages[l] + + // We've moved into a new level, so let's update i to our new + // starting index. This is a no-op for level 0. + i <<= levelBits[l] + + // Slice out the block of entries we care about. + entries := s.summary[l][i : i+entriesPerBlock] + + // Determine j0, the first index we should start iterating from. + // The searchAddr may help us eliminate iterations if we followed the + // searchAddr on the previous level or we're on the root leve, in which + // case the searchAddr should be the same as i after levelShift. + j0 := 0 + if searchIdx := int((s.searchAddr + arenaBaseOffset) >> levelShift[l]); searchIdx&^(entriesPerBlock-1) == i { + j0 = searchIdx & (entriesPerBlock - 1) + } + + // Run over the level entries looking for + // a contiguous run of at least npages either + // within an entry or across entries. + // + // base contains the page index (relative to + // the first entry's first page) of the currently + // considered run of consecutive pages. + // + // size contains the size of the currently considered + // run of consecutive pages. + var base, size uint + for j := j0; j < len(entries); j++ { + sum := entries[j] + if sum == 0 { + // A full entry means we broke any streak and + // that we should skip it altogether. + size = 0 + continue + } + + // We've encountered a non-zero summary which means + // free memory, so update firstFree. + foundFree(uintptr((i+j)<= uint(npages) { + // If size == 0 we don't have a run yet, + // which means base isn't valid. So, set + // base to the first page in this block. + if size == 0 { + base = uint(j) << logMaxPages + } + // We hit npages; we're done! + size += s + break + } + if sum.max() >= uint(npages) { + // The entry itself contains npages contiguous + // free pages, so continue on the next level + // to find that run. + i += j + lastSumIdx = i + lastSum = sum + continue nextLevel + } + if size == 0 || s < 1<= uint(npages) { + // We found a sufficiently large run of free pages straddling + // some boundary, so compute the address and return it. + addr := uintptr(i<= s.end { + return 0, 0 + } + + // If npages has a chance of fitting in the chunk where the searchAddr is, + // search it directly. + searchAddr := uintptr(0) + if pallocChunkPages-chunkPageIndex(s.searchAddr) >= uint(npages) { + // npages is guaranteed to be no greater than pallocChunkPages here. + i := chunkIndex(s.searchAddr) + if max := s.summary[len(s.summary)-1][i].max(); max >= uint(npages) { + j, searchIdx := s.chunkOf(i).find(npages, chunkPageIndex(s.searchAddr)) + if j < 0 { + print("runtime: max = ", max, ", npages = ", npages, "\n") + print("runtime: searchIdx = ", chunkPageIndex(s.searchAddr), ", s.searchAddr = ", hex(s.searchAddr), "\n") + throw("bad summary data") + } + addr = chunkBase(i) + uintptr(j)*pageSize + searchAddr = chunkBase(i) + uintptr(searchIdx)*pageSize + goto Found + } + } + // We failed to use a searchAddr for one reason or another, so try + // the slow path. + addr, searchAddr = s.find(npages) + if addr == 0 { + if npages == 1 { + // We failed to find a single free page, the smallest unit + // of allocation. This means we know the heap is completely + // exhausted. Otherwise, the heap still might have free + // space in it, just not enough contiguous space to + // accommodate npages. + s.searchAddr = maxSearchAddr + } + return 0, 0 + } +Found: + // Go ahead and actually mark the bits now that we have an address. + scav = s.allocRange(addr, npages) + + // If we found a higher (linearized) searchAddr, we know that all the + // heap memory before that searchAddr in a linear address space is + // allocated, so bump s.searchAddr up to the new one. + if s.compareSearchAddrTo(searchAddr) > 0 { + s.searchAddr = searchAddr + } + return addr, scav +} + +// free returns npages worth of memory starting at base back to the page heap. +// +// s.mheapLock must be held. +func (s *pageAlloc) free(base, npages uintptr) { + // If we're freeing pages below the (linearized) s.searchAddr, update searchAddr. + if s.compareSearchAddrTo(base) < 0 { + s.searchAddr = base + } + if npages == 1 { + // Fast path: we're clearing a single bit, and we know exactly + // where it is, so mark it directly. + i := chunkIndex(base) + s.chunkOf(i).free1(chunkPageIndex(base)) + } else { + // Slow path: we're clearing more bits so we may need to iterate. + limit := base + npages*pageSize - 1 + sc, ec := chunkIndex(base), chunkIndex(limit) + si, ei := chunkPageIndex(base), chunkPageIndex(limit) + + if sc == ec { + // The range doesn't cross any chunk boundaries. + s.chunkOf(sc).free(si, ei+1-si) + } else { + // The range crosses at least one chunk boundary. + s.chunkOf(sc).free(si, pallocChunkPages-si) + for c := sc + 1; c < ec; c++ { + s.chunkOf(c).freeAll() + } + s.chunkOf(ec).free(0, ei+1) + } + } + s.update(base, npages, true, false) +} + +const ( + pallocSumBytes = unsafe.Sizeof(pallocSum(0)) + + // maxPackedValue is the maximum value that any of the three fields in + // the pallocSum may take on. + maxPackedValue = 1 << logMaxPackedValue + logMaxPackedValue = logPallocChunkPages + (summaryLevels-1)*summaryLevelBits + + freeChunkSum = pallocSum(uint64(pallocChunkPages) | + uint64(pallocChunkPages<> logMaxPackedValue) & (maxPackedValue - 1)) +} + +// end extracts the end value from a packed sum. +func (p pallocSum) end() uint { + if uint64(p)&uint64(1<<63) != 0 { + return maxPackedValue + } + return uint((uint64(p) >> (2 * logMaxPackedValue)) & (maxPackedValue - 1)) +} + +// unpack unpacks all three values from the summary. +func (p pallocSum) unpack() (uint, uint, uint) { + if uint64(p)&uint64(1<<63) != 0 { + return maxPackedValue, maxPackedValue, maxPackedValue + } + return uint(uint64(p) & (maxPackedValue - 1)), + uint((uint64(p) >> logMaxPackedValue) & (maxPackedValue - 1)), + uint((uint64(p) >> (2 * logMaxPackedValue)) & (maxPackedValue - 1)) +} + +// mergeSummaries merges consecutive summaries which may each represent at +// most 1 << logMaxPagesPerSum pages each together into one. +func mergeSummaries(sums []pallocSum, logMaxPagesPerSum uint) pallocSum { + // Merge the summaries in sums into one. + // + // We do this by keeping a running summary representing the merged + // summaries of sums[:i] in start, max, and end. + start, max, end := sums[0].unpack() + for i := 1; i < len(sums); i++ { + // Merge in sums[i]. + si, mi, ei := sums[i].unpack() + + // Merge in sums[i].start only if the running summary is + // completely free, otherwise this summary's start + // plays no role in the combined sum. + if start == uint(i)< max { + max = end + si + } + if mi > max { + max = mi + } + + // Merge in end by checking if this new summary is totally + // free. If it is, then we want to extend the running sum's + // end by the new summary. If not, then we have some alloc'd + // pages in there and we just want to take the end value in + // sums[i]. + if ei == 1<= 0; l-- { + // Figure out what part of the summary array this new address space needs. + // Note that we need to align the ranges to the block width (1< len(s.summary[l]) { + s.summary[l] = s.summary[l][:hi] + } + } +} diff --git a/libgo/go/runtime/mpagealloc_64bit.go b/libgo/go/runtime/mpagealloc_64bit.go new file mode 100644 index 00000000000..dd44da1199e --- /dev/null +++ b/libgo/go/runtime/mpagealloc_64bit.go @@ -0,0 +1,180 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build amd64 !darwin,arm64 mips64 mips64le ppc64 ppc64le s390x arm64be alpha sparc64 ia64 riscv64 + +// See mpagealloc_32bit.go for why darwin/arm64 is excluded here. + +package runtime + +import "unsafe" + +const ( + // The number of levels in the radix tree. + summaryLevels = 5 + + // Constants for testing. + pageAlloc32Bit = 0 + pageAlloc64Bit = 1 + + // Number of bits needed to represent all indices into the L1 of the + // chunks map. + // + // See (*pageAlloc).chunks for more details. Update the documentation + // there should this number change. + pallocChunksL1Bits = 13 +) + +// levelBits is the number of bits in the radix for a given level in the super summary +// structure. +// +// The sum of all the entries of levelBits should equal heapAddrBits. +var levelBits = [summaryLevels]uint{ + summaryL0Bits, + summaryLevelBits, + summaryLevelBits, + summaryLevelBits, + summaryLevelBits, +} + +// levelShift is the number of bits to shift to acquire the radix for a given level +// in the super summary structure. +// +// With levelShift, one can compute the index of the summary at level l related to a +// pointer p by doing: +// p >> levelShift[l] +var levelShift = [summaryLevels]uint{ + heapAddrBits - summaryL0Bits, + heapAddrBits - summaryL0Bits - 1*summaryLevelBits, + heapAddrBits - summaryL0Bits - 2*summaryLevelBits, + heapAddrBits - summaryL0Bits - 3*summaryLevelBits, + heapAddrBits - summaryL0Bits - 4*summaryLevelBits, +} + +// levelLogPages is log2 the maximum number of runtime pages in the address space +// a summary in the given level represents. +// +// The leaf level always represents exactly log2 of 1 chunk's worth of pages. +var levelLogPages = [summaryLevels]uint{ + logPallocChunkPages + 4*summaryLevelBits, + logPallocChunkPages + 3*summaryLevelBits, + logPallocChunkPages + 2*summaryLevelBits, + logPallocChunkPages + 1*summaryLevelBits, + logPallocChunkPages, +} + +// sysInit performs architecture-dependent initialization of fields +// in pageAlloc. pageAlloc should be uninitialized except for sysStat +// if any runtime statistic should be updated. +func (s *pageAlloc) sysInit() { + // Reserve memory for each level. This will get mapped in + // as R/W by setArenas. + for l, shift := range levelShift { + entries := 1 << (heapAddrBits - shift) + + // Reserve b bytes of memory anywhere in the address space. + b := alignUp(uintptr(entries)*pallocSumBytes, physPageSize) + r := sysReserve(nil, b) + if r == nil { + throw("failed to reserve page summary memory") + } + + // Put this reservation into a slice. + sl := notInHeapSlice{(*notInHeap)(r), 0, entries} + s.summary[l] = *(*[]pallocSum)(unsafe.Pointer(&sl)) + } +} + +// sysGrow performs architecture-dependent operations on heap +// growth for the page allocator, such as mapping in new memory +// for summaries. It also updates the length of the slices in +// s.summary. +// +// base is the base of the newly-added heap memory and limit is +// the first address past the end of the newly-added heap memory. +// Both must be aligned to pallocChunkBytes. +// +// The caller must update s.start and s.end after calling sysGrow. +func (s *pageAlloc) sysGrow(base, limit uintptr) { + if base%pallocChunkBytes != 0 || limit%pallocChunkBytes != 0 { + print("runtime: base = ", hex(base), ", limit = ", hex(limit), "\n") + throw("sysGrow bounds not aligned to pallocChunkBytes") + } + + // addrRangeToSummaryRange converts a range of addresses into a range + // of summary indices which must be mapped to support those addresses + // in the summary range. + addrRangeToSummaryRange := func(level int, r addrRange) (int, int) { + sumIdxBase, sumIdxLimit := addrsToSummaryRange(level, r.base, r.limit) + return blockAlignSummaryRange(level, sumIdxBase, sumIdxLimit) + } + + // summaryRangeToSumAddrRange converts a range of indices in any + // level of s.summary into page-aligned addresses which cover that + // range of indices. + summaryRangeToSumAddrRange := func(level, sumIdxBase, sumIdxLimit int) addrRange { + baseOffset := alignDown(uintptr(sumIdxBase)*pallocSumBytes, physPageSize) + limitOffset := alignUp(uintptr(sumIdxLimit)*pallocSumBytes, physPageSize) + base := unsafe.Pointer(&s.summary[level][0]) + return addrRange{ + uintptr(add(base, baseOffset)), + uintptr(add(base, limitOffset)), + } + } + + // addrRangeToSumAddrRange is a convienience function that converts + // an address range r to the address range of the given summary level + // that stores the summaries for r. + addrRangeToSumAddrRange := func(level int, r addrRange) addrRange { + sumIdxBase, sumIdxLimit := addrRangeToSummaryRange(level, r) + return summaryRangeToSumAddrRange(level, sumIdxBase, sumIdxLimit) + } + + // Find the first inUse index which is strictly greater than base. + // + // Because this function will never be asked remap the same memory + // twice, this index is effectively the index at which we would insert + // this new growth, and base will never overlap/be contained within + // any existing range. + // + // This will be used to look at what memory in the summary array is already + // mapped before and after this new range. + inUseIndex := s.inUse.findSucc(base) + + // Walk up the radix tree and map summaries in as needed. + for l := range s.summary { + // Figure out what part of the summary array this new address space needs. + needIdxBase, needIdxLimit := addrRangeToSummaryRange(l, addrRange{base, limit}) + + // Update the summary slices with a new upper-bound. This ensures + // we get tight bounds checks on at least the top bound. + // + // We must do this regardless of whether we map new memory. + if needIdxLimit > len(s.summary[l]) { + s.summary[l] = s.summary[l][:needIdxLimit] + } + + // Compute the needed address range in the summary array for level l. + need := summaryRangeToSumAddrRange(l, needIdxBase, needIdxLimit) + + // Prune need down to what needs to be newly mapped. Some parts of it may + // already be mapped by what inUse describes due to page alignment requirements + // for mapping. prune's invariants are guaranteed by the fact that this + // function will never be asked to remap the same memory twice. + if inUseIndex > 0 { + need = need.subtract(addrRangeToSumAddrRange(l, s.inUse.ranges[inUseIndex-1])) + } + if inUseIndex < len(s.inUse.ranges) { + need = need.subtract(addrRangeToSumAddrRange(l, s.inUse.ranges[inUseIndex])) + } + // It's possible that after our pruning above, there's nothing new to map. + if need.size() == 0 { + continue + } + + // Map and commit need. + sysMap(unsafe.Pointer(need.base), need.size(), s.sysStat) + sysUsed(unsafe.Pointer(need.base), need.size()) + } +} diff --git a/libgo/go/runtime/mpagealloc_test.go b/libgo/go/runtime/mpagealloc_test.go new file mode 100644 index 00000000000..6c48296487e --- /dev/null +++ b/libgo/go/runtime/mpagealloc_test.go @@ -0,0 +1,921 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "fmt" + . "runtime" + "testing" +) + +func checkPageAlloc(t *testing.T, want, got *PageAlloc) { + // Ensure start and end are correct. + wantStart, wantEnd := want.Bounds() + gotStart, gotEnd := got.Bounds() + if gotStart != wantStart { + t.Fatalf("start values not equal: got %d, want %d", gotStart, wantStart) + } + if gotEnd != wantEnd { + t.Fatalf("end values not equal: got %d, want %d", gotEnd, wantEnd) + } + + for i := gotStart; i < gotEnd; i++ { + // Check the bitmaps. Note that we may have nil data. + gb, wb := got.PallocData(i), want.PallocData(i) + if gb == nil && wb == nil { + continue + } + if (gb == nil && wb != nil) || (gb != nil && wb == nil) { + t.Errorf("chunk %d nilness mismatch", i) + } + if !checkPallocBits(t, gb.PallocBits(), wb.PallocBits()) { + t.Logf("in chunk %d (mallocBits)", i) + } + if !checkPallocBits(t, gb.Scavenged(), wb.Scavenged()) { + t.Logf("in chunk %d (scavenged)", i) + } + } + // TODO(mknyszek): Verify summaries too? +} + +func TestPageAllocGrow(t *testing.T) { + type test struct { + chunks []ChunkIdx + inUse []AddrRange + } + tests := map[string]test{ + "One": { + chunks: []ChunkIdx{ + BaseChunkIdx, + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+1, 0)}, + }, + }, + "Contiguous2": { + chunks: []ChunkIdx{ + BaseChunkIdx, + BaseChunkIdx + 1, + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+2, 0)}, + }, + }, + "Contiguous5": { + chunks: []ChunkIdx{ + BaseChunkIdx, + BaseChunkIdx + 1, + BaseChunkIdx + 2, + BaseChunkIdx + 3, + BaseChunkIdx + 4, + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+5, 0)}, + }, + }, + "Discontiguous": { + chunks: []ChunkIdx{ + BaseChunkIdx, + BaseChunkIdx + 2, + BaseChunkIdx + 4, + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+1, 0)}, + {PageBase(BaseChunkIdx+2, 0), PageBase(BaseChunkIdx+3, 0)}, + {PageBase(BaseChunkIdx+4, 0), PageBase(BaseChunkIdx+5, 0)}, + }, + }, + "Mixed": { + chunks: []ChunkIdx{ + BaseChunkIdx, + BaseChunkIdx + 1, + BaseChunkIdx + 2, + BaseChunkIdx + 4, + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+3, 0)}, + {PageBase(BaseChunkIdx+4, 0), PageBase(BaseChunkIdx+5, 0)}, + }, + }, + "WildlyDiscontiguous": { + chunks: []ChunkIdx{ + BaseChunkIdx, + BaseChunkIdx + 1, + BaseChunkIdx + 0x10, + BaseChunkIdx + 0x21, + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+2, 0)}, + {PageBase(BaseChunkIdx+0x10, 0), PageBase(BaseChunkIdx+0x11, 0)}, + {PageBase(BaseChunkIdx+0x21, 0), PageBase(BaseChunkIdx+0x22, 0)}, + }, + }, + "ManyDiscontiguous": { + // The initial cap is 16. Test 33 ranges, to exercise the growth path (twice). + chunks: []ChunkIdx{ + BaseChunkIdx, BaseChunkIdx + 2, BaseChunkIdx + 4, BaseChunkIdx + 6, + BaseChunkIdx + 8, BaseChunkIdx + 10, BaseChunkIdx + 12, BaseChunkIdx + 14, + BaseChunkIdx + 16, BaseChunkIdx + 18, BaseChunkIdx + 20, BaseChunkIdx + 22, + BaseChunkIdx + 24, BaseChunkIdx + 26, BaseChunkIdx + 28, BaseChunkIdx + 30, + BaseChunkIdx + 32, BaseChunkIdx + 34, BaseChunkIdx + 36, BaseChunkIdx + 38, + BaseChunkIdx + 40, BaseChunkIdx + 42, BaseChunkIdx + 44, BaseChunkIdx + 46, + BaseChunkIdx + 48, BaseChunkIdx + 50, BaseChunkIdx + 52, BaseChunkIdx + 54, + BaseChunkIdx + 56, BaseChunkIdx + 58, BaseChunkIdx + 60, BaseChunkIdx + 62, + BaseChunkIdx + 64, + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+1, 0)}, + {PageBase(BaseChunkIdx+2, 0), PageBase(BaseChunkIdx+3, 0)}, + {PageBase(BaseChunkIdx+4, 0), PageBase(BaseChunkIdx+5, 0)}, + {PageBase(BaseChunkIdx+6, 0), PageBase(BaseChunkIdx+7, 0)}, + {PageBase(BaseChunkIdx+8, 0), PageBase(BaseChunkIdx+9, 0)}, + {PageBase(BaseChunkIdx+10, 0), PageBase(BaseChunkIdx+11, 0)}, + {PageBase(BaseChunkIdx+12, 0), PageBase(BaseChunkIdx+13, 0)}, + {PageBase(BaseChunkIdx+14, 0), PageBase(BaseChunkIdx+15, 0)}, + {PageBase(BaseChunkIdx+16, 0), PageBase(BaseChunkIdx+17, 0)}, + {PageBase(BaseChunkIdx+18, 0), PageBase(BaseChunkIdx+19, 0)}, + {PageBase(BaseChunkIdx+20, 0), PageBase(BaseChunkIdx+21, 0)}, + {PageBase(BaseChunkIdx+22, 0), PageBase(BaseChunkIdx+23, 0)}, + {PageBase(BaseChunkIdx+24, 0), PageBase(BaseChunkIdx+25, 0)}, + {PageBase(BaseChunkIdx+26, 0), PageBase(BaseChunkIdx+27, 0)}, + {PageBase(BaseChunkIdx+28, 0), PageBase(BaseChunkIdx+29, 0)}, + {PageBase(BaseChunkIdx+30, 0), PageBase(BaseChunkIdx+31, 0)}, + {PageBase(BaseChunkIdx+32, 0), PageBase(BaseChunkIdx+33, 0)}, + {PageBase(BaseChunkIdx+34, 0), PageBase(BaseChunkIdx+35, 0)}, + {PageBase(BaseChunkIdx+36, 0), PageBase(BaseChunkIdx+37, 0)}, + {PageBase(BaseChunkIdx+38, 0), PageBase(BaseChunkIdx+39, 0)}, + {PageBase(BaseChunkIdx+40, 0), PageBase(BaseChunkIdx+41, 0)}, + {PageBase(BaseChunkIdx+42, 0), PageBase(BaseChunkIdx+43, 0)}, + {PageBase(BaseChunkIdx+44, 0), PageBase(BaseChunkIdx+45, 0)}, + {PageBase(BaseChunkIdx+46, 0), PageBase(BaseChunkIdx+47, 0)}, + {PageBase(BaseChunkIdx+48, 0), PageBase(BaseChunkIdx+49, 0)}, + {PageBase(BaseChunkIdx+50, 0), PageBase(BaseChunkIdx+51, 0)}, + {PageBase(BaseChunkIdx+52, 0), PageBase(BaseChunkIdx+53, 0)}, + {PageBase(BaseChunkIdx+54, 0), PageBase(BaseChunkIdx+55, 0)}, + {PageBase(BaseChunkIdx+56, 0), PageBase(BaseChunkIdx+57, 0)}, + {PageBase(BaseChunkIdx+58, 0), PageBase(BaseChunkIdx+59, 0)}, + {PageBase(BaseChunkIdx+60, 0), PageBase(BaseChunkIdx+61, 0)}, + {PageBase(BaseChunkIdx+62, 0), PageBase(BaseChunkIdx+63, 0)}, + {PageBase(BaseChunkIdx+64, 0), PageBase(BaseChunkIdx+65, 0)}, + }, + }, + } + if PageAlloc64Bit != 0 { + tests["ExtremelyDiscontiguous"] = test{ + chunks: []ChunkIdx{ + BaseChunkIdx, + BaseChunkIdx + 0x100000, // constant translates to O(TiB) + }, + inUse: []AddrRange{ + {PageBase(BaseChunkIdx, 0), PageBase(BaseChunkIdx+1, 0)}, + {PageBase(BaseChunkIdx+0x100000, 0), PageBase(BaseChunkIdx+0x100001, 0)}, + }, + } + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + // By creating a new pageAlloc, we will + // grow it for each chunk defined in x. + x := make(map[ChunkIdx][]BitRange) + for _, c := range v.chunks { + x[c] = []BitRange{} + } + b := NewPageAlloc(x, nil) + defer FreePageAlloc(b) + + got := b.InUse() + want := v.inUse + + // Check for mismatches. + if len(got) != len(want) { + t.Fail() + } else { + for i := range want { + if want[i] != got[i] { + t.Fail() + break + } + } + } + if t.Failed() { + t.Logf("found inUse mismatch") + t.Logf("got:") + for i, r := range got { + t.Logf("\t#%d [0x%x, 0x%x)", i, r.Base, r.Limit) + } + t.Logf("want:") + for i, r := range want { + t.Logf("\t#%d [0x%x, 0x%x)", i, r.Base, r.Limit) + } + } + }) + } +} + +func TestPageAllocAlloc(t *testing.T) { + type hit struct { + npages, base, scav uintptr + } + tests := map[string]struct { + scav map[ChunkIdx][]BitRange + before map[ChunkIdx][]BitRange + after map[ChunkIdx][]BitRange + hits []hit + }{ + "AllFree1": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 1}, {2, 2}}, + }, + hits: []hit{ + {1, PageBase(BaseChunkIdx, 0), PageSize}, + {1, PageBase(BaseChunkIdx, 1), 0}, + {1, PageBase(BaseChunkIdx, 2), PageSize}, + {1, PageBase(BaseChunkIdx, 3), PageSize}, + {1, PageBase(BaseChunkIdx, 4), 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 5}}, + }, + }, + "ManyArena1": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages - 1}}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + }, + hits: []hit{ + {1, PageBase(BaseChunkIdx+2, PallocChunkPages-1), PageSize}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + }, + }, + "NotContiguous1": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 0xff: {{0, 0}}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 0xff: {{0, PallocChunkPages}}, + }, + hits: []hit{ + {1, PageBase(BaseChunkIdx+0xff, 0), PageSize}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 0xff: {{0, 1}}, + }, + }, + "AllFree2": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 3}, {7, 1}}, + }, + hits: []hit{ + {2, PageBase(BaseChunkIdx, 0), 2 * PageSize}, + {2, PageBase(BaseChunkIdx, 2), PageSize}, + {2, PageBase(BaseChunkIdx, 4), 0}, + {2, PageBase(BaseChunkIdx, 6), PageSize}, + {2, PageBase(BaseChunkIdx, 8), 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 10}}, + }, + }, + "Straddle2": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages - 1}}, + BaseChunkIdx + 1: {{1, PallocChunkPages - 1}}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{PallocChunkPages - 1, 1}}, + BaseChunkIdx + 1: {}, + }, + hits: []hit{ + {2, PageBase(BaseChunkIdx, PallocChunkPages-1), PageSize}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + }, + }, + "AllFree5": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 8}, {9, 1}, {17, 5}}, + }, + hits: []hit{ + {5, PageBase(BaseChunkIdx, 0), 5 * PageSize}, + {5, PageBase(BaseChunkIdx, 5), 4 * PageSize}, + {5, PageBase(BaseChunkIdx, 10), 0}, + {5, PageBase(BaseChunkIdx, 15), 3 * PageSize}, + {5, PageBase(BaseChunkIdx, 20), 2 * PageSize}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 25}}, + }, + }, + "AllFree64": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{21, 1}, {63, 65}}, + }, + hits: []hit{ + {64, PageBase(BaseChunkIdx, 0), 2 * PageSize}, + {64, PageBase(BaseChunkIdx, 64), 64 * PageSize}, + {64, PageBase(BaseChunkIdx, 128), 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 192}}, + }, + }, + "AllFree65": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{129, 1}}, + }, + hits: []hit{ + {65, PageBase(BaseChunkIdx, 0), 0}, + {65, PageBase(BaseChunkIdx, 65), PageSize}, + {65, PageBase(BaseChunkIdx, 130), 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 195}}, + }, + }, + // TODO(mknyszek): Add tests close to the chunk size. + "ExhaustPallocChunkPages-3": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{10, 1}}, + }, + hits: []hit{ + {PallocChunkPages - 3, PageBase(BaseChunkIdx, 0), PageSize}, + {PallocChunkPages - 3, 0, 0}, + {1, PageBase(BaseChunkIdx, PallocChunkPages-3), 0}, + {2, PageBase(BaseChunkIdx, PallocChunkPages-2), 0}, + {1, 0, 0}, + {PallocChunkPages - 3, 0, 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + }, + "AllFreePallocChunkPages": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 1}, {PallocChunkPages - 1, 1}}, + }, + hits: []hit{ + {PallocChunkPages, PageBase(BaseChunkIdx, 0), 2 * PageSize}, + {PallocChunkPages, 0, 0}, + {1, 0, 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + }, + "StraddlePallocChunkPages": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages / 2}}, + BaseChunkIdx + 1: {{PallocChunkPages / 2, PallocChunkPages / 2}}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {{3, 100}}, + }, + hits: []hit{ + {PallocChunkPages, PageBase(BaseChunkIdx, PallocChunkPages/2), 100 * PageSize}, + {PallocChunkPages, 0, 0}, + {1, 0, 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + }, + }, + "StraddlePallocChunkPages+1": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages / 2}}, + BaseChunkIdx + 1: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + }, + hits: []hit{ + {PallocChunkPages + 1, PageBase(BaseChunkIdx, PallocChunkPages/2), (PallocChunkPages + 1) * PageSize}, + {PallocChunkPages, 0, 0}, + {1, PageBase(BaseChunkIdx+1, PallocChunkPages/2+1), PageSize}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages/2 + 2}}, + }, + }, + "AllFreePallocChunkPages*2": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + }, + hits: []hit{ + {PallocChunkPages * 2, PageBase(BaseChunkIdx, 0), 0}, + {PallocChunkPages * 2, 0, 0}, + {1, 0, 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + }, + }, + "NotContiguousPallocChunkPages*2": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 0x40: {}, + BaseChunkIdx + 0x41: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 0x40: {}, + BaseChunkIdx + 0x41: {}, + }, + hits: []hit{ + {PallocChunkPages * 2, PageBase(BaseChunkIdx+0x40, 0), 0}, + {21, PageBase(BaseChunkIdx, 0), 21 * PageSize}, + {1, PageBase(BaseChunkIdx, 21), PageSize}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 22}}, + BaseChunkIdx + 0x40: {{0, PallocChunkPages}}, + BaseChunkIdx + 0x41: {{0, PallocChunkPages}}, + }, + }, + "StraddlePallocChunkPages*2": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages / 2}}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {{PallocChunkPages / 2, PallocChunkPages / 2}}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, 7}}, + BaseChunkIdx + 1: {{3, 5}, {121, 10}}, + BaseChunkIdx + 2: {{PallocChunkPages/2 + 12, 2}}, + }, + hits: []hit{ + {PallocChunkPages * 2, PageBase(BaseChunkIdx, PallocChunkPages/2), 15 * PageSize}, + {PallocChunkPages * 2, 0, 0}, + {1, 0, 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + }, + }, + "StraddlePallocChunkPages*5/4": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages * 3 / 4}}, + BaseChunkIdx + 2: {{0, PallocChunkPages * 3 / 4}}, + BaseChunkIdx + 3: {{0, 0}}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{PallocChunkPages / 2, PallocChunkPages/4 + 1}}, + BaseChunkIdx + 2: {{PallocChunkPages / 3, 1}}, + BaseChunkIdx + 3: {{PallocChunkPages * 2 / 3, 1}}, + }, + hits: []hit{ + {PallocChunkPages * 5 / 4, PageBase(BaseChunkIdx+2, PallocChunkPages*3/4), PageSize}, + {PallocChunkPages * 5 / 4, 0, 0}, + {1, PageBase(BaseChunkIdx+1, PallocChunkPages*3/4), PageSize}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages*3/4 + 1}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + BaseChunkIdx + 3: {{0, PallocChunkPages}}, + }, + }, + "AllFreePallocChunkPages*7+5": { + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {}, + BaseChunkIdx + 3: {}, + BaseChunkIdx + 4: {}, + BaseChunkIdx + 5: {}, + BaseChunkIdx + 6: {}, + BaseChunkIdx + 7: {}, + }, + scav: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{50, 1}}, + BaseChunkIdx + 1: {{31, 1}}, + BaseChunkIdx + 2: {{7, 1}}, + BaseChunkIdx + 3: {{200, 1}}, + BaseChunkIdx + 4: {{3, 1}}, + BaseChunkIdx + 5: {{51, 1}}, + BaseChunkIdx + 6: {{20, 1}}, + BaseChunkIdx + 7: {{1, 1}}, + }, + hits: []hit{ + {PallocChunkPages*7 + 5, PageBase(BaseChunkIdx, 0), 8 * PageSize}, + {PallocChunkPages*7 + 5, 0, 0}, + {1, PageBase(BaseChunkIdx+7, 5), 0}, + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + BaseChunkIdx + 3: {{0, PallocChunkPages}}, + BaseChunkIdx + 4: {{0, PallocChunkPages}}, + BaseChunkIdx + 5: {{0, PallocChunkPages}}, + BaseChunkIdx + 6: {{0, PallocChunkPages}}, + BaseChunkIdx + 7: {{0, 6}}, + }, + }, + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + b := NewPageAlloc(v.before, v.scav) + defer FreePageAlloc(b) + + for iter, i := range v.hits { + a, s := b.Alloc(i.npages) + if a != i.base { + t.Fatalf("bad alloc #%d: want base 0x%x, got 0x%x", iter+1, i.base, a) + } + if s != i.scav { + t.Fatalf("bad alloc #%d: want scav %d, got %d", iter+1, i.scav, s) + } + } + want := NewPageAlloc(v.after, v.scav) + defer FreePageAlloc(want) + + checkPageAlloc(t, want, b) + }) + } +} + +func TestPageAllocExhaust(t *testing.T) { + for _, npages := range []uintptr{1, 2, 3, 4, 5, 8, 16, 64, 1024, 1025, 2048, 2049} { + npages := npages + t.Run(fmt.Sprintf("%d", npages), func(t *testing.T) { + // Construct b. + bDesc := make(map[ChunkIdx][]BitRange) + for i := ChunkIdx(0); i < 4; i++ { + bDesc[BaseChunkIdx+i] = []BitRange{} + } + b := NewPageAlloc(bDesc, nil) + defer FreePageAlloc(b) + + // Allocate into b with npages until we've exhausted the heap. + nAlloc := (PallocChunkPages * 4) / int(npages) + for i := 0; i < nAlloc; i++ { + addr := PageBase(BaseChunkIdx, uint(i)*uint(npages)) + if a, _ := b.Alloc(npages); a != addr { + t.Fatalf("bad alloc #%d: want 0x%x, got 0x%x", i+1, addr, a) + } + } + + // Check to make sure the next allocation fails. + if a, _ := b.Alloc(npages); a != 0 { + t.Fatalf("bad alloc #%d: want 0, got 0x%x", nAlloc, a) + } + + // Construct what we want the heap to look like now. + allocPages := nAlloc * int(npages) + wantDesc := make(map[ChunkIdx][]BitRange) + for i := ChunkIdx(0); i < 4; i++ { + if allocPages >= PallocChunkPages { + wantDesc[BaseChunkIdx+i] = []BitRange{{0, PallocChunkPages}} + allocPages -= PallocChunkPages + } else if allocPages > 0 { + wantDesc[BaseChunkIdx+i] = []BitRange{{0, uint(allocPages)}} + allocPages = 0 + } else { + wantDesc[BaseChunkIdx+i] = []BitRange{} + } + } + want := NewPageAlloc(wantDesc, nil) + defer FreePageAlloc(want) + + // Check to make sure the heap b matches what we want. + checkPageAlloc(t, want, b) + }) + } +} + +func TestPageAllocFree(t *testing.T) { + tests := map[string]struct { + before map[ChunkIdx][]BitRange + after map[ChunkIdx][]BitRange + npages uintptr + frees []uintptr + }{ + "Free1": { + npages: 1, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + PageBase(BaseChunkIdx, 1), + PageBase(BaseChunkIdx, 2), + PageBase(BaseChunkIdx, 3), + PageBase(BaseChunkIdx, 4), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{5, PallocChunkPages - 5}}, + }, + }, + "ManyArena1": { + npages: 1, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, PallocChunkPages/2), + PageBase(BaseChunkIdx+1, 0), + PageBase(BaseChunkIdx+2, PallocChunkPages-1), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages / 2}, {PallocChunkPages/2 + 1, PallocChunkPages/2 - 1}}, + BaseChunkIdx + 1: {{1, PallocChunkPages - 1}}, + BaseChunkIdx + 2: {{0, PallocChunkPages - 1}}, + }, + }, + "Free2": { + npages: 2, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + PageBase(BaseChunkIdx, 2), + PageBase(BaseChunkIdx, 4), + PageBase(BaseChunkIdx, 6), + PageBase(BaseChunkIdx, 8), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{10, PallocChunkPages - 10}}, + }, + }, + "Straddle2": { + npages: 2, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{PallocChunkPages - 1, 1}}, + BaseChunkIdx + 1: {{0, 1}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, PallocChunkPages-1), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + }, + }, + "Free5": { + npages: 5, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + PageBase(BaseChunkIdx, 5), + PageBase(BaseChunkIdx, 10), + PageBase(BaseChunkIdx, 15), + PageBase(BaseChunkIdx, 20), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{25, PallocChunkPages - 25}}, + }, + }, + "Free64": { + npages: 64, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + PageBase(BaseChunkIdx, 64), + PageBase(BaseChunkIdx, 128), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{192, PallocChunkPages - 192}}, + }, + }, + "Free65": { + npages: 65, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + PageBase(BaseChunkIdx, 65), + PageBase(BaseChunkIdx, 130), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{195, PallocChunkPages - 195}}, + }, + }, + "FreePallocChunkPages": { + npages: PallocChunkPages, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + }, + }, + "StraddlePallocChunkPages": { + npages: PallocChunkPages, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{PallocChunkPages / 2, PallocChunkPages / 2}}, + BaseChunkIdx + 1: {{0, PallocChunkPages / 2}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, PallocChunkPages/2), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + }, + }, + "StraddlePallocChunkPages+1": { + npages: PallocChunkPages + 1, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, PallocChunkPages/2), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages / 2}}, + BaseChunkIdx + 1: {{PallocChunkPages/2 + 1, PallocChunkPages/2 - 1}}, + }, + }, + "FreePallocChunkPages*2": { + npages: PallocChunkPages * 2, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + }, + }, + "StraddlePallocChunkPages*2": { + npages: PallocChunkPages * 2, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, PallocChunkPages/2), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages / 2}}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {{PallocChunkPages / 2, PallocChunkPages / 2}}, + }, + }, + "AllFreePallocChunkPages*7+5": { + npages: PallocChunkPages*7 + 5, + before: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {{0, PallocChunkPages}}, + BaseChunkIdx + 1: {{0, PallocChunkPages}}, + BaseChunkIdx + 2: {{0, PallocChunkPages}}, + BaseChunkIdx + 3: {{0, PallocChunkPages}}, + BaseChunkIdx + 4: {{0, PallocChunkPages}}, + BaseChunkIdx + 5: {{0, PallocChunkPages}}, + BaseChunkIdx + 6: {{0, PallocChunkPages}}, + BaseChunkIdx + 7: {{0, PallocChunkPages}}, + }, + frees: []uintptr{ + PageBase(BaseChunkIdx, 0), + }, + after: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {}, + BaseChunkIdx + 3: {}, + BaseChunkIdx + 4: {}, + BaseChunkIdx + 5: {}, + BaseChunkIdx + 6: {}, + BaseChunkIdx + 7: {{5, PallocChunkPages - 5}}, + }, + }, + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + b := NewPageAlloc(v.before, nil) + defer FreePageAlloc(b) + + for _, addr := range v.frees { + b.Free(addr, v.npages) + } + want := NewPageAlloc(v.after, nil) + defer FreePageAlloc(want) + + checkPageAlloc(t, want, b) + }) + } +} + +func TestPageAllocAllocAndFree(t *testing.T) { + type hit struct { + alloc bool + npages uintptr + base uintptr + } + tests := map[string]struct { + init map[ChunkIdx][]BitRange + hits []hit + }{ + // TODO(mknyszek): Write more tests here. + "Chunks8": { + init: map[ChunkIdx][]BitRange{ + BaseChunkIdx: {}, + BaseChunkIdx + 1: {}, + BaseChunkIdx + 2: {}, + BaseChunkIdx + 3: {}, + BaseChunkIdx + 4: {}, + BaseChunkIdx + 5: {}, + BaseChunkIdx + 6: {}, + BaseChunkIdx + 7: {}, + }, + hits: []hit{ + {true, PallocChunkPages * 8, PageBase(BaseChunkIdx, 0)}, + {false, PallocChunkPages * 8, PageBase(BaseChunkIdx, 0)}, + {true, PallocChunkPages * 8, PageBase(BaseChunkIdx, 0)}, + {false, PallocChunkPages * 8, PageBase(BaseChunkIdx, 0)}, + {true, PallocChunkPages * 8, PageBase(BaseChunkIdx, 0)}, + {false, PallocChunkPages * 8, PageBase(BaseChunkIdx, 0)}, + {true, 1, PageBase(BaseChunkIdx, 0)}, + {false, 1, PageBase(BaseChunkIdx, 0)}, + {true, PallocChunkPages * 8, PageBase(BaseChunkIdx, 0)}, + }, + }, + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + b := NewPageAlloc(v.init, nil) + defer FreePageAlloc(b) + + for iter, i := range v.hits { + if i.alloc { + if a, _ := b.Alloc(i.npages); a != i.base { + t.Fatalf("bad alloc #%d: want 0x%x, got 0x%x", iter+1, i.base, a) + } + } else { + b.Free(i.base, i.npages) + } + } + }) + } +} diff --git a/libgo/go/runtime/mpagecache.go b/libgo/go/runtime/mpagecache.go new file mode 100644 index 00000000000..9fc338bd8e4 --- /dev/null +++ b/libgo/go/runtime/mpagecache.go @@ -0,0 +1,156 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +import ( + "runtime/internal/sys" + "unsafe" +) + +const pageCachePages = 8 * unsafe.Sizeof(pageCache{}.cache) + +// pageCache represents a per-p cache of pages the allocator can +// allocate from without a lock. More specifically, it represents +// a pageCachePages*pageSize chunk of memory with 0 or more free +// pages in it. +type pageCache struct { + base uintptr // base address of the chunk + cache uint64 // 64-bit bitmap representing free pages (1 means free) + scav uint64 // 64-bit bitmap representing scavenged pages (1 means scavenged) +} + +// empty returns true if the pageCache has any free pages, and false +// otherwise. +func (c *pageCache) empty() bool { + return c.cache == 0 +} + +// alloc allocates npages from the page cache and is the main entry +// point for allocation. +// +// Returns a base address and the amount of scavenged memory in the +// allocated region in bytes. +// +// Returns a base address of zero on failure, in which case the +// amount of scavenged memory should be ignored. +func (c *pageCache) alloc(npages uintptr) (uintptr, uintptr) { + if c.cache == 0 { + return 0, 0 + } + if npages == 1 { + i := uintptr(sys.TrailingZeros64(c.cache)) + scav := (c.scav >> i) & 1 + c.cache &^= 1 << i // set bit to mark in-use + c.scav &^= 1 << i // clear bit to mark unscavenged + return c.base + i*pageSize, uintptr(scav) * pageSize + } + return c.allocN(npages) +} + +// allocN is a helper which attempts to allocate npages worth of pages +// from the cache. It represents the general case for allocating from +// the page cache. +// +// Returns a base address and the amount of scavenged memory in the +// allocated region in bytes. +func (c *pageCache) allocN(npages uintptr) (uintptr, uintptr) { + i := findBitRange64(c.cache, uint(npages)) + if i >= 64 { + return 0, 0 + } + mask := ((uint64(1) << npages) - 1) << i + scav := sys.OnesCount64(c.scav & mask) + c.cache &^= mask // mark in-use bits + c.scav &^= mask // clear scavenged bits + return c.base + uintptr(i*pageSize), uintptr(scav) * pageSize +} + +// flush empties out unallocated free pages in the given cache +// into s. Then, it clears the cache, such that empty returns +// true. +// +// s.mheapLock must be held or the world must be stopped. +func (c *pageCache) flush(s *pageAlloc) { + if c.empty() { + return + } + ci := chunkIndex(c.base) + pi := chunkPageIndex(c.base) + + // This method is called very infrequently, so just do the + // slower, safer thing by iterating over each bit individually. + for i := uint(0); i < 64; i++ { + if c.cache&(1<= s.end { + return pageCache{} + } + c := pageCache{} + ci := chunkIndex(s.searchAddr) // chunk index + if s.summary[len(s.summary)-1][ci] != 0 { + // Fast path: there's free pages at or near the searchAddr address. + chunk := s.chunkOf(ci) + j, _ := chunk.find(1, chunkPageIndex(s.searchAddr)) + if j < 0 { + throw("bad summary data") + } + c = pageCache{ + base: chunkBase(ci) + alignDown(uintptr(j), 64)*pageSize, + cache: ^chunk.pages64(j), + scav: chunk.scavenged.block64(j), + } + } else { + // Slow path: the searchAddr address had nothing there, so go find + // the first free page the slow way. + addr, _ := s.find(1) + if addr == 0 { + // We failed to find adequate free space, so mark the searchAddr as OoM + // and return an empty pageCache. + s.searchAddr = maxSearchAddr + return pageCache{} + } + ci := chunkIndex(addr) + chunk := s.chunkOf(ci) + c = pageCache{ + base: alignDown(addr, 64*pageSize), + cache: ^chunk.pages64(chunkPageIndex(addr)), + scav: chunk.scavenged.block64(chunkPageIndex(addr)), + } + } + + // Set the bits as allocated and clear the scavenged bits. + s.allocRange(c.base, pageCachePages) + + // Update as an allocation, but note that it's not contiguous. + s.update(c.base, pageCachePages, false, true) + + // We're always searching for the first free page, and we always know the + // up to pageCache size bits will be allocated, so we can always move the + // searchAddr past the cache. + s.searchAddr = c.base + pageSize*pageCachePages + return c +} diff --git a/libgo/go/runtime/mpagecache_test.go b/libgo/go/runtime/mpagecache_test.go new file mode 100644 index 00000000000..6fdaa04d726 --- /dev/null +++ b/libgo/go/runtime/mpagecache_test.go @@ -0,0 +1,364 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "math/rand" + . "runtime" + "testing" +) + +func checkPageCache(t *testing.T, got, want PageCache) { + if got.Base() != want.Base() { + t.Errorf("bad pageCache base: got 0x%x, want 0x%x", got.Base(), want.Base()) + } + if got.Cache() != want.Cache() { + t.Errorf("bad pageCache bits: got %016x, want %016x", got.Base(), want.Base()) + } + if got.Scav() != want.Scav() { + t.Errorf("bad pageCache scav: got %016x, want %016x", got.Scav(), want.Scav()) + } +} + +func TestPageCacheAlloc(t *testing.T) { + base := PageBase(BaseChunkIdx, 0) + type hit struct { + npages uintptr + base uintptr + scav uintptr + } + tests := map[string]struct { + cache PageCache + hits []hit + }{ + "Empty": { + cache: NewPageCache(base, 0, 0), + hits: []hit{ + {1, 0, 0}, + {2, 0, 0}, + {3, 0, 0}, + {4, 0, 0}, + {5, 0, 0}, + {11, 0, 0}, + {12, 0, 0}, + {16, 0, 0}, + {27, 0, 0}, + {32, 0, 0}, + {43, 0, 0}, + {57, 0, 0}, + {64, 0, 0}, + {121, 0, 0}, + }, + }, + "Lo1": { + cache: NewPageCache(base, 0x1, 0x1), + hits: []hit{ + {1, base, PageSize}, + {1, 0, 0}, + {10, 0, 0}, + }, + }, + "Hi1": { + cache: NewPageCache(base, 0x1<<63, 0x1), + hits: []hit{ + {1, base + 63*PageSize, 0}, + {1, 0, 0}, + {10, 0, 0}, + }, + }, + "Swiss1": { + cache: NewPageCache(base, 0x20005555, 0x5505), + hits: []hit{ + {2, 0, 0}, + {1, base, PageSize}, + {1, base + 2*PageSize, PageSize}, + {1, base + 4*PageSize, 0}, + {1, base + 6*PageSize, 0}, + {1, base + 8*PageSize, PageSize}, + {1, base + 10*PageSize, PageSize}, + {1, base + 12*PageSize, PageSize}, + {1, base + 14*PageSize, PageSize}, + {1, base + 29*PageSize, 0}, + {1, 0, 0}, + {10, 0, 0}, + }, + }, + "Lo2": { + cache: NewPageCache(base, 0x3, 0x2<<62), + hits: []hit{ + {2, base, 0}, + {2, 0, 0}, + {1, 0, 0}, + }, + }, + "Hi2": { + cache: NewPageCache(base, 0x3<<62, 0x3<<62), + hits: []hit{ + {2, base + 62*PageSize, 2 * PageSize}, + {2, 0, 0}, + {1, 0, 0}, + }, + }, + "Swiss2": { + cache: NewPageCache(base, 0x3333<<31, 0x3030<<31), + hits: []hit{ + {2, base + 31*PageSize, 0}, + {2, base + 35*PageSize, 2 * PageSize}, + {2, base + 39*PageSize, 0}, + {2, base + 43*PageSize, 2 * PageSize}, + {2, 0, 0}, + }, + }, + "Hi53": { + cache: NewPageCache(base, ((uint64(1)<<53)-1)<<10, ((uint64(1)<<16)-1)<<10), + hits: []hit{ + {53, base + 10*PageSize, 16 * PageSize}, + {53, 0, 0}, + {1, 0, 0}, + }, + }, + "Full53": { + cache: NewPageCache(base, ^uint64(0), ((uint64(1)<<16)-1)<<10), + hits: []hit{ + {53, base, 16 * PageSize}, + {53, 0, 0}, + {1, base + 53*PageSize, 0}, + }, + }, + "Full64": { + cache: NewPageCache(base, ^uint64(0), ^uint64(0)), + hits: []hit{ + {64, base, 64 * PageSize}, + {64, 0, 0}, + {1, 0, 0}, + }, + }, + "FullMixed": { + cache: NewPageCache(base, ^uint64(0), ^uint64(0)), + hits: []hit{ + {5, base, 5 * PageSize}, + {7, base + 5*PageSize, 7 * PageSize}, + {1, base + 12*PageSize, 1 * PageSize}, + {23, base + 13*PageSize, 23 * PageSize}, + {63, 0, 0}, + {3, base + 36*PageSize, 3 * PageSize}, + {3, base + 39*PageSize, 3 * PageSize}, + {3, base + 42*PageSize, 3 * PageSize}, + {12, base + 45*PageSize, 12 * PageSize}, + {11, 0, 0}, + {4, base + 57*PageSize, 4 * PageSize}, + {4, 0, 0}, + {6, 0, 0}, + {36, 0, 0}, + {2, base + 61*PageSize, 2 * PageSize}, + {3, 0, 0}, + {1, base + 63*PageSize, 1 * PageSize}, + {4, 0, 0}, + {2, 0, 0}, + {62, 0, 0}, + {1, 0, 0}, + }, + }, + } + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + c := test.cache + for i, h := range test.hits { + b, s := c.Alloc(h.npages) + if b != h.base { + t.Fatalf("bad alloc base #%d: got 0x%x, want 0x%x", i, b, h.base) + } + if s != h.scav { + t.Fatalf("bad alloc scav #%d: got %d, want %d", i, s, h.scav) + } + } + }) + } +} + +func TestPageCacheFlush(t *testing.T) { + bits64ToBitRanges := func(bits uint64, base uint) []BitRange { + var ranges []BitRange + start, size := uint(0), uint(0) + for i := 0; i < 64; i++ { + if bits&(1<> (i % 64)) & 1) +} + +// block64 returns the 64-bit aligned block of bits containing the i'th bit. +func (b *pageBits) block64(i uint) uint64 { + return b[i/64] +} + +// set sets bit i of pageBits. +func (b *pageBits) set(i uint) { + b[i/64] |= 1 << (i % 64) +} + +// setRange sets bits in the range [i, i+n). +func (b *pageBits) setRange(i, n uint) { + _ = b[i/64] + if n == 1 { + // Fast path for the n == 1 case. + b.set(i) + return + } + // Set bits [i, j]. + j := i + n - 1 + if i/64 == j/64 { + b[i/64] |= ((uint64(1) << n) - 1) << (i % 64) + return + } + _ = b[j/64] + // Set leading bits. + b[i/64] |= ^uint64(0) << (i % 64) + for k := i/64 + 1; k < j/64; k++ { + b[k] = ^uint64(0) + } + // Set trailing bits. + b[j/64] |= (uint64(1) << (j%64 + 1)) - 1 +} + +// setAll sets all the bits of b. +func (b *pageBits) setAll() { + for i := range b { + b[i] = ^uint64(0) + } +} + +// clear clears bit i of pageBits. +func (b *pageBits) clear(i uint) { + b[i/64] &^= 1 << (i % 64) +} + +// clearRange clears bits in the range [i, i+n). +func (b *pageBits) clearRange(i, n uint) { + _ = b[i/64] + if n == 1 { + // Fast path for the n == 1 case. + b.clear(i) + return + } + // Clear bits [i, j]. + j := i + n - 1 + if i/64 == j/64 { + b[i/64] &^= ((uint64(1) << n) - 1) << (i % 64) + return + } + _ = b[j/64] + // Clear leading bits. + b[i/64] &^= ^uint64(0) << (i % 64) + for k := i/64 + 1; k < j/64; k++ { + b[k] = 0 + } + // Clear trailing bits. + b[j/64] &^= (uint64(1) << (j%64 + 1)) - 1 +} + +// clearAll frees all the bits of b. +func (b *pageBits) clearAll() { + for i := range b { + b[i] = 0 + } +} + +// popcntRange counts the number of set bits in the +// range [i, i+n). +func (b *pageBits) popcntRange(i, n uint) (s uint) { + if n == 1 { + return uint((b[i/64] >> (i % 64)) & 1) + } + _ = b[i/64] + j := i + n - 1 + if i/64 == j/64 { + return uint(sys.OnesCount64((b[i/64] >> (i % 64)) & ((1 << n) - 1))) + } + _ = b[j/64] + s += uint(sys.OnesCount64(b[i/64] >> (i % 64))) + for k := i/64 + 1; k < j/64; k++ { + s += uint(sys.OnesCount64(b[k])) + } + s += uint(sys.OnesCount64(b[j/64] & ((1 << (j%64 + 1)) - 1))) + return +} + +// pallocBits is a bitmap that tracks page allocations for at most one +// palloc chunk. +// +// The precise representation is an implementation detail, but for the +// sake of documentation, 0s are free pages and 1s are allocated pages. +type pallocBits pageBits + +// consec8tab is a table containing the number of consecutive +// zero bits for any uint8 value. +// +// The table is generated by calling consec8(i) for each +// possible uint8 value, which is defined as: +// +// // consec8 counts the maximum number of consecutive 0 bits +// // in a uint8. +// func consec8(n uint8) int { +// n = ^n +// i := 0 +// for n != 0 { +// n &= (n << 1) +// i++ +// } +// return i +// } +var consec8tab = [256]uint{ + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 5, 4, 3, 3, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, + 4, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, + 6, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 4, 3, 2, 2, 2, 1, 1, 1, 3, 2, 1, 1, 2, 1, 1, 1, + 5, 4, 3, 3, 2, 2, 2, 2, 3, 2, 1, 1, 2, 1, 1, 1, + 4, 3, 2, 2, 2, 1, 1, 1, 3, 2, 1, 1, 2, 1, 1, 1, + 7, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 3, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, + 5, 4, 3, 3, 2, 2, 2, 2, 3, 2, 1, 1, 2, 1, 1, 1, + 4, 3, 2, 2, 2, 1, 1, 1, 3, 2, 1, 1, 2, 1, 1, 1, + 6, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, + 4, 3, 2, 2, 2, 1, 1, 1, 3, 2, 1, 1, 2, 1, 1, 1, + 5, 4, 3, 3, 2, 2, 2, 2, 3, 2, 1, 1, 2, 1, 1, 1, + 4, 3, 2, 2, 2, 1, 1, 1, 3, 2, 1, 1, 2, 1, 1, 0, +} + +// summarize returns a packed summary of the bitmap in pallocBits. +func (b *pallocBits) summarize() pallocSum { + // TODO(mknyszek): There may be something more clever to be done + // here to make the summarize operation more efficient. For example, + // we can compute start and end with 64-bit wide operations easily, + // but max is a bit more complex. Perhaps there exists some way to + // leverage the 64-bit start and end to our advantage? + var start, max, end uint + for i := 0; i < len(b); i++ { + a := b[i] + for j := 0; j < 64; j += 8 { + k := uint8(a >> j) + + // Compute start. + si := uint(sys.TrailingZeros8(k)) + if start == uint(i*64+j) { + start += si + } + + // Compute max. + if end+si > max { + max = end + si + } + if mi := consec8tab[k]; mi > max { + max = mi + } + + // Compute end. + if k == 0 { + end += 8 + } else { + end = uint(sys.LeadingZeros8(k)) + } + } + } + return packPallocSum(start, max, end) +} + +// find searches for npages contiguous free pages in pallocBits and returns +// the index where that run starts, as well as the index of the first free page +// it found in the search. searchIdx represents the first known free page and +// where to begin the search from. +// +// If find fails to find any free space, it returns an index of ^uint(0) and +// the new searchIdx should be ignored. +// +// The returned searchIdx is always the index of the first free page found +// in this bitmap during the search, except if npages == 1, in which +// case it will be the index just after the first free page, because the +// index returned as the first result is assumed to be allocated and so +// represents a minor optimization for that case. +func (b *pallocBits) find(npages uintptr, searchIdx uint) (uint, uint) { + if npages == 1 { + addr := b.find1(searchIdx) + // Return a searchIdx of addr + 1 since we assume addr will be + // allocated. + return addr, addr + 1 + } else if npages <= 64 { + return b.findSmallN(npages, searchIdx) + } + return b.findLargeN(npages, searchIdx) +} + +// find1 is a helper for find which searches for a single free page +// in the pallocBits and returns the index. +// +// See find for an explanation of the searchIdx parameter. +func (b *pallocBits) find1(searchIdx uint) uint { + for i := searchIdx / 64; i < uint(len(b)); i++ { + x := b[i] + if x == ^uint64(0) { + continue + } + return i*64 + uint(sys.TrailingZeros64(^x)) + } + return ^uint(0) +} + +// findSmallN is a helper for find which searches for npages contiguous free pages +// in this pallocBits and returns the index where that run of contiguous pages +// starts as well as the index of the first free page it finds in its search. +// +// See find for an explanation of the searchIdx parameter. +// +// Returns a ^uint(0) index on failure and the new searchIdx should be ignored. +// +// findSmallN assumes npages <= 64, where any such contiguous run of pages +// crosses at most one aligned 64-bit boundary in the bits. +func (b *pallocBits) findSmallN(npages uintptr, searchIdx uint) (uint, uint) { + end, newSearchIdx := uint(0), ^uint(0) + for i := searchIdx / 64; i < uint(len(b)); i++ { + bi := b[i] + if bi == ^uint64(0) { + end = 0 + continue + } + // First see if we can pack our allocation in the trailing + // zeros plus the end of the last 64 bits. + start := uint(sys.TrailingZeros64(bi)) + if newSearchIdx == ^uint(0) { + // The new searchIdx is going to be at these 64 bits after any + // 1s we file, so count trailing 1s. + newSearchIdx = i*64 + uint(sys.TrailingZeros64(^bi)) + } + if end+start >= uint(npages) { + return i*64 - end, newSearchIdx + } + // Next, check the interior of the 64-bit chunk. + j := findBitRange64(^bi, uint(npages)) + if j < 64 { + return i*64 + j, newSearchIdx + } + end = uint(sys.LeadingZeros64(bi)) + } + return ^uint(0), newSearchIdx +} + +// findLargeN is a helper for find which searches for npages contiguous free pages +// in this pallocBits and returns the index where that run starts, as well as the +// index of the first free page it found it its search. +// +// See alloc for an explanation of the searchIdx parameter. +// +// Returns a ^uint(0) index on failure and the new searchIdx should be ignored. +// +// findLargeN assumes npages > 64, where any such run of free pages +// crosses at least one aligned 64-bit boundary in the bits. +func (b *pallocBits) findLargeN(npages uintptr, searchIdx uint) (uint, uint) { + start, size, newSearchIdx := ^uint(0), uint(0), ^uint(0) + for i := searchIdx / 64; i < uint(len(b)); i++ { + x := b[i] + if x == ^uint64(0) { + size = 0 + continue + } + if newSearchIdx == ^uint(0) { + // The new searchIdx is going to be at these 64 bits after any + // 1s we file, so count trailing 1s. + newSearchIdx = i*64 + uint(sys.TrailingZeros64(^x)) + } + if size == 0 { + size = uint(sys.LeadingZeros64(x)) + start = i*64 + 64 - size + continue + } + s := uint(sys.TrailingZeros64(x)) + if s+size >= uint(npages) { + size += s + return start, newSearchIdx + } + if s < 64 { + size = uint(sys.LeadingZeros64(x)) + start = i*64 + 64 - size + continue + } + size += 64 + } + if size < uint(npages) { + return ^uint(0), newSearchIdx + } + return start, newSearchIdx +} + +// allocRange allocates the range [i, i+n). +func (b *pallocBits) allocRange(i, n uint) { + (*pageBits)(b).setRange(i, n) +} + +// allocAll allocates all the bits of b. +func (b *pallocBits) allocAll() { + (*pageBits)(b).setAll() +} + +// free1 frees a single page in the pallocBits at i. +func (b *pallocBits) free1(i uint) { + (*pageBits)(b).clear(i) +} + +// free frees the range [i, i+n) of pages in the pallocBits. +func (b *pallocBits) free(i, n uint) { + (*pageBits)(b).clearRange(i, n) +} + +// freeAll frees all the bits of b. +func (b *pallocBits) freeAll() { + (*pageBits)(b).clearAll() +} + +// pages64 returns a 64-bit bitmap representing a block of 64 pages aligned +// to 64 pages. The returned block of pages is the one containing the i'th +// page in this pallocBits. Each bit represents whether the page is in-use. +func (b *pallocBits) pages64(i uint) uint64 { + return (*pageBits)(b).block64(i) +} + +// findBitRange64 returns the bit index of the first set of +// n consecutive 1 bits. If no consecutive set of 1 bits of +// size n may be found in c, then it returns an integer >= 64. +func findBitRange64(c uint64, n uint) uint { + i := uint(0) + cont := uint(sys.TrailingZeros64(^c)) + for cont < n && i < 64 { + i += cont + i += uint(sys.TrailingZeros64(c >> i)) + cont = uint(sys.TrailingZeros64(^(c >> i))) + } + return i +} + +// pallocData encapsulates pallocBits and a bitmap for +// whether or not a given page is scavenged in a single +// structure. It's effectively a pallocBits with +// additional functionality. +// +// Update the comment on (*pageAlloc).chunks should this +// structure change. +type pallocData struct { + pallocBits + scavenged pageBits +} + +// allocRange sets bits [i, i+n) in the bitmap to 1 and +// updates the scavenged bits appropriately. +func (m *pallocData) allocRange(i, n uint) { + // Clear the scavenged bits when we alloc the range. + m.pallocBits.allocRange(i, n) + m.scavenged.clearRange(i, n) +} + +// allocAll sets every bit in the bitmap to 1 and updates +// the scavenged bits appropriately. +func (m *pallocData) allocAll() { + // Clear the scavenged bits when we alloc the range. + m.pallocBits.allocAll() + m.scavenged.clearAll() +} diff --git a/libgo/go/runtime/mpallocbits_test.go b/libgo/go/runtime/mpallocbits_test.go new file mode 100644 index 00000000000..71a29f3b3a2 --- /dev/null +++ b/libgo/go/runtime/mpallocbits_test.go @@ -0,0 +1,510 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "fmt" + "math/rand" + . "runtime" + "testing" +) + +// Ensures that got and want are the same, and if not, reports +// detailed diff information. +func checkPallocBits(t *testing.T, got, want *PallocBits) bool { + d := DiffPallocBits(got, want) + if len(d) != 0 { + t.Errorf("%d range(s) different", len(d)) + for _, bits := range d { + t.Logf("\t@ bit index %d", bits.I) + t.Logf("\t| got: %s", StringifyPallocBits(got, bits)) + t.Logf("\t| want: %s", StringifyPallocBits(want, bits)) + } + return false + } + return true +} + +// makePallocBits produces an initialized PallocBits by setting +// the ranges in s to 1 and the rest to zero. +func makePallocBits(s []BitRange) *PallocBits { + b := new(PallocBits) + for _, v := range s { + b.AllocRange(v.I, v.N) + } + return b +} + +// Ensures that PallocBits.AllocRange works, which is a fundamental +// method used for testing and initialization since it's used by +// makePallocBits. +func TestPallocBitsAllocRange(t *testing.T) { + test := func(t *testing.T, i, n uint, want *PallocBits) { + checkPallocBits(t, makePallocBits([]BitRange{{i, n}}), want) + } + t.Run("OneLow", func(t *testing.T) { + want := new(PallocBits) + want[0] = 0x1 + test(t, 0, 1, want) + }) + t.Run("OneHigh", func(t *testing.T) { + want := new(PallocBits) + want[PallocChunkPages/64-1] = 1 << 63 + test(t, PallocChunkPages-1, 1, want) + }) + t.Run("Inner", func(t *testing.T) { + want := new(PallocBits) + want[2] = 0x3e + test(t, 129, 5, want) + }) + t.Run("Aligned", func(t *testing.T) { + want := new(PallocBits) + want[2] = ^uint64(0) + want[3] = ^uint64(0) + test(t, 128, 128, want) + }) + t.Run("Begin", func(t *testing.T) { + want := new(PallocBits) + want[0] = ^uint64(0) + want[1] = ^uint64(0) + want[2] = ^uint64(0) + want[3] = ^uint64(0) + want[4] = ^uint64(0) + want[5] = 0x1 + test(t, 0, 321, want) + }) + t.Run("End", func(t *testing.T) { + want := new(PallocBits) + want[PallocChunkPages/64-1] = ^uint64(0) + want[PallocChunkPages/64-2] = ^uint64(0) + want[PallocChunkPages/64-3] = ^uint64(0) + want[PallocChunkPages/64-4] = 1 << 63 + test(t, PallocChunkPages-(64*3+1), 64*3+1, want) + }) + t.Run("All", func(t *testing.T) { + want := new(PallocBits) + for i := range want { + want[i] = ^uint64(0) + } + test(t, 0, PallocChunkPages, want) + }) +} + +// Inverts every bit in the PallocBits. +func invertPallocBits(b *PallocBits) { + for i := range b { + b[i] = ^b[i] + } +} + +// Ensures two packed summaries are identical, and reports a detailed description +// of the difference if they're not. +func checkPallocSum(t *testing.T, got, want PallocSum) { + if got.Start() != want.Start() { + t.Errorf("inconsistent start: got %d, want %d", got.Start(), want.Start()) + } + if got.Max() != want.Max() { + t.Errorf("inconsistent max: got %d, want %d", got.Max(), want.Max()) + } + if got.End() != want.End() { + t.Errorf("inconsistent end: got %d, want %d", got.End(), want.End()) + } +} + +func TestMallocBitsPopcntRange(t *testing.T) { + type test struct { + i, n uint // bit range to popcnt over. + want uint // expected popcnt result on that range. + } + tests := map[string]struct { + init []BitRange // bit ranges to set to 1 in the bitmap. + tests []test // a set of popcnt tests to run over the bitmap. + }{ + "None": { + tests: []test{ + {0, 1, 0}, + {5, 3, 0}, + {2, 11, 0}, + {PallocChunkPages/4 + 1, PallocChunkPages / 2, 0}, + {0, PallocChunkPages, 0}, + }, + }, + "All": { + init: []BitRange{{0, PallocChunkPages}}, + tests: []test{ + {0, 1, 1}, + {5, 3, 3}, + {2, 11, 11}, + {PallocChunkPages/4 + 1, PallocChunkPages / 2, PallocChunkPages / 2}, + {0, PallocChunkPages, PallocChunkPages}, + }, + }, + "Half": { + init: []BitRange{{PallocChunkPages / 2, PallocChunkPages / 2}}, + tests: []test{ + {0, 1, 0}, + {5, 3, 0}, + {2, 11, 0}, + {PallocChunkPages/2 - 1, 1, 0}, + {PallocChunkPages / 2, 1, 1}, + {PallocChunkPages/2 + 10, 1, 1}, + {PallocChunkPages/2 - 1, 2, 1}, + {PallocChunkPages / 4, PallocChunkPages / 4, 0}, + {PallocChunkPages / 4, PallocChunkPages/4 + 1, 1}, + {PallocChunkPages/4 + 1, PallocChunkPages / 2, PallocChunkPages/4 + 1}, + {0, PallocChunkPages, PallocChunkPages / 2}, + }, + }, + "OddBound": { + init: []BitRange{{0, 111}}, + tests: []test{ + {0, 1, 1}, + {5, 3, 3}, + {2, 11, 11}, + {110, 2, 1}, + {99, 50, 12}, + {110, 1, 1}, + {111, 1, 0}, + {99, 1, 1}, + {120, 1, 0}, + {PallocChunkPages / 2, PallocChunkPages / 2, 0}, + {0, PallocChunkPages, 111}, + }, + }, + "Scattered": { + init: []BitRange{ + {1, 3}, {5, 1}, {7, 1}, {10, 2}, {13, 1}, {15, 4}, + {21, 1}, {23, 1}, {26, 2}, {30, 5}, {36, 2}, {40, 3}, + {44, 6}, {51, 1}, {53, 2}, {58, 3}, {63, 1}, {67, 2}, + {71, 10}, {84, 1}, {89, 7}, {99, 2}, {103, 1}, {107, 2}, + {111, 1}, {113, 1}, {115, 1}, {118, 1}, {120, 2}, {125, 5}, + }, + tests: []test{ + {0, 11, 6}, + {0, 64, 39}, + {13, 64, 40}, + {64, 64, 34}, + {0, 128, 73}, + {1, 128, 74}, + {0, PallocChunkPages, 75}, + }, + }, + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + b := makePallocBits(v.init) + for _, h := range v.tests { + if got := b.PopcntRange(h.i, h.n); got != h.want { + t.Errorf("bad popcnt (i=%d, n=%d): got %d, want %d", h.i, h.n, got, h.want) + } + } + }) + } +} + +// Ensures computing bit summaries works as expected by generating random +// bitmaps and checking against a reference implementation. +func TestPallocBitsSummarizeRandom(t *testing.T) { + b := new(PallocBits) + for i := 0; i < 1000; i++ { + // Randomize bitmap. + for i := range b { + b[i] = rand.Uint64() + } + // Check summary against reference implementation. + checkPallocSum(t, b.Summarize(), SummarizeSlow(b)) + } +} + +// Ensures computing bit summaries works as expected. +func TestPallocBitsSummarize(t *testing.T) { + var emptySum = PackPallocSum(PallocChunkPages, PallocChunkPages, PallocChunkPages) + type test struct { + free []BitRange // Ranges of free (zero) bits. + hits []PallocSum + } + tests := make(map[string]test) + tests["NoneFree"] = test{ + free: []BitRange{}, + hits: []PallocSum{ + PackPallocSum(0, 0, 0), + }, + } + tests["OnlyStart"] = test{ + free: []BitRange{{0, 10}}, + hits: []PallocSum{ + PackPallocSum(10, 10, 0), + }, + } + tests["OnlyEnd"] = test{ + free: []BitRange{{PallocChunkPages - 40, 40}}, + hits: []PallocSum{ + PackPallocSum(0, 40, 40), + }, + } + tests["StartAndEnd"] = test{ + free: []BitRange{{0, 11}, {PallocChunkPages - 23, 23}}, + hits: []PallocSum{ + PackPallocSum(11, 23, 23), + }, + } + tests["StartMaxEnd"] = test{ + free: []BitRange{{0, 4}, {50, 100}, {PallocChunkPages - 4, 4}}, + hits: []PallocSum{ + PackPallocSum(4, 100, 4), + }, + } + tests["OnlyMax"] = test{ + free: []BitRange{{1, 20}, {35, 241}, {PallocChunkPages - 50, 30}}, + hits: []PallocSum{ + PackPallocSum(0, 241, 0), + }, + } + tests["MultiMax"] = test{ + free: []BitRange{{35, 2}, {40, 5}, {100, 5}}, + hits: []PallocSum{ + PackPallocSum(0, 5, 0), + }, + } + tests["One"] = test{ + free: []BitRange{{2, 1}}, + hits: []PallocSum{ + PackPallocSum(0, 1, 0), + }, + } + tests["AllFree"] = test{ + free: []BitRange{{0, PallocChunkPages}}, + hits: []PallocSum{ + emptySum, + }, + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + b := makePallocBits(v.free) + // In the PallocBits we create 1's represent free spots, but in our actual + // PallocBits 1 means not free, so invert. + invertPallocBits(b) + for _, h := range v.hits { + checkPallocSum(t, b.Summarize(), h) + } + }) + } +} + +// Benchmarks how quickly we can summarize a PallocBits. +func BenchmarkPallocBitsSummarize(b *testing.B) { + buf0 := new(PallocBits) + buf1 := new(PallocBits) + for i := 0; i < len(buf1); i++ { + buf1[i] = ^uint64(0) + } + bufa := new(PallocBits) + for i := 0; i < len(bufa); i++ { + bufa[i] = 0xaa + } + for _, buf := range []*PallocBits{buf0, buf1, bufa} { + b.Run(fmt.Sprintf("Unpacked%02X", buf[0]), func(b *testing.B) { + for i := 0; i < b.N; i++ { + buf.Summarize() + } + }) + } +} + +// Ensures page allocation works. +func TestPallocBitsAlloc(t *testing.T) { + tests := map[string]struct { + before []BitRange + after []BitRange + npages uintptr + hits []uint + }{ + "AllFree1": { + npages: 1, + hits: []uint{0, 1, 2, 3, 4, 5}, + after: []BitRange{{0, 6}}, + }, + "AllFree2": { + npages: 2, + hits: []uint{0, 2, 4, 6, 8, 10}, + after: []BitRange{{0, 12}}, + }, + "AllFree5": { + npages: 5, + hits: []uint{0, 5, 10, 15, 20}, + after: []BitRange{{0, 25}}, + }, + "AllFree64": { + npages: 64, + hits: []uint{0, 64, 128}, + after: []BitRange{{0, 192}}, + }, + "AllFree65": { + npages: 65, + hits: []uint{0, 65, 130}, + after: []BitRange{{0, 195}}, + }, + "SomeFree64": { + before: []BitRange{{0, 32}, {64, 32}, {100, PallocChunkPages - 100}}, + npages: 64, + hits: []uint{^uint(0)}, + after: []BitRange{{0, 32}, {64, 32}, {100, PallocChunkPages - 100}}, + }, + "NoneFree1": { + before: []BitRange{{0, PallocChunkPages}}, + npages: 1, + hits: []uint{^uint(0), ^uint(0)}, + after: []BitRange{{0, PallocChunkPages}}, + }, + "NoneFree2": { + before: []BitRange{{0, PallocChunkPages}}, + npages: 2, + hits: []uint{^uint(0), ^uint(0)}, + after: []BitRange{{0, PallocChunkPages}}, + }, + "NoneFree5": { + before: []BitRange{{0, PallocChunkPages}}, + npages: 5, + hits: []uint{^uint(0), ^uint(0)}, + after: []BitRange{{0, PallocChunkPages}}, + }, + "NoneFree65": { + before: []BitRange{{0, PallocChunkPages}}, + npages: 65, + hits: []uint{^uint(0), ^uint(0)}, + after: []BitRange{{0, PallocChunkPages}}, + }, + "ExactFit1": { + before: []BitRange{{0, PallocChunkPages/2 - 3}, {PallocChunkPages/2 - 2, PallocChunkPages/2 + 2}}, + npages: 1, + hits: []uint{PallocChunkPages/2 - 3, ^uint(0)}, + after: []BitRange{{0, PallocChunkPages}}, + }, + "ExactFit2": { + before: []BitRange{{0, PallocChunkPages/2 - 3}, {PallocChunkPages/2 - 1, PallocChunkPages/2 + 1}}, + npages: 2, + hits: []uint{PallocChunkPages/2 - 3, ^uint(0)}, + after: []BitRange{{0, PallocChunkPages}}, + }, + "ExactFit5": { + before: []BitRange{{0, PallocChunkPages/2 - 3}, {PallocChunkPages/2 + 2, PallocChunkPages/2 - 2}}, + npages: 5, + hits: []uint{PallocChunkPages/2 - 3, ^uint(0)}, + after: []BitRange{{0, PallocChunkPages}}, + }, + "ExactFit65": { + before: []BitRange{{0, PallocChunkPages/2 - 31}, {PallocChunkPages/2 + 34, PallocChunkPages/2 - 34}}, + npages: 65, + hits: []uint{PallocChunkPages/2 - 31, ^uint(0)}, + after: []BitRange{{0, PallocChunkPages}}, + }, + "SomeFree161": { + before: []BitRange{{0, 185}, {331, 1}}, + npages: 161, + hits: []uint{332}, + after: []BitRange{{0, 185}, {331, 162}}, + }, + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + b := makePallocBits(v.before) + for iter, i := range v.hits { + a, _ := b.Find(v.npages, 0) + if i != a { + t.Fatalf("find #%d picked wrong index: want %d, got %d", iter+1, i, a) + } + if i != ^uint(0) { + b.AllocRange(a, uint(v.npages)) + } + } + want := makePallocBits(v.after) + checkPallocBits(t, b, want) + }) + } +} + +// Ensures page freeing works. +func TestPallocBitsFree(t *testing.T) { + tests := map[string]struct { + beforeInv []BitRange + afterInv []BitRange + frees []uint + npages uintptr + }{ + "SomeFree": { + npages: 1, + beforeInv: []BitRange{{0, 32}, {64, 32}, {100, 1}}, + frees: []uint{32}, + afterInv: []BitRange{{0, 33}, {64, 32}, {100, 1}}, + }, + "NoneFree1": { + npages: 1, + frees: []uint{0, 1, 2, 3, 4, 5}, + afterInv: []BitRange{{0, 6}}, + }, + "NoneFree2": { + npages: 2, + frees: []uint{0, 2, 4, 6, 8, 10}, + afterInv: []BitRange{{0, 12}}, + }, + "NoneFree5": { + npages: 5, + frees: []uint{0, 5, 10, 15, 20}, + afterInv: []BitRange{{0, 25}}, + }, + "NoneFree64": { + npages: 64, + frees: []uint{0, 64, 128}, + afterInv: []BitRange{{0, 192}}, + }, + "NoneFree65": { + npages: 65, + frees: []uint{0, 65, 130}, + afterInv: []BitRange{{0, 195}}, + }, + } + for name, v := range tests { + v := v + t.Run(name, func(t *testing.T) { + b := makePallocBits(v.beforeInv) + invertPallocBits(b) + for _, i := range v.frees { + b.Free(i, uint(v.npages)) + } + want := makePallocBits(v.afterInv) + invertPallocBits(want) + checkPallocBits(t, b, want) + }) + } +} + +func TestFindBitRange64(t *testing.T) { + check := func(x uint64, n uint, result uint) { + i := FindBitRange64(x, n) + if result == ^uint(0) && i < 64 { + t.Errorf("case (%016x, %d): got %d, want failure", x, n, i) + } else if result != ^uint(0) && i != result { + t.Errorf("case (%016x, %d): got %d, want %d", x, n, i, result) + } + } + for i := uint(0); i <= 64; i++ { + check(^uint64(0), i, 0) + } + check(0, 0, 0) + for i := uint(1); i <= 64; i++ { + check(0, i, ^uint(0)) + } + check(0x8000000000000000, 1, 63) + check(0xc000010001010000, 2, 62) + check(0xc000010001030000, 2, 16) + check(0xe000030001030000, 3, 61) + check(0xe000030001070000, 3, 16) + check(0xffff03ff01070000, 16, 48) + check(0xffff03ff0107ffff, 16, 0) + check(0x0fff03ff01079fff, 16, ^uint(0)) +} diff --git a/libgo/go/runtime/mprof.go b/libgo/go/runtime/mprof.go index 132c2ff5c21..dd257d1b06f 100644 --- a/libgo/go/runtime/mprof.go +++ b/libgo/go/runtime/mprof.go @@ -614,10 +614,20 @@ func fixupStack(stk []uintptr, skip int, canonStack *[maxStack]uintptr, size uin // Increase the skip count to take into account the frames corresponding // to runtime.callersRaw and to the C routine that it invokes. skip += 2 + sawSigtramp := false for _, pc := range stk { // Subtract 1 from PC to undo the 1 we added in callback in // go-callers.c. - function, file, _, frames := funcfileline(pc-1, -1) + function, file, _, frames := funcfileline(pc-1, -1, false) + + // Skip an unnamed function above sigtramp, as it is + // likely the signal handler. + if sawSigtramp { + sawSigtramp = false + if function == "" { + continue + } + } // Skip split-stack functions (match by function name) skipFrame := false @@ -630,11 +640,18 @@ func fixupStack(stk []uintptr, skip int, canonStack *[maxStack]uintptr, size uin skipFrame = true } - // Skip thunks and recover functions. There is no equivalent to - // these functions in the gc toolchain. + // Skip thunks and recover functions and other functions + // specific to gccgo, that do not appear in the gc toolchain. fcn := function if hasSuffix(fcn, "..r") { skipFrame = true + } else if function == "runtime.deferreturn" || function == "runtime.sighandler" { + skipFrame = true + } else if function == "runtime.sigtramp" || function == "runtime.sigtrampgo" { + skipFrame = true + // Also skip subsequent unnamed functions, + // which will be the signal handler itself. + sawSigtramp = true } else { for fcn != "" && (fcn[len(fcn)-1] >= '0' && fcn[len(fcn)-1] <= '9') { fcn = fcn[:len(fcn)-1] diff --git a/libgo/go/runtime/mranges.go b/libgo/go/runtime/mranges.go new file mode 100644 index 00000000000..c14e5c7efd0 --- /dev/null +++ b/libgo/go/runtime/mranges.go @@ -0,0 +1,147 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Address range data structure. +// +// This file contains an implementation of a data structure which +// manages ordered address ranges. + +package runtime + +import ( + "runtime/internal/sys" + "unsafe" +) + +// addrRange represents a region of address space. +type addrRange struct { + // base and limit together represent the region of address space + // [base, limit). That is, base is inclusive, limit is exclusive. + base, limit uintptr +} + +// size returns the size of the range represented in bytes. +func (a addrRange) size() uintptr { + if a.limit <= a.base { + return 0 + } + return a.limit - a.base +} + +// subtract takes the addrRange toPrune and cuts out any overlap with +// from, then returns the new range. subtract assumes that a and b +// either don't overlap at all, only overlap on one side, or are equal. +// If b is strictly contained in a, thus forcing a split, it will throw. +func (a addrRange) subtract(b addrRange) addrRange { + if a.base >= b.base && a.limit <= b.limit { + return addrRange{} + } else if a.base < b.base && a.limit > b.limit { + throw("bad prune") + } else if a.limit > b.limit && a.base < b.limit { + a.base = b.limit + } else if a.base < b.base && a.limit > b.base { + a.limit = b.base + } + return a +} + +// addrRanges is a data structure holding a collection of ranges of +// address space. +// +// The ranges are coalesced eagerly to reduce the +// number ranges it holds. +// +// The slice backing store for this field is persistentalloc'd +// and thus there is no way to free it. +// +// addrRanges is not thread-safe. +type addrRanges struct { + // ranges is a slice of ranges sorted by base. + ranges []addrRange + + // sysStat is the stat to track allocations by this type + sysStat *uint64 +} + +func (a *addrRanges) init(sysStat *uint64) { + ranges := (*notInHeapSlice)(unsafe.Pointer(&a.ranges)) + ranges.len = 0 + ranges.cap = 16 + ranges.array = (*notInHeap)(persistentalloc(unsafe.Sizeof(addrRange{})*uintptr(ranges.cap), sys.PtrSize, sysStat)) + a.sysStat = sysStat +} + +// findSucc returns the first index in a such that base is +// less than the base of the addrRange at that index. +func (a *addrRanges) findSucc(base uintptr) int { + // TODO(mknyszek): Consider a binary search for large arrays. + // While iterating over these ranges is potentially expensive, + // the expected number of ranges is small, ideally just 1, + // since Go heaps are usually mostly contiguous. + for i := range a.ranges { + if base < a.ranges[i].base { + return i + } + } + return len(a.ranges) +} + +// add inserts a new address range to a. +// +// r must not overlap with any address range in a. +func (a *addrRanges) add(r addrRange) { + // The copies in this function are potentially expensive, but this data + // structure is meant to represent the Go heap. At worst, copying this + // would take ~160µs assuming a conservative copying rate of 25 GiB/s (the + // copy will almost never trigger a page fault) for a 1 TiB heap with 4 MiB + // arenas which is completely discontiguous. ~160µs is still a lot, but in + // practice most platforms have 64 MiB arenas (which cuts this by a factor + // of 16) and Go heaps are usually mostly contiguous, so the chance that + // an addrRanges even grows to that size is extremely low. + + // Because we assume r is not currently represented in a, + // findSucc gives us our insertion index. + i := a.findSucc(r.base) + coalescesDown := i > 0 && a.ranges[i-1].limit == r.base + coalescesUp := i < len(a.ranges) && r.limit == a.ranges[i].base + if coalescesUp && coalescesDown { + // We have neighbors and they both border us. + // Merge a.ranges[i-1], r, and a.ranges[i] together into a.ranges[i-1]. + a.ranges[i-1].limit = a.ranges[i].limit + + // Delete a.ranges[i]. + copy(a.ranges[i:], a.ranges[i+1:]) + a.ranges = a.ranges[:len(a.ranges)-1] + } else if coalescesDown { + // We have a neighbor at a lower address only and it borders us. + // Merge the new space into a.ranges[i-1]. + a.ranges[i-1].limit = r.limit + } else if coalescesUp { + // We have a neighbor at a higher address only and it borders us. + // Merge the new space into a.ranges[i]. + a.ranges[i].base = r.base + } else { + // We may or may not have neighbors which don't border us. + // Add the new range. + if len(a.ranges)+1 > cap(a.ranges) { + // Grow the array. Note that this leaks the old array, but since + // we're doubling we have at most 2x waste. For a 1 TiB heap and + // 4 MiB arenas which are all discontiguous (both very conservative + // assumptions), this would waste at most 4 MiB of memory. + oldRanges := a.ranges + ranges := (*notInHeapSlice)(unsafe.Pointer(&a.ranges)) + ranges.len = len(oldRanges) + 1 + ranges.cap = cap(oldRanges) * 2 + ranges.array = (*notInHeap)(persistentalloc(unsafe.Sizeof(addrRange{})*uintptr(ranges.cap), sys.PtrSize, a.sysStat)) + + // Copy in the old array, but make space for the new range. + copy(a.ranges[:i], oldRanges[:i]) + copy(a.ranges[i+1:], oldRanges[i:]) + } else { + a.ranges = a.ranges[:len(a.ranges)+1] + copy(a.ranges[i+1:], a.ranges[i:]) + } + a.ranges[i] = r + } +} diff --git a/libgo/go/runtime/msize.go b/libgo/go/runtime/msize.go index 0accb83eb89..11d06ce0251 100644 --- a/libgo/go/runtime/msize.go +++ b/libgo/go/runtime/msize.go @@ -21,5 +21,5 @@ func roundupsize(size uintptr) uintptr { if size+_PageSize < size { return size } - return round(size, _PageSize) + return alignUp(size, _PageSize) } diff --git a/libgo/go/runtime/mstats.go b/libgo/go/runtime/mstats.go index cdab2ca7b87..2d4cdbe042c 100644 --- a/libgo/go/runtime/mstats.go +++ b/libgo/go/runtime/mstats.go @@ -31,7 +31,7 @@ type mstats struct { nfree uint64 // number of frees // Statistics about malloc heap. - // Protected by mheap.lock + // Updated atomically, or with the world stopped. // // Like MemStats, heap_sys and heap_inuse do not count memory // in manually-managed spans. @@ -40,19 +40,22 @@ type mstats struct { heap_idle uint64 // bytes in idle spans heap_inuse uint64 // bytes in mSpanInUse spans heap_released uint64 // bytes released to the os - heap_objects uint64 // total number of allocated objects + + // heap_objects is not used by the runtime directly and instead + // computed on the fly by updatememstats. + heap_objects uint64 // total number of allocated objects // Statistics about allocation of low-level fixed-size structures. // Protected by FixAlloc locks. - stacks_inuse uint64 // bytes in manually-managed stack spans + stacks_inuse uint64 // bytes in manually-managed stack spans; updated atomically or during STW stacks_sys uint64 // only counts newosproc0 stack in mstats; differs from MemStats.StackSys mspan_inuse uint64 // mspan structures mspan_sys uint64 mcache_inuse uint64 // mcache structures mcache_sys uint64 buckhash_sys uint64 // profiling bucket hash table - gc_sys uint64 - other_sys uint64 + gc_sys uint64 // updated atomically or during STW + other_sys uint64 // updated atomically or during STW // Statistics about garbage collector. // Protected by mheap or stopping the world during GC. @@ -79,6 +82,8 @@ type mstats struct { last_gc_nanotime uint64 // last gc (monotonic time) tinyallocs uint64 // number of tiny allocations that didn't cause actual allocation; not exported to go directly + last_next_gc uint64 // next_gc for the previous GC + last_heap_inuse uint64 // heap_inuse at mark termination of the previous GC // triggerRatio is the heap growth ratio that triggers marking. // diff --git a/libgo/go/runtime/nbpipe_pipe.go b/libgo/go/runtime/nbpipe_pipe.go new file mode 100644 index 00000000000..822b2944dbf --- /dev/null +++ b/libgo/go/runtime/nbpipe_pipe.go @@ -0,0 +1,19 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix darwin dragonfly + +package runtime + +func nonblockingPipe() (r, w int32, errno int32) { + r, w, errno = pipe() + if errno != 0 { + return -1, -1, errno + } + closeonexec(r) + setNonblock(r) + closeonexec(w) + setNonblock(w) + return r, w, errno +} diff --git a/libgo/go/runtime/nbpipe_pipe2.go b/libgo/go/runtime/nbpipe_pipe2.go new file mode 100644 index 00000000000..e3639d99b15 --- /dev/null +++ b/libgo/go/runtime/nbpipe_pipe2.go @@ -0,0 +1,22 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build freebsd linux netbsd openbsd solaris + +package runtime + +func nonblockingPipe() (r, w int32, errno int32) { + r, w, errno = pipe2(_O_NONBLOCK | _O_CLOEXEC) + if errno == -_ENOSYS { + r, w, errno = pipe() + if errno != 0 { + return -1, -1, errno + } + closeonexec(r) + setNonblock(r) + closeonexec(w) + setNonblock(w) + } + return r, w, errno +} diff --git a/libgo/go/runtime/nbpipe_test.go b/libgo/go/runtime/nbpipe_test.go new file mode 100644 index 00000000000..981143ec27b --- /dev/null +++ b/libgo/go/runtime/nbpipe_test.go @@ -0,0 +1,102 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris + +package runtime_test + +import ( + "runtime" + "syscall" + "testing" + "unsafe" +) + +func TestNonblockingPipe(t *testing.T) { + t.Parallel() + + // NonblockingPipe is the test name for nonblockingPipe. + r, w, errno := runtime.NonblockingPipe() + if errno != 0 { + t.Fatal(syscall.Errno(errno)) + } + defer func() { + runtime.Close(r) + runtime.Close(w) + }() + + checkIsPipe(t, r, w) + checkNonblocking(t, r, "reader") + checkCloseonexec(t, r, "reader") + checkNonblocking(t, w, "writer") + checkCloseonexec(t, w, "writer") +} + +func checkIsPipe(t *testing.T, r, w int32) { + bw := byte(42) + if n := runtime.Write(uintptr(w), unsafe.Pointer(&bw), 1); n != 1 { + t.Fatalf("Write(w, &b, 1) == %d, expected 1", n) + } + var br byte + if n := runtime.Read(r, unsafe.Pointer(&br), 1); n != 1 { + t.Fatalf("Read(r, &b, 1) == %d, expected 1", n) + } + if br != bw { + t.Errorf("pipe read %d, expected %d", br, bw) + } +} + +func checkNonblocking(t *testing.T, fd int32, name string) { + t.Helper() + flags, errno := fcntl(uintptr(fd), syscall.F_GETFL, 0) + if errno != 0 { + t.Errorf("fcntl(%s, F_GETFL) failed: %v", name, syscall.Errno(errno)) + } else if flags&syscall.O_NONBLOCK == 0 { + t.Errorf("O_NONBLOCK not set in %s flags %#x", name, flags) + } +} + +func checkCloseonexec(t *testing.T, fd int32, name string) { + t.Helper() + flags, errno := fcntl(uintptr(fd), syscall.F_GETFD, 0) + if errno != 0 { + t.Errorf("fcntl(%s, F_GETFD) failed: %v", name, syscall.Errno(errno)) + } else if flags&syscall.FD_CLOEXEC == 0 { + t.Errorf("FD_CLOEXEC not set in %s flags %#x", name, flags) + } +} + +func TestSetNonblock(t *testing.T) { + t.Parallel() + + r, w, errno := runtime.Pipe() + if errno != 0 { + t.Fatal(syscall.Errno(errno)) + } + defer func() { + runtime.Close(r) + runtime.Close(w) + }() + + checkIsPipe(t, r, w) + + runtime.SetNonblock(r) + runtime.SetNonblock(w) + checkNonblocking(t, r, "reader") + checkNonblocking(t, w, "writer") + + runtime.Closeonexec(r) + runtime.Closeonexec(w) + checkCloseonexec(t, r, "reader") + checkCloseonexec(t, w, "writer") +} + +//extern __go_fcntl_uintptr +func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr) + +// Call fcntl libc function rather than calling syscall. +func fcntl(fd uintptr, cmd int, arg uintptr) (uintptr, syscall.Errno) { + res, errno := fcntlUintptr(fd, uintptr(cmd), arg) + return res, syscall.Errno(errno) +} diff --git a/libgo/go/runtime/netpoll.go b/libgo/go/runtime/netpoll.go index 1ce98082d10..d2fb77569d6 100644 --- a/libgo/go/runtime/netpoll.go +++ b/libgo/go/runtime/netpoll.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris windows +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris windows package runtime @@ -15,12 +15,26 @@ import ( //go:linkname netpoll // Integrated network poller (platform-independent part). -// A particular implementation (epoll/kqueue) must define the following functions: -// func netpollinit() // to initialize the poller -// func netpollopen(fd uintptr, pd *pollDesc) int32 // to arm edge-triggered notifications -// and associate fd with pd. -// An implementation must call the following function to denote that the pd is ready. -// func netpollready(gpp **g, pd *pollDesc, mode int32) +// A particular implementation (epoll/kqueue/port/AIX/Windows) +// must define the following functions: +// +// func netpollinit() +// Initialize the poller. Only called once. +// +// func netpollopen(fd uintptr, pd *pollDesc) int32 +// Arm edge-triggered notifications for fd. The pd argument is to pass +// back to netpollready when fd is ready. Return an errno value. +// +// func netpoll(delta int64) gList +// Poll the network. If delta < 0, block indefinitely. If delta == 0, +// poll without blocking. If delta > 0, block for up to delta nanoseconds. +// Return a list of goroutines built by calling netpollready. +// +// func netpollBreak() +// Wake up the network poller, assumed to be blocked in netpoll. +// +// func netpollIsPollDescriptor(fd uintptr) bool +// Reports whether fd is a file descriptor used by the poller. // pollDesc contains 2 binary semaphores, rg and wg, to park reader and writer // goroutines respectively. The semaphore can be in the following states: @@ -82,15 +96,27 @@ type pollCache struct { } var ( - netpollInited uint32 + netpollInitLock mutex + netpollInited uint32 + pollcache pollCache netpollWaiters uint32 ) //go:linkname poll_runtime_pollServerInit internal..z2fpoll.runtime_pollServerInit func poll_runtime_pollServerInit() { - netpollinit() - atomic.Store(&netpollInited, 1) + netpollGenericInit() +} + +func netpollGenericInit() { + if atomic.Load(&netpollInited) == 0 { + lock(&netpollInitLock) + if netpollInited == 0 { + netpollinit() + atomic.Store(&netpollInited, 1) + } + unlock(&netpollInitLock) + } } func netpollinited() bool { @@ -102,14 +128,7 @@ func netpollinited() bool { // poll_runtime_isPollServerDescriptor reports whether fd is a // descriptor being used by netpoll. func poll_runtime_isPollServerDescriptor(fd uintptr) bool { - fds := netpolldescriptor() - if GOOS != "aix" && GOOS != "hurd" { - return fd == fds - } else { - // AIX have a pipe in its netpoll implementation. - // Therefore, two fd are returned by netpolldescriptor using a mask. - return fd == fds&0xFFFF || fd == (fds>>16)&0xFFFF - } + return netpollIsPollDescriptor(fd) } //go:linkname poll_runtime_pollOpen internal..z2fpoll.runtime_pollOpen @@ -240,13 +259,12 @@ func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) { if pd.rt.f == nil { if pd.rd > 0 { pd.rt.f = rtf - pd.rt.when = pd.rd // Copy current seq into the timer arg. // Timer func will check the seq against current descriptor seq, // if they differ the descriptor was reused or timers were reset. pd.rt.arg = pd pd.rt.seq = pd.rseq - addtimer(&pd.rt) + resettimer(&pd.rt, pd.rd) } } else if pd.rd != rd0 || combo != combo0 { pd.rseq++ // invalidate current timers @@ -260,10 +278,9 @@ func poll_runtime_pollSetDeadline(ctx uintptr, d int64, mode int) { if pd.wt.f == nil { if pd.wd > 0 && !combo { pd.wt.f = netpollWriteDeadline - pd.wt.when = pd.wd pd.wt.arg = pd pd.wt.seq = pd.wseq - addtimer(&pd.wt) + resettimer(&pd.wt, pd.wd) } } else if pd.wd != wd0 || combo != combo0 { pd.wseq++ // invalidate current timers @@ -325,8 +342,13 @@ func poll_runtime_pollUnblock(ctx uintptr) { } } -// make pd ready, newly runnable goroutines (if any) are added to toRun. -// May run during STW, so write barriers are not allowed. +// netpollready is called by the platform-specific netpoll function. +// It declares that the fd associated with pd is ready for I/O. +// The toRun argument is used to build a list of goroutines to return +// from netpoll. The mode argument is 'r', 'w', or 'r'+'w' to indicate +// whether the fd is ready for reading or writing or both. +// +// This may run while the world is stopped, so write barriers are not allowed. //go:nowritebarrier func netpollready(toRun *gList, pd *pollDesc, mode int32) { var rg, wg *g diff --git a/libgo/go/runtime/netpoll_aix.go b/libgo/go/runtime/netpoll_aix.go index 39e36c70274..a00742e39ae 100644 --- a/libgo/go/runtime/netpoll_aix.go +++ b/libgo/go/runtime/netpoll_aix.go @@ -14,18 +14,6 @@ import "unsafe" //extern poll func libc_poll(pfds *pollfd, npfds uintptr, timeout uintptr) int32 -//go:noescape -//extern pipe -func libc_pipe(fd *int32) int32 - -//extern __go_fcntl_uintptr -func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr) - -func fcntl(fd, cmd int32, arg uintptr) int32 { - r, _ := fcntlUintptr(uintptr(fd), uintptr(cmd), arg) - return int32(r) -} - // pollfd represents the poll structure for AIX operating system. type pollfd struct { fd int32 @@ -49,22 +37,13 @@ var ( ) func netpollinit() { - var p [2]int32 - // Create the pipe we use to wakeup poll. - if err := libc_pipe(&p[0]); err < 0 { + r, w, errno := nonblockingPipe() + if errno != 0 { throw("netpollinit: failed to create pipe") } - rdwake = p[0] - wrwake = p[1] - - fl := uintptr(fcntl(rdwake, _F_GETFL, 0)) - fcntl(rdwake, _F_SETFL, fl|_O_NONBLOCK) - fcntl(rdwake, _F_SETFD, _FD_CLOEXEC) - - fl = uintptr(fcntl(wrwake, _F_GETFL, 0)) - fcntl(wrwake, _F_SETFL, fl|_O_NONBLOCK) - fcntl(wrwake, _F_SETFD, _FD_CLOEXEC) + rdwake = r + wrwake = w // Pre-allocate array of pollfd structures for poll. pfds = make([]pollfd, 1, 128) @@ -77,12 +56,8 @@ func netpollinit() { pds[0] = nil } -func netpolldescriptor() uintptr { - // Both fd must be returned - if rdwake > 0xFFFF || wrwake > 0xFFFF { - throw("netpolldescriptor: invalid fd number") - } - return uintptr(rdwake<<16 | wrwake) +func netpollIsPollDescriptor(fd uintptr) bool { + return fd == uintptr(rdwake) || fd == uintptr(wrwake) } // netpollwakeup writes on wrwake to wakeup poll before any changes. @@ -146,12 +121,32 @@ func netpollarm(pd *pollDesc, mode int) { unlock(&mtxset) } +// netpollBreak interrupts an epollwait. +func netpollBreak() { + netpollwakeup() +} + +// netpoll checks for ready network connections. +// Returns list of goroutines that become runnable. +// delay < 0: blocks indefinitely +// delay == 0: does not block, just polls +// delay > 0: block for up to that many nanoseconds //go:nowritebarrierrec -func netpoll(block bool) gList { - timeout := ^uintptr(0) - if !block { - timeout = 0 +func netpoll(delay int64) gList { + var timeout uintptr + if delay < 0 { + timeout = ^uintptr(0) + } else if delay == 0 { + // TODO: call poll with timeout == 0 return gList{} + } else if delay < 1e6 { + timeout = 1 + } else if delay < 1e15 { + timeout = uintptr(delay / 1e6) + } else { + // An arbitrary cap on how long to wait for a timer. + // 1e9 ms == ~11.5 days. + timeout = 1e9 } retry: lock(&mtxpoll) @@ -167,20 +162,29 @@ retry: throw("poll failed") } unlock(&mtxset) + // If a timed sleep was interrupted, just return to + // recalculate how long we should sleep now. + if timeout > 0 { + return gList{} + } goto retry } // Check if some descriptors need to be changed if n != 0 && pfds[0].revents&(_POLLIN|_POLLHUP|_POLLERR) != 0 { - var b [1]byte - for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 { + if delay != 0 { + // A netpollwakeup could be picked up by a + // non-blocking poll. Only clear the wakeup + // if blocking. + var b [1]byte + for read(rdwake, unsafe.Pointer(&b[0]), 1) == 1 { + } } - // Do not look at the other fds in this case as the mode may have changed - // XXX only additions of flags are made, so maybe it is ok - unlock(&mtxset) - goto retry + // Still look at the other fds even if the mode may have + // changed, as netpollBreak might have been called. + n-- } var toRun gList - for i := 0; i < len(pfds) && n > 0; i++ { + for i := 1; i < len(pfds) && n > 0; i++ { pfd := &pfds[i] var mode int32 @@ -202,8 +206,5 @@ retry: } } unlock(&mtxset) - if block && toRun.empty() { - goto retry - } return toRun } diff --git a/libgo/go/runtime/netpoll_epoll.go b/libgo/go/runtime/netpoll_epoll.go index 885ac1fe1e5..7b215f31871 100644 --- a/libgo/go/runtime/netpoll_epoll.go +++ b/libgo/go/runtime/netpoll_epoll.go @@ -22,33 +22,44 @@ func epollctl(epfd, op, fd int32, ev *epollevent) int32 //extern epoll_wait func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32 -//extern __go_fcntl_uintptr -func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr) - -func closeonexec(fd int32) { - fcntlUintptr(uintptr(fd), _F_SETFD, _FD_CLOEXEC) -} - var ( epfd int32 = -1 // epoll descriptor + + netpollBreakRd, netpollBreakWr uintptr // for netpollBreak ) func netpollinit() { epfd = epollcreate1(_EPOLL_CLOEXEC) - if epfd >= 0 { - return - } - epfd = epollcreate(1024) - if epfd >= 0 { + if epfd < 0 { + epfd = epollcreate(1024) + if epfd < 0 { + println("runtime: epollcreate failed with", -epfd) + throw("runtime: netpollinit failed") + } closeonexec(epfd) - return } - println("netpollinit: failed to create epoll descriptor", errno()) - throw("netpollinit: failed to create descriptor") + r, w, cerrno := nonblockingPipe() + if cerrno != 0 { + println("runtime: pipe failed with", cerrno) + throw("runtime: pipe failed") + } + ev := epollevent{ + events: _EPOLLIN, + } + *(**uintptr)(unsafe.Pointer(&ev.data)) = &netpollBreakRd + if epollctl(epfd, _EPOLL_CTL_ADD, r, &ev) < 0 { + cerrno = int32(errno()) + } + if cerrno != 0 { + println("runtime: epollctl failed with", cerrno) + throw("runtime: epollctl failed") + } + netpollBreakRd = uintptr(r) + netpollBreakWr = uintptr(w) } -func netpolldescriptor() uintptr { - return uintptr(epfd) +func netpollIsPollDescriptor(fd uintptr) bool { + return fd == uintptr(epfd) || fd == netpollBreakRd || fd == netpollBreakWr } func netpollopen(fd uintptr, pd *pollDesc) int32 { @@ -73,15 +84,47 @@ func netpollarm(pd *pollDesc, mode int) { throw("runtime: unused") } -// polls for ready network connections -// returns list of goroutines that become runnable -func netpoll(block bool) gList { +// netpollBreak interrupts an epollwait. +func netpollBreak() { + for { + var b byte + n := write(netpollBreakWr, unsafe.Pointer(&b), 1) + if n == 1 { + break + } + if n == -_EINTR { + continue + } + if n == -_EAGAIN { + return + } + println("runtime: netpollBreak write failed with", -n) + throw("runtime: netpollBreak write failed") + } +} + +// netpoll checks for ready network connections. +// Returns list of goroutines that become runnable. +// delay < 0: blocks indefinitely +// delay == 0: does not block, just polls +// delay > 0: block for up to that many nanoseconds +func netpoll(delay int64) gList { if epfd == -1 { return gList{} } - waitms := int32(-1) - if !block { + var waitms int32 + if delay < 0 { + waitms = -1 + } else if delay == 0 { waitms = 0 + } else if delay < 1e6 { + waitms = 1 + } else if delay < 1e15 { + waitms = int32(delay / 1e6) + } else { + // An arbitrary cap on how long to wait for a timer. + // 1e9 ms == ~11.5 days. + waitms = 1e9 } var events [128]epollevent retry: @@ -92,6 +135,11 @@ retry: println("runtime: epollwait on fd", epfd, "failed with", e) throw("runtime: netpoll failed") } + // If a timed sleep was interrupted, just return to + // recalculate how long we should sleep now. + if waitms > 0 { + return gList{} + } goto retry } var toRun gList @@ -100,6 +148,22 @@ retry: if ev.events == 0 { continue } + + if *(**uintptr)(unsafe.Pointer(&ev.data)) == &netpollBreakRd { + if ev.events != _EPOLLIN { + println("runtime: netpoll: break fd ready for", ev.events) + throw("runtime: netpoll: break fd ready for something unexpected") + } + if delay != 0 { + // netpollBreak could be picked up by a + // nonblocking poll. Only read the byte + // if blocking. + var tmp [16]byte + read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp))) + } + continue + } + var mode int32 if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 { mode += 'r' @@ -116,8 +180,5 @@ retry: netpollready(&toRun, pd, mode) } } - if block && toRun.empty() { - goto retry - } return toRun } diff --git a/libgo/go/runtime/netpoll_fake.go b/libgo/go/runtime/netpoll_fake.go index 5b1a63a8787..b2af3b89b2c 100644 --- a/libgo/go/runtime/netpoll_fake.go +++ b/libgo/go/runtime/netpoll_fake.go @@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Fake network poller for NaCl and wasm/js. -// Should never be used, because NaCl and wasm/js network connections do not honor "SetNonblock". +// Fake network poller for wasm/js. +// Should never be used, because wasm/js network connections do not honor "SetNonblock". -// +build nacl js,wasm +// +build js,wasm package runtime func netpollinit() { } -func netpolldescriptor() uintptr { - return ^uintptr(0) +func netpollIsPollDescriptor(fd uintptr) bool { + return false } func netpollopen(fd uintptr, pd *pollDesc) int32 { @@ -27,6 +27,9 @@ func netpollclose(fd uintptr) int32 { func netpollarm(pd *pollDesc, mode int) { } -func netpoll(block bool) gList { +func netpollBreak() { +} + +func netpoll(delay int64) gList { return gList{} } diff --git a/libgo/go/runtime/netpoll_kqueue.go b/libgo/go/runtime/netpoll_kqueue.go index ce1acdf0cf5..94504613787 100644 --- a/libgo/go/runtime/netpoll_kqueue.go +++ b/libgo/go/runtime/netpoll_kqueue.go @@ -17,16 +17,10 @@ func kqueue() int32 //extern kevent func kevent(kq int32, ch *keventt, nch uintptr, ev *keventt, nev uintptr, ts *timespec) int32 -//extern __go_fcntl_uintptr -func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr) - -//go:nosplit -func closeonexec(fd int32) { - fcntlUintptr(uintptr(fd), _F_SETFD, _FD_CLOEXEC) -} - var ( kq int32 = -1 + + netpollBreakRd, netpollBreakWr uintptr // for netpollBreak ) func netpollinit() { @@ -36,10 +30,27 @@ func netpollinit() { throw("runtime: netpollinit failed") } closeonexec(kq) + r, w, errno := nonblockingPipe() + if errno != 0 { + println("runtime: pipe failed with", -errno) + throw("runtime: pipe failed") + } + ev := keventt{ + filter: _EVFILT_READ, + flags: _EV_ADD, + } + *(*uintptr)(unsafe.Pointer(&ev.ident)) = uintptr(r) + n := kevent(kq, &ev, 1, nil, 0, nil) + if n < 0 { + println("runtime: kevent failed with", -n) + throw("runtime: kevent failed") + } + netpollBreakRd = uintptr(r) + netpollBreakWr = uintptr(w) } -func netpolldescriptor() uintptr { - return uintptr(kq) +func netpollIsPollDescriptor(fd uintptr) bool { + return fd == uintptr(kq) || fd == netpollBreakRd || fd == netpollBreakWr } func netpollopen(fd uintptr, pd *pollDesc) int32 { @@ -72,15 +83,43 @@ func netpollarm(pd *pollDesc, mode int) { throw("runtime: unused") } -// Polls for ready network connections. +// netpollBreak interrupts an epollwait. +func netpollBreak() { + for { + var b byte + n := write(netpollBreakWr, unsafe.Pointer(&b), 1) + if n == 1 || n == -_EAGAIN { + break + } + if n == -_EINTR { + continue + } + println("runtime: netpollBreak write failed with", -n) + throw("runtime: netpollBreak write failed") + } +} + +// netpoll checks for ready network connections. // Returns list of goroutines that become runnable. -func netpoll(block bool) gList { +// delay < 0: blocks indefinitely +// delay == 0: does not block, just polls +// delay > 0: block for up to that many nanoseconds +func netpoll(delay int64) gList { if kq == -1 { return gList{} } var tp *timespec var ts timespec - if !block { + if delay < 0 { + tp = nil + } else if delay == 0 { + tp = &ts + } else { + ts.setNsec(delay) + if ts.tv_sec > 1e6 { + // Darwin returns EINVAL if the sleep time is too long. + ts.tv_sec = 1e6 + } tp = &ts } var events [64]keventt @@ -92,11 +131,32 @@ retry: println("runtime: kevent on fd", kq, "failed with", e) throw("runtime: netpoll failed") } + // If a timed sleep was interrupted, just return to + // recalculate how long we should sleep now. + if delay > 0 { + return gList{} + } goto retry } var toRun gList for i := 0; i < int(n); i++ { ev := &events[i] + + if uintptr(ev.ident) == netpollBreakRd { + if ev.filter != _EVFILT_READ { + println("runtime: netpoll: break fd ready for", ev.filter) + throw("runtime: netpoll: break fd ready for something unexpected") + } + if delay != 0 { + // netpollBreak could be picked up by a + // nonblocking poll. Only read the byte + // if blocking. + var tmp [16]byte + read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp))) + } + continue + } + var mode int32 switch ev.filter { case _EVFILT_READ: @@ -126,8 +186,5 @@ retry: netpollready(&toRun, pd, mode) } } - if block && toRun.empty() { - goto retry - } return toRun } diff --git a/libgo/go/runtime/netpoll_solaris.go b/libgo/go/runtime/netpoll_solaris.go index 222af29b73e..acb8bab77b6 100644 --- a/libgo/go/runtime/netpoll_solaris.go +++ b/libgo/go/runtime/netpoll_solaris.go @@ -67,14 +67,6 @@ import "unsafe" // again we know for sure we are always talking about the same file // descriptor and can safely access the data we want (the event set). -//extern __go_fcntl_uintptr -func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr) - -func fcntl(fd, cmd int32, arg uintptr) int32 { - r, _ := fcntlUintptr(uintptr(fd), uintptr(cmd), arg) - return int32(r) -} - //extern port_create func port_create() int32 @@ -88,12 +80,15 @@ func port_dissociate(port, source int32, object uintptr) int32 //extern port_getn func port_getn(port int32, evs *portevent, max uint32, nget *uint32, timeout *timespec) int32 +//extern port_alert +func port_alert(port int32, flags, events uint32, user uintptr) int32 + var portfd int32 = -1 func netpollinit() { portfd = port_create() if portfd >= 0 { - fcntl(portfd, _F_SETFD, _FD_CLOEXEC) + closeonexec(portfd) return } @@ -101,8 +96,8 @@ func netpollinit() { throw("runtime: netpollinit failed") } -func netpolldescriptor() uintptr { - return uintptr(portfd) +func netpollIsPollDescriptor(fd uintptr) bool { + return fd == uintptr(portfd) } func netpollopen(fd uintptr, pd *pollDesc) int32 { @@ -164,27 +159,68 @@ func netpollarm(pd *pollDesc, mode int) { unlock(&pd.lock) } -// polls for ready network connections -// returns list of goroutines that become runnable -func netpoll(block bool) gList { +// netpollBreak interrupts a port_getn wait. +func netpollBreak() { + // Use port_alert to put portfd into alert mode. + // This will wake up all threads sleeping in port_getn on portfd, + // and cause their calls to port_getn to return immediately. + // Further, until portfd is taken out of alert mode, + // all calls to port_getn will return immediately. + if port_alert(portfd, _PORT_ALERT_UPDATE, _POLLHUP, uintptr(unsafe.Pointer(&portfd))) < 0 { + if e := errno(); e != _EBUSY { + println("runtime: port_alert failed with", e) + throw("runtime: netpoll: port_alert failed") + } + } +} + +// netpoll checks for ready network connections. +// Returns list of goroutines that become runnable. +// delay < 0: blocks indefinitely +// delay == 0: does not block, just polls +// delay > 0: block for up to that many nanoseconds +func netpoll(delay int64) gList { if portfd == -1 { return gList{} } var wait *timespec - var zero timespec - if !block { - wait = &zero + var ts timespec + if delay < 0 { + wait = nil + } else if delay == 0 { + wait = &ts + } else { + ts.setNsec(delay) + if ts.tv_sec > 1e6 { + // An arbitrary cap on how long to wait for a timer. + // 1e6 s == ~11.5 days. + ts.tv_sec = 1e6 + } + wait = &ts } var events [128]portevent retry: var n uint32 = 1 - if port_getn(portfd, &events[0], uint32(len(events)), &n, wait) < 0 { - if e := errno(); e != _EINTR { + r := port_getn(portfd, &events[0], uint32(len(events)), &n, wait) + e := errno() + if r < 0 && e == _ETIME && n > 0 { + // As per port_getn(3C), an ETIME failure does not preclude the + // delivery of some number of events. Treat a timeout failure + // with delivered events as a success. + r = 0 + } + if r < 0 { + if e != _EINTR && e != _ETIME { print("runtime: port_getn on fd ", portfd, " failed (errno=", e, ")\n") throw("runtime: netpoll failed") } + // If a timed sleep was interrupted and there are no events, + // just return to recalculate how long we should sleep now. + if delay > 0 { + return gList{} + } goto retry } @@ -192,6 +228,24 @@ retry: for i := 0; i < int(n); i++ { ev := &events[i] + if ev.portev_source == _PORT_SOURCE_ALERT { + if ev.portev_events != _POLLHUP || unsafe.Pointer(ev.portev_user) != unsafe.Pointer(&portfd) { + throw("runtime: netpoll: bad port_alert wakeup") + } + if delay != 0 { + // Now that a blocking call to netpoll + // has seen the alert, take portfd + // back out of alert mode. + // See the comment in netpollBreak. + if port_alert(portfd, 0, 0, 0) < 0 { + e := errno() + println("runtime: port_alert failed with", e) + throw("runtime: netpoll: port_alert failed") + } + } + continue + } + if ev.portev_events == 0 { continue } @@ -228,8 +282,5 @@ retry: } } - if block && toRun.empty() { - goto retry - } return toRun } diff --git a/libgo/go/runtime/netpoll_stub.go b/libgo/go/runtime/netpoll_stub.go index f585333579d..fe45cfbd400 100644 --- a/libgo/go/runtime/netpoll_stub.go +++ b/libgo/go/runtime/netpoll_stub.go @@ -6,16 +6,42 @@ package runtime +import "runtime/internal/atomic" + +var netpollInited uint32 var netpollWaiters uint32 +var netpollStubLock mutex +var netpollNote note +var netpollBroken uint32 + +func netpollGenericInit() { + atomic.Store(&netpollInited, 1) +} + +func netpollBreak() { + if atomic.Cas(&netpollBroken, 0, 1) { + notewakeup(&netpollNote) + } +} + // Polls for ready network connections. // Returns list of goroutines that become runnable. -func netpoll(block bool) gList { +func netpoll(delay int64) gList { // Implementation for platforms that do not support // integrated network poller. + if delay != 0 { + // This lock ensures that only one goroutine tries to use + // the note. It should normally be completely uncontended. + lock(&netpollStubLock) + noteclear(&netpollNote) + atomic.Store(&netpollBroken, 0) + notetsleep(&netpollNote, delay) + unlock(&netpollStubLock) + } return gList{} } func netpollinited() bool { - return false + return atomic.Load(&netpollInited) != 0 } diff --git a/libgo/go/runtime/netpoll_windows.go b/libgo/go/runtime/netpoll_windows.go index 07ef15ce2f3..ced52cbd3a3 100644 --- a/libgo/go/runtime/netpoll_windows.go +++ b/libgo/go/runtime/netpoll_windows.go @@ -41,8 +41,8 @@ func netpollinit() { } } -func netpolldescriptor() uintptr { - return iocphandle +func netpollIsPollDescriptor(fd uintptr) bool { + return fd == iocphandle } func netpollopen(fd uintptr, pd *pollDesc) int32 { @@ -61,9 +61,19 @@ func netpollarm(pd *pollDesc, mode int) { throw("runtime: unused") } -// Polls for completed network IO. +func netpollBreak() { + if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 { + println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")") + throw("runtime: netpoll: PostQueuedCompletionStatus failed") + } +} + +// netpoll checks for ready network connections. // Returns list of goroutines that become runnable. -func netpoll(block bool) gList { +// delay < 0: blocks indefinitely +// delay == 0: does not block, just polls +// delay > 0: block for up to that many nanoseconds +func netpoll(delay int64) gList { var entries [64]overlappedEntry var wait, qty, key, flags, n, i uint32 var errno int32 @@ -75,23 +85,32 @@ func netpoll(block bool) gList { if iocphandle == _INVALID_HANDLE_VALUE { return gList{} } - wait = 0 - if block { + if delay < 0 { wait = _INFINITE + } else if delay == 0 { + wait = 0 + } else if delay < 1e6 { + wait = 1 + } else if delay < 1e15 { + wait = uint32(delay / 1e6) + } else { + // An arbitrary cap on how long to wait for a timer. + // 1e9 ms == ~11.5 days. + wait = 1e9 } -retry: + if _GetQueuedCompletionStatusEx != nil { n = uint32(len(entries) / int(gomaxprocs)) if n < 8 { n = 8 } - if block { + if delay != 0 { mp.blocked = true } if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 { mp.blocked = false errno = int32(getlasterror()) - if !block && errno == _WAIT_TIMEOUT { + if errno == _WAIT_TIMEOUT { return gList{} } println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")") @@ -100,24 +119,32 @@ retry: mp.blocked = false for i = 0; i < n; i++ { op = entries[i].op - errno = 0 - qty = 0 - if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 { - errno = int32(getlasterror()) + if op != nil { + errno = 0 + qty = 0 + if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 { + errno = int32(getlasterror()) + } + handlecompletion(&toRun, op, errno, qty) + } else { + if delay == 0 { + // Forward the notification to the + // blocked poller. + netpollBreak() + } } - handlecompletion(&toRun, op, errno, qty) } } else { op = nil errno = 0 qty = 0 - if block { + if delay != 0 { mp.blocked = true } if stdcall5(_GetQueuedCompletionStatus, iocphandle, uintptr(unsafe.Pointer(&qty)), uintptr(unsafe.Pointer(&key)), uintptr(unsafe.Pointer(&op)), uintptr(wait)) == 0 { mp.blocked = false errno = int32(getlasterror()) - if !block && errno == _WAIT_TIMEOUT { + if errno == _WAIT_TIMEOUT { return gList{} } if op == nil { @@ -127,11 +154,16 @@ retry: // dequeued failed IO packet, so report that } mp.blocked = false + if op == nil { + if delay == 0 { + // Forward the notification to the + // blocked poller. + netpollBreak() + } + return gList{} + } handlecompletion(&toRun, op, errno, qty) } - if block && toRun.empty() { - goto retry - } return toRun } diff --git a/libgo/go/runtime/os3_solaris.go b/libgo/go/runtime/os3_solaris.go index d5fbccd36e7..001feed3e06 100644 --- a/libgo/go/runtime/os3_solaris.go +++ b/libgo/go/runtime/os3_solaris.go @@ -25,13 +25,6 @@ func getncpu() int32 { return n } -func osinit() { - ncpu = getncpu() - if physPageSize == 0 { - physPageSize = uintptr(getPageSize()) - } -} - func sysargs(argc int32, argv **byte) { executablePath = gostringnocopy(getexecname()) } diff --git a/libgo/go/runtime/os_darwin.go b/libgo/go/runtime/os_darwin.go index 498bd430e54..58e0412600c 100644 --- a/libgo/go/runtime/os_darwin.go +++ b/libgo/go/runtime/os_darwin.go @@ -6,24 +6,6 @@ package runtime import "unsafe" -//extern pipe -func libcPipe([2]int32) int32 - -func pipe() (r, w int32, e int32) { - var p [2]int32 - r := libcPipe(noescape(unsafe.Pointer(&p))) - if r < 0 { - e = int32(errno()) - } - return p[0], p[1], e -} - -//go:nosplit -func setNonblock(fd int32) { - flags := fcntlUintptr(uintptr(fd), _F_GETFL, 0) - fcntlUintptr(uintptr(fd), _F_SETFL, flags|_O_NONBLOCK) -} - type mOS struct { initialized bool mutex pthreadmutex diff --git a/libgo/go/runtime/os_freebsd_arm64.go b/libgo/go/runtime/os_freebsd_arm64.go new file mode 100644 index 00000000000..51ebf9d4784 --- /dev/null +++ b/libgo/go/runtime/os_freebsd_arm64.go @@ -0,0 +1,155 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +import "internal/cpu" + +const ( + hwcap_FP = 1 << 0 + hwcap_ASIMD = 1 << 1 + hwcap_EVTSTRM = 1 << 2 + hwcap_AES = 1 << 3 + hwcap_PMULL = 1 << 4 + hwcap_SHA1 = 1 << 5 + hwcap_SHA2 = 1 << 6 + hwcap_CRC32 = 1 << 7 + hwcap_ATOMICS = 1 << 8 + hwcap_FPHP = 1 << 9 + hwcap_ASIMDHP = 1 << 10 + hwcap_CPUID = 1 << 11 + hwcap_ASIMDRDM = 1 << 12 + hwcap_JSCVT = 1 << 13 + hwcap_FCMA = 1 << 14 + hwcap_LRCPC = 1 << 15 + hwcap_DCPOP = 1 << 16 + hwcap_SHA3 = 1 << 17 + hwcap_SM3 = 1 << 18 + hwcap_SM4 = 1 << 19 + hwcap_ASIMDDP = 1 << 20 + hwcap_SHA512 = 1 << 21 + hwcap_SVE = 1 << 22 + hwcap_ASIMDFHM = 1 << 23 +) + +func getisar0() uint64 +func getisar1() uint64 +func getpfr0() uint64 + +// no hwcap support on FreeBSD aarch64, we need to retrieve the info from +// ID_AA64ISAR0_EL1, ID_AA64ISAR1_EL1 and ID_AA64PFR0_EL1 +func archauxv(tag, val uintptr) { + var isar0, isar1, pfr0 uint64 + + isar0 = getisar0() + isar1 = getisar1() + pfr0 = getpfr0() + + // ID_AA64ISAR0_EL1 + switch extractBits(isar0, 4, 7) { + case 1: + cpu.HWCap |= hwcap_AES + case 2: + cpu.HWCap |= hwcap_PMULL | hwcap_AES + } + + switch extractBits(isar0, 8, 11) { + case 1: + cpu.HWCap |= hwcap_SHA1 + } + + switch extractBits(isar0, 12, 15) { + case 1: + cpu.HWCap |= hwcap_SHA2 + case 2: + cpu.HWCap |= hwcap_SHA2 | hwcap_SHA512 + } + + switch extractBits(isar0, 16, 19) { + case 1: + cpu.HWCap |= hwcap_CRC32 + } + + switch extractBits(isar0, 20, 23) { + case 2: + cpu.HWCap |= hwcap_ATOMICS + } + + switch extractBits(isar0, 28, 31) { + case 1: + cpu.HWCap |= hwcap_ASIMDRDM + } + + switch extractBits(isar0, 32, 35) { + case 1: + cpu.HWCap |= hwcap_SHA3 + } + + switch extractBits(isar0, 36, 39) { + case 1: + cpu.HWCap |= hwcap_SM3 + } + + switch extractBits(isar0, 40, 43) { + case 1: + cpu.HWCap |= hwcap_SM4 + } + + switch extractBits(isar0, 44, 47) { + case 1: + cpu.HWCap |= hwcap_ASIMDDP + } + + // ID_AA64ISAR1_EL1 + switch extractBits(isar1, 0, 3) { + case 1: + cpu.HWCap |= hwcap_DCPOP + } + + switch extractBits(isar1, 12, 15) { + case 1: + cpu.HWCap |= hwcap_JSCVT + } + + switch extractBits(isar1, 16, 19) { + case 1: + cpu.HWCap |= hwcap_FCMA + } + + switch extractBits(isar1, 20, 23) { + case 1: + cpu.HWCap |= hwcap_LRCPC + } + + // ID_AA64PFR0_EL1 + switch extractBits(pfr0, 16, 19) { + case 0: + cpu.HWCap |= hwcap_FP + case 1: + cpu.HWCap |= hwcap_FP | hwcap_FPHP + } + + switch extractBits(pfr0, 20, 23) { + case 0: + cpu.HWCap |= hwcap_ASIMD + case 1: + cpu.HWCap |= hwcap_ASIMD | hwcap_ASIMDHP + } + + switch extractBits(pfr0, 32, 35) { + case 1: + cpu.HWCap |= hwcap_SVE + } +} + +func extractBits(data uint64, start, end uint) uint { + return (uint)(data>>start) & ((1 << (end - start + 1)) - 1) +} + +//go:nosplit +func cputicks() int64 { + // Currently cputicks() is used in blocking profiler and to seed fastrand(). + // nanotime() is a poor approximation of CPU ticks that is enough for the profiler. + return nanotime() +} diff --git a/libgo/go/runtime/os_gccgo.go b/libgo/go/runtime/os_gccgo.go index ef33d679fe4..ab190229860 100644 --- a/libgo/go/runtime/os_gccgo.go +++ b/libgo/go/runtime/os_gccgo.go @@ -51,3 +51,45 @@ func getRandomData(r []byte) { closefd(fd) extendRandom(r, int(n)) } + +//go:noescape +//extern pipe +func libcPipe(*[2]int32) int32 + +func pipe() (r, w int32, e int32) { + var p [2]int32 + res := libcPipe(&p) + if res < 0 { + e = int32(errno()) + } + return p[0], p[1], e +} + +//go:noescape +//extern pipe2 +func libcPipe2(*[2]int32, int32) int32 + +func pipe2(flags int32) (r, w int32, e int32) { + var p [2]int32 + res := libcPipe2(&p, flags) + if res < 0 { + e = int32(errno()) + } + return p[0], p[1], e +} + +//extern __go_fcntl_uintptr +func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr) + +//go:nosplit +func closeonexec(fd int32) { + fcntlUintptr(uintptr(fd), _F_SETFD, _FD_CLOEXEC) +} + +//go:nosplit +func setNonblock(fd int32) { + flags, errno := fcntlUintptr(uintptr(fd), _F_GETFL, 0) + if errno == 0 { + fcntlUintptr(uintptr(fd), _F_SETFL, flags|_O_NONBLOCK) + } +} diff --git a/libgo/go/runtime/os_illumos.go b/libgo/go/runtime/os_illumos.go new file mode 100644 index 00000000000..ddcb8c9271a --- /dev/null +++ b/libgo/go/runtime/os_illumos.go @@ -0,0 +1,102 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime + +import ( + "unsafe" +) + +// Return the minimum value seen for the zone CPU cap, or 0 if no cap is +// detected. +func getcpucap() uint64 { + // The resource control block is an opaque object whose size is only + // known to libc. In practice, given the contents, it is unlikely to + // grow beyond 8KB so we'll use a static buffer of that size here. + const rblkmaxsize = 8 * 1024 + if rctlblk_size() > rblkmaxsize { + return 0 + } + + // The "zone.cpu-cap" resource control, as described in + // resource_controls(5), "sets a limit on the amount of CPU time that + // can be used by a zone. The unit used is the percentage of a single + // CPU that can be used by all user threads in a zone, expressed as an + // integer." A C string of the name must be passed to getrctl(2). + name := []byte("zone.cpu-cap\x00") + + // To iterate over the list of values for a particular resource + // control, we need two blocks: one for the previously read value and + // one for the next value. + var rblk0 [rblkmaxsize]byte + var rblk1 [rblkmaxsize]byte + rblk := &rblk0[0] + rblkprev := &rblk1[0] + + var flag uint32 = _RCTL_FIRST + var capval uint64 = 0 + + for { + if getrctl(unsafe.Pointer(&name[0]), unsafe.Pointer(rblkprev), unsafe.Pointer(rblk), flag) != 0 { + // The end of the sequence is reported as an ENOENT + // failure, but determining the CPU cap is not critical + // here. We'll treat any failure as if it were the end + // of sequence. + break + } + + lflags := rctlblk_get_local_flags(unsafe.Pointer(rblk)) + action := rctlblk_get_local_action(unsafe.Pointer(rblk), 0) + if (lflags&_RCTL_LOCAL_MAXIMAL) == 0 && action == _RCTL_LOCAL_DENY { + // This is a finite (not maximal) value representing a + // cap (deny) action. + v := rctlblk_get_value(unsafe.Pointer(rblk)) + if capval == 0 || capval > v { + capval = v + } + } + + // Swap the blocks around so that we can fetch the next value + t := rblk + rblk = rblkprev + rblkprev = t + flag = _RCTL_NEXT + } + + return capval +} + +func getncpu() int32 { + n := int32(sysconf(__SC_NPROCESSORS_ONLN)) + if n < 1 { + return 1 + } + + if cents := int32(getcpucap()); cents > 0 { + // Convert from a percentage of CPUs to a number of CPUs, + // rounding up to make use of a fractional CPU + // e.g., 336% becomes 4 CPUs + ncap := (cents + 99) / 100 + if ncap < n { + return ncap + } + } + + return n +} + +//extern getrctl +func getrctl(controlname, oldbuf, newbuf unsafe.Pointer, flags uint32) int32 + +//extern rctlblk_get_local_action +func rctlblk_get_local_action(buf, signalp unsafe.Pointer) uint32 + +//extern rctlblk_get_local_flags +func rctlblk_get_local_flags(buf unsafe.Pointer) uint32 + +//extern rctlblk_get_value +func rctlblk_get_value(buf unsafe.Pointer) uint64 + +//extern rctlblk_size +func rclblk_size() uintptr diff --git a/libgo/go/runtime/os_js.go b/libgo/go/runtime/os_js.go index ad6db18b747..ff0ee3aa6be 100644 --- a/libgo/go/runtime/os_js.go +++ b/libgo/go/runtime/os_js.go @@ -12,7 +12,7 @@ import ( func exit(code int32) -func write(fd uintptr, p unsafe.Pointer, n int32) int32 { +func write1(fd uintptr, p unsafe.Pointer, n int32) int32 { if fd > 2 { throw("runtime.write to fd > 2 is unsupported") } @@ -131,7 +131,6 @@ func os_sigpipe() { func cputicks() int64 { // Currently cputicks() is used in blocking profiler and to seed runtime·fastrand(). // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler. - // TODO: need more entropy to better seed fastrand. return nanotime() } @@ -143,3 +142,9 @@ func syscall_now() (sec int64, nsec int32) { // gsignalStack is unused on js. type gsignalStack struct{} + +const preemptMSupported = false + +func preemptM(mp *m) { + // No threads, so nothing to do. +} diff --git a/libgo/go/runtime/os_linux_arm.go b/libgo/go/runtime/os_linux_arm.go index 8de9d110934..0a9018861ac 100644 --- a/libgo/go/runtime/os_linux_arm.go +++ b/libgo/go/runtime/os_linux_arm.go @@ -6,16 +6,8 @@ package runtime import "internal/cpu" -var randomNumber uint32 - func archauxv(tag, val uintptr) { switch tag { - case _AT_RANDOM: - // sysargs filled in startupRandomData, but that - // pointer may not be word aligned, so we must treat - // it as a byte array. - randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 | - uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24 case _AT_HWCAP: cpu.HWCap = uint(val) case _AT_HWCAP2: diff --git a/libgo/go/runtime/os_linux_arm64.go b/libgo/go/runtime/os_linux_arm64.go index 30d63bfbdbc..a482d47acdd 100644 --- a/libgo/go/runtime/os_linux_arm64.go +++ b/libgo/go/runtime/os_linux_arm64.go @@ -8,17 +8,8 @@ package runtime import "internal/cpu" -var randomNumber uint32 - func archauxv(tag, val uintptr) { switch tag { - case _AT_RANDOM: - // sysargs filled in startupRandomData, but that - // pointer may not be word aligned, so we must treat - // it as a byte array. - randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 | - uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24 - case _AT_HWCAP: // arm64 doesn't have a 'cpuid' instruction equivalent and relies on // HWCAP/HWCAP2 bits for hardware capabilities. diff --git a/libgo/go/runtime/os_linux_mips64x.go b/libgo/go/runtime/os_linux_mips64x.go index b7f737fdf8e..2b59dcbf17c 100644 --- a/libgo/go/runtime/os_linux_mips64x.go +++ b/libgo/go/runtime/os_linux_mips64x.go @@ -7,15 +7,5 @@ package runtime -var randomNumber uint32 - func archauxv(tag, val uintptr) { - switch tag { - case _AT_RANDOM: - // sysargs filled in startupRandomData, but that - // pointer may not be word aligned, so we must treat - // it as a byte array. - randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 | - uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24 - } } diff --git a/libgo/go/runtime/os_linux_mipsx.go b/libgo/go/runtime/os_linux_mipsx.go index a2696deea1a..2bfd6f40cc9 100644 --- a/libgo/go/runtime/os_linux_mipsx.go +++ b/libgo/go/runtime/os_linux_mipsx.go @@ -7,15 +7,5 @@ package runtime -var randomNumber uint32 - func archauxv(tag, val uintptr) { - switch tag { - case _AT_RANDOM: - // sysargs filled in startupRandomData, but that - // pointer may not be word aligned, so we must treat - // it as a byte array. - randomNumber = uint32(startupRandomData[4]) | uint32(startupRandomData[5])<<8 | - uint32(startupRandomData[6])<<16 | uint32(startupRandomData[7])<<24 - } } diff --git a/libgo/go/runtime/os_netbsd_arm64.go b/libgo/go/runtime/os_netbsd_arm64.go index fd81eb7557d..8d21b0a430f 100644 --- a/libgo/go/runtime/os_netbsd_arm64.go +++ b/libgo/go/runtime/os_netbsd_arm64.go @@ -19,6 +19,5 @@ func lwp_mcontext_init(mc *mcontextt, stk unsafe.Pointer, mp *m, gp *g, fn uintp func cputicks() int64 { // Currently cputicks() is used in blocking profiler and to seed runtime·fastrand(). // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler. - // TODO: need more entropy to better seed fastrand. return nanotime() } diff --git a/libgo/go/runtime/os_only_solaris.go b/libgo/go/runtime/os_only_solaris.go new file mode 100644 index 00000000000..e2f5409354d --- /dev/null +++ b/libgo/go/runtime/os_only_solaris.go @@ -0,0 +1,18 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Solaris code that doesn't also apply to illumos. + +// +build !illumos + +package runtime + +func getncpu() int32 { + n := int32(sysconf(__SC_NPROCESSORS_ONLN)) + if n < 1 { + return 1 + } + + return n +} diff --git a/libgo/go/runtime/os_openbsd_arm64.go b/libgo/go/runtime/os_openbsd_arm64.go index f15a95b653f..d559a2a3e5a 100644 --- a/libgo/go/runtime/os_openbsd_arm64.go +++ b/libgo/go/runtime/os_openbsd_arm64.go @@ -12,7 +12,6 @@ import ( func cputicks() int64 { // Currently cputicks() is used in blocking profiler and to seed runtime·fastrand(). // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler. - // TODO: need more entropy to better seed fastrand. return nanotime() } diff --git a/libgo/go/runtime/panic.go b/libgo/go/runtime/panic.go index 9667181c99f..88c598ee980 100644 --- a/libgo/go/runtime/panic.go +++ b/libgo/go/runtime/panic.go @@ -50,7 +50,7 @@ import ( // pc should be the program counter of the compiler-generated code that // triggered this panic. func panicCheck1(pc uintptr, msg string) { - name, _, _, _ := funcfileline(pc-1, -1) + name, _, _, _ := funcfileline(pc-1, -1, false) if hasPrefix(name, "runtime.") { throw(msg) } @@ -548,6 +548,14 @@ func Goexit() { // for detailed comments. gp := getg() gp.goexiting = true + + // Create a panic object for Goexit, so we can recognize when it might be + // bypassed by a recover(). + var p _panic + p.goexit = true + p.link = gp._panic + gp._panic = (*_panic)(noescape(unsafe.Pointer(&p))) + for { d := gp._defer if d == nil { @@ -608,7 +616,12 @@ func preprintpanics(p *_panic) { func printpanics(p *_panic) { if p.link != nil { printpanics(p.link) - print("\t") + if !p.link.goexit { + print("\t") + } + } + if p.goexit { + return } print("panic: ") printany(p.arg) @@ -704,9 +717,12 @@ func gopanic(e interface{}) { d._panic = nil if p.recovered { - atomic.Xadd(&runningPanicDefers, -1) - gp._panic = p.link + if gp._panic != nil && gp._panic.goexit && gp._panic.aborted { + Goexit() + throw("Goexit returned") + } + atomic.Xadd(&runningPanicDefers, -1) // Aborted panics are marked but remain on the g.panic list. // Remove them from the list. @@ -717,6 +733,11 @@ func gopanic(e interface{}) { gp.sig = 0 } + if gp._panic != nil && gp._panic.goexit { + Goexit() + throw("Goexit returned") + } + // Unwind the stack by throwing an exception. // The compiler has arranged to create // exception handlers in each function @@ -922,7 +943,7 @@ func makefuncreturning() { func gorecover() interface{} { gp := getg() p := gp._panic - if p != nil && !p.recovered { + if p != nil && !p.goexit && !p.recovered { p.recovered = true return p.arg } diff --git a/libgo/go/runtime/pprof/label.go b/libgo/go/runtime/pprof/label.go index 20f9cdbae6f..2d92ef7e8a2 100644 --- a/libgo/go/runtime/pprof/label.go +++ b/libgo/go/runtime/pprof/label.go @@ -60,11 +60,11 @@ func Labels(args ...string) LabelSet { if len(args)%2 != 0 { panic("uneven number of arguments to pprof.Labels") } - labels := LabelSet{} + list := make([]label, 0, len(args)/2) for i := 0; i+1 < len(args); i += 2 { - labels.list = append(labels.list, label{key: args[i], value: args[i+1]}) + list = append(list, label{key: args[i], value: args[i+1]}) } - return labels + return LabelSet{list: list} } // Label returns the value of the label with the given key on ctx, and a boolean indicating diff --git a/libgo/go/runtime/pprof/label_test.go b/libgo/go/runtime/pprof/label_test.go index 240445f098e..de39d85d3af 100644 --- a/libgo/go/runtime/pprof/label_test.go +++ b/libgo/go/runtime/pprof/label_test.go @@ -24,7 +24,7 @@ func (s labelSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s labelSorter) Less(i, j int) bool { return s[i].key < s[j].key } func TestContextLabels(t *testing.T) { - // Background context starts with no lablels. + // Background context starts with no labels. ctx := context.Background() labels := labelsSorted(ctx) if len(labels) != 0 { diff --git a/libgo/go/runtime/pprof/mprof_test.go b/libgo/go/runtime/pprof/mprof_test.go index 6fe892b46f4..c352dea83ae 100644 --- a/libgo/go/runtime/pprof/mprof_test.go +++ b/libgo/go/runtime/pprof/mprof_test.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !js + package pprof import ( @@ -10,6 +12,7 @@ import ( "reflect" "regexp" "runtime" + "runtime/pprof/internal/profile" "testing" "unsafe" ) @@ -27,6 +30,10 @@ func allocateTransient2M() { memSink = make([]byte, 2<<20) } +func allocateTransient2MInline() { + memSink = make([]byte, 4<<20) +} + type Obj32 struct { link *Obj32 pad [32 - unsafe.Sizeof(uintptr(0))]byte @@ -71,47 +78,102 @@ func TestMemoryProfiler(t *testing.T) { // Do the interesting allocations. allocateTransient1M() allocateTransient2M() + allocateTransient2MInline() allocatePersistent1K() allocateReflect() memSink = nil runtime.GC() // materialize stats - var buf bytes.Buffer - if err := Lookup("heap").WriteTo(&buf, 1); err != nil { - t.Fatalf("failed to write heap profile: %v", err) - } memoryProfilerRun++ - tests := []string{ - - fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f x]+ -# 0x[0-9,a-f]+ pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:40 -# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test\.go:74 + tests := []struct { + stk []string + legacy string + }{{ + stk: []string{"pprof.allocatePersistent1K", "runtime/pprof.TestMemoryProfiler"}, + legacy: fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f x]+ +# 0x[0-9,a-f]+ pprof\.allocatePersistent1K\+0x[0-9,a-f]+ .*/mprof_test\.go:47 +# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test\.go:82 `, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun), - - fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f x]+ -# 0x[0-9,a-f]+ pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:21 -# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:72 -`, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun), - + }, { + stk: []string{"pprof.allocateTransient1M", "runtime/pprof.TestMemoryProfiler"}, + legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+ +# 0x[0-9,a-f]+ pprof\.allocateTransient1M\+0x[0-9,a-f]+ .*/mprof_test.go:24 +# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:79 +`, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun), + }, { + stk: []string{"pprof.allocateTransient2M", "runtime/pprof.TestMemoryProfiler"}, // This should start with "0: 0" but gccgo's imprecise // GC means that sometimes the value is not collected. - fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+ -# 0x[0-9,a-f]+ pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:27 -# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:73 + legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+ +# 0x[0-9,a-f]+ pprof\.allocateTransient2M\+0x[0-9,a-f]+ .*/mprof_test.go:30 +# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:80 `, memoryProfilerRun, (2<<20)*memoryProfilerRun, memoryProfilerRun, (2<<20)*memoryProfilerRun), - - // This should start with "0: 0" but gccgo's imprecise - // GC means that sometimes the value is not collected. - fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @( 0x[0-9,a-f]+)+ -# 0x[0-9,a-f]+ pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:48 + }, { + stk: []string{"pprof.allocateTransient2MInline", "runtime/pprof.TestMemoryProfiler"}, + legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @ 0x[0-9,a-f x]+ +# 0x[0-9,a-f]+ pprof\.allocateTransient2MInline\+0x[0-9,a-f]+ .*/mprof_test.go:34 +# 0x[0-9,a-f]+ runtime/pprof\.TestMemoryProfiler\+0x[0-9,a-f]+ .*/mprof_test.go:81 +`, memoryProfilerRun, (4<<20)*memoryProfilerRun, memoryProfilerRun, (4<<20)*memoryProfilerRun), + }, { + stk: []string{"pprof.allocateReflectTransient"}, + legacy: fmt.Sprintf(`(0|%v): (0|%v) \[%v: %v\] @( 0x[0-9,a-f]+)+ +# 0x[0-9,a-f]+ pprof\.allocateReflectTransient\+0x[0-9,a-f]+ .*/mprof_test.go:55 `, memoryProfilerRun, (3<<20)*memoryProfilerRun, memoryProfilerRun, (3<<20)*memoryProfilerRun), - } + }} - for _, test := range tests { - if !regexp.MustCompile(test).Match(buf.Bytes()) { - t.Fatalf("The entry did not match:\n%v\n\nProfile:\n%v\n", test, buf.String()) + t.Run("debug=1", func(t *testing.T) { + var buf bytes.Buffer + if err := Lookup("heap").WriteTo(&buf, 1); err != nil { + t.Fatalf("failed to write heap profile: %v", err) } - } + + for _, test := range tests { + if !regexp.MustCompile(test.legacy).Match(buf.Bytes()) { + t.Fatalf("The entry did not match:\n%v\n\nProfile:\n%v\n", test.legacy, buf.String()) + } + } + }) + + t.Run("proto", func(t *testing.T) { + var buf bytes.Buffer + if err := Lookup("heap").WriteTo(&buf, 0); err != nil { + t.Fatalf("failed to write heap profile: %v", err) + } + p, err := profile.Parse(&buf) + if err != nil { + t.Fatalf("failed to parse heap profile: %v", err) + } + t.Logf("Profile = %v", p) + + stks := stacks(p) + for _, test := range tests { + if !containsStack(stks, test.stk) { + t.Logf("stks:\n%v", stks) + t.Fatalf("No matching stack entry for %q\n\nProfile:\n%v\n", test.stk, p) + } + } + + if !containsInlinedCall(TestMemoryProfiler, 4<<10) { + t.Logf("Can't determine whether allocateTransient2MInline was inlined into TestMemoryProfiler.") + return + } + + // Check the inlined function location is encoded correctly. + for _, loc := range p.Location { + inlinedCaller, inlinedCallee := false, false + for _, line := range loc.Line { + if line.Function.Name == "runtime/pprof.allocateTransient2MInline" { + inlinedCallee = true + } + if inlinedCallee && line.Function.Name == "runtime/pprof.TestMemoryProfiler" { + inlinedCaller = true + } + } + if inlinedCallee != inlinedCaller { + t.Errorf("want allocateTransient2MInline after TestMemoryProfiler in one location, got separate location entries:\n%v", loc) + } + } + }) } diff --git a/libgo/go/runtime/pprof/pprof.go b/libgo/go/runtime/pprof/pprof.go index 996b3cbf468..183881cfd3e 100644 --- a/libgo/go/runtime/pprof/pprof.go +++ b/libgo/go/runtime/pprof/pprof.go @@ -28,7 +28,7 @@ // if err != nil { // log.Fatal("could not create CPU profile: ", err) // } -// defer f.Close() +// defer f.Close() // error handling omitted for example // if err := pprof.StartCPUProfile(f); err != nil { // log.Fatal("could not start CPU profile: ", err) // } @@ -42,7 +42,7 @@ // if err != nil { // log.Fatal("could not create memory profile: ", err) // } -// defer f.Close() +// defer f.Close() // error handling omitted for example // runtime.GC() // get up-to-date statistics // if err := pprof.WriteHeapProfile(f); err != nil { // log.Fatal("could not write memory profile: ", err) @@ -386,16 +386,9 @@ func printCountCycleProfile(w io.Writer, countName, cycleName string, scaler fun count, nanosec := scaler(r.Count, float64(r.Cycles)/cpuGHz) values[0] = count values[1] = int64(nanosec) - locs = locs[:0] - for _, addr := range r.Stack() { - // For count profiles, all stack addresses are - // return PCs, which is what locForPC expects. - l := b.locForPC(addr) - if l == 0 { // runtime.goexit - continue - } - locs = append(locs, l) - } + // For count profiles, all stack addresses are + // return PCs, which is what appendLocsForStack expects. + locs = b.appendLocsForStack(locs[:0], r.Stack()) b.pbSample(values, locs, nil) } b.build() @@ -451,16 +444,9 @@ func printCountProfile(w io.Writer, debug int, name string, p countProfile) erro var locs []uint64 for _, k := range keys { values[0] = int64(count[k]) - locs = locs[:0] - for _, addr := range p.Stack(index[k]) { - // For count profiles, all stack addresses are - // return PCs, which is what locForPC expects. - l := b.locForPC(addr) - if l == 0 { // runtime.goexit - continue - } - locs = append(locs, l) - } + // For count profiles, all stack addresses are + // return PCs, which is what appendLocsForStack expects. + locs = b.appendLocsForStack(locs[:0], p.Stack(index[k])) b.pbSample(values, locs, nil) } b.build() diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go index 49a555c82c8..bba9ee36c6a 100644 --- a/libgo/go/runtime/pprof/pprof_test.go +++ b/libgo/go/runtime/pprof/pprof_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !nacl,!js +// +build !js package pprof @@ -49,8 +49,12 @@ var ( // Must not call other functions nor access heap/globals in the loop, // otherwise under race detector the samples will be in the race runtime. func cpuHog1(x int) int { + return cpuHog0(x, 1e5) +} + +func cpuHog0(x, n int) int { foo := x - for i := 0; i < 1e5; i++ { + for i := 0; i < n; i++ { if foo > 0 { foo *= foo } else { @@ -100,35 +104,111 @@ func TestCPUProfileMultithreaded(t *testing.T) { }) } +// containsInlinedCall reports whether the function body for the function f is +// known to contain an inlined function call within the first maxBytes bytes. +func containsInlinedCall(f interface{}, maxBytes int) bool { + _, found := findInlinedCall(f, maxBytes) + return found +} + +// findInlinedCall returns the PC of an inlined function call within +// the function body for the function f if any. +func findInlinedCall(f interface{}, maxBytes int) (pc uint64, found bool) { + fFunc := runtime.FuncForPC(uintptr(funcPC(f))) + if fFunc == nil || fFunc.Entry() == 0 { + panic("failed to locate function entry") + } + + for offset := 0; offset < maxBytes; offset++ { + innerPC := fFunc.Entry() + uintptr(offset) + inner := runtime.FuncForPC(innerPC) + if inner == nil { + // No function known for this PC value. + // It might simply be misaligned, so keep searching. + continue + } + if inner.Entry() != fFunc.Entry() { + // Scanned past f and didn't find any inlined functions. + break + } + if inner.Name() != fFunc.Name() { + // This PC has f as its entry-point, but is not f. Therefore, it must be a + // function inlined into f. + return uint64(innerPC), true + } + } + + return 0, false +} + func TestCPUProfileInlining(t *testing.T) { - testCPUProfile(t, stackContains, []string{"pprof.inlinedCallee", "pprof.inlinedCaller"}, avoidFunctions(), func(dur time.Duration) { + if !containsInlinedCall(inlinedCaller, 4<<10) { + t.Skip("Can't determine whether inlinedCallee was inlined into inlinedCaller.") + } + + p := testCPUProfile(t, stackContains, []string{"pprof.inlinedCallee", "pprof.inlinedCaller"}, avoidFunctions(), func(dur time.Duration) { cpuHogger(inlinedCaller, &salt1, dur) }) + + // Check if inlined function locations are encoded correctly. The inlinedCalee and inlinedCaller should be in one location. + for _, loc := range p.Location { + hasInlinedCallerAfterInlinedCallee, hasInlinedCallee := false, false + for _, line := range loc.Line { + if line.Function.Name == "runtime/pprof.inlinedCallee" { + hasInlinedCallee = true + } + if hasInlinedCallee && line.Function.Name == "runtime/pprof.inlinedCaller" { + hasInlinedCallerAfterInlinedCallee = true + } + } + if hasInlinedCallee != hasInlinedCallerAfterInlinedCallee { + t.Fatalf("want inlinedCallee followed by inlinedCaller, got separate Location entries:\n%v", p) + } + } } func inlinedCaller(x int) int { - x = inlinedCallee(x) + x = inlinedCallee(x, 1e5) return x } -func inlinedCallee(x int) int { - // We could just use cpuHog1, but for loops prevent inlining - // right now. :( - foo := x - i := 0 -loop: - if foo > 0 { - foo *= foo - } else { - foo *= foo + 1 +func inlinedCallee(x, n int) int { + return cpuHog0(x, n) +} + +func TestCPUProfileRecursion(t *testing.T) { + p := testCPUProfile(t, stackContains, []string{"runtime/pprof.inlinedCallee", "runtime/pprof.recursionCallee", "runtime/pprof.recursionCaller"}, avoidFunctions(), func(dur time.Duration) { + cpuHogger(recursionCaller, &salt1, dur) + }) + + // check the Location encoding was not confused by recursive calls. + for i, loc := range p.Location { + recursionFunc := 0 + for _, line := range loc.Line { + if name := line.Function.Name; name == "runtime/pprof.recursionCaller" || name == "runtime/pprof.recursionCallee" { + recursionFunc++ + } + } + if recursionFunc > 1 { + t.Fatalf("want at most one recursionCaller or recursionCallee in one Location, got a violating Location (index: %d):\n%v", i, p) + } } - if i++; i < 1e5 { - goto loop +} + +func recursionCaller(x int) int { + y := recursionCallee(3, x) + return y +} + +func recursionCallee(n, x int) int { + if n == 0 { + return 1 } - return foo + y := inlinedCallee(x, 1e4) + return y * recursionCallee(n-1, x) } -func parseProfile(t *testing.T, valBytes []byte, f func(uintptr, []*profile.Location, map[string][]string)) { +func parseProfile(t *testing.T, valBytes []byte, f func(uintptr, []*profile.Location, map[string][]string)) *profile.Profile { p, err := profile.Parse(bytes.NewReader(valBytes)) if err != nil { t.Fatal(err) @@ -137,11 +217,12 @@ func parseProfile(t *testing.T, valBytes []byte, f func(uintptr, []*profile.Loca count := uintptr(sample.Value[0]) f(count, sample.Location, sample.Label) } + return p } // testCPUProfile runs f under the CPU profiler, checking for some conditions specified by need, -// as interpreted by matches. -func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []string, f func(dur time.Duration)) { +// as interpreted by matches, and returns the parsed profile. +func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []string, f func(dur time.Duration)) *profile.Profile { switch runtime.GOOS { case "darwin": switch runtime.GOARCH { @@ -195,8 +276,8 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri f(duration) StopCPUProfile() - if profileOk(t, matches, need, avoid, prof, duration) { - return + if p, ok := profileOk(t, matches, need, avoid, prof, duration); ok { + return p } duration *= 2 @@ -217,6 +298,7 @@ func testCPUProfile(t *testing.T, matches matchFunc, need []string, avoid []stri t.Skip("ignore the failure in QEMU; see golang.org/issue/9605") } t.FailNow() + return nil } func contains(slice []string, s string) bool { @@ -242,7 +324,7 @@ func stackContains(spec string, count uintptr, stk []*profile.Location, labels m type matchFunc func(spec string, count uintptr, stk []*profile.Location, labels map[string][]string) bool -func profileOk(t *testing.T, matches matchFunc, need []string, avoid []string, prof bytes.Buffer, duration time.Duration) (ok bool) { +func profileOk(t *testing.T, matches matchFunc, need []string, avoid []string, prof bytes.Buffer, duration time.Duration) (_ *profile.Profile, ok bool) { ok = true // Check that profile is well formed, contains 'need', and does not contain @@ -251,7 +333,7 @@ func profileOk(t *testing.T, matches matchFunc, need []string, avoid []string, p avoidSamples := make([]uintptr, len(avoid)) var samples uintptr var buf bytes.Buffer - parseProfile(t, prof.Bytes(), func(count uintptr, stk []*profile.Location, labels map[string][]string) { + p := parseProfile(t, prof.Bytes(), func(count uintptr, stk []*profile.Location, labels map[string][]string) { fmt.Fprintf(&buf, "%d:", count) fprintStack(&buf, stk) samples += count @@ -287,7 +369,7 @@ func profileOk(t *testing.T, matches matchFunc, need []string, avoid []string, p // not enough samples due to coarse timer // resolution. Let it go. t.Log("too few samples on Windows (golang.org/issue/10842)") - return false + return p, false } // Check that we got a reasonable number of samples. @@ -309,7 +391,7 @@ func profileOk(t *testing.T, matches matchFunc, need []string, avoid []string, p } if len(need) == 0 { - return ok + return p, ok } var total uintptr @@ -332,7 +414,7 @@ func profileOk(t *testing.T, matches matchFunc, need []string, avoid []string, p ok = false } } - return ok + return p, ok } // Fork can hang if preempted with signals frequently enough (see issue 5517). @@ -1076,3 +1158,111 @@ func TestTracebackAll(t *testing.T) { runtime.Stack(buf, true) } } + +// TestTryAdd tests the cases that's hard to test with real program execution. +// For example, the current go compilers may not inline functions involved in recursion +// but that may not be true in the future compilers. This tests such cases by +// using fake call sequences and forcing the profile build utilizing +// translateCPUProfile defined in proto_test.go +func TestTryAdd(t *testing.T) { + inlinedCallerPtr := uint64(funcPC(inlinedCaller)) + 1 + inlinedCalleePtr, found := findInlinedCall(inlinedCaller, 4<<10) + if !found { + t.Skip("Can't determine whether inlinedCallee was inlined into inlinedCaller.") + } + inlinedCalleePtr += 1 // +1 to be safely inside of the function body. + + period := int64(2000 * 1000) // 1/500*1e9 nanosec. + + testCases := []struct { + name string + input []uint64 // following the input format assumed by profileBuilder.addCPUData. + wantLocs [][]string // ordered location entries with function names. + wantSamples []*profile.Sample // ordered samples, we care only about Value and the profile location IDs. + }{{ + name: "bug35538", + input: []uint64{ + 3, 0, 500, // hz = 500. Must match the period. + 7, 0, 10, inlinedCalleePtr, inlinedCallerPtr, inlinedCalleePtr, inlinedCallerPtr, + 5, 0, 20, inlinedCalleePtr, inlinedCallerPtr, + }, + wantLocs: [][]string{{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}}, + wantSamples: []*profile.Sample{ + {Value: []int64{10, 10 * period}, Location: []*profile.Location{{ID: 1}, {ID: 1}}}, + {Value: []int64{20, 20 * period}, Location: []*profile.Location{{ID: 1}}}, + }, + }, { + name: "recursive_inlined_funcs", + input: []uint64{ + 3, 0, 500, // hz = 500. Must match the period. + 5, 0, 30, inlinedCalleePtr, inlinedCalleePtr, + 4, 0, 40, inlinedCalleePtr, + }, + wantLocs: [][]string{{"runtime/pprof.inlinedCallee"}}, + wantSamples: []*profile.Sample{ + {Value: []int64{30, 30 * period}, Location: []*profile.Location{{ID: 1}, {ID: 1}}}, + {Value: []int64{40, 40 * period}, Location: []*profile.Location{{ID: 1}}}, + }, + }, { + name: "truncated_stack_trace_later", + input: []uint64{ + 3, 0, 500, // hz = 500. Must match the period. + 5, 0, 50, inlinedCalleePtr, inlinedCallerPtr, + 4, 0, 60, inlinedCalleePtr, + }, + wantLocs: [][]string{{"runtime/pprof.inlinedCallee", "runtime/pprof.inlinedCaller"}}, + wantSamples: []*profile.Sample{ + {Value: []int64{50, 50 * period}, Location: []*profile.Location{{ID: 1}}}, + {Value: []int64{60, 60 * period}, Location: []*profile.Location{{ID: 1}}}, + }, + }, { + name: "truncated_stack_trace_first", + input: []uint64{ + 3, 0, 500, // hz = 500. Must match the period. + 4, 0, 70, inlinedCalleePtr, + 5, 0, 80, inlinedCalleePtr, inlinedCallerPtr, + }, + wantLocs: [][]string{ // the inline info is screwed up, but better than a crash. + {"runtime/pprof.inlinedCallee"}, + {"runtime/pprof.inlinedCaller"}}, + wantSamples: []*profile.Sample{ + {Value: []int64{70, 70 * period}, Location: []*profile.Location{{ID: 1}}}, + {Value: []int64{80, 80 * period}, Location: []*profile.Location{{ID: 1}, {ID: 2}}}, + }, + }} + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + p, err := translateCPUProfile(tc.input) + if err != nil { + t.Fatalf("translating profile: %v", err) + } + t.Logf("Profile: %v\n", p) + + // One location entry with all inlined functions. + var gotLoc [][]string + for _, loc := range p.Location { + var names []string + for _, line := range loc.Line { + names = append(names, line.Function.Name) + } + gotLoc = append(gotLoc, names) + } + if got, want := fmtJSON(gotLoc), fmtJSON(tc.wantLocs); got != want { + t.Errorf("Got Location = %+v\n\twant %+v", got, want) + } + // All samples should point to one location. + var gotSamples []*profile.Sample + for _, sample := range p.Sample { + var locs []*profile.Location + for _, loc := range sample.Location { + locs = append(locs, &profile.Location{ID: loc.ID}) + } + gotSamples = append(gotSamples, &profile.Sample{Value: sample.Value, Location: locs}) + } + if got, want := fmtJSON(gotSamples), fmtJSON(tc.wantSamples); got != want { + t.Errorf("Got Samples = %+v\n\twant %+v", got, want) + } + }) + } +} diff --git a/libgo/go/runtime/pprof/proto.go b/libgo/go/runtime/pprof/proto.go index ef3eeb156bf..ba5db853b1b 100644 --- a/libgo/go/runtime/pprof/proto.go +++ b/libgo/go/runtime/pprof/proto.go @@ -54,9 +54,10 @@ type profileBuilder struct { pb protobuf strings []string stringMap map[string]int - locs map[uintptr]int - funcs map[string]int // Package path-qualified function name to Function.ID + locs map[uintptr]locInfo // list of locInfo starting with the given PC. + funcs map[string]int // Package path-qualified function name to Function.ID mem []memMap + deck pcDeck } type memMap struct { @@ -220,15 +221,7 @@ func (b *profileBuilder) pbMapping(tag int, id, base, limit, offset uint64, file b.pb.endMessage(tag, start) } -// locForPC returns the location ID for addr. -// addr must a return PC or 1 + the PC of an inline marker. This returns the location of the corresponding call. -// It may emit to b.pb, so there must be no message encoding in progress. -func (b *profileBuilder) locForPC(addr uintptr) uint64 { - id := uint64(b.locs[addr]) - if id != 0 { - return id - } - +func allFrames(addr uintptr) ([]runtime.Frame, symbolizeFlag) { // Expand this one address using CallersFrames so we can cache // each expansion. In general, CallersFrames takes a whole // stack, but in this case we know there will be no skips in @@ -238,7 +231,7 @@ func (b *profileBuilder) locForPC(addr uintptr) uint64 { if frame.Function == "runtime.goexit" || frame.Function == "runtime.kickoff" { // Short-circuit if we see runtime.goexit so the loop // below doesn't allocate a useless empty location. - return 0 + return nil, 0 } symbolizeResult := lookupTried @@ -251,59 +244,22 @@ func (b *profileBuilder) locForPC(addr uintptr) uint64 { // a reasonable call PC. This mostly happens in tests. frame.PC = addr - 1 } - - // We can't write out functions while in the middle of the - // Location message, so record new functions we encounter and - // write them out after the Location. - type newFunc struct { - id uint64 - name, file string - } - newFuncs := make([]newFunc, 0, 8) - - id = uint64(len(b.locs)) + 1 - b.locs[addr] = int(id) - start := b.pb.startMessage() - b.pb.uint64Opt(tagLocation_ID, id) - b.pb.uint64Opt(tagLocation_Address, uint64(frame.PC)) - for frame.Function != "runtime.goexit" && frame.Function != "runtime.kickoff" { - // Write out each line in frame expansion. - funcID := uint64(b.funcs[frame.Function]) - if funcID == 0 { - funcID = uint64(len(b.funcs)) + 1 - b.funcs[frame.Function] = int(funcID) - newFuncs = append(newFuncs, newFunc{funcID, frame.Function, frame.File}) - } - b.pbLine(tagLocation_Line, funcID, int64(frame.Line)) - if !more { - break - } + ret := []runtime.Frame{frame} + for frame.Function != "runtime.goexit" && frame.Function != "runtime.kickoff" && more == true { frame, more = frames.Next() + ret = append(ret, frame) } - for i := range b.mem { - if b.mem[i].start <= addr && addr < b.mem[i].end || b.mem[i].fake { - b.pb.uint64Opt(tagLocation_MappingID, uint64(i+1)) - - m := b.mem[i] - m.funcs |= symbolizeResult - b.mem[i] = m - break - } - } - b.pb.endMessage(tagProfile_Location, start) + return ret, symbolizeResult +} - // Write out functions we found during frame expansion. - for _, fn := range newFuncs { - start := b.pb.startMessage() - b.pb.uint64Opt(tagFunction_ID, fn.id) - b.pb.int64Opt(tagFunction_Name, b.stringIndex(fn.name)) - b.pb.int64Opt(tagFunction_SystemName, b.stringIndex(fn.name)) - b.pb.int64Opt(tagFunction_Filename, b.stringIndex(fn.file)) - b.pb.endMessage(tagProfile_Function, start) - } +type locInfo struct { + // location id assigned by the profileBuilder + id uint64 - b.flush() - return id + // sequence of PCs, including the fake PCs returned by the traceback + // to represent inlined functions + // https://github.com/golang/go/blob/d6f2f833c93a41ec1c68e49804b8387a06b131c5/src/runtime/traceback.go#L347-L368 + pcs []uintptr } // newProfileBuilder returns a new profileBuilder. @@ -318,7 +274,7 @@ func newProfileBuilder(w io.Writer) *profileBuilder { start: time.Now(), strings: []string{""}, stringMap: map[string]int{"": 0}, - locs: map[uintptr]int{}, + locs: map[uintptr]locInfo{}, funcs: map[string]int{}, } b.readMapping() @@ -402,6 +358,7 @@ func (b *profileBuilder) build() { values := []int64{0, 0} var locs []uint64 + for e := b.m.all; e != nil; e = e.nextAll { values[0] = e.count values[1] = e.count * b.period @@ -415,23 +372,8 @@ func (b *profileBuilder) build() { } } - locs = locs[:0] - for i, addr := range e.stk { - // Addresses from stack traces point to the - // next instruction after each call, except - // for the leaf, which points to where the - // signal occurred. locForPC expects return - // PCs, so increment the leaf address to look - // like a return PC. - if i == 0 { - addr++ - } - l := b.locForPC(addr) - if l == 0 { // runtime.goexit - continue - } - locs = append(locs, l) - } + locs = b.appendLocsForStack(locs[:0], e.stk) + b.pbSample(values, locs, labels) } @@ -448,6 +390,203 @@ func (b *profileBuilder) build() { b.zw.Close() } +// appendLocsForStack appends the location IDs for the given stack trace to the given +// location ID slice, locs. The addresses in the stack are return PCs or 1 + the PC of +// an inline marker as the runtime traceback function returns. +// +// It may emit to b.pb, so there must be no message encoding in progress. +func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLocs []uint64) { + b.deck.reset() + for len(stk) > 0 { + addr := stk[0] + if l, ok := b.locs[addr]; ok { + // first record the location if there is any pending accumulated info. + if id := b.emitLocation(); id > 0 { + locs = append(locs, id) + } + + // then, record the cached location. + locs = append(locs, l.id) + + // The stk may be truncated due to the stack depth limit + // (e.g. See maxStack and maxCPUProfStack in runtime) or + // bugs in runtime. Avoid the crash in either case. + // TODO(hyangah): The correct fix may require using the exact + // pcs as the key for b.locs cache management instead of just + // relying on the very first pc. We are late in the go1.14 dev + // cycle, so this is a workaround with little code change. + if len(l.pcs) > len(stk) { + stk = nil + // TODO(hyangah): would be nice if we can enable + // debug print out on demand and report the problematic + // cached location entry and stack traces. Do we already + // have such facility to utilize (e.g. GODEBUG)? + } else { + stk = stk[len(l.pcs):] // skip the matching pcs. + } + continue + } + + frames, symbolizeResult := allFrames(addr) + if len(frames) == 0 { // runtime.goexit. + if id := b.emitLocation(); id > 0 { + locs = append(locs, id) + } + stk = stk[1:] + continue + } + + if added := b.deck.tryAdd(addr, frames, symbolizeResult); added { + stk = stk[1:] + continue + } + // add failed because this addr is not inlined with + // the existing PCs in the deck. Flush the deck and retry to + // handle this pc. + if id := b.emitLocation(); id > 0 { + locs = append(locs, id) + } + + // check cache again - previous emitLocation added a new entry + if l, ok := b.locs[addr]; ok { + locs = append(locs, l.id) + stk = stk[len(l.pcs):] // skip the matching pcs. + } else { + b.deck.tryAdd(addr, frames, symbolizeResult) // must succeed. + stk = stk[1:] + } + } + if id := b.emitLocation(); id > 0 { // emit remaining location. + locs = append(locs, id) + } + return locs +} + +// pcDeck is a helper to detect a sequence of inlined functions from +// a stack trace returned by the runtime. +// +// The stack traces returned by runtime's trackback functions are fully +// expanded (at least for Go functions) and include the fake pcs representing +// inlined functions. The profile proto expects the inlined functions to be +// encoded in one Location message. +// https://github.com/google/pprof/blob/5e965273ee43930341d897407202dd5e10e952cb/proto/profile.proto#L177-L184 +// +// Runtime does not directly expose whether a frame is for an inlined function +// and looking up debug info is not ideal, so we use a heuristic to filter +// the fake pcs and restore the inlined and entry functions. Inlined functions +// have the following properties: +// Frame's Func is nil (note: also true for non-Go functions), and +// Frame's Entry matches its entry function frame's Entry. (note: could also be true for recursive calls and non-Go functions), +// Frame's Name does not match its entry function frame's name. +// +// As reading and processing the pcs in a stack trace one by one (from leaf to the root), +// we use pcDeck to temporarily hold the observed pcs and their expanded frames +// until we observe the entry function frame. +type pcDeck struct { + pcs []uintptr + frames []runtime.Frame + symbolizeResult symbolizeFlag +} + +func (d *pcDeck) reset() { + d.pcs = d.pcs[:0] + d.frames = d.frames[:0] + d.symbolizeResult = 0 +} + +// tryAdd tries to add the pc and Frames expanded from it (most likely one, +// since the stack trace is already fully expanded) and the symbolizeResult +// to the deck. If it fails the caller needs to flush the deck and retry. +func (d *pcDeck) tryAdd(pc uintptr, frames []runtime.Frame, symbolizeResult symbolizeFlag) (success bool) { + if existing := len(d.pcs); existing > 0 { + // 'frames' are all expanded from one 'pc' and represent all inlined functions + // so we check only the last one. + newFrame := frames[0] + last := d.frames[existing-1] + if last.Func != nil { // the last frame can't be inlined. Flush. + return false + } + if last.Entry == 0 || newFrame.Entry == 0 { // Possibly not a Go function. Don't try to merge. + return false + } + + if last.Entry != newFrame.Entry { // newFrame is for a different function. + return false + } + if last.Function == newFrame.Function { // maybe recursion. + return false + } + } + d.pcs = append(d.pcs, pc) + d.frames = append(d.frames, frames...) + d.symbolizeResult |= symbolizeResult + return true +} + +// emitLocation emits the new location and function information recorded in the deck +// and returns the location ID encoded in the profile protobuf. +// It emits to b.pb, so there must be no message encoding in progress. +// It resets the deck. +func (b *profileBuilder) emitLocation() uint64 { + if len(b.deck.pcs) == 0 { + return 0 + } + defer b.deck.reset() + + addr := b.deck.pcs[0] + firstFrame := b.deck.frames[0] + + // We can't write out functions while in the middle of the + // Location message, so record new functions we encounter and + // write them out after the Location. + type newFunc struct { + id uint64 + name, file string + } + newFuncs := make([]newFunc, 0, 8) + + id := uint64(len(b.locs)) + 1 + b.locs[addr] = locInfo{id: id, pcs: append([]uintptr{}, b.deck.pcs...)} + + start := b.pb.startMessage() + b.pb.uint64Opt(tagLocation_ID, id) + b.pb.uint64Opt(tagLocation_Address, uint64(firstFrame.PC)) + for _, frame := range b.deck.frames { + // Write out each line in frame expansion. + funcID := uint64(b.funcs[frame.Function]) + if funcID == 0 { + funcID = uint64(len(b.funcs)) + 1 + b.funcs[frame.Function] = int(funcID) + newFuncs = append(newFuncs, newFunc{funcID, frame.Function, frame.File}) + } + b.pbLine(tagLocation_Line, funcID, int64(frame.Line)) + } + for i := range b.mem { + if b.mem[i].start <= addr && addr < b.mem[i].end || b.mem[i].fake { + b.pb.uint64Opt(tagLocation_MappingID, uint64(i+1)) + + m := b.mem[i] + m.funcs |= b.deck.symbolizeResult + b.mem[i] = m + break + } + } + b.pb.endMessage(tagProfile_Location, start) + + // Write out functions we found during frame expansion. + for _, fn := range newFuncs { + start := b.pb.startMessage() + b.pb.uint64Opt(tagFunction_ID, fn.id) + b.pb.int64Opt(tagFunction_Name, b.stringIndex(fn.name)) + b.pb.int64Opt(tagFunction_SystemName, b.stringIndex(fn.name)) + b.pb.int64Opt(tagFunction_Filename, b.stringIndex(fn.file)) + b.pb.endMessage(tagProfile_Function, start) + } + + b.flush() + return id +} + // readMapping reads /proc/self/maps and writes mappings to b.pb. // It saves the address ranges of the mappings in b.mem for use // when emitting locations. diff --git a/libgo/go/runtime/pprof/proto_test.go b/libgo/go/runtime/pprof/proto_test.go index 7e7c7cc6f0a..67d6b5d0ddb 100644 --- a/libgo/go/runtime/pprof/proto_test.go +++ b/libgo/go/runtime/pprof/proto_test.go @@ -118,9 +118,9 @@ func TestConvertCPUProfile(t *testing.T) { b := []uint64{ 3, 0, 500, // hz = 500 - 5, 0, 10, uint64(addr1), uint64(addr1 + 2), // 10 samples in addr1 - 5, 0, 40, uint64(addr2), uint64(addr2 + 2), // 40 samples in addr2 - 5, 0, 10, uint64(addr1), uint64(addr1 + 2), // 10 samples in addr1 + 5, 0, 10, uint64(addr1 + 1), uint64(addr1 + 2), // 10 samples in addr1 + 5, 0, 40, uint64(addr2 + 1), uint64(addr2 + 2), // 40 samples in addr2 + 5, 0, 10, uint64(addr1 + 1), uint64(addr1 + 2), // 10 samples in addr1 } p, err := translateCPUProfile(b) if err != nil { @@ -360,6 +360,17 @@ func TestMapping(t *testing.T) { continue } } + + if traceback == "Go+C" { + // The test code was arranged to have PCs from C and + // they are not symbolized. + // Check no Location containing those unsymbolized PCs contains multiple lines. + for i, loc := range prof.Location { + if !symbolized(loc) && len(loc.Line) > 1 { + t.Errorf("Location[%d] contains unsymbolized PCs and multiple lines: %v", i, loc) + } + } + } }) } } diff --git a/libgo/go/runtime/pprof/protomem.go b/libgo/go/runtime/pprof/protomem.go index 1c88aae43a0..fa75a28c626 100644 --- a/libgo/go/runtime/pprof/protomem.go +++ b/libgo/go/runtime/pprof/protomem.go @@ -27,30 +27,27 @@ func writeHeapProto(w io.Writer, p []runtime.MemProfileRecord, rate int64, defau values := []int64{0, 0, 0, 0} var locs []uint64 for _, r := range p { - locs = locs[:0] hideRuntime := true for tries := 0; tries < 2; tries++ { - for _, addr := range r.Stack() { - // For heap profiles, all stack - // addresses are return PCs, which is - // what locForPC expects. - if hideRuntime { + stk := r.Stack() + // For heap profiles, all stack + // addresses are return PCs, which is + // what appendLocsForStack expects. + if hideRuntime { + for i, addr := range stk { if f := runtime.FuncForPC(addr); f != nil && strings.HasPrefix(f.Name(), "runtime.") { continue } // Found non-runtime. Show any runtime uses above it. - hideRuntime = false + stk = stk[i:] + break } - l := b.locForPC(addr) - if l == 0 { // runtime.goexit - continue - } - locs = append(locs, l) } + locs = b.appendLocsForStack(locs[:0], stk) if len(locs) > 0 { break } - hideRuntime = false // try again, and show all frames + hideRuntime = false // try again, and show all frames next time. } values[0], values[1] = scaleHeapSample(r.AllocObjects, r.AllocBytes, rate) diff --git a/libgo/go/runtime/pprof/testdata/README b/libgo/go/runtime/pprof/testdata/README new file mode 100644 index 00000000000..876538e5d51 --- /dev/null +++ b/libgo/go/runtime/pprof/testdata/README @@ -0,0 +1,9 @@ +These binaries were generated by: + +$ cat empty.s +.global _start +_start: +$ as --32 -o empty.o empty.s && ld --build-id -m elf_i386 -o test32 empty.o +$ as --64 -o empty.o empty.s && ld --build-id -o test64 empty.o +$ powerpc-linux-gnu-as -o empty.o empty.s && powerpc-linux-gnu-ld --build-id -o test32be empty.o +$ powerpc64-linux-gnu-as -o empty.o empty.s && powerpc64-linux-gnu-ld --build-id -o test64be empty.o diff --git a/libgo/go/runtime/pprof/testdata/mappingtest/main.go b/libgo/go/runtime/pprof/testdata/mappingtest/main.go index 476b9e88a32..484b7f9d06c 100644 --- a/libgo/go/runtime/pprof/testdata/mappingtest/main.go +++ b/libgo/go/runtime/pprof/testdata/mappingtest/main.go @@ -17,8 +17,7 @@ package main int cpuHogCSalt1 = 0; int cpuHogCSalt2 = 0; -void CPUHogCFunction() { - int foo = cpuHogCSalt1; +void CPUHogCFunction0(int foo) { int i; for (i = 0; i < 100000; i++) { if (foo > 0) { @@ -30,6 +29,10 @@ void CPUHogCFunction() { } } +void CPUHogCFunction() { + CPUHogCFunction0(cpuHogCSalt1); +} + struct CgoTracebackArg { uintptr_t context; uintptr_t sigContext; @@ -39,8 +42,9 @@ struct CgoTracebackArg { void CollectCgoTraceback(void* parg) { struct CgoTracebackArg* arg = (struct CgoTracebackArg*)(parg); - arg->buf[0] = (uintptr_t)(CPUHogCFunction); - arg->buf[1] = 0; + arg->buf[0] = (uintptr_t)(CPUHogCFunction0); + arg->buf[1] = (uintptr_t)(CPUHogCFunction); + arg->buf[2] = 0; }; */ import "C" @@ -81,7 +85,6 @@ var salt1 int var salt2 int func cpuHogGoFunction() { - // Generates CPU profile samples including a Go call path. for { foo := salt1 for i := 0; i < 1e5; i++ { diff --git a/libgo/go/runtime/pprof/testdata/test32 b/libgo/go/runtime/pprof/testdata/test32 new file mode 100755 index 00000000000..ce594720dbf Binary files /dev/null and b/libgo/go/runtime/pprof/testdata/test32 differ diff --git a/libgo/go/runtime/pprof/testdata/test32be b/libgo/go/runtime/pprof/testdata/test32be new file mode 100755 index 00000000000..f13a732203f Binary files /dev/null and b/libgo/go/runtime/pprof/testdata/test32be differ diff --git a/libgo/go/runtime/pprof/testdata/test64 b/libgo/go/runtime/pprof/testdata/test64 new file mode 100755 index 00000000000..3fb42fb3bf4 Binary files /dev/null and b/libgo/go/runtime/pprof/testdata/test64 differ diff --git a/libgo/go/runtime/pprof/testdata/test64be b/libgo/go/runtime/pprof/testdata/test64be new file mode 100755 index 00000000000..09b4b018944 Binary files /dev/null and b/libgo/go/runtime/pprof/testdata/test64be differ diff --git a/libgo/go/runtime/preempt.go b/libgo/go/runtime/preempt.go new file mode 100644 index 00000000000..1a8f9ac4a3d --- /dev/null +++ b/libgo/go/runtime/preempt.go @@ -0,0 +1,370 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Goroutine preemption +// +// A goroutine can be preempted at any safe-point. Currently, there +// are a few categories of safe-points: +// +// 1. A blocked safe-point occurs for the duration that a goroutine is +// descheduled, blocked on synchronization, or in a system call. +// +// 2. Synchronous safe-points occur when a running goroutine checks +// for a preemption request. +// +// 3. Asynchronous safe-points occur at any instruction in user code +// where the goroutine can be safely paused and a conservative +// stack and register scan can find stack roots. The runtime can +// stop a goroutine at an async safe-point using a signal. +// +// At both blocked and synchronous safe-points, a goroutine's CPU +// state is minimal and the garbage collector has complete information +// about its entire stack. This makes it possible to deschedule a +// goroutine with minimal space, and to precisely scan a goroutine's +// stack. +// +// Synchronous safe-points are implemented by overloading the stack +// bound check in function prologues. To preempt a goroutine at the +// next synchronous safe-point, the runtime poisons the goroutine's +// stack bound to a value that will cause the next stack bound check +// to fail and enter the stack growth implementation, which will +// detect that it was actually a preemption and redirect to preemption +// handling. +// +// Preemption at asynchronous safe-points is implemented by suspending +// the thread using an OS mechanism (e.g., signals) and inspecting its +// state to determine if the goroutine was at an asynchronous +// safe-point. Since the thread suspension itself is generally +// asynchronous, it also checks if the running goroutine wants to be +// preempted, since this could have changed. If all conditions are +// satisfied, it adjusts the signal context to make it look like the +// signaled thread just called asyncPreempt and resumes the thread. +// asyncPreempt spills all registers and enters the scheduler. +// +// (An alternative would be to preempt in the signal handler itself. +// This would let the OS save and restore the register state and the +// runtime would only need to know how to extract potentially +// pointer-containing registers from the signal context. However, this +// would consume an M for every preempted G, and the scheduler itself +// is not designed to run from a signal handler, as it tends to +// allocate memory and start threads in the preemption path.) + +package runtime + +import ( + "runtime/internal/atomic" +) + +type suspendGState struct { + g *g + + // dead indicates the goroutine was not suspended because it + // is dead. This goroutine could be reused after the dead + // state was observed, so the caller must not assume that it + // remains dead. + dead bool + + // stopped indicates that this suspendG transitioned the G to + // _Gwaiting via g.preemptStop and thus is responsible for + // readying it when done. + stopped bool +} + +// suspendG suspends goroutine gp at a safe-point and returns the +// state of the suspended goroutine. The caller gets read access to +// the goroutine until it calls resumeG. +// +// It is safe for multiple callers to attempt to suspend the same +// goroutine at the same time. The goroutine may execute between +// subsequent successful suspend operations. The current +// implementation grants exclusive access to the goroutine, and hence +// multiple callers will serialize. However, the intent is to grant +// shared read access, so please don't depend on exclusive access. +// +// This must be called from the system stack and the user goroutine on +// the current M (if any) must be in a preemptible state. This +// prevents deadlocks where two goroutines attempt to suspend each +// other and both are in non-preemptible states. There are other ways +// to resolve this deadlock, but this seems simplest. +// +// TODO(austin): What if we instead required this to be called from a +// user goroutine? Then we could deschedule the goroutine while +// waiting instead of blocking the thread. If two goroutines tried to +// suspend each other, one of them would win and the other wouldn't +// complete the suspend until it was resumed. We would have to be +// careful that they couldn't actually queue up suspend for each other +// and then both be suspended. This would also avoid the need for a +// kernel context switch in the synchronous case because we could just +// directly schedule the waiter. The context switch is unavoidable in +// the signal case. +// +//go:systemstack +func suspendG(gp *g) suspendGState { + if mp := getg().m; mp.curg != nil && readgstatus(mp.curg) == _Grunning { + // Since we're on the system stack of this M, the user + // G is stuck at an unsafe point. If another goroutine + // were to try to preempt m.curg, it could deadlock. + throw("suspendG from non-preemptible goroutine") + } + + // See https://golang.org/cl/21503 for justification of the yield delay. + const yieldDelay = 10 * 1000 + var nextYield int64 + + // Drive the goroutine to a preemption point. + stopped := false + var asyncM *m + var asyncGen uint32 + var nextPreemptM int64 + for i := 0; ; i++ { + switch s := readgstatus(gp); s { + default: + if s&_Gscan != 0 { + // Someone else is suspending it. Wait + // for them to finish. + // + // TODO: It would be nicer if we could + // coalesce suspends. + break + } + + dumpgstatus(gp) + throw("invalid g status") + + case _Gdead: + // Nothing to suspend. + // + // preemptStop may need to be cleared, but + // doing that here could race with goroutine + // reuse. Instead, goexit0 clears it. + return suspendGState{dead: true} + + case _Gcopystack: + // The stack is being copied. We need to wait + // until this is done. + + case _Gexitingsyscall: + // This is a transient state. Try again. + + case _Gpreempted: + // We (or someone else) suspended the G. Claim + // ownership of it by transitioning it to + // _Gwaiting. + if !casGFromPreempted(gp, _Gpreempted, _Gwaiting) { + break + } + + // We stopped the G, so we have to ready it later. + stopped = true + + s = _Gwaiting + fallthrough + + case _Grunnable, _Gsyscall, _Gwaiting: + // Claim goroutine by setting scan bit. + // This may race with execution or readying of gp. + // The scan bit keeps it from transition state. + if !castogscanstatus(gp, s, s|_Gscan) { + break + } + + // Clear the preemption request. It's safe to + // reset the stack guard because we hold the + // _Gscan bit and thus own the stack. + gp.preemptStop = false + gp.preempt = false + + // The goroutine was already at a safe-point + // and we've now locked that in. + // + // TODO: It would be much better if we didn't + // leave it in _Gscan, but instead gently + // prevented its scheduling until resumption. + // Maybe we only use this to bump a suspended + // count and the scheduler skips suspended + // goroutines? That wouldn't be enough for + // {_Gsyscall,_Gwaiting} -> _Grunning. Maybe + // for all those transitions we need to check + // suspended and deschedule? + return suspendGState{g: gp, stopped: stopped} + + case _Grunning: + // Optimization: if there is already a pending preemption request + // (from the previous loop iteration), don't bother with the atomics. + if asyncM != nil && gp.preemptStop && gp.preempt && asyncM == gp.m && atomic.Load(&asyncM.preemptGen) == asyncGen { + break + } + + // Temporarily block state transitions. + if !castogscanstatus(gp, _Grunning, _Gscanrunning) { + break + } + + // Request synchronous preemption. + gp.preemptStop = true + gp.preempt = true + + // Prepare for asynchronous preemption. + asyncM2 := gp.m + asyncGen2 := atomic.Load(&asyncM2.preemptGen) + needAsync := asyncM != asyncM2 || asyncGen != asyncGen2 + asyncM = asyncM2 + asyncGen = asyncGen2 + + casfrom_Gscanstatus(gp, _Gscanrunning, _Grunning) + + // Send asynchronous preemption. We do this + // after CASing the G back to _Grunning + // because preemptM may be synchronous and we + // don't want to catch the G just spinning on + // its status. + if preemptMSupported && debug.asyncpreemptoff == 0 && needAsync { + // Rate limit preemptM calls. This is + // particularly important on Windows + // where preemptM is actually + // synchronous and the spin loop here + // can lead to live-lock. + now := nanotime() + if now >= nextPreemptM { + nextPreemptM = now + yieldDelay/2 + preemptM(asyncM) + } + } + } + + // TODO: Don't busy wait. This loop should really only + // be a simple read/decide/CAS loop that only fails if + // there's an active race. Once the CAS succeeds, we + // should queue up the preemption (which will require + // it to be reliable in the _Grunning case, not + // best-effort) and then sleep until we're notified + // that the goroutine is suspended. + if i == 0 { + nextYield = nanotime() + yieldDelay + } + if nanotime() < nextYield { + procyield(10) + } else { + osyield() + nextYield = nanotime() + yieldDelay/2 + } + } +} + +// resumeG undoes the effects of suspendG, allowing the suspended +// goroutine to continue from its current safe-point. +func resumeG(state suspendGState) { + if state.dead { + // We didn't actually stop anything. + return + } + + gp := state.g + switch s := readgstatus(gp); s { + default: + dumpgstatus(gp) + throw("unexpected g status") + + case _Grunnable | _Gscan, + _Gwaiting | _Gscan, + _Gsyscall | _Gscan: + casfrom_Gscanstatus(gp, s, s&^_Gscan) + } + + if state.stopped { + // We stopped it, so we need to re-schedule it. + ready(gp, 0, true) + } +} + +// canPreemptM reports whether mp is in a state that is safe to preempt. +// +// It is nosplit because it has nosplit callers. +// +//go:nosplit +func canPreemptM(mp *m) bool { + return mp.locks == 0 && mp.mallocing == 0 && mp.preemptoff == "" && mp.p.ptr().status == _Prunning +} + +//go:generate go run mkpreempt.go + +// asyncPreempt saves all user registers and calls asyncPreempt2. +// +// When stack scanning encounters an asyncPreempt frame, it scans that +// frame and its parent frame conservatively. +// +// asyncPreempt is implemented in assembly. +func asyncPreempt() + +//go:nosplit +func asyncPreempt2() { + gp := getg() + gp.asyncSafePoint = true + if gp.preemptStop { + mcall(preemptPark) + } else { + mcall(gopreempt_m) + } + gp.asyncSafePoint = false +} + +// wantAsyncPreempt returns whether an asynchronous preemption is +// queued for gp. +func wantAsyncPreempt(gp *g) bool { + // Check both the G and the P. + return (gp.preempt || gp.m.p != 0 && gp.m.p.ptr().preempt) && readgstatus(gp)&^_Gscan == _Grunning +} + +// isAsyncSafePoint reports whether gp at instruction PC is an +// asynchronous safe point. This indicates that: +// +// 1. It's safe to suspend gp and conservatively scan its stack and +// registers. There are no potentially hidden pointer values and it's +// not in the middle of an atomic sequence like a write barrier. +// +// 2. gp has enough stack space to inject the asyncPreempt call. +// +// 3. It's generally safe to interact with the runtime, even if we're +// in a signal handler stopped here. For example, there are no runtime +// locks held, so acquiring a runtime lock won't self-deadlock. +func isAsyncSafePoint(gp *g, pc uintptr) bool { + mp := gp.m + + // Only user Gs can have safe-points. We check this first + // because it's extremely common that we'll catch mp in the + // scheduler processing this G preemption. + if mp.curg != gp { + return false + } + + // Check M state. + if mp.p == 0 || !canPreemptM(mp) { + return false + } + + // Check if PC is an unsafe-point. + f := FuncForPC(pc) + if f == nil { + // Not Go code. + return false + } + name := f.Name() + if hasPrefix(name, "runtime.") || + hasPrefix(name, "runtime..z2finternal..z2f") || + hasPrefix(name, "reflect.") { + // For now we never async preempt the runtime or + // anything closely tied to the runtime. Known issues + // include: various points in the scheduler ("don't + // preempt between here and here"), much of the defer + // implementation (untyped info on stack), bulk write + // barriers (write barrier check), + // reflect.{makeFuncStub,methodValueCall}. + // + // TODO(austin): We should improve this, or opt things + // in incrementally. + return false + } + + return true +} diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index a025137f367..c0e85773098 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -548,6 +548,7 @@ func schedinit() { usestackmaps = probestackmaps() mallocinit() + fastrandinit() // must run before mcommoninit mcommoninit(_g_.m) cpuinit() // must run before alginit alginit() // maps must not be used before this call @@ -622,8 +623,8 @@ func mcommoninit(mp *m) { sched.mnext++ checkmcount() - mp.fastrand[0] = 1597334677 * uint32(mp.id) - mp.fastrand[1] = uint32(cputicks()) + mp.fastrand[0] = uint32(int64Hash(uint64(mp.id), fastrandseed)) + mp.fastrand[1] = uint32(int64Hash(uint64(cputicks()), ^fastrandseed)) if mp.fastrand[0]|mp.fastrand[1] == 0 { mp.fastrand[1] = 1 } @@ -640,6 +641,13 @@ func mcommoninit(mp *m) { unlock(&sched.lock) } +var fastrandseed uintptr + +func fastrandinit() { + s := (*[unsafe.Sizeof(fastrandseed)]byte)(unsafe.Pointer(&fastrandseed))[:] + getRandomData(s) +} + // Mark gp ready to run. func ready(gp *g, traceskip int, next bool) { if trace.enabled { @@ -704,18 +712,6 @@ func readgstatus(gp *g) uint32 { return atomic.Load(&gp.atomicstatus) } -// Ownership of gcscanvalid: -// -// If gp is running (meaning status == _Grunning or _Grunning|_Gscan), -// then gp owns gp.gcscanvalid, and other goroutines must not modify it. -// -// Otherwise, a second goroutine can lock the scan state by setting _Gscan -// in the status bit and then modify gcscanvalid, and then unlock the scan state. -// -// Note that the first condition implies an exception to the second: -// if a second goroutine changes gp's status to _Grunning|_Gscan, -// that second goroutine still does not have the right to modify gcscanvalid. - // The Gscanstatuses are acting like locks and this releases them. // If it proves to be a performance hit we should be able to make these // simple atomic stores but for now we are going to throw if @@ -732,7 +728,8 @@ func casfrom_Gscanstatus(gp *g, oldval, newval uint32) { case _Gscanrunnable, _Gscanwaiting, _Gscanrunning, - _Gscansyscall: + _Gscansyscall, + _Gscanpreempted: if newval == oldval&^_Gscan { success = atomic.Cas(&gp.atomicstatus, oldval, newval) } @@ -774,17 +771,6 @@ func casgstatus(gp *g, oldval, newval uint32) { }) } - if oldval == _Grunning && gp.gcscanvalid { - // If oldvall == _Grunning, then the actual status must be - // _Grunning or _Grunning|_Gscan; either way, - // we own gp.gcscanvalid, so it's safe to read. - // gp.gcscanvalid must not be true when we are running. - systemstack(func() { - print("runtime: casgstatus ", hex(oldval), "->", hex(newval), " gp.status=", hex(gp.atomicstatus), " gp.gcscanvalid=true\n") - throw("casgstatus") - }) - } - // See https://golang.org/cl/21503 for justification of the yield delay. const yieldDelay = 5 * 1000 var nextYield int64 @@ -795,14 +781,6 @@ func casgstatus(gp *g, oldval, newval uint32) { if oldval == _Gwaiting && gp.atomicstatus == _Grunnable { throw("casgstatus: waiting for Gwaiting but is Grunnable") } - // Help GC if needed. - // if gp.preemptscan && !gp.gcworkdone && (oldval == _Grunning || oldval == _Gsyscall) { - // gp.preemptscan = false - // systemstack(func() { - // gcphasework(gp) - // }) - // } - // But meanwhile just yield. if i == 0 { nextYield = nanotime() + yieldDelay } @@ -815,174 +793,28 @@ func casgstatus(gp *g, oldval, newval uint32) { nextYield = nanotime() + yieldDelay/2 } } - if newval == _Grunning { - gp.gcscanvalid = false - } } -// scang blocks until gp's stack has been scanned. -// It might be scanned by scang or it might be scanned by the goroutine itself. -// Either way, the stack scan has completed when scang returns. -func scang(gp *g, gcw *gcWork) { - // Invariant; we (the caller, markroot for a specific goroutine) own gp.gcscandone. - // Nothing is racing with us now, but gcscandone might be set to true left over - // from an earlier round of stack scanning (we scan twice per GC). - // We use gcscandone to record whether the scan has been done during this round. - - gp.gcscandone = false - - // See https://golang.org/cl/21503 for justification of the yield delay. - const yieldDelay = 10 * 1000 - var nextYield int64 - - // Endeavor to get gcscandone set to true, - // either by doing the stack scan ourselves or by coercing gp to scan itself. - // gp.gcscandone can transition from false to true when we're not looking - // (if we asked for preemption), so any time we lock the status using - // castogscanstatus we have to double-check that the scan is still not done. -loop: - for i := 0; !gp.gcscandone; i++ { - switch s := readgstatus(gp); s { - default: - dumpgstatus(gp) - throw("stopg: invalid status") - - case _Gdead: - // No stack. - gp.gcscandone = true - break loop - - case _Gcopystack: - // Stack being switched. Go around again. - - case _Gsyscall: - if usestackmaps { - // Claim goroutine by setting scan bit. - // Racing with execution or readying of gp. - // The scan bit keeps them from running - // the goroutine until we're done. - if castogscanstatus(gp, s, s|_Gscan) { - if gp.scanningself { - // Don't try to scan the stack - // if the goroutine is going to do - // it itself. - // FIXME: can this happen? - restartg(gp) - break - } - if !gp.gcscandone { - // Send a signal to let the goroutine scan - // itself. This races with enter/exitsyscall. - // If the goroutine is not stopped at a safepoint, - // it will not scan the stack and we'll try again. - mp := gp.m - noteclear(&mp.scannote) - gp.scangcw = uintptr(unsafe.Pointer(gcw)) - tgkill(getpid(), _pid_t(mp.procid), _SIGURG) - - // Wait for gp to scan its own stack. - notesleep(&mp.scannote) - - if !gp.gcscandone { - // The signal delivered at a bad time. - // Try again. - restartg(gp) - break - } - } - restartg(gp) - break loop - } - break - } - fallthrough - - case _Grunnable, _Gwaiting: - // Claim goroutine by setting scan bit. - // Racing with execution or readying of gp. - // The scan bit keeps them from running - // the goroutine until we're done. - if castogscanstatus(gp, s, s|_Gscan) { - if gp.scanningself { - // Don't try to scan the stack - // if the goroutine is going to do - // it itself. - restartg(gp) - break - } - if !gp.gcscandone { - scanstack(gp, gcw) - gp.gcscandone = true - } - restartg(gp) - break loop - } - - case _Gexitingsyscall: - // This is a transient state during which we should not scan its stack. - // Try again. - - case _Gscanwaiting: - // newstack is doing a scan for us right now. Wait. - - case _Gscanrunning: - // checkPreempt is scanning. Wait. - - case _Grunning: - // Goroutine running. Try to preempt execution so it can scan itself. - // The preemption handler (in newstack) does the actual scan. - - // Optimization: if there is already a pending preemption request - // (from the previous loop iteration), don't bother with the atomics. - if gp.preemptscan && gp.preempt { - break - } - - // Ask for preemption and self scan. - if castogscanstatus(gp, _Grunning, _Gscanrunning) { - if !gp.gcscandone { - gp.preemptscan = true - gp.preempt = true - } - casfrom_Gscanstatus(gp, _Gscanrunning, _Grunning) - } - } - - if i == 0 { - nextYield = nanotime() + yieldDelay - } - if nanotime() < nextYield { - procyield(10) - } else { - osyield() - nextYield = nanotime() + yieldDelay/2 - } +// casGToPreemptScan transitions gp from _Grunning to _Gscan|_Gpreempted. +// +// TODO(austin): This is the only status operation that both changes +// the status and locks the _Gscan bit. Rethink this. +func casGToPreemptScan(gp *g, old, new uint32) { + if old != _Grunning || new != _Gscan|_Gpreempted { + throw("bad g transition") } - - gp.preemptscan = false // cancel scan request if no longer needed -} - -// The GC requests that this routine be moved from a scanmumble state to a mumble state. -func restartg(gp *g) { - if gp.scang != 0 || gp.scangcw != 0 { - print("g ", gp.goid, "is being scanned scang=", gp.scang, " scangcw=", gp.scangcw, "\n") - throw("restartg: being scanned") + for !atomic.Cas(&gp.atomicstatus, _Grunning, _Gscan|_Gpreempted) { } +} - s := readgstatus(gp) - switch s { - default: - dumpgstatus(gp) - throw("restartg: unexpected status") - - case _Gdead: - // ok - - case _Gscanrunnable, - _Gscanwaiting, - _Gscansyscall: - casfrom_Gscanstatus(gp, s, s&^_Gscan) +// casGFromPreempted attempts to transition gp from _Gpreempted to +// _Gwaiting. If successful, the caller is responsible for +// re-scheduling gp. +func casGFromPreempted(gp *g, old, new uint32) bool { + if old != _Gpreempted || new != _Gwaiting { + throw("bad g transition") } + return atomic.Cas(&gp.atomicstatus, _Gpreempted, _Gwaiting) } // stopTheWorld stops all P's from executing goroutines, interrupting @@ -1001,8 +833,23 @@ func restartg(gp *g) { // goroutines. func stopTheWorld(reason string) { semacquire(&worldsema) - getg().m.preemptoff = reason - systemstack(stopTheWorldWithSema) + gp := getg() + gp.m.preemptoff = reason + systemstack(func() { + // Mark the goroutine which called stopTheWorld preemptible so its + // stack may be scanned. + // This lets a mark worker scan us while we try to stop the world + // since otherwise we could get in a mutual preemption deadlock. + // We must not modify anything on the G stack because a stack shrink + // may occur. A stack shrink is otherwise OK though because in order + // to return from this function (and to leave the system stack) we + // must have preempted all goroutines, including any attempting + // to scan our stack, in which case, any stack shrinking will + // have already completed by the time we exit. + casgstatus(gp, _Grunning, _Gwaiting) + stopTheWorldWithSema() + casgstatus(gp, _Gwaiting, _Grunning) + }) } // startTheWorld undoes the effects of stopTheWorld. @@ -1014,10 +861,31 @@ func startTheWorld() { getg().m.preemptoff = "" } -// Holding worldsema grants an M the right to try to stop the world -// and prevents gomaxprocs from changing concurrently. +// stopTheWorldGC has the same effect as stopTheWorld, but blocks +// until the GC is not running. It also blocks a GC from starting +// until startTheWorldGC is called. +func stopTheWorldGC(reason string) { + semacquire(&gcsema) + stopTheWorld(reason) +} + +// startTheWorldGC undoes the effects of stopTheWorldGC. +func startTheWorldGC() { + startTheWorld() + semrelease(&gcsema) +} + +// Holding worldsema grants an M the right to try to stop the world. var worldsema uint32 = 1 +// Holding gcsema grants the M the right to block a GC, and blocks +// until the current GC is done. In particular, it prevents gomaxprocs +// from changing concurrently. +// +// TODO(mknyszek): Once gomaxprocs and the execution tracer can handle +// being changed/enabled during a GC, remove this. +var gcsema uint32 = 1 + // stopTheWorldWithSema is the core implementation of stopTheWorld. // The caller is responsible for acquiring worldsema and disabling // preemption first and then should stopTheWorldWithSema on the system @@ -1119,7 +987,7 @@ func stopTheWorldWithSema() { func startTheWorldWithSema(emitTraceEvent bool) int64 { mp := acquirem() // disable preemption because it can be holding p in a local var if netpollinited() { - list := netpoll(false) // non-blocking + list := netpoll(0) // non-blocking injectglist(&list) } lock(&sched.lock) @@ -1299,6 +1167,11 @@ func mexit(osStack bool) { // Free the gsignal stack. if m.gsignal != nil { stackfree(m.gsignal) + // On some platforms, when calling into VDSO (e.g. nanotime) + // we store our g on the gsignal stack, if there is one. + // Now the stack is freed, unlink it from the m, so we + // won't write to it when calling VDSO code. + m.gsignal = nil } // Remove m from allm. @@ -1637,8 +1510,6 @@ func oneNewExtraM() { // the goroutine stack ends. mp, g0SP, g0SPSize := allocm(nil, nil, true) gp := malg(true, false, nil, nil) - gp.gcscanvalid = true - gp.gcscandone = true // malg returns status as _Gidle. Change to _Gdead before // adding to allg where GC can see it. We use _Gdead to hide // this from tracebacks and stack scans since it isn't a @@ -1704,6 +1575,7 @@ func dropm() { // Return mp.curg to dead state. casgstatus(mp.curg, _Gsyscall, _Gdead) + mp.curg.preemptStop = false atomic.Xadd(&sched.ngsys, +1) // Block signals before unminit. @@ -2034,6 +1906,9 @@ func handoffp(_p_ *p) { startm(_p_, false) return } + if when := nobarrierWakeTime(_p_); when != 0 { + wakeNetPoller(when) + } pidleput(_p_) unlock(&sched.lock) } @@ -2135,14 +2010,16 @@ func gcstopm() { func execute(gp *g, inheritTime bool) { _g_ := getg() + // Assign gp.m before entering _Grunning so running Gs have an + // M. + _g_.m.curg = gp + gp.m = _g_.m casgstatus(gp, _Grunnable, _Grunning) gp.waitsince = 0 gp.preempt = false if !inheritTime { _g_.m.p.ptr().schedtick++ } - _g_.m.curg = gp - gp.m = _g_.m // Check whether the profiler needs to be turned on or off. hz := sched.profilehz @@ -2163,7 +2040,7 @@ func execute(gp *g, inheritTime bool) { } // Finds a runnable goroutine to execute. -// Tries to steal from other P's, get g from global queue, poll network. +// Tries to steal from other P's, get g from local or global queue, poll network. func findrunnable() (gp *g, inheritTime bool) { _g_ := getg() @@ -2180,6 +2057,9 @@ top: if _p_.runSafePointFn != 0 { runSafePointFn() } + + now, pollUntil, _ := checkTimers(_p_, 0) + if fingwait && fingwake { if gp := wakefing(); gp != nil { ready(gp, 0, true) @@ -2212,7 +2092,7 @@ top: // not set lastpoll yet), this thread will do blocking netpoll below // anyway. if netpollinited() && atomic.Load(&netpollWaiters) > 0 && atomic.Load64(&sched.lastpoll) != 0 { - if list := netpoll(false); !list.empty() { // non-blocking + if list := netpoll(0); !list.empty() { // non-blocking gp := list.pop() injectglist(&list) casgstatus(gp, _Gwaiting, _Grunnable) @@ -2225,12 +2105,7 @@ top: // Steal work from other P's. procs := uint32(gomaxprocs) - if atomic.Load(&sched.npidle) == procs-1 { - // Either GOMAXPROCS=1 or everybody, except for us, is idle already. - // New work can appear from returning syscall/cgocall, network or timers. - // Neither of that submits to local run queues, so no point in stealing. - goto stop - } + ranTimer := false // If number of spinning M's >= number of busy P's, block. // This is necessary to prevent excessive CPU consumption // when GOMAXPROCS>>1 but the program parallelism is low. @@ -2247,11 +2122,48 @@ top: goto top } stealRunNextG := i > 2 // first look for ready queues with more than 1 g - if gp := runqsteal(_p_, allp[enum.position()], stealRunNextG); gp != nil { + p2 := allp[enum.position()] + if _p_ == p2 { + continue + } + if gp := runqsteal(_p_, p2, stealRunNextG); gp != nil { return gp, false } + + // Consider stealing timers from p2. + // This call to checkTimers is the only place where + // we hold a lock on a different P's timers. + // Lock contention can be a problem here, so avoid + // grabbing the lock if p2 is running and not marked + // for preemption. If p2 is running and not being + // preempted we assume it will handle its own timers. + if i > 2 && shouldStealTimers(p2) { + tnow, w, ran := checkTimers(p2, now) + now = tnow + if w != 0 && (pollUntil == 0 || w < pollUntil) { + pollUntil = w + } + if ran { + // Running the timers may have + // made an arbitrary number of G's + // ready and added them to this P's + // local run queue. That invalidates + // the assumption of runqsteal + // that is always has room to add + // stolen G's. So check now if there + // is a local G to run. + if gp, inheritTime := runqget(_p_); gp != nil { + return gp, inheritTime + } + ranTimer = true + } + } } } + if ranTimer { + // Running a timer may have made some goroutine ready. + goto top + } stop: @@ -2268,10 +2180,16 @@ stop: return gp, false } + delta := int64(-1) + if pollUntil != 0 { + // checkTimers ensures that polluntil > now. + delta = pollUntil - now + } + // wasm only: // If a callback returned and no other goroutine is awake, // then pause execution until a callback was triggered. - if beforeIdle() { + if beforeIdle(delta) { // At least one goroutine got woken. goto top } @@ -2359,21 +2277,35 @@ stop: } // poll network - if netpollinited() && atomic.Load(&netpollWaiters) > 0 && atomic.Xchg64(&sched.lastpoll, 0) != 0 { + if netpollinited() && (atomic.Load(&netpollWaiters) > 0 || pollUntil != 0) && atomic.Xchg64(&sched.lastpoll, 0) != 0 { + atomic.Store64(&sched.pollUntil, uint64(pollUntil)) if _g_.m.p != 0 { throw("findrunnable: netpoll with p") } if _g_.m.spinning { throw("findrunnable: netpoll with spinning") } - list := netpoll(true) // block until new work is available + if faketime != 0 { + // When using fake time, just poll. + delta = 0 + } + list := netpoll(delta) // block until new work is available + atomic.Store64(&sched.pollUntil, 0) atomic.Store64(&sched.lastpoll, uint64(nanotime())) - if !list.empty() { - lock(&sched.lock) - _p_ = pidleget() - unlock(&sched.lock) - if _p_ != nil { - acquirep(_p_) + if faketime != 0 && list.empty() { + // Using fake time and nothing is ready; stop M. + // When all M's stop, checkdead will call timejump. + stopm() + goto top + } + lock(&sched.lock) + _p_ = pidleget() + unlock(&sched.lock) + if _p_ == nil { + injectglist(&list) + } else { + acquirep(_p_) + if !list.empty() { gp := list.pop() injectglist(&list) casgstatus(gp, _Gwaiting, _Grunnable) @@ -2382,7 +2314,16 @@ stop: } return gp, false } - injectglist(&list) + if wasSpinning { + _g_.m.spinning = true + atomic.Xadd(&sched.nmspinning, 1) + } + goto top + } + } else if pollUntil != 0 && netpollinited() { + pollerPollUntil := int64(atomic.Load64(&sched.pollUntil)) + if pollerPollUntil == 0 || pollerPollUntil > pollUntil { + netpollBreak() } } stopm() @@ -2402,7 +2343,7 @@ func pollWork() bool { return true } if netpollinited() && atomic.Load(&netpollWaiters) > 0 && sched.lastpoll != 0 { - if list := netpoll(false); !list.empty() { + if list := netpoll(0); !list.empty() { injectglist(&list) return true } @@ -2410,6 +2351,22 @@ func pollWork() bool { return false } +// wakeNetPoller wakes up the thread sleeping in the network poller, +// if there is one, and if it isn't going to wake up anyhow before +// the when argument. +func wakeNetPoller(when int64) { + if atomic.Load64(&sched.lastpoll) == 0 { + // In findrunnable we ensure that when polling the pollUntil + // field is either zero or the time to which the current + // poll is expected to run. This can have a spurious wakeup + // but should never miss a wakeup. + pollerPollUntil := int64(atomic.Load64(&sched.pollUntil)) + if pollerPollUntil == 0 || pollerPollUntil > when { + netpollBreak() + } + } +} + func resetspinning() { _g_ := getg() if !_g_.m.spinning { @@ -2474,14 +2431,26 @@ func schedule() { } top: + pp := _g_.m.p.ptr() + pp.preempt = false + if sched.gcwaiting != 0 { gcstopm() goto top } - if _g_.m.p.ptr().runSafePointFn != 0 { + if pp.runSafePointFn != 0 { runSafePointFn() } + // Sanity check: if we are spinning, the run queue should be empty. + // Check this before calling checkTimers, as that might call + // goready to put a ready goroutine on the local run queue. + if _g_.m.spinning && (pp.runnext != 0 || pp.runqhead != pp.runqtail) { + throw("schedule: spinning with local work") + } + + checkTimers(pp, 0) + var gp *g var inheritTime bool @@ -2513,9 +2482,8 @@ top: } if gp == nil { gp, inheritTime = runqget(_g_.m.p.ptr()) - if gp != nil && _g_.m.spinning { - throw("schedule: spinning with local work") - } + // We can see gp != nil here even if the M is spinning, + // if checkTimers added a local goroutine via goready. // Because gccgo does not implement preemption as a stack check, // we need to check for preemption here for fairness. @@ -2591,6 +2559,62 @@ func dropg() { setGNoWB(&_g_.m.curg, nil) } +// checkTimers runs any timers for the P that are ready. +// If now is not 0 it is the current time. +// It returns the current time or 0 if it is not known, +// and the time when the next timer should run or 0 if there is no next timer, +// and reports whether it ran any timers. +// If the time when the next timer should run is not 0, +// it is always larger than the returned time. +// We pass now in and out to avoid extra calls of nanotime. +//go:yeswritebarrierrec +func checkTimers(pp *p, now int64) (rnow, pollUntil int64, ran bool) { + lock(&pp.timersLock) + + adjusttimers(pp) + + rnow = now + if len(pp.timers) > 0 { + if rnow == 0 { + rnow = nanotime() + } + for len(pp.timers) > 0 { + // Note that runtimer may temporarily unlock + // pp.timersLock. + if tw := runtimer(pp, rnow); tw != 0 { + if tw > 0 { + pollUntil = tw + } + break + } + ran = true + } + } + + unlock(&pp.timersLock) + + return rnow, pollUntil, ran +} + +// shouldStealTimers reports whether we should try stealing the timers from p2. +// We don't steal timers from a running P that is not marked for preemption, +// on the assumption that it will run its own timers. This reduces +// contention on the timers lock. +func shouldStealTimers(p2 *p) bool { + if p2.status != _Prunning { + return true + } + mp := p2.m.ptr() + if mp == nil || mp.locks > 0 { + return false + } + gp := mp.curg + if gp == nil || gp.atomicstatus != _Grunning || !gp.preempt { + return false + } + return true +} + func parkunlock_c(gp *g, lock unsafe.Pointer) bool { unlock((*mutex)(lock)) return true @@ -2604,8 +2628,8 @@ func park_m(gp *g) { traceGoPark(_g_.m.waittraceev, _g_.m.waittraceskip) } - dropg() casgstatus(gp, _Grunning, _Gwaiting) + dropg() if fn := _g_.m.waitunlockf; fn != nil { ok := fn(gp, _g_.m.waitlock) @@ -2628,8 +2652,8 @@ func goschedImpl(gp *g) { dumpgstatus(gp) throw("bad g status") } - dropg() casgstatus(gp, _Grunning, _Grunnable) + dropg() lock(&sched.lock) globrunqput(gp) unlock(&sched.lock) @@ -2648,7 +2672,7 @@ func gosched_m(gp *g) { // goschedguarded is a forbidden-states-avoided version of gosched_m func goschedguarded_m(gp *g) { - if gp.m.locks != 0 || gp.m.mallocing != 0 || gp.m.preemptoff != "" || gp.m.p.ptr().status != _Prunning { + if !canPreemptM(gp.m) { gogo(gp) // never return } @@ -2665,6 +2689,47 @@ func gopreempt_m(gp *g) { goschedImpl(gp) } +// preemptPark parks gp and puts it in _Gpreempted. +// +//go:systemstack +func preemptPark(gp *g) { + if trace.enabled { + traceGoPark(traceEvGoBlock, 0) + } + status := readgstatus(gp) + if status&^_Gscan != _Grunning { + dumpgstatus(gp) + throw("bad g status") + } + gp.waitreason = waitReasonPreempted + // Transition from _Grunning to _Gscan|_Gpreempted. We can't + // be in _Grunning when we dropg because then we'd be running + // without an M, but the moment we're in _Gpreempted, + // something could claim this G before we've fully cleaned it + // up. Hence, we set the scan bit to lock down further + // transitions until we can dropg. + casGToPreemptScan(gp, _Grunning, _Gscan|_Gpreempted) + dropg() + casfrom_Gscanstatus(gp, _Gscan|_Gpreempted, _Gpreempted) + schedule() +} + +// goyield is like Gosched, but it: +// - does not emit a GoSched trace event +// - puts the current G on the runq of the current P instead of the globrunq +func goyield() { + checkTimeouts() + mcall(goyield_m) +} + +func goyield_m(gp *g) { + pp := gp.m.p.ptr() + casgstatus(gp, _Grunning, _Grunnable) + dropg() + runqput(pp, gp, false) + schedule() +} + // Finishes execution of the current goroutine. func goexit1() { if trace.enabled { @@ -2687,6 +2752,7 @@ func goexit0(gp *g) { gp.lockedm = 0 _g_.m.lockedg = 0 gp.entry = nil + gp.preemptStop = false gp.paniconfault = false gp._defer = nil // should be true already but just in case. gp._panic = nil // non-nil for Goexit during panic. points at stack-allocated data. @@ -2705,9 +2771,6 @@ func goexit0(gp *g) { gp.gcAssistBytes = 0 } - // Note that gp's stack scan is now "valid" because it has no - // stack. - gp.gcscanvalid = true dropg() if GOARCH == "wasm" { // no threads yet on wasm @@ -3215,7 +3278,6 @@ func newproc(fn uintptr, arg unsafe.Pointer) *g { if isSystemGoroutine(newg, false) { atomic.Xadd(&sched.ngsys, +1) } - newg.gcscanvalid = false casgstatus(newg, _Gdead, _Grunnable) if _p_.goidcache == _p_.goidcacheend { @@ -3736,6 +3798,20 @@ func (pp *p) destroy() { globrunqputhead(pp.runnext.ptr()) pp.runnext = 0 } + if len(pp.timers) > 0 { + plocal := getg().m.p.ptr() + // The world is stopped, but we acquire timersLock to + // protect against sysmon calling timeSleepUntil. + // This is the only case where we hold the timersLock of + // more than one P, so there are no deadlock concerns. + lock(&plocal.timersLock) + lock(&pp.timersLock) + moveTimers(plocal, pp.timers) + pp.timers = nil + pp.adjustTimers = 0 + unlock(&pp.timersLock) + unlock(&plocal.timersLock) + } // If there's a background worker, make it runnable and put // it on the global queue so it can clean itself up. if gp := pp.gcBgMarkWorker.ptr(); gp != nil { @@ -3761,14 +3837,18 @@ func (pp *p) destroy() { pp.deferpoolbuf[i] = nil } pp.deferpool = pp.deferpoolbuf[:0] + systemstack(func() { + for i := 0; i < pp.mspancache.len; i++ { + // Safe to call since the world is stopped. + mheap_.spanalloc.free(unsafe.Pointer(pp.mspancache.buf[i])) + } + pp.mspancache.len = 0 + pp.pcache.flush(&mheap_.pages) + }) freemcache(pp.mcache) pp.mcache = nil gfpurge(pp) traceProcFree(pp) - if raceenabled { - raceprocdestroy(pp.raceprocctx) - pp.raceprocctx = 0 - } pp.gcAssistTime = 0 pp.status = _Pdead } @@ -4016,7 +4096,8 @@ func checkdead() { } s := readgstatus(gp) switch s &^ _Gscan { - case _Gwaiting: + case _Gwaiting, + _Gpreempted: grunning++ case _Grunnable, _Grunning, @@ -4028,17 +4109,18 @@ func checkdead() { } unlock(&allglock) if grunning == 0 { // possible if main goroutine calls runtime·Goexit() + unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang throw("no goroutines (main called runtime.Goexit) - deadlock!") } // Maybe jump time forward for playground. - gp := timejump() - if gp != nil { - casgstatus(gp, _Gwaiting, _Grunnable) - globrunqput(gp) - _p_ := pidleget() - if _p_ == nil { - throw("checkdead: no p for timer") + _p_ := timejump() + if _p_ != nil { + for pp := &sched.pidle; *pp != 0; pp = &(*pp).ptr().link { + if (*pp).ptr() == _p_ { + *pp = _p_.link + break + } } mp := mget() if mp == nil { @@ -4051,7 +4133,15 @@ func checkdead() { return } + // There are no goroutines running, so we can look at the P's. + for _, _p_ := range allp { + if len(_p_.timers) > 0 { + return + } + } + getg().m.throwing = -1 // do not dump full stacks + unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang throw("all goroutines are asleep - deadlock!") } @@ -4084,32 +4174,34 @@ func sysmon() { delay = 10 * 1000 } usleep(delay) + now := nanotime() + next := timeSleepUntil() if debug.schedtrace <= 0 && (sched.gcwaiting != 0 || atomic.Load(&sched.npidle) == uint32(gomaxprocs)) { lock(&sched.lock) if atomic.Load(&sched.gcwaiting) != 0 || atomic.Load(&sched.npidle) == uint32(gomaxprocs) { - atomic.Store(&sched.sysmonwait, 1) - unlock(&sched.lock) - // Make wake-up period small enough - // for the sampling to be correct. - maxsleep := forcegcperiod / 2 - shouldRelax := true - if osRelaxMinNS > 0 { - next := timeSleepUntil() - now := nanotime() - if next-now < osRelaxMinNS { - shouldRelax = false + if next > now { + atomic.Store(&sched.sysmonwait, 1) + unlock(&sched.lock) + // Make wake-up period small enough + // for the sampling to be correct. + sleep := forcegcperiod / 2 + if next-now < sleep { + sleep = next - now } + shouldRelax := sleep >= osRelaxMinNS + if shouldRelax { + osRelax(true) + } + notetsleep(&sched.sysmonnote, sleep) + if shouldRelax { + osRelax(false) + } + now = nanotime() + next = timeSleepUntil() + lock(&sched.lock) + atomic.Store(&sched.sysmonwait, 0) + noteclear(&sched.sysmonnote) } - if shouldRelax { - osRelax(true) - } - notetsleep(&sched.sysmonnote, maxsleep) - if shouldRelax { - osRelax(false) - } - lock(&sched.lock) - atomic.Store(&sched.sysmonwait, 0) - noteclear(&sched.sysmonnote) idle = 0 delay = 20 } @@ -4121,10 +4213,9 @@ func sysmon() { } // poll network if not polled for more than 10ms lastpoll := int64(atomic.Load64(&sched.lastpoll)) - now := nanotime() if netpollinited() && lastpoll != 0 && lastpoll+10*1000*1000 < now { atomic.Cas64(&sched.lastpoll, uint64(lastpoll), uint64(now)) - list := netpoll(false) // non-blocking - returns list of goroutines + list := netpoll(0) // non-blocking - returns list of goroutines if !list.empty() { // Need to decrement number of idle locked M's // (pretending that one more is running) before injectglist. @@ -4138,6 +4229,12 @@ func sysmon() { incidlelocked(1) } } + if next < now { + // There are timers that should have already run, + // perhaps because there is an unpreemptible P. + // Try to start an M to run them. + startm(nil, false) + } // retake P's blocked in syscalls // and preempt long running G's if retake(now) != 0 { @@ -4296,6 +4393,12 @@ func preemptone(_p_ *p) bool { // and a few other places, which is at least better than doing // nothing at all. + // Request an async preemption of this P. + if preemptMSupported && debug.asyncpreemptoff == 0 { + _p_.preempt = true + preemptM(mp) + } + return true } @@ -4324,7 +4427,7 @@ func schedtrace(detailed bool) { if mp != nil { id = mp.id } - print(" P", i, ": status=", _p_.status, " schedtick=", _p_.schedtick, " syscalltick=", _p_.syscalltick, " m=", id, " runqsize=", t-h, " gfreecnt=", _p_.gFree.n, "\n") + print(" P", i, ": status=", _p_.status, " schedtick=", _p_.schedtick, " syscalltick=", _p_.syscalltick, " m=", id, " runqsize=", t-h, " gfreecnt=", _p_.gFree.n, " timerslen=", len(_p_.timers), "\n") } else { // In non-detailed mode format lengths of per-P run queues as: // [len1 len2 len3 len4] diff --git a/libgo/go/runtime/proc_test.go b/libgo/go/runtime/proc_test.go index fee03be6e58..a693937aa1e 100644 --- a/libgo/go/runtime/proc_test.go +++ b/libgo/go/runtime/proc_test.go @@ -362,6 +362,17 @@ func TestPreemptionGC(t *testing.T) { atomic.StoreUint32(&stop, 1) } +func TestAsyncPreempt(t *testing.T) { + if !runtime.PreemptMSupported { + t.Skip("asynchronous preemption not supported on this platform") + } + output := runTestProg(t, "testprog", "AsyncPreempt") + want := "OK\n" + if output != want { + t.Fatalf("want %s, got %s\n", want, output) + } +} + func TestGCFairness(t *testing.T) { output := runTestProg(t, "testprog", "GCFairness") want := "OK\n" @@ -988,3 +999,42 @@ func TestPreemptionAfterSyscall(t *testing.T) { func TestGetgThreadSwitch(t *testing.T) { runtime.RunGetgThreadSwitchTest() } + +// TestNetpollBreak tests that netpollBreak can break a netpoll. +// This test is not particularly safe since the call to netpoll +// will pick up any stray files that are ready, but it should work +// OK as long it is not run in parallel. +func TestNetpollBreak(t *testing.T) { + if runtime.GOMAXPROCS(0) == 1 { + t.Skip("skipping: GOMAXPROCS=1") + } + + // Make sure that netpoll is initialized. + runtime.NetpollGenericInit() + + start := time.Now() + c := make(chan bool, 2) + go func() { + c <- true + runtime.Netpoll(10 * time.Second.Nanoseconds()) + c <- true + }() + <-c + // Loop because the break might get eaten by the scheduler. + // Break twice to break both the netpoll we started and the + // scheduler netpoll. +loop: + for { + runtime.Usleep(100) + runtime.NetpollBreak() + runtime.NetpollBreak() + select { + case <-c: + break loop + default: + } + } + if dur := time.Since(start); dur > 5*time.Second { + t.Errorf("netpollBreak did not interrupt netpoll: slept for: %v", dur) + } +} diff --git a/libgo/go/runtime/race0.go b/libgo/go/runtime/race0.go index f1d37062317..6f26afa854f 100644 --- a/libgo/go/runtime/race0.go +++ b/libgo/go/runtime/race0.go @@ -29,6 +29,7 @@ func racereadrangepc(addr unsafe.Pointer, sz, callerpc, pc uintptr) { th func racewriterangepc(addr unsafe.Pointer, sz, callerpc, pc uintptr) { throw("race") } func raceacquire(addr unsafe.Pointer) { throw("race") } func raceacquireg(gp *g, addr unsafe.Pointer) { throw("race") } +func raceacquirectx(racectx uintptr, addr unsafe.Pointer) { throw("race") } func racerelease(addr unsafe.Pointer) { throw("race") } func racereleaseg(gp *g, addr unsafe.Pointer) { throw("race") } func racereleasemerge(addr unsafe.Pointer) { throw("race") } @@ -38,3 +39,4 @@ func racemalloc(p unsafe.Pointer, sz uintptr) { th func racefree(p unsafe.Pointer, sz uintptr) { throw("race") } func racegostart(pc uintptr) uintptr { throw("race"); return 0 } func racegoend() { throw("race") } +func racectxend(racectx uintptr) { throw("race") } diff --git a/libgo/go/runtime/runtime1.go b/libgo/go/runtime/runtime1.go index c64549cd255..60aa90f58fb 100644 --- a/libgo/go/runtime/runtime1.go +++ b/libgo/go/runtime/runtime1.go @@ -326,6 +326,7 @@ var debug struct { scheddetail int32 schedtrace int32 tracebackancestors int32 + asyncpreemptoff int32 } var dbgvars = []dbgVar{ @@ -345,6 +346,7 @@ var dbgvars = []dbgVar{ {"scheddetail", &debug.scheddetail}, {"schedtrace", &debug.schedtrace}, {"tracebackancestors", &debug.tracebackancestors}, + {"asyncpreemptoff", &debug.asyncpreemptoff}, } func parsedebugvars() { diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go index 77648c2477a..d50f82abd87 100644 --- a/libgo/go/runtime/runtime2.go +++ b/libgo/go/runtime/runtime2.go @@ -40,7 +40,7 @@ const ( // _Grunning means this goroutine may execute user code. The // stack is owned by this goroutine. It is not on a run queue. - // It is assigned an M and a P. + // It is assigned an M and a P (g.m and g.m.p are valid). _Grunning // 2 // _Gsyscall means this goroutine is executing a system call. @@ -78,11 +78,18 @@ const ( // stack is owned by the goroutine that put it in _Gcopystack. _Gcopystack // 8 + // _Gpreempted means this goroutine stopped itself for a + // suspendG preemption. It is like _Gwaiting, but nothing is + // yet responsible for ready()ing it. Some suspendG must CAS + // the status to _Gwaiting to take responsibility for + // ready()ing this G. + _Gpreempted // 9 + // _Gexitingsyscall means this goroutine is exiting from a // system call. This is like _Gsyscall, but the GC should not // scan its stack. Currently this is only used in exitsyscall0 // as a transient state when it drops the G. - _Gexitingsyscall // 9 + _Gexitingsyscall // 10 // _Gscan combined with one of the above states other than // _Grunning indicates that GC is scanning the stack. The @@ -95,11 +102,12 @@ const ( // // atomicstatus&~Gscan gives the state the goroutine will // return to when the scan completes. - _Gscan = 0x1000 - _Gscanrunnable = _Gscan + _Grunnable // 0x1001 - _Gscanrunning = _Gscan + _Grunning // 0x1002 - _Gscansyscall = _Gscan + _Gsyscall // 0x1003 - _Gscanwaiting = _Gscan + _Gwaiting // 0x1004 + _Gscan = 0x1000 + _Gscanrunnable = _Gscan + _Grunnable // 0x1001 + _Gscanrunning = _Gscan + _Grunning // 0x1002 + _Gscansyscall = _Gscan + _Gsyscall // 0x1003 + _Gscanwaiting = _Gscan + _Gwaiting // 0x1004 + _Gscanpreempted = _Gscan + _Gpreempted // 0x1009 ) const ( @@ -407,21 +415,36 @@ type g struct { param unsafe.Pointer // passed parameter on wakeup atomicstatus uint32 // Not for gccgo: stackLock uint32 // sigprof/scang lock; TODO: fold in to atomicstatus - goid int64 - schedlink guintptr - waitsince int64 // approx time when the g become blocked - waitreason waitReason // if status==Gwaiting - preempt bool // preemption signal, duplicates stackguard0 = stackpreempt - paniconfault bool // panic (instead of crash) on unexpected fault address - preemptscan bool // preempted g does scan for gc - gcscandone bool // g has scanned stack; protected by _Gscan bit in status - gcscanvalid bool // false at start of gc cycle, true if G has not run since last scan; TODO: remove? - throwsplit bool // must not split stack - raceignore int8 // ignore race detection events - sysblocktraced bool // StartTrace has emitted EvGoInSyscall about this goroutine - sysexitticks int64 // cputicks when syscall has returned (for tracing) - traceseq uint64 // trace event sequencer - tracelastp puintptr // last P emitted an event for this goroutine + goid int64 + schedlink guintptr + waitsince int64 // approx time when the g become blocked + waitreason waitReason // if status==Gwaiting + preempt bool // preemption signal, duplicates stackguard0 = stackpreempt + preemptStop bool // transition to _Gpreempted on preemption; otherwise, just deschedule + // Not for gccgo: preemptShrink bool // shrink stack at synchronous safe point + // asyncSafePoint is set if g is stopped at an asynchronous + // safe point. This means there are frames on the stack + // without precise pointer information. + asyncSafePoint bool + + paniconfault bool // panic (instead of crash) on unexpected fault address + preemptscan bool // preempted g does scan for gc + gcscandone bool // g has scanned stack; protected by _Gscan bit in status + throwsplit bool // must not split stack + + gcScannedSyscallStack bool // gccgo specific; see scanSyscallStack + + // activeStackChans indicates that there are unlocked channels + // pointing into this goroutine's stack. If true, stack + // copying needs to acquire channel locks to protect these + // areas of the stack. + activeStackChans bool + + raceignore int8 // ignore race detection events + sysblocktraced bool // StartTrace has emitted EvGoInSyscall about this goroutine + sysexitticks int64 // cputicks when syscall has returned (for tracing) + traceseq uint64 // trace event sequencer + tracelastp puintptr // last P emitted an event for this goroutine lockedm muintptr sig uint32 writebuf []byte @@ -555,8 +578,7 @@ type m struct { waittraceskip int startingtrace bool syscalltick uint32 - // Not for gccgo: thread uintptr // thread handle - freelink *m // on sched.freem + freelink *m // on sched.freem // these are here because they are too large to be on the stack // of low-level NOSPLIT functions. @@ -566,6 +588,11 @@ type m struct { // Not for gccgo: libcallg guintptr // Not for gccgo: syscall libcall // stores syscall parameters on windows + // preemptGen counts the number of completed preemption + // signals. This is used to detect when a preemption is + // requested, but fails. Accessed atomically. + preemptGen uint32 + dlogPerM mOS @@ -590,6 +617,7 @@ type p struct { sysmontick sysmontick // last tick observed by sysmon m muintptr // back-link to associated m (nil if idle) mcache *mcache + pcache pageCache raceprocctx uintptr // gccgo has only one size of defer. @@ -624,6 +652,17 @@ type p struct { sudogcache []*sudog sudogbuf [128]*sudog + // Cache of mspan objects from the heap. + mspancache struct { + // We need an explicit length here because this field is used + // in allocation codepaths where write barriers are not allowed, + // and eliminating the write barrier/keeping it eliminated from + // slice updates is tricky, moreso than just managing the length + // ourselves. + len int + buf [128]*mspan + } + tracebuf traceBufPtr // traceSweep indicates the sweep events should be traced. @@ -660,13 +699,36 @@ type p struct { runSafePointFn uint32 // if 1, run sched.safePointFn at next safe point + // Lock for timers. We normally access the timers while running + // on this P, but the scheduler can also do it from a different P. + timersLock mutex + + // Actions to take at some time. This is used to implement the + // standard library's time package. + // Must hold timersLock to access. + timers []*timer + + // Number of timerModifiedEarlier timers on P's heap. + // This should only be modified while holding timersLock, + // or while the timer status is in a transient state + // such as timerModifying. + adjustTimers uint32 + + // Race context used while executing timer functions. + // Not for gccgo: timerRaceCtx uintptr + + // preempt is set to indicate that this P should be enter the + // scheduler ASAP (regardless of what G is running on it). + preempt bool + pad cpu.CacheLinePad } type schedt struct { // accessed atomically. keep at top to ensure alignment on 32-bit systems. - goidgen uint64 - lastpoll uint64 + goidgen uint64 + lastpoll uint64 // time of last network poll, 0 if currently polling + pollUntil uint64 // time to which current poll is sleeping lock mutex @@ -841,6 +903,11 @@ type _defer struct { // panics // This is the gccgo version. +// +// This is marked go:notinheap because _panic values must only ever +// live on the stack. +// +//go:notinheap type _panic struct { // The next entry in the stack. link *_panic @@ -858,6 +925,9 @@ type _panic struct { // Whether this panic was already seen by a deferred function // which called panic again. aborted bool + + // Whether this panic was created for goexit. + goexit bool } // ancestorInfo records details of where a goroutine was started. @@ -906,6 +976,7 @@ const ( waitReasonTraceReaderBlocked // "trace reader (blocked)" waitReasonWaitForGCCycle // "wait for GC cycle" waitReasonGCWorkerIdle // "GC worker (idle)" + waitReasonPreempted // "preempted" ) var waitReasonStrings = [...]string{ @@ -934,6 +1005,7 @@ var waitReasonStrings = [...]string{ waitReasonTraceReaderBlocked: "trace reader (blocked)", waitReasonWaitForGCCycle: "wait for GC cycle", waitReasonGCWorkerIdle: "GC worker (idle)", + waitReasonPreempted: "preempted", } func (w waitReason) String() string { diff --git a/libgo/go/runtime/runtime_mmap_test.go b/libgo/go/runtime/runtime_mmap_test.go index c7703f47053..21918c50bb4 100644 --- a/libgo/go/runtime/runtime_mmap_test.go +++ b/libgo/go/runtime/runtime_mmap_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris package runtime_test diff --git a/libgo/go/runtime/runtime_test.go b/libgo/go/runtime/runtime_test.go index e60786804d0..ca352055755 100644 --- a/libgo/go/runtime/runtime_test.go +++ b/libgo/go/runtime/runtime_test.go @@ -122,6 +122,21 @@ func BenchmarkDeferMany(b *testing.B) { } } +func BenchmarkPanicRecover(b *testing.B) { + for i := 0; i < b.N; i++ { + defer3() + } +} + +func defer3() { + defer func(x, y, z int) { + if recover() == nil { + panic("failed recover") + } + }(1, 2, 3) + panic("hi") +} + // golang.org/issue/7063 func TestStopCPUProfilingWithProfilerOff(t *testing.T) { SetCPUProfileRate(0) @@ -177,13 +192,14 @@ func TestSetPanicOnFault(t *testing.T) { } } +// testSetPanicOnFault tests one potentially faulting address. +// It deliberately constructs and uses an invalid pointer, +// so mark it as nocheckptr. +//go:nocheckptr func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) { if strings.Contains(Version(), "llvm") { t.Skip("LLVM doesn't support non-call exception") } - if GOOS == "nacl" { - t.Skip("nacl doesn't seem to fault on high addresses") - } if GOOS == "js" { t.Skip("js does not support catching faults") } @@ -283,32 +299,6 @@ func TestTrailingZero(t *testing.T) { } */ -func TestBadOpen(t *testing.T) { - if GOOS == "windows" || GOOS == "nacl" || GOOS == "js" { - t.Skip("skipping OS that doesn't have open/read/write/close") - } - // make sure we get the correct error code if open fails. Same for - // read/write/close on the resulting -1 fd. See issue 10052. - nonfile := []byte("/notreallyafile") - fd := Open(&nonfile[0], 0, 0) - if fd != -1 { - t.Errorf("open(\"%s\")=%d, want -1", string(nonfile), fd) - } - var buf [32]byte - r := Read(-1, unsafe.Pointer(&buf[0]), int32(len(buf))) - if r != -1 { - t.Errorf("read()=%d, want -1", r) - } - w := Write(^uintptr(0), unsafe.Pointer(&buf[0]), int32(len(buf))) - if w != -1 { - t.Errorf("write()=%d, want -1", w) - } - c := Close(-1) - if c != -1 { - t.Errorf("close()=%d, want -1", c) - } -} - func TestAppendGrowth(t *testing.T) { var x []int64 check := func(want int) { diff --git a/libgo/go/runtime/select.go b/libgo/go/runtime/select.go index 41e5e88b286..c9e3dd77d70 100644 --- a/libgo/go/runtime/select.go +++ b/libgo/go/runtime/select.go @@ -19,7 +19,7 @@ const debugSelect = false // scase.kind values. // Known to compiler. -// Changes here must also be made in src/cmd/compile/internal/gc/select.go's walkselect. +// Changes here must also be made in src/cmd/compile/internal/gc/select.go's walkselectcases. const ( caseNil = iota caseRecv @@ -70,6 +70,9 @@ func selunlock(scases []scase, lockorder []uint16) { } func selparkcommit(gp *g, _ unsafe.Pointer) bool { + // There are unlocked sudogs that point into gp's stack. Stack + // copying must lock the channels of those sudogs. + gp.activeStackChans = true // This must not access gp's stack (see gopark). In // particular, it must not access the *hselect. That's okay, // because by the time this is called, gp.waiting has all @@ -308,6 +311,7 @@ loop: // wait for someone to wake us up gp.param = nil gopark(selparkcommit, nil, waitReasonSelect, traceEvGoBlockSelect, 1) + gp.activeStackChans = false sellock(scases, lockorder) @@ -458,8 +462,6 @@ sclose: } func (c *hchan) sortkey() uintptr { - // TODO(khr): if we have a moving garbage collector, we'll need to - // change this function. return uintptr(unsafe.Pointer(c)) } diff --git a/libgo/go/runtime/sema.go b/libgo/go/runtime/sema.go index c002e2930be..fb16796d2be 100644 --- a/libgo/go/runtime/sema.go +++ b/libgo/go/runtime/sema.go @@ -180,7 +180,7 @@ func semrelease1(addr *uint32, handoff bool, skipframes int) { atomic.Xadd(&root.nwait, -1) } unlock(&root.lock) - if s != nil { // May be slow, so unlock first + if s != nil { // May be slow or even yield, so unlock first acquiretime := s.acquiretime if acquiretime != 0 { mutexevent(t0-acquiretime, 3+skipframes) @@ -192,6 +192,25 @@ func semrelease1(addr *uint32, handoff bool, skipframes int) { s.ticket = 1 } readyWithTime(s, 5+skipframes) + if s.ticket == 1 && getg().m.locks == 0 { + // Direct G handoff + // readyWithTime has added the waiter G as runnext in the + // current P; we now call the scheduler so that we start running + // the waiter G immediately. + // Note that waiter inherits our time slice: this is desirable + // to avoid having a highly contended semaphore hog the P + // indefinitely. goyield is like Gosched, but it does not emit a + // GoSched trace event and, more importantly, puts the current G + // on the local runq instead of the global one. + // We only do this in the starving regime (handoff=true), as in + // the non-starving case it is possible for a different waiter + // to acquire the semaphore while we are yielding/scheduling, + // and this would be wasteful. We wait instead to enter starving + // regime, and then we start to do direct handoffs of ticket and + // P. + // See issue 33747 for discussion. + goyield() + } } } @@ -373,19 +392,11 @@ Found: func (root *semaRoot) rotateLeft(x *sudog) { // p -> (x a (y b c)) p := x.parent - a, y := x.prev, x.next - b, c := y.prev, y.next + y := x.next + b := y.prev y.prev = x x.parent = y - y.next = c - if c != nil { - c.parent = y - } - x.prev = a - if a != nil { - a.parent = x - } x.next = b if b != nil { b.parent = x @@ -409,23 +420,15 @@ func (root *semaRoot) rotateLeft(x *sudog) { func (root *semaRoot) rotateRight(y *sudog) { // p -> (y (x a b) c) p := y.parent - x, c := y.prev, y.next - a, b := x.prev, x.next + x := y.prev + b := x.next - x.prev = a - if a != nil { - a.parent = x - } x.next = y y.parent = x y.prev = b if b != nil { b.parent = y } - y.next = c - if c != nil { - c.parent = y - } x.parent = p if p == nil { diff --git a/libgo/go/runtime/sema_test.go b/libgo/go/runtime/sema_test.go new file mode 100644 index 00000000000..8bd5d4ce57c --- /dev/null +++ b/libgo/go/runtime/sema_test.go @@ -0,0 +1,97 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + . "runtime" + "sync/atomic" + "testing" +) + +// TestSemaHandoff checks that when semrelease+handoff is +// requested, the G that releases the semaphore yields its +// P directly to the first waiter in line. +// See issue 33747 for discussion. +func TestSemaHandoff(t *testing.T) { + const iter = 10000 + ok := 0 + for i := 0; i < iter; i++ { + if testSemaHandoff() { + ok++ + } + } + // As long as two thirds of handoffs are direct, we + // consider the test successful. The scheduler is + // nondeterministic, so this test checks that we get the + // desired outcome in a significant majority of cases. + // The actual ratio of direct handoffs is much higher + // (>90%) but we use a lower threshold to minimize the + // chances that unrelated changes in the runtime will + // cause the test to fail or become flaky. + if ok < iter*2/3 { + t.Fatal("direct handoff < 2/3:", ok, iter) + } +} + +func TestSemaHandoff1(t *testing.T) { + if GOMAXPROCS(-1) <= 1 { + t.Skip("GOMAXPROCS <= 1") + } + defer GOMAXPROCS(GOMAXPROCS(-1)) + GOMAXPROCS(1) + TestSemaHandoff(t) +} + +func TestSemaHandoff2(t *testing.T) { + if GOMAXPROCS(-1) <= 2 { + t.Skip("GOMAXPROCS <= 2") + } + defer GOMAXPROCS(GOMAXPROCS(-1)) + GOMAXPROCS(2) + TestSemaHandoff(t) +} + +func testSemaHandoff() bool { + var sema, res uint32 + done := make(chan struct{}) + + // We're testing that the current goroutine is able to yield its time slice + // to another goroutine. Stop the current goroutine from migrating to + // another CPU where it can win the race (and appear to have not yielded) by + // keeping the CPUs slightly busy. + for i := 0; i < GOMAXPROCS(-1); i++ { + go func() { + for { + select { + case <-done: + return + default: + } + Gosched() + } + }() + } + + go func() { + Semacquire(&sema) + atomic.CompareAndSwapUint32(&res, 0, 1) + + Semrelease1(&sema, true, 0) + close(done) + }() + for SemNwait(&sema) == 0 { + Gosched() // wait for goroutine to block in Semacquire + } + + // The crux of the test: we release the semaphore with handoff + // and immediately perform a CAS both here and in the waiter; we + // want the CAS in the waiter to execute first. + Semrelease1(&sema, true, 0) + atomic.CompareAndSwapUint32(&res, 0, 2) + + <-done // wait for goroutines to finish to avoid data races + + return res == 1 // did the waiter run first? +} diff --git a/libgo/go/runtime/semasleep_test.go b/libgo/go/runtime/semasleep_test.go index f5b4a506972..9b371b07324 100644 --- a/libgo/go/runtime/semasleep_test.go +++ b/libgo/go/runtime/semasleep_test.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//+build !nacl,!plan9,!windows,!js +// +build !plan9,!windows,!js package runtime_test diff --git a/libgo/go/runtime/signal_sighandler.go b/libgo/go/runtime/signal_sighandler.go deleted file mode 100644 index 3583c7b98a0..00000000000 --- a/libgo/go/runtime/signal_sighandler.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build aix darwin dragonfly freebsd hurd linux nacl netbsd openbsd solaris - -package runtime - -import ( - "unsafe" -) - -// crashing is the number of m's we have waited for when implementing -// GOTRACEBACK=crash when a signal is received. -var crashing int32 - -// testSigtrap is used by the runtime tests. If non-nil, it is called -// on SIGTRAP. If it returns true, the normal behavior on SIGTRAP is -// suppressed. -var testSigtrap func(info *_siginfo_t, ctxt *sigctxt, gp *g) bool - -// sighandler is invoked when a signal occurs. The global g will be -// set to a gsignal goroutine and we will be running on the alternate -// signal stack. The parameter g will be the value of the global g -// when the signal occurred. The sig, info, and ctxt parameters are -// from the system signal handler: they are the parameters passed when -// the SA is passed to the sigaction system call. -// -// The garbage collector may have stopped the world, so write barriers -// are not allowed. -// -//go:nowritebarrierrec -func sighandler(sig uint32, info *_siginfo_t, ctxt unsafe.Pointer, gp *g) { - _g_ := getg() - c := &sigctxt{info, ctxt} - - sigfault, sigpc := getSiginfo(info, ctxt) - - if sig == _SIGURG && usestackmaps { - // We may be signaled to do a stack scan. - // The signal delivery races with enter/exitsyscall. - // We may be on g0 stack now. gp.m.curg is the g we - // want to scan. - // If we're not on g stack, give up. The sender will - // try again later. - // If we're not stopped at a safepoint (doscanstack will - // return false), also give up. - if s := readgstatus(gp.m.curg); s == _Gscansyscall { - if gp == gp.m.curg { - if doscanstack(gp, (*gcWork)(unsafe.Pointer(gp.scangcw))) { - gp.gcscanvalid = true - gp.gcscandone = true - } - } - gp.m.curg.scangcw = 0 - notewakeup(&gp.m.scannote) - return - } - } - - if sig == _SIGPROF { - sigprof(sigpc, gp, _g_.m) - return - } - - if sig == _SIGTRAP && testSigtrap != nil && testSigtrap(info, (*sigctxt)(noescape(unsafe.Pointer(c))), gp) { - return - } - - flags := int32(_SigThrow) - if sig < uint32(len(sigtable)) { - flags = sigtable[sig].flags - } - if flags&_SigPanic != 0 && gp.throwsplit { - // We can't safely sigpanic because it may grow the - // stack. Abort in the signal handler instead. - flags = (flags &^ _SigPanic) | _SigThrow - } - if isAbortPC(sigpc) { - // On many architectures, the abort function just - // causes a memory fault. Don't turn that into a panic. - flags = _SigThrow - } - if c.sigcode() != _SI_USER && flags&_SigPanic != 0 { - // Emulate gc by passing arguments out of band, - // although we don't really have to. - gp.sig = sig - gp.sigcode0 = uintptr(c.sigcode()) - gp.sigcode1 = sigfault - gp.sigpc = sigpc - - setg(gp) - - // All signals were blocked due to the sigaction mask; - // unblock them. - var set sigset - sigfillset(&set) - sigprocmask(_SIG_UNBLOCK, &set, nil) - - sigpanic() - throw("sigpanic returned") - } - - if c.sigcode() == _SI_USER || flags&_SigNotify != 0 { - if sigsend(sig) { - return - } - } - - if c.sigcode() == _SI_USER && signal_ignored(sig) { - return - } - - if flags&_SigKill != 0 { - dieFromSignal(sig) - } - - if flags&_SigThrow == 0 { - return - } - - _g_.m.throwing = 1 - _g_.m.caughtsig.set(gp) - - if crashing == 0 { - startpanic_m() - } - - if sig < uint32(len(sigtable)) { - print(sigtable[sig].name, "\n") - } else { - print("Signal ", sig, "\n") - } - - print("PC=", hex(sigpc), " m=", _g_.m.id, " sigcode=", c.sigcode(), "\n") - if _g_.m.lockedg != 0 && _g_.m.ncgo > 0 && gp == _g_.m.g0 { - print("signal arrived during cgo execution\n") - gp = _g_.m.lockedg.ptr() - } - print("\n") - - level, _, docrash := gotraceback() - if level > 0 { - goroutineheader(gp) - traceback(0) - if crashing == 0 { - tracebackothers(gp) - print("\n") - } - dumpregs(info, ctxt) - } - - if docrash { - crashing++ - if crashing < mcount()-int32(extraMCount) { - // There are other m's that need to dump their stacks. - // Relay SIGQUIT to the next m by sending it to the current process. - // All m's that have already received SIGQUIT have signal masks blocking - // receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet. - // When the last m receives the SIGQUIT, it will fall through to the call to - // crash below. Just in case the relaying gets botched, each m involved in - // the relay sleeps for 5 seconds and then does the crash/exit itself. - // In expected operation, the last m has received the SIGQUIT and run - // crash/exit and the process is gone, all long before any of the - // 5-second sleeps have finished. - print("\n-----\n\n") - raiseproc(_SIGQUIT) - usleep(5 * 1000 * 1000) - } - crash() - } - - printDebugLog() - - exit(2) -} diff --git a/libgo/go/runtime/signal_unix.go b/libgo/go/runtime/signal_unix.go index 365f5dd0ad6..29f9443d13d 100644 --- a/libgo/go/runtime/signal_unix.go +++ b/libgo/go/runtime/signal_unix.go @@ -42,6 +42,38 @@ const ( _SIG_IGN uintptr = 1 ) +// sigPreempt is the signal used for non-cooperative preemption. +// +// There's no good way to choose this signal, but there are some +// heuristics: +// +// 1. It should be a signal that's passed-through by debuggers by +// default. On Linux, this is SIGALRM, SIGURG, SIGCHLD, SIGIO, +// SIGVTALRM, SIGPROF, and SIGWINCH, plus some glibc-internal signals. +// +// 2. It shouldn't be used internally by libc in mixed Go/C binaries +// because libc may assume it's the only thing that can handle these +// signals. For example SIGCANCEL or SIGSETXID. +// +// 3. It should be a signal that can happen spuriously without +// consequences. For example, SIGALRM is a bad choice because the +// signal handler can't tell if it was caused by the real process +// alarm or not (arguably this means the signal is broken, but I +// digress). SIGUSR1 and SIGUSR2 are also bad because those are often +// used in meaningful ways by applications. +// +// 4. We need to deal with platforms without real-time signals (like +// macOS), so those are out. +// +// We use SIGURG because it meets all of these criteria, is extremely +// unlikely to be used by an application for its "real" meaning (both +// because out-of-band data is basically unused and because SIGURG +// doesn't report which socket has the condition, making it pretty +// useless), and even if it is, the application has to be ready for +// spurious SIGURG. SIGIO wouldn't be a bad choice either, but is more +// likely to be used for real. +const sigPreempt = _SIGURG + // Stores the signal handlers registered before Go installed its own. // These signal handlers will be invoked in cases where Go doesn't want to // handle a particular signal (e.g., signal occurred on a non-Go thread). @@ -251,10 +283,26 @@ func setProcessCPUProfiler(hz int32) { } } else { // If the Go signal handler should be disabled by default, - // disable it if it is enabled. + // switch back to the signal handler that was installed + // when we enabled profiling. We don't try to handle the case + // of a program that changes the SIGPROF handler while Go + // profiling is enabled. + // + // If no signal handler was installed before, then start + // ignoring SIGPROF signals. We do this, rather than change + // to SIG_DFL, because there may be a pending SIGPROF + // signal that has not yet been delivered to some other thread. + // If we change to SIG_DFL here, the program will crash + // when that SIGPROF is delivered. We assume that programs + // that use profiling don't want to crash on a stray SIGPROF. + // See issue 19320. if !sigInstallGoHandler(_SIGPROF) { if atomic.Cas(&handlingSig[_SIGPROF], 1, 0) { - setsig(_SIGPROF, atomic.Loaduintptr(&fwdSig[_SIGPROF])) + h := atomic.Loaduintptr(&fwdSig[_SIGPROF]) + if h == _SIG_DFL { + h = _SIG_IGN + } + setsig(_SIGPROF, h) } } } @@ -283,6 +331,51 @@ func sigpipe() { dieFromSignal(_SIGPIPE) } +// doSigPreempt handles a preemption signal on gp. +func doSigPreempt(gp *g, ctxt *sigctxt, sigpc uintptr) { + // Check if this G wants to be preempted and is safe to + // preempt. + if wantAsyncPreempt(gp) && isAsyncSafePoint(gp, sigpc) { + // Inject a call to asyncPreempt. + // ctxt.pushCall(funcPC(asyncPreempt)) + throw("pushCall not implemented") + } + + // Acknowledge the preemption. + atomic.Xadd(&gp.m.preemptGen, 1) +} + +// gccgo-specific definition. +const pushCallSupported = false + +const preemptMSupported = pushCallSupported + +// preemptM sends a preemption request to mp. This request may be +// handled asynchronously and may be coalesced with other requests to +// the M. When the request is received, if the running G or P are +// marked for preemption and the goroutine is at an asynchronous +// safe-point, it will preempt the goroutine. It always atomically +// increments mp.preemptGen after handling a preemption request. +func preemptM(mp *m) { + if !pushCallSupported { + // This architecture doesn't support ctxt.pushCall + // yet, so doSigPreempt won't work. + return + } + if GOOS == "darwin" && (GOARCH == "arm" || GOARCH == "arm64") && !iscgo { + // On darwin, we use libc calls, and cgo is required on ARM and ARM64 + // so we have TLS set up to save/restore G during C calls. If cgo is + // absent, we cannot save/restore G in TLS, and if a signal is + // received during C execution we cannot get the G. Therefore don't + // send signals. + // This can only happen in the go_bootstrap program (otherwise cgo is + // required). + return + } + // signalM(mp, sigPreempt) + throw("signalM not implemented") +} + // sigtrampgo is called from the signal handler function, sigtramp, // written in assembly code. // This is called by the signal handler, and the world may be stopped. @@ -315,6 +408,183 @@ func sigtrampgo(sig uint32, info *_siginfo_t, ctx unsafe.Pointer) { setg(g) } +// crashing is the number of m's we have waited for when implementing +// GOTRACEBACK=crash when a signal is received. +var crashing int32 + +// testSigtrap and testSigusr1 are used by the runtime tests. If +// non-nil, it is called on SIGTRAP/SIGUSR1. If it returns true, the +// normal behavior on this signal is suppressed. +var testSigtrap func(info *_siginfo_t, ctxt *sigctxt, gp *g) bool +var testSigusr1 func(gp *g) bool + +// sighandler is invoked when a signal occurs. The global g will be +// set to a gsignal goroutine and we will be running on the alternate +// signal stack. The parameter g will be the value of the global g +// when the signal occurred. The sig, info, and ctxt parameters are +// from the system signal handler: they are the parameters passed when +// the SA is passed to the sigaction system call. +// +// The garbage collector may have stopped the world, so write barriers +// are not allowed. +// +//go:nowritebarrierrec +func sighandler(sig uint32, info *_siginfo_t, ctxt unsafe.Pointer, gp *g) { + _g_ := getg() + c := &sigctxt{info, ctxt} + + sigfault, sigpc := getSiginfo(info, ctxt) + + if sig == _SIGURG && usestackmaps { + // We may be signaled to do a stack scan. + // The signal delivery races with enter/exitsyscall. + // We may be on g0 stack now. gp.m.curg is the g we + // want to scan. + // If we're not on g stack, give up. The sender will + // try again later. + // If we're not stopped at a safepoint (doscanstack will + // return false), also give up. + if s := readgstatus(gp.m.curg); s == _Gscansyscall { + if gp == gp.m.curg { + if doscanstack(gp, (*gcWork)(unsafe.Pointer(gp.scangcw))) { + gp.gcScannedSyscallStack = true + } + } + gp.m.curg.scangcw = 0 + notewakeup(&gp.m.scannote) + return + } + } + + if sig == _SIGPROF { + sigprof(sigpc, gp, _g_.m) + return + } + + if sig == _SIGTRAP && testSigtrap != nil && testSigtrap(info, (*sigctxt)(noescape(unsafe.Pointer(c))), gp) { + return + } + + if sig == _SIGUSR1 && testSigusr1 != nil && testSigusr1(gp) { + return + } + + if sig == sigPreempt { + // Might be a preemption signal. + doSigPreempt(gp, c, sigpc) + // Even if this was definitely a preemption signal, it + // may have been coalesced with another signal, so we + // still let it through to the application. + } + + flags := int32(_SigThrow) + if sig < uint32(len(sigtable)) { + flags = sigtable[sig].flags + } + if flags&_SigPanic != 0 && gp.throwsplit { + // We can't safely sigpanic because it may grow the + // stack. Abort in the signal handler instead. + flags = (flags &^ _SigPanic) | _SigThrow + } + if isAbortPC(sigpc) { + // On many architectures, the abort function just + // causes a memory fault. Don't turn that into a panic. + flags = _SigThrow + } + if c.sigcode() != _SI_USER && flags&_SigPanic != 0 { + // Emulate gc by passing arguments out of band, + // although we don't really have to. + gp.sig = sig + gp.sigcode0 = uintptr(c.sigcode()) + gp.sigcode1 = sigfault + gp.sigpc = sigpc + + setg(gp) + + // All signals were blocked due to the sigaction mask; + // unblock them. + var set sigset + sigfillset(&set) + sigprocmask(_SIG_UNBLOCK, &set, nil) + + sigpanic() + throw("sigpanic returned") + } + + if c.sigcode() == _SI_USER || flags&_SigNotify != 0 { + if sigsend(sig) { + return + } + } + + if c.sigcode() == _SI_USER && signal_ignored(sig) { + return + } + + if flags&_SigKill != 0 { + dieFromSignal(sig) + } + + if flags&_SigThrow == 0 { + return + } + + _g_.m.throwing = 1 + _g_.m.caughtsig.set(gp) + + if crashing == 0 { + startpanic_m() + } + + if sig < uint32(len(sigtable)) { + print(sigtable[sig].name, "\n") + } else { + print("Signal ", sig, "\n") + } + + print("PC=", hex(sigpc), " m=", _g_.m.id, " sigcode=", c.sigcode(), "\n") + if _g_.m.lockedg != 0 && _g_.m.ncgo > 0 && gp == _g_.m.g0 { + print("signal arrived during cgo execution\n") + gp = _g_.m.lockedg.ptr() + } + print("\n") + + level, _, docrash := gotraceback() + if level > 0 { + goroutineheader(gp) + traceback(0) + if crashing == 0 { + tracebackothers(gp) + print("\n") + } + dumpregs(info, ctxt) + } + + if docrash { + crashing++ + if crashing < mcount()-int32(extraMCount) { + // There are other m's that need to dump their stacks. + // Relay SIGQUIT to the next m by sending it to the current process. + // All m's that have already received SIGQUIT have signal masks blocking + // receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet. + // When the last m receives the SIGQUIT, it will fall through to the call to + // crash below. Just in case the relaying gets botched, each m involved in + // the relay sleeps for 5 seconds and then does the crash/exit itself. + // In expected operation, the last m has received the SIGQUIT and run + // crash/exit and the process is gone, all long before any of the + // 5-second sleeps have finished. + print("\n-----\n\n") + raiseproc(_SIGQUIT) + usleep(5 * 1000 * 1000) + } + crash() + } + + printDebugLog() + + exit(2) +} + // sigpanic turns a synchronous signal into a run-time panic. // If the signal handler sees a synchronous panic, it arranges the // stack to look like the function where the signal occurred called @@ -551,11 +821,22 @@ func signalDuringFork(sig uint32) { throw("signal received during fork") } +var badginsignalMsg = "fatal: bad g in signal handler\n" + // This runs on a foreign stack, without an m or a g. No stack split. //go:nosplit //go:norace //go:nowritebarrierrec func badsignal(sig uintptr, c *sigctxt) { + if !iscgo && !cgoHasExtraM { + // There is no extra M. needm will not be able to grab + // an M. Instead of hanging, just crash. + // Cannot call split-stack function as there is no G. + s := stringStructOf(&badginsignalMsg) + write(2, s.str, int32(s.len)) + exit(2) + *(*uintptr)(unsafe.Pointer(uintptr(123))) = 2 + } needm(0) if !sigsend(uint32(sig)) { // A foreign thread received the signal sig, and the @@ -596,6 +877,13 @@ func sigfwdgo(sig uint32, info *_siginfo_t, ctx unsafe.Pointer) bool { return true } + // This function and its caller sigtrampgo assumes SIGPIPE is delivered on the + // originating thread. This property does not hold on macOS (golang.org/issue/33384), + // so we have no choice but to ignore SIGPIPE. + if GOOS == "darwin" && sig == _SIGPIPE { + return true + } + // If there is no handler to forward to, no need to forward. if fwdFn == _SIG_DFL { return false @@ -610,8 +898,9 @@ func sigfwdgo(sig uint32, info *_siginfo_t, ctx unsafe.Pointer) bool { return false } // Determine if the signal occurred inside Go code. We test that: - // (1) we were in a goroutine (i.e., m.curg != nil), and - // (2) we weren't in CGO. + // (1) we weren't in VDSO page, + // (2) we were in a goroutine (i.e., m.curg != nil), and + // (3) we weren't in CGO. g := getg() if g != nil && g.m != nil && g.m.curg != nil && !g.m.incgo { return false @@ -687,13 +976,15 @@ func minitSignals() { // stack to the gsignal stack. If the alternate signal stack is set // for the thread (the case when a non-Go thread sets the alternate // signal stack and then calls a Go function) then set the gsignal -// stack to the alternate signal stack. Record which choice was made -// in newSigstack, so that it can be undone in unminit. +// stack to the alternate signal stack. We also set the alternate +// signal stack to the gsignal stack if cgo is not used (regardless +// of whether it is already set). Record which choice was made in +// newSigstack, so that it can be undone in unminit. func minitSignalStack() { _g_ := getg() var st _stack_t sigaltstack(nil, &st) - if st.ss_flags&_SS_DISABLE != 0 { + if st.ss_flags&_SS_DISABLE != 0 || !iscgo { signalstack(_g_.m.gsignalstack, _g_.m.gsignalstacksize) _g_.m.newSigstack = true } else { diff --git a/libgo/go/runtime/signal_windows_test.go b/libgo/go/runtime/signal_windows_test.go new file mode 100644 index 00000000000..97484034126 --- /dev/null +++ b/libgo/go/runtime/signal_windows_test.go @@ -0,0 +1,61 @@ +// +build windows + +package runtime_test + +import ( + "internal/testenv" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "testing" +) + +func TestVectoredHandlerDontCrashOnLibrary(t *testing.T) { + if *flagQuick { + t.Skip("-quick") + } + if runtime.GOARCH != "amd64" { + t.Skip("this test can only run on windows/amd64") + } + testenv.MustHaveGoBuild(t) + testenv.MustHaveExecPath(t, "gcc") + testprog.Lock() + defer testprog.Unlock() + dir, err := ioutil.TempDir("", "go-build") + if err != nil { + t.Fatalf("failed to create temp directory: %v", err) + } + defer os.RemoveAll(dir) + + // build go dll + dll := filepath.Join(dir, "testwinlib.dll") + cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dll, "--buildmode", "c-shared", "testdata/testwinlib/main.go") + out, err := testenv.CleanCmdEnv(cmd).CombinedOutput() + if err != nil { + t.Fatalf("failed to build go library: %s\n%s", err, out) + } + + // build c program + exe := filepath.Join(dir, "test.exe") + cmd = exec.Command("gcc", "-L"+dir, "-I"+dir, "-ltestwinlib", "-o", exe, "testdata/testwinlib/main.c") + out, err = testenv.CleanCmdEnv(cmd).CombinedOutput() + if err != nil { + t.Fatalf("failed to build c exe: %s\n%s", err, out) + } + + // run test program + cmd = exec.Command(exe) + out, err = testenv.CleanCmdEnv(cmd).CombinedOutput() + if err != nil { + t.Fatalf("failure while running executable: %s\n%s", err, out) + } + expectedOutput := "exceptionCount: 1\ncontinueCount: 1\n" + // cleaning output + cleanedOut := strings.ReplaceAll(string(out), "\r\n", "\n") + if cleanedOut != expectedOutput { + t.Errorf("expected output %q, got %q", expectedOutput, cleanedOut) + } +} diff --git a/libgo/go/runtime/sizeof_test.go b/libgo/go/runtime/sizeof_test.go index ecda82a988e..d829c5865db 100644 --- a/libgo/go/runtime/sizeof_test.go +++ b/libgo/go/runtime/sizeof_test.go @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !nacl - package runtime_test import ( diff --git a/libgo/go/runtime/slice.go b/libgo/go/runtime/slice.go index 49d5a861054..b61c2b10c7e 100644 --- a/libgo/go/runtime/slice.go +++ b/libgo/go/runtime/slice.go @@ -26,7 +26,7 @@ type slice struct { cap int } -// An notInHeapSlice is a slice backed by go:notinheap memory. +// A notInHeapSlice is a slice backed by go:notinheap memory. type notInHeapSlice struct { array *notInHeap len int diff --git a/libgo/go/runtime/stack_test.go b/libgo/go/runtime/stack_test.go index 6ed65e8285f..169dde27d10 100644 --- a/libgo/go/runtime/stack_test.go +++ b/libgo/go/runtime/stack_test.go @@ -116,6 +116,13 @@ func TestStackGrowth(t *testing.T) { wg.Add(1) go func() { defer wg.Done() + + if Compiler == "gccgo" && !*Pusestackmaps { + // This test is flaky for gccgo's + // conservative stack scanning. + return + } + done := make(chan bool) var startTime time.Time var started, progress uint32 @@ -599,9 +606,6 @@ func (s structWithMethod) callers() []uintptr { return pc[:Callers(0, pc)] } -// The noinline prevents this function from being inlined -// into a wrapper. TODO: remove this when issue 28640 is fixed. -//go:noinline func (s structWithMethod) stack() string { buf := make([]byte, 4<<10) return string(buf[:Stack(buf, false)]) diff --git a/libgo/go/runtime/string.go b/libgo/go/runtime/string.go index 741b6b4ca2f..df4cae7bcef 100644 --- a/libgo/go/runtime/string.go +++ b/libgo/go/runtime/string.go @@ -508,3 +508,37 @@ func __go_byte_array_to_string(p unsafe.Pointer, l int) string { func __go_string_to_byte_array(s string) []byte { return stringtoslicebyte(nil, s) } + +// parseRelease parses a dot-separated version number. It follows the +// semver syntax, but allows the minor and patch versions to be +// elided. +func parseRelease(rel string) (major, minor, patch int, ok bool) { + // Strip anything after a dash or plus. + for i := 0; i < len(rel); i++ { + if rel[i] == '-' || rel[i] == '+' { + rel = rel[:i] + break + } + } + + next := func() (int, bool) { + for i := 0; i < len(rel); i++ { + if rel[i] == '.' { + ver, ok := atoi(rel[:i]) + rel = rel[i+1:] + return ver, ok + } + } + ver, ok := atoi(rel) + rel = "" + return ver, ok + } + if major, ok = next(); !ok || rel == "" { + return + } + if minor, ok = next(); !ok || rel == "" { + return + } + patch, ok = next() + return +} diff --git a/libgo/go/runtime/string_test.go b/libgo/go/runtime/string_test.go index ec83bb4d458..e388f706b5f 100644 --- a/libgo/go/runtime/string_test.go +++ b/libgo/go/runtime/string_test.go @@ -462,3 +462,34 @@ func TestAtoi32(t *testing.T) { } } } + +type parseReleaseTest struct { + in string + major, minor, patch int +} + +var parseReleaseTests = []parseReleaseTest{ + {"", -1, -1, -1}, + {"x", -1, -1, -1}, + {"5", 5, 0, 0}, + {"5.12", 5, 12, 0}, + {"5.12-x", 5, 12, 0}, + {"5.12.1", 5, 12, 1}, + {"5.12.1-x", 5, 12, 1}, + {"5.12.1.0", 5, 12, 1}, + {"5.20496382327982653440", -1, -1, -1}, +} + +func TestParseRelease(t *testing.T) { + for _, test := range parseReleaseTests { + major, minor, patch, ok := runtime.ParseRelease(test.in) + if !ok { + major, minor, patch = -1, -1, -1 + } + if test.major != major || test.minor != minor || test.patch != patch { + t.Errorf("parseRelease(%q) = (%v, %v, %v) want (%v, %v, %v)", + test.in, major, minor, patch, + test.major, test.minor, test.patch) + } + } +} diff --git a/libgo/go/runtime/stubs.go b/libgo/go/runtime/stubs.go index a2e1530d107..ae6134dcb52 100644 --- a/libgo/go/runtime/stubs.go +++ b/libgo/go/runtime/stubs.go @@ -240,11 +240,16 @@ func asmcgocall(fn, arg unsafe.Pointer) int32 { return 0 } -// round n up to a multiple of a. a must be a power of 2. -func round(n, a uintptr) uintptr { +// alignUp rounds n up to a multiple of a. a must be a power of 2. +func alignUp(n, a uintptr) uintptr { return (n + a - 1) &^ (a - 1) } +// alignDown rounds n down to a multiple of a. a must be a power of 2. +func alignDown(n, a uintptr) uintptr { + return n &^ (a - 1) +} + // checkASM returns whether assembly runtime checks have passed. func checkASM() bool { return true diff --git a/libgo/go/runtime/stubs2.go b/libgo/go/runtime/stubs2.go index dcbbffa9180..454afee51fc 100644 --- a/libgo/go/runtime/stubs2.go +++ b/libgo/go/runtime/stubs2.go @@ -4,23 +4,27 @@ // +build !plan9 // +build !windows -// +build !nacl // +build !js package runtime import "unsafe" +// read calls the read system call. +// It returns a non-negative number of bytes written or a negative errno value. //go:noescape func read(fd int32, p unsafe.Pointer, n int32) int32 + func closefd(fd int32) int32 //extern exit func exit(code int32) func usleep(usec uint32) +// write calls the write system call. +// It returns a non-negative number of bytes written or a negative errno value. //go:noescape -func write(fd uintptr, p unsafe.Pointer, n int32) int32 +func write1(fd uintptr, p unsafe.Pointer, n int32) int32 //go:noescape func open(name *byte, mode, perm int32) int32 diff --git a/libgo/go/runtime/stubs3.go b/libgo/go/runtime/stubs3.go index d339787d0f8..35feb100c85 100644 --- a/libgo/go/runtime/stubs3.go +++ b/libgo/go/runtime/stubs3.go @@ -4,4 +4,4 @@ package runtime -func nanotime() int64 +func nanotime1() int64 diff --git a/libgo/go/runtime/symtab.go b/libgo/go/runtime/symtab.go index a2ecf388fea..5dd38949aa3 100644 --- a/libgo/go/runtime/symtab.go +++ b/libgo/go/runtime/symtab.go @@ -79,7 +79,7 @@ func (ci *Frames) Next() (frame Frame, more bool) { // Subtract 1 from PC to undo the 1 we added in callback in // go-callers.c. - function, file, line, _ := funcfileline(pc-1, int32(i)) + function, file, line, _ := funcfileline(pc-1, int32(i), more) if function == "" && file == "" { return Frame{}, more } @@ -127,7 +127,7 @@ type Func struct { // the a *Func describing the innermost function, but with an entry // of the outermost function. func FuncForPC(pc uintptr) *Func { - name, _, _, _ := funcfileline(pc, -1) + name, _, _, _ := funcfileline(pc, -1, false) if name == "" { return nil } @@ -156,7 +156,7 @@ func (f *Func) Entry() uintptr { // The result will not be accurate if pc is not a program // counter within f. func (f *Func) FileLine(pc uintptr) (file string, line int) { - _, file, line, _ = funcfileline(pc, -1) + _, file, line, _ = funcfileline(pc, -1, false) return file, line } @@ -230,5 +230,5 @@ func demangleSymbol(s string) string { } // implemented in go-caller.c -func funcfileline(uintptr, int32) (string, string, int, int) +func funcfileline(uintptr, int32, bool) (string, string, int, int) func funcentry(uintptr) uintptr diff --git a/libgo/go/runtime/testdata/testfaketime/faketime.go b/libgo/go/runtime/testdata/testfaketime/faketime.go new file mode 100644 index 00000000000..1fb15ebb160 --- /dev/null +++ b/libgo/go/runtime/testdata/testfaketime/faketime.go @@ -0,0 +1,28 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test faketime support. This is its own test program because we have +// to build it with custom build tags and hence want to minimize +// dependencies. + +package main + +import ( + "os" + "time" +) + +func main() { + println("line 1") + // Stream switch, increments time + os.Stdout.WriteString("line 2\n") + os.Stdout.WriteString("line 3\n") + // Stream switch, increments time + os.Stderr.WriteString("line 4\n") + // Time jump + time.Sleep(1 * time.Second) + os.Stdout.WriteString("line 5\n") + // Print the current time. + os.Stdout.WriteString(time.Now().UTC().Format(time.RFC3339)) +} diff --git a/libgo/go/runtime/testdata/testprog/deadlock.go b/libgo/go/runtime/testdata/testprog/deadlock.go index 5f0d1200047..105d6a5faae 100644 --- a/libgo/go/runtime/testdata/testprog/deadlock.go +++ b/libgo/go/runtime/testdata/testprog/deadlock.go @@ -22,6 +22,9 @@ func init() { register("StackOverflow", StackOverflow) register("ThreadExhaustion", ThreadExhaustion) register("RecursivePanic", RecursivePanic) + register("RecursivePanic2", RecursivePanic2) + register("RecursivePanic3", RecursivePanic3) + register("RecursivePanic4", RecursivePanic4) register("GoexitExit", GoexitExit) register("GoNil", GoNil) register("MainGoroutineID", MainGoroutineID) @@ -29,6 +32,8 @@ func init() { register("GoexitInPanic", GoexitInPanic) register("PanicAfterGoexit", PanicAfterGoexit) register("RecoveredPanicAfterGoexit", RecoveredPanicAfterGoexit) + register("RecoverBeforePanicAfterGoexit", RecoverBeforePanicAfterGoexit) + register("RecoverBeforePanicAfterGoexit2", RecoverBeforePanicAfterGoexit2) register("PanicTraceback", PanicTraceback) register("GoschedInPanic", GoschedInPanic) register("SyscallInPanic", SyscallInPanic) @@ -111,6 +116,50 @@ func RecursivePanic() { panic("again") } +// Same as RecursivePanic, but do the first recover and the second panic in +// separate defers, and make sure they are executed in the correct order. +func RecursivePanic2() { + func() { + defer func() { + fmt.Println(recover()) + }() + var x [8192]byte + func(x [8192]byte) { + defer func() { + panic("second panic") + }() + defer func() { + fmt.Println(recover()) + }() + panic("first panic") + }(x) + }() + panic("third panic") +} + +// Make sure that the first panic finished as a panic, even though the second +// panic was recovered +func RecursivePanic3() { + defer func() { + defer func() { + recover() + }() + panic("second panic") + }() + panic("first panic") +} + +// Test case where a single defer recovers one panic but starts another panic. If +// the second panic is never recovered, then the recovered first panic will still +// appear on the panic stack (labeled '[recovered]') and the runtime stack. +func RecursivePanic4() { + defer func() { + recover() + panic("second panic") + }() + panic("first panic") +} + func GoexitExit() { println("t1") go func() { @@ -202,6 +251,50 @@ func RecoveredPanicAfterGoexit() { runtime.Goexit() } +func RecoverBeforePanicAfterGoexit() { + // 1. defer a function that recovers + // 2. defer a function that panics + // 3. call goexit + // Goexit runs the #2 defer. Its panic + // is caught by the #1 defer. For Goexit, we explicitly + // resume execution in the Goexit loop, instead of resuming + // execution in the caller (which would make the Goexit disappear!) + defer func() { + r := recover() + if r == nil { + panic("bad recover") + } + }() + defer func() { + panic("hello") + }() + runtime.Goexit() +} + +func RecoverBeforePanicAfterGoexit2() { + for i := 0; i < 2; i++ { + defer func() { + }() + } + // 1. defer a function that recovers + // 2. defer a function that panics + // 3. call goexit + // Goexit runs the #2 defer. Its panic + // is caught by the #1 defer. For Goexit, we explicitly + // resume execution in the Goexit loop, instead of resuming + // execution in the caller (which would make the Goexit disappear!) + defer func() { + r := recover() + if r == nil { + panic("bad recover") + } + }() + defer func() { + panic("hello") + }() + runtime.Goexit() +} + func PanicTraceback() { pt1() } diff --git a/libgo/go/runtime/testdata/testprog/gc.go b/libgo/go/runtime/testdata/testprog/gc.go index 3fd1cd8a1ff..cc16413ef5c 100644 --- a/libgo/go/runtime/testdata/testprog/gc.go +++ b/libgo/go/runtime/testdata/testprog/gc.go @@ -27,7 +27,6 @@ func GCSys() { runtime.GC() runtime.ReadMemStats(memstats) sys := memstats.Sys - fmt.Printf("original sys: %#x\n", sys) runtime.MemProfileRate = 0 // disable profiler @@ -39,8 +38,6 @@ func GCSys() { // Should only be using a few MB. // We allocated 100 MB or (if not short) 1 GB. runtime.ReadMemStats(memstats) - fmt.Printf("final sys: %#x\n", memstats.Sys) - fmt.Printf("%#v\n", *memstats) if sys > memstats.Sys { sys = 0 } else { @@ -150,9 +147,20 @@ func GCPhys() { size = 4 << 20 split = 64 << 10 objects = 2 + + // The page cache could hide 64 8-KiB pages from the scavenger today. + maxPageCache = (8 << 10) * 64 ) // Set GOGC so that this test operates under consistent assumptions. debug.SetGCPercent(100) + // Reduce GOMAXPROCS down to 4 if it's greater. We need to bound the amount + // of memory held in the page cache because the scavenger can't reach it. + // The page cache will hold at most maxPageCache of memory per-P, so this + // bounds the amount of memory hidden from the scavenger to 4*maxPageCache. + procs := runtime.GOMAXPROCS(-1) + if procs > 4 { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) + } // Save objects which we want to survive, and condemn objects which we don't. // Note that we condemn objects in this way and release them all at once in // order to avoid having the GC start freeing up these objects while the loop @@ -200,10 +208,22 @@ func GCPhys() { // Since the runtime should scavenge the entirety of the remaining holes, // theoretically there should be no more free and unscavenged memory. However due // to other allocations that happen during this test we may still see some physical - // memory over-use. 10% here is an arbitrary but very conservative threshold which - // should easily account for any other allocations this test may have done. + // memory over-use. overuse := (float64(heapBacked) - float64(stats.HeapAlloc)) / float64(stats.HeapAlloc) - if overuse <= 0.10 { + // Compute the threshold. + // + // In theory, this threshold should just be zero, but that's not possible in practice. + // Firstly, the runtime's page cache can hide up to maxPageCache of free memory from the + // scavenger per P. To account for this, we increase the threshold by the ratio between the + // total amount the runtime could hide from the scavenger to the amount of memory we expect + // to be able to scavenge here, which is (size-split)*objects. This computation is the crux + // GOMAXPROCS above; if GOMAXPROCS is too high the threshold just becomes 100%+ since the + // amount of memory being allocated is fixed. Then we add 5% to account for noise, such as + // other allocations this test may have performed that we don't explicitly account for The + // baseline threshold here is around 11% for GOMAXPROCS=1, capping out at around 30% for + // GOMAXPROCS=4. + threshold := 0.05 + float64(procs)*maxPageCache/float64((size-split)*objects) + if overuse <= threshold { fmt.Println("OK") return } @@ -213,8 +233,8 @@ func GCPhys() { // In the context of this test, this indicates a large amount of // fragmentation with physical pages that are otherwise unused but not // returned to the OS. - fmt.Printf("exceeded physical memory overuse threshold of 10%%: %3.2f%%\n"+ - "(alloc: %d, goal: %d, sys: %d, rel: %d, objs: %d)\n", overuse*100, + fmt.Printf("exceeded physical memory overuse threshold of %3.2f%%: %3.2f%%\n"+ + "(alloc: %d, goal: %d, sys: %d, rel: %d, objs: %d)\n", threshold*100, overuse*100, stats.HeapAlloc, stats.NextGC, stats.HeapSys, stats.HeapReleased, len(saved)) runtime.KeepAlive(saved) } diff --git a/libgo/go/runtime/testdata/testprog/preempt.go b/libgo/go/runtime/testdata/testprog/preempt.go new file mode 100644 index 00000000000..1c74d0e4352 --- /dev/null +++ b/libgo/go/runtime/testdata/testprog/preempt.go @@ -0,0 +1,71 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "runtime" + "runtime/debug" + "sync/atomic" +) + +func init() { + register("AsyncPreempt", AsyncPreempt) +} + +func AsyncPreempt() { + // Run with just 1 GOMAXPROCS so the runtime is required to + // use scheduler preemption. + runtime.GOMAXPROCS(1) + // Disable GC so we have complete control of what we're testing. + debug.SetGCPercent(-1) + + // Start a goroutine with no sync safe-points. + var ready, ready2 uint32 + go func() { + for { + atomic.StoreUint32(&ready, 1) + dummy() + dummy() + } + }() + // Also start one with a frameless function. + // This is an especially interesting case for + // LR machines. + go func() { + atomic.AddUint32(&ready2, 1) + frameless() + }() + // Also test empty infinite loop. + go func() { + atomic.AddUint32(&ready2, 1) + for { + } + }() + + // Wait for the goroutine to stop passing through sync + // safe-points. + for atomic.LoadUint32(&ready) == 0 || atomic.LoadUint32(&ready2) < 2 { + runtime.Gosched() + } + + // Run a GC, which will have to stop the goroutine for STW and + // for stack scanning. If this doesn't work, the test will + // deadlock and timeout. + runtime.GC() + + println("OK") +} + +//go:noinline +func frameless() { + for i := int64(0); i < 1<<62; i++ { + out += i * i * i * i * i * 12345 + } +} + +var out int64 + +//go:noinline +func dummy() {} diff --git a/libgo/go/runtime/testdata/testprog/signal.go b/libgo/go/runtime/testdata/testprog/signal.go index 2ccbada57b3..417e105c68a 100644 --- a/libgo/go/runtime/testdata/testprog/signal.go +++ b/libgo/go/runtime/testdata/testprog/signal.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !windows,!plan9,!nacl +// +build !windows,!plan9 package main diff --git a/libgo/go/runtime/testdata/testprog/vdso.go b/libgo/go/runtime/testdata/testprog/vdso.go new file mode 100644 index 00000000000..ef92f487581 --- /dev/null +++ b/libgo/go/runtime/testdata/testprog/vdso.go @@ -0,0 +1,55 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Invoke signal hander in the VDSO context (see issue 32912). + +package main + +import ( + "fmt" + "io/ioutil" + "os" + "runtime/pprof" + "time" +) + +func init() { + register("SignalInVDSO", signalInVDSO) +} + +func signalInVDSO() { + f, err := ioutil.TempFile("", "timeprofnow") + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(2) + } + + if err := pprof.StartCPUProfile(f); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(2) + } + + t0 := time.Now() + t1 := t0 + // We should get a profiling signal 100 times a second, + // so running for 1 second should be sufficient. + for t1.Sub(t0) < time.Second { + t1 = time.Now() + } + + pprof.StopCPUProfile() + + name := f.Name() + if err := f.Close(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(2) + } + + if err := os.Remove(name); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(2) + } + + fmt.Println("success") +} diff --git a/libgo/go/runtime/testdata/testprogcgo/bigstack_windows.c b/libgo/go/runtime/testdata/testprogcgo/bigstack_windows.c new file mode 100644 index 00000000000..cd85ac88d05 --- /dev/null +++ b/libgo/go/runtime/testdata/testprogcgo/bigstack_windows.c @@ -0,0 +1,46 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This test source is used by both TestBigStackCallbackCgo (linked +// directly into the Go binary) and TestBigStackCallbackSyscall +// (compiled into a DLL). + +#include +#include + +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION +#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 +#endif + +typedef void callback(char*); + +// Allocate a stack that's much larger than the default. +static const int STACK_SIZE = 16<<20; + +static callback *bigStackCallback; + +static void useStack(int bytes) { + // Windows doesn't like huge frames, so we grow the stack 64k at a time. + char x[64<<10]; + if (bytes < sizeof x) { + bigStackCallback(x); + } else { + useStack(bytes - sizeof x); + } +} + +static DWORD WINAPI threadEntry(LPVOID lpParam) { + useStack(STACK_SIZE - (128<<10)); + return 0; +} + +void bigStack(callback *cb) { + bigStackCallback = cb; + HANDLE hThread = CreateThread(NULL, STACK_SIZE, threadEntry, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL); + if (hThread == NULL) { + fprintf(stderr, "CreateThread failed\n"); + exit(1); + } + WaitForSingleObject(hThread, INFINITE); +} diff --git a/libgo/go/runtime/testdata/testprogcgo/numgoroutine.go b/libgo/go/runtime/testdata/testprogcgo/numgoroutine.go index 68f1738dd6b..b7134a492f0 100644 --- a/libgo/go/runtime/testdata/testprogcgo/numgoroutine.go +++ b/libgo/go/runtime/testdata/testprogcgo/numgoroutine.go @@ -41,13 +41,6 @@ func NumGoroutine() { // Test that there are just the expected number of goroutines // running. Specifically, test that the spare M's goroutine // doesn't show up. - // - // On non-Windows platforms there's a signal handling thread - // started by os/signal.init in addition to the main - // goroutine. - if runtime.GOOS != "windows" { - baseGoroutines = 1 - } if _, ok := checkNumGoroutine("first", 1+baseGoroutines); !ok { return } diff --git a/libgo/go/runtime/testdata/testprognet/signal.go b/libgo/go/runtime/testdata/testprognet/signal.go index a1559fe6163..4d2de79d97c 100644 --- a/libgo/go/runtime/testdata/testprognet/signal.go +++ b/libgo/go/runtime/testdata/testprognet/signal.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !windows,!plan9,!nacl +// +build !windows,!plan9 // This is in testprognet instead of testprog because testprog // must not import anything (like net, but also like os/signal) diff --git a/libgo/go/runtime/testdata/testwinlib/main.c b/libgo/go/runtime/testdata/testwinlib/main.c new file mode 100644 index 00000000000..e84a32f7539 --- /dev/null +++ b/libgo/go/runtime/testdata/testwinlib/main.c @@ -0,0 +1,57 @@ +#include +#include +#include "testwinlib.h" + +int exceptionCount; +int continueCount; +LONG WINAPI customExceptionHandlder(struct _EXCEPTION_POINTERS *ExceptionInfo) +{ + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) + { + exceptionCount++; + // prepare context to resume execution + CONTEXT *c = ExceptionInfo->ContextRecord; + c->Rip = *(ULONG_PTR *)c->Rsp; + c->Rsp += 8; + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; +} +LONG WINAPI customContinueHandlder(struct _EXCEPTION_POINTERS *ExceptionInfo) +{ + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) + { + continueCount++; + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; +} + +void throwFromC() +{ + DebugBreak(); +} +int main() +{ + // simulate a "lazily" attached debugger, by calling some go code before attaching the exception/continue handler + Dummy(); + exceptionCount = 0; + continueCount = 0; + void *exceptionHandlerHandle = AddVectoredExceptionHandler(0, customExceptionHandlder); + if (NULL == exceptionHandlerHandle) + { + printf("cannot add vectored exception handler\n"); + return 2; + } + void *continueHandlerHandle = AddVectoredContinueHandler(0, customContinueHandlder); + if (NULL == continueHandlerHandle) + { + printf("cannot add vectored continue handler\n"); + return 2; + } + CallMeBack(throwFromC); + RemoveVectoredContinueHandler(continueHandlerHandle); + RemoveVectoredExceptionHandler(exceptionHandlerHandle); + printf("exceptionCount: %d\ncontinueCount: %d\n", exceptionCount, continueCount); + return 0; +} \ No newline at end of file diff --git a/libgo/go/runtime/testdata/testwinlib/main.go b/libgo/go/runtime/testdata/testwinlib/main.go new file mode 100644 index 00000000000..400eaa1c82d --- /dev/null +++ b/libgo/go/runtime/testdata/testwinlib/main.go @@ -0,0 +1,28 @@ +// +build windows,cgo + +package main + +// #include +// typedef void(*callmeBackFunc)(); +// static void bridgeCallback(callmeBackFunc callback) { +// callback(); +//} +import "C" + +// CallMeBack call backs C code. +//export CallMeBack +func CallMeBack(callback C.callmeBackFunc) { + C.bridgeCallback(callback) +} + +// Dummy is called by the C code before registering the exception/continue handlers simulating a debugger. +// This makes sure that the Go runtime's lastcontinuehandler is reached before the C continue handler and thus, +// validate that it does not crash the program before another handler could take an action. +// The idea here is to reproduce what happens when you attach a debugger to a running program. +// It also simulate the behavior of the .Net debugger, which register its exception/continue handlers lazily. +//export Dummy +func Dummy() int { + return 42 +} + +func main() {} diff --git a/libgo/go/runtime/time.go b/libgo/go/runtime/time.go index 71e7556776e..ded68eda858 100644 --- a/libgo/go/runtime/time.go +++ b/libgo/go/runtime/time.go @@ -7,17 +7,17 @@ package runtime import ( - "internal/cpu" + "runtime/internal/atomic" "unsafe" ) // Package time knows the layout of this structure. // If this struct changes, adjust ../time/sleep.go:/runtimeTimer. -// For GOOS=nacl, package syscall knows the layout of this structure. -// If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer. type timer struct { - tb *timersBucket // the bucket the timer lives in - i int // heap index + // If this timer is on a heap, which P's heap it is on. + // puintptr rather than *p to match uintptr in the versions + // of this struct defined in other packages. + pp puintptr // Timer wakes up at when, and then at when+period, ... (period > 0 only) // each time calling f(arg, now) in the timer goroutine, so f must be @@ -27,52 +27,146 @@ type timer struct { f func(interface{}, uintptr) arg interface{} seq uintptr + + // What to set the when field to in timerModifiedXX status. + nextwhen int64 + + // The status field holds one of the values below. + status uint32 } -// timersLen is the length of timers array. +// Code outside this file has to be careful in using a timer value. // -// Ideally, this would be set to GOMAXPROCS, but that would require -// dynamic reallocation +// The pp, status, and nextwhen fields may only be used by code in this file. // -// The current value is a compromise between memory usage and performance -// that should cover the majority of GOMAXPROCS values used in the wild. -const timersLen = 64 - -// timers contains "per-P" timer heaps. +// Code that creates a new timer value can set the when, period, f, +// arg, and seq fields. +// A new timer value may be passed to addtimer (called by time.startTimer). +// After doing that no fields may be touched. // -// Timers are queued into timersBucket associated with the current P, -// so each P may work with its own timers independently of other P instances. +// An active timer (one that has been passed to addtimer) may be +// passed to deltimer (time.stopTimer), after which it is no longer an +// active timer. It is an inactive timer. +// In an inactive timer the period, f, arg, and seq fields may be modified, +// but not the when field. +// It's OK to just drop an inactive timer and let the GC collect it. +// It's not OK to pass an inactive timer to addtimer. +// Only newly allocated timer values may be passed to addtimer. // -// Each timersBucket may be associated with multiple P -// if GOMAXPROCS > timersLen. -var timers [timersLen]struct { - timersBucket - - // The padding should eliminate false sharing - // between timersBucket values. - pad [cpu.CacheLinePadSize - unsafe.Sizeof(timersBucket{})%cpu.CacheLinePadSize]byte -} +// An active timer may be passed to modtimer. No fields may be touched. +// It remains an active timer. +// +// An inactive timer may be passed to resettimer to turn into an +// active timer with an updated when field. +// It's OK to pass a newly allocated timer value to resettimer. +// +// Timer operations are addtimer, deltimer, modtimer, resettimer, +// cleantimers, adjusttimers, and runtimer. +// +// We don't permit calling addtimer/deltimer/modtimer/resettimer simultaneously, +// but adjusttimers and runtimer can be called at the same time as any of those. +// +// Active timers live in heaps attached to P, in the timers field. +// Inactive timers live there too temporarily, until they are removed. +// +// addtimer: +// timerNoStatus -> timerWaiting +// anything else -> panic: invalid value +// deltimer: +// timerWaiting -> timerDeleted +// timerModifiedXX -> timerDeleted +// timerNoStatus -> do nothing +// timerDeleted -> do nothing +// timerRemoving -> do nothing +// timerRemoved -> do nothing +// timerRunning -> wait until status changes +// timerMoving -> wait until status changes +// timerModifying -> panic: concurrent deltimer/modtimer calls +// modtimer: +// timerWaiting -> timerModifying -> timerModifiedXX +// timerModifiedXX -> timerModifying -> timerModifiedYY +// timerNoStatus -> timerWaiting +// timerRemoved -> timerWaiting +// timerRunning -> wait until status changes +// timerMoving -> wait until status changes +// timerRemoving -> wait until status changes +// timerDeleted -> panic: concurrent modtimer/deltimer calls +// timerModifying -> panic: concurrent modtimer calls +// resettimer: +// timerNoStatus -> timerWaiting +// timerRemoved -> timerWaiting +// timerDeleted -> timerModifying -> timerModifiedXX +// timerRemoving -> wait until status changes +// timerRunning -> wait until status changes +// timerWaiting -> panic: resettimer called on active timer +// timerMoving -> panic: resettimer called on active timer +// timerModifiedXX -> panic: resettimer called on active timer +// timerModifying -> panic: resettimer called on active timer +// cleantimers (looks in P's timer heap): +// timerDeleted -> timerRemoving -> timerRemoved +// timerModifiedXX -> timerMoving -> timerWaiting +// adjusttimers (looks in P's timer heap): +// timerDeleted -> timerRemoving -> timerRemoved +// timerModifiedXX -> timerMoving -> timerWaiting +// runtimer (looks in P's timer heap): +// timerNoStatus -> panic: uninitialized timer +// timerWaiting -> timerWaiting or +// timerWaiting -> timerRunning -> timerNoStatus or +// timerWaiting -> timerRunning -> timerWaiting +// timerModifying -> wait until status changes +// timerModifiedXX -> timerMoving -> timerWaiting +// timerDeleted -> timerRemoving -> timerRemoved +// timerRunning -> panic: concurrent runtimer calls +// timerRemoved -> panic: inconsistent timer heap +// timerRemoving -> panic: inconsistent timer heap +// timerMoving -> panic: inconsistent timer heap -func (t *timer) assignBucket() *timersBucket { - id := uint8(getg().m.p.ptr().id) % timersLen - t.tb = &timers[id].timersBucket - return t.tb -} +// Values for the timer status field. +const ( + // Timer has no status set yet. + timerNoStatus = iota -//go:notinheap -type timersBucket struct { - lock mutex - gp *g - created bool - sleeping bool - rescheduling bool - sleepUntil int64 - waitnote note - t []*timer -} + // Waiting for timer to fire. + // The timer is in some P's heap. + timerWaiting + + // Running the timer function. + // A timer will only have this status briefly. + timerRunning + + // The timer is deleted and should be removed. + // It should not be run, but it is still in some P's heap. + timerDeleted -// nacl fake time support - time in nanoseconds since 1970 -var faketime int64 + // The timer is being removed. + // The timer will only have this status briefly. + timerRemoving + + // The timer has been stopped. + // It is not in any P's heap. + timerRemoved + + // The timer is being modified. + // The timer will only have this status briefly. + timerModifying + + // The timer has been modified to an earlier time. + // The new when value is in the nextwhen field. + // The timer is in some P's heap, possibly in the wrong place. + timerModifiedEarlier + + // The timer has been modified to the same or a later time. + // The new when value is in the nextwhen field. + // The timer is in some P's heap, possibly in the wrong place. + timerModifiedLater + + // The timer has been modified and is being moved. + // The timer will only have this status briefly. + timerMoving +) + +// maxWhen is the maximum value for timer's when field. +const maxWhen = 1<<63 - 1 // Package time APIs. // Godoc uses the comments in package time, not these. @@ -92,17 +186,20 @@ func timeSleep(ns int64) { t = new(timer) gp.timer = t } - *t = timer{} - t.when = nanotime() + ns t.f = goroutineReady t.arg = gp - tb := t.assignBucket() - lock(&tb.lock) - if !tb.addtimerLocked(t) { - unlock(&tb.lock) - badTimer() - } - goparkunlock(&tb.lock, waitReasonSleep, traceEvGoSleep, 2) + t.nextwhen = nanotime() + ns + gopark(resetForSleep, unsafe.Pointer(t), waitReasonSleep, traceEvGoSleep, 1) +} + +// resetForSleep is called after the goroutine is parked for timeSleep. +// We can't call resettimer in timeSleep itself because if this is a short +// sleep and there are many goroutines then the P can wind up running the +// timer function, goroutineReady, before the goroutine has been parked. +func resetForSleep(gp *g, ut unsafe.Pointer) bool { + t := (*timer)(ut) + resettimer(t, t.nextwhen) + return true } // startTimer adds t to the timer heap. @@ -114,13 +211,22 @@ func startTimer(t *timer) { addtimer(t) } -// stopTimer removes t from the timer heap if it is there. -// It returns true if t was removed, false if t wasn't even there. +// stopTimer stops a timer. +// It reports whether t was stopped before being run. //go:linkname stopTimer time.stopTimer func stopTimer(t *timer) bool { return deltimer(t) } +// resetTimer resets an inactive timer, adding it to the heap. +//go:linkname resetTimer time.resetTimer +func resetTimer(t *timer, when int64) { + if raceenabled { + racerelease(unsafe.Pointer(t)) + } + resettimer(t, when) +} + // Go runtime. // Ready the goroutine arg. @@ -128,252 +234,714 @@ func goroutineReady(arg interface{}, seq uintptr) { goready(arg.(*g), 0) } +// addtimer adds a timer to the current P. +// This should only be called with a newly created timer. +// That avoids the risk of changing the when field of a timer in some P's heap, +// which could cause the heap to become unsorted. func addtimer(t *timer) { - tb := t.assignBucket() - lock(&tb.lock) - ok := tb.addtimerLocked(t) - unlock(&tb.lock) - if !ok { - badTimer() - } -} - -// Add a timer to the heap and start or kick timerproc if the new timer is -// earlier than any of the others. -// Timers are locked. -// Returns whether all is well: false if the data structure is corrupt -// due to user-level races. -func (tb *timersBucket) addtimerLocked(t *timer) bool { - // when must never be negative; otherwise timerproc will overflow + // when must never be negative; otherwise runtimer will overflow // during its delta calculation and never expire other runtime timers. if t.when < 0 { - t.when = 1<<63 - 1 + t.when = maxWhen } - t.i = len(tb.t) - tb.t = append(tb.t, t) - if !siftupTimer(tb.t, t.i) { - return false + if t.status != timerNoStatus { + badTimer() } - if t.i == 0 { - // siftup moved to top: new earliest deadline. - if tb.sleeping && tb.sleepUntil > t.when { - tb.sleeping = false - notewakeup(&tb.waitnote) - } - if tb.rescheduling { - tb.rescheduling = false - goready(tb.gp, 0) - } - if !tb.created { - tb.created = true - expectSystemGoroutine() - go timerproc(tb) - } + t.status = timerWaiting + + addInitializedTimer(t) +} + +// addInitializedTimer adds an initialized timer to the current P. +func addInitializedTimer(t *timer) { + when := t.when + + pp := getg().m.p.ptr() + lock(&pp.timersLock) + ok := cleantimers(pp) && doaddtimer(pp, t) + unlock(&pp.timersLock) + if !ok { + badTimer() } - return true + + wakeNetPoller(when) } -// Delete timer t from the heap. -// Do not need to update the timerproc: if it wakes up early, no big deal. -func deltimer(t *timer) bool { - if t.tb == nil { - // t.tb can be nil if the user created a timer - // directly, without invoking startTimer e.g - // time.Ticker{C: c} - // In this case, return early without any deletion. - // See Issue 21874. - return false +// doaddtimer adds t to the current P's heap. +// It reports whether it saw no problems due to races. +// The caller must have locked the timers for pp. +func doaddtimer(pp *p, t *timer) bool { + // Timers rely on the network poller, so make sure the poller + // has started. + if netpollInited == 0 { + netpollGenericInit() } - tb := t.tb + if t.pp != 0 { + throw("doaddtimer: P already set in timer") + } + t.pp.set(pp) + i := len(pp.timers) + pp.timers = append(pp.timers, t) + return siftupTimer(pp.timers, i) +} - lock(&tb.lock) - removed, ok := tb.deltimerLocked(t) - unlock(&tb.lock) - if !ok { - badTimer() +// deltimer deletes the timer t. It may be on some other P, so we can't +// actually remove it from the timers heap. We can only mark it as deleted. +// It will be removed in due course by the P whose heap it is on. +// Reports whether the timer was removed before it was run. +func deltimer(t *timer) bool { + for { + switch s := atomic.Load(&t.status); s { + case timerWaiting, timerModifiedLater: + if atomic.Cas(&t.status, s, timerDeleted) { + // Timer was not yet run. + return true + } + case timerModifiedEarlier: + tpp := t.pp.ptr() + if atomic.Cas(&t.status, s, timerModifying) { + atomic.Xadd(&tpp.adjustTimers, -1) + if !atomic.Cas(&t.status, timerModifying, timerDeleted) { + badTimer() + } + // Timer was not yet run. + return true + } + case timerDeleted, timerRemoving, timerRemoved: + // Timer was already run. + return false + case timerRunning, timerMoving: + // The timer is being run or moved, by a different P. + // Wait for it to complete. + osyield() + case timerNoStatus: + // Removing timer that was never added or + // has already been run. Also see issue 21874. + return false + case timerModifying: + // Simultaneous calls to deltimer and modtimer. + badTimer() + default: + badTimer() + } } - return removed } -func (tb *timersBucket) deltimerLocked(t *timer) (removed, ok bool) { - // t may not be registered anymore and may have - // a bogus i (typically 0, if generated by Go). - // Verify it before proceeding. - i := t.i - last := len(tb.t) - 1 - if i < 0 || i > last || tb.t[i] != t { - return false, true +// dodeltimer removes timer i from the current P's heap. +// We are locked on the P when this is called. +// It reports whether it saw no problems due to races. +// The caller must have locked the timers for pp. +func dodeltimer(pp *p, i int) bool { + if t := pp.timers[i]; t.pp.ptr() != pp { + throw("dodeltimer: wrong P") + } else { + t.pp = 0 } + last := len(pp.timers) - 1 if i != last { - tb.t[i] = tb.t[last] - tb.t[i].i = i + pp.timers[i] = pp.timers[last] } - tb.t[last] = nil - tb.t = tb.t[:last] - ok = true + pp.timers[last] = nil + pp.timers = pp.timers[:last] + ok := true if i != last { - if !siftupTimer(tb.t, i) { + // Moving to i may have moved the last timer to a new parent, + // so sift up to preserve the heap guarantee. + if !siftupTimer(pp.timers, i) { ok = false } - if !siftdownTimer(tb.t, i) { + if !siftdownTimer(pp.timers, i) { ok = false } } - return true, ok + return ok } +// dodeltimer0 removes timer 0 from the current P's heap. +// We are locked on the P when this is called. +// It reports whether it saw no problems due to races. +// The caller must have locked the timers for pp. +func dodeltimer0(pp *p) bool { + if t := pp.timers[0]; t.pp.ptr() != pp { + throw("dodeltimer0: wrong P") + } else { + t.pp = 0 + } + last := len(pp.timers) - 1 + if last > 0 { + pp.timers[0] = pp.timers[last] + } + pp.timers[last] = nil + pp.timers = pp.timers[:last] + ok := true + if last > 0 { + ok = siftdownTimer(pp.timers, 0) + } + return ok +} + +// modtimer modifies an existing timer. +// This is called by the netpoll code. func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg interface{}, seq uintptr) { - tb := t.tb + if when < 0 { + when = maxWhen + } - lock(&tb.lock) - _, ok := tb.deltimerLocked(t) - if ok { - t.when = when - t.period = period - t.f = f - t.arg = arg - t.seq = seq - ok = tb.addtimerLocked(t) + status := uint32(timerNoStatus) + wasRemoved := false +loop: + for { + switch status = atomic.Load(&t.status); status { + case timerWaiting, timerModifiedEarlier, timerModifiedLater: + if atomic.Cas(&t.status, status, timerModifying) { + break loop + } + case timerNoStatus, timerRemoved: + // Timer was already run and t is no longer in a heap. + // Act like addtimer. + if atomic.Cas(&t.status, status, timerWaiting) { + wasRemoved = true + break loop + } + case timerRunning, timerRemoving, timerMoving: + // The timer is being run or moved, by a different P. + // Wait for it to complete. + osyield() + case timerDeleted: + // Simultaneous calls to modtimer and deltimer. + badTimer() + case timerModifying: + // Multiple simultaneous calls to modtimer. + badTimer() + default: + badTimer() + } } - unlock(&tb.lock) - if !ok { - badTimer() + + t.period = period + t.f = f + t.arg = arg + t.seq = seq + + if wasRemoved { + t.when = when + addInitializedTimer(t) + } else { + // The timer is in some other P's heap, so we can't change + // the when field. If we did, the other P's heap would + // be out of order. So we put the new when value in the + // nextwhen field, and let the other P set the when field + // when it is prepared to resort the heap. + t.nextwhen = when + + newStatus := uint32(timerModifiedLater) + if when < t.when { + newStatus = timerModifiedEarlier + } + + // Update the adjustTimers field. Subtract one if we + // are removing a timerModifiedEarlier, add one if we + // are adding a timerModifiedEarlier. + tpp := t.pp.ptr() + adjust := int32(0) + if status == timerModifiedEarlier { + adjust-- + } + if newStatus == timerModifiedEarlier { + adjust++ + } + if adjust != 0 { + atomic.Xadd(&tpp.adjustTimers, adjust) + } + + // Set the new status of the timer. + if !atomic.Cas(&t.status, timerModifying, newStatus) { + badTimer() + } + + // If the new status is earlier, wake up the poller. + if newStatus == timerModifiedEarlier { + wakeNetPoller(when) + } } } -// Timerproc runs the time-driven events. -// It sleeps until the next event in the tb heap. -// If addtimer inserts a new earlier event, it wakes timerproc early. -func timerproc(tb *timersBucket) { - setSystemGoroutine() +// resettimer resets an existing inactive timer to turn it into an active timer, +// with a new time for when the timer should fire. +// This should be called instead of addtimer if the timer value has been, +// or may have been, used previously. +func resettimer(t *timer, when int64) { + if when < 0 { + when = maxWhen + } - tb.gp = getg() for { - lock(&tb.lock) - tb.sleeping = false - now := nanotime() - delta := int64(-1) - for { - if len(tb.t) == 0 { - delta = -1 - break + switch s := atomic.Load(&t.status); s { + case timerNoStatus, timerRemoved: + if atomic.Cas(&t.status, s, timerWaiting) { + t.when = when + addInitializedTimer(t) + return } - t := tb.t[0] - delta = t.when - now - if delta > 0 { - break - } - ok := true - if t.period > 0 { - // leave in heap but adjust next time to fire - t.when += t.period * (1 + -delta/t.period) - if !siftdownTimer(tb.t, 0) { - ok = false + case timerDeleted: + if atomic.Cas(&t.status, s, timerModifying) { + t.nextwhen = when + newStatus := uint32(timerModifiedLater) + if when < t.when { + newStatus = timerModifiedEarlier + atomic.Xadd(&t.pp.ptr().adjustTimers, 1) } - } else { - // remove from heap - last := len(tb.t) - 1 - if last > 0 { - tb.t[0] = tb.t[last] - tb.t[0].i = 0 + if !atomic.Cas(&t.status, timerModifying, newStatus) { + badTimer() } - tb.t[last] = nil - tb.t = tb.t[:last] - if last > 0 { - if !siftdownTimer(tb.t, 0) { - ok = false - } + if newStatus == timerModifiedEarlier { + wakeNetPoller(when) } - t.i = -1 // mark as removed + return + } + case timerRemoving: + // Wait for the removal to complete. + osyield() + case timerRunning: + // Even though the timer should not be active, + // we can see timerRunning if the timer function + // permits some other goroutine to call resettimer. + // Wait until the run is complete. + osyield() + case timerWaiting, timerModifying, timerModifiedEarlier, timerModifiedLater, timerMoving: + // Called resettimer on active timer. + badTimer() + default: + badTimer() + } + } +} + +// cleantimers cleans up the head of the timer queue. This speeds up +// programs that create and delete timers; leaving them in the heap +// slows down addtimer. Reports whether no timer problems were found. +// The caller must have locked the timers for pp. +func cleantimers(pp *p) bool { + for { + if len(pp.timers) == 0 { + return true + } + t := pp.timers[0] + if t.pp.ptr() != pp { + throw("cleantimers: bad p") + } + switch s := atomic.Load(&t.status); s { + case timerDeleted: + if !atomic.Cas(&t.status, s, timerRemoving) { + continue + } + if !dodeltimer0(pp) { + return false } - f := t.f - arg := t.arg - seq := t.seq - unlock(&tb.lock) - if !ok { + if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { + return false + } + case timerModifiedEarlier, timerModifiedLater: + if !atomic.Cas(&t.status, s, timerMoving) { + continue + } + // Now we can change the when field. + t.when = t.nextwhen + // Move t to the right position. + if !dodeltimer0(pp) { + return false + } + if !doaddtimer(pp, t) { + return false + } + if s == timerModifiedEarlier { + atomic.Xadd(&pp.adjustTimers, -1) + } + if !atomic.Cas(&t.status, timerMoving, timerWaiting) { + return false + } + default: + // Head of timers does not need adjustment. + return true + } + } +} + +// moveTimers moves a slice of timers to pp. The slice has been taken +// from a different P. +// This is currently called when the world is stopped, but the caller +// is expected to have locked the timers for pp. +func moveTimers(pp *p, timers []*timer) { + for _, t := range timers { + loop: + for { + switch s := atomic.Load(&t.status); s { + case timerWaiting: + t.pp = 0 + if !doaddtimer(pp, t) { + badTimer() + } + break loop + case timerModifiedEarlier, timerModifiedLater: + if !atomic.Cas(&t.status, s, timerMoving) { + continue + } + t.when = t.nextwhen + t.pp = 0 + if !doaddtimer(pp, t) { + badTimer() + } + if !atomic.Cas(&t.status, timerMoving, timerWaiting) { + badTimer() + } + break loop + case timerDeleted: + if !atomic.Cas(&t.status, s, timerRemoved) { + continue + } + t.pp = 0 + // We no longer need this timer in the heap. + break loop + case timerModifying: + // Loop until the modification is complete. + osyield() + case timerNoStatus, timerRemoved: + // We should not see these status values in a timers heap. badTimer() + case timerRunning, timerRemoving, timerMoving: + // Some other P thinks it owns this timer, + // which should not happen. + badTimer() + default: + badTimer() + } + } + } +} + +// adjusttimers looks through the timers in the current P's heap for +// any timers that have been modified to run earlier, and puts them in +// the correct place in the heap. While looking for those timers, +// it also moves timers that have been modified to run later, +// and removes deleted timers. The caller must have locked the timers for pp. +func adjusttimers(pp *p) { + if len(pp.timers) == 0 { + return + } + if atomic.Load(&pp.adjustTimers) == 0 { + return + } + var moved []*timer + for i := 0; i < len(pp.timers); i++ { + t := pp.timers[i] + if t.pp.ptr() != pp { + throw("adjusttimers: bad p") + } + switch s := atomic.Load(&t.status); s { + case timerDeleted: + if atomic.Cas(&t.status, s, timerRemoving) { + if !dodeltimer(pp, i) { + badTimer() + } + if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { + badTimer() + } + // Look at this heap position again. + i-- } - if raceenabled { - raceacquire(unsafe.Pointer(t)) + case timerModifiedEarlier, timerModifiedLater: + if atomic.Cas(&t.status, s, timerMoving) { + // Now we can change the when field. + t.when = t.nextwhen + // Take t off the heap, and hold onto it. + // We don't add it back yet because the + // heap manipulation could cause our + // loop to skip some other timer. + if !dodeltimer(pp, i) { + badTimer() + } + moved = append(moved, t) + if s == timerModifiedEarlier { + if n := atomic.Xadd(&pp.adjustTimers, -1); int32(n) <= 0 { + addAdjustedTimers(pp, moved) + return + } + } } - f(arg, seq) - lock(&tb.lock) + case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving: + badTimer() + case timerWaiting: + // OK, nothing to do. + case timerModifying: + // Check again after modification is complete. + osyield() + i-- + default: + badTimer() } - if delta < 0 || faketime > 0 { - // No timers left - put goroutine to sleep. - tb.rescheduling = true - goparkunlock(&tb.lock, waitReasonTimerGoroutineIdle, traceEvGoBlock, 1) - continue + } + + if len(moved) > 0 { + addAdjustedTimers(pp, moved) + } +} + +// addAdjustedTimers adds any timers we adjusted in adjusttimers +// back to the timer heap. +func addAdjustedTimers(pp *p, moved []*timer) { + for _, t := range moved { + if !doaddtimer(pp, t) { + badTimer() + } + if !atomic.Cas(&t.status, timerMoving, timerWaiting) { + badTimer() } - // At least one timer pending. Sleep until then. - tb.sleeping = true - tb.sleepUntil = now + delta - noteclear(&tb.waitnote) - unlock(&tb.lock) - notetsleepg(&tb.waitnote, delta) } } -func timejump() *g { - if faketime == 0 { - return nil +// nobarrierWakeTime looks at P's timers and returns the time when we +// should wake up the netpoller. It returns 0 if there are no timers. +// This function is invoked when dropping a P, and must run without +// any write barriers. Therefore, if there are any timers that needs +// to be moved earlier, it conservatively returns the current time. +// The netpoller M will wake up and adjust timers before sleeping again. +//go:nowritebarrierrec +func nobarrierWakeTime(pp *p) int64 { + lock(&pp.timersLock) + ret := int64(0) + if len(pp.timers) > 0 { + if atomic.Load(&pp.adjustTimers) > 0 { + ret = nanotime() + } else { + ret = pp.timers[0].when + } } + unlock(&pp.timersLock) + return ret +} + +// runtimer examines the first timer in timers. If it is ready based on now, +// it runs the timer and removes or updates it. +// Returns 0 if it ran a timer, -1 if there are no more timers, or the time +// when the first timer should run. +// The caller must have locked the timers for pp. +// If a timer is run, this will temporarily unlock the timers. +//go:systemstack +func runtimer(pp *p, now int64) int64 { + for { + t := pp.timers[0] + if t.pp.ptr() != pp { + throw("runtimer: bad p") + } + switch s := atomic.Load(&t.status); s { + case timerWaiting: + if t.when > now { + // Not ready to run. + return t.when + } + + if !atomic.Cas(&t.status, s, timerRunning) { + continue + } + // Note that runOneTimer may temporarily unlock + // pp.timersLock. + runOneTimer(pp, t, now) + return 0 - for i := range timers { - lock(&timers[i].lock) + case timerDeleted: + if !atomic.Cas(&t.status, s, timerRemoving) { + continue + } + if !dodeltimer0(pp) { + badTimer() + } + if !atomic.Cas(&t.status, timerRemoving, timerRemoved) { + badTimer() + } + if len(pp.timers) == 0 { + return -1 + } + + case timerModifiedEarlier, timerModifiedLater: + if !atomic.Cas(&t.status, s, timerMoving) { + continue + } + t.when = t.nextwhen + if !dodeltimer0(pp) { + badTimer() + } + if !doaddtimer(pp, t) { + badTimer() + } + if s == timerModifiedEarlier { + atomic.Xadd(&pp.adjustTimers, -1) + } + if !atomic.Cas(&t.status, timerMoving, timerWaiting) { + badTimer() + } + + case timerModifying: + // Wait for modification to complete. + osyield() + + case timerNoStatus, timerRemoved: + // Should not see a new or inactive timer on the heap. + badTimer() + case timerRunning, timerRemoving, timerMoving: + // These should only be set when timers are locked, + // and we didn't do it. + badTimer() + default: + badTimer() + } } - gp := timejumpLocked() - for i := range timers { - unlock(&timers[i].lock) +} + +// runOneTimer runs a single timer. +// The caller must have locked the timers for pp. +// This will temporarily unlock the timers while running the timer function. +//go:systemstack +func runOneTimer(pp *p, t *timer, now int64) { + f := t.f + arg := t.arg + seq := t.seq + + if t.period > 0 { + // Leave in heap but adjust next time to fire. + delta := t.when - now + t.when += t.period * (1 + -delta/t.period) + if !siftdownTimer(pp.timers, 0) { + badTimer() + } + if !atomic.Cas(&t.status, timerRunning, timerWaiting) { + badTimer() + } + } else { + // Remove from heap. + if !dodeltimer0(pp) { + badTimer() + } + if !atomic.Cas(&t.status, timerRunning, timerNoStatus) { + badTimer() + } } - return gp + unlock(&pp.timersLock) + + f(arg, seq) + + lock(&pp.timersLock) } -func timejumpLocked() *g { +func timejump() *p { + if faketime == 0 { + return nil + } + + // Nothing is running, so we can look at all the P's. // Determine a timer bucket with minimum when. - var minT *timer - for i := range timers { - tb := &timers[i] - if !tb.created || len(tb.t) == 0 { + var ( + minT *timer + minWhen int64 + minP *p + ) + for _, pp := range allp { + if pp.status != _Pidle && pp.status != _Pdead { + throw("non-idle P in timejump") + } + if len(pp.timers) == 0 { continue } - t := tb.t[0] - if minT == nil || t.when < minT.when { - minT = t + c := pp.adjustTimers + for _, t := range pp.timers { + switch s := atomic.Load(&t.status); s { + case timerWaiting: + if minT == nil || t.when < minWhen { + minT = t + minWhen = t.when + minP = pp + } + case timerModifiedEarlier, timerModifiedLater: + if minT == nil || t.nextwhen < minWhen { + minT = t + minWhen = t.nextwhen + minP = pp + } + if s == timerModifiedEarlier { + c-- + } + case timerRunning, timerModifying, timerMoving: + badTimer() + } + // The timers are sorted, so we only have to check + // the first timer for each P, unless there are + // some timerModifiedEarlier timers. The number + // of timerModifiedEarlier timers is in the adjustTimers + // field, used to initialize c, above. + if c == 0 { + break + } } } - if minT == nil || minT.when <= faketime { - return nil - } - faketime = minT.when - tb := minT.tb - if !tb.rescheduling { + if minT == nil || minWhen <= faketime { return nil } - tb.rescheduling = false - return tb.gp + + faketime = minWhen + return minP } +// timeSleepUntil returns the time when the next timer should fire. +// This is only called by sysmon. func timeSleepUntil() int64 { - next := int64(1<<63 - 1) + next := int64(maxWhen) - // Determine minimum sleepUntil across all the timer buckets. - // - // The function can not return a precise answer, - // as another timer may pop in as soon as timers have been unlocked. - // So lock the timers one by one instead of all at once. - for i := range timers { - tb := &timers[i] + // Prevent allp slice changes. This is like retake. + lock(&allpLock) + for _, pp := range allp { + if pp == nil { + // This can happen if procresize has grown + // allp but not yet created new Ps. + continue + } - lock(&tb.lock) - if tb.sleeping && tb.sleepUntil < next { - next = tb.sleepUntil + lock(&pp.timersLock) + c := atomic.Load(&pp.adjustTimers) + for _, t := range pp.timers { + switch s := atomic.Load(&t.status); s { + case timerWaiting: + if t.when < next { + next = t.when + } + case timerModifiedEarlier, timerModifiedLater: + if t.nextwhen < next { + next = t.nextwhen + } + if s == timerModifiedEarlier { + c-- + } + } + // The timers are sorted, so we only have to check + // the first timer for each P, unless there are + // some timerModifiedEarlier timers. The number + // of timerModifiedEarlier timers is in the adjustTimers + // field, used to initialize c, above. + // + // We don't worry about cases like timerModifying. + // New timers can show up at any time, + // so this function is necessarily imprecise. + // Do a signed check here since we aren't + // synchronizing the read of pp.adjustTimers + // with the check of a timer status. + if int32(c) <= 0 { + break + } } - unlock(&tb.lock) + unlock(&pp.timersLock) } + unlock(&allpLock) return next } @@ -385,9 +953,6 @@ func timeSleepUntil() int64 { // it will cause the program to crash with a mysterious // "panic holding locks" message. Instead, we panic while not // holding a lock. -// The races can occur despite the bucket locks because assignBucket -// itself is called without locks, so racy calls can cause a timer to -// change buckets while executing these functions. func siftupTimer(t []*timer, i int) bool { if i >= len(t) { @@ -401,12 +966,10 @@ func siftupTimer(t []*timer, i int) bool { break } t[i] = t[p] - t[i].i = i i = p } if tmp != t[i] { t[i] = tmp - t[i].i = i } return true } @@ -444,12 +1007,10 @@ func siftdownTimer(t []*timer, i int) bool { break } t[i] = t[c] - t[i].i = i i = c } if tmp != t[i] { t[i] = tmp - t[i].i = i } return true } diff --git a/libgo/go/runtime/time_fake.go b/libgo/go/runtime/time_fake.go new file mode 100644 index 00000000000..c64d2994a90 --- /dev/null +++ b/libgo/go/runtime/time_fake.go @@ -0,0 +1,100 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build faketime +// +build !windows + +// Faketime isn't currently supported on Windows. This would require: +// +// 1. Shadowing time_now, which is implemented in assembly on Windows. +// Since that's exported directly to the time package from runtime +// assembly, this would involve moving it from sys_windows_*.s into +// its own assembly files build-tagged with !faketime and using the +// implementation of time_now from timestub.go in faketime mode. +// +// 2. Modifying syscall.Write to call syscall.faketimeWrite, +// translating the Stdout and Stderr handles into FDs 1 and 2. +// (See CL 192739 PS 3.) + +package runtime + +import "unsafe" + +// faketime is the simulated time in nanoseconds since 1970 for the +// playground. +var faketime int64 = 1257894000000000000 + +var faketimeState struct { + lock mutex + + // lastfaketime is the last faketime value written to fd 1 or 2. + lastfaketime int64 + + // lastfd is the fd to which lastfaketime was written. + // + // Subsequent writes to the same fd may use the same + // timestamp, but the timestamp must increase if the fd + // changes. + lastfd uintptr +} + +//go:nosplit +func nanotime() int64 { + return faketime +} + +func walltime() (sec int64, nsec int32) { + return faketime / 1000000000, int32(faketime % 1000000000) +} + +func write(fd uintptr, p unsafe.Pointer, n int32) int32 { + if !(fd == 1 || fd == 2) { + // Do an ordinary write. + return write1(fd, p, n) + } + + // Write with the playback header. + + // First, lock to avoid interleaving writes. + lock(&faketimeState.lock) + + // If the current fd doesn't match the fd of the previous write, + // ensure that the timestamp is strictly greater. That way, we can + // recover the original order even if we read the fds separately. + t := faketimeState.lastfaketime + if fd != faketimeState.lastfd { + t++ + faketimeState.lastfd = fd + } + if faketime > t { + t = faketime + } + faketimeState.lastfaketime = t + + // Playback header: 0 0 P B <8-byte time> <4-byte data length> (big endian) + var buf [4 + 8 + 4]byte + buf[2] = 'P' + buf[3] = 'B' + tu := uint64(t) + buf[4] = byte(tu >> (7 * 8)) + buf[5] = byte(tu >> (6 * 8)) + buf[6] = byte(tu >> (5 * 8)) + buf[7] = byte(tu >> (4 * 8)) + buf[8] = byte(tu >> (3 * 8)) + buf[9] = byte(tu >> (2 * 8)) + buf[10] = byte(tu >> (1 * 8)) + buf[11] = byte(tu >> (0 * 8)) + nu := uint32(n) + buf[12] = byte(nu >> (3 * 8)) + buf[13] = byte(nu >> (2 * 8)) + buf[14] = byte(nu >> (1 * 8)) + buf[15] = byte(nu >> (0 * 8)) + write1(fd, unsafe.Pointer(&buf[0]), int32(len(buf))) + + // Write actual data. + res := write1(fd, p, n) + + unlock(&faketimeState.lock) + return res +} diff --git a/libgo/go/runtime/time_nofake.go b/libgo/go/runtime/time_nofake.go new file mode 100644 index 00000000000..1912a94e873 --- /dev/null +++ b/libgo/go/runtime/time_nofake.go @@ -0,0 +1,31 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !faketime + +package runtime + +import "unsafe" + +// faketime is the simulated time in nanoseconds since 1970 for the +// playground. +// +// Zero means not to use faketime. +var faketime int64 + +//go:nosplit +func nanotime() int64 { + return nanotime1() +} + +func walltime() (sec int64, nsec int32) { + return walltime1() +} + +// write must be nosplit on Windows (see write1) +// +//go:nosplit +func write(fd uintptr, p unsafe.Pointer, n int32) int32 { + return write1(fd, p, n) +} diff --git a/libgo/go/runtime/time_test.go b/libgo/go/runtime/time_test.go new file mode 100644 index 00000000000..9b1922d4c43 --- /dev/null +++ b/libgo/go/runtime/time_test.go @@ -0,0 +1,96 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package runtime_test + +import ( + "bytes" + "encoding/binary" + "errors" + "internal/testenv" + "os/exec" + "reflect" + "runtime" + "testing" +) + +func TestFakeTime(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("faketime not supported on windows") + } + if runtime.Compiler == "gccgo" { + t.Skip("faketime not supported for gccgo") + } + + t.Parallel() + + exe, err := buildTestProg(t, "testfaketime", "-tags=faketime") + if err != nil { + t.Fatal(err) + } + + var stdout, stderr bytes.Buffer + cmd := exec.Command(exe) + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + err = testenv.CleanCmdEnv(cmd).Run() + if err != nil { + t.Fatalf("exit status: %v\n%s", err, stderr.String()) + } + + t.Logf("raw stdout: %q", stdout.String()) + t.Logf("raw stderr: %q", stdout.String()) + + f1, err1 := parseFakeTime(stdout.Bytes()) + if err1 != nil { + t.Fatal(err1) + } + f2, err2 := parseFakeTime(stderr.Bytes()) + if err2 != nil { + t.Fatal(err2) + } + + const time0 = 1257894000000000000 + got := [][]fakeTimeFrame{f1, f2} + var want = [][]fakeTimeFrame{{ + {time0 + 1, "line 2\n"}, + {time0 + 1, "line 3\n"}, + {time0 + 1e9, "line 5\n"}, + {time0 + 1e9, "2009-11-10T23:00:01Z"}, + }, { + {time0, "line 1\n"}, + {time0 + 2, "line 4\n"}, + }} + if !reflect.DeepEqual(want, got) { + t.Fatalf("want %v, got %v", want, got) + } +} + +type fakeTimeFrame struct { + time uint64 + data string +} + +func parseFakeTime(x []byte) ([]fakeTimeFrame, error) { + var frames []fakeTimeFrame + for len(x) != 0 { + if len(x) < 4+8+4 { + return nil, errors.New("truncated header") + } + const magic = "\x00\x00PB" + if string(x[:len(magic)]) != magic { + return nil, errors.New("bad magic") + } + x = x[len(magic):] + time := binary.BigEndian.Uint64(x) + x = x[8:] + dlen := binary.BigEndian.Uint32(x) + x = x[4:] + data := string(x[:dlen]) + x = x[dlen:] + frames = append(frames, fakeTimeFrame{time, data}) + } + return frames, nil +} diff --git a/libgo/go/runtime/timestub2.go b/libgo/go/runtime/timestub2.go index 7a28603d45e..38446fbbbb9 100644 --- a/libgo/go/runtime/timestub2.go +++ b/libgo/go/runtime/timestub2.go @@ -5,6 +5,7 @@ // +build !darwin // +build !windows // +build !freebsd + package runtime -func walltime() (sec int64, nsec int32) +func walltime1() (sec int64, nsec int32) diff --git a/libgo/go/runtime/trace.go b/libgo/go/runtime/trace.go index 6db5b62558e..81ff0cad986 100644 --- a/libgo/go/runtime/trace.go +++ b/libgo/go/runtime/trace.go @@ -54,7 +54,7 @@ const ( traceEvGoInSyscall = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id] traceEvHeapAlloc = 33 // memstats.heap_live change [timestamp, heap_alloc] traceEvNextGC = 34 // memstats.next_gc change [timestamp, next_gc] - traceEvTimerGoroutine = 35 // denotes timer goroutine [timer goroutine id] + traceEvTimerGoroutine = 35 // not currently used; previously denoted timer goroutine [timer goroutine id] traceEvFutileWakeup = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp] traceEvString = 37 // string dictionary entry [ID, length, string] traceEvGoStartLocal = 38 // goroutine starts running on the same P as the last event [timestamp, goroutine id] @@ -84,7 +84,7 @@ const ( // and ppc64le. // Tracing won't work reliably for architectures where cputicks is emulated // by nanotime, so the value doesn't matter for those architectures. - traceTickDiv = 16 + 48*(sys.Goarch386|sys.GoarchAmd64|sys.GoarchAmd64p32) + traceTickDiv = 16 + 48*(sys.Goarch386|sys.GoarchAmd64) // Maximum number of PCs in a single stack trace. // Since events contain only stack id rather than whole stack trace, // we can allow quite large values here. @@ -181,9 +181,12 @@ func traceBufPtrOf(b *traceBuf) traceBufPtr { // Most clients should use the runtime/trace package or the testing package's // -test.trace flag instead of calling StartTrace directly. func StartTrace() error { - // Stop the world, so that we can take a consistent snapshot + // Stop the world so that we can take a consistent snapshot // of all goroutines at the beginning of the trace. - stopTheWorld("start tracing") + // Do not stop the world during GC so we ensure we always see + // a consistent view of GC-related events (e.g. a start is always + // paired with an end). + stopTheWorldGC("start tracing") // We are in stop-the-world, but syscalls can finish and write to trace concurrently. // Exitsyscall could check trace.enabled long before and then suddenly wake up @@ -194,7 +197,7 @@ func StartTrace() error { if trace.enabled || trace.shutdown { unlock(&trace.bufLock) - startTheWorld() + startTheWorldGC() return errorString("tracing is already enabled") } @@ -265,7 +268,7 @@ func StartTrace() error { unlock(&trace.bufLock) - startTheWorld() + startTheWorldGC() return nil } @@ -274,14 +277,14 @@ func StartTrace() error { func StopTrace() { // Stop the world so that we can collect the trace buffers from all p's below, // and also to avoid races with traceEvent. - stopTheWorld("stop tracing") + stopTheWorldGC("stop tracing") // See the comment in StartTrace. lock(&trace.bufLock) if !trace.enabled { unlock(&trace.bufLock) - startTheWorld() + startTheWorldGC() return } @@ -318,7 +321,7 @@ func StopTrace() { trace.shutdown = true unlock(&trace.bufLock) - startTheWorld() + startTheWorldGC() // The world is started but we've set trace.shutdown, so new tracing can't start. // Wait for the trace reader to flush pending buffers and stop. @@ -414,13 +417,6 @@ func ReadTrace() []byte { var data []byte data = append(data, traceEvFrequency|0< uintptr(len(a.head.ptr().data)) { if n > uintptr(len(a.head.ptr().data)) { throw("trace: alloc too large") diff --git a/libgo/go/runtime/trace/trace_stack_test.go b/libgo/go/runtime/trace/trace_stack_test.go index 62c06e67d9d..e3608c687fa 100644 --- a/libgo/go/runtime/trace/trace_stack_test.go +++ b/libgo/go/runtime/trace/trace_stack_test.go @@ -233,6 +233,7 @@ func TestTraceSymbolize(t *testing.T) { }}, {trace.EvGomaxprocs, []frame{ {"runtime.startTheWorld", 0}, // this is when the current gomaxprocs is logged. + {"runtime.startTheWorldGC", 0}, {"runtime.GOMAXPROCS", 0}, {"runtime/trace_test.TestTraceSymbolize", 0}, {"testing.tRunner", 0}, diff --git a/libgo/go/runtime/traceback_gccgo.go b/libgo/go/runtime/traceback_gccgo.go index 4134d28a599..1ba91af76ae 100644 --- a/libgo/go/runtime/traceback_gccgo.go +++ b/libgo/go/runtime/traceback_gccgo.go @@ -20,7 +20,7 @@ func printcreatedby(gp *g) { if entry != 0 && tracepc > entry { tracepc -= sys.PCQuantum } - function, file, line, _ := funcfileline(tracepc, -1) + function, file, line, _ := funcfileline(tracepc, -1, false) if function != "" && showframe(function, gp, false) && gp.goid != 1 { printcreatedby1(function, file, line, entry, pc) } @@ -93,7 +93,7 @@ func traceback(skip int32) { func printAncestorTraceback(ancestor ancestorInfo) { print("[originating from goroutine ", ancestor.goid, "]:\n") for fidx, pc := range ancestor.pcs { - function, file, line, _ := funcfileline(pc, -1) + function, file, line, _ := funcfileline(pc, -1, false) if showfuncinfo(function, fidx == 0) { printAncestorTracebackFuncInfo(function, file, line, pc) } @@ -102,7 +102,7 @@ func printAncestorTraceback(ancestor ancestorInfo) { print("...additional frames elided...\n") } // Show what created goroutine, except main goroutine (goid 1). - function, file, line, _ := funcfileline(ancestor.gopc, -1) + function, file, line, _ := funcfileline(ancestor.gopc, -1, false) if function != "" && showfuncinfo(function, false) && ancestor.goid != 1 { printcreatedby1(function, file, line, funcentry(ancestor.gopc), ancestor.gopc) } diff --git a/libgo/go/runtime/treap_test.go b/libgo/go/runtime/treap_test.go deleted file mode 100644 index 110f51c811c..00000000000 --- a/libgo/go/runtime/treap_test.go +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package runtime_test - -import ( - "fmt" - "runtime" - "testing" -) - -var spanDesc = map[uintptr]struct { - pages uintptr - scav bool -}{ - 0xc0000000: {2, false}, - 0xc0006000: {1, false}, - 0xc0010000: {8, false}, - 0xc0022000: {7, false}, - 0xc0034000: {4, true}, - 0xc0040000: {5, false}, - 0xc0050000: {5, true}, - 0xc0060000: {5000, false}, -} - -// Wrap the Treap one more time because go:notinheap doesn't -// actually follow a structure across package boundaries. -// -//go:notinheap -type treap struct { - runtime.Treap -} - -func maskMatchName(mask, match runtime.TreapIterType) string { - return fmt.Sprintf("%0*b-%0*b", runtime.TreapIterBits, uint8(mask), runtime.TreapIterBits, uint8(match)) -} - -func TestTreapFilter(t *testing.T) { - var iterTypes = [...]struct { - mask, match runtime.TreapIterType - filter runtime.TreapIterFilter // expected filter - }{ - {0, 0, 0xf}, - {runtime.TreapIterScav, 0, 0x5}, - {runtime.TreapIterScav, runtime.TreapIterScav, 0xa}, - {runtime.TreapIterScav | runtime.TreapIterHuge, runtime.TreapIterHuge, 0x4}, - {runtime.TreapIterScav | runtime.TreapIterHuge, 0, 0x1}, - {0, runtime.TreapIterScav, 0x0}, - } - for _, it := range iterTypes { - t.Run(maskMatchName(it.mask, it.match), func(t *testing.T) { - if f := runtime.TreapFilter(it.mask, it.match); f != it.filter { - t.Fatalf("got %#x, want %#x", f, it.filter) - } - }) - } -} - -// This test ensures that the treap implementation in the runtime -// maintains all stated invariants after different sequences of -// insert, removeSpan, find, and erase. Invariants specific to the -// treap data structure are checked implicitly: after each mutating -// operation, treap-related invariants are checked for the entire -// treap. -func TestTreap(t *testing.T) { - // Set up a bunch of spans allocated into mheap_. - // Also, derive a set of typeCounts of each type of span - // according to runtime.TreapIterType so we can verify against - // them later. - spans := make([]runtime.Span, 0, len(spanDesc)) - typeCounts := [1 << runtime.TreapIterBits][1 << runtime.TreapIterBits]int{} - for base, de := range spanDesc { - s := runtime.AllocSpan(base, de.pages, de.scav) - defer s.Free() - spans = append(spans, s) - - for i := runtime.TreapIterType(0); i < 1< i.Span().Base() { - t.Fatalf("not iterating in correct order: encountered base %x before %x", lastBase, i.Span().Base()) - } - lastBase = i.Span().Base() - if !i.Span().MatchesIter(mask, match) { - t.Fatalf("found non-matching span while iteration over mask/match %s: base %x", iterName, i.Span().Base()) - } - } - if nspans != typeCounts[mask][match] { - t.Fatal("failed to iterate forwards over full treap") - } - for _, s := range spans { - tr.RemoveSpan(s) - } - }) - t.Run("EndToStart", func(t *testing.T) { - // See StartToEnd tests. - tr := treap{} - for _, s := range spans { - tr.Insert(s) - } - nspans := 0 - lastBase := ^uintptr(0) - for i := tr.End(mask, match); i.Valid(); i = i.Prev() { - nspans++ - if lastBase < i.Span().Base() { - t.Fatalf("not iterating in correct order: encountered base %x before %x", lastBase, i.Span().Base()) - } - lastBase = i.Span().Base() - if !i.Span().MatchesIter(mask, match) { - t.Fatalf("found non-matching span while iteration over mask/match %s: base %x", iterName, i.Span().Base()) - } - } - if nspans != typeCounts[mask][match] { - t.Fatal("failed to iterate backwards over full treap") - } - for _, s := range spans { - tr.RemoveSpan(s) - } - }) - }) - } - } - t.Run("Prev", func(t *testing.T) { - // Test the iterator invariant that i.prev().next() == i. - tr := treap{} - for _, s := range spans { - tr.Insert(s) - } - i := tr.Start(0, 0).Next().Next() - p := i.Prev() - if !p.Valid() { - t.Fatal("i.prev() is invalid") - } - if p.Next().Span() != i.Span() { - t.Fatal("i.prev().next() != i") - } - for _, s := range spans { - tr.RemoveSpan(s) - } - }) - t.Run("Next", func(t *testing.T) { - // Test the iterator invariant that i.next().prev() == i. - tr := treap{} - for _, s := range spans { - tr.Insert(s) - } - i := tr.Start(0, 0).Next().Next() - n := i.Next() - if !n.Valid() { - t.Fatal("i.next() is invalid") - } - if n.Prev().Span() != i.Span() { - t.Fatal("i.next().prev() != i") - } - for _, s := range spans { - tr.RemoveSpan(s) - } - }) - }) - t.Run("EraseOne", func(t *testing.T) { - // Test that erasing one iterator correctly retains - // all relationships between elements. - tr := treap{} - for _, s := range spans { - tr.Insert(s) - } - i := tr.Start(0, 0).Next().Next().Next() - s := i.Span() - n := i.Next() - p := i.Prev() - tr.Erase(i) - if n.Prev().Span() != p.Span() { - t.Fatal("p, n := i.Prev(), i.Next(); n.prev() != p after i was erased") - } - if p.Next().Span() != n.Span() { - t.Fatal("p, n := i.Prev(), i.Next(); p.next() != n after i was erased") - } - tr.Insert(s) - for _, s := range spans { - tr.RemoveSpan(s) - } - }) - t.Run("EraseAll", func(t *testing.T) { - // Test that erasing iterators actually removes nodes from the treap. - tr := treap{} - for _, s := range spans { - tr.Insert(s) - } - for i := tr.Start(0, 0); i.Valid(); { - n := i.Next() - tr.Erase(i) - i = n - } - if size := tr.Size(); size != 0 { - t.Fatalf("should have emptied out treap, %d spans left", size) - } - }) -} diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go index d531bda33fe..4dbe68b16b5 100644 --- a/libgo/go/strconv/atof.go +++ b/libgo/go/strconv/atof.go @@ -85,7 +85,7 @@ func (b *decimal) set(s string) (ok bool) { for ; i < len(s); i++ { switch { case s[i] == '_': - // underscoreOK already called + // readFloat already checked underscores continue case s[i] == '.': if sawdot { @@ -141,7 +141,7 @@ func (b *decimal) set(s string) (ok bool) { e := 0 for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ { if s[i] == '_' { - // underscoreOK already called + // readFloat already checked underscores continue } if e < 10000 { @@ -160,10 +160,11 @@ func (b *decimal) set(s string) (ok bool) { } // readFloat reads a decimal mantissa and exponent from a float -// string representation. It returns ok==false if the number could -// not fit return types or is invalid. +// string representation. It returns ok==false if the number +// is invalid. func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) { i := 0 + underscores := false // optional sign if i >= len(s) { @@ -196,7 +197,7 @@ func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) { for ; i < len(s); i++ { switch c := s[i]; true { case c == '_': - // underscoreOK already called + underscores = true continue case c == '.': @@ -272,7 +273,7 @@ func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) { e := 0 for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i++ { if s[i] == '_' { - // underscoreOK already called + underscores = true continue } if e < 10000 { @@ -292,6 +293,11 @@ func readFloat(s string) (mantissa uint64, exp int, neg, trunc, hex, ok bool) { if mantissa != 0 { exp = dp - ndMant } + + if underscores && !underscoreOK(s) { + return + } + ok = true return } @@ -560,12 +566,16 @@ func atof32(s string) (f float32, err error) { } mantissa, exp, neg, trunc, hex, ok := readFloat(s) - if hex && ok { + if !ok { + return 0, syntaxError(fnParseFloat, s) + } + + if hex { f, err := atofHex(s, &float32info, mantissa, exp, neg, trunc) return float32(f), err } - if optimize && ok { + if optimize { // Try pure floating-point arithmetic conversion. if !trunc { if f, ok := atof32exact(mantissa, exp, neg); ok { @@ -603,11 +613,15 @@ func atof64(s string) (f float64, err error) { } mantissa, exp, neg, trunc, hex, ok := readFloat(s) - if hex && ok { + if !ok { + return 0, syntaxError(fnParseFloat, s) + } + + if hex { return atofHex(s, &float64info, mantissa, exp, neg, trunc) } - if optimize && ok { + if optimize { // Try pure floating-point arithmetic conversion. if !trunc { if f, ok := atof64exact(mantissa, exp, neg); ok { @@ -664,9 +678,6 @@ func atof64(s string) (f float64, err error) { // ParseFloat recognizes the strings "NaN", "+Inf", and "-Inf" as their // respective special floating point values. It ignores case when matching. func ParseFloat(s string, bitSize int) (float64, error) { - if !underscoreOK(s) { - return 0, syntaxError(fnParseFloat, s) - } if bitSize == 32 { f, err := atof32(s) return float64(f), err diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go index 0233f14b406..a4a8a37fb42 100644 --- a/libgo/go/strconv/atoi.go +++ b/libgo/go/strconv/atoi.go @@ -31,6 +31,8 @@ func (e *NumError) Error() string { return "strconv." + e.Func + ": " + "parsing " + Quote(e.Num) + ": " + e.Err.Error() } +func (e *NumError) Unwrap() error { return e.Err } + func syntaxError(fn, str string) *NumError { return &NumError{fn, str, ErrSyntax} } @@ -58,7 +60,7 @@ const maxUint64 = 1<<64 - 1 func ParseUint(s string, base int, bitSize int) (uint64, error) { const fnParseUint = "ParseUint" - if s == "" || !underscoreOK(s) { + if s == "" { return 0, syntaxError(fnParseUint, s) } @@ -113,12 +115,13 @@ func ParseUint(s string, base int, bitSize int) (uint64, error) { maxVal := uint64(1)< 0 { - t.Fatalf("got %d alloc(s); want 0", allocs) - } - // Issue 23382; verify that copyCheck doesn't force the // Builder to escape and be heap allocated. n := testing.AllocsPerRun(10000, func() { diff --git a/libgo/go/strings/strings.go b/libgo/go/strings/strings.go index cee315ce9e4..69f51b6e2d4 100644 --- a/libgo/go/strings/strings.go +++ b/libgo/go/strings/strings.go @@ -969,7 +969,8 @@ func ReplaceAll(s, old, new string) string { } // EqualFold reports whether s and t, interpreted as UTF-8 strings, -// are equal under Unicode case-folding. +// are equal under Unicode case-folding, which is a more general +// form of case-insensitivity. func EqualFold(s, t string) bool { for s != "" && t != "" { // Extract first rune from each string. @@ -1093,7 +1094,7 @@ func Index(s, substr string) int { i++ fails++ if fails >= 4+i>>4 && i < t { - // See comment in ../bytes/bytes_generic.go. + // See comment in ../bytes/bytes.go. j := indexRabinKarp(s[i:], substr) if j < 0 { return -1 diff --git a/libgo/go/strings/strings_test.go b/libgo/go/strings/strings_test.go index 76d827b47fa..7eddce5233f 100644 --- a/libgo/go/strings/strings_test.go +++ b/libgo/go/strings/strings_test.go @@ -195,10 +195,12 @@ func runIndexTests(t *testing.T, f func(s, sep string) int, funcName string, tes } } -func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) } -func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) } -func TestIndexAny(t *testing.T) { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) } -func TestLastIndexAny(t *testing.T) { runIndexTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) } +func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) } +func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) } +func TestIndexAny(t *testing.T) { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) } +func TestLastIndexAny(t *testing.T) { + runIndexTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) +} func TestIndexByte(t *testing.T) { for _, tt := range indexTests { diff --git a/libgo/go/sync/atomic/atomic_test.go b/libgo/go/sync/atomic/atomic_test.go index 39c40c6aaf5..286eadc6cdf 100644 --- a/libgo/go/sync/atomic/atomic_test.go +++ b/libgo/go/sync/atomic/atomic_test.go @@ -1140,6 +1140,9 @@ func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) { StoreUintptr(addr, new) } +//go:nocheckptr +// This code is just testing that LoadPointer/StorePointer operate +// atomically; it's not actually calculating pointers. func hammerStoreLoadPointer(t *testing.T, paddr unsafe.Pointer) { addr := (*unsafe.Pointer)(paddr) v := uintptr(LoadPointer(addr)) @@ -1391,15 +1394,8 @@ func TestUnaligned64(t *testing.T) { // Unaligned 64-bit atomics on 32-bit systems are // a continual source of pain. Test that on 32-bit systems they crash // instead of failing silently. - - switch runtime.GOARCH { - default: - if !arch32 { - t.Skip("test only runs on 32-bit systems") - } - case "amd64p32": - // amd64p32 can handle unaligned atomics. - t.Skipf("test not needed on %v", runtime.GOARCH) + if !arch32 { + t.Skip("test only runs on 32-bit systems") } x := make([]uint32, 4) diff --git a/libgo/go/sync/mutex.go b/libgo/go/sync/mutex.go index 11ad20c9757..3028552f743 100644 --- a/libgo/go/sync/mutex.go +++ b/libgo/go/sync/mutex.go @@ -216,7 +216,8 @@ func (m *Mutex) unlockSlow(new int32) { old = m.state } } else { - // Starving mode: handoff mutex ownership to the next waiter. + // Starving mode: handoff mutex ownership to the next waiter, and yield + // our time slice so that the next waiter can start to run immediately. // Note: mutexLocked is not set, the waiter will set it after wakeup. // But mutex is still considered locked if mutexStarving is set, // so new coming goroutines won't acquire it. diff --git a/libgo/go/sync/waitgroup_test.go b/libgo/go/sync/waitgroup_test.go index 4ab438cbab1..c569e0faa2e 100644 --- a/libgo/go/sync/waitgroup_test.go +++ b/libgo/go/sync/waitgroup_test.go @@ -147,7 +147,7 @@ func TestWaitGroupMisuse3(t *testing.T) { } }() defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - done := make(chan interface{}, 2) + done := make(chan interface{}, 3) // The detection is opportunistically, so we want it to panic // at least in one run out of a million. for i := 0; i < 1e6; i++ { @@ -171,8 +171,13 @@ func TestWaitGroupMisuse3(t *testing.T) { }() wg.Wait() }() - wg.Wait() - for j := 0; j < 2; j++ { + go func() { + defer func() { + done <- recover() + }() + wg.Wait() + }() + for j := 0; j < 3; j++ { if err := <-done; err != nil { panic(err) } diff --git a/libgo/go/syscall/dirent.go b/libgo/go/syscall/dirent.go index 58c34c3fe66..57264493163 100644 --- a/libgo/go/syscall/dirent.go +++ b/libgo/go/syscall/dirent.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package syscall diff --git a/libgo/go/syscall/dirent_bsd_test.go b/libgo/go/syscall/dirent_bsd_test.go deleted file mode 100644 index 43b667b6b62..00000000000 --- a/libgo/go/syscall/dirent_bsd_test.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd netbsd openbsd - -package syscall_test - -import ( - "bytes" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "runtime" - "sort" - "strconv" - "strings" - "syscall" - "testing" - "unsafe" -) - -func TestDirent(t *testing.T) { - const ( - direntBufSize = 2048 - filenameMinSize = 11 - ) - - d, err := ioutil.TempDir("", "dirent-test") - if err != nil { - t.Fatalf("tempdir: %v", err) - } - defer os.RemoveAll(d) - t.Logf("tmpdir: %s", d) - - for i, c := range []byte("0123456789") { - name := string(bytes.Repeat([]byte{c}, filenameMinSize+i)) - err = ioutil.WriteFile(filepath.Join(d, name), nil, 0644) - if err != nil { - t.Fatalf("writefile: %v", err) - } - } - - buf := bytes.Repeat([]byte("DEADBEAF"), direntBufSize/8) - fd, err := syscall.Open(d, syscall.O_RDONLY, 0) - if err != nil { - t.Fatalf("syscall.open: %v", err) - } - defer syscall.Close(fd) - n, err := syscall.ReadDirent(fd, buf) - if err != nil { - t.Fatalf("syscall.readdir: %v", err) - } - buf = buf[:n] - - names := make([]string, 0, 10) - for len(buf) > 0 { - var bc int - bc, _, names = syscall.ParseDirent(buf, -1, names) - buf = buf[bc:] - } - - sort.Strings(names) - t.Logf("names: %q", names) - - if len(names) != 10 { - t.Errorf("got %d names; expected 10", len(names)) - } - for i, name := range names { - ord, err := strconv.Atoi(name[:1]) - if err != nil { - t.Fatalf("names[%d] is non-integer %q: %v", i, names[i], err) - } - if expected := string(strings.Repeat(name[:1], filenameMinSize+ord)); name != expected { - t.Errorf("names[%d] is %q (len %d); expected %q (len %d)", i, name, len(name), expected, len(expected)) - } - } -} - -func TestDirentRepeat(t *testing.T) { - const N = 100 - // Note: the size of the buffer is small enough that the loop - // below will need to execute multiple times. See issue #31368. - size := N * unsafe.Offsetof(syscall.Dirent{}.Name) / 4 - if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { - if size < 1024 { - size = 1024 // DIRBLKSIZ, see issue 31403. - } - if runtime.GOOS == "freebsd" { - t.Skip("need to fix issue 31416 first") - } - } - - // Make a directory containing N files - d, err := ioutil.TempDir("", "direntRepeat-test") - if err != nil { - t.Fatalf("tempdir: %v", err) - } - defer os.RemoveAll(d) - - var files []string - for i := 0; i < N; i++ { - files = append(files, fmt.Sprintf("file%d", i)) - } - for _, file := range files { - err = ioutil.WriteFile(filepath.Join(d, file), []byte("contents"), 0644) - if err != nil { - t.Fatalf("writefile: %v", err) - } - } - - // Read the directory entries using ReadDirent. - fd, err := syscall.Open(d, syscall.O_RDONLY, 0) - if err != nil { - t.Fatalf("syscall.open: %v", err) - } - defer syscall.Close(fd) - var files2 []string - for { - buf := make([]byte, size) - n, err := syscall.ReadDirent(fd, buf) - if err != nil { - t.Fatalf("syscall.readdir: %v", err) - } - if n == 0 { - break - } - buf = buf[:n] - for len(buf) > 0 { - var consumed int - consumed, _, files2 = syscall.ParseDirent(buf, -1, files2) - buf = buf[consumed:] - } - } - - // Check results - sort.Strings(files) - sort.Strings(files2) - if strings.Join(files, "|") != strings.Join(files2, "|") { - t.Errorf("bad file list: want\n%q\ngot\n%q", files, files2) - } -} diff --git a/libgo/go/syscall/dirent_test.go b/libgo/go/syscall/dirent_test.go new file mode 100644 index 00000000000..f63153340aa --- /dev/null +++ b/libgo/go/syscall/dirent_test.go @@ -0,0 +1,143 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris + +package syscall_test + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "runtime" + "sort" + "strconv" + "strings" + "syscall" + "testing" + "unsafe" +) + +func TestDirent(t *testing.T) { + const ( + direntBufSize = 2048 + filenameMinSize = 11 + ) + + d, err := ioutil.TempDir("", "dirent-test") + if err != nil { + t.Fatalf("tempdir: %v", err) + } + defer os.RemoveAll(d) + t.Logf("tmpdir: %s", d) + + for i, c := range []byte("0123456789") { + name := string(bytes.Repeat([]byte{c}, filenameMinSize+i)) + err = ioutil.WriteFile(filepath.Join(d, name), nil, 0644) + if err != nil { + t.Fatalf("writefile: %v", err) + } + } + + buf := bytes.Repeat([]byte("DEADBEAF"), direntBufSize/8) + fd, err := syscall.Open(d, syscall.O_RDONLY, 0) + if err != nil { + t.Fatalf("syscall.open: %v", err) + } + defer syscall.Close(fd) + n, err := syscall.ReadDirent(fd, buf) + if err != nil { + t.Fatalf("syscall.readdir: %v", err) + } + buf = buf[:n] + + names := make([]string, 0, 10) + for len(buf) > 0 { + var bc int + bc, _, names = syscall.ParseDirent(buf, -1, names) + buf = buf[bc:] + } + + sort.Strings(names) + t.Logf("names: %q", names) + + if len(names) != 10 { + t.Errorf("got %d names; expected 10", len(names)) + } + for i, name := range names { + ord, err := strconv.Atoi(name[:1]) + if err != nil { + t.Fatalf("names[%d] is non-integer %q: %v", i, names[i], err) + } + if expected := string(strings.Repeat(name[:1], filenameMinSize+ord)); name != expected { + t.Errorf("names[%d] is %q (len %d); expected %q (len %d)", i, name, len(name), expected, len(expected)) + } + } +} + +func TestDirentRepeat(t *testing.T) { + const N = 100 + // Note: the size of the buffer is small enough that the loop + // below will need to execute multiple times. See issue #31368. + size := N * unsafe.Offsetof(syscall.Dirent{}.Name) / 4 + if runtime.GOOS == "freebsd" || runtime.GOOS == "netbsd" { + if size < 1024 { + size = 1024 // DIRBLKSIZ, see issue 31403. + } + if runtime.GOOS == "freebsd" { + t.Skip("need to fix issue 31416 first") + } + } + + // Make a directory containing N files + d, err := ioutil.TempDir("", "direntRepeat-test") + if err != nil { + t.Fatalf("tempdir: %v", err) + } + defer os.RemoveAll(d) + + var files []string + for i := 0; i < N; i++ { + files = append(files, fmt.Sprintf("file%d", i)) + } + for _, file := range files { + err = ioutil.WriteFile(filepath.Join(d, file), []byte("contents"), 0644) + if err != nil { + t.Fatalf("writefile: %v", err) + } + } + + // Read the directory entries using ReadDirent. + fd, err := syscall.Open(d, syscall.O_RDONLY, 0) + if err != nil { + t.Fatalf("syscall.open: %v", err) + } + defer syscall.Close(fd) + var files2 []string + for { + buf := make([]byte, size) + n, err := syscall.ReadDirent(fd, buf) + if err != nil { + t.Fatalf("syscall.readdir: %v", err) + } + if n == 0 { + break + } + buf = buf[:n] + for len(buf) > 0 { + var consumed int + consumed, _, files2 = syscall.ParseDirent(buf, -1, files2) + buf = buf[consumed:] + } + } + + // Check results + sort.Strings(files) + sort.Strings(files2) + if strings.Join(files, "|") != strings.Join(files2, "|") { + t.Errorf("bad file list: want\n%q\ngot\n%q", files, files2) + } +} diff --git a/libgo/go/syscall/env_plan9.go b/libgo/go/syscall/env_plan9.go index 9a8a837e7d3..e403a25e314 100644 --- a/libgo/go/syscall/env_plan9.go +++ b/libgo/go/syscall/env_plan9.go @@ -74,7 +74,21 @@ func Setenv(key, value string) error { } func Clearenv() { - RawSyscall(SYS_RFORK, RFCENVG, 0, 0) + // Creating a new environment group using rfork(RFCENVG) can race + // with access to files in /env (e.g. from Setenv or Getenv). + // Remove all environment variables in current environment group instead. + fd, err := open("/env", O_RDONLY) + if err != nil { + return + } + defer Close(fd) + files, err := readdirnames(fd) + if err != nil { + return + } + for _, key := range files { + Remove("/env/" + key) + } } func Unsetenv(key string) error { diff --git a/libgo/go/syscall/env_unix.go b/libgo/go/syscall/env_unix.go index c22af18ba54..3564f7f38c4 100644 --- a/libgo/go/syscall/env_unix.go +++ b/libgo/go/syscall/env_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris // Unix environment variables. diff --git a/libgo/go/syscall/exec_linux_test.go b/libgo/go/syscall/exec_linux_test.go index 7bd39100632..1a44f04c8c1 100644 --- a/libgo/go/syscall/exec_linux_test.go +++ b/libgo/go/syscall/exec_linux_test.go @@ -34,6 +34,14 @@ func isLXC() bool { } func skipInContainer(t *testing.T) { + // TODO: the callers of this func are using this func to skip + // tests when running as some sort of "fake root" that's uid 0 + // but lacks certain Linux capabilities. Most of the Go builds + // run in privileged containers, though, where root is much + // closer (if not identical) to the real root. We should test + // for what we need exactly (which capabilities are active?), + // instead of just assuming "docker == bad". Then we'd get more test + // coverage on a bunch of builders too. if isDocker() { t.Skip("skip this test in Docker container") } @@ -42,6 +50,18 @@ func skipInContainer(t *testing.T) { } } +func skipNoUserNamespaces(t *testing.T) { + if _, err := os.Stat("/proc/self/ns/user"); err != nil { + if os.IsNotExist(err) { + t.Skip("kernel doesn't support user namespaces") + } + if os.IsPermission(err) { + t.Skip("unable to test user namespaces due to permissions") + } + t.Fatalf("Failed to stat /proc/self/ns/user: %v", err) + } +} + func skipUnprivilegedUserClone(t *testing.T) { // Skip the test if the sysctl that prevents unprivileged user // from creating user namespaces is enabled. @@ -64,15 +84,7 @@ func isChrooted(t *testing.T) bool { func checkUserNS(t *testing.T) { skipInContainer(t) - if _, err := os.Stat("/proc/self/ns/user"); err != nil { - if os.IsNotExist(err) { - t.Skip("kernel doesn't support user namespaces") - } - if os.IsPermission(err) { - t.Skip("unable to test user namespaces due to permissions") - } - t.Fatalf("Failed to stat /proc/self/ns/user: %v", err) - } + skipNoUserNamespaces(t) if isChrooted(t) { // create_user_ns in the kernel (see // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/kernel/user_namespace.c) @@ -305,6 +317,7 @@ func TestGroupCleanupUserNamespace(t *testing.T) { "uid=0(root) gid=0(root) groups=0(root),65534(nogroup)", "uid=0(root) gid=0(root) groups=0(root),65534", "uid=0(root) gid=0(root) groups=0(root),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody),65534(nobody)", // Alpine; see https://golang.org/issue/19938 + "uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023", // CentOS with SELinux context, see https://golang.org/issue/34547 } for _, e := range expected { if strOut == e { @@ -336,14 +349,6 @@ func TestUnshareMountNameSpace(t *testing.T) { t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace") } - // When running under the Go continuous build, skip tests for - // now when under Kubernetes. (where things are root but not quite) - // Both of these are our own environment variables. - // See Issue 12815. - if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" { - t.Skip("skipping test on Kubernetes-based builders; see Issue 12815") - } - d, err := ioutil.TempDir("", "unshare") if err != nil { t.Fatalf("tempdir: %v", err) @@ -386,14 +391,6 @@ func TestUnshareMountNameSpaceChroot(t *testing.T) { t.Skip("kernel prohibits unshare in unprivileged process, unless using user namespace") } - // When running under the Go continuous build, skip tests for - // now when under Kubernetes. (where things are root but not quite) - // Both of these are our own environment variables. - // See Issue 12815. - if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" { - t.Skip("skipping test on Kubernetes-based builders; see Issue 12815") - } - d, err := ioutil.TempDir("", "unshare") if err != nil { t.Fatalf("tempdir: %v", err) @@ -573,6 +570,7 @@ func TestAmbientCaps(t *testing.T) { } func TestAmbientCapsUserns(t *testing.T) { + checkUserNS(t) testAmbientCaps(t, true) } @@ -580,14 +578,6 @@ func testAmbientCaps(t *testing.T, userns bool) { skipInContainer(t) mustSupportAmbientCaps(t) - // When running under the Go continuous build, skip tests for - // now when under Kubernetes. (where things are root but not quite) - // Both of these are our own environment variables. - // See Issue 12815. - if os.Getenv("GO_BUILDER_NAME") != "" && os.Getenv("IN_KUBERNETES") == "1" { - t.Skip("skipping test on Kubernetes-based builders; see Issue 12815") - } - skipUnprivilegedUserClone(t) // skip on android, due to lack of lookup support diff --git a/libgo/go/syscall/fs_js.go b/libgo/go/syscall/fs_js.go index 1b835c50484..16d9f58b8c4 100644 --- a/libgo/go/syscall/fs_js.go +++ b/libgo/go/syscall/fs_js.go @@ -34,6 +34,7 @@ var ( type jsFile struct { path string entries []string + dirIdx int // entries[:dirIdx] have already been returned in ReadDirent pos int64 seeked bool } @@ -141,8 +142,8 @@ func ReadDirent(fd int, buf []byte) (int, error) { } n := 0 - for len(f.entries) > 0 { - entry := f.entries[0] + for f.dirIdx < len(f.entries) { + entry := f.entries[f.dirIdx] l := 2 + len(entry) if l > len(buf) { break @@ -152,7 +153,7 @@ func ReadDirent(fd int, buf []byte) (int, error) { copy(buf[2:], entry) buf = buf[l:] n += l - f.entries = f.entries[1:] + f.dirIdx++ } return n, nil @@ -259,7 +260,7 @@ func Lchown(path string, uid, gid int) error { if err := checkPath(path); err != nil { return err } - if jsFS.Get("lchown") == js.Undefined() { + if jsFS.Get("lchown").IsUndefined() { // fs.lchown is unavailable on Linux until Node.js 10.6.0 // TODO(neelance): remove when we require at least this Node.js version return ENOSYS @@ -404,6 +405,14 @@ func Write(fd int, b []byte) (int, error) { return n, err } + if faketime && (fd == 1 || fd == 2) { + n := faketimeWrite(fd, b) + if n < 0 { + return 0, errnoErr(Errno(-n)) + } + return n, nil + } + buf := uint8Array.New(len(b)) js.CopyBytesToJS(buf, b) n, err := fsCall("write", fd, buf, 0, len(b), nil) @@ -462,6 +471,7 @@ func Seek(fd int, offset int64, whence int) (int64, error) { } f.seeked = true + f.dirIdx = 0 // Reset directory read position. See issue 35767. f.pos = newPos return newPos, nil } @@ -489,7 +499,7 @@ func fsCall(name string, args ...interface{}) (js.Value, error) { var res callResult if len(args) >= 1 { // on Node.js 8, fs.utimes calls the callback without any arguments - if jsErr := args[0]; jsErr != js.Null() { + if jsErr := args[0]; !jsErr.IsNull() { res.err = mapJSError(jsErr) } } diff --git a/libgo/go/syscall/getdirentries_test.go b/libgo/go/syscall/getdirentries_test.go index 8505a0bb897..2a3419c2300 100644 --- a/libgo/go/syscall/getdirentries_test.go +++ b/libgo/go/syscall/getdirentries_test.go @@ -66,7 +66,11 @@ func testGetdirentries(t *testing.T, count int) { } data := buf[:n] for len(data) > 0 { - dirent := (*syscall.Dirent)(unsafe.Pointer(&data[0])) + // If multiple Dirents are written into buf, sometimes when we reach the final one, + // we have cap(buf) < Sizeof(Dirent). So use an appropriate slice to copy from data. + var dirent syscall.Dirent + copy((*[unsafe.Sizeof(dirent)]byte)(unsafe.Pointer(&dirent))[:], data) + data = data[dirent.Reclen:] name := make([]byte, dirent.Namlen) for i := 0; i < int(dirent.Namlen); i++ { diff --git a/libgo/go/syscall/js/export_test.go b/libgo/go/syscall/js/export_test.go new file mode 100644 index 00000000000..1b5ed3ce849 --- /dev/null +++ b/libgo/go/syscall/js/export_test.go @@ -0,0 +1,9 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build js,wasm + +package js + +var JSGo = jsGo diff --git a/libgo/go/syscall/js/func.go b/libgo/go/syscall/js/func.go index 6b7f39b8784..6c145c9da6f 100644 --- a/libgo/go/syscall/js/func.go +++ b/libgo/go/syscall/js/func.go @@ -64,7 +64,7 @@ func init() { func handleEvent() { cb := jsGo.Get("_pendingEvent") - if cb == Null() { + if cb.IsNull() { return } jsGo.Set("_pendingEvent", Null()) diff --git a/libgo/go/syscall/js/js.go b/libgo/go/syscall/js/js.go index 7300d2c7695..8a043991711 100644 --- a/libgo/go/syscall/js/js.go +++ b/libgo/go/syscall/js/js.go @@ -12,6 +12,7 @@ package js import ( + "runtime" "unsafe" ) @@ -20,7 +21,7 @@ import ( // The JavaScript value "undefined" is represented by the value 0. // A JavaScript number (64-bit float, except 0 and NaN) is represented by its IEEE 754 binary representation. // All other values are represented as an IEEE 754 binary representation of NaN with bits 0-31 used as -// an ID and bits 32-33 used to differentiate between string, symbol, function and object. +// an ID and bits 32-34 used to differentiate between string, symbol, function and object. type ref uint64 // nanHead are the upper 32 bits of a ref which are set if the value is not encoded as an IEEE 754 number (see above). @@ -33,21 +34,45 @@ type Wrapper interface { } // Value represents a JavaScript value. The zero value is the JavaScript value "undefined". +// Values can be checked for equality with the Equal method. type Value struct { - ref ref + _ [0]func() // uncomparable; to make == not compile + ref ref // identifies a JavaScript value, see ref type + gcPtr *ref // used to trigger the finalizer when the Value is not referenced any more } +const ( + // the type flags need to be in sync with wasm_exec.js + typeFlagNone = iota + typeFlagObject + typeFlagString + typeFlagSymbol + typeFlagFunction +) + // JSValue implements Wrapper interface. func (v Value) JSValue() Value { return v } -func makeValue(v ref) Value { - return Value{ref: v} +func makeValue(r ref) Value { + var gcPtr *ref + typeFlag := (r >> 32) & 7 + if (r>>32)&nanHead == nanHead && typeFlag != typeFlagNone { + gcPtr = new(ref) + *gcPtr = r + runtime.SetFinalizer(gcPtr, func(p *ref) { + finalizeRef(*p) + }) + } + + return Value{ref: r, gcPtr: gcPtr} } -func predefValue(id uint32) Value { - return Value{ref: nanHead<<32 | ref(id)} +func finalizeRef(r ref) + +func predefValue(id uint32, typeFlag byte) Value { + return Value{ref: (nanHead|ref(typeFlag))<<32 | ref(id)} } func floatValue(f float64) Value { @@ -73,28 +98,48 @@ func (e Error) Error() string { var ( valueUndefined = Value{ref: 0} - valueNaN = predefValue(0) - valueZero = predefValue(1) - valueNull = predefValue(2) - valueTrue = predefValue(3) - valueFalse = predefValue(4) - valueGlobal = predefValue(5) - jsGo = predefValue(6) // instance of the Go class in JavaScript + valueNaN = predefValue(0, typeFlagNone) + valueZero = predefValue(1, typeFlagNone) + valueNull = predefValue(2, typeFlagNone) + valueTrue = predefValue(3, typeFlagNone) + valueFalse = predefValue(4, typeFlagNone) + valueGlobal = predefValue(5, typeFlagObject) + jsGo = predefValue(6, typeFlagObject) // instance of the Go class in JavaScript objectConstructor = valueGlobal.Get("Object") arrayConstructor = valueGlobal.Get("Array") ) +// Equal reports whether v and w are equal according to JavaScript's === operator. +func (v Value) Equal(w Value) bool { + return v.ref == w.ref && v.ref != valueNaN.ref +} + // Undefined returns the JavaScript value "undefined". func Undefined() Value { return valueUndefined } +// IsUndefined reports whether v is the JavaScript value "undefined". +func (v Value) IsUndefined() bool { + return v.ref == valueUndefined.ref +} + // Null returns the JavaScript value "null". func Null() Value { return valueNull } +// IsNull reports whether v is the JavaScript value "null". +func (v Value) IsNull() bool { + return v.ref == valueNull.ref +} + +// IsNaN reports whether v is the JavaScript value "NaN". +func (v Value) IsNaN() bool { + return v.ref == valueNaN.ref +} + // Global returns the JavaScript global object, usually "window" or "global". func Global() Value { return valueGlobal @@ -232,16 +277,18 @@ func (v Value) Type() Type { if v.isNumber() { return TypeNumber } - typeFlag := v.ref >> 32 & 3 + typeFlag := (v.ref >> 32) & 7 switch typeFlag { - case 1: + case typeFlagObject: + return TypeObject + case typeFlagString: return TypeString - case 2: + case typeFlagSymbol: return TypeSymbol - case 3: + case typeFlagFunction: return TypeFunction default: - return TypeObject + panic("bad type flag") } } @@ -251,7 +298,9 @@ func (v Value) Get(p string) Value { if vType := v.Type(); !vType.isObject() { panic(&ValueError{"Value.Get", vType}) } - return makeValue(valueGet(v.ref, p)) + r := makeValue(valueGet(v.ref, p)) + runtime.KeepAlive(v) + return r } func valueGet(v ref, p string) ref @@ -262,18 +311,35 @@ func (v Value) Set(p string, x interface{}) { if vType := v.Type(); !vType.isObject() { panic(&ValueError{"Value.Set", vType}) } - valueSet(v.ref, p, ValueOf(x).ref) + xv := ValueOf(x) + valueSet(v.ref, p, xv.ref) + runtime.KeepAlive(v) + runtime.KeepAlive(xv) } func valueSet(v ref, p string, x ref) +// Delete deletes the JavaScript property p of value v. +// It panics if v is not a JavaScript object. +func (v Value) Delete(p string) { + if vType := v.Type(); !vType.isObject() { + panic(&ValueError{"Value.Delete", vType}) + } + valueDelete(v.ref, p) + runtime.KeepAlive(v) +} + +func valueDelete(v ref, p string) + // Index returns JavaScript index i of value v. // It panics if v is not a JavaScript object. func (v Value) Index(i int) Value { if vType := v.Type(); !vType.isObject() { panic(&ValueError{"Value.Index", vType}) } - return makeValue(valueIndex(v.ref, i)) + r := makeValue(valueIndex(v.ref, i)) + runtime.KeepAlive(v) + return r } func valueIndex(v ref, i int) ref @@ -284,17 +350,23 @@ func (v Value) SetIndex(i int, x interface{}) { if vType := v.Type(); !vType.isObject() { panic(&ValueError{"Value.SetIndex", vType}) } - valueSetIndex(v.ref, i, ValueOf(x).ref) + xv := ValueOf(x) + valueSetIndex(v.ref, i, xv.ref) + runtime.KeepAlive(v) + runtime.KeepAlive(xv) } func valueSetIndex(v ref, i int, x ref) -func makeArgs(args []interface{}) []ref { - argVals := make([]ref, len(args)) +func makeArgs(args []interface{}) ([]Value, []ref) { + argVals := make([]Value, len(args)) + argRefs := make([]ref, len(args)) for i, arg := range args { - argVals[i] = ValueOf(arg).ref + v := ValueOf(arg) + argVals[i] = v + argRefs[i] = v.ref } - return argVals + return argVals, argRefs } // Length returns the JavaScript property "length" of v. @@ -303,7 +375,9 @@ func (v Value) Length() int { if vType := v.Type(); !vType.isObject() { panic(&ValueError{"Value.SetIndex", vType}) } - return valueLength(v.ref) + r := valueLength(v.ref) + runtime.KeepAlive(v) + return r } func valueLength(v ref) int @@ -312,7 +386,10 @@ func valueLength(v ref) int // It panics if v has no method m. // The arguments get mapped to JavaScript values according to the ValueOf function. func (v Value) Call(m string, args ...interface{}) Value { - res, ok := valueCall(v.ref, m, makeArgs(args)) + argVals, argRefs := makeArgs(args) + res, ok := valueCall(v.ref, m, argRefs) + runtime.KeepAlive(v) + runtime.KeepAlive(argVals) if !ok { if vType := v.Type(); !vType.isObject() { // check here to avoid overhead in success case panic(&ValueError{"Value.Call", vType}) @@ -331,7 +408,10 @@ func valueCall(v ref, m string, args []ref) (ref, bool) // It panics if v is not a JavaScript function. // The arguments get mapped to JavaScript values according to the ValueOf function. func (v Value) Invoke(args ...interface{}) Value { - res, ok := valueInvoke(v.ref, makeArgs(args)) + argVals, argRefs := makeArgs(args) + res, ok := valueInvoke(v.ref, argRefs) + runtime.KeepAlive(v) + runtime.KeepAlive(argVals) if !ok { if vType := v.Type(); vType != TypeFunction { // check here to avoid overhead in success case panic(&ValueError{"Value.Invoke", vType}) @@ -347,7 +427,10 @@ func valueInvoke(v ref, args []ref) (ref, bool) // It panics if v is not a JavaScript function. // The arguments get mapped to JavaScript values according to the ValueOf function. func (v Value) New(args ...interface{}) Value { - res, ok := valueNew(v.ref, makeArgs(args)) + argVals, argRefs := makeArgs(args) + res, ok := valueNew(v.ref, argRefs) + runtime.KeepAlive(v) + runtime.KeepAlive(argVals) if !ok { if vType := v.Type(); vType != TypeFunction { // check here to avoid overhead in success case panic(&ValueError{"Value.Invoke", vType}) @@ -362,7 +445,7 @@ func valueNew(v ref, args []ref) (ref, bool) func (v Value) isNumber() bool { return v.ref == valueZero.ref || v.ref == valueNaN.ref || - (v.ref != valueUndefined.ref && v.ref>>32&nanHead != nanHead) + (v.ref != valueUndefined.ref && (v.ref>>32)&nanHead != nanHead) } func (v Value) float(method string) float64 { @@ -427,15 +510,15 @@ func (v Value) Truthy() bool { func (v Value) String() string { switch v.Type() { case TypeString: - return jsString(v.ref) + return jsString(v) case TypeUndefined: return "" case TypeNull: return "" case TypeBoolean: - return "" + return "" case TypeNumber: - return "" + return "" case TypeSymbol: return "" case TypeObject: @@ -447,10 +530,12 @@ func (v Value) String() string { } } -func jsString(v ref) string { - str, length := valuePrepareString(v) +func jsString(v Value) string { + str, length := valuePrepareString(v.ref) + runtime.KeepAlive(v) b := make([]byte, length) valueLoadString(str, b) + finalizeRef(str) return string(b) } @@ -460,7 +545,10 @@ func valueLoadString(v ref, b []byte) // InstanceOf reports whether v is an instance of type t according to JavaScript's instanceof operator. func (v Value) InstanceOf(t Value) bool { - return valueInstanceOf(v.ref, t.ref) + r := valueInstanceOf(v.ref, t.ref) + runtime.KeepAlive(v) + runtime.KeepAlive(t) + return r } func valueInstanceOf(v ref, t ref) bool @@ -482,6 +570,7 @@ func (e *ValueError) Error() string { // CopyBytesToGo panics if src is not an Uint8Array. func CopyBytesToGo(dst []byte, src Value) int { n, ok := copyBytesToGo(dst, src.ref) + runtime.KeepAlive(src) if !ok { panic("syscall/js: CopyBytesToGo: expected src to be an Uint8Array") } @@ -495,6 +584,7 @@ func copyBytesToGo(dst []byte, src ref) (int, bool) // CopyBytesToJS panics if dst is not an Uint8Array. func CopyBytesToJS(dst Value, src []byte) int { n, ok := copyBytesToJS(dst.ref, src) + runtime.KeepAlive(dst) if !ok { panic("syscall/js: CopyBytesToJS: expected dst to be an Uint8Array") } diff --git a/libgo/go/syscall/js/js_test.go b/libgo/go/syscall/js/js_test.go index 7a1e346f55f..fea4c135afc 100644 --- a/libgo/go/syscall/js/js_test.go +++ b/libgo/go/syscall/js/js_test.go @@ -18,6 +18,7 @@ package js_test import ( "fmt" "math" + "runtime" "syscall/js" "testing" ) @@ -53,7 +54,7 @@ func TestBool(t *testing.T) { if got := dummys.Get("otherBool").Bool(); got != want { t.Errorf("got %#v, want %#v", got, want) } - if dummys.Get("someBool") != dummys.Get("someBool") { + if !dummys.Get("someBool").Equal(dummys.Get("someBool")) { t.Errorf("same value not equal") } } @@ -68,7 +69,7 @@ func TestString(t *testing.T) { if got := dummys.Get("otherString").String(); got != want { t.Errorf("got %#v, want %#v", got, want) } - if dummys.Get("someString") != dummys.Get("someString") { + if !dummys.Get("someString").Equal(dummys.Get("someString")) { t.Errorf("same value not equal") } @@ -105,7 +106,7 @@ func TestInt(t *testing.T) { if got := dummys.Get("otherInt").Int(); got != want { t.Errorf("got %#v, want %#v", got, want) } - if dummys.Get("someInt") != dummys.Get("someInt") { + if !dummys.Get("someInt").Equal(dummys.Get("someInt")) { t.Errorf("same value not equal") } if got := dummys.Get("zero").Int(); got != 0 { @@ -141,20 +142,20 @@ func TestFloat(t *testing.T) { if got := dummys.Get("otherFloat").Float(); got != want { t.Errorf("got %#v, want %#v", got, want) } - if dummys.Get("someFloat") != dummys.Get("someFloat") { + if !dummys.Get("someFloat").Equal(dummys.Get("someFloat")) { t.Errorf("same value not equal") } } func TestObject(t *testing.T) { - if dummys.Get("someArray") != dummys.Get("someArray") { + if !dummys.Get("someArray").Equal(dummys.Get("someArray")) { t.Errorf("same value not equal") } // An object and its prototype should not be equal. proto := js.Global().Get("Object").Get("prototype") o := js.Global().Call("eval", "new Object()") - if proto == o { + if proto.Equal(o) { t.Errorf("object equals to its prototype") } } @@ -167,26 +168,66 @@ func TestFrozenObject(t *testing.T) { } } +func TestEqual(t *testing.T) { + if !dummys.Get("someFloat").Equal(dummys.Get("someFloat")) { + t.Errorf("same float is not equal") + } + if !dummys.Get("emptyObj").Equal(dummys.Get("emptyObj")) { + t.Errorf("same object is not equal") + } + if dummys.Get("someFloat").Equal(dummys.Get("someInt")) { + t.Errorf("different values are not unequal") + } +} + func TestNaN(t *testing.T) { - want := js.ValueOf(math.NaN()) - got := dummys.Get("NaN") - if got != want { - t.Errorf("got %#v, want %#v", got, want) + if !dummys.Get("NaN").IsNaN() { + t.Errorf("JS NaN is not NaN") + } + if !js.ValueOf(math.NaN()).IsNaN() { + t.Errorf("Go NaN is not NaN") + } + if dummys.Get("NaN").Equal(dummys.Get("NaN")) { + t.Errorf("NaN is equal to NaN") } } func TestUndefined(t *testing.T) { - dummys.Set("test", js.Undefined()) - if dummys == js.Undefined() || dummys.Get("test") != js.Undefined() || dummys.Get("xyz") != js.Undefined() { - t.Errorf("js.Undefined expected") + if !js.Undefined().IsUndefined() { + t.Errorf("undefined is not undefined") + } + if !js.Undefined().Equal(js.Undefined()) { + t.Errorf("undefined is not equal to undefined") + } + if dummys.IsUndefined() { + t.Errorf("object is undefined") + } + if js.Undefined().IsNull() { + t.Errorf("undefined is null") + } + if dummys.Set("test", js.Undefined()); !dummys.Get("test").IsUndefined() { + t.Errorf("could not set undefined") } } func TestNull(t *testing.T) { - dummys.Set("test1", nil) - dummys.Set("test2", js.Null()) - if dummys == js.Null() || dummys.Get("test1") != js.Null() || dummys.Get("test2") != js.Null() { - t.Errorf("js.Null expected") + if !js.Null().IsNull() { + t.Errorf("null is not null") + } + if !js.Null().Equal(js.Null()) { + t.Errorf("null is not equal to null") + } + if dummys.IsNull() { + t.Errorf("object is null") + } + if js.Null().IsUndefined() { + t.Errorf("null is undefined") + } + if dummys.Set("test", js.Null()); !dummys.Get("test").IsNull() { + t.Errorf("could not set null") + } + if dummys.Set("test", nil); !dummys.Get("test").IsNull() { + t.Errorf("could not set nil") } } @@ -212,6 +253,18 @@ func TestSet(t *testing.T) { }) } +func TestDelete(t *testing.T) { + dummys.Set("test", 42) + dummys.Delete("test") + if dummys.Call("hasOwnProperty", "test").Bool() { + t.Errorf("property still exists") + } + + expectValueError(t, func() { + dummys.Get("zero").Delete("badField") + }) +} + func TestIndex(t *testing.T) { if got := dummys.Get("someArray").Index(1).Int(); got != 42 { t.Errorf("got %#v, want %#v", got, 42) @@ -328,7 +381,7 @@ func TestValueOf(t *testing.T) { func TestZeroValue(t *testing.T) { var v js.Value - if v != js.Undefined() { + if !v.IsUndefined() { t.Error("zero js.Value is not js.Undefined()") } } @@ -366,6 +419,25 @@ func TestInvokeFunction(t *testing.T) { } } +func TestInterleavedFunctions(t *testing.T) { + c1 := make(chan struct{}) + c2 := make(chan struct{}) + + js.Global().Get("setTimeout").Invoke(js.FuncOf(func(this js.Value, args []js.Value) interface{} { + c1 <- struct{}{} + <-c2 + return nil + }), 0) + + <-c1 + c2 <- struct{}{} + // this goroutine is running, but the callback of setTimeout did not return yet, invoke another function now + f := js.FuncOf(func(this js.Value, args []js.Value) interface{} { + return nil + }) + f.Invoke() +} + func ExampleFuncOf() { var cb js.Func cb = js.FuncOf(func(this js.Value, args []js.Value) interface{} { @@ -484,3 +556,38 @@ func TestCopyBytesToJS(t *testing.T) { }) } } + +func TestGarbageCollection(t *testing.T) { + before := js.JSGo.Get("_values").Length() + for i := 0; i < 1000; i++ { + _ = js.Global().Get("Object").New().Call("toString").String() + runtime.GC() + } + after := js.JSGo.Get("_values").Length() + if after-before > 500 { + t.Errorf("garbage collection ineffective") + } +} + +// BenchmarkDOM is a simple benchmark which emulates a webapp making DOM operations. +// It creates a div, and sets its id. Then searches by that id and sets some data. +// Finally it removes that div. +func BenchmarkDOM(b *testing.B) { + document := js.Global().Get("document") + if document.IsUndefined() { + b.Skip("Not a browser environment. Skipping.") + } + const data = "someString" + for i := 0; i < b.N; i++ { + div := document.Call("createElement", "div") + div.Call("setAttribute", "id", "myDiv") + document.Get("body").Call("appendChild", div) + myDiv := document.Call("getElementById", "myDiv") + myDiv.Set("innerHTML", data) + + if got, want := myDiv.Get("innerHTML").String(), data; got != want { + b.Errorf("got %s, want %s", got, want) + } + document.Get("body").Call("removeChild", div) + } +} diff --git a/libgo/go/syscall/lsf_linux.go b/libgo/go/syscall/lsf_linux.go index 16b702a9840..f38de620962 100644 --- a/libgo/go/syscall/lsf_linux.go +++ b/libgo/go/syscall/lsf_linux.go @@ -23,6 +23,8 @@ func LsfJump(code, k, jt, jf int) *SockFilter { // Deprecated: Use golang.org/x/net/bpf instead. func LsfSocket(ifindex, proto int) (int, error) { var lsall SockaddrLinklayer + // This is missing SOCK_CLOEXEC, but adding the flag + // could break callers. s, e := Socket(AF_PACKET, SOCK_RAW, proto) if e != nil { return 0, e @@ -46,7 +48,7 @@ type iflags struct { // Deprecated: Use golang.org/x/net/bpf instead. func SetLsfPromisc(name string, m bool) error { - s, e := Socket(AF_INET, SOCK_DGRAM, 0) + s, e := cloexecSocket(AF_INET, SOCK_DGRAM, 0) if e != nil { return e } diff --git a/libgo/go/syscall/net_js.go b/libgo/go/syscall/net_js.go index d5bf1f4f993..25f171bda87 100644 --- a/libgo/go/syscall/net_js.go +++ b/libgo/go/syscall/net_js.go @@ -42,7 +42,7 @@ const ( const ( _ = iota F_DUPFD_CLOEXEC - SYS_FCNTL = 500 // unsupported; same value as net_nacl.go + SYS_FCNTL = 500 // unsupported ) type Sockaddr interface { diff --git a/libgo/go/syscall/netlink_linux.go b/libgo/go/syscall/netlink_linux.go index 1cda8c7704e..0937ff797ad 100644 --- a/libgo/go/syscall/netlink_linux.go +++ b/libgo/go/syscall/netlink_linux.go @@ -50,7 +50,7 @@ func newNetlinkRouteRequest(proto, seq, family int) []byte { // NetlinkRIB returns routing information base, as known as RIB, which // consists of network facility information, states and parameters. func NetlinkRIB(proto, family int) ([]byte, error) { - s, err := Socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE) + s, err := cloexecSocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE) if err != nil { return nil, err } diff --git a/libgo/go/syscall/route_freebsd_64bit.go b/libgo/go/syscall/route_freebsd_64bit.go index 728837ebb5a..e70ba3df896 100644 --- a/libgo/go/syscall/route_freebsd_64bit.go +++ b/libgo/go/syscall/route_freebsd_64bit.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build freebsd,amd64 +// +build freebsd,amd64 freebsd,arm64 package syscall diff --git a/libgo/go/syscall/security_windows.go b/libgo/go/syscall/security_windows.go index db80d98a084..3a757596066 100644 --- a/libgo/go/syscall/security_windows.go +++ b/libgo/go/syscall/security_windows.go @@ -163,7 +163,7 @@ func (sid *SID) String() (string, error) { return "", e } defer LocalFree((Handle)(unsafe.Pointer(s))) - return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil + return utf16PtrToString(s, 256), nil } // Len returns the length, in bytes, of a valid security identifier sid. diff --git a/libgo/go/syscall/sock_cloexec_linux.go b/libgo/go/syscall/sock_cloexec_linux.go new file mode 100644 index 00000000000..600cf25c150 --- /dev/null +++ b/libgo/go/syscall/sock_cloexec_linux.go @@ -0,0 +1,29 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syscall + +// This is a stripped down version of sysSocket from net/sock_cloexec.go. +func cloexecSocket(family, sotype, proto int) (int, error) { + s, err := Socket(family, sotype|SOCK_CLOEXEC, proto) + switch err { + case nil: + return s, nil + default: + return -1, err + case EINVAL: + } + + ForkLock.RLock() + s, err = Socket(family, sotype, proto) + if err == nil { + CloseOnExec(s) + } + ForkLock.RUnlock() + if err != nil { + Close(s) + return -1, err + } + return s, nil +} diff --git a/libgo/go/syscall/sockcmsg_dragonfly.go b/libgo/go/syscall/sockcmsg_dragonfly.go new file mode 100644 index 00000000000..d217d9eed14 --- /dev/null +++ b/libgo/go/syscall/sockcmsg_dragonfly.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syscall + +// Round the length of a raw sockaddr up to align it properly. +func cmsgAlignOf(salen int) int { + salign := sizeofPtr + if sizeofPtr == 8 && !supportsABI(_dragonflyABIChangeVersion) { + // 64-bit Dragonfly before the September 2019 ABI changes still requires + // 32-bit aligned access to network subsystem. + salign = 4 + } + return (salen + salign - 1) & ^(salign - 1) +} diff --git a/libgo/go/syscall/sockcmsg_linux.go b/libgo/go/syscall/sockcmsg_linux.go index 4cb9075ba8c..d97667cf7e9 100644 --- a/libgo/go/syscall/sockcmsg_linux.go +++ b/libgo/go/syscall/sockcmsg_linux.go @@ -17,7 +17,7 @@ func UnixCredentials(ucred *Ucred) []byte { h.Level = SOL_SOCKET h.Type = SCM_CREDENTIALS h.SetLen(CmsgLen(SizeofUcred)) - *((*Ucred)(cmsgData(h))) = *ucred + *(*Ucred)(h.data(0)) = *ucred return b } diff --git a/libgo/go/syscall/sockcmsg_unix.go b/libgo/go/syscall/sockcmsg_unix.go index dd74417708e..6530bea5236 100644 --- a/libgo/go/syscall/sockcmsg_unix.go +++ b/libgo/go/syscall/sockcmsg_unix.go @@ -9,35 +9,9 @@ package syscall import ( - "runtime" "unsafe" ) -// Round the length of a raw sockaddr up to align it properly. -func cmsgAlignOf(salen int) int { - salign := int(sizeofPtr) - - switch runtime.GOOS { - case "aix": - // There is no alignment on AIX. - salign = 1 - case "darwin", "dragonfly", "illumos", "solaris": - // NOTE: It seems like 64-bit Darwin, DragonFly BSD and - // Solaris kernels still require 32-bit aligned access to - // network subsystem. - if sizeofPtr == 8 { - salign = 4 - } - case "netbsd", "openbsd": - // NetBSD and OpenBSD armv7 require 64-bit alignment. - if runtime.GOARCH == "arm" { - salign = 8 - } - } - - return (salen + salign - 1) & ^(salign - 1) -} - // CmsgLen returns the value to store in the Len field of the Cmsghdr // structure, taking into account any necessary alignment. func CmsgLen(datalen int) int { @@ -50,8 +24,8 @@ func CmsgSpace(datalen int) int { return cmsgAlignOf(SizeofCmsghdr) + cmsgAlignOf(datalen) } -func cmsgData(h *Cmsghdr) unsafe.Pointer { - return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr))) +func (h *Cmsghdr) data(offset uintptr) unsafe.Pointer { + return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(SizeofCmsghdr)) + offset) } // SocketControlMessage represents a socket control message. @@ -94,10 +68,8 @@ func UnixRights(fds ...int) []byte { h.Level = SOL_SOCKET h.Type = SCM_RIGHTS h.SetLen(CmsgLen(datalen)) - data := cmsgData(h) - for _, fd := range fds { - *(*int32)(data) = int32(fd) - data = unsafe.Pointer(uintptr(data) + 4) + for i, fd := range fds { + *(*int32)(h.data(4 * uintptr(i))) = int32(fd) } return b } diff --git a/libgo/go/syscall/sockcmsg_unix_other.go b/libgo/go/syscall/sockcmsg_unix_other.go new file mode 100644 index 00000000000..65d9f187c4e --- /dev/null +++ b/libgo/go/syscall/sockcmsg_unix_other.go @@ -0,0 +1,38 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build aix darwin freebsd linux netbsd openbsd solaris + +package syscall + +import ( + "runtime" +) + +// Round the length of a raw sockaddr up to align it properly. +func cmsgAlignOf(salen int) int { + salign := int(sizeofPtr) + + // dragonfly needs to check ABI version at runtime, see cmsgAlignOf in + // sockcmsg_dragonfly.go + switch runtime.GOOS { + case "aix": + // There is no alignment on AIX. + salign = 1 + case "darwin", "illumos", "solaris": + // NOTE: It seems like 64-bit Darwin, Illumos and Solaris + // kernels still require 32-bit aligned access to network + // subsystem. + if sizeofPtr == 8 { + salign = 4 + } + case "netbsd", "openbsd": + // NetBSD and OpenBSD armv7 require 64-bit alignment. + if runtime.GOARCH == "arm" { + salign = 8 + } + } + + return (salen + salign - 1) & ^(salign - 1) +} diff --git a/libgo/go/syscall/syscall.go b/libgo/go/syscall/syscall.go index 9b74afe4fe2..4e1187be0a2 100644 --- a/libgo/go/syscall/syscall.go +++ b/libgo/go/syscall/syscall.go @@ -28,7 +28,7 @@ package syscall import "unsafe" -//go:generate go run mksyscall_windows.go -systemdll -output zsyscall_windows.go syscall_windows.go security_windows.go +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -systemdll -output zsyscall_windows.go syscall_windows.go security_windows.go // StringByteSlice converts a string to a NUL-terminated []byte, // If s contains a NUL byte this function panics instead of diff --git a/libgo/go/syscall/syscall_aix.go b/libgo/go/syscall/syscall_aix.go index 231ff40500f..f4cac0185db 100644 --- a/libgo/go/syscall/syscall_aix.go +++ b/libgo/go/syscall/syscall_aix.go @@ -23,5 +23,9 @@ func direntReclen(buf []byte) (uint64, bool) { } func direntNamlen(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) + reclen, ok := direntReclen(buf) + if !ok { + return 0, false + } + return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true } diff --git a/libgo/go/syscall/syscall_dragonfly.go b/libgo/go/syscall/syscall_dragonfly.go index 3e6617cc6a6..930bb46ee3c 100644 --- a/libgo/go/syscall/syscall_dragonfly.go +++ b/libgo/go/syscall/syscall_dragonfly.go @@ -4,7 +4,25 @@ package syscall -import "unsafe" +import ( + "sync" + "unsafe" +) + +// See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h +var ( + osreldateOnce sync.Once + osreldate uint32 +) + +// First __DragonFly_version after September 2019 ABI changes +// http://lists.dragonflybsd.org/pipermail/users/2019-September/358280.html +const _dragonflyABIChangeVersion = 500705 + +func supportsABI(ver uint32) bool { + osreldateOnce.Do(func() { osreldate, _ = SysctlUint32("kern.osreldate") }) + return osreldate >= ver +} func direntIno(buf []byte) (uint64, bool) { return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno)) diff --git a/libgo/go/syscall/syscall_errno.go b/libgo/go/syscall/syscall_errno.go index a339ae82588..0d781decdb8 100644 --- a/libgo/go/syscall/syscall_errno.go +++ b/libgo/go/syscall/syscall_errno.go @@ -13,6 +13,12 @@ import "internal/oserror" // if errno != 0 { // err = errno // } +// +// Errno values can be tested against error values from the os package +// using errors.Is. For example: +// +// _, _, err := syscall.Syscall(...) +// if errors.Is(err, os.ErrNotExist) ... type Errno uintptr func (e Errno) Error() string { @@ -32,7 +38,7 @@ func (e Errno) Is(target error) bool { } func (e Errno) Temporary() bool { - return e == EINTR || e == EMFILE || e.Timeout() + return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout() } func (e Errno) Timeout() bool { diff --git a/libgo/go/syscall/syscall_freebsd_arm64.go b/libgo/go/syscall/syscall_freebsd_arm64.go new file mode 100644 index 00000000000..b561141a727 --- /dev/null +++ b/libgo/go/syscall/syscall_freebsd_arm64.go @@ -0,0 +1,33 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syscall + +import "unsafe" + +func setTimespec(sec, nsec int64) Timespec { + return Timespec{Sec: sec, Nsec: nsec} +} + +func setTimeval(sec, usec int64) Timeval { + return Timeval{Sec: sec, Usec: usec} +} + +func SetKevent(k *Kevent_t, fd, mode, flags int) { + k.Ident = uint64(fd) + k.Filter = int16(mode) + k.Flags = uint16(flags) +} + +func (iov *Iovec) SetLen(length int) { + iov.Len = uint64(length) +} + +func (msghdr *Msghdr) SetControllen(length int) { + msghdr.Controllen = uint32(length) +} + +func (cmsg *Cmsghdr) SetLen(length int) { + cmsg.Len = uint32(length) +} diff --git a/libgo/go/syscall/syscall_js.go b/libgo/go/syscall/syscall_js.go index 175fe47fcaa..dfb4a275e30 100644 --- a/libgo/go/syscall/syscall_js.go +++ b/libgo/go/syscall/syscall_js.go @@ -44,6 +44,12 @@ const PathMax = 256 // if errno != 0 { // err = errno // } +// +// Errno values can be tested against error values from the os package +// using errors.Is. For example: +// +// _, _, err := syscall.Syscall(...) +// if errors.Is(err, os.ErrNotExist) ... type Errno uintptr func (e Errno) Error() string { @@ -297,9 +303,10 @@ func Getegid() int { return jsProcess.Call("getegid").Int() } -func Getgroups() ([]int, error) { +func Getgroups() (groups []int, err error) { + defer recoverErr(&err) array := jsProcess.Call("getgroups") - groups := make([]int, array.Length()) + groups = make([]int, array.Length()) for i := range groups { groups[i] = array.Index(i).Int() } diff --git a/libgo/go/syscall/syscall_linux_riscv64.go b/libgo/go/syscall/syscall_linux_riscv64.go new file mode 100644 index 00000000000..e9aab94e3a1 --- /dev/null +++ b/libgo/go/syscall/syscall_linux_riscv64.go @@ -0,0 +1,23 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package syscall + +import "unsafe" + +func (r *PtraceRegs) PC() uint64 { return r.Pc } + +func (r *PtraceRegs) SetPC(pc uint64) { r.Pc = pc } + +func (iov *Iovec) SetLen(length int) { + iov.Len = uint64(length) +} + +func (msghdr *Msghdr) SetControllen(length int) { + msghdr.Controllen = uint64(length) +} + +func (cmsg *Cmsghdr) SetLen(length int) { + cmsg.Len = uint64(length) +} diff --git a/libgo/go/syscall/syscall_linux_test.go b/libgo/go/syscall/syscall_linux_test.go index 2ad236573e4..97059c87d3d 100644 --- a/libgo/go/syscall/syscall_linux_test.go +++ b/libgo/go/syscall/syscall_linux_test.go @@ -299,6 +299,14 @@ func TestSyscallNoError(t *testing.T) { t.Skip("skipping on non-32bit architecture") } + // See https://golang.org/issue/35422 + // On MIPS, Linux returns whether the syscall had an error in a separate + // register (R7), not using a negative return value as on other + // architectures. + if runtime.GOARCH == "mips" || runtime.GOARCH == "mipsle" { + t.Skipf("skipping on %s", runtime.GOARCH) + } + if os.Getuid() != 0 { t.Skip("skipping root only test") } @@ -367,7 +375,8 @@ func TestSyscallNoError(t *testing.T) { if filesystemIsNoSUID(tmpBinary) { t.Skip("skipping test when temp dir is mounted nosuid") } - t.Errorf("expected %s, got %s", want, got) + // formatted so the values are aligned for easier comparison + t.Errorf("expected %s,\ngot %s", want, got) } } diff --git a/libgo/go/syscall/syscall_test.go b/libgo/go/syscall/syscall_test.go index 2a9d90e64c6..5390f8aace9 100644 --- a/libgo/go/syscall/syscall_test.go +++ b/libgo/go/syscall/syscall_test.go @@ -62,7 +62,7 @@ func TestExecErrPermutedFds(t *testing.T) { } func TestGettimeofday(t *testing.T) { - if runtime.GOOS == "nacl" || runtime.GOOS == "js" { + if runtime.GOOS == "js" { t.Skip("not implemented on " + runtime.GOOS) } tv := &syscall.Timeval{} diff --git a/libgo/go/syscall/syscall_unix.go b/libgo/go/syscall/syscall_unix.go index 37999a2d83d..16e4d480b02 100644 --- a/libgo/go/syscall/syscall_unix.go +++ b/libgo/go/syscall/syscall_unix.go @@ -165,7 +165,14 @@ func Write(fd int, p []byte) (n int, err error) { if race.Enabled { race.ReleaseMerge(unsafe.Pointer(&ioSync)) } - n, err = write(fd, p) + if faketime && (fd == 1 || fd == 2) { + n = faketimeWrite(fd, p) + if n < 0 { + n, err = 0, errnoErr(Errno(-n)) + } + } else { + n, err = write(fd, p) + } if race.Enabled && n > 0 { race.ReadRange(unsafe.Pointer(&p[0]), n) } diff --git a/libgo/go/syscall/syscall_unix_test.go b/libgo/go/syscall/syscall_unix_test.go index da259b997f9..b99e07dd38b 100644 --- a/libgo/go/syscall/syscall_unix_test.go +++ b/libgo/go/syscall/syscall_unix_test.go @@ -386,3 +386,9 @@ func TestSetsockoptString(t *testing.T) { t.Fatalf("SetsockoptString: did not fail") } } + +func TestENFILETemporary(t *testing.T) { + if !syscall.ENFILE.Temporary() { + t.Error("ENFILE is not treated as a temporary error") + } +} diff --git a/libgo/go/syscall/tables_js.go b/libgo/go/syscall/tables_js.go new file mode 100644 index 00000000000..a7c4f8c890f --- /dev/null +++ b/libgo/go/syscall/tables_js.go @@ -0,0 +1,494 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build js,wasm + +package syscall + +import "runtime" + +// These were originally used by Nacl, then later also used by +// js/wasm. Now that they're only used by js/wasm, these numbers are +// just arbitrary. +// +// TODO: delete? replace with something meaningful? +const ( + sys_null = 1 + sys_nameservice = 2 + sys_dup = 8 + sys_dup2 = 9 + sys_open = 10 + sys_close = 11 + sys_read = 12 + sys_write = 13 + sys_lseek = 14 + sys_stat = 16 + sys_fstat = 17 + sys_chmod = 18 + sys_isatty = 19 + sys_brk = 20 + sys_mmap = 21 + sys_munmap = 22 + sys_getdents = 23 + sys_mprotect = 24 + sys_list_mappings = 25 + sys_exit = 30 + sys_getpid = 31 + sys_sched_yield = 32 + sys_sysconf = 33 + sys_gettimeofday = 40 + sys_clock = 41 + sys_nanosleep = 42 + sys_clock_getres = 43 + sys_clock_gettime = 44 + sys_mkdir = 45 + sys_rmdir = 46 + sys_chdir = 47 + sys_getcwd = 48 + sys_unlink = 49 + sys_imc_makeboundsock = 60 + sys_imc_accept = 61 + sys_imc_connect = 62 + sys_imc_sendmsg = 63 + sys_imc_recvmsg = 64 + sys_imc_mem_obj_create = 65 + sys_imc_socketpair = 66 + sys_mutex_create = 70 + sys_mutex_lock = 71 + sys_mutex_trylock = 72 + sys_mutex_unlock = 73 + sys_cond_create = 74 + sys_cond_wait = 75 + sys_cond_signal = 76 + sys_cond_broadcast = 77 + sys_cond_timed_wait_abs = 79 + sys_thread_create = 80 + sys_thread_exit = 81 + sys_tls_init = 82 + sys_thread_nice = 83 + sys_tls_get = 84 + sys_second_tls_set = 85 + sys_second_tls_get = 86 + sys_exception_handler = 87 + sys_exception_stack = 88 + sys_exception_clear_flag = 89 + sys_sem_create = 100 + sys_sem_wait = 101 + sys_sem_post = 102 + sys_sem_get_value = 103 + sys_dyncode_create = 104 + sys_dyncode_modify = 105 + sys_dyncode_delete = 106 + sys_test_infoleak = 109 + sys_test_crash = 110 + sys_test_syscall_1 = 111 + sys_test_syscall_2 = 112 + sys_futex_wait_abs = 120 + sys_futex_wake = 121 + sys_pread = 130 + sys_pwrite = 131 + sys_truncate = 140 + sys_lstat = 141 + sys_link = 142 + sys_rename = 143 + sys_symlink = 144 + sys_access = 145 + sys_readlink = 146 + sys_utimes = 147 + sys_get_random_bytes = 150 +) + +// TODO: Auto-generate some day. (Hard-coded in binaries so not likely to change.) +const ( + // native_client/src/trusted/service_runtime/include/sys/errno.h + // The errors are mainly copied from Linux. + EPERM Errno = 1 /* Operation not permitted */ + ENOENT Errno = 2 /* No such file or directory */ + ESRCH Errno = 3 /* No such process */ + EINTR Errno = 4 /* Interrupted system call */ + EIO Errno = 5 /* I/O error */ + ENXIO Errno = 6 /* No such device or address */ + E2BIG Errno = 7 /* Argument list too long */ + ENOEXEC Errno = 8 /* Exec format error */ + EBADF Errno = 9 /* Bad file number */ + ECHILD Errno = 10 /* No child processes */ + EAGAIN Errno = 11 /* Try again */ + ENOMEM Errno = 12 /* Out of memory */ + EACCES Errno = 13 /* Permission denied */ + EFAULT Errno = 14 /* Bad address */ + EBUSY Errno = 16 /* Device or resource busy */ + EEXIST Errno = 17 /* File exists */ + EXDEV Errno = 18 /* Cross-device link */ + ENODEV Errno = 19 /* No such device */ + ENOTDIR Errno = 20 /* Not a directory */ + EISDIR Errno = 21 /* Is a directory */ + EINVAL Errno = 22 /* Invalid argument */ + ENFILE Errno = 23 /* File table overflow */ + EMFILE Errno = 24 /* Too many open files */ + ENOTTY Errno = 25 /* Not a typewriter */ + EFBIG Errno = 27 /* File too large */ + ENOSPC Errno = 28 /* No space left on device */ + ESPIPE Errno = 29 /* Illegal seek */ + EROFS Errno = 30 /* Read-only file system */ + EMLINK Errno = 31 /* Too many links */ + EPIPE Errno = 32 /* Broken pipe */ + ENAMETOOLONG Errno = 36 /* File name too long */ + ENOSYS Errno = 38 /* Function not implemented */ + EDQUOT Errno = 122 /* Quota exceeded */ + EDOM Errno = 33 /* Math arg out of domain of func */ + ERANGE Errno = 34 /* Math result not representable */ + EDEADLK Errno = 35 /* Deadlock condition */ + ENOLCK Errno = 37 /* No record locks available */ + ENOTEMPTY Errno = 39 /* Directory not empty */ + ELOOP Errno = 40 /* Too many symbolic links */ + ENOMSG Errno = 42 /* No message of desired type */ + EIDRM Errno = 43 /* Identifier removed */ + ECHRNG Errno = 44 /* Channel number out of range */ + EL2NSYNC Errno = 45 /* Level 2 not synchronized */ + EL3HLT Errno = 46 /* Level 3 halted */ + EL3RST Errno = 47 /* Level 3 reset */ + ELNRNG Errno = 48 /* Link number out of range */ + EUNATCH Errno = 49 /* Protocol driver not attached */ + ENOCSI Errno = 50 /* No CSI structure available */ + EL2HLT Errno = 51 /* Level 2 halted */ + EBADE Errno = 52 /* Invalid exchange */ + EBADR Errno = 53 /* Invalid request descriptor */ + EXFULL Errno = 54 /* Exchange full */ + ENOANO Errno = 55 /* No anode */ + EBADRQC Errno = 56 /* Invalid request code */ + EBADSLT Errno = 57 /* Invalid slot */ + EDEADLOCK Errno = EDEADLK /* File locking deadlock error */ + EBFONT Errno = 59 /* Bad font file fmt */ + ENOSTR Errno = 60 /* Device not a stream */ + ENODATA Errno = 61 /* No data (for no delay io) */ + ETIME Errno = 62 /* Timer expired */ + ENOSR Errno = 63 /* Out of streams resources */ + ENONET Errno = 64 /* Machine is not on the network */ + ENOPKG Errno = 65 /* Package not installed */ + EREMOTE Errno = 66 /* The object is remote */ + ENOLINK Errno = 67 /* The link has been severed */ + EADV Errno = 68 /* Advertise error */ + ESRMNT Errno = 69 /* Srmount error */ + ECOMM Errno = 70 /* Communication error on send */ + EPROTO Errno = 71 /* Protocol error */ + EMULTIHOP Errno = 72 /* Multihop attempted */ + EDOTDOT Errno = 73 /* Cross mount point (not really error) */ + EBADMSG Errno = 74 /* Trying to read unreadable message */ + EOVERFLOW Errno = 75 /* Value too large for defined data type */ + ENOTUNIQ Errno = 76 /* Given log. name not unique */ + EBADFD Errno = 77 /* f.d. invalid for this operation */ + EREMCHG Errno = 78 /* Remote address changed */ + ELIBACC Errno = 79 /* Can't access a needed shared lib */ + ELIBBAD Errno = 80 /* Accessing a corrupted shared lib */ + ELIBSCN Errno = 81 /* .lib section in a.out corrupted */ + ELIBMAX Errno = 82 /* Attempting to link in too many libs */ + ELIBEXEC Errno = 83 /* Attempting to exec a shared library */ + EILSEQ Errno = 84 + EUSERS Errno = 87 + ENOTSOCK Errno = 88 /* Socket operation on non-socket */ + EDESTADDRREQ Errno = 89 /* Destination address required */ + EMSGSIZE Errno = 90 /* Message too long */ + EPROTOTYPE Errno = 91 /* Protocol wrong type for socket */ + ENOPROTOOPT Errno = 92 /* Protocol not available */ + EPROTONOSUPPORT Errno = 93 /* Unknown protocol */ + ESOCKTNOSUPPORT Errno = 94 /* Socket type not supported */ + EOPNOTSUPP Errno = 95 /* Operation not supported on transport endpoint */ + EPFNOSUPPORT Errno = 96 /* Protocol family not supported */ + EAFNOSUPPORT Errno = 97 /* Address family not supported by protocol family */ + EADDRINUSE Errno = 98 /* Address already in use */ + EADDRNOTAVAIL Errno = 99 /* Address not available */ + ENETDOWN Errno = 100 /* Network interface is not configured */ + ENETUNREACH Errno = 101 /* Network is unreachable */ + ENETRESET Errno = 102 + ECONNABORTED Errno = 103 /* Connection aborted */ + ECONNRESET Errno = 104 /* Connection reset by peer */ + ENOBUFS Errno = 105 /* No buffer space available */ + EISCONN Errno = 106 /* Socket is already connected */ + ENOTCONN Errno = 107 /* Socket is not connected */ + ESHUTDOWN Errno = 108 /* Can't send after socket shutdown */ + ETOOMANYREFS Errno = 109 + ETIMEDOUT Errno = 110 /* Connection timed out */ + ECONNREFUSED Errno = 111 /* Connection refused */ + EHOSTDOWN Errno = 112 /* Host is down */ + EHOSTUNREACH Errno = 113 /* Host is unreachable */ + EALREADY Errno = 114 /* Socket already connected */ + EINPROGRESS Errno = 115 /* Connection already in progress */ + ESTALE Errno = 116 + ENOTSUP Errno = EOPNOTSUPP /* Not supported */ + ENOMEDIUM Errno = 123 /* No medium (in tape drive) */ + ECANCELED Errno = 125 /* Operation canceled. */ + ELBIN Errno = 2048 /* Inode is remote (not really error) */ + EFTYPE Errno = 2049 /* Inappropriate file type or format */ + ENMFILE Errno = 2050 /* No more files */ + EPROCLIM Errno = 2051 + ENOSHARE Errno = 2052 /* No such host or network path */ + ECASECLASH Errno = 2053 /* Filename exists with different case */ + EWOULDBLOCK Errno = EAGAIN /* Operation would block */ +) + +// TODO: Auto-generate some day. (Hard-coded in binaries so not likely to change.) +var errorstr = [...]string{ + EPERM: "Operation not permitted", + ENOENT: "No such file or directory", + ESRCH: "No such process", + EINTR: "Interrupted system call", + EIO: "I/O error", + ENXIO: "No such device or address", + E2BIG: "Argument list too long", + ENOEXEC: "Exec format error", + EBADF: "Bad file number", + ECHILD: "No child processes", + EAGAIN: "Try again", + ENOMEM: "Out of memory", + EACCES: "Permission denied", + EFAULT: "Bad address", + EBUSY: "Device or resource busy", + EEXIST: "File exists", + EXDEV: "Cross-device link", + ENODEV: "No such device", + ENOTDIR: "Not a directory", + EISDIR: "Is a directory", + EINVAL: "Invalid argument", + ENFILE: "File table overflow", + EMFILE: "Too many open files", + ENOTTY: "Not a typewriter", + EFBIG: "File too large", + ENOSPC: "No space left on device", + ESPIPE: "Illegal seek", + EROFS: "Read-only file system", + EMLINK: "Too many links", + EPIPE: "Broken pipe", + ENAMETOOLONG: "File name too long", + ENOSYS: "not implemented on " + runtime.GOOS, + EDQUOT: "Quota exceeded", + EDOM: "Math arg out of domain of func", + ERANGE: "Math result not representable", + EDEADLK: "Deadlock condition", + ENOLCK: "No record locks available", + ENOTEMPTY: "Directory not empty", + ELOOP: "Too many symbolic links", + ENOMSG: "No message of desired type", + EIDRM: "Identifier removed", + ECHRNG: "Channel number out of range", + EL2NSYNC: "Level 2 not synchronized", + EL3HLT: "Level 3 halted", + EL3RST: "Level 3 reset", + ELNRNG: "Link number out of range", + EUNATCH: "Protocol driver not attached", + ENOCSI: "No CSI structure available", + EL2HLT: "Level 2 halted", + EBADE: "Invalid exchange", + EBADR: "Invalid request descriptor", + EXFULL: "Exchange full", + ENOANO: "No anode", + EBADRQC: "Invalid request code", + EBADSLT: "Invalid slot", + EBFONT: "Bad font file fmt", + ENOSTR: "Device not a stream", + ENODATA: "No data (for no delay io)", + ETIME: "Timer expired", + ENOSR: "Out of streams resources", + ENONET: "Machine is not on the network", + ENOPKG: "Package not installed", + EREMOTE: "The object is remote", + ENOLINK: "The link has been severed", + EADV: "Advertise error", + ESRMNT: "Srmount error", + ECOMM: "Communication error on send", + EPROTO: "Protocol error", + EMULTIHOP: "Multihop attempted", + EDOTDOT: "Cross mount point (not really error)", + EBADMSG: "Trying to read unreadable message", + EOVERFLOW: "Value too large for defined data type", + ENOTUNIQ: "Given log. name not unique", + EBADFD: "f.d. invalid for this operation", + EREMCHG: "Remote address changed", + ELIBACC: "Can't access a needed shared lib", + ELIBBAD: "Accessing a corrupted shared lib", + ELIBSCN: ".lib section in a.out corrupted", + ELIBMAX: "Attempting to link in too many libs", + ELIBEXEC: "Attempting to exec a shared library", + ENOTSOCK: "Socket operation on non-socket", + EDESTADDRREQ: "Destination address required", + EMSGSIZE: "Message too long", + EPROTOTYPE: "Protocol wrong type for socket", + ENOPROTOOPT: "Protocol not available", + EPROTONOSUPPORT: "Unknown protocol", + ESOCKTNOSUPPORT: "Socket type not supported", + EOPNOTSUPP: "Operation not supported on transport endpoint", + EPFNOSUPPORT: "Protocol family not supported", + EAFNOSUPPORT: "Address family not supported by protocol family", + EADDRINUSE: "Address already in use", + EADDRNOTAVAIL: "Address not available", + ENETDOWN: "Network interface is not configured", + ENETUNREACH: "Network is unreachable", + ECONNABORTED: "Connection aborted", + ECONNRESET: "Connection reset by peer", + ENOBUFS: "No buffer space available", + EISCONN: "Socket is already connected", + ENOTCONN: "Socket is not connected", + ESHUTDOWN: "Can't send after socket shutdown", + ETIMEDOUT: "Connection timed out", + ECONNREFUSED: "Connection refused", + EHOSTDOWN: "Host is down", + EHOSTUNREACH: "Host is unreachable", + EALREADY: "Socket already connected", + EINPROGRESS: "Connection already in progress", + ENOMEDIUM: "No medium (in tape drive)", + ECANCELED: "Operation canceled.", + ELBIN: "Inode is remote (not really error)", + EFTYPE: "Inappropriate file type or format", + ENMFILE: "No more files", + ENOSHARE: "No such host or network path", + ECASECLASH: "Filename exists with different case", +} + +// Do the interface allocations only once for common +// Errno values. +var ( + errEAGAIN error = EAGAIN + errEINVAL error = EINVAL + errENOENT error = ENOENT +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e Errno) error { + switch e { + case 0: + return nil + case EAGAIN: + return errEAGAIN + case EINVAL: + return errEINVAL + case ENOENT: + return errENOENT + } + return e +} + +var errnoByCode = map[string]Errno{ + "EPERM": EPERM, + "ENOENT": ENOENT, + "ESRCH": ESRCH, + "EINTR": EINTR, + "EIO": EIO, + "ENXIO": ENXIO, + "E2BIG": E2BIG, + "ENOEXEC": ENOEXEC, + "EBADF": EBADF, + "ECHILD": ECHILD, + "EAGAIN": EAGAIN, + "ENOMEM": ENOMEM, + "EACCES": EACCES, + "EFAULT": EFAULT, + "EBUSY": EBUSY, + "EEXIST": EEXIST, + "EXDEV": EXDEV, + "ENODEV": ENODEV, + "ENOTDIR": ENOTDIR, + "EISDIR": EISDIR, + "EINVAL": EINVAL, + "ENFILE": ENFILE, + "EMFILE": EMFILE, + "ENOTTY": ENOTTY, + "EFBIG": EFBIG, + "ENOSPC": ENOSPC, + "ESPIPE": ESPIPE, + "EROFS": EROFS, + "EMLINK": EMLINK, + "EPIPE": EPIPE, + "ENAMETOOLONG": ENAMETOOLONG, + "ENOSYS": ENOSYS, + "EDQUOT": EDQUOT, + "EDOM": EDOM, + "ERANGE": ERANGE, + "EDEADLK": EDEADLK, + "ENOLCK": ENOLCK, + "ENOTEMPTY": ENOTEMPTY, + "ELOOP": ELOOP, + "ENOMSG": ENOMSG, + "EIDRM": EIDRM, + "ECHRNG": ECHRNG, + "EL2NSYNC": EL2NSYNC, + "EL3HLT": EL3HLT, + "EL3RST": EL3RST, + "ELNRNG": ELNRNG, + "EUNATCH": EUNATCH, + "ENOCSI": ENOCSI, + "EL2HLT": EL2HLT, + "EBADE": EBADE, + "EBADR": EBADR, + "EXFULL": EXFULL, + "ENOANO": ENOANO, + "EBADRQC": EBADRQC, + "EBADSLT": EBADSLT, + "EDEADLOCK": EDEADLOCK, + "EBFONT": EBFONT, + "ENOSTR": ENOSTR, + "ENODATA": ENODATA, + "ETIME": ETIME, + "ENOSR": ENOSR, + "ENONET": ENONET, + "ENOPKG": ENOPKG, + "EREMOTE": EREMOTE, + "ENOLINK": ENOLINK, + "EADV": EADV, + "ESRMNT": ESRMNT, + "ECOMM": ECOMM, + "EPROTO": EPROTO, + "EMULTIHOP": EMULTIHOP, + "EDOTDOT": EDOTDOT, + "EBADMSG": EBADMSG, + "EOVERFLOW": EOVERFLOW, + "ENOTUNIQ": ENOTUNIQ, + "EBADFD": EBADFD, + "EREMCHG": EREMCHG, + "ELIBACC": ELIBACC, + "ELIBBAD": ELIBBAD, + "ELIBSCN": ELIBSCN, + "ELIBMAX": ELIBMAX, + "ELIBEXEC": ELIBEXEC, + "EILSEQ": EILSEQ, + "EUSERS": EUSERS, + "ENOTSOCK": ENOTSOCK, + "EDESTADDRREQ": EDESTADDRREQ, + "EMSGSIZE": EMSGSIZE, + "EPROTOTYPE": EPROTOTYPE, + "ENOPROTOOPT": ENOPROTOOPT, + "EPROTONOSUPPORT": EPROTONOSUPPORT, + "ESOCKTNOSUPPORT": ESOCKTNOSUPPORT, + "EOPNOTSUPP": EOPNOTSUPP, + "EPFNOSUPPORT": EPFNOSUPPORT, + "EAFNOSUPPORT": EAFNOSUPPORT, + "EADDRINUSE": EADDRINUSE, + "EADDRNOTAVAIL": EADDRNOTAVAIL, + "ENETDOWN": ENETDOWN, + "ENETUNREACH": ENETUNREACH, + "ENETRESET": ENETRESET, + "ECONNABORTED": ECONNABORTED, + "ECONNRESET": ECONNRESET, + "ENOBUFS": ENOBUFS, + "EISCONN": EISCONN, + "ENOTCONN": ENOTCONN, + "ESHUTDOWN": ESHUTDOWN, + "ETOOMANYREFS": ETOOMANYREFS, + "ETIMEDOUT": ETIMEDOUT, + "ECONNREFUSED": ECONNREFUSED, + "EHOSTDOWN": EHOSTDOWN, + "EHOSTUNREACH": EHOSTUNREACH, + "EALREADY": EALREADY, + "EINPROGRESS": EINPROGRESS, + "ESTALE": ESTALE, + "ENOTSUP": ENOTSUP, + "ENOMEDIUM": ENOMEDIUM, + "ECANCELED": ECANCELED, + "ELBIN": ELBIN, + "EFTYPE": EFTYPE, + "ENMFILE": ENMFILE, + "EPROCLIM": EPROCLIM, + "ENOSHARE": ENOSHARE, + "ECASECLASH": ECASECLASH, + "EWOULDBLOCK": EWOULDBLOCK, +} diff --git a/libgo/go/syscall/tables_nacljs.go b/libgo/go/syscall/tables_nacljs.go deleted file mode 100644 index 1c265f25c7a..00000000000 --- a/libgo/go/syscall/tables_nacljs.go +++ /dev/null @@ -1,490 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build nacl js,wasm - -package syscall - -import "runtime" - -// TODO: generate with runtime/mknacl.sh, allow override with IRT. -const ( - sys_null = 1 - sys_nameservice = 2 - sys_dup = 8 - sys_dup2 = 9 - sys_open = 10 - sys_close = 11 - sys_read = 12 - sys_write = 13 - sys_lseek = 14 - sys_stat = 16 - sys_fstat = 17 - sys_chmod = 18 - sys_isatty = 19 - sys_brk = 20 - sys_mmap = 21 - sys_munmap = 22 - sys_getdents = 23 - sys_mprotect = 24 - sys_list_mappings = 25 - sys_exit = 30 - sys_getpid = 31 - sys_sched_yield = 32 - sys_sysconf = 33 - sys_gettimeofday = 40 - sys_clock = 41 - sys_nanosleep = 42 - sys_clock_getres = 43 - sys_clock_gettime = 44 - sys_mkdir = 45 - sys_rmdir = 46 - sys_chdir = 47 - sys_getcwd = 48 - sys_unlink = 49 - sys_imc_makeboundsock = 60 - sys_imc_accept = 61 - sys_imc_connect = 62 - sys_imc_sendmsg = 63 - sys_imc_recvmsg = 64 - sys_imc_mem_obj_create = 65 - sys_imc_socketpair = 66 - sys_mutex_create = 70 - sys_mutex_lock = 71 - sys_mutex_trylock = 72 - sys_mutex_unlock = 73 - sys_cond_create = 74 - sys_cond_wait = 75 - sys_cond_signal = 76 - sys_cond_broadcast = 77 - sys_cond_timed_wait_abs = 79 - sys_thread_create = 80 - sys_thread_exit = 81 - sys_tls_init = 82 - sys_thread_nice = 83 - sys_tls_get = 84 - sys_second_tls_set = 85 - sys_second_tls_get = 86 - sys_exception_handler = 87 - sys_exception_stack = 88 - sys_exception_clear_flag = 89 - sys_sem_create = 100 - sys_sem_wait = 101 - sys_sem_post = 102 - sys_sem_get_value = 103 - sys_dyncode_create = 104 - sys_dyncode_modify = 105 - sys_dyncode_delete = 106 - sys_test_infoleak = 109 - sys_test_crash = 110 - sys_test_syscall_1 = 111 - sys_test_syscall_2 = 112 - sys_futex_wait_abs = 120 - sys_futex_wake = 121 - sys_pread = 130 - sys_pwrite = 131 - sys_truncate = 140 - sys_lstat = 141 - sys_link = 142 - sys_rename = 143 - sys_symlink = 144 - sys_access = 145 - sys_readlink = 146 - sys_utimes = 147 - sys_get_random_bytes = 150 -) - -// TODO: Auto-generate some day. (Hard-coded in binaries so not likely to change.) -const ( - // native_client/src/trusted/service_runtime/include/sys/errno.h - // The errors are mainly copied from Linux. - EPERM Errno = 1 /* Operation not permitted */ - ENOENT Errno = 2 /* No such file or directory */ - ESRCH Errno = 3 /* No such process */ - EINTR Errno = 4 /* Interrupted system call */ - EIO Errno = 5 /* I/O error */ - ENXIO Errno = 6 /* No such device or address */ - E2BIG Errno = 7 /* Argument list too long */ - ENOEXEC Errno = 8 /* Exec format error */ - EBADF Errno = 9 /* Bad file number */ - ECHILD Errno = 10 /* No child processes */ - EAGAIN Errno = 11 /* Try again */ - ENOMEM Errno = 12 /* Out of memory */ - EACCES Errno = 13 /* Permission denied */ - EFAULT Errno = 14 /* Bad address */ - EBUSY Errno = 16 /* Device or resource busy */ - EEXIST Errno = 17 /* File exists */ - EXDEV Errno = 18 /* Cross-device link */ - ENODEV Errno = 19 /* No such device */ - ENOTDIR Errno = 20 /* Not a directory */ - EISDIR Errno = 21 /* Is a directory */ - EINVAL Errno = 22 /* Invalid argument */ - ENFILE Errno = 23 /* File table overflow */ - EMFILE Errno = 24 /* Too many open files */ - ENOTTY Errno = 25 /* Not a typewriter */ - EFBIG Errno = 27 /* File too large */ - ENOSPC Errno = 28 /* No space left on device */ - ESPIPE Errno = 29 /* Illegal seek */ - EROFS Errno = 30 /* Read-only file system */ - EMLINK Errno = 31 /* Too many links */ - EPIPE Errno = 32 /* Broken pipe */ - ENAMETOOLONG Errno = 36 /* File name too long */ - ENOSYS Errno = 38 /* Function not implemented */ - EDQUOT Errno = 122 /* Quota exceeded */ - EDOM Errno = 33 /* Math arg out of domain of func */ - ERANGE Errno = 34 /* Math result not representable */ - EDEADLK Errno = 35 /* Deadlock condition */ - ENOLCK Errno = 37 /* No record locks available */ - ENOTEMPTY Errno = 39 /* Directory not empty */ - ELOOP Errno = 40 /* Too many symbolic links */ - ENOMSG Errno = 42 /* No message of desired type */ - EIDRM Errno = 43 /* Identifier removed */ - ECHRNG Errno = 44 /* Channel number out of range */ - EL2NSYNC Errno = 45 /* Level 2 not synchronized */ - EL3HLT Errno = 46 /* Level 3 halted */ - EL3RST Errno = 47 /* Level 3 reset */ - ELNRNG Errno = 48 /* Link number out of range */ - EUNATCH Errno = 49 /* Protocol driver not attached */ - ENOCSI Errno = 50 /* No CSI structure available */ - EL2HLT Errno = 51 /* Level 2 halted */ - EBADE Errno = 52 /* Invalid exchange */ - EBADR Errno = 53 /* Invalid request descriptor */ - EXFULL Errno = 54 /* Exchange full */ - ENOANO Errno = 55 /* No anode */ - EBADRQC Errno = 56 /* Invalid request code */ - EBADSLT Errno = 57 /* Invalid slot */ - EDEADLOCK Errno = EDEADLK /* File locking deadlock error */ - EBFONT Errno = 59 /* Bad font file fmt */ - ENOSTR Errno = 60 /* Device not a stream */ - ENODATA Errno = 61 /* No data (for no delay io) */ - ETIME Errno = 62 /* Timer expired */ - ENOSR Errno = 63 /* Out of streams resources */ - ENONET Errno = 64 /* Machine is not on the network */ - ENOPKG Errno = 65 /* Package not installed */ - EREMOTE Errno = 66 /* The object is remote */ - ENOLINK Errno = 67 /* The link has been severed */ - EADV Errno = 68 /* Advertise error */ - ESRMNT Errno = 69 /* Srmount error */ - ECOMM Errno = 70 /* Communication error on send */ - EPROTO Errno = 71 /* Protocol error */ - EMULTIHOP Errno = 72 /* Multihop attempted */ - EDOTDOT Errno = 73 /* Cross mount point (not really error) */ - EBADMSG Errno = 74 /* Trying to read unreadable message */ - EOVERFLOW Errno = 75 /* Value too large for defined data type */ - ENOTUNIQ Errno = 76 /* Given log. name not unique */ - EBADFD Errno = 77 /* f.d. invalid for this operation */ - EREMCHG Errno = 78 /* Remote address changed */ - ELIBACC Errno = 79 /* Can't access a needed shared lib */ - ELIBBAD Errno = 80 /* Accessing a corrupted shared lib */ - ELIBSCN Errno = 81 /* .lib section in a.out corrupted */ - ELIBMAX Errno = 82 /* Attempting to link in too many libs */ - ELIBEXEC Errno = 83 /* Attempting to exec a shared library */ - EILSEQ Errno = 84 - EUSERS Errno = 87 - ENOTSOCK Errno = 88 /* Socket operation on non-socket */ - EDESTADDRREQ Errno = 89 /* Destination address required */ - EMSGSIZE Errno = 90 /* Message too long */ - EPROTOTYPE Errno = 91 /* Protocol wrong type for socket */ - ENOPROTOOPT Errno = 92 /* Protocol not available */ - EPROTONOSUPPORT Errno = 93 /* Unknown protocol */ - ESOCKTNOSUPPORT Errno = 94 /* Socket type not supported */ - EOPNOTSUPP Errno = 95 /* Operation not supported on transport endpoint */ - EPFNOSUPPORT Errno = 96 /* Protocol family not supported */ - EAFNOSUPPORT Errno = 97 /* Address family not supported by protocol family */ - EADDRINUSE Errno = 98 /* Address already in use */ - EADDRNOTAVAIL Errno = 99 /* Address not available */ - ENETDOWN Errno = 100 /* Network interface is not configured */ - ENETUNREACH Errno = 101 /* Network is unreachable */ - ENETRESET Errno = 102 - ECONNABORTED Errno = 103 /* Connection aborted */ - ECONNRESET Errno = 104 /* Connection reset by peer */ - ENOBUFS Errno = 105 /* No buffer space available */ - EISCONN Errno = 106 /* Socket is already connected */ - ENOTCONN Errno = 107 /* Socket is not connected */ - ESHUTDOWN Errno = 108 /* Can't send after socket shutdown */ - ETOOMANYREFS Errno = 109 - ETIMEDOUT Errno = 110 /* Connection timed out */ - ECONNREFUSED Errno = 111 /* Connection refused */ - EHOSTDOWN Errno = 112 /* Host is down */ - EHOSTUNREACH Errno = 113 /* Host is unreachable */ - EALREADY Errno = 114 /* Socket already connected */ - EINPROGRESS Errno = 115 /* Connection already in progress */ - ESTALE Errno = 116 - ENOTSUP Errno = EOPNOTSUPP /* Not supported */ - ENOMEDIUM Errno = 123 /* No medium (in tape drive) */ - ECANCELED Errno = 125 /* Operation canceled. */ - ELBIN Errno = 2048 /* Inode is remote (not really error) */ - EFTYPE Errno = 2049 /* Inappropriate file type or format */ - ENMFILE Errno = 2050 /* No more files */ - EPROCLIM Errno = 2051 - ENOSHARE Errno = 2052 /* No such host or network path */ - ECASECLASH Errno = 2053 /* Filename exists with different case */ - EWOULDBLOCK Errno = EAGAIN /* Operation would block */ -) - -// TODO: Auto-generate some day. (Hard-coded in binaries so not likely to change.) -var errorstr = [...]string{ - EPERM: "Operation not permitted", - ENOENT: "No such file or directory", - ESRCH: "No such process", - EINTR: "Interrupted system call", - EIO: "I/O error", - ENXIO: "No such device or address", - E2BIG: "Argument list too long", - ENOEXEC: "Exec format error", - EBADF: "Bad file number", - ECHILD: "No child processes", - EAGAIN: "Try again", - ENOMEM: "Out of memory", - EACCES: "Permission denied", - EFAULT: "Bad address", - EBUSY: "Device or resource busy", - EEXIST: "File exists", - EXDEV: "Cross-device link", - ENODEV: "No such device", - ENOTDIR: "Not a directory", - EISDIR: "Is a directory", - EINVAL: "Invalid argument", - ENFILE: "File table overflow", - EMFILE: "Too many open files", - ENOTTY: "Not a typewriter", - EFBIG: "File too large", - ENOSPC: "No space left on device", - ESPIPE: "Illegal seek", - EROFS: "Read-only file system", - EMLINK: "Too many links", - EPIPE: "Broken pipe", - ENAMETOOLONG: "File name too long", - ENOSYS: "not implemented on " + runtime.GOOS, - EDQUOT: "Quota exceeded", - EDOM: "Math arg out of domain of func", - ERANGE: "Math result not representable", - EDEADLK: "Deadlock condition", - ENOLCK: "No record locks available", - ENOTEMPTY: "Directory not empty", - ELOOP: "Too many symbolic links", - ENOMSG: "No message of desired type", - EIDRM: "Identifier removed", - ECHRNG: "Channel number out of range", - EL2NSYNC: "Level 2 not synchronized", - EL3HLT: "Level 3 halted", - EL3RST: "Level 3 reset", - ELNRNG: "Link number out of range", - EUNATCH: "Protocol driver not attached", - ENOCSI: "No CSI structure available", - EL2HLT: "Level 2 halted", - EBADE: "Invalid exchange", - EBADR: "Invalid request descriptor", - EXFULL: "Exchange full", - ENOANO: "No anode", - EBADRQC: "Invalid request code", - EBADSLT: "Invalid slot", - EBFONT: "Bad font file fmt", - ENOSTR: "Device not a stream", - ENODATA: "No data (for no delay io)", - ETIME: "Timer expired", - ENOSR: "Out of streams resources", - ENONET: "Machine is not on the network", - ENOPKG: "Package not installed", - EREMOTE: "The object is remote", - ENOLINK: "The link has been severed", - EADV: "Advertise error", - ESRMNT: "Srmount error", - ECOMM: "Communication error on send", - EPROTO: "Protocol error", - EMULTIHOP: "Multihop attempted", - EDOTDOT: "Cross mount point (not really error)", - EBADMSG: "Trying to read unreadable message", - EOVERFLOW: "Value too large for defined data type", - ENOTUNIQ: "Given log. name not unique", - EBADFD: "f.d. invalid for this operation", - EREMCHG: "Remote address changed", - ELIBACC: "Can't access a needed shared lib", - ELIBBAD: "Accessing a corrupted shared lib", - ELIBSCN: ".lib section in a.out corrupted", - ELIBMAX: "Attempting to link in too many libs", - ELIBEXEC: "Attempting to exec a shared library", - ENOTSOCK: "Socket operation on non-socket", - EDESTADDRREQ: "Destination address required", - EMSGSIZE: "Message too long", - EPROTOTYPE: "Protocol wrong type for socket", - ENOPROTOOPT: "Protocol not available", - EPROTONOSUPPORT: "Unknown protocol", - ESOCKTNOSUPPORT: "Socket type not supported", - EOPNOTSUPP: "Operation not supported on transport endpoint", - EPFNOSUPPORT: "Protocol family not supported", - EAFNOSUPPORT: "Address family not supported by protocol family", - EADDRINUSE: "Address already in use", - EADDRNOTAVAIL: "Address not available", - ENETDOWN: "Network interface is not configured", - ENETUNREACH: "Network is unreachable", - ECONNABORTED: "Connection aborted", - ECONNRESET: "Connection reset by peer", - ENOBUFS: "No buffer space available", - EISCONN: "Socket is already connected", - ENOTCONN: "Socket is not connected", - ESHUTDOWN: "Can't send after socket shutdown", - ETIMEDOUT: "Connection timed out", - ECONNREFUSED: "Connection refused", - EHOSTDOWN: "Host is down", - EHOSTUNREACH: "Host is unreachable", - EALREADY: "Socket already connected", - EINPROGRESS: "Connection already in progress", - ENOMEDIUM: "No medium (in tape drive)", - ECANCELED: "Operation canceled.", - ELBIN: "Inode is remote (not really error)", - EFTYPE: "Inappropriate file type or format", - ENMFILE: "No more files", - ENOSHARE: "No such host or network path", - ECASECLASH: "Filename exists with different case", -} - -// Do the interface allocations only once for common -// Errno values. -var ( - errEAGAIN error = EAGAIN - errEINVAL error = EINVAL - errENOENT error = ENOENT -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e Errno) error { - switch e { - case 0: - return nil - case EAGAIN: - return errEAGAIN - case EINVAL: - return errEINVAL - case ENOENT: - return errENOENT - } - return e -} - -var errnoByCode = map[string]Errno{ - "EPERM": EPERM, - "ENOENT": ENOENT, - "ESRCH": ESRCH, - "EINTR": EINTR, - "EIO": EIO, - "ENXIO": ENXIO, - "E2BIG": E2BIG, - "ENOEXEC": ENOEXEC, - "EBADF": EBADF, - "ECHILD": ECHILD, - "EAGAIN": EAGAIN, - "ENOMEM": ENOMEM, - "EACCES": EACCES, - "EFAULT": EFAULT, - "EBUSY": EBUSY, - "EEXIST": EEXIST, - "EXDEV": EXDEV, - "ENODEV": ENODEV, - "ENOTDIR": ENOTDIR, - "EISDIR": EISDIR, - "EINVAL": EINVAL, - "ENFILE": ENFILE, - "EMFILE": EMFILE, - "ENOTTY": ENOTTY, - "EFBIG": EFBIG, - "ENOSPC": ENOSPC, - "ESPIPE": ESPIPE, - "EROFS": EROFS, - "EMLINK": EMLINK, - "EPIPE": EPIPE, - "ENAMETOOLONG": ENAMETOOLONG, - "ENOSYS": ENOSYS, - "EDQUOT": EDQUOT, - "EDOM": EDOM, - "ERANGE": ERANGE, - "EDEADLK": EDEADLK, - "ENOLCK": ENOLCK, - "ENOTEMPTY": ENOTEMPTY, - "ELOOP": ELOOP, - "ENOMSG": ENOMSG, - "EIDRM": EIDRM, - "ECHRNG": ECHRNG, - "EL2NSYNC": EL2NSYNC, - "EL3HLT": EL3HLT, - "EL3RST": EL3RST, - "ELNRNG": ELNRNG, - "EUNATCH": EUNATCH, - "ENOCSI": ENOCSI, - "EL2HLT": EL2HLT, - "EBADE": EBADE, - "EBADR": EBADR, - "EXFULL": EXFULL, - "ENOANO": ENOANO, - "EBADRQC": EBADRQC, - "EBADSLT": EBADSLT, - "EDEADLOCK": EDEADLOCK, - "EBFONT": EBFONT, - "ENOSTR": ENOSTR, - "ENODATA": ENODATA, - "ETIME": ETIME, - "ENOSR": ENOSR, - "ENONET": ENONET, - "ENOPKG": ENOPKG, - "EREMOTE": EREMOTE, - "ENOLINK": ENOLINK, - "EADV": EADV, - "ESRMNT": ESRMNT, - "ECOMM": ECOMM, - "EPROTO": EPROTO, - "EMULTIHOP": EMULTIHOP, - "EDOTDOT": EDOTDOT, - "EBADMSG": EBADMSG, - "EOVERFLOW": EOVERFLOW, - "ENOTUNIQ": ENOTUNIQ, - "EBADFD": EBADFD, - "EREMCHG": EREMCHG, - "ELIBACC": ELIBACC, - "ELIBBAD": ELIBBAD, - "ELIBSCN": ELIBSCN, - "ELIBMAX": ELIBMAX, - "ELIBEXEC": ELIBEXEC, - "EILSEQ": EILSEQ, - "EUSERS": EUSERS, - "ENOTSOCK": ENOTSOCK, - "EDESTADDRREQ": EDESTADDRREQ, - "EMSGSIZE": EMSGSIZE, - "EPROTOTYPE": EPROTOTYPE, - "ENOPROTOOPT": ENOPROTOOPT, - "EPROTONOSUPPORT": EPROTONOSUPPORT, - "ESOCKTNOSUPPORT": ESOCKTNOSUPPORT, - "EOPNOTSUPP": EOPNOTSUPP, - "EPFNOSUPPORT": EPFNOSUPPORT, - "EAFNOSUPPORT": EAFNOSUPPORT, - "EADDRINUSE": EADDRINUSE, - "EADDRNOTAVAIL": EADDRNOTAVAIL, - "ENETDOWN": ENETDOWN, - "ENETUNREACH": ENETUNREACH, - "ENETRESET": ENETRESET, - "ECONNABORTED": ECONNABORTED, - "ECONNRESET": ECONNRESET, - "ENOBUFS": ENOBUFS, - "EISCONN": EISCONN, - "ENOTCONN": ENOTCONN, - "ESHUTDOWN": ESHUTDOWN, - "ETOOMANYREFS": ETOOMANYREFS, - "ETIMEDOUT": ETIMEDOUT, - "ECONNREFUSED": ECONNREFUSED, - "EHOSTDOWN": EHOSTDOWN, - "EHOSTUNREACH": EHOSTUNREACH, - "EALREADY": EALREADY, - "EINPROGRESS": EINPROGRESS, - "ESTALE": ESTALE, - "ENOTSUP": ENOTSUP, - "ENOMEDIUM": ENOMEDIUM, - "ECANCELED": ECANCELED, - "ELBIN": ELBIN, - "EFTYPE": EFTYPE, - "ENMFILE": ENMFILE, - "EPROCLIM": EPROCLIM, - "ENOSHARE": ENOSHARE, - "ECASECLASH": ECASECLASH, - "EWOULDBLOCK": EWOULDBLOCK, -} diff --git a/libgo/go/syscall/time_fake.go b/libgo/go/syscall/time_fake.go new file mode 100644 index 00000000000..5dec57a25ac --- /dev/null +++ b/libgo/go/syscall/time_fake.go @@ -0,0 +1,26 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build faketime + +package syscall + +import "unsafe" + +const faketime = true + +// When faketime is enabled, we redirect writes to FDs 1 and 2 through +// the runtime's write function, since that adds the framing that +// reports the emulated time. + +//go:linkname runtimeWrite runtime.write +func runtimeWrite(fd uintptr, p unsafe.Pointer, n int32) int32 + +func faketimeWrite(fd int, p []byte) int { + var pp *byte + if len(p) > 0 { + pp = &p[0] + } + return int(runtimeWrite(uintptr(fd), unsafe.Pointer(pp), int32(len(p)))) +} diff --git a/libgo/go/syscall/time_nofake.go b/libgo/go/syscall/time_nofake.go new file mode 100644 index 00000000000..c94cef86862 --- /dev/null +++ b/libgo/go/syscall/time_nofake.go @@ -0,0 +1,14 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !faketime + +package syscall + +const faketime = false + +func faketimeWrite(fd int, p []byte) int { + // This should never be called since faketime is false. + panic("not implemented") +} diff --git a/libgo/go/syscall/timestruct.go b/libgo/go/syscall/timestruct.go index e2b770425f5..bd0b3deb523 100644 --- a/libgo/go/syscall/timestruct.go +++ b/libgo/go/syscall/timestruct.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package syscall // TimespecToNsec converts a Timespec value into a number of // nanoseconds since the Unix epoch. -func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } +func TimespecToNsec(ts Timespec) int64 { return ts.Nano() } // NsecToTimespec takes a number of nanoseconds since the Unix epoch // and returns the corresponding Timespec value. @@ -24,7 +24,7 @@ func NsecToTimespec(nsec int64) Timespec { // TimevalToNsec converts a Timeval value into a number of nanoseconds // since the Unix epoch. -func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } +func TimevalToNsec(tv Timeval) int64 { return tv.Nano() } // NsecToTimeval takes a number of nanoseconds since the Unix epoch // and returns the corresponding Timeval value. diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go index 0e348be3583..04127727c11 100644 --- a/libgo/go/testing/benchmark.go +++ b/libgo/go/testing/benchmark.go @@ -69,8 +69,8 @@ var benchmarkLock sync.Mutex // Used for every benchmark for measuring memory. var memStats runtime.MemStats -// An internal type but exported because it is cross-package; part of the implementation -// of the "go test" command. +// InternalBenchmark is an internal type but exported because it is cross-package; +// it is part of the implementation of the "go test" command. type InternalBenchmark struct { Name string F func(b *B) @@ -342,7 +342,7 @@ func (b *B) ReportMetric(n float64, unit string) { b.extra[unit] = n } -// The results of a benchmark run. +// BenchmarkResult contains the results of a benchmark run. type BenchmarkResult struct { N int // The number of iterations. T time.Duration // The total time taken. @@ -488,8 +488,8 @@ type benchContext struct { extLen int // Maximum extension length. } -// An internal function but exported because it is cross-package; part of the implementation -// of the "go test" command. +// RunBenchmarks is an internal function but exported because it is cross-package; +// it is part of the implementation of the "go test" command. func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) { runBenchmarks("", matchString, benchmarks) } @@ -545,7 +545,11 @@ func (ctx *benchContext) processBench(b *B) { for j := uint(0); j < *count; j++ { runtime.GOMAXPROCS(procs) benchName := benchmarkName(b.name, procs) - fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName) + + // If it's chatty, we've already printed this information. + if !b.chatty { + fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName) + } // Recompute the running time for all but the first iteration. if i > 0 || j > 0 { b = &B{ @@ -569,6 +573,9 @@ func (ctx *benchContext) processBench(b *B) { continue } results := r.String() + if b.chatty { + fmt.Fprintf(b.w, "%-*s\t", ctx.maxLen, benchName) + } if *benchmarkMemory || b.showAllocResult { results += "\t" + r.MemString() } @@ -627,6 +634,19 @@ func (b *B) Run(name string, f func(b *B)) bool { // Only process sub-benchmarks, if any. atomic.StoreInt32(&sub.hasSub, 1) } + + if b.chatty { + labelsOnce.Do(func() { + fmt.Printf("goos: %s\n", runtime.GOOS) + fmt.Printf("goarch: %s\n", runtime.GOARCH) + if b.importPath != "" { + fmt.Printf("pkg: %s\n", b.importPath) + } + }) + + fmt.Println(benchName) + } + if sub.run1() { sub.run() } diff --git a/libgo/go/testing/example.go b/libgo/go/testing/example.go index c122121289d..adc91d5faf6 100644 --- a/libgo/go/testing/example.go +++ b/libgo/go/testing/example.go @@ -19,8 +19,8 @@ type InternalExample struct { Unordered bool } -// An internal function but exported because it is cross-package; part of the implementation -// of the "go test" command. +// RunExamples is an internal function but exported because it is cross-package; +// it is part of the implementation of the "go test" command. func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) { _, ok = runExamples(matchString, examples) return ok diff --git a/libgo/go/testing/iotest/logger_test.go b/libgo/go/testing/iotest/logger_test.go new file mode 100644 index 00000000000..c121bf48f7c --- /dev/null +++ b/libgo/go/testing/iotest/logger_test.go @@ -0,0 +1,160 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package iotest + +import ( + "bytes" + "errors" + "fmt" + "log" + "testing" +) + +type errWriter struct { + err error +} + +func (w errWriter) Write([]byte) (int, error) { + return 0, w.err +} + +func TestWriteLogger(t *testing.T) { + olw := log.Writer() + olf := log.Flags() + olp := log.Prefix() + + // Revert the original log settings before we exit. + defer func() { + log.SetFlags(olf) + log.SetPrefix(olp) + log.SetOutput(olw) + }() + + lOut := new(bytes.Buffer) + log.SetPrefix("lw: ") + log.SetOutput(lOut) + log.SetFlags(0) + + lw := new(bytes.Buffer) + wl := NewWriteLogger("write:", lw) + if _, err := wl.Write([]byte("Hello, World!")); err != nil { + t.Fatalf("Unexpectedly failed to write: %v", err) + } + + if g, w := lw.String(), "Hello, World!"; g != w { + t.Errorf("WriteLogger mismatch\n\tgot: %q\n\twant: %q", g, w) + } + wantLogWithHex := fmt.Sprintf("lw: write: %x\n", "Hello, World!") + if g, w := lOut.String(), wantLogWithHex; g != w { + t.Errorf("WriteLogger mismatch\n\tgot: %q\n\twant: %q", g, w) + } +} + +func TestWriteLogger_errorOnWrite(t *testing.T) { + olw := log.Writer() + olf := log.Flags() + olp := log.Prefix() + + // Revert the original log settings before we exit. + defer func() { + log.SetFlags(olf) + log.SetPrefix(olp) + log.SetOutput(olw) + }() + + lOut := new(bytes.Buffer) + log.SetPrefix("lw: ") + log.SetOutput(lOut) + log.SetFlags(0) + + lw := errWriter{err: errors.New("Write Error!")} + wl := NewWriteLogger("write:", lw) + if _, err := wl.Write([]byte("Hello, World!")); err == nil { + t.Fatalf("Unexpectedly succeeded to write: %v", err) + } + + wantLogWithHex := fmt.Sprintf("lw: write: %x: %v\n", "", "Write Error!") + if g, w := lOut.String(), wantLogWithHex; g != w { + t.Errorf("WriteLogger mismatch\n\tgot: %q\n\twant: %q", g, w) + } +} + +type errReader struct { + err error +} + +func (r errReader) Read([]byte) (int, error) { + return 0, r.err +} + +func TestReadLogger(t *testing.T) { + olw := log.Writer() + olf := log.Flags() + olp := log.Prefix() + + // Revert the original log settings before we exit. + defer func() { + log.SetFlags(olf) + log.SetPrefix(olp) + log.SetOutput(olw) + }() + + lOut := new(bytes.Buffer) + log.SetPrefix("lr: ") + log.SetOutput(lOut) + log.SetFlags(0) + + data := []byte("Hello, World!") + p := make([]byte, len(data)) + lr := bytes.NewReader(data) + rl := NewReadLogger("read:", lr) + + n, err := rl.Read(p) + if err != nil { + t.Fatalf("Unexpectedly failed to read: %v", err) + } + + if g, w := p[:n], data; !bytes.Equal(g, w) { + t.Errorf("ReadLogger mismatch\n\tgot: %q\n\twant: %q", g, w) + } + + wantLogWithHex := fmt.Sprintf("lr: read: %x\n", "Hello, World!") + if g, w := lOut.String(), wantLogWithHex; g != w { + t.Errorf("ReadLogger mismatch\n\tgot: %q\n\twant: %q", g, w) + } +} + +func TestReadLogger_errorOnRead(t *testing.T) { + olw := log.Writer() + olf := log.Flags() + olp := log.Prefix() + + // Revert the original log settings before we exit. + defer func() { + log.SetFlags(olf) + log.SetPrefix(olp) + log.SetOutput(olw) + }() + + lOut := new(bytes.Buffer) + log.SetPrefix("lr: ") + log.SetOutput(lOut) + log.SetFlags(0) + + data := []byte("Hello, World!") + p := make([]byte, len(data)) + + lr := errReader{err: errors.New("Read Error!")} + rl := NewReadLogger("read", lr) + n, err := rl.Read(p) + if err == nil { + t.Fatalf("Unexpectedly succeeded to read: %v", err) + } + + wantLogWithHex := fmt.Sprintf("lr: read %x: %v\n", p[:n], "Read Error!") + if g, w := lOut.String(), wantLogWithHex; g != w { + t.Errorf("ReadLogger mismatch\n\tgot: %q\n\twant: %q", g, w) + } +} diff --git a/libgo/go/testing/iotest/reader_test.go b/libgo/go/testing/iotest/reader_test.go new file mode 100644 index 00000000000..9397837e08a --- /dev/null +++ b/libgo/go/testing/iotest/reader_test.go @@ -0,0 +1,226 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package iotest + +import ( + "bytes" + "io" + "testing" +) + +func TestOneByteReader_nonEmptyReader(t *testing.T) { + msg := "Hello, World!" + buf := new(bytes.Buffer) + buf.WriteString(msg) + + obr := OneByteReader(buf) + var b []byte + n, err := obr.Read(b) + if err != nil || n != 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + + b = make([]byte, 3) + // Read from obr until EOF. + got := new(bytes.Buffer) + for i := 0; ; i++ { + n, err = obr.Read(b) + if err != nil { + break + } + if g, w := n, 1; g != w { + t.Errorf("Iteration #%d read %d bytes, want %d", i, g, w) + } + got.Write(b[:n]) + } + if g, w := err, io.EOF; g != w { + t.Errorf("Unexpected error after reading all bytes\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := got.String(), "Hello, World!"; g != w { + t.Errorf("Read mismatch\n\tGot: %q\n\tWant: %q", g, w) + } +} + +func TestOneByteReader_emptyReader(t *testing.T) { + r := new(bytes.Buffer) + + obr := OneByteReader(r) + var b []byte + if n, err := obr.Read(b); err != nil || n != 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + + b = make([]byte, 5) + n, err := obr.Read(b) + if g, w := err, io.EOF; g != w { + t.Errorf("Error mismatch\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := n, 0; g != w { + t.Errorf("Unexpectedly read %d bytes, wanted %d", g, w) + } +} + +func TestHalfReader_nonEmptyReader(t *testing.T) { + msg := "Hello, World!" + buf := new(bytes.Buffer) + buf.WriteString(msg) + // empty read buffer + hr := HalfReader(buf) + var b []byte + n, err := hr.Read(b) + if err != nil || n != 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + // non empty read buffer + b = make([]byte, 2) + got := new(bytes.Buffer) + for i := 0; ; i++ { + n, err = hr.Read(b) + if err != nil { + break + } + if g, w := n, 1; g != w { + t.Errorf("Iteration #%d read %d bytes, want %d", i, g, w) + } + got.Write(b[:n]) + } + if g, w := err, io.EOF; g != w { + t.Errorf("Unexpected error after reading all bytes\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := got.String(), "Hello, World!"; g != w { + t.Errorf("Read mismatch\n\tGot: %q\n\tWant: %q", g, w) + } +} + +func TestHalfReader_emptyReader(t *testing.T) { + r := new(bytes.Buffer) + + hr := HalfReader(r) + var b []byte + if n, err := hr.Read(b); err != nil || n != 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + + b = make([]byte, 5) + n, err := hr.Read(b) + if g, w := err, io.EOF; g != w { + t.Errorf("Error mismatch\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := n, 0; g != w { + t.Errorf("Unexpectedly read %d bytes, wanted %d", g, w) + } +} + +func TestTimeOutReader_nonEmptyReader(t *testing.T) { + msg := "Hello, World!" + buf := new(bytes.Buffer) + buf.WriteString(msg) + // empty read buffer + tor := TimeoutReader(buf) + var b []byte + n, err := tor.Read(b) + if err != nil || n != 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + // Second call should timeout + n, err = tor.Read(b) + if g, w := err, ErrTimeout; g != w { + t.Errorf("Error mismatch\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := n, 0; g != w { + t.Errorf("Unexpectedly read %d bytes, wanted %d", g, w) + } + // non empty read buffer + tor2 := TimeoutReader(buf) + b = make([]byte, 3) + if n, err := tor2.Read(b); err != nil || n == 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + // Second call should timeout + n, err = tor2.Read(b) + if g, w := err, ErrTimeout; g != w { + t.Errorf("Error mismatch\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := n, 0; g != w { + t.Errorf("Unexpectedly read %d bytes, wanted %d", g, w) + } +} + +func TestTimeOutReader_emptyReader(t *testing.T) { + r := new(bytes.Buffer) + // empty read buffer + tor := TimeoutReader(r) + var b []byte + if n, err := tor.Read(b); err != nil || n != 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + // Second call should timeout + n, err := tor.Read(b) + if g, w := err, ErrTimeout; g != w { + t.Errorf("Error mismatch\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := n, 0; g != w { + t.Errorf("Unexpectedly read %d bytes, wanted %d", g, w) + } + // non empty read buffer + tor2 := TimeoutReader(r) + b = make([]byte, 5) + if n, err := tor2.Read(b); err != io.EOF || n != 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + // Second call should timeout + n, err = tor2.Read(b) + if g, w := err, ErrTimeout; g != w { + t.Errorf("Error mismatch\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := n, 0; g != w { + t.Errorf("Unexpectedly read %d bytes, wanted %d", g, w) + } +} + +func TestDataErrReader_nonEmptyReader(t *testing.T) { + msg := "Hello, World!" + buf := new(bytes.Buffer) + buf.WriteString(msg) + + der := DataErrReader(buf) + + b := make([]byte, 3) + got := new(bytes.Buffer) + var n int + var err error + for { + n, err = der.Read(b) + got.Write(b[:n]) + if err != nil { + break + } + } + if err != io.EOF || n == 0 { + t.Errorf("Last Read returned n=%d err=%v", n, err) + } + if g, w := got.String(), "Hello, World!"; g != w { + t.Errorf("Read mismatch\n\tGot: %q\n\tWant: %q", g, w) + } +} + +func TestDataErrReader_emptyReader(t *testing.T) { + r := new(bytes.Buffer) + + der := DataErrReader(r) + var b []byte + if n, err := der.Read(b); err != io.EOF || n != 0 { + t.Errorf("Empty buffer read returned n=%d err=%v", n, err) + } + + b = make([]byte, 5) + n, err := der.Read(b) + if g, w := err, io.EOF; g != w { + t.Errorf("Error mismatch\n\tGot: %v\n\tWant: %v", g, w) + } + if g, w := n, 0; g != w { + t.Errorf("Unexpectedly read %d bytes, wanted %d", g, w) + } +} diff --git a/libgo/go/testing/iotest/writer_test.go b/libgo/go/testing/iotest/writer_test.go new file mode 100644 index 00000000000..5aaa77cc74c --- /dev/null +++ b/libgo/go/testing/iotest/writer_test.go @@ -0,0 +1,39 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package iotest + +import ( + "bytes" + "testing" +) + +var truncateWriterTests = []struct { + in string + want string + trunc int64 + n int +}{ + {"hello", "", -1, 5}, + {"world", "", 0, 5}, + {"abcde", "abc", 3, 5}, + {"edcba", "edcba", 7, 5}, +} + +func TestTruncateWriter(t *testing.T) { + for _, tt := range truncateWriterTests { + buf := new(bytes.Buffer) + tw := TruncateWriter(buf, tt.trunc) + n, err := tw.Write([]byte(tt.in)) + if err != nil { + t.Errorf("Unexpected error %v for\n\t%+v", err, tt) + } + if g, w := buf.String(), tt.want; g != w { + t.Errorf("got %q, expected %q", g, w) + } + if g, w := n, tt.n; g != w { + t.Errorf("read %d bytes, but expected to have read %d bytes for\n\t%+v", g, w, tt) + } + } +} diff --git a/libgo/go/testing/panic_test.go b/libgo/go/testing/panic_test.go new file mode 100644 index 00000000000..3491510b81c --- /dev/null +++ b/libgo/go/testing/panic_test.go @@ -0,0 +1,83 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testing_test + +import ( + "flag" + "fmt" + "internal/testenv" + "os" + "os/exec" + "regexp" + "strings" + "testing" +) + +var testPanicTest = flag.String("test_panic_test", "", "TestPanic: indicates which test should panic") + +func TestPanic(t *testing.T) { + testenv.MustHaveExec(t) + + testCases := []struct { + desc string + flags []string + want string + }{{ + desc: "root test panics", + flags: []string{"-test_panic_test=TestPanicHelper"}, + want: ` +--- FAIL: TestPanicHelper (N.NNs) + panic_test.go:NNN: TestPanicHelper +`, + }, { + desc: "subtest panics", + flags: []string{"-test_panic_test=TestPanicHelper/1"}, + want: ` +--- FAIL: TestPanicHelper (N.NNs) + panic_test.go:NNN: TestPanicHelper + --- FAIL: TestPanicHelper/1 (N.NNs) + panic_test.go:NNN: TestPanicHelper/1 +`, + }} + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + cmd := exec.Command(os.Args[0], "-test.run=TestPanicHelper") + cmd.Args = append(cmd.Args, tc.flags...) + cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1") + b, _ := cmd.CombinedOutput() + got := string(b) + want := strings.TrimSpace(tc.want) + re := makeRegexp(want) + if ok, err := regexp.MatchString(re, got); !ok || err != nil { + t.Errorf("output:\ngot:\n%s\nwant:\n%s", got, want) + } + }) + } +} + +func makeRegexp(s string) string { + s = regexp.QuoteMeta(s) + s = strings.ReplaceAll(s, ":NNN:", `:\d+:`) + s = strings.ReplaceAll(s, "N\\.NNs", `\d*\.\d*s`) + return s +} + +func TestPanicHelper(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { + return + } + t.Log(t.Name()) + if t.Name() == *testPanicTest { + panic("panic") + } + for i := 0; i < 3; i++ { + t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { + t.Log(t.Name()) + if t.Name() == *testPanicTest { + panic("panic") + } + }) + } +} diff --git a/libgo/go/testing/sub_test.go b/libgo/go/testing/sub_test.go index cc5dd2f3cfb..3f0f71f647d 100644 --- a/libgo/go/testing/sub_test.go +++ b/libgo/go/testing/sub_test.go @@ -7,6 +7,7 @@ package testing import ( "bytes" "fmt" + "reflect" "regexp" "runtime" "strings" @@ -434,6 +435,31 @@ func TestTRun(t *T) { <-ch t.Errorf("error") }, + }, { + // A chatty test should always log with fmt.Print, even if the + // parent test has completed. + // TODO(deklerk) Capture the log of fmt.Print and assert that the + // subtest message is not lost. + desc: "log in finished sub test with chatty", + ok: false, + chatty: true, + output: ` + --- FAIL: log in finished sub test with chatty (N.NNs)`, + maxPar: 1, + f: func(t *T) { + ch := make(chan bool) + t.Run("sub", func(t2 *T) { + go func() { + <-ch + t2.Log("message1") + ch <- true + }() + }) + t.Log("message2") + ch <- true + <-ch + t.Errorf("error") + }, }} for _, tc := range testCases { ctx := newTestContext(tc.maxPar, newMatcher(regexp.MatchString, "", "")) @@ -521,13 +547,6 @@ func TestBRun(t *T) { chatty: true, output: "--- SKIP: root", f: func(b *B) { b.SkipNow() }, - }, { - desc: "skipping with message, chatty", - chatty: true, - output: ` ---- SKIP: root - sub_test.go:NNN: skipping`, - f: func(b *B) { b.Skip("skipping") }, }, { desc: "chatty with recursion", chatty: true, @@ -772,3 +791,67 @@ func TestBenchmark(t *T) { t.Errorf("want >5ms; got %v", time.Duration(res.NsPerOp())) } } + +func TestCleanup(t *T) { + var cleanups []int + t.Run("test", func(t *T) { + t.Cleanup(func() { cleanups = append(cleanups, 1) }) + t.Cleanup(func() { cleanups = append(cleanups, 2) }) + }) + if got, want := cleanups, []int{2, 1}; !reflect.DeepEqual(got, want) { + t.Errorf("unexpected cleanup record; got %v want %v", got, want) + } +} + +func TestConcurrentCleanup(t *T) { + cleanups := 0 + t.Run("test", func(t *T) { + done := make(chan struct{}) + for i := 0; i < 2; i++ { + i := i + go func() { + t.Cleanup(func() { + cleanups |= 1 << i + }) + done <- struct{}{} + }() + } + <-done + <-done + }) + if cleanups != 1|2 { + t.Errorf("unexpected cleanup; got %d want 3", cleanups) + } +} + +func TestCleanupCalledEvenAfterGoexit(t *T) { + cleanups := 0 + t.Run("test", func(t *T) { + t.Cleanup(func() { + cleanups++ + }) + t.Cleanup(func() { + runtime.Goexit() + }) + }) + if cleanups != 1 { + t.Errorf("unexpected cleanup count; got %d want 1", cleanups) + } +} + +func TestRunCleanup(t *T) { + outerCleanup := 0 + innerCleanup := 0 + t.Run("test", func(t *T) { + t.Cleanup(func() { outerCleanup++ }) + t.Run("x", func(t *T) { + t.Cleanup(func() { innerCleanup++ }) + }) + }) + if innerCleanup != 1 { + t.Errorf("unexpected inner cleanup count; got %d want 1", innerCleanup) + } + if outerCleanup != 1 { + t.Errorf("unexpected outer cleanup count; got %d want 0", outerCleanup) + } +} diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go index 6ab9b791961..e05314e85fa 100644 --- a/libgo/go/testing/testing.go +++ b/libgo/go/testing/testing.go @@ -99,7 +99,7 @@ // line order: // // func ExamplePerm() { -// for _, value := range Perm(4) { +// for _, value := range Perm(5) { // fmt.Println(value) // } // // Unordered output: 4 @@ -344,6 +344,7 @@ type common struct { skipped bool // Test of benchmark has been skipped. done bool // Test is finished and all subtests have completed. helpers map[string]struct{} // functions to be skipped when writing file/line info + cleanup func() // optional function to be called at the end of the test chatty bool // A copy of the chatty flag. finished bool // Test function has completed. @@ -479,6 +480,9 @@ func (c *common) decorate(s string, skip int) string { buf := new(strings.Builder) // Every line is indented at least 4 spaces. buf.WriteString(" ") + if c.chatty { + fmt.Fprintf(buf, "%s: ", c.name) + } fmt.Fprintf(buf, "%s:%d: ", file, line) lines := strings.Split(s, "\n") if l := len(lines); l > 1 && lines[l-1] == "" { @@ -540,6 +544,7 @@ func fmtDuration(d time.Duration) string { // TB is the interface common to T and B. type TB interface { + Cleanup(func()) Error(args ...interface{}) Errorf(format string, args ...interface{}) Fail() @@ -547,6 +552,7 @@ type TB interface { Failed() bool Fatal(args ...interface{}) Fatalf(format string, args ...interface{}) + Helper() Log(args ...interface{}) Logf(format string, args ...interface{}) Name() string @@ -554,7 +560,6 @@ type TB interface { SkipNow() Skipf(format string, args ...interface{}) Skipped() bool - Helper() // A private method to prevent users implementing the // interface and so future additions to it will not @@ -662,9 +667,7 @@ func (c *common) log(s string) { func (c *common) logDepth(s string, depth int) { c.mu.Lock() defer c.mu.Unlock() - if !c.done { - c.output = append(c.output, c.decorate(s, depth+1)...) - } else { + if c.done { // This test has already finished. Try and log this message // with our parent. If we don't have a parent, panic. for parent := c.parent; parent != nil; parent = parent.parent { @@ -676,9 +679,21 @@ func (c *common) logDepth(s string, depth int) { } } panic("Log in goroutine after " + c.name + " has completed") + } else { + if c.chatty { + fmt.Print(c.decorate(s, depth+1)) + return + } + c.output = append(c.output, c.decorate(s, depth+1)...) } } +// This is needed for gccgo to get the tests to pass, because +// runtime.Callers doesn't correctly handle skips that land in the +// middle of a sequence of inlined functions. +// This shouldn't make any difference for normal use. +//go:noinline + // Log formats its arguments using default formatting, analogous to Println, // and records the text in the error log. For tests, the text will be printed only if // the test fails or the -test.v flag is set. For benchmarks, the text is always @@ -692,30 +707,60 @@ func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) } // depend on the value of the -test.v flag. func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) } +// This is needed for gccgo to get the tests to pass, because +// runtime.Callers doesn't correctly handle skips that land in the +// middle of a sequence of inlined functions. +// This shouldn't make any difference for normal use. +//go:noinline + // Error is equivalent to Log followed by Fail. func (c *common) Error(args ...interface{}) { c.log(fmt.Sprintln(args...)) c.Fail() } +// This is needed for gccgo to get the tests to pass, because +// runtime.Callers doesn't correctly handle skips that land in the +// middle of a sequence of inlined functions. +// This shouldn't make any difference for normal use. +//go:noinline + // Errorf is equivalent to Logf followed by Fail. func (c *common) Errorf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) c.Fail() } +// This is needed for gccgo to get the tests to pass, because +// runtime.Callers doesn't correctly handle skips that land in the +// middle of a sequence of inlined functions. +// This shouldn't make any difference for normal use. +//go:noinline + // Fatal is equivalent to Log followed by FailNow. func (c *common) Fatal(args ...interface{}) { c.log(fmt.Sprintln(args...)) c.FailNow() } +// This is needed for gccgo to get the tests to pass, because +// runtime.Callers doesn't correctly handle skips that land in the +// middle of a sequence of inlined functions. +// This shouldn't make any difference for normal use. +//go:noinline + // Fatalf is equivalent to Logf followed by FailNow. func (c *common) Fatalf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) c.FailNow() } +// This is needed for gccgo to get the tests to pass, because +// runtime.Callers doesn't correctly handle skips that land in the +// middle of a sequence of inlined functions. +// This shouldn't make any difference for normal use. +//go:noinline + // Skip is equivalent to Log followed by SkipNow. func (c *common) Skip(args ...interface{}) { c.log(fmt.Sprintln(args...)) @@ -767,11 +812,37 @@ func (c *common) Helper() { c.helpers[callerName(1)] = struct{}{} } +// Cleanup registers a function to be called when the test finishes. +// Cleanup functions will be called in last added, first called +// order. +func (c *common) Cleanup(f func()) { + c.mu.Lock() + defer c.mu.Unlock() + oldCleanup := c.cleanup + c.cleanup = func() { + if oldCleanup != nil { + defer oldCleanup() + } + f() + } +} + +// runCleanup is called at the end of the test. +func (c *common) runCleanup() { + c.mu.Lock() + cleanup := c.cleanup + c.cleanup = nil + c.mu.Unlock() + if cleanup != nil { + cleanup() + } +} + // callerName gives the function name (qualified with a package path) // for the caller after skip frames (where 0 means the current function). func callerName(skip int) string { // Make room for the skip PC. - var pc [1]uintptr + var pc [2]uintptr n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerName if n == 0 { panic("testing: zero callers found") @@ -828,8 +899,8 @@ func (t *T) Parallel() { t.raceErrors += -race.Errors() } -// An internal type but exported because it is cross-package; part of the implementation -// of the "go test" command. +// InternalTest is an internal type but exported because it is cross-package; +// it is part of the implementation of the "go test" command. type InternalTest struct { Name string F func(*T) @@ -853,7 +924,6 @@ func tRunner(t *T, fn func(t *T)) { t.Errorf("race detected during execution of test") } - t.duration += time.Since(t.start) // If the test panicked, print any test output before dying. err := recover() signal := true @@ -870,10 +940,20 @@ func tRunner(t *T, fn func(t *T)) { } if err != nil { t.Fail() - t.report() + // Flush the output log up to the root before dying. + t.mu.Lock() + root := &t.common + for ; root.parent != nil; root = root.parent { + root.duration += time.Since(root.start) + fmt.Fprintf(root.parent.w, "--- FAIL: %s (%s)\n", root.name, fmtDuration(root.duration)) + root.parent.mu.Lock() + io.Copy(root.parent.w, bytes.NewReader(root.output)) + } panic(err) } + t.duration += time.Since(t.start) + if len(t.sub) > 0 { // Run parallel subtests. // Decrease the running count for this test. @@ -903,6 +983,7 @@ func tRunner(t *T, fn func(t *T)) { } t.signal <- signal }() + defer t.runCleanup() t.start = time.Now() t.raceErrors = -race.Errors() @@ -1169,8 +1250,8 @@ func listTests(matchString func(pat, str string) (bool, error), tests []Internal } } -// An internal function but exported because it is cross-package; part of the implementation -// of the "go test" command. +// RunTests is an internal function but exported because it is cross-package; +// it is part of the implementation of the "go test" command. func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) { ran, ok := runTests(matchString, tests) if !ran && !haveExamples { diff --git a/libgo/go/text/template/doc.go b/libgo/go/text/template/doc.go index dbffaa49580..4b0efd2df87 100644 --- a/libgo/go/text/template/doc.go +++ b/libgo/go/text/template/doc.go @@ -102,8 +102,8 @@ data, defined in detail in the corresponding sections that follow. If the value of the pipeline has length zero, nothing is output; otherwise, dot is set to the successive elements of the array, slice, or map and T1 is executed. If the value is a map and the - keys are of basic type with a defined order ("comparable"), the - elements will be visited in sorted key order. + keys are of basic type with a defined order, the elements will be + visited in sorted key order. {{range pipeline}} T1 {{else}} T0 {{end}} The value of the pipeline must be an array, slice, map, or channel. @@ -385,14 +385,12 @@ returning in effect (Unlike with || in Go, however, eq is a function call and all the arguments will be evaluated.) -The comparison functions work on basic types only (or named basic -types, such as "type Celsius float32"). They implement the Go rules -for comparison of values, except that size and exact type are -ignored, so any integer value, signed or unsigned, may be compared -with any other integer value. (The arithmetic value is compared, -not the bit pattern, so all negative integers are less than all -unsigned integers.) However, as usual, one may not compare an int -with a float32 and so on. +The comparison functions work on any values whose type Go defines as +comparable. For basic types such as integers, the rules are relaxed: +size and exact type are ignored, so any integer value, signed or unsigned, +may be compared with any other integer value. (The arithmetic value is compared, +not the bit pattern, so all negative integers are less than all unsigned integers.) +However, as usual, one may not compare an int with a float32 and so on. Associated templates diff --git a/libgo/go/text/template/exec.go b/libgo/go/text/template/exec.go index 6d2e5ec4762..df2c4457af8 100644 --- a/libgo/go/text/template/exec.go +++ b/libgo/go/text/template/exec.go @@ -5,7 +5,6 @@ package template import ( - "bytes" "fmt" "internal/fmtsort" "io" @@ -232,21 +231,19 @@ func (t *Template) DefinedTemplates() string { if t.common == nil { return "" } - var b bytes.Buffer + var b strings.Builder for name, tmpl := range t.tmpl { if tmpl.Tree == nil || tmpl.Root == nil { continue } - if b.Len() > 0 { + if b.Len() == 0 { + b.WriteString("; defined templates are: ") + } else { b.WriteString(", ") } fmt.Fprintf(&b, "%q", name) } - var s string - if b.Len() > 0 { - s = "; defined templates are: " + b.String() - } - return s + return b.String() } // Walk functions step through the major pieces of the template structure, @@ -466,7 +463,8 @@ func (s *state) evalCommand(dot reflect.Value, cmd *parse.CommandNode, final ref // Must be a function. return s.evalFunction(dot, n, cmd, cmd.Args, final) case *parse.PipeNode: - // Parenthesized pipeline. The arguments are all inside the pipeline; final is ignored. + // Parenthesized pipeline. The arguments are all inside the pipeline; final must be absent. + s.notAFunction(cmd.Args, final) return s.evalPipeline(dot, n) case *parse.VariableNode: return s.evalVariableNode(dot, n, cmd.Args, final) @@ -501,20 +499,29 @@ func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value { switch { case constant.IsComplex: return reflect.ValueOf(constant.Complex128) // incontrovertible. - case constant.IsFloat && !isHexInt(constant.Text) && strings.ContainsAny(constant.Text, ".eEpP"): + + case constant.IsFloat && + !isHexInt(constant.Text) && !isRuneInt(constant.Text) && + strings.ContainsAny(constant.Text, ".eEpP"): return reflect.ValueOf(constant.Float64) + case constant.IsInt: n := int(constant.Int64) if int64(n) != constant.Int64 { s.errorf("%s overflows int", constant.Text) } return reflect.ValueOf(n) + case constant.IsUint: s.errorf("%s overflows int", constant.Text) } return zero } +func isRuneInt(s string) bool { + return len(s) > 0 && s[0] == '\'' +} + func isHexInt(s string) bool { return len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') && !strings.ContainsAny(s, "pP") } diff --git a/libgo/go/text/template/exec_test.go b/libgo/go/text/template/exec_test.go index a7d3f39f9ab..c64b83511a2 100644 --- a/libgo/go/text/template/exec_test.go +++ b/libgo/go/text/template/exec_test.go @@ -352,6 +352,12 @@ var execTests = []execTest{ {"field on interface", "{{.foo}}", "", nil, true}, {"field on parenthesized interface", "{{(.).foo}}", "", nil, true}, + // Issue 31810: Parenthesized first element of pipeline with arguments. + // See also TestIssue31810. + {"unparenthesized non-function", "{{1 2}}", "", nil, false}, + {"parenthesized non-function", "{{(1) 2}}", "", nil, false}, + {"parenthesized non-function with no args", "{{(1)}}", "1", nil, true}, // This is fine. + // Method calls. {".Method0", "-{{.Method0}}-", "-M0-", tVal, true}, {".Method1(1234)", "-{{.Method1 1234}}-", "-1234-", tVal, true}, @@ -663,6 +669,12 @@ var execTests = []execTest{ {"bug17c", "{{len .NonEmptyInterfacePtS}}", "2", tVal, true}, {"bug17d", "{{index .NonEmptyInterfacePtS 0}}", "a", tVal, true}, {"bug17e", "{{range .NonEmptyInterfacePtS}}-{{.}}-{{end}}", "-a--b-", tVal, true}, + + // More variadic function corner cases. Some runes would get evaluated + // as constant floats instead of ints. Issue 34483. + {"bug18a", "{{eq . '.'}}", "true", '.', true}, + {"bug18b", "{{eq . 'e'}}", "true", 'e', true}, + {"bug18c", "{{eq . 'P'}}", "true", 'P', true}, } func zeroArgs() string { @@ -897,6 +909,8 @@ func TestJSEscaping(t *testing.T) { {`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`}, {"unprintable \uFDFF", `unprintable \uFDFF`}, {``, `\x3Chtml\x3E`}, + {`no = in attributes`, `no \x3D in attributes`}, + {`' does not become HTML entity`, `\x26#x27; does not become HTML entity`}, } for _, tc := range testCases { s := JSEscapeString(tc.in) @@ -1156,19 +1170,41 @@ var cmpTests = []cmpTest{ {"ge .Uthree .NegOne", "true", true}, {"eq (index `x` 0) 'x'", "true", true}, // The example that triggered this rule. {"eq (index `x` 0) 'y'", "false", true}, + {"eq .V1 .V2", "true", true}, + {"eq .Ptr .Ptr", "true", true}, + {"eq .Ptr .NilPtr", "false", true}, + {"eq .NilPtr .NilPtr", "true", true}, + {"eq .Iface1 .Iface1", "true", true}, + {"eq .Iface1 .Iface2", "false", true}, + {"eq .Iface2 .Iface2", "true", true}, // Errors - {"eq `xy` 1", "", false}, // Different types. - {"eq 2 2.0", "", false}, // Different types. - {"lt true true", "", false}, // Unordered types. - {"lt 1+0i 1+0i", "", false}, // Unordered types. + {"eq `xy` 1", "", false}, // Different types. + {"eq 2 2.0", "", false}, // Different types. + {"lt true true", "", false}, // Unordered types. + {"lt 1+0i 1+0i", "", false}, // Unordered types. + {"eq .Ptr 1", "", false}, // Incompatible types. + {"eq .Ptr .NegOne", "", false}, // Incompatible types. + {"eq .Map .Map", "", false}, // Uncomparable types. + {"eq .Map .V1", "", false}, // Uncomparable types. } func TestComparison(t *testing.T) { b := new(bytes.Buffer) var cmpStruct = struct { - Uthree, Ufour uint - NegOne, Three int - }{3, 4, -1, 3} + Uthree, Ufour uint + NegOne, Three int + Ptr, NilPtr *int + Map map[int]int + V1, V2 V + Iface1, Iface2 fmt.Stringer + }{ + Uthree: 3, + Ufour: 4, + NegOne: -1, + Three: 3, + Ptr: new(int), + Iface1: b, + } for _, test := range cmpTests { text := fmt.Sprintf("{{if %s}}true{{else}}false{{end}}", test.expr) tmpl, err := New("empty").Parse(text) @@ -1620,3 +1656,41 @@ func TestExecutePanicDuringCall(t *testing.T) { } } } + +// Issue 31810. Check that a parenthesized first argument behaves properly. +func TestIssue31810(t *testing.T) { + // A simple value with no arguments is fine. + var b bytes.Buffer + const text = "{{ (.) }}" + tmpl, err := New("").Parse(text) + if err != nil { + t.Error(err) + } + err = tmpl.Execute(&b, "result") + if err != nil { + t.Error(err) + } + if b.String() != "result" { + t.Errorf("%s got %q, expected %q", text, b.String(), "result") + } + + // Even a plain function fails - need to use call. + f := func() string { return "result" } + b.Reset() + err = tmpl.Execute(&b, f) + if err == nil { + t.Error("expected error with no call, got none") + } + + // Works if the function is explicitly called. + const textCall = "{{ (call .) }}" + tmpl, err = New("").Parse(textCall) + b.Reset() + err = tmpl.Execute(&b, f) + if err != nil { + t.Error(err) + } + if b.String() != "result" { + t.Errorf("%s got %q, expected %q", textCall, b.String(), "result") + } +} diff --git a/libgo/go/text/template/funcs.go b/libgo/go/text/template/funcs.go index 248dbcf22ed..0568c798a84 100644 --- a/libgo/go/text/template/funcs.go +++ b/libgo/go/text/template/funcs.go @@ -441,19 +441,18 @@ func basicKind(v reflect.Value) (kind, error) { // eq evaluates the comparison a == b || a == c || ... func eq(arg1 reflect.Value, arg2 ...reflect.Value) (bool, error) { v1 := indirectInterface(arg1) - k1, err := basicKind(v1) - if err != nil { - return false, err + if v1 != zero { + if t1 := v1.Type(); !t1.Comparable() { + return false, fmt.Errorf("uncomparable type %s: %v", t1, v1) + } } if len(arg2) == 0 { return false, errNoComparison } + k1, _ := basicKind(v1) for _, arg := range arg2 { v2 := indirectInterface(arg) - k2, err := basicKind(v2) - if err != nil { - return false, err - } + k2, _ := basicKind(v2) truth := false if k1 != k2 { // Special case: Can compare integer values regardless of type's sign. @@ -480,7 +479,14 @@ func eq(arg1 reflect.Value, arg2 ...reflect.Value) (bool, error) { case uintKind: truth = v1.Uint() == v2.Uint() default: - panic("invalid kind") + if v2 == zero { + truth = v1 == v2 + } else { + if t2 := v2.Type(); !t2.Comparable() { + return false, fmt.Errorf("uncomparable type %s: %v", t2, v2) + } + truth = v1.Interface() == v2.Interface() + } } } if truth { @@ -636,6 +642,8 @@ var ( jsQuot = []byte(`\"`) jsLt = []byte(`\x3C`) jsGt = []byte(`\x3E`) + jsAmp = []byte(`\x26`) + jsEq = []byte(`\x3D`) ) // JSEscape writes to w the escaped JavaScript equivalent of the plain text data b. @@ -664,6 +672,10 @@ func JSEscape(w io.Writer, b []byte) { w.Write(jsLt) case '>': w.Write(jsGt) + case '&': + w.Write(jsAmp) + case '=': + w.Write(jsEq) default: w.Write(jsLowUni) t, b := c>>4, c&0x0f @@ -698,7 +710,7 @@ func JSEscapeString(s string) string { func jsIsSpecial(r rune) bool { switch r { - case '\\', '\'', '"', '<', '>': + case '\\', '\'', '"', '<', '>', '&', '=': return true } return r < ' ' || utf8.RuneSelf <= r diff --git a/libgo/go/text/template/parse/node.go b/libgo/go/text/template/parse/node.go index 1174a4b9706..1c116ea6fab 100644 --- a/libgo/go/text/template/parse/node.go +++ b/libgo/go/text/template/parse/node.go @@ -7,7 +7,6 @@ package parse import ( - "bytes" "fmt" "strconv" "strings" @@ -29,6 +28,8 @@ type Node interface { // tree returns the containing *Tree. // It is unexported so all implementations of Node are in this package. tree() *Tree + // writeTo writes the String output to the builder. + writeTo(*strings.Builder) } // NodeType identifies the type of a parse tree node. @@ -94,11 +95,15 @@ func (l *ListNode) tree() *Tree { } func (l *ListNode) String() string { - b := new(bytes.Buffer) + var sb strings.Builder + l.writeTo(&sb) + return sb.String() +} + +func (l *ListNode) writeTo(sb *strings.Builder) { for _, n := range l.Nodes { - fmt.Fprint(b, n) + n.writeTo(sb) } - return b.String() } func (l *ListNode) CopyList() *ListNode { @@ -132,6 +137,10 @@ func (t *TextNode) String() string { return fmt.Sprintf(textFormat, t.Text) } +func (t *TextNode) writeTo(sb *strings.Builder) { + sb.WriteString(t.String()) +} + func (t *TextNode) tree() *Tree { return t.tr } @@ -160,23 +169,27 @@ func (p *PipeNode) append(command *CommandNode) { } func (p *PipeNode) String() string { - s := "" + var sb strings.Builder + p.writeTo(&sb) + return sb.String() +} + +func (p *PipeNode) writeTo(sb *strings.Builder) { if len(p.Decl) > 0 { for i, v := range p.Decl { if i > 0 { - s += ", " + sb.WriteString(", ") } - s += v.String() + v.writeTo(sb) } - s += " := " + sb.WriteString(" := ") } for i, c := range p.Cmds { if i > 0 { - s += " | " + sb.WriteString(" | ") } - s += c.String() + c.writeTo(sb) } - return s } func (p *PipeNode) tree() *Tree { @@ -187,9 +200,9 @@ func (p *PipeNode) CopyPipe() *PipeNode { if p == nil { return p } - var vars []*VariableNode - for _, d := range p.Decl { - vars = append(vars, d.Copy().(*VariableNode)) + vars := make([]*VariableNode, len(p.Decl)) + for i, d := range p.Decl { + vars[i] = d.Copy().(*VariableNode) } n := p.tr.newPipeline(p.Pos, p.Line, vars) n.IsAssign = p.IsAssign @@ -219,8 +232,15 @@ func (t *Tree) newAction(pos Pos, line int, pipe *PipeNode) *ActionNode { } func (a *ActionNode) String() string { - return fmt.Sprintf("{{%s}}", a.Pipe) + var sb strings.Builder + a.writeTo(&sb) + return sb.String() +} +func (a *ActionNode) writeTo(sb *strings.Builder) { + sb.WriteString("{{") + a.Pipe.writeTo(sb) + sb.WriteString("}}") } func (a *ActionNode) tree() *Tree { @@ -249,18 +269,24 @@ func (c *CommandNode) append(arg Node) { } func (c *CommandNode) String() string { - s := "" + var sb strings.Builder + c.writeTo(&sb) + return sb.String() +} + +func (c *CommandNode) writeTo(sb *strings.Builder) { for i, arg := range c.Args { if i > 0 { - s += " " + sb.WriteByte(' ') } if arg, ok := arg.(*PipeNode); ok { - s += "(" + arg.String() + ")" + sb.WriteByte('(') + arg.writeTo(sb) + sb.WriteByte(')') continue } - s += arg.String() + arg.writeTo(sb) } - return s } func (c *CommandNode) tree() *Tree { @@ -311,6 +337,10 @@ func (i *IdentifierNode) String() string { return i.Ident } +func (i *IdentifierNode) writeTo(sb *strings.Builder) { + sb.WriteString(i.String()) +} + func (i *IdentifierNode) tree() *Tree { return i.tr } @@ -333,14 +363,18 @@ func (t *Tree) newVariable(pos Pos, ident string) *VariableNode { } func (v *VariableNode) String() string { - s := "" + var sb strings.Builder + v.writeTo(&sb) + return sb.String() +} + +func (v *VariableNode) writeTo(sb *strings.Builder) { for i, id := range v.Ident { if i > 0 { - s += "." + sb.WriteByte('.') } - s += id + sb.WriteString(id) } - return s } func (v *VariableNode) tree() *Tree { @@ -373,6 +407,10 @@ func (d *DotNode) String() string { return "." } +func (d *DotNode) writeTo(sb *strings.Builder) { + sb.WriteString(d.String()) +} + func (d *DotNode) tree() *Tree { return d.tr } @@ -403,6 +441,10 @@ func (n *NilNode) String() string { return "nil" } +func (n *NilNode) writeTo(sb *strings.Builder) { + sb.WriteString(n.String()) +} + func (n *NilNode) tree() *Tree { return n.tr } @@ -426,11 +468,16 @@ func (t *Tree) newField(pos Pos, ident string) *FieldNode { } func (f *FieldNode) String() string { - s := "" + var sb strings.Builder + f.writeTo(&sb) + return sb.String() +} + +func (f *FieldNode) writeTo(sb *strings.Builder) { for _, id := range f.Ident { - s += "." + id + sb.WriteByte('.') + sb.WriteString(id) } - return s } func (f *FieldNode) tree() *Tree { @@ -469,14 +516,23 @@ func (c *ChainNode) Add(field string) { } func (c *ChainNode) String() string { - s := c.Node.String() + var sb strings.Builder + c.writeTo(&sb) + return sb.String() +} + +func (c *ChainNode) writeTo(sb *strings.Builder) { if _, ok := c.Node.(*PipeNode); ok { - s = "(" + s + ")" + sb.WriteByte('(') + c.Node.writeTo(sb) + sb.WriteByte(')') + } else { + c.Node.writeTo(sb) } for _, field := range c.Field { - s += "." + field + sb.WriteByte('.') + sb.WriteString(field) } - return s } func (c *ChainNode) tree() *Tree { @@ -506,6 +562,10 @@ func (b *BoolNode) String() string { return "false" } +func (b *BoolNode) writeTo(sb *strings.Builder) { + sb.WriteString(b.String()) +} + func (b *BoolNode) tree() *Tree { return b.tr } @@ -639,6 +699,10 @@ func (n *NumberNode) String() string { return n.Text } +func (n *NumberNode) writeTo(sb *strings.Builder) { + sb.WriteString(n.String()) +} + func (n *NumberNode) tree() *Tree { return n.tr } @@ -666,6 +730,10 @@ func (s *StringNode) String() string { return s.Quoted } +func (s *StringNode) writeTo(sb *strings.Builder) { + sb.WriteString(s.String()) +} + func (s *StringNode) tree() *Tree { return s.tr } @@ -690,6 +758,10 @@ func (e *endNode) String() string { return "{{end}}" } +func (e *endNode) writeTo(sb *strings.Builder) { + sb.WriteString(e.String()) +} + func (e *endNode) tree() *Tree { return e.tr } @@ -718,6 +790,10 @@ func (e *elseNode) String() string { return "{{else}}" } +func (e *elseNode) writeTo(sb *strings.Builder) { + sb.WriteString(e.String()) +} + func (e *elseNode) tree() *Tree { return e.tr } @@ -738,6 +814,12 @@ type BranchNode struct { } func (b *BranchNode) String() string { + var sb strings.Builder + b.writeTo(&sb) + return sb.String() +} + +func (b *BranchNode) writeTo(sb *strings.Builder) { name := "" switch b.NodeType { case NodeIf: @@ -749,10 +831,17 @@ func (b *BranchNode) String() string { default: panic("unknown branch type") } + sb.WriteString("{{") + sb.WriteString(name) + sb.WriteByte(' ') + b.Pipe.writeTo(sb) + sb.WriteString("}}") + b.List.writeTo(sb) if b.ElseList != nil { - return fmt.Sprintf("{{%s %s}}%s{{else}}%s{{end}}", name, b.Pipe, b.List, b.ElseList) + sb.WriteString("{{else}}") + b.ElseList.writeTo(sb) } - return fmt.Sprintf("{{%s %s}}%s{{end}}", name, b.Pipe, b.List) + sb.WriteString("{{end}}") } func (b *BranchNode) tree() *Tree { @@ -826,10 +915,19 @@ func (t *Tree) newTemplate(pos Pos, line int, name string, pipe *PipeNode) *Temp } func (t *TemplateNode) String() string { - if t.Pipe == nil { - return fmt.Sprintf("{{template %q}}", t.Name) + var sb strings.Builder + t.writeTo(&sb) + return sb.String() +} + +func (t *TemplateNode) writeTo(sb *strings.Builder) { + sb.WriteString("{{template ") + sb.WriteString(strconv.Quote(t.Name)) + if t.Pipe != nil { + sb.WriteByte(' ') + t.Pipe.writeTo(sb) } - return fmt.Sprintf("{{template %q %s}}", t.Name, t.Pipe) + sb.WriteString("}}") } func (t *TemplateNode) tree() *Tree { diff --git a/libgo/go/text/template/parse/parse.go b/libgo/go/text/template/parse/parse.go index 7c35b0ff3d8..c9b80f4a248 100644 --- a/libgo/go/text/template/parse/parse.go +++ b/libgo/go/text/template/parse/parse.go @@ -108,13 +108,8 @@ func (t *Tree) nextNonSpace() (token item) { } // peekNonSpace returns but does not consume the next non-space token. -func (t *Tree) peekNonSpace() (token item) { - for { - token = t.next() - if token.typ != itemSpace { - break - } - } +func (t *Tree) peekNonSpace() item { + token := t.nextNonSpace() t.backup() return token } diff --git a/libgo/go/text/template/parse/parse_test.go b/libgo/go/text/template/parse/parse_test.go index 6932cf232ea..4e09a7852c9 100644 --- a/libgo/go/text/template/parse/parse_test.go +++ b/libgo/go/text/template/parse/parse_test.go @@ -304,7 +304,8 @@ var parseTests = []parseTest{ } var builtins = map[string]interface{}{ - "printf": fmt.Sprintf, + "printf": fmt.Sprintf, + "contains": strings.Contains, } func testParse(doCopy bool, t *testing.T) { @@ -553,3 +554,52 @@ func BenchmarkParseLarge(b *testing.B) { } } } + +var sinkv, sinkl string + +func BenchmarkVariableString(b *testing.B) { + v := &VariableNode{ + Ident: []string{"$", "A", "BB", "CCC", "THIS_IS_THE_VARIABLE_BEING_PROCESSED"}, + } + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + sinkv = v.String() + } + if sinkv == "" { + b.Fatal("Benchmark was not run") + } +} + +func BenchmarkListString(b *testing.B) { + text := ` +{{(printf .Field1.Field2.Field3).Value}} +{{$x := (printf .Field1.Field2.Field3).Value}} +{{$y := (printf $x.Field1.Field2.Field3).Value}} +{{$z := $y.Field1.Field2.Field3}} +{{if contains $y $z}} + {{printf "%q" $y}} +{{else}} + {{printf "%q" $x}} +{{end}} +{{with $z.Field1 | contains "boring"}} + {{printf "%q" . | printf "%s"}} +{{else}} + {{printf "%d %d %d" 11 11 11}} + {{printf "%d %d %s" 22 22 $x.Field1.Field2.Field3 | printf "%s"}} + {{printf "%v" (contains $z.Field1.Field2 $y)}} +{{end}} +` + tree, err := New("bench").Parse(text, "", "", make(map[string]*Tree), builtins) + if err != nil { + b.Fatal(err) + } + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + sinkl = tree.Root.String() + } + if sinkl == "" { + b.Fatal("Benchmark was not run") + } +} diff --git a/libgo/go/text/template/template.go b/libgo/go/text/template/template.go index 1135d819b99..e0c096207c7 100644 --- a/libgo/go/text/template/template.go +++ b/libgo/go/text/template/template.go @@ -110,20 +110,21 @@ func (t *Template) Clone() (*Template, error) { // copy returns a shallow copy of t, with common set to the argument. func (t *Template) copy(c *common) *Template { - nt := New(t.name) - nt.Tree = t.Tree - nt.common = c - nt.leftDelim = t.leftDelim - nt.rightDelim = t.rightDelim - return nt + return &Template{ + name: t.name, + Tree: t.Tree, + common: c, + leftDelim: t.leftDelim, + rightDelim: t.rightDelim, + } } -// AddParseTree adds parse tree for template with given name and associates it with t. -// If the template does not already exist, it will create a new one. -// If the template does exist, it will be replaced. +// AddParseTree associates the argument parse tree with the template t, giving +// it the specified name. If the template has not been defined, this tree becomes +// its definition. If it has been defined and already has that name, the existing +// definition is replaced; otherwise a new template is created, defined, and returned. func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) { t.init() - // If the name is the name of this template, overwrite this template. nt := t if name != t.name { nt = t.New(name) diff --git a/libgo/go/time/example_test.go b/libgo/go/time/example_test.go index 25c34ebc1cb..5a037daeafb 100644 --- a/libgo/go/time/example_test.go +++ b/libgo/go/time/example_test.go @@ -113,6 +113,20 @@ func ExampleDuration_Hours() { // Output: I've got 4.5 hours of work left. } +func ExampleDuration_Microseconds() { + u, _ := time.ParseDuration("1s") + fmt.Printf("One second is %d microseconds.\n", u.Microseconds()) + // Output: + // One second is 1000000 microseconds. +} + +func ExampleDuration_Milliseconds() { + u, _ := time.ParseDuration("1s") + fmt.Printf("One second is %d milliseconds.\n", u.Milliseconds()) + // Output: + // One second is 1000 milliseconds. +} + func ExampleDuration_Minutes() { m, _ := time.ParseDuration("1h30m") fmt.Printf("The movie is %.0f minutes long.", m.Minutes()) @@ -153,8 +167,8 @@ func statusUpdate() string { return "" } func ExampleTick() { c := time.Tick(5 * time.Second) - for now := range c { - fmt.Printf("%v %s\n", now, statusUpdate()) + for next := range c { + fmt.Printf("%v %s\n", next, statusUpdate()) } } @@ -349,6 +363,7 @@ func ExampleParse() { func ExampleParseInLocation() { loc, _ := time.LoadLocation("Europe/Berlin") + // This will look for the name CEST in the Europe/Berlin time zone. const longForm = "Jan 2, 2006 at 3:04pm (MST)" t, _ := time.ParseInLocation(longForm, "Jul 9, 2012 at 5:02am (CEST)", loc) fmt.Println(t) diff --git a/libgo/go/time/format_test.go b/libgo/go/time/format_test.go index ac215706e15..3dbb7742c33 100644 --- a/libgo/go/time/format_test.go +++ b/libgo/go/time/format_test.go @@ -119,7 +119,7 @@ var formatTests = []FormatTest{ } func TestFormat(t *testing.T) { - // The numeric time represents Thu Feb 4 21:00:57.012345600 PST 2010 + // The numeric time represents Thu Feb 4 21:00:57.012345600 PST 2009 time := Unix(0, 1233810057012345600) for _, test := range formatTests { result := time.Format(test.format) diff --git a/libgo/go/time/genzabbrs.go b/libgo/go/time/genzabbrs.go index e062cc2efd0..38397f91b71 100644 --- a/libgo/go/time/genzabbrs.go +++ b/libgo/go/time/genzabbrs.go @@ -52,7 +52,7 @@ type zone struct { DSTime string } -const wzURL = "http://unicode.org/cldr/data/common/supplemental/windowsZones.xml" +const wzURL = "https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml" type MapZone struct { Other string `xml:"other,attr"` diff --git a/libgo/go/time/internal_test.go b/libgo/go/time/internal_test.go index ba5e00e33cc..1e14f6c50ce 100644 --- a/libgo/go/time/internal_test.go +++ b/libgo/go/time/internal_test.go @@ -69,8 +69,7 @@ func CheckRuntimeTimerOverflow() { // once more. stopTimer(r) t.Stop() - r.when = 0 - startTimer(r) + resetTimer(r, 0) }() // If the test fails, we will hang here until the timeout in the testing package diff --git a/libgo/go/time/sleep.go b/libgo/go/time/sleep.go index 2cc908da55e..37de846b114 100644 --- a/libgo/go/time/sleep.go +++ b/libgo/go/time/sleep.go @@ -11,14 +11,14 @@ func Sleep(d Duration) // Interface to timers implemented in package runtime. // Must be in sync with ../runtime/time.go:/^type timer type runtimeTimer struct { - tb uintptr - i int - - when int64 - period int64 - f func(interface{}, uintptr) // NOTE: must not be closure - arg interface{} - seq uintptr + pp uintptr + when int64 + period int64 + f func(interface{}, uintptr) // NOTE: must not be closure + arg interface{} + seq uintptr + nextwhen int64 + status uint32 } // when is a helper function for setting the 'when' field of a runtimeTimer. @@ -38,6 +38,7 @@ func when(d Duration) int64 { func startTimer(*runtimeTimer) func stopTimer(*runtimeTimer) bool +func resetTimer(*runtimeTimer, int64) // The Timer type represents a single event. // When the Timer expires, the current time will be sent on C, @@ -63,7 +64,7 @@ type Timer struct { // } // // This cannot be done concurrent to other receives from the Timer's -// channel. +// channel or other calls to the Timer's Stop method. // // For a timer created with AfterFunc(d, f), if t.Stop returns false, then the timer // has already expired and the function f has been started in its own goroutine; @@ -122,8 +123,7 @@ func (t *Timer) Reset(d Duration) bool { } w := when(d) active := stopTimer(&t.r) - t.r.when = w - startTimer(&t.r) + resetTimer(&t.r, w) return active } diff --git a/libgo/go/time/sleep_test.go b/libgo/go/time/sleep_test.go index 42df6d1ba4d..26cc48870b4 100644 --- a/libgo/go/time/sleep_test.go +++ b/libgo/go/time/sleep_test.go @@ -235,28 +235,59 @@ func TestAfterTick(t *testing.T) { } func TestAfterStop(t *testing.T) { - AfterFunc(100*Millisecond, func() {}) - t0 := NewTimer(50 * Millisecond) - c1 := make(chan bool, 1) - t1 := AfterFunc(150*Millisecond, func() { c1 <- true }) - c2 := After(200 * Millisecond) - if !t0.Stop() { - t.Fatalf("failed to stop event 0") - } - if !t1.Stop() { - t.Fatalf("failed to stop event 1") - } - <-c2 - select { - case <-t0.C: - t.Fatalf("event 0 was not stopped") - case <-c1: - t.Fatalf("event 1 was not stopped") - default: + // We want to test that we stop a timer before it runs. + // We also want to test that it didn't run after a longer timer. + // Since we don't want the test to run for too long, we don't + // want to use lengthy times. That makes the test inherently flaky. + // So only report an error if it fails five times in a row. + + var errs []string + logErrs := func() { + for _, e := range errs { + t.Log(e) + } } - if t1.Stop() { - t.Fatalf("Stop returned true twice") + + for i := 0; i < 5; i++ { + AfterFunc(100*Millisecond, func() {}) + t0 := NewTimer(50 * Millisecond) + c1 := make(chan bool, 1) + t1 := AfterFunc(150*Millisecond, func() { c1 <- true }) + c2 := After(200 * Millisecond) + if !t0.Stop() { + errs = append(errs, "failed to stop event 0") + continue + } + if !t1.Stop() { + errs = append(errs, "failed to stop event 1") + continue + } + <-c2 + select { + case <-t0.C: + errs = append(errs, "event 0 was not stopped") + continue + case <-c1: + errs = append(errs, "event 1 was not stopped") + continue + default: + } + if t1.Stop() { + errs = append(errs, "Stop returned true twice") + continue + } + + // Test passed, so all done. + if len(errs) > 0 { + t.Logf("saw %d errors, ignoring to avoid flakiness", len(errs)) + logErrs() + } + + return } + + t.Errorf("saw %d errors", len(errs)) + logErrs() } func TestAfterQueuing(t *testing.T) { diff --git a/libgo/go/time/sys_unix.go b/libgo/go/time/sys_unix.go index 3af2288034c..ec98d6e6f39 100644 --- a/libgo/go/time/sys_unix.go +++ b/libgo/go/time/sys_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin dragonfly freebsd hurd js,wasm linux nacl netbsd openbsd solaris +// +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris package time diff --git a/libgo/go/time/tick_test.go b/libgo/go/time/tick_test.go index dd17aab1b15..71ea3672b86 100644 --- a/libgo/go/time/tick_test.go +++ b/libgo/go/time/tick_test.go @@ -5,34 +5,70 @@ package time_test import ( + "fmt" + "runtime" "testing" . "time" ) func TestTicker(t *testing.T) { - const Count = 10 - Delta := 100 * Millisecond - ticker := NewTicker(Delta) - t0 := Now() - for i := 0; i < Count; i++ { - <-ticker.C + // We want to test that a ticker takes as much time as expected. + // Since we don't want the test to run for too long, we don't + // want to use lengthy times. This makes the test inherently flaky. + // So only report an error if it fails five times in a row. + + count := 10 + delta := 20 * Millisecond + + // On Darwin ARM64 the tick frequency seems limited. Issue 35692. + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + count = 5 + delta = 100 * Millisecond } - ticker.Stop() - t1 := Now() - dt := t1.Sub(t0) - target := Delta * Count - slop := target * 2 / 10 - if dt < target-slop || (!testing.Short() && dt > target+slop) { - t.Fatalf("%d %s ticks took %s, expected [%s,%s]", Count, Delta, dt, target-slop, target+slop) + + var errs []string + logErrs := func() { + for _, e := range errs { + t.Log(e) + } } - // Now test that the ticker stopped - Sleep(2 * Delta) - select { - case <-ticker.C: - t.Fatal("Ticker did not shut down") - default: - // ok + + for i := 0; i < 5; i++ { + ticker := NewTicker(delta) + t0 := Now() + for i := 0; i < count; i++ { + <-ticker.C + } + ticker.Stop() + t1 := Now() + dt := t1.Sub(t0) + target := delta * Duration(count) + slop := target * 2 / 10 + if dt < target-slop || dt > target+slop { + errs = append(errs, fmt.Sprintf("%d %s ticks took %s, expected [%s,%s]", count, delta, dt, target-slop, target+slop)) + continue + } + // Now test that the ticker stopped. + Sleep(2 * delta) + select { + case <-ticker.C: + errs = append(errs, "Ticker did not shut down") + continue + default: + // ok + } + + // Test passed, so all done. + if len(errs) > 0 { + t.Logf("saw %d errors, ignoring to avoid flakiness", len(errs)) + logErrs() + } + + return } + + t.Errorf("saw %d errors", len(errs)) + logErrs() } // Issue 21874 diff --git a/libgo/go/time/time.go b/libgo/go/time/time.go index 0d1cb9e5a15..10a132fa238 100644 --- a/libgo/go/time/time.go +++ b/libgo/go/time/time.go @@ -257,7 +257,7 @@ func (t Time) Before(u Time) bool { // Equal reports whether t and u represent the same time instant. // Two times can be equal even if they are in different locations. -// For example, 6:00 +0200 CEST and 4:00 UTC are Equal. +// For example, 6:00 +0200 and 4:00 UTC are Equal. // See the documentation on the Time type for the pitfalls of using == with // Time values; most code should use Equal instead. func (t Time) Equal(u Time) bool { diff --git a/libgo/go/time/zoneinfo.go b/libgo/go/time/zoneinfo.go index 7dffbfad5e4..558803f24ed 100644 --- a/libgo/go/time/zoneinfo.go +++ b/libgo/go/time/zoneinfo.go @@ -14,7 +14,8 @@ import ( // A Location maps time instants to the zone in use at that time. // Typically, the Location represents the collection of time offsets -// in use in a geographical area, such as CEST and CET for central Europe. +// in use in a geographical area. For many Locations the time offset varies +// depending on whether daylight savings time is in use at the time instant. type Location struct { name string zone []zone @@ -34,7 +35,7 @@ type Location struct { cacheZone *zone } -// A zone represents a single time zone such as CEST or CET. +// A zone represents a single time zone such as CET. type zone struct { name string // abbreviated name, "CET" offset int // seconds east of UTC @@ -64,6 +65,11 @@ var UTC *Location = &utcLoc var utcLoc = Location{name: "UTC"} // Local represents the system's local time zone. +// On Unix systems, Local consults the TZ environment +// variable to find the time zone to use. No TZ means +// use the system default /etc/localtime. +// TZ="" means use UTC. +// TZ="foo" means use file foo in the system timezone directory. var Local *Location = &localLoc // localLoc is separate so that initLocal can initialize diff --git a/libgo/go/time/zoneinfo_abbrs_windows.go b/libgo/go/time/zoneinfo_abbrs_windows.go index 5411325ffe4..3294d0d7868 100644 --- a/libgo/go/time/zoneinfo_abbrs_windows.go +++ b/libgo/go/time/zoneinfo_abbrs_windows.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // Code generated by genzabbrs.go; DO NOT EDIT. -// Based on information from http://unicode.org/cldr/data/common/supplemental/windowsZones.xml +// Based on information from https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml package time @@ -14,11 +14,12 @@ type abbr struct { var abbrs = map[string]abbr{ "Egypt Standard Time": {"EET", "EET"}, // Africa/Cairo - "Morocco Standard Time": {"WET", "WEST"}, // Africa/Casablanca + "Morocco Standard Time": {"+00", "+01"}, // Africa/Casablanca "South Africa Standard Time": {"SAST", "SAST"}, // Africa/Johannesburg "Sudan Standard Time": {"CAT", "CAT"}, // Africa/Khartoum "W. Central Africa Standard Time": {"WAT", "WAT"}, // Africa/Lagos "E. Africa Standard Time": {"EAT", "EAT"}, // Africa/Nairobi + "Sao Tome Standard Time": {"GMT", "WAT"}, // Africa/Sao_Tome "Libya Standard Time": {"EET", "EET"}, // Africa/Tripoli "Namibia Standard Time": {"CAT", "CAT"}, // Africa/Windhoek "Aleutian Standard Time": {"HST", "HDT"}, // America/Adak @@ -36,7 +37,7 @@ var abbrs = map[string]abbr{ "Central Brazilian Standard Time": {"-04", "-03"}, // America/Cuiaba "Mountain Standard Time": {"MST", "MDT"}, // America/Denver "Greenland Standard Time": {"-03", "-02"}, // America/Godthab - "Turks And Caicos Standard Time": {"AST", "EDT"}, // America/Grand_Turk + "Turks And Caicos Standard Time": {"EST", "EDT"}, // America/Grand_Turk "Central America Standard Time": {"CST", "CST"}, // America/Guatemala "Atlantic Standard Time": {"AST", "ADT"}, // America/Halifax "Cuba Standard Time": {"CST", "CDT"}, // America/Havana @@ -81,6 +82,7 @@ var abbrs = map[string]abbr{ "N. Central Asia Standard Time": {"+07", "+07"}, // Asia/Novosibirsk "Omsk Standard Time": {"+06", "+06"}, // Asia/Omsk "North Korea Standard Time": {"KST", "KST"}, // Asia/Pyongyang + "Qyzylorda Standard Time": {"+05", "+06"}, // Asia/Qyzylorda "Myanmar Standard Time": {"+0630", "+0630"}, // Asia/Rangoon "Arab Standard Time": {"+03", "+03"}, // Asia/Riyadh "Sakhalin Standard Time": {"+11", "+11"}, // Asia/Sakhalin @@ -132,6 +134,7 @@ var abbrs = map[string]abbr{ "Romance Standard Time": {"CET", "CEST"}, // Europe/Paris "Russia Time Zone 3": {"+04", "+04"}, // Europe/Samara "Saratov Standard Time": {"+04", "+04"}, // Europe/Saratov + "Volgograd Standard Time": {"+04", "+04"}, // Europe/Volgograd "Central European Standard Time": {"CET", "CEST"}, // Europe/Warsaw "Mauritius Standard Time": {"+04", "+04"}, // Indian/Mauritius "Samoa Standard Time": {"+13", "+14"}, // Pacific/Apia diff --git a/libgo/go/time/zoneinfo_unix.go b/libgo/go/time/zoneinfo_unix.go index 495a7e68f77..dc425a5591c 100644 --- a/libgo/go/time/zoneinfo_unix.go +++ b/libgo/go/time/zoneinfo_unix.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build aix darwin,386 darwin,amd64 dragonfly freebsd hurd js,wasm linux,!android nacl netbsd openbsd solaris +// +build aix darwin,386 darwin,amd64 dragonfly freebsd hurd linux,!android netbsd openbsd solaris // Parse "zoneinfo" time zone file. // This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others. diff --git a/libgo/go/unicode/tables.go b/libgo/go/unicode/tables.go index ba7631b6d81..12441682d03 100644 --- a/libgo/go/unicode/tables.go +++ b/libgo/go/unicode/tables.go @@ -3,7 +3,7 @@ package unicode // Version is the Unicode edition from which the tables are derived. -const Version = "11.0.0" +const Version = "12.0.0" // Categories is the set of Unicode category tables. var Categories = map[string]*RangeTable{ @@ -64,6 +64,7 @@ var _C = &RangeTable{ }, R32: []Range32{ {0x110bd, 0x110cd, 16}, + {0x13430, 0x13438, 1}, {0x1bca0, 0x1bca3, 1}, {0x1d173, 0x1d17a, 1}, {0xe0001, 0xe0020, 31}, @@ -98,6 +99,7 @@ var _Cf = &RangeTable{ }, R32: []Range32{ {0x110bd, 0x110cd, 16}, + {0x13430, 0x13438, 1}, {0x1bca0, 0x1bca3, 1}, {0x1d173, 0x1d17a, 1}, {0xe0001, 0xe0020, 31}, @@ -255,15 +257,11 @@ var _L = &RangeTable{ {0x0e32, 0x0e33, 1}, {0x0e40, 0x0e46, 1}, {0x0e81, 0x0e82, 1}, - {0x0e84, 0x0e87, 3}, - {0x0e88, 0x0e8a, 2}, - {0x0e8d, 0x0e94, 7}, - {0x0e95, 0x0e97, 1}, - {0x0e99, 0x0e9f, 1}, - {0x0ea1, 0x0ea3, 1}, + {0x0e84, 0x0e86, 2}, + {0x0e87, 0x0e8a, 1}, + {0x0e8c, 0x0ea3, 1}, {0x0ea5, 0x0ea7, 2}, - {0x0eaa, 0x0eab, 1}, - {0x0ead, 0x0eb0, 1}, + {0x0ea8, 0x0eb0, 1}, {0x0eb2, 0x0eb3, 1}, {0x0ebd, 0x0ec0, 3}, {0x0ec1, 0x0ec4, 1}, @@ -342,9 +340,10 @@ var _L = &RangeTable{ {0x1c90, 0x1cba, 1}, {0x1cbd, 0x1cbf, 1}, {0x1ce9, 0x1cec, 1}, - {0x1cee, 0x1cf1, 1}, + {0x1cee, 0x1cf3, 1}, {0x1cf5, 0x1cf6, 1}, - {0x1d00, 0x1dbf, 1}, + {0x1cfa, 0x1d00, 6}, + {0x1d01, 0x1dbf, 1}, {0x1e00, 0x1f15, 1}, {0x1f18, 0x1f1d, 1}, {0x1f20, 0x1f45, 1}, @@ -417,7 +416,8 @@ var _L = &RangeTable{ {0xa6a0, 0xa6e5, 1}, {0xa717, 0xa71f, 1}, {0xa722, 0xa788, 1}, - {0xa78b, 0xa7b9, 1}, + {0xa78b, 0xa7bf, 1}, + {0xa7c2, 0xa7c6, 1}, {0xa7f7, 0xa801, 1}, {0xa803, 0xa805, 1}, {0xa807, 0xa80a, 1}, @@ -454,7 +454,7 @@ var _L = &RangeTable{ {0xab20, 0xab26, 1}, {0xab28, 0xab2e, 1}, {0xab30, 0xab5a, 1}, - {0xab5c, 0xab65, 1}, + {0xab5c, 0xab67, 1}, {0xab70, 0xabe2, 1}, {0xac00, 0xd7a3, 1}, {0xd7b0, 0xd7c6, 1}, @@ -543,6 +543,7 @@ var _L = &RangeTable{ {0x10f00, 0x10f1c, 1}, {0x10f27, 0x10f30, 9}, {0x10f31, 0x10f45, 1}, + {0x10fe0, 0x10ff6, 1}, {0x11003, 0x11037, 1}, {0x11083, 0x110af, 1}, {0x110d0, 0x110e8, 1}, @@ -571,7 +572,8 @@ var _L = &RangeTable{ {0x1135d, 0x11361, 1}, {0x11400, 0x11434, 1}, {0x11447, 0x1144a, 1}, - {0x11480, 0x114af, 1}, + {0x1145f, 0x11480, 33}, + {0x11481, 0x114af, 1}, {0x114c4, 0x114c5, 1}, {0x114c7, 0x11580, 185}, {0x11581, 0x115ae, 1}, @@ -579,14 +581,18 @@ var _L = &RangeTable{ {0x11600, 0x1162f, 1}, {0x11644, 0x11680, 60}, {0x11681, 0x116aa, 1}, - {0x11700, 0x1171a, 1}, + {0x116b8, 0x11700, 72}, + {0x11701, 0x1171a, 1}, {0x11800, 0x1182b, 1}, {0x118a0, 0x118df, 1}, - {0x118ff, 0x11a00, 257}, - {0x11a0b, 0x11a32, 1}, + {0x118ff, 0x119a0, 161}, + {0x119a1, 0x119a7, 1}, + {0x119aa, 0x119d0, 1}, + {0x119e1, 0x119e3, 2}, + {0x11a00, 0x11a0b, 11}, + {0x11a0c, 0x11a32, 1}, {0x11a3a, 0x11a50, 22}, - {0x11a5c, 0x11a83, 1}, - {0x11a86, 0x11a89, 1}, + {0x11a5c, 0x11a89, 1}, {0x11a9d, 0x11ac0, 35}, {0x11ac1, 0x11af8, 1}, {0x11c00, 0x11c08, 1}, @@ -614,13 +620,16 @@ var _L = &RangeTable{ {0x16b63, 0x16b77, 1}, {0x16b7d, 0x16b8f, 1}, {0x16e40, 0x16e7f, 1}, - {0x16f00, 0x16f44, 1}, + {0x16f00, 0x16f4a, 1}, {0x16f50, 0x16f93, 67}, {0x16f94, 0x16f9f, 1}, {0x16fe0, 0x16fe1, 1}, - {0x17000, 0x187f1, 1}, + {0x16fe3, 0x17000, 29}, + {0x17001, 0x187f7, 1}, {0x18800, 0x18af2, 1}, {0x1b000, 0x1b11e, 1}, + {0x1b150, 0x1b152, 1}, + {0x1b164, 0x1b167, 1}, {0x1b170, 0x1b2fb, 1}, {0x1bc00, 0x1bc6a, 1}, {0x1bc70, 0x1bc7c, 1}, @@ -656,9 +665,14 @@ var _L = &RangeTable{ {0x1d78a, 0x1d7a8, 1}, {0x1d7aa, 0x1d7c2, 1}, {0x1d7c4, 0x1d7cb, 1}, + {0x1e100, 0x1e12c, 1}, + {0x1e137, 0x1e13d, 1}, + {0x1e14e, 0x1e2c0, 370}, + {0x1e2c1, 0x1e2eb, 1}, {0x1e800, 0x1e8c4, 1}, {0x1e900, 0x1e943, 1}, - {0x1ee00, 0x1ee03, 1}, + {0x1e94b, 0x1ee00, 1205}, + {0x1ee01, 0x1ee03, 1}, {0x1ee05, 0x1ee1f, 1}, {0x1ee21, 0x1ee22, 1}, {0x1ee24, 0x1ee27, 3}, @@ -806,10 +820,10 @@ var _Ll = &RangeTable{ {0xa794, 0xa795, 1}, {0xa797, 0xa7a9, 2}, {0xa7af, 0xa7b5, 6}, - {0xa7b7, 0xa7b9, 2}, - {0xa7fa, 0xab30, 822}, - {0xab31, 0xab5a, 1}, - {0xab60, 0xab65, 1}, + {0xa7b7, 0xa7bf, 2}, + {0xa7c3, 0xa7fa, 55}, + {0xab30, 0xab5a, 1}, + {0xab60, 0xab67, 1}, {0xab70, 0xabbf, 1}, {0xfb00, 0xfb06, 1}, {0xfb13, 0xfb17, 1}, @@ -901,6 +915,9 @@ var _Lm = &RangeTable{ {0x16b40, 0x16b43, 1}, {0x16f93, 0x16f9f, 1}, {0x16fe0, 0x16fe1, 1}, + {0x16fe3, 0x1e137, 29012}, + {0x1e138, 0x1e13d, 1}, + {0x1e94b, 0x1e94b, 1}, }, } @@ -1015,15 +1032,11 @@ var _Lo = &RangeTable{ {0x0e32, 0x0e33, 1}, {0x0e40, 0x0e45, 1}, {0x0e81, 0x0e82, 1}, - {0x0e84, 0x0e87, 3}, - {0x0e88, 0x0e8a, 2}, - {0x0e8d, 0x0e94, 7}, - {0x0e95, 0x0e97, 1}, - {0x0e99, 0x0e9f, 1}, - {0x0ea1, 0x0ea3, 1}, + {0x0e84, 0x0e86, 2}, + {0x0e87, 0x0e8a, 1}, + {0x0e8c, 0x0ea3, 1}, {0x0ea5, 0x0ea7, 2}, - {0x0eaa, 0x0eab, 1}, - {0x0ead, 0x0eb0, 1}, + {0x0ea8, 0x0eb0, 1}, {0x0eb2, 0x0eb3, 1}, {0x0ebd, 0x0ec0, 3}, {0x0ec1, 0x0ec4, 1}, @@ -1093,9 +1106,10 @@ var _Lo = &RangeTable{ {0x1c4d, 0x1c4f, 1}, {0x1c5a, 0x1c77, 1}, {0x1ce9, 0x1cec, 1}, - {0x1cee, 0x1cf1, 1}, + {0x1cee, 0x1cf3, 1}, {0x1cf5, 0x1cf6, 1}, - {0x2135, 0x2138, 1}, + {0x1cfa, 0x2135, 1083}, + {0x2136, 0x2138, 1}, {0x2d30, 0x2d67, 1}, {0x2d80, 0x2d96, 1}, {0x2da0, 0x2da6, 1}, @@ -1243,6 +1257,7 @@ var _Lo = &RangeTable{ {0x10f00, 0x10f1c, 1}, {0x10f27, 0x10f30, 9}, {0x10f31, 0x10f45, 1}, + {0x10fe0, 0x10ff6, 1}, {0x11003, 0x11037, 1}, {0x11083, 0x110af, 1}, {0x110d0, 0x110e8, 1}, @@ -1271,7 +1286,8 @@ var _Lo = &RangeTable{ {0x1135d, 0x11361, 1}, {0x11400, 0x11434, 1}, {0x11447, 0x1144a, 1}, - {0x11480, 0x114af, 1}, + {0x1145f, 0x11480, 33}, + {0x11481, 0x114af, 1}, {0x114c4, 0x114c5, 1}, {0x114c7, 0x11580, 185}, {0x11581, 0x115ae, 1}, @@ -1279,13 +1295,17 @@ var _Lo = &RangeTable{ {0x11600, 0x1162f, 1}, {0x11644, 0x11680, 60}, {0x11681, 0x116aa, 1}, - {0x11700, 0x1171a, 1}, + {0x116b8, 0x11700, 72}, + {0x11701, 0x1171a, 1}, {0x11800, 0x1182b, 1}, - {0x118ff, 0x11a00, 257}, - {0x11a0b, 0x11a32, 1}, + {0x118ff, 0x119a0, 161}, + {0x119a1, 0x119a7, 1}, + {0x119aa, 0x119d0, 1}, + {0x119e1, 0x119e3, 2}, + {0x11a00, 0x11a0b, 11}, + {0x11a0c, 0x11a32, 1}, {0x11a3a, 0x11a50, 22}, - {0x11a5c, 0x11a83, 1}, - {0x11a86, 0x11a89, 1}, + {0x11a5c, 0x11a89, 1}, {0x11a9d, 0x11ac0, 35}, {0x11ac1, 0x11af8, 1}, {0x11c00, 0x11c08, 1}, @@ -1311,16 +1331,21 @@ var _Lo = &RangeTable{ {0x16b00, 0x16b2f, 1}, {0x16b63, 0x16b77, 1}, {0x16b7d, 0x16b8f, 1}, - {0x16f00, 0x16f44, 1}, + {0x16f00, 0x16f4a, 1}, {0x16f50, 0x17000, 176}, - {0x17001, 0x187f1, 1}, + {0x17001, 0x187f7, 1}, {0x18800, 0x18af2, 1}, {0x1b000, 0x1b11e, 1}, + {0x1b150, 0x1b152, 1}, + {0x1b164, 0x1b167, 1}, {0x1b170, 0x1b2fb, 1}, {0x1bc00, 0x1bc6a, 1}, {0x1bc70, 0x1bc7c, 1}, {0x1bc80, 0x1bc88, 1}, {0x1bc90, 0x1bc99, 1}, + {0x1e100, 0x1e12c, 1}, + {0x1e14e, 0x1e2c0, 370}, + {0x1e2c1, 0x1e2eb, 1}, {0x1e800, 0x1e8c4, 1}, {0x1ee00, 0x1ee03, 1}, {0x1ee05, 0x1ee1f, 1}, @@ -1473,7 +1498,9 @@ var _Lu = &RangeTable{ {0xa796, 0xa7aa, 2}, {0xa7ab, 0xa7ae, 1}, {0xa7b0, 0xa7b4, 1}, - {0xa7b6, 0xa7b8, 2}, + {0xa7b6, 0xa7be, 2}, + {0xa7c2, 0xa7c4, 2}, + {0xa7c5, 0xa7c6, 1}, {0xff21, 0xff3a, 1}, }, R32: []Range32{ @@ -1610,8 +1637,7 @@ var _M = &RangeTable{ {0x0e35, 0x0e3a, 1}, {0x0e47, 0x0e4e, 1}, {0x0eb1, 0x0eb4, 3}, - {0x0eb5, 0x0eb9, 1}, - {0x0ebb, 0x0ebc, 1}, + {0x0eb5, 0x0ebc, 1}, {0x0ec8, 0x0ecd, 1}, {0x0f18, 0x0f19, 1}, {0x0f35, 0x0f39, 2}, @@ -1656,8 +1682,7 @@ var _M = &RangeTable{ {0x1c24, 0x1c37, 1}, {0x1cd0, 0x1cd2, 1}, {0x1cd4, 0x1ce8, 1}, - {0x1ced, 0x1cf2, 5}, - {0x1cf3, 0x1cf4, 1}, + {0x1ced, 0x1cf4, 7}, {0x1cf7, 0x1cf9, 1}, {0x1dc0, 0x1df9, 1}, {0x1dfb, 0x1dff, 1}, @@ -1744,7 +1769,10 @@ var _M = &RangeTable{ {0x116ab, 0x116b7, 1}, {0x1171d, 0x1172b, 1}, {0x1182c, 0x1183a, 1}, - {0x11a01, 0x11a0a, 1}, + {0x119d1, 0x119d7, 1}, + {0x119da, 0x119e0, 1}, + {0x119e4, 0x11a01, 29}, + {0x11a02, 0x11a0a, 1}, {0x11a33, 0x11a39, 1}, {0x11a3b, 0x11a3e, 1}, {0x11a47, 0x11a51, 10}, @@ -1765,7 +1793,8 @@ var _M = &RangeTable{ {0x11ef3, 0x11ef6, 1}, {0x16af0, 0x16af4, 1}, {0x16b30, 0x16b36, 1}, - {0x16f51, 0x16f7e, 1}, + {0x16f4f, 0x16f51, 2}, + {0x16f52, 0x16f87, 1}, {0x16f8f, 0x16f92, 1}, {0x1bc9d, 0x1bc9e, 1}, {0x1d165, 0x1d169, 1}, @@ -1784,6 +1813,8 @@ var _M = &RangeTable{ {0x1e01b, 0x1e021, 1}, {0x1e023, 0x1e024, 1}, {0x1e026, 0x1e02a, 1}, + {0x1e130, 0x1e136, 1}, + {0x1e2ec, 0x1e2ef, 1}, {0x1e8d0, 0x1e8d6, 1}, {0x1e944, 0x1e94a, 1}, {0xe0100, 0xe01ef, 1}, @@ -1868,8 +1899,7 @@ var _Mc = &RangeTable{ {0x1bf3, 0x1c24, 49}, {0x1c25, 0x1c2b, 1}, {0x1c34, 0x1c35, 1}, - {0x1ce1, 0x1cf2, 17}, - {0x1cf3, 0x1cf7, 4}, + {0x1ce1, 0x1cf7, 22}, {0x302e, 0x302f, 1}, {0xa823, 0xa824, 1}, {0xa827, 0xa880, 89}, @@ -1878,8 +1908,8 @@ var _Mc = &RangeTable{ {0xa952, 0xa953, 1}, {0xa983, 0xa9b4, 49}, {0xa9b5, 0xa9ba, 5}, - {0xa9bb, 0xa9bd, 2}, - {0xa9be, 0xa9c0, 1}, + {0xa9bb, 0xa9be, 3}, + {0xa9bf, 0xa9c0, 1}, {0xaa2f, 0xaa30, 1}, {0xaa33, 0xaa34, 1}, {0xaa4d, 0xaa7b, 46}, @@ -1927,7 +1957,10 @@ var _Mc = &RangeTable{ {0x116b6, 0x11720, 106}, {0x11721, 0x11726, 5}, {0x1182c, 0x1182e, 1}, - {0x11838, 0x11a39, 513}, + {0x11838, 0x119d1, 409}, + {0x119d2, 0x119d3, 1}, + {0x119dc, 0x119df, 1}, + {0x119e4, 0x11a39, 85}, {0x11a57, 0x11a58, 1}, {0x11a97, 0x11c2f, 408}, {0x11c3e, 0x11ca9, 107}, @@ -1936,7 +1969,7 @@ var _Mc = &RangeTable{ {0x11d93, 0x11d94, 1}, {0x11d96, 0x11ef5, 351}, {0x11ef6, 0x16f51, 20571}, - {0x16f52, 0x16f7e, 1}, + {0x16f52, 0x16f87, 1}, {0x1d165, 0x1d166, 1}, {0x1d16d, 0x1d172, 1}, }, @@ -2029,8 +2062,7 @@ var _Mn = &RangeTable{ {0x0e34, 0x0e3a, 1}, {0x0e47, 0x0e4e, 1}, {0x0eb1, 0x0eb4, 3}, - {0x0eb5, 0x0eb9, 1}, - {0x0ebb, 0x0ebc, 1}, + {0x0eb5, 0x0ebc, 1}, {0x0ec8, 0x0ecd, 1}, {0x0f18, 0x0f19, 1}, {0x0f35, 0x0f39, 2}, @@ -2119,8 +2151,9 @@ var _Mn = &RangeTable{ {0xa980, 0xa982, 1}, {0xa9b3, 0xa9b6, 3}, {0xa9b7, 0xa9b9, 1}, - {0xa9bc, 0xa9e5, 41}, - {0xaa29, 0xaa2e, 1}, + {0xa9bc, 0xa9bd, 1}, + {0xa9e5, 0xaa29, 68}, + {0xaa2a, 0xaa2e, 1}, {0xaa31, 0xaa32, 1}, {0xaa35, 0xaa36, 1}, {0xaa43, 0xaa4c, 9}, @@ -2190,7 +2223,10 @@ var _Mn = &RangeTable{ {0x11727, 0x1172b, 1}, {0x1182f, 0x11837, 1}, {0x11839, 0x1183a, 1}, - {0x11a01, 0x11a0a, 1}, + {0x119d4, 0x119d7, 1}, + {0x119da, 0x119db, 1}, + {0x119e0, 0x11a01, 33}, + {0x11a02, 0x11a0a, 1}, {0x11a33, 0x11a38, 1}, {0x11a3b, 0x11a3e, 1}, {0x11a47, 0x11a51, 10}, @@ -2215,7 +2251,8 @@ var _Mn = &RangeTable{ {0x11ef4, 0x16af0, 19452}, {0x16af1, 0x16af4, 1}, {0x16b30, 0x16b36, 1}, - {0x16f8f, 0x16f92, 1}, + {0x16f4f, 0x16f8f, 64}, + {0x16f90, 0x16f92, 1}, {0x1bc9d, 0x1bc9e, 1}, {0x1d167, 0x1d169, 1}, {0x1d17b, 0x1d182, 1}, @@ -2232,6 +2269,8 @@ var _Mn = &RangeTable{ {0x1e01b, 0x1e021, 1}, {0x1e023, 0x1e024, 1}, {0x1e026, 0x1e02a, 1}, + {0x1e130, 0x1e136, 1}, + {0x1e2ec, 0x1e2ef, 1}, {0x1e8d0, 0x1e8d6, 1}, {0x1e944, 0x1e94a, 1}, {0xe0100, 0xe01ef, 1}, @@ -2351,6 +2390,7 @@ var _N = &RangeTable{ {0x11c50, 0x11c6c, 1}, {0x11d50, 0x11d59, 1}, {0x11da0, 0x11da9, 1}, + {0x11fc0, 0x11fd4, 1}, {0x12400, 0x1246e, 1}, {0x16a60, 0x16a69, 1}, {0x16b50, 0x16b59, 1}, @@ -2359,11 +2399,15 @@ var _N = &RangeTable{ {0x1d2e0, 0x1d2f3, 1}, {0x1d360, 0x1d378, 1}, {0x1d7ce, 0x1d7ff, 1}, + {0x1e140, 0x1e149, 1}, + {0x1e2f0, 0x1e2f9, 1}, {0x1e8c7, 0x1e8cf, 1}, {0x1e950, 0x1e959, 1}, {0x1ec71, 0x1ecab, 1}, {0x1ecad, 0x1ecaf, 1}, {0x1ecb1, 0x1ecb4, 1}, + {0x1ed01, 0x1ed2d, 1}, + {0x1ed2f, 0x1ed3d, 1}, {0x1f100, 0x1f10c, 1}, }, LatinOffset: 4, @@ -2429,6 +2473,8 @@ var _Nd = &RangeTable{ {0x16a60, 0x16a69, 1}, {0x16b50, 0x16b59, 1}, {0x1d7ce, 0x1d7ff, 1}, + {0x1e140, 0x1e149, 1}, + {0x1e2f0, 0x1e2f9, 1}, {0x1e950, 0x1e959, 1}, }, LatinOffset: 1, @@ -2513,6 +2559,7 @@ var _No = &RangeTable{ {0x1173a, 0x1173b, 1}, {0x118ea, 0x118f2, 1}, {0x11c5a, 0x11c6c, 1}, + {0x11fc0, 0x11fd4, 1}, {0x16b5b, 0x16b61, 1}, {0x16e80, 0x16e96, 1}, {0x1d2e0, 0x1d2f3, 1}, @@ -2521,6 +2568,8 @@ var _No = &RangeTable{ {0x1ec71, 0x1ecab, 1}, {0x1ecad, 0x1ecaf, 1}, {0x1ecb1, 0x1ecb4, 1}, + {0x1ed01, 0x1ed2d, 1}, + {0x1ed2f, 0x1ed3d, 1}, {0x1f100, 0x1f10c, 1}, }, LatinOffset: 3, @@ -2557,10 +2606,11 @@ var _P = &RangeTable{ {0x085e, 0x0964, 262}, {0x0965, 0x0970, 11}, {0x09fd, 0x0a76, 121}, - {0x0af0, 0x0c84, 404}, - {0x0df4, 0x0e4f, 91}, - {0x0e5a, 0x0e5b, 1}, - {0x0f04, 0x0f12, 1}, + {0x0af0, 0x0c77, 391}, + {0x0c84, 0x0df4, 368}, + {0x0e4f, 0x0e5a, 11}, + {0x0e5b, 0x0f04, 169}, + {0x0f05, 0x0f12, 1}, {0x0f14, 0x0f3a, 38}, {0x0f3b, 0x0f3d, 1}, {0x0f85, 0x0fd0, 75}, @@ -2569,10 +2619,9 @@ var _P = &RangeTable{ {0x104a, 0x104f, 1}, {0x10fb, 0x1360, 613}, {0x1361, 0x1368, 1}, - {0x1400, 0x166d, 621}, - {0x166e, 0x169b, 45}, - {0x169c, 0x16eb, 79}, - {0x16ec, 0x16ed, 1}, + {0x1400, 0x166e, 622}, + {0x169b, 0x169c, 1}, + {0x16eb, 0x16ed, 1}, {0x1735, 0x1736, 1}, {0x17d4, 0x17d6, 1}, {0x17d8, 0x17da, 1}, @@ -2605,7 +2654,7 @@ var _P = &RangeTable{ {0x2cfe, 0x2cff, 1}, {0x2d70, 0x2e00, 144}, {0x2e01, 0x2e2e, 1}, - {0x2e30, 0x2e4e, 1}, + {0x2e30, 0x2e4f, 1}, {0x3001, 0x3003, 1}, {0x3008, 0x3011, 1}, {0x3014, 0x301f, 1}, @@ -2670,21 +2719,22 @@ var _P = &RangeTable{ {0x11641, 0x11643, 1}, {0x11660, 0x1166c, 1}, {0x1173c, 0x1173e, 1}, - {0x1183b, 0x11a3f, 516}, - {0x11a40, 0x11a46, 1}, + {0x1183b, 0x119e2, 423}, + {0x11a3f, 0x11a46, 1}, {0x11a9a, 0x11a9c, 1}, {0x11a9e, 0x11aa2, 1}, {0x11c41, 0x11c45, 1}, {0x11c70, 0x11c71, 1}, {0x11ef7, 0x11ef8, 1}, - {0x12470, 0x12474, 1}, + {0x11fff, 0x12470, 1137}, + {0x12471, 0x12474, 1}, {0x16a6e, 0x16a6f, 1}, {0x16af5, 0x16b37, 66}, {0x16b38, 0x16b3b, 1}, {0x16b44, 0x16e97, 851}, {0x16e98, 0x16e9a, 1}, - {0x1bc9f, 0x1da87, 7656}, - {0x1da88, 0x1da8b, 1}, + {0x16fe2, 0x1bc9f, 19645}, + {0x1da87, 0x1da8b, 1}, {0x1e95e, 0x1e95f, 1}, }, LatinOffset: 11, @@ -2793,18 +2843,19 @@ var _Po = &RangeTable{ {0x085e, 0x0964, 262}, {0x0965, 0x0970, 11}, {0x09fd, 0x0a76, 121}, - {0x0af0, 0x0c84, 404}, - {0x0df4, 0x0e4f, 91}, - {0x0e5a, 0x0e5b, 1}, - {0x0f04, 0x0f12, 1}, + {0x0af0, 0x0c77, 391}, + {0x0c84, 0x0df4, 368}, + {0x0e4f, 0x0e5a, 11}, + {0x0e5b, 0x0f04, 169}, + {0x0f05, 0x0f12, 1}, {0x0f14, 0x0f85, 113}, {0x0fd0, 0x0fd4, 1}, {0x0fd9, 0x0fda, 1}, {0x104a, 0x104f, 1}, {0x10fb, 0x1360, 613}, {0x1361, 0x1368, 1}, - {0x166d, 0x166e, 1}, - {0x16eb, 0x16ed, 1}, + {0x166e, 0x16eb, 125}, + {0x16ec, 0x16ed, 1}, {0x1735, 0x1736, 1}, {0x17d4, 0x17d6, 1}, {0x17d8, 0x17da, 1}, @@ -2842,7 +2893,7 @@ var _Po = &RangeTable{ {0x2e30, 0x2e39, 1}, {0x2e3c, 0x2e3f, 1}, {0x2e41, 0x2e43, 2}, - {0x2e44, 0x2e4e, 1}, + {0x2e44, 0x2e4f, 1}, {0x3001, 0x3003, 1}, {0x303d, 0x30fb, 190}, {0xa4fe, 0xa4ff, 1}, @@ -2906,21 +2957,22 @@ var _Po = &RangeTable{ {0x11641, 0x11643, 1}, {0x11660, 0x1166c, 1}, {0x1173c, 0x1173e, 1}, - {0x1183b, 0x11a3f, 516}, - {0x11a40, 0x11a46, 1}, + {0x1183b, 0x119e2, 423}, + {0x11a3f, 0x11a46, 1}, {0x11a9a, 0x11a9c, 1}, {0x11a9e, 0x11aa2, 1}, {0x11c41, 0x11c45, 1}, {0x11c70, 0x11c71, 1}, {0x11ef7, 0x11ef8, 1}, - {0x12470, 0x12474, 1}, + {0x11fff, 0x12470, 1137}, + {0x12471, 0x12474, 1}, {0x16a6e, 0x16a6f, 1}, {0x16af5, 0x16b37, 66}, {0x16b38, 0x16b3b, 1}, {0x16b44, 0x16e97, 851}, {0x16e98, 0x16e9a, 1}, - {0x1bc9f, 0x1da87, 7656}, - {0x1da88, 0x1da8b, 1}, + {0x16fe2, 0x1bc9f, 19645}, + {0x1da87, 0x1da8b, 1}, {0x1e95e, 0x1e95f, 1}, }, LatinOffset: 8, @@ -3001,8 +3053,9 @@ var _S = &RangeTable{ {0x0fd5, 0x0fd8, 1}, {0x109e, 0x109f, 1}, {0x1390, 0x1399, 1}, - {0x17db, 0x1940, 357}, - {0x19de, 0x19ff, 1}, + {0x166d, 0x17db, 366}, + {0x1940, 0x19de, 158}, + {0x19df, 0x19ff, 1}, {0x1b61, 0x1b6a, 1}, {0x1b74, 0x1b7c, 1}, {0x1fbd, 0x1fbf, 2}, @@ -3041,8 +3094,7 @@ var _S = &RangeTable{ {0x29dc, 0x29fb, 1}, {0x29fe, 0x2b73, 1}, {0x2b76, 0x2b95, 1}, - {0x2b98, 0x2bc8, 1}, - {0x2bca, 0x2bfe, 1}, + {0x2b98, 0x2bff, 1}, {0x2ce5, 0x2cea, 1}, {0x2e80, 0x2e99, 1}, {0x2e9b, 0x2ef3, 1}, @@ -3094,6 +3146,7 @@ var _S = &RangeTable{ {0x101d1, 0x101fc, 1}, {0x10877, 0x10878, 1}, {0x10ac8, 0x1173f, 3191}, + {0x11fd5, 0x11ff1, 1}, {0x16b3c, 0x16b3f, 1}, {0x16b45, 0x1bc9c, 20823}, {0x1d000, 0x1d0f5, 1}, @@ -3116,41 +3169,46 @@ var _S = &RangeTable{ {0x1da6d, 0x1da74, 1}, {0x1da76, 0x1da83, 1}, {0x1da85, 0x1da86, 1}, + {0x1e14f, 0x1e2ff, 432}, {0x1ecac, 0x1ecb0, 4}, - {0x1eef0, 0x1eef1, 1}, - {0x1f000, 0x1f02b, 1}, + {0x1ed2e, 0x1eef0, 450}, + {0x1eef1, 0x1f000, 271}, + {0x1f001, 0x1f02b, 1}, {0x1f030, 0x1f093, 1}, {0x1f0a0, 0x1f0ae, 1}, {0x1f0b1, 0x1f0bf, 1}, {0x1f0c1, 0x1f0cf, 1}, {0x1f0d1, 0x1f0f5, 1}, - {0x1f110, 0x1f16b, 1}, + {0x1f110, 0x1f16c, 1}, {0x1f170, 0x1f1ac, 1}, {0x1f1e6, 0x1f202, 1}, {0x1f210, 0x1f23b, 1}, {0x1f240, 0x1f248, 1}, {0x1f250, 0x1f251, 1}, {0x1f260, 0x1f265, 1}, - {0x1f300, 0x1f6d4, 1}, + {0x1f300, 0x1f6d5, 1}, {0x1f6e0, 0x1f6ec, 1}, - {0x1f6f0, 0x1f6f9, 1}, + {0x1f6f0, 0x1f6fa, 1}, {0x1f700, 0x1f773, 1}, {0x1f780, 0x1f7d8, 1}, + {0x1f7e0, 0x1f7eb, 1}, {0x1f800, 0x1f80b, 1}, {0x1f810, 0x1f847, 1}, {0x1f850, 0x1f859, 1}, {0x1f860, 0x1f887, 1}, {0x1f890, 0x1f8ad, 1}, {0x1f900, 0x1f90b, 1}, - {0x1f910, 0x1f93e, 1}, - {0x1f940, 0x1f970, 1}, + {0x1f90d, 0x1f971, 1}, {0x1f973, 0x1f976, 1}, - {0x1f97a, 0x1f97c, 2}, - {0x1f97d, 0x1f9a2, 1}, - {0x1f9b0, 0x1f9b9, 1}, - {0x1f9c0, 0x1f9c2, 1}, - {0x1f9d0, 0x1f9ff, 1}, + {0x1f97a, 0x1f9a2, 1}, + {0x1f9a5, 0x1f9aa, 1}, + {0x1f9ae, 0x1f9ca, 1}, + {0x1f9cd, 0x1fa53, 1}, {0x1fa60, 0x1fa6d, 1}, + {0x1fa70, 0x1fa73, 1}, + {0x1fa78, 0x1fa7a, 1}, + {0x1fa80, 0x1fa82, 1}, + {0x1fa90, 0x1fa95, 1}, }, LatinOffset: 10, } @@ -3172,7 +3230,8 @@ var _Sc = &RangeTable{ {0xffe5, 0xffe6, 1}, }, R32: []Range32{ - {0x1ecb0, 0x1ecb0, 1}, + {0x11fdd, 0x11fe0, 1}, + {0x1e2ff, 0x1ecb0, 2481}, }, LatinOffset: 2, } @@ -3290,8 +3349,8 @@ var _So = &RangeTable{ {0x0fd5, 0x0fd8, 1}, {0x109e, 0x109f, 1}, {0x1390, 0x1399, 1}, - {0x1940, 0x19de, 158}, - {0x19df, 0x19ff, 1}, + {0x166d, 0x1940, 723}, + {0x19de, 0x19ff, 1}, {0x1b61, 0x1b6a, 1}, {0x1b74, 0x1b7c, 1}, {0x2100, 0x2101, 1}, @@ -3335,8 +3394,7 @@ var _So = &RangeTable{ {0x2b45, 0x2b46, 1}, {0x2b4d, 0x2b73, 1}, {0x2b76, 0x2b95, 1}, - {0x2b98, 0x2bc8, 1}, - {0x2bca, 0x2bfe, 1}, + {0x2b98, 0x2bff, 1}, {0x2ce5, 0x2cea, 1}, {0x2e80, 0x2e99, 1}, {0x2e9b, 0x2ef3, 1}, @@ -3376,6 +3434,8 @@ var _So = &RangeTable{ {0x101d1, 0x101fc, 1}, {0x10877, 0x10878, 1}, {0x10ac8, 0x1173f, 3191}, + {0x11fd5, 0x11fdc, 1}, + {0x11fe1, 0x11ff1, 1}, {0x16b3c, 0x16b3f, 1}, {0x16b45, 0x1bc9c, 20823}, {0x1d000, 0x1d0f5, 1}, @@ -3393,14 +3453,15 @@ var _So = &RangeTable{ {0x1da6d, 0x1da74, 1}, {0x1da76, 0x1da83, 1}, {0x1da85, 0x1da86, 1}, - {0x1ecac, 0x1f000, 852}, + {0x1e14f, 0x1ecac, 2909}, + {0x1ed2e, 0x1f000, 722}, {0x1f001, 0x1f02b, 1}, {0x1f030, 0x1f093, 1}, {0x1f0a0, 0x1f0ae, 1}, {0x1f0b1, 0x1f0bf, 1}, {0x1f0c1, 0x1f0cf, 1}, {0x1f0d1, 0x1f0f5, 1}, - {0x1f110, 0x1f16b, 1}, + {0x1f110, 0x1f16c, 1}, {0x1f170, 0x1f1ac, 1}, {0x1f1e6, 0x1f202, 1}, {0x1f210, 0x1f23b, 1}, @@ -3408,26 +3469,29 @@ var _So = &RangeTable{ {0x1f250, 0x1f251, 1}, {0x1f260, 0x1f265, 1}, {0x1f300, 0x1f3fa, 1}, - {0x1f400, 0x1f6d4, 1}, + {0x1f400, 0x1f6d5, 1}, {0x1f6e0, 0x1f6ec, 1}, - {0x1f6f0, 0x1f6f9, 1}, + {0x1f6f0, 0x1f6fa, 1}, {0x1f700, 0x1f773, 1}, {0x1f780, 0x1f7d8, 1}, + {0x1f7e0, 0x1f7eb, 1}, {0x1f800, 0x1f80b, 1}, {0x1f810, 0x1f847, 1}, {0x1f850, 0x1f859, 1}, {0x1f860, 0x1f887, 1}, {0x1f890, 0x1f8ad, 1}, {0x1f900, 0x1f90b, 1}, - {0x1f910, 0x1f93e, 1}, - {0x1f940, 0x1f970, 1}, + {0x1f90d, 0x1f971, 1}, {0x1f973, 0x1f976, 1}, - {0x1f97a, 0x1f97c, 2}, - {0x1f97d, 0x1f9a2, 1}, - {0x1f9b0, 0x1f9b9, 1}, - {0x1f9c0, 0x1f9c2, 1}, - {0x1f9d0, 0x1f9ff, 1}, + {0x1f97a, 0x1f9a2, 1}, + {0x1f9a5, 0x1f9aa, 1}, + {0x1f9ae, 0x1f9ca, 1}, + {0x1f9cd, 0x1fa53, 1}, {0x1fa60, 0x1fa6d, 1}, + {0x1fa70, 0x1fa73, 1}, + {0x1fa78, 0x1fa7a, 1}, + {0x1fa80, 0x1fa82, 1}, + {0x1fa90, 0x1fa95, 1}, }, LatinOffset: 2, } @@ -3554,6 +3618,7 @@ var Scripts = map[string]*RangeTable{ "Duployan": Duployan, "Egyptian_Hieroglyphs": Egyptian_Hieroglyphs, "Elbasan": Elbasan, + "Elymaic": Elymaic, "Ethiopic": Ethiopic, "Georgian": Georgian, "Glagolitic": Glagolitic, @@ -3611,10 +3676,12 @@ var Scripts = map[string]*RangeTable{ "Multani": Multani, "Myanmar": Myanmar, "Nabataean": Nabataean, + "Nandinagari": Nandinagari, "New_Tai_Lue": New_Tai_Lue, "Newa": Newa, "Nko": Nko, "Nushu": Nushu, + "Nyiakeng_Puachue_Hmong": Nyiakeng_Puachue_Hmong, "Ogham": Ogham, "Ol_Chiki": Ol_Chiki, "Old_Hungarian": Old_Hungarian, @@ -3665,6 +3732,7 @@ var Scripts = map[string]*RangeTable{ "Tirhuta": Tirhuta, "Ugaritic": Ugaritic, "Vai": Vai, + "Wancho": Wancho, "Warang_Citi": Warang_Citi, "Yi": Yi, "Zanabazar_Square": Zanabazar_Square, @@ -3673,7 +3741,7 @@ var Scripts = map[string]*RangeTable{ var _Adlam = &RangeTable{ R16: []Range16{}, R32: []Range32{ - {0x1e900, 0x1e94a, 1}, + {0x1e900, 0x1e94b, 1}, {0x1e950, 0x1e959, 1}, {0x1e95e, 0x1e95f, 1}, }, @@ -3939,7 +4007,8 @@ var _Common = &RangeTable{ {0x1cea, 0x1cec, 1}, {0x1cee, 0x1cf3, 1}, {0x1cf5, 0x1cf7, 1}, - {0x2000, 0x200b, 1}, + {0x1cfa, 0x2000, 774}, + {0x2001, 0x200b, 1}, {0x200e, 0x2064, 1}, {0x2066, 0x2070, 1}, {0x2074, 0x207e, 1}, @@ -3956,9 +4025,8 @@ var _Common = &RangeTable{ {0x2460, 0x27ff, 1}, {0x2900, 0x2b73, 1}, {0x2b76, 0x2b95, 1}, - {0x2b98, 0x2bc8, 1}, - {0x2bca, 0x2bfe, 1}, - {0x2e00, 0x2e4e, 1}, + {0x2b98, 0x2bff, 1}, + {0x2e00, 0x2e4f, 1}, {0x2ff0, 0x2ffb, 1}, {0x3000, 0x3004, 1}, {0x3006, 0x3008, 2}, @@ -4001,6 +4069,7 @@ var _Common = &RangeTable{ {0x10190, 0x1019b, 1}, {0x101d0, 0x101fc, 1}, {0x102e1, 0x102fb, 1}, + {0x16fe2, 0x16fe3, 1}, {0x1bca0, 0x1bca3, 1}, {0x1d000, 0x1d0f5, 1}, {0x1d100, 0x1d126, 1}, @@ -4034,6 +4103,7 @@ var _Common = &RangeTable{ {0x1d6a8, 0x1d7cb, 1}, {0x1d7ce, 0x1d7ff, 1}, {0x1ec71, 0x1ecb4, 1}, + {0x1ed01, 0x1ed3d, 1}, {0x1f000, 0x1f02b, 1}, {0x1f030, 0x1f093, 1}, {0x1f0a0, 0x1f0ae, 1}, @@ -4041,7 +4111,7 @@ var _Common = &RangeTable{ {0x1f0c1, 0x1f0cf, 1}, {0x1f0d1, 0x1f0f5, 1}, {0x1f100, 0x1f10c, 1}, - {0x1f110, 0x1f16b, 1}, + {0x1f110, 0x1f16c, 1}, {0x1f170, 0x1f1ac, 1}, {0x1f1e6, 0x1f1ff, 1}, {0x1f201, 0x1f202, 1}, @@ -4049,26 +4119,29 @@ var _Common = &RangeTable{ {0x1f240, 0x1f248, 1}, {0x1f250, 0x1f251, 1}, {0x1f260, 0x1f265, 1}, - {0x1f300, 0x1f6d4, 1}, + {0x1f300, 0x1f6d5, 1}, {0x1f6e0, 0x1f6ec, 1}, - {0x1f6f0, 0x1f6f9, 1}, + {0x1f6f0, 0x1f6fa, 1}, {0x1f700, 0x1f773, 1}, {0x1f780, 0x1f7d8, 1}, + {0x1f7e0, 0x1f7eb, 1}, {0x1f800, 0x1f80b, 1}, {0x1f810, 0x1f847, 1}, {0x1f850, 0x1f859, 1}, {0x1f860, 0x1f887, 1}, {0x1f890, 0x1f8ad, 1}, {0x1f900, 0x1f90b, 1}, - {0x1f910, 0x1f93e, 1}, - {0x1f940, 0x1f970, 1}, + {0x1f90d, 0x1f971, 1}, {0x1f973, 0x1f976, 1}, - {0x1f97a, 0x1f97c, 2}, - {0x1f97d, 0x1f9a2, 1}, - {0x1f9b0, 0x1f9b9, 1}, - {0x1f9c0, 0x1f9c2, 1}, - {0x1f9d0, 0x1f9ff, 1}, + {0x1f97a, 0x1f9a2, 1}, + {0x1f9a5, 0x1f9aa, 1}, + {0x1f9ae, 0x1f9ca, 1}, + {0x1f9cd, 0x1fa53, 1}, {0x1fa60, 0x1fa6d, 1}, + {0x1fa70, 0x1fa73, 1}, + {0x1fa78, 0x1fa7a, 1}, + {0x1fa80, 0x1fa82, 1}, + {0x1fa90, 0x1fa95, 1}, {0xe0001, 0xe0020, 31}, {0xe0021, 0xe007f, 1}, }, @@ -4126,7 +4199,7 @@ var _Deseret = &RangeTable{ var _Devanagari = &RangeTable{ R16: []Range16{ {0x0900, 0x0950, 1}, - {0x0953, 0x0963, 1}, + {0x0955, 0x0963, 1}, {0x0966, 0x097f, 1}, {0xa8e0, 0xa8ff, 1}, }, @@ -4154,6 +4227,7 @@ var _Egyptian_Hieroglyphs = &RangeTable{ R16: []Range16{}, R32: []Range32{ {0x13000, 0x1342e, 1}, + {0x13430, 0x13438, 1}, }, } @@ -4164,6 +4238,13 @@ var _Elbasan = &RangeTable{ }, } +var _Elymaic = &RangeTable{ + R16: []Range16{}, + R32: []Range32{ + {0x10fe0, 0x10ff6, 1}, + }, +} + var _Ethiopic = &RangeTable{ R16: []Range16{ {0x1200, 0x1248, 1}, @@ -4432,6 +4513,7 @@ var _Hiragana = &RangeTable{ }, R32: []Range32{ {0x1b001, 0x1b11e, 1}, + {0x1b150, 0x1b152, 1}, {0x1f200, 0x1f200, 1}, }, } @@ -4450,8 +4532,8 @@ var _Inherited = &RangeTable{ {0x0485, 0x0486, 1}, {0x064b, 0x0655, 1}, {0x0670, 0x0951, 737}, - {0x0952, 0x1ab0, 4446}, - {0x1ab1, 0x1abe, 1}, + {0x0952, 0x0954, 1}, + {0x1ab0, 0x1abe, 1}, {0x1cd0, 0x1cd2, 1}, {0x1cd4, 0x1ce0, 1}, {0x1ce2, 0x1ce8, 1}, @@ -4538,7 +4620,8 @@ var _Katakana = &RangeTable{ {0xff71, 0xff9d, 1}, }, R32: []Range32{ - {0x1b000, 0x1b000, 1}, + {0x1b000, 0x1b164, 356}, + {0x1b165, 0x1b167, 1}, }, } @@ -4591,16 +4674,11 @@ var _Khudawadi = &RangeTable{ var _Lao = &RangeTable{ R16: []Range16{ {0x0e81, 0x0e82, 1}, - {0x0e84, 0x0e87, 3}, - {0x0e88, 0x0e8a, 2}, - {0x0e8d, 0x0e94, 7}, - {0x0e95, 0x0e97, 1}, - {0x0e99, 0x0e9f, 1}, - {0x0ea1, 0x0ea3, 1}, + {0x0e84, 0x0e86, 2}, + {0x0e87, 0x0e8a, 1}, + {0x0e8c, 0x0ea3, 1}, {0x0ea5, 0x0ea7, 2}, - {0x0eaa, 0x0eab, 1}, - {0x0ead, 0x0eb9, 1}, - {0x0ebb, 0x0ebd, 1}, + {0x0ea8, 0x0ebd, 1}, {0x0ec0, 0x0ec4, 1}, {0x0ec6, 0x0ec8, 2}, {0x0ec9, 0x0ecd, 1}, @@ -4631,10 +4709,12 @@ var _Latin = &RangeTable{ {0x2160, 0x2188, 1}, {0x2c60, 0x2c7f, 1}, {0xa722, 0xa787, 1}, - {0xa78b, 0xa7b9, 1}, + {0xa78b, 0xa7bf, 1}, + {0xa7c2, 0xa7c6, 1}, {0xa7f7, 0xa7ff, 1}, {0xab30, 0xab5a, 1}, {0xab5c, 0xab64, 1}, + {0xab66, 0xab67, 1}, {0xfb00, 0xfb06, 1}, {0xff21, 0xff3a, 1}, {0xff41, 0xff5a, 1}, @@ -4809,8 +4889,8 @@ var _Meroitic_Hieroglyphs = &RangeTable{ var _Miao = &RangeTable{ R16: []Range16{}, R32: []Range32{ - {0x16f00, 0x16f44, 1}, - {0x16f50, 0x16f7e, 1}, + {0x16f00, 0x16f4a, 1}, + {0x16f4f, 0x16f87, 1}, {0x16f8f, 0x16f9f, 1}, }, } @@ -4873,6 +4953,15 @@ var _Nabataean = &RangeTable{ }, } +var _Nandinagari = &RangeTable{ + R16: []Range16{}, + R32: []Range32{ + {0x119a0, 0x119a7, 1}, + {0x119aa, 0x119d7, 1}, + {0x119da, 0x119e4, 1}, + }, +} + var _New_Tai_Lue = &RangeTable{ R16: []Range16{ {0x1980, 0x19ab, 1}, @@ -4887,7 +4976,7 @@ var _Newa = &RangeTable{ R32: []Range32{ {0x11400, 0x11459, 1}, {0x1145b, 0x1145d, 2}, - {0x1145e, 0x1145e, 1}, + {0x1145e, 0x1145f, 1}, }, } @@ -4906,6 +4995,16 @@ var _Nushu = &RangeTable{ }, } +var _Nyiakeng_Puachue_Hmong = &RangeTable{ + R16: []Range16{}, + R32: []Range32{ + {0x1e100, 0x1e12c, 1}, + {0x1e130, 0x1e13d, 1}, + {0x1e140, 0x1e149, 1}, + {0x1e14e, 0x1e14f, 1}, + }, +} + var _Ogham = &RangeTable{ R16: []Range16{ {0x1680, 0x169c, 1}, @@ -5159,8 +5258,7 @@ var _Sora_Sompeng = &RangeTable{ var _Soyombo = &RangeTable{ R16: []Range16{}, R32: []Range32{ - {0x11a50, 0x11a83, 1}, - {0x11a86, 0x11aa2, 1}, + {0x11a50, 0x11aa2, 1}, }, } @@ -5228,7 +5326,7 @@ var _Tai_Viet = &RangeTable{ var _Takri = &RangeTable{ R16: []Range16{}, R32: []Range32{ - {0x11680, 0x116b7, 1}, + {0x11680, 0x116b8, 1}, {0x116c0, 0x116c9, 1}, }, } @@ -5251,13 +5349,17 @@ var _Tamil = &RangeTable{ {0x0bd0, 0x0bd7, 7}, {0x0be6, 0x0bfa, 1}, }, + R32: []Range32{ + {0x11fc0, 0x11ff1, 1}, + {0x11fff, 0x11fff, 1}, + }, } var _Tangut = &RangeTable{ R16: []Range16{}, R32: []Range32{ {0x16fe0, 0x17000, 32}, - {0x17001, 0x187f1, 1}, + {0x17001, 0x187f7, 1}, {0x18800, 0x18af2, 1}, }, } @@ -5275,7 +5377,7 @@ var _Telugu = &RangeTable{ {0x0c58, 0x0c5a, 1}, {0x0c60, 0x0c63, 1}, {0x0c66, 0x0c6f, 1}, - {0x0c78, 0x0c7f, 1}, + {0x0c77, 0x0c7f, 1}, }, } @@ -5334,6 +5436,14 @@ var _Vai = &RangeTable{ }, } +var _Wancho = &RangeTable{ + R16: []Range16{}, + R32: []Range32{ + {0x1e2c0, 0x1e2f9, 1}, + {0x1e2ff, 0x1e2ff, 1}, + }, +} + var _Warang_Citi = &RangeTable{ R16: []Range16{}, R32: []Range32{ @@ -5392,6 +5502,7 @@ var ( Duployan = _Duployan // Duployan is the set of Unicode characters in script Duployan. Egyptian_Hieroglyphs = _Egyptian_Hieroglyphs // Egyptian_Hieroglyphs is the set of Unicode characters in script Egyptian_Hieroglyphs. Elbasan = _Elbasan // Elbasan is the set of Unicode characters in script Elbasan. + Elymaic = _Elymaic // Elymaic is the set of Unicode characters in script Elymaic. Ethiopic = _Ethiopic // Ethiopic is the set of Unicode characters in script Ethiopic. Georgian = _Georgian // Georgian is the set of Unicode characters in script Georgian. Glagolitic = _Glagolitic // Glagolitic is the set of Unicode characters in script Glagolitic. @@ -5449,10 +5560,12 @@ var ( Multani = _Multani // Multani is the set of Unicode characters in script Multani. Myanmar = _Myanmar // Myanmar is the set of Unicode characters in script Myanmar. Nabataean = _Nabataean // Nabataean is the set of Unicode characters in script Nabataean. + Nandinagari = _Nandinagari // Nandinagari is the set of Unicode characters in script Nandinagari. New_Tai_Lue = _New_Tai_Lue // New_Tai_Lue is the set of Unicode characters in script New_Tai_Lue. Newa = _Newa // Newa is the set of Unicode characters in script Newa. Nko = _Nko // Nko is the set of Unicode characters in script Nko. Nushu = _Nushu // Nushu is the set of Unicode characters in script Nushu. + Nyiakeng_Puachue_Hmong = _Nyiakeng_Puachue_Hmong // Nyiakeng_Puachue_Hmong is the set of Unicode characters in script Nyiakeng_Puachue_Hmong. Ogham = _Ogham // Ogham is the set of Unicode characters in script Ogham. Ol_Chiki = _Ol_Chiki // Ol_Chiki is the set of Unicode characters in script Ol_Chiki. Old_Hungarian = _Old_Hungarian // Old_Hungarian is the set of Unicode characters in script Old_Hungarian. @@ -5503,6 +5616,7 @@ var ( Tirhuta = _Tirhuta // Tirhuta is the set of Unicode characters in script Tirhuta. Ugaritic = _Ugaritic // Ugaritic is the set of Unicode characters in script Ugaritic. Vai = _Vai // Vai is the set of Unicode characters in script Vai. + Wancho = _Wancho // Wancho is the set of Unicode characters in script Wancho. Warang_Citi = _Warang_Citi // Warang_Citi is the set of Unicode characters in script Warang_Citi. Yi = _Yi // Yi is the set of Unicode characters in script Yi. Zanabazar_Square = _Zanabazar_Square // Zanabazar_Square is the set of Unicode characters in script Zanabazar_Square. @@ -5637,8 +5751,8 @@ var _Diacritic = &RangeTable{ {0x0d3b, 0x0d3c, 1}, {0x0d4d, 0x0e47, 125}, {0x0e48, 0x0e4c, 1}, - {0x0e4e, 0x0ec8, 122}, - {0x0ec9, 0x0ecc, 1}, + {0x0e4e, 0x0eba, 108}, + {0x0ec8, 0x0ecc, 1}, {0x0f18, 0x0f19, 1}, {0x0f35, 0x0f39, 2}, {0x0f3e, 0x0f3f, 1}, @@ -5646,10 +5760,13 @@ var _Diacritic = &RangeTable{ {0x0f86, 0x0f87, 1}, {0x0fc6, 0x1037, 113}, {0x1039, 0x103a, 1}, + {0x1063, 0x1064, 1}, + {0x1069, 0x106d, 1}, {0x1087, 0x108d, 1}, {0x108f, 0x109a, 11}, - {0x109b, 0x17c9, 1838}, - {0x17ca, 0x17d3, 1}, + {0x109b, 0x135d, 706}, + {0x135e, 0x135f, 1}, + {0x17c9, 0x17d3, 1}, {0x17dd, 0x1939, 348}, {0x193a, 0x193b, 1}, {0x1a75, 0x1a7c, 1}, @@ -5681,11 +5798,12 @@ var _Diacritic = &RangeTable{ {0xa67c, 0xa67d, 1}, {0xa67f, 0xa69c, 29}, {0xa69d, 0xa6f0, 83}, - {0xa6f1, 0xa717, 38}, - {0xa718, 0xa721, 1}, - {0xa788, 0xa7f8, 112}, - {0xa7f9, 0xa8c4, 203}, - {0xa8e0, 0xa8f1, 1}, + {0xa6f1, 0xa700, 15}, + {0xa701, 0xa721, 1}, + {0xa788, 0xa78a, 1}, + {0xa7f8, 0xa7f9, 1}, + {0xa8c4, 0xa8e0, 28}, + {0xa8e1, 0xa8f1, 1}, {0xa92b, 0xa92e, 1}, {0xa953, 0xa9b3, 96}, {0xa9c0, 0xa9e5, 37}, @@ -5720,17 +5838,21 @@ var _Diacritic = &RangeTable{ {0x1163f, 0x116b6, 119}, {0x116b7, 0x1172b, 116}, {0x11839, 0x1183a, 1}, - {0x11a34, 0x11a47, 19}, - {0x11a99, 0x11c3f, 422}, - {0x11d42, 0x11d44, 2}, - {0x11d45, 0x11d97, 82}, - {0x16af0, 0x16af4, 1}, + {0x119e0, 0x11a34, 84}, + {0x11a47, 0x11a99, 82}, + {0x11c3f, 0x11d42, 259}, + {0x11d44, 0x11d45, 1}, + {0x11d97, 0x16af0, 19801}, + {0x16af1, 0x16af4, 1}, + {0x16b30, 0x16b36, 1}, {0x16f8f, 0x16f9f, 1}, {0x1d167, 0x1d169, 1}, {0x1d16d, 0x1d172, 1}, {0x1d17b, 0x1d182, 1}, {0x1d185, 0x1d18b, 1}, {0x1d1aa, 0x1d1ad, 1}, + {0x1e130, 0x1e136, 1}, + {0x1e2ec, 0x1e2ef, 1}, {0x1e8d0, 0x1e8d6, 1}, {0x1e944, 0x1e946, 1}, {0x1e948, 0x1e94a, 1}, @@ -5761,8 +5883,9 @@ var _Extender = &RangeTable{ {0x115c7, 0x115c8, 1}, {0x11a98, 0x16b42, 20650}, {0x16b43, 0x16fe0, 1181}, - {0x16fe1, 0x1e944, 31075}, - {0x1e945, 0x1e946, 1}, + {0x16fe1, 0x16fe3, 2}, + {0x1e13c, 0x1e13d, 1}, + {0x1e944, 0x1e946, 1}, }, } @@ -5814,7 +5937,7 @@ var _Ideographic = &RangeTable{ {0xfa70, 0xfad9, 1}, }, R32: []Range32{ - {0x17000, 0x187f1, 1}, + {0x17000, 0x187f7, 1}, {0x18800, 0x18af2, 1}, {0x1b170, 0x1b2fb, 1}, {0x20000, 0x2a6d6, 1}, @@ -5963,17 +6086,17 @@ var _Other_Alphabetic = &RangeTable{ {0x103c, 0x103e, 1}, {0x1056, 0x1059, 1}, {0x105e, 0x1060, 1}, - {0x1062, 0x1067, 5}, - {0x1068, 0x1071, 9}, - {0x1072, 0x1074, 1}, - {0x1082, 0x1086, 1}, - {0x109c, 0x109d, 1}, - {0x135f, 0x1712, 947}, - {0x1713, 0x1732, 31}, - {0x1733, 0x1752, 31}, - {0x1753, 0x1772, 31}, - {0x1773, 0x17b6, 67}, - {0x17b7, 0x17c8, 1}, + {0x1062, 0x1064, 1}, + {0x1067, 0x106d, 1}, + {0x1071, 0x1074, 1}, + {0x1082, 0x108d, 1}, + {0x108f, 0x109a, 11}, + {0x109b, 0x109d, 1}, + {0x1712, 0x1713, 1}, + {0x1732, 0x1733, 1}, + {0x1752, 0x1753, 1}, + {0x1772, 0x1773, 1}, + {0x17b6, 0x17c8, 1}, {0x1885, 0x1886, 1}, {0x18a9, 0x1920, 119}, {0x1921, 0x192b, 1}, @@ -5987,25 +6110,28 @@ var _Other_Alphabetic = &RangeTable{ {0x1ba1, 0x1ba9, 1}, {0x1bac, 0x1bad, 1}, {0x1be7, 0x1bf1, 1}, - {0x1c24, 0x1c35, 1}, - {0x1cf2, 0x1cf3, 1}, + {0x1c24, 0x1c36, 1}, {0x1de7, 0x1df4, 1}, {0x24b6, 0x24e9, 1}, {0x2de0, 0x2dff, 1}, {0xa674, 0xa67b, 1}, {0xa69e, 0xa69f, 1}, + {0xa802, 0xa80b, 9}, {0xa823, 0xa827, 1}, {0xa880, 0xa881, 1}, {0xa8b4, 0xa8c3, 1}, - {0xa8c5, 0xa926, 97}, - {0xa927, 0xa92a, 1}, + {0xa8c5, 0xa8ff, 58}, + {0xa926, 0xa92a, 1}, {0xa947, 0xa952, 1}, {0xa980, 0xa983, 1}, {0xa9b4, 0xa9bf, 1}, - {0xaa29, 0xaa36, 1}, + {0xa9e5, 0xaa29, 68}, + {0xaa2a, 0xaa36, 1}, {0xaa43, 0xaa4c, 9}, - {0xaa4d, 0xaab0, 99}, - {0xaab2, 0xaab4, 1}, + {0xaa4d, 0xaa7b, 46}, + {0xaa7c, 0xaa7d, 1}, + {0xaab0, 0xaab2, 2}, + {0xaab3, 0xaab4, 1}, {0xaab7, 0xaab8, 1}, {0xaabe, 0xaaeb, 45}, {0xaaec, 0xaaef, 1}, @@ -6048,7 +6174,10 @@ var _Other_Alphabetic = &RangeTable{ {0x116ac, 0x116b5, 1}, {0x1171d, 0x1172a, 1}, {0x1182c, 0x11838, 1}, - {0x11a01, 0x11a0a, 1}, + {0x119d1, 0x119d7, 1}, + {0x119da, 0x119df, 1}, + {0x119e4, 0x11a01, 29}, + {0x11a02, 0x11a0a, 1}, {0x11a35, 0x11a39, 1}, {0x11a3b, 0x11a3e, 1}, {0x11a51, 0x11a5b, 1}, @@ -6066,8 +6195,9 @@ var _Other_Alphabetic = &RangeTable{ {0x11d90, 0x11d91, 1}, {0x11d93, 0x11d96, 1}, {0x11ef3, 0x11ef6, 1}, - {0x16b30, 0x16b36, 1}, - {0x16f51, 0x16f7e, 1}, + {0x16f4f, 0x16f51, 2}, + {0x16f52, 0x16f87, 1}, + {0x16f8f, 0x16f92, 1}, {0x1bc9e, 0x1e000, 9058}, {0x1e001, 0x1e006, 1}, {0x1e008, 0x1e018, 1}, @@ -6105,9 +6235,10 @@ var _Other_Grapheme_Extend = &RangeTable{ {0x0cc2, 0x0cd5, 19}, {0x0cd6, 0x0d3e, 104}, {0x0d57, 0x0dcf, 120}, - {0x0ddf, 0x200c, 4653}, - {0x302e, 0x302f, 1}, - {0xff9e, 0xff9f, 1}, + {0x0ddf, 0x1b35, 3414}, + {0x200c, 0x302e, 4130}, + {0x302f, 0xff9e, 53103}, + {0xff9f, 0xff9f, 1}, }, R32: []Range32{ {0x1133e, 0x11357, 25}, @@ -6495,8 +6626,8 @@ var _Terminal_Punctuation = &RangeTable{ {0x0f0d, 0x0f12, 1}, {0x104a, 0x104b, 1}, {0x1361, 0x1368, 1}, - {0x166d, 0x166e, 1}, - {0x16eb, 0x16ed, 1}, + {0x166e, 0x16eb, 125}, + {0x16ec, 0x16ed, 1}, {0x1735, 0x1736, 1}, {0x17d4, 0x17d6, 1}, {0x17da, 0x1802, 40}, @@ -6512,10 +6643,10 @@ var _Terminal_Punctuation = &RangeTable{ {0x2047, 0x2049, 1}, {0x2e2e, 0x2e3c, 14}, {0x2e41, 0x2e4c, 11}, - {0x2e4e, 0x3001, 435}, - {0x3002, 0xa4fe, 29948}, - {0xa4ff, 0xa60d, 270}, - {0xa60e, 0xa60f, 1}, + {0x2e4e, 0x2e4f, 1}, + {0x3001, 0x3002, 1}, + {0xa4fe, 0xa4ff, 1}, + {0xa60d, 0xa60f, 1}, {0xa6f3, 0xa6f7, 1}, {0xa876, 0xa877, 1}, {0xa8ce, 0xa8cf, 1}, @@ -6764,6 +6895,7 @@ var _CaseRanges = []CaseRange{ {0x0275, 0x0275, d{-214, 0, -214}}, {0x027D, 0x027D, d{10727, 0, 10727}}, {0x0280, 0x0280, d{-218, 0, -218}}, + {0x0282, 0x0282, d{42307, 0, 42307}}, {0x0283, 0x0283, d{-218, 0, -218}}, {0x0287, 0x0287, d{42282, 0, 42282}}, {0x0288, 0x0288, d{-218, 0, -218}}, @@ -6840,6 +6972,7 @@ var _CaseRanges = []CaseRange{ {0x1CBD, 0x1CBF, d{0, -3008, 0}}, {0x1D79, 0x1D79, d{35332, 0, 35332}}, {0x1D7D, 0x1D7D, d{3814, 0, 3814}}, + {0x1D8E, 0x1D8E, d{35384, 0, 35384}}, {0x1E00, 0x1E95, d{UpperLower, UpperLower, UpperLower}}, {0x1E9B, 0x1E9B, d{-59, 0, -59}}, {0x1E9E, 0x1E9E, d{0, -7615, 0}}, @@ -6939,6 +7072,7 @@ var _CaseRanges = []CaseRange{ {0xA78B, 0xA78C, d{UpperLower, UpperLower, UpperLower}}, {0xA78D, 0xA78D, d{0, -42280, 0}}, {0xA790, 0xA793, d{UpperLower, UpperLower, UpperLower}}, + {0xA794, 0xA794, d{48, 0, 48}}, {0xA796, 0xA7A9, d{UpperLower, UpperLower, UpperLower}}, {0xA7AA, 0xA7AA, d{0, -42308, 0}}, {0xA7AB, 0xA7AB, d{0, -42319, 0}}, @@ -6949,7 +7083,11 @@ var _CaseRanges = []CaseRange{ {0xA7B1, 0xA7B1, d{0, -42282, 0}}, {0xA7B2, 0xA7B2, d{0, -42261, 0}}, {0xA7B3, 0xA7B3, d{0, 928, 0}}, - {0xA7B4, 0xA7B9, d{UpperLower, UpperLower, UpperLower}}, + {0xA7B4, 0xA7BF, d{UpperLower, UpperLower, UpperLower}}, + {0xA7C2, 0xA7C3, d{UpperLower, UpperLower, UpperLower}}, + {0xA7C4, 0xA7C4, d{0, -48, 0}}, + {0xA7C5, 0xA7C5, d{0, -42307, 0}}, + {0xA7C6, 0xA7C6, d{0, -35384, 0}}, {0xAB53, 0xAB53, d{-928, 0, -928}}, {0xAB70, 0xABBF, d{-38864, 0, -38864}}, {0xFF21, 0xFF3A, d{0, 32, 0}}, @@ -7571,7 +7709,9 @@ var foldLl = &RangeTable{ {0xa796, 0xa7aa, 2}, {0xa7ab, 0xa7ae, 1}, {0xa7b0, 0xa7b4, 1}, - {0xa7b6, 0xa7b8, 2}, + {0xa7b6, 0xa7be, 2}, + {0xa7c2, 0xa7c4, 2}, + {0xa7c5, 0xa7c6, 1}, {0xff21, 0xff3a, 1}, }, R32: []Range32{ @@ -7642,7 +7782,8 @@ var foldLu = &RangeTable{ {0x0269, 0x026c, 1}, {0x026f, 0x0271, 2}, {0x0272, 0x0275, 3}, - {0x027d, 0x0283, 3}, + {0x027d, 0x0280, 3}, + {0x0282, 0x0283, 1}, {0x0287, 0x028c, 1}, {0x0292, 0x029d, 11}, {0x029e, 0x0345, 167}, @@ -7667,7 +7808,8 @@ var foldLu = &RangeTable{ {0x13f8, 0x13fd, 1}, {0x1c80, 0x1c88, 1}, {0x1d79, 0x1d7d, 4}, - {0x1e01, 0x1e95, 2}, + {0x1d8e, 0x1e01, 115}, + {0x1e03, 0x1e95, 2}, {0x1e9b, 0x1ea1, 6}, {0x1ea3, 0x1eff, 2}, {0x1f00, 0x1f07, 1}, @@ -7699,11 +7841,11 @@ var foldLu = &RangeTable{ {0xa77a, 0xa77c, 2}, {0xa77f, 0xa787, 2}, {0xa78c, 0xa791, 5}, - {0xa793, 0xa797, 4}, - {0xa799, 0xa7a9, 2}, - {0xa7b5, 0xa7b9, 2}, - {0xab53, 0xab70, 29}, - {0xab71, 0xabbf, 1}, + {0xa793, 0xa794, 1}, + {0xa797, 0xa7a9, 2}, + {0xa7b5, 0xa7bf, 2}, + {0xa7c3, 0xab53, 912}, + {0xab70, 0xabbf, 1}, {0xff41, 0xff5a, 1}, }, R32: []Range32{ @@ -7760,7 +7902,7 @@ var foldInherited = &RangeTable{ }, } -// Range entries: 3480 16-bit, 1632 32-bit, 5112 total. -// Range bytes: 20880 16-bit, 19584 32-bit, 40464 total. +// Range entries: 3483 16-bit, 1730 32-bit, 5213 total. +// Range bytes: 20898 16-bit, 20760 32-bit, 41658 total. // Fold orbit bytes: 88 pairs, 352 bytes diff --git a/libgo/go/unicode/utf8/utf8.go b/libgo/go/unicode/utf8/utf8.go index eae4ead0dae..b722a039239 100644 --- a/libgo/go/unicode/utf8/utf8.go +++ b/libgo/go/unicode/utf8/utf8.go @@ -4,6 +4,7 @@ // Package utf8 implements functions and constants to support text encoded in // UTF-8. It includes functions to translate between runes and UTF-8 byte sequences. +// See https://en.wikipedia.org/wiki/UTF-8 package utf8 // The conditions RuneError==unicode.ReplacementChar and diff --git a/libgo/gotool-packages.txt b/libgo/gotool-packages.txt index b5a3bbda3b8..90521ae0b50 100644 --- a/libgo/gotool-packages.txt +++ b/libgo/gotool-packages.txt @@ -5,7 +5,6 @@ cmd/go/internal/cache cmd/go/internal/cfg cmd/go/internal/clean cmd/go/internal/cmdflag -cmd/go/internal/dirhash cmd/go/internal/doc cmd/go/internal/envcmd cmd/go/internal/fix @@ -22,23 +21,17 @@ cmd/go/internal/modcmd cmd/go/internal/modconv cmd/go/internal/modfetch cmd/go/internal/modfetch/codehost -cmd/go/internal/modfile cmd/go/internal/modget cmd/go/internal/modinfo cmd/go/internal/modload -cmd/go/internal/module cmd/go/internal/mvs -cmd/go/internal/note cmd/go/internal/par cmd/go/internal/renameio cmd/go/internal/robustio cmd/go/internal/run cmd/go/internal/search -cmd/go/internal/semver cmd/go/internal/str -cmd/go/internal/sumweb cmd/go/internal/test -cmd/go/internal/tlog cmd/go/internal/tool cmd/go/internal/txtar cmd/go/internal/version @@ -47,10 +40,22 @@ cmd/go/internal/web cmd/go/internal/work cmd/internal/browser cmd/internal/buildid +cmd/internal/diff cmd/internal/edit cmd/internal/objabi cmd/internal/sys cmd/internal/test2json +golang.org/x/crypto/ed25519 +golang.org/x/crypto/ed25519/internal/edwards25519 +golang.org/x/mod/internal/lazyregexp +golang.org/x/mod/modfile +golang.org/x/mod/module +golang.org/x/mod/semver +golang.org/x/mod/sumdb +golang.org/x/mod/sumdb/dirhash +golang.org/x/mod/sumdb/note +golang.org/x/mod/sumdb/tlog +golang.org/x/mod/zip golang.org/x/tools/go/analysis golang.org/x/tools/go/analysis/internal/analysisflags golang.org/x/tools/go/analysis/internal/facts @@ -86,3 +91,5 @@ golang.org/x/tools/go/ast/inspector golang.org/x/tools/go/cfg golang.org/x/tools/go/types/objectpath golang.org/x/tools/go/types/typeutil +golang.org/x/xerrors +golang.org/x/xerrors/internal diff --git a/libgo/libgo-packages.txt b/libgo/libgo-packages.txt index b19747a05b9..2b5fba806c6 100644 --- a/libgo/libgo-packages.txt +++ b/libgo/libgo-packages.txt @@ -72,12 +72,12 @@ go/printer go/scanner go/token go/types +golang.org/x/crypto/chacha20 golang.org/x/crypto/chacha20poly1305 golang.org/x/crypto/cryptobyte golang.org/x/crypto/cryptobyte/asn1 golang.org/x/crypto/curve25519 golang.org/x/crypto/hkdf -golang.org/x/crypto/internal/chacha20 golang.org/x/crypto/internal/subtle golang.org/x/crypto/poly1305 golang.org/x/net/dns/dnsmessage @@ -96,6 +96,7 @@ hash/adler32 hash/crc32 hash/crc64 hash/fnv +hash/maphash html html/template image @@ -116,6 +117,7 @@ internal/goversion internal/lazyregexp internal/lazytemplate internal/nettrace +internal/obscuretestdata internal/oserror internal/poll internal/race diff --git a/libgo/match.sh b/libgo/match.sh index 281acf7ae13..cd35942f8bc 100755 --- a/libgo/match.sh +++ b/libgo/match.sh @@ -113,7 +113,7 @@ for f in $gofiles; do "") ;; $goarch) ;; $goos) ;; - aix | android | darwin | dragonfly | freebsd | hurd | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) + aix | android | darwin | dragonfly | freebsd | illumos | hurd | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag1=nonmatchingtag ;; 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) @@ -125,7 +125,7 @@ for f in $gofiles; do "") ;; $goarch) ;; $goos) ;; - aix | android | darwin | dragonfly | freebsd | hurd | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) + aix | android | darwin | dragonfly | freebsd | hurd | illumos | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag2=nonmatchingtag ;; 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le | nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) diff --git a/libgo/merge.sh b/libgo/merge.sh index 7138891cd61..b15189e5c4a 100755 --- a/libgo/merge.sh +++ b/libgo/merge.sh @@ -128,7 +128,7 @@ echo ${rev} > VERSION (cd ${NEWDIR}/src && find . -name '*.go' -print) | while read f; do skip=false case "$f" in - ./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/testjson/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/testj2on/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/* ) + ./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/testjson/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/testj2on/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/* | ./cmd/vendor/golang.org/x/mod/* | ./cmd/vendor/golang.org/x/xerrors/* | ./cmd/vendor/golang.org/x/crypto/ed25519) ;; ./cmd/*) skip=true @@ -150,7 +150,7 @@ done (cd ${NEWDIR}/src && find . -name testdata -print) | while read d; do skip=false case "$d" in - ./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/testjson/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/testj2on/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/* ) + ./cmd/buildid/* | ./cmd/cgo/* | ./cmd/go/* | ./cmd/gofmt/* | ./cmd/testjson/* | ./cmd/vet/* | ./cmd/internal/browser/* | ./cmd/internal/buildid/* | ./cmd/internal/diff/* | | ./cmd/internal/edit/* | ./cmd/internal/objabi/* | ./cmd/internal/testj2on/* | ./cmd/internal/sys/* | ./cmd/vendor/golang.org/x/tools/* ) ;; ./cmd/*) skip=true @@ -165,7 +165,7 @@ done oldtd=${OLDDIR}/src/$d newtd=${NEWDIR}/src/$d - libgofile=go/`echo $d | sed -e 's|cmd/vendor/|/|' | sed -e 's|/vendor/|/|'` + libgotd=go/`echo $d | sed -e 's|cmd/vendor/|/|' | sed -e 's|/vendor/|/|'` if ! test -d ${oldtd}; then echo "merge.sh: $d: NEWDIR" continue diff --git a/libgo/misc/cgo/fortran/test.bash b/libgo/misc/cgo/fortran/test.bash index 9498da0208f..2b61730815f 100644 --- a/libgo/misc/cgo/fortran/test.bash +++ b/libgo/misc/cgo/fortran/test.bash @@ -28,7 +28,7 @@ case "$FC" in ;; esac -if ! $FC helloworld/helloworld.f90 -o main.exe >& /dev/null; then +if ! $FC helloworld/helloworld.f90 -o /dev/null >& /dev/null; then echo "skipping Fortran test: could not build helloworld.f90 with $FC" exit 0 fi diff --git a/libgo/misc/cgo/life/overlaydir_test.go b/libgo/misc/cgo/life/overlaydir_test.go index f381ea62f3b..034c836248d 100644 --- a/libgo/misc/cgo/life/overlaydir_test.go +++ b/libgo/misc/cgo/life/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/misc/cgo/stdio/overlaydir_test.go b/libgo/misc/cgo/stdio/overlaydir_test.go index 8a8dcdb3a5a..027ebf17c3f 100644 --- a/libgo/misc/cgo/stdio/overlaydir_test.go +++ b/libgo/misc/cgo/stdio/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/misc/cgo/test/cgo_test.go b/libgo/misc/cgo/test/cgo_test.go index c66df2cd461..b745a4417f1 100644 --- a/libgo/misc/cgo/test/cgo_test.go +++ b/libgo/misc/cgo/test/cgo_test.go @@ -58,6 +58,7 @@ func Test27660(t *testing.T) { test27660(t) } func Test28896(t *testing.T) { test28896(t) } func Test30065(t *testing.T) { test30065(t) } func Test32579(t *testing.T) { test32579(t) } +func Test31891(t *testing.T) { test31891(t) } func TestAlign(t *testing.T) { testAlign(t) } func TestAtol(t *testing.T) { testAtol(t) } func TestBlocking(t *testing.T) { testBlocking(t) } @@ -91,5 +92,6 @@ func TestThreadLock(t *testing.T) { testThreadLockFunc(t) } func TestUnsignedInt(t *testing.T) { testUnsignedInt(t) } func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) } -func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } -func BenchmarkGoString(b *testing.B) { benchGoString(b) } +func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } +func BenchmarkGoString(b *testing.B) { benchGoString(b) } +func BenchmarkCGoCallback(b *testing.B) { benchCallback(b) } diff --git a/libgo/misc/cgo/test/issue31891.c b/libgo/misc/cgo/test/issue31891.c new file mode 100644 index 00000000000..67a0dda2d68 --- /dev/null +++ b/libgo/misc/cgo/test/issue31891.c @@ -0,0 +1,13 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "_cgo_export.h" + +void callIssue31891() { + Issue31891A a; + useIssue31891A(&a); + + Issue31891B b; + useIssue31891B(&b); +} diff --git a/libgo/misc/cgo/test/issue8945.go b/libgo/misc/cgo/test/issue8945.go deleted file mode 100644 index 57a5b2db44b..00000000000 --- a/libgo/misc/cgo/test/issue8945.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gccgo - -package cgotest - -//typedef void (*PFunc)(); -//PFunc success_cb; -import "C" - -//export Test -func Test() { - _ = C.success_cb -} diff --git a/libgo/misc/cgo/test/overlaydir_test.go b/libgo/misc/cgo/test/overlaydir_test.go index 1b5c67de70f..f651979b657 100644 --- a/libgo/misc/cgo/test/overlaydir_test.go +++ b/libgo/misc/cgo/test/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/misc/cgo/test/test.go b/libgo/misc/cgo/test/test.go index 2d060bfeac4..b0148995fe5 100644 --- a/libgo/misc/cgo/test/test.go +++ b/libgo/misc/cgo/test/test.go @@ -115,6 +115,44 @@ int add(int x, int y) { return x+y; }; +// Following mimicks vulkan complex definitions for benchmarking cgocheck overhead. + +typedef uint32_t VkFlags; +typedef VkFlags VkDeviceQueueCreateFlags; +typedef uint32_t VkStructureType; + +typedef struct VkDeviceQueueCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueCount; + const float* pQueuePriorities; +} VkDeviceQueueCreateInfo; + +typedef struct VkPhysicalDeviceFeatures { + uint32_t bools[56]; +} VkPhysicalDeviceFeatures; + +typedef struct VkDeviceCreateInfo { + VkStructureType sType; + const void* pNext; + VkFlags flags; + uint32_t queueCreateInfoCount; + const VkDeviceQueueCreateInfo* pQueueCreateInfos; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; + const VkPhysicalDeviceFeatures* pEnabledFeatures; +} VkDeviceCreateInfo; + +void handleComplexPointer(VkDeviceCreateInfo *a0) {} +void handleComplexPointer8( + VkDeviceCreateInfo *a0, VkDeviceCreateInfo *a1, VkDeviceCreateInfo *a2, VkDeviceCreateInfo *a3, + VkDeviceCreateInfo *a4, VkDeviceCreateInfo *a5, VkDeviceCreateInfo *a6, VkDeviceCreateInfo *a7 +) {} + // complex alignment struct { @@ -524,6 +562,11 @@ void issue8811Execute() { issue8811Init(); } +// issue 8945 + +typedef void (*PFunc8945)(); +PFunc8945 func8945; + // issue 9557 struct issue9557_t { @@ -993,10 +1036,55 @@ type Context struct { } func benchCgoCall(b *testing.B) { - const x = C.int(2) - const y = C.int(3) + b.Run("add-int", func(b *testing.B) { + const x = C.int(2) + const y = C.int(3) + + for i := 0; i < b.N; i++ { + C.add(x, y) + } + }) + + b.Run("one-pointer", func(b *testing.B) { + var a0 C.VkDeviceCreateInfo + for i := 0; i < b.N; i++ { + C.handleComplexPointer(&a0) + } + }) + b.Run("eight-pointers", func(b *testing.B) { + var a0, a1, a2, a3, a4, a5, a6, a7 C.VkDeviceCreateInfo + for i := 0; i < b.N; i++ { + C.handleComplexPointer8(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7) + } + }) + b.Run("eight-pointers-nil", func(b *testing.B) { + var a0, a1, a2, a3, a4, a5, a6, a7 *C.VkDeviceCreateInfo + for i := 0; i < b.N; i++ { + C.handleComplexPointer8(a0, a1, a2, a3, a4, a5, a6, a7) + } + }) + b.Run("eight-pointers-array", func(b *testing.B) { + var a [8]C.VkDeviceCreateInfo + for i := 0; i < b.N; i++ { + C.handleComplexPointer8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]) + } + }) + b.Run("eight-pointers-slice", func(b *testing.B) { + a := make([]C.VkDeviceCreateInfo, 8) + for i := 0; i < b.N; i++ { + C.handleComplexPointer8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]) + } + }) +} + +// Benchmark measuring overhead from Go to C and back to Go (via a callback) +func benchCallback(b *testing.B) { + var x = false for i := 0; i < b.N; i++ { - C.add(x, y) + nestedCall(func() { x = true }) + } + if !x { + b.Fatal("nestedCall was not invoked") } } @@ -1956,12 +2044,14 @@ func test27660(t *testing.T) { locks[j].Lock() ints[j]++ locks[j].Unlock() - // Avoid making the loop unpreemptible - // for gccgo. - if i%0x1000000 == 0 { + // needed for gccgo, to avoid creation of an + // unpreemptible "fast path" in this loop. Choice + // of (1<<24) is somewhat arbitrary. + if i%(1<<24) == 0 { runtime.Gosched() } i++ + } }() time.Sleep(time.Millisecond) diff --git a/libgo/misc/cgo/test/testdata/issue9026/issue9026.go b/libgo/misc/cgo/test/testdata/issue9026/issue9026.go index 149c26562ad..ff269ca9eb0 100644 --- a/libgo/misc/cgo/test/testdata/issue9026/issue9026.go +++ b/libgo/misc/cgo/test/testdata/issue9026/issue9026.go @@ -4,9 +4,9 @@ package issue9026 // per-package counter used to create fresh identifiers. /* -typedef struct {} git_merge_file_input; +typedef struct { int i; } git_merge_file_input; -typedef struct {} git_merge_file_options; +typedef struct { int j; } git_merge_file_options; void git_merge_file( git_merge_file_input *in, @@ -29,7 +29,7 @@ func Test(t *testing.T) { // Brittle: the assertion may fail spuriously when the algorithm // changes, but should remain stable otherwise. got := fmt.Sprintf("%T %T", in, opts) - want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___0" + want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___1" if got != want { t.Errorf("Non-deterministic type names: got %s, want %s", got, want) } diff --git a/libgo/misc/cgo/test/testx.go b/libgo/misc/cgo/test/testx.go index 67def903aba..42979b5f4d5 100644 --- a/libgo/misc/cgo/test/testx.go +++ b/libgo/misc/cgo/test/testx.go @@ -102,12 +102,28 @@ static void issue7978c(uint32_t *sync) { // #include'd twice. No runtime test; just make sure it compiles. #include "issue8331.h" +// issue 8945 + +typedef void (*PFunc8945)(); +extern PFunc8945 func8945; // definition is in test.go + // issue 20910 void callMulti(void); // issue 28772 part 2 - part 1 in issuex.go #define issue28772Constant2 2 + +// issue 31891 +typedef struct { + long obj; +} Issue31891A; + +typedef struct { + long obj; +} Issue31891B; + +void callIssue31891(void); */ import "C" @@ -503,6 +519,13 @@ func test7978(t *testing.T) { var issue8331Var C.issue8331 +// issue 8945 + +//export Test8945 +func Test8945() { + _ = C.func8945 +} + // issue 20910 //export multi @@ -517,3 +540,15 @@ func test20910(t *testing.T) { // issue 28772 part 2 const issue28772Constant2 = C.issue28772Constant2 + +// issue 31891 + +//export useIssue31891A +func useIssue31891A(c *C.Issue31891A) {} + +//export useIssue31891B +func useIssue31891B(c *C.Issue31891B) {} + +func test31891(t *testing.T) { + C.callIssue31891() +} diff --git a/libgo/misc/cgo/testasan/main.go b/libgo/misc/cgo/testasan/main.go index 1837c6cc81d..bc77678c25a 100644 --- a/libgo/misc/cgo/testasan/main.go +++ b/libgo/misc/cgo/testasan/main.go @@ -36,14 +36,21 @@ thread(void *p) import "C" import ( + "fmt" + "os" + "path/filepath" "time" ) func main() { + start := time.Now() + // ensure that we can function normally var v [][]byte for i := 0; i < 1000; i++ { time.Sleep(10 * time.Microsecond) v = append(v, make([]byte, 64<<10)) } + + fmt.Printf("ok\t%s\t%s\n", filepath.Base(os.Args[0]), time.Since(start).Round(time.Millisecond)) } diff --git a/libgo/misc/cgo/testcarchive/carchive_test.go b/libgo/misc/cgo/testcarchive/carchive_test.go index 70516703d96..98cd41ab1d1 100644 --- a/libgo/misc/cgo/testcarchive/carchive_test.go +++ b/libgo/misc/cgo/testcarchive/carchive_test.go @@ -36,7 +36,10 @@ var exeSuffix string var GOOS, GOARCH, GOPATH string var libgodir string +var testWork bool // If true, preserve temporary directories. + func TestMain(m *testing.M) { + flag.BoolVar(&testWork, "testwork", false, "if true, log and preserve the test's temporary working directory") flag.Parse() if testing.Short() && os.Getenv("GO_BUILDER_NAME") == "" { fmt.Printf("SKIP - short mode and $GO_BUILDER_NAME not set\n") @@ -54,7 +57,11 @@ func testMain(m *testing.M) int { if err != nil { log.Panic(err) } - defer os.RemoveAll(GOPATH) + if testWork { + log.Println(GOPATH) + } else { + defer os.RemoveAll(GOPATH) + } os.Setenv("GOPATH", GOPATH) // Copy testdata into GOPATH/src/testarchive, along with a go.mod file @@ -164,6 +171,38 @@ func cmdToRun(name string) []string { return []string{executor, name} } +// genHeader writes a C header file for the C-exported declarations found in .go +// source files in dir. +// +// TODO(golang.org/issue/35715): This should be simpler. +func genHeader(t *testing.T, header, dir string) { + t.Helper() + + // The 'cgo' command generates a number of additional artifacts, + // but we're only interested in the header. + // Shunt the rest of the outputs to a temporary directory. + objDir, err := ioutil.TempDir(GOPATH, "_obj") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(objDir) + + files, err := filepath.Glob(filepath.Join(dir, "*.go")) + if err != nil { + t.Fatal(err) + } + + cmd := exec.Command("go", "tool", "cgo", + "-objdir", objDir, + "-exportheader", header) + cmd.Args = append(cmd.Args, files...) + t.Log(cmd.Args) + if out, err := cmd.CombinedOutput(); err != nil { + t.Logf("%s", out) + t.Fatal(err) + } +} + func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) { t.Helper() cmd := exec.Command(buildcmd[0], buildcmd[1:]...) @@ -172,10 +211,12 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) { t.Logf("%s", out) t.Fatal(err) } - defer func() { - os.Remove(libgoa) - os.Remove(libgoh) - }() + if !testWork { + defer func() { + os.Remove(libgoa) + os.Remove(libgoh) + }() + } ccArgs := append(cc, "-o", exe, "main.c") if GOOS == "windows" { @@ -191,7 +232,9 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) { t.Logf("%s", out) t.Fatal(err) } - defer os.Remove(exe) + if !testWork { + defer os.Remove(exe) + } binArgs := append(cmdToRun(exe), "arg1", "arg2") cmd = exec.Command(binArgs[0], binArgs[1:]...) @@ -227,17 +270,27 @@ func checkLineComments(t *testing.T, hdrname string) { } func TestInstall(t *testing.T) { - defer os.RemoveAll(filepath.Join(GOPATH, "pkg")) + if !testWork { + defer os.RemoveAll(filepath.Join(GOPATH, "pkg")) + } libgoa := "libgo.a" if runtime.Compiler == "gccgo" { libgoa = "liblibgo.a" } + // Generate the p.h header file. + // + // 'go install -i -buildmode=c-archive ./libgo' would do that too, but that + // would also attempt to install transitive standard-library dependencies to + // GOROOT, and we cannot assume that GOROOT is writable. (A non-root user may + // be running this test in a GOROOT owned by root.) + genHeader(t, "p.h", "./p") + testInstall(t, "./testp1"+exeSuffix, filepath.Join(libgodir, libgoa), filepath.Join(libgodir, "libgo.h"), - "go", "install", "-i", "-buildmode=c-archive", "./libgo") + "go", "install", "-buildmode=c-archive", "./libgo") // Test building libgo other than installing it. // Header files are now present. @@ -259,12 +312,14 @@ func TestEarlySignalHandler(t *testing.T) { t.Skip("skipping signal test on Windows") } - defer func() { - os.Remove("libgo2.a") - os.Remove("libgo2.h") - os.Remove("testp") - os.RemoveAll(filepath.Join(GOPATH, "pkg")) - }() + if !testWork { + defer func() { + os.Remove("libgo2.a") + os.Remove("libgo2.h") + os.Remove("testp") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) + }() + } cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") if out, err := cmd.CombinedOutput(); err != nil { @@ -282,7 +337,13 @@ func TestEarlySignalHandler(t *testing.T) { t.Fatal(err) } - if out, err := exec.Command(bin[0], bin[1:]...).CombinedOutput(); err != nil { + darwin := "0" + if runtime.GOOS == "darwin" { + darwin = "1" + } + cmd = exec.Command(bin[0], append(bin[1:], darwin)...) + + if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) } @@ -291,12 +352,14 @@ func TestEarlySignalHandler(t *testing.T) { func TestSignalForwarding(t *testing.T) { checkSignalForwardingTest(t) - defer func() { - os.Remove("libgo2.a") - os.Remove("libgo2.h") - os.Remove("testp") - os.RemoveAll(filepath.Join(GOPATH, "pkg")) - }() + if !testWork { + defer func() { + os.Remove("libgo2.a") + os.Remove("libgo2.h") + os.Remove("testp") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) + }() + } cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") if out, err := cmd.CombinedOutput(); err != nil { @@ -320,12 +383,15 @@ func TestSignalForwarding(t *testing.T) { t.Logf("%s", out) expectSignal(t, err, syscall.SIGSEGV) - // Test SIGPIPE forwarding - cmd = exec.Command(bin[0], append(bin[1:], "3")...) + // SIGPIPE is never forwarded on darwin. See golang.org/issue/33384. + if runtime.GOOS != "darwin" { + // Test SIGPIPE forwarding + cmd = exec.Command(bin[0], append(bin[1:], "3")...) - out, err = cmd.CombinedOutput() - t.Logf("%s", out) - expectSignal(t, err, syscall.SIGPIPE) + out, err = cmd.CombinedOutput() + t.Logf("%s", out) + expectSignal(t, err, syscall.SIGPIPE) + } } func TestSignalForwardingExternal(t *testing.T) { @@ -336,12 +402,14 @@ func TestSignalForwardingExternal(t *testing.T) { } checkSignalForwardingTest(t) - defer func() { - os.Remove("libgo2.a") - os.Remove("libgo2.h") - os.Remove("testp") - os.RemoveAll(filepath.Join(GOPATH, "pkg")) - }() + if !testWork { + defer func() { + os.Remove("libgo2.a") + os.Remove("libgo2.h") + os.Remove("testp") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) + }() + } cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo2.a", "./libgo2") if out, err := cmd.CombinedOutput(); err != nil { @@ -451,12 +519,14 @@ func TestOsSignal(t *testing.T) { t.Skip("skipping signal test on Windows") } - defer func() { - os.Remove("libgo3.a") - os.Remove("libgo3.h") - os.Remove("testp") - os.RemoveAll(filepath.Join(GOPATH, "pkg")) - }() + if !testWork { + defer func() { + os.Remove("libgo3.a") + os.Remove("libgo3.h") + os.Remove("testp") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) + }() + } cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo3.a", "./libgo3") if out, err := cmd.CombinedOutput(); err != nil { @@ -486,12 +556,14 @@ func TestSigaltstack(t *testing.T) { t.Skip("skipping signal test on Windows") } - defer func() { - os.Remove("libgo4.a") - os.Remove("libgo4.h") - os.Remove("testp") - os.RemoveAll(filepath.Join(GOPATH, "pkg")) - }() + if !testWork { + defer func() { + os.Remove("libgo4.a") + os.Remove("libgo4.h") + os.Remove("testp") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) + }() + } cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo4.a", "./libgo4") if out, err := cmd.CombinedOutput(); err != nil { @@ -535,13 +607,15 @@ func TestExtar(t *testing.T) { t.Skip("shell scripts are not executable on iOS hosts") } - defer func() { - os.Remove("libgo4.a") - os.Remove("libgo4.h") - os.Remove("testar") - os.Remove("testar.ran") - os.RemoveAll(filepath.Join(GOPATH, "pkg")) - }() + if !testWork { + defer func() { + os.Remove("libgo4.a") + os.Remove("libgo4.h") + os.Remove("testar") + os.Remove("testar.ran") + os.RemoveAll(filepath.Join(GOPATH, "pkg")) + }() + } os.Remove("testar") dir, err := os.Getwd() @@ -575,12 +649,22 @@ func TestPIE(t *testing.T) { t.Skipf("skipping PIE test on %s", GOOS) } - defer func() { - os.Remove("testp" + exeSuffix) - os.RemoveAll(filepath.Join(GOPATH, "pkg")) - }() + if !testWork { + defer func() { + os.Remove("testp" + exeSuffix) + os.RemoveAll(filepath.Join(GOPATH, "pkg")) + }() + } + + // Generate the p.h header file. + // + // 'go install -i -buildmode=c-archive ./libgo' would do that too, but that + // would also attempt to install transitive standard-library dependencies to + // GOROOT, and we cannot assume that GOROOT is writable. (A non-root user may + // be running this test in a GOROOT owned by root.) + genHeader(t, "p.h", "./p") - cmd := exec.Command("go", "install", "-i", "-buildmode=c-archive", "./libgo") + cmd := exec.Command("go", "install", "-buildmode=c-archive", "./libgo") if out, err := cmd.CombinedOutput(); err != nil { t.Logf("%s", out) t.Fatal(err) @@ -660,11 +744,13 @@ func TestSIGPROF(t *testing.T) { t.Parallel() - defer func() { - os.Remove("testp6" + exeSuffix) - os.Remove("libgo6.a") - os.Remove("libgo6.h") - }() + if !testWork { + defer func() { + os.Remove("testp6" + exeSuffix) + os.Remove("libgo6.a") + os.Remove("libgo6.h") + }() + } cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo6.a", "./libgo6") if out, err := cmd.CombinedOutput(); err != nil { @@ -700,10 +786,12 @@ func TestCompileWithoutShared(t *testing.T) { // For simplicity, reuse the signal forwarding test. checkSignalForwardingTest(t) - defer func() { - os.Remove("libgo2.a") - os.Remove("libgo2.h") - }() + if !testWork { + defer func() { + os.Remove("libgo2.a") + os.Remove("libgo2.h") + }() + } cmd := exec.Command("go", "build", "-buildmode=c-archive", "-gcflags=-shared=false", "-o", "libgo2.a", "./libgo2") t.Log(cmd.Args) @@ -742,23 +830,35 @@ func TestCompileWithoutShared(t *testing.T) { if err != nil { t.Fatal(err) } - defer os.Remove(exe) + if !testWork { + defer os.Remove(exe) + } - binArgs := append(cmdToRun(exe), "3") + binArgs := append(cmdToRun(exe), "1") t.Log(binArgs) out, err = exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput() t.Logf("%s", out) - expectSignal(t, err, syscall.SIGPIPE) + expectSignal(t, err, syscall.SIGSEGV) + + // SIGPIPE is never forwarded on darwin. See golang.org/issue/33384. + if runtime.GOOS != "darwin" { + binArgs := append(cmdToRun(exe), "3") + t.Log(binArgs) + out, err = exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput() + t.Logf("%s", out) + expectSignal(t, err, syscall.SIGPIPE) + } } -// Test that installing a second time recreates the header files. +// Test that installing a second time recreates the header file. func TestCachedInstall(t *testing.T) { - defer os.RemoveAll(filepath.Join(GOPATH, "pkg")) + if !testWork { + defer os.RemoveAll(filepath.Join(GOPATH, "pkg")) + } - h1 := filepath.Join(libgodir, "libgo.h") - h2 := filepath.Join(libgodir, "p.h") + h := filepath.Join(libgodir, "libgo.h") - buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "./libgo"} + buildcmd := []string{"go", "install", "-buildmode=c-archive", "./libgo"} cmd := exec.Command(buildcmd[0], buildcmd[1:]...) t.Log(buildcmd) @@ -767,17 +867,11 @@ func TestCachedInstall(t *testing.T) { t.Fatal(err) } - if _, err := os.Stat(h1); err != nil { + if _, err := os.Stat(h); err != nil { t.Errorf("libgo.h not installed: %v", err) } - if _, err := os.Stat(h2); err != nil { - t.Errorf("p.h not installed: %v", err) - } - if err := os.Remove(h1); err != nil { - t.Fatal(err) - } - if err := os.Remove(h2); err != nil { + if err := os.Remove(h); err != nil { t.Fatal(err) } @@ -788,10 +882,58 @@ func TestCachedInstall(t *testing.T) { t.Fatal(err) } - if _, err := os.Stat(h1); err != nil { + if _, err := os.Stat(h); err != nil { t.Errorf("libgo.h not installed in second run: %v", err) } - if _, err := os.Stat(h2); err != nil { - t.Errorf("p.h not installed in second run: %v", err) +} + +// Issue 35294. +func TestManyCalls(t *testing.T) { + t.Parallel() + + if !testWork { + defer func() { + os.Remove("testp7" + exeSuffix) + os.Remove("libgo7.a") + os.Remove("libgo7.h") + }() + } + + cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo7.a", "./libgo7") + if out, err := cmd.CombinedOutput(); err != nil { + t.Logf("%s", out) + t.Fatal(err) + } + checkLineComments(t, "libgo7.h") + + ccArgs := append(cc, "-o", "testp7"+exeSuffix, "main7.c", "libgo7.a") + if runtime.Compiler == "gccgo" { + ccArgs = append(ccArgs, "-lgo") + } + if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil { + t.Logf("%s", out) + t.Fatal(err) + } + + argv := cmdToRun("./testp7") + cmd = exec.Command(argv[0], argv[1:]...) + var sb strings.Builder + cmd.Stdout = &sb + cmd.Stderr = &sb + if err := cmd.Start(); err != nil { + t.Fatal(err) + } + + timer := time.AfterFunc(time.Minute, + func() { + t.Error("test program timed out") + cmd.Process.Kill() + }, + ) + defer timer.Stop() + + if err := cmd.Wait(); err != nil { + t.Log(sb.String()) + t.Error(err) } } diff --git a/libgo/misc/cgo/testcarchive/overlaydir_test.go b/libgo/misc/cgo/testcarchive/overlaydir_test.go index 68878e4c66a..67974c5ed8d 100644 --- a/libgo/misc/cgo/testcarchive/overlaydir_test.go +++ b/libgo/misc/cgo/testcarchive/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/misc/cgo/testcarchive/testdata/libgo7/sink.go b/libgo/misc/cgo/testcarchive/testdata/libgo7/sink.go new file mode 100644 index 00000000000..d61638b38e8 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/libgo7/sink.go @@ -0,0 +1,17 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "C" + +var sink []byte + +//export GoFunction7 +func GoFunction7() { + sink = make([]byte, 4096) +} + +func main() { +} diff --git a/libgo/misc/cgo/testcarchive/testdata/main2.c b/libgo/misc/cgo/testcarchive/testdata/main2.c index 769cd497e6c..da35673421b 100644 --- a/libgo/misc/cgo/testcarchive/testdata/main2.c +++ b/libgo/misc/cgo/testcarchive/testdata/main2.c @@ -123,8 +123,12 @@ int main(int argc, char** argv) { sigset_t mask; int i; struct timespec ts; + int darwin; + + darwin = atoi(argv[1]); + + verbose = argc > 2; - verbose = argc > 1; setvbuf(stdout, NULL, _IONBF, 0); // Call setsid so that we can use kill(0, SIGIO) below. @@ -186,22 +190,25 @@ int main(int argc, char** argv) { printf("provoking SIGPIPE\n"); } - GoRaiseSIGPIPE(); + // SIGPIPE is never forwarded on Darwin, see golang.org/issue/33384. + if (!darwin) { + GoRaiseSIGPIPE(); - if (verbose) { - printf("waiting for sigpipeSeen\n"); - } + if (verbose) { + printf("waiting for sigpipeSeen\n"); + } - // Wait until the signal has been delivered. - i = 0; - while (!sigpipeSeen) { - ts.tv_sec = 0; - ts.tv_nsec = 1000000; - nanosleep(&ts, NULL); - i++; - if (i > 5000) { - fprintf(stderr, "looping too long waiting for SIGPIPE\n"); - exit(EXIT_FAILURE); + // Wait until the signal has been delivered. + i = 0; + while (!sigpipeSeen) { + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + nanosleep(&ts, NULL); + i++; + if (i > 5000) { + fprintf(stderr, "looping too long waiting for SIGPIPE\n"); + exit(EXIT_FAILURE); + } } } diff --git a/libgo/misc/cgo/testcarchive/testdata/main3.c b/libgo/misc/cgo/testcarchive/testdata/main3.c index 60a16cf5fc4..4d11d9ce4c3 100644 --- a/libgo/misc/cgo/testcarchive/testdata/main3.c +++ b/libgo/misc/cgo/testcarchive/testdata/main3.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "libgo3.h" @@ -51,11 +52,18 @@ static void init() { } } +static void *provokeSIGPIPE(void *arg) { + ProvokeSIGPIPE(); + return NULL; +} + int main(int argc, char** argv) { int verbose; struct sigaction sa; int i; struct timespec ts; + int res; + pthread_t tid; verbose = argc > 2; setvbuf(stdout, NULL, _IONBF, 0); @@ -68,6 +76,19 @@ int main(int argc, char** argv) { // a non-default SIGPIPE handler before the runtime initializes. ProvokeSIGPIPE(); + // Test that SIGPIPE on a non-main thread is also handled by Go. + res = pthread_create(&tid, NULL, provokeSIGPIPE, NULL); + if (res != 0) { + fprintf(stderr, "pthread_create: %s\n", strerror(res)); + exit(EXIT_FAILURE); + } + + res = pthread_join(tid, NULL); + if (res != 0) { + fprintf(stderr, "pthread_join: %s\n", strerror(res)); + exit(EXIT_FAILURE); + } + if (verbose) { printf("calling sigaction\n"); } diff --git a/libgo/misc/cgo/testcarchive/testdata/main7.c b/libgo/misc/cgo/testcarchive/testdata/main7.c new file mode 100644 index 00000000000..2c6d98daa83 --- /dev/null +++ b/libgo/misc/cgo/testcarchive/testdata/main7.c @@ -0,0 +1,18 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test that lots of calls don't deadlock. + +#include + +#include "libgo7.h" + +int main() { + int i; + + for (i = 0; i < 100000; i++) { + GoFunction7(); + } + return 0; +} diff --git a/libgo/misc/cgo/testcshared/cshared_test.go b/libgo/misc/cgo/testcshared/cshared_test.go index daef3a9e546..cb95153abf6 100644 --- a/libgo/misc/cgo/testcshared/cshared_test.go +++ b/libgo/misc/cgo/testcshared/cshared_test.go @@ -103,7 +103,7 @@ func testMain(m *testing.M) int { // TODO(crawshaw): can we do better? cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...) case "android": - cc = append(cc, "-pie", "-fuse-ld=gold") + cc = append(cc, "-pie") } libgodir := GOOS + "_" + GOARCH switch GOOS { @@ -130,8 +130,6 @@ func testMain(m *testing.M) int { defer os.RemoveAll(GOPATH) os.Setenv("GOPATH", GOPATH) - // Copy testdata into GOPATH/src/testarchive, along with a go.mod file - // declaring the same path. modRoot := filepath.Join(GOPATH, "src", "testcshared") if err := overlayDir(modRoot, "testdata"); err != nil { log.Panic(err) @@ -257,14 +255,38 @@ func runCC(t *testing.T, args ...string) string { } func createHeaders() error { - args := []string{"go", "install", "-i", "-buildmode=c-shared", - "-installsuffix", "testcshared", "./libgo"} + // The 'cgo' command generates a number of additional artifacts, + // but we're only interested in the header. + // Shunt the rest of the outputs to a temporary directory. + objDir, err := ioutil.TempDir("", "testcshared_obj") + if err != nil { + return err + } + defer os.RemoveAll(objDir) + + // Generate a C header file for p, which is a non-main dependency + // of main package libgo. + // + // TODO(golang.org/issue/35715): This should be simpler. + args := []string{"go", "tool", "cgo", + "-objdir", objDir, + "-exportheader", "p.h", + filepath.Join(".", "p", "p.go")} cmd := exec.Command(args[0], args[1:]...) out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out) } + // Generate a C header file for libgo itself. + args = []string{"go", "install", "-buildmode=c-shared", + "-installsuffix", "testcshared", "./libgo"} + cmd = exec.Command(args[0], args[1:]...) + out, err = cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("command failed: %v\n%v\n%s\n", args, err, out) + } + args = []string{"go", "build", "-buildmode=c-shared", "-installsuffix", "testcshared", "-o", libgoname, @@ -522,7 +544,7 @@ func TestPIE(t *testing.T) { } } -// Test that installing a second time recreates the header files. +// Test that installing a second time recreates the header file. func TestCachedInstall(t *testing.T) { tmpdir, err := ioutil.TempDir("", "cshared") if err != nil { @@ -536,7 +558,7 @@ func TestCachedInstall(t *testing.T) { env := append(os.Environ(), "GOPATH="+tmpdir, "GOBIN="+filepath.Join(tmpdir, "bin")) - buildcmd := []string{"go", "install", "-x", "-i", "-buildmode=c-shared", "-installsuffix", "testcshared", "./libgo"} + buildcmd := []string{"go", "install", "-x", "-buildmode=c-shared", "-installsuffix", "testcshared", "./libgo"} cmd := exec.Command(buildcmd[0], buildcmd[1:]...) cmd.Dir = filepath.Join(tmpdir, "src", "testcshared") @@ -577,16 +599,10 @@ func TestCachedInstall(t *testing.T) { if libgoh == "" { t.Fatal("libgo.h not installed") } - if ph == "" { - t.Fatal("p.h not installed") - } if err := os.Remove(libgoh); err != nil { t.Fatal(err) } - if err := os.Remove(ph); err != nil { - t.Fatal(err) - } cmd = exec.Command(buildcmd[0], buildcmd[1:]...) cmd.Dir = filepath.Join(tmpdir, "src", "testcshared") @@ -601,9 +617,6 @@ func TestCachedInstall(t *testing.T) { if _, err := os.Stat(libgoh); err != nil { t.Errorf("libgo.h not installed in second run: %v", err) } - if _, err := os.Stat(ph); err != nil { - t.Errorf("p.h not installed in second run: %v", err) - } } // copyFile copies src to dst. diff --git a/libgo/misc/cgo/testcshared/overlaydir_test.go b/libgo/misc/cgo/testcshared/overlaydir_test.go index 1eaabf6fe21..85d6b44eef5 100644 --- a/libgo/misc/cgo/testcshared/overlaydir_test.go +++ b/libgo/misc/cgo/testcshared/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/misc/cgo/testgodefs/test.bash b/libgo/misc/cgo/testgodefs/test.bash deleted file mode 100644 index e4ce2ee7a86..00000000000 --- a/libgo/misc/cgo/testgodefs/test.bash +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2014 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -# We are testing cgo -godefs, which translates Go files that use -# import "C" into Go files with Go definitions of types defined in the -# import "C" block. Add more tests here. -FILE_PREFIXES="anonunion issue8478 fieldtypedef" - -cd testdata - -RM= -for FP in $FILE_PREFIXES -do - go tool cgo -godefs -srcdir . ${FP}.go > ${FP}_defs.go - RM="${RM} ${FP}_defs.go" -done - -go build -o testgodefs . && ./testgodefs -EXIT=$? -rm -rf _obj testgodefs ${RM} -exit $EXIT diff --git a/libgo/misc/cgo/testgodefs/testgodefs_test.go b/libgo/misc/cgo/testgodefs/testgodefs_test.go new file mode 100644 index 00000000000..c02c3ff0acd --- /dev/null +++ b/libgo/misc/cgo/testgodefs/testgodefs_test.go @@ -0,0 +1,83 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testgodefs + +import ( + "bytes" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +// We are testing cgo -godefs, which translates Go files that use +// import "C" into Go files with Go definitions of types defined in the +// import "C" block. Add more tests here. +var filePrefixes = []string{ + "anonunion", + "issue8478", + "fieldtypedef", +} + +func TestGoDefs(t *testing.T) { + testdata, err := filepath.Abs("testdata") + if err != nil { + t.Fatal(err) + } + + gopath, err := ioutil.TempDir("", "testgodefs-gopath") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(gopath) + + dir := filepath.Join(gopath, "src", "testgodefs") + if err := os.MkdirAll(dir, 0755); err != nil { + t.Fatal(err) + } + + for _, fp := range filePrefixes { + cmd := exec.Command("go", "tool", "cgo", + "-godefs", + "-srcdir", testdata, + "-objdir", dir, + fp+".go") + cmd.Stderr = new(bytes.Buffer) + + out, err := cmd.Output() + if err != nil { + t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, cmd.Stderr) + } + + if err := ioutil.WriteFile(filepath.Join(dir, fp+"_defs.go"), out, 0644); err != nil { + t.Fatal(err) + } + } + + main, err := ioutil.ReadFile(filepath.Join("testdata", "main.go")) + if err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(filepath.Join(dir, "main.go"), main, 0644); err != nil { + t.Fatal(err) + } + + if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module testgodefs\ngo 1.14\n"), 0644); err != nil { + t.Fatal(err) + } + + // Use 'go run' to build and run the resulting binary in a single step, + // instead of invoking 'go build' and the resulting binary separately, so that + // this test can pass on mobile builders, which do not copy artifacts back + // from remote invocations. + cmd := exec.Command("go", "run", ".") + cmd.Env = append(os.Environ(), "GOPATH="+gopath) + cmd.Dir = dir + if out, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("%s [%s]: %v\n%s", strings.Join(cmd.Args, " "), dir, err, out) + } +} diff --git a/libgo/misc/cgo/testplugin/overlaydir_test.go b/libgo/misc/cgo/testplugin/overlaydir_test.go index b68436ac035..e2c32d83ce1 100644 --- a/libgo/misc/cgo/testplugin/overlaydir_test.go +++ b/libgo/misc/cgo/testplugin/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/misc/cgo/testplugin/plugin_test.go b/libgo/misc/cgo/testplugin/plugin_test.go index 7e2b6eb04c0..ab98f61c0ad 100644 --- a/libgo/misc/cgo/testplugin/plugin_test.go +++ b/libgo/misc/cgo/testplugin/plugin_test.go @@ -14,7 +14,6 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "strings" "testing" "time" @@ -71,7 +70,7 @@ func testMain(m *testing.M) int { os.Setenv("LD_LIBRARY_PATH", modRoot) - goCmd(nil, "build", "-i", "-buildmode=plugin", "./plugin1") + goCmd(nil, "build", "-buildmode=plugin", "./plugin1") goCmd(nil, "build", "-buildmode=plugin", "./plugin2") so, err := ioutil.ReadFile("plugin2.so") if err != nil { @@ -114,11 +113,7 @@ func run(t *testing.T, bin string, args ...string) string { func TestDWARFSections(t *testing.T) { // test that DWARF sections are emitted for plugins and programs importing "plugin" - if runtime.GOOS != "darwin" { - // On macOS, for some reason, the linker doesn't add debug sections to .so, - // see issue #27502. - goCmd(t, "run", "./checkdwarf/main.go", "plugin2.so", "plugin2.UnexportedNameReuse") - } + goCmd(t, "run", "./checkdwarf/main.go", "plugin2.so", "plugin2.UnexportedNameReuse") goCmd(t, "run", "./checkdwarf/main.go", "./host.exe", "main.main") } diff --git a/libgo/misc/cgo/testshared/overlaydir_test.go b/libgo/misc/cgo/testshared/overlaydir_test.go index 68be0562567..eb587a2d44d 100644 --- a/libgo/misc/cgo/testshared/overlaydir_test.go +++ b/libgo/misc/cgo/testshared/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/misc/cgo/testshared/shared_test.go b/libgo/misc/cgo/testshared/shared_test.go index 9d16338c0f6..b9ef6dad8e2 100644 --- a/libgo/misc/cgo/testshared/shared_test.go +++ b/libgo/misc/cgo/testshared/shared_test.go @@ -9,31 +9,33 @@ import ( "bytes" "debug/elf" "encoding/binary" - "errors" "flag" "fmt" "go/build" "io" "io/ioutil" "log" - "math/rand" "os" "os/exec" "path/filepath" "regexp" "runtime" + "sort" "strings" "testing" "time" ) -var gopathInstallDir, gorootInstallDir, suffix string +var gopathInstallDir, gorootInstallDir string // This is the smallest set of packages we can link into a shared // library (runtime/cgo is built implicitly). var minpkgs = []string{"runtime", "sync/atomic"} var soname = "libruntime,sync-atomic.so" +var testX = flag.Bool("testx", false, "if true, pass -x to 'go' subcommands invoked by the test") +var testWork = flag.Bool("testwork", false, "if true, log and do not delete the temporary working directory") + // run runs a command and calls t.Errorf if it fails. func run(t *testing.T, msg string, args ...string) { c := exec.Command(args[0], args[1:]...) @@ -45,31 +47,34 @@ func run(t *testing.T, msg string, args ...string) { // goCmd invokes the go tool with the installsuffix set up by TestMain. It calls // t.Fatalf if the command fails. func goCmd(t *testing.T, args ...string) string { - newargs := []string{args[0], "-installsuffix=" + suffix} - if testing.Verbose() { + newargs := []string{args[0]} + if *testX { newargs = append(newargs, "-x") } newargs = append(newargs, args[1:]...) c := exec.Command("go", newargs...) - stderr := new(strings.Builder) - var output []byte - var err error - if testing.Verbose() { - fmt.Printf("+ go %s\n", strings.Join(args, " ")) + c.Stderr = stderr + + if testing.Verbose() && t == nil { + fmt.Fprintf(os.Stderr, "+ go %s\n", strings.Join(args, " ")) c.Stderr = os.Stderr - stderr.WriteString("(output above)") - } else { - c.Stderr = stderr } - output, err = c.Output() + output, err := c.Output() if err != nil { if t != nil { t.Helper() t.Fatalf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, stderr) } else { - log.Fatalf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, stderr) + // Panic instead of using log.Fatalf so that deferred cleanup may run in testMain. + log.Panicf("executing %s failed %v:\n%s", strings.Join(c.Args, " "), err, stderr) + } + } + if testing.Verbose() && t != nil { + t.Logf("go %s", strings.Join(args, " ")) + if stderr.Len() > 0 { + t.Logf("%s", stderr) } } return string(bytes.TrimSpace(output)) @@ -77,73 +82,61 @@ func goCmd(t *testing.T, args ...string) string { // TestMain calls testMain so that the latter can use defer (TestMain exits with os.Exit). func testMain(m *testing.M) (int, error) { - // Because go install -buildmode=shared $standard_library_package always - // installs into $GOROOT, here are some gymnastics to come up with a unique - // installsuffix to use in this test that we can clean up afterwards. - myContext := build.Default - runtimeP, err := myContext.Import("runtime", ".", build.ImportComment) + workDir, err := ioutil.TempDir("", "shared_test") if err != nil { - return 0, fmt.Errorf("import failed: %v", err) - } - for i := 0; i < 10000; i++ { - try := fmt.Sprintf("%s_%d_dynlink", runtimeP.PkgTargetRoot, rand.Int63()) - err = os.Mkdir(try, 0700) - if os.IsExist(err) { - continue - } - if err == nil { - gorootInstallDir = try - } - break - } - if err != nil { - return 0, fmt.Errorf("can't create temporary directory: %v", err) + return 0, err } - if gorootInstallDir == "" { - return 0, errors.New("could not create temporary directory after 10000 tries") + if *testWork || testing.Verbose() { + fmt.Printf("+ mkdir -p %s\n", workDir) } - if testing.Verbose() { - fmt.Printf("+ mkdir -p %s\n", gorootInstallDir) + if !*testWork { + defer os.RemoveAll(workDir) } - defer os.RemoveAll(gorootInstallDir) // Some tests need to edit the source in GOPATH, so copy this directory to a // temporary directory and chdir to that. - gopath, err := ioutil.TempDir("", "testshared") + gopath := filepath.Join(workDir, "gopath") + modRoot, err := cloneTestdataModule(gopath) if err != nil { - return 0, fmt.Errorf("TempDir failed: %v", err) - } - if testing.Verbose() { - fmt.Printf("+ mkdir -p %s\n", gopath) - } - defer os.RemoveAll(gopath) - - modRoot := filepath.Join(gopath, "src", "testshared") - if err := overlayDir(modRoot, "testdata"); err != nil { return 0, err } if testing.Verbose() { + fmt.Printf("+ export GOPATH=%s\n", gopath) fmt.Printf("+ cd %s\n", modRoot) } + os.Setenv("GOPATH", gopath) os.Chdir(modRoot) os.Setenv("PWD", modRoot) - if err := ioutil.WriteFile("go.mod", []byte("module testshared\n"), 0666); err != nil { + + // The test also needs to install libraries into GOROOT/pkg, so copy the + // subset of GOROOT that we need. + // + // TODO(golang.org/issue/28553): Rework -buildmode=shared so that it does not + // need to write to GOROOT. + goroot := filepath.Join(workDir, "goroot") + if err := cloneGOROOTDeps(goroot); err != nil { return 0, err } - - os.Setenv("GOPATH", gopath) if testing.Verbose() { - fmt.Printf("+ export GOPATH=%s\n", gopath) + fmt.Fprintf(os.Stderr, "+ export GOROOT=%s\n", goroot) } + os.Setenv("GOROOT", goroot) + + myContext := build.Default + myContext.GOROOT = goroot myContext.GOPATH = gopath + runtimeP, err := myContext.Import("runtime", ".", build.ImportComment) + if err != nil { + return 0, fmt.Errorf("import failed: %v", err) + } + gorootInstallDir = runtimeP.PkgTargetRoot + "_dynlink" // All tests depend on runtime being built into a shared library. Because // that takes a few seconds, do it here and have all tests use the version // built here. - suffix = strings.Split(filepath.Base(gorootInstallDir), "_")[2] goCmd(nil, append([]string{"install", "-buildmode=shared"}, minpkgs...)...) - myContext.InstallSuffix = suffix + "_dynlink" + myContext.InstallSuffix = "_dynlink" depP, err := myContext.Import("./depBase", ".", build.ImportComment) if err != nil { return 0, fmt.Errorf("import failed: %v", err) @@ -171,6 +164,75 @@ func TestMain(m *testing.M) { os.Exit(exitCode) } +// cloneTestdataModule clones the packages from src/testshared into gopath. +// It returns the directory within gopath at which the module root is located. +func cloneTestdataModule(gopath string) (string, error) { + modRoot := filepath.Join(gopath, "src", "testshared") + if err := overlayDir(modRoot, "testdata"); err != nil { + return "", err + } + if err := ioutil.WriteFile(filepath.Join(modRoot, "go.mod"), []byte("module testshared\n"), 0644); err != nil { + return "", err + } + return modRoot, nil +} + +// cloneGOROOTDeps copies (or symlinks) the portions of GOROOT/src and +// GOROOT/pkg relevant to this test into the given directory. +// It must be run from within the testdata module. +func cloneGOROOTDeps(goroot string) error { + oldGOROOT := strings.TrimSpace(goCmd(nil, "env", "GOROOT")) + if oldGOROOT == "" { + return fmt.Errorf("go env GOROOT returned an empty string") + } + + // Before we clone GOROOT, figure out which packages we need to copy over. + listArgs := []string{ + "list", + "-deps", + "-f", "{{if and .Standard (not .ForTest)}}{{.ImportPath}}{{end}}", + } + stdDeps := goCmd(nil, append(listArgs, minpkgs...)...) + testdataDeps := goCmd(nil, append(listArgs, "-test", "./...")...) + + pkgs := append(strings.Split(strings.TrimSpace(stdDeps), "\n"), + strings.Split(strings.TrimSpace(testdataDeps), "\n")...) + sort.Strings(pkgs) + var pkgRoots []string + for _, pkg := range pkgs { + parentFound := false + for _, prev := range pkgRoots { + if strings.HasPrefix(pkg, prev) { + // We will copy in the source for pkg when we copy in prev. + parentFound = true + break + } + } + if !parentFound { + pkgRoots = append(pkgRoots, pkg) + } + } + + gorootDirs := []string{ + "pkg/tool", + "pkg/include", + } + for _, pkg := range pkgRoots { + gorootDirs = append(gorootDirs, filepath.Join("src", pkg)) + } + + for _, dir := range gorootDirs { + if testing.Verbose() { + fmt.Fprintf(os.Stderr, "+ cp -r %s %s\n", filepath.Join(goroot, dir), filepath.Join(oldGOROOT, dir)) + } + if err := overlayDir(filepath.Join(goroot, dir), filepath.Join(oldGOROOT, dir)); err != nil { + return err + } + } + + return nil +} + // The shared library was built at the expected location. func TestSOBuilt(t *testing.T) { _, err := os.Stat(filepath.Join(gorootInstallDir, soname)) @@ -219,6 +281,7 @@ func TestNoTextrel(t *testing.T) { } // The shared library does not contain symbols called ".dup" +// (See golang.org/issue/14841.) func TestNoDupSymbols(t *testing.T) { sopath := filepath.Join(gorootInstallDir, soname) f, err := elf.Open(sopath) @@ -695,7 +758,7 @@ func resetFileStamps() { } reset := func(path string) { if err := filepath.Walk(path, chtime); err != nil { - log.Fatalf("resetFileStamps failed: %v", err) + log.Panicf("resetFileStamps failed: %v", err) } } @@ -708,6 +771,7 @@ func resetFileStamps() { // touch changes path and returns a function that changes it back. // It also sets the time of the file, so that we can see if it is rewritten. func touch(t *testing.T, path string) (cleanup func()) { + t.Helper() data, err := ioutil.ReadFile(path) if err != nil { t.Fatal(err) @@ -736,14 +800,32 @@ func touch(t *testing.T, path string) (cleanup func()) { // assume it's a text file data = append(data, '\n') } - if err := ioutil.WriteFile(path, data, 0666); err != nil { + + // If the file is still a symlink from an overlay, delete it so that we will + // replace it with a regular file instead of overwriting the symlinked one. + fi, err := os.Lstat(path) + if err == nil && !fi.Mode().IsRegular() { + fi, err = os.Stat(path) + if err := os.Remove(path); err != nil { + t.Fatal(err) + } + } + if err != nil { + t.Fatal(err) + } + + // If we're replacing a symlink to a read-only file, make the new file + // user-writable. + perm := fi.Mode().Perm() | 0200 + + if err := ioutil.WriteFile(path, data, perm); err != nil { t.Fatal(err) } if err := os.Chtimes(path, nearlyNew, nearlyNew); err != nil { t.Fatal(err) } return func() { - if err := ioutil.WriteFile(path, old, 0666); err != nil { + if err := ioutil.WriteFile(path, old, perm); err != nil { t.Fatal(err) } } diff --git a/libgo/misc/cgo/testsigfwd/main.go b/libgo/misc/cgo/testsigfwd/main.go index 61bd0da88a8..6d970500781 100644 --- a/libgo/misc/cgo/testsigfwd/main.go +++ b/libgo/misc/cgo/testsigfwd/main.go @@ -25,6 +25,7 @@ static void sigsegv() { static void segvhandler(int signum) { if (signum == SIGSEGV) { + fprintf(stdout, "ok\ttestsigfwd\n"); exit(0); // success } } diff --git a/libgo/misc/cgo/testso/overlaydir_test.go b/libgo/misc/cgo/testso/overlaydir_test.go index 10c874d9258..09a1d512f1e 100644 --- a/libgo/misc/cgo/testso/overlaydir_test.go +++ b/libgo/misc/cgo/testso/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/misc/cgo/testsovar/overlaydir_test.go b/libgo/misc/cgo/testsovar/overlaydir_test.go index 10c874d9258..09a1d512f1e 100644 --- a/libgo/misc/cgo/testsovar/overlaydir_test.go +++ b/libgo/misc/cgo/testsovar/overlaydir_test.go @@ -21,12 +21,9 @@ func overlayDir(dstRoot, srcRoot string) error { return err } - symBase, err := filepath.Rel(srcRoot, dstRoot) + srcRoot, err := filepath.Abs(srcRoot) if err != nil { - symBase, err = filepath.Abs(srcRoot) - if err != nil { - return err - } + return err } return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { @@ -52,11 +49,11 @@ func overlayDir(dstRoot, srcRoot string) error { // Always copy directories (don't symlink them). // If we add a file in the overlay, we don't want to add it in the original. if info.IsDir() { - return os.Mkdir(dstPath, perm) + return os.MkdirAll(dstPath, perm|0200) } // If the OS supports symlinks, use them instead of copying bytes. - if err := os.Symlink(filepath.Join(symBase, suffix), dstPath); err == nil { + if err := os.Symlink(srcPath, dstPath); err == nil { return nil } diff --git a/libgo/runtime/go-caller.c b/libgo/runtime/go-caller.c index 5e31f912e0a..a18787671d1 100644 --- a/libgo/runtime/go-caller.c +++ b/libgo/runtime/go-caller.c @@ -27,6 +27,7 @@ struct caller intgo line; intgo index; intgo frames; + bool more; }; /* Collect file/line information for a PC value. If this is called @@ -40,7 +41,19 @@ callback (void *data, uintptr_t pc __attribute__ ((unused)), { struct caller *c = (struct caller *) data; - c->frames++; + /* We want to make sure we return at least one frame. If we already + have at least one frame, see if we should skip this one. */ + if (c->frames > 0 + && function != NULL + && runtime_skipInCallback (function, NULL)) + return 0; + + /* If we already have a frame, don't increment frames if we should + skip that one. */ + if (c->frames == 0 + || c->fn.len == 0 + || !runtime_skipInCallback ((const char *) c->fn.str, NULL)) + c->frames++; /* The libbacktrace library says that these strings might disappear, but with the current implementation they won't. We can't easily @@ -51,7 +64,16 @@ callback (void *data, uintptr_t pc __attribute__ ((unused)), c->line = lineno; if (c->index == 0) - return 1; + { + /* If there are more frames after the indexed one, and we should + skip this one, then skip it. */ + if (c->more + && c->fn.len > 0 + && runtime_skipInCallback((const char *) c->fn.str, NULL)) + return 0; + + return 1; + } if (c->index > 0) --c->index; @@ -129,18 +151,21 @@ __go_get_backtrace_state () return back_state; } -/* Return function/file/line/nframes information for PC. The index parameter - is the entry on the stack of inlined functions; -1 means the last - one, with *nframes set to the count of inlined frames for this PC. */ +/* Return function/file/line/nframes information for PC. The index + parameter is the entry on the stack of inlined functions; -1 means + the last one, with *nframes set to the count of inlined frames for + this PC. If index is not -1, more is whether there are more frames + after this one. */ static _Bool -__go_file_line (uintptr pc, int index, String *fn, String *file, intgo *line, intgo *nframes) +__go_file_line (uintptr pc, int index, bool more, String *fn, String *file, intgo *line, intgo *nframes) { struct caller c; struct backtrace_state *state; runtime_memclr (&c, sizeof c); c.index = index; + c.more = more; c.frames = 0; runtime_xadd (&__go_runtime_in_callers, 1); state = __go_get_backtrace_state (); @@ -223,11 +248,11 @@ Caller (intgo skip) /* Look up the function name, file name, and line number for a PC. */ struct funcfileline_return -runtime_funcfileline (uintptr targetpc, int32 index) +runtime_funcfileline (uintptr targetpc, int32 index, bool more) { struct funcfileline_return ret; - if (!__go_file_line (targetpc, index, &ret.retfn, &ret.retfile, + if (!__go_file_line (targetpc, index, more, &ret.retfn, &ret.retfile, &ret.retline, &ret.retframes)) runtime_memclr (&ret, sizeof ret); return ret; diff --git a/libgo/runtime/go-callers.c b/libgo/runtime/go-callers.c index e7d53a32a5f..33956ca4dfc 100644 --- a/libgo/runtime/go-callers.c +++ b/libgo/runtime/go-callers.c @@ -27,8 +27,59 @@ struct callers_data int index; int max; int keep_thunks; + int saw_sigtramp; }; +/* Whether to skip a particular function name in the traceback. This + is mostly to keep the output similar to the gc output for + runtime.Caller(N). + + See also similar code in runtime/mprof.go that strips out such + functions for block/mutex/memory profiles. */ + +bool +runtime_skipInCallback(const char *function, struct callers_data *arg) +{ + const char *p; + + /* Skip thunks and recover functions. There is no equivalent to + these functions in the gc toolchain. */ + + p = function + __builtin_strlen (function); + while (p > function && p[-1] >= '0' && p[-1] <= '9') + --p; + if (p - function > 7 && __builtin_strncmp (p - 7, "..thunk", 7) == 0) + return true; + if (p - function > 3 && __builtin_strcmp (p - 3, "..r") == 0) + return true; + if (p - function > 6 && __builtin_strncmp (p - 6, "..stub", 6) == 0) + return true; + + /* Skip runtime.deferreturn and runtime.sighandler as the gc + compiler has no corresponding function. */ + if (p - function == sizeof ("runtime.deferreturn") - 1 + && __builtin_strcmp (function, "runtime.deferreturn") == 0) + return true; + if (p - function == sizeof ("runtime.sighandler") - 1 + && __builtin_strcmp (function, "runtime.sighandler") == 0) + return true; + + /* Skip the signal handler functions that remain on the stack for us + but not for gc. */ + if ((p - function == sizeof ("runtime.sigtramp") - 1 + && __builtin_strcmp (function, "runtime.sigtramp") == 0) + || (p - function == sizeof ("runtime.sigtrampgo") - 1 + && __builtin_strcmp (function, "runtime.sigtrampgo") == 0)) + { + /* Also try to skip the signal handler function. */ + if (arg != NULL) + arg->saw_sigtramp = 1; + return true; + } + + return false; +} + /* Callback function for backtrace_full. Just collect the locations. Return zero to continue, non-zero to stop. */ @@ -39,6 +90,15 @@ callback (void *data, uintptr_t pc, const char *filename, int lineno, struct callers_data *arg = (struct callers_data *) data; Location *loc; + /* Skip an unnamed function above sigtramp. It is likely the signal + handler function. */ + if (arg->saw_sigtramp) + { + arg->saw_sigtramp = 0; + if (function == NULL) + return 0; + } + /* Skip split stack functions. */ if (function != NULL) { @@ -61,25 +121,10 @@ callback (void *data, uintptr_t pc, const char *filename, int lineno, return 0; } - /* Skip thunks and recover functions. There is no equivalent to - these functions in the gc toolchain, so returning them here means - significantly different results for runtime.Caller(N). See also - similar code in runtime/mprof.go that strips out such functions - for block/mutex/memory profiles. */ - if (function != NULL && !arg->keep_thunks) - { - const char *p; - - p = function + __builtin_strlen (function); - while (p > function && p[-1] >= '0' && p[-1] <= '9') - --p; - if (p - function > 7 && __builtin_strncmp (p - 7, "..thunk", 7) == 0) - return 0; - if (p - function > 3 && __builtin_strcmp (p - 3, "..r") == 0) - return 0; - if (p - function > 6 && __builtin_strncmp (p - 6, "..stub", 6) == 0) - return 0; - } + if (function != NULL + && !arg->keep_thunks + && runtime_skipInCallback (function, arg)) + return 0; if (arg->skip > 0) { @@ -204,6 +249,7 @@ runtime_callers (int32 skip, Location *locbuf, int32 m, bool keep_thunks) data.index = 0; data.max = m; data.keep_thunks = keep_thunks; + data.saw_sigtramp = 0; runtime_xadd (&__go_runtime_in_callers, 1); state = __go_get_backtrace_state (); backtrace_full (state, 0, callback, error_callback, &data); @@ -248,6 +294,9 @@ Callers (intgo skip, struct __go_open_array pc) int ret; int i; + if (pc.__count == 0) + return 0; + /* Note that calling mallocgc here assumes that we are not going to store any allocated Go pointers in the slice. */ locbuf = (Location *) runtime_mallocgc (pc.__count * sizeof (Location), diff --git a/libgo/runtime/go-nanotime.c b/libgo/runtime/go-nanotime.c index d221847adac..c7adfffb4f5 100644 --- a/libgo/runtime/go-nanotime.c +++ b/libgo/runtime/go-nanotime.c @@ -8,11 +8,11 @@ #include "runtime.h" -int64 runtime_nanotime (void) +int64 runtime_nanotime1 (void) __attribute__ ((no_split_stack)); int64 -runtime_nanotime (void) +runtime_nanotime1 (void) { struct timespec ts; diff --git a/libgo/runtime/go-now.c b/libgo/runtime/go-now.c index a45890bfd5a..1c02e5220e4 100644 --- a/libgo/runtime/go-now.c +++ b/libgo/runtime/go-now.c @@ -8,7 +8,7 @@ #include "runtime.h" -// Return current time. This is the implementation of time.walltime(). +// Return current time. This is the implementation of time.walltime1(). struct walltime_ret { @@ -16,7 +16,7 @@ struct walltime_ret int32_t nsec; }; -struct walltime_ret now(void) __asm__ (GOSYM_PREFIX "runtime.walltime") +struct walltime_ret now(void) __asm__ (GOSYM_PREFIX "runtime.walltime1") __attribute__ ((no_split_stack)); struct walltime_ret diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 89134c1d0e0..f46eaea07b9 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -283,8 +283,11 @@ void runtime_entersyscallblock() __asm__ (GOSYM_PREFIX "runtime.entersyscallblock"); G* __go_go(uintptr, void*); int32 runtime_callers(int32, Location*, int32, bool keep_callers); -int64 runtime_nanotime(void) // monotonic time - __asm__(GOSYM_PREFIX "runtime.nanotime"); +struct callers_data; +bool runtime_skipInCallback(const char *, struct callers_data *) + __asm__ (GOSYM_PREFIX "runtime.skipInCallback"); +int64 runtime_nanotime1(void) // monotonic time + __asm__(GOSYM_PREFIX "runtime.nanotime1"); void runtime_dopanic(int32) __attribute__ ((noreturn)); void runtime_startpanic(void) __asm__ (GOSYM_PREFIX "runtime.startpanic"); @@ -464,7 +467,7 @@ struct funcfileline_return }; struct funcfileline_return -runtime_funcfileline (uintptr targetpc, int32 index) +runtime_funcfileline (uintptr targetpc, int32 index, bool more) __asm__ (GOSYM_PREFIX "runtime.funcfileline"); /* diff --git a/libgo/runtime/runtime_c.c b/libgo/runtime/runtime_c.c index 7531431342c..e7951a051a6 100644 --- a/libgo/runtime/runtime_c.c +++ b/libgo/runtime/runtime_c.c @@ -134,16 +134,22 @@ int32 go_read(int32, void *, int32) int32 go_read(int32 fd, void *p, int32 n) { - return runtime_read(fd, p, n); + ssize_t r = runtime_read(fd, p, n); + if (r < 0) + r = - errno; + return (int32)r; } -int32 go_write(uintptr, void *, int32) - __asm__ (GOSYM_PREFIX "runtime.write"); +int32 go_write1(uintptr, void *, int32) + __asm__ (GOSYM_PREFIX "runtime.write1"); int32 -go_write(uintptr fd, void *p, int32 n) +go_write1(uintptr fd, void *p, int32 n) { - return runtime_write(fd, p, n); + ssize_t r = runtime_write(fd, p, n); + if (r < 0) + r = - errno; + return (int32)r; } int32 go_closefd(int32) diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest index 6929de34ba0..de4a392b8cd 100755 --- a/libgo/testsuite/gotest +++ b/libgo/testsuite/gotest @@ -305,7 +305,7 @@ x) "") ;; $goarch) ;; $goos) ;; - aix | android | darwin | dragonfly | freebsd | hurd | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) + aix | android | darwin | dragonfly | freebsd | hurd | illumos | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag1=nonmatchingtag ;; 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le·| nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) @@ -317,7 +317,7 @@ x) "") ;; $goarch) ;; $goos) ;; - aix | android | darwin | dragonfly | freebsd | hurd | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) + aix | android | darwin | dragonfly | freebsd | hurd | illumos | js | linux | nacl | netbsd | openbsd | plan9 | solaris | windows) tag2=nonmatchingtag ;; 386 | amd64 | amd64p32 | arm | armbe | arm64 | arm64be | alpha | ia64 | m68k | mips | mipsle | mips64 | mips64le | mips64p32 | mips64p32le·| nios2 | ppc | ppc64 | ppc64le | riscv64 | s390 | s390x | sh | shbe | sparc | sparc64 | wasm) @@ -624,7 +624,9 @@ exampleoutput() { echo 'import _ "./_xtest_"' fi fi - echo 'import "testing"' + if test "$package" != "testing"; then + echo 'import "testing"' + fi echo 'import "testing/internal/testdeps"' if ! test -n "$testmain"; then echo 'import __os__ "os"'