From cfcbb4227fb20191e04eb8d7766ae6202f526afd Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 23 Dec 2020 09:57:37 -0800 Subject: [PATCH] libgo: update to Go1.16beta1 release This does not yet include support for the //go:embed directive added in this release. * Makefile.am (check-runtime): Don't create check-runtime-dir. (mostlyclean-local): Don't remove check-runtime-dir. (check-go-tool, check-vet): Copy in go.mod and modules.txt. (check-cgo-test, check-carchive-test): Add go.mod file. * Makefile.in: Regenerate. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/280172 --- gcc/go/gofrontend/MERGE | 2 +- gotools/Makefile.am | 17 +- gotools/Makefile.in | 19 +- libgo/MERGE | 2 +- libgo/Makefile.am | 11 + libgo/Makefile.in | 12 +- libgo/VERSION | 2 +- libgo/check-packages.txt | 6 + libgo/config.h.in | 18 + libgo/configure | 254 +- libgo/configure.ac | 6 +- libgo/go/archive/tar/common.go | 68 +- libgo/go/archive/tar/reader.go | 7 +- libgo/go/archive/tar/reader_test.go | 5 +- libgo/go/archive/tar/stat_unix.go | 6 +- libgo/go/archive/tar/tar_test.go | 30 +- libgo/go/archive/tar/writer_test.go | 3 +- libgo/go/archive/zip/reader.go | 189 + libgo/go/archive/zip/reader_test.go | 39 +- libgo/go/archive/zip/register.go | 3 +- libgo/go/archive/zip/struct.go | 75 +- libgo/go/archive/zip/writer_test.go | 16 +- libgo/go/archive/zip/zip_test.go | 3 +- libgo/go/bufio/bufio.go | 2 +- libgo/go/bufio/bufio_test.go | 21 +- libgo/go/bytes/example_test.go | 7 + libgo/go/bytes/reader_test.go | 9 +- libgo/go/cmd/buildid/buildid.go | 21 +- libgo/go/cmd/cgo/ast.go | 16 +- libgo/go/cmd/cgo/doc.go | 9 +- libgo/go/cmd/cgo/gcc.go | 52 +- libgo/go/cmd/cgo/godefs.go | 2 +- libgo/go/cmd/cgo/main.go | 15 +- libgo/go/cmd/cgo/out.go | 177 +- libgo/go/cmd/go.mod | 12 + libgo/go/cmd/go/alldocs.go | 460 +- libgo/go/cmd/go/go_test.go | 196 +- libgo/go/cmd/go/go_windows_test.go | 14 +- libgo/go/cmd/go/help_test.go | 4 +- libgo/go/cmd/go/init_test.go | 26 +- libgo/go/cmd/go/internal/auth/netrc.go | 3 +- libgo/go/cmd/go/internal/base/base.go | 17 +- libgo/go/cmd/go/internal/base/flag.go | 37 +- libgo/go/cmd/go/internal/base/goflags.go | 43 +- libgo/go/cmd/go/internal/base/signal.go | 2 +- libgo/go/cmd/go/internal/bug/bug.go | 10 +- libgo/go/cmd/go/internal/cache/cache.go | 8 +- libgo/go/cmd/go/internal/cache/cache_test.go | 13 +- libgo/go/cmd/go/internal/cache/default.go | 3 +- libgo/go/cmd/go/internal/cache/hash_test.go | 3 +- libgo/go/cmd/go/internal/cfg/cfg.go | 22 +- libgo/go/cmd/go/internal/clean/clean.go | 29 +- libgo/go/cmd/go/internal/doc/doc.go | 3 +- libgo/go/cmd/go/internal/envcmd/env.go | 58 +- libgo/go/cmd/go/internal/fix/fix.go | 17 +- libgo/go/cmd/go/internal/fmtcmd/fmt.go | 8 +- libgo/go/cmd/go/internal/fsys/fsys.go | 689 + libgo/go/cmd/go/internal/fsys/fsys_test.go | 1094 + libgo/go/cmd/go/internal/generate/generate.go | 8 +- libgo/go/cmd/go/internal/get/get.go | 75 +- libgo/go/cmd/go/internal/get/path.go | 192 - libgo/go/cmd/go/internal/help/helpdoc.go | 11 +- libgo/go/cmd/go/internal/imports/build.go | 5 + libgo/go/cmd/go/internal/imports/read.go | 4 +- libgo/go/cmd/go/internal/imports/scan.go | 15 +- libgo/go/cmd/go/internal/imports/scan_test.go | 8 +- libgo/go/cmd/go/internal/imports/tags.go | 23 +- .../internal/imports/testdata/android/.h.go | 3 + .../internal/imports/testdata/illumos/.h.go | 3 + libgo/go/cmd/go/internal/list/list.go | 190 +- libgo/go/cmd/go/internal/load/pkg.go | 492 +- libgo/go/cmd/go/internal/load/test.go | 49 +- .../lockedfile/internal/filelock/filelock.go | 5 +- .../internal/filelock/filelock_fcntl.go | 11 +- .../internal/filelock/filelock_other.go | 6 +- .../internal/filelock/filelock_plan9.go | 8 +- .../internal/filelock/filelock_test.go | 7 +- .../internal/filelock/filelock_unix.go | 6 +- .../internal/filelock/filelock_windows.go | 6 +- .../cmd/go/internal/lockedfile/lockedfile.go | 14 +- .../lockedfile/lockedfile_filelock.go | 6 +- .../internal/lockedfile/lockedfile_plan9.go | 13 +- .../go/internal/lockedfile/lockedfile_test.go | 9 +- libgo/go/cmd/go/internal/modcmd/download.go | 94 +- libgo/go/cmd/go/internal/modcmd/edit.go | 107 +- libgo/go/cmd/go/internal/modcmd/graph.go | 38 +- libgo/go/cmd/go/internal/modcmd/init.go | 45 +- libgo/go/cmd/go/internal/modcmd/tidy.go | 76 +- libgo/go/cmd/go/internal/modcmd/vendor.go | 90 +- libgo/go/cmd/go/internal/modcmd/verify.go | 31 +- libgo/go/cmd/go/internal/modcmd/why.go | 32 +- libgo/go/cmd/go/internal/modconv/convert.go | 59 +- .../cmd/go/internal/modconv/convert_test.go | 10 +- .../cmd/go/internal/modconv/modconv_test.go | 6 +- libgo/go/cmd/go/internal/modfetch/cache.go | 82 +- .../go/cmd/go/internal/modfetch/cache_test.go | 3 +- .../go/internal/modfetch/codehost/codehost.go | 22 +- .../cmd/go/internal/modfetch/codehost/git.go | 27 +- .../go/internal/modfetch/codehost/git_test.go | 9 +- .../go/internal/modfetch/codehost/shell.go | 6 +- .../cmd/go/internal/modfetch/codehost/vcs.go | 10 +- libgo/go/cmd/go/internal/modfetch/coderepo.go | 90 +- .../cmd/go/internal/modfetch/coderepo_test.go | 41 +- libgo/go/cmd/go/internal/modfetch/fetch.go | 319 +- libgo/go/cmd/go/internal/modfetch/insecure.go | 6 +- libgo/go/cmd/go/internal/modfetch/proxy.go | 24 +- libgo/go/cmd/go/internal/modfetch/pseudo.go | 12 + libgo/go/cmd/go/internal/modfetch/repo.go | 68 +- libgo/go/cmd/go/internal/modfetch/sumdb.go | 15 +- .../modfetch/zip_sum_test/zip_sum_test.go | 6 +- libgo/go/cmd/go/internal/modget/get.go | 2059 +- libgo/go/cmd/go/internal/modget/query.go | 357 + libgo/go/cmd/go/internal/modinfo/info.go | 17 +- libgo/go/cmd/go/internal/modload/build.go | 101 +- libgo/go/cmd/go/internal/modload/buildlist.go | 267 + libgo/go/cmd/go/internal/modload/help.go | 97 +- libgo/go/cmd/go/internal/modload/import.go | 380 +- .../go/cmd/go/internal/modload/import_test.go | 47 +- libgo/go/cmd/go/internal/modload/init.go | 521 +- libgo/go/cmd/go/internal/modload/list.go | 71 +- libgo/go/cmd/go/internal/modload/load.go | 1059 +- libgo/go/cmd/go/internal/modload/modfile.go | 457 +- libgo/go/cmd/go/internal/modload/mvs.go | 210 +- libgo/go/cmd/go/internal/modload/mvs_test.go | 31 + libgo/go/cmd/go/internal/modload/query.go | 840 +- .../go/cmd/go/internal/modload/query_test.go | 36 +- libgo/go/cmd/go/internal/modload/search.go | 57 +- .../cmd/go/internal/modload/stat_openfile.go | 5 +- libgo/go/cmd/go/internal/modload/stat_unix.go | 5 +- .../cmd/go/internal/modload/stat_windows.go | 6 +- libgo/go/cmd/go/internal/modload/testgo.go | 11 - libgo/go/cmd/go/internal/modload/vendor.go | 10 +- libgo/go/cmd/go/internal/mvs/errors.go | 101 + libgo/go/cmd/go/internal/mvs/mvs.go | 141 +- libgo/go/cmd/go/internal/mvs/mvs_test.go | 47 +- libgo/go/cmd/go/internal/par/queue.go | 88 + libgo/go/cmd/go/internal/par/queue_test.go | 79 + libgo/go/cmd/go/internal/renameio/renameio.go | 11 +- .../cmd/go/internal/renameio/renameio_test.go | 13 +- .../go/cmd/go/internal/renameio/umask_test.go | 8 +- libgo/go/cmd/go/internal/robustio/robustio.go | 2 +- .../go/internal/robustio/robustio_flaky.go | 5 +- .../go/internal/robustio/robustio_other.go | 3 +- libgo/go/cmd/go/internal/run/run.go | 11 +- libgo/go/cmd/go/internal/search/search.go | 14 +- libgo/go/cmd/go/internal/str/path.go | 45 - libgo/go/cmd/go/internal/str/str_test.go | 27 + .../go/cmd/go/internal/test/flagdefs_test.go | 11 +- libgo/go/cmd/go/internal/test/genflags.go | 7 +- libgo/go/cmd/go/internal/test/test.go | 77 +- libgo/go/cmd/go/internal/test/testflag.go | 16 + libgo/go/cmd/go/internal/tool/tool.go | 3 +- libgo/go/cmd/go/internal/trace/trace.go | 206 + libgo/go/cmd/go/internal/txtar/archive.go | 4 +- .../cmd/go/internal/{get => vcs}/discovery.go | 2 +- .../pkg_test.go => vcs/discovery_test.go} | 23 +- libgo/go/cmd/go/internal/{get => vcs}/vcs.go | 561 +- .../cmd/go/internal/{get => vcs}/vcs_test.go | 160 +- libgo/go/cmd/go/internal/version/version.go | 24 +- libgo/go/cmd/go/internal/vet/vet.go | 36 +- libgo/go/cmd/go/internal/web/api.go | 11 +- libgo/go/cmd/go/internal/web/file_test.go | 8 +- libgo/go/cmd/go/internal/web/http.go | 7 + libgo/go/cmd/go/internal/work/action.go | 29 +- libgo/go/cmd/go/internal/work/build.go | 314 +- libgo/go/cmd/go/internal/work/build_test.go | 18 +- libgo/go/cmd/go/internal/work/buildid.go | 45 +- libgo/go/cmd/go/internal/work/exec.go | 280 +- libgo/go/cmd/go/internal/work/exec_test.go | 86 + libgo/go/cmd/go/internal/work/gc.go | 128 +- libgo/go/cmd/go/internal/work/gccgo.go | 40 +- libgo/go/cmd/go/internal/work/init.go | 27 +- libgo/go/cmd/go/internal/work/security.go | 4 +- .../go/cmd/go/internal/work/security_test.go | 3 + libgo/go/cmd/go/main.go | 28 +- libgo/go/cmd/go/proxy_test.go | 35 +- libgo/go/cmd/go/script_test.go | 77 +- libgo/go/cmd/go/testdata/addmod.go | 18 +- libgo/go/cmd/go/testdata/savedir.go | 8 +- libgo/go/cmd/go/testdata/script/README | 1 + .../cmd/go/testdata/script/build_GOTMPDIR.txt | 49 +- .../cmd/go/testdata/script/build_trimpath.txt | 31 +- libgo/go/cmd/go/testdata/script/env_write.txt | 56 + .../go/testdata/script/gcflags_patterns.txt | 4 + .../go/cmd/go/testdata/script/get_unicode.txt | 40 - .../go/testdata/script/gopath_moved_repo.txt | 5 +- .../testdata/script/link_syso_issue33139.txt | 11 +- .../go/testdata/script/list_bad_import.txt | 18 +- .../cmd/go/testdata/script/list_test_err.txt | 3 + libgo/go/cmd/go/testdata/script/mod_auth.txt | 3 +- .../cmd/go/testdata/script/mod_bad_domain.txt | 18 +- .../go/testdata/script/mod_bad_filenames.txt | 6 +- .../go/testdata/script/mod_build_info_err.txt | 15 +- libgo/go/cmd/go/testdata/script/mod_case.txt | 9 +- .../cmd/go/testdata/script/mod_case_cgo.txt | 4 +- .../cmd/go/testdata/script/mod_concurrent.txt | 1 + libgo/go/cmd/go/testdata/script/mod_doc.txt | 2 + .../go/testdata/script/mod_domain_root.txt | 2 +- libgo/go/cmd/go/testdata/script/mod_dot.txt | 6 +- .../cmd/go/testdata/script/mod_download.txt | 97 +- .../go/testdata/script/mod_download_json.txt | 3 +- libgo/go/cmd/go/testdata/script/mod_edit.txt | 114 +- .../go/cmd/go/testdata/script/mod_enabled.txt | 4 +- libgo/go/cmd/go/testdata/script/mod_find.txt | 5 + .../cmd/go/testdata/script/mod_get_commit.txt | 5 +- .../go/testdata/script/mod_get_downgrade.txt | 17 +- .../testdata/script/mod_get_incompatible.txt | 6 +- .../go/testdata/script/mod_get_indirect.txt | 2 +- .../testdata/script/mod_get_latest_pseudo.txt | 2 +- .../cmd/go/testdata/script/mod_get_main.txt | 30 +- .../cmd/go/testdata/script/mod_get_moved.txt | 7 +- .../go/testdata/script/mod_get_newcycle.txt | 3 +- .../cmd/go/testdata/script/mod_get_none.txt | 4 +- .../go/testdata/script/mod_get_patterns.txt | 12 +- .../cmd/go/testdata/script/mod_get_test.txt | 2 +- .../script/mod_get_trailing_slash.txt | 3 + .../go/testdata/script/mod_get_upgrade.txt | 2 +- .../cmd/go/testdata/script/mod_go_version.txt | 41 +- .../go/testdata/script/mod_gobuild_import.txt | 2 +- .../cmd/go/testdata/script/mod_gonoproxy.txt | 20 +- .../go/testdata/script/mod_gopkg_unstable.txt | 2 +- .../go/cmd/go/testdata/script/mod_import.txt | 2 +- .../testdata/script/mod_in_testdata_dir.txt | 6 +- .../cmd/go/testdata/script/mod_indirect.txt | 2 +- .../cmd/go/testdata/script/mod_init_dep.txt | 21 +- .../cmd/go/testdata/script/mod_init_path.txt | 2 +- .../testdata/script/mod_install_versioned.txt | 2 + .../cmd/go/testdata/script/mod_internal.txt | 14 +- .../testdata/script/mod_invalid_version.txt | 7 +- .../cmd/go/testdata/script/mod_issue35317.txt | 2 +- libgo/go/cmd/go/testdata/script/mod_list.txt | 8 +- .../testdata/script/mod_list_bad_import.txt | 20 +- .../cmd/go/testdata/script/mod_list_dir.txt | 5 + .../go/testdata/script/mod_list_direct.txt | 2 +- .../go/testdata/script/mod_list_pseudo.txt | 21 +- .../testdata/script/mod_list_replace_dir.txt | 12 +- .../cmd/go/testdata/script/mod_list_std.txt | 64 +- .../cmd/go/testdata/script/mod_list_test.txt | 14 + .../go/testdata/script/mod_list_upgrade.txt | 4 + .../go/testdata/script/mod_load_badchain.txt | 22 +- .../go/testdata/script/mod_load_badmod.txt | 7 +- .../go/testdata/script/mod_load_badzip.txt | 4 +- .../script/mod_missingpkg_prerelease.txt | 4 +- .../go/cmd/go/testdata/script/mod_modinfo.txt | 4 +- .../cmd/go/testdata/script/mod_multirepo.txt | 1 + libgo/go/cmd/go/testdata/script/mod_off.txt | 4 +- .../cmd/go/testdata/script/mod_off_init.txt | 2 +- .../go/cmd/go/testdata/script/mod_outside.txt | 41 +- .../go/testdata/script/mod_permissions.txt | 2 +- .../cmd/go/testdata/script/mod_proxy_list.txt | 14 +- libgo/go/cmd/go/testdata/script/mod_query.txt | 10 + .../go/testdata/script/mod_query_empty.txt | 4 +- .../go/testdata/script/mod_query_exclude.txt | 41 +- .../cmd/go/testdata/script/mod_readonly.txt | 45 +- .../go/cmd/go/testdata/script/mod_replace.txt | 4 +- .../testdata/script/mod_replace_gopkgin.txt | 3 +- .../go/testdata/script/mod_replace_import.txt | 13 +- .../testdata/script/mod_require_exclude.txt | 62 +- .../cmd/go/testdata/script/mod_retention.txt | 6 +- .../cmd/go/testdata/script/mod_std_vendor.txt | 6 +- libgo/go/cmd/go/testdata/script/mod_sumdb.txt | 8 +- .../testdata/script/mod_sumdb_file_path.txt | 2 +- .../go/testdata/script/mod_sumdb_golang.txt | 12 +- .../go/testdata/script/mod_sumdb_proxy.txt | 6 +- .../go/cmd/go/testdata/script/mod_symlink.txt | 5 +- libgo/go/cmd/go/testdata/script/mod_test.txt | 1 + .../go/testdata/script/mod_test_cached.txt | 7 +- .../go/testdata/script/mod_tidy_replace.txt | 3 +- .../go/testdata/script/mod_upgrade_patch.txt | 22 +- .../go/testdata/script/mod_vcs_missing.txt | 4 +- .../go/testdata/script/mod_vendor_auto.txt | 2 +- .../go/testdata/script/mod_vendor_build.txt | 5 +- .../go/cmd/go/testdata/script/mod_verify.txt | 10 +- libgo/go/cmd/go/testdata/script/mod_why.txt | 17 +- .../cmd/go/testdata/script/modfile_flag.txt | 6 +- .../cmd/go/testdata/script/sum_readonly.txt | 29 - .../go/testdata/script/test_cache_inputs.txt | 4 +- .../testdata/script/test_compile_tempfile.txt | 2 +- .../testdata/script/test_generated_main.txt | 3 +- libgo/go/cmd/go/testdata/script/version.txt | 1 + libgo/go/cmd/go/testdata/script/vet_flags.txt | 16 +- libgo/go/cmd/gofmt/gofmt.go | 18 +- libgo/go/cmd/gofmt/gofmt_test.go | 13 +- libgo/go/cmd/gofmt/long_test.go | 18 +- libgo/go/cmd/internal/buildid/buildid.go | 38 +- libgo/go/cmd/internal/buildid/buildid_test.go | 31 + libgo/go/cmd/internal/buildid/note.go | 7 +- libgo/go/cmd/internal/buildid/rewrite.go | 71 + libgo/go/cmd/internal/codesign/codesign.go | 268 + libgo/go/cmd/internal/objabi/doc.go | 122 - libgo/go/cmd/internal/objabi/flag.go | 39 + libgo/go/cmd/internal/objabi/flag_test.go | 26 + libgo/go/cmd/internal/objabi/funcdata.go | 15 +- libgo/go/cmd/internal/objabi/funcid.go | 28 +- libgo/go/cmd/internal/objabi/head.go | 2 +- libgo/go/cmd/internal/objabi/line.go | 33 +- libgo/go/cmd/internal/objabi/path.go | 22 + libgo/go/cmd/internal/objabi/reloctype.go | 22 + .../cmd/internal/objabi/reloctype_string.go | 70 +- libgo/go/cmd/internal/objabi/symkind.go | 7 +- .../go/cmd/internal/objabi/symkind_string.go | 21 +- libgo/go/cmd/internal/objabi/util.go | 30 +- libgo/go/cmd/internal/sys/supported.go | 27 +- libgo/go/cmd/internal/sys/supported_test.go | 18 + libgo/go/cmd/internal/traceviewer/format.go | 38 + libgo/go/cmd/vendor/modules.txt | 91 + libgo/go/cmd/vet/main.go | 4 + libgo/go/cmd/vet/vet_test.go | 5 +- libgo/go/compress/bzip2/bzip2.go | 8 +- libgo/go/compress/bzip2/bzip2_test.go | 10 +- libgo/go/compress/flate/deflate_test.go | 30 +- libgo/go/compress/flate/dict_decoder.go | 6 +- libgo/go/compress/flate/flate_test.go | 5 +- libgo/go/compress/flate/huffman_bit_writer.go | 4 +- .../compress/flate/huffman_bit_writer_test.go | 29 +- libgo/go/compress/flate/inflate_test.go | 3 +- libgo/go/compress/flate/reader_test.go | 8 +- libgo/go/compress/flate/writer_test.go | 9 +- libgo/go/compress/gzip/gunzip_test.go | 9 +- libgo/go/compress/gzip/gzip_test.go | 9 +- libgo/go/compress/gzip/issue14937_test.go | 3 +- libgo/go/compress/lzw/reader_test.go | 8 +- libgo/go/compress/lzw/writer_test.go | 13 +- libgo/go/compress/zlib/writer_test.go | 7 +- libgo/go/crypto/cipher/xor_arm64.go | 31 + libgo/go/crypto/cipher/xor_generic.go | 2 +- libgo/go/crypto/des/block.go | 2 +- libgo/go/crypto/dsa/dsa.go | 6 + libgo/go/crypto/ecdsa/ecdsa_s390x.go | 59 +- .../internal/edwards25519/edwards25519.go | 2 +- libgo/go/crypto/hmac/hmac.go | 15 + libgo/go/crypto/hmac/hmac_test.go | 24 +- libgo/go/crypto/md5/gen.go | 4 +- libgo/go/crypto/rand/eagain.go | 4 +- libgo/go/crypto/rand/rand.go | 6 +- libgo/go/crypto/rand/rand_unix.go | 4 + libgo/go/crypto/rand/rand_windows.go | 40 +- libgo/go/crypto/tls/cipher_suites.go | 51 +- libgo/go/crypto/tls/common.go | 123 +- libgo/go/crypto/tls/conn.go | 189 +- libgo/go/crypto/tls/handshake_client.go | 51 +- libgo/go/crypto/tls/handshake_client_test.go | 36 + libgo/go/crypto/tls/handshake_client_tls13.go | 17 +- libgo/go/crypto/tls/handshake_server.go | 40 +- libgo/go/crypto/tls/handshake_server_test.go | 358 +- libgo/go/crypto/tls/handshake_server_tls13.go | 19 +- libgo/go/crypto/tls/handshake_test.go | 7 +- libgo/go/crypto/tls/link_test.go | 16 +- .../go/crypto/tls/testdata/Server-TLSv12-ALPN | 84 +- .../tls/testdata/Server-TLSv12-ALPN-NoMatch | 84 +- ...er-TLSv12-ClientAuthRequestedAndECDSAGiven | 170 +- ...-TLSv12-ClientAuthRequestedAndEd25519Given | 171 +- .../Server-TLSv12-ClientAuthRequestedAndGiven | 170 +- ...TLSv12-ClientAuthRequestedAndPKCS1v15Given | 170 +- .../Server-TLSv12-ClientAuthRequestedNotGiven | 152 +- .../crypto/tls/testdata/Server-TLSv12-Ed25519 | 61 +- .../Server-TLSv12-ExportKeyingMaterial | 81 +- .../tls/testdata/Server-TLSv12-IssueTicket | 66 +- .../Server-TLSv12-IssueTicketPreDisable | 66 +- .../testdata/Server-TLSv12-RSA-RSAPKCS1v15 | 63 +- .../tls/testdata/Server-TLSv12-RSA-RSAPSS | 48 +- .../crypto/tls/testdata/Server-TLSv12-Resume | 60 +- .../tls/testdata/Server-TLSv12-ResumeDisabled | 167 +- .../go/crypto/tls/testdata/Server-TLSv13-ALPN | 186 +- .../tls/testdata/Server-TLSv13-ALPN-NoMatch | 186 +- ...er-TLSv13-ClientAuthRequestedAndECDSAGiven | 345 +- ...-TLSv13-ClientAuthRequestedAndEd25519Given | 285 +- .../Server-TLSv13-ClientAuthRequestedAndGiven | 339 +- .../Server-TLSv13-ClientAuthRequestedNotGiven | 195 +- .../crypto/tls/testdata/Server-TLSv13-Ed25519 | 139 +- .../Server-TLSv13-ExportKeyingMaterial | 184 +- .../testdata/Server-TLSv13-HelloRetryRequest | 218 +- .../tls/testdata/Server-TLSv13-IssueTicket | 184 +- .../Server-TLSv13-IssueTicketPreDisable | 184 +- .../go/crypto/tls/testdata/Server-TLSv13-P256 | 186 +- .../tls/testdata/Server-TLSv13-RSA-RSAPSS | 109 +- .../Server-TLSv13-RSA-RSAPSS-TooSmall | 25 +- .../crypto/tls/testdata/Server-TLSv13-Resume | 106 +- .../Server-TLSv13-Resume-HelloRetryRequest | 168 +- .../tls/testdata/Server-TLSv13-ResumeDisabled | 185 +- .../crypto/tls/testdata/Server-TLSv13-X25519 | 182 +- libgo/go/crypto/tls/tls.go | 61 +- libgo/go/crypto/tls/tls_test.go | 18 +- libgo/go/crypto/x509/cert_pool.go | 179 +- .../x509/internal/macos/corefoundation.go | 6 +- .../go/crypto/x509/internal/macos/security.go | 6 +- libgo/go/crypto/x509/name_constraints_test.go | 15 +- libgo/go/crypto/x509/pem_decrypt.go | 35 +- libgo/go/crypto/x509/root.go | 2 +- libgo/go/crypto/x509/root_aix.go | 6 + libgo/go/crypto/x509/root_bsd.go | 7 + libgo/go/crypto/x509/root_cgo_darwin_amd64.go | 322 - .../{root_darwin_amd64.go => root_darwin.go} | 4 - .../x509/{root_darwin_ios.go => root_ios.go} | 218 +- ...root_darwin_ios_gen.go => root_ios_gen.go} | 23 +- libgo/go/crypto/x509/root_js.go | 4 + libgo/go/crypto/x509/root_linux.go | 8 + libgo/go/crypto/x509/root_omit.go | 3 - libgo/go/crypto/x509/root_plan9.go | 3 +- libgo/go/crypto/x509/root_solaris.go | 6 + libgo/go/crypto/x509/root_unix.go | 39 +- libgo/go/crypto/x509/root_unix_test.go | 20 +- libgo/go/crypto/x509/root_windows.go | 118 +- libgo/go/crypto/x509/verify.go | 22 +- libgo/go/crypto/x509/verify_test.go | 133 +- libgo/go/crypto/x509/x509.go | 594 +- libgo/go/crypto/x509/x509_test.go | 395 +- libgo/go/database/sql/sql.go | 30 +- libgo/go/database/sql/sql_test.go | 83 +- libgo/go/debug/dwarf/const.go | 12 + libgo/go/debug/dwarf/dwarf5ranges_test.go | 41 + libgo/go/debug/dwarf/entry.go | 354 +- libgo/go/debug/dwarf/entry_test.go | 142 +- libgo/go/debug/dwarf/line.go | 6 +- libgo/go/debug/dwarf/line_test.go | 8 + libgo/go/debug/dwarf/open.go | 13 +- libgo/go/debug/dwarf/testdata/debug_rnglists | Bin 0 -> 23 bytes .../dwarf/testdata/line-clang-dwarf5.elf | Bin 0 -> 18384 bytes .../debug/dwarf/testdata/line-gcc-dwarf5.elf | Bin 0 -> 18040 bytes libgo/go/debug/elf/elf.go | 223 +- libgo/go/debug/elf/file.go | 82 +- libgo/go/debug/elf/file_test.go | 625 +- ...location-test-gcc930-ranges-no-rela-x86-64 | Bin 0 -> 5696 bytes ...cation-test-gcc930-ranges-with-rela-x86-64 | Bin 0 -> 7680 bytes .../elf/testdata/multiple-code-sections.c | 28 + libgo/go/debug/gosym/pclntab.go | 221 +- libgo/go/debug/gosym/pclntab_test.go | 54 +- libgo/go/debug/pe/file_test.go | 13 +- libgo/go/embed/embed.go | 406 + .../embed/internal/embedtest/concurrency.txt | 1 + .../go/embed/internal/embedtest/embed_test.go | 124 + .../embed/internal/embedtest/embedx_test.go | 106 + .../embedtest/testdata/.hidden/.more/tip.txt | 1 + .../embedtest/testdata/.hidden/_more/tip.txt | 1 + .../embedtest/testdata/.hidden/fortune.txt | 2 + .../embedtest/testdata/.hidden/more/tip.txt | 1 + .../embedtest/testdata/_hidden/fortune.txt | 2 + .../internal/embedtest/testdata/ascii.txt | 25 + .../internal/embedtest/testdata/glass.txt | 1 + .../internal/embedtest/testdata/hello.txt | 1 + .../internal/embedtest/testdata/i/i18n.txt | 1 + .../internal/embedtest/testdata/i/j/k/k8s.txt | 1 + .../embed/internal/embedtest/testdata/ken.txt | 1 + libgo/go/encoding/ascii85/ascii85_test.go | 7 +- libgo/go/encoding/asn1/asn1.go | 84 +- libgo/go/encoding/asn1/asn1_test.go | 23 + libgo/go/encoding/asn1/common.go | 11 +- libgo/go/encoding/asn1/marshal_test.go | 28 + libgo/go/encoding/base32/base32_test.go | 13 +- libgo/go/encoding/base64/base64_test.go | 15 +- libgo/go/encoding/binary/binary.go | 2 +- libgo/go/encoding/binary/binary_test.go | 27 +- libgo/go/encoding/binary/varint.go | 4 +- libgo/go/encoding/gob/encoder_test.go | 4 +- libgo/go/encoding/hex/hex_test.go | 3 +- libgo/go/encoding/json/bench_test.go | 8 +- libgo/go/encoding/json/encode.go | 31 +- libgo/go/encoding/json/encode_test.go | 27 +- libgo/go/encoding/json/stream_test.go | 5 +- libgo/go/encoding/json/tagkey_test.go | 4 +- libgo/go/encoding/pem/pem_test.go | 4 +- libgo/go/encoding/xml/marshal.go | 7 +- libgo/go/encoding/xml/marshal_test.go | 24 + libgo/go/errors/errors.go | 12 +- libgo/go/errors/wrap.go | 4 +- libgo/go/errors/wrap_test.go | 11 +- libgo/go/flag/example_func_test.go | 41 + libgo/go/flag/flag.go | 22 +- libgo/go/flag/flag_test.go | 55 +- libgo/go/fmt/doc.go | 3 +- libgo/go/fmt/fmt_test.go | 8 +- libgo/go/fmt/print.go | 14 +- libgo/go/go.mod | 10 + libgo/go/go/ast/ast.go | 11 + libgo/go/go/ast/commentmap_test.go | 29 +- libgo/go/go/build/build.go | 464 +- libgo/go/go/build/build_test.go | 238 +- libgo/go/go/build/deps_test.go | 67 +- libgo/go/go/build/read.go | 268 +- libgo/go/go/build/read_test.go | 91 +- libgo/go/go/build/syslist.go | 2 +- libgo/go/go/build/syslist_test.go | 2 +- libgo/go/go/constant/value.go | 24 +- libgo/go/go/constant/value_test.go | 106 +- libgo/go/go/doc/comment.go | 2 +- libgo/go/go/doc/comment_test.go | 11 + libgo/go/go/doc/doc_test.go | 10 +- libgo/go/go/doc/example.go | 2 +- libgo/go/go/doc/example_test.go | 9 +- libgo/go/go/doc/headscan.go | 7 +- libgo/go/go/format/benchmark_test.go | 4 +- libgo/go/go/format/format_test.go | 6 +- libgo/go/go/importer/importer_test.go | 3 +- .../go/go/internal/gccgoimporter/importer.go | 2 +- .../internal/gccgoimporter/importer_test.go | 6 +- .../gccgoimporter/testdata/notinheap.go | 4 + .../gccgoimporter/testdata/notinheap.gox | 7 + libgo/go/go/internal/gcimporter/gcimporter.go | 3 +- .../go/internal/gcimporter/gcimporter_test.go | 11 +- libgo/go/go/internal/gcimporter/support.go | 5 +- .../go/go/internal/srcimporter/srcimporter.go | 3 +- .../internal/srcimporter/srcimporter_test.go | 3 +- libgo/go/go/parser/error_test.go | 10 +- libgo/go/go/parser/interface.go | 50 +- libgo/go/go/parser/parser_test.go | 12 +- libgo/go/go/parser/performance_test.go | 4 +- .../issue42951/not_a_file.go/invalid.go | 1 + libgo/go/go/printer/performance_test.go | 6 +- libgo/go/go/printer/printer_test.go | 12 +- libgo/go/go/scanner/scanner_test.go | 3 +- libgo/go/go/token/position.go | 21 +- libgo/go/go/types/api.go | 12 +- libgo/go/go/types/api_test.go | 44 + libgo/go/go/types/assignments.go | 55 +- libgo/go/go/types/builtins.go | 92 +- libgo/go/go/types/call.go | 40 +- libgo/go/go/types/check.go | 17 +- libgo/go/go/types/check_test.go | 47 +- libgo/go/go/types/conversions.go | 20 +- libgo/go/go/types/decl.go | 307 +- libgo/go/go/types/errorcodes.go | 1366 ++ libgo/go/go/types/errorcodes_test.go | 199 + libgo/go/go/types/errors.go | 134 +- libgo/go/go/types/expr.go | 314 +- libgo/go/go/types/gotype.go | 12 +- libgo/go/go/types/hilbert_test.go | 4 +- libgo/go/go/types/initorder.go | 6 +- libgo/go/go/types/issues_test.go | 26 + libgo/go/go/types/labels.go | 18 +- libgo/go/go/types/operand.go | 75 +- libgo/go/go/types/predicates.go | 16 +- libgo/go/go/types/resolver.go | 318 +- libgo/go/go/types/self_test.go | 91 +- libgo/go/go/types/stdlib_test.go | 67 +- libgo/go/go/types/stmt.go | 123 +- libgo/go/go/types/testdata/builtins.src | 4 +- libgo/go/go/types/testdata/constdecl.src | 31 + libgo/go/go/types/testdata/cycles.src | 8 +- libgo/go/go/types/testdata/cycles2.src | 5 +- libgo/go/go/types/testdata/decls1.src | 2 + libgo/go/go/types/testdata/decls2b.src | 8 +- libgo/go/go/types/testdata/expr3.src | 35 +- libgo/go/go/types/testdata/issue23203a.src | 14 - libgo/go/go/types/testdata/issue23203b.src | 14 - libgo/go/go/types/testdata/issue26390.src | 11 - libgo/go/go/types/testdata/issue28251.src | 65 - libgo/go/go/types/testdata/issue6977.src | 82 - libgo/go/go/types/testdata/issues.src | 4 +- libgo/go/go/types/testdata/shifts.src | 23 +- libgo/go/go/types/testdata/stmt0.src | 12 +- libgo/go/go/types/typexpr.go | 70 +- libgo/go/golang.org/x/mod/modfile/read.go | 8 + libgo/go/golang.org/x/mod/modfile/rule.go | 243 +- libgo/go/golang.org/x/mod/module/module.go | 80 +- libgo/go/golang.org/x/mod/semver/semver.go | 3 + libgo/go/golang.org/x/mod/zip/zip.go | 621 +- .../golang.org/x/net/http/httpproxy/proxy.go | 6 +- .../idna/{tables12.00.go => tables12.0.0.go} | 2 +- .../go/golang.org/x/net/idna/tables13.0.0.go | 4839 ++++ libgo/go/golang.org/x/net/nettest/nettest.go | 6 +- .../golang.org/x/net/nettest/nettest_stub.go | 2 +- .../golang.org/x/net/nettest/nettest_unix.go | 2 +- libgo/go/golang.org/x/net/route/address.go | 2 +- .../golang.org/x/net/route/route_classic.go | 2 +- libgo/go/golang.org/x/sys/cpu/byteorder.go | 4 +- libgo/go/golang.org/x/sys/cpu/cpu.go | 156 +- libgo/go/golang.org/x/sys/cpu/cpu_aix.go | 2 +- libgo/go/golang.org/x/sys/cpu/cpu_arm.go | 33 + libgo/go/golang.org/x/sys/cpu/cpu_arm64.go | 64 +- libgo/go/golang.org/x/sys/cpu/cpu_gc_arm64.go | 2 +- libgo/go/golang.org/x/sys/cpu/cpu_gc_s390x.go | 2 +- libgo/go/golang.org/x/sys/cpu/cpu_gc_x86.go | 2 +- libgo/go/golang.org/x/sys/cpu/cpu_linux.go | 2 +- .../golang.org/x/sys/cpu/cpu_linux_mips64x.go | 1 + .../golang.org/x/sys/cpu/cpu_linux_ppc64x.go | 2 - .../golang.org/x/sys/cpu/cpu_linux_s390x.go | 123 +- libgo/go/golang.org/x/sys/cpu/cpu_mips64x.go | 6 + libgo/go/golang.org/x/sys/cpu/cpu_mipsx.go | 2 + .../golang.org/x/sys/cpu/cpu_netbsd_arm64.go | 173 + .../go/golang.org/x/sys/cpu/cpu_other_arm.go | 9 + .../golang.org/x/sys/cpu/cpu_other_arm64.go | 3 +- .../golang.org/x/sys/cpu/cpu_other_mips64x.go | 12 + libgo/go/golang.org/x/sys/cpu/cpu_ppc64x.go | 16 + libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go | 2 + libgo/go/golang.org/x/sys/cpu/cpu_s390x.go | 172 + libgo/go/golang.org/x/sys/cpu/cpu_wasm.go | 4 + libgo/go/golang.org/x/sys/cpu/cpu_x86.go | 82 +- libgo/go/golang.org/x/sys/cpu/cpu_zos.go | 10 + .../go/golang.org/x/sys/cpu/cpu_zos_s390x.go | 25 + .../golang.org/x/sys/cpu/syscall_aix_gccgo.go | 4 +- .../x/sys/cpu/syscall_aix_ppc64_gc.go | 2 +- .../golang.org/x/text/transform/transform.go | 6 +- .../x/text/unicode/bidi/tables12.0.0.go | 2 +- .../x/text/unicode/bidi/tables13.0.0.go | 1955 ++ .../x/text/unicode/norm/tables12.0.0.go | 2 +- .../x/text/unicode/norm/tables13.0.0.go | 7760 ++++++ .../x/tools/go/analysis/analysis.go | 13 +- .../go/golang.org/x/tools/go/analysis/doc.go | 21 +- .../go/analysis/passes/asmdecl/asmdecl.go | 13 +- .../go/analysis/passes/buildtag/buildtag.go | 22 +- .../passes/framepointer/framepointer.go | 91 + .../passes/ifaceassert/ifaceassert.go | 4 + .../go/analysis/passes/structtag/structtag.go | 100 +- .../testinggoroutine/testinggoroutine.go | 154 + .../go/analysis/passes/unmarshal/unmarshal.go | 7 +- .../go/analysis/passes/unsafeptr/unsafeptr.go | 122 +- .../passes/unusedresult/unusedresult.go | 2 +- .../go/analysis/unitchecker/unitchecker.go | 2 + .../x/tools/go/analysis/validate.go | 33 +- .../internal/analysisinternal/analysis.go | 343 +- .../x/tools/internal/lsp/fuzzy/input.go | 168 + .../x/tools/internal/lsp/fuzzy/matcher.go | 398 + libgo/go/hash/crc32/crc32.go | 16 +- libgo/go/hash/crc32/crc32_test.go | 10 + libgo/go/hash/crc32/gen_const_ppc64le.go | 4 +- libgo/go/hash/maphash/maphash.go | 5 +- libgo/go/hash/maphash/maphash_test.go | 29 + libgo/go/html/template/clone_test.go | 14 +- libgo/go/html/template/escape.go | 2 + libgo/go/html/template/examplefiles_test.go | 3 +- libgo/go/html/template/exec_test.go | 80 +- libgo/go/html/template/multi_test.go | 43 + libgo/go/html/template/template.go | 150 +- libgo/go/html/template/template_test.go | 16 + libgo/go/html/template/testdata/fs.zip | Bin 0 -> 406 bytes libgo/go/image/color/palette/gen.go | 4 +- libgo/go/image/gif/reader_test.go | 4 +- libgo/go/image/gif/writer_test.go | 87 +- libgo/go/image/internal/imageutil/gen.go | 3 +- libgo/go/image/jpeg/reader_test.go | 7 +- libgo/go/image/jpeg/writer_test.go | 6 +- libgo/go/image/png/reader_test.go | 3 +- libgo/go/image/png/writer_test.go | 17 +- libgo/go/index/suffixarray/gen.go | 6 +- .../go/index/suffixarray/suffixarray_test.go | 8 +- libgo/go/internal/bytealg/bytealg.go | 4 +- libgo/go/internal/bytealg/count_generic.go | 2 +- libgo/go/internal/bytealg/count_native.go | 2 +- libgo/go/internal/cfg/cfg.go | 1 + libgo/go/internal/cpu/cpu.go | 37 +- libgo/go/internal/cpu/cpu_arm64.go | 88 +- libgo/go/internal/cpu/cpu_arm64_android.go | 11 + libgo/go/internal/cpu/cpu_arm64_darwin.go | 34 + libgo/go/internal/cpu/cpu_arm64_freebsd.go | 45 + libgo/go/internal/cpu/cpu_arm64_hwcap.go | 63 + libgo/go/internal/cpu/cpu_arm64_linux.go | 13 + libgo/go/internal/cpu/cpu_arm64_other.go | 17 + libgo/go/internal/cpu/cpu_no_init.go | 19 - libgo/go/internal/cpu/cpu_no_name.go | 19 + libgo/go/internal/cpu/cpu_ppc64x_aix.go | 21 + libgo/go/internal/cpu/cpu_ppc64x_linux.go | 29 + libgo/go/internal/cpu/cpu_riscv64.go | 5 + libgo/go/internal/cpu/cpu_s390x.go | 17 +- libgo/go/internal/cpu/cpu_s390x_test.go | 4 +- libgo/go/internal/cpu/cpu_test.go | 8 +- libgo/go/internal/cpu/cpu_x86.go | 60 +- libgo/go/internal/fmtsort/sort.go | 2 +- libgo/go/internal/fmtsort/sort_test.go | 22 + libgo/go/internal/goversion/goversion.go | 11 +- .../obscuretestdata/obscuretestdata.go | 5 +- libgo/go/internal/poll/error_test.go | 3 +- libgo/go/internal/poll/fd_fsync_darwin.go | 7 +- libgo/go/internal/poll/fd_fsync_posix.go | 4 +- libgo/go/internal/poll/fd_opendir_darwin.go | 8 +- libgo/go/internal/poll/fd_posix.go | 33 +- libgo/go/internal/poll/fd_unix.go | 42 +- libgo/go/internal/poll/fd_windows.go | 27 + libgo/go/internal/poll/fd_writev_illumos.go | 16 + libgo/go/internal/poll/hook_cloexec.go | 2 +- libgo/go/internal/poll/iovec_illumos.go | 16 + libgo/go/internal/poll/iovec_unix.go | 13 + libgo/go/internal/poll/read_test.go | 5 +- libgo/go/internal/poll/sock_cloexec.go | 2 +- libgo/go/internal/poll/sys_cloexec.go | 2 +- libgo/go/internal/poll/writev.go | 4 +- libgo/go/internal/profile/profile.go | 5 +- .../reflectlite/reflect_mirror_test.go | 3 +- libgo/go/internal/reflectlite/type.go | 38 + libgo/go/internal/reflectlite/value.go | 5 +- .../go/internal/syscall/windows/mksyscall.go | 2 +- .../internal/syscall/windows/registry/key.go | 17 +- .../syscall/windows/registry/mksyscall.go | 2 +- .../syscall/windows/registry/registry_test.go | 6 +- .../syscall/windows/registry/value.go | 13 +- .../windows/registry/zsyscall_windows.go | 25 +- .../syscall/windows/syscall_windows.go | 9 + .../syscall/windows/zsyscall_windows.go | 352 +- libgo/go/internal/sysinfo/sysinfo.go | 31 + libgo/go/internal/testenv/testenv.go | 64 +- libgo/go/internal/testenv/testenv_windows.go | 3 +- libgo/go/internal/testlog/exit.go | 33 + libgo/go/internal/trace/gc_test.go | 6 +- libgo/go/internal/trace/parser_test.go | 9 +- libgo/go/io/example_test.go | 17 +- libgo/go/io/export_test.go | 8 + libgo/go/io/fs/fs.go | 251 + libgo/go/io/fs/fs_test.go | 48 + libgo/go/io/fs/glob.go | 120 + libgo/go/io/fs/glob_test.go | 88 + libgo/go/io/fs/readdir.go | 47 + libgo/go/io/fs/readdir_test.go | 43 + libgo/go/io/fs/readfile.go | 63 + libgo/go/io/fs/readfile_test.go | 59 + libgo/go/io/fs/stat.go | 31 + libgo/go/io/fs/stat_test.go | 36 + libgo/go/io/fs/sub.go | 127 + libgo/go/io/fs/sub_test.go | 57 + libgo/go/io/fs/walk.go | 132 + libgo/go/io/fs/walk_test.go | 155 + libgo/go/io/io.go | 105 +- libgo/go/io/io_test.go | 28 + libgo/go/io/ioutil/ioutil.go | 136 +- libgo/go/io/ioutil/tempfile_test.go | 3 +- libgo/go/io/multi_test.go | 11 +- libgo/go/log/log.go | 3 + libgo/go/log/log_test.go | 6 + libgo/go/log/syslog/syslog.go | 5 +- libgo/go/log/syslog/syslog_test.go | 45 +- libgo/go/math/acosh.go | 5 +- libgo/go/math/big/arith.go | 89 +- libgo/go/math/big/arith_decl.go | 2 - libgo/go/math/big/arith_decl_pure.go | 8 - libgo/go/math/big/arith_test.go | 215 +- libgo/go/math/big/decimal.go | 3 + libgo/go/math/big/float.go | 7 +- libgo/go/math/big/link_test.go | 4 +- libgo/go/math/big/nat.go | 3 +- libgo/go/math/big/nat_test.go | 10 + libgo/go/math/bits/make_examples.go | 4 +- libgo/go/math/bits/make_tables.go | 4 +- libgo/go/math/log1p.go | 5 +- libgo/go/mime/encodedword_test.go | 3 +- libgo/go/mime/example_test.go | 31 +- libgo/go/mime/multipart/formdata.go | 11 +- libgo/go/mime/multipart/formdata_test.go | 14 + libgo/go/mime/multipart/multipart.go | 3 +- libgo/go/mime/multipart/multipart_test.go | 13 +- libgo/go/mime/multipart/writer_test.go | 8 +- libgo/go/mime/quotedprintable/example_test.go | 4 +- libgo/go/mime/quotedprintable/writer_test.go | 6 +- libgo/go/mime/type_unix.go | 1 + libgo/go/mime/type_windows.go | 2 +- libgo/go/net/conf.go | 7 +- libgo/go/net/conf_test.go | 21 +- libgo/go/net/conn_test.go | 2 +- libgo/go/net/dial_test.go | 4 +- libgo/go/net/dnsclient.go | 19 +- libgo/go/net/dnsclient_test.go | 5 +- libgo/go/net/dnsclient_unix.go | 3 +- libgo/go/net/dnsclient_unix_test.go | 3 +- libgo/go/net/dnsconfig_unix_test.go | 3 +- libgo/go/net/error_test.go | 33 +- libgo/go/net/example_test.go | 21 + libgo/go/net/http/alpn_test.go | 5 +- libgo/go/net/http/cgi/child.go | 6 +- libgo/go/net/http/cgi/child_test.go | 11 - libgo/go/net/http/cgi/integration_test.go | 21 + libgo/go/net/http/client.go | 7 +- libgo/go/net/http/client_test.go | 82 +- libgo/go/net/http/clientserver_test.go | 49 +- libgo/go/net/http/cookie.go | 2 +- libgo/go/net/http/cookie_test.go | 11 +- libgo/go/net/http/doc.go | 2 +- libgo/go/net/http/example_filesystem_test.go | 14 +- libgo/go/net/http/example_test.go | 3 +- libgo/go/net/http/export_test.go | 13 +- libgo/go/net/http/fcgi/child.go | 8 +- libgo/go/net/http/fcgi/fcgi_test.go | 6 +- libgo/go/net/http/filetransport_test.go | 8 +- libgo/go/net/http/fs.go | 152 +- libgo/go/net/http/fs_test.go | 158 +- libgo/go/net/http/h2_bundle.go | 110 +- libgo/go/net/http/http_test.go | 7 +- libgo/go/net/http/httptest/example_test.go | 9 +- libgo/go/net/http/httptest/httptest.go | 3 +- libgo/go/net/http/httptest/httptest_test.go | 3 +- libgo/go/net/http/httptest/recorder.go | 4 +- libgo/go/net/http/httptest/recorder_test.go | 3 +- libgo/go/net/http/httptest/server_test.go | 10 +- libgo/go/net/http/httputil/dump.go | 9 +- libgo/go/net/http/httputil/dump_test.go | 9 +- libgo/go/net/http/httputil/example_test.go | 6 +- libgo/go/net/http/httputil/reverseproxy.go | 22 +- .../go/net/http/httputil/reverseproxy_test.go | 71 +- libgo/go/net/http/internal/chunked_test.go | 5 +- libgo/go/net/http/main_test.go | 4 +- libgo/go/net/http/omithttp2.go | 6 +- libgo/go/net/http/pprof/pprof.go | 74 +- libgo/go/net/http/pprof/pprof_test.go | 6 +- libgo/go/net/http/readrequest_test.go | 3 +- libgo/go/net/http/request.go | 34 +- libgo/go/net/http/request_test.go | 70 +- libgo/go/net/http/requestwrite_test.go | 52 +- libgo/go/net/http/response.go | 21 +- libgo/go/net/http/response_test.go | 5 +- libgo/go/net/http/responsewrite_test.go | 20 +- libgo/go/net/http/roundtrip_js.go | 11 +- libgo/go/net/http/serve_test.go | 264 +- libgo/go/net/http/server.go | 180 +- libgo/go/net/http/sniff_test.go | 7 +- libgo/go/net/http/transfer.go | 27 +- libgo/go/net/http/transfer_test.go | 19 +- libgo/go/net/http/transport.go | 108 +- libgo/go/net/http/transport_internal_test.go | 3 +- libgo/go/net/http/transport_test.go | 326 +- libgo/go/net/interface_solaris.go | 28 +- libgo/go/net/interface_unix_test.go | 2 +- libgo/go/net/internal/socktest/sys_cloexec.go | 2 +- libgo/go/net/ipsock_plan9.go | 3 +- libgo/go/net/lookup_test.go | 4 +- libgo/go/net/mail/example_test.go | 4 +- libgo/go/net/mail/message.go | 24 +- libgo/go/net/mail/message_test.go | 44 +- libgo/go/net/main_cloexec_test.go | 2 +- libgo/go/net/main_test.go | 2 +- libgo/go/net/mockserver_test.go | 17 +- libgo/go/net/net.go | 12 + libgo/go/net/platform_test.go | 4 +- libgo/go/net/protoconn_test.go | 2 +- libgo/go/net/rawconn_unix_test.go | 20 +- libgo/go/net/rawconn_windows_test.go | 20 +- libgo/go/net/rpc/client.go | 1 - libgo/go/net/rpc/jsonrpc/all_test.go | 5 +- libgo/go/net/sendfile_test.go | 3 +- libgo/go/net/server_test.go | 4 +- libgo/go/net/smtp/smtp.go | 6 +- libgo/go/net/smtp/smtp_test.go | 213 + libgo/go/net/sock_bsd.go | 2 +- libgo/go/net/sock_cloexec.go | 2 +- libgo/go/net/sock_linux.go | 63 +- libgo/go/net/sock_linux_test.go | 22 + libgo/go/net/splice_test.go | 3 +- libgo/go/net/sys_cloexec.go | 2 +- libgo/go/net/tcpsock_test.go | 4 +- libgo/go/net/textproto/reader.go | 3 +- libgo/go/net/timeout_test.go | 3 +- libgo/go/net/udpsock.go | 3 + libgo/go/net/udpsock_test.go | 2 +- libgo/go/net/unixsock_test.go | 3 +- libgo/go/net/url/url.go | 55 +- libgo/go/net/url/url_test.go | 8 + libgo/go/net/writev_test.go | 7 +- libgo/go/net/writev_unix.go | 2 +- libgo/go/os/dir.go | 80 +- libgo/go/os/dir_gccgo.go | 163 +- libgo/go/os/dir_gccgo_c.c | 58 + libgo/go/os/dir_largefile.go | 4 +- libgo/go/os/dir_plan9.go | 42 +- libgo/go/os/dir_regfile.go | 4 +- libgo/go/os/error.go | 47 +- libgo/go/os/error_test.go | 64 +- libgo/go/os/error_unix_test.go | 11 +- libgo/go/os/error_windows_test.go | 11 +- libgo/go/os/example_test.go | 101 +- libgo/go/os/exec.go | 4 + libgo/go/os/exec/exec_plan9.go | 4 +- libgo/go/os/exec/exec_test.go | 25 +- libgo/go/os/exec/exec_unix.go | 4 +- libgo/go/os/exec/exec_windows.go | 4 +- libgo/go/os/exec/lp_plan9.go | 3 +- libgo/go/os/exec/lp_unix.go | 3 +- libgo/go/os/exec/lp_unix_test.go | 3 +- libgo/go/os/exec/lp_windows.go | 5 +- libgo/go/os/exec/read3.go | 8 +- libgo/go/os/exec_plan9.go | 5 +- libgo/go/os/exec_posix.go | 2 +- libgo/go/os/exec_unix.go | 6 +- libgo/go/os/exec_unix_test.go | 29 + libgo/go/os/exec_windows.go | 2 +- libgo/go/os/executable_dragonfly.go | 12 + libgo/go/os/executable_freebsd.go | 33 +- libgo/go/os/executable_procfs.go | 4 +- libgo/go/os/executable_sysctl.go | 35 + libgo/go/os/export_test.go | 2 + libgo/go/os/fifo_test.go | 3 +- libgo/go/os/file.go | 113 +- libgo/go/os/file_plan9.go | 63 +- libgo/go/os/file_posix.go | 40 +- libgo/go/os/file_unix.go | 130 +- libgo/go/os/getwd.go | 19 +- libgo/go/os/getwd_darwin.go | 15 - libgo/go/os/os_test.go | 252 +- libgo/go/os/os_unix_test.go | 4 +- libgo/go/os/os_windows_test.go | 40 +- libgo/go/os/path.go | 2 +- libgo/go/os/path_test.go | 6 +- libgo/go/os/path_windows_test.go | 3 +- libgo/go/os/pipe2_illumos.go | 25 + libgo/go/os/pipe_bsd.go | 2 +- libgo/go/os/pipe_test.go | 20 +- libgo/go/os/proc.go | 8 + libgo/go/os/read_test.go | 131 + libgo/go/os/readfrom_linux_test.go | 4 +- libgo/go/os/removeall_at.go | 14 +- libgo/go/os/removeall_noat.go | 2 +- libgo/go/os/removeall_test.go | 29 +- libgo/go/os/signal/example_unix_test.go | 47 + libgo/go/os/signal/signal.go | 75 + libgo/go/os/signal/signal_cgo_test.go | 3 +- libgo/go/os/signal/signal_test.go | 165 +- libgo/go/os/stat_plan9.go | 8 +- libgo/go/os/stat_test.go | 28 +- libgo/go/os/stat_unix.go | 14 +- libgo/go/os/tempfile.go | 118 + libgo/go/os/tempfile_test.go | 193 + libgo/go/os/testdata/hello | 1 + libgo/go/os/timeout_test.go | 7 +- libgo/go/os/types.go | 86 +- libgo/go/os/types_windows.go | 6 +- libgo/go/os/user/lookup_plan9.go | 3 +- libgo/go/path/example_test.go | 5 + libgo/go/path/filepath/example_unix_test.go | 4 + .../path/filepath/example_unix_walk_test.go | 6 +- libgo/go/path/filepath/match.go | 61 +- libgo/go/path/filepath/match_test.go | 19 +- libgo/go/path/filepath/path.go | 163 +- libgo/go/path/filepath/path_test.go | 147 +- libgo/go/path/filepath/symlink.go | 3 +- libgo/go/path/filepath/symlink_windows.go | 2 +- libgo/go/path/match.go | 64 +- libgo/go/path/match_test.go | 11 +- libgo/go/path/path.go | 36 +- libgo/go/path/path_test.go | 3 +- libgo/go/reflect/all_test.go | 249 +- libgo/go/reflect/deepequal.go | 18 +- libgo/go/reflect/type.go | 65 +- libgo/go/reflect/value.go | 37 +- libgo/go/regexp/syntax/doc.go | 3 +- libgo/go/runtime/auxv_none.go | 1 - libgo/go/runtime/cgo_gccgo.go | 2 +- libgo/go/runtime/cgocall.go | 2 +- libgo/go/runtime/chan.go | 54 +- libgo/go/runtime/closure_test.go | 1 + libgo/go/runtime/cpuflags_arm64.go | 17 + libgo/go/runtime/crash_cgo_test.go | 23 +- libgo/go/runtime/crash_test.go | 28 +- libgo/go/runtime/crash_unix_test.go | 20 +- libgo/go/runtime/debug.go | 5 +- libgo/go/runtime/debug/garbage.go | 7 + libgo/go/runtime/debug/heapdump_test.go | 5 +- libgo/go/runtime/debug/panic_test.go | 53 + libgo/go/runtime/debug_test.go | 4 +- libgo/go/runtime/error.go | 20 + libgo/go/runtime/export_pipe2_test.go | 15 + libgo/go/runtime/export_pipe_test.go | 9 + libgo/go/runtime/export_test.go | 281 +- libgo/go/runtime/export_unix_test.go | 1 - libgo/go/runtime/extern.go | 21 +- libgo/go/runtime/gc_test.go | 23 +- libgo/go/runtime/gcinfo_test.go | 19 +- libgo/go/runtime/heapdump.go | 98 +- libgo/go/runtime/histogram.go | 148 + libgo/go/runtime/histogram_test.go | 58 + libgo/go/runtime/internal/atomic/atomic.c | 82 +- .../go/runtime/internal/atomic/atomic_test.go | 128 +- .../go/runtime/internal/atomic/bench_test.go | 91 + libgo/go/runtime/internal/atomic/gccgo.go | 18 + libgo/go/runtime/internal/atomic/unaligned.go | 14 + libgo/go/runtime/lockrank.go | 48 +- libgo/go/runtime/lockrank_off.go | 34 +- libgo/go/runtime/lockrank_on.go | 195 +- libgo/go/runtime/malloc.go | 184 +- libgo/go/runtime/malloc_test.go | 57 + libgo/go/runtime/map.go | 19 +- libgo/go/runtime/map_benchmark_test.go | 1 + libgo/go/runtime/map_fast32.go | 21 +- libgo/go/runtime/map_fast64.go | 21 +- libgo/go/runtime/map_faststr.go | 9 +- libgo/go/runtime/map_test.go | 22 + libgo/go/runtime/mbarrier.go | 23 +- libgo/go/runtime/mbitmap.go | 317 +- libgo/go/runtime/mcache.go | 155 +- libgo/go/runtime/mcentral.go | 284 +- libgo/go/runtime/mcheckmark.go | 109 + libgo/go/runtime/mem_gccgo.go | 12 +- libgo/go/runtime/memmove_linux_amd64_test.go | 3 +- libgo/go/runtime/memmove_test.go | 69 +- libgo/go/runtime/metrics.go | 485 + libgo/go/runtime/metrics/description.go | 180 + libgo/go/runtime/metrics/description_test.go | 115 + libgo/go/runtime/metrics/doc.go | 144 + libgo/go/runtime/metrics/histogram.go | 30 + libgo/go/runtime/metrics/sample.go | 47 + libgo/go/runtime/metrics/value.go | 69 + libgo/go/runtime/metrics_test.go | 224 + libgo/go/runtime/mfinal.go | 20 +- libgo/go/runtime/mfixalloc.go | 4 +- libgo/go/runtime/mgc.go | 492 +- libgo/go/runtime/mgcmark.go | 218 +- libgo/go/runtime/mgcscavenge.go | 136 +- libgo/go/runtime/mgcscavenge_test.go | 53 +- libgo/go/runtime/mgcsweep.go | 251 +- libgo/go/runtime/mgcsweepbuf.go | 176 - libgo/go/runtime/mgcwork.go | 77 +- libgo/go/runtime/mheap.go | 291 +- libgo/go/runtime/mkfastlog2table.go | 4 +- libgo/go/runtime/mkpreempt.go | 24 +- libgo/go/runtime/mksizeclasses.go | 9 +- libgo/go/runtime/mpagealloc.go | 224 +- libgo/go/runtime/mpagealloc_32bit.go | 18 +- libgo/go/runtime/mpagealloc_64bit.go | 34 +- libgo/go/runtime/mpagealloc_test.go | 98 +- libgo/go/runtime/mpagecache.go | 54 +- libgo/go/runtime/mpallocbits.go | 188 +- libgo/go/runtime/mpallocbits_test.go | 69 +- libgo/go/runtime/mranges.go | 52 +- libgo/go/runtime/mranges_test.go | 275 + libgo/go/runtime/mspanset.go | 4 +- libgo/go/runtime/mstats.go | 566 +- libgo/go/runtime/mwbbuf.go | 32 +- libgo/go/runtime/os_aix.go | 20 - libgo/go/runtime/os_freebsd_arm64.go | 143 - libgo/go/runtime/os_linux.go | 4 + libgo/go/runtime/os_linux_arm64.go | 14 +- libgo/go/runtime/os_linux_s390x.go | 25 +- libgo/go/runtime/os_netbsd.go | 21 +- libgo/go/runtime/os_openbsd_arm64.go | 23 - libgo/go/runtime/panic.go | 24 +- libgo/go/runtime/pprof/mprof_test.go | 2 +- libgo/go/runtime/pprof/pprof_rusage.go | 2 +- libgo/go/runtime/pprof/pprof_test.go | 13 +- libgo/go/runtime/pprof/proto.go | 4 +- libgo/go/runtime/pprof/proto_test.go | 3 +- libgo/go/runtime/preempt.go | 5 - libgo/go/runtime/print.go | 3 + libgo/go/runtime/proc.go | 777 +- libgo/go/runtime/race0.go | 2 + libgo/go/runtime/runtime-lldb_test.go | 9 +- libgo/go/runtime/runtime1.go | 29 +- libgo/go/runtime/runtime2.go | 92 +- libgo/go/runtime/select.go | 5 + libgo/go/runtime/signal_unix.go | 68 +- libgo/go/runtime/signal_windows_test.go | 5 +- libgo/go/runtime/sigqueue.go | 6 +- libgo/go/runtime/sizeclasses.go | 141 +- libgo/go/runtime/slice.go | 48 +- libgo/go/runtime/slice_test.go | 1 + libgo/go/runtime/stack_test.go | 41 + libgo/go/runtime/string.go | 50 - libgo/go/runtime/string_test.go | 31 - libgo/go/runtime/stubs.go | 6 + libgo/go/runtime/testdata/testprog/memprof.go | 3 +- .../testdata/testprog/syscalls_linux.go | 3 +- .../go/runtime/testdata/testprog/timeprof.go | 3 +- libgo/go/runtime/testdata/testprog/vdso.go | 3 +- .../go/runtime/testdata/testprogcgo/eintr.go | 3 +- libgo/go/runtime/testdata/testprogcgo/exec.go | 3 +- .../go/runtime/testdata/testprogcgo/pprof.go | 3 +- .../testdata/testprogcgo/threadpprof.go | 3 +- .../runtime/testdata/testprogcgo/traceback.go | 79 +- libgo/go/runtime/time.go | 147 +- libgo/go/runtime/time_test.go | 6 +- libgo/go/runtime/trace.go | 7 +- libgo/go/runtime/trace/annotation.go | 4 + libgo/go/runtime/trace/annotation_test.go | 4 + libgo/go/runtime/trace/trace_stack_test.go | 3 +- libgo/go/runtime/trace/trace_test.go | 3 +- libgo/go/runtime/traceback_gccgo.go | 5 +- libgo/go/sort/genzfunc.go | 4 +- libgo/go/sort/slice.go | 40 +- libgo/go/sort/sort.go | 107 +- libgo/go/strconv/atoc.go | 2 +- libgo/go/strconv/atoc_test.go | 27 + libgo/go/strconv/atof.go | 44 +- libgo/go/strconv/atof_test.go | 60 +- libgo/go/strconv/ctoa_test.go | 53 + libgo/go/strconv/eisel_lemire.go | 884 + libgo/go/strconv/extfloat.go | 143 - libgo/go/strconv/ftoa_test.go | 9 + libgo/go/strconv/isprint.go | 98 +- libgo/go/strconv/makeisprint.go | 4 +- libgo/go/strings/reader.go | 10 +- libgo/go/strings/reader_test.go | 7 +- libgo/go/strings/strings.go | 12 +- libgo/go/strings/strings_test.go | 9 + libgo/go/sync/atomic/atomic.c | 24 +- libgo/go/sync/atomic/atomic_test.go | 9 +- libgo/go/sync/atomic/doc.go | 11 +- libgo/go/sync/atomic/unaligned.go | 14 + libgo/go/sync/cond_test.go | 1 + libgo/go/sync/mutex_test.go | 2 +- libgo/go/sync/once.go | 4 +- libgo/go/sync/pool.go | 20 +- libgo/go/sync/poolqueue.go | 2 +- libgo/go/sync/rwmutex.go | 13 + libgo/go/syscall/dirent_test.go | 9 +- libgo/go/syscall/exec_linux_test.go | 15 +- libgo/go/syscall/exec_unix.go | 4 +- libgo/go/syscall/exec_windows.go | 81 +- libgo/go/syscall/exec_windows_test.go | 43 + libgo/go/syscall/export_unix_test.go | 2 +- libgo/go/syscall/fs_js.go | 7 +- libgo/go/syscall/getdirentries_test.go | 5 +- libgo/go/syscall/libcall_posix.go | 6 + libgo/go/syscall/mkasm_darwin.go | 9 +- libgo/go/syscall/setuidgid_32_linux.go | 6 + libgo/go/syscall/setuidgid_linux.go | 6 + libgo/go/syscall/signame.c | 3 + libgo/go/syscall/sockcmsg_unix_other.go | 6 +- libgo/go/syscall/syscall.go | 12 +- libgo/go/syscall/syscall_errno.go | 4 +- libgo/go/syscall/syscall_js.go | 2 +- libgo/go/syscall/syscall_linux.go | 34 + libgo/go/syscall/syscall_linux_386.go | 3 - libgo/go/syscall/syscall_linux_test.go | 268 +- libgo/go/syscall/syscall_unix.go | 2 +- libgo/go/syscall/syscall_unix_test.go | 25 +- libgo/go/syscall/timestruct.go | 12 +- libgo/go/testing/benchmark.go | 27 +- libgo/go/testing/benchmark_test.go | 21 +- libgo/go/testing/example.go | 11 +- libgo/go/testing/fstest/mapfs.go | 238 + libgo/go/testing/fstest/mapfs_test.go | 19 + libgo/go/testing/fstest/testfs.go | 602 + libgo/go/testing/helper_test.go | 31 + libgo/go/testing/internal/testdeps/deps.go | 5 + libgo/go/testing/iotest/example_test.go | 22 + libgo/go/testing/iotest/logger_test.go | 12 +- libgo/go/testing/iotest/reader.go | 180 + libgo/go/testing/iotest/reader_test.go | 35 + libgo/go/testing/run_example.go | 4 +- libgo/go/testing/run_example_js.go | 4 +- libgo/go/testing/sub_test.go | 27 + libgo/go/testing/testing.go | 195 +- libgo/go/testing/testing_test.go | 39 +- libgo/go/text/tabwriter/tabwriter_test.go | 11 +- libgo/go/text/template/doc.go | 21 +- libgo/go/text/template/exec.go | 5 + libgo/go/text/template/exec_test.go | 23 +- libgo/go/text/template/helper.go | 61 +- libgo/go/text/template/link_test.go | 7 +- libgo/go/text/template/multi_test.go | 30 + libgo/go/text/template/parse/lex.go | 88 +- libgo/go/text/template/parse/lex_test.go | 9 +- libgo/go/text/template/parse/node.go | 33 + libgo/go/text/template/parse/parse.go | 79 +- libgo/go/text/template/parse/parse_test.go | 61 +- libgo/go/time/genzabbrs.go | 7 +- libgo/go/time/internal_test.go | 52 +- libgo/go/time/sleep.go | 2 + libgo/go/time/sleep_test.go | 210 +- libgo/go/time/tick.go | 13 +- libgo/go/time/tick_test.go | 2 +- libgo/go/time/tzdata/generate_zipdata.go | 3 +- libgo/go/time/tzdata/tzdata.go | 2 +- libgo/go/time/tzdata/zipdata.go | 19739 ++++++---------- libgo/go/time/zoneinfo_ios.go | 3 +- libgo/go/time/zoneinfo_read.go | 2 +- libgo/go/time/zoneinfo_unix.go | 29 +- libgo/go/time/zoneinfo_unix_test.go | 90 + libgo/go/time/zoneinfo_windows.go | 2 +- libgo/go/unicode/tables.go | 544 +- libgo/go/unicode/utf8/example_test.go | 20 + libgo/go/unicode/utf8/utf8.go | 1 + libgo/go/unicode/utf8/utf8_test.go | 30 +- libgo/go/vendor/modules.txt | 29 + libgo/gotool-packages.txt | 8 + libgo/libgo-packages.txt | 5 + libgo/match.sh | 8 +- libgo/merge.sh | 26 +- libgo/misc/cgo/test/callback.go | 2 +- libgo/misc/cgo/test/cgo_linux_test.go | 1 + libgo/misc/cgo/test/cgo_test.go | 2 + libgo/misc/cgo/test/issue1435.go | 184 + libgo/misc/cgo/test/issue18146.go | 2 +- libgo/misc/cgo/test/issue4029.c | 1 + libgo/misc/cgo/test/issue4029.go | 5 + libgo/misc/cgo/test/issue4029w.go | 2 +- libgo/misc/cgo/test/issue42495.go | 15 + libgo/misc/cgo/test/pkg_test.go | 2 +- libgo/misc/cgo/test/sigaltstack.go | 2 +- libgo/misc/cgo/test/test.go | 29 +- .../cgo/test/testdata/issue9400/asm_riscv64.s | 31 + libgo/misc/cgo/test/testx.go | 2 +- libgo/misc/cgo/testcarchive/carchive_test.go | 20 +- libgo/misc/cgo/testcshared/cshared_test.go | 105 +- .../misc/cgo/testgodefs/testdata/bitfields.go | 31 + libgo/misc/cgo/testgodefs/testdata/main.go | 28 + libgo/misc/cgo/testgodefs/testgodefs_test.go | 1 + libgo/misc/cgo/testplugin/plugin_test.go | 14 + .../cgo/testplugin/testdata/method/main.go | 26 + .../cgo/testplugin/testdata/method/plugin.go | 13 + libgo/misc/cgo/testsanitizers/msan_test.go | 1 + .../misc/cgo/testsanitizers/testdata/msan7.go | 38 + libgo/misc/cgo/testso/so_test.go | 6 +- libgo/misc/cgo/testsovar/so_test.go | 6 +- libgo/mkruntimeinc.sh | 3 +- libgo/runtime/go-caller.c | 7 +- libgo/testsuite/gotest | 8 +- 1189 files changed, 67412 insertions(+), 30825 deletions(-) create mode 100644 libgo/go/cmd/go.mod create mode 100644 libgo/go/cmd/go/internal/fsys/fsys.go create mode 100644 libgo/go/cmd/go/internal/fsys/fsys_test.go delete mode 100644 libgo/go/cmd/go/internal/get/path.go create mode 100644 libgo/go/cmd/go/internal/imports/testdata/android/.h.go create mode 100644 libgo/go/cmd/go/internal/imports/testdata/illumos/.h.go create mode 100644 libgo/go/cmd/go/internal/modget/query.go create mode 100644 libgo/go/cmd/go/internal/modload/buildlist.go create mode 100644 libgo/go/cmd/go/internal/modload/mvs_test.go delete mode 100644 libgo/go/cmd/go/internal/modload/testgo.go create mode 100644 libgo/go/cmd/go/internal/mvs/errors.go create mode 100644 libgo/go/cmd/go/internal/par/queue.go create mode 100644 libgo/go/cmd/go/internal/par/queue_test.go create mode 100644 libgo/go/cmd/go/internal/str/str_test.go create mode 100644 libgo/go/cmd/go/internal/trace/trace.go rename libgo/go/cmd/go/internal/{get => vcs}/discovery.go (99%) rename libgo/go/cmd/go/internal/{get/pkg_test.go => vcs/discovery_test.go} (85%) rename libgo/go/cmd/go/internal/{get => vcs}/vcs.go (66%) rename libgo/go/cmd/go/internal/{get => vcs}/vcs_test.go (68%) create mode 100644 libgo/go/cmd/go/internal/work/exec_test.go delete mode 100644 libgo/go/cmd/go/testdata/script/get_unicode.txt delete mode 100644 libgo/go/cmd/go/testdata/script/sum_readonly.txt create mode 100644 libgo/go/cmd/internal/codesign/codesign.go delete mode 100644 libgo/go/cmd/internal/objabi/doc.go create mode 100644 libgo/go/cmd/internal/objabi/flag_test.go create mode 100644 libgo/go/cmd/internal/sys/supported_test.go create mode 100644 libgo/go/cmd/internal/traceviewer/format.go create mode 100644 libgo/go/cmd/vendor/modules.txt create mode 100644 libgo/go/crypto/cipher/xor_arm64.go delete mode 100644 libgo/go/crypto/x509/root_cgo_darwin_amd64.go rename libgo/go/crypto/x509/{root_darwin_amd64.go => root_darwin.go} (98%) rename libgo/go/crypto/x509/{root_darwin_ios.go => root_ios.go} (96%) rename libgo/go/crypto/x509/{root_darwin_ios_gen.go => root_ios_gen.go} (88%) create mode 100644 libgo/go/debug/dwarf/dwarf5ranges_test.go create mode 100644 libgo/go/debug/dwarf/testdata/debug_rnglists create mode 100644 libgo/go/debug/dwarf/testdata/line-clang-dwarf5.elf create mode 100644 libgo/go/debug/dwarf/testdata/line-gcc-dwarf5.elf create mode 100644 libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64 create mode 100644 libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64 create mode 100644 libgo/go/debug/elf/testdata/multiple-code-sections.c create mode 100644 libgo/go/embed/embed.go create mode 100644 libgo/go/embed/internal/embedtest/concurrency.txt create mode 100644 libgo/go/embed/internal/embedtest/embed_test.go create mode 100644 libgo/go/embed/internal/embedtest/embedx_test.go create mode 100644 libgo/go/embed/internal/embedtest/testdata/.hidden/.more/tip.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/.hidden/_more/tip.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/.hidden/fortune.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/.hidden/more/tip.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/_hidden/fortune.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/ascii.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/glass.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/hello.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/i/i18n.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/i/j/k/k8s.txt create mode 100644 libgo/go/embed/internal/embedtest/testdata/ken.txt create mode 100644 libgo/go/flag/example_func_test.go create mode 100644 libgo/go/go.mod create mode 100644 libgo/go/go/internal/gccgoimporter/testdata/notinheap.go create mode 100644 libgo/go/go/internal/gccgoimporter/testdata/notinheap.gox create mode 100644 libgo/go/go/parser/testdata/issue42951/not_a_file.go/invalid.go create mode 100644 libgo/go/go/types/errorcodes.go create mode 100644 libgo/go/go/types/errorcodes_test.go delete mode 100644 libgo/go/go/types/testdata/issue23203a.src delete mode 100644 libgo/go/go/types/testdata/issue23203b.src delete mode 100644 libgo/go/go/types/testdata/issue26390.src delete mode 100644 libgo/go/go/types/testdata/issue28251.src delete mode 100644 libgo/go/go/types/testdata/issue6977.src rename libgo/go/golang.org/x/net/idna/{tables12.00.go => tables12.0.0.go} (99%) create mode 100644 libgo/go/golang.org/x/net/idna/tables13.0.0.go create mode 100644 libgo/go/golang.org/x/sys/cpu/cpu_netbsd_arm64.go create mode 100644 libgo/go/golang.org/x/sys/cpu/cpu_other_arm.go create mode 100644 libgo/go/golang.org/x/sys/cpu/cpu_other_mips64x.go create mode 100644 libgo/go/golang.org/x/sys/cpu/cpu_ppc64x.go create mode 100644 libgo/go/golang.org/x/sys/cpu/cpu_s390x.go create mode 100644 libgo/go/golang.org/x/sys/cpu/cpu_zos.go create mode 100644 libgo/go/golang.org/x/sys/cpu/cpu_zos_s390x.go create mode 100644 libgo/go/golang.org/x/text/unicode/bidi/tables13.0.0.go create mode 100644 libgo/go/golang.org/x/text/unicode/norm/tables13.0.0.go create mode 100644 libgo/go/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go create mode 100644 libgo/go/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go create mode 100644 libgo/go/golang.org/x/tools/internal/lsp/fuzzy/input.go create mode 100644 libgo/go/golang.org/x/tools/internal/lsp/fuzzy/matcher.go create mode 100644 libgo/go/html/template/testdata/fs.zip create mode 100644 libgo/go/internal/cpu/cpu_arm64_android.go create mode 100644 libgo/go/internal/cpu/cpu_arm64_darwin.go create mode 100644 libgo/go/internal/cpu/cpu_arm64_freebsd.go create mode 100644 libgo/go/internal/cpu/cpu_arm64_hwcap.go create mode 100644 libgo/go/internal/cpu/cpu_arm64_linux.go create mode 100644 libgo/go/internal/cpu/cpu_arm64_other.go delete mode 100644 libgo/go/internal/cpu/cpu_no_init.go create mode 100644 libgo/go/internal/cpu/cpu_no_name.go create mode 100644 libgo/go/internal/cpu/cpu_ppc64x_aix.go create mode 100644 libgo/go/internal/cpu/cpu_ppc64x_linux.go create mode 100644 libgo/go/internal/poll/fd_writev_illumos.go create mode 100644 libgo/go/internal/poll/iovec_illumos.go create mode 100644 libgo/go/internal/poll/iovec_unix.go create mode 100644 libgo/go/internal/sysinfo/sysinfo.go create mode 100644 libgo/go/internal/testlog/exit.go create mode 100644 libgo/go/io/export_test.go create mode 100644 libgo/go/io/fs/fs.go create mode 100644 libgo/go/io/fs/fs_test.go create mode 100644 libgo/go/io/fs/glob.go create mode 100644 libgo/go/io/fs/glob_test.go create mode 100644 libgo/go/io/fs/readdir.go create mode 100644 libgo/go/io/fs/readdir_test.go create mode 100644 libgo/go/io/fs/readfile.go create mode 100644 libgo/go/io/fs/readfile_test.go create mode 100644 libgo/go/io/fs/stat.go create mode 100644 libgo/go/io/fs/stat_test.go create mode 100644 libgo/go/io/fs/sub.go create mode 100644 libgo/go/io/fs/sub_test.go create mode 100644 libgo/go/io/fs/walk.go create mode 100644 libgo/go/io/fs/walk_test.go create mode 100644 libgo/go/net/sock_linux_test.go create mode 100644 libgo/go/os/dir_gccgo_c.c create mode 100644 libgo/go/os/exec_unix_test.go create mode 100644 libgo/go/os/executable_dragonfly.go create mode 100644 libgo/go/os/executable_sysctl.go delete mode 100644 libgo/go/os/getwd_darwin.go create mode 100644 libgo/go/os/pipe2_illumos.go create mode 100644 libgo/go/os/read_test.go create mode 100644 libgo/go/os/signal/example_unix_test.go create mode 100644 libgo/go/os/tempfile.go create mode 100644 libgo/go/os/tempfile_test.go create mode 100644 libgo/go/os/testdata/hello create mode 100644 libgo/go/runtime/cpuflags_arm64.go create mode 100644 libgo/go/runtime/debug/panic_test.go create mode 100644 libgo/go/runtime/export_pipe2_test.go create mode 100644 libgo/go/runtime/export_pipe_test.go create mode 100644 libgo/go/runtime/histogram.go create mode 100644 libgo/go/runtime/histogram_test.go create mode 100644 libgo/go/runtime/internal/atomic/unaligned.go create mode 100644 libgo/go/runtime/mcheckmark.go create mode 100644 libgo/go/runtime/metrics.go create mode 100644 libgo/go/runtime/metrics/description.go create mode 100644 libgo/go/runtime/metrics/description_test.go create mode 100644 libgo/go/runtime/metrics/doc.go create mode 100644 libgo/go/runtime/metrics/histogram.go create mode 100644 libgo/go/runtime/metrics/sample.go create mode 100644 libgo/go/runtime/metrics/value.go create mode 100644 libgo/go/runtime/metrics_test.go delete mode 100644 libgo/go/runtime/mgcsweepbuf.go create mode 100644 libgo/go/runtime/mranges_test.go delete mode 100644 libgo/go/runtime/os_openbsd_arm64.go create mode 100644 libgo/go/strconv/ctoa_test.go create mode 100644 libgo/go/strconv/eisel_lemire.go create mode 100644 libgo/go/sync/atomic/unaligned.go create mode 100644 libgo/go/syscall/exec_windows_test.go create mode 100644 libgo/go/syscall/syscall_linux.go create mode 100644 libgo/go/testing/fstest/mapfs.go create mode 100644 libgo/go/testing/fstest/mapfs_test.go create mode 100644 libgo/go/testing/fstest/testfs.go create mode 100644 libgo/go/testing/iotest/example_test.go create mode 100644 libgo/go/time/zoneinfo_unix_test.go create mode 100644 libgo/go/vendor/modules.txt create mode 100644 libgo/misc/cgo/test/issue1435.go create mode 100644 libgo/misc/cgo/test/issue42495.go create mode 100644 libgo/misc/cgo/test/testdata/issue9400/asm_riscv64.s create mode 100644 libgo/misc/cgo/testgodefs/testdata/bitfields.go create mode 100644 libgo/misc/cgo/testplugin/testdata/method/main.go create mode 100644 libgo/misc/cgo/testplugin/testdata/method/plugin.go create mode 100644 libgo/misc/cgo/testsanitizers/testdata/msan7.go diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 1e461f06e95..fc5ef4498dd 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -d67579759e1769c08148304b2d378ec0b05637d6 +47bdc8bb36f16f9d1dec72df5dd6b45d7b0b0725 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gotools/Makefile.am b/gotools/Makefile.am index 1b8702e98bb..3bbccb96c28 100644 --- a/gotools/Makefile.am +++ b/gotools/Makefile.am @@ -101,7 +101,7 @@ MOSTLYCLEANFILES = \ mostlyclean-local: if test -d check-go-dir; then chmod -R u+w check-go-dir; fi - rm -rf check-go-dir check-runtime-dir cgo-test-dir carchive-test-dir \ + rm -rf check-go-dir cgo-test-dir carchive-test-dir \ check-vet-dir gocache-test if NATIVE @@ -210,6 +210,11 @@ check-go-tool: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc if test -d check-go-dir; then chmod -R u+w check-go-dir; fi rm -rf check-go-dir cmd_go-testlog $(MKDIR_P) check-go-dir/src/cmd/go + cp $(libgosrcdir)/go.mod check-go-dir/src/ + cp $(cmdsrcdir)/go.mod check-go-dir/src/cmd/ + $(MKDIR_P) check-go-dir/src/vendor check-go-dir/src/cmd/vendor + cp $(libgosrcdir)/vendor/modules.txt check-go-dir/src/vendor/ + cp $(libgosrcdir)/cmd/vendor/modules.txt check-go-dir/src/cmd/vendor/ cp $(cmdsrcdir)/go/*.go check-go-dir/src/cmd/go/ cp -r $(cmdsrcdir)/go/internal check-go-dir/src/cmd/go/ cp $(libgodir)/zdefaultcc.go check-go-dir/src/cmd/go/internal/cfg/ @@ -234,8 +239,7 @@ check-go-tool: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc # but the runtime tests use the go tool heavily, so testing # here too will catch more problems. check-runtime: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc - rm -rf check-runtime-dir runtime-testlog - $(MKDIR_P) check-runtime-dir + rm -f runtime-testlog @abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \ LD_LIBRARY_PATH=`echo $${abs_libgodir}/.libs:$${LD_LIBRARY_PATH} | sed 's,::*,:,g;s,^:*,,;s,:*$$,,'`; \ export LD_LIBRARY_PATH; \ @@ -256,6 +260,7 @@ check-runtime: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc check-cgo-test: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc rm -rf cgo-test-dir cgo-testlog $(MKDIR_P) cgo-test-dir/misc/cgo + echo 'module misc' > cgo-test-dir/misc/go.mod cp -r $(libgomiscdir)/cgo/test cgo-test-dir/misc/cgo/ @abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \ echo "cd cgo-test-dir/misc/cgo/test && $(ECHO_ENV) GOTRACEBACK=2 $(abs_builddir)/go$(EXEEXT) test -test.short -test.timeout=$(GOTOOLS_TEST_TIMEOUT)s -test.v" > cgo-testlog @@ -270,6 +275,7 @@ check-cgo-test: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc check-carchive-test: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc rm -rf carchive-test-dir carchive-testlog $(MKDIR_P) carchive-test-dir/misc/cgo + echo 'module misc' > carchive-test-dir/misc/go.mod cp -r $(libgomiscdir)/cgo/testcarchive carchive-test-dir/misc/cgo/ @abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \ echo "cd carchive-test-dir/misc/cgo/testcarchive && $(ECHO_ENV) LIBRARY_PATH=`echo $${abs_libgodir}/.libs` $(abs_builddir)/go$(EXEEXT) test -test.timeout=$(GOTOOLS_TEST_TIMEOUT)s -test.v" > carchive-testlog @@ -283,6 +289,11 @@ check-carchive-test: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check check-vet: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc rm -rf check-vet-dir cmd_vet-testlog $(MKDIR_P) check-vet-dir/src/cmd/internal check-vet-dir/src/cmd/vendor/golang.org/x + cp $(libgosrcdir)/go.mod check-vet-dir/src/ + cp $(cmdsrcdir)/go.mod check-vet-dir/src/cmd/ + $(MKDIR_P) check-vet-dir/src/vendor check-vet-dir/src/cmd/vendor + cp $(libgosrcdir)/vendor/modules.txt check-vet-dir/src/vendor/ + cp $(libgosrcdir)/cmd/vendor/modules.txt check-vet-dir/src/cmd/vendor/ cp -r $(cmdsrcdir)/vet check-vet-dir/src/cmd/ cp -r $(cmdsrcdir)/internal/objabi check-vet-dir/src/cmd/internal cp $(libgodir)/objabi.go check-vet-dir/src/cmd/internal/objabi/ diff --git a/gotools/Makefile.in b/gotools/Makefile.in index 9292312a385..f440a0b301a 100644 --- a/gotools/Makefile.in +++ b/gotools/Makefile.in @@ -703,8 +703,8 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -@NATIVE_FALSE@uninstall-local: @NATIVE_FALSE@install-exec-local: +@NATIVE_FALSE@uninstall-local: clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ @@ -814,7 +814,7 @@ s-zdefaultcc: Makefile mostlyclean-local: if test -d check-go-dir; then chmod -R u+w check-go-dir; fi - rm -rf check-go-dir check-runtime-dir cgo-test-dir carchive-test-dir \ + rm -rf check-go-dir cgo-test-dir carchive-test-dir \ check-vet-dir gocache-test @NATIVE_TRUE@go$(EXEEXT): $(go_cmd_go_files) $(LIBGOTOOL) $(LIBGODEP) @@ -881,6 +881,11 @@ mostlyclean-local: @NATIVE_TRUE@ if test -d check-go-dir; then chmod -R u+w check-go-dir; fi @NATIVE_TRUE@ rm -rf check-go-dir cmd_go-testlog @NATIVE_TRUE@ $(MKDIR_P) check-go-dir/src/cmd/go +@NATIVE_TRUE@ cp $(libgosrcdir)/go.mod check-go-dir/src/ +@NATIVE_TRUE@ cp $(cmdsrcdir)/go.mod check-go-dir/src/cmd/ +@NATIVE_TRUE@ $(MKDIR_P) check-go-dir/src/vendor check-go-dir/src/cmd/vendor +@NATIVE_TRUE@ cp $(libgosrcdir)/vendor/modules.txt check-go-dir/src/vendor/ +@NATIVE_TRUE@ cp $(libgosrcdir)/cmd/vendor/modules.txt check-go-dir/src/cmd/vendor/ @NATIVE_TRUE@ cp $(cmdsrcdir)/go/*.go check-go-dir/src/cmd/go/ @NATIVE_TRUE@ cp -r $(cmdsrcdir)/go/internal check-go-dir/src/cmd/go/ @NATIVE_TRUE@ cp $(libgodir)/zdefaultcc.go check-go-dir/src/cmd/go/internal/cfg/ @@ -905,8 +910,7 @@ mostlyclean-local: # but the runtime tests use the go tool heavily, so testing # here too will catch more problems. @NATIVE_TRUE@check-runtime: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc -@NATIVE_TRUE@ rm -rf check-runtime-dir runtime-testlog -@NATIVE_TRUE@ $(MKDIR_P) check-runtime-dir +@NATIVE_TRUE@ rm -f runtime-testlog @NATIVE_TRUE@ @abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \ @NATIVE_TRUE@ LD_LIBRARY_PATH=`echo $${abs_libgodir}/.libs:$${LD_LIBRARY_PATH} | sed 's,::*,:,g;s,^:*,,;s,:*$$,,'`; \ @NATIVE_TRUE@ export LD_LIBRARY_PATH; \ @@ -927,6 +931,7 @@ mostlyclean-local: @NATIVE_TRUE@check-cgo-test: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc @NATIVE_TRUE@ rm -rf cgo-test-dir cgo-testlog @NATIVE_TRUE@ $(MKDIR_P) cgo-test-dir/misc/cgo +@NATIVE_TRUE@ echo 'module misc' > cgo-test-dir/misc/go.mod @NATIVE_TRUE@ cp -r $(libgomiscdir)/cgo/test cgo-test-dir/misc/cgo/ @NATIVE_TRUE@ @abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \ @NATIVE_TRUE@ echo "cd cgo-test-dir/misc/cgo/test && $(ECHO_ENV) GOTRACEBACK=2 $(abs_builddir)/go$(EXEEXT) test -test.short -test.timeout=$(GOTOOLS_TEST_TIMEOUT)s -test.v" > cgo-testlog @@ -941,6 +946,7 @@ mostlyclean-local: @NATIVE_TRUE@check-carchive-test: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc @NATIVE_TRUE@ rm -rf carchive-test-dir carchive-testlog @NATIVE_TRUE@ $(MKDIR_P) carchive-test-dir/misc/cgo +@NATIVE_TRUE@ echo 'module misc' > carchive-test-dir/misc/go.mod @NATIVE_TRUE@ cp -r $(libgomiscdir)/cgo/testcarchive carchive-test-dir/misc/cgo/ @NATIVE_TRUE@ @abs_libgodir=`cd $(libgodir) && $(PWD_COMMAND)`; \ @NATIVE_TRUE@ echo "cd carchive-test-dir/misc/cgo/testcarchive && $(ECHO_ENV) LIBRARY_PATH=`echo $${abs_libgodir}/.libs` $(abs_builddir)/go$(EXEEXT) test -test.timeout=$(GOTOOLS_TEST_TIMEOUT)s -test.v" > carchive-testlog @@ -954,6 +960,11 @@ mostlyclean-local: @NATIVE_TRUE@check-vet: go$(EXEEXT) $(noinst_PROGRAMS) check-head check-gccgo check-gcc @NATIVE_TRUE@ rm -rf check-vet-dir cmd_vet-testlog @NATIVE_TRUE@ $(MKDIR_P) check-vet-dir/src/cmd/internal check-vet-dir/src/cmd/vendor/golang.org/x +@NATIVE_TRUE@ cp $(libgosrcdir)/go.mod check-vet-dir/src/ +@NATIVE_TRUE@ cp $(cmdsrcdir)/go.mod check-vet-dir/src/cmd/ +@NATIVE_TRUE@ $(MKDIR_P) check-vet-dir/src/vendor check-vet-dir/src/cmd/vendor +@NATIVE_TRUE@ cp $(libgosrcdir)/vendor/modules.txt check-vet-dir/src/vendor/ +@NATIVE_TRUE@ cp $(libgosrcdir)/cmd/vendor/modules.txt check-vet-dir/src/cmd/vendor/ @NATIVE_TRUE@ cp -r $(cmdsrcdir)/vet check-vet-dir/src/cmd/ @NATIVE_TRUE@ cp -r $(cmdsrcdir)/internal/objabi check-vet-dir/src/cmd/internal @NATIVE_TRUE@ cp $(libgodir)/objabi.go check-vet-dir/src/cmd/internal/objabi/ diff --git a/libgo/MERGE b/libgo/MERGE index e95c59a132d..c5546950b8b 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -9b955d2d3fcff6a5bc8bce7bafdc4c634a28e95b +2ff33f5e443165e55a080f3a649e4c070c4096d1 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 4d3e54e9225..2e8c37e170d 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -775,6 +775,7 @@ libgo_go_objs = \ syscall/errno.lo \ syscall/signame.lo \ syscall/wait.lo \ + os/dir_gccgo_c.lo \ $(golangorg_x_net_lif_lo) \ $(golangorg_x_net_route_lo) \ log/syslog/syslog_c.lo \ @@ -1062,6 +1063,7 @@ extra_go_files_os_user = os_user_linknames.go os/user.lo.dep: $(extra_go_files_os_user) extra_check_libs_cmd_go_internal_cache = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_go_internal_fsys = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_generate = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_get = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_load = $(abs_builddir)/libgotool.a @@ -1075,10 +1077,14 @@ extra_check_libs_cmd_go_internal_modload = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_module = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_mvs = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_search = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_go_internal_str = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_test = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_go_internal_vcs = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_web2 = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_work = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_internal_buildid = $(abs_builddir)/libgotool.a + extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a # FIXME: The following C files may as well move to the runtime @@ -1122,6 +1128,11 @@ syscall/wait.lo: go/syscall/wait.c runtime.inc @$(MKDIR_P) syscall $(LTCOMPILE) -c -o $@ $(srcdir)/go/syscall/wait.c +# An os function is written in C. +os/dir_gccgo_c.lo: go/os/dir_gccgo_c.c runtime.inc + @$(MKDIR_P) os + $(LTCOMPILE) -c -o $@ $(srcdir)/go/os/dir_gccgo_c.c + # internal/cpu needs some C code. internal/cpu/cpu_gccgo.lo: go/internal/cpu/cpu_gccgo.c runtime.inc @$(MKDIR_P) internal/cpu diff --git a/libgo/Makefile.in b/libgo/Makefile.in index d6ac066df41..34b0e1d0056 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -224,7 +224,7 @@ LTLIBRARIES = $(toolexeclib_LTLIBRARIES) am__DEPENDENCIES_3 = $(addsuffix .lo,$(PACKAGES)) \ internal/bytealg/bytealg.lo reflect/makefunc_ffi_c.lo \ $(am__DEPENDENCIES_1) syscall/errno.lo syscall/signame.lo \ - syscall/wait.lo $(golangorg_x_net_lif_lo) \ + syscall/wait.lo os/dir_gccgo_c.lo $(golangorg_x_net_lif_lo) \ $(golangorg_x_net_route_lo) log/syslog/syslog_c.lo \ runtime/internal/atomic_c.lo sync/atomic_c.lo \ internal/cpu/cpu_gccgo.lo $(am__DEPENDENCIES_2) @@ -940,6 +940,7 @@ libgo_go_objs = \ syscall/errno.lo \ syscall/signame.lo \ syscall/wait.lo \ + os/dir_gccgo_c.lo \ $(golangorg_x_net_lif_lo) \ $(golangorg_x_net_route_lo) \ log/syslog/syslog_c.lo \ @@ -1130,6 +1131,7 @@ extra_go_files_cmd_go_internal_cfg = zdefaultcc.go extra_go_files_os = os_linknames.go extra_go_files_os_user = os_user_linknames.go extra_check_libs_cmd_go_internal_cache = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_go_internal_fsys = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_generate = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_get = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_load = $(abs_builddir)/libgotool.a @@ -1143,9 +1145,12 @@ extra_check_libs_cmd_go_internal_modload = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_module = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_mvs = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_search = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_go_internal_str = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_test = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_go_internal_vcs = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_web2 = $(abs_builddir)/libgotool.a extra_check_libs_cmd_go_internal_work = $(abs_builddir)/libgotool.a +extra_check_libs_cmd_internal_buildid = $(abs_builddir)/libgotool.a extra_check_libs_cmd_vet_internal_cfg = $(abs_builddir)/libgotool.a @HAVE_STAT_TIMESPEC_FALSE@@LIBGO_IS_SOLARIS_TRUE@matchargs_os = @@ -3009,6 +3014,11 @@ syscall/wait.lo: go/syscall/wait.c runtime.inc @$(MKDIR_P) syscall $(LTCOMPILE) -c -o $@ $(srcdir)/go/syscall/wait.c +# An os function is written in C. +os/dir_gccgo_c.lo: go/os/dir_gccgo_c.c runtime.inc + @$(MKDIR_P) os + $(LTCOMPILE) -c -o $@ $(srcdir)/go/os/dir_gccgo_c.c + # internal/cpu needs some C code. internal/cpu/cpu_gccgo.lo: go/internal/cpu/cpu_gccgo.c runtime.inc @$(MKDIR_P) internal/cpu diff --git a/libgo/VERSION b/libgo/VERSION index 7b6d7469626..257f7ce59ec 100644 --- a/libgo/VERSION +++ b/libgo/VERSION @@ -1 +1 @@ -go1.15.6 +go1.16beta1 diff --git a/libgo/check-packages.txt b/libgo/check-packages.txt index da77e84517e..a0148cfccc4 100644 --- a/libgo/check-packages.txt +++ b/libgo/check-packages.txt @@ -3,6 +3,7 @@ archive/zip bufio bytes cmd/go/internal/cache +cmd/go/internal/fsys cmd/go/internal/generate cmd/go/internal/get cmd/go/internal/imports @@ -16,8 +17,10 @@ cmd/go/internal/modload cmd/go/internal/mvs cmd/go/internal/par cmd/go/internal/search +cmd/go/internal/str cmd/go/internal/test cmd/go/internal/txtar +cmd/go/internal/vcs cmd/go/internal/work cmd/internal/buildid cmd/internal/edit @@ -113,6 +116,7 @@ internal/trace internal/unsafeheader internal/xcoff io +io/fs io/ioutil log log/syslog @@ -155,6 +159,7 @@ runtime/debug runtime/internal/atomic runtime/internal/math runtime/internal/sys +runtime/metrics runtime/pprof runtime/trace sort @@ -164,6 +169,7 @@ sync sync/atomic syscall testing +testing/fstest testing/iotest testing/quick text/scanner diff --git a/libgo/config.h.in b/libgo/config.h.in index 1126790379b..25b8ab8f9ee 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -36,6 +36,10 @@ /* Define to 1 if you have the `cosl' function. */ #undef HAVE_COSL +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H @@ -159,6 +163,9 @@ /* Define to 1 if you have the `mknodat' function. */ #undef HAVE_MKNODAT +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_ICMP6_H @@ -249,6 +256,9 @@ /* Define to 1 if you have the `strsignal' function. */ #undef HAVE_STRSIGNAL +/* Define to 1 if `d_type' is a member of `struct dirent'. */ +#undef HAVE_STRUCT_DIRENT_D_TYPE + /* Define to 1 if defines struct exception */ #undef HAVE_STRUCT_EXCEPTION @@ -261,6 +271,10 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYSCALL_H +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EPOLL_H @@ -279,6 +293,10 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MOUNT_H +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PRCTL_H diff --git a/libgo/configure b/libgo/configure index 1d7d007f88e..c1956d81a20 100755 --- a/libgo/configure +++ b/libgo/configure @@ -1956,6 +1956,63 @@ fi } # ac_fn_c_check_header_mongrel +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member + # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -2551,7 +2608,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" -libtool_VERSION=18:0:0 +libtool_VERSION=19:0:0 # Default to --enable-multilib @@ -11497,7 +11554,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11500 "configure" +#line 11557 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11603,7 +11660,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11606 "configure" +#line 11663 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -13923,7 +13980,7 @@ go_include="-include" # All known GOOS values. This is the union of all operating systems # supported by the gofrontend and all operating systems supported by # the gc toolchain. -ALLGOOS="aix android darwin dragonfly freebsd hurd illumos irix js linux netbsd openbsd plan9 rtems solaris windows" +ALLGOOS="aix android darwin dragonfly freebsd hurd illumos ios irix js linux netbsd openbsd plan9 rtems solaris windows zos" is_darwin=no is_freebsd=no @@ -15287,6 +15344,195 @@ else fi +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if eval \${$as_ac_Header+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + + + + ac_fn_c_check_member "$LINENO" "struct dirent" "d_type" "ac_cv_member_struct_dirent_d_type" " +#include +#ifdef HAVE_DIRENT_H +# include +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +#endif + +" +if test "x$ac_cv_member_struct_dirent_d_type" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_DIRENT_D_TYPE 1 +_ACEOF + + +fi + + + for ac_func in accept4 dup3 epoll_create1 faccessat fallocate fchmodat fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 inotify_rm_watch listxattr mkdirat mknodat open64 openat pipe2 removexattr renameat setxattr sync_file_range splice syscall tee unlinkat unshare utimensat do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` diff --git a/libgo/configure.ac b/libgo/configure.ac index 5013f4142a6..ebab9d9de3e 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=18:0:0 +libtool_VERSION=19:0:0 AC_SUBST(libtool_VERSION) AM_ENABLE_MULTILIB(, ..) @@ -167,7 +167,7 @@ AC_SUBST(go_include) # All known GOOS values. This is the union of all operating systems # supported by the gofrontend and all operating systems supported by # the gc toolchain. -ALLGOOS="aix android darwin dragonfly freebsd hurd illumos irix js linux netbsd openbsd plan9 rtems solaris windows" +ALLGOOS="aix android darwin dragonfly freebsd hurd illumos ios irix js linux netbsd openbsd plan9 rtems solaris windows zos" is_darwin=no is_freebsd=no @@ -598,6 +598,8 @@ AC_CHECK_FUNCS(strerror_r strsignal wait4 mincore setenv unsetenv dl_iterate_phd AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes) AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes) +AC_STRUCT_DIRENT_D_TYPE + AC_CHECK_FUNCS(accept4 dup3 epoll_create1 faccessat fallocate fchmodat fchownat futimesat getxattr inotify_add_watch inotify_init inotify_init1 inotify_rm_watch listxattr mkdirat mknodat open64 openat pipe2 removexattr renameat setxattr sync_file_range splice syscall tee unlinkat unshare utimensat) AC_TYPE_OFF_T AC_CHECK_TYPES([loff_t]) diff --git a/libgo/go/archive/tar/common.go b/libgo/go/archive/tar/common.go index dee9e47e4ae..c667cfc8720 100644 --- a/libgo/go/archive/tar/common.go +++ b/libgo/go/archive/tar/common.go @@ -13,8 +13,8 @@ package tar import ( "errors" "fmt" + "io/fs" "math" - "os" "path" "reflect" "strconv" @@ -525,12 +525,12 @@ func (h Header) allowedFormats() (format Format, paxHdrs map[string]string, err return format, paxHdrs, err } -// FileInfo returns an os.FileInfo for the Header. -func (h *Header) FileInfo() os.FileInfo { +// FileInfo returns an fs.FileInfo for the Header. +func (h *Header) FileInfo() fs.FileInfo { return headerFileInfo{h} } -// headerFileInfo implements os.FileInfo. +// headerFileInfo implements fs.FileInfo. type headerFileInfo struct { h *Header } @@ -549,57 +549,57 @@ func (fi headerFileInfo) Name() string { } // Mode returns the permission and mode bits for the headerFileInfo. -func (fi headerFileInfo) Mode() (mode os.FileMode) { +func (fi headerFileInfo) Mode() (mode fs.FileMode) { // Set file permission bits. - mode = os.FileMode(fi.h.Mode).Perm() + mode = fs.FileMode(fi.h.Mode).Perm() // Set setuid, setgid and sticky bits. if fi.h.Mode&c_ISUID != 0 { - mode |= os.ModeSetuid + mode |= fs.ModeSetuid } if fi.h.Mode&c_ISGID != 0 { - mode |= os.ModeSetgid + mode |= fs.ModeSetgid } if fi.h.Mode&c_ISVTX != 0 { - mode |= os.ModeSticky + mode |= fs.ModeSticky } // Set file mode bits; clear perm, setuid, setgid, and sticky bits. - switch m := os.FileMode(fi.h.Mode) &^ 07777; m { + switch m := fs.FileMode(fi.h.Mode) &^ 07777; m { case c_ISDIR: - mode |= os.ModeDir + mode |= fs.ModeDir case c_ISFIFO: - mode |= os.ModeNamedPipe + mode |= fs.ModeNamedPipe case c_ISLNK: - mode |= os.ModeSymlink + mode |= fs.ModeSymlink case c_ISBLK: - mode |= os.ModeDevice + mode |= fs.ModeDevice case c_ISCHR: - mode |= os.ModeDevice - mode |= os.ModeCharDevice + mode |= fs.ModeDevice + mode |= fs.ModeCharDevice case c_ISSOCK: - mode |= os.ModeSocket + mode |= fs.ModeSocket } switch fi.h.Typeflag { case TypeSymlink: - mode |= os.ModeSymlink + mode |= fs.ModeSymlink case TypeChar: - mode |= os.ModeDevice - mode |= os.ModeCharDevice + mode |= fs.ModeDevice + mode |= fs.ModeCharDevice case TypeBlock: - mode |= os.ModeDevice + mode |= fs.ModeDevice case TypeDir: - mode |= os.ModeDir + mode |= fs.ModeDir case TypeFifo: - mode |= os.ModeNamedPipe + mode |= fs.ModeNamedPipe } return mode } // sysStat, if non-nil, populates h from system-dependent fields of fi. -var sysStat func(fi os.FileInfo, h *Header) error +var sysStat func(fi fs.FileInfo, h *Header) error const ( // Mode constants from the USTAR spec: @@ -623,10 +623,10 @@ const ( // If fi describes a symlink, FileInfoHeader records link as the link target. // If fi describes a directory, a slash is appended to the name. // -// Since os.FileInfo's Name method only returns the base name of +// Since fs.FileInfo's Name method only returns the base name of // the file it describes, it may be necessary to modify Header.Name // to provide the full path name of the file. -func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) { +func FileInfoHeader(fi fs.FileInfo, link string) (*Header, error) { if fi == nil { return nil, errors.New("archive/tar: FileInfo is nil") } @@ -643,29 +643,29 @@ func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) { case fi.IsDir(): h.Typeflag = TypeDir h.Name += "/" - case fm&os.ModeSymlink != 0: + case fm&fs.ModeSymlink != 0: h.Typeflag = TypeSymlink h.Linkname = link - case fm&os.ModeDevice != 0: - if fm&os.ModeCharDevice != 0 { + case fm&fs.ModeDevice != 0: + if fm&fs.ModeCharDevice != 0 { h.Typeflag = TypeChar } else { h.Typeflag = TypeBlock } - case fm&os.ModeNamedPipe != 0: + case fm&fs.ModeNamedPipe != 0: h.Typeflag = TypeFifo - case fm&os.ModeSocket != 0: + case fm&fs.ModeSocket != 0: return nil, fmt.Errorf("archive/tar: sockets not supported") default: return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm) } - if fm&os.ModeSetuid != 0 { + if fm&fs.ModeSetuid != 0 { h.Mode |= c_ISUID } - if fm&os.ModeSetgid != 0 { + if fm&fs.ModeSetgid != 0 { h.Mode |= c_ISGID } - if fm&os.ModeSticky != 0 { + if fm&fs.ModeSticky != 0 { h.Mode |= c_ISVTX } // If possible, populate additional fields from OS-specific diff --git a/libgo/go/archive/tar/reader.go b/libgo/go/archive/tar/reader.go index 4f9135b7919..1b1d5b46891 100644 --- a/libgo/go/archive/tar/reader.go +++ b/libgo/go/archive/tar/reader.go @@ -7,7 +7,6 @@ package tar import ( "bytes" "io" - "io/ioutil" "strconv" "strings" "time" @@ -104,7 +103,7 @@ func (tr *Reader) next() (*Header, error) { continue // This is a meta header affecting the next header case TypeGNULongName, TypeGNULongLink: format.mayOnlyBe(FormatGNU) - realname, err := ioutil.ReadAll(tr) + realname, err := io.ReadAll(tr) if err != nil { return nil, err } @@ -294,7 +293,7 @@ func mergePAX(hdr *Header, paxHdrs map[string]string) (err error) { // parsePAX parses PAX headers. // If an extended header (type 'x') is invalid, ErrHeader is returned func parsePAX(r io.Reader) (map[string]string, error) { - buf, err := ioutil.ReadAll(r) + buf, err := io.ReadAll(r) if err != nil { return nil, err } @@ -850,7 +849,7 @@ func discard(r io.Reader, n int64) error { } } - copySkipped, err := io.CopyN(ioutil.Discard, r, n-seekSkipped) + copySkipped, err := io.CopyN(io.Discard, r, n-seekSkipped) if err == io.EOF && seekSkipped+copySkipped < n { err = io.ErrUnexpectedEOF } diff --git a/libgo/go/archive/tar/reader_test.go b/libgo/go/archive/tar/reader_test.go index f153b668def..789ddc1bc03 100644 --- a/libgo/go/archive/tar/reader_test.go +++ b/libgo/go/archive/tar/reader_test.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math" "os" "path" @@ -773,7 +772,7 @@ func TestReadTruncation(t *testing.T) { "testdata/pax-path-hdr.tar", "testdata/sparse-formats.tar", } { - buf, err := ioutil.ReadFile(p) + buf, err := os.ReadFile(p) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -865,7 +864,7 @@ func TestReadTruncation(t *testing.T) { } cnt++ if s2 == "manual" { - if _, err = tr.writeTo(ioutil.Discard); err != nil { + if _, err = tr.writeTo(io.Discard); err != nil { break } } diff --git a/libgo/go/archive/tar/stat_unix.go b/libgo/go/archive/tar/stat_unix.go index 0ff86e62be9..93a3fcd60e9 100644 --- a/libgo/go/archive/tar/stat_unix.go +++ b/libgo/go/archive/tar/stat_unix.go @@ -7,7 +7,7 @@ package tar import ( - "os" + "io/fs" "os/user" "runtime" "strconv" @@ -23,7 +23,7 @@ func init() { // The downside is that renaming uname or gname by the OS never takes effect. var userMap, groupMap sync.Map // map[int]string -func statUnix(fi os.FileInfo, h *Header) error { +func statUnix(fi fs.FileInfo, h *Header) error { sys, ok := fi.Sys().(*syscall.Stat_t) if !ok { return nil @@ -71,7 +71,7 @@ func statUnix(fi os.FileInfo, h *Header) error { minor := uint32((dev & 0x00000000000000ff) >> 0) minor |= uint32((dev & 0x00000ffffff00000) >> 12) h.Devmajor, h.Devminor = int64(major), int64(minor) - case "darwin": + case "darwin", "ios": // Copied from golang.org/x/sys/unix/dev_darwin.go. major := uint32((dev >> 24) & 0xff) minor := uint32(dev & 0xffffff) diff --git a/libgo/go/archive/tar/tar_test.go b/libgo/go/archive/tar/tar_test.go index 2676853122a..91b38401b6c 100644 --- a/libgo/go/archive/tar/tar_test.go +++ b/libgo/go/archive/tar/tar_test.go @@ -10,7 +10,7 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" + "io/fs" "math" "os" "path" @@ -262,7 +262,7 @@ func TestFileInfoHeaderDir(t *testing.T) { func TestFileInfoHeaderSymlink(t *testing.T) { testenv.MustHaveSymlink(t) - tmpdir, err := ioutil.TempDir("", "TestFileInfoHeaderSymlink") + tmpdir, err := os.MkdirTemp("", "TestFileInfoHeaderSymlink") if err != nil { t.Fatal(err) } @@ -327,7 +327,7 @@ func TestRoundTrip(t *testing.T) { if !reflect.DeepEqual(rHdr, hdr) { t.Errorf("Header mismatch.\n got %+v\nwant %+v", rHdr, hdr) } - rData, err := ioutil.ReadAll(tr) + rData, err := io.ReadAll(tr) if err != nil { t.Fatalf("Read: %v", err) } @@ -338,7 +338,7 @@ func TestRoundTrip(t *testing.T) { type headerRoundTripTest struct { h *Header - fm os.FileMode + fm fs.FileMode } func TestHeaderRoundTrip(t *testing.T) { @@ -361,7 +361,7 @@ func TestHeaderRoundTrip(t *testing.T) { ModTime: time.Unix(1360600852, 0), Typeflag: TypeSymlink, }, - fm: 0777 | os.ModeSymlink, + fm: 0777 | fs.ModeSymlink, }, { // character device node. h: &Header{ @@ -371,7 +371,7 @@ func TestHeaderRoundTrip(t *testing.T) { ModTime: time.Unix(1360578951, 0), Typeflag: TypeChar, }, - fm: 0666 | os.ModeDevice | os.ModeCharDevice, + fm: 0666 | fs.ModeDevice | fs.ModeCharDevice, }, { // block device node. h: &Header{ @@ -381,7 +381,7 @@ func TestHeaderRoundTrip(t *testing.T) { ModTime: time.Unix(1360578954, 0), Typeflag: TypeBlock, }, - fm: 0660 | os.ModeDevice, + fm: 0660 | fs.ModeDevice, }, { // directory. h: &Header{ @@ -391,7 +391,7 @@ func TestHeaderRoundTrip(t *testing.T) { ModTime: time.Unix(1360601116, 0), Typeflag: TypeDir, }, - fm: 0755 | os.ModeDir, + fm: 0755 | fs.ModeDir, }, { // fifo node. h: &Header{ @@ -401,7 +401,7 @@ func TestHeaderRoundTrip(t *testing.T) { ModTime: time.Unix(1360578949, 0), Typeflag: TypeFifo, }, - fm: 0600 | os.ModeNamedPipe, + fm: 0600 | fs.ModeNamedPipe, }, { // setuid. h: &Header{ @@ -411,7 +411,7 @@ func TestHeaderRoundTrip(t *testing.T) { ModTime: time.Unix(1355405093, 0), Typeflag: TypeReg, }, - fm: 0755 | os.ModeSetuid, + fm: 0755 | fs.ModeSetuid, }, { // setguid. h: &Header{ @@ -421,7 +421,7 @@ func TestHeaderRoundTrip(t *testing.T) { ModTime: time.Unix(1360602346, 0), Typeflag: TypeReg, }, - fm: 0750 | os.ModeSetgid, + fm: 0750 | fs.ModeSetgid, }, { // sticky. h: &Header{ @@ -431,7 +431,7 @@ func TestHeaderRoundTrip(t *testing.T) { ModTime: time.Unix(1360602540, 0), Typeflag: TypeReg, }, - fm: 0600 | os.ModeSticky, + fm: 0600 | fs.ModeSticky, }, { // hard link. h: &Header{ @@ -804,9 +804,9 @@ func Benchmark(b *testing.B) { b.Run(v.label, func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { - // Writing to ioutil.Discard because we want to + // Writing to io.Discard because we want to // test purely the writer code and not bring in disk performance into this. - tw := NewWriter(ioutil.Discard) + tw := NewWriter(io.Discard) for _, file := range v.files { if err := tw.WriteHeader(file.hdr); err != nil { b.Errorf("unexpected WriteHeader error: %v", err) @@ -844,7 +844,7 @@ func Benchmark(b *testing.B) { if _, err := tr.Next(); err != nil { b.Errorf("unexpected Next error: %v", err) } - if _, err := io.Copy(ioutil.Discard, tr); err != nil { + if _, err := io.Copy(io.Discard, tr); err != nil { b.Errorf("unexpected Copy error : %v", err) } } diff --git a/libgo/go/archive/tar/writer_test.go b/libgo/go/archive/tar/writer_test.go index 30556d27d02..a00f02d8fab 100644 --- a/libgo/go/archive/tar/writer_test.go +++ b/libgo/go/archive/tar/writer_test.go @@ -9,7 +9,6 @@ import ( "encoding/hex" "errors" "io" - "io/ioutil" "os" "path" "reflect" @@ -520,7 +519,7 @@ func TestWriter(t *testing.T) { } if v.file != "" { - want, err := ioutil.ReadFile(v.file) + want, err := os.ReadFile(v.file) if err != nil { t.Fatalf("ReadFile() = %v, want nil", err) } diff --git a/libgo/go/archive/zip/reader.go b/libgo/go/archive/zip/reader.go index 13ff9ddcf42..8b4e77875fb 100644 --- a/libgo/go/archive/zip/reader.go +++ b/libgo/go/archive/zip/reader.go @@ -11,7 +11,12 @@ import ( "hash" "hash/crc32" "io" + "io/fs" "os" + "path" + "sort" + "strings" + "sync" "time" ) @@ -21,18 +26,28 @@ var ( ErrChecksum = errors.New("zip: checksum error") ) +// A Reader serves content from a ZIP archive. type Reader struct { r io.ReaderAt File []*File Comment string decompressors map[uint16]Decompressor + + // fileList is a list of files sorted by ename, + // for use by the Open method. + fileListOnce sync.Once + fileList []fileListEntry } +// A ReadCloser is a Reader that must be closed when no longer needed. type ReadCloser struct { f *os.File Reader } +// A File is a single file in a ZIP archive. +// The file information is in the embedded FileHeader. +// The file content can be accessed by calling Open. type File struct { FileHeader zip *Reader @@ -187,6 +202,10 @@ type checksumReader struct { err error // sticky error } +func (r *checksumReader) Stat() (fs.FileInfo, error) { + return headerFileInfo{&r.f.FileHeader}, nil +} + func (r *checksumReader) Read(b []byte) (n int, err error) { if r.err != nil { return 0, r.err @@ -607,3 +626,173 @@ func (b *readBuf) sub(n int) readBuf { *b = (*b)[n:] return b2 } + +// A fileListEntry is a File and its ename. +// If file == nil, the fileListEntry describes a directory, without metadata. +type fileListEntry struct { + name string + file *File // nil for directories +} + +type fileInfoDirEntry interface { + fs.FileInfo + fs.DirEntry +} + +func (e *fileListEntry) stat() fileInfoDirEntry { + if e.file != nil { + return headerFileInfo{&e.file.FileHeader} + } + return e +} + +// Only used for directories. +func (f *fileListEntry) Name() string { _, elem, _ := split(f.name); return elem } +func (f *fileListEntry) Size() int64 { return 0 } +func (f *fileListEntry) ModTime() time.Time { return time.Time{} } +func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 } +func (f *fileListEntry) Type() fs.FileMode { return fs.ModeDir } +func (f *fileListEntry) IsDir() bool { return true } +func (f *fileListEntry) Sys() interface{} { return nil } + +func (f *fileListEntry) Info() (fs.FileInfo, error) { return f, nil } + +// toValidName coerces name to be a valid name for fs.FS.Open. +func toValidName(name string) string { + name = strings.ReplaceAll(name, `\`, `/`) + p := path.Clean(name) + if strings.HasPrefix(p, "/") { + p = p[len("/"):] + } + for strings.HasPrefix(name, "../") { + p = p[len("../"):] + } + return p +} + +func (r *Reader) initFileList() { + r.fileListOnce.Do(func() { + dirs := make(map[string]bool) + for _, file := range r.File { + name := toValidName(file.Name) + for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) { + dirs[dir] = true + } + r.fileList = append(r.fileList, fileListEntry{name, file}) + } + for dir := range dirs { + r.fileList = append(r.fileList, fileListEntry{dir + "/", nil}) + } + + sort.Slice(r.fileList, func(i, j int) bool { return fileEntryLess(r.fileList[i].name, r.fileList[j].name) }) + }) +} + +func fileEntryLess(x, y string) bool { + xdir, xelem, _ := split(x) + ydir, yelem, _ := split(y) + return xdir < ydir || xdir == ydir && xelem < yelem +} + +// Open opens the named file in the ZIP archive, +// using the semantics of fs.FS.Open: +// paths are always slash separated, with no +// leading / or ../ elements. +func (r *Reader) Open(name string) (fs.File, error) { + r.initFileList() + + e := r.openLookup(name) + if e == nil || !fs.ValidPath(name) { + return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist} + } + if e.file == nil || strings.HasSuffix(e.file.Name, "/") { + return &openDir{e, r.openReadDir(name), 0}, nil + } + rc, err := e.file.Open() + if err != nil { + return nil, err + } + return rc.(fs.File), nil +} + +func split(name string) (dir, elem string, isDir bool) { + if name[len(name)-1] == '/' { + isDir = true + name = name[:len(name)-1] + } + i := len(name) - 1 + for i >= 0 && name[i] != '/' { + i-- + } + if i < 0 { + return ".", name, isDir + } + return name[:i], name[i+1:], isDir +} + +var dotFile = &fileListEntry{name: "./"} + +func (r *Reader) openLookup(name string) *fileListEntry { + if name == "." { + return dotFile + } + + dir, elem, _ := split(name) + files := r.fileList + i := sort.Search(len(files), func(i int) bool { + idir, ielem, _ := split(files[i].name) + return idir > dir || idir == dir && ielem >= elem + }) + if i < len(files) { + fname := files[i].name + if fname == name || len(fname) == len(name)+1 && fname[len(name)] == '/' && fname[:len(name)] == name { + return &files[i] + } + } + return nil +} + +func (r *Reader) openReadDir(dir string) []fileListEntry { + files := r.fileList + i := sort.Search(len(files), func(i int) bool { + idir, _, _ := split(files[i].name) + return idir >= dir + }) + j := sort.Search(len(files), func(j int) bool { + jdir, _, _ := split(files[j].name) + return jdir > dir + }) + return files[i:j] +} + +type openDir struct { + e *fileListEntry + files []fileListEntry + offset int +} + +func (d *openDir) Close() error { return nil } +func (d *openDir) Stat() (fs.FileInfo, error) { return d.e.stat(), nil } + +func (d *openDir) Read([]byte) (int, error) { + return 0, &fs.PathError{Op: "read", Path: d.e.name, Err: errors.New("is a directory")} +} + +func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) { + n := len(d.files) - d.offset + if count > 0 && n > count { + n = count + } + if n == 0 { + if count <= 0 { + return nil, nil + } + return nil, io.EOF + } + list := make([]fs.DirEntry, n) + for i := range list { + list[i] = d.files[d.offset+i].stat() + } + d.offset += n + return list, nil +} diff --git a/libgo/go/archive/zip/reader_test.go b/libgo/go/archive/zip/reader_test.go index adca87a8b38..34e96f7da43 100644 --- a/libgo/go/archive/zip/reader_test.go +++ b/libgo/go/archive/zip/reader_test.go @@ -10,12 +10,13 @@ import ( "encoding/hex" "internal/obscuretestdata" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "regexp" "strings" "testing" + "testing/fstest" "time" ) @@ -30,7 +31,7 @@ type ZipTest struct { type ZipTestFile struct { Name string - Mode os.FileMode + Mode fs.FileMode NonUTF8 bool ModTime time.Time Modified time.Time @@ -107,7 +108,7 @@ var tests = []ZipTest{ Name: "symlink", Content: []byte("../target"), Modified: time.Date(2012, 2, 3, 19, 56, 48, 0, timeZone(-2*time.Hour)), - Mode: 0777 | os.ModeSymlink, + Mode: 0777 | fs.ModeSymlink, }, }, }, @@ -149,7 +150,7 @@ var tests = []ZipTest{ Name: "dir/empty/", Content: []byte{}, Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, time.UTC), - Mode: os.ModeDir | 0777, + Mode: fs.ModeDir | 0777, }, { Name: "readonly", @@ -179,7 +180,7 @@ var tests = []ZipTest{ Name: "dir/empty/", Content: []byte{}, Modified: time.Date(2011, 12, 8, 10, 8, 6, 0, timeZone(0)), - Mode: os.ModeDir | 0777, + Mode: fs.ModeDir | 0777, }, { Name: "readonly", @@ -627,7 +628,7 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) { var c []byte if ft.Content != nil { c = ft.Content - } else if c, err = ioutil.ReadFile("testdata/" + ft.File); err != nil { + } else if c, err = os.ReadFile("testdata/" + ft.File); err != nil { t.Error(err) return } @@ -645,7 +646,7 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) { } } -func testFileMode(t *testing.T, f *File, want os.FileMode) { +func testFileMode(t *testing.T, f *File, want fs.FileMode) { mode := f.Mode() if want == 0 { t.Errorf("%s mode: got %v, want none", f.Name, mode) @@ -683,7 +684,7 @@ func TestInvalidFiles(t *testing.T) { } func messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) { - data, err := ioutil.ReadFile(filepath.Join("testdata", fileName)) + data, err := os.ReadFile(filepath.Join("testdata", fileName)) if err != nil { panic("Error reading " + fileName + ": " + err.Error()) } @@ -790,17 +791,17 @@ func returnRecursiveZip() (r io.ReaderAt, size int64) { // // func main() { // bigZip := makeZip("big.file", io.LimitReader(zeros{}, 1<<32-1)) -// if err := ioutil.WriteFile("/tmp/big.zip", bigZip, 0666); err != nil { +// if err := os.WriteFile("/tmp/big.zip", bigZip, 0666); err != nil { // log.Fatal(err) // } // // biggerZip := makeZip("big.zip", bytes.NewReader(bigZip)) -// if err := ioutil.WriteFile("/tmp/bigger.zip", biggerZip, 0666); err != nil { +// if err := os.WriteFile("/tmp/bigger.zip", biggerZip, 0666); err != nil { // log.Fatal(err) // } // // biggestZip := makeZip("bigger.zip", bytes.NewReader(biggerZip)) -// if err := ioutil.WriteFile("/tmp/biggest.zip", biggestZip, 0666); err != nil { +// if err := os.WriteFile("/tmp/biggest.zip", biggestZip, 0666); err != nil { // log.Fatal(err) // } // } @@ -928,7 +929,7 @@ func returnBigZipBytes() (r io.ReaderAt, size int64) { if err != nil { panic(err) } - b, err = ioutil.ReadAll(f) + b, err = io.ReadAll(f) if err != nil { panic(err) } @@ -985,7 +986,7 @@ func TestIssue10957(t *testing.T) { continue } if f.UncompressedSize64 < 1e6 { - n, err := io.Copy(ioutil.Discard, r) + n, err := io.Copy(io.Discard, r) if i == 3 && err != io.ErrUnexpectedEOF { t.Errorf("File[3] error = %v; want io.ErrUnexpectedEOF", err) } @@ -1027,7 +1028,7 @@ func TestIssue11146(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = ioutil.ReadAll(r) + _, err = io.ReadAll(r) if err != io.ErrUnexpectedEOF { t.Errorf("File[0] error = %v; want io.ErrUnexpectedEOF", err) } @@ -1070,3 +1071,13 @@ func TestIssue12449(t *testing.T) { t.Errorf("Error reading the archive: %v", err) } } + +func TestFS(t *testing.T) { + z, err := OpenReader("testdata/unix.zip") + if err != nil { + t.Fatal(err) + } + if err := fstest.TestFS(z, "hello", "dir/bar", "dir/empty", "readonly"); err != nil { + t.Fatal(err) + } +} diff --git a/libgo/go/archive/zip/register.go b/libgo/go/archive/zip/register.go index 51e9c3e4d4b..4389246286f 100644 --- a/libgo/go/archive/zip/register.go +++ b/libgo/go/archive/zip/register.go @@ -8,7 +8,6 @@ import ( "compress/flate" "errors" "io" - "io/ioutil" "sync" ) @@ -111,7 +110,7 @@ func init() { compressors.Store(Store, Compressor(func(w io.Writer) (io.WriteCloser, error) { return &nopCloser{w}, nil })) compressors.Store(Deflate, Compressor(func(w io.Writer) (io.WriteCloser, error) { return newFlateWriter(w), nil })) - decompressors.Store(Store, Decompressor(ioutil.NopCloser)) + decompressors.Store(Store, Decompressor(io.NopCloser)) decompressors.Store(Deflate, Decompressor(newFlateReader)) } diff --git a/libgo/go/archive/zip/struct.go b/libgo/go/archive/zip/struct.go index 686e79781ac..4dd29f35fa6 100644 --- a/libgo/go/archive/zip/struct.go +++ b/libgo/go/archive/zip/struct.go @@ -20,7 +20,7 @@ fields must be used instead. package zip import ( - "os" + "io/fs" "path" "time" ) @@ -137,12 +137,12 @@ type FileHeader struct { ExternalAttrs uint32 // Meaning depends on CreatorVersion } -// FileInfo returns an os.FileInfo for the FileHeader. -func (h *FileHeader) FileInfo() os.FileInfo { +// FileInfo returns an fs.FileInfo for the FileHeader. +func (h *FileHeader) FileInfo() fs.FileInfo { return headerFileInfo{h} } -// headerFileInfo implements os.FileInfo. +// headerFileInfo implements fs.FileInfo. type headerFileInfo struct { fh *FileHeader } @@ -161,17 +161,20 @@ func (fi headerFileInfo) ModTime() time.Time { } return fi.fh.Modified.UTC() } -func (fi headerFileInfo) Mode() os.FileMode { return fi.fh.Mode() } +func (fi headerFileInfo) Mode() fs.FileMode { return fi.fh.Mode() } +func (fi headerFileInfo) Type() fs.FileMode { return fi.fh.Mode().Type() } func (fi headerFileInfo) Sys() interface{} { return fi.fh } +func (fi headerFileInfo) Info() (fs.FileInfo, error) { return fi, nil } + // FileInfoHeader creates a partially-populated FileHeader from an -// os.FileInfo. -// Because os.FileInfo's Name method returns only the base name of +// fs.FileInfo. +// Because fs.FileInfo's Name method returns only the base name of // the file it describes, it may be necessary to modify the Name field // of the returned header to provide the full path name of the file. // If compression is desired, callers should set the FileHeader.Method // field; it is unset by default. -func FileInfoHeader(fi os.FileInfo) (*FileHeader, error) { +func FileInfoHeader(fi fs.FileInfo) (*FileHeader, error) { size := fi.Size() fh := &FileHeader{ Name: fi.Name(), @@ -280,7 +283,7 @@ const ( ) // Mode returns the permission and mode bits for the FileHeader. -func (h *FileHeader) Mode() (mode os.FileMode) { +func (h *FileHeader) Mode() (mode fs.FileMode) { switch h.CreatorVersion >> 8 { case creatorUnix, creatorMacOSX: mode = unixModeToFileMode(h.ExternalAttrs >> 16) @@ -288,18 +291,18 @@ func (h *FileHeader) Mode() (mode os.FileMode) { mode = msdosModeToFileMode(h.ExternalAttrs) } if len(h.Name) > 0 && h.Name[len(h.Name)-1] == '/' { - mode |= os.ModeDir + mode |= fs.ModeDir } return mode } // SetMode changes the permission and mode bits for the FileHeader. -func (h *FileHeader) SetMode(mode os.FileMode) { +func (h *FileHeader) SetMode(mode fs.FileMode) { h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8 h.ExternalAttrs = fileModeToUnixMode(mode) << 16 // set MSDOS attributes too, as the original zip does. - if mode&os.ModeDir != 0 { + if mode&fs.ModeDir != 0 { h.ExternalAttrs |= msdosDir } if mode&0200 == 0 { @@ -312,9 +315,9 @@ func (h *FileHeader) isZip64() bool { return h.CompressedSize64 >= uint32max || h.UncompressedSize64 >= uint32max } -func msdosModeToFileMode(m uint32) (mode os.FileMode) { +func msdosModeToFileMode(m uint32) (mode fs.FileMode) { if m&msdosDir != 0 { - mode = os.ModeDir | 0777 + mode = fs.ModeDir | 0777 } else { mode = 0666 } @@ -324,64 +327,64 @@ func msdosModeToFileMode(m uint32) (mode os.FileMode) { return mode } -func fileModeToUnixMode(mode os.FileMode) uint32 { +func fileModeToUnixMode(mode fs.FileMode) uint32 { var m uint32 - switch mode & os.ModeType { + switch mode & fs.ModeType { default: m = s_IFREG - case os.ModeDir: + case fs.ModeDir: m = s_IFDIR - case os.ModeSymlink: + case fs.ModeSymlink: m = s_IFLNK - case os.ModeNamedPipe: + case fs.ModeNamedPipe: m = s_IFIFO - case os.ModeSocket: + case fs.ModeSocket: m = s_IFSOCK - case os.ModeDevice: - if mode&os.ModeCharDevice != 0 { + case fs.ModeDevice: + if mode&fs.ModeCharDevice != 0 { m = s_IFCHR } else { m = s_IFBLK } } - if mode&os.ModeSetuid != 0 { + if mode&fs.ModeSetuid != 0 { m |= s_ISUID } - if mode&os.ModeSetgid != 0 { + if mode&fs.ModeSetgid != 0 { m |= s_ISGID } - if mode&os.ModeSticky != 0 { + if mode&fs.ModeSticky != 0 { m |= s_ISVTX } return m | uint32(mode&0777) } -func unixModeToFileMode(m uint32) os.FileMode { - mode := os.FileMode(m & 0777) +func unixModeToFileMode(m uint32) fs.FileMode { + mode := fs.FileMode(m & 0777) switch m & s_IFMT { case s_IFBLK: - mode |= os.ModeDevice + mode |= fs.ModeDevice case s_IFCHR: - mode |= os.ModeDevice | os.ModeCharDevice + mode |= fs.ModeDevice | fs.ModeCharDevice case s_IFDIR: - mode |= os.ModeDir + mode |= fs.ModeDir case s_IFIFO: - mode |= os.ModeNamedPipe + mode |= fs.ModeNamedPipe case s_IFLNK: - mode |= os.ModeSymlink + mode |= fs.ModeSymlink case s_IFREG: // nothing to do case s_IFSOCK: - mode |= os.ModeSocket + mode |= fs.ModeSocket } if m&s_ISGID != 0 { - mode |= os.ModeSetgid + mode |= fs.ModeSetgid } if m&s_ISUID != 0 { - mode |= os.ModeSetuid + mode |= fs.ModeSetuid } if m&s_ISVTX != 0 { - mode |= os.ModeSticky + mode |= fs.ModeSticky } return mode } diff --git a/libgo/go/archive/zip/writer_test.go b/libgo/go/archive/zip/writer_test.go index 1fedfd85e82..5985144e5c2 100644 --- a/libgo/go/archive/zip/writer_test.go +++ b/libgo/go/archive/zip/writer_test.go @@ -9,7 +9,7 @@ import ( "encoding/binary" "fmt" "io" - "io/ioutil" + "io/fs" "math/rand" "os" "strings" @@ -23,7 +23,7 @@ type WriteTest struct { Name string Data []byte Method uint16 - Mode os.FileMode + Mode fs.FileMode } var writeTests = []WriteTest{ @@ -43,19 +43,19 @@ var writeTests = []WriteTest{ Name: "setuid", Data: []byte("setuid file"), Method: Deflate, - Mode: 0755 | os.ModeSetuid, + Mode: 0755 | fs.ModeSetuid, }, { Name: "setgid", Data: []byte("setgid file"), Method: Deflate, - Mode: 0755 | os.ModeSetgid, + Mode: 0755 | fs.ModeSetgid, }, { Name: "symlink", Data: []byte("../link/target"), Method: Deflate, - Mode: 0755 | os.ModeSymlink, + Mode: 0755 | fs.ModeSymlink, }, } @@ -237,7 +237,7 @@ func TestWriterTime(t *testing.T) { t.Fatalf("unexpected Close error: %v", err) } - want, err := ioutil.ReadFile("testdata/time-go.zip") + want, err := os.ReadFile("testdata/time-go.zip") if err != nil { t.Fatalf("unexpected ReadFile error: %v", err) } @@ -301,7 +301,7 @@ func TestWriterFlush(t *testing.T) { } func TestWriterDir(t *testing.T) { - w := NewWriter(ioutil.Discard) + w := NewWriter(io.Discard) dw, err := w.Create("dir/") if err != nil { t.Fatal(err) @@ -380,7 +380,7 @@ func testReadFile(t *testing.T, f *File, wt *WriteTest) { if err != nil { t.Fatal("opening:", err) } - b, err := ioutil.ReadAll(rc) + b, err := io.ReadAll(rc) if err != nil { t.Fatal("reading:", err) } diff --git a/libgo/go/archive/zip/zip_test.go b/libgo/go/archive/zip/zip_test.go index b3a7caac7f2..ead9cd3aab9 100644 --- a/libgo/go/archive/zip/zip_test.go +++ b/libgo/go/archive/zip/zip_test.go @@ -13,7 +13,6 @@ import ( "hash" "internal/testenv" "io" - "io/ioutil" "runtime" "sort" "strings" @@ -620,7 +619,7 @@ func testZip64(t testing.TB, size int64) *rleBuffer { t.Fatal("read:", err) } } - gotEnd, err := ioutil.ReadAll(rc) + gotEnd, err := io.ReadAll(rc) if err != nil { t.Fatal("read end:", err) } diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go index 7cbd5424ea6..6baf9b9e400 100644 --- a/libgo/go/bufio/bufio.go +++ b/libgo/go/bufio/bufio.go @@ -425,7 +425,7 @@ func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) { // of bytes in the combined first two elements, error). // The complete result is equal to // `bytes.Join(append(fullBuffers, finalFragment), nil)`, which has a -// length of `totalLen`. The result is strucured in this way to allow callers +// length of `totalLen`. The result is structured in this way to allow callers // to minimize allocations and copies. func (b *Reader) collectFragments(delim byte) (fullBuffers [][]byte, finalFragment []byte, totalLen int, err error) { var frag []byte diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go index cb68f3ba239..d7b34bd0d8f 100644 --- a/libgo/go/bufio/bufio_test.go +++ b/libgo/go/bufio/bufio_test.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "strings" "testing" "testing/iotest" @@ -147,7 +146,7 @@ func TestReader(t *testing.T) { for i := 0; i < len(texts)-1; i++ { texts[i] = str + "\n" all += texts[i] - str += string(rune(i)%26 + 'a') + str += string(rune(i%26 + 'a')) } texts[len(texts)-1] = all @@ -886,7 +885,7 @@ func TestReadEmptyBuffer(t *testing.T) { func TestLinesAfterRead(t *testing.T) { l := NewReaderSize(bytes.NewReader([]byte("foo")), minReadBufferSize) - _, err := ioutil.ReadAll(l) + _, err := io.ReadAll(l) if err != nil { t.Error(err) return @@ -1130,7 +1129,7 @@ func TestWriterReadFromCounts(t *testing.T) { } } -// A writeCountingDiscard is like ioutil.Discard and counts the number of times +// A writeCountingDiscard is like io.Discard and counts the number of times // Write is called on it. type writeCountingDiscard int @@ -1300,7 +1299,7 @@ func TestReaderReset(t *testing.T) { t.Errorf("buf = %q; want foo", buf) } r.Reset(strings.NewReader("bar bar")) - all, err := ioutil.ReadAll(r) + all, err := io.ReadAll(r) if err != nil { t.Fatal(err) } @@ -1645,13 +1644,13 @@ func BenchmarkReaderWriteToOptimal(b *testing.B) { buf := make([]byte, bufSize) r := bytes.NewReader(buf) srcReader := NewReaderSize(onlyReader{r}, 1<<10) - if _, ok := ioutil.Discard.(io.ReaderFrom); !ok { - b.Fatal("ioutil.Discard doesn't support ReaderFrom") + if _, ok := io.Discard.(io.ReaderFrom); !ok { + b.Fatal("io.Discard doesn't support ReaderFrom") } for i := 0; i < b.N; i++ { r.Seek(0, io.SeekStart) srcReader.Reset(onlyReader{r}) - n, err := srcReader.WriteTo(ioutil.Discard) + n, err := srcReader.WriteTo(io.Discard) if err != nil { b.Fatal(err) } @@ -1722,7 +1721,7 @@ func BenchmarkReaderEmpty(b *testing.B) { str := strings.Repeat("x", 16<<10) for i := 0; i < b.N; i++ { br := NewReader(strings.NewReader(str)) - n, err := io.Copy(ioutil.Discard, br) + n, err := io.Copy(io.Discard, br) if err != nil { b.Fatal(err) } @@ -1737,7 +1736,7 @@ func BenchmarkWriterEmpty(b *testing.B) { str := strings.Repeat("x", 1<<10) bs := []byte(str) for i := 0; i < b.N; i++ { - bw := NewWriter(ioutil.Discard) + bw := NewWriter(io.Discard) bw.Flush() bw.WriteByte('a') bw.Flush() @@ -1752,7 +1751,7 @@ func BenchmarkWriterEmpty(b *testing.B) { func BenchmarkWriterFlush(b *testing.B) { b.ReportAllocs() - bw := NewWriter(ioutil.Discard) + bw := NewWriter(io.Discard) str := strings.Repeat("x", 50) for i := 0; i < b.N; i++ { bw.WriteString(str) diff --git a/libgo/go/bytes/example_test.go b/libgo/go/bytes/example_test.go index 5ba7077c1de..ae93202b570 100644 --- a/libgo/go/bytes/example_test.go +++ b/libgo/go/bytes/example_test.go @@ -30,6 +30,13 @@ func ExampleBuffer_reader() { // Output: Gophers rule! } +func ExampleBuffer_Bytes() { + buf := bytes.Buffer{} + buf.Write([]byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}) + os.Stdout.Write(buf.Bytes()) + // Output: hello world +} + func ExampleBuffer_Grow() { var b bytes.Buffer b.Grow(64) diff --git a/libgo/go/bytes/reader_test.go b/libgo/go/bytes/reader_test.go index d799e036f0c..8baac5046cb 100644 --- a/libgo/go/bytes/reader_test.go +++ b/libgo/go/bytes/reader_test.go @@ -8,7 +8,6 @@ import ( . "bytes" "fmt" "io" - "io/ioutil" "sync" "testing" ) @@ -235,7 +234,7 @@ func TestReaderCopyNothing(t *testing.T) { type justWriter struct { io.Writer } - discard := justWriter{ioutil.Discard} // hide ReadFrom + discard := justWriter{io.Discard} // hide ReadFrom var with, withOut nErr with.n, with.err = io.Copy(discard, NewReader(nil)) @@ -248,7 +247,7 @@ func TestReaderCopyNothing(t *testing.T) { // tests that Len is affected by reads, but Size is not. func TestReaderLenSize(t *testing.T) { r := NewReader([]byte("abc")) - io.CopyN(ioutil.Discard, r, 1) + io.CopyN(io.Discard, r, 1) if r.Len() != 2 { t.Errorf("Len = %d; want 2", r.Len()) } @@ -268,7 +267,7 @@ func TestReaderReset(t *testing.T) { if err := r.UnreadRune(); err == nil { t.Errorf("UnreadRune: expected error, got nil") } - buf, err := ioutil.ReadAll(r) + buf, err := io.ReadAll(r) if err != nil { t.Errorf("ReadAll: unexpected error: %v", err) } @@ -314,7 +313,7 @@ func TestReaderZero(t *testing.T) { t.Errorf("UnreadRune: got nil, want error") } - if n, err := (&Reader{}).WriteTo(ioutil.Discard); n != 0 || err != nil { + if n, err := (&Reader{}).WriteTo(io.Discard); n != 0 || err != nil { t.Errorf("WriteTo: got %d, %v; want 0, nil", n, err) } } diff --git a/libgo/go/cmd/buildid/buildid.go b/libgo/go/cmd/buildid/buildid.go index 1c7b228c987..8e02a7ae109 100644 --- a/libgo/go/cmd/buildid/buildid.go +++ b/libgo/go/cmd/buildid/buildid.go @@ -22,21 +22,6 @@ func usage() { var wflag = flag.Bool("w", false, "write build ID") -// taken from cmd/go/internal/work/buildid.go -func hashToString(h [32]byte) string { - const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" - const chunks = 5 - var dst [chunks * 4]byte - for i := 0; i < chunks; i++ { - v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2]) - dst[4*i+0] = b64[(v>>18)&0x3F] - dst[4*i+1] = b64[(v>>12)&0x3F] - dst[4*i+2] = b64[(v>>6)&0x3F] - dst[4*i+3] = b64[v&0x3F] - } - return string(dst[:]) -} - func main() { log.SetPrefix("buildid: ") log.SetFlags(0) @@ -63,12 +48,12 @@ func main() { log.Fatal(err) } matches, hash, err := buildid.FindAndHash(f, id, 0) + f.Close() if err != nil { log.Fatal(err) } - f.Close() - newID := id[:strings.LastIndex(id, "/")] + "/" + hashToString(hash) + newID := id[:strings.LastIndex(id, "/")] + "/" + buildid.HashToString(hash) if len(newID) != len(id) { log.Fatalf("%s: build ID length mismatch %q vs %q", file, id, newID) } @@ -77,7 +62,7 @@ func main() { return } - f, err = os.OpenFile(file, os.O_WRONLY, 0) + f, err = os.OpenFile(file, os.O_RDWR, 0) if err != nil { log.Fatal(err) } diff --git a/libgo/go/cmd/cgo/ast.go b/libgo/go/cmd/cgo/ast.go index 54d6bc2559d..a073407a961 100644 --- a/libgo/go/cmd/cgo/ast.go +++ b/libgo/go/cmd/cgo/ast.go @@ -13,7 +13,6 @@ import ( "go/scanner" "go/token" "os" - "path/filepath" "strings" ) @@ -44,14 +43,7 @@ func sourceLine(n ast.Node) int { // attached to the import "C" comment, a list of references to C.xxx, // a list of exported functions, and the actual AST, to be rewritten and // printed. -func (f *File) ParseGo(name string, src []byte) { - // Create absolute path for file, so that it will be used in error - // messages and recorded in debug line number information. - // This matches the rest of the toolchain. See golang.org/issue/5122. - if aname, err := filepath.Abs(name); err == nil { - name = aname - } - +func (f *File) ParseGo(abspath string, src []byte) { // Two different parses: once with comments, once without. // The printer is not good enough at printing comments in the // right place when we start editing the AST behind its back, @@ -60,8 +52,8 @@ func (f *File) ParseGo(name string, src []byte) { // and reprinting. // In cgo mode, we ignore ast2 and just apply edits directly // the text behind ast1. In godefs mode we modify and print ast2. - ast1 := parse(name, src, parser.ParseComments) - ast2 := parse(name, src, 0) + ast1 := parse(abspath, src, parser.ParseComments) + ast2 := parse(abspath, src, 0) f.Package = ast1.Name.Name f.Name = make(map[string]*Name) @@ -88,7 +80,7 @@ func (f *File) ParseGo(name string, src []byte) { cg = d.Doc } if cg != nil { - f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), name) + f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), abspath) f.Preamble += commentText(cg) + "\n" f.Preamble += "#line 1 \"cgo-generated-wrapper\"\n" } diff --git a/libgo/go/cmd/cgo/doc.go b/libgo/go/cmd/cgo/doc.go index ca18c45d9d9..e782c866ac7 100644 --- a/libgo/go/cmd/cgo/doc.go +++ b/libgo/go/cmd/cgo/doc.go @@ -112,6 +112,13 @@ The default C and C++ compilers may be changed by the CC and CXX environment variables, respectively; those environment variables may include command line options. +The cgo tool will always invoke the C compiler with the source file's +directory in the include path; i.e. -I${SRCDIR} is always implied. This +means that if a header file foo/bar.h exists both in the source +directory and also in the system include directory (or some other place +specified by a -I flag), then "#include " will always find the +local version in preference to any other version. + The cgo tool is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross-compiling. You can control this by setting the CGO_ENABLED @@ -714,7 +721,7 @@ linkage to the desired libraries. The main function is provided by _cgo_main.c: int main() { return 0; } - void crosscall2(void(*fn)(void*, int, uintptr_t), void *a, int c, uintptr_t ctxt) { } + void crosscall2(void(*fn)(void*), void *a, int c, uintptr_t ctxt) { } uintptr_t _cgo_wait_runtime_init_done(void) { return 0; } void _cgo_release_context(uintptr_t ctxt) { } char* _cgo_topofstack(void) { return (char*)0; } diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go index 37bafcf189e..796ff8ac520 100644 --- a/libgo/go/cmd/cgo/gcc.go +++ b/libgo/go/cmd/cgo/gcc.go @@ -316,7 +316,7 @@ func (p *Package) guessKinds(f *File) []*Name { continue } - if goos == "darwin" && strings.HasSuffix(n.C, "Ref") { + if (goos == "darwin" || goos == "ios") && strings.HasSuffix(n.C, "Ref") { // For FooRef, find out if FooGetTypeID exists. s := n.C[:len(n.C)-3] + "GetTypeID" n := &Name{Go: s, C: s} @@ -387,7 +387,18 @@ func (p *Package) guessKinds(f *File) []*Name { fmt.Fprintf(&b, "#line 1 \"completed\"\n"+ "int __cgo__1 = __cgo__2;\n") - stderr := p.gccErrors(b.Bytes()) + // We need to parse the output from this gcc command, so ensure that it + // doesn't have any ANSI escape sequences in it. (TERM=dumb is + // insufficient; if the user specifies CGO_CFLAGS=-fdiagnostics-color, + // GCC will ignore TERM, and GCC can also be configured at compile-time + // to ignore TERM.) + stderr := p.gccErrors(b.Bytes(), "-fdiagnostics-color=never") + if strings.Contains(stderr, "unrecognized command line option") { + // We're using an old version of GCC that doesn't understand + // -fdiagnostics-color. Those versions can't print color anyway, + // so just rerun without that option. + stderr = p.gccErrors(b.Bytes()) + } if stderr == "" { fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes()) } @@ -1995,22 +2006,25 @@ func (p *Package) gccDefines(stdin []byte) string { // gccErrors runs gcc over the C program stdin and returns // the errors that gcc prints. That is, this function expects // gcc to fail. -func (p *Package) gccErrors(stdin []byte) string { +func (p *Package) gccErrors(stdin []byte, extraArgs ...string) string { // TODO(rsc): require failure args := p.gccCmd() // Optimization options can confuse the error messages; remove them. - nargs := make([]string, 0, len(args)) + nargs := make([]string, 0, len(args)+len(extraArgs)) for _, arg := range args { if !strings.HasPrefix(arg, "-O") { nargs = append(nargs, arg) } } - // Force -O0 optimization but keep the trailing "-" at the end. - nargs = append(nargs, "-O0") - nl := len(nargs) - nargs[nl-2], nargs[nl-1] = nargs[nl-1], nargs[nl-2] + // Force -O0 optimization and append extra arguments, but keep the + // trailing "-" at the end. + li := len(nargs) - 1 + last := nargs[li] + nargs[li] = "-O0" + nargs = append(nargs, extraArgs...) + nargs = append(nargs, last) if *debugGcc { fmt.Fprintf(os.Stderr, "$ %s < 0 { - switch f.BitSize { - case 8, 16, 32, 64: - default: - continue - } - size = f.BitSize / 8 - name := tgo.(*ast.Ident).String() - if strings.HasPrefix(name, "int") { - name = "int" - } else { - name = "uint" - } - tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize)) - talign = size + if f.BitOffset > 0 || f.BitSize > 0 { + // The layout of bitfields is implementation defined, + // so we don't know how they correspond to Go fields + // even if they are aligned at byte boundaries. + continue } if talign > 0 && f.ByteOffset%talign != 0 { @@ -3096,7 +3100,7 @@ func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool { // We identify the correct set of types as those ending in Ref and for which // there exists a corresponding GetTypeID function. // See comment below for details about the bad pointers. - if goos != "darwin" { + if goos != "darwin" && goos != "ios" { return false } s := dt.Name diff --git a/libgo/go/cmd/cgo/godefs.go b/libgo/go/cmd/cgo/godefs.go index b4fd9c5a6e3..c0d59aee01d 100644 --- a/libgo/go/cmd/cgo/godefs.go +++ b/libgo/go/cmd/cgo/godefs.go @@ -16,7 +16,7 @@ import ( ) // godefs returns the output for -godefs mode. -func (p *Package) godefs(f *File, srcfile string) string { +func (p *Package) godefs(f *File) string { var buf bytes.Buffer fmt.Fprintf(&buf, "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n") diff --git a/libgo/go/cmd/cgo/main.go b/libgo/go/cmd/cgo/main.go index 4952118b1f8..c47e99170c0 100644 --- a/libgo/go/cmd/cgo/main.go +++ b/libgo/go/cmd/cgo/main.go @@ -247,6 +247,8 @@ var gccgopkgpath = flag.String("gccgopkgpath", "", "-fgo-pkgpath option used wit var gccgoMangler func(string) string var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code") var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code") +var trimpath = flag.String("trimpath", "", "applies supplied rewrites or trims prefixes to recorded source file paths") + var goarch, goos string func main() { @@ -326,6 +328,13 @@ func main() { input = filepath.Join(*srcDir, input) } + // Create absolute path for file, so that it will be used in error + // messages and recorded in debug line number information. + // This matches the rest of the toolchain. See golang.org/issue/5122. + if aname, err := filepath.Abs(input); err == nil { + input = aname + } + b, err := ioutil.ReadFile(input) if err != nil { fatalf("%s", err) @@ -334,6 +343,10 @@ func main() { fatalf("%s", err) } + // Apply trimpath to the file path. The path won't be read from after this point. + input, _ = objabi.ApplyRewrites(input, *trimpath) + goFiles[i] = input + f := new(File) f.Edit = edit.NewBuffer(b) f.ParseGo(input, b) @@ -371,7 +384,7 @@ func main() { p.PackagePath = f.Package p.Record(f) if *godefs { - os.Stdout.WriteString(p.godefs(f, input)) + os.Stdout.WriteString(p.godefs(f)) } else { p.writeOutput(f, input) } diff --git a/libgo/go/cmd/cgo/out.go b/libgo/go/cmd/cgo/out.go index 1c143d7aa38..6cdebac5e2b 100644 --- a/libgo/go/cmd/cgo/out.go +++ b/libgo/go/cmd/cgo/out.go @@ -64,14 +64,14 @@ func (p *Package) writeDefs() { // Write C main file for using gcc to resolve imports. fmt.Fprintf(fm, "int main() { return 0; }\n") if *importRuntimeCgo { - fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int, __SIZE_TYPE__), void *a, int c, __SIZE_TYPE__ ctxt) { }\n") + fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*), void *a, int c, __SIZE_TYPE__ ctxt) { }\n") fmt.Fprintf(fm, "__SIZE_TYPE__ _cgo_wait_runtime_init_done(void) { return 0; }\n") fmt.Fprintf(fm, "void _cgo_release_context(__SIZE_TYPE__ ctxt) { }\n") fmt.Fprintf(fm, "char* _cgo_topofstack(void) { return (char*)0; }\n") } else { // If we're not importing runtime/cgo, we *are* runtime/cgo, // which provides these functions. We just need a prototype. - fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int, __SIZE_TYPE__), void *a, int c, __SIZE_TYPE__ ctxt);\n") + fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*), void *a, int c, __SIZE_TYPE__ ctxt);\n") fmt.Fprintf(fm, "__SIZE_TYPE__ _cgo_wait_runtime_init_done(void);\n") fmt.Fprintf(fm, "void _cgo_release_context(__SIZE_TYPE__);\n") } @@ -251,6 +251,7 @@ func (p *Package) writeDefs() { if err != nil { fatalf("%s", err) } + defer fgcch.Close() _, err = io.Copy(fexp, fgcch) if err != nil { fatalf("%s", err) @@ -879,7 +880,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Wpragmas\"\n") fmt.Fprintf(fgcc, "#pragma GCC diagnostic ignored \"-Waddress-of-packed-member\"\n") - fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *, int, __SIZE_TYPE__), void *, int, __SIZE_TYPE__);\n") + fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *), void *, int, __SIZE_TYPE__);\n") fmt.Fprintf(fgcc, "extern __SIZE_TYPE__ _cgo_wait_runtime_init_done(void);\n") fmt.Fprintf(fgcc, "extern void _cgo_release_context(__SIZE_TYPE__);\n\n") fmt.Fprintf(fgcc, "extern char* _cgo_topofstack(void);") @@ -889,59 +890,48 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { for _, exp := range p.ExpFunc { fn := exp.Func - // Construct a gcc struct matching the gc argument and - // result frame. The gcc struct will be compiled with - // __attribute__((packed)) so all padding must be accounted - // for explicitly. + // Construct a struct that will be used to communicate + // arguments from C to Go. The C and Go definitions + // just have to agree. The gcc struct will be compiled + // with __attribute__((packed)) so all padding must be + // accounted for explicitly. ctype := "struct {\n" + gotype := new(bytes.Buffer) + fmt.Fprintf(gotype, "struct {\n") off := int64(0) npad := 0 - if fn.Recv != nil { - t := p.cgoType(fn.Recv.List[0].Type) - ctype += fmt.Sprintf("\t\t%s recv;\n", t.C) + argField := func(typ ast.Expr, namePat string, args ...interface{}) { + name := fmt.Sprintf(namePat, args...) + t := p.cgoType(typ) + if off%t.Align != 0 { + pad := t.Align - off%t.Align + ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) + off += pad + npad++ + } + ctype += fmt.Sprintf("\t\t%s %s;\n", t.C, name) + fmt.Fprintf(gotype, "\t\t%s ", name) + noSourceConf.Fprint(gotype, fset, typ) + fmt.Fprintf(gotype, "\n") off += t.Size } + if fn.Recv != nil { + argField(fn.Recv.List[0].Type, "recv") + } fntype := fn.Type forFieldList(fntype.Params, func(i int, aname string, atype ast.Expr) { - t := p.cgoType(atype) - if off%t.Align != 0 { - pad := t.Align - off%t.Align - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) - off += pad - npad++ - } - ctype += fmt.Sprintf("\t\t%s p%d;\n", t.C, i) - off += t.Size + argField(atype, "p%d", i) }) - if off%p.PtrSize != 0 { - pad := p.PtrSize - off%p.PtrSize - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) - off += pad - npad++ - } forFieldList(fntype.Results, func(i int, aname string, atype ast.Expr) { - t := p.cgoType(atype) - if off%t.Align != 0 { - pad := t.Align - off%t.Align - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) - off += pad - npad++ - } - ctype += fmt.Sprintf("\t\t%s r%d;\n", t.C, i) - off += t.Size + argField(atype, "r%d", i) }) - if off%p.PtrSize != 0 { - pad := p.PtrSize - off%p.PtrSize - ctype += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad) - off += pad - npad++ - } if ctype == "struct {\n" { ctype += "\t\tchar unused;\n" // avoid empty struct } ctype += "\t}" + fmt.Fprintf(gotype, "\t}") // Get the return type of the wrapper function // compiled by gcc. @@ -966,7 +956,11 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { } // Build the wrapper function compiled by gcc. - s := fmt.Sprintf("%s %s(", gccResult, exp.ExpName) + gccExport := "" + if goos == "windows" { + gccExport = "__declspec(dllexport)" + } + s := fmt.Sprintf("%s %s %s(", gccExport, gccResult, exp.ExpName) if fn.Recv != nil { s += p.cgoType(fn.Recv.List[0].Type).C.String() s += " recv" @@ -988,12 +982,23 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { } fmt.Fprintf(fgcch, "extern %s;\n", s) - fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int, __SIZE_TYPE__);\n", cPrefix, exp.ExpName) + fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *);\n", cPrefix, exp.ExpName) fmt.Fprintf(fgcc, "\nCGO_NO_SANITIZE_THREAD") fmt.Fprintf(fgcc, "\n%s\n", s) fmt.Fprintf(fgcc, "{\n") fmt.Fprintf(fgcc, "\t__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();\n") - fmt.Fprintf(fgcc, "\t%s %v _cgo_a;\n", ctype, p.packedAttribute()) + // The results part of the argument structure must be + // initialized to 0 so the write barriers generated by + // the assignments to these fields in Go are safe. + // + // We use a local static variable to get the zeroed + // value of the argument type. This avoids including + // string.h for memset, and is also robust to C++ + // types with constructors. Both GCC and LLVM optimize + // this into just zeroing _cgo_a. + fmt.Fprintf(fgcc, "\ttypedef %s %v _cgo_argtype;\n", ctype, p.packedAttribute()) + fmt.Fprintf(fgcc, "\tstatic _cgo_argtype _cgo_zero;\n") + fmt.Fprintf(fgcc, "\t_cgo_argtype _cgo_a = _cgo_zero;\n") if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) { fmt.Fprintf(fgcc, "\t%s r;\n", gccResult) } @@ -1022,82 +1027,28 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { fmt.Fprintf(fgcc, "}\n") // Build the wrapper function compiled by cmd/compile. - goname := "_cgoexpwrap" + cPrefix + "_" - if fn.Recv != nil { - goname += fn.Recv.List[0].Names[0].Name + "_" - } - goname += exp.Func.Name.Name + // This unpacks the argument struct above and calls the Go function. fmt.Fprintf(fgo2, "//go:cgo_export_dynamic %s\n", exp.ExpName) fmt.Fprintf(fgo2, "//go:linkname _cgoexp%s_%s _cgoexp%s_%s\n", cPrefix, exp.ExpName, cPrefix, exp.ExpName) fmt.Fprintf(fgo2, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName) - fmt.Fprintf(fgo2, "//go:nosplit\n") // no split stack, so no use of m or g - fmt.Fprintf(fgo2, "//go:norace\n") // must not have race detector calls inserted - fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a unsafe.Pointer, n int32, ctxt uintptr) {\n", cPrefix, exp.ExpName) - fmt.Fprintf(fgo2, "\tfn := %s\n", goname) - // The indirect here is converting from a Go function pointer to a C function pointer. - fmt.Fprintf(fgo2, "\t_cgo_runtime_cgocallback(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), a, uintptr(n), ctxt);\n") - fmt.Fprintf(fgo2, "}\n") + fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a *%s) {\n", cPrefix, exp.ExpName, gotype) fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName) - // This code uses printer.Fprint, not conf.Fprint, - // because we don't want //line comments in the middle - // of the function types. - fmt.Fprintf(fgo2, "\n") - fmt.Fprintf(fgo2, "func %s(", goname) - comma := false - if fn.Recv != nil { - fmt.Fprintf(fgo2, "recv ") - printer.Fprint(fgo2, fset, fn.Recv.List[0].Type) - comma = true - } - forFieldList(fntype.Params, - func(i int, aname string, atype ast.Expr) { - if comma { - fmt.Fprintf(fgo2, ", ") - } - fmt.Fprintf(fgo2, "p%d ", i) - printer.Fprint(fgo2, fset, atype) - comma = true - }) - fmt.Fprintf(fgo2, ")") if gccResult != "void" { - fmt.Fprint(fgo2, " (") + // Write results back to frame. + fmt.Fprintf(fgo2, "\t") forFieldList(fntype.Results, func(i int, aname string, atype ast.Expr) { if i > 0 { - fmt.Fprint(fgo2, ", ") - } - fmt.Fprintf(fgo2, "r%d ", i) - printer.Fprint(fgo2, fset, atype) - }) - fmt.Fprint(fgo2, ")") - } - fmt.Fprint(fgo2, " {\n") - if gccResult == "void" { - fmt.Fprint(fgo2, "\t") - } else { - // Verify that any results don't contain any - // Go pointers. - addedDefer := false - forFieldList(fntype.Results, - func(i int, aname string, atype ast.Expr) { - if !p.hasPointer(nil, atype, false) { - return + fmt.Fprintf(fgo2, ", ") } - if !addedDefer { - fmt.Fprint(fgo2, "\tdefer func() {\n") - addedDefer = true - } - fmt.Fprintf(fgo2, "\t\t_cgoCheckResult(r%d)\n", i) + fmt.Fprintf(fgo2, "a.r%d", i) }) - if addedDefer { - fmt.Fprint(fgo2, "\t}()\n") - } - fmt.Fprint(fgo2, "\treturn ") + fmt.Fprintf(fgo2, " = ") } if fn.Recv != nil { - fmt.Fprintf(fgo2, "recv.") + fmt.Fprintf(fgo2, "a.recv.") } fmt.Fprintf(fgo2, "%s(", exp.Func.Name) forFieldList(fntype.Params, @@ -1105,9 +1056,20 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { if i > 0 { fmt.Fprint(fgo2, ", ") } - fmt.Fprintf(fgo2, "p%d", i) + fmt.Fprintf(fgo2, "a.p%d", i) }) fmt.Fprint(fgo2, ")\n") + if gccResult != "void" { + // Verify that any results don't contain any + // Go pointers. + forFieldList(fntype.Results, + func(i int, aname string, atype ast.Expr) { + if !p.hasPointer(nil, atype, false) { + return + } + fmt.Fprintf(fgo2, "\t_cgoCheckResult(a.r%d)\n", i) + }) + } fmt.Fprint(fgo2, "}\n") } @@ -1604,9 +1566,6 @@ const goProlog = ` //go:linkname _cgo_runtime_cgocall runtime.cgocall func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32 -//go:linkname _cgo_runtime_cgocallback runtime.cgocallback -func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr, uintptr) - //go:linkname _cgoCheckPointer runtime.cgoCheckPointer func _cgoCheckPointer(interface{}, interface{}) diff --git a/libgo/go/cmd/go.mod b/libgo/go/cmd/go.mod new file mode 100644 index 00000000000..031b8d4ab75 --- /dev/null +++ b/libgo/go/cmd/go.mod @@ -0,0 +1,12 @@ +module cmd + +go 1.16 + +require ( + github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2 + golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff + golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 + golang.org/x/mod v0.4.0 + golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect + golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11 +) diff --git a/libgo/go/cmd/go/alldocs.go b/libgo/go/cmd/go/alldocs.go index 68bad3cff1b..c4913ce6954 100644 --- a/libgo/go/cmd/go/alldocs.go +++ b/libgo/go/cmd/go/alldocs.go @@ -49,10 +49,11 @@ // modules modules, module versions, and more // module-get module-aware go get // module-auth module authentication using go.sum -// module-private module configuration for non-public modules // packages package lists and patterns +// private configuration for downloading non-public code // testflag testing flags // testfunc testing functions +// vcs controlling version control with GOVCS // // Use "go help " for more information about that topic. // @@ -71,7 +72,7 @@ // // Usage: // -// go build [-o output] [-i] [build flags] [packages] +// go build [-o output] [build flags] [packages] // // Build compiles the packages named by the import paths, // along with their dependencies, but it does not install the results. @@ -93,10 +94,12 @@ // // The -o flag forces build to write the resulting executable or object // to the named output file or directory, instead of the default behavior described -// in the last two paragraphs. If the named output is a directory that exists, -// then any resulting executables will be written to that directory. +// in the last two paragraphs. If the named output is an existing directory or +// ends with a slash or backslash, then any resulting executables +// will be written to that directory. // // The -i flag installs the packages that are dependencies of the target. +// The -i flag is deprecated. Compiled packages are cached automatically. // // The build flags are shared by the build, clean, get, install, list, run, // and test commands: @@ -161,6 +164,17 @@ // 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". +// -overlay file +// read a JSON config file that provides an overlay for build operations. +// The file is a JSON struct with a single field, named 'Replace', that +// maps each disk file path (a string) to its backing file path, so that +// a build will run as if the disk file path exists with the contents +// given by the backing file paths, or as if the disk file path does not +// exist if its backing file path is empty. Support for the -overlay flag +// has some limitations:importantly, cgo files included from outside the +// include path must be in the same directory as the Go package they are +// included from, and overlays will not appear when binaries and tests are +// run through go run and go test respectively. // -pkgdir dir // install and load all packages from dir instead of the usual locations. // For example, when building with a non-standard configuration, @@ -616,15 +630,15 @@ // dependency should be removed entirely, downgrading or removing modules // depending on it as needed. // -// The version suffix @latest explicitly requests the latest minor release of the -// module named by the given path. The suffix @upgrade is like @latest but +// The version suffix @latest explicitly requests the latest minor release of +// the module named by the given path. The suffix @upgrade is like @latest but // will not downgrade a module if it is already required at a revision or // pre-release version newer than the latest released version. The suffix // @patch requests the latest patch release: the latest released version // with the same major and minor version numbers as the currently required // version. Like @upgrade, @patch will not downgrade a module already required -// at a newer version. If the path is not already required, @upgrade and @patch -// are equivalent to @latest. +// at a newer version. If the path is not already required, @upgrade is +// equivalent to @latest, and @patch is disallowed. // // Although get defaults to using the latest version of the module containing // a named package, it does not use the latest version of that module's @@ -661,14 +675,27 @@ // this automatically as well. // // The -insecure flag permits fetching from repositories and resolving -// custom domains using insecure schemes such as HTTP. Use with caution. The -// GOINSECURE environment variable is usually a better alternative, since it -// provides control over which modules may be retrieved using an insecure scheme. -// See 'go help environment' for details. +// custom domains using insecure schemes such as HTTP, and also bypassess +// module sum validation using the checksum database. Use with caution. +// This flag is deprecated and will be removed in a future version of go. +// To permit the use of insecure schemes, use the GOINSECURE environment +// variable instead. To bypass module sum validation, use GOPRIVATE or +// GONOSUMDB. See 'go help environment' for details. // // The second step is to download (if needed), build, and install // the named packages. // +// The -d flag instructs get to skip this step, downloading source code +// needed to build the named packages and their dependencies, but not +// building or installing. +// +// Building and installing packages with get is deprecated. In a future release, +// the -d flag will be enabled by default, and 'go get' will be only be used to +// adjust dependencies of the current module. To install a package using +// dependencies from the current module, use 'go install'. To install a package +// ignoring the current module, use 'go install' with an @version suffix like +// "@latest" after each argument. +// // If an argument names a module but not a package (because there is no // Go source code in the module's root directory), then the install step // is skipped for that argument, instead of causing a build failure. @@ -680,10 +707,6 @@ // adds the latest golang.org/x/perf and then installs the commands in that // latest version. // -// The -d flag instructs get to download the source code needed to build -// the named packages, including downloading necessary dependencies, -// but not to build and install them. -// // With no package arguments, 'go get' applies to Go package in the // current directory, if any. In particular, 'go get -u' and // 'go get -u=patch' update all the dependencies of that package. @@ -706,7 +729,7 @@ // // Usage: // -// go install [-i] [build flags] [packages] +// go install [build flags] [packages] // // Install compiles and installs the packages named by the import paths. // @@ -715,11 +738,39 @@ // environment variable is not set. Executables in $GOROOT // are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN. // +// If the arguments have version suffixes (like @latest or @v1.0.0), "go install" +// builds packages in module-aware mode, ignoring the go.mod file in the current +// directory or any parent directory, if there is one. This is useful for +// installing executables without affecting the dependencies of the main module. +// To eliminate ambiguity about which module versions are used in the build, the +// arguments must satisfy the following constraints: +// +// - Arguments must be package paths or package patterns (with "..." wildcards). +// They must not be standard packages (like fmt), meta-patterns (std, cmd, +// all), or relative or absolute file paths. +// - All arguments must have the same version suffix. Different queries are not +// allowed, even if they refer to the same version. +// - All arguments must refer to packages in the same module at the same version. +// - No module is considered the "main" module. If the module containing +// packages named on the command line has a go.mod file, it must not contain +// directives (replace and exclude) that would cause it to be interpreted +// differently than if it were the main module. The module must not require +// a higher version of itself. +// - Package path arguments must refer to main packages. Pattern arguments +// will only match main packages. +// +// If the arguments don't have version suffixes, "go install" may run in +// module-aware mode or GOPATH mode, depending on the GO111MODULE environment +// variable and the presence of a go.mod file. See 'go help modules' for details. +// If module-aware mode is enabled, "go install" runs in the context of the main +// module. +// // When module-aware mode is disabled, other packages are installed in the // directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled, // other packages are built and cached but not installed. // // The -i flag installs the dependencies of the named packages as well. +// The -i flag is deprecated. Compiled packages are cached automatically. // // For more about the build flags, see 'go help build'. // For more about specifying packages, see 'go help packages'. @@ -766,26 +817,28 @@ // BinaryOnly bool // binary-only package (no longer supported) // ForTest string // package is only for use in named test // Export string // file containing export data (when using -export) +// BuildID string // build ID of the compiled package (when using -export) // Module *Module // info about package's containing module, if any (can be nil) // Match []string // command-line patterns matching this package // DepOnly bool // package is only a dependency, not explicitly listed // // // Source files -// GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) -// CgoFiles []string // .go source files that import "C" -// CompiledGoFiles []string // .go files presented to compiler (when using -compiled) -// IgnoredGoFiles []string // .go source files ignored due to build constraints -// CFiles []string // .c source files -// CXXFiles []string // .cc, .cxx and .cpp source files -// MFiles []string // .m source files -// HFiles []string // .h, .hh, .hpp and .hxx source files -// FFiles []string // .f, .F, .for and .f90 Fortran source files -// SFiles []string // .s source files -// SwigFiles []string // .swig files -// SwigCXXFiles []string // .swigcxx files -// SysoFiles []string // .syso object files to add to archive -// TestGoFiles []string // _test.go files in package -// XTestGoFiles []string // _test.go files outside package +// GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) +// CgoFiles []string // .go source files that import "C" +// CompiledGoFiles []string // .go files presented to compiler (when using -compiled) +// IgnoredGoFiles []string // .go source files ignored due to build constraints +// IgnoredOtherFiles []string // non-.go source files ignored due to build constraints +// CFiles []string // .c source files +// CXXFiles []string // .cc, .cxx and .cpp source files +// MFiles []string // .m source files +// HFiles []string // .h, .hh, .hpp and .hxx source files +// FFiles []string // .f, .F, .for and .f90 Fortran source files +// SFiles []string // .s source files +// SwigFiles []string // .swig files +// SwigCXXFiles []string // .swigcxx files +// SysoFiles []string // .syso object files to add to archive +// TestGoFiles []string // _test.go files in package +// XTestGoFiles []string // _test.go files outside package // // // Cgo directives // CgoCFLAGS []string // cgo: flags for C compiler @@ -916,6 +969,7 @@ // Dir string // directory holding files for this module, if any // GoMod string // path to go.mod file used when loading this module, if any // GoVersion string // go version used in module +// Retracted string // retraction information, if any (with -retracted or -u) // Error *ModuleError // error loading module // } // @@ -947,14 +1001,16 @@ // The -u flag adds information about available upgrades. // When the latest version of a given module is newer than // the current one, list -u sets the Module's Update field -// to information about the newer module. +// to information about the newer module. list -u will also set +// the module's Retracted field if the current version is retracted. // The Module's String method indicates an available upgrade by // formatting the newer version in brackets after the current version. +// If a version is retracted, the string "(retracted)" will follow it. // For example, 'go list -m -u all' might print: // // my/main/module // golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text -// rsc.io/pdf v0.1.1 [v0.1.2] +// rsc.io/pdf v0.1.1 (retracted) [v0.1.2] // // (For tools, 'go list -m -u -json all' may be more convenient to parse.) // @@ -964,6 +1020,14 @@ // the default output format to display the module path followed by the // space-separated version list. // +// The -retracted flag causes list to report information about retracted +// module versions. When -retracted is used with -f or -json, the Retracted +// field will be set to a string explaining why the version was retracted. +// The string is taken from comments on the retract directive in the +// module's go.mod file. When -retracted is used with -versions, retracted +// versions are listed together with unretracted versions. The -retracted +// flag may be used with or without -m. +// // The arguments to list -m are interpreted as a list of modules, not packages. // The main module is the module containing the current directory. // The active modules are the main module and its dependencies. @@ -1100,9 +1164,14 @@ // module path and version pair. If the @v is omitted, a replacement without // a version on the left side is dropped. // +// The -retract=version and -dropretract=version flags add and drop a +// retraction on the given version. The version may be a single version +// like "v1.2.3" or a closed interval like "[v1.1.0,v1.1.9]". Note that +// -retract=version is a no-op if that retraction already exists. +// // The -require, -droprequire, -exclude, -dropexclude, -replace, -// and -dropreplace editing flags may be repeated, and the changes -// are applied in the order given. +// -dropreplace, -retract, and -dropretract editing flags may be repeated, +// and the changes are applied in the order given. // // The -go=version flag sets the expected Go language version. // @@ -1136,6 +1205,15 @@ // New Module // } // +// type Retract struct { +// Low string +// High string +// Rationale string +// } +// +// Retract entries representing a single version (not an interval) will have +// the "Low" and "High" fields set to the same value. +// // Note that this only describes the go.mod file itself, not other modules // referred to indirectly. For the full set of modules available to a build, // use 'go list -m -json all'. @@ -1163,19 +1241,24 @@ // // go mod init [module] // -// Init initializes and writes a new go.mod to the current directory, -// in effect creating a new module rooted at the current directory. -// The file go.mod must not already exist. -// If possible, init will guess the module path from import comments -// (see 'go help importpath') or from version control configuration. -// To override this guess, supply the module path as an argument. +// Init initializes and writes a new go.mod file in the current directory, in +// effect creating a new module rooted at the current directory. The go.mod file +// must not already exist. +// +// Init accepts one optional argument, the module path for the new module. If the +// module path argument is omitted, init will attempt to infer the module path +// using import comments in .go files, vendoring tool configuration files (like +// Gopkg.lock), and the current directory (if in GOPATH). +// +// If a configuration file for a vendoring tool is present, init will attempt to +// import module requirements from it. // // // Add missing and remove unused modules // // Usage: // -// go mod tidy [-v] +// go mod tidy [-e] [-v] // // Tidy makes sure go.mod matches the source code in the module. // It adds any missing modules necessary to build the current module's @@ -1186,12 +1269,15 @@ // The -v flag causes tidy to print information about removed modules // to standard error. // +// The -e flag causes tidy to attempt to proceed despite errors +// encountered while loading packages. +// // // Make vendored copy of dependencies // // Usage: // -// go mod vendor [-v] +// go mod vendor [-e] [-v] // // Vendor resets the main module's vendor directory to include all packages // needed to build and test all the main module's packages. @@ -1200,6 +1286,9 @@ // The -v flag causes vendor to print the names of vendored // modules and packages to standard error. // +// The -e flag causes vendor to attempt to proceed despite errors +// encountered while loading packages. +// // // Verify dependencies have expected content // @@ -1388,6 +1477,7 @@ // -i // Install packages that are dependencies of the test. // Do not run the test. +// The -i flag is deprecated. Compiled packages are cached automatically. // // -json // Convert test output to JSON suitable for automated processing. @@ -1546,6 +1636,9 @@ // Using GOOS=illumos matches build tags and files as for GOOS=solaris // in addition to illumos tags and files. // +// Using GOOS=ios matches build tags and files as for GOOS=darwin +// in addition to ios tags and files. +// // To keep a file from being considered for the build: // // // +build ignore @@ -1733,7 +1826,7 @@ // Comma-separated list of glob patterns (in the syntax of Go's path.Match) // of module path prefixes that should always be fetched directly // or that should not be compared against the checksum database. -// See 'go help module-private'. +// See 'go help private'. // GOROOT // The root of the go tree. // GOSUMDB @@ -1789,8 +1882,8 @@ // For GOARCH=arm, the ARM architecture for which to compile. // Valid values are 5, 6, 7. // GO386 -// For GOARCH=386, the floating point instruction set. -// Valid values are 387, sse2. +// For GOARCH=386, how to implement floating point instructions. +// Valid values are sse2 (default), softfloat. // GOMIPS // For GOARCH=mips{,le}, whether to use floating point instructions. // Valid values are hardfloat (default), softfloat. @@ -1839,6 +1932,8 @@ // 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. +// GOVERSION +// The version of the installed Go tree, as reported by runtime.Version. // // // File types @@ -1894,21 +1989,23 @@ // require new/thing/v2 v2.3.4 // exclude old/thing v1.2.3 // replace bad/thing v1.4.5 => good/thing v1.4.5 +// retract v1.5.6 // // The verbs are // module, to define the module path; // go, to set the expected language version; // require, to require a particular module at a given version or later; -// exclude, to exclude a particular module version from use; and -// replace, to replace a module version with a different module version. +// exclude, to exclude a particular module version from use; +// replace, to replace a module version with a different module version; and +// retract, to indicate a previously released version should not be used. // Exclude and replace apply only in the main module's go.mod and are ignored -// in dependencies. See https://research.swtch.com/vgo-mvs for details. +// in dependencies. See https://golang.org/ref/mod for details. // // The leading verb can be factored out of adjacent lines to create a block, // like in Go imports: // // require ( -// new/thing v2.3.4 +// new/thing/v2 v2.3.4 // old/thing v1.2.3 // ) // @@ -2146,6 +2243,10 @@ // // The -insecure flag permits fetching from repositories and resolving // custom domains using insecure schemes such as HTTP. Use with caution. +// This flag is deprecated and will be removed in a future version of go. +// The GOINSECURE environment variable should be used instead, since it +// provides control over which packages may be retrieved using an insecure +// scheme. See 'go help environment' for details. // // The -t flag instructs get to also download the packages required to build // the tests for the specified packages. @@ -2556,72 +2657,63 @@ // // Maintaining module requirements // -// The go.mod file is meant to be readable and editable by both -// programmers and tools. The go command itself automatically updates the go.mod file -// to maintain a standard formatting and the accuracy of require statements. -// -// Any go command that finds an unfamiliar import will look up the module -// containing that import and add the latest version of that module -// to go.mod automatically. In most cases, therefore, it suffices to -// add an import to source code and run 'go build', 'go test', or even 'go list': -// as part of analyzing the package, the go command will discover -// and resolve the import and update the go.mod file. -// -// Any go command can determine that a module requirement is -// missing and must be added, even when considering only a single -// package from the module. On the other hand, determining that a module requirement -// is no longer necessary and can be deleted requires a full view of -// all packages in the module, across all possible build configurations -// (architectures, operating systems, build tags, and so on). -// The 'go mod tidy' command builds that view and then -// adds any missing module requirements and removes unnecessary ones. +// The go.mod file is meant to be readable and editable by both programmers and +// tools. Most updates to dependencies can be performed using "go get" and +// "go mod tidy". Other module-aware build commands may be invoked using the +// -mod=mod flag to automatically add missing requirements and fix inconsistencies. +// +// The "go get" command updates go.mod to change the module versions used in a +// build. An upgrade of one module may imply upgrading others, and similarly a +// downgrade of one module may imply downgrading others. The "go get" command +// makes these implied changes as well. See "go help module-get". +// +// The "go mod" command provides other functionality for use in maintaining +// and understanding modules and go.mod files. See "go help mod", particularly +// "go help mod tidy" and "go help mod edit". // // As part of maintaining the require statements in go.mod, the go command // tracks which ones provide packages imported directly by the current module // and which ones provide packages only used indirectly by other module // dependencies. Requirements needed only for indirect uses are marked with a -// "// indirect" comment in the go.mod file. Indirect requirements are +// "// indirect" comment in the go.mod file. Indirect requirements may be // automatically removed from the go.mod file once they are implied by other // direct requirements. Indirect requirements only arise when using modules // that fail to state some of their own dependencies or when explicitly // upgrading a module's dependencies ahead of its own stated requirements. // -// Because of this automatic maintenance, the information in go.mod is an -// up-to-date, readable description of the build. -// -// The 'go get' command updates go.mod to change the module versions used in a -// build. An upgrade of one module may imply upgrading others, and similarly a -// downgrade of one module may imply downgrading others. The 'go get' command -// makes these implied changes as well. If go.mod is edited directly, commands -// like 'go build' or 'go list' will assume that an upgrade is intended and -// automatically make any implied upgrades and update go.mod to reflect them. -// -// The 'go mod' command provides other functionality for use in maintaining -// and understanding modules and go.mod files. See 'go help mod'. -// -// The -mod build flag provides additional control over updating and use of go.mod. -// -// If invoked with -mod=readonly, the go command is disallowed from the implicit -// automatic updating of go.mod described above. Instead, it fails when any changes -// to go.mod are needed. This setting is most useful to check that go.mod does -// not need updates, such as in a continuous integration and testing system. -// The "go get" command remains permitted to update go.mod even with -mod=readonly, -// and the "go mod" commands do not take the -mod flag (or any other build flags). +// The -mod build flag provides additional control over the updating and use of +// go.mod for commands that build packages like "go build" and "go test". +// +// If invoked with -mod=readonly (the default in most situations), the go command +// reports an error if a package named on the command line or an imported package +// is not provided by any module in the build list computed from the main module's +// requirements. The go command also reports an error if a module's checksum is +// missing from go.sum (see Module downloading and verification). Either go.mod or +// go.sum must be updated in these situations. +// +// If invoked with -mod=mod, the go command automatically updates go.mod and +// go.sum, fixing inconsistencies and adding missing requirements and checksums +// as needed. If the go command finds an unfamiliar import, it looks up the +// module containing that import and adds a requirement for the latest version +// of that module to go.mod. In most cases, therefore, one may add an import to +// source code and run "go build", "go test", or even "go list" with -mod=mod: +// as part of analyzing the package, the go command will resolve the import and +// update the go.mod file. // // If invoked with -mod=vendor, the go command loads packages from the main // module's vendor directory instead of downloading modules to and loading packages // from the module cache. The go command assumes the vendor directory holds // correct copies of dependencies, and it does not compute the set of required // module versions from go.mod files. However, the go command does check that -// vendor/modules.txt (generated by 'go mod vendor') contains metadata consistent +// vendor/modules.txt (generated by "go mod vendor") contains metadata consistent // with go.mod. // -// If invoked with -mod=mod, the go command loads modules from the module cache -// even if there is a vendor directory present. +// If the go command is not invoked with a -mod flag, and the vendor directory +// is present, and the "go" version in go.mod is 1.14 or higher, the go command +// will act as if it were invoked with -mod=vendor. Otherwise, the -mod flag +// defaults to -mod=readonly. // -// If the go command is not invoked with a -mod flag and the vendor directory -// is present and the "go" version in go.mod is 1.14 or higher, the go command -// will act as if it were invoked with -mod=vendor. +// Note that neither "go get" nor the "go mod" subcommands accept the -mod flag. // // Pseudo-versions // @@ -2806,7 +2898,7 @@ // followed by a pipe character, indicating it is safe to fall back on any error. // // The GOPRIVATE and GONOPROXY environment variables allow bypassing -// the proxy for selected modules. See 'go help module-private' for details. +// the proxy for selected modules. See 'go help private' for details. // // No matter the source of the modules, the go command checks downloads against // known checksums, to detect unexpected changes in the content of any specific @@ -2926,52 +3018,7 @@ // accepted, at the cost of giving up the security guarantee of verified repeatable // downloads for all modules. A better way to bypass the checksum database // for specific modules is to use the GOPRIVATE or GONOSUMDB environment -// variables. See 'go help module-private' for details. -// -// The 'go env -w' command (see 'go help env') can be used to set these variables -// for future go command invocations. -// -// -// Module configuration for non-public modules -// -// The go command defaults to downloading modules from the public Go module -// mirror at proxy.golang.org. It also defaults to validating downloaded modules, -// regardless of source, against the public Go checksum database at sum.golang.org. -// These defaults work well for publicly available source code. -// -// The GOPRIVATE environment variable controls which modules the go command -// considers to be private (not available publicly) and should therefore not use the -// proxy or checksum database. The variable is a comma-separated list of -// glob patterns (in the syntax of Go's path.Match) of module path prefixes. -// For example, -// -// GOPRIVATE=*.corp.example.com,rsc.io/private -// -// causes the go command to treat as private any module with a path prefix -// matching either pattern, including git.corp.example.com/xyzzy, rsc.io/private, -// and rsc.io/private/quux. -// -// The GOPRIVATE environment variable may be used by other tools as well to -// identify non-public modules. For example, an editor could use GOPRIVATE -// to decide whether to hyperlink a package import to a godoc.org page. -// -// For fine-grained control over module download and validation, the GONOPROXY -// and GONOSUMDB environment variables accept the same kind of glob list -// and override GOPRIVATE for the specific decision of whether to use the proxy -// and checksum database, respectively. -// -// For example, if a company ran a module proxy serving private modules, -// users would configure go using: -// -// GOPRIVATE=*.corp.example.com -// GOPROXY=proxy.example.com -// GONOPROXY=none -// -// This would tell the go command and other tools that modules beginning with -// a corp.example.com subdomain are private but that the company proxy should -// be used for downloading both public and private modules, because -// GONOPROXY has been set to a pattern that won't match any modules, -// overriding GOPRIVATE. +// variables. See 'go help private' for details. // // The 'go env -w' command (see 'go help env') can be used to set these variables // for future go command invocations. @@ -3061,6 +3108,56 @@ // by the go tool, as are directories named "testdata". // // +// Configuration for downloading non-public code +// +// The go command defaults to downloading modules from the public Go module +// mirror at proxy.golang.org. It also defaults to validating downloaded modules, +// regardless of source, against the public Go checksum database at sum.golang.org. +// These defaults work well for publicly available source code. +// +// The GOPRIVATE environment variable controls which modules the go command +// considers to be private (not available publicly) and should therefore not use the +// proxy or checksum database. The variable is a comma-separated list of +// glob patterns (in the syntax of Go's path.Match) of module path prefixes. +// For example, +// +// GOPRIVATE=*.corp.example.com,rsc.io/private +// +// causes the go command to treat as private any module with a path prefix +// matching either pattern, including git.corp.example.com/xyzzy, rsc.io/private, +// and rsc.io/private/quux. +// +// The GOPRIVATE environment variable may be used by other tools as well to +// identify non-public modules. For example, an editor could use GOPRIVATE +// to decide whether to hyperlink a package import to a godoc.org page. +// +// For fine-grained control over module download and validation, the GONOPROXY +// and GONOSUMDB environment variables accept the same kind of glob list +// and override GOPRIVATE for the specific decision of whether to use the proxy +// and checksum database, respectively. +// +// For example, if a company ran a module proxy serving private modules, +// users would configure go using: +// +// GOPRIVATE=*.corp.example.com +// GOPROXY=proxy.example.com +// GONOPROXY=none +// +// This would tell the go command and other tools that modules beginning with +// a corp.example.com subdomain are private but that the company proxy should +// be used for downloading both public and private modules, because +// GONOPROXY has been set to a pattern that won't match any modules, +// overriding GOPRIVATE. +// +// The GOPRIVATE variable is also used to define the "public" and "private" +// patterns for the GOVCS variable; see 'go help vcs'. For that usage, +// GOPRIVATE applies even in GOPATH mode. In that case, it matches import paths +// instead of module paths. +// +// The 'go env -w' command (see 'go help env') can be used to set these variables +// for future go command invocations. +// +// // Testing flags // // The 'go test' command takes both flags that apply to 'go test' itself @@ -3353,4 +3450,77 @@ // See the documentation of the testing package for more information. // // +// Controlling version control with GOVCS +// +// The 'go get' command can run version control commands like git +// to download imported code. This functionality is critical to the decentralized +// Go package ecosystem, in which code can be imported from any server, +// but it is also a potential security problem, if a malicious server finds a +// way to cause the invoked version control command to run unintended code. +// +// To balance the functionality and security concerns, the 'go get' command +// by default will only use git and hg to download code from public servers. +// But it will use any known version control system (bzr, fossil, git, hg, svn) +// to download code from private servers, defined as those hosting packages +// matching the GOPRIVATE variable (see 'go help private'). The rationale behind +// allowing only Git and Mercurial is that these two systems have had the most +// attention to issues of being run as clients of untrusted servers. In contrast, +// Bazaar, Fossil, and Subversion have primarily been used in trusted, +// authenticated environments and are not as well scrutinized as attack surfaces. +// +// The version control command restrictions only apply when using direct version +// control access to download code. When downloading modules from a proxy, +// 'go get' uses the proxy protocol instead, which is always permitted. +// By default, the 'go get' command uses the Go module mirror (proxy.golang.org) +// for public packages and only falls back to version control for private +// packages or when the mirror refuses to serve a public package (typically for +// legal reasons). Therefore, clients can still access public code served from +// Bazaar, Fossil, or Subversion repositories by default, because those downloads +// use the Go module mirror, which takes on the security risk of running the +// version control commands, using a custom sandbox. +// +// The GOVCS variable can be used to change the allowed version control systems +// for specific packages (identified by a module or import path). +// The GOVCS variable applies both when using modules and when using GOPATH. +// When using modules, the patterns match against the module path. +// When using GOPATH, the patterns match against the import path +// corresponding to the root of the version control repository. +// +// The general form of the GOVCS setting is a comma-separated list of +// pattern:vcslist rules. The pattern is a glob pattern that must match +// one or more leading elements of the module or import path. The vcslist +// is a pipe-separated list of allowed version control commands, or "all" +// to allow use of any known command, or "off" to allow nothing. +// The earliest matching pattern in the list applies, even if later patterns +// might also match. +// +// For example, consider: +// +// GOVCS=github.com:git,evil.com:off,*:git|hg +// +// With this setting, code with an module or import path beginning with +// github.com/ can only use git; paths on evil.com cannot use any version +// control command, and all other paths (* matches everything) can use +// only git or hg. +// +// The special patterns "public" and "private" match public and private +// module or import paths. A path is private if it matches the GOPRIVATE +// variable; otherwise it is public. +// +// If no rules in the GOVCS variable match a particular module or import path, +// the 'go get' command applies its default rule, which can now be summarized +// in GOVCS notation as 'public:git|hg,private:all'. +// +// To allow unfettered use of any version control system for any package, use: +// +// GOVCS=*:all +// +// To disable all use of version control, use: +// +// GOVCS=*:off +// +// The 'go env -w' command (see 'go help env') can be used to set the GOVCS +// variable for future go command invocations. +// +// package main diff --git a/libgo/go/cmd/go/go_test.go b/libgo/go/cmd/go/go_test.go index 021930a8a81..c472620db29 100644 --- a/libgo/go/cmd/go/go_test.go +++ b/libgo/go/cmd/go/go_test.go @@ -9,13 +9,14 @@ import ( "debug/elf" "debug/macho" "debug/pe" + "encoding/binary" "flag" "fmt" "go/format" "internal/race" "internal/testenv" "io" - "io/ioutil" + "io/fs" "log" "os" "os/exec" @@ -30,77 +31,42 @@ import ( "cmd/go/internal/cache" "cmd/go/internal/cfg" "cmd/go/internal/robustio" + "cmd/go/internal/work" "cmd/internal/sys" ) +func init() { + // GOVCS defaults to public:git|hg,private:all, + // which breaks many tests here - they can't use non-git, non-hg VCS at all! + // Change to fully permissive. + // The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt. + os.Setenv("GOVCS", "*:all") +} + var ( - canRun = true // whether we can run go or ./testgo canRace = false // whether we can run the race detector canCgo = false // whether we can use cgo canMSan = false // whether we can run the memory sanitizer - - exeSuffix string // ".exe" on Windows - - skipExternal = false // skip external tests ) +var exeSuffix string = func() string { + if runtime.GOOS == "windows" { + return ".exe" + } + return "" +}() + func tooSlow(t *testing.T) { if testing.Short() { // In -short mode; skip test, except run it on the {darwin,linux,windows}/amd64 builders. if testenv.Builder() != "" && runtime.GOARCH == "amd64" && (runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") { return } + t.Helper() t.Skip("skipping test in -short mode") } } -func init() { - switch runtime.GOOS { - case "android", "js": - canRun = false - case "darwin": - switch runtime.GOARCH { - case "arm64": - canRun = false - } - case "linux": - switch runtime.GOARCH { - case "arm": - // many linux/arm machines are too slow to run - // the full set of external tests. - skipExternal = true - case "mips", "mipsle", "mips64", "mips64le": - // Also slow. - skipExternal = true - if testenv.Builder() != "" { - // On the builders, skip the cmd/go - // tests. They're too slow and already - // covered by other ports. There's - // nothing os/arch specific in the - // tests. - canRun = false - } - } - case "freebsd": - switch runtime.GOARCH { - case "arm": - // many freebsd/arm machines are too slow to run - // the full set of external tests. - skipExternal = true - canRun = false - } - case "plan9": - switch runtime.GOARCH { - case "arm": - // many plan9/arm machines are too slow to run - // the full set of external tests. - skipExternal = true - } - case "windows": - exeSuffix = ".exe" - } -} - // testGOROOT is the GOROOT to use when running testgo, a cmd/go binary // build from this process's current GOROOT, but run from a different // (temp) directory. @@ -134,7 +100,7 @@ func TestMain(m *testing.M) { // Run with a temporary TMPDIR to check that the tests don't // leave anything behind. - topTmpdir, err := ioutil.TempDir("", "cmd-go-test-") + topTmpdir, err := os.MkdirTemp("", "cmd-go-test-") if err != nil { log.Fatal(err) } @@ -143,7 +109,7 @@ func TestMain(m *testing.M) { } os.Setenv(tempEnvName(), topTmpdir) - dir, err := ioutil.TempDir(topTmpdir, "tmpdir") + dir, err := os.MkdirTemp(topTmpdir, "tmpdir") if err != nil { log.Fatal(err) } @@ -153,7 +119,7 @@ func TestMain(m *testing.M) { } testGOCACHE = cache.DefaultDir() - if canRun { + if testenv.HasGoBuild() { testBin = filepath.Join(testTmpDir, "testbin") if err := os.Mkdir(testBin, 0777); err != nil { log.Fatal(err) @@ -224,7 +190,7 @@ func TestMain(m *testing.M) { cmd.Stderr = new(strings.Builder) if out, err := cmd.Output(); err != nil { fmt.Fprintf(os.Stderr, "running testgo failed: %v\n%s", err, cmd.Stderr) - canRun = false + os.Exit(2) } else { canCgo, err = strconv.ParseBool(strings.TrimSpace(string(out))) if err != nil { @@ -324,10 +290,7 @@ func skipIfGccgo(t *testing.T, msg string) { func testgo(t *testing.T) *testgoData { t.Helper() testenv.MustHaveGoBuild(t) - - if skipExternal { - t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH) - } + testenv.SkipIfShortAndSlow(t) return &testgoData{t: t} } @@ -416,9 +379,6 @@ func (tg *testgoData) goTool() string { // returning exit status. func (tg *testgoData) doRun(args []string) error { tg.t.Helper() - if !canRun { - panic("testgoData.doRun called but canRun false") - } if tg.inParallel { for _, arg := range args { if strings.HasPrefix(arg, "testdata") || strings.HasPrefix(arg, "./testdata") { @@ -656,7 +616,7 @@ func (tg *testgoData) makeTempdir() { tg.t.Helper() if tg.tempdir == "" { var err error - tg.tempdir, err = ioutil.TempDir("", "gotest") + tg.tempdir, err = os.MkdirTemp("", "gotest") tg.must(err) } } @@ -673,7 +633,7 @@ func (tg *testgoData) tempFile(path, contents string) { bytes = formatted } } - tg.must(ioutil.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644)) + tg.must(os.WriteFile(filepath.Join(tg.tempdir, path), bytes, 0644)) } // tempDir adds a temporary directory for a run of testgo. @@ -814,7 +774,7 @@ func (tg *testgoData) cleanup() { func removeAll(dir string) error { // module cache has 0444 directories; // make them writable in order to remove content. - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { // chmod not only directories, but also things that we couldn't even stat // due to permission errors: they may also be unreadable directories. if err != nil || info.IsDir() { @@ -860,8 +820,8 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { } { srcdir := filepath.Join(testGOROOT, copydir) tg.tempDir(filepath.Join("goroot", copydir)) - err := filepath.Walk(srcdir, - func(path string, info os.FileInfo, err error) error { + err := filepath.WalkDir(srcdir, + func(path string, info fs.DirEntry, err error) error { if err != nil { return err } @@ -873,13 +833,13 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { return err } dest := filepath.Join("goroot", copydir, srcrel) - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return err } tg.tempFile(dest, string(data)) - if err := os.Chmod(tg.path(dest), info.Mode()|0200); err != nil { - return err + if strings.Contains(copydir, filepath.Join("pkg", "tool")) { + os.Chmod(tg.path(dest), 0777) } return nil }) @@ -890,18 +850,18 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) { tg.setenv("GOROOT", tg.path("goroot")) addVar := func(name string, idx int) (restore func()) { - data, err := ioutil.ReadFile(name) + data, err := os.ReadFile(name) if err != nil { t.Fatal(err) } old := data data = append(data, fmt.Sprintf("var DummyUnusedVar%d bool\n", idx)...) - if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil { + if err := os.WriteFile(name, append(data, '\n'), 0666); err != nil { t.Fatal(err) } tg.sleep() return func() { - if err := ioutil.WriteFile(name, old, 0666); err != nil { + if err := os.WriteFile(name, old, 0666); err != nil { t.Fatal(err) } } @@ -1237,6 +1197,18 @@ func TestGoListExport(t *testing.T) { if _, err := os.Stat(file); err != nil { t.Fatalf("cannot find .Export result %s: %v", file, err) } + + tg.run("list", "-export", "-f", "{{.BuildID}}", "strings") + buildID := strings.TrimSpace(tg.stdout.String()) + if buildID == "" { + t.Fatalf(".BuildID with -export was empty") + } + + tg.run("tool", "buildid", file) + toolBuildID := strings.TrimSpace(tg.stdout.String()) + if buildID != toolBuildID { + t.Fatalf(".BuildID with -export %q disagrees with 'go tool buildid' %q", buildID, toolBuildID) + } } // Issue 4096. Validate the output of unsuccessful go install foo/quxx. @@ -1394,6 +1366,30 @@ func TestLdflagsArgumentsWithSpacesIssue3941(t *testing.T) { tg.grepStderr("^hello world", `ldflags -X "main.extern=hello world"' failed`) } +func TestLdFlagsLongArgumentsIssue42295(t *testing.T) { + // Test the extremely long command line arguments that contain '\n' characters + // get encoded and passed correctly. + skipIfGccgo(t, "gccgo does not support -ldflags -X") + tooSlow(t) + tg := testgo(t) + defer tg.cleanup() + tg.parallel() + tg.tempFile("main.go", `package main + var extern string + func main() { + print(extern) + }`) + testStr := "test test test test test \n\\ " + var buf bytes.Buffer + for buf.Len() < work.ArgLengthForResponseFile+1 { + buf.WriteString(testStr) + } + tg.run("run", "-ldflags", fmt.Sprintf(`-X "main.extern=%s"`, buf.String()), tg.path("main.go")) + if tg.stderr.String() != buf.String() { + t.Errorf("strings differ") + } +} + func TestGoTestDashCDashOControlsBinaryLocation(t *testing.T) { skipIfGccgo(t, "gccgo has no standard packages") tooSlow(t) @@ -1914,6 +1910,18 @@ func TestGoEnv(t *testing.T) { tg.grepStdout("gcc", "CC not found") tg.run("env", "GOGCCFLAGS") tg.grepStdout("-ffaster", "CC arguments not found") + + tg.run("env", "GOVERSION") + envVersion := strings.TrimSpace(tg.stdout.String()) + + tg.run("version") + cmdVersion := strings.TrimSpace(tg.stdout.String()) + + // If 'go version' is "go version /", then + // 'go env GOVERSION' is just "". + if cmdVersion == envVersion || !strings.Contains(cmdVersion, envVersion) { + t.Fatalf("'go env GOVERSION' %q should be a shorter substring of 'go version' %q", envVersion, cmdVersion) + } } const ( @@ -2019,7 +2027,7 @@ func main() { tg.run("build", "-o", exe, "p") } -func copyFile(src, dst string, perm os.FileMode) error { +func copyFile(src, dst string, perm fs.FileMode) error { sf, err := os.Open(src) if err != nil { return err @@ -2058,7 +2066,7 @@ func TestBuildmodePIE(t *testing.T) { platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) switch platform { - case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", + case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x", "android/amd64", "android/arm", "android/arm64", "android/386", "freebsd/amd64", "windows/386", "windows/amd64", "windows/arm": @@ -2166,6 +2174,38 @@ func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) { if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 { t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set") } + if useCgo { + // Test that only one symbol is exported (#40795). + // PIE binaries don´t require .edata section but unfortunately + // binutils doesn´t generate a .reloc section unless there is + // at least one symbol exported. + // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011 + section := f.Section(".edata") + if section == nil { + t.Fatalf(".edata section is not present") + } + // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go + type IMAGE_EXPORT_DIRECTORY struct { + _ [2]uint32 + _ [2]uint16 + _ [2]uint32 + NumberOfFunctions uint32 + NumberOfNames uint32 + _ [3]uint32 + } + var e IMAGE_EXPORT_DIRECTORY + if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil { + t.Fatalf("binary.Read failed: %v", err) + } + + // Only _cgo_dummy_export should be exported + if e.NumberOfFunctions != 1 { + t.Fatalf("got %d exported functions; want 1", e.NumberOfFunctions) + } + if e.NumberOfNames != 1 { + t.Fatalf("got %d exported names; want 1", e.NumberOfNames) + } + } default: panic("unreachable") } @@ -2658,7 +2698,7 @@ echo $* >>`+tg.path("pkg-config.out")) tg.setenv("GOPATH", tg.path(".")) tg.setenv("PKG_CONFIG", tg.path("pkg-config.sh")) tg.run("build", "x") - out, err := ioutil.ReadFile(tg.path("pkg-config.out")) + out, err := os.ReadFile(tg.path("pkg-config.out")) tg.must(err) out = bytes.TrimSpace(out) want := "--cflags --static --static -- a a\n--libs --static --static -- a a" diff --git a/libgo/go/cmd/go/go_windows_test.go b/libgo/go/cmd/go/go_windows_test.go index 3999166ed98..3094212bae2 100644 --- a/libgo/go/cmd/go/go_windows_test.go +++ b/libgo/go/cmd/go/go_windows_test.go @@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package main +package main_test import ( - "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -17,16 +15,18 @@ import ( ) func TestAbsolutePath(t *testing.T) { - t.Parallel() + tg := testgo(t) + defer tg.cleanup() + tg.parallel() - tmp, err := ioutil.TempDir("", "TestAbsolutePath") + tmp, err := os.MkdirTemp("", "TestAbsolutePath") if err != nil { t.Fatal(err) } defer robustio.RemoveAll(tmp) file := filepath.Join(tmp, "a.go") - err = ioutil.WriteFile(file, []byte{}, 0644) + err = os.WriteFile(file, []byte{}, 0644) if err != nil { t.Fatal(err) } @@ -38,7 +38,7 @@ func TestAbsolutePath(t *testing.T) { noVolume := file[len(filepath.VolumeName(file)):] wrongPath := filepath.Join(dir, noVolume) - cmd := exec.Command(testenv.GoToolPath(t), "build", noVolume) + cmd := exec.Command(tg.goTool(), "build", noVolume) cmd.Dir = dir output, err := cmd.CombinedOutput() if err == nil { diff --git a/libgo/go/cmd/go/help_test.go b/libgo/go/cmd/go/help_test.go index 78d63ff05e9..abfc3db9936 100644 --- a/libgo/go/cmd/go/help_test.go +++ b/libgo/go/cmd/go/help_test.go @@ -6,7 +6,7 @@ package main_test import ( "bytes" - "io/ioutil" + "os" "testing" "cmd/go/internal/help" @@ -23,7 +23,7 @@ func TestDocsUpToDate(t *testing.T) { buf := new(bytes.Buffer) // Match the command in mkalldocs.sh that generates alldocs.go. help.Help(buf, []string{"documentation"}) - data, err := ioutil.ReadFile("alldocs.go") + data, err := os.ReadFile("alldocs.go") if err != nil { t.Fatalf("error reading alldocs.go: %v", err) } diff --git a/libgo/go/cmd/go/init_test.go b/libgo/go/cmd/go/init_test.go index ed90a778416..5a5cbe52936 100644 --- a/libgo/go/cmd/go/init_test.go +++ b/libgo/go/cmd/go/init_test.go @@ -7,6 +7,7 @@ package main_test import ( "internal/testenv" "os/exec" + "sync/atomic" "testing" ) @@ -15,20 +16,27 @@ import ( // the benchmark if any changes were done. func BenchmarkExecGoEnv(b *testing.B) { testenv.MustHaveExec(b) - b.StopTimer() gotool, err := testenv.GoTool() if err != nil { b.Fatal(err) } - for i := 0; i < b.N; i++ { - cmd := exec.Command(gotool, "env", "GOARCH") - b.StartTimer() - err := cmd.Run() - b.StopTimer() + // We collect extra metrics. + var n, userTime, systemTime int64 - if err != nil { - b.Fatal(err) + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + cmd := exec.Command(gotool, "env", "GOARCH") + + if err := cmd.Run(); err != nil { + b.Fatal(err) + } + atomic.AddInt64(&n, 1) + atomic.AddInt64(&userTime, int64(cmd.ProcessState.UserTime())) + atomic.AddInt64(&systemTime, int64(cmd.ProcessState.SystemTime())) } - } + }) + b.ReportMetric(float64(userTime)/float64(n), "user-ns/op") + b.ReportMetric(float64(systemTime)/float64(n), "sys-ns/op") } diff --git a/libgo/go/cmd/go/internal/auth/netrc.go b/libgo/go/cmd/go/internal/auth/netrc.go index 7a9bdbb72c8..0107f20d7a6 100644 --- a/libgo/go/cmd/go/internal/auth/netrc.go +++ b/libgo/go/cmd/go/internal/auth/netrc.go @@ -5,7 +5,6 @@ package auth import ( - "io/ioutil" "os" "path/filepath" "runtime" @@ -99,7 +98,7 @@ func readNetrc() { return } - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { if !os.IsNotExist(err) { netrcErr = err diff --git a/libgo/go/cmd/go/internal/base/base.go b/libgo/go/cmd/go/internal/base/base.go index ab2f1bb4e2c..004588c7320 100644 --- a/libgo/go/cmd/go/internal/base/base.go +++ b/libgo/go/cmd/go/internal/base/base.go @@ -7,6 +7,7 @@ package base import ( + "context" "flag" "fmt" "log" @@ -24,7 +25,7 @@ import ( type Command struct { // Run runs the command. // The args are the arguments after the command name. - Run func(cmd *Command, args []string) + Run func(ctx context.Context, cmd *Command, args []string) // UsageLine is the one-line usage message. // The words between "go" and the first flag or argument in the line are taken to be the command name. @@ -55,6 +56,20 @@ var Go = &Command{ // Commands initialized in package main } +// hasFlag reports whether a command or any of its subcommands contain the given +// flag. +func hasFlag(c *Command, name string) bool { + if f := c.Flag.Lookup(name); f != nil { + return true + } + for _, sub := range c.Commands { + if hasFlag(sub, name) { + return true + } + } + return false +} + // LongName returns the command's long name: all the words in the usage line between "go" and a flag or argument, func (c *Command) LongName() string { name := c.UsageLine diff --git a/libgo/go/cmd/go/internal/base/flag.go b/libgo/go/cmd/go/internal/base/flag.go index 6727196816b..677f8196827 100644 --- a/libgo/go/cmd/go/internal/base/flag.go +++ b/libgo/go/cmd/go/internal/base/flag.go @@ -8,6 +8,7 @@ import ( "flag" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/str" ) @@ -28,13 +29,43 @@ func (v *StringsFlag) String() string { return "" } +// explicitStringFlag is like a regular string flag, but it also tracks whether +// the string was set explicitly to a non-empty value. +type explicitStringFlag struct { + value *string + explicit *bool +} + +func (f explicitStringFlag) String() string { + if f.value == nil { + return "" + } + return *f.value +} + +func (f explicitStringFlag) Set(v string) error { + *f.value = v + if v != "" { + *f.explicit = true + } + return nil +} + // AddBuildFlagsNX adds the -n and -x build flags to the flag set. 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", "", "") +// AddModFlag adds the -mod build flag to the flag set. +func AddModFlag(flags *flag.FlagSet) { + flags.Var(explicitStringFlag{value: &cfg.BuildMod, explicit: &cfg.BuildModExplicit}, "mod", "") +} + +// AddModCommonFlags adds the module-related flags common to build commands +// and 'go mod' subcommands. +func AddModCommonFlags(flags *flag.FlagSet) { + flags.BoolVar(&cfg.ModCacheRW, "modcacherw", false, "") + flags.StringVar(&cfg.ModFile, "modfile", "", "") + flags.StringVar(&fsys.OverlayFile, "overlay", "", "") } diff --git a/libgo/go/cmd/go/internal/base/goflags.go b/libgo/go/cmd/go/internal/base/goflags.go index f29cc3cf9a5..267006be7a2 100644 --- a/libgo/go/cmd/go/internal/base/goflags.go +++ b/libgo/go/cmd/go/internal/base/goflags.go @@ -13,15 +13,7 @@ import ( "cmd/go/internal/cfg" ) -var ( - goflags []string // cached $GOFLAGS list; can be -x or --x form - knownFlag = make(map[string]bool) // flags allowed to appear in $GOFLAGS; no leading dashes -) - -// AddKnownFlag adds name to the list of known flags for use in $GOFLAGS. -func AddKnownFlag(name string) { - knownFlag[name] = true -} +var goflags []string // cached $GOFLAGS list; can be -x or --x form // GOFLAGS returns the flags from $GOFLAGS. // The list can be assumed to contain one string per flag, @@ -38,22 +30,12 @@ func InitGOFLAGS() { return } - // Build list of all flags for all commands. - // If no command has that flag, then we report the problem. - // This catches typos while still letting users record flags in GOFLAGS - // that only apply to a subset of go commands. - // Commands using CustomFlags can report their flag names - // by calling AddKnownFlag instead. - var walkFlags func(*Command) - walkFlags = func(cmd *Command) { - for _, sub := range cmd.Commands { - walkFlags(sub) - } - cmd.Flag.VisitAll(func(f *flag.Flag) { - knownFlag[f.Name] = true - }) + goflags = strings.Fields(cfg.Getenv("GOFLAGS")) + if len(goflags) == 0 { + // nothing to do; avoid work on later InitGOFLAGS call + goflags = []string{} + return } - walkFlags(Go) // Ignore bad flag in go env and go bug, because // they are what people reach for when debugging @@ -61,11 +43,6 @@ func InitGOFLAGS() { // (Both will show the GOFLAGS setting if let succeed.) hideErrors := cfg.CmdName == "env" || cfg.CmdName == "bug" - goflags = strings.Fields(cfg.Getenv("GOFLAGS")) - if goflags == nil { - goflags = []string{} // avoid work on later InitGOFLAGS call - } - // Each of the words returned by strings.Fields must be its own flag. // To set flag arguments use -x=value instead of -x value. // For boolean flags, -x is fine instead of -x=true. @@ -85,7 +62,7 @@ func InitGOFLAGS() { if i := strings.Index(name, "="); i >= 0 { name = name[:i] } - if !knownFlag[name] { + if !hasFlag(Go, name) { if hideErrors { continue } @@ -115,7 +92,11 @@ func SetFromGOFLAGS(flags *flag.FlagSet) { } for _, goflag := range goflags { name, value, hasValue := goflag, "", false - if i := strings.Index(goflag, "="); i >= 0 { + // Ignore invalid flags like '=' or '=value'. + // If it is not reported in InitGOFlags it means we don't want to report it. + if i := strings.Index(goflag, "="); i == 0 { + continue + } else if i > 0 { name, value, hasValue = goflag[:i], goflag[i+1:], true } if strings.HasPrefix(name, "--") { diff --git a/libgo/go/cmd/go/internal/base/signal.go b/libgo/go/cmd/go/internal/base/signal.go index 54d11876d07..05befcf7f0c 100644 --- a/libgo/go/cmd/go/internal/base/signal.go +++ b/libgo/go/cmd/go/internal/base/signal.go @@ -15,7 +15,7 @@ var Interrupted = make(chan struct{}) // processSignals setups signal handler. func processSignals() { - sig := make(chan os.Signal) + sig := make(chan os.Signal, 1) signal.Notify(sig, signalsToIgnore...) go func() { <-sig diff --git a/libgo/go/cmd/go/internal/bug/bug.go b/libgo/go/cmd/go/internal/bug/bug.go index fe71281ef05..1085feaaee8 100644 --- a/libgo/go/cmd/go/internal/bug/bug.go +++ b/libgo/go/cmd/go/internal/bug/bug.go @@ -7,9 +7,9 @@ package bug import ( "bytes" + "context" "fmt" "io" - "io/ioutil" urlpkg "net/url" "os" "os/exec" @@ -37,7 +37,7 @@ func init() { CmdBug.Flag.BoolVar(&cfg.BuildV, "v", false, "") } -func runBug(cmd *base.Command, args []string) { +func runBug(ctx context.Context, cmd *base.Command, args []string) { if len(args) > 0 { base.Fatalf("go bug: bug takes no arguments") } @@ -104,7 +104,7 @@ func printGoDetails(w io.Writer) { func printOSDetails(w io.Writer) { switch runtime.GOOS { - case "darwin": + case "darwin", "ios": printCmdOut(w, "uname -v: ", "uname", "-v") printCmdOut(w, "", "sw_vers") case "linux": @@ -116,7 +116,7 @@ func printOSDetails(w io.Writer) { case "illumos", "solaris": // Be sure to use the OS-supplied uname, in "/usr/bin": printCmdOut(w, "uname -srv: ", "/usr/bin/uname", "-srv") - out, err := ioutil.ReadFile("/etc/release") + out, err := os.ReadFile("/etc/release") if err == nil { fmt.Fprintf(w, "/etc/release: %s\n", out) } else { @@ -176,7 +176,7 @@ func printGlibcVersion(w io.Writer) { src := []byte(`int main() {}`) srcfile := filepath.Join(tempdir, "go-bug.c") outfile := filepath.Join(tempdir, "go-bug") - err := ioutil.WriteFile(srcfile, src, 0644) + err := os.WriteFile(srcfile, src, 0644) if err != nil { return } diff --git a/libgo/go/cmd/go/internal/cache/cache.go b/libgo/go/cmd/go/internal/cache/cache.go index 15545ac31f8..41f921641d4 100644 --- a/libgo/go/cmd/go/internal/cache/cache.go +++ b/libgo/go/cmd/go/internal/cache/cache.go @@ -12,7 +12,7 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "strconv" @@ -54,7 +54,7 @@ func Open(dir string) (*Cache, error) { return nil, err } if !info.IsDir() { - return nil, &os.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")} + return nil, &fs.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")} } for i := 0; i < 256; i++ { name := filepath.Join(dir, fmt.Sprintf("%02x", i)) @@ -238,7 +238,7 @@ func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) { if err != nil { return nil, entry, err } - data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID)) + data, _ := os.ReadFile(c.OutputFile(entry.OutputID)) if sha256.Sum256(data) != entry.OutputID { return nil, entry, &entryNotFoundError{Err: errors.New("bad checksum")} } @@ -377,7 +377,7 @@ func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify // Truncate the file only *after* writing it. // (This should be a no-op, but truncate just in case of previous corruption.) // - // This differs from ioutil.WriteFile, which truncates to 0 *before* writing + // This differs from os.WriteFile, which truncates to 0 *before* writing // via os.O_TRUNC. Truncating only after writing ensures that a second write // of the same content to the same file is idempotent, and does not — even // temporarily! — undo the effect of the first write. diff --git a/libgo/go/cmd/go/internal/cache/cache_test.go b/libgo/go/cmd/go/internal/cache/cache_test.go index 1988c345023..a865b97018d 100644 --- a/libgo/go/cmd/go/internal/cache/cache_test.go +++ b/libgo/go/cmd/go/internal/cache/cache_test.go @@ -8,7 +8,6 @@ import ( "bytes" "encoding/binary" "fmt" - "io/ioutil" "os" "path/filepath" "testing" @@ -20,7 +19,7 @@ func init() { } func TestBasic(t *testing.T) { - dir, err := ioutil.TempDir("", "cachetest-") + dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } @@ -65,7 +64,7 @@ func TestBasic(t *testing.T) { } func TestGrowth(t *testing.T) { - dir, err := ioutil.TempDir("", "cachetest-") + dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } @@ -118,7 +117,7 @@ func TestVerifyPanic(t *testing.T) { t.Fatal("initEnv did not set verify") } - dir, err := ioutil.TempDir("", "cachetest-") + dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } @@ -151,7 +150,7 @@ func dummyID(x int) [HashSize]byte { } func TestCacheTrim(t *testing.T) { - dir, err := ioutil.TempDir("", "cachetest-") + dir, err := os.MkdirTemp("", "cachetest-") if err != nil { t.Fatal(err) } @@ -207,7 +206,7 @@ func TestCacheTrim(t *testing.T) { t.Fatal(err) } c.OutputFile(entry.OutputID) - data, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt")) + data, err := os.ReadFile(filepath.Join(dir, "trim.txt")) if err != nil { t.Fatal(err) } @@ -220,7 +219,7 @@ func TestCacheTrim(t *testing.T) { t.Fatal(err) } c.OutputFile(entry.OutputID) - data2, err := ioutil.ReadFile(filepath.Join(dir, "trim.txt")) + data2, err := os.ReadFile(filepath.Join(dir, "trim.txt")) if err != nil { t.Fatal(err) } diff --git a/libgo/go/cmd/go/internal/cache/default.go b/libgo/go/cmd/go/internal/cache/default.go index 9f8dd8af4b6..0b1c1e0c203 100644 --- a/libgo/go/cmd/go/internal/cache/default.go +++ b/libgo/go/cmd/go/internal/cache/default.go @@ -6,7 +6,6 @@ package cache import ( "fmt" - "io/ioutil" "os" "path/filepath" "sync" @@ -49,7 +48,7 @@ func initDefaultCache() { } if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { // Best effort. - ioutil.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) + os.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) } c, err := Open(dir) diff --git a/libgo/go/cmd/go/internal/cache/hash_test.go b/libgo/go/cmd/go/internal/cache/hash_test.go index 3bf7143039c..a0356771cac 100644 --- a/libgo/go/cmd/go/internal/cache/hash_test.go +++ b/libgo/go/cmd/go/internal/cache/hash_test.go @@ -6,7 +6,6 @@ package cache import ( "fmt" - "io/ioutil" "os" "testing" ) @@ -28,7 +27,7 @@ func TestHash(t *testing.T) { } func TestHashFile(t *testing.T) { - f, err := ioutil.TempFile("", "cmd-go-test-") + f, err := os.CreateTemp("", "cmd-go-test-") if err != nil { t.Fatal(err) } diff --git a/libgo/go/cmd/go/internal/cfg/cfg.go b/libgo/go/cmd/go/internal/cfg/cfg.go index 7f8f8e92be3..c48904eacce 100644 --- a/libgo/go/cmd/go/internal/cfg/cfg.go +++ b/libgo/go/cmd/go/internal/cfg/cfg.go @@ -11,13 +11,15 @@ import ( "fmt" "go/build" "internal/cfg" - "io/ioutil" + "io" "os" "path/filepath" "runtime" "strings" "sync" + "cmd/go/internal/fsys" + "cmd/internal/objabi" ) @@ -27,7 +29,8 @@ var ( BuildBuildmode string // -buildmode flag BuildContext = defaultContext() BuildMod string // -mod flag - BuildModReason string // reason -mod flag is set, if set by default + BuildModExplicit bool // whether -mod was set explicitly + BuildModReason string // reason -mod was set, if set by default BuildI bool // -i flag BuildLinkshared bool // -linkshared flag BuildMSan bool // -msan flag @@ -48,9 +51,12 @@ var ( ModCacheRW bool // -modcacherw flag ModFile string // -modfile flag + Insecure bool // -insecure flag + CmdName string // "build", "install", "list", "mod tidy", etc. DebugActiongraph string // -debug-actiongraph flag (undocumented, unstable) + DebugTrace string // -debug-trace flag ) func defaultContext() build.Context { @@ -100,6 +106,15 @@ func defaultContext() build.Context { // Nothing to do here. } + ctxt.OpenFile = func(path string) (io.ReadCloser, error) { + return fsys.Open(path) + } + ctxt.ReadDir = fsys.ReadDir + ctxt.IsDir = func(path string) bool { + isDir, err := fsys.IsDir(path) + return err == nil && isDir + } + return ctxt } @@ -171,7 +186,7 @@ func initEnvCache() { if file == "" { return } - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil { return } @@ -252,6 +267,7 @@ var ( GONOPROXY = envOr("GONOPROXY", GOPRIVATE) GONOSUMDB = envOr("GONOSUMDB", GOPRIVATE) GOINSECURE = Getenv("GOINSECURE") + GOVCS = Getenv("GOVCS") ) var SumdbDir = gopathDir("pkg/sumdb") diff --git a/libgo/go/cmd/go/internal/clean/clean.go b/libgo/go/cmd/go/internal/clean/clean.go index 99704cb2b1b..b1d40feb273 100644 --- a/libgo/go/cmd/go/internal/clean/clean.go +++ b/libgo/go/cmd/go/internal/clean/clean.go @@ -6,8 +6,9 @@ package clean import ( + "context" "fmt" - "io/ioutil" + "io" "os" "path/filepath" "strconv" @@ -105,7 +106,7 @@ func init() { work.AddBuildFlags(CmdClean, work.DefaultBuildFlags) } -func runClean(cmd *base.Command, args []string) { +func runClean(ctx context.Context, cmd *base.Command, args []string) { // golang.org/issue/29925: only load packages before cleaning if // either the flags and arguments explicitly imply a package, // or no other target (such as a cache) was requested to be cleaned. @@ -116,7 +117,7 @@ func runClean(cmd *base.Command, args []string) { } if cleanPkg { - for _, pkg := range load.PackagesAndErrors(args) { + for _, pkg := range load.PackagesAndErrors(ctx, args) { clean(pkg) } } @@ -171,7 +172,7 @@ func runClean(cmd *base.Command, args []string) { f, err := lockedfile.Edit(filepath.Join(dir, "testexpire.txt")) if err == nil { now := time.Now().UnixNano() - buf, _ := ioutil.ReadAll(f) + buf, _ := io.ReadAll(f) prev, _ := strconv.ParseInt(strings.TrimSpace(string(buf)), 10, 64) if now > prev { if err = f.Truncate(0); err == nil { @@ -242,7 +243,7 @@ func clean(p *load.Package) { base.Errorf("%v", p.Error) return } - dirs, err := ioutil.ReadDir(p.Dir) + dirs, err := os.ReadDir(p.Dir) if err != nil { base.Errorf("go clean %s: %v", p.Dir, err) return @@ -274,6 +275,8 @@ func clean(p *load.Package) { allRemove = append(allRemove, elem, elem+".exe", + p.DefaultExecName(), + p.DefaultExecName()+".exe", ) } @@ -281,16 +284,28 @@ func clean(p *load.Package) { allRemove = append(allRemove, elem+".test", elem+".test.exe", + p.DefaultExecName()+".test", + p.DefaultExecName()+".test.exe", ) - // Remove a potential executable for each .go file in the directory that + // Remove a potential executable, test executable for each .go file in the directory that // is not part of the directory's package. for _, dir := range dirs { name := dir.Name() if packageFile[name] { continue } - if !dir.IsDir() && strings.HasSuffix(name, ".go") { + + if dir.IsDir() { + continue + } + + if strings.HasSuffix(name, "_test.go") { + base := name[:len(name)-len("_test.go")] + allRemove = append(allRemove, base+".test", base+".test.exe") + } + + if strings.HasSuffix(name, ".go") { // TODO(adg,rsc): check that this .go file is actually // in "package main", and therefore capable of building // to an executable file. diff --git a/libgo/go/cmd/go/internal/doc/doc.go b/libgo/go/cmd/go/internal/doc/doc.go index 4ff08bb9289..67f76e22563 100644 --- a/libgo/go/cmd/go/internal/doc/doc.go +++ b/libgo/go/cmd/go/internal/doc/doc.go @@ -8,6 +8,7 @@ package doc import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "context" ) var CmdDoc = &base.Command{ @@ -129,6 +130,6 @@ Flags: `, } -func runDoc(cmd *base.Command, args []string) { +func runDoc(ctx context.Context, cmd *base.Command, args []string) { base.Run(cfg.BuildToolexec, base.Tool("doc"), args) } diff --git a/libgo/go/cmd/go/internal/envcmd/env.go b/libgo/go/cmd/go/internal/envcmd/env.go index 252025dc255..6937187522b 100644 --- a/libgo/go/cmd/go/internal/envcmd/env.go +++ b/libgo/go/cmd/go/internal/envcmd/env.go @@ -6,10 +6,10 @@ package envcmd import ( + "context" "encoding/json" "fmt" "go/build" - "io/ioutil" "os" "path/filepath" "runtime" @@ -20,6 +20,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cache" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/load" "cmd/go/internal/modload" "cmd/go/internal/work" @@ -62,9 +63,6 @@ var ( ) func MkEnv() []cfg.EnvVar { - var b work.Builder - b.Init() - envFile, _ := cfg.EnvFile() env := []cfg.EnvVar{ {Name: "GO111MODULE", Value: cfg.Getenv("GO111MODULE")}, @@ -88,6 +86,8 @@ func MkEnv() []cfg.EnvVar { {Name: "GOSUMDB", Value: cfg.GOSUMDB}, {Name: "GOTMPDIR", Value: cfg.Getenv("GOTMPDIR")}, {Name: "GOTOOLDIR", Value: base.ToolDir}, + {Name: "GOVCS", Value: cfg.GOVCS}, + {Name: "GOVERSION", Value: runtime.Version()}, } if work.GccgoBin != "" { @@ -186,7 +186,7 @@ func argKey(arg string) string { return arg[:i] } -func runEnv(cmd *base.Command, args []string) { +func runEnv(ctx context.Context, cmd *base.Command, args []string) { if *envJson && *envU { base.Fatalf("go env: cannot use -json with -u") } @@ -199,12 +199,26 @@ func runEnv(cmd *base.Command, args []string) { env := cfg.CmdEnv env = append(env, ExtraEnvVars()...) + if err := fsys.Init(base.Cwd); err != nil { + base.Fatalf("go: %v", err) + } + // Do we need to call ExtraEnvVarsCostly, which is a bit expensive? - // Only if we're listing all environment variables ("go env") - // or the variables being requested are in the extra list. - needCostly := true - if len(args) > 0 { + needCostly := false + if *envU || *envW { + // We're overwriting or removing default settings, + // so it doesn't really matter what the existing settings are. + // + // Moreover, we haven't validated the new settings yet, so it is + // important that we NOT perform any actions based on them, + // such as initializing the builder to compute other variables. + } else if len(args) == 0 { + // We're listing all environment variables ("go env"), + // including the expensive ones. + needCostly = true + } else { needCostly = false + checkCostly: for _, arg := range args { switch argKey(arg) { case "CGO_CFLAGS", @@ -215,6 +229,7 @@ func runEnv(cmd *base.Command, args []string) { "PKG_CONFIG", "GOGCCFLAGS": needCostly = true + break checkCostly } } } @@ -266,6 +281,13 @@ func runEnv(cmd *base.Command, args []string) { } } + gotmp, okGOTMP := add["GOTMPDIR"] + if okGOTMP { + if !filepath.IsAbs(gotmp) && gotmp != "" { + base.Fatalf("go env -w: GOTMPDIR must be an absolute path") + } + } + updateEnvFile(add, nil) return } @@ -377,7 +399,7 @@ func getOrigEnv(key string) string { func checkEnvWrite(key, val string) error { switch key { - case "GOEXE", "GOGCCFLAGS", "GOHOSTARCH", "GOHOSTOS", "GOMOD", "GOTOOLDIR": + case "GOEXE", "GOGCCFLAGS", "GOHOSTARCH", "GOHOSTOS", "GOMOD", "GOTOOLDIR", "GOVERSION": return fmt.Errorf("%s cannot be modified", key) case "GOENV": return fmt.Errorf("%s can only be set using the OS environment", key) @@ -405,6 +427,11 @@ func checkEnvWrite(key, val string) error { if !filepath.IsAbs(val) && val != "" { return fmt.Errorf("GOPATH entry is relative; must be absolute path: %q", val) } + // Make sure CC and CXX are absolute paths + case "CC", "CXX": + if !filepath.IsAbs(val) && val != "" && val != filepath.Base(val) { + return fmt.Errorf("%s entry is relative; must be absolute path: %q", key, val) + } } if !utf8.ValidString(val) { @@ -424,7 +451,7 @@ func updateEnvFile(add map[string]string, del map[string]bool) { if file == "" { base.Fatalf("go env: cannot find go env config: %v", err) } - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil && (!os.IsNotExist(err) || len(add) == 0) { base.Fatalf("go env: reading go env config: %v", err) } @@ -478,11 +505,11 @@ func updateEnvFile(add map[string]string, del map[string]bool) { } data = []byte(strings.Join(lines, "")) - err = ioutil.WriteFile(file, data, 0666) + err = os.WriteFile(file, data, 0666) if err != nil { // Try creating directory. os.MkdirAll(filepath.Dir(file), 0777) - err = ioutil.WriteFile(file, data, 0666) + err = os.WriteFile(file, data, 0666) if err != nil { base.Fatalf("go env: writing go env config: %v", err) } @@ -499,7 +526,10 @@ func lineToKey(line string) string { } // sortKeyValues sorts a sequence of lines by key. -// It differs from sort.Strings in that GO386= sorts after GO=. +// It differs from sort.Strings in that keys which are GOx where x is an ASCII +// character smaller than = sort after GO=. +// (There are no such keys currently. It used to matter for GO386 which was +// removed in Go 1.16.) func sortKeyValues(lines []string) { sort.Slice(lines, func(i, j int) bool { return lineToKey(lines[i]) < lineToKey(lines[j]) diff --git a/libgo/go/cmd/go/internal/fix/fix.go b/libgo/go/cmd/go/internal/fix/fix.go index 4d741df2b4f..c7588c66d3e 100644 --- a/libgo/go/cmd/go/internal/fix/fix.go +++ b/libgo/go/cmd/go/internal/fix/fix.go @@ -11,6 +11,7 @@ import ( "cmd/go/internal/load" "cmd/go/internal/modload" "cmd/go/internal/str" + "context" "fmt" "os" ) @@ -31,9 +32,21 @@ See also: go fmt, go vet. `, } -func runFix(cmd *base.Command, args []string) { +func runFix(ctx context.Context, cmd *base.Command, args []string) { + pkgs := load.PackagesAndErrors(ctx, args) + w := 0 + for _, pkg := range pkgs { + if pkg.Error != nil { + base.Errorf("%v", pkg.Error) + continue + } + pkgs[w] = pkg + w++ + } + pkgs = pkgs[:w] + printed := false - for _, pkg := range load.Packages(args) { + for _, pkg := range pkgs { if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main { if !printed { fmt.Fprintf(os.Stderr, "go: not fixing packages in dependency modules\n") diff --git a/libgo/go/cmd/go/internal/fmtcmd/fmt.go b/libgo/go/cmd/go/internal/fmtcmd/fmt.go index d6894edc9f5..b0c1c59b40c 100644 --- a/libgo/go/cmd/go/internal/fmtcmd/fmt.go +++ b/libgo/go/cmd/go/internal/fmtcmd/fmt.go @@ -6,6 +6,7 @@ package fmtcmd import ( + "context" "errors" "fmt" "os" @@ -22,7 +23,8 @@ import ( func init() { base.AddBuildFlagsNX(&CmdFmt.Flag) - base.AddLoadFlags(&CmdFmt.Flag) + base.AddModFlag(&CmdFmt.Flag) + base.AddModCommonFlags(&CmdFmt.Flag) } var CmdFmt = &base.Command{ @@ -48,7 +50,7 @@ See also: go fix, go vet. `, } -func runFmt(cmd *base.Command, args []string) { +func runFmt(ctx context.Context, cmd *base.Command, args []string) { printed := false gofmt := gofmtPath() procs := runtime.GOMAXPROCS(0) @@ -63,7 +65,7 @@ func runFmt(cmd *base.Command, args []string) { } }() } - for _, pkg := range load.PackagesAndErrors(args) { + for _, pkg := range load.PackagesAndErrors(ctx, args) { if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main { if !printed { fmt.Fprintf(os.Stderr, "go: not formatting packages in dependency modules\n") diff --git a/libgo/go/cmd/go/internal/fsys/fsys.go b/libgo/go/cmd/go/internal/fsys/fsys.go new file mode 100644 index 00000000000..7b06c3c7f3a --- /dev/null +++ b/libgo/go/cmd/go/internal/fsys/fsys.go @@ -0,0 +1,689 @@ +// Package fsys is an abstraction for reading files that +// allows for virtual overlays on top of the files on disk. +package fsys + +import ( + "encoding/json" + "errors" + "fmt" + "io/fs" + "io/ioutil" + "os" + "path/filepath" + "runtime" + "sort" + "strings" + "time" +) + +// OverlayFile is the path to a text file in the OverlayJSON format. +// It is the value of the -overlay flag. +var OverlayFile string + +// OverlayJSON is the format overlay files are expected to be in. +// The Replace map maps from overlaid paths to replacement paths: +// the Go command will forward all reads trying to open +// each overlaid path to its replacement path, or consider the overlaid +// path not to exist if the replacement path is empty. +type OverlayJSON struct { + Replace map[string]string +} + +type node struct { + actualFilePath string // empty if a directory + children map[string]*node // path element → file or directory +} + +func (n *node) isDir() bool { + return n.actualFilePath == "" && n.children != nil +} + +func (n *node) isDeleted() bool { + return n.actualFilePath == "" && n.children == nil +} + +// TODO(matloob): encapsulate these in an io/fs-like interface +var overlay map[string]*node // path -> file or directory node +var cwd string // copy of base.Cwd to avoid dependency + +// Canonicalize a path for looking it up in the overlay. +// Important: filepath.Join(cwd, path) doesn't always produce +// the correct absolute path if path is relative, because on +// Windows producing the correct absolute path requires making +// a syscall. So this should only be used when looking up paths +// in the overlay, or canonicalizing the paths in the overlay. +func canonicalize(path string) string { + if path == "" { + return "" + } + if filepath.IsAbs(path) { + return filepath.Clean(path) + } + + if v := filepath.VolumeName(cwd); v != "" && path[0] == filepath.Separator { + // On Windows filepath.Join(cwd, path) doesn't always work. In general + // filepath.Abs needs to make a syscall on Windows. Elsewhere in cmd/go + // use filepath.Join(cwd, path), but cmd/go specifically supports Windows + // paths that start with "\" which implies the path is relative to the + // volume of the working directory. See golang.org/issue/8130. + return filepath.Join(v, path) + } + + // Make the path absolute. + return filepath.Join(cwd, path) +} + +// Init initializes the overlay, if one is being used. +func Init(wd string) error { + if overlay != nil { + // already initialized + return nil + } + + cwd = wd + + if OverlayFile == "" { + return nil + } + + b, err := os.ReadFile(OverlayFile) + if err != nil { + return fmt.Errorf("reading overlay file: %v", err) + } + + var overlayJSON OverlayJSON + if err := json.Unmarshal(b, &overlayJSON); err != nil { + return fmt.Errorf("parsing overlay JSON: %v", err) + } + + return initFromJSON(overlayJSON) +} + +func initFromJSON(overlayJSON OverlayJSON) error { + // Canonicalize the paths in in the overlay map. + // Use reverseCanonicalized to check for collisions: + // no two 'from' paths should canonicalize to the same path. + overlay = make(map[string]*node) + reverseCanonicalized := make(map[string]string) // inverse of canonicalize operation, to check for duplicates + // Build a table of file and directory nodes from the replacement map. + + // Remove any potential non-determinism from iterating over map by sorting it. + replaceFrom := make([]string, 0, len(overlayJSON.Replace)) + for k := range overlayJSON.Replace { + replaceFrom = append(replaceFrom, k) + } + sort.Strings(replaceFrom) + + for _, from := range replaceFrom { + to := overlayJSON.Replace[from] + // Canonicalize paths and check for a collision. + if from == "" { + return fmt.Errorf("empty string key in overlay file Replace map") + } + cfrom := canonicalize(from) + if to != "" { + // Don't canonicalize "", meaning to delete a file, because then it will turn into ".". + to = canonicalize(to) + } + if otherFrom, seen := reverseCanonicalized[cfrom]; seen { + return fmt.Errorf( + "paths %q and %q both canonicalize to %q in overlay file Replace map", otherFrom, from, cfrom) + } + reverseCanonicalized[cfrom] = from + from = cfrom + + // Create node for overlaid file. + dir, base := filepath.Dir(from), filepath.Base(from) + if n, ok := overlay[from]; ok { + // All 'from' paths in the overlay are file paths. Since the from paths + // are in a map, they are unique, so if the node already exists we added + // it below when we create parent directory nodes. That is, that + // both a file and a path to one of its parent directories exist as keys + // in the Replace map. + // + // This only applies if the overlay directory has any files or directories + // in it: placeholder directories that only contain deleted files don't + // count. They are safe to be overwritten with actual files. + for _, f := range n.children { + if !f.isDeleted() { + return fmt.Errorf("invalid overlay: path %v is used as both file and directory", from) + } + } + } + overlay[from] = &node{actualFilePath: to} + + // Add parent directory nodes to overlay structure. + childNode := overlay[from] + for { + dirNode := overlay[dir] + if dirNode == nil || dirNode.isDeleted() { + dirNode = &node{children: make(map[string]*node)} + overlay[dir] = dirNode + } + if childNode.isDeleted() { + // Only create one parent for a deleted file: + // the directory only conditionally exists if + // there are any non-deleted children, so + // we don't create their parents. + if dirNode.isDir() { + dirNode.children[base] = childNode + } + break + } + if !dirNode.isDir() { + // This path already exists as a file, so it can't be a parent + // directory. See comment at error above. + return fmt.Errorf("invalid overlay: path %v is used as both file and directory", dir) + } + dirNode.children[base] = childNode + parent := filepath.Dir(dir) + if parent == dir { + break // reached the top; there is no parent + } + dir, base = parent, filepath.Base(dir) + childNode = dirNode + } + } + + return nil +} + +// IsDir returns true if path is a directory on disk or in the +// overlay. +func IsDir(path string) (bool, error) { + path = canonicalize(path) + + if _, ok := parentIsOverlayFile(path); ok { + return false, nil + } + + if n, ok := overlay[path]; ok { + return n.isDir(), nil + } + + fi, err := os.Stat(path) + if err != nil { + return false, err + } + + return fi.IsDir(), nil +} + +// parentIsOverlayFile returns whether name or any of +// its parents are files in the overlay, and the first parent found, +// including name itself, that's a file in the overlay. +func parentIsOverlayFile(name string) (string, bool) { + if overlay != nil { + // Check if name can't possibly be a directory because + // it or one of its parents is overlaid with a file. + // TODO(matloob): Maybe save this to avoid doing it every time? + prefix := name + for { + node := overlay[prefix] + if node != nil && !node.isDir() { + return prefix, true + } + parent := filepath.Dir(prefix) + if parent == prefix { + break + } + prefix = parent + } + } + + return "", false +} + +// errNotDir is used to communicate from ReadDir to IsDirWithGoFiles +// that the argument is not a directory, so that IsDirWithGoFiles doesn't +// return an error. +var errNotDir = errors.New("not a directory") + +// readDir reads a dir on disk, returning an error that is errNotDir if the dir is not a directory. +// Unfortunately, the error returned by ioutil.ReadDir if dir is not a directory +// can vary depending on the OS (Linux, Mac, Windows return ENOTDIR; BSD returns EINVAL). +func readDir(dir string) ([]fs.FileInfo, error) { + fis, err := ioutil.ReadDir(dir) + if err == nil { + return fis, nil + } + + if os.IsNotExist(err) { + return nil, err + } + if dirfi, staterr := os.Stat(dir); staterr == nil && !dirfi.IsDir() { + return nil, &fs.PathError{Op: "ReadDir", Path: dir, Err: errNotDir} + } + return nil, err +} + +// ReadDir provides a slice of fs.FileInfo entries corresponding +// to the overlaid files in the directory. +func ReadDir(dir string) ([]fs.FileInfo, error) { + dir = canonicalize(dir) + if _, ok := parentIsOverlayFile(dir); ok { + return nil, &fs.PathError{Op: "ReadDir", Path: dir, Err: errNotDir} + } + + dirNode := overlay[dir] + if dirNode == nil { + return readDir(dir) + } + if dirNode.isDeleted() { + return nil, &fs.PathError{Op: "ReadDir", Path: dir, Err: fs.ErrNotExist} + } + diskfis, err := readDir(dir) + if err != nil && !os.IsNotExist(err) && !errors.Is(err, errNotDir) { + return nil, err + } + + // Stat files in overlay to make composite list of fileinfos + files := make(map[string]fs.FileInfo) + for _, f := range diskfis { + files[f.Name()] = f + } + for name, to := range dirNode.children { + switch { + case to.isDir(): + files[name] = fakeDir(name) + case to.isDeleted(): + delete(files, name) + default: + // This is a regular file. + f, err := os.Lstat(to.actualFilePath) + if err != nil { + files[name] = missingFile(name) + continue + } else if f.IsDir() { + return nil, fmt.Errorf("for overlay of %q to %q: overlay Replace entries can't point to dirctories", + filepath.Join(dir, name), to.actualFilePath) + } + // Add a fileinfo for the overlaid file, so that it has + // the original file's name, but the overlaid file's metadata. + files[name] = fakeFile{name, f} + } + } + sortedFiles := diskfis[:0] + for _, f := range files { + sortedFiles = append(sortedFiles, f) + } + sort.Slice(sortedFiles, func(i, j int) bool { return sortedFiles[i].Name() < sortedFiles[j].Name() }) + return sortedFiles, nil +} + +// OverlayPath returns the path to the overlaid contents of the +// file, the empty string if the overlay deletes the file, or path +// itself if the file is not in the overlay, the file is a directory +// in the overlay, or there is no overlay. +// It returns true if the path is overlaid with a regular file +// or deleted, and false otherwise. +func OverlayPath(path string) (string, bool) { + if p, ok := overlay[canonicalize(path)]; ok && !p.isDir() { + return p.actualFilePath, ok + } + + return path, false +} + +// Open opens the file at or overlaid on the given path. +func Open(path string) (*os.File, error) { + return OpenFile(path, os.O_RDONLY, 0) +} + +// OpenFile opens the file at or overlaid on the given path with the flag and perm. +func OpenFile(path string, flag int, perm os.FileMode) (*os.File, error) { + cpath := canonicalize(path) + if node, ok := overlay[cpath]; ok { + // Opening a file in the overlay. + if node.isDir() { + return nil, &fs.PathError{Op: "OpenFile", Path: path, Err: errors.New("fsys.OpenFile doesn't support opening directories yet")} + } + // We can't open overlaid paths for write. + if perm != os.FileMode(os.O_RDONLY) { + return nil, &fs.PathError{Op: "OpenFile", Path: path, Err: errors.New("overlaid files can't be opened for write")} + } + return os.OpenFile(node.actualFilePath, flag, perm) + } + if parent, ok := parentIsOverlayFile(filepath.Dir(cpath)); ok { + // The file is deleted explicitly in the Replace map, + // or implicitly because one of its parent directories was + // replaced by a file. + return nil, &fs.PathError{ + Op: "Open", + Path: path, + Err: fmt.Errorf("file %s does not exist: parent directory %s is replaced by a file in overlay", path, parent), + } + } + return os.OpenFile(cpath, flag, perm) +} + +// IsDirWithGoFiles reports whether dir is a directory containing Go files +// either on disk or in the overlay. +func IsDirWithGoFiles(dir string) (bool, error) { + fis, err := ReadDir(dir) + if os.IsNotExist(err) || errors.Is(err, errNotDir) { + return false, nil + } + if err != nil { + return false, err + } + + var firstErr error + for _, fi := range fis { + if fi.IsDir() { + continue + } + + // TODO(matloob): this enforces that the "from" in the map + // has a .go suffix, but the actual destination file + // doesn't need to have a .go suffix. Is this okay with the + // compiler? + if !strings.HasSuffix(fi.Name(), ".go") { + continue + } + if fi.Mode().IsRegular() { + return true, nil + } + + // fi is the result of an Lstat, so it doesn't follow symlinks. + // But it's okay if the file is a symlink pointing to a regular + // file, so use os.Stat to follow symlinks and check that. + actualFilePath, _ := OverlayPath(filepath.Join(dir, fi.Name())) + fi, err := os.Stat(actualFilePath) + if err == nil && fi.Mode().IsRegular() { + return true, nil + } + if err != nil && firstErr == nil { + firstErr = err + } + } + + // No go files found in directory. + return false, firstErr +} + +// walk recursively descends path, calling walkFn. Copied, with some +// modifications from path/filepath.walk. +func walk(path string, info fs.FileInfo, walkFn filepath.WalkFunc) error { + if !info.IsDir() { + return walkFn(path, info, nil) + } + + fis, readErr := ReadDir(path) + walkErr := walkFn(path, info, readErr) + // If readErr != nil, walk can't walk into this directory. + // walkErr != nil means walkFn want walk to skip this directory or stop walking. + // Therefore, if one of readErr and walkErr isn't nil, walk will return. + if readErr != nil || walkErr != nil { + // The caller's behavior is controlled by the return value, which is decided + // by walkFn. walkFn may ignore readErr and return nil. + // If walkFn returns SkipDir, it will be handled by the caller. + // So walk should return whatever walkFn returns. + return walkErr + } + + for _, fi := range fis { + filename := filepath.Join(path, fi.Name()) + if walkErr = walk(filename, fi, walkFn); walkErr != nil { + if !fi.IsDir() || walkErr != filepath.SkipDir { + return walkErr + } + } + } + return nil +} + +// Walk walks the file tree rooted at root, calling walkFn for each file or +// directory in the tree, including root. +func Walk(root string, walkFn filepath.WalkFunc) error { + info, err := Lstat(root) + if err != nil { + err = walkFn(root, nil, err) + } else { + err = walk(root, info, walkFn) + } + if err == filepath.SkipDir { + return nil + } + return err +} + +// lstat implements a version of os.Lstat that operates on the overlay filesystem. +func Lstat(path string) (fs.FileInfo, error) { + return overlayStat(path, os.Lstat, "lstat") +} + +// Stat implements a version of os.Stat that operates on the overlay filesystem. +func Stat(path string) (fs.FileInfo, error) { + return overlayStat(path, os.Stat, "stat") +} + +// overlayStat implements lstat or Stat (depending on whether os.Lstat or os.Stat is passed in). +func overlayStat(path string, osStat func(string) (fs.FileInfo, error), opName string) (fs.FileInfo, error) { + cpath := canonicalize(path) + + if _, ok := parentIsOverlayFile(filepath.Dir(cpath)); ok { + return nil, &fs.PathError{Op: opName, Path: cpath, Err: fs.ErrNotExist} + } + + node, ok := overlay[cpath] + if !ok { + // The file or directory is not overlaid. + return osStat(path) + } + + switch { + case node.isDeleted(): + return nil, &fs.PathError{Op: "lstat", Path: cpath, Err: fs.ErrNotExist} + case node.isDir(): + return fakeDir(filepath.Base(path)), nil + default: + fi, err := osStat(node.actualFilePath) + if err != nil { + return nil, err + } + return fakeFile{name: filepath.Base(path), real: fi}, nil + } +} + +// fakeFile provides an fs.FileInfo implementation for an overlaid file, +// so that the file has the name of the overlaid file, but takes all +// other characteristics of the replacement file. +type fakeFile struct { + name string + real fs.FileInfo +} + +func (f fakeFile) Name() string { return f.name } +func (f fakeFile) Size() int64 { return f.real.Size() } +func (f fakeFile) Mode() fs.FileMode { return f.real.Mode() } +func (f fakeFile) ModTime() time.Time { return f.real.ModTime() } +func (f fakeFile) IsDir() bool { return f.real.IsDir() } +func (f fakeFile) Sys() interface{} { return f.real.Sys() } + +// missingFile provides an fs.FileInfo for an overlaid file where the +// destination file in the overlay doesn't exist. It returns zero values +// for the fileInfo methods other than Name, set to the file's name, and Mode +// set to ModeIrregular. +type missingFile string + +func (f missingFile) Name() string { return string(f) } +func (f missingFile) Size() int64 { return 0 } +func (f missingFile) Mode() fs.FileMode { return fs.ModeIrregular } +func (f missingFile) ModTime() time.Time { return time.Unix(0, 0) } +func (f missingFile) IsDir() bool { return false } +func (f missingFile) Sys() interface{} { return nil } + +// fakeDir provides an fs.FileInfo implementation for directories that are +// implicitly created by overlaid files. Each directory in the +// path of an overlaid file is considered to exist in the overlay filesystem. +type fakeDir string + +func (f fakeDir) Name() string { return string(f) } +func (f fakeDir) Size() int64 { return 0 } +func (f fakeDir) Mode() fs.FileMode { return fs.ModeDir | 0500 } +func (f fakeDir) ModTime() time.Time { return time.Unix(0, 0) } +func (f fakeDir) IsDir() bool { return true } +func (f fakeDir) Sys() interface{} { return nil } + +// Glob is like filepath.Glob but uses the overlay file system. +func Glob(pattern string) (matches []string, err error) { + // Check pattern is well-formed. + if _, err := filepath.Match(pattern, ""); err != nil { + return nil, err + } + if !hasMeta(pattern) { + if _, err = Lstat(pattern); err != nil { + return nil, nil + } + return []string{pattern}, nil + } + + dir, file := filepath.Split(pattern) + volumeLen := 0 + if runtime.GOOS == "windows" { + volumeLen, dir = cleanGlobPathWindows(dir) + } else { + dir = cleanGlobPath(dir) + } + + if !hasMeta(dir[volumeLen:]) { + return glob(dir, file, nil) + } + + // Prevent infinite recursion. See issue 15879. + if dir == pattern { + return nil, filepath.ErrBadPattern + } + + var m []string + m, err = Glob(dir) + if err != nil { + return + } + for _, d := range m { + matches, err = glob(d, file, matches) + if err != nil { + return + } + } + return +} + +// cleanGlobPath prepares path for glob matching. +func cleanGlobPath(path string) string { + switch path { + case "": + return "." + case string(filepath.Separator): + // do nothing to the path + return path + default: + return path[0 : len(path)-1] // chop off trailing separator + } +} + +func volumeNameLen(path string) int { + isSlash := func(c uint8) bool { + return c == '\\' || c == '/' + } + if len(path) < 2 { + return 0 + } + // with drive letter + c := path[0] + if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') { + return 2 + } + // is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx + if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) && + !isSlash(path[2]) && path[2] != '.' { + // first, leading `\\` and next shouldn't be `\`. its server name. + for n := 3; n < l-1; n++ { + // second, next '\' shouldn't be repeated. + if isSlash(path[n]) { + n++ + // third, following something characters. its share name. + if !isSlash(path[n]) { + if path[n] == '.' { + break + } + for ; n < l; n++ { + if isSlash(path[n]) { + break + } + } + return n + } + break + } + } + } + return 0 +} + +// cleanGlobPathWindows is windows version of cleanGlobPath. +func cleanGlobPathWindows(path string) (prefixLen int, cleaned string) { + vollen := volumeNameLen(path) + switch { + case path == "": + return 0, "." + case vollen+1 == len(path) && os.IsPathSeparator(path[len(path)-1]): // /, \, C:\ and C:/ + // do nothing to the path + return vollen + 1, path + case vollen == len(path) && len(path) == 2: // C: + return vollen, path + "." // convert C: into C:. + default: + if vollen >= len(path) { + vollen = len(path) - 1 + } + return vollen, path[0 : len(path)-1] // chop off trailing separator + } +} + +// glob searches for files matching pattern in the directory dir +// and appends them to matches. If the directory cannot be +// opened, it returns the existing matches. New matches are +// added in lexicographical order. +func glob(dir, pattern string, matches []string) (m []string, e error) { + m = matches + fi, err := Stat(dir) + if err != nil { + return // ignore I/O error + } + if !fi.IsDir() { + return // ignore I/O error + } + + list, err := ReadDir(dir) + if err != nil { + return // ignore I/O error + } + + var names []string + for _, info := range list { + names = append(names, info.Name()) + } + sort.Strings(names) + + for _, n := range names { + matched, err := filepath.Match(pattern, n) + if err != nil { + return m, err + } + if matched { + m = append(m, filepath.Join(dir, n)) + } + } + return +} + +// hasMeta reports whether path contains any of the magic characters +// recognized by filepath.Match. +func hasMeta(path string) bool { + magicChars := `*?[` + if runtime.GOOS != "windows" { + magicChars = `*?[\` + } + return strings.ContainsAny(path, magicChars) +} diff --git a/libgo/go/cmd/go/internal/fsys/fsys_test.go b/libgo/go/cmd/go/internal/fsys/fsys_test.go new file mode 100644 index 00000000000..7f175c70311 --- /dev/null +++ b/libgo/go/cmd/go/internal/fsys/fsys_test.go @@ -0,0 +1,1094 @@ +package fsys + +import ( + "cmd/go/internal/txtar" + "encoding/json" + "errors" + "fmt" + "internal/testenv" + "io" + "io/fs" + "os" + "path/filepath" + "reflect" + "testing" +) + +// initOverlay resets the overlay state to reflect the config. +// config should be a text archive string. The comment is the overlay config +// json, and the files, in the archive are laid out in a temp directory +// that cwd is set to. +func initOverlay(t *testing.T, config string) { + t.Helper() + + // Create a temporary directory and chdir to it. + prevwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + cwd = filepath.Join(t.TempDir(), "root") + if err := os.Mkdir(cwd, 0777); err != nil { + t.Fatal(err) + } + if err := os.Chdir(cwd); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + overlay = nil + if err := os.Chdir(prevwd); err != nil { + t.Fatal(err) + } + }) + + a := txtar.Parse([]byte(config)) + for _, f := range a.Files { + name := filepath.Join(cwd, f.Name) + if err := os.MkdirAll(filepath.Dir(name), 0777); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(name, f.Data, 0666); err != nil { + t.Fatal(err) + } + } + + var overlayJSON OverlayJSON + if err := json.Unmarshal(a.Comment, &overlayJSON); err != nil { + t.Fatal(fmt.Errorf("parsing overlay JSON: %v", err)) + } + + initFromJSON(overlayJSON) +} + +func TestIsDir(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "subdir2/file2.txt": "overlayfiles/subdir2_file2.txt", + "subdir4": "overlayfiles/subdir4", + "subdir3/file3b.txt": "overlayfiles/subdir3_file3b.txt", + "subdir5": "", + "subdir6": "" + } +} +-- subdir1/file1.txt -- + +-- subdir3/file3a.txt -- +33 +-- subdir4/file4.txt -- +444 +-- overlayfiles/subdir2_file2.txt -- +2 +-- overlayfiles/subdir3_file3b.txt -- +66666 +-- overlayfiles/subdir4 -- +x +-- subdir6/file6.txt -- +six +`) + + testCases := []struct { + path string + want, wantErr bool + }{ + {"", true, true}, + {".", true, false}, + {cwd, true, false}, + {cwd + string(filepath.Separator), true, false}, + // subdir1 is only on disk + {filepath.Join(cwd, "subdir1"), true, false}, + {"subdir1", true, false}, + {"subdir1" + string(filepath.Separator), true, false}, + {"subdir1/file1.txt", false, false}, + {"subdir1/doesntexist.txt", false, true}, + {"doesntexist", false, true}, + // subdir2 is only in overlay + {filepath.Join(cwd, "subdir2"), true, false}, + {"subdir2", true, false}, + {"subdir2" + string(filepath.Separator), true, false}, + {"subdir2/file2.txt", false, false}, + {"subdir2/doesntexist.txt", false, true}, + // subdir3 has files on disk and in overlay + {filepath.Join(cwd, "subdir3"), true, false}, + {"subdir3", true, false}, + {"subdir3" + string(filepath.Separator), true, false}, + {"subdir3/file3a.txt", false, false}, + {"subdir3/file3b.txt", false, false}, + {"subdir3/doesntexist.txt", false, true}, + // subdir4 is overlaid with a file + {filepath.Join(cwd, "subdir4"), false, false}, + {"subdir4", false, false}, + {"subdir4" + string(filepath.Separator), false, false}, + {"subdir4/file4.txt", false, false}, + {"subdir4/doesntexist.txt", false, false}, + // subdir5 doesn't exist, and is overlaid with a "delete" entry + {filepath.Join(cwd, "subdir5"), false, false}, + {"subdir5", false, false}, + {"subdir5" + string(filepath.Separator), false, false}, + {"subdir5/file5.txt", false, false}, + {"subdir5/doesntexist.txt", false, false}, + // subdir6 does exist, and is overlaid with a "delete" entry + {filepath.Join(cwd, "subdir6"), false, false}, + {"subdir6", false, false}, + {"subdir6" + string(filepath.Separator), false, false}, + {"subdir6/file6.txt", false, false}, + {"subdir6/doesntexist.txt", false, false}, + } + + for _, tc := range testCases { + got, err := IsDir(tc.path) + if err != nil { + if !tc.wantErr { + t.Errorf("IsDir(%q): got error with string %q, want no error", tc.path, err.Error()) + } + continue + } + if tc.wantErr { + t.Errorf("IsDir(%q): got no error, want error", tc.path) + } + if tc.want != got { + t.Errorf("IsDir(%q) = %v, want %v", tc.path, got, tc.want) + } + } +} + +const readDirOverlay = ` +{ + "Replace": { + "subdir2/file2.txt": "overlayfiles/subdir2_file2.txt", + "subdir4": "overlayfiles/subdir4", + "subdir3/file3b.txt": "overlayfiles/subdir3_file3b.txt", + "subdir5": "", + "subdir6/asubsubdir/afile.txt": "overlayfiles/subdir6_asubsubdir_afile.txt", + "subdir6/asubsubdir/zfile.txt": "overlayfiles/subdir6_asubsubdir_zfile.txt", + "subdir6/zsubsubdir/file.txt": "overlayfiles/subdir6_zsubsubdir_file.txt", + "subdir7/asubsubdir/file.txt": "overlayfiles/subdir7_asubsubdir_file.txt", + "subdir7/zsubsubdir/file.txt": "overlayfiles/subdir7_zsubsubdir_file.txt", + "subdir8/doesntexist": "this_file_doesnt_exist_anywhere", + "other/pointstodir": "overlayfiles/this_is_a_directory", + "parentoverwritten/subdir1": "overlayfiles/parentoverwritten_subdir1", + "subdir9/this_file_is_overlaid.txt": "overlayfiles/subdir9_this_file_is_overlaid.txt", + "subdir10/only_deleted_file.txt": "", + "subdir11/deleted.txt": "", + "subdir11": "overlayfiles/subdir11", + "textfile.txt/file.go": "overlayfiles/textfile_txt_file.go" + } +} +-- subdir1/file1.txt -- + +-- subdir3/file3a.txt -- +33 +-- subdir4/file4.txt -- +444 +-- subdir6/file.txt -- +-- subdir6/asubsubdir/file.txt -- +-- subdir6/anothersubsubdir/file.txt -- +-- subdir9/this_file_is_overlaid.txt -- +-- subdir10/only_deleted_file.txt -- +this will be deleted in overlay +-- subdir11/deleted.txt -- +-- parentoverwritten/subdir1/subdir2/subdir3/file.txt -- +-- textfile.txt -- +this will be overridden by textfile.txt/file.go +-- overlayfiles/subdir2_file2.txt -- +2 +-- overlayfiles/subdir3_file3b.txt -- +66666 +-- overlayfiles/subdir4 -- +x +-- overlayfiles/subdir6_asubsubdir_afile.txt -- +-- overlayfiles/subdir6_asubsubdir_zfile.txt -- +-- overlayfiles/subdir6_zsubsubdir_file.txt -- +-- overlayfiles/subdir7_asubsubdir_file.txt -- +-- overlayfiles/subdir7_zsubsubdir_file.txt -- +-- overlayfiles/parentoverwritten_subdir1 -- +x +-- overlayfiles/subdir9_this_file_is_overlaid.txt -- +99999999 +-- overlayfiles/subdir11 -- +-- overlayfiles/this_is_a_directory/file.txt -- +-- overlayfiles/textfile_txt_file.go -- +x +` + +func TestReadDir(t *testing.T) { + initOverlay(t, readDirOverlay) + + type entry struct { + name string + size int64 + isDir bool + } + + testCases := []struct { + dir string + want []entry + }{ + { + ".", []entry{ + {"other", 0, true}, + {"overlayfiles", 0, true}, + {"parentoverwritten", 0, true}, + {"subdir1", 0, true}, + {"subdir10", 0, true}, + {"subdir11", 0, false}, + {"subdir2", 0, true}, + {"subdir3", 0, true}, + {"subdir4", 2, false}, + // no subdir5. + {"subdir6", 0, true}, + {"subdir7", 0, true}, + {"subdir8", 0, true}, + {"subdir9", 0, true}, + {"textfile.txt", 0, true}, + }, + }, + { + "subdir1", []entry{ + {"file1.txt", 1, false}, + }, + }, + { + "subdir2", []entry{ + {"file2.txt", 2, false}, + }, + }, + { + "subdir3", []entry{ + {"file3a.txt", 3, false}, + {"file3b.txt", 6, false}, + }, + }, + { + "subdir6", []entry{ + {"anothersubsubdir", 0, true}, + {"asubsubdir", 0, true}, + {"file.txt", 0, false}, + {"zsubsubdir", 0, true}, + }, + }, + { + "subdir6/asubsubdir", []entry{ + {"afile.txt", 0, false}, + {"file.txt", 0, false}, + {"zfile.txt", 0, false}, + }, + }, + { + "subdir8", []entry{ + {"doesntexist", 0, false}, // entry is returned even if destination file doesn't exist + }, + }, + { + // check that read dir actually redirects files that already exist + // the original this_file_is_overlaid.txt is empty + "subdir9", []entry{ + {"this_file_is_overlaid.txt", 9, false}, + }, + }, + { + "subdir10", []entry{}, + }, + { + "parentoverwritten", []entry{ + {"subdir1", 2, false}, + }, + }, + { + "textfile.txt", []entry{ + {"file.go", 2, false}, + }, + }, + } + + for _, tc := range testCases { + dir, want := tc.dir, tc.want + infos, err := ReadDir(dir) + if err != nil { + t.Errorf("ReadDir(%q): %v", dir, err) + continue + } + // Sorted diff of want and infos. + for len(infos) > 0 || len(want) > 0 { + switch { + case len(want) == 0 || len(infos) > 0 && infos[0].Name() < want[0].name: + t.Errorf("ReadDir(%q): unexpected entry: %s IsDir=%v Size=%v", dir, infos[0].Name(), infos[0].IsDir(), infos[0].Size()) + infos = infos[1:] + case len(infos) == 0 || len(want) > 0 && want[0].name < infos[0].Name(): + t.Errorf("ReadDir(%q): missing entry: %s IsDir=%v Size=%v", dir, want[0].name, want[0].isDir, want[0].size) + want = want[1:] + default: + infoSize := infos[0].Size() + if want[0].isDir { + infoSize = 0 + } + if infos[0].IsDir() != want[0].isDir || want[0].isDir && infoSize != want[0].size { + t.Errorf("ReadDir(%q): %s: IsDir=%v Size=%v, want IsDir=%v Size=%v", dir, want[0].name, infos[0].IsDir(), infoSize, want[0].isDir, want[0].size) + } + infos = infos[1:] + want = want[1:] + } + } + } + + errCases := []string{ + "subdir1/file1.txt", // regular file on disk + "subdir2/file2.txt", // regular file in overlay + "subdir4", // directory overlaid with regular file + "subdir5", // directory deleted in overlay + "parentoverwritten/subdir1/subdir2/subdir3", // parentoverwritten/subdir1 overlaid with regular file + "parentoverwritten/subdir1/subdir2", // parentoverwritten/subdir1 overlaid with regular file + "subdir11", // directory with deleted child, overlaid with regular file + "other/pointstodir", + } + + for _, dir := range errCases { + _, err := ReadDir(dir) + if _, ok := err.(*fs.PathError); !ok { + t.Errorf("ReadDir(%q): err = %T (%v), want fs.PathError", dir, err, err) + } + } +} + +func TestGlob(t *testing.T) { + initOverlay(t, readDirOverlay) + + testCases := []struct { + pattern string + match []string + }{ + { + "*o*", + []string{ + "other", + "overlayfiles", + "parentoverwritten", + }, + }, + { + "subdir2/file2.txt", + []string{ + "subdir2/file2.txt", + }, + }, + { + "*/*.txt", + []string{ + "overlayfiles/subdir2_file2.txt", + "overlayfiles/subdir3_file3b.txt", + "overlayfiles/subdir6_asubsubdir_afile.txt", + "overlayfiles/subdir6_asubsubdir_zfile.txt", + "overlayfiles/subdir6_zsubsubdir_file.txt", + "overlayfiles/subdir7_asubsubdir_file.txt", + "overlayfiles/subdir7_zsubsubdir_file.txt", + "overlayfiles/subdir9_this_file_is_overlaid.txt", + "subdir1/file1.txt", + "subdir2/file2.txt", + "subdir3/file3a.txt", + "subdir3/file3b.txt", + "subdir6/file.txt", + "subdir9/this_file_is_overlaid.txt", + }, + }, + } + + for _, tc := range testCases { + pattern := tc.pattern + match, err := Glob(pattern) + if err != nil { + t.Errorf("Glob(%q): %v", pattern, err) + continue + } + want := tc.match + for i, name := range want { + if name != tc.pattern { + want[i] = filepath.FromSlash(name) + } + } + for len(match) > 0 || len(want) > 0 { + switch { + case len(match) == 0 || len(want) > 0 && want[0] < match[0]: + t.Errorf("Glob(%q): missing match: %s", pattern, want[0]) + want = want[1:] + case len(want) == 0 || len(match) > 0 && match[0] < want[0]: + t.Errorf("Glob(%q): extra match: %s", pattern, match[0]) + match = match[1:] + default: + want = want[1:] + match = match[1:] + } + } + } +} + +func TestOverlayPath(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "subdir2/file2.txt": "overlayfiles/subdir2_file2.txt", + "subdir3/doesntexist": "this_file_doesnt_exist_anywhere", + "subdir4/this_file_is_overlaid.txt": "overlayfiles/subdir4_this_file_is_overlaid.txt", + "subdir5/deleted.txt": "", + "parentoverwritten/subdir1": "" + } +} +-- subdir1/file1.txt -- +file 1 +-- subdir4/this_file_is_overlaid.txt -- +these contents are replaced by the overlay +-- parentoverwritten/subdir1/subdir2/subdir3/file.txt -- +-- subdir5/deleted.txt -- +deleted +-- overlayfiles/subdir2_file2.txt -- +file 2 +-- overlayfiles/subdir4_this_file_is_overlaid.txt -- +99999999 +`) + + testCases := []struct { + path string + wantPath string + wantOK bool + }{ + {"subdir1/file1.txt", "subdir1/file1.txt", false}, + // OverlayPath returns false for directories + {"subdir2", "subdir2", false}, + {"subdir2/file2.txt", filepath.Join(cwd, "overlayfiles/subdir2_file2.txt"), true}, + // OverlayPath doesn't stat a file to see if it exists, so it happily returns + // the 'to' path and true even if the 'to' path doesn't exist on disk. + {"subdir3/doesntexist", filepath.Join(cwd, "this_file_doesnt_exist_anywhere"), true}, + // Like the subdir2/file2.txt case above, but subdir4 exists on disk, but subdir2 does not. + {"subdir4/this_file_is_overlaid.txt", filepath.Join(cwd, "overlayfiles/subdir4_this_file_is_overlaid.txt"), true}, + {"subdir5", "subdir5", false}, + {"subdir5/deleted.txt", "", true}, + } + + for _, tc := range testCases { + gotPath, gotOK := OverlayPath(tc.path) + if gotPath != tc.wantPath || gotOK != tc.wantOK { + t.Errorf("OverlayPath(%q): got %v, %v; want %v, %v", + tc.path, gotPath, gotOK, tc.wantPath, tc.wantOK) + } + } +} + +func TestOpen(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "subdir2/file2.txt": "overlayfiles/subdir2_file2.txt", + "subdir3/doesntexist": "this_file_doesnt_exist_anywhere", + "subdir4/this_file_is_overlaid.txt": "overlayfiles/subdir4_this_file_is_overlaid.txt", + "subdir5/deleted.txt": "", + "parentoverwritten/subdir1": "", + "childoverlay/subdir1.txt/child.txt": "overlayfiles/child.txt", + "subdir11/deleted.txt": "", + "subdir11": "overlayfiles/subdir11", + "parentdeleted": "", + "parentdeleted/file.txt": "overlayfiles/parentdeleted_file.txt" + } +} +-- subdir11/deleted.txt -- +-- subdir1/file1.txt -- +file 1 +-- subdir4/this_file_is_overlaid.txt -- +these contents are replaced by the overlay +-- parentoverwritten/subdir1/subdir2/subdir3/file.txt -- +-- childoverlay/subdir1.txt -- +this file doesn't exist because the path +childoverlay/subdir1.txt/child.txt is in the overlay +-- subdir5/deleted.txt -- +deleted +-- parentdeleted -- +this will be deleted so that parentdeleted/file.txt can exist +-- overlayfiles/subdir2_file2.txt -- +file 2 +-- overlayfiles/subdir4_this_file_is_overlaid.txt -- +99999999 +-- overlayfiles/child.txt -- +-- overlayfiles/subdir11 -- +11 +-- overlayfiles/parentdeleted_file.txt -- +this can exist because the parent directory is deleted +`) + + testCases := []struct { + path string + wantContents string + isErr bool + }{ + {"subdir1/file1.txt", "file 1\n", false}, + {"subdir2/file2.txt", "file 2\n", false}, + {"subdir3/doesntexist", "", true}, + {"subdir4/this_file_is_overlaid.txt", "99999999\n", false}, + {"subdir5/deleted.txt", "", true}, + {"parentoverwritten/subdir1/subdir2/subdir3/file.txt", "", true}, + {"childoverlay/subdir1.txt", "", true}, + {"subdir11", "11\n", false}, + {"parentdeleted/file.txt", "this can exist because the parent directory is deleted\n", false}, + } + + for _, tc := range testCases { + f, err := Open(tc.path) + if tc.isErr { + if err == nil { + f.Close() + t.Errorf("Open(%q): got no error, but want error", tc.path) + } + continue + } + if err != nil { + t.Errorf("Open(%q): got error %v, want nil", tc.path, err) + continue + } + contents, err := io.ReadAll(f) + if err != nil { + t.Errorf("unexpected error reading contents of file: %v", err) + } + if string(contents) != tc.wantContents { + t.Errorf("contents of file opened with Open(%q): got %q, want %q", + tc.path, contents, tc.wantContents) + } + f.Close() + } +} + +func TestIsDirWithGoFiles(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "goinoverlay/file.go": "dummy", + "directory/removed/by/file": "dummy", + "directory_with_go_dir/dir.go/file.txt": "dummy", + "otherdirectory/deleted.go": "", + "nonexistentdirectory/deleted.go": "", + "textfile.txt/file.go": "dummy" + } +} +-- dummy -- +a destination file for the overlay entries to point to +contents don't matter for this test +-- nogo/file.txt -- +-- goondisk/file.go -- +-- goinoverlay/file.txt -- +-- directory/removed/by/file/in/overlay/file.go -- +-- otherdirectory/deleted.go -- +-- textfile.txt -- +`) + + testCases := []struct { + dir string + want bool + wantErr bool + }{ + {"nogo", false, false}, + {"goondisk", true, false}, + {"goinoverlay", true, false}, + {"directory/removed/by/file/in/overlay", false, false}, + {"directory_with_go_dir", false, false}, + {"otherdirectory", false, false}, + {"nonexistentdirectory", false, false}, + {"textfile.txt", true, false}, + } + + for _, tc := range testCases { + got, gotErr := IsDirWithGoFiles(tc.dir) + if tc.wantErr { + if gotErr == nil { + t.Errorf("IsDirWithGoFiles(%q): got %v, %v; want non-nil error", tc.dir, got, gotErr) + } + continue + } + if gotErr != nil { + t.Errorf("IsDirWithGoFiles(%q): got %v, %v; want nil error", tc.dir, got, gotErr) + } + if got != tc.want { + t.Errorf("IsDirWithGoFiles(%q) = %v; want %v", tc.dir, got, tc.want) + } + } +} + +func TestWalk(t *testing.T) { + // The root of the walk must be a name with an actual basename, not just ".". + // Walk uses Lstat to obtain the name of the root, and Lstat on platforms + // other than Plan 9 reports the name "." instead of the actual base name of + // the directory. (See https://golang.org/issue/42115.) + + type file struct { + path string + name string + size int64 + mode fs.FileMode + isDir bool + } + testCases := []struct { + name string + overlay string + root string + wantFiles []file + }{ + {"no overlay", ` +{} +-- dir/file.txt -- +`, + "dir", + []file{ + {"dir", "dir", 0, fs.ModeDir | 0700, true}, + {"dir/file.txt", "file.txt", 0, 0600, false}, + }, + }, + {"overlay with different file", ` +{ + "Replace": { + "dir/file.txt": "dir/other.txt" + } +} +-- dir/file.txt -- +-- dir/other.txt -- +contents of other file +`, + "dir", + []file{ + {"dir", "dir", 0, fs.ModeDir | 0500, true}, + {"dir/file.txt", "file.txt", 23, 0600, false}, + {"dir/other.txt", "other.txt", 23, 0600, false}, + }, + }, + {"overlay with new file", ` +{ + "Replace": { + "dir/file.txt": "dir/other.txt" + } +} +-- dir/other.txt -- +contents of other file +`, + "dir", + []file{ + {"dir", "dir", 0, fs.ModeDir | 0500, true}, + {"dir/file.txt", "file.txt", 23, 0600, false}, + {"dir/other.txt", "other.txt", 23, 0600, false}, + }, + }, + {"overlay with new directory", ` +{ + "Replace": { + "dir/subdir/file.txt": "dir/other.txt" + } +} +-- dir/other.txt -- +contents of other file +`, + "dir", + []file{ + {"dir", "dir", 0, fs.ModeDir | 0500, true}, + {"dir/other.txt", "other.txt", 23, 0600, false}, + {"dir/subdir", "subdir", 0, fs.ModeDir | 0500, true}, + {"dir/subdir/file.txt", "file.txt", 23, 0600, false}, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + initOverlay(t, tc.overlay) + + var got []file + Walk(tc.root, func(path string, info fs.FileInfo, err error) error { + got = append(got, file{path, info.Name(), info.Size(), info.Mode(), info.IsDir()}) + return nil + }) + + if len(got) != len(tc.wantFiles) { + t.Errorf("Walk: saw %#v in walk; want %#v", got, tc.wantFiles) + } + for i := 0; i < len(got) && i < len(tc.wantFiles); i++ { + wantPath := filepath.FromSlash(tc.wantFiles[i].path) + if got[i].path != wantPath { + t.Errorf("path of file #%v in walk, got %q, want %q", i, got[i].path, wantPath) + } + if got[i].name != tc.wantFiles[i].name { + t.Errorf("name of file #%v in walk, got %q, want %q", i, got[i].name, tc.wantFiles[i].name) + } + if got[i].mode&(fs.ModeDir|0700) != tc.wantFiles[i].mode { + t.Errorf("mode&(fs.ModeDir|0700) for mode of file #%v in walk, got %v, want %v", i, got[i].mode&(fs.ModeDir|0700), tc.wantFiles[i].mode) + } + if got[i].isDir != tc.wantFiles[i].isDir { + t.Errorf("isDir for file #%v in walk, got %v, want %v", i, got[i].isDir, tc.wantFiles[i].isDir) + } + if tc.wantFiles[i].isDir { + continue // don't check size for directories + } + if got[i].size != tc.wantFiles[i].size { + t.Errorf("size of file #%v in walk, got %v, want %v", i, got[i].size, tc.wantFiles[i].size) + } + } + }) + } +} + +func TestWalkSkipDir(t *testing.T) { + initOverlay(t, ` +{ + "Replace": { + "dir/skip/file.go": "dummy.txt", + "dir/dontskip/file.go": "dummy.txt", + "dir/dontskip/skip/file.go": "dummy.txt" + } +} +-- dummy.txt -- +`) + + var seen []string + Walk("dir", func(path string, info fs.FileInfo, err error) error { + seen = append(seen, filepath.ToSlash(path)) + if info.Name() == "skip" { + return filepath.SkipDir + } + return nil + }) + + wantSeen := []string{"dir", "dir/dontskip", "dir/dontskip/file.go", "dir/dontskip/skip", "dir/skip"} + + if len(seen) != len(wantSeen) { + t.Errorf("paths seen in walk: got %v entries; want %v entries", len(seen), len(wantSeen)) + } + + for i := 0; i < len(seen) && i < len(wantSeen); i++ { + if seen[i] != wantSeen[i] { + t.Errorf("path #%v seen walking tree: want %q, got %q", i, seen[i], wantSeen[i]) + } + } +} + +func TestWalkError(t *testing.T) { + initOverlay(t, "{}") + + alreadyCalled := false + err := Walk("foo", func(path string, info fs.FileInfo, err error) error { + if alreadyCalled { + t.Fatal("expected walk function to be called exactly once, but it was called more than once") + } + alreadyCalled = true + return errors.New("returned from function") + }) + if !alreadyCalled { + t.Fatal("expected walk function to be called exactly once, but it was never called") + + } + if err == nil { + t.Fatalf("Walk: got no error, want error") + } + if err.Error() != "returned from function" { + t.Fatalf("Walk: got error %v, want \"returned from function\" error", err) + } +} + +func TestWalkSymlink(t *testing.T) { + testenv.MustHaveSymlink(t) + + initOverlay(t, `{ + "Replace": {"overlay_symlink": "symlink"} +} +-- dir/file --`) + + // Create symlink + if err := os.Symlink("dir", "symlink"); err != nil { + t.Error(err) + } + + testCases := []struct { + name string + dir string + wantFiles []string + }{ + {"control", "dir", []string{"dir", "dir" + string(filepath.Separator) + "file"}}, + // ensure Walk doesn't walk into the directory pointed to by the symlink + // (because it's supposed to use Lstat instead of Stat). + {"symlink_to_dir", "symlink", []string{"symlink"}}, + {"overlay_to_symlink_to_dir", "overlay_symlink", []string{"overlay_symlink"}}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var got []string + + err := Walk(tc.dir, func(path string, info fs.FileInfo, err error) error { + got = append(got, path) + if err != nil { + t.Errorf("walkfn: got non nil err argument: %v, want nil err argument", err) + } + return nil + }) + if err != nil { + t.Errorf("Walk: got error %q, want nil", err) + } + + if !reflect.DeepEqual(got, tc.wantFiles) { + t.Errorf("files examined by walk: got %v, want %v", got, tc.wantFiles) + } + }) + } + +} + +func TestLstat(t *testing.T) { + type file struct { + name string + size int64 + mode fs.FileMode // mode & (fs.ModeDir|0x700): only check 'user' permissions + isDir bool + } + + testCases := []struct { + name string + overlay string + path string + + want file + wantErr bool + }{ + { + "regular_file", + `{} +-- file.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "new_file_in_overlay", + `{"Replace": {"file.txt": "dummy.txt"}} +-- dummy.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "file_replaced_in_overlay", + `{"Replace": {"file.txt": "dummy.txt"}} +-- file.txt -- +-- dummy.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "file_cant_exist", + `{"Replace": {"deleted": "dummy.txt"}} +-- deleted/file.txt -- +-- dummy.txt -- +`, + "deleted/file.txt", + file{}, + true, + }, + { + "deleted", + `{"Replace": {"deleted": ""}} +-- deleted -- +`, + "deleted", + file{}, + true, + }, + { + "dir_on_disk", + `{} +-- dir/foo.txt -- +`, + "dir", + file{"dir", 0, 0700 | fs.ModeDir, true}, + false, + }, + { + "dir_in_overlay", + `{"Replace": {"dir/file.txt": "dummy.txt"}} +-- dummy.txt -- +`, + "dir", + file{"dir", 0, 0500 | fs.ModeDir, true}, + false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + initOverlay(t, tc.overlay) + got, err := Lstat(tc.path) + if tc.wantErr { + if err == nil { + t.Errorf("lstat(%q): got no error, want error", tc.path) + } + return + } + if err != nil { + t.Fatalf("lstat(%q): got error %v, want no error", tc.path, err) + } + if got.Name() != tc.want.name { + t.Errorf("lstat(%q).Name(): got %q, want %q", tc.path, got.Name(), tc.want.name) + } + if got.Mode()&(fs.ModeDir|0700) != tc.want.mode { + t.Errorf("lstat(%q).Mode()&(fs.ModeDir|0700): got %v, want %v", tc.path, got.Mode()&(fs.ModeDir|0700), tc.want.mode) + } + if got.IsDir() != tc.want.isDir { + t.Errorf("lstat(%q).IsDir(): got %v, want %v", tc.path, got.IsDir(), tc.want.isDir) + } + if tc.want.isDir { + return // don't check size for directories + } + if got.Size() != tc.want.size { + t.Errorf("lstat(%q).Size(): got %v, want %v", tc.path, got.Size(), tc.want.size) + } + }) + } +} + +func TestStat(t *testing.T) { + testenv.MustHaveSymlink(t) + + type file struct { + name string + size int64 + mode os.FileMode // mode & (os.ModeDir|0x700): only check 'user' permissions + isDir bool + } + + testCases := []struct { + name string + overlay string + path string + + want file + wantErr bool + }{ + { + "regular_file", + `{} +-- file.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "new_file_in_overlay", + `{"Replace": {"file.txt": "dummy.txt"}} +-- dummy.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "file_replaced_in_overlay", + `{"Replace": {"file.txt": "dummy.txt"}} +-- file.txt -- +-- dummy.txt -- +contents`, + "file.txt", + file{"file.txt", 9, 0600, false}, + false, + }, + { + "file_cant_exist", + `{"Replace": {"deleted": "dummy.txt"}} +-- deleted/file.txt -- +-- dummy.txt -- +`, + "deleted/file.txt", + file{}, + true, + }, + { + "deleted", + `{"Replace": {"deleted": ""}} +-- deleted -- +`, + "deleted", + file{}, + true, + }, + { + "dir_on_disk", + `{} +-- dir/foo.txt -- +`, + "dir", + file{"dir", 0, 0700 | os.ModeDir, true}, + false, + }, + { + "dir_in_overlay", + `{"Replace": {"dir/file.txt": "dummy.txt"}} +-- dummy.txt -- +`, + "dir", + file{"dir", 0, 0500 | os.ModeDir, true}, + false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + initOverlay(t, tc.overlay) + got, err := Stat(tc.path) + if tc.wantErr { + if err == nil { + t.Errorf("Stat(%q): got no error, want error", tc.path) + } + return + } + if err != nil { + t.Fatalf("Stat(%q): got error %v, want no error", tc.path, err) + } + if got.Name() != tc.want.name { + t.Errorf("Stat(%q).Name(): got %q, want %q", tc.path, got.Name(), tc.want.name) + } + if got.Mode()&(os.ModeDir|0700) != tc.want.mode { + t.Errorf("Stat(%q).Mode()&(os.ModeDir|0700): got %v, want %v", tc.path, got.Mode()&(os.ModeDir|0700), tc.want.mode) + } + if got.IsDir() != tc.want.isDir { + t.Errorf("Stat(%q).IsDir(): got %v, want %v", tc.path, got.IsDir(), tc.want.isDir) + } + if tc.want.isDir { + return // don't check size for directories + } + if got.Size() != tc.want.size { + t.Errorf("Stat(%q).Size(): got %v, want %v", tc.path, got.Size(), tc.want.size) + } + }) + } +} + +func TestStatSymlink(t *testing.T) { + testenv.MustHaveSymlink(t) + + initOverlay(t, `{ + "Replace": {"file.go": "symlink"} +} +-- to.go -- +0123456789 +`) + + // Create symlink + if err := os.Symlink("to.go", "symlink"); err != nil { + t.Error(err) + } + + f := "file.go" + fi, err := Stat(f) + if err != nil { + t.Errorf("Stat(%q): got error %q, want nil error", f, err) + } + + if !fi.Mode().IsRegular() { + t.Errorf("Stat(%q).Mode(): got %v, want regular mode", f, fi.Mode()) + } + + if fi.Size() != 11 { + t.Errorf("Stat(%q).Size(): got %v, want 11", f, fi.Size()) + } +} diff --git a/libgo/go/cmd/go/internal/generate/generate.go b/libgo/go/cmd/go/internal/generate/generate.go index 093b19817b5..c7401948b8b 100644 --- a/libgo/go/cmd/go/internal/generate/generate.go +++ b/libgo/go/cmd/go/internal/generate/generate.go @@ -8,11 +8,11 @@ package generate import ( "bufio" "bytes" + "context" "fmt" "go/parser" "go/token" "io" - "io/ioutil" "log" "os" "os/exec" @@ -160,7 +160,7 @@ func init() { CmdGenerate.Flag.StringVar(&generateRunFlag, "run", "", "") } -func runGenerate(cmd *base.Command, args []string) { +func runGenerate(ctx context.Context, cmd *base.Command, args []string) { load.IgnoreImports = true if generateRunFlag != "" { @@ -175,7 +175,7 @@ func runGenerate(cmd *base.Command, args []string) { // Even if the arguments are .go files, this loop suffices. printed := false - for _, pkg := range load.PackagesAndErrors(args) { + for _, pkg := range load.PackagesAndErrors(ctx, args) { if modload.Enabled() && pkg.Module != nil && !pkg.Module.Main { if !printed { fmt.Fprintf(os.Stderr, "go: not generating in packages in dependency modules\n") @@ -200,7 +200,7 @@ func runGenerate(cmd *base.Command, args []string) { // generate runs the generation directives for a single file. func generate(absFile string) bool { - src, err := ioutil.ReadFile(absFile) + src, err := os.ReadFile(absFile) if err != nil { log.Fatalf("generate: %s", err) } diff --git a/libgo/go/cmd/go/internal/get/get.go b/libgo/go/cmd/go/internal/get/get.go index d38350c2a82..94a42c4f73a 100644 --- a/libgo/go/cmd/go/internal/get/get.go +++ b/libgo/go/cmd/go/internal/get/get.go @@ -6,6 +6,7 @@ package get import ( + "context" "fmt" "os" "path/filepath" @@ -17,8 +18,11 @@ import ( "cmd/go/internal/load" "cmd/go/internal/search" "cmd/go/internal/str" + "cmd/go/internal/vcs" "cmd/go/internal/web" "cmd/go/internal/work" + + "golang.org/x/mod/module" ) var CmdGet = &base.Command{ @@ -41,6 +45,10 @@ before resolving dependencies or building the code. The -insecure flag permits fetching from repositories and resolving custom domains using insecure schemes such as HTTP. Use with caution. +This flag is deprecated and will be removed in a future version of go. +The GOINSECURE environment variable should be used instead, since it +provides control over which packages may be retrieved using an insecure +scheme. See 'go help environment' for details. The -t flag instructs get to also download the packages required to build the tests for the specified packages. @@ -102,17 +110,15 @@ var ( getT = CmdGet.Flag.Bool("t", false, "") getU = CmdGet.Flag.Bool("u", false, "") getFix = CmdGet.Flag.Bool("fix", false, "") - - Insecure bool ) func init() { work.AddBuildFlags(CmdGet, work.OmitModFlag|work.OmitModCommonFlags) CmdGet.Run = runGet // break init loop - CmdGet.Flag.BoolVar(&Insecure, "insecure", Insecure, "") + CmdGet.Flag.BoolVar(&cfg.Insecure, "insecure", cfg.Insecure, "") } -func runGet(cmd *base.Command, args []string) { +func runGet(ctx context.Context, cmd *base.Command, args []string) { if cfg.ModulesEnabled { // Should not happen: main.go should install the separate module-enabled get code. base.Fatalf("go get: modules not implemented") @@ -123,6 +129,9 @@ func runGet(cmd *base.Command, args []string) { if *getF && !*getU { base.Fatalf("go get: cannot use -f flag without -u") } + if cfg.Insecure { + fmt.Fprintf(os.Stderr, "go get: -insecure flag is deprecated; see 'go help get' for details\n") + } // Disable any prompting for passwords by Git. // Only has an effect for 2.3.0 or later, but avoiding @@ -171,17 +180,18 @@ func runGet(cmd *base.Command, args []string) { // everything. load.ClearPackageCache() - pkgs := load.PackagesForBuild(args) + pkgs := load.PackagesAndErrors(ctx, args) + load.CheckPackageErrors(pkgs) // Phase 3. Install. if *getD { // Download only. - // Check delayed until now so that importPaths - // and packagesForBuild have a chance to print errors. + // Check delayed until now so that downloadPaths + // and CheckPackageErrors have a chance to print errors. return } - work.InstallPackages(args, pkgs) + work.InstallPackages(ctx, args, pkgs) } // downloadPaths prepares the list of paths to pass to download. @@ -245,9 +255,9 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) load1 := func(path string, mode int) *load.Package { if parent == nil { mode := 0 // don't do module or vendor resolution - return load.LoadImport(path, base.Cwd, nil, stk, nil, mode) + return load.LoadImport(context.TODO(), path, base.Cwd, nil, stk, nil, mode) } - return load.LoadImport(path, parent.Dir, parent, stk, nil, mode|load.ResolveModule) + return load.LoadImport(context.TODO(), path, parent.Dir, parent, stk, nil, mode|load.ResolveModule) } p := load1(arg, mode) @@ -402,17 +412,12 @@ func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) // to make the first copy of or update a copy of the given package. func downloadPackage(p *load.Package) error { var ( - vcs *vcsCmd + vcsCmd *vcs.Cmd repo, rootPath string err error blindRepo bool // set if the repo has unusual configuration ) - security := web.SecureOnly - if Insecure { - security = web.Insecure - } - // p can be either a real package, or a pseudo-package whose “import path” is // actually a wildcard pattern. // Trim the path at the element containing the first wildcard, @@ -426,22 +431,26 @@ func downloadPackage(p *load.Package) error { } importPrefix = importPrefix[:slash] } - if err := CheckImportPath(importPrefix); err != nil { + if err := module.CheckImportPath(importPrefix); err != nil { return fmt.Errorf("%s: invalid import path: %v", p.ImportPath, err) } + security := web.SecureOnly + if cfg.Insecure || module.MatchPrefixPatterns(cfg.GOINSECURE, importPrefix) { + security = web.Insecure + } if p.Internal.Build.SrcRoot != "" { // Directory exists. Look for checkout along path to src. - vcs, rootPath, err = vcsFromDir(p.Dir, p.Internal.Build.SrcRoot) + vcsCmd, rootPath, err = vcs.FromDir(p.Dir, p.Internal.Build.SrcRoot) if err != nil { return err } repo = "" // should be unused; make distinctive // Double-check where it came from. - if *getU && vcs.remoteRepo != nil { + if *getU && vcsCmd.RemoteRepo != nil { dir := filepath.Join(p.Internal.Build.SrcRoot, filepath.FromSlash(rootPath)) - remote, err := vcs.remoteRepo(vcs, dir) + remote, err := vcsCmd.RemoteRepo(vcsCmd, dir) if err != nil { // Proceed anyway. The package is present; we likely just don't understand // the repo configuration (e.g. unusual remote protocol). @@ -449,10 +458,10 @@ func downloadPackage(p *load.Package) error { } repo = remote if !*getF && err == nil { - if rr, err := RepoRootForImportPath(importPrefix, IgnoreMod, security); err == nil { + if rr, err := vcs.RepoRootForImportPath(importPrefix, vcs.IgnoreMod, security); err == nil { repo := rr.Repo - if rr.vcs.resolveRepo != nil { - resolved, err := rr.vcs.resolveRepo(rr.vcs, dir, repo) + if rr.VCS.ResolveRepo != nil { + resolved, err := rr.VCS.ResolveRepo(rr.VCS, dir, repo) if err == nil { repo = resolved } @@ -466,13 +475,13 @@ func downloadPackage(p *load.Package) error { } else { // Analyze the import path to determine the version control system, // repository, and the import path for the root of the repository. - rr, err := RepoRootForImportPath(importPrefix, IgnoreMod, security) + rr, err := vcs.RepoRootForImportPath(importPrefix, vcs.IgnoreMod, security) if err != nil { return err } - vcs, repo, rootPath = rr.vcs, rr.Repo, rr.Root + vcsCmd, repo, rootPath = rr.VCS, rr.Repo, rr.Root } - if !blindRepo && !vcs.isSecure(repo) && !Insecure { + if !blindRepo && !vcsCmd.IsSecure(repo) && security != web.Insecure { return fmt.Errorf("cannot download, %v uses insecure protocol", repo) } @@ -495,7 +504,7 @@ func downloadPackage(p *load.Package) error { } root := filepath.Join(p.Internal.Build.SrcRoot, filepath.FromSlash(rootPath)) - if err := checkNestedVCS(vcs, root, p.Internal.Build.SrcRoot); err != nil { + if err := vcs.CheckNested(vcsCmd, root, p.Internal.Build.SrcRoot); err != nil { return err } @@ -511,7 +520,7 @@ func downloadPackage(p *load.Package) error { // Check that this is an appropriate place for the repo to be checked out. // The target directory must either not exist or have a repo checked out already. - meta := filepath.Join(root, "."+vcs.cmd) + meta := filepath.Join(root, "."+vcsCmd.Cmd) if _, err := os.Stat(meta); err != nil { // Metadata file or directory does not exist. Prepare to checkout new copy. // Some version control tools require the target directory not to exist. @@ -532,12 +541,12 @@ func downloadPackage(p *load.Package) error { fmt.Fprintf(os.Stderr, "created GOPATH=%s; see 'go help gopath'\n", p.Internal.Build.Root) } - if err = vcs.create(root, repo); err != nil { + if err = vcsCmd.Create(root, repo); err != nil { return err } } else { // Metadata directory does exist; download incremental updates. - if err = vcs.download(root); err != nil { + if err = vcsCmd.Download(root); err != nil { return err } } @@ -546,12 +555,12 @@ func downloadPackage(p *load.Package) error { // Do not show tag sync in -n; it's noise more than anything, // and since we're not running commands, no tag will be found. // But avoid printing nothing. - fmt.Fprintf(os.Stderr, "# cd %s; %s sync/update\n", root, vcs.cmd) + fmt.Fprintf(os.Stderr, "# cd %s; %s sync/update\n", root, vcsCmd.Cmd) return nil } // Select and sync to appropriate version of the repository. - tags, err := vcs.tags(root) + tags, err := vcsCmd.Tags(root) if err != nil { return err } @@ -559,7 +568,7 @@ func downloadPackage(p *load.Package) error { if i := strings.Index(vers, " "); i >= 0 { vers = vers[:i] } - if err := vcs.tagSync(root, selectTag(vers, tags)); err != nil { + if err := vcsCmd.TagSync(root, selectTag(vers, tags)); err != nil { return err } diff --git a/libgo/go/cmd/go/internal/get/path.go b/libgo/go/cmd/go/internal/get/path.go deleted file mode 100644 index ce2e0cdd709..00000000000 --- a/libgo/go/cmd/go/internal/get/path.go +++ /dev/null @@ -1,192 +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 get - -import ( - "fmt" - "strings" - "unicode" - "unicode/utf8" -) - -// 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). -// -// TODO(bcmills): After the call site for this function is backported, -// consolidate this back down to a single copy. -// -// NOTE: DO NOT MERGE THESE UNTIL WE DECIDE ABOUT ARBITRARY LETTERS IN MODULE MODE. - -// 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 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("disallowed path element %q", elem) - } - } - - // Reject path components that look like Windows short-names. - // Those usually end in a tilde followed by one or more ASCII digits. - if tilde := strings.LastIndexByte(short, '~'); tilde >= 0 && tilde < len(short)-1 { - suffix := short[tilde+1:] - suffixIsDigits := true - for _, r := range suffix { - if r < '0' || r > '9' { - suffixIsDigits = false - break - } - } - if suffixIsDigits { - return fmt.Errorf("trailing tilde and digits in path element") - } - } - - return nil -} - -// pathOK reports whether r can appear in an import path element. -// -// NOTE: This function DIVERGES from module mode pathOK by accepting Unicode letters. -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 unicode.IsLetter(r) -} - -// 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) -} - -// 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", -} diff --git a/libgo/go/cmd/go/internal/help/helpdoc.go b/libgo/go/cmd/go/internal/help/helpdoc.go index e1f0521ea41..98f58441b4d 100644 --- a/libgo/go/cmd/go/internal/help/helpdoc.go +++ b/libgo/go/cmd/go/internal/help/helpdoc.go @@ -526,7 +526,7 @@ General-purpose environment variables: Comma-separated list of glob patterns (in the syntax of Go's path.Match) of module path prefixes that should always be fetched directly or that should not be compared against the checksum database. - See 'go help module-private'. + See 'go help private'. GOROOT The root of the go tree. GOSUMDB @@ -582,8 +582,8 @@ Architecture-specific environment variables: For GOARCH=arm, the ARM architecture for which to compile. Valid values are 5, 6, 7. GO386 - For GOARCH=386, the floating point instruction set. - Valid values are 387, sse2. + For GOARCH=386, how to implement floating point instructions. + Valid values are sse2 (default), softfloat. GOMIPS For GOARCH=mips{,le}, whether to use floating point instructions. Valid values are hardfloat (default), softfloat. @@ -632,6 +632,8 @@ Additional information available from 'go env' but not read from the environment 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. + GOVERSION + The version of the installed Go tree, as reported by runtime.Version. `, } @@ -838,6 +840,9 @@ in addition to android tags and files. Using GOOS=illumos matches build tags and files as for GOOS=solaris in addition to illumos tags and files. +Using GOOS=ios matches build tags and files as for GOOS=darwin +in addition to ios tags and files. + To keep a file from being considered for the build: // +build ignore diff --git a/libgo/go/cmd/go/internal/imports/build.go b/libgo/go/cmd/go/internal/imports/build.go index eb070eef4c1..50aeabc578c 100644 --- a/libgo/go/cmd/go/internal/imports/build.go +++ b/libgo/go/cmd/go/internal/imports/build.go @@ -141,6 +141,9 @@ func matchTag(name string, tags map[string]bool, want bool) bool { if name == "solaris" { have = have || tags["illumos"] } + if name == "darwin" { + have = have || tags["ios"] + } return have == want } @@ -158,6 +161,7 @@ func matchTag(name string, tags map[string]bool, want bool) bool { // Exceptions: // if GOOS=android, then files with GOOS=linux are also matched. // if GOOS=illumos, then files with GOOS=solaris are also matched. +// if GOOS=ios, then files with GOOS=darwin are also matched. // // If tags["*"] is true, then MatchFile will consider all possible // GOOS and GOARCH to be available and will consequently @@ -208,6 +212,7 @@ var KnownOS = map[string]bool{ "freebsd": true, "hurd": true, "illumos": true, + "ios": true, "js": true, "linux": true, "nacl": true, // legacy; don't remove diff --git a/libgo/go/cmd/go/internal/imports/read.go b/libgo/go/cmd/go/internal/imports/read.go index 58c2abdc29a..5e270781d77 100644 --- a/libgo/go/cmd/go/internal/imports/read.go +++ b/libgo/go/cmd/go/internal/imports/read.go @@ -198,7 +198,7 @@ func (r *importReader) readImport(imports *[]string) { r.readString(imports) } -// ReadComments is like ioutil.ReadAll, except that it only reads the leading +// ReadComments is like io.ReadAll, except that it only reads the leading // block of comments in the file. func ReadComments(f io.Reader) ([]byte, error) { r := &importReader{b: bufio.NewReader(f)} @@ -210,7 +210,7 @@ func ReadComments(f io.Reader) ([]byte, error) { return r.buf, r.err } -// ReadImports is like ioutil.ReadAll, except that it expects a Go file as input +// ReadImports is like io.ReadAll, except that it expects a Go file as input // and stops reading the input once the imports have completed. func ReadImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) { r := &importReader{b: bufio.NewReader(f)} diff --git a/libgo/go/cmd/go/internal/imports/scan.go b/libgo/go/cmd/go/internal/imports/scan.go index 3d9b6132b12..ee11a8708b5 100644 --- a/libgo/go/cmd/go/internal/imports/scan.go +++ b/libgo/go/cmd/go/internal/imports/scan.go @@ -6,16 +6,17 @@ package imports import ( "fmt" - "io/ioutil" - "os" + "io/fs" "path/filepath" "sort" "strconv" "strings" + + "cmd/go/internal/fsys" ) func ScanDir(dir string, tags map[string]bool) ([]string, []string, error) { - infos, err := ioutil.ReadDir(dir) + infos, err := fsys.ReadDir(dir) if err != nil { return nil, nil, err } @@ -25,14 +26,14 @@ func ScanDir(dir string, tags map[string]bool) ([]string, []string, error) { // If the directory entry is a symlink, stat it to obtain the info for the // link target instead of the link itself. - if info.Mode()&os.ModeSymlink != 0 { - info, err = os.Stat(filepath.Join(dir, name)) + if info.Mode()&fs.ModeSymlink != 0 { + info, err = fsys.Stat(filepath.Join(dir, name)) if err != nil { continue // Ignore broken symlinks. } } - if info.Mode().IsRegular() && !strings.HasPrefix(name, "_") && strings.HasSuffix(name, ".go") && MatchFile(name, tags) { + if info.Mode().IsRegular() && !strings.HasPrefix(name, "_") && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") && MatchFile(name, tags) { files = append(files, filepath.Join(dir, name)) } } @@ -49,7 +50,7 @@ func scanFiles(files []string, tags map[string]bool, explicitFiles bool) ([]stri numFiles := 0 Files: for _, name := range files { - r, err := os.Open(name) + r, err := fsys.Open(name) if err != nil { return nil, nil, err } diff --git a/libgo/go/cmd/go/internal/imports/scan_test.go b/libgo/go/cmd/go/internal/imports/scan_test.go index e424656cae2..2d245ee7872 100644 --- a/libgo/go/cmd/go/internal/imports/scan_test.go +++ b/libgo/go/cmd/go/internal/imports/scan_test.go @@ -7,7 +7,7 @@ package imports import ( "bytes" "internal/testenv" - "io/ioutil" + "os" "path" "path/filepath" "runtime" @@ -57,7 +57,7 @@ func TestScan(t *testing.T) { func TestScanDir(t *testing.T) { testenv.MustHaveGoBuild(t) - dirs, err := ioutil.ReadDir("testdata") + dirs, err := os.ReadDir("testdata") if err != nil { t.Fatal(err) } @@ -66,7 +66,7 @@ func TestScanDir(t *testing.T) { continue } t.Run(dir.Name(), func(t *testing.T) { - tagsData, err := ioutil.ReadFile(filepath.Join("testdata", dir.Name(), "tags.txt")) + tagsData, err := os.ReadFile(filepath.Join("testdata", dir.Name(), "tags.txt")) if err != nil { t.Fatalf("error reading tags: %v", err) } @@ -75,7 +75,7 @@ func TestScanDir(t *testing.T) { tags[t] = true } - wantData, err := ioutil.ReadFile(filepath.Join("testdata", dir.Name(), "want.txt")) + wantData, err := os.ReadFile(filepath.Join("testdata", dir.Name(), "want.txt")) if err != nil { t.Fatalf("error reading want: %v", err) } diff --git a/libgo/go/cmd/go/internal/imports/tags.go b/libgo/go/cmd/go/internal/imports/tags.go index 14b4e21a024..01b448b9142 100644 --- a/libgo/go/cmd/go/internal/imports/tags.go +++ b/libgo/go/cmd/go/internal/imports/tags.go @@ -4,17 +4,23 @@ package imports -import "cmd/go/internal/cfg" +import ( + "cmd/go/internal/cfg" + "sync" +) -var tags map[string]bool +var ( + tags map[string]bool + tagsOnce sync.Once +) // Tags returns a set of build tags that are true for the target platform. // It includes GOOS, GOARCH, the compiler, possibly "cgo", // release tags like "go1.13", and user-specified build tags. func Tags() map[string]bool { - if tags == nil { + tagsOnce.Do(func() { tags = loadTags() - } + }) return tags } @@ -36,14 +42,17 @@ func loadTags() map[string]bool { return tags } -var anyTags map[string]bool +var ( + anyTags map[string]bool + anyTagsOnce sync.Once +) // AnyTags returns a special set of build tags that satisfy nearly all // build tag expressions. Only "ignore" and malformed build tag requirements // are considered false. func AnyTags() map[string]bool { - if anyTags == nil { + anyTagsOnce.Do(func() { anyTags = map[string]bool{"*": true} - } + }) return anyTags } diff --git a/libgo/go/cmd/go/internal/imports/testdata/android/.h.go b/libgo/go/cmd/go/internal/imports/testdata/android/.h.go new file mode 100644 index 00000000000..53c529e7774 --- /dev/null +++ b/libgo/go/cmd/go/internal/imports/testdata/android/.h.go @@ -0,0 +1,3 @@ +package android + +import _ "h" diff --git a/libgo/go/cmd/go/internal/imports/testdata/illumos/.h.go b/libgo/go/cmd/go/internal/imports/testdata/illumos/.h.go new file mode 100644 index 00000000000..53c529e7774 --- /dev/null +++ b/libgo/go/cmd/go/internal/imports/testdata/illumos/.h.go @@ -0,0 +1,3 @@ +package android + +import _ "h" diff --git a/libgo/go/cmd/go/internal/list/list.go b/libgo/go/cmd/go/internal/list/list.go index 6ca15611211..ce6f579c058 100644 --- a/libgo/go/cmd/go/internal/list/list.go +++ b/libgo/go/cmd/go/internal/list/list.go @@ -8,7 +8,9 @@ package list import ( "bufio" "bytes" + "context" "encoding/json" + "fmt" "io" "os" "sort" @@ -19,6 +21,7 @@ import ( "cmd/go/internal/cache" "cmd/go/internal/cfg" "cmd/go/internal/load" + "cmd/go/internal/modinfo" "cmd/go/internal/modload" "cmd/go/internal/str" "cmd/go/internal/work" @@ -63,26 +66,28 @@ to -f '{{.ImportPath}}'. The struct being passed to the template is: BinaryOnly bool // binary-only package (no longer supported) ForTest string // package is only for use in named test Export string // file containing export data (when using -export) + BuildID string // build ID of the compiled package (when using -export) Module *Module // info about package's containing module, if any (can be nil) Match []string // command-line patterns matching this package DepOnly bool // package is only a dependency, not explicitly listed // Source files - GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) - CgoFiles []string // .go source files that import "C" - CompiledGoFiles []string // .go files presented to compiler (when using -compiled) - IgnoredGoFiles []string // .go source files ignored due to build constraints - CFiles []string // .c source files - CXXFiles []string // .cc, .cxx and .cpp source files - MFiles []string // .m source files - HFiles []string // .h, .hh, .hpp and .hxx source files - FFiles []string // .f, .F, .for and .f90 Fortran source files - SFiles []string // .s source files - SwigFiles []string // .swig files - SwigCXXFiles []string // .swigcxx files - SysoFiles []string // .syso object files to add to archive - TestGoFiles []string // _test.go files in package - XTestGoFiles []string // _test.go files outside package + GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) + CgoFiles []string // .go source files that import "C" + CompiledGoFiles []string // .go files presented to compiler (when using -compiled) + IgnoredGoFiles []string // .go source files ignored due to build constraints + IgnoredOtherFiles []string // non-.go source files ignored due to build constraints + CFiles []string // .c source files + CXXFiles []string // .cc, .cxx and .cpp source files + MFiles []string // .m source files + HFiles []string // .h, .hh, .hpp and .hxx source files + FFiles []string // .f, .F, .for and .f90 Fortran source files + SFiles []string // .s source files + SwigFiles []string // .swig files + SwigCXXFiles []string // .swigcxx files + SysoFiles []string // .syso object files to add to archive + TestGoFiles []string // _test.go files in package + XTestGoFiles []string // _test.go files outside package // Cgo directives CgoCFLAGS []string // cgo: flags for C compiler @@ -213,6 +218,7 @@ applied to a Go struct, but now a Module struct: Dir string // directory holding files for this module, if any GoMod string // path to go.mod file used when loading this module, if any GoVersion string // go version used in module + Retracted string // retraction information, if any (with -retracted or -u) Error *ModuleError // error loading module } @@ -244,14 +250,16 @@ the replaced source code.) The -u flag adds information about available upgrades. When the latest version of a given module is newer than the current one, list -u sets the Module's Update field -to information about the newer module. +to information about the newer module. list -u will also set +the module's Retracted field if the current version is retracted. The Module's String method indicates an available upgrade by formatting the newer version in brackets after the current version. +If a version is retracted, the string "(retracted)" will follow it. For example, 'go list -m -u all' might print: my/main/module golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text - rsc.io/pdf v0.1.1 [v0.1.2] + rsc.io/pdf v0.1.1 (retracted) [v0.1.2] (For tools, 'go list -m -u -json all' may be more convenient to parse.) @@ -261,6 +269,14 @@ to semantic versioning, earliest to latest. The flag also changes the default output format to display the module path followed by the space-separated version list. +The -retracted flag causes list to report information about retracted +module versions. When -retracted is used with -f or -json, the Retracted +field will be set to a string explaining why the version was retracted. +The string is taken from comments on the retract directive in the +module's go.mod file. When -retracted is used with -versions, retracted +versions are listed together with unretracted versions. The -retracted +flag may be used with or without -m. + The arguments to list -m are interpreted as a list of modules, not packages. The main module is the module containing the current directory. The active modules are the main module and its dependencies. @@ -294,23 +310,24 @@ func init() { } var ( - listCompiled = CmdList.Flag.Bool("compiled", false, "") - listDeps = CmdList.Flag.Bool("deps", false, "") - listE = CmdList.Flag.Bool("e", false, "") - listExport = CmdList.Flag.Bool("export", false, "") - listFmt = CmdList.Flag.String("f", "", "") - listFind = CmdList.Flag.Bool("find", false, "") - listJson = CmdList.Flag.Bool("json", false, "") - listM = CmdList.Flag.Bool("m", false, "") - listU = CmdList.Flag.Bool("u", false, "") - listTest = CmdList.Flag.Bool("test", false, "") - listVersions = CmdList.Flag.Bool("versions", false, "") + listCompiled = CmdList.Flag.Bool("compiled", false, "") + listDeps = CmdList.Flag.Bool("deps", false, "") + listE = CmdList.Flag.Bool("e", false, "") + listExport = CmdList.Flag.Bool("export", false, "") + listFmt = CmdList.Flag.String("f", "", "") + listFind = CmdList.Flag.Bool("find", false, "") + listJson = CmdList.Flag.Bool("json", false, "") + listM = CmdList.Flag.Bool("m", false, "") + listRetracted = CmdList.Flag.Bool("retracted", false, "") + listTest = CmdList.Flag.Bool("test", false, "") + listU = CmdList.Flag.Bool("u", false, "") + listVersions = CmdList.Flag.Bool("versions", false, "") ) var nl = []byte{'\n'} -func runList(cmd *base.Command, args []string) { - modload.LoadTests = *listTest +func runList(ctx context.Context, cmd *base.Command, args []string) { + load.ModResolveTests = *listTest work.BuildInit() out := newTrackingWriter(os.Stdout) defer out.w.Flush() @@ -348,7 +365,7 @@ func runList(cmd *base.Command, args []string) { fm := template.FuncMap{ "join": strings.Join, "context": context, - "module": modload.ModuleInfo, + "module": func(path string) *modinfo.ModulePublic { return modload.ModuleInfo(ctx, path) }, } tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt) if err != nil { @@ -365,6 +382,16 @@ func runList(cmd *base.Command, args []string) { } } + modload.Init() + if *listRetracted { + if cfg.BuildMod == "vendor" { + base.Fatalf("go list -retracted cannot be used when vendoring is enabled") + } + if !modload.Enabled() { + base.Fatalf("go list -retracted can only be used in module-aware mode") + } + } + if *listM { // Module mode. if *listCompiled { @@ -388,7 +415,7 @@ func runList(cmd *base.Command, args []string) { base.Fatalf("go list -m: not using modules") } - modload.InitMod() // Parses go.mod and sets cfg.BuildMod. + modload.LoadModFile(ctx) // Parses go.mod and sets cfg.BuildMod. if cfg.BuildMod == "vendor" { const actionDisabledFormat = "go list -m: can't %s using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)" @@ -412,9 +439,7 @@ func runList(cmd *base.Command, args []string) { } } - modload.LoadBuildList() - - mods := modload.ListModules(args, *listU, *listVersions) + mods := modload.ListModules(ctx, args, *listU, *listVersions, *listRetracted) if !*listE { for _, m := range mods { if m.Error != nil { @@ -446,11 +471,18 @@ func runList(cmd *base.Command, args []string) { } load.IgnoreImports = *listFind - var pkgs []*load.Package - if *listE { - pkgs = load.PackagesAndErrors(args) - } else { - pkgs = load.Packages(args) + pkgs := load.PackagesAndErrors(ctx, args) + if !*listE { + w := 0 + for _, pkg := range pkgs { + if pkg.Error != nil { + base.Errorf("%v", pkg.Error) + continue + } + pkgs[w] = pkg + w++ + } + pkgs = pkgs[:w] base.ExitIfErrors() } @@ -476,9 +508,9 @@ func runList(cmd *base.Command, args []string) { var pmain, ptest, pxtest *load.Package var err error if *listE { - pmain, ptest, pxtest = load.TestPackagesAndErrors(p, nil) + pmain, ptest, pxtest = load.TestPackagesAndErrors(ctx, p, nil) } else { - pmain, ptest, pxtest, err = load.TestPackagesFor(p, nil) + pmain, ptest, pxtest, err = load.TestPackagesFor(ctx, p, nil) if err != nil { base.Errorf("can't load test package: %s", err) } @@ -520,7 +552,7 @@ func runList(cmd *base.Command, args []string) { // Note that -deps is applied after -test, // so that you only get descriptions of tests for the things named // explicitly on the command line, not for all dependencies. - pkgs = load.PackageList(pkgs) + pkgs = loadPackageList(pkgs) } // Do we need to run a build to gather information? @@ -538,13 +570,15 @@ func runList(cmd *base.Command, args []string) { a.Deps = append(a.Deps, b.AutoAction(work.ModeInstall, work.ModeInstall, p)) } } - b.Do(a) + b.Do(ctx, a) } for _, p := range pkgs { // Show vendor-expanded paths in listing p.TestImports = p.Resolve(p.TestImports) p.XTestImports = p.Resolve(p.XTestImports) + p.TestEmbedFiles = p.ResolveEmbed(p.TestEmbedPatterns) + p.XTestEmbedFiles = p.ResolveEmbed(p.XTestEmbedPatterns) p.DepOnly = !cmdline[p] if *listCompiled { @@ -555,7 +589,7 @@ func runList(cmd *base.Command, args []string) { if *listTest { all := pkgs if !*listDeps { - all = load.PackageList(pkgs) + all = loadPackageList(pkgs) } // Update import paths to distinguish the real package p // from p recompiled for q.test. @@ -605,6 +639,55 @@ func runList(cmd *base.Command, args []string) { } } + // TODO(golang.org/issue/40676): This mechanism could be extended to support + // -u without -m. + if *listRetracted { + // Load retractions for modules that provide packages that will be printed. + // TODO(golang.org/issue/40775): Packages from the same module refer to + // distinct ModulePublic instance. It would be nice if they could all point + // to the same instance. This would require additional global state in + // modload.loaded, so that should be refactored first. For now, we update + // all instances. + modToArg := make(map[*modinfo.ModulePublic]string) + argToMods := make(map[string][]*modinfo.ModulePublic) + var args []string + addModule := func(mod *modinfo.ModulePublic) { + if mod.Version == "" { + return + } + arg := fmt.Sprintf("%s@%s", mod.Path, mod.Version) + if argToMods[arg] == nil { + args = append(args, arg) + } + argToMods[arg] = append(argToMods[arg], mod) + modToArg[mod] = arg + } + for _, p := range pkgs { + if p.Module == nil { + continue + } + addModule(p.Module) + if p.Module.Replace != nil { + addModule(p.Module.Replace) + } + } + + if len(args) > 0 { + listU := false + listVersions := false + rmods := modload.ListModules(ctx, args, listU, listVersions, *listRetracted) + for i, arg := range args { + rmod := rmods[i] + for _, mod := range argToMods[arg] { + mod.Retracted = rmod.Retracted + if rmod.Error != nil && mod.Error == nil { + mod.Error = rmod.Error + } + } + } + } + } + // Record non-identity import mappings in p.ImportMap. for _, p := range pkgs { for i, srcPath := range p.Internal.RawImports { @@ -623,6 +706,23 @@ func runList(cmd *base.Command, args []string) { } } +// loadPackageList is like load.PackageList, but prints error messages and exits +// with nonzero status if listE is not set and any package in the expanded list +// has errors. +func loadPackageList(roots []*load.Package) []*load.Package { + pkgs := load.PackageList(roots) + + if !*listE { + for _, pkg := range pkgs { + if pkg.Error != nil { + base.Errorf("%v", pkg.Error) + } + } + } + + return pkgs +} + // TrackingWriter tracks the last byte written on every write so // we can avoid printing a newline if one was already written or // if there is no output at all. diff --git a/libgo/go/cmd/go/internal/load/pkg.go b/libgo/go/cmd/go/internal/load/pkg.go index 28220ce6107..b3679728f1f 100644 --- a/libgo/go/cmd/go/internal/load/pkg.go +++ b/libgo/go/cmd/go/internal/load/pkg.go @@ -7,14 +7,16 @@ package load import ( "bytes" + "context" "encoding/json" "errors" "fmt" "go/build" "go/scanner" "go/token" - "io/ioutil" + "io/fs" "os" + "path" pathpkg "path" "path/filepath" "runtime" @@ -26,25 +28,14 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/modinfo" + "cmd/go/internal/modload" "cmd/go/internal/par" "cmd/go/internal/search" "cmd/go/internal/str" -) - -var ( - // module initialization hook; never nil, no-op if module use is disabled - ModInit func() - - // module hooks; nil if module use is disabled - ModBinDir func() string // return effective bin directory - ModLookup func(parentPath string, parentIsStd bool, path string) (dir, realPath string, err error) // lookup effective meaning of import - 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, 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 + "cmd/go/internal/trace" + "cmd/internal/sys" ) var IgnoreImports bool // control whether we ignore imports in packages @@ -70,6 +61,7 @@ type PackagePublic struct { ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory ForTest string `json:",omitempty"` // package is only for use in named test Export string `json:",omitempty"` // file containing export data (set by go list -export) + BuildID string `json:",omitempty"` // build ID of the compiled package (set by go list -export) Module *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any Match []string `json:",omitempty"` // command-line patterns matching this package Goroot bool `json:",omitempty"` // is this package found in the Go root? @@ -87,19 +79,24 @@ type PackagePublic struct { // Source files // If you add to this list you MUST add to p.AllFiles (below) too. // Otherwise file name security lists will not apply to any new additions. - GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) - CgoFiles []string `json:",omitempty"` // .go source files that import "C" - CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles - IgnoredGoFiles []string `json:",omitempty"` // .go source files ignored due to build constraints - CFiles []string `json:",omitempty"` // .c source files - CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files - MFiles []string `json:",omitempty"` // .m source files - HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files - FFiles []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files - SFiles []string `json:",omitempty"` // .s source files - SwigFiles []string `json:",omitempty"` // .swig files - SwigCXXFiles []string `json:",omitempty"` // .swigcxx files - SysoFiles []string `json:",omitempty"` // .syso system object files added to package + GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) + CgoFiles []string `json:",omitempty"` // .go source files that import "C" + CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles + IgnoredGoFiles []string `json:",omitempty"` // .go source files ignored due to build constraints + IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints + CFiles []string `json:",omitempty"` // .c source files + CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files + MFiles []string `json:",omitempty"` // .m source files + HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files + FFiles []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files + SFiles []string `json:",omitempty"` // .s source files + SwigFiles []string `json:",omitempty"` // .swig files + SwigCXXFiles []string `json:",omitempty"` // .swigcxx files + SysoFiles []string `json:",omitempty"` // .syso system object files added to package + + // Embedded files + EmbedPatterns []string `json:",omitempty"` // //go:embed patterns + EmbedFiles []string `json:",omitempty"` // files and directories matched by EmbedPatterns // Cgo directives CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler @@ -122,10 +119,14 @@ type PackagePublic struct { // Test information // If you add to this list you MUST add to p.AllFiles (below) too. // Otherwise file name security lists will not apply to any new additions. - TestGoFiles []string `json:",omitempty"` // _test.go files in package - TestImports []string `json:",omitempty"` // imports from TestGoFiles - XTestGoFiles []string `json:",omitempty"` // _test.go files outside package - XTestImports []string `json:",omitempty"` // imports from XTestGoFiles + TestGoFiles []string `json:",omitempty"` // _test.go files in package + TestImports []string `json:",omitempty"` // imports from TestGoFiles + TestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns + TestEmbedFiles []string `json:",omitempty"` // //files matched by EmbedPatterns + XTestGoFiles []string `json:",omitempty"` // _test.go files outside package + XTestImports []string `json:",omitempty"` // imports from XTestGoFiles + XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns + XTestEmbedFiles []string `json:",omitempty"` // //files matched by EmbedPatterns } // AllFiles returns the names of all the files considered for the package. @@ -134,11 +135,12 @@ type PackagePublic struct { // The go/build package filtered others out (like foo_wrongGOARCH.s) // and that's OK. func (p *Package) AllFiles() []string { - return str.StringList( + files := str.StringList( p.GoFiles, p.CgoFiles, // no p.CompiledGoFiles, because they are from GoFiles or generated by us p.IgnoredGoFiles, + p.IgnoredOtherFiles, p.CFiles, p.CXXFiles, p.MFiles, @@ -151,6 +153,27 @@ func (p *Package) AllFiles() []string { p.TestGoFiles, p.XTestGoFiles, ) + + // EmbedFiles may overlap with the other files. + // Dedup, but delay building the map as long as possible. + // Only files in the current directory (no slash in name) + // need to be checked against the files variable above. + var have map[string]bool + for _, file := range p.EmbedFiles { + if !strings.Contains(file, "/") { + if have == nil { + have = make(map[string]bool) + for _, file := range files { + have[file] = true + } + } + if have[file] { + continue + } + } + files = append(files, file) + } + return files } // Desc returns the package "description", for use in b.showOutput. @@ -180,6 +203,7 @@ type PackageInternal struct { GobinSubdir bool // install target would be subdir of GOBIN BuildInfo string // add this info to package main TestmainGo *[]byte // content for _testmain.go + Embed map[string][]string // //go:embed comment mapping Asmflags []string // -asmflags for this package Gcflags []string // -gcflags for this package @@ -197,7 +221,7 @@ type NoGoError struct { } func (e *NoGoError) Error() string { - if len(e.Package.constraintIgnoredGoFiles()) > 0 { + if len(e.Package.IgnoredGoFiles) > 0 { // Go files exist, but they were ignored due to build constraints. return "build constraints exclude all Go files in " + e.Package.Dir } @@ -260,8 +284,8 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta // package's source files themselves (scanner errors). // // TODO(matloob): Perhaps make each of those the errors in the first group - // (including modload.ImportMissingError, and the corresponding - // "cannot find package %q in any of" GOPATH-mode error + // (including modload.ImportMissingError, ImportMissingSumError, and the + // corresponding "cannot find package %q in any of" GOPATH-mode error // produced in build.(*Context).Import; modload.AmbiguousImportError, // and modload.PackageNotInModuleError; and the malformed module path errors // produced in golang.org/x/mod/module.CheckMod) implement an interface @@ -342,6 +366,7 @@ func (p *Package) copyBuild(pp *build.Package) { p.GoFiles = pp.GoFiles p.CgoFiles = pp.CgoFiles p.IgnoredGoFiles = pp.IgnoredGoFiles + p.IgnoredOtherFiles = pp.IgnoredOtherFiles p.CFiles = pp.CFiles p.CXXFiles = pp.CXXFiles p.MFiles = pp.MFiles @@ -371,6 +396,9 @@ func (p *Package) copyBuild(pp *build.Package) { p.TestImports = nil p.XTestImports = nil } + p.EmbedPatterns = pp.EmbedPatterns + p.TestEmbedPatterns = pp.TestEmbedPatterns + p.XTestEmbedPatterns = pp.XTestEmbedPatterns } // A PackageError describes an error loading information about a package. @@ -432,13 +460,17 @@ type ImportPathError interface { ImportPath() string } +var ( + _ ImportPathError = (*importError)(nil) + _ ImportPathError = (*modload.ImportMissingError)(nil) + _ ImportPathError = (*modload.ImportMissingSumError)(nil) +) + 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) { @@ -551,7 +583,7 @@ func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package { }) packageDataCache.Delete(p.ImportPath) } - return LoadImport(arg, base.Cwd, nil, stk, nil, 0) + return LoadImport(context.TODO(), arg, base.Cwd, nil, stk, nil, 0) } // dirToImportPath returns the pseudo-import path we use for a package @@ -603,11 +635,11 @@ const ( // LoadImport does not set tool flags and should only be used by // this package, as part of a bigger load operation, and by GOPATH-based "go get". // TODO(rsc): When GOPATH-based "go get" is removed, unexport this function. -func LoadImport(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { - return loadImport(nil, path, srcDir, parent, stk, importPos, mode) +func LoadImport(ctx context.Context, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { + return loadImport(ctx, nil, path, srcDir, parent, stk, importPos, mode) } -func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { +func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { if path == "" { panic("LoadImport called with empty package path") } @@ -655,7 +687,7 @@ func loadImport(pre *preload, path, srcDir string, parent *Package, stk *ImportS // Load package. // loadPackageData may return bp != nil even if an error occurs, // in order to return partial information. - p.load(path, stk, importPos, bp, err) + p.load(ctx, path, stk, importPos, bp, err) if !cfg.ModulesEnabled && path != cleanImport(path) { p.Error = &PackageError{ @@ -751,7 +783,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd // 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 + // canonicalized by modload.LoadPackages 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{ @@ -768,7 +800,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd r.dir = filepath.Join(parentDir, path) r.path = dirToImportPath(r.dir) } else if cfg.ModulesEnabled { - r.dir, r.path, r.err = ModLookup(parentPath, parentIsStd, path) + r.dir, r.path, r.err = modload.Lookup(parentPath, parentIsStd, path) } else if mode&ResolveImport != 0 { // We do our own path resolution, because we want to // find out the key to use in packageCache without the @@ -799,7 +831,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd } data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode) if data.p.Root == "" && cfg.ModulesEnabled { - if info := ModPackageModuleInfo(path); info != nil { + if info := modload.PackageModuleInfo(path); info != nil { data.p.Root = info.Dir } } @@ -825,7 +857,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd if cfg.GOBIN != "" { data.p.BinDir = cfg.GOBIN } else if cfg.ModulesEnabled { - data.p.BinDir = ModBinDir() + data.p.BinDir = modload.BinDir() } } @@ -893,8 +925,8 @@ var preloadWorkerCount = runtime.GOMAXPROCS(0) // to ensure preload goroutines are no longer active. This is necessary // because of global mutable state that cannot safely be read and written // concurrently. In particular, packageDataCache may be cleared by "go get" -// in GOPATH mode, and modload.loaded (accessed via ModLookup) may be -// modified by modload.ImportPaths (ModImportPaths). +// in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be +// modified by modload.LoadPackages. type preload struct { cancel chan struct{} sema chan struct{} @@ -961,6 +993,12 @@ func (pre *preload) preloadImports(imports []string, parent *build.Package) { // loadPackageData have completed. The preloader will not make any new calls // to loadPackageData. func (pre *preload) flush() { + // flush is usually deferred. + // Don't hang program waiting for workers on panic. + if v := recover(); v != nil { + panic(v) + } + close(pre.cancel) for i := 0; i < preloadWorkerCount; i++ { pre.sema <- struct{}{} @@ -980,7 +1018,7 @@ var isDirCache par.Cache func isDir(path string) bool { return isDirCache.Do(path, func() interface{} { - fi, err := os.Stat(path) + fi, err := fsys.Stat(path) return err == nil && fi.IsDir() }).(bool) } @@ -1004,7 +1042,7 @@ func ResolveImportPath(parent *Package, path string) (found string) { func resolveImportPath(path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) { if cfg.ModulesEnabled { - if _, p, e := ModLookup(parentPath, parentIsStd, path); e == nil { + if _, p, e := modload.Lookup(parentPath, parentIsStd, path); e == nil { return p } return path @@ -1108,7 +1146,7 @@ var ( // goModPath returns the module path in the go.mod in dir, if any. func goModPath(dir string) (path string) { return goModPathCache.Do(dir, func() interface{} { - data, err := ioutil.ReadFile(filepath.Join(dir, "go.mod")) + data, err := os.ReadFile(filepath.Join(dir, "go.mod")) if err != nil { return "" } @@ -1257,9 +1295,9 @@ HaveGoMod: // Otherwise it is not possible to vendor just a/b/c and still import the // non-vendored a/b. See golang.org/issue/13832. func hasGoFiles(dir string) bool { - fis, _ := ioutil.ReadDir(dir) - for _, fi := range fis { - if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".go") { + files, _ := os.ReadDir(dir) + for _, f := range files { + if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") { return true } } @@ -1373,7 +1411,7 @@ func disallowInternal(srcDir string, importer *Package, importerPath string, p * // directory containing them. // If the directory is outside the main module, this will resolve to ".", // which is not a prefix of any valid module. - importerPath = ModDirImportPath(importer.Dir) + importerPath = modload.DirImportPath(importer.Dir) } parentOfInternal := p.ImportPath[:i] if str.HasPathPrefix(importerPath, parentOfInternal) { @@ -1595,7 +1633,7 @@ func (p *Package) DefaultExecName() string { // load populates p using information from bp, err, which should // be the result of calling build.Context.Import. // stk contains the import stack, not including path itself. -func (p *Package) load(path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) { +func (p *Package) load(ctx context.Context, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) { p.copyBuild(bp) // The localPrefix is the path we interpret ./ imports relative to. @@ -1631,6 +1669,11 @@ func (p *Package) load(path string, stk *ImportStack, importPos []token.Position p.setLoadPackageDataError(err, path, stk, importPos) } + p.EmbedFiles, p.Internal.Embed, err = p.resolveEmbed(p.EmbedPatterns) + if err != nil { + setError(err) + } + useBindir := p.Name == "main" if !p.Standard { switch cfg.BuildBuildmode { @@ -1656,7 +1699,7 @@ func (p *Package) load(path string, stk *ImportStack, importPos []token.Position elem = full } if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled { - p.Internal.Build.BinDir = ModBinDir() + p.Internal.Build.BinDir = modload.BinDir() } if p.Internal.Build.BinDir != "" { // Install to GOBIN or bin of GOPATH entry. @@ -1690,7 +1733,7 @@ func (p *Package) load(path string, stk *ImportStack, importPos []token.Position // 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) + shlib, err := os.ReadFile(shlibnamefile) if err != nil && !os.IsNotExist(err) { base.Fatalf("reading shlibname: %v", err) } @@ -1804,7 +1847,7 @@ func (p *Package) load(path string, stk *ImportStack, importPos []token.Position if path == "C" { continue } - p1 := LoadImport(path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport) + p1 := LoadImport(ctx, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport) path = p1.ImportPath importPaths[i] = path @@ -1865,13 +1908,169 @@ func (p *Package) load(path string, stk *ImportStack, importPos []token.Position if p.Internal.CmdlineFiles { mainPath = "command-line-arguments" } - p.Module = ModPackageModuleInfo(mainPath) + p.Module = modload.PackageModuleInfo(mainPath) if p.Name == "main" && len(p.DepsErrors) == 0 { - p.Internal.BuildInfo = ModPackageBuildInfo(mainPath, p.Deps) + p.Internal.BuildInfo = modload.PackageBuildInfo(mainPath, p.Deps) } } } +// ResolveEmbed resolves //go:embed patterns and returns only the file list. +// For use by go list to compute p.TestEmbedFiles and p.XTestEmbedFiles. +func (p *Package) ResolveEmbed(patterns []string) []string { + files, _, _ := p.resolveEmbed(patterns) + return files +} + +// resolveEmbed resolves //go:embed patterns to precise file lists. +// It sets files to the list of unique files matched (for go list), +// and it sets pmap to the more precise mapping from +// patterns to files. +// TODO(rsc): All these messages need position information for better error reports. +func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[string][]string, err error) { + pmap = make(map[string][]string) + have := make(map[string]int) + dirOK := make(map[string]bool) + pid := 0 // pattern ID, to allow reuse of have map + for _, pattern := range patterns { + pid++ + + // Check pattern is valid for //go:embed. + if _, err := path.Match(pattern, ""); err != nil || !validEmbedPattern(pattern) { + return nil, nil, fmt.Errorf("pattern %s: invalid pattern syntax", pattern) + } + + // Glob to find matches. + match, err := fsys.Glob(p.Dir + string(filepath.Separator) + filepath.FromSlash(pattern)) + if err != nil { + return nil, nil, fmt.Errorf("pattern %s: %v", pattern, err) + } + + // Filter list of matches down to the ones that will still exist when + // the directory is packaged up as a module. (If p.Dir is in the module cache, + // only those files exist already, but if p.Dir is in the current module, + // then there may be other things lying around, like symbolic links or .git directories.) + var list []string + for _, file := range match { + rel := filepath.ToSlash(file[len(p.Dir)+1:]) // file, relative to p.Dir + + what := "file" + info, err := fsys.Lstat(file) + if err != nil { + return nil, nil, err + } + if info.IsDir() { + what = "directory" + } + + // Check that directories along path do not begin a new module + // (do not contain a go.mod). + for dir := file; len(dir) > len(p.Dir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) { + if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil { + return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in different module", pattern, what, rel) + } + if dir != file { + if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() { + return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in non-directory %s", pattern, what, rel, dir[len(p.Dir)+1:]) + } + } + dirOK[dir] = true + if elem := filepath.Base(dir); isBadEmbedName(elem) { + if dir == file { + return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: invalid name %s", pattern, what, rel, elem) + } else { + return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in invalid directory %s", pattern, what, rel, elem) + } + } + } + + switch { + default: + return nil, nil, fmt.Errorf("pattern %s: cannot embed irregular file %s", pattern, rel) + + case info.Mode().IsRegular(): + if have[rel] != pid { + have[rel] = pid + list = append(list, rel) + } + + case info.IsDir(): + // Gather all files in the named directory, stopping at module boundaries + // and ignoring files that wouldn't be packaged into a module. + count := 0 + err := fsys.Walk(file, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + rel := filepath.ToSlash(path[len(p.Dir)+1:]) + name := info.Name() + if path != file && (isBadEmbedName(name) || name[0] == '.' || name[0] == '_') { + // Ignore bad names, assuming they won't go into modules. + // Also avoid hidden files that user may not know about. + // See golang.org/issue/42328. + if info.IsDir() { + return fs.SkipDir + } + return nil + } + if info.IsDir() { + if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil { + return filepath.SkipDir + } + return nil + } + if !info.Mode().IsRegular() { + return nil + } + count++ + if have[rel] != pid { + have[rel] = pid + list = append(list, rel) + } + return nil + }) + if err != nil { + return nil, nil, err + } + if count == 0 { + return nil, nil, fmt.Errorf("pattern %s: cannot embed directory %s: contains no embeddable files", pattern, rel) + } + } + } + + if len(list) == 0 { + return nil, nil, fmt.Errorf("pattern %s: no matching files found", pattern) + } + sort.Strings(list) + pmap[pattern] = list + } + + for file := range have { + files = append(files, file) + } + sort.Strings(files) + return files, pmap, nil +} + +func validEmbedPattern(pattern string) bool { + return pattern != "." && fs.ValidPath(pattern) +} + +// isBadEmbedName reports whether name is the base name of a file that +// can't or won't be included in modules and therefore shouldn't be treated +// as existing for embedding. +func isBadEmbedName(name string) bool { + switch name { + // Empty string should be impossible but make it bad. + case "": + return true + // Version control directories won't be present in module. + case ".bzr", ".hg", ".git", ".svn": + return true + } + return false +} + // collectDeps populates p.Deps and p.DepsErrors by iterating over // p.Internal.Imports. // @@ -1959,37 +2158,40 @@ func LinkerDeps(p *Package) []string { // externalLinkingForced reports whether external linking is being // forced even for programs that do not use cgo. func externalLinkingForced(p *Package) bool { + if !cfg.BuildContext.CgoEnabled { + return false + } + // Some targets must use external linking even inside GOROOT. switch cfg.BuildContext.GOOS { case "android": if cfg.BuildContext.GOARCH != "arm64" { return true } - case "darwin": - if cfg.BuildContext.GOARCH == "arm64" { - return true - } + case "ios": + return true } - if !cfg.BuildContext.CgoEnabled { - return false - } // Currently build modes c-shared, pie (on systems that do not // support PIE with internal linking mode (currently all // systems: issue #18968)), plugin, and -linkshared force // external linking mode, as of course does // -ldflags=-linkmode=external. External linking mode forces // an import of runtime/cgo. - pieCgo := cfg.BuildBuildmode == "pie" + // If there are multiple -linkmode options, the last one wins. + pieCgo := cfg.BuildBuildmode == "pie" && !sys.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH) linkmodeExternal := false if p != nil { ldflags := BuildLdflags.For(p) - for i, a := range ldflags { - if a == "-linkmode=external" { - linkmodeExternal = true - } - if a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" { + for i := len(ldflags) - 1; i >= 0; i-- { + a := ldflags[i] + if a == "-linkmode=external" || + a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" { linkmodeExternal = true + break + } else if a == "-linkmode=internal" || + a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" { + break } } } @@ -2024,22 +2226,7 @@ func (p *Package) InternalXGoFiles() []string { // using absolute paths. "Possibly relevant" means that files are not excluded // due to build tags, but files with names beginning with . or _ are still excluded. func (p *Package) InternalAllGoFiles() []string { - return p.mkAbs(str.StringList(p.constraintIgnoredGoFiles(), p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) -} - -// constraintIgnoredGoFiles returns the list of Go files ignored for reasons -// other than having a name beginning with '.' or '_'. -func (p *Package) constraintIgnoredGoFiles() []string { - if len(p.IgnoredGoFiles) == 0 { - return nil - } - files := make([]string, 0, len(p.IgnoredGoFiles)) - for _, f := range p.IgnoredGoFiles { - if f != "" && f[0] != '.' && f[0] != '_' { - files = append(files, f) - } - } - return files + return p.mkAbs(str.StringList(p.IgnoredGoFiles, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) } // usesSwig reports whether the package needs to run SWIG. @@ -2077,7 +2264,7 @@ func PackageList(roots []*Package) []*Package { // TestPackageList returns the list of packages in the dag rooted at roots // as visited in a depth-first post-order traversal, including the test // imports of the roots. This ignores errors in test packages. -func TestPackageList(roots []*Package) []*Package { +func TestPackageList(ctx context.Context, roots []*Package) []*Package { seen := map[*Package]bool{} all := []*Package{} var walk func(*Package) @@ -2093,7 +2280,7 @@ func TestPackageList(roots []*Package) []*Package { } walkTest := func(root *Package, path string) { var stk ImportStack - p1 := LoadImport(path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport) + p1 := LoadImport(ctx, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport) if p1.Error == nil { walk(p1) } @@ -2116,36 +2303,35 @@ func TestPackageList(roots []*Package) []*Package { // TODO(jayconrod): delete this function and set flags automatically // in LoadImport instead. func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { - p := LoadImport(path, srcDir, parent, stk, importPos, mode) + p := LoadImport(context.TODO(), path, srcDir, parent, stk, importPos, mode) setToolFlags(p) return p } -// Packages returns the packages named by the -// command line arguments 'args'. If a named package -// cannot be loaded at all (for example, if the directory does not exist), -// then packages prints an error and does not include that -// package in the results. However, if errors occur trying -// to load dependencies of a named package, the named -// package is still returned, with p.Incomplete = true -// and details in p.DepsErrors. -func Packages(args []string) []*Package { - var pkgs []*Package - for _, pkg := range PackagesAndErrors(args) { - if pkg.Error != nil { - base.Errorf("%v", pkg.Error) - continue - } - pkgs = append(pkgs, pkg) - } - return pkgs -} +// ModResolveTests indicates whether calls to the module loader should also +// resolve test dependencies of the requested packages. +// +// If ModResolveTests is true, then the module loader needs to resolve test +// dependencies at the same time as packages; otherwise, the test dependencies +// of those packages could be missing, and resolving those missing dependencies +// could change the selected versions of modules that provide other packages. +// +// TODO(#40775): Change this from a global variable to an explicit function +// argument where needed. +var ModResolveTests bool + +// PackagesAndErrors returns the packages named by the command line arguments +// 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns +// a *Package with the Error field describing the failure. If errors are found +// loading imported packages, the DepsErrors field is set. The Incomplete field +// may be set as well. +// +// To obtain a flat list of packages, use PackageList. +// To report errors loading packages, use ReportPackageErrors. +func PackagesAndErrors(ctx context.Context, patterns []string) []*Package { + ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors") + defer span.Done() -// PackagesAndErrors is like 'packages' but returns a -// *Package for every argument, even the ones that -// cannot be loaded at all. -// The packages that fail to load will have p.Error != nil. -func PackagesAndErrors(patterns []string) []*Package { for _, p := range patterns { // Listing is only supported with all patterns referring to either: // - Files that are part of the same directory. @@ -2153,13 +2339,24 @@ func PackagesAndErrors(patterns []string) []*Package { 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)} + if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() { + return []*Package{GoFilesPackage(ctx, patterns)} } } } - matches := ImportPaths(patterns) + var matches []*search.Match + if modload.Init(); cfg.ModulesEnabled { + loadOpts := modload.PackageOpts{ + ResolveMissingImports: true, + LoadTests: ModResolveTests, + SilenceErrors: true, + } + matches, _ = modload.LoadPackages(ctx, loadOpts, patterns...) + } else { + matches = search.ImportPaths(patterns) + } + var ( pkgs []*Package stk ImportStack @@ -2175,7 +2372,7 @@ func PackagesAndErrors(patterns []string) []*Package { if pkg == "" { panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern())) } - p := loadImport(pre, pkg, base.Cwd, nil, &stk, nil, 0) + p := loadImport(ctx, pre, pkg, base.Cwd, nil, &stk, nil, 0) p.Match = append(p.Match, m.Pattern()) p.Internal.CmdlinePkg = true if m.IsLiteral() { @@ -2220,27 +2417,9 @@ func PackagesAndErrors(patterns []string) []*Package { return pkgs } -func setToolFlags(pkgs ...*Package) { - for _, p := range PackageList(pkgs) { - p.Internal.Asmflags = BuildAsmflags.For(p) - p.Internal.Gcflags = BuildGcflags.For(p) - p.Internal.Ldflags = BuildLdflags.For(p) - p.Internal.Gccgoflags = BuildGccgoflags.For(p) - } -} - -func ImportPaths(args []string) []*search.Match { - if ModInit(); cfg.ModulesEnabled { - return ModImportPaths(args) - } - return search.ImportPaths(args) -} - -// PackagesForBuild is like Packages but exits -// if any of the packages or their dependencies have errors -// (cannot be built). -func PackagesForBuild(args []string) []*Package { - pkgs := PackagesAndErrors(args) +// CheckPackageErrors prints errors encountered loading pkgs and their +// dependencies, then exits with a non-zero status if any errors were found. +func CheckPackageErrors(pkgs []*Package) { printed := map[*PackageError]bool{} for _, pkg := range pkgs { if pkg.Error != nil { @@ -2275,15 +2454,22 @@ func PackagesForBuild(args []string) []*Package { seen[pkg.ImportPath] = true } base.ExitIfErrors() +} - return pkgs +func setToolFlags(pkgs ...*Package) { + for _, p := range PackageList(pkgs) { + p.Internal.Asmflags = BuildAsmflags.For(p) + p.Internal.Gcflags = BuildGcflags.For(p) + p.Internal.Ldflags = BuildLdflags.For(p) + p.Internal.Gccgoflags = BuildGccgoflags.For(p) + } } // GoFilesPackage creates a package for building a collection of Go files // (typically named on the command line). The target is named p.a for // package p or named after the first Go file for package main. -func GoFilesPackage(gofiles []string) *Package { - ModInit() +func GoFilesPackage(ctx context.Context, gofiles []string) *Package { + modload.Init() for _, f := range gofiles { if !strings.HasSuffix(f, ".go") { @@ -2306,10 +2492,10 @@ func GoFilesPackage(gofiles []string) *Package { // to make it look like this is a standard package or // command directory. So that local imports resolve // consistently, the files must all be in the same directory. - var dirent []os.FileInfo + var dirent []fs.FileInfo var dir string for _, file := range gofiles { - fi, err := os.Stat(file) + fi, err := fsys.Stat(file) if err != nil { base.Fatalf("%s", err) } @@ -2327,10 +2513,10 @@ func GoFilesPackage(gofiles []string) *Package { } dirent = append(dirent, fi) } - ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil } + ctxt.ReadDir = func(string) ([]fs.FileInfo, error) { return dirent, nil } if cfg.ModulesEnabled { - ModImportFromFiles(gofiles) + modload.ImportFromFiles(ctx, gofiles) } var err error @@ -2346,7 +2532,7 @@ func GoFilesPackage(gofiles []string) *Package { pkg := new(Package) pkg.Internal.Local = true pkg.Internal.CmdlineFiles = true - pkg.load("command-line-arguments", &stk, nil, bp, err) + pkg.load(ctx, "command-line-arguments", &stk, nil, bp, err) pkg.Internal.LocalPrefix = dirToImportPath(dir) pkg.ImportPath = "command-line-arguments" pkg.Target = "" @@ -2358,7 +2544,7 @@ func GoFilesPackage(gofiles []string) *Package { if cfg.GOBIN != "" { pkg.Target = filepath.Join(cfg.GOBIN, exe) } else if cfg.ModulesEnabled { - pkg.Target = filepath.Join(ModBinDir(), exe) + pkg.Target = filepath.Join(modload.BinDir(), exe) } } diff --git a/libgo/go/cmd/go/internal/load/test.go b/libgo/go/cmd/go/internal/load/test.go index 6d251e83583..d884361aaad 100644 --- a/libgo/go/cmd/go/internal/load/test.go +++ b/libgo/go/cmd/go/internal/load/test.go @@ -6,7 +6,7 @@ package load import ( "bytes" - "cmd/go/internal/str" + "context" "errors" "fmt" "go/ast" @@ -20,6 +20,9 @@ import ( "strings" "unicode" "unicode/utf8" + + "cmd/go/internal/str" + "cmd/go/internal/trace" ) var TestMainDeps = []string{ @@ -42,8 +45,8 @@ type TestCover struct { // TestPackagesFor is like TestPackagesAndErrors but it returns // an error if the test packages or their dependencies have errors. // Only test packages without errors are returned. -func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Package, err error) { - pmain, ptest, pxtest = TestPackagesAndErrors(p, cover) +func TestPackagesFor(ctx context.Context, p *Package, cover *TestCover) (pmain, ptest, pxtest *Package, err error) { + pmain, ptest, pxtest = TestPackagesAndErrors(ctx, p, cover) for _, p1 := range []*Package{ptest, pxtest, pmain} { if p1 == nil { // pxtest may be nil @@ -89,7 +92,10 @@ func TestPackagesFor(p *Package, cover *TestCover) (pmain, ptest, pxtest *Packag // // The caller is expected to have checked that len(p.TestGoFiles)+len(p.XTestGoFiles) > 0, // or else there's no point in any of this. -func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest *Package) { +func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (pmain, ptest, pxtest *Package) { + ctx, span := trace.StartSpan(ctx, "load.TestPackagesAndErrors") + defer span.Done() + pre := newPreload() defer pre.flush() allImports := append([]string{}, p.TestImports...) @@ -99,10 +105,11 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * var ptestErr, pxtestErr *PackageError var imports, ximports []*Package var stk ImportStack + var testEmbed, xtestEmbed map[string][]string stk.Push(p.ImportPath + " (test)") rawTestImports := str.StringList(p.TestImports) for i, path := range p.TestImports { - p1 := loadImport(pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport) + p1 := loadImport(ctx, pre, path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], ResolveImport) if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath { // Same error that loadPackage returns (via reusePackage) in pkg.go. // Can't change that code, because that code is only for loading the @@ -116,12 +123,21 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * p.TestImports[i] = p1.ImportPath imports = append(imports, p1) } + var err error + p.TestEmbedFiles, testEmbed, err = p.resolveEmbed(p.TestEmbedPatterns) + if err != nil && ptestErr == nil { + ptestErr = &PackageError{ + ImportStack: stk.Copy(), + Err: err, + } + } stk.Pop() + stk.Push(p.ImportPath + "_test") pxtestNeedsPtest := false rawXTestImports := str.StringList(p.XTestImports) for i, path := range p.XTestImports { - p1 := loadImport(pre, path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], ResolveImport) + p1 := loadImport(ctx, pre, path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], ResolveImport) if p1.ImportPath == p.ImportPath { pxtestNeedsPtest = true } else { @@ -129,6 +145,13 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * } p.XTestImports[i] = p1.ImportPath } + p.XTestEmbedFiles, xtestEmbed, err = p.resolveEmbed(p.XTestEmbedPatterns) + if err != nil && pxtestErr == nil { + pxtestErr = &PackageError{ + ImportStack: stk.Copy(), + Err: err, + } + } stk.Pop() // Test package. @@ -168,6 +191,14 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * m[k] = append(m[k], v...) } ptest.Internal.Build.ImportPos = m + if testEmbed == nil && len(p.Internal.Embed) > 0 { + testEmbed = map[string][]string{} + } + for k, v := range p.Internal.Embed { + testEmbed[k] = v + } + ptest.Internal.Embed = testEmbed + ptest.EmbedFiles = str.StringList(p.EmbedFiles, p.TestEmbedFiles) ptest.collectDeps() } else { ptest = p @@ -185,7 +216,9 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * GoFiles: p.XTestGoFiles, Imports: p.XTestImports, ForTest: p.ImportPath, + Module: p.Module, Error: pxtestErr, + EmbedFiles: p.XTestEmbedFiles, }, Internal: PackageInternal{ LocalPrefix: p.Internal.LocalPrefix, @@ -199,6 +232,7 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * Gcflags: p.Internal.Gcflags, Ldflags: p.Internal.Ldflags, Gccgoflags: p.Internal.Gccgoflags, + Embed: xtestEmbed, }, } if pxtestNeedsPtest { @@ -216,6 +250,7 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * ImportPath: p.ImportPath + ".test", Root: p.Root, Imports: str.StringList(TestMainDeps), + Module: p.Module, }, Internal: PackageInternal{ Build: &build.Package{Name: "main"}, @@ -238,7 +273,7 @@ func TestPackagesAndErrors(p *Package, cover *TestCover) (pmain, ptest, pxtest * if dep == ptest.ImportPath { pmain.Internal.Imports = append(pmain.Internal.Imports, ptest) } else { - p1 := loadImport(pre, dep, "", nil, &stk, nil, 0) + p1 := loadImport(ctx, pre, dep, "", nil, &stk, nil, 0) pmain.Internal.Imports = append(pmain.Internal.Imports, p1) } } diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock.go index aba3eed7767..05f27c321a8 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock.go @@ -9,6 +9,7 @@ package filelock import ( "errors" + "io/fs" "os" ) @@ -24,7 +25,7 @@ type File interface { Fd() uintptr // Stat returns the FileInfo structure describing file. - Stat() (os.FileInfo, error) + Stat() (fs.FileInfo, error) } // Lock places an advisory write lock on the file, blocking until it can be @@ -87,7 +88,7 @@ var ErrNotSupported = errors.New("operation not supported") // underlyingError returns the underlying error for known os error types. func underlyingError(err error) error { switch err := err.(type) { - case *os.PathError: + case *fs.PathError: return err.Err case *os.LinkError: return err.Err diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go index c3e09bbab57..ea480f8c2f6 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_fcntl.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 solaris +// +build aix solaris,!illumos // This code implements the filelock API using POSIX 'fcntl' locks, which attach // to an (inode, process) pair rather than a file descriptor. To avoid unlocking @@ -12,17 +12,14 @@ // Most platforms provide some alternative API, such as an 'flock' system call // or an F_OFD_SETLK command for 'fcntl', that allows for better concurrency and // does not require per-inode bookkeeping in the application. -// -// TODO(golang.org/issue/35618): add a syscall.Flock binding for Illumos and -// switch it over to use filelock_unix.go. package filelock import ( "errors" "io" + "io/fs" "math/rand" - "os" "sync" "syscall" "time" @@ -66,7 +63,7 @@ func lock(f File, lt lockType) (err error) { mu.Lock() if i, dup := inodes[f]; dup && i != ino { mu.Unlock() - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: errors.New("inode for file changed since last Lock or RLock"), @@ -157,7 +154,7 @@ func lock(f File, lt lockType) (err error) { if err != nil { unlock(f) - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go index 2c88c46b0ba..c09530d1b70 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_other.go @@ -6,7 +6,7 @@ package filelock -import "os" +import "io/fs" type lockType int8 @@ -16,7 +16,7 @@ const ( ) func lock(f File, lt lockType) error { - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: ErrNotSupported, @@ -24,7 +24,7 @@ func lock(f File, lt lockType) error { } func unlock(f File) error { - return &os.PathError{ + return &fs.PathError{ Op: "Unlock", Path: f.Name(), Err: ErrNotSupported, diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go index afdffe323fc..0798ee469a4 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_plan9.go @@ -6,9 +6,7 @@ package filelock -import ( - "os" -) +import "io/fs" type lockType int8 @@ -18,7 +16,7 @@ const ( ) func lock(f File, lt lockType) error { - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: ErrNotSupported, @@ -26,7 +24,7 @@ func lock(f File, lt lockType) error { } func unlock(f File) error { - return &os.PathError{ + return &fs.PathError{ Op: "Unlock", Path: f.Name(), Err: ErrNotSupported, 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 faf73446f79..2ac2052b8f5 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 @@ -9,7 +9,6 @@ package filelock_test import ( "fmt" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -51,9 +50,9 @@ func mustTempFile(t *testing.T) (f *os.File, remove func()) { t.Helper() base := filepath.Base(t.Name()) - f, err := ioutil.TempFile("", base) + f, err := os.CreateTemp("", base) if err != nil { - t.Fatalf(`ioutil.TempFile("", %q) = %v`, base, err) + t.Fatalf(`os.CreateTemp("", %q) = %v`, base, err) } t.Logf("fd %d = %s", f.Fd(), f.Name()) @@ -161,7 +160,7 @@ func TestRLockExcludesOnlyLock(t *testing.T) { doUnlockTF := false switch runtime.GOOS { - case "aix", "illumos", "solaris": + case "aix", "solaris": // When using POSIX locks (as on Solaris), we can't safely read-lock the // same inode through two different descriptors at the same time: when the // first descriptor is closed, the second descriptor would still be open but diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go index a1282fcea65..c06b0f77427 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_unix.go @@ -2,12 +2,12 @@ // 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 +// +build darwin dragonfly freebsd hurd illumos linux netbsd openbsd package filelock import ( - "os" + "io/fs" "syscall" ) @@ -26,7 +26,7 @@ func lock(f File, lt lockType) (err error) { } } if err != nil { - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, diff --git a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go index 43e85e450ec..19de27eb9b6 100644 --- a/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go +++ b/libgo/go/cmd/go/internal/lockedfile/internal/filelock/filelock_windows.go @@ -8,7 +8,7 @@ package filelock import ( "internal/syscall/windows" - "os" + "io/fs" "syscall" ) @@ -34,7 +34,7 @@ func lock(f File, lt lockType) error { err := windows.LockFileEx(syscall.Handle(f.Fd()), uint32(lt), reserved, allBytes, allBytes, ol) if err != nil { - return &os.PathError{ + return &fs.PathError{ Op: lt.String(), Path: f.Name(), Err: err, @@ -47,7 +47,7 @@ func unlock(f File) error { ol := new(syscall.Overlapped) err := windows.UnlockFileEx(syscall.Handle(f.Fd()), reserved, allBytes, allBytes, ol) if err != nil { - return &os.PathError{ + return &fs.PathError{ Op: "Unlock", Path: f.Name(), Err: err, diff --git a/libgo/go/cmd/go/internal/lockedfile/lockedfile.go b/libgo/go/cmd/go/internal/lockedfile/lockedfile.go index 59b2dba44cd..82e1a89675e 100644 --- a/libgo/go/cmd/go/internal/lockedfile/lockedfile.go +++ b/libgo/go/cmd/go/internal/lockedfile/lockedfile.go @@ -9,7 +9,7 @@ package lockedfile import ( "fmt" "io" - "io/ioutil" + "io/fs" "os" "runtime" ) @@ -35,7 +35,7 @@ type osFile struct { // OpenFile is like os.OpenFile, but returns a locked file. // If flag includes os.O_WRONLY or os.O_RDWR, the file is write-locked; // otherwise, it is read-locked. -func OpenFile(name string, flag int, perm os.FileMode) (*File, error) { +func OpenFile(name string, flag int, perm fs.FileMode) (*File, error) { var ( f = new(File) err error @@ -82,10 +82,10 @@ func Edit(name string) (*File, error) { // non-nil error. func (f *File) Close() error { if f.closed { - return &os.PathError{ + return &fs.PathError{ Op: "close", Path: f.Name(), - Err: os.ErrClosed, + Err: fs.ErrClosed, } } f.closed = true @@ -103,12 +103,12 @@ func Read(name string) ([]byte, error) { } defer f.Close() - return ioutil.ReadAll(f) + return io.ReadAll(f) } // Write opens the named file (creating it with the given permissions if needed), // then write-locks it and overwrites it with the given content. -func Write(name string, content io.Reader, perm os.FileMode) (err error) { +func Write(name string, content io.Reader, perm fs.FileMode) (err error) { f, err := OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) if err != nil { return err @@ -135,7 +135,7 @@ func Transform(name string, t func([]byte) ([]byte, error)) (err error) { } defer f.Close() - old, err := ioutil.ReadAll(f) + old, err := io.ReadAll(f) if err != nil { return err } diff --git a/libgo/go/cmd/go/internal/lockedfile/lockedfile_filelock.go b/libgo/go/cmd/go/internal/lockedfile/lockedfile_filelock.go index f63dd8664b0..efc66461ed2 100644 --- a/libgo/go/cmd/go/internal/lockedfile/lockedfile_filelock.go +++ b/libgo/go/cmd/go/internal/lockedfile/lockedfile_filelock.go @@ -7,18 +7,20 @@ package lockedfile import ( + "io/fs" "os" + "cmd/go/internal/fsys" "cmd/go/internal/lockedfile/internal/filelock" ) -func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { +func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { // On BSD systems, we could add the O_SHLOCK or O_EXLOCK flag to the OpenFile // call instead of locking separately, but we have to support separate locking // calls for Linux and Windows anyway, so it's simpler to use that approach // consistently. - f, err := os.OpenFile(name, flag&^os.O_TRUNC, perm) + f, err := fsys.OpenFile(name, flag&^os.O_TRUNC, perm) if err != nil { return nil, err } diff --git a/libgo/go/cmd/go/internal/lockedfile/lockedfile_plan9.go b/libgo/go/cmd/go/internal/lockedfile/lockedfile_plan9.go index 4a52c949763..70d6eddf2d2 100644 --- a/libgo/go/cmd/go/internal/lockedfile/lockedfile_plan9.go +++ b/libgo/go/cmd/go/internal/lockedfile/lockedfile_plan9.go @@ -7,10 +7,13 @@ package lockedfile import ( + "io/fs" "math/rand" "os" "strings" "time" + + "cmd/go/internal/fsys" ) // Opening an exclusive-use file returns an error. @@ -41,7 +44,7 @@ func isLocked(err error) bool { return false } -func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { +func openFile(name string, flag int, perm fs.FileMode) (*os.File, error) { // Plan 9 uses a mode bit instead of explicit lock/unlock syscalls. // // Per http://man.cat-v.org/plan_9/5/stat: “Exclusive use files may be open @@ -55,9 +58,9 @@ func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { // If the file was unpacked or created by some other program, it might not // have the ModeExclusive bit set. Set it before we call OpenFile, so that we // can be confident that a successful OpenFile implies exclusive use. - if fi, err := os.Stat(name); err == nil { - if fi.Mode()&os.ModeExclusive == 0 { - if err := os.Chmod(name, fi.Mode()|os.ModeExclusive); err != nil { + if fi, err := fsys.Stat(name); err == nil { + if fi.Mode()&fs.ModeExclusive == 0 { + if err := os.Chmod(name, fi.Mode()|fs.ModeExclusive); err != nil { return nil, err } } @@ -68,7 +71,7 @@ func openFile(name string, flag int, perm os.FileMode) (*os.File, error) { nextSleep := 1 * time.Millisecond const maxSleep = 500 * time.Millisecond for { - f, err := os.OpenFile(name, flag, perm|os.ModeExclusive) + f, err := fsys.OpenFile(name, flag, perm|fs.ModeExclusive) if err == nil { return f, nil } diff --git a/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go b/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go index 416c69d83bc..34327dd841e 100644 --- a/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go +++ b/libgo/go/cmd/go/internal/lockedfile/lockedfile_test.go @@ -10,7 +10,6 @@ package lockedfile_test import ( "fmt" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -23,7 +22,7 @@ import ( func mustTempDir(t *testing.T) (dir string, remove func()) { t.Helper() - dir, err := ioutil.TempDir("", filepath.Base(t.Name())) + dir, err := os.MkdirTemp("", filepath.Base(t.Name())) if err != nil { t.Fatal(err) } @@ -155,8 +154,8 @@ func TestCanLockExistingFile(t *testing.T) { defer remove() path := filepath.Join(dir, "existing.txt") - if err := ioutil.WriteFile(path, []byte("ok"), 0777); err != nil { - t.Fatalf("ioutil.WriteFile: %v", err) + if err := os.WriteFile(path, []byte("ok"), 0777); err != nil { + t.Fatalf("os.WriteFile: %v", err) } f, err := lockedfile.Edit(path) @@ -201,7 +200,7 @@ func TestSpuriousEDEADLK(t *testing.T) { } defer b.Close() - if err := ioutil.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil { + if err := os.WriteFile(filepath.Join(dir, "locked"), []byte("ok"), 0666); err != nil { t.Fatal(err) } diff --git a/libgo/go/cmd/go/internal/modcmd/download.go b/libgo/go/cmd/go/internal/modcmd/download.go index 584434935b4..ef1ad780c81 100644 --- a/libgo/go/cmd/go/internal/modcmd/download.go +++ b/libgo/go/cmd/go/internal/modcmd/download.go @@ -5,15 +5,15 @@ package modcmd import ( + "context" "encoding/json" "os" + "runtime" "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/par" - "cmd/go/internal/work" "golang.org/x/mod/module" ) @@ -63,7 +63,7 @@ func init() { // TODO(jayconrod): https://golang.org/issue/35849 Apply -x to other 'go mod' commands. cmdDownload.Flag.BoolVar(&cfg.BuildX, "x", false, "") - work.AddModCommonFlags(cmdDownload) + base.AddModCommonFlags(&cmdDownload.Flag) } type moduleJSON struct { @@ -78,56 +78,27 @@ type moduleJSON struct { GoModSum string `json:",omitempty"` } -func runDownload(cmd *base.Command, args []string) { +func runDownload(ctx context.Context, cmd *base.Command, args []string) { // Check whether modules are enabled and whether we're in a module. - if cfg.Getenv("GO111MODULE") == "off" { - base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") - } + modload.ForceUseModules = true if !modload.HasModRoot() && len(args) == 0 { base.Fatalf("go mod download: no modules specified (see 'go help mod download')") } if len(args) == 0 { args = []string{"all"} } else if modload.HasModRoot() { - modload.InitMod() // to fill Target - targetAtLatest := modload.Target.Path + "@latest" + modload.LoadModFile(ctx) // to fill Target targetAtUpgrade := modload.Target.Path + "@upgrade" targetAtPatch := modload.Target.Path + "@patch" for _, arg := range args { switch arg { - case modload.Target.Path, targetAtLatest, targetAtUpgrade, targetAtPatch: + case modload.Target.Path, targetAtUpgrade, targetAtPatch: os.Stderr.WriteString("go mod download: skipping argument " + arg + " that resolves to the main module\n") } } } - var mods []*moduleJSON - var work par.Work - listU := false - listVersions := false - for _, info := range modload.ListModules(args, listU, listVersions) { - if info.Replace != nil { - info = info.Replace - } - if info.Version == "" && info.Error == nil { - // main module or module replaced with file path. - // Nothing to download. - continue - } - m := &moduleJSON{ - Path: info.Path, - Version: info.Version, - } - mods = append(mods, m) - if info.Error != nil { - m.Error = info.Error.Err - continue - } - work.Add(m) - } - - work.Do(10, func(item interface{}) { - m := item.(*moduleJSON) + downloadModule := func(m *moduleJSON) { var err error m.Info, err = modfetch.InfoFile(m.Path, m.Version) if err != nil { @@ -145,24 +116,60 @@ func runDownload(cmd *base.Command, args []string) { return } mod := module.Version{Path: m.Path, Version: m.Version} - m.Zip, err = modfetch.DownloadZip(mod) + m.Zip, err = modfetch.DownloadZip(ctx, mod) if err != nil { m.Error = err.Error() return } m.Sum = modfetch.Sum(mod) - m.Dir, err = modfetch.Download(mod) + m.Dir, err = modfetch.Download(ctx, mod) if err != nil { m.Error = err.Error() return } - }) + } + + var mods []*moduleJSON + listU := false + listVersions := false + listRetractions := false + type token struct{} + sem := make(chan token, runtime.GOMAXPROCS(0)) + for _, info := range modload.ListModules(ctx, args, listU, listVersions, listRetractions) { + if info.Replace != nil { + info = info.Replace + } + if info.Version == "" && info.Error == nil { + // main module or module replaced with file path. + // Nothing to download. + continue + } + m := &moduleJSON{ + Path: info.Path, + Version: info.Version, + } + mods = append(mods, m) + if info.Error != nil { + m.Error = info.Error.Err + continue + } + sem <- token{} + go func() { + downloadModule(m) + <-sem + }() + } + + // Fill semaphore channel to wait for goroutines to finish. + for n := cap(sem); n > 0; n-- { + sem <- token{} + } if *downloadJSON { for _, m := range mods { b, err := json.MarshalIndent(m, "", "\t") if err != nil { - base.Fatalf("%v", err) + base.Fatalf("go mod download: %v", err) } os.Stdout.Write(append(b, '\n')) if m.Error != "" { @@ -172,9 +179,12 @@ func runDownload(cmd *base.Command, args []string) { } else { for _, m := range mods { if m.Error != "" { - base.Errorf("%s", m.Error) + base.Errorf("go mod download: %v", m.Error) } } base.ExitIfErrors() } + + // Update go.mod and especially go.sum if needed. + modload.WriteGoMod() } diff --git a/libgo/go/cmd/go/internal/modcmd/edit.go b/libgo/go/cmd/go/internal/modcmd/edit.go index dbbfb96e42b..b203a8a2b0a 100644 --- a/libgo/go/cmd/go/internal/modcmd/edit.go +++ b/libgo/go/cmd/go/internal/modcmd/edit.go @@ -8,6 +8,7 @@ package modcmd import ( "bytes" + "context" "encoding/json" "errors" "fmt" @@ -18,7 +19,6 @@ import ( "cmd/go/internal/lockedfile" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/modfile" "golang.org/x/mod/module" @@ -67,9 +67,14 @@ 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 -retract=version and -dropretract=version flags add and drop a +retraction on the given version. The version may be a single version +like "v1.2.3" or a closed interval like "[v1.1.0,v1.1.9]". Note that +-retract=version is a no-op if that retraction already exists. + The -require, -droprequire, -exclude, -dropexclude, -replace, -and -dropreplace editing flags may be repeated, and the changes -are applied in the order given. +-dropreplace, -retract, and -dropretract editing flags may be repeated, +and the changes are applied in the order given. The -go=version flag sets the expected Go language version. @@ -103,6 +108,15 @@ writing it back to go.mod. The JSON output corresponds to these Go types: New Module } + type Retract struct { + Low string + High string + Rationale string + } + +Retract entries representing a single version (not an interval) will have +the "Low" and "High" fields set to the same value. + Note that this only describes the go.mod file itself, not other modules referred to indirectly. For the full set of modules available to a build, use 'go list -m -json all'. @@ -136,12 +150,14 @@ func init() { cmdEdit.Flag.Var(flagFunc(flagDropReplace), "dropreplace", "") cmdEdit.Flag.Var(flagFunc(flagReplace), "replace", "") cmdEdit.Flag.Var(flagFunc(flagDropExclude), "dropexclude", "") + cmdEdit.Flag.Var(flagFunc(flagRetract), "retract", "") + cmdEdit.Flag.Var(flagFunc(flagDropRetract), "dropretract", "") - work.AddModCommonFlags(cmdEdit) + base.AddModCommonFlags(&cmdEdit.Flag) base.AddBuildFlagsNX(&cmdEdit.Flag) } -func runEdit(cmd *base.Command, args []string) { +func runEdit(ctx context.Context, cmd *base.Command, args []string) { anyFlags := *editModule != "" || *editGo != "" || @@ -251,12 +267,7 @@ func parsePathVersion(flag, arg string) (path, version string) { base.Fatalf("go mod: -%s=%s: invalid path: %v", flag, arg, err) } - // We don't call modfile.CheckPathVersion, because that insists - // on versions being in semver form, but here we want to allow - // versions like "master" or "1234abcdef", which the go command will resolve - // the next time it runs (or during -fix). - // Even so, we need to make sure the version is a valid token. - if modfile.MustQuote(version) { + if !allowedVersionArg(version) { base.Fatalf("go mod: -%s=%s: invalid version %q", flag, arg, version) } @@ -288,12 +299,48 @@ func parsePathVersionOptional(adj, arg string, allowDirPath bool) (path, version return path, version, fmt.Errorf("invalid %s path: %v", adj, err) } } - if path != arg && modfile.MustQuote(version) { + if path != arg && !allowedVersionArg(version) { return path, version, fmt.Errorf("invalid %s version: %q", adj, version) } return path, version, nil } +// parseVersionInterval parses a single version like "v1.2.3" or a closed +// interval like "[v1.2.3,v1.4.5]". Note that a single version has the same +// representation as an interval with equal upper and lower bounds: both +// Low and High are set. +func parseVersionInterval(arg string) (modfile.VersionInterval, error) { + if !strings.HasPrefix(arg, "[") { + if !allowedVersionArg(arg) { + return modfile.VersionInterval{}, fmt.Errorf("invalid version: %q", arg) + } + return modfile.VersionInterval{Low: arg, High: arg}, nil + } + if !strings.HasSuffix(arg, "]") { + return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg) + } + s := arg[1 : len(arg)-1] + i := strings.Index(s, ",") + if i < 0 { + return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg) + } + low := strings.TrimSpace(s[:i]) + high := strings.TrimSpace(s[i+1:]) + if !allowedVersionArg(low) || !allowedVersionArg(high) { + return modfile.VersionInterval{}, fmt.Errorf("invalid version interval: %q", arg) + } + return modfile.VersionInterval{Low: low, High: high}, nil +} + +// allowedVersionArg returns whether a token may be used as a version in go.mod. +// We don't call modfile.CheckPathVersion, because that insists on versions +// being in semver form, but here we want to allow versions like "master" or +// "1234abcdef", which the go command will resolve the next time it runs (or +// during -fix). Even so, we need to make sure the version is a valid token. +func allowedVersionArg(arg string) bool { + return !modfile.MustQuote(arg) +} + // flagRequire implements the -require flag. func flagRequire(arg string) { path, version := parsePathVersion("require", arg) @@ -376,6 +423,32 @@ func flagDropReplace(arg string) { }) } +// flagRetract implements the -retract flag. +func flagRetract(arg string) { + vi, err := parseVersionInterval(arg) + if err != nil { + base.Fatalf("go mod: -retract=%s: %v", arg, err) + } + edits = append(edits, func(f *modfile.File) { + if err := f.AddRetract(vi, ""); err != nil { + base.Fatalf("go mod: -retract=%s: %v", arg, err) + } + }) +} + +// flagDropRetract implements the -dropretract flag. +func flagDropRetract(arg string) { + vi, err := parseVersionInterval(arg) + if err != nil { + base.Fatalf("go mod: -dropretract=%s: %v", arg, err) + } + edits = append(edits, func(f *modfile.File) { + if err := f.DropRetract(vi); err != nil { + base.Fatalf("go mod: -dropretract=%s: %v", arg, err) + } + }) +} + // fileJSON is the -json output data structure. type fileJSON struct { Module module.Version @@ -383,6 +456,7 @@ type fileJSON struct { Require []requireJSON Exclude []module.Version Replace []replaceJSON + Retract []retractJSON } type requireJSON struct { @@ -396,6 +470,12 @@ type replaceJSON struct { New module.Version } +type retractJSON struct { + Low string `json:",omitempty"` + High string `json:",omitempty"` + Rationale string `json:",omitempty"` +} + // editPrintJSON prints the -json output. func editPrintJSON(modFile *modfile.File) { var f fileJSON @@ -414,6 +494,9 @@ func editPrintJSON(modFile *modfile.File) { for _, r := range modFile.Replace { f.Replace = append(f.Replace, replaceJSON{r.Old, r.New}) } + for _, r := range modFile.Retract { + f.Retract = append(f.Retract, retractJSON{r.Low, r.High, r.Rationale}) + } data, err := json.MarshalIndent(&f, "", "\t") if err != nil { base.Fatalf("go: internal error: %v", err) diff --git a/libgo/go/cmd/go/internal/modcmd/graph.go b/libgo/go/cmd/go/internal/modcmd/graph.go index 27ae9354f3d..3277548c235 100644 --- a/libgo/go/cmd/go/internal/modcmd/graph.go +++ b/libgo/go/cmd/go/internal/modcmd/graph.go @@ -8,14 +8,12 @@ package modcmd import ( "bufio" + "context" "os" "sort" "cmd/go/internal/base" - "cmd/go/internal/cfg" "cmd/go/internal/modload" - "cmd/go/internal/par" - "cmd/go/internal/work" "golang.org/x/mod/module" ) @@ -33,22 +31,16 @@ path@version, except for the main module, which has no @version suffix. } func init() { - work.AddModCommonFlags(cmdGraph) + base.AddModCommonFlags(&cmdGraph.Flag) } -func runGraph(cmd *base.Command, args []string) { +func runGraph(ctx context.Context, cmd *base.Command, args []string) { if len(args) > 0 { base.Fatalf("go mod graph: graph takes no arguments") } - // Checks go mod expected behavior - if !modload.Enabled() { - if cfg.Getenv("GO111MODULE") == "off" { - base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") - } else { - base.Fatalf("go: cannot find main module; see 'go help modules'") - } - } - modload.LoadBuildList() + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot + modload.LoadAllModules(ctx) reqs := modload.MinReqs() format := func(m module.Version) string { @@ -58,23 +50,25 @@ func runGraph(cmd *base.Command, args []string) { return m.Path + "@" + m.Version } - // Note: using par.Work only to manage work queue. - // No parallelism here, so no locking. var out []string var deps int // index in out where deps start - var work par.Work - work.Add(modload.Target) - work.Do(1, func(item interface{}) { - m := item.(module.Version) + seen := map[module.Version]bool{modload.Target: true} + queue := []module.Version{modload.Target} + for len(queue) > 0 { + var m module.Version + m, queue = queue[0], queue[1:] list, _ := reqs.Required(m) for _, r := range list { - work.Add(r) + if !seen[r] { + queue = append(queue, r) + seen[r] = true + } out = append(out, format(m)+" "+format(r)+"\n") } if m == modload.Target { deps = len(out) } - }) + } sort.Slice(out[deps:], func(i, j int) bool { return out[deps+i][0] < out[deps+j][0] diff --git a/libgo/go/cmd/go/internal/modcmd/init.go b/libgo/go/cmd/go/internal/modcmd/init.go index 714ff2e205a..c081bb547d1 100644 --- a/libgo/go/cmd/go/internal/modcmd/init.go +++ b/libgo/go/cmd/go/internal/modcmd/init.go @@ -9,46 +9,41 @@ package modcmd import ( "cmd/go/internal/base" "cmd/go/internal/modload" - "cmd/go/internal/work" - "os" - "strings" + "context" ) var cmdInit = &base.Command{ UsageLine: "go mod init [module]", Short: "initialize new module in current directory", Long: ` -Init initializes and writes a new go.mod to the current directory, -in effect creating a new module rooted at the current directory. -The file go.mod must not already exist. -If possible, init will guess the module path from import comments -(see 'go help importpath') or from version control configuration. -To override this guess, supply the module path as an argument. - `, +Init initializes and writes a new go.mod file in the current directory, in +effect creating a new module rooted at the current directory. The go.mod file +must not already exist. + +Init accepts one optional argument, the module path for the new module. If the +module path argument is omitted, init will attempt to infer the module path +using import comments in .go files, vendoring tool configuration files (like +Gopkg.lock), and the current directory (if in GOPATH). + +If a configuration file for a vendoring tool is present, init will attempt to +import module requirements from it. +`, Run: runInit, } func init() { - work.AddModCommonFlags(cmdInit) + base.AddModCommonFlags(&cmdInit.Flag) } -func runInit(cmd *base.Command, args []string) { - modload.CmdModInit = true +func runInit(ctx context.Context, cmd *base.Command, args []string) { if len(args) > 1 { base.Fatalf("go mod init: too many arguments") } + var modPath string if len(args) == 1 { - modload.CmdModModule = args[0] - } - if os.Getenv("GO111MODULE") == "off" { - base.Fatalf("go mod init: modules disabled by GO111MODULE=off; see 'go help modules'") + modPath = args[0] } - modFilePath := modload.ModFilePath() - if _, err := os.Stat(modFilePath); err == nil { - base.Fatalf("go mod init: go.mod already exists") - } - if strings.Contains(modload.CmdModModule, "@") { - base.Fatalf("go mod init: module path must not contain '@'") - } - modload.InitMod() // does all the hard work + + modload.ForceUseModules = true + modload.CreateModFile(ctx, modPath) // does all the hard work } diff --git a/libgo/go/cmd/go/internal/modcmd/tidy.go b/libgo/go/cmd/go/internal/modcmd/tidy.go index af2b04c0c20..fb43e33ec58 100644 --- a/libgo/go/cmd/go/internal/modcmd/tidy.go +++ b/libgo/go/cmd/go/internal/modcmd/tidy.go @@ -9,15 +9,13 @@ package modcmd import ( "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/modfetch" + "cmd/go/internal/imports" "cmd/go/internal/modload" - "cmd/go/internal/work" - - "golang.org/x/mod/module" + "context" ) var cmdTidy = &base.Command{ - UsageLine: "go mod tidy [-v]", + UsageLine: "go mod tidy [-e] [-v]", Short: "add missing and remove unused modules", Long: ` Tidy makes sure go.mod matches the source code in the module. @@ -28,55 +26,47 @@ to go.sum and removes any unnecessary ones. The -v flag causes tidy to print information about removed modules to standard error. + +The -e flag causes tidy to attempt to proceed despite errors +encountered while loading packages. `, + Run: runTidy, } +var tidyE bool // if true, report errors but proceed anyway. + func init() { - cmdTidy.Run = runTidy // break init cycle cmdTidy.Flag.BoolVar(&cfg.BuildV, "v", false, "") - work.AddModCommonFlags(cmdTidy) + cmdTidy.Flag.BoolVar(&tidyE, "e", false, "") + base.AddModCommonFlags(&cmdTidy.Flag) } -func runTidy(cmd *base.Command, args []string) { +func runTidy(ctx context.Context, cmd *base.Command, args []string) { if len(args) > 0 { base.Fatalf("go mod tidy: no arguments allowed") } - modload.LoadALL() + // Tidy aims to make 'go test' reproducible for any package in 'all', so we + // need to include test dependencies. For modules that specify go 1.15 or + // earlier this is a no-op (because 'all' saturates transitive test + // dependencies). + // + // However, with lazy loading (go 1.16+) 'all' includes only the packages that + // are transitively imported by the main module, not the test dependencies of + // those packages. In order to make 'go test' reproducible for the packages + // that are in 'all' but outside of the main module, we must explicitly + // request that their test dependencies be included. + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot + + modload.LoadPackages(ctx, modload.PackageOpts{ + Tags: imports.AnyTags(), + ResolveMissingImports: true, + LoadTests: true, + AllowErrors: tidyE, + }, "all") + modload.TidyBuildList() - modTidyGoSum() // updates memory copy; WriteGoMod on next line flushes it out + modload.TrimGoSum() modload.WriteGoMod() } - -// modTidyGoSum resets the go.sum file content -// to be exactly what's needed for the current go.mod. -func modTidyGoSum() { - // Assuming go.sum already has at least enough from the successful load, - // we only have to tell modfetch what needs keeping. - reqs := modload.Reqs() - keep := make(map[module.Version]bool) - replaced := make(map[module.Version]bool) - var walk func(module.Version) - walk = func(m module.Version) { - // If we build using a replacement module, keep the sum for the replacement, - // since that's the code we'll actually use during a build. - // - // TODO(golang.org/issue/29182): Perhaps we should keep both sums, and the - // sums for both sets of transitive requirements. - r := modload.Replacement(m) - if r.Path == "" { - keep[m] = true - } else { - keep[r] = true - replaced[m] = true - } - list, _ := reqs.Required(m) - for _, r := range list { - if !keep[r] && !replaced[r] { - walk(r) - } - } - } - walk(modload.Target) - modfetch.TrimGoSum(keep) -} diff --git a/libgo/go/cmd/go/internal/modcmd/vendor.go b/libgo/go/cmd/go/internal/modcmd/vendor.go index 8509ceb7a8b..1bbb57d353b 100644 --- a/libgo/go/cmd/go/internal/modcmd/vendor.go +++ b/libgo/go/cmd/go/internal/modcmd/vendor.go @@ -6,9 +6,10 @@ package modcmd import ( "bytes" + "context" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "sort" @@ -16,16 +17,16 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/imports" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/module" "golang.org/x/mod/semver" ) var cmdVendor = &base.Command{ - UsageLine: "go mod vendor [-v]", + UsageLine: "go mod vendor [-e] [-v]", Short: "make vendored copy of dependencies", Long: ` Vendor resets the main module's vendor directory to include all packages @@ -34,20 +35,35 @@ It does not include test code for vendored packages. The -v flag causes vendor to print the names of vendored modules and packages to standard error. + +The -e flag causes vendor to attempt to proceed despite errors +encountered while loading packages. `, Run: runVendor, } +var vendorE bool // if true, report errors but proceed anyway + func init() { cmdVendor.Flag.BoolVar(&cfg.BuildV, "v", false, "") - work.AddModCommonFlags(cmdVendor) + cmdVendor.Flag.BoolVar(&vendorE, "e", false, "") + base.AddModCommonFlags(&cmdVendor.Flag) } -func runVendor(cmd *base.Command, args []string) { +func runVendor(ctx context.Context, cmd *base.Command, args []string) { if len(args) != 0 { base.Fatalf("go mod vendor: vendor takes no arguments") } - pkgs := modload.LoadVendor() + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot + + loadOpts := modload.PackageOpts{ + Tags: imports.AnyTags(), + ResolveMissingImports: true, + UseVendorAll: true, + AllowErrors: vendorE, + } + _, pkgs := modload.LoadPackages(ctx, loadOpts, "all") vdir := filepath.Join(modload.ModRoot(), "vendor") if err := os.RemoveAll(vdir); err != nil { @@ -57,7 +73,7 @@ func runVendor(cmd *base.Command, args []string) { modpkgs := make(map[module.Version][]string) for _, pkg := range pkgs { m := modload.PackageModule(pkg) - if m == modload.Target { + if m.Path == "" || m == modload.Target { continue } modpkgs[m] = append(modpkgs[m], pkg) @@ -75,28 +91,38 @@ func runVendor(cmd *base.Command, args []string) { includeAllReplacements = true } + var vendorMods []module.Version + for m := range isExplicit { + vendorMods = append(vendorMods, m) + } + for m := range modpkgs { + if !isExplicit[m] { + vendorMods = append(vendorMods, m) + } + } + module.Sort(vendorMods) + var buf bytes.Buffer - for _, m := range modload.BuildList()[1:] { - if pkgs := modpkgs[m]; len(pkgs) > 0 || isExplicit[m] { - line := moduleLine(m, modload.Replacement(m)) - buf.WriteString(line) + for _, m := range vendorMods { + line := moduleLine(m, modload.Replacement(m)) + buf.WriteString(line) + if cfg.BuildV { + os.Stderr.WriteString(line) + } + if isExplicit[m] { + buf.WriteString("## explicit\n") if cfg.BuildV { - os.Stderr.WriteString(line) + os.Stderr.WriteString("## explicit\n") } - if isExplicit[m] { - buf.WriteString("## explicit\n") - if cfg.BuildV { - os.Stderr.WriteString("## explicit\n") - } - } - sort.Strings(pkgs) - for _, pkg := range pkgs { - fmt.Fprintf(&buf, "%s\n", pkg) - if cfg.BuildV { - fmt.Fprintf(os.Stderr, "%s\n", pkg) - } - vendorPkg(vdir, pkg) + } + pkgs := modpkgs[m] + sort.Strings(pkgs) + for _, pkg := range pkgs { + fmt.Fprintf(&buf, "%s\n", pkg) + if cfg.BuildV { + fmt.Fprintf(os.Stderr, "%s\n", pkg) } + vendorPkg(vdir, pkg) } } @@ -128,7 +154,7 @@ func runVendor(cmd *base.Command, args []string) { base.Fatalf("go mod vendor: %v", err) } - if err := ioutil.WriteFile(filepath.Join(vdir, "modules.txt"), buf.Bytes(), 0666); err != nil { + if err := os.WriteFile(filepath.Join(vdir, "modules.txt"), buf.Bytes(), 0666); err != nil { base.Fatalf("go mod vendor: %v", err) } } @@ -217,7 +243,7 @@ var metaPrefixes = []string{ } // matchMetadata reports whether info is a metadata file. -func matchMetadata(dir string, info os.FileInfo) bool { +func matchMetadata(dir string, info fs.DirEntry) bool { name := info.Name() for _, p := range metaPrefixes { if strings.HasPrefix(name, p) { @@ -228,12 +254,12 @@ func matchMetadata(dir string, info os.FileInfo) bool { } // matchPotentialSourceFile reports whether info may be relevant to a build operation. -func matchPotentialSourceFile(dir string, info os.FileInfo) bool { +func matchPotentialSourceFile(dir string, info fs.DirEntry) bool { if strings.HasSuffix(info.Name(), "_test.go") { return false } if strings.HasSuffix(info.Name(), ".go") { - f, err := os.Open(filepath.Join(dir, info.Name())) + f, err := fsys.Open(filepath.Join(dir, info.Name())) if err != nil { base.Fatalf("go mod vendor: %v", err) } @@ -254,8 +280,8 @@ func matchPotentialSourceFile(dir string, info os.FileInfo) bool { } // copyDir copies all regular files satisfying match(info) from src to dst. -func copyDir(dst, src string, match func(dir string, info os.FileInfo) bool) { - files, err := ioutil.ReadDir(src) +func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool) { + files, err := os.ReadDir(src) if err != nil { base.Fatalf("go mod vendor: %v", err) } @@ -263,7 +289,7 @@ func copyDir(dst, src string, match func(dir string, info os.FileInfo) bool) { base.Fatalf("go mod vendor: %v", err) } for _, file := range files { - if file.IsDir() || !file.Mode().IsRegular() || !match(src, file) { + if file.IsDir() || !file.Type().IsRegular() || !match(src, file) { continue } r, err := os.Open(filepath.Join(src, file.Name())) diff --git a/libgo/go/cmd/go/internal/modcmd/verify.go b/libgo/go/cmd/go/internal/modcmd/verify.go index b7fd7fa8e01..c83e70076ae 100644 --- a/libgo/go/cmd/go/internal/modcmd/verify.go +++ b/libgo/go/cmd/go/internal/modcmd/verify.go @@ -6,17 +6,16 @@ package modcmd import ( "bytes" + "context" "errors" "fmt" - "io/ioutil" + "io/fs" "os" "runtime" "cmd/go/internal/base" - "cmd/go/internal/cfg" "cmd/go/internal/modfetch" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/module" "golang.org/x/mod/sumdb/dirhash" @@ -37,29 +36,23 @@ non-zero status. } func init() { - work.AddModCommonFlags(cmdVerify) + base.AddModCommonFlags(&cmdVerify.Flag) } -func runVerify(cmd *base.Command, args []string) { +func runVerify(ctx context.Context, 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() || !modload.HasModRoot() { - if cfg.Getenv("GO111MODULE") == "off" { - base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") - } else { - base.Fatalf("go: cannot find main module; see 'go help modules'") - } - } + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot // Only verify up to GOMAXPROCS zips at once. type token struct{} sem := make(chan token, runtime.GOMAXPROCS(0)) // Use a slice of result channels, so that the output is deterministic. - mods := modload.LoadBuildList()[1:] + mods := modload.LoadAllModules(ctx)[1:] errsChans := make([]<-chan []error, len(mods)) for i, mod := range mods { @@ -93,10 +86,10 @@ func verifyMod(mod module.Version) []error { _, zipErr = os.Stat(zip) } dir, dirErr := modfetch.DownloadDir(mod) - data, err := ioutil.ReadFile(zip + "hash") + data, err := os.ReadFile(zip + "hash") if err != nil { - if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) && - dirErr != nil && errors.Is(dirErr, os.ErrNotExist) { + if zipErr != nil && errors.Is(zipErr, fs.ErrNotExist) && + dirErr != nil && errors.Is(dirErr, fs.ErrNotExist) { // Nothing downloaded yet. Nothing to verify. return nil } @@ -105,7 +98,7 @@ func verifyMod(mod module.Version) []error { } h := string(bytes.TrimSpace(data)) - if zipErr != nil && errors.Is(zipErr, os.ErrNotExist) { + if zipErr != nil && errors.Is(zipErr, fs.ErrNotExist) { // ok } else { hZ, err := dirhash.HashZip(zip, dirhash.DefaultHash) @@ -116,7 +109,7 @@ func verifyMod(mod module.Version) []error { errs = append(errs, fmt.Errorf("%s %s: zip has been modified (%v)", mod.Path, mod.Version, zip)) } } - if dirErr != nil && errors.Is(dirErr, os.ErrNotExist) { + if dirErr != nil && errors.Is(dirErr, fs.ErrNotExist) { // ok } else { hD, err := dirhash.HashDir(dir, mod.Path+"@"+mod.Version, dirhash.DefaultHash) diff --git a/libgo/go/cmd/go/internal/modcmd/why.go b/libgo/go/cmd/go/internal/modcmd/why.go index 40d238519b2..e287c880601 100644 --- a/libgo/go/cmd/go/internal/modcmd/why.go +++ b/libgo/go/cmd/go/internal/modcmd/why.go @@ -5,12 +5,13 @@ package modcmd import ( + "context" "fmt" "strings" "cmd/go/internal/base" + "cmd/go/internal/imports" "cmd/go/internal/modload" - "cmd/go/internal/work" "golang.org/x/mod/module" ) @@ -57,25 +58,33 @@ var ( func init() { cmdWhy.Run = runWhy // break init cycle - work.AddModCommonFlags(cmdWhy) + base.AddModCommonFlags(&cmdWhy.Flag) } -func runWhy(cmd *base.Command, args []string) { - loadALL := modload.LoadALL - if *whyVendor { - loadALL = modload.LoadVendor +func runWhy(ctx context.Context, cmd *base.Command, args []string) { + modload.ForceUseModules = true + modload.RootMode = modload.NeedRoot + + loadOpts := modload.PackageOpts{ + Tags: imports.AnyTags(), + LoadTests: !*whyVendor, + SilenceErrors: true, + UseVendorAll: *whyVendor, } + if *whyM { listU := false listVersions := false + listRetractions := false for _, arg := range args { if strings.Contains(arg, "@") { base.Fatalf("go mod why: module query not allowed") } } - mods := modload.ListModules(args, listU, listVersions) + mods := modload.ListModules(ctx, args, listU, listVersions, listRetractions) byModule := make(map[module.Version][]string) - for _, path := range loadALL() { + _, pkgs := modload.LoadPackages(ctx, loadOpts, "all") + for _, path := range pkgs { m := modload.PackageModule(path) if m.Path != "" { byModule[m] = append(byModule[m], path) @@ -104,8 +113,11 @@ func runWhy(cmd *base.Command, args []string) { sep = "\n" } } else { - matches := modload.ImportPaths(args) // resolve to packages - loadALL() // rebuild graph, from main module (not from named packages) + // Resolve to packages. + matches, _ := modload.LoadPackages(ctx, loadOpts, args...) + + modload.LoadPackages(ctx, loadOpts, "all") // rebuild graph, from main module (not from named packages) + sep := "" for _, m := range matches { for _, path := range m.Pkgs { diff --git a/libgo/go/cmd/go/internal/modconv/convert.go b/libgo/go/cmd/go/internal/modconv/convert.go index f465a9f395b..5d4165c9443 100644 --- a/libgo/go/cmd/go/internal/modconv/convert.go +++ b/libgo/go/cmd/go/internal/modconv/convert.go @@ -7,13 +7,12 @@ package modconv import ( "fmt" "os" + "runtime" "sort" "strings" - "sync" "cmd/go/internal/base" "cmd/go/internal/modfetch" - "cmd/go/internal/par" "golang.org/x/mod/modfile" "golang.org/x/mod/module" @@ -42,46 +41,54 @@ func ConvertLegacyConfig(f *modfile.File, file string, data []byte) error { // Convert requirements block, which may use raw SHA1 hashes as versions, // to valid semver requirement list, respecting major versions. - var ( - work par.Work - mu sync.Mutex - need = make(map[string]string) - replace = make(map[string]*modfile.Replace) - ) + versions := make([]module.Version, len(mf.Require)) + replace := make(map[string]*modfile.Replace) for _, r := range mf.Replace { replace[r.New.Path] = r replace[r.Old.Path] = r } - for _, r := range mf.Require { + + type token struct{} + sem := make(chan token, runtime.GOMAXPROCS(0)) + for i, r := range mf.Require { m := r.Mod if m.Path == "" { continue } if re, ok := replace[m.Path]; ok { - work.Add(re.New) - continue + m = re.New } - work.Add(r.Mod) + sem <- token{} + go func(i int, m module.Version) { + defer func() { <-sem }() + repo, info, err := modfetch.ImportRepoRev(m.Path, m.Version) + if err != nil { + fmt.Fprintf(os.Stderr, "go: converting %s: stat %s@%s: %v\n", base.ShortPath(file), m.Path, m.Version, err) + return + } + + path := repo.ModulePath() + versions[i].Path = path + versions[i].Version = info.Version + }(i, m) + } + // Fill semaphore channel to wait for all tasks to finish. + for n := cap(sem); n > 0; n-- { + sem <- token{} } - work.Do(10, func(item interface{}) { - r := item.(module.Version) - repo, info, err := modfetch.ImportRepoRev(r.Path, r.Version) - if err != nil { - fmt.Fprintf(os.Stderr, "go: converting %s: stat %s@%s: %v\n", base.ShortPath(file), r.Path, r.Version, err) - return + need := map[string]string{} + for _, v := range versions { + if v.Path == "" { + continue } - mu.Lock() - path := repo.ModulePath() // Don't use semver.Max here; need to preserve +incompatible suffix. - if v, ok := need[path]; !ok || semver.Compare(v, info.Version) < 0 { - need[path] = info.Version + if needv, ok := need[v.Path]; !ok || semver.Compare(needv, v.Version) < 0 { + need[v.Path] = v.Version } - mu.Unlock() - }) - - var paths []string + } + paths := make([]string, 0, len(need)) for path := range need { paths = append(paths, path) } diff --git a/libgo/go/cmd/go/internal/modconv/convert_test.go b/libgo/go/cmd/go/internal/modconv/convert_test.go index a04a13b14f5..66b9ff4f382 100644 --- a/libgo/go/cmd/go/internal/modconv/convert_test.go +++ b/libgo/go/cmd/go/internal/modconv/convert_test.go @@ -6,9 +6,9 @@ package modconv import ( "bytes" + "context" "fmt" "internal/testenv" - "io/ioutil" "log" "os" "os/exec" @@ -36,7 +36,7 @@ func testMain(m *testing.M) int { return 0 } - dir, err := ioutil.TempDir("", "modconv-test-") + dir, err := os.MkdirTemp("", "modconv-test-") if err != nil { log.Fatal(err) } @@ -146,6 +146,8 @@ func TestConvertLegacyConfig(t *testing.T) { }, } + ctx := context.Background() + for _, tt := range tests { t.Run(strings.ReplaceAll(tt.path, "/", "_")+"_"+tt.vers, func(t *testing.T) { f, err := modfile.Parse("golden", []byte(tt.gomod), nil) @@ -157,14 +159,14 @@ func TestConvertLegacyConfig(t *testing.T) { t.Fatal(err) } - dir, err := modfetch.Download(module.Version{Path: tt.path, Version: tt.vers}) + dir, err := modfetch.Download(ctx, module.Version{Path: tt.path, Version: tt.vers}) if err != nil { t.Fatal(err) } for name := range Converters { file := filepath.Join(dir, name) - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err == nil { f := new(modfile.File) f.AddModuleStmt(tt.path) diff --git a/libgo/go/cmd/go/internal/modconv/modconv_test.go b/libgo/go/cmd/go/internal/modconv/modconv_test.go index ccc4f3d576f..750525d404b 100644 --- a/libgo/go/cmd/go/internal/modconv/modconv_test.go +++ b/libgo/go/cmd/go/internal/modconv/modconv_test.go @@ -7,7 +7,7 @@ package modconv import ( "bytes" "fmt" - "io/ioutil" + "os" "path/filepath" "testing" ) @@ -42,7 +42,7 @@ func Test(t *testing.T) { if Converters[extMap[ext]] == nil { t.Fatalf("Converters[%q] == nil", extMap[ext]) } - data, err := ioutil.ReadFile(test) + data, err := os.ReadFile(test) if err != nil { t.Fatal(err) } @@ -50,7 +50,7 @@ func Test(t *testing.T) { if err != nil { t.Fatal(err) } - want, err := ioutil.ReadFile(test[:len(test)-len(ext)] + ".out") + want, err := os.ReadFile(test[:len(test)-len(ext)] + ".out") if err != nil { t.Error(err) } diff --git a/libgo/go/cmd/go/internal/modfetch/cache.go b/libgo/go/cmd/go/internal/modfetch/cache.go index e3074b775e6..3a2ff63721c 100644 --- a/libgo/go/cmd/go/internal/modfetch/cache.go +++ b/libgo/go/cmd/go/internal/modfetch/cache.go @@ -10,10 +10,11 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "strings" + "sync" "cmd/go/internal/base" "cmd/go/internal/cfg" @@ -59,7 +60,7 @@ func CachePath(m module.Version, suffix string) (string, error) { // DownloadDir returns the directory to which m should have been downloaded. // An error will be returned if the module path or version cannot be escaped. -// An error satisfying errors.Is(err, os.ErrNotExist) will be returned +// An error satisfying errors.Is(err, fs.ErrNotExist) will be returned // along with the directory if the directory does not exist or if the directory // is not completely populated. func DownloadDir(m module.Version) (string, error) { @@ -106,14 +107,14 @@ func DownloadDir(m module.Version) (string, error) { // DownloadDirPartialError is returned by DownloadDir if a module directory // exists but was not completely populated. // -// DownloadDirPartialError is equivalent to os.ErrNotExist. +// DownloadDirPartialError is equivalent to fs.ErrNotExist. type DownloadDirPartialError struct { Dir string Err error } func (e *DownloadDirPartialError) Error() string { return fmt.Sprintf("%s: %v", e.Dir, e.Err) } -func (e *DownloadDirPartialError) Is(err error) bool { return err == os.ErrNotExist } +func (e *DownloadDirPartialError) Is(err error) bool { return err == fs.ErrNotExist } // lockVersion locks a file within the module cache that guards the downloading // and extraction of the zipfile for the given module version. @@ -155,16 +156,30 @@ func SideLock() (unlock func(), err error) { type cachingRepo struct { path string cache par.Cache // cache for all operations - r Repo + + once sync.Once + initRepo func() (Repo, error) + r Repo } -func newCachingRepo(r Repo) *cachingRepo { +func newCachingRepo(path string, initRepo func() (Repo, error)) *cachingRepo { return &cachingRepo{ - r: r, - path: r.ModulePath(), + path: path, + initRepo: initRepo, } } +func (r *cachingRepo) repo() Repo { + r.once.Do(func() { + var err error + r.r, err = r.initRepo() + if err != nil { + r.r = errRepo{r.path, err} + } + }) + return r.r +} + func (r *cachingRepo) ModulePath() string { return r.path } @@ -175,7 +190,7 @@ func (r *cachingRepo) Versions(prefix string) ([]string, error) { err error } c := r.cache.Do("versions:"+prefix, func() interface{} { - list, err := r.r.Versions(prefix) + list, err := r.repo().Versions(prefix) return cached{list, err} }).(cached) @@ -197,7 +212,7 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) { return cachedInfo{info, nil} } - info, err = r.r.Stat(rev) + info, err = r.repo().Stat(rev) if err == nil { // If we resolved, say, 1234abcde to v0.0.0-20180604122334-1234abcdef78, // then save the information under the proper version, for future use. @@ -224,7 +239,7 @@ func (r *cachingRepo) Stat(rev string) (*RevInfo, error) { func (r *cachingRepo) Latest() (*RevInfo, error) { c := r.cache.Do("latest:", func() interface{} { - info, err := r.r.Latest() + info, err := r.repo().Latest() // Save info for likely future Stat call. if err == nil { @@ -258,7 +273,7 @@ func (r *cachingRepo) GoMod(version string) ([]byte, error) { return cached{text, nil} } - text, err = r.r.GoMod(version) + text, err = r.repo().GoMod(version) if err == nil { if err := checkGoMod(r.path, version, text); err != nil { return cached{text, err} @@ -277,26 +292,11 @@ func (r *cachingRepo) GoMod(version string) ([]byte, error) { } func (r *cachingRepo) Zip(dst io.Writer, version string) error { - return r.r.Zip(dst, version) -} - -// Stat is like Lookup(path).Stat(rev) but avoids the -// repository path resolution in Lookup if the result is -// already cached on local disk. -func Stat(proxy, path, rev string) (*RevInfo, error) { - _, info, err := readDiskStat(path, rev) - if err == nil { - return info, nil - } - repo, err := Lookup(proxy, path) - if err != nil { - return nil, err - } - return repo.Stat(rev) + return r.repo().Zip(dst, version) } -// InfoFile is like Stat but returns the name of the file containing -// the cached information. +// InfoFile is like Lookup(path).Stat(version) but returns the name of the file +// containing the cached information. func InfoFile(path, version string) (string, error) { if !semver.IsValid(version) { return "", fmt.Errorf("invalid version %q", version) @@ -307,10 +307,7 @@ func InfoFile(path, version string) (string, error) { } err := TryProxies(func(proxy string) error { - repo, err := Lookup(proxy, path) - if err == nil { - _, err = repo.Stat(version) - } + _, err := Lookup(proxy, path).Stat(version) return err }) if err != nil { @@ -336,11 +333,7 @@ func GoMod(path, rev string) ([]byte, error) { rev = info.Version } else { err := TryProxies(func(proxy string) error { - repo, err := Lookup(proxy, path) - if err != nil { - return err - } - info, err := repo.Stat(rev) + info, err := Lookup(proxy, path).Stat(rev) if err == nil { rev = info.Version } @@ -357,11 +350,8 @@ func GoMod(path, rev string) ([]byte, error) { return data, nil } - err = TryProxies(func(proxy string) error { - repo, err := Lookup(proxy, path) - if err == nil { - data, err = repo.GoMod(rev) - } + err = TryProxies(func(proxy string) (err error) { + data, err = Lookup(proxy, path).GoMod(rev) return err }) return data, err @@ -492,7 +482,7 @@ func readDiskStatByHash(path, rev string) (file string, info *RevInfo, err error for _, name := range names { if strings.HasSuffix(name, suffix) { v := strings.TrimSuffix(name, ".info") - if IsPseudoVersion(v) && semver.Max(maxVersion, v) == v { + if IsPseudoVersion(v) && semver.Compare(v, maxVersion) > 0 { maxVersion = v file, info, err = readDiskStat(path, strings.TrimSuffix(name, ".info")) } @@ -607,7 +597,7 @@ func rewriteVersionList(dir string) { } defer unlock() - infos, err := ioutil.ReadDir(dir) + infos, err := os.ReadDir(dir) if err != nil { return } diff --git a/libgo/go/cmd/go/internal/modfetch/cache_test.go b/libgo/go/cmd/go/internal/modfetch/cache_test.go index 241c800e692..722c984e376 100644 --- a/libgo/go/cmd/go/internal/modfetch/cache_test.go +++ b/libgo/go/cmd/go/internal/modfetch/cache_test.go @@ -5,14 +5,13 @@ package modfetch import ( - "io/ioutil" "os" "path/filepath" "testing" ) func TestWriteDiskCache(t *testing.T) { - tmpdir, err := ioutil.TempDir("", "go-writeCache-test-") + tmpdir, err := os.MkdirTemp("", "go-writeCache-test-") if err != nil { t.Fatal(err) } diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go index d85eddf767b..86c1c14d4a7 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/codehost.go @@ -11,7 +11,7 @@ import ( "crypto/sha256" "fmt" "io" - "io/ioutil" + "io/fs" "os" "os/exec" "path/filepath" @@ -79,9 +79,8 @@ type Repo interface { 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. - // An empty major string matches any major version. - RecentTag(rev, prefix, major string) (tag string, err error) + // with the given prefix. allowed may be used to filter out unwanted versions. + RecentTag(rev, prefix string, allowed func(string) bool) (tag string, err error) // DescendsFrom reports whether rev or any of its ancestors has the given tag. // @@ -106,7 +105,7 @@ type FileRev struct { Err error // error if any; os.IsNotExist(Err)==true if rev exists but file does not exist in that rev } -// UnknownRevisionError is an error equivalent to os.ErrNotExist, but for a +// UnknownRevisionError is an error equivalent to fs.ErrNotExist, but for a // revision rather than a file. type UnknownRevisionError struct { Rev string @@ -116,10 +115,10 @@ func (e *UnknownRevisionError) Error() string { return "unknown revision " + e.Rev } func (UnknownRevisionError) Is(err error) bool { - return err == os.ErrNotExist + return err == fs.ErrNotExist } -// ErrNoCommits is an error equivalent to os.ErrNotExist indicating that a given +// ErrNoCommits is an error equivalent to fs.ErrNotExist indicating that a given // repository or module contains no commits. var ErrNoCommits error = noCommitsError{} @@ -129,7 +128,7 @@ func (noCommitsError) Error() string { return "no commits" } func (noCommitsError) Is(err error) bool { - return err == os.ErrNotExist + return err == fs.ErrNotExist } // AllHex reports whether the revision rev is entirely lower-case hexadecimal digits. @@ -189,7 +188,7 @@ func WorkDir(typ, name string) (dir, lockfile string, err error) { } defer unlock() - data, err := ioutil.ReadFile(dir + ".info") + data, err := os.ReadFile(dir + ".info") info, err2 := os.Stat(dir) if err == nil && err2 == nil && info.IsDir() { // Info file and directory both already exist: reuse. @@ -211,7 +210,7 @@ func WorkDir(typ, name string) (dir, lockfile string, err error) { if err := os.MkdirAll(dir, 0777); err != nil { return "", "", err } - if err := ioutil.WriteFile(dir+".info", []byte(key), 0666); err != nil { + if err := os.WriteFile(dir+".info", []byte(key), 0666); err != nil { os.RemoveAll(dir) return "", "", err } @@ -264,6 +263,9 @@ func RunWithStdin(dir string, stdin io.Reader, cmdline ...interface{}) ([]byte, } cmd := str.StringList(cmdline...) + if os.Getenv("TESTGOVCS") == "panic" { + panic(fmt.Sprintf("use of vcs: %v", cmd)) + } if cfg.BuildX { text := new(strings.Builder) if dir != "" { diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/git.go b/libgo/go/cmd/go/internal/modfetch/codehost/git.go index 31921324a7d..8abc039e7fc 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/git.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/git.go @@ -9,7 +9,7 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "net/url" "os" "os/exec" @@ -34,13 +34,13 @@ func LocalGitRepo(remote string) (Repo, error) { } // A notExistError wraps another error to retain its original text -// but makes it opaquely equivalent to os.ErrNotExist. +// but makes it opaquely equivalent to fs.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 } +func (notExistError) Is(err error) bool { return err == fs.ErrNotExist } const gitWorkDirType = "git3" @@ -188,7 +188,7 @@ func (r *gitRepo) loadRefs() { // 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) { + if _, err := web.GetBytes(u); errors.Is(err, fs.ErrNotExist) { gitErr = notExistError{gitErr} } } @@ -505,7 +505,7 @@ func (r *gitRepo) ReadFile(rev, file string, maxSize int64) ([]byte, error) { } out, err := Run(r.dir, "git", "cat-file", "blob", info.Name+":"+file) if err != nil { - return nil, os.ErrNotExist + return nil, fs.ErrNotExist } return out, nil } @@ -629,9 +629,9 @@ func (r *gitRepo) readFileRevs(tags []string, file string, fileMap map[string]*F case "tag", "commit": switch fileType { default: - f.Err = &os.PathError{Path: tag + ":" + file, Op: "read", Err: fmt.Errorf("unexpected non-blob type %q", fileType)} + f.Err = &fs.PathError{Path: tag + ":" + file, Op: "read", Err: fmt.Errorf("unexpected non-blob type %q", fileType)} case "missing": - f.Err = &os.PathError{Path: tag + ":" + file, Op: "read", Err: os.ErrNotExist} + f.Err = &fs.PathError{Path: tag + ":" + file, Op: "read", Err: fs.ErrNotExist} case "blob": f.Data = fileData } @@ -644,7 +644,7 @@ func (r *gitRepo) readFileRevs(tags []string, file string, fileMap map[string]*F return missing, nil } -func (r *gitRepo) RecentTag(rev, prefix, major string) (tag string, err error) { +func (r *gitRepo) RecentTag(rev, prefix string, allowed func(string) bool) (tag string, err error) { info, err := r.Stat(rev) if err != nil { return "", err @@ -680,7 +680,10 @@ func (r *gitRepo) RecentTag(rev, prefix, major string) (tag string, err error) { // NOTE: Do not replace the call to semver.Compare with semver.Max. // We want to return the actual tag, not a canonicalized version of it, // and semver.Max currently canonicalizes (see golang.org/issue/32700). - if c := semver.Canonical(semtag); c != "" && strings.HasPrefix(semtag, c) && (major == "" || semver.Major(c) == major) && semver.Compare(semtag, highest) > 0 { + if c := semver.Canonical(semtag); c == "" || !strings.HasPrefix(semtag, c) || !allowed(semtag) { + continue + } + if semver.Compare(semtag, highest) > 0 { highest = semtag } } @@ -823,12 +826,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, fs.ErrNotExist } return nil, err } - return ioutil.NopCloser(bytes.NewReader(archive)), nil + return io.NopCloser(bytes.NewReader(archive)), nil } // ensureGitAttributes makes sure export-subst and export-ignore features are @@ -859,7 +862,7 @@ func ensureGitAttributes(repoDir string) (err error) { } }() - b, err := ioutil.ReadAll(f) + b, err := io.ReadAll(f) if err != nil { return err } 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 ba27c70f5a0..89a73baad9d 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/git_test.go @@ -10,7 +10,8 @@ import ( "flag" "fmt" "internal/testenv" - "io/ioutil" + "io" + "io/fs" "log" "os" "os/exec" @@ -52,7 +53,7 @@ func testMain(m *testing.M) int { return 0 } - dir, err := ioutil.TempDir("", "gitrepo-test-") + dir, err := os.MkdirTemp("", "gitrepo-test-") if err != nil { log.Fatal(err) } @@ -210,7 +211,7 @@ var readFileTests = []struct { repo: gitrepo1, rev: "v2.3.4", file: "another.txt", - err: os.ErrNotExist.Error(), + err: fs.ErrNotExist.Error(), }, } @@ -432,7 +433,7 @@ func TestReadZip(t *testing.T) { if tt.err != "" { t.Fatalf("ReadZip: no error, wanted %v", tt.err) } - zipdata, err := ioutil.ReadAll(rc) + zipdata, err := io.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 2762c557203..ce8b501d53c 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/shell.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/shell.go @@ -14,7 +14,7 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" + "io" "log" "os" "strings" @@ -115,7 +115,7 @@ func main() { fmt.Fprintf(os.Stderr, "?%s\n", err) continue } - data, err := ioutil.ReadAll(rc) + data, err := io.ReadAll(rc) rc.Close() if err != nil { fmt.Fprintf(os.Stderr, "?%s\n", err) @@ -123,7 +123,7 @@ func main() { } if f[3] != "-" { - if err := ioutil.WriteFile(f[3], data, 0666); err != nil { + if err := os.WriteFile(f[3], data, 0666); err != nil { fmt.Fprintf(os.Stderr, "?%s\n", err) continue } diff --git a/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go b/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go index 7284557f4ba..c2cca084e30 100644 --- a/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go +++ b/libgo/go/cmd/go/internal/modfetch/codehost/vcs.go @@ -9,7 +9,7 @@ import ( "fmt" "internal/lazyregexp" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "sort" @@ -377,7 +377,7 @@ func (r *vcsRepo) ReadFile(rev, file string, maxSize int64) ([]byte, error) { out, err := Run(r.dir, r.cmd.readFile(rev, file, r.remote)) if err != nil { - return nil, os.ErrNotExist + return nil, fs.ErrNotExist } return out, nil } @@ -395,7 +395,7 @@ func (r *vcsRepo) ReadFileRevs(revs []string, file string, maxSize int64) (map[s return nil, vcsErrorf("ReadFileRevs not implemented") } -func (r *vcsRepo) RecentTag(rev, prefix, major string) (tag string, err error) { +func (r *vcsRepo) RecentTag(rev, prefix string, allowed func(string) bool) (tag string, err error) { // We don't technically need to lock here since we're returning an error // uncondititonally, but doing so anyway will help to avoid baking in // lock-inversion bugs. @@ -432,7 +432,7 @@ func (r *vcsRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, if rev == "latest" { rev = r.cmd.latest } - f, err := ioutil.TempFile("", "go-readzip-*.zip") + f, err := os.CreateTemp("", "go-readzip-*.zip") if err != nil { return nil, err } @@ -567,7 +567,7 @@ func bzrParseStat(rev, out string) (*RevInfo, error) { func fossilParseStat(rev, out string) (*RevInfo, error) { for _, line := range strings.Split(out, "\n") { - if strings.HasPrefix(line, "uuid:") { + if strings.HasPrefix(line, "uuid:") || strings.HasPrefix(line, "hash:") { f := strings.Fields(line) if len(f) != 5 || len(f[1]) != 40 || f[4] != "UTC" { return nil, vcsErrorf("unexpected response from fossil info: %q", line) diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo.go b/libgo/go/cmd/go/internal/modfetch/coderepo.go index d043903336c..2dcbb99b185 100644 --- a/libgo/go/cmd/go/internal/modfetch/coderepo.go +++ b/libgo/go/cmd/go/internal/modfetch/coderepo.go @@ -10,7 +10,7 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path" "sort" @@ -419,9 +419,14 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e tagPrefix = r.codeDir + "/" } + isRetracted, err := r.retractedVersions() + if err != nil { + isRetracted = func(string) bool { return false } + } + // tagToVersion returns the version obtained by trimming tagPrefix from tag. - // If the tag is invalid or a pseudo-version, tagToVersion returns an empty - // version. + // If the tag is invalid, retracted, or a pseudo-version, tagToVersion returns + // an empty version. tagToVersion := func(tag string) (v string, tagIsCanonical bool) { if !strings.HasPrefix(tag, tagPrefix) { return "", false @@ -436,6 +441,9 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e if v == "" || !strings.HasPrefix(trimmed, v) { return "", false // Invalid or incomplete version (just vX or vX.Y). } + if isRetracted(v) { + return "", false + } if v == trimmed { tagIsCanonical = true } @@ -500,15 +508,24 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e return checkGoMod() } + // Find the highest tagged version in the revision's history, subject to + // major version and +incompatible constraints. Use that version as the + // pseudo-version base so that the pseudo-version sorts higher. Ignore + // retracted versions. + allowedMajor := func(major string) func(v string) bool { + return func(v string) bool { + return (major == "" || semver.Major(v) == major) && !isRetracted(v) + } + } if pseudoBase == "" { var tag string if r.pseudoMajor != "" || canUseIncompatible() { - tag, _ = r.code.RecentTag(info.Name, tagPrefix, r.pseudoMajor) + tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor(r.pseudoMajor)) } else { // Allow either v1 or v0, but not incompatible higher versions. - tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v1") + tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v1")) if tag == "" { - tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v0") + tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v0")) } } pseudoBase, _ = tagToVersion(tag) // empty if the tag is invalid @@ -869,6 +886,57 @@ func (r *codeRepo) modPrefix(rev string) string { return r.modPath + "@" + rev } +func (r *codeRepo) retractedVersions() (func(string) bool, error) { + versions, err := r.Versions("") + if err != nil { + return nil, err + } + + for i, v := range versions { + if strings.HasSuffix(v, "+incompatible") { + versions = versions[:i] + break + } + } + if len(versions) == 0 { + return func(string) bool { return false }, nil + } + + var highest string + for i := len(versions) - 1; i >= 0; i-- { + v := versions[i] + if semver.Prerelease(v) == "" { + highest = v + break + } + } + if highest == "" { + highest = versions[len(versions)-1] + } + + data, err := r.GoMod(highest) + if err != nil { + return nil, err + } + f, err := modfile.ParseLax("go.mod", data, nil) + if err != nil { + return nil, err + } + retractions := make([]modfile.VersionInterval, len(f.Retract)) + for _, r := range f.Retract { + retractions = append(retractions, r.VersionInterval) + } + + return func(v string) bool { + for _, r := range retractions { + if semver.Compare(r.Low, v) <= 0 && semver.Compare(v, r.High) <= 0 { + return true + } + } + return false + }, nil +} + func (r *codeRepo) Zip(dst io.Writer, version string) error { if version != module.CanonicalVersion(version) { return fmt.Errorf("version %s is not canonical", version) @@ -897,7 +965,7 @@ func (r *codeRepo) Zip(dst io.Writer, version string) error { subdir = strings.Trim(subdir, "/") // Spool to local file. - f, err := ioutil.TempFile("", "go-codehost-") + f, err := os.CreateTemp("", "go-codehost-") if err != nil { dl.Close() return err @@ -972,7 +1040,7 @@ type zipFile struct { } func (f zipFile) Path() string { return f.name } -func (f zipFile) Lstat() (os.FileInfo, error) { return f.f.FileInfo(), nil } +func (f zipFile) Lstat() (fs.FileInfo, error) { return f.f.FileInfo(), nil } func (f zipFile) Open() (io.ReadCloser, error) { return f.f.Open() } type dataFile struct { @@ -981,9 +1049,9 @@ type dataFile struct { } func (f dataFile) Path() string { return f.name } -func (f dataFile) Lstat() (os.FileInfo, error) { return dataFileInfo{f}, nil } +func (f dataFile) Lstat() (fs.FileInfo, error) { return dataFileInfo{f}, nil } func (f dataFile) Open() (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewReader(f.data)), nil + return io.NopCloser(bytes.NewReader(f.data)), nil } type dataFileInfo struct { @@ -992,7 +1060,7 @@ type dataFileInfo struct { 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) Mode() fs.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 } diff --git a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go index 9a0cd7dba69..02e399f3525 100644 --- a/libgo/go/cmd/go/internal/modfetch/coderepo_test.go +++ b/libgo/go/cmd/go/internal/modfetch/coderepo_test.go @@ -11,7 +11,6 @@ import ( "hash" "internal/testenv" "io" - "io/ioutil" "log" "os" "reflect" @@ -38,7 +37,7 @@ func testMain(m *testing.M) int { // code, bypass the sum database. cfg.GOSUMDB = "off" - dir, err := ioutil.TempDir("", "gitrepo-test-") + dir, err := os.MkdirTemp("", "gitrepo-test-") if err != nil { log.Fatal(err) } @@ -60,7 +59,6 @@ var altVgotests = map[string]string{ type codeRepoTest struct { vcs string path string - lookErr string mpath string rev string err string @@ -332,9 +330,9 @@ var codeRepoTests = []codeRepoTest{ // package in subdirectory - custom domain // In general we can't reject these definitively in Lookup, // but gopkg.in is special. - vcs: "git", - path: "gopkg.in/yaml.v2/abc", - lookErr: "invalid module path \"gopkg.in/yaml.v2/abc\"", + vcs: "git", + path: "gopkg.in/yaml.v2/abc", + err: "invalid module path \"gopkg.in/yaml.v2/abc\"", }, { // package in subdirectory - github @@ -425,7 +423,7 @@ var codeRepoTests = []codeRepoTest{ func TestCodeRepo(t *testing.T) { testenv.MustHaveExternalNetwork(t) - tmpdir, err := ioutil.TempDir("", "modfetch-test-") + tmpdir, err := os.MkdirTemp("", "modfetch-test-") if err != nil { t.Fatal(err) } @@ -440,16 +438,7 @@ func TestCodeRepo(t *testing.T) { testenv.MustHaveExecPath(t, tt.vcs) } - repo, err := Lookup("direct", tt.path) - if tt.lookErr != "" { - if err != nil && err.Error() == tt.lookErr { - return - } - t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookErr) - } - if err != nil { - t.Fatalf("Lookup(%q): %v", tt.path, err) - } + repo := Lookup("direct", tt.path) if tt.mpath == "" { tt.mpath = tt.path @@ -501,9 +490,9 @@ func TestCodeRepo(t *testing.T) { needHash := !testing.Short() && (tt.zipFileHash != "" || tt.zipSum != "") if tt.zip != nil || tt.zipErr != "" || needHash { - f, err := ioutil.TempFile(tmpdir, tt.version+".zip.") + f, err := os.CreateTemp(tmpdir, tt.version+".zip.") if err != nil { - t.Fatalf("ioutil.TempFile: %v", err) + t.Fatalf("os.CreateTemp: %v", err) } zipfile := f.Name() defer func() { @@ -665,7 +654,7 @@ var codeRepoVersionsTests = []struct { func TestCodeRepoVersions(t *testing.T) { testenv.MustHaveExternalNetwork(t) - tmpdir, err := ioutil.TempDir("", "vgo-modfetch-test-") + tmpdir, err := os.MkdirTemp("", "vgo-modfetch-test-") if err != nil { t.Fatal(err) } @@ -680,10 +669,7 @@ func TestCodeRepoVersions(t *testing.T) { testenv.MustHaveExecPath(t, tt.vcs) } - repo, err := Lookup("direct", tt.path) - if err != nil { - t.Fatalf("Lookup(%q): %v", tt.path, err) - } + repo := Lookup("direct", tt.path) list, err := repo.Versions(tt.prefix) if err != nil { t.Fatalf("Versions(%q): %v", tt.prefix, err) @@ -742,7 +728,7 @@ var latestTests = []struct { func TestLatest(t *testing.T) { testenv.MustHaveExternalNetwork(t) - tmpdir, err := ioutil.TempDir("", "vgo-modfetch-test-") + tmpdir, err := os.MkdirTemp("", "vgo-modfetch-test-") if err != nil { t.Fatal(err) } @@ -758,10 +744,7 @@ func TestLatest(t *testing.T) { testenv.MustHaveExecPath(t, tt.vcs) } - repo, err := Lookup("direct", tt.path) - if err != nil { - t.Fatalf("Lookup(%q): %v", tt.path, err) - } + repo := Lookup("direct", tt.path) info, err := repo.Latest() if err != nil { if tt.err != "" { diff --git a/libgo/go/cmd/go/internal/modfetch/fetch.go b/libgo/go/cmd/go/internal/modfetch/fetch.go index fd7a5cef831..debeb3f3194 100644 --- a/libgo/go/cmd/go/internal/modfetch/fetch.go +++ b/libgo/go/cmd/go/internal/modfetch/fetch.go @@ -7,10 +7,11 @@ package modfetch import ( "archive/zip" "bytes" + "context" "errors" "fmt" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "sort" @@ -23,6 +24,7 @@ import ( "cmd/go/internal/par" "cmd/go/internal/renameio" "cmd/go/internal/robustio" + "cmd/go/internal/trace" "golang.org/x/mod/module" "golang.org/x/mod/sumdb/dirhash" @@ -34,7 +36,7 @@ var downloadCache par.Cache // Download downloads the specific module version to the // local download cache and returns the name of the directory // corresponding to the root of the module's file tree. -func Download(mod module.Version) (dir string, err error) { +func Download(ctx context.Context, mod module.Version) (dir string, err error) { if cfg.GOMODCACHE == "" { // modload.Init exits if GOPATH[0] is empty, and cfg.GOMODCACHE // is set to GOPATH[0]/pkg/mod if GOMODCACHE is empty, so this should never happen. @@ -47,7 +49,7 @@ func Download(mod module.Version) (dir string, err error) { err error } c := downloadCache.Do(mod, func() interface{} { - dir, err := download(mod) + dir, err := download(ctx, mod) if err != nil { return cached{"", err} } @@ -57,22 +59,22 @@ func Download(mod module.Version) (dir string, err error) { return c.dir, c.err } -func download(mod module.Version) (dir string, err error) { - // If the directory exists, and no .partial file exists, the module has - // already been completely extracted. .partial files may be created when a - // module zip directory is extracted in place instead of being extracted to a - // temporary directory and renamed. +func download(ctx context.Context, mod module.Version) (dir string, err error) { + ctx, span := trace.StartSpan(ctx, "modfetch.download "+mod.String()) + defer span.Done() + dir, err = DownloadDir(mod) if err == nil { + // The directory has already been completely extracted (no .partial file exists). return dir, nil - } else if dir == "" || !errors.Is(err, os.ErrNotExist) { + } else if dir == "" || !errors.Is(err, fs.ErrNotExist) { return "", err } // To avoid cluttering the cache with extraneous files, // DownloadZip uses the same lockfile as Download. // Invoke DownloadZip before locking the file. - zipfile, err := DownloadZip(mod) + zipfile, err := DownloadZip(ctx, mod) if err != nil { return "", err } @@ -83,6 +85,9 @@ func download(mod module.Version) (dir string, err error) { } defer unlock() + ctx, span = trace.StartSpan(ctx, "unzip "+zipfile) + defer span.Done() + // Check whether the directory was populated while we were waiting on the lock. _, dirErr := DownloadDir(mod) if dirErr == nil { @@ -90,10 +95,11 @@ func download(mod module.Version) (dir string, err error) { } _, dirExists := dirErr.(*DownloadDirPartialError) - // Clean up any remaining temporary directories from previous runs, as well - // as partially extracted diectories created by future versions of cmd/go. - // This is only safe to do because the lock file ensures that their writers - // are no longer active. + // Clean up any remaining temporary directories created by old versions + // (before 1.16), as well as partially extracted directories (indicated by + // DownloadDirPartialError, usually because of a .partial file). This is only + // safe to do because the lock file ensures that their writers are no longer + // active. parentDir := filepath.Dir(dir) tmpPrefix := filepath.Base(dir) + ".tmp-" if old, err := filepath.Glob(filepath.Join(parentDir, tmpPrefix+"*")); err == nil { @@ -111,91 +117,49 @@ func download(mod module.Version) (dir string, err error) { if err != nil { return "", err } - if err := os.Remove(partialPath); err != nil && !os.IsNotExist(err) { - return "", err - } - // Extract the module zip directory. + // Extract the module zip directory at its final location. // - // By default, we extract to a temporary directory, then atomically rename to - // its final location. We use the existence of the source directory to signal - // that it has been extracted successfully (see DownloadDir). If someone - // deletes the entire directory (e.g., as an attempt to prune out file - // corruption), the module cache will still be left in a recoverable - // state. + // To prevent other processes from reading the directory if we crash, + // create a .partial file before extracting the directory, and delete + // the .partial file afterward (all while holding the lock). // - // Unfortunately, os.Rename may fail with ERROR_ACCESS_DENIED on Windows if - // another process opens files in the temporary directory. This is partially - // mitigated by using robustio.Rename, which retries os.Rename for a short - // time. + // Before Go 1.16, we extracted to a temporary directory with a random name + // then renamed it into place with os.Rename. On Windows, this failed with + // ERROR_ACCESS_DENIED when another process (usually an anti-virus scanner) + // opened files in the temporary directory. // - // To avoid this error completely, if unzipInPlace is set, we instead create a - // .partial file (indicating the directory isn't fully extracted), then we - // extract the directory at its final location, then we delete the .partial - // file. This is not the default behavior because older versions of Go may - // simply stat the directory to check whether it exists without looking for a - // .partial file. If multiple versions run concurrently, the older version may - // assume a partially extracted directory is complete. - // TODO(golang.org/issue/36568): when these older versions are no longer - // supported, remove the old default behavior and the unzipInPlace flag. + // Go 1.14.2 and higher respect .partial files. Older versions may use + // partially extracted directories. 'go mod verify' can detect this, + // and 'go clean -modcache' can fix it. if err := os.MkdirAll(parentDir, 0777); err != nil { return "", err } - - if unzipInPlace { - if err := ioutil.WriteFile(partialPath, nil, 0666); err != nil { - return "", err - } - if err := modzip.Unzip(dir, mod, zipfile); err != nil { - fmt.Fprintf(os.Stderr, "-> %s\n", err) - if rmErr := RemoveAll(dir); rmErr == nil { - os.Remove(partialPath) - } - return "", err - } - if err := os.Remove(partialPath); err != nil { - return "", err - } - } else { - tmpDir, err := ioutil.TempDir(parentDir, tmpPrefix) - if err != nil { - return "", err - } - if err := modzip.Unzip(tmpDir, mod, zipfile); err != nil { - fmt.Fprintf(os.Stderr, "-> %s\n", err) - RemoveAll(tmpDir) - return "", err - } - if err := robustio.Rename(tmpDir, dir); err != nil { - RemoveAll(tmpDir) - return "", err + if err := os.WriteFile(partialPath, nil, 0666); err != nil { + return "", err + } + if err := modzip.Unzip(dir, mod, zipfile); err != nil { + fmt.Fprintf(os.Stderr, "-> %s\n", err) + if rmErr := RemoveAll(dir); rmErr == nil { + os.Remove(partialPath) } + return "", err + } + if err := os.Remove(partialPath); err != nil { + return "", err } 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 dir, nil } -var unzipInPlace bool - -func init() { - for _, f := range strings.Split(os.Getenv("GODEBUG"), ",") { - if f == "modcacheunzipinplace=1" { - unzipInPlace = true - break - } - } -} - var downloadZipCache par.Cache // DownloadZip downloads the specific module version to the // local zip cache and returns the name of the zip file. -func DownloadZip(mod module.Version) (zipfile string, err error) { +func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err error) { // The par.Cache here avoids duplicate work. type cached struct { zipfile string @@ -230,7 +194,7 @@ func DownloadZip(mod module.Version) (zipfile string, err error) { if err := os.MkdirAll(filepath.Dir(zipfile), 0777); err != nil { return cached{"", err} } - if err := downloadZip(mod, zipfile); err != nil { + if err := downloadZip(ctx, mod, zipfile); err != nil { return cached{"", err} } return cached{zipfile, nil} @@ -238,7 +202,10 @@ func DownloadZip(mod module.Version) (zipfile string, err error) { return c.zipfile, c.err } -func downloadZip(mod module.Version, zipfile string) (err error) { +func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err error) { + ctx, span := trace.StartSpan(ctx, "modfetch.downloadZip "+zipfile) + defer span.Done() + // Clean up any remaining tempfiles from previous runs. // This is only safe to do because the lock file ensures that their // writers are no longer active. @@ -255,7 +222,7 @@ func downloadZip(mod module.Version, zipfile string) (err error) { // contents of the file (by hashing it) before we commit it. Because the file // is zip-compressed, we need an actual file — or at least an io.ReaderAt — to // validate it: we can't just tee the stream as we write it. - f, err := ioutil.TempFile(filepath.Dir(zipfile), filepath.Base(renameio.Pattern(zipfile))) + f, err := os.CreateTemp(filepath.Dir(zipfile), filepath.Base(renameio.Pattern(zipfile))) if err != nil { return err } @@ -266,12 +233,28 @@ func downloadZip(mod module.Version, zipfile string) (err error) { } }() + var unrecoverableErr error err = TryProxies(func(proxy string) error { - repo, err := Lookup(proxy, mod.Path) + if unrecoverableErr != nil { + return unrecoverableErr + } + repo := Lookup(proxy, mod.Path) + err := repo.Zip(f, mod.Version) if err != nil { - return err + // Zip may have partially written to f before failing. + // (Perhaps the server crashed while sending the file?) + // Since we allow fallback on error in some cases, we need to fix up the + // file to be empty again for the next attempt. + if _, err := f.Seek(0, io.SeekStart); err != nil { + unrecoverableErr = err + return err + } + if err := f.Truncate(0); err != nil { + unrecoverableErr = err + return err + } } - return repo.Zip(f, mod.Version) + return err }) if err != nil { return err @@ -331,12 +314,13 @@ func downloadZip(mod module.Version, zipfile string) (err error) { func makeDirsReadOnly(dir string) { type pathMode struct { path string - mode os.FileMode + mode fs.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() { + filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { + if err == nil && d.IsDir() { + info, err := d.Info() + if err == nil && info.Mode()&0222 != 0 { dirs = append(dirs, pathMode{path, info.Mode()}) } } @@ -353,7 +337,7 @@ func makeDirsReadOnly(dir string) { // 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 { + filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { if err != nil { return nil // ignore errors walking in file system } @@ -374,12 +358,14 @@ type modSum struct { var goSum struct { mu sync.Mutex - m map[module.Version][]string // content of go.sum file (+ go.modverify if present) - checked map[modSum]bool // sums actually checked during execution - dirty bool // whether we added any new sums to m + m map[module.Version][]string // content of go.sum file + status map[modSum]modSumStatus // state of sums in m overwrite bool // if true, overwrite go.sum without incorporating its contents enabled bool // whether to use go.sum at all - modverify string // path to go.modverify, to be deleted +} + +type modSumStatus struct { + used, dirty bool } // initGoSum initializes the go.sum data. @@ -395,7 +381,7 @@ func initGoSum() (bool, error) { } goSum.m = make(map[module.Version][]string) - goSum.checked = make(map[modSum]bool) + goSum.status = make(map[modSum]modSumStatus) data, err := lockedfile.Read(GoSumFile) if err != nil && !os.IsNotExist(err) { return false, err @@ -403,19 +389,6 @@ func initGoSum() (bool, error) { goSum.enabled = true readGoSum(goSum.m, GoSumFile, data) - // Add old go.modverify file. - // We'll delete go.modverify in WriteGoSum. - alt := strings.TrimSuffix(GoSumFile, ".sum") + ".modverify" - if data, err := renameio.ReadFile(alt); err == nil { - migrate := make(map[module.Version][]string) - readGoSum(migrate, alt, data) - for mod, sums := range migrate { - for _, sum := range sums { - addModSumLocked(mod, sum) - } - } - goSum.modverify = alt - } return true, nil } @@ -455,6 +428,28 @@ func readGoSum(dst map[module.Version][]string, file string, data []byte) error return nil } +// HaveSum returns true if the go.sum file contains an entry for mod. +// The entry's hash must be generated with a known hash algorithm. +// mod.Version may have a "/go.mod" suffix to distinguish sums for +// .mod and .zip files. +func HaveSum(mod module.Version) bool { + goSum.mu.Lock() + defer goSum.mu.Unlock() + inited, err := initGoSum() + if err != nil || !inited { + return false + } + for _, h := range goSum.m[mod] { + if !strings.HasPrefix(h, "h1:") { + continue + } + if !goSum.status[modSum{mod, h}].dirty { + return true + } + } + return false +} + // checkMod checks the given module's checksum. func checkMod(mod module.Version) { if cfg.GOMODCACHE == "" { @@ -469,7 +464,7 @@ func checkMod(mod module.Version) { } data, err := renameio.ReadFile(ziphash) if err != nil { - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { // This can happen if someone does rm -rf GOPATH/src/cache/download. So it goes. return } @@ -488,7 +483,7 @@ func checkMod(mod module.Version) { // goModSum returns the checksum for the go.mod contents. func goModSum(data []byte) (string, error) { return dirhash.Hash1([]string{"go.mod"}, func(string) (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewReader(data)), nil + return io.NopCloser(bytes.NewReader(data)), nil }) } @@ -504,6 +499,9 @@ func checkGoMod(path, version string, data []byte) error { } // checkModSum checks that the recorded checksum for mod is h. +// +// mod.Version may have the additional suffix "/go.mod" to request the checksum +// for the module's go.mod file only. func checkModSum(mod module.Version, h string) error { // We lock goSum when manipulating it, // but we arrange to release the lock when calling checkSumDB, @@ -518,6 +516,11 @@ func checkModSum(mod module.Version, h string) error { return err } done := inited && haveModSumLocked(mod, h) + if inited { + st := goSum.status[modSum{mod, h}] + st.used = true + goSum.status[modSum{mod, h}] = st + } goSum.mu.Unlock() if done { @@ -537,6 +540,9 @@ func checkModSum(mod module.Version, h string) error { if inited { goSum.mu.Lock() addModSumLocked(mod, h) + st := goSum.status[modSum{mod, h}] + st.dirty = true + goSum.status[modSum{mod, h}] = st goSum.mu.Unlock() } return nil @@ -546,7 +552,6 @@ func checkModSum(mod module.Version, h string) error { // If it finds a conflicting pair instead, it calls base.Fatalf. // goSum.mu must be locked. func haveModSumLocked(mod module.Version, h string) bool { - goSum.checked[modSum{mod, h}] = true for _, vh := range goSum.m[mod] { if h == vh { return true @@ -568,15 +573,21 @@ func addModSumLocked(mod module.Version, h string) { fmt.Fprintf(os.Stderr, "warning: verifying %s@%s: unknown hashes in go.sum: %v; adding %v"+hashVersionMismatch, mod.Path, mod.Version, strings.Join(goSum.m[mod], ", "), h) } goSum.m[mod] = append(goSum.m[mod], h) - goSum.dirty = true } // 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) error { + modWithoutSuffix := mod + noun := "module" + if strings.HasSuffix(mod.Version, "/go.mod") { + noun = "go.mod" + modWithoutSuffix.Version = strings.TrimSuffix(mod.Version, "/go.mod") + } + db, lines, err := lookupSumDB(mod) if err != nil { - return module.VersionError(mod, fmt.Errorf("verifying module: %v", err)) + return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: %v", noun, err)) } have := mod.Path + " " + mod.Version + " " + h @@ -586,7 +597,7 @@ func checkSumDB(mod module.Version, h string) error { return nil } if strings.HasPrefix(line, prefix) { - 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 module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, noun, h, db, line[len(prefix)-len("h1:"):])) } } return nil @@ -612,18 +623,35 @@ func Sum(mod module.Version) string { } // WriteGoSum writes the go.sum file if it needs to be updated. -func WriteGoSum() { +// +// keep is used to check whether a newly added sum should be saved in go.sum. +// It should have entries for both module content sums and go.mod sums +// (version ends with "/go.mod"). Existing sums will be preserved unless they +// have been marked for deletion with TrimGoSum. +func WriteGoSum(keep map[module.Version]bool) { goSum.mu.Lock() defer goSum.mu.Unlock() + // If we haven't read the go.sum file yet, don't bother writing it. if !goSum.enabled { - // If we haven't read the go.sum file yet, don't bother writing it: at best, - // we could rename the go.modverify file if it isn't empty, but we haven't - // needed to touch it so far — how important could it be? return } - if !goSum.dirty { - // Don't bother opening the go.sum file if we don't have anything to add. + + // Check whether we need to add sums for which keep[m] is true or remove + // unused sums marked with TrimGoSum. If there are no changes to make, + // just return without opening go.sum. + dirty := false +Outer: + for m, hs := range goSum.m { + for _, h := range hs { + st := goSum.status[modSum{m, h}] + if st.dirty && (!st.used || keep[m]) { + dirty = true + break Outer + } + } + } + if !dirty { return } if cfg.BuildMod == "readonly" { @@ -644,9 +672,10 @@ func WriteGoSum() { // 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 + for ms, st := range goSum.status { + if st.used { + addModSumLocked(ms.mod, ms.sum) + } } } @@ -661,7 +690,10 @@ func WriteGoSum() { list := goSum.m[m] sort.Strings(list) for _, h := range list { - fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h) + st := goSum.status[modSum{m, h}] + if !st.dirty || (st.used && keep[m]) { + fmt.Fprintf(&buf, "%s %s %s\n", m.Path, m.Version, h) + } } } return buf.Bytes(), nil @@ -671,16 +703,16 @@ func WriteGoSum() { base.Fatalf("go: updating go.sum: %v", err) } - goSum.checked = make(map[modSum]bool) - goSum.dirty = false + goSum.status = make(map[modSum]modSumStatus) goSum.overwrite = false - - if goSum.modverify != "" { - os.Remove(goSum.modverify) // best effort - } } -// TrimGoSum trims go.sum to contain only the modules for which keep[m] is true. +// TrimGoSum trims go.sum to contain only the modules needed for reproducible +// builds. +// +// keep is used to check whether a sum should be retained in go.mod. It should +// have entries for both module content sums and go.mod sums (version ends +// with "/go.mod"). func TrimGoSum(keep map[module.Version]bool) { goSum.mu.Lock() defer goSum.mu.Unlock() @@ -692,13 +724,11 @@ func TrimGoSum(keep map[module.Version]bool) { return } - for m := range goSum.m { - // If we're keeping x@v we also keep x@v/go.mod. - // Map x@v/go.mod back to x@v for the keep lookup. - noGoMod := module.Version{Path: m.Path, Version: strings.TrimSuffix(m.Version, "/go.mod")} - if !keep[m] && !keep[noGoMod] { - delete(goSum.m, m) - goSum.dirty = true + for m, hs := range goSum.m { + if !keep[m] { + for _, h := range hs { + goSum.status[modSum{m, h}] = modSumStatus{used: false, dirty: true} + } goSum.overwrite = true } } @@ -818,16 +848,16 @@ the checksum database is not consulted, and all unrecognized modules are accepted, at the cost of giving up the security guarantee of verified repeatable downloads for all modules. A better way to bypass the checksum database for specific modules is to use the GOPRIVATE or GONOSUMDB environment -variables. See 'go help module-private' for details. +variables. See 'go help private' for details. The 'go env -w' command (see 'go help env') can be used to set these variables for future go command invocations. `, } -var HelpModulePrivate = &base.Command{ - UsageLine: "module-private", - Short: "module configuration for non-public modules", +var HelpPrivate = &base.Command{ + UsageLine: "private", + Short: "configuration for downloading non-public code", Long: ` The go command defaults to downloading modules from the public Go module mirror at proxy.golang.org. It also defaults to validating downloaded modules, @@ -868,6 +898,11 @@ be used for downloading both public and private modules, because GONOPROXY has been set to a pattern that won't match any modules, overriding GOPRIVATE. +The GOPRIVATE variable is also used to define the "public" and "private" +patterns for the GOVCS variable; see 'go help vcs'. For that usage, +GOPRIVATE applies even in GOPATH mode. In that case, it matches import paths +instead of module paths. + The 'go env -w' command (see 'go help env') can be used to set these variables for future go command invocations. `, diff --git a/libgo/go/cmd/go/internal/modfetch/insecure.go b/libgo/go/cmd/go/internal/modfetch/insecure.go index 8420432d6cd..012d05f29db 100644 --- a/libgo/go/cmd/go/internal/modfetch/insecure.go +++ b/libgo/go/cmd/go/internal/modfetch/insecure.go @@ -6,11 +6,11 @@ package modfetch import ( "cmd/go/internal/cfg" - "cmd/go/internal/get" - "cmd/go/internal/str" + + "golang.org/x/mod/module" ) // 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) + return cfg.Insecure || module.MatchPrefixPatterns(cfg.GOINSECURE, path) } diff --git a/libgo/go/cmd/go/internal/modfetch/proxy.go b/libgo/go/cmd/go/internal/modfetch/proxy.go index 1c35d0b99bd..d75b4da5215 100644 --- a/libgo/go/cmd/go/internal/modfetch/proxy.go +++ b/libgo/go/cmd/go/internal/modfetch/proxy.go @@ -9,9 +9,8 @@ import ( "errors" "fmt" "io" - "io/ioutil" + "io/fs" "net/url" - "os" "path" pathpkg "path" "path/filepath" @@ -186,7 +185,7 @@ func proxyList() ([]proxySpec, error) { // TryProxies iterates f over each configured proxy (including "noproxy" and // "direct" if applicable) until f returns no error or until f returns an -// error that is not equivalent to os.ErrNotExist on a proxy configured +// error that is not equivalent to fs.ErrNotExist on a proxy configured // not to fall back on errors. // // TryProxies then returns that final error. @@ -222,7 +221,7 @@ func TryProxies(f func(proxy string) error) error { if err == nil { return nil } - isNotExistErr := errors.Is(err, os.ErrNotExist) + isNotExistErr := errors.Is(err, fs.ErrNotExist) if proxy.url == "direct" || (proxy.url == "noproxy" && err != errUseProxy) { bestErr = err @@ -242,8 +241,9 @@ func TryProxies(f func(proxy string) error) error { } type proxyRepo struct { - url *url.URL - path string + url *url.URL + path string + redactedURL string } func newProxyRepo(baseURL, path string) (Repo, error) { @@ -268,10 +268,10 @@ func newProxyRepo(baseURL, path string) (Repo, error) { if err != nil { return nil, err } - + redactedURL := base.Redacted() base.Path = strings.TrimSuffix(base.Path, "/") + "/" + enc base.RawPath = strings.TrimSuffix(base.RawPath, "/") + "/" + pathEscape(enc) - return &proxyRepo{base, path}, nil + return &proxyRepo{base, path, redactedURL}, nil } func (p *proxyRepo) ModulePath() string { @@ -304,7 +304,7 @@ func (p *proxyRepo) getBytes(path string) ([]byte, error) { return nil, err } defer body.Close() - return ioutil.ReadAll(body) + return io.ReadAll(body) } func (p *proxyRepo) getBody(path string) (io.ReadCloser, error) { @@ -413,7 +413,7 @@ func (p *proxyRepo) Stat(rev string) (*RevInfo, error) { } info := new(RevInfo) if err := json.Unmarshal(data, info); err != nil { - return nil, p.versionError(rev, err) + return nil, p.versionError(rev, fmt.Errorf("invalid response from proxy %q: %w", p.redactedURL, err)) } if info.Version != rev && rev == module.CanonicalVersion(rev) && module.Check(p.path, rev) == nil { // If we request a correct, appropriate version for the module path, the @@ -427,14 +427,14 @@ func (p *proxyRepo) Stat(rev string) (*RevInfo, error) { func (p *proxyRepo) Latest() (*RevInfo, error) { data, err := p.getBytes("@latest") if err != nil { - if !errors.Is(err, os.ErrNotExist) { + if !errors.Is(err, fs.ErrNotExist) { return nil, p.versionError("", err) } return p.latest() } info := new(RevInfo) if err := json.Unmarshal(data, info); err != nil { - return nil, p.versionError("", err) + return nil, p.versionError("", fmt.Errorf("invalid response from proxy %q: %w", p.redactedURL, err)) } return info, nil } diff --git a/libgo/go/cmd/go/internal/modfetch/pseudo.go b/libgo/go/cmd/go/internal/modfetch/pseudo.go index 20c0b060ab4..93eb0fad961 100644 --- a/libgo/go/cmd/go/internal/modfetch/pseudo.go +++ b/libgo/go/cmd/go/internal/modfetch/pseudo.go @@ -76,6 +76,12 @@ func PseudoVersion(major, older string, t time.Time, rev string) string { return v + incDecimal(patch) + "-0." + segment + build } +// ZeroPseudoVersion returns a pseudo-version with a zero timestamp and +// revision, which may be used as a placeholder. +func ZeroPseudoVersion(major string) string { + return PseudoVersion(major, "", time.Time{}, "000000000000") +} + // incDecimal returns the decimal string incremented by 1. func incDecimal(decimal string) string { // Scan right to left turning 9s to 0s until you find a digit to increment. @@ -120,6 +126,12 @@ func IsPseudoVersion(v string) bool { return strings.Count(v, "-") >= 2 && semver.IsValid(v) && pseudoVersionRE.MatchString(v) } +// IsZeroPseudoVersion returns whether v is a pseudo-version with a zero base, +// timestamp, and revision, as returned by ZeroPseudoVersion. +func IsZeroPseudoVersion(v string) bool { + return v == ZeroPseudoVersion(semver.Major(v)) +} + // PseudoVersionTime returns the time stamp of the pseudo-version v. // It returns an error if v is not a pseudo-version or if the time stamp // embedded in the pseudo-version is not a valid time. diff --git a/libgo/go/cmd/go/internal/modfetch/repo.go b/libgo/go/cmd/go/internal/modfetch/repo.go index f03bdd8d038..af9e24cefdc 100644 --- a/libgo/go/cmd/go/internal/modfetch/repo.go +++ b/libgo/go/cmd/go/internal/modfetch/repo.go @@ -7,18 +7,19 @@ package modfetch import ( "fmt" "io" + "io/fs" "os" "sort" "strconv" "time" "cmd/go/internal/cfg" - "cmd/go/internal/get" "cmd/go/internal/modfetch/codehost" "cmd/go/internal/par" - "cmd/go/internal/str" + "cmd/go/internal/vcs" web "cmd/go/internal/web" + "golang.org/x/mod/module" "golang.org/x/mod/semver" ) @@ -32,8 +33,17 @@ type Repo interface { // Versions lists all known versions with the given prefix. // Pseudo-versions are not included. + // // Versions should be returned sorted in semver order // (implementations can use SortVersions). + // + // Versions returns a non-nil error only if there was a problem + // fetching the list of versions: it may return an empty list + // along with a nil error if the list of matching versions + // is known to be empty. + // + // If the underlying repository does not exist, + // Versions returns an error matching errors.Is(_, os.NotExist). Versions(prefix string) ([]string, error) // Stat returns information about the revision rev. @@ -188,27 +198,26 @@ type lookupCacheKey struct { // // A successful return does not guarantee that the module // has any defined versions. -func Lookup(proxy, path string) (Repo, error) { +func Lookup(proxy, path string) Repo { if traceRepo { defer logCall("Lookup(%q, %q)", proxy, path)() } type cached struct { - r Repo - err error + r Repo } c := lookupCache.Do(lookupCacheKey{proxy, path}, func() interface{} { - r, err := lookup(proxy, path) - if err == nil { - if traceRepo { + r := newCachingRepo(path, func() (Repo, error) { + r, err := lookup(proxy, path) + if err == nil && traceRepo { r = newLoggingRepo(r) } - r = newCachingRepo(r) - } - return cached{r, err} + return r, err + }) + return cached{r} }).(cached) - return c.r, c.err + return c.r } // lookup returns the module with the given module path. @@ -217,7 +226,7 @@ func lookup(proxy, path string) (r Repo, err error) { return nil, errLookupDisabled } - if str.GlobsMatchPath(cfg.GONOPROXY, path) { + if module.MatchPrefixPatterns(cfg.GONOPROXY, path) { switch proxy { case "noproxy", "direct": return lookupDirect(path) @@ -228,7 +237,7 @@ func lookup(proxy, path string) (r Repo, err error) { switch proxy { case "off": - return nil, errProxyOff + return errRepo{path, errProxyOff}, nil case "direct": return lookupDirect(path) case "noproxy": @@ -261,13 +270,13 @@ func lookupDirect(path string) (Repo, error) { if allowInsecure(path) { security = web.Insecure } - rr, err := get.RepoRootForImportPath(path, get.PreferMod, security) + rr, err := vcs.RepoRootForImportPath(path, vcs.PreferMod, security) if err != nil { // We don't know where to find code for a module with this path. return nil, notExistError{err: err} } - if rr.VCS == "mod" { + if rr.VCS.Name == "mod" { // Fetch module from proxy with base URL rr.Repo. return newProxyRepo(rr.Repo, path) } @@ -279,8 +288,8 @@ func lookupDirect(path string) (Repo, error) { return newCodeRepo(code, rr.Root, path) } -func lookupCodeRepo(rr *get.RepoRoot) (codehost.Repo, error) { - code, err := codehost.NewRepo(rr.VCS, rr.Repo) +func lookupCodeRepo(rr *vcs.RepoRoot) (codehost.Repo, error) { + code, err := codehost.NewRepo(rr.VCS.Cmd, rr.Repo) if err != nil { if _, ok := err.(*codehost.VCSError); ok { return nil, err @@ -306,7 +315,7 @@ func ImportRepoRev(path, rev string) (Repo, *RevInfo, error) { if allowInsecure(path) { security = web.Insecure } - rr, err := get.RepoRootForImportPath(path, get.IgnoreMod, security) + rr, err := vcs.RepoRootForImportPath(path, vcs.IgnoreMod, security) if err != nil { return nil, nil, err } @@ -407,7 +416,24 @@ func (l *loggingRepo) Zip(dst io.Writer, version string) error { return l.r.Zip(dst, version) } -// A notExistError is like os.ErrNotExist, but with a custom message +// errRepo is a Repo that returns the same error for all operations. +// +// It is useful in conjunction with caching, since cache hits will not attempt +// the prohibited operations. +type errRepo struct { + modulePath string + err error +} + +func (r errRepo) ModulePath() string { return r.modulePath } + +func (r errRepo) Versions(prefix string) (tags []string, err error) { return nil, r.err } +func (r errRepo) Stat(rev string) (*RevInfo, error) { return nil, r.err } +func (r errRepo) Latest() (*RevInfo, error) { return nil, r.err } +func (r errRepo) GoMod(version string) ([]byte, error) { return nil, r.err } +func (r errRepo) Zip(dst io.Writer, version string) error { return r.err } + +// A notExistError is like fs.ErrNotExist, but with a custom message type notExistError struct { err error } @@ -421,7 +447,7 @@ func (e notExistError) Error() string { } func (notExistError) Is(target error) bool { - return target == os.ErrNotExist + return target == fs.ErrNotExist } func (e notExistError) Unwrap() error { diff --git a/libgo/go/cmd/go/internal/modfetch/sumdb.go b/libgo/go/cmd/go/internal/modfetch/sumdb.go index 7973f474268..4fbc54d15ce 100644 --- a/libgo/go/cmd/go/internal/modfetch/sumdb.go +++ b/libgo/go/cmd/go/internal/modfetch/sumdb.go @@ -12,7 +12,8 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" + "io" + "io/fs" "net/url" "os" "path/filepath" @@ -22,9 +23,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/get" "cmd/go/internal/lockedfile" - "cmd/go/internal/str" "cmd/go/internal/web" "golang.org/x/mod/module" @@ -34,7 +33,7 @@ import ( // useSumDB reports whether to use the Go checksum database for the given module. func useSumDB(mod module.Version) bool { - return cfg.GOSUMDB != "off" && !get.Insecure && !str.GlobsMatchPath(cfg.GONOSUMDB, mod.Path) + return cfg.GOSUMDB != "off" && !cfg.Insecure && !module.MatchPrefixPatterns(cfg.GONOSUMDB, mod.Path) } // lookupSumDB returns the Go checksum database's go.sum lines for the given module, @@ -184,7 +183,7 @@ func (c *dbClient) initBase() { return nil } }) - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { // No proxies, or all proxies failed (with 404, 410, or were were allowed // to fall back), or we reached an explicit "direct" or "off". c.base = c.direct @@ -205,7 +204,7 @@ func (c *dbClient) ReadConfig(file string) (data []byte, err error) { } targ := filepath.Join(cfg.SumdbDir, file) data, err = lockedfile.Read(targ) - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { // Treat non-existent as empty, to bootstrap the "latest" file // the first time we connect to a given database. return []byte{}, nil @@ -229,7 +228,7 @@ func (*dbClient) WriteConfig(file string, old, new []byte) error { return err } defer f.Close() - data, err := ioutil.ReadAll(f) + data, err := io.ReadAll(f) if err != nil { return err } @@ -259,7 +258,7 @@ func (*dbClient) ReadCache(file string) ([]byte, error) { // during which the empty file can be locked for reading. // Treat observing an empty file as file not found. if err == nil && len(data) == 0 { - err = &os.PathError{Op: "read", Path: targ, Err: os.ErrNotExist} + err = &fs.PathError{Op: "read", Path: targ, Err: fs.ErrNotExist} } return data, err } 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 index eac9b32fa85..d9ba8ef2dae 100644 --- 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 @@ -16,6 +16,7 @@ package zip_sum_test import ( + "context" "crypto/sha256" "encoding/csv" "encoding/hex" @@ -23,7 +24,6 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -80,7 +80,7 @@ func TestZipSums(t *testing.T) { if *modCacheDir != "" { cfg.BuildContext.GOPATH = *modCacheDir } else { - tmpDir, err := ioutil.TempDir("", "TestZipSums") + tmpDir, err := os.MkdirTemp("", "TestZipSums") if err != nil { t.Fatal(err) } @@ -119,7 +119,7 @@ func TestZipSums(t *testing.T) { 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) + zipPath, err := modfetch.DownloadZip(context.Background(), test.m) if err != nil { if *updateTestData { t.Logf("%s: could not download module: %s (will remove from testdata)", test.m, err) diff --git a/libgo/go/cmd/go/internal/modget/get.go b/libgo/go/cmd/go/internal/modget/get.go index 4c6982426fb..8463ec4e9c7 100644 --- a/libgo/go/cmd/go/internal/modget/get.go +++ b/libgo/go/cmd/go/internal/modget/get.go @@ -5,25 +5,47 @@ // Package modget implements the module-aware ``go get'' command. package modget +// The arguments to 'go get' are patterns with optional version queries, with +// the version queries defaulting to "upgrade". +// +// The patterns are normally interpreted as package patterns. However, if a +// pattern cannot match a package, it is instead interpreted as a *module* +// pattern. For version queries such as "upgrade" and "patch" that depend on the +// selected version of a module (or of the module containing a package), +// whether a pattern denotes a package or module may change as updates are +// applied (see the example in mod_get_patchmod.txt). +// +// There are a few other ambiguous cases to resolve, too. A package can exist in +// two different modules at the same version: for example, the package +// example.com/foo might be found in module example.com and also in module +// example.com/foo, and those modules may have independent v0.1.0 tags — so the +// input 'example.com/foo@v0.1.0' could syntactically refer to the variant of +// the package loaded from either module! (See mod_get_ambiguous_pkg.txt.) +// If the argument is ambiguous, the user can often disambiguate by specifying +// explicit versions for *all* of the potential module paths involved. + import ( + "context" "errors" "fmt" "os" "path/filepath" + "reflect" + "runtime" "sort" "strings" "sync" "cmd/go/internal/base" - "cmd/go/internal/get" + "cmd/go/internal/cfg" "cmd/go/internal/imports" "cmd/go/internal/load" "cmd/go/internal/modload" - "cmd/go/internal/mvs" "cmd/go/internal/par" "cmd/go/internal/search" "cmd/go/internal/work" + "golang.org/x/mod/modfile" "golang.org/x/mod/module" "golang.org/x/mod/semver" ) @@ -69,15 +91,15 @@ downgrades the dependency. The version suffix @none indicates that the dependency should be removed entirely, downgrading or removing modules depending on it as needed. -The version suffix @latest explicitly requests the latest minor release of the -module named by the given path. The suffix @upgrade is like @latest but +The version suffix @latest explicitly requests the latest minor release of +the module named by the given path. The suffix @upgrade is like @latest but will not downgrade a module if it is already required at a revision or pre-release version newer than the latest released version. The suffix @patch requests the latest patch release: the latest released version with the same major and minor version numbers as the currently required version. Like @upgrade, @patch will not downgrade a module already required -at a newer version. If the path is not already required, @upgrade and @patch -are equivalent to @latest. +at a newer version. If the path is not already required, @upgrade is +equivalent to @latest, and @patch is disallowed. Although get defaults to using the latest version of the module containing a named package, it does not use the latest version of that module's @@ -114,14 +136,27 @@ require downgrading other dependencies, and 'go get' does this automatically as well. The -insecure flag permits fetching from repositories and resolving -custom domains using insecure schemes such as HTTP. Use with caution. The -GOINSECURE environment variable is usually a better alternative, since it -provides control over which modules may be retrieved using an insecure scheme. -See 'go help environment' for details. +custom domains using insecure schemes such as HTTP, and also bypassess +module sum validation using the checksum database. Use with caution. +This flag is deprecated and will be removed in a future version of go. +To permit the use of insecure schemes, use the GOINSECURE environment +variable instead. To bypass module sum validation, use GOPRIVATE or +GONOSUMDB. See 'go help environment' for details. The second step is to download (if needed), build, and install the named packages. +The -d flag instructs get to skip this step, downloading source code +needed to build the named packages and their dependencies, but not +building or installing. + +Building and installing packages with get is deprecated. In a future release, +the -d flag will be enabled by default, and 'go get' will be only be used to +adjust dependencies of the current module. To install a package using +dependencies from the current module, use 'go install'. To install a package +ignoring the current module, use 'go install' with an @version suffix like +"@latest" after each argument. + If an argument names a module but not a package (because there is no Go source code in the module's root directory), then the install step is skipped for that argument, instead of causing a build failure. @@ -133,10 +168,6 @@ the module versions. For example, 'go get golang.org/x/perf/cmd/...' adds the latest golang.org/x/perf and then installs the commands in that latest version. -The -d flag instructs get to download the source code needed to build -the named packages, including downloading necessary dependencies, -but not to build and install them. - With no package arguments, 'go get' applies to Go package in the current directory, if any. In particular, 'go get -u' and 'go get -u=patch' update all the dependencies of that package. @@ -173,6 +204,82 @@ Usage: ` + CmdGet.UsageLine + ` ` + CmdGet.Long, } +var HelpVCS = &base.Command{ + UsageLine: "vcs", + Short: "controlling version control with GOVCS", + Long: ` +The 'go get' command can run version control commands like git +to download imported code. This functionality is critical to the decentralized +Go package ecosystem, in which code can be imported from any server, +but it is also a potential security problem, if a malicious server finds a +way to cause the invoked version control command to run unintended code. + +To balance the functionality and security concerns, the 'go get' command +by default will only use git and hg to download code from public servers. +But it will use any known version control system (bzr, fossil, git, hg, svn) +to download code from private servers, defined as those hosting packages +matching the GOPRIVATE variable (see 'go help private'). The rationale behind +allowing only Git and Mercurial is that these two systems have had the most +attention to issues of being run as clients of untrusted servers. In contrast, +Bazaar, Fossil, and Subversion have primarily been used in trusted, +authenticated environments and are not as well scrutinized as attack surfaces. + +The version control command restrictions only apply when using direct version +control access to download code. When downloading modules from a proxy, +'go get' uses the proxy protocol instead, which is always permitted. +By default, the 'go get' command uses the Go module mirror (proxy.golang.org) +for public packages and only falls back to version control for private +packages or when the mirror refuses to serve a public package (typically for +legal reasons). Therefore, clients can still access public code served from +Bazaar, Fossil, or Subversion repositories by default, because those downloads +use the Go module mirror, which takes on the security risk of running the +version control commands, using a custom sandbox. + +The GOVCS variable can be used to change the allowed version control systems +for specific packages (identified by a module or import path). +The GOVCS variable applies both when using modules and when using GOPATH. +When using modules, the patterns match against the module path. +When using GOPATH, the patterns match against the import path +corresponding to the root of the version control repository. + +The general form of the GOVCS setting is a comma-separated list of +pattern:vcslist rules. The pattern is a glob pattern that must match +one or more leading elements of the module or import path. The vcslist +is a pipe-separated list of allowed version control commands, or "all" +to allow use of any known command, or "off" to allow nothing. +The earliest matching pattern in the list applies, even if later patterns +might also match. + +For example, consider: + + GOVCS=github.com:git,evil.com:off,*:git|hg + +With this setting, code with an module or import path beginning with +github.com/ can only use git; paths on evil.com cannot use any version +control command, and all other paths (* matches everything) can use +only git or hg. + +The special patterns "public" and "private" match public and private +module or import paths. A path is private if it matches the GOPRIVATE +variable; otherwise it is public. + +If no rules in the GOVCS variable match a particular module or import path, +the 'go get' command applies its default rule, which can now be summarized +in GOVCS notation as 'public:git|hg,private:all'. + +To allow unfettered use of any version control system for any package, use: + + GOVCS=*:all + +To disable all use of version control, use: + + GOVCS=*:off + +The 'go env -w' command (see 'go help env') can be used to set the GOVCS +variable for future go command invocations. +`, +} + var ( getD = CmdGet.Flag.Bool("d", false, "") getF = CmdGet.Flag.Bool("f", false, "") @@ -180,23 +287,29 @@ var ( getM = CmdGet.Flag.Bool("m", false, "") getT = CmdGet.Flag.Bool("t", false, "") getU upgradeFlag - // -insecure is get.Insecure + // -insecure is cfg.Insecure // -v is cfg.BuildV ) // upgradeFlag is a custom flag.Value for -u. -type upgradeFlag string +type upgradeFlag struct { + rawVersion string + version string +} func (*upgradeFlag) IsBoolFlag() bool { return true } // allow -u func (v *upgradeFlag) Set(s string) error { if s == "false" { - s = "" + v.version = "" + v.rawVersion = "" + } else if s == "true" { + v.version = "upgrade" + v.rawVersion = "" + } else { + v.version = s + v.rawVersion = s } - if s == "true" { - s = "upgrade" - } - *v = upgradeFlag(s) return nil } @@ -205,66 +318,16 @@ func (v *upgradeFlag) String() string { return "" } func init() { work.AddBuildFlags(CmdGet, work.OmitModFlag) CmdGet.Run = runGet // break init loop - CmdGet.Flag.BoolVar(&get.Insecure, "insecure", get.Insecure, "") + CmdGet.Flag.BoolVar(&cfg.Insecure, "insecure", cfg.Insecure, "") CmdGet.Flag.Var(&getU, "u", "") } -// A getArg holds a parsed positional argument for go get (path@vers). -type getArg struct { - // raw is the original argument, to be printed in error messages. - raw string - - // path is the part of the argument before "@" (or the whole argument - // if there is no "@"). path specifies the modules or packages to get. - path string - - // vers is the part of the argument after "@" or an implied - // "upgrade" or "patch" if there is no "@". vers specifies the - // module version to get. - vers string -} - -// querySpec describes a query for a specific module. path may be a -// module path, package path, or package pattern. vers is a version -// query string from a command line argument. -type querySpec struct { - // path is a module path, package path, or package pattern that - // specifies which module to query. - path string - - // vers specifies what version of the module to get. - vers string - - // forceModulePath is true if path should be interpreted as a module path. - // If forceModulePath is true, prevM must be set. - forceModulePath bool - - // prevM is the previous version of the module. prevM is needed - // to determine the minor version number if vers is "patch". It's also - // used to avoid downgrades from prerelease versions newer than - // "latest" and "patch". If prevM is set, forceModulePath must be true. - prevM module.Version -} - -// query holds the state for a query made for a specific module. -// After a query is performed, we know the actual module path and -// version and whether any packages were matched by the query path. -type query struct { - querySpec - - // arg is the command line argument that matched the specified module. - arg string - - // m is the module path and version found by the query. - m module.Version -} - -func runGet(cmd *base.Command, args []string) { - switch getU { +func runGet(ctx context.Context, cmd *base.Command, args []string) { + switch getU.version { case "", "upgrade", "patch": // ok default: - base.Fatalf("go get: unknown upgrade flag -u=%s", getU) + base.Fatalf("go get: unknown upgrade flag -u=%s", getU.rawVersion) } if *getF { fmt.Fprintf(os.Stderr, "go get: -f flag is a no-op when using modules\n") @@ -275,770 +338,1394 @@ func runGet(cmd *base.Command, args []string) { if *getM { base.Fatalf("go get: -m flag is no longer supported; consider -d to skip building packages") } - modload.LoadTests = *getT - - buildList := modload.LoadBuildList() - buildList = buildList[:len(buildList):len(buildList)] // copy on append - versionByPath := make(map[string]string) - for _, m := range buildList { - versionByPath[m.Path] = m.Version + if cfg.Insecure { + fmt.Fprintf(os.Stderr, "go get: -insecure flag is deprecated; see 'go help get' for details\n") } + load.ModResolveTests = *getT // Do not allow any updating of go.mod until we've applied // all the requested changes and checked that the result matches // what was requested. modload.DisallowWriteGoMod() - // Allow looking up modules for import paths outside of a module. + // Allow looking up modules for import paths when 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". - var gets []getArg - var queries []*query - for _, arg := range search.CleanPatterns(args) { - // Argument is path or path@vers. - path := arg - vers := "" - if i := strings.Index(arg, "@"); i >= 0 { - path, vers = arg[:i], arg[i+1:] + modload.LoadModFile(ctx) // Initializes modload.Target. + + queries := parseArgs(ctx, args) + + r := newResolver(ctx, queries) + r.performLocalQueries(ctx) + r.performPathQueries(ctx) + + for { + r.performWildcardQueries(ctx) + r.performPatternAllQueries(ctx) + + if changed := r.resolveCandidates(ctx, queries, nil); changed { + // 'go get' arguments can be (and often are) package patterns rather than + // (just) modules. A package can be provided by any module with a prefix + // of its import path, and a wildcard can even match packages in modules + // with totally different paths. Because of these effects, and because any + // change to the selected version of a module can bring in entirely new + // module paths as dependencies, we need to reissue queries whenever we + // change the build list. + // + // The result of any version query for a given module — even "upgrade" or + // "patch" — is always relative to the build list at the start of + // the 'go get' command, not an intermediate state, and is therefore + // dederministic and therefore cachable, and the constraints on the + // selected version of each module can only narrow as we iterate. + // + // "all" is functionally very similar to a wildcard pattern. The set of + // packages imported by the main module does not change, and the query + // result for the module containing each such package also does not change + // (it is always relative to the initial build list, before applying + // queries). So the only way that the result of an "all" query can change + // is if some matching package moves from one module in the build list + // to another, which should not happen very often. + continue } - if strings.Contains(vers, "@") || arg != path && vers == "" { - base.Errorf("go get %s: invalid module version syntax", arg) + + // When we load imports, we detect the following conditions: + // + // - missing transitive depencies that need to be resolved from outside the + // current build list (note that these may add new matches for existing + // pattern queries!) + // + // - transitive dependencies that didn't match any other query, + // but need to be upgraded due to the -u flag + // + // - ambiguous import errors. + // TODO(#27899): Try to resolve ambiguous import errors automatically. + upgrades := r.findAndUpgradeImports(ctx, queries) + if changed := r.resolveCandidates(ctx, nil, upgrades); changed { + continue + } + + r.findMissingWildcards(ctx) + if changed := r.resolveCandidates(ctx, r.wildcardQueries, nil); changed { continue } + break + } + + r.checkWildcardVersions(ctx) + + var pkgPatterns []string + for _, q := range queries { + if q.matchesPackages { + pkgPatterns = append(pkgPatterns, q.pattern) + } + } + r.checkPackagesAndRetractions(ctx, pkgPatterns) + + // We've already downloaded modules (and identified direct and indirect + // dependencies) by loading packages in findAndUpgradeImports. + // So if -d is set, we're done after the module work. + // + // Otherwise, we need to build and install the packages matched by + // command line arguments. + // Note that 'go get -u' without arguments is equivalent to + // 'go get -u .', so we'll typically build the package in the current + // directory. + if !*getD && len(pkgPatterns) > 0 { + work.BuildInit() + pkgs := load.PackagesAndErrors(ctx, pkgPatterns) + load.CheckPackageErrors(pkgs) + work.InstallPackages(ctx, pkgPatterns, pkgs) + // TODO(#40276): After Go 1.16, print a deprecation notice when building + // and installing main packages. 'go install pkg' or + // 'go install pkg@version' should be used instead. + // Give the specific argument to use if possible. + } + + if !modload.HasModRoot() { + return + } + + // Everything succeeded. Update go.mod. + oldReqs := reqsFromGoMod(modload.ModFile()) + + modload.AllowWriteGoMod() + modload.WriteGoMod() + modload.DisallowWriteGoMod() + + newReqs := reqsFromGoMod(modload.ModFile()) + r.reportChanges(oldReqs, newReqs) +} + +// parseArgs parses command-line arguments and reports errors. +// +// The command-line arguments are of the form path@version or simply path, with +// implicit @upgrade. path@none is "downgrade away". +func parseArgs(ctx context.Context, rawArgs []string) []*query { + defer base.ExitIfErrors() + + var queries []*query + for _, arg := range search.CleanPatterns(rawArgs) { + q, err := newQuery(arg) + if err != nil { + base.Errorf("go get: %v", err) + continue + } + + // If there were no arguments, CleanPatterns returns ".". Set the raw + // string back to "" for better errors. + if len(rawArgs) == 0 { + q.raw = "" + } + // Guard against 'go get x.go', a common mistake. // Note that package and module paths may end with '.go', so only print an error // if the argument has no version and either has no slash or refers to an existing file. - if strings.HasSuffix(arg, ".go") && vers == "" { - if !strings.Contains(arg, "/") { - base.Errorf("go get %s: arguments must be package or module paths", arg) + if strings.HasSuffix(q.raw, ".go") && q.rawVersion == "" { + if !strings.Contains(q.raw, "/") { + base.Errorf("go get %s: arguments must be package or module paths", q.raw) continue } - if fi, err := os.Stat(arg); err == nil && !fi.IsDir() { - base.Errorf("go get: %s exists as a file, but 'go get' requires package arguments", arg) + if fi, err := os.Stat(q.raw); err == nil && !fi.IsDir() { + base.Errorf("go get: %s exists as a file, but 'go get' requires package arguments", q.raw) continue } } - // If no version suffix is specified, assume @upgrade. - // If -u=patch was specified, assume @patch instead. - if vers == "" { - if getU != "" { - vers = string(getU) + queries = append(queries, q) + } + + return queries +} + +type resolver struct { + localQueries []*query // queries for absolute or relative paths + pathQueries []*query // package path literal queries in original order + wildcardQueries []*query // path wildcard queries in original order + patternAllQueries []*query // queries with the pattern "all" + + // Indexed "none" queries. These are also included in the slices above; + // they are indexed here to speed up noneForPath. + nonesByPath map[string]*query // path-literal "@none" queries indexed by path + wildcardNones []*query // wildcard "@none" queries + + // resolvedVersion maps each module path to the version of that module that + // must be selected in the final build list, along with the first query + // that resolved the module to that version (the “reason”). + resolvedVersion map[string]versionReason + + buildList []module.Version + buildListResolvedVersions int // len(resolvedVersion) when buildList was computed + buildListVersion map[string]string // index of buildList (module path → version) + + initialVersion map[string]string // index of the initial build list at the start of 'go get' + + missing []pathSet // candidates for missing transitive dependencies + + work *par.Queue + + matchInModuleCache par.Cache +} + +type versionReason struct { + version string + reason *query +} + +func newResolver(ctx context.Context, queries []*query) *resolver { + buildList := modload.LoadAllModules(ctx) + initialVersion := make(map[string]string, len(buildList)) + for _, m := range buildList { + initialVersion[m.Path] = m.Version + } + + r := &resolver{ + work: par.NewQueue(runtime.GOMAXPROCS(0)), + resolvedVersion: map[string]versionReason{}, + buildList: buildList, + buildListVersion: initialVersion, + initialVersion: initialVersion, + nonesByPath: map[string]*query{}, + } + + for _, q := range queries { + if q.pattern == "all" { + r.patternAllQueries = append(r.patternAllQueries, q) + } else if q.patternIsLocal { + r.localQueries = append(r.localQueries, q) + } else if q.isWildcard() { + r.wildcardQueries = append(r.wildcardQueries, q) + } else { + r.pathQueries = append(r.pathQueries, q) + } + + if q.version == "none" { + // Index "none" queries to make noneForPath more efficient. + if q.isWildcard() { + r.wildcardNones = append(r.wildcardNones, q) } else { - vers = "upgrade" + // All "@none" queries for the same path are identical; we only + // need to index one copy. + r.nonesByPath[q.pattern] = q } } + } - gets = append(gets, getArg{raw: arg, path: path, vers: vers}) - - // Determine the modules that path refers to, and create queries - // to lookup modules at target versions before loading packages. - // This is an imprecise process, but it helps reduce unnecessary - // queries and package loading. It's also necessary for handling - // patterns like golang.org/x/tools/..., which can't be expanded - // during package loading until they're in the build list. - switch { - case filepath.IsAbs(path) || search.IsRelativePath(path): - // Absolute paths like C:\foo and relative paths like ../foo... - // are restricted to matching packages in the main module. If the path - // is explicit and contains no wildcards (...), check that it is a - // package in the main module. If the path contains wildcards but - // matches no packages, we'll warn after package loading. - if !strings.Contains(path, "...") { - m := search.NewMatch(path) - if pkgPath := modload.DirImportPath(path); pkgPath != "." { - m = modload.TargetPackages(pkgPath) - } - if len(m.Pkgs) == 0 { - for _, err := range m.Errs { - base.Errorf("go get %s: %v", arg, err) - } + return r +} - abs, err := filepath.Abs(path) - if err != nil { - abs = path - } - base.Errorf("go get %s: path %s is not a package in module rooted at %s", arg, abs, modload.ModRoot()) - continue - } - } +// initialSelected returns the version of the module with the given path that +// was selected at the start of this 'go get' invocation. +func (r *resolver) initialSelected(mPath string) (version string) { + v, ok := r.initialVersion[mPath] + if !ok { + return "none" + } + return v +} - if path != arg { - base.Errorf("go get %s: can't request explicit version of path in main module", arg) - continue - } +// selected returns the version of the module with the given path that is +// selected in the resolver's current build list. +func (r *resolver) selected(mPath string) (version string) { + v, ok := r.buildListVersion[mPath] + if !ok { + return "none" + } + return v +} + +// noneForPath returns a "none" query matching the given module path, +// or found == false if no such query exists. +func (r *resolver) noneForPath(mPath string) (nq *query, found bool) { + if nq = r.nonesByPath[mPath]; nq != nil { + return nq, true + } + for _, nq := range r.wildcardNones { + if nq.matchesPath(mPath) { + return nq, true + } + } + return nil, false +} + +// queryModule wraps modload.Query, substituting r.checkAllowedOr to decide +// allowed versions. +func (r *resolver) queryModule(ctx context.Context, mPath, query string, selected func(string) string) (module.Version, error) { + current := r.initialSelected(mPath) + rev, err := modload.Query(ctx, mPath, query, current, r.checkAllowedOr(query, selected)) + if err != nil { + return module.Version{}, err + } + return module.Version{Path: mPath, Version: rev.Version}, nil +} - case strings.Contains(path, "..."): - // Wait until we load packages to look up modules. - // We don't know yet whether any modules in the build list provide - // packages matching the pattern. For example, suppose - // golang.org/x/tools and golang.org/x/tools/playground are separate - // modules, and only golang.org/x/tools is in the build list. If the - // user runs 'go get golang.org/x/tools/playground/...', we should - // add a requirement for golang.org/x/tools/playground. We should not - // 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) +// queryPackage wraps modload.QueryPackage, substituting r.checkAllowedOr to +// decide allowed versions. +func (r *resolver) queryPackages(ctx context.Context, pattern, query string, selected func(string) string) (pkgMods []module.Version, err error) { + results, err := modload.QueryPackages(ctx, pattern, query, selected, r.checkAllowedOr(query, selected)) + if len(results) > 0 { + pkgMods = make([]module.Version, 0, len(results)) + for _, qr := range results { + pkgMods = append(pkgMods, qr.Mod) + } + } + return pkgMods, err +} + +// queryPattern wraps modload.QueryPattern, substituting r.checkAllowedOr to +// decide allowed versions. +func (r *resolver) queryPattern(ctx context.Context, pattern, query string, selected func(string) string) (pkgMods []module.Version, mod module.Version, err error) { + results, modOnly, err := modload.QueryPattern(ctx, pattern, query, selected, r.checkAllowedOr(query, selected)) + if len(results) > 0 { + pkgMods = make([]module.Version, 0, len(results)) + for _, qr := range results { + pkgMods = append(pkgMods, qr.Mod) + } + } + if modOnly != nil { + mod = modOnly.Mod + } + return pkgMods, mod, err +} + +// checkAllowedOr is like modload.CheckAllowed, but it always allows the requested +// and current versions (even if they are retracted or otherwise excluded). +func (r *resolver) checkAllowedOr(requested string, selected func(string) string) modload.AllowedFunc { + return func(ctx context.Context, m module.Version) error { + if m.Version == requested { + return modload.CheckExclusions(ctx, m) + } + if (requested == "upgrade" || requested == "patch") && m.Version == selected(m.Path) { + return nil + } + return modload.CheckAllowed(ctx, m) + } +} + +// matchInModule is a caching wrapper around modload.MatchInModule. +func (r *resolver) matchInModule(ctx context.Context, pattern string, m module.Version) (packages []string, err error) { + type key struct { + pattern string + m module.Version + } + type entry struct { + packages []string + err error + } + + e := r.matchInModuleCache.Do(key{pattern, m}, func() interface{} { + match := modload.MatchInModule(ctx, pattern, m, imports.AnyTags()) + if len(match.Errs) > 0 { + return entry{match.Pkgs, match.Errs[0]} + } + return entry{match.Pkgs, nil} + }).(entry) + + return e.packages, e.err +} + +// queryNone adds a candidate set to q for each module matching q.pattern. +// Each candidate set has only one possible module version: the matched +// module at version "none". +// +// We interpret arguments to 'go get' as packages first, and fall back to +// modules second. However, no module exists at version "none", and therefore no +// package exists at that version either: we know that the argument cannot match +// any packages, and thus it must match modules instead. +func (r *resolver) queryNone(ctx context.Context, q *query) { + if search.IsMetaPackage(q.pattern) { + panic(fmt.Sprintf("internal error: queryNone called with pattern %q", q.pattern)) + } + + if !q.isWildcard() { + q.pathOnce(q.pattern, func() pathSet { + if modload.HasModRoot() && q.pattern == modload.Target.Path { + // The user has explicitly requested to downgrade their own module to + // version "none". This is not an entirely unreasonable request: it + // could plausibly mean “downgrade away everything that depends on any + // explicit version of the main module”, or “downgrade away the + // package with the same path as the main module, found in a module + // with a prefix of the main module's path”. + // + // However, neither of those behaviors would be consistent with the + // plain meaning of the query. To try to reduce confusion, reject the + // query explicitly. + return errSet(&modload.QueryMatchesMainModuleError{Pattern: q.pattern, Query: q.version}) } - // Don't query modules until we load packages. We'll automatically - // look up any missing modules. - case search.IsMetaPackage(path): - base.Errorf("go get %s: explicit requirement on standard-library module %s not allowed", path, path) + return pathSet{mod: module.Version{Path: q.pattern, Version: "none"}} + }) + } + + for _, curM := range r.buildList { + if !q.matchesPath(curM.Path) { continue + } + q.pathOnce(curM.Path, func() pathSet { + if modload.HasModRoot() && curM == modload.Target { + return errSet(&modload.QueryMatchesMainModuleError{Pattern: q.pattern, Query: q.version}) + } + return pathSet{mod: module.Version{Path: curM.Path, Version: "none"}} + }) + } +} - default: - // The argument is a package or module path. - if modload.HasModRoot() { - if m := modload.TargetPackages(path); len(m.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 +func (r *resolver) performLocalQueries(ctx context.Context) { + for _, q := range r.localQueries { + q.pathOnce(q.pattern, func() pathSet { + absDetail := "" + if !filepath.IsAbs(q.pattern) { + if absPath, err := filepath.Abs(q.pattern); err == nil { + absDetail = fmt.Sprintf(" (%s)", absPath) } } - first := path - if i := strings.IndexByte(first, '/'); i >= 0 { - first = path + // Absolute paths like C:\foo and relative paths like ../foo... are + // restricted to matching packages in the main module. + pkgPattern := modload.DirImportPath(q.pattern) + if pkgPattern == "." { + return errSet(fmt.Errorf("%s%s is not within module rooted at %s", q.pattern, absDetail, modload.ModRoot())) } - if !strings.Contains(first, ".") { - // The path doesn't have a dot in the first component and cannot be - // queried as a module. It may be a package in the standard library, - // which is fine, so don't report an error unless we encounter - // a problem loading packages below. - continue + + match := modload.MatchInModule(ctx, pkgPattern, modload.Target, imports.AnyTags()) + if len(match.Errs) > 0 { + return pathSet{err: match.Errs[0]} + } + + if len(match.Pkgs) == 0 { + if q.raw == "" || q.raw == "." { + return errSet(fmt.Errorf("no package in current directory")) + } + if !q.isWildcard() { + return errSet(fmt.Errorf("%s%s is not a package in module rooted at %s", q.pattern, absDetail, modload.ModRoot())) + } + search.WarnUnmatched([]*search.Match{match}) + return pathSet{} } - // If we're querying "upgrade" or "patch", we need to know the current - // version of the module. For "upgrade", we want to avoid accidentally - // downgrading from a newer prerelease. For "patch", we need to query - // the correct minor version. - // Here, we check if "path" is the name of a module in the build list - // (other than the main module) and set prevM if so. If "path" isn't - // a module in the build list, the current version doesn't matter - // since it's either an unknown module or a package within a module - // that we'll discover later. - q := &query{querySpec: querySpec{path: path, vers: vers}, arg: arg} - if v, ok := versionByPath[path]; ok && path != modload.Target.Path { - q.prevM = module.Version{Path: path, Version: v} - q.forceModulePath = true + return pathSet{pkgMods: []module.Version{modload.Target}} + }) + } +} + +// performWildcardQueries populates the candidates for each query whose pattern +// is a wildcard. +// +// The candidates for a given module path matching (or containing a package +// matching) a wildcard query depend only on the initial build list, but the set +// of modules may be expanded by other queries, so wildcard queries need to be +// re-evaluated whenever a potentially-matching module path is added to the +// build list. +func (r *resolver) performWildcardQueries(ctx context.Context) { + for _, q := range r.wildcardQueries { + q := q + r.work.Add(func() { + if q.version == "none" { + r.queryNone(ctx, q) + } else { + r.queryWildcard(ctx, q) } - queries = append(queries, q) + }) + } + <-r.work.Idle() +} + +// queryWildcard adds a candidate set to q for each module for which: +// - some version of the module is already in the build list, and +// - that module exists at some version matching q.version, and +// - either the module path itself matches q.pattern, or some package within +// the module at q.version matches q.pattern. +func (r *resolver) queryWildcard(ctx context.Context, q *query) { + // For wildcard patterns, modload.QueryPattern only identifies modules + // matching the prefix of the path before the wildcard. However, the build + // list may already contain other modules with matching packages, and we + // should consider those modules to satisfy the query too. + // We want to match any packages in existing dependencies, but we only want to + // resolve new dependencies if nothing else turns up. + for _, curM := range r.buildList { + if !q.canMatchInModule(curM.Path) { + continue } + q.pathOnce(curM.Path, func() pathSet { + if _, hit := r.noneForPath(curM.Path); hit { + // This module is being removed, so it will no longer be in the build list + // (and thus will no longer match the pattern). + return pathSet{} + } + + if curM.Path == modload.Target.Path && !versionOkForMainModule(q.version) { + if q.matchesPath(curM.Path) { + return errSet(&modload.QueryMatchesMainModuleError{ + Pattern: q.pattern, + Query: q.version, + }) + } + + packages, err := r.matchInModule(ctx, q.pattern, curM) + if err != nil { + return errSet(err) + } + if len(packages) > 0 { + return errSet(&modload.QueryMatchesPackagesInMainModuleError{ + Pattern: q.pattern, + Query: q.version, + Packages: packages, + }) + } + + return r.tryWildcard(ctx, q, curM) + } + + m, err := r.queryModule(ctx, curM.Path, q.version, r.initialSelected) + if err != nil { + if !isNoSuchModuleVersion(err) { + // We can't tell whether a matching version exists. + return errSet(err) + } + // There is no version of curM.Path matching the query. + + // We haven't checked whether curM contains any matching packages at its + // currently-selected version, or whether curM.Path itself matches q. If + // either of those conditions holds, *and* no other query changes the + // selected version of curM, then we will fail in checkWildcardVersions. + // (This could be an error, but it's too soon to tell.) + // + // However, even then the transitive requirements of some other query + // may downgrade this module out of the build list entirely, in which + // case the pattern will no longer include it and it won't be an error. + // + // Either way, punt on the query rather than erroring out just yet. + return pathSet{} + } + + return r.tryWildcard(ctx, q, m) + }) } - base.ExitIfErrors() - // Query modules referenced by command line arguments at requested versions. - // We need to do this before loading packages since patterns that refer to - // packages in unknown modules can't be expanded. This also avoids looking - // up new modules while loading packages, only to downgrade later. - queryCache := make(map[querySpec]*query) - byPath := runQueries(queryCache, queries, nil) + // Even if no modules matched, we shouldn't query for a new module to provide + // the pattern yet: some other query may yet induce a new requirement that + // will match the wildcard. Instead, we'll check in findMissingWildcards. +} - // Add missing modules to the build list. - // We call SetBuildList here and elsewhere, since newUpgrader, - // ImportPathsQuiet, and other functions read the global build list. - for _, q := range queries { - if _, ok := versionByPath[q.m.Path]; !ok && q.m.Version != "none" { - buildList = append(buildList, q.m) - } +// tryWildcard returns a pathSet for module m matching query q. +// If m does not actually match q, tryWildcard returns an empty pathSet. +func (r *resolver) tryWildcard(ctx context.Context, q *query, m module.Version) pathSet { + mMatches := q.matchesPath(m.Path) + packages, err := r.matchInModule(ctx, q.pattern, m) + if err != nil { + return errSet(err) } - versionByPath = nil // out of date now; rebuilt later when needed - modload.SetBuildList(buildList) - - // Upgrade modules specifically named on the command line. This is our only - // chance to upgrade modules without root packages (modOnly below). - // This also skips loading packages at an old version, only to upgrade - // and reload at a new version. - upgrade := make(map[string]*query) - for path, q := range byPath { - if q.path == q.m.Path && q.m.Version != "none" { - upgrade[path] = q - } + if len(packages) > 0 { + return pathSet{pkgMods: []module.Version{m}} } - buildList, err := mvs.UpgradeAll(modload.Target, newUpgrader(upgrade, nil)) - if err != nil { - base.Fatalf("go get: %v", err) + if mMatches { + return pathSet{mod: m} } - modload.SetBuildList(buildList) - base.ExitIfErrors() - prevBuildList := buildList - - // Build a set of module paths that we don't plan to load packages from. - // 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 + return pathSet{} +} + +// findMissingWildcards adds a candidate set for each query in r.wildcardQueries +// that has not yet resolved to any version containing packages. +func (r *resolver) findMissingWildcards(ctx context.Context) { + for _, q := range r.wildcardQueries { + if q.version == "none" || q.matchesPackages { + continue // q is not “missing” } - if q.path == q.m.Path { - wg.Add(1) - go func(q *query) { - 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() + r.work.Add(func() { + q.pathOnce(q.pattern, func() pathSet { + pkgMods, mod, err := r.queryPattern(ctx, q.pattern, q.version, r.initialSelected) + if err != nil { + if isNoSuchPackageVersion(err) && len(q.resolved) > 0 { + // q already resolved one or more modules but matches no packages. + // That's ok: this pattern is just a module pattern, and we don't + // need to add any more modules to satisfy it. + return pathSet{} + } + return errSet(err) } - wg.Done() - }(q) - } - } - wg.Wait() - base.ExitIfErrors() - // Build a list of arguments that may refer to packages. - var pkgPatterns []string - var pkgGets []getArg - for _, arg := range gets { - if modOnly[arg.path] == nil && arg.vers != "none" { - pkgPatterns = append(pkgPatterns, arg.path) - pkgGets = append(pkgGets, arg) - } + return pathSet{pkgMods: pkgMods, mod: mod} + }) + }) } + <-r.work.Idle() +} - // Load packages and upgrade the modules that provide them. We do this until - // we reach a fixed point, since modules providing packages may change as we - // change versions. This must terminate because the module graph is finite, - // and the load and upgrade operations may only add and upgrade modules - // in the build list. - var matches []*search.Match - for { - var seenPkgs map[string]bool - seenQuery := make(map[querySpec]bool) - var queries []*query - addQuery := func(q *query) { - if !seenQuery[q.querySpec] { - seenQuery[q.querySpec] = true - queries = append(queries, q) - } - } +// checkWildcardVersions reports an error if any module in the build list has a +// path (or contains a package) matching a query with a wildcard pattern, but +// has a selected version that does *not* match the query. +func (r *resolver) checkWildcardVersions(ctx context.Context) { + defer base.ExitIfErrors() - if len(pkgPatterns) > 0 { - // Don't load packages if pkgPatterns is empty. Both - // modload.ImportPathsQuiet and ModulePackages convert an empty list - // of patterns to []string{"."}, which is not what we want. - matches = modload.ImportPathsQuiet(pkgPatterns, imports.AnyTags()) - seenPkgs = make(map[string]bool) - for i, match := range matches { - arg := pkgGets[i] - - if len(match.Pkgs) == 0 { - // If the pattern did not match any packages, look up a new module. - // If the pattern doesn't match anything on the last iteration, - // we'll print a warning after the outer loop. - if !match.IsLocal() && !match.IsLiteral() && arg.path != "all" { - addQuery(&query{querySpec: querySpec{path: arg.path, vers: arg.vers}, arg: arg.raw}) - } else { - for _, err := range match.Errs { - base.Errorf("go get: %v", err) - } + for _, q := range r.wildcardQueries { + for _, curM := range r.buildList { + if !q.canMatchInModule(curM.Path) { + continue + } + if !q.matchesPath(curM.Path) { + packages, err := r.matchInModule(ctx, q.pattern, curM) + if len(packages) == 0 { + if err != nil { + reportError(q, err) } - continue + continue // curM is not relevant to q. } + } - allStd := true - for _, pkg := range match.Pkgs { - if !seenPkgs[pkg] { - seenPkgs[pkg] = true - if _, _, err := modload.Lookup("", false, pkg); err != nil { - allStd = false - base.Errorf("go get %s: %v", arg.raw, err) - continue - } - } - m := modload.PackageModule(pkg) - if m.Path == "" { - // pkg is in the standard library. - continue - } - allStd = false - if m.Path == modload.Target.Path { - // pkg is in the main module. - continue - } - addQuery(&query{querySpec: querySpec{path: m.Path, vers: arg.vers, forceModulePath: true, prevM: m}, arg: arg.raw}) + rev, err := r.queryModule(ctx, curM.Path, q.version, r.initialSelected) + if err != nil { + reportError(q, err) + continue + } + if rev.Version == curM.Version { + continue // curM already matches q. + } + + if !q.matchesPath(curM.Path) { + m := module.Version{Path: curM.Path, Version: rev.Version} + packages, err := r.matchInModule(ctx, q.pattern, m) + if err != nil { + reportError(q, err) + continue } - if allStd && arg.path != arg.raw { - base.Errorf("go get %s: cannot use pattern %q with explicit version", arg.raw, arg.raw) + if len(packages) == 0 { + // curM at its original version contains a path matching q.pattern, + // but at rev.Version it does not, so (somewhat paradoxically) if + // we changed the version of curM it would no longer match the query. + var version interface{} = m + if rev.Version != q.version { + version = fmt.Sprintf("%s@%s (%s)", m.Path, q.version, m.Version) + } + reportError(q, fmt.Errorf("%v matches packages in %v but not %v: specify a different version for module %s", q, curM, version, m.Path)) + continue } } + + // Since queryModule succeeded and either curM or one of the packages it + // contains matches q.pattern, we should have either selected the version + // of curM matching q, or reported a conflict error (and exited). + // If we're still here and the version doesn't match, + // something has gone very wrong. + reportError(q, fmt.Errorf("internal error: selected %v instead of %v", curM, rev.Version)) } - base.ExitIfErrors() + } +} - // Query target versions for modules providing packages matched by - // command line arguments. - byPath = runQueries(queryCache, queries, modOnly) +// performPathQueries populates the candidates for each query whose pattern is +// a path literal. +// +// The candidate packages and modules for path literals depend only on the +// initial build list, not the current build list, so we only need to query path +// literals once. +func (r *resolver) performPathQueries(ctx context.Context) { + for _, q := range r.pathQueries { + q := q + r.work.Add(func() { + if q.version == "none" { + r.queryNone(ctx, q) + } else { + r.queryPath(ctx, q) + } + }) + } + <-r.work.Idle() +} - // Handle upgrades. This is needed for arguments that didn't match - // modules or matched different modules from a previous iteration. It - // also upgrades modules providing package dependencies if -u is set. - buildList, err := mvs.UpgradeAll(modload.Target, newUpgrader(byPath, seenPkgs)) - if err != nil { - base.Fatalf("go get: %v", err) +// queryPath adds a candidate set to q for the package with path q.pattern. +// The candidate set consists of all modules that could provide q.pattern +// and have a version matching q, plus (if it exists) the module whose path +// is itself q.pattern (at a matching version). +func (r *resolver) queryPath(ctx context.Context, q *query) { + q.pathOnce(q.pattern, func() pathSet { + if search.IsMetaPackage(q.pattern) || q.isWildcard() { + panic(fmt.Sprintf("internal error: queryPath called with pattern %q", q.pattern)) } - modload.SetBuildList(buildList) - base.ExitIfErrors() + if q.version == "none" { + panic(`internal error: queryPath called with version "none"`) + } + + if search.IsStandardImportPath(q.pattern) { + stdOnly := module.Version{} + packages, _ := r.matchInModule(ctx, q.pattern, stdOnly) + if len(packages) > 0 { + if q.rawVersion != "" { + return errSet(fmt.Errorf("can't request explicit version %q of standard library package %s", q.version, q.pattern)) + } - // Stop if no changes have been made to the build list. - buildList = modload.BuildList() - eq := len(buildList) == len(prevBuildList) - for i := 0; eq && i < len(buildList); i++ { - eq = buildList[i] == prevBuildList[i] + q.matchesPackages = true + return pathSet{} // No module needed for standard library. + } } - if eq { - break + + pkgMods, mod, err := r.queryPattern(ctx, q.pattern, q.version, r.initialSelected) + if err != nil { + return errSet(err) } - prevBuildList = buildList + return pathSet{pkgMods: pkgMods, mod: mod} + }) +} + +// performPatternAllQueries populates the candidates for each query whose +// pattern is "all". +// +// The candidate modules for a given package in "all" depend only on the initial +// build list, but we cannot follow the dependencies of a given package until we +// know which candidate is selected — and that selection may depend on the +// results of other queries. We need to re-evaluate the "all" queries whenever +// the module for one or more packages in "all" are resolved. +func (r *resolver) performPatternAllQueries(ctx context.Context) { + if len(r.patternAllQueries) == 0 { + return } - if !*getD { - // Only print warnings after the last iteration, - // and only if we aren't going to build. - search.WarnUnmatched(matches) + + findPackage := func(ctx context.Context, path string, m module.Version) (versionOk bool) { + versionOk = true + for _, q := range r.patternAllQueries { + q.pathOnce(path, func() pathSet { + pkgMods, err := r.queryPackages(ctx, path, q.version, r.initialSelected) + if len(pkgMods) != 1 || pkgMods[0] != m { + // There are candidates other than m for the given path, so we can't + // be certain that m will actually be the module selected to provide + // the package. Don't load its dependencies just yet, because they + // might no longer be dependencies after we resolve the correct + // version. + versionOk = false + } + return pathSet{pkgMods: pkgMods, err: err} + }) + } + return versionOk + } + + r.loadPackages(ctx, []string{"all"}, findPackage) + + // Since we built up the candidate lists concurrently, they may be in a + // nondeterministic order. We want 'go get' to be fully deterministic, + // including in which errors it chooses to report, so sort the candidates + // into a deterministic-but-arbitrary order. + for _, q := range r.patternAllQueries { + sort.Slice(q.candidates, func(i, j int) bool { + return q.candidates[i].path < q.candidates[j].path + }) } +} - // Handle downgrades. - var down []module.Version - for _, m := range modload.BuildList() { - q := byPath[m.Path] - if q != nil && semver.Compare(m.Version, q.m.Version) > 0 { - down = append(down, module.Version{Path: m.Path, Version: q.m.Version}) +// findAndUpgradeImports returns a pathSet for each package that is not yet +// in the build list but is transitively imported by the packages matching the +// given queries (which must already have been resolved). +// +// If the getU flag ("-u") is set, findAndUpgradeImports also returns a +// pathSet for each module that is not constrained by any other +// command-line argument and has an available matching upgrade. +func (r *resolver) findAndUpgradeImports(ctx context.Context, queries []*query) (upgrades []pathSet) { + patterns := make([]string, 0, len(queries)) + for _, q := range queries { + if q.matchesPackages { + patterns = append(patterns, q.pattern) } } - if len(down) > 0 { - buildList, err := mvs.Downgrade(modload.Target, modload.Reqs(), down...) + if len(patterns) == 0 { + return nil + } + + // mu guards concurrent writes to upgrades, which will be sorted + // (to restore determinism) after loading. + var mu sync.Mutex + + findPackage := func(ctx context.Context, path string, m module.Version) (versionOk bool) { + version := "latest" + if m.Path != "" { + if getU.version == "" { + // The user did not request that we upgrade transitive dependencies. + return true + } + if _, ok := r.resolvedVersion[m.Path]; ok { + // We cannot upgrade m implicitly because its version is determined by + // an explicit pattern argument. + return true + } + version = getU.version + } + + // Unlike other queries, the "-u" flag upgrades relative to the build list + // after applying changes so far, not the initial build list. + // This is for two reasons: + // + // - The "-u" flag intentionally applies to transitive dependencies, + // which may not be known or even resolved in advance of applying + // other version changes. + // + // - The "-u" flag, unlike other arguments, does not cause version + // conflicts with other queries. (The other query always wins.) + + pkgMods, err := r.queryPackages(ctx, path, version, r.selected) + for _, u := range pkgMods { + if u == m { + // The selected package version is already upgraded appropriately; there + // is no need to change it. + return true + } + } + if err != nil { - base.Fatalf("go: %v", err) + if isNoSuchPackageVersion(err) || (m.Path == "" && module.CheckPath(path) != nil) { + // We can't find the package because it doesn't — or can't — even exist + // in any module at the latest version. (Note that invalid module paths + // could in general exist due to replacements, so we at least need to + // run the query to check those.) + // + // There is no version change we can make to fix the package, so leave + // it unresolved. Either some other query (perhaps a wildcard matching a + // newly-added dependency for some other missing package) will fill in + // the gaps, or we will report an error (with a better import stack) in + // the final LoadPackages call. + return true + } } - modload.SetBuildList(buildList) - modload.ReloadBuildList() // note: does not update go.mod - base.ExitIfErrors() + + mu.Lock() + upgrades = append(upgrades, pathSet{path: path, pkgMods: pkgMods, err: err}) + mu.Unlock() + return false + } + + r.loadPackages(ctx, patterns, findPackage) + + // Since we built up the candidate lists concurrently, they may be in a + // nondeterministic order. We want 'go get' to be fully deterministic, + // including in which errors it chooses to report, so sort the candidates + // into a deterministic-but-arbitrary order. + sort.Slice(upgrades, func(i, j int) bool { + return upgrades[i].path < upgrades[j].path + }) + return upgrades +} + +// loadPackages loads the packages matching the given patterns, invoking the +// findPackage function for each package that may require a change to the +// build list. +// +// loadPackages invokes the findPackage function for each package loaded from a +// module outside the main module. If the module or version that supplies that +// package needs to be changed due to a query, findPackage may return false +// and the imports of that package will not be loaded. +// +// loadPackages also invokes the findPackage function for each imported package +// that is neither present in the standard library nor in any module in the +// build list. +func (r *resolver) loadPackages(ctx context.Context, patterns []string, findPackage func(ctx context.Context, path string, m module.Version) (versionOk bool)) { + opts := modload.PackageOpts{ + Tags: imports.AnyTags(), + LoadTests: *getT, + SilenceErrors: true, // May be fixed by subsequent upgrades or downgrades. } - // Scan for any upgrades lost by the downgrades. - var lostUpgrades []*query - if len(down) > 0 { - versionByPath = make(map[string]string) - for _, m := range modload.BuildList() { - versionByPath[m.Path] = m.Version + opts.AllowPackage = func(ctx context.Context, path string, m module.Version) error { + if m.Path == "" || m == modload.Target { + // Packages in the standard library and main module are already at their + // latest (and only) available versions. + return nil } - for _, q := range byPath { - if v, ok := versionByPath[q.m.Path]; q.m.Version != "none" && (!ok || semver.Compare(v, q.m.Version) != 0) { - lostUpgrades = append(lostUpgrades, q) - } + if ok := findPackage(ctx, path, m); !ok { + return errVersionChange } - sort.Slice(lostUpgrades, func(i, j int) bool { - return lostUpgrades[i].m.Path < lostUpgrades[j].m.Path - }) + return nil } - if len(lostUpgrades) > 0 { - desc := func(m module.Version) string { - s := m.Path + "@" + m.Version - t := byPath[m.Path] - if t != nil && t.arg != s { - s += " from " + t.arg - } - return s + + _, pkgs := modload.LoadPackages(ctx, opts, patterns...) + for _, path := range pkgs { + const ( + parentPath = "" + parentIsStd = false + ) + _, _, err := modload.Lookup(parentPath, parentIsStd, path) + if err == nil { + continue } - downByPath := make(map[string]module.Version) - for _, d := range down { - downByPath[d.Path] = d + if errors.Is(err, errVersionChange) { + // We already added candidates during loading. + continue } - var buf strings.Builder - fmt.Fprintf(&buf, "go get: inconsistent versions:") - reqs := modload.Reqs() - for _, q := range lostUpgrades { - // We lost q because its build list requires a newer version of something in down. - // Figure out exactly what. - // Repeatedly constructing the build list is inefficient - // if there are MANY command-line arguments, - // but at least all the necessary requirement lists are cached at this point. - list, err := buildListForLostUpgrade(q.m, reqs) - if err != nil { - base.Fatalf("go: %v", err) - } + var ( + importMissing *modload.ImportMissingError + ambiguous *modload.AmbiguousImportError + ) + if !errors.As(err, &importMissing) && !errors.As(err, &ambiguous) { + // The package, which is a dependency of something we care about, has some + // problem that we can't resolve with a version change. + // Leave the error for the final LoadPackages call. + continue + } + + path := path + r.work.Add(func() { + findPackage(ctx, path, module.Version{}) + }) + } + <-r.work.Idle() +} - fmt.Fprintf(&buf, "\n\t%s", desc(q.m)) - sep := " requires" - for _, m := range list { - if down, ok := downByPath[m.Path]; ok && semver.Compare(down.Version, m.Version) < 0 { - fmt.Fprintf(&buf, "%s %s@%s (not %s)", sep, m.Path, m.Version, desc(down)) - sep = "," +// errVersionChange is a sentinel error indicating that a module's version needs +// to be updated before its dependencies can be loaded. +var errVersionChange = errors.New("version change needed") + +// resolveCandidates resolves candidates sets that are attached to the given +// queries and/or needed to provide the given missing-package dependencies. +// +// resolveCandidates starts by resolving one module version from each +// unambiguous pathSet attached to the given queries. +// +// If no unambiguous query results in a change to the build list, +// resolveCandidates modifies the build list by adding one module version from +// each pathSet in missing, but does not mark those versions as resolved +// (so they can still be modified by other queries). +// +// If that still does not result in any changes to the build list, +// resolveCandidates revisits the ambiguous query candidates and resolves them +// arbitrarily in order to guarantee forward progress. +// +// If all pathSets are resolved without any changes to the build list, +// resolveCandidates returns with changed=false. +func (r *resolver) resolveCandidates(ctx context.Context, queries []*query, upgrades []pathSet) (changed bool) { + defer base.ExitIfErrors() + + // Note: this is O(N²) with the number of pathSets in the worst case. + // + // We could perhaps get it down to O(N) if we were to index the pathSets + // by module path, so that we only revisit a given pathSet when the + // version of some module in its containingPackage list has been determined. + // + // However, N tends to be small, and most candidate sets will include only one + // candidate module (so they will be resolved in the first iteration), so for + // now we'll stick to the simple O(N²) approach. + + resolved := 0 + for { + prevResolved := resolved + + for _, q := range queries { + unresolved := q.candidates[:0] + + for _, cs := range q.candidates { + if cs.err != nil { + reportError(q, cs.err) + resolved++ + continue } - } - if sep != "," { - // We have no idea why this happened. - // At least report the problem. - if v := versionByPath[q.m.Path]; v == "" { - fmt.Fprintf(&buf, " removed unexpectedly") - } else { - fmt.Fprintf(&buf, " ended up at %s unexpectedly", v) + + filtered, isPackage, m, unique := r.disambiguate(cs) + if !unique { + unresolved = append(unresolved, filtered) + continue } - fmt.Fprintf(&buf, " (please report at golang.org/issue/new)") + + if m.Path == "" { + // The query is not viable. Choose an arbitrary candidate from + // before filtering and “resolve” it to report a conflict. + isPackage, m = r.chooseArbitrarily(cs) + } + if isPackage { + q.matchesPackages = true + } + r.resolve(q, m) + resolved++ } + + q.candidates = unresolved } - base.Fatalf("%v", buf.String()) - } - // Everything succeeded. Update go.mod. - modload.AllowWriteGoMod() - modload.WriteGoMod() + base.ExitIfErrors() + if resolved == prevResolved { + break // No unambiguous candidate remains. + } + } - // If -d was specified, we're done after the module work. - // We've already downloaded modules by loading packages above. - // Otherwise, we need to build and install the packages matched by - // command line arguments. This may be a different set of packages, - // since we only build packages for the target platform. - // Note that 'go get -u' without arguments is equivalent to - // 'go get -u .', so we'll typically build the package in the current - // directory. - if *getD || len(pkgPatterns) == 0 { - return + if changed := r.updateBuildList(ctx, nil); changed { + // The build list has changed, so disregard any missing packages: they might + // now be determined by requirements in the build list, which we would + // prefer to use instead of arbitrary "latest" versions. + return true } - work.BuildInit() - pkgs := load.PackagesForBuild(pkgPatterns) - work.InstallPackages(pkgPatterns, pkgs) -} -// runQueries looks up modules at target versions in parallel. Results will be -// cached. If the same module is referenced by multiple queries at different -// versions (including earlier queries in the modOnly map), an error will be -// reported. A map from module paths to queries is returned, which includes -// queries and modOnly. -func runQueries(cache map[querySpec]*query, queries []*query, modOnly map[string]*query) map[string]*query { - var lookup par.Work - for _, q := range queries { - if cached := cache[q.querySpec]; cached != nil { - *q = *cached - } else { - cache[q.querySpec] = q - lookup.Add(q) + // Arbitrarily add a "latest" version that provides each missing package, but + // do not mark the version as resolved: we still want to allow the explicit + // queries to modify the resulting versions. + var tentative []module.Version + for _, cs := range upgrades { + if cs.err != nil { + base.Errorf("go get: %v", cs.err) + continue } - } - lookup.Do(10, func(item interface{}) { - q := item.(*query) - if q.vers == "none" { - // Wait for downgrade step. - q.m = module.Version{Path: q.path, Version: "none"} - return + filtered, _, m, unique := r.disambiguate(cs) + if !unique { + _, m = r.chooseArbitrarily(filtered) } - m, err := getQuery(q.path, q.vers, q.prevM, q.forceModulePath) - if err != nil { - base.Errorf("go get %s: %v", q.arg, err) + if m.Path == "" { + // There is no viable candidate for the missing package. + // Leave it unresolved. + continue } - q.m = m - }) + tentative = append(tentative, m) + } base.ExitIfErrors() - - byPath := make(map[string]*query) - check := func(q *query) { - if prev, ok := byPath[q.m.Path]; prev != nil && prev.m != q.m { - base.Errorf("go get: conflicting versions for module %s: %s and %s", q.m.Path, prev.m.Version, q.m.Version) - byPath[q.m.Path] = nil // sentinel to stop errors - return - } else if !ok { - byPath[q.m.Path] = q - } + if changed := r.updateBuildList(ctx, tentative); changed { + return true } + + // The build list will be the same on the next iteration as it was on this + // iteration, so any ambiguous queries will remain so. In order to make + // progress, resolve them arbitrarily but deterministically. + // + // If that results in conflicting versions, the user can re-run 'go get' + // with additional explicit versions for the conflicting packages or + // modules. for _, q := range queries { - check(q) + for _, cs := range q.candidates { + isPackage, m := r.chooseArbitrarily(cs) + if isPackage { + q.matchesPackages = true + } + r.resolve(q, m) + } } - for _, q := range modOnly { - check(q) + return r.updateBuildList(ctx, nil) +} + +// disambiguate eliminates candidates from cs that conflict with other module +// versions that have already been resolved. If there is only one (unique) +// remaining candidate, disambiguate returns that candidate, along with +// an indication of whether that result interprets cs.path as a package +// +// Note: we're only doing very simple disambiguation here. The goal is to +// reproduce the user's intent, not to find a solution that a human couldn't. +// In the vast majority of cases, we expect only one module per pathSet, +// but we want to give some minimal additional tools so that users can add an +// extra argument or two on the command line to resolve simple ambiguities. +func (r *resolver) disambiguate(cs pathSet) (filtered pathSet, isPackage bool, m module.Version, unique bool) { + if len(cs.pkgMods) == 0 && cs.mod.Path == "" { + panic("internal error: resolveIfUnambiguous called with empty pathSet") } - base.ExitIfErrors() - return byPath -} + for _, m := range cs.pkgMods { + if _, ok := r.noneForPath(m.Path); ok { + // A query with version "none" forces the candidate module to version + // "none", so we cannot use any other version for that module. + continue + } -// getQuery evaluates the given (package or module) path and version -// to determine the underlying module version being requested. -// If forceModulePath is set, getQuery must interpret path -// as a module path. -func getQuery(path, vers string, prevM module.Version, forceModulePath bool) (module.Version, error) { - if (prevM.Version != "") != forceModulePath { - // We resolve package patterns by calling QueryPattern, which does not - // accept a previous version and therefore cannot take it into account for - // the "latest" or "patch" queries. - // If we are resolving a package path or pattern, the caller has already - // resolved any existing packages to their containing module(s), and - // will set both prevM.Version and forceModulePath for those modules. - // The only remaining package patterns are those that are not already - // provided by the build list, which are indicated by - // an empty prevM.Version. - base.Fatalf("go get: internal error: prevM may be set if and only if forceModulePath is set") - } - - // If the query must be a module path, try only that module path. - if forceModulePath { - if path == modload.Target.Path { - if vers != "latest" { - return module.Version{}, fmt.Errorf("can't get a specific version of the main module") + if m.Path == modload.Target.Path { + if m.Version == modload.Target.Version { + return pathSet{}, true, m, true } + // The main module can only be set to its own version. + continue } - 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 + vr, ok := r.resolvedVersion[m.Path] + if !ok { + // m is a viable answer to the query, but other answers may also + // still be viable. + filtered.pkgMods = append(filtered.pkgMods, m) + continue } - // If the query was "upgrade" or "patch" and the current version has been - // replaced, check to see whether the error was for that same version: - // if so, the version was probably replaced because it is invalid, - // and we should keep that replacement without complaining. - if vers == "upgrade" || vers == "patch" { - var vErr *module.InvalidVersionError - if errors.As(err, &vErr) && vErr.Version == prevM.Version && modload.Replacement(prevM).Path != "" { - return prevM, nil - } + if vr.version != m.Version { + // Some query forces the candidate module to a version other than this + // one. + // + // The command could be something like + // + // go get example.com/foo/bar@none example.com/foo/bar/baz@latest + // + // in which case we *cannot* resolve the package from + // example.com/foo/bar (because it is constrained to version + // "none") and must fall through to module example.com/foo@latest. + continue } - return module.Version{}, err + // Some query forces the candidate module *to* the candidate version. + // As a result, this candidate is the only viable choice to provide + // its package(s): any other choice would result in an ambiguous import + // for this path. + // + // For example, consider the command + // + // go get example.com/foo@latest example.com/foo/bar/baz@latest + // + // If modules example.com/foo and example.com/foo/bar both provide + // package example.com/foo/bar/baz, then we *must* resolve the package + // from example.com/foo: if we instead resolved it from + // example.com/foo/bar, we would have two copies of the package. + return pathSet{}, true, m, true } - // If the query may be either a package or a module, try it as a package path. - // If it turns out to only exist as a module, we can detect the resulting - // PackageNotInModuleError and avoid a second round-trip through (potentially) - // all of the configured proxies. - results, err := modload.QueryPattern(path, vers, modload.Allowed) - if err != nil { - // If the path doesn't contain a wildcard, check whether it was actually a - // module path instead. If so, return that. - 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 - } + if cs.mod.Path != "" { + vr, ok := r.resolvedVersion[cs.mod.Path] + if !ok || vr.version == cs.mod.Version { + filtered.mod = cs.mod } + } - return module.Version{}, err + if len(filtered.pkgMods) == 1 && + (filtered.mod.Path == "" || filtered.mod == filtered.pkgMods[0]) { + // Exactly one viable module contains the package with the given path + // (by far the common case), so we can resolve it unambiguously. + return pathSet{}, true, filtered.pkgMods[0], true } - 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) + if len(filtered.pkgMods) == 0 { + // All modules that could provide the path as a package conflict with other + // resolved arguments. If it can refer to a module instead, return that; + // otherwise, this pathSet cannot be resolved (and we will return the + // zero module.Version). + return pathSet{}, false, filtered.mod, true } - return m, nil + + // The query remains ambiguous: there are at least two different modules + // to which cs.path could refer. + return filtered, false, module.Version{}, false } -// An upgrader adapts an underlying mvs.Reqs to apply an -// upgrade policy to a list of targets and their dependencies. -type upgrader struct { - mvs.Reqs +// chooseArbitrarily returns an arbitrary (but deterministic) module version +// from among those in the given set. +// +// chooseArbitrarily prefers module paths that were already in the build list at +// the start of 'go get', prefers modules that provide packages over those that +// do not, and chooses the first module meeting those criteria (so biases toward +// longer paths). +func (r *resolver) chooseArbitrarily(cs pathSet) (isPackage bool, m module.Version) { + // Prefer to upgrade some module that was already in the build list. + for _, m := range cs.pkgMods { + if r.initialSelected(m.Path) != "none" { + return true, m + } + } - // cmdline maps a module path to a query made for that module at a - // specific target version. Each query corresponds to a module - // matched by a command line argument. - cmdline map[string]*query + // Otherwise, arbitrarily choose the first module that provides the package. + if len(cs.pkgMods) > 0 { + return true, cs.pkgMods[0] + } - // upgrade is a set of modules providing dependencies of packages - // matched by command line arguments. If -u or -u=patch is set, - // these modules are upgraded accordingly. - upgrade map[string]bool + return false, cs.mod } -// newUpgrader creates an upgrader. cmdline contains queries made at -// specific versions for modules matched by command line arguments. pkgs -// is the set of packages matched by command line arguments. If -u or -u=patch -// is set, modules providing dependencies of pkgs are upgraded accordingly. -func newUpgrader(cmdline map[string]*query, pkgs map[string]bool) *upgrader { - u := &upgrader{ - Reqs: modload.Reqs(), - cmdline: cmdline, - } - if getU != "" { - u.upgrade = make(map[string]bool) - - // Traverse package import graph. - // Initialize work queue with root packages. - seen := make(map[string]bool) - var work []string - add := func(path string) { - if !seen[path] { - seen[path] = true - work = append(work, path) - } +// checkPackagesAndRetractions reloads packages for the given patterns and +// reports missing and ambiguous package errors. It also reports loads and +// reports retractions for resolved modules and modules needed to build +// named packages. +// +// We skip missing-package errors earlier in the process, since we want to +// resolve pathSets ourselves, but at that point, we don't have enough context +// to log the package-import chains leading to each error. +func (r *resolver) checkPackagesAndRetractions(ctx context.Context, pkgPatterns []string) { + defer base.ExitIfErrors() + + // Build a list of modules to load retractions for. Start with versions + // selected based on command line queries. + // + // This is a subset of the build list. If the main module has a lot of + // dependencies, loading retractions for the entire build list would be slow. + relevantMods := make(map[module.Version]struct{}) + for path, reason := range r.resolvedVersion { + relevantMods[module.Version{Path: path, Version: reason.version}] = struct{}{} + } + + // Reload packages, reporting errors for missing and ambiguous imports. + if len(pkgPatterns) > 0 { + // LoadPackages will print errors (since it has more context) but will not + // exit, since we need to load retractions later. + pkgOpts := modload.PackageOpts{ + LoadTests: *getT, + ResolveMissingImports: false, + AllowErrors: true, } - for pkg := range pkgs { - add(pkg) + matches, pkgs := modload.LoadPackages(ctx, pkgOpts, pkgPatterns...) + for _, m := range matches { + if len(m.Errs) > 0 { + base.SetExitStatus(1) + break + } } - for len(work) > 0 { - pkg := work[0] - work = work[1:] - m := modload.PackageModule(pkg) - u.upgrade[m.Path] = true - - // testImports is empty unless test imports were actually loaded, - // i.e., -t was set or "all" was one of the arguments. - imports, testImports := modload.PackageImports(pkg) - for _, imp := range imports { - add(imp) + for _, pkg := range pkgs { + if _, _, err := modload.Lookup("", false, pkg); err != nil { + base.SetExitStatus(1) + if ambiguousErr := (*modload.AmbiguousImportError)(nil); errors.As(err, &ambiguousErr) { + for _, m := range ambiguousErr.Modules { + relevantMods[m] = struct{}{} + } + } } - for _, imp := range testImports { - add(imp) + if m := modload.PackageModule(pkg); m.Path != "" { + relevantMods[m] = struct{}{} } } } - return u -} -// Required returns the requirement list for m. -// For the main module, we override requirements with the modules named -// one the command line, and we include new requirements. Otherwise, -// we defer to u.Reqs. -func (u *upgrader) Required(m module.Version) ([]module.Version, error) { - rs, err := u.Reqs.Required(m) - if err != nil { - return nil, err + // Load and report retractions. + type retraction struct { + m module.Version + err error } - if m != modload.Target { - return rs, nil + retractions := make([]retraction, 0, len(relevantMods)) + for m := range relevantMods { + retractions = append(retractions, retraction{m: m}) } - - overridden := make(map[string]bool) - for i, m := range rs { - if q := u.cmdline[m.Path]; q != nil && q.m.Version != "none" { - rs[i] = q.m - overridden[q.m.Path] = true - } + sort.Slice(retractions, func(i, j int) bool { + return retractions[i].m.Path < retractions[j].m.Path + }) + for i := 0; i < len(retractions); i++ { + i := i + r.work.Add(func() { + err := modload.CheckRetractions(ctx, retractions[i].m) + if retractErr := (*modload.ModuleRetractedError)(nil); errors.As(err, &retractErr) { + retractions[i].err = err + } + }) } - for _, q := range u.cmdline { - if !overridden[q.m.Path] && q.m.Path != modload.Target.Path && q.m.Version != "none" { - rs = append(rs, q.m) + <-r.work.Idle() + var retractPath string + for _, r := range retractions { + if r.err != nil { + fmt.Fprintf(os.Stderr, "go: warning: %v\n", r.err) + if retractPath == "" { + retractPath = r.m.Path + } else { + retractPath = "" + } } } - return rs, nil + if retractPath != "" { + fmt.Fprintf(os.Stderr, "go: run 'go get %s@latest' to switch to the latest unretracted version\n", retractPath) + } } -// Upgrade returns the desired upgrade for m. -// -// If m was requested at a specific version on the command line, then -// Upgrade returns that version. +// reportChanges logs version changes to os.Stderr. // -// If -u is set and m provides a dependency of a package matched by -// command line arguments, then Upgrade may provider a newer tagged version. -// If m is a tagged version, then Upgrade will return the latest tagged -// version (with the same minor version number if -u=patch). -// If m is a pseudo-version, then Upgrade returns the latest tagged version -// only if that version has a time-stamp newer than m. This special case -// prevents accidental downgrades when already using a pseudo-version -// newer than the latest tagged version. +// reportChanges only logs changes to modules named on the command line and to +// explicitly required modules in go.mod. Most changes to indirect requirements +// are not relevant to the user and are not logged. // -// If none of the above cases apply, then Upgrade returns m. -func (u *upgrader) Upgrade(m module.Version) (module.Version, error) { - // Allow pkg@vers on the command line to override the upgrade choice v. - // If q's version is < m.Version, then we're going to downgrade anyway, - // and it's cleaner to avoid moving back and forth and picking up - // extraneous other newer dependencies. - // If q's version is > m.Version, then we're going to upgrade past - // m.Version anyway, and again it's cleaner to avoid moving back and forth - // picking up extraneous other newer dependencies. - if q := u.cmdline[m.Path]; q != nil { - return q.m, nil - } - - if !u.upgrade[m.Path] { - // Not involved in upgrade. Leave alone. - return m, nil - } - - // Run query required by upgrade semantics. - // Note that Query "latest" is not the same as using repo.Latest, - // which may return a pseudoversion for the latest commit. - // Query "latest" returns the newest tagged version or the newest - // prerelease version if there are no non-prereleases, or repo.Latest - // if there aren't any tagged versions. - // If we're querying "upgrade" or "patch", Query will compare the current - // version against the chosen version and will return the current version - // if it is newer. - info, err := modload.Query(m.Path, string(getU), m.Version, modload.Allowed) - if err != nil { - // Report error but return m, to let version selection continue. - // (Reporting the error will fail the command at the next base.ExitIfErrors.) - - // Special case: if the error is for m.Version itself and m.Version has a - // replacement, then keep it and don't report the error: the fact that the - // version is invalid is likely the reason it was replaced to begin with. - var vErr *module.InvalidVersionError - if errors.As(err, &vErr) && vErr.Version == m.Version && modload.Replacement(m).Path != "" { - return m, nil +// reportChanges should be called after WriteGoMod. +func (r *resolver) reportChanges(oldReqs, newReqs []module.Version) { + type change struct { + path, old, new string + } + changes := make(map[string]change) + + // Collect changes in modules matched by command line arguments. + for path, reason := range r.resolvedVersion { + old := r.initialVersion[path] + new := reason.version + if old != new && (old != "" || new != "none") { + changes[path] = change{path, old, new} } + } - // Special case: if the error is "no matching versions" then don't - // even report the error. Because Query does not consider pseudo-versions, - // it may happen that we have a pseudo-version but during -u=patch - // the query v0.0 matches no versions (not even the one we're using). - var noMatch *modload.NoMatchingVersionError - if !errors.As(err, &noMatch) { - base.Errorf("go get: upgrading %s@%s: %v", m.Path, m.Version, err) + // Collect changes to explicit requirements in go.mod. + for _, req := range oldReqs { + path := req.Path + old := req.Version + new := r.buildListVersion[path] + if old != new { + changes[path] = change{path, old, new} + } + } + for _, req := range newReqs { + path := req.Path + old := r.initialVersion[path] + new := req.Version + if old != new { + changes[path] = change{path, old, new} } - return m, nil } - if info.Version != m.Version { - logOncef("go: %s %s => %s", m.Path, getU, info.Version) + sortedChanges := make([]change, 0, len(changes)) + for _, c := range changes { + sortedChanges = append(sortedChanges, c) } - return module.Version{Path: m.Path, Version: info.Version}, nil + sort.Slice(sortedChanges, func(i, j int) bool { + return sortedChanges[i].path < sortedChanges[j].path + }) + for _, c := range sortedChanges { + if c.old == "" { + fmt.Fprintf(os.Stderr, "go get: added %s %s\n", c.path, c.new) + } else if c.new == "none" || c.new == "" { + fmt.Fprintf(os.Stderr, "go get: removed %s %s\n", c.path, c.old) + } else if semver.Compare(c.new, c.old) > 0 { + fmt.Fprintf(os.Stderr, "go get: upgraded %s %s => %s\n", c.path, c.old, c.new) + } else { + fmt.Fprintf(os.Stderr, "go get: downgraded %s %s => %s\n", c.path, c.old, c.new) + } + } + + // TODO(golang.org/issue/33284): attribute changes to command line arguments. + // For modules matched by command line arguments, this probably isn't + // necessary, but it would be useful for unmatched direct dependencies of + // the main module. } -// buildListForLostUpgrade returns the build list for the module graph -// rooted at lost. Unlike mvs.BuildList, the target module (lost) is not -// treated specially. The returned build list may contain a newer version -// of lost. -// -// buildListForLostUpgrade is used after a downgrade has removed a module -// requested at a specific version. This helps us understand the requirements -// implied by each downgrade. -func buildListForLostUpgrade(lost module.Version, reqs mvs.Reqs) ([]module.Version, error) { - return mvs.BuildList(lostUpgradeRoot, &lostUpgradeReqs{Reqs: reqs, lost: lost}) +// resolve records that module m must be at its indicated version (which may be +// "none") due to query q. If some other query forces module m to be at a +// different version, resolve reports a conflict error. +func (r *resolver) resolve(q *query, m module.Version) { + if m.Path == "" { + panic("internal error: resolving a module.Version with an empty path") + } + + if m.Path == modload.Target.Path && m.Version != modload.Target.Version { + reportError(q, &modload.QueryMatchesMainModuleError{ + Pattern: q.pattern, + Query: q.version, + }) + return + } + + vr, ok := r.resolvedVersion[m.Path] + if ok && vr.version != m.Version { + reportConflict(q, m, vr) + return + } + r.resolvedVersion[m.Path] = versionReason{m.Version, q} + q.resolved = append(q.resolved, m) } -var lostUpgradeRoot = module.Version{Path: "lost-upgrade-root", Version: ""} +// updateBuildList updates the module loader's global build list to be +// consistent with r.resolvedVersion, and to include additional modules +// provided that they do not conflict with the resolved versions. +// +// If the additional modules conflict with the resolved versions, they will be +// downgraded to a non-conflicting version (possibly "none"). +func (r *resolver) updateBuildList(ctx context.Context, additions []module.Version) (changed bool) { + if len(additions) == 0 && len(r.resolvedVersion) == r.buildListResolvedVersions { + return false + } + + defer base.ExitIfErrors() -type lostUpgradeReqs struct { - mvs.Reqs - lost module.Version + resolved := make([]module.Version, 0, len(r.resolvedVersion)) + for mPath, rv := range r.resolvedVersion { + if mPath != modload.Target.Path { + resolved = append(resolved, module.Version{Path: mPath, Version: rv.version}) + } + } + + if err := modload.EditBuildList(ctx, additions, resolved); err != nil { + var constraint *modload.ConstraintError + if !errors.As(err, &constraint) { + base.Errorf("go get: %v", err) + return false + } + + reason := func(m module.Version) string { + rv, ok := r.resolvedVersion[m.Path] + if !ok { + panic(fmt.Sprintf("internal error: can't find reason for requirement on %v", m)) + } + return rv.reason.ResolvedString(module.Version{Path: m.Path, Version: rv.version}) + } + for _, c := range constraint.Conflicts { + base.Errorf("go get: %v requires %v, not %v", reason(c.Source), c.Dep, reason(c.Constraint)) + } + return false + } + + buildList := modload.LoadAllModules(ctx) + r.buildListResolvedVersions = len(r.resolvedVersion) + if reflect.DeepEqual(r.buildList, buildList) { + return false + } + r.buildList = buildList + r.buildListVersion = make(map[string]string, len(r.buildList)) + for _, m := range r.buildList { + r.buildListVersion[m.Path] = m.Version + } + return true } -func (r *lostUpgradeReqs) Required(mod module.Version) ([]module.Version, error) { - if mod == lostUpgradeRoot { - return []module.Version{r.lost}, nil +func reqsFromGoMod(f *modfile.File) []module.Version { + reqs := make([]module.Version, len(f.Require)) + for i, r := range f.Require { + reqs[i] = r.Mod } - return r.Reqs.Required(mod) + return reqs } -var loggedLines sync.Map +// isNoSuchModuleVersion reports whether err indicates that the requested module +// does not exist at the requested version, either because the module does not +// exist at all or because it does not include that specific version. +func isNoSuchModuleVersion(err error) bool { + var noMatch *modload.NoMatchingVersionError + return errors.Is(err, os.ErrNotExist) || errors.As(err, &noMatch) +} -func logOncef(format string, args ...interface{}) { - msg := fmt.Sprintf(format, args...) - if _, dup := loggedLines.LoadOrStore(msg, true); !dup { - fmt.Fprintln(os.Stderr, msg) - } +// isNoSuchPackageVersion reports whether err indicates that the requested +// package does not exist at the requested version, either because no module +// that could contain it exists at that version, or because every such module +// that does exist does not actually contain the package. +func isNoSuchPackageVersion(err error) bool { + var noPackage *modload.PackageNotInModuleError + return isNoSuchModuleVersion(err) || errors.As(err, &noPackage) } diff --git a/libgo/go/cmd/go/internal/modget/query.go b/libgo/go/cmd/go/internal/modget/query.go new file mode 100644 index 00000000000..20eb0b6364e --- /dev/null +++ b/libgo/go/cmd/go/internal/modget/query.go @@ -0,0 +1,357 @@ +// Copyright 2020 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 modget + +import ( + "fmt" + "path/filepath" + "regexp" + "strings" + "sync" + + "cmd/go/internal/base" + "cmd/go/internal/modload" + "cmd/go/internal/search" + "cmd/go/internal/str" + + "golang.org/x/mod/module" +) + +// A query describes a command-line argument and the modules and/or packages +// to which that argument may resolve.. +type query struct { + // raw is the original argument, to be printed in error messages. + raw string + + // rawVersion is the portion of raw corresponding to version, if any + rawVersion string + + // pattern is the part of the argument before "@" (or the whole argument + // if there is no "@"), which may match either packages (preferred) or + // modules (if no matching packages). + // + // The pattern may also be "-u", for the synthetic query representing the -u + // (“upgrade”)flag. + pattern string + + // patternIsLocal indicates whether pattern is restricted to match only paths + // local to the main module, such as absolute filesystem paths or paths + // beginning with './'. + // + // A local pattern must resolve to one or more packages in the main module. + patternIsLocal bool + + // version is the part of the argument after "@", or an implied + // "upgrade" or "patch" if there is no "@". version specifies the + // module version to get. + version string + + // matchWildcard, if non-nil, reports whether pattern, which must be a + // wildcard (with the substring "..."), matches the given package or module + // path. + matchWildcard func(path string) bool + + // canMatchWildcard, if non-nil, reports whether the module with the given + // path could lexically contain a package matching pattern, which must be a + // wildcard. + canMatchWildcardInModule func(mPath string) bool + + // conflict is the first query identified as incompatible with this one. + // conflict forces one or more of the modules matching this query to a + // version that does not match version. + conflict *query + + // candidates is a list of sets of alternatives for a path that matches (or + // contains packages that match) the pattern. The query can be resolved by + // choosing exactly one alternative from each set in the list. + // + // A path-literal query results in only one set: the path itself, which + // may resolve to either a package path or a module path. + // + // A wildcard query results in one set for each matching module path, each + // module for which the matching version contains at least one matching + // package, and (if no other modules match) one candidate set for the pattern + // overall if no existing match is identified in the build list. + // + // A query for pattern "all" results in one set for each package transitively + // imported by the main module. + // + // The special query for the "-u" flag results in one set for each + // otherwise-unconstrained package that has available upgrades. + candidates []pathSet + candidatesMu sync.Mutex + + // pathSeen ensures that only one pathSet is added to the query per + // unique path. + pathSeen sync.Map + + // resolved contains the set of modules whose versions have been determined by + // this query, in the order in which they were determined. + // + // The resolver examines the candidate sets for each query, resolving one + // module per candidate set in a way that attempts to avoid obvious conflicts + // between the versions resolved by different queries. + resolved []module.Version + + // matchesPackages is true if the resolved modules provide at least one + // package mathcing q.pattern. + matchesPackages bool +} + +// A pathSet describes the possible options for resolving a specific path +// to a package and/or module. +type pathSet struct { + // path is a package (if "all" or "-u" or a non-wildcard) or module (if + // wildcard) path that could be resolved by adding any of the modules in this + // set. For a wildcard pattern that so far matches no packages, the path is + // the wildcard pattern itself. + // + // Each path must occur only once in a query's candidate sets, and the path is + // added implicitly to each pathSet returned to pathOnce. + path string + + // pkgMods is a set of zero or more modules, each of which contains the + // package with the indicated path. Due to the requirement that imports be + // unambiguous, only one such module can be in the build list, and all others + // must be excluded. + pkgMods []module.Version + + // mod is either the zero Version, or a module that does not contain any + // packages matching the query but for which the module path itself + // matches the query pattern. + // + // We track this module separately from pkgMods because, all else equal, we + // prefer to match a query to a package rather than just a module. Also, + // unlike the modules in pkgMods, this module does not inherently exclude + // any other module in pkgMods. + mod module.Version + + err error +} + +// errSet returns a pathSet containing the given error. +func errSet(err error) pathSet { return pathSet{err: err} } + +// newQuery returns a new query parsed from the raw argument, +// which must be either path or path@version. +func newQuery(raw string) (*query, error) { + pattern := raw + rawVers := "" + if i := strings.Index(raw, "@"); i >= 0 { + pattern, rawVers = raw[:i], raw[i+1:] + if strings.Contains(rawVers, "@") || rawVers == "" { + return nil, fmt.Errorf("invalid module version syntax %q", raw) + } + } + + // If no version suffix is specified, assume @upgrade. + // If -u=patch was specified, assume @patch instead. + version := rawVers + if version == "" { + if getU.version == "" { + version = "upgrade" + } else { + version = getU.version + } + } + + q := &query{ + raw: raw, + rawVersion: rawVers, + pattern: pattern, + patternIsLocal: filepath.IsAbs(pattern) || search.IsRelativePath(pattern), + version: version, + } + if strings.Contains(q.pattern, "...") { + q.matchWildcard = search.MatchPattern(q.pattern) + q.canMatchWildcardInModule = search.TreeCanMatchPattern(q.pattern) + } + if err := q.validate(); err != nil { + return q, err + } + return q, nil +} + +// validate reports a non-nil error if q is not sensible and well-formed. +func (q *query) validate() error { + if q.patternIsLocal { + if q.rawVersion != "" { + return fmt.Errorf("can't request explicit version %q of path %q in main module", q.rawVersion, q.pattern) + } + return nil + } + + if q.pattern == "all" { + // If there is no main module, "all" is not meaningful. + if !modload.HasModRoot() { + return fmt.Errorf(`cannot match "all": working directory is not part of a module`) + } + if !versionOkForMainModule(q.version) { + // TODO(bcmills): "all@none" seems like a totally reasonable way to + // request that we remove all module requirements, leaving only the main + // module and standard library. Perhaps we should implement that someday. + return &modload.QueryMatchesMainModuleError{ + Pattern: q.pattern, + Query: q.version, + } + } + } + + if search.IsMetaPackage(q.pattern) && q.pattern != "all" { + if q.pattern != q.raw { + return fmt.Errorf("can't request explicit version of standard-library pattern %q", q.pattern) + } + } + + return nil +} + +// String returns the original argument from which q was parsed. +func (q *query) String() string { return q.raw } + +// ResolvedString returns a string describing m as a resolved match for q. +func (q *query) ResolvedString(m module.Version) string { + if m.Path != q.pattern { + if m.Version != q.version { + return fmt.Sprintf("%v (matching %s@%s)", m, q.pattern, q.version) + } + return fmt.Sprintf("%v (matching %v)", m, q) + } + if m.Version != q.version { + return fmt.Sprintf("%s@%s (%s)", q.pattern, q.version, m.Version) + } + return q.String() +} + +// isWildcard reports whether q is a pattern that can match multiple paths. +func (q *query) isWildcard() bool { + return q.matchWildcard != nil || (q.patternIsLocal && strings.Contains(q.pattern, "...")) +} + +// matchesPath reports whether the given path matches q.pattern. +func (q *query) matchesPath(path string) bool { + if q.matchWildcard != nil { + return q.matchWildcard(path) + } + return path == q.pattern +} + +// canMatchInModule reports whether the given module path can potentially +// contain q.pattern. +func (q *query) canMatchInModule(mPath string) bool { + if q.canMatchWildcardInModule != nil { + return q.canMatchWildcardInModule(mPath) + } + return str.HasPathPrefix(q.pattern, mPath) +} + +// pathOnce invokes f to generate the pathSet for the given path, +// if one is still needed. +// +// Note that, unlike sync.Once, pathOnce does not guarantee that a concurrent +// call to f for the given path has completed on return. +// +// pathOnce is safe for concurrent use by multiple goroutines, but note that +// multiple concurrent calls will result in the sets being added in +// nondeterministic order. +func (q *query) pathOnce(path string, f func() pathSet) { + if _, dup := q.pathSeen.LoadOrStore(path, nil); dup { + return + } + + cs := f() + + if len(cs.pkgMods) > 0 || cs.mod != (module.Version{}) || cs.err != nil { + cs.path = path + q.candidatesMu.Lock() + q.candidates = append(q.candidates, cs) + q.candidatesMu.Unlock() + } +} + +// reportError logs err concisely using base.Errorf. +func reportError(q *query, err error) { + errStr := err.Error() + + // If err already mentions all of the relevant parts of q, just log err to + // reduce stutter. Otherwise, log both q and err. + // + // TODO(bcmills): Use errors.As to unpack these errors instead of parsing + // strings with regular expressions. + + patternRE := regexp.MustCompile("(?m)(?:[ \t(\"`]|^)" + regexp.QuoteMeta(q.pattern) + "(?:[ @:)\"`]|$)") + if patternRE.MatchString(errStr) { + if q.rawVersion == "" { + base.Errorf("go get: %s", errStr) + return + } + + versionRE := regexp.MustCompile("(?m)(?:[ @(\"`]|^)" + regexp.QuoteMeta(q.version) + "(?:[ :)\"`]|$)") + if versionRE.MatchString(errStr) { + base.Errorf("go get: %s", errStr) + return + } + } + + if qs := q.String(); qs != "" { + base.Errorf("go get %s: %s", qs, errStr) + } else { + base.Errorf("go get: %s", errStr) + } +} + +func reportConflict(pq *query, m module.Version, conflict versionReason) { + if pq.conflict != nil { + // We've already reported a conflict for the proposed query. + // Don't report it again, even if it has other conflicts. + return + } + pq.conflict = conflict.reason + + proposed := versionReason{ + version: m.Version, + reason: pq, + } + if pq.isWildcard() && !conflict.reason.isWildcard() { + // Prefer to report the specific path first and the wildcard second. + proposed, conflict = conflict, proposed + } + reportError(pq, &conflictError{ + mPath: m.Path, + proposed: proposed, + conflict: conflict, + }) +} + +type conflictError struct { + mPath string + proposed versionReason + conflict versionReason +} + +func (e *conflictError) Error() string { + argStr := func(q *query, v string) string { + if v != q.version { + return fmt.Sprintf("%s@%s (%s)", q.pattern, q.version, v) + } + return q.String() + } + + pq := e.proposed.reason + rq := e.conflict.reason + modDetail := "" + if e.mPath != pq.pattern { + modDetail = fmt.Sprintf("for module %s, ", e.mPath) + } + + return fmt.Sprintf("%s%s conflicts with %s", + modDetail, + argStr(pq, e.proposed.version), + argStr(rq, e.conflict.version)) +} + +func versionOkForMainModule(version string) bool { + return version == "upgrade" || version == "patch" +} diff --git a/libgo/go/cmd/go/internal/modinfo/info.go b/libgo/go/cmd/go/internal/modinfo/info.go index 07248d1a61c..897be56397d 100644 --- a/libgo/go/cmd/go/internal/modinfo/info.go +++ b/libgo/go/cmd/go/internal/modinfo/info.go @@ -21,6 +21,7 @@ type ModulePublic struct { Dir string `json:",omitempty"` // directory holding local copy of files, if any GoMod string `json:",omitempty"` // path to go.mod file describing module, if any GoVersion string `json:",omitempty"` // go version used in module + Retracted []string `json:",omitempty"` // retraction information, if any (with -retracted or -u) Error *ModuleError `json:",omitempty"` // error loading module } @@ -30,18 +31,26 @@ type ModuleError struct { func (m *ModulePublic) String() string { s := m.Path + versionString := func(mm *ModulePublic) string { + v := mm.Version + if len(mm.Retracted) == 0 { + return v + } + return v + " (retracted)" + } + if m.Version != "" { - s += " " + m.Version + s += " " + versionString(m) if m.Update != nil { - s += " [" + m.Update.Version + "]" + s += " [" + versionString(m.Update) + "]" } } if m.Replace != nil { s += " => " + m.Replace.Path if m.Replace.Version != "" { - s += " " + m.Replace.Version + s += " " + versionString(m.Replace) if m.Replace.Update != nil { - s += " [" + m.Replace.Update.Version + "]" + s += " [" + versionString(m.Replace.Update) + "]" } } } diff --git a/libgo/go/cmd/go/internal/modload/build.go b/libgo/go/cmd/go/internal/modload/build.go index e7e7d56bb4d..d2f8f8670a2 100644 --- a/libgo/go/cmd/go/internal/modload/build.go +++ b/libgo/go/cmd/go/internal/modload/build.go @@ -6,12 +6,13 @@ package modload import ( "bytes" + "context" "encoding/hex" + "errors" "fmt" "internal/goroot" "os" "path/filepath" - "runtime/debug" "strings" "cmd/go/internal/base" @@ -48,7 +49,7 @@ func findStandardImportPath(path string) string { // 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. +// LoadPackages or ImportFromFiles, nil is returned. func PackageModuleInfo(pkgpath string) *modinfo.ModulePublic { if isStandardImportPath(pkgpath) || !Enabled() { return nil @@ -57,21 +58,27 @@ func PackageModuleInfo(pkgpath string) *modinfo.ModulePublic { if !ok { return nil } - return moduleInfo(m, true) + fromBuildList := true + listRetracted := false + return moduleInfo(context.TODO(), m, fromBuildList, listRetracted) } -func ModuleInfo(path string) *modinfo.ModulePublic { +func ModuleInfo(ctx context.Context, path string) *modinfo.ModulePublic { if !Enabled() { return nil } + listRetracted := false if i := strings.Index(path, "@"); i >= 0 { - return moduleInfo(module.Version{Path: path[:i], Version: path[i+1:]}, false) + m := module.Version{Path: path[:i], Version: path[i+1:]} + fromBuildList := false + return moduleInfo(ctx, m, fromBuildList, listRetracted) } - for _, m := range BuildList() { + for _, m := range buildList { if m.Path == path { - return moduleInfo(m, true) + fromBuildList := true + return moduleInfo(ctx, m, fromBuildList, listRetracted) } } @@ -84,12 +91,12 @@ func ModuleInfo(path string) *modinfo.ModulePublic { } // addUpdate fills in m.Update if an updated version is available. -func addUpdate(m *modinfo.ModulePublic) { +func addUpdate(ctx context.Context, m *modinfo.ModulePublic) { if m.Version == "" { return } - if info, err := Query(m.Path, "upgrade", m.Version, Allowed); err == nil && semver.Compare(info.Version, m.Version) > 0 { + if info, err := Query(ctx, m.Path, "upgrade", m.Version, CheckAllowed); err == nil && semver.Compare(info.Version, m.Version) > 0 { m.Update = &modinfo.ModulePublic{ Path: m.Path, Version: info.Version, @@ -99,11 +106,37 @@ func addUpdate(m *modinfo.ModulePublic) { } // addVersions fills in m.Versions with the list of known versions. -func addVersions(m *modinfo.ModulePublic) { - m.Versions, _ = versions(m.Path) +// Excluded versions will be omitted. If listRetracted is false, retracted +// versions will also be omitted. +func addVersions(ctx context.Context, m *modinfo.ModulePublic, listRetracted bool) { + allowed := CheckAllowed + if listRetracted { + allowed = CheckExclusions + } + m.Versions, _ = versions(ctx, m.Path, allowed) +} + +// addRetraction fills in m.Retracted if the module was retracted by its author. +// m.Error is set if there's an error loading retraction information. +func addRetraction(ctx context.Context, m *modinfo.ModulePublic) { + if m.Version == "" { + return + } + + err := CheckRetractions(ctx, module.Version{Path: m.Path, Version: m.Version}) + var rerr *ModuleRetractedError + if errors.As(err, &rerr) { + if len(rerr.Rationale) == 0 { + m.Retracted = []string{"retracted by module author"} + } else { + m.Retracted = rerr.Rationale + } + } else if err != nil && m.Error == nil { + m.Error = &modinfo.ModuleError{Err: err.Error()} + } } -func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { +func moduleInfo(ctx context.Context, m module.Version, fromBuildList, listRetracted bool) *modinfo.ModulePublic { if m == Target { info := &modinfo.ModulePublic{ Path: m.Path, @@ -125,21 +158,22 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { Version: m.Version, Indirect: fromBuildList && loaded != nil && !loaded.direct[m.Path], } - if loaded != nil { - info.GoVersion = loaded.goVersion[m.Path] + if v, ok := rawGoVersion.Load(m); ok { + info.GoVersion = v.(string) } // completeFromModCache fills in the extra fields in m using the module cache. completeFromModCache := func(m *modinfo.ModulePublic) { + mod := module.Version{Path: m.Path, Version: m.Version} + if m.Version != "" { - if q, err := Query(m.Path, m.Version, "", nil); err != nil { + if q, err := Query(ctx, m.Path, m.Version, "", nil); err != nil { m.Error = &modinfo.ModuleError{Err: err.Error()} } else { m.Version = q.Version m.Time = &q.Time } - mod := module.Version{Path: m.Path, Version: m.Version} gomod, err := modfetch.CachePath(mod, "mod") if err == nil { if info, err := os.Stat(gomod); err == nil && info.Mode().IsRegular() { @@ -150,10 +184,22 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { if err == nil { m.Dir = dir } + + if listRetracted { + addRetraction(ctx, m) + } + } + + if m.GoVersion == "" { + if summary, err := rawGoModSummary(mod); err == nil && summary.goVersionV != "" { + m.GoVersion = summary.goVersionV[1:] + } } } if !fromBuildList { + // If this was an explicitly-versioned argument to 'go mod download' or + // 'go list -m', report the actual requested version, not its replacement. completeFromModCache(info) // Will set m.Error in vendor mode. return info } @@ -177,9 +223,11 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { // worth the cost, and we're going to overwrite the GoMod and Dir from the // replacement anyway. See https://golang.org/issue/27859. info.Replace = &modinfo.ModulePublic{ - Path: r.Path, - Version: r.Version, - GoVersion: info.GoVersion, + Path: r.Path, + Version: r.Version, + } + if v, ok := rawGoVersion.Load(m); ok { + info.Replace.GoVersion = v.(string) } if r.Version == "" { if filepath.IsAbs(r.Path) { @@ -193,14 +241,15 @@ func moduleInfo(m module.Version, fromBuildList bool) *modinfo.ModulePublic { completeFromModCache(info.Replace) info.Dir = info.Replace.Dir info.GoMod = info.Replace.GoMod + info.Retracted = info.Replace.Retracted } + info.GoVersion = info.Replace.GoVersion 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. +// name packages that were resolved successfully with LoadPackages. func PackageBuildInfo(path string, deps []string) string { if isStandardImportPath(path) || !Enabled() { return "" @@ -262,17 +311,13 @@ func mustFindModule(target, path string) module.Version { return Target } - if printStackInDie { - debug.PrintStack() - } base.Fatalf("build %v: cannot find module for path %v", target, path) panic("unreachable") } // 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. +// If the package was loaded, 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{} @@ -312,6 +357,6 @@ 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))) +`, string(infoStart)+info+string(infoEnd))) } } diff --git a/libgo/go/cmd/go/internal/modload/buildlist.go b/libgo/go/cmd/go/internal/modload/buildlist.go new file mode 100644 index 00000000000..896adebbb19 --- /dev/null +++ b/libgo/go/cmd/go/internal/modload/buildlist.go @@ -0,0 +1,267 @@ +// 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 modload + +import ( + "cmd/go/internal/base" + "cmd/go/internal/cfg" + "cmd/go/internal/imports" + "cmd/go/internal/mvs" + "context" + "fmt" + "os" + "strings" + + "golang.org/x/mod/module" +) + +// buildList is the list of modules to use for building packages. +// It is initialized by calling LoadPackages or ImportFromFiles, +// each of which uses loaded.load. +// +// Ideally, exactly ONE of those functions would be called, +// and exactly once. Most of the time, that's true. +// During "go get" it may not be. TODO(rsc): Figure out if +// that restriction can be established, or else document why not. +// +var buildList []module.Version + +// capVersionSlice returns s with its cap reduced to its length. +func capVersionSlice(s []module.Version) []module.Version { + return s[:len(s):len(s)] +} + +// LoadAllModules loads and returns the list of modules matching the "all" +// module pattern, starting with the Target module and in a deterministic +// (stable) order, without loading any packages. +// +// Modules are loaded automatically (and lazily) in LoadPackages: +// LoadAllModules need only be called if LoadPackages is not, +// typically in commands that care about modules but no particular package. +// +// The caller must not modify the returned list, but may append to it. +func LoadAllModules(ctx context.Context) []module.Version { + LoadModFile(ctx) + ReloadBuildList() + WriteGoMod() + return capVersionSlice(buildList) +} + +// Selected returns the selected version of the module with the given path, or +// the empty string if the given module has no selected version +// (either because it is not required or because it is the Target module). +func Selected(path string) (version string) { + if path == Target.Path { + return "" + } + for _, m := range buildList { + if m.Path == path { + return m.Version + } + } + return "" +} + +// EditBuildList edits the global build list by first adding every module in add +// to the existing build list, then adjusting versions (and adding or removing +// requirements as needed) until every module in mustSelect is selected at the +// given version. +// +// (Note that the newly-added modules might not be selected in the resulting +// build list: they could be lower than existing requirements or conflict with +// versions in mustSelect.) +// +// If the versions listed in mustSelect are mutually incompatible (due to one of +// the listed modules requiring a higher version of another), EditBuildList +// returns a *ConstraintError and leaves the build list in its previous state. +func EditBuildList(ctx context.Context, add, mustSelect []module.Version) error { + var upgraded = capVersionSlice(buildList) + if len(add) > 0 { + // First, upgrade the build list with any additions. + // In theory we could just append the additions to the build list and let + // mvs.Downgrade take care of resolving the upgrades too, but the + // diagnostics from Upgrade are currently much better in case of errors. + var err error + upgraded, err = mvs.Upgrade(Target, &mvsReqs{buildList: upgraded}, add...) + if err != nil { + return err + } + } + + downgraded, err := mvs.Downgrade(Target, &mvsReqs{buildList: append(upgraded, mustSelect...)}, mustSelect...) + if err != nil { + return err + } + + final, err := mvs.Upgrade(Target, &mvsReqs{buildList: downgraded}, mustSelect...) + if err != nil { + return err + } + + selected := make(map[string]module.Version, len(final)) + for _, m := range final { + selected[m.Path] = m + } + inconsistent := false + for _, m := range mustSelect { + s, ok := selected[m.Path] + if !ok { + if m.Version != "none" { + panic(fmt.Sprintf("internal error: mvs.BuildList lost %v", m)) + } + continue + } + if s.Version != m.Version { + inconsistent = true + break + } + } + + if !inconsistent { + buildList = final + return nil + } + + // We overshot one or more of the modules in mustSelected, which means that + // Downgrade removed something in mustSelect because it conflicted with + // something else in mustSelect. + // + // Walk the requirement graph to find the conflict. + // + // TODO(bcmills): Ideally, mvs.Downgrade (or a replacement for it) would do + // this directly. + + reqs := &mvsReqs{buildList: final} + reason := map[module.Version]module.Version{} + for _, m := range mustSelect { + reason[m] = m + } + queue := mustSelect[:len(mustSelect):len(mustSelect)] + for len(queue) > 0 { + var m module.Version + m, queue = queue[0], queue[1:] + required, err := reqs.Required(m) + if err != nil { + return err + } + for _, r := range required { + if _, ok := reason[r]; !ok { + reason[r] = reason[m] + queue = append(queue, r) + } + } + } + + var conflicts []Conflict + for _, m := range mustSelect { + s, ok := selected[m.Path] + if !ok { + if m.Version != "none" { + panic(fmt.Sprintf("internal error: mvs.BuildList lost %v", m)) + } + continue + } + if s.Version != m.Version { + conflicts = append(conflicts, Conflict{ + Source: reason[s], + Dep: s, + Constraint: m, + }) + } + } + + return &ConstraintError{ + Conflicts: conflicts, + } +} + +// A ConstraintError describes inconsistent constraints in EditBuildList +type ConstraintError struct { + // Conflict lists the source of the conflict for each version in mustSelect + // that could not be selected due to the requirements of some other version in + // mustSelect. + Conflicts []Conflict +} + +func (e *ConstraintError) Error() string { + b := new(strings.Builder) + b.WriteString("version constraints conflict:") + for _, c := range e.Conflicts { + fmt.Fprintf(b, "\n\t%v requires %v, but %v is requested", c.Source, c.Dep, c.Constraint) + } + return b.String() +} + +// A Conflict documents that Source requires Dep, which conflicts with Constraint. +// (That is, Dep has the same module path as Constraint but a higher version.) +type Conflict struct { + Source module.Version + Dep module.Version + Constraint module.Version +} + +// ReloadBuildList resets the state of loaded packages, then loads and returns +// the build list set by EditBuildList. +func ReloadBuildList() []module.Version { + loaded = loadFromRoots(loaderParams{ + PackageOpts: PackageOpts{ + Tags: imports.Tags(), + }, + listRoots: func() []string { return nil }, + allClosesOverTests: index.allPatternClosesOverTests(), // but doesn't matter because the root list is empty. + }) + return capVersionSlice(buildList) +} + +// TidyBuildList trims the build list to the minimal requirements needed to +// retain the same versions of all packages from the preceding call to +// LoadPackages. +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...) +} + +// 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 + if rep := Replacement(mod); rep.Path != "" { + src = rep + } + if prev, ok := firstPath[src]; !ok { + firstPath[src] = mod.Path + } else if prev != mod.Path { + base.Errorf("go: %s@%s used for two different module paths (%s and %s)", src.Path, src.Version, prev, mod.Path) + } + } + base.ExitIfErrors() +} diff --git a/libgo/go/cmd/go/internal/modload/help.go b/libgo/go/cmd/go/internal/modload/help.go index d80206b1948..d81dfd56fb5 100644 --- a/libgo/go/cmd/go/internal/modload/help.go +++ b/libgo/go/cmd/go/internal/modload/help.go @@ -124,72 +124,63 @@ and the build list. For example: Maintaining module requirements -The go.mod file is meant to be readable and editable by both -programmers and tools. The go command itself automatically updates the go.mod file -to maintain a standard formatting and the accuracy of require statements. - -Any go command that finds an unfamiliar import will look up the module -containing that import and add the latest version of that module -to go.mod automatically. In most cases, therefore, it suffices to -add an import to source code and run 'go build', 'go test', or even 'go list': -as part of analyzing the package, the go command will discover -and resolve the import and update the go.mod file. - -Any go command can determine that a module requirement is -missing and must be added, even when considering only a single -package from the module. On the other hand, determining that a module requirement -is no longer necessary and can be deleted requires a full view of -all packages in the module, across all possible build configurations -(architectures, operating systems, build tags, and so on). -The 'go mod tidy' command builds that view and then -adds any missing module requirements and removes unnecessary ones. +The go.mod file is meant to be readable and editable by both programmers and +tools. Most updates to dependencies can be performed using "go get" and +"go mod tidy". Other module-aware build commands may be invoked using the +-mod=mod flag to automatically add missing requirements and fix inconsistencies. + +The "go get" command updates go.mod to change the module versions used in a +build. An upgrade of one module may imply upgrading others, and similarly a +downgrade of one module may imply downgrading others. The "go get" command +makes these implied changes as well. See "go help module-get". + +The "go mod" command provides other functionality for use in maintaining +and understanding modules and go.mod files. See "go help mod", particularly +"go help mod tidy" and "go help mod edit". As part of maintaining the require statements in go.mod, the go command tracks which ones provide packages imported directly by the current module and which ones provide packages only used indirectly by other module dependencies. Requirements needed only for indirect uses are marked with a -"// indirect" comment in the go.mod file. Indirect requirements are +"// indirect" comment in the go.mod file. Indirect requirements may be automatically removed from the go.mod file once they are implied by other direct requirements. Indirect requirements only arise when using modules that fail to state some of their own dependencies or when explicitly upgrading a module's dependencies ahead of its own stated requirements. -Because of this automatic maintenance, the information in go.mod is an -up-to-date, readable description of the build. - -The 'go get' command updates go.mod to change the module versions used in a -build. An upgrade of one module may imply upgrading others, and similarly a -downgrade of one module may imply downgrading others. The 'go get' command -makes these implied changes as well. If go.mod is edited directly, commands -like 'go build' or 'go list' will assume that an upgrade is intended and -automatically make any implied upgrades and update go.mod to reflect them. - -The 'go mod' command provides other functionality for use in maintaining -and understanding modules and go.mod files. See 'go help mod'. - -The -mod build flag provides additional control over updating and use of go.mod. - -If invoked with -mod=readonly, the go command is disallowed from the implicit -automatic updating of go.mod described above. Instead, it fails when any changes -to go.mod are needed. This setting is most useful to check that go.mod does -not need updates, such as in a continuous integration and testing system. -The "go get" command remains permitted to update go.mod even with -mod=readonly, -and the "go mod" commands do not take the -mod flag (or any other build flags). +The -mod build flag provides additional control over the updating and use of +go.mod for commands that build packages like "go build" and "go test". + +If invoked with -mod=readonly (the default in most situations), the go command +reports an error if a package named on the command line or an imported package +is not provided by any module in the build list computed from the main module's +requirements. The go command also reports an error if a module's checksum is +missing from go.sum (see Module downloading and verification). Either go.mod or +go.sum must be updated in these situations. + +If invoked with -mod=mod, the go command automatically updates go.mod and +go.sum, fixing inconsistencies and adding missing requirements and checksums +as needed. If the go command finds an unfamiliar import, it looks up the +module containing that import and adds a requirement for the latest version +of that module to go.mod. In most cases, therefore, one may add an import to +source code and run "go build", "go test", or even "go list" with -mod=mod: +as part of analyzing the package, the go command will resolve the import and +update the go.mod file. If invoked with -mod=vendor, the go command loads packages from the main module's vendor directory instead of downloading modules to and loading packages from the module cache. The go command assumes the vendor directory holds correct copies of dependencies, and it does not compute the set of required module versions from go.mod files. However, the go command does check that -vendor/modules.txt (generated by 'go mod vendor') contains metadata consistent +vendor/modules.txt (generated by "go mod vendor") contains metadata consistent with go.mod. -If invoked with -mod=mod, the go command loads modules from the module cache -even if there is a vendor directory present. +If the go command is not invoked with a -mod flag, and the vendor directory +is present, and the "go" version in go.mod is 1.14 or higher, the go command +will act as if it were invoked with -mod=vendor. Otherwise, the -mod flag +defaults to -mod=readonly. -If the go command is not invoked with a -mod flag and the vendor directory -is present and the "go" version in go.mod is 1.14 or higher, the go command -will act as if it were invoked with -mod=vendor. +Note that neither "go get" nor the "go mod" subcommands accept the -mod flag. Pseudo-versions @@ -374,7 +365,7 @@ list if the error is a 404 or 410 HTTP response or if the current proxy is followed by a pipe character, indicating it is safe to fall back on any error. The GOPRIVATE and GONOPROXY environment variables allow bypassing -the proxy for selected modules. See 'go help module-private' for details. +the proxy for selected modules. See 'go help private' for details. No matter the source of the modules, the go command checks downloads against known checksums, to detect unexpected changes in the content of any specific @@ -432,21 +423,23 @@ verb followed by arguments. For example: require new/thing/v2 v2.3.4 exclude old/thing v1.2.3 replace bad/thing v1.4.5 => good/thing v1.4.5 + retract v1.5.6 The verbs are module, to define the module path; go, to set the expected language version; require, to require a particular module at a given version or later; - exclude, to exclude a particular module version from use; and - replace, to replace a module version with a different module version. + exclude, to exclude a particular module version from use; + replace, to replace a module version with a different module version; and + retract, to indicate a previously released version should not be used. Exclude and replace apply only in the main module's go.mod and are ignored -in dependencies. See https://research.swtch.com/vgo-mvs for details. +in dependencies. See https://golang.org/ref/mod for details. The leading verb can be factored out of adjacent lines to create a block, like in Go imports: require ( - new/thing v2.3.4 + new/thing/v2 v2.3.4 old/thing v1.2.3 ) diff --git a/libgo/go/cmd/go/internal/modload/import.go b/libgo/go/cmd/go/internal/modload/import.go index 4d2bc805e2f..ce5671728e0 100644 --- a/libgo/go/cmd/go/internal/modload/import.go +++ b/libgo/go/cmd/go/internal/modload/import.go @@ -5,18 +5,19 @@ package modload import ( + "context" "errors" "fmt" "go/build" "internal/goroot" + "io/fs" "os" "path/filepath" "sort" "strings" - "time" "cmd/go/internal/cfg" - "cmd/go/internal/load" + "cmd/go/internal/fsys" "cmd/go/internal/modfetch" "cmd/go/internal/par" "cmd/go/internal/search" @@ -30,23 +31,60 @@ type ImportMissingError struct { Module module.Version QueryErr error + // inAll indicates whether Path is in the "all" package pattern, + // and thus would be added by 'go mod tidy'. + inAll bool + + // isStd indicates whether we would expect to find the package in the standard + // library. This is normally true for all dotless import paths, but replace + // directives can cause us to treat the replaced paths as also being in + // modules. + isStd bool + + // replaced the highest replaced version of the module where the replacement + // contains the package. replaced is only set if the replacement is unused. + replaced module.Version + // 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 search.IsStandardImportPath(e.Path) { + if e.isStd { 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 + if cfg.BuildMod == "mod" { + return "cannot find module providing package " + e.Path + } + + if e.replaced.Path != "" { + suggestArg := e.replaced.Path + if !modfetch.IsZeroPseudoVersion(e.replaced.Version) { + suggestArg = e.replaced.String() + } + return fmt.Sprintf("module %s provides package %s and is replaced but not required; try 'go get -d %s' to add it", e.replaced.Path, e.Path, suggestArg) + } + + suggestion := "" + if !HasModRoot() { + suggestion = ": working directory is not part of a module" + } else if e.inAll { + suggestion = "; try 'go mod tidy' to add it" + } else { + suggestion = fmt.Sprintf("; try 'go get -d %s' to add it", e.Path) + } + return fmt.Sprintf("no required module provides package %s%s", e.Path, suggestion) } + + if e.newMissingVersion != "" { + return fmt.Sprintf("package %s provided by %s at latest version %s but not at required version %s", e.Path, e.Module.Path, e.Module.Version, e.newMissingVersion) + } + return fmt.Sprintf("missing module for import: %s@%s provides %s", e.Module.Path, e.Module.Version, e.Path) } @@ -97,20 +135,62 @@ func (e *AmbiguousImportError) Error() string { return buf.String() } -var _ load.ImportPathError = &AmbiguousImportError{} +// ImportMissingSumError is reported in readonly mode when we need to check +// if a module in the build list contains a package, but we don't have a sum +// for its .zip file. +type ImportMissingSumError struct { + importPath string + found, inAll bool +} -// Import finds the module and directory in the build list -// containing the package with the given import path. -// The answer must be unique: Import returns an error -// if multiple modules attempt to provide the same package. -// Import can return a module with an empty m.Path, for packages in the standard library. -// Import can return an empty directory string, for fake packages like "C" and "unsafe". +func (e *ImportMissingSumError) Error() string { + var message string + if e.found { + message = fmt.Sprintf("missing go.sum entry needed to verify package %s is provided by exactly one module", e.importPath) + } else { + message = fmt.Sprintf("missing go.sum entry for module providing package %s", e.importPath) + } + if e.inAll { + return message + "; try 'go mod tidy' to add it" + } + return message +} + +func (e *ImportMissingSumError) ImportPath() string { + return e.importPath +} + +type invalidImportError struct { + importPath string + err error +} + +func (e *invalidImportError) ImportPath() string { + return e.importPath +} + +func (e *invalidImportError) Error() string { + return e.err.Error() +} + +func (e *invalidImportError) Unwrap() error { + return e.err +} + +// importFromBuildList finds the module and directory in the build list +// containing the package with the given import path. The answer must be unique: +// importFromBuildList returns an error if multiple modules attempt to provide +// the same package. // -// If the package cannot be found in the current build list, -// Import returns an ImportMissingError as the error. -// If Import can identify a module that could be added to supply the package, -// the ImportMissingError records that module. -func Import(path string) (m module.Version, dir string, err error) { +// importFromBuildList can return a module with an empty m.Path, for packages in +// the standard library. +// +// importFromBuildList can return an empty directory string, for fake packages +// like "C" and "unsafe". +// +// If the package cannot be found in buildList, +// importFromBuildList returns an *ImportMissingError. +func importFromBuildList(ctx context.Context, path string, buildList []module.Version) (m module.Version, dir string, err error) { if strings.Contains(path, "@") { return module.Version{}, "", fmt.Errorf("import path should not have @version") } @@ -121,6 +201,10 @@ func Import(path string) (m module.Version, dir string, err error) { // There's no directory for import "C" or import "unsafe". return module.Version{}, "", nil } + // Before any further lookup, check that the path is valid. + if err := module.CheckImportPath(path); err != nil { + return module.Version{}, "", &invalidImportError{importPath: path, err: err} + } // Is the package in the standard library? pathIsStd := search.IsStandardImportPath(path) @@ -160,13 +244,23 @@ func Import(path string) (m module.Version, dir string, err error) { // Check each module on the build list. var dirs []string var mods []module.Version + haveSumErr := false for _, m := range buildList { if !maybeInModule(path, m.Path) { // Avoid possibly downloading irrelevant modules. continue } - root, isLocal, err := fetch(m) + needSum := true + root, isLocal, err := fetch(ctx, m, needSum) if err != nil { + if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) { + // We are missing a sum needed to fetch a module in the build list. + // We can't verify that the package is unique, and we may not find + // the package at all. Keep checking other modules to decide which + // error to report. + haveSumErr = true + continue + } // Report fetch error. // Note that we don't know for sure this module is necessary, // but it certainly _could_ provide the package, and even if we @@ -182,88 +276,76 @@ func Import(path string) (m module.Version, dir string, err error) { dirs = append(dirs, dir) } } - if len(mods) == 1 { - return mods[0], dirs[0], nil - } - if len(mods) > 0 { + if len(mods) > 1 { 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" { - var queryErr error - if !pathIsStd { - if cfg.BuildModReason == "" { - queryErr = fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod) - } else { - 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 haveSumErr { + return module.Version{}, "", &ImportMissingSumError{importPath: path, found: len(mods) > 0} } - if modRoot == "" && !allowMissingModuleImports { - return module.Version{}, "", &ImportMissingError{ - Path: path, - QueryErr: errors.New("working directory is not part of a module"), - } + if len(mods) == 1 { + return mods[0], dirs[0], nil } - // Not on build list. - // To avoid spurious remote fetches, next try the latest replacement for each module. - // (golang.org/issue/26241) - if modFile != nil { - latest := map[string]string{} // path -> version - for _, r := range modFile.Replace { - if maybeInModule(path, r.Old.Path) { - // Don't use semver.Max here; need to preserve +incompatible suffix. - v := latest[r.Old.Path] - if semver.Compare(r.Old.Version, v) > 0 { - v = r.Old.Version - } - latest[r.Old.Path] = v - } - } + return module.Version{}, "", &ImportMissingError{Path: path, isStd: pathIsStd} +} - mods = make([]module.Version, 0, len(latest)) - for p, v := range latest { - // If the replacement didn't specify a version, synthesize a - // pseudo-version with an appropriate major version and a timestamp below - // any real timestamp. That way, if the main module is used from within - // some other module, the user will be able to upgrade the requirement to - // any real version they choose. - if v == "" { - if _, pathMajor, ok := module.SplitPathVersion(p); ok && len(pathMajor) > 0 { - v = modfetch.PseudoVersion(pathMajor[1:], "", time.Time{}, "000000000000") +// queryImport attempts to locate a module that can be added to the current +// build list to provide the package with the given import path. +// +// Unlike QueryPattern, queryImport prefers to add a replaced version of a +// module *before* checking the proxies for a version to add. +func queryImport(ctx context.Context, path string) (module.Version, error) { + // To avoid spurious remote fetches, try the latest replacement for each + // module (golang.org/issue/26241). + if index != nil { + var mods []module.Version + for mp, mv := range index.highestReplaced { + if !maybeInModule(path, mp) { + continue + } + if mv == "" { + // The only replacement is a wildcard that doesn't specify a version, so + // synthesize a pseudo-version with an appropriate major version and a + // timestamp below any real timestamp. That way, if the main module is + // used from within some other module, the user will be able to upgrade + // the requirement to any real version they choose. + if _, pathMajor, ok := module.SplitPathVersion(mp); ok && len(pathMajor) > 0 { + mv = modfetch.ZeroPseudoVersion(pathMajor[1:]) } else { - v = modfetch.PseudoVersion("v0", "", time.Time{}, "000000000000") + mv = modfetch.ZeroPseudoVersion("v0") } } - mods = append(mods, module.Version{Path: p, Version: v}) + mods = append(mods, module.Version{Path: mp, Version: mv}) } // Every module path in mods is a prefix of the import path. - // As in QueryPackage, prefer the longest prefix that satisfies the import. + // As in QueryPattern, prefer the longest prefix that satisfies the import. sort.Slice(mods, func(i, j int) bool { return len(mods[i].Path) > len(mods[j].Path) }) for _, m := range mods { - root, isLocal, err := fetch(m) + needSum := true + root, isLocal, err := fetch(ctx, m, needSum) if err != nil { - // Report fetch error as above. - return module.Version{}, "", err + if sumErr := (*sumMissingError)(nil); errors.As(err, &sumErr) { + return module.Version{}, &ImportMissingSumError{importPath: path} + } + return module.Version{}, err } if _, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil { - return m, "", err + return m, err } else if ok { - return m, "", &ImportMissingError{Path: path, Module: m} + if cfg.BuildMod == "readonly" { + return module.Version{}, &ImportMissingError{Path: path, replaced: m} + } + return m, nil } } 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, + // so it can only exist in a replaced module, // and we know from the above loop that it is not. - return module.Version{}, "", &PackageNotInModuleError{ + return module.Version{}, &PackageNotInModuleError{ Mod: mods[0], Query: "latest", Pattern: path, @@ -272,36 +354,53 @@ func Import(path string) (m module.Version, dir string, err error) { } } - if pathIsStd { + if search.IsStandardImportPath(path) { // 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. + // QueryPattern cannot possibly find a module containing this package. // - // Instead of trying QueryPackage, report an ImportMissingError immediately. - return module.Version{}, "", &ImportMissingError{Path: path} + // Instead of trying QueryPattern, report an ImportMissingError immediately. + return module.Version{}, &ImportMissingError{Path: path, isStd: true} + } + + if cfg.BuildMod == "readonly" { + // In readonly mode, we can't write go.mod, so we shouldn't try to look up + // the module. If readonly mode was enabled explicitly, include that in + // the error message. + var queryErr error + if cfg.BuildModExplicit { + queryErr = fmt.Errorf("import lookup disabled by -mod=%s", cfg.BuildMod) + } else if cfg.BuildModReason != "" { + queryErr = fmt.Errorf("import lookup disabled by -mod=%s\n\t(%s)", cfg.BuildMod, cfg.BuildModReason) + } + return module.Version{}, &ImportMissingError{Path: path, QueryErr: queryErr} } + // 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, ImpportMissingError. fmt.Fprintf(os.Stderr, "go: finding module for package %s\n", path) - candidates, err := QueryPackage(path, "latest", Allowed) + candidates, err := QueryPackages(ctx, path, "latest", Selected, CheckAllowed) if err != nil { - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { // Return "cannot find module providing package […]" instead of whatever - // low-level error QueryPackage produced. - return module.Version{}, "", &ImportMissingError{Path: path, QueryErr: err} + // low-level error QueryPattern produced. + return module.Version{}, &ImportMissingError{Path: path, QueryErr: err} } else { - return module.Version{}, "", err + return module.Version{}, err } } - m = candidates[0].Mod - newMissingVersion := "" - for _, c := range candidates { + + candidate0MissingVersion := "" + for i, c := range candidates { cm := c.Mod + canAdd := true for _, bm := range buildList { if bm.Path == cm.Path && semver.Compare(bm.Version, cm.Version) > 0 { - // QueryPackage proposed that we add module cm to provide the package, + // QueryPattern proposed that we add module cm to provide the package, // but we already depend on a newer version of that module (and we don't // have the package). // @@ -309,13 +408,22 @@ func Import(path string) (m module.Version, dir string, err error) { // version (e.g., v1.0.0) of a module, but we have a newer version // of the same module in the build list (e.g., v1.0.1-beta), and // the package is not present there. - m = cm - newMissingVersion = bm.Version + canAdd = false + if i == 0 { + candidate0MissingVersion = bm.Version + } break } } + if canAdd { + return cm, nil + } + } + return module.Version{}, &ImportMissingError{ + Path: path, + Module: candidates[0].Mod, + newMissingVersion: candidate0MissingVersion, } - return m, "", &ImportMissingError{Path: path, Module: m, newMissingVersion: newMissingVersion} } // maybeInModule reports whether, syntactically, @@ -369,7 +477,7 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile if isLocal { for d := dir; d != mdir && len(d) > len(mdir); { haveGoMod := haveGoModCache.Do(d, func() interface{} { - fi, err := os.Stat(filepath.Join(d, "go.mod")) + fi, err := fsys.Stat(filepath.Join(d, "go.mod")) return err == nil && !fi.IsDir() }).(bool) @@ -392,57 +500,65 @@ func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFile // We don't care about build tags, not even "+build ignore". // We're just looking for a plausible directory. res := haveGoFilesCache.Do(dir, func() interface{} { - ok, err := isDirWithGoFiles(dir) + ok, err := fsys.IsDirWithGoFiles(dir) return goFilesEntry{haveGoFiles: ok, err: err} }).(goFilesEntry) return dir, res.haveGoFiles, res.err } -func isDirWithGoFiles(dir string) (bool, error) { - f, err := os.Open(dir) - if err != nil { - if os.IsNotExist(err) { - return false, nil - } - return false, err - } - defer f.Close() - - names, firstErr := f.Readdirnames(-1) - if firstErr != nil { - if fi, err := f.Stat(); err == nil && !fi.IsDir() { - return false, nil - } - - // Rewrite the error from ReadDirNames to include the path if not present. - // See https://golang.org/issue/38923. - var pe *os.PathError - if !errors.As(firstErr, &pe) { - firstErr = &os.PathError{Op: "readdir", Path: dir, Err: firstErr} - } +// fetch downloads the given module (or its replacement) +// and returns its location. +// +// needSum indicates whether the module may be downloaded in readonly mode +// without a go.sum entry. It should only be false for modules fetched +// speculatively (for example, for incompatible version filtering). The sum +// will still be verified normally. +// +// The isLocal return value reports whether the replacement, +// if any, is local to the filesystem. +func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, isLocal bool, err error) { + if mod == Target { + return ModRoot(), true, nil } - - for _, name := range names { - if strings.HasSuffix(name, ".go") { - info, err := os.Stat(filepath.Join(dir, name)) - if err == nil && info.Mode().IsRegular() { - // If any .go source file exists, the package exists regardless of - // errors for other source files. Leave further error reporting for - // later. - return true, nil + if r := Replacement(mod); r.Path != "" { + if r.Version == "" { + dir = r.Path + if !filepath.IsAbs(dir) { + dir = filepath.Join(ModRoot(), dir) } - if firstErr == nil { + // Ensure that the replacement directory actually exists: + // dirInModule does not report errors for missing modules, + // so if we don't report the error now, later failures will be + // very mysterious. + if _, err := fsys.Stat(dir); err != nil { if os.IsNotExist(err) { - // If the file was concurrently deleted, or was a broken symlink, - // convert the error to an opaque error instead of one matching - // os.IsNotExist. - err = errors.New(err.Error()) + // Semantically the module version itself “exists” — we just don't + // have its source code. Remove the equivalence to os.ErrNotExist, + // and make the message more concise while we're at it. + err = fmt.Errorf("replacement directory %s does not exist", r.Path) + } else { + err = fmt.Errorf("replacement directory %s: %w", r.Path, err) } - firstErr = err + return dir, true, module.VersionError(mod, err) } + return dir, true, nil } + mod = r + } + + if cfg.BuildMod == "readonly" && needSum && !modfetch.HaveSum(mod) { + return "", false, module.VersionError(mod, &sumMissingError{}) } - return false, firstErr + dir, err = modfetch.Download(ctx, mod) + return dir, false, err +} + +type sumMissingError struct { + suggestion string +} + +func (e *sumMissingError) Error() string { + return "missing go.sum entry" + e.suggestion } diff --git a/libgo/go/cmd/go/internal/modload/import_test.go b/libgo/go/cmd/go/internal/modload/import_test.go index accc60eecdf..22d5b82e211 100644 --- a/libgo/go/cmd/go/internal/modload/import_test.go +++ b/libgo/go/cmd/go/internal/modload/import_test.go @@ -5,19 +5,25 @@ package modload import ( + "context" "internal/testenv" "regexp" "strings" "testing" + + "golang.org/x/mod/module" ) var importTests = []struct { path string + m module.Version err string }{ { path: "golang.org/x/net/context", - err: "missing module for import: golang.org/x/net@.* provides golang.org/x/net/context", + m: module.Version{ + Path: "golang.org/x/net", + }, }, { path: "golang.org/x/net", @@ -25,15 +31,23 @@ var importTests = []struct { }, { path: "golang.org/x/text", - err: "missing module for import: golang.org/x/text@.* provides golang.org/x/text", + m: module.Version{ + Path: "golang.org/x/text", + }, }, { path: "github.com/rsc/quote/buggy", - err: "missing module for import: github.com/rsc/quote@v1.5.2 provides github.com/rsc/quote/buggy", + m: module.Version{ + Path: "github.com/rsc/quote", + Version: "v1.5.2", + }, }, { path: "github.com/rsc/quote", - err: "missing module for import: github.com/rsc/quote@v1.5.2 provides github.com/rsc/quote", + m: module.Version{ + Path: "github.com/rsc/quote", + Version: "v1.5.2", + }, }, { path: "golang.org/x/foo/bar", @@ -41,7 +55,7 @@ var importTests = []struct { }, } -func TestImport(t *testing.T) { +func TestQueryImport(t *testing.T) { testenv.MustHaveExternalNetwork(t) testenv.MustHaveExecPath(t, "git") defer func(old bool) { @@ -49,15 +63,28 @@ func TestImport(t *testing.T) { }(allowMissingModuleImports) AllowMissingModuleImports() + ctx := context.Background() + for _, tt := range importTests { t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) { // Note that there is no build list, so Import should always fail. - m, dir, err := Import(tt.path) - if err == nil { - t.Fatalf("Import(%q) = %v, %v, nil; expected error", tt.path, m, dir) + m, err := queryImport(ctx, tt.path) + + if tt.err == "" { + if err != nil { + t.Fatalf("queryImport(_, %q): %v", tt.path, err) + } + } else { + if err == nil { + t.Fatalf("queryImport(_, %q) = %v, nil; expected error", tt.path, m) + } + if !regexp.MustCompile(tt.err).MatchString(err.Error()) { + t.Fatalf("queryImport(_, %q): error %q, want error matching %#q", tt.path, err, tt.err) + } } - if !regexp.MustCompile(tt.err).MatchString(err.Error()) { - t.Fatalf("Import(%q): error %q, want error matching %#q", tt.path, err, tt.err) + + if m.Path != tt.m.Path || (tt.m.Version != "" && m.Version != tt.m.Version) { + t.Errorf("queryImport(_, %q) = %v, _; want %v", tt.path, m, tt.m) } }) } diff --git a/libgo/go/cmd/go/internal/modload/init.go b/libgo/go/cmd/go/internal/modload/init.go index 664a2a15943..3f70d041451 100644 --- a/libgo/go/cmd/go/internal/modload/init.go +++ b/libgo/go/cmd/go/internal/modload/init.go @@ -6,23 +6,22 @@ package modload import ( "bytes" + "context" "encoding/json" "errors" "fmt" "go/build" "internal/lazyregexp" - "io/ioutil" "os" "path" "path/filepath" - "runtime/debug" "strconv" "strings" + "sync" "cmd/go/internal/base" - "cmd/go/internal/cache" "cmd/go/internal/cfg" - "cmd/go/internal/load" + "cmd/go/internal/fsys" "cmd/go/internal/lockedfile" "cmd/go/internal/modconv" "cmd/go/internal/modfetch" @@ -35,8 +34,7 @@ import ( ) var ( - mustUseModules = false - initialized bool + initialized bool modRoot string Target module.Version @@ -52,20 +50,42 @@ var ( gopath string - CmdModInit bool // running 'go mod init' - CmdModModule string // module argument for 'go mod init' + // RootMode determines whether a module root is needed. + RootMode Root + + // ForceUseModules may be set to force modules to be enabled when + // GO111MODULE=auto or to report an error when GO111MODULE=off. + ForceUseModules bool allowMissingModuleImports bool ) +type Root int + +const ( + // AutoRoot is the default for most commands. modload.Init will look for + // a go.mod file in the current directory or any parent. If none is found, + // modules may be disabled (GO111MODULE=on) or commands may run in a + // limited module mode. + AutoRoot Root = iota + + // NoRoot is used for commands that run in module mode and ignore any go.mod + // file the current directory or in parent directories. + NoRoot + + // NeedRoot is used for commands that must run in module mode and don't + // make sense without a main module. + NeedRoot +) + // ModFile returns the parsed go.mod file. // -// Note that after calling ImportPaths or LoadBuildList, +// Note that after calling LoadPackages or LoadAllModules, // the require statements in the modfile.File are no longer // the source of truth and will be ignored: edits made directly // will be lost at the next call to WriteGoMod. // To make permanent changes to the require statements -// in go.mod, edit it before calling ImportPaths or LoadBuildList. +// in go.mod, edit it before loading. func ModFile() *modfile.File { Init() if modFile == nil { @@ -92,19 +112,27 @@ func Init() { // 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. + var mustUseModules bool env := cfg.Getenv("GO111MODULE") switch env { default: base.Fatalf("go: unknown environment setting GO111MODULE=%s", env) - case "auto", "": - mustUseModules = false - case "on": + case "auto": + mustUseModules = ForceUseModules + case "on", "": mustUseModules = true case "off": + if ForceUseModules { + base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") + } mustUseModules = false return } + if err := fsys.Init(base.Cwd); err != nil { + base.Fatalf("go: %v", err) + } + // Disable any prompting for passwords by Git. // Only has an effect for 2.3.0 or later, but avoiding // the prompt in earlier versions is just too hard. @@ -132,15 +160,23 @@ func Init() { os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no") } - if CmdModInit { - // Running 'go mod init': go.mod will be created in current directory. - modRoot = base.Cwd + if modRoot != "" { + // modRoot set before Init was called ("go mod init" does this). + // No need to search for go.mod. + } else if RootMode == NoRoot { + if cfg.ModFile != "" && !base.InGOFLAGS("-modfile") { + base.Fatalf("go: -modfile cannot be used with commands that ignore the current module") + } + modRoot = "" } else { 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 RootMode == NeedRoot { + base.Fatalf("go: cannot find main module; see 'go help modules'") + } if !mustUseModules { // GO111MODULE is 'auto', and we can't find a module root. // Stay in GOPATH mode. @@ -154,38 +190,26 @@ func Init() { // when it happens. See golang.org/issue/26708. modRoot = "" fmt.Fprintf(os.Stderr, "go: warning: ignoring go.mod in system temp root %v\n", os.TempDir()) + if !mustUseModules { + return + } } } 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. - - if c := cache.Default(); c == nil { - // With modules, there are no install locations for packages - // other than the build cache. - base.Fatalf("go: cannot use modules with build cache disabled") - } - + // We're in module mode. Set any global variables that need to be set. list := filepath.SplitList(cfg.BuildContext.GOPATH) if len(list) == 0 || list[0] == "" { base.Fatalf("missing $GOPATH") } gopath = list[0] - if _, err := os.Stat(filepath.Join(gopath, "go.mod")); err == nil { + if _, err := fsys.Stat(filepath.Join(gopath, "go.mod")); err == nil { base.Fatalf("$GOPATH/go.mod exists but should not") } cfg.ModulesEnabled = true - load.ModBinDir = BinDir - load.ModLookup = Lookup - load.ModPackageModuleInfo = PackageModuleInfo - load.ModImportPaths = ImportPaths - load.ModPackageBuildInfo = PackageBuildInfo - load.ModInfoProg = ModInfoProg - load.ModImportFromFiles = ImportFromFiles - load.ModDirImportPath = DirImportPath if modRoot == "" { // We're in module mode, but not inside a module. @@ -211,10 +235,6 @@ func Init() { } } -func init() { - load.ModInit = 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. @@ -225,10 +245,12 @@ func init() { // 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 { + if modRoot != "" || cfg.ModulesEnabled { + // Already enabled. return true } if initialized { + // Initialized, not enabled. return false } @@ -236,18 +258,14 @@ func WillBeEnabled() bool { // exits, so it can't call this function directly. env := cfg.Getenv("GO111MODULE") switch env { - case "on": + case "on", "": return true - case "auto", "": + 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. @@ -269,7 +287,7 @@ func WillBeEnabled() bool { // (usually through MustModRoot). func Enabled() bool { Init() - return modRoot != "" || mustUseModules + return modRoot != "" || cfg.ModulesEnabled } // ModRoot returns the root of the main module. @@ -303,16 +321,7 @@ func ModFilePath() string { 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 -// unexpectedly require a main module. -var printStackInDie = false - func die() { - if printStackInDie { - debug.PrintStack() - } if cfg.Getenv("GO111MODULE") == "off" { base.Fatalf("go: modules disabled by GO111MODULE=off; see 'go help modules'") } @@ -330,12 +339,16 @@ func die() { 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. +// LoadModFile sets Target and, if there is a main module, parses the initial +// build list from its go.mod file. // -// As a side-effect, InitMod sets a default for cfg.BuildMod if it does not +// LoadModFile may make changes in memory, like adding a go directive and +// ensuring requirements are consistent. WriteGoMod should be called later to +// write changes out to disk or report errors in readonly mode. +// +// As a side-effect, LoadModFile sets a default for cfg.BuildMod if it does not // already have an explicit value. -func InitMod() { +func LoadModFile(ctx context.Context) { if len(buildList) > 0 { return } @@ -348,14 +361,6 @@ func InitMod() { return } - if CmdModInit { - // Running go mod init: do legacy module conversion - legacyModInit() - modFileToBuildList() - WriteGoMod() - return - } - gomod := ModFilePath() data, err := lockedfile.Read(gomod) if err != nil { @@ -363,7 +368,7 @@ func InitMod() { } var fixed bool - f, err := modfile.Parse(gomod, data, fixVersion(&fixed)) + f, err := modfile.Parse(gomod, data, fixVersion(ctx, &fixed)) if err != nil { // Errors returned by modfile.Parse begin with file:line. base.Fatalf("go: errors parsing go.mod:\n%s\n", err) @@ -371,32 +376,133 @@ func InitMod() { modFile = f index = indexModFile(data, f, fixed) - if len(f.Syntax.Stmt) == 0 || f.Module == nil { - // Empty mod file. Must add module path. - path, err := findModulePath(modRoot) - if err != nil { - base.Fatalf("go: %v", err) - } - f.AddModuleStmt(path) + if f.Module == nil { + // No module declaration. Must add module path. + base.Fatalf("go: no module declaration in go.mod.\n\tRun 'go mod edit -module=example.com/mod' to specify the module path.") } - if len(f.Syntax.Stmt) == 1 && f.Module != nil { - // Entire file is just a module statement. - // Populate require if possible. - legacyModInit() + if err := checkModulePathLax(f.Module.Mod.Path); err != nil { + base.Fatalf("go: %v", err) } - modFileToBuildList() setDefaultBuildMod() + modFileToBuildList() if cfg.BuildMod == "vendor" { readVendorList() checkVendorConsistency() - } else { - // TODO(golang.org/issue/33326): if cfg.BuildMod != "readonly"? - WriteGoMod() } } +// CreateModFile initializes a new module by creating a go.mod file. +// +// If modPath is empty, CreateModFile will attempt to infer the path from the +// directory location within GOPATH. +// +// If a vendoring configuration file is present, CreateModFile will attempt to +// translate it to go.mod directives. The resulting build list may not be +// exactly the same as in the legacy configuration (for example, we can't get +// packages at multiple versions from the same module). +func CreateModFile(ctx context.Context, modPath string) { + modRoot = base.Cwd + Init() + modFilePath := ModFilePath() + if _, err := fsys.Stat(modFilePath); err == nil { + base.Fatalf("go: %s already exists", modFilePath) + } + + if modPath == "" { + var err error + modPath, err = findModulePath(modRoot) + if err != nil { + base.Fatalf("go: %v", err) + } + } else if err := checkModulePathLax(modPath); err != nil { + base.Fatalf("go: %v", err) + } + + fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", modPath) + modFile = new(modfile.File) + modFile.AddModuleStmt(modPath) + addGoStmt() // Add the go directive before converted module requirements. + + convertedFrom, err := convertLegacyConfig(modPath) + if convertedFrom != "" { + fmt.Fprintf(os.Stderr, "go: copying requirements from %s\n", base.ShortPath(convertedFrom)) + } + if err != nil { + base.Fatalf("go: %v", err) + } + + modFileToBuildList() + WriteGoMod() + + // Suggest running 'go mod tidy' unless the project is empty. Even if we + // imported all the correct requirements above, we're probably missing + // some sums, so the next build command in -mod=readonly will likely fail. + // + // We look for non-hidden .go files or subdirectories to determine whether + // this is an existing project. Walking the tree for packages would be more + // accurate, but could take much longer. + empty := true + files, _ := os.ReadDir(modRoot) + for _, f := range files { + name := f.Name() + if strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_") { + continue + } + if strings.HasSuffix(name, ".go") || f.IsDir() { + empty = false + break + } + } + if !empty { + fmt.Fprintf(os.Stderr, "go: run 'go mod tidy' to add module requirements and sums\n") + } +} + +// checkModulePathLax checks that the path meets some minimum requirements +// to avoid confusing users or the module cache. The requirements are weaker +// than those of module.CheckPath to allow room for weakening module path +// requirements in the future, but strong enough to help users avoid significant +// problems. +func checkModulePathLax(p string) error { + // TODO(matloob): Replace calls of this function in this CL with calls + // to module.CheckImportPath once it's been laxened, if it becomes laxened. + // See golang.org/issue/29101 for a discussion about whether to make CheckImportPath + // more lax or more strict. + + errorf := func(format string, args ...interface{}) error { + return fmt.Errorf("invalid module path %q: %s", p, fmt.Sprintf(format, args...)) + } + + // Disallow shell characters " ' * < > ? ` | to avoid triggering bugs + // with file systems and subcommands. Disallow file path separators : and \ + // because path separators other than / will confuse the module cache. + // See fileNameOK in golang.org/x/mod/module/module.go. + shellChars := "`" + `\"'*<>?|` + fsChars := `\:` + if i := strings.IndexAny(p, shellChars); i >= 0 { + return errorf("contains disallowed shell character %q", p[i]) + } + if i := strings.IndexAny(p, fsChars); i >= 0 { + return errorf("contains disallowed path separator character %q", p[i]) + } + + // Ensure path.IsAbs and build.IsLocalImport are false, and that the path is + // invariant under path.Clean, also to avoid confusing the module cache. + if path.IsAbs(p) { + return errorf("is an absolute path") + } + if build.IsLocalImport(p) { + return errorf("is a local import path") + } + if path.Clean(p) != p { + return errorf("is not clean") + } + + return nil +} + // fixVersion returns a modfile.VersionFixer implemented using the Query function. // // It resolves commit hashes and branch names to versions, @@ -404,7 +510,7 @@ func InitMod() { // 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 { +func fixVersion(ctx context.Context, fixed *bool) modfile.VersionFixer { return func(path, vers string) (resolved string, err error) { defer func() { if err == nil && resolved != vers { @@ -436,7 +542,7 @@ func fixVersion(fixed *bool) modfile.VersionFixer { } } - info, err := Query(path, vers, "", nil) + info, err := Query(ctx, path, vers, "", nil) if err != nil { return "", err } @@ -465,7 +571,15 @@ func modFileToBuildList() { list := []module.Version{Target} for _, r := range modFile.Require { - list = append(list, r.Mod) + if index != nil && index.exclude[r.Mod] { + if cfg.BuildMod == "mod" { + fmt.Fprintf(os.Stderr, "go: dropping requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version) + } else { + fmt.Fprintf(os.Stderr, "go: ignoring requirement on excluded version %s %s\n", r.Mod.Path, r.Mod.Version) + } + } else { + list = append(list, r.Mod) + } } buildList = list } @@ -473,80 +587,62 @@ func modFileToBuildList() { // setDefaultBuildMod sets a default value for cfg.BuildMod // if it is currently empty. func setDefaultBuildMod() { - if cfg.BuildMod != "" { + if cfg.BuildModExplicit { // 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. + // 'get' and 'go mod' commands may update go.mod automatically. + // TODO(jayconrod): should this narrower? Should 'go mod download' or + // 'go mod graph' update go.mod by default? + cfg.BuildMod = "mod" return } if modRoot == "" { + cfg.BuildMod = "readonly" return } - if fi, err := os.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() { + if fi, err := fsys.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() { modGo := "unspecified" - if index.goVersion != "" { - if semver.Compare("v"+index.goVersion, "v1.14") >= 0 { + if index.goVersionV != "" { + if semver.Compare(index.goVersionV, "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 + modGo = index.goVersionV[1:] } } - // 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) + // Since a vendor directory exists, we should record why we didn't use it. + // This message won't normally be shown, but it may appear with import errors. + cfg.BuildModReason = fmt.Sprintf("Go version in go.mod is %s, so vendor directory was not used.", 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." - } + cfg.BuildMod = "readonly" } -func legacyModInit() { - if modFile == nil { - path, err := findModulePath(modRoot) - if err != nil { - base.Fatalf("go: %v", err) - } - fmt.Fprintf(os.Stderr, "go: creating new go.mod: module %s\n", path) - modFile = new(modfile.File) - modFile.AddModuleStmt(path) - addGoStmt() // Add the go directive before converted module requirements. - } - +// convertLegacyConfig imports module requirements from a legacy vendoring +// configuration file, if one is present. +func convertLegacyConfig(modPath string) (from string, err error) { for _, name := range altConfigs { cfg := filepath.Join(modRoot, name) - data, err := ioutil.ReadFile(cfg) + data, err := os.ReadFile(cfg) if err == nil { convert := modconv.Converters[name] if convert == nil { - return + return "", nil } - fmt.Fprintf(os.Stderr, "go: copying requirements from %s\n", base.ShortPath(cfg)) cfg = filepath.ToSlash(cfg) - if err := modconv.ConvertLegacyConfig(modFile, cfg, data); err != nil { - base.Fatalf("go: %v", err) - } - if len(modFile.Syntax.Stmt) == 1 { - // Add comment to avoid re-converting every time it runs. - modFile.AddComment("// go: no requirements found in " + name) - } - return + err := modconv.ConvertLegacyConfig(modFile, cfg, data) + return name, err } } + return "", nil } // addGoStmt adds a go directive to the go.mod file if it does not already include one. @@ -588,7 +684,7 @@ func findModuleRoot(dir string) (root string) { // Look for enclosing go.mod. for { - if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() { + if fi, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() { return dir } d := filepath.Dir(dir) @@ -612,7 +708,7 @@ func findAltConfig(dir string) (root, name string) { } for { for _, name := range altConfigs { - if fi, err := os.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() { + if fi, err := fsys.Stat(filepath.Join(dir, name)); err == nil && !fi.IsDir() { return dir, name } } @@ -626,14 +722,6 @@ func findAltConfig(dir string) (root, name string) { } func findModulePath(dir string) (string, error) { - if CmdModModule != "" { - // Running go mod init x/y/z; return x/y/z. - if err := module.CheckImportPath(CmdModModule); err != nil { - return "", err - } - return CmdModModule, nil - } - // TODO(bcmills): once we have located a plausible module path, we should // query version control (if available) to verify that it matches the major // version of the most recent tag. @@ -642,9 +730,9 @@ func findModulePath(dir string) (string, error) { // Cast about for import comments, // first in top-level directory, then in subdirectories. - list, _ := ioutil.ReadDir(dir) + list, _ := os.ReadDir(dir) for _, info := range list { - if info.Mode().IsRegular() && strings.HasSuffix(info.Name(), ".go") { + if info.Type().IsRegular() && strings.HasSuffix(info.Name(), ".go") { if com := findImportComment(filepath.Join(dir, info.Name())); com != "" { return com, nil } @@ -652,9 +740,9 @@ func findModulePath(dir string) (string, error) { } for _, info1 := range list { if info1.IsDir() { - files, _ := ioutil.ReadDir(filepath.Join(dir, info1.Name())) + files, _ := os.ReadDir(filepath.Join(dir, info1.Name())) for _, info2 := range files { - if info2.Mode().IsRegular() && strings.HasSuffix(info2.Name(), ".go") { + if info2.Type().IsRegular() && strings.HasSuffix(info2.Name(), ".go") { if com := findImportComment(filepath.Join(dir, info1.Name(), info2.Name())); com != "" { return path.Dir(com), nil } @@ -664,7 +752,7 @@ func findModulePath(dir string) (string, error) { } // Look for Godeps.json declaring import path. - data, _ := ioutil.ReadFile(filepath.Join(dir, "Godeps/Godeps.json")) + data, _ := os.ReadFile(filepath.Join(dir, "Godeps/Godeps.json")) var cfg1 struct{ ImportPath string } json.Unmarshal(data, &cfg1) if cfg1.ImportPath != "" { @@ -672,7 +760,7 @@ func findModulePath(dir string) (string, error) { } // Look for vendor.json declaring import path. - data, _ = ioutil.ReadFile(filepath.Join(dir, "vendor/vendor.json")) + data, _ = os.ReadFile(filepath.Join(dir, "vendor/vendor.json")) var cfg2 struct{ RootPath string } json.Unmarshal(data, &cfg2) if cfg2.RootPath != "" { @@ -680,16 +768,35 @@ func findModulePath(dir string) (string, error) { } // Look for path in GOPATH. + var badPathErr error for _, gpdir := range filepath.SplitList(cfg.BuildContext.GOPATH) { if gpdir == "" { continue } if rel := search.InDir(dir, filepath.Join(gpdir, "src")); rel != "" && rel != "." { - return filepath.ToSlash(rel), nil + path := filepath.ToSlash(rel) + // TODO(matloob): replace this with module.CheckImportPath + // once it's been laxened. + // Only checkModulePathLax here. There are some unpublishable + // module names that are compatible with checkModulePathLax + // but they already work in GOPATH so don't break users + // trying to do a build with modules. gorelease will alert users + // publishing their modules to fix their paths. + if err := checkModulePathLax(path); err != nil { + badPathErr = err + break + } + return path, nil } } - msg := `cannot determine module path for source directory %s (outside GOPATH, module path must be specified) + reason := "outside GOPATH, module path must be specified" + if badPathErr != nil { + // return a different error message if the module was in GOPATH, but + // the module path determined above would be an invalid path. + reason = fmt.Sprintf("bad module path inferred from directory in GOPATH: %v", badPathErr) + } + msg := `cannot determine module path for source directory %s (%s) Example usage: 'go mod init example.com/m' to initialize a v0 or v1 module @@ -697,7 +804,7 @@ Example usage: Run 'go help mod init' for more information. ` - return "", fmt.Errorf(msg, dir) + return "", fmt.Errorf(msg, dir, reason) } var ( @@ -705,7 +812,7 @@ var ( ) func findImportComment(file string) string { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil { return "" } @@ -745,7 +852,7 @@ func MinReqs() mvs.Reqs { retain = append(retain, m.Path) } } - min, err := mvs.Req(Target, retain, Reqs()) + min, err := mvs.Req(Target, retain, &mvsReqs{buildList: buildList}) if err != nil { base.Fatalf("go: %v", err) } @@ -791,20 +898,23 @@ func WriteGoMod() { 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 - if cfg.BuildModReason != "" { + if cfg.BuildModExplicit { + base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly") + } else 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") + base.Fatalf("go: updates to go.mod needed; try 'go mod tidy' first") } } - // 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 && 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. + // Don't write go.mod, but write go.sum in case we added or trimmed sums. + // 'go mod init' shouldn't write go.sum, since it will be incomplete. + if cfg.CmdName != "mod init" { + modfetch.WriteGoSum(keepSums(true)) + } return } @@ -815,6 +925,12 @@ func WriteGoMod() { defer func() { // At this point we have determined to make the go.mod file on disk equal to new. index = indexModFile(new, modFile, false) + + // Update go.sum after releasing the side lock and refreshing the index. + // 'go mod init' shouldn't write go.sum, since it will be incomplete. + if cfg.CmdName != "mod init" { + modfetch.WriteGoSum(keepSums(true)) + } }() // Make a best-effort attempt to acquire the side lock, only to exclude @@ -849,3 +965,102 @@ func WriteGoMod() { base.Fatalf("go: updating go.mod: %v", err) } } + +// keepSums returns a set of module sums to preserve in go.sum. The set +// includes entries for all modules used to load packages (according to +// the last load function such as LoadPackages or ImportFromFiles). +// It also contains entries for go.mod files needed for MVS (the version +// of these entries ends with "/go.mod"). +// +// If addDirect is true, the set also includes sums for modules directly +// required by go.mod, as represented by the index, with replacements applied. +func keepSums(addDirect bool) map[module.Version]bool { + // Re-derive the build list using the current list of direct requirements. + // Keep the sum for the go.mod of each visited module version (or its + // replacement). + modkey := func(m module.Version) module.Version { + return module.Version{Path: m.Path, Version: m.Version + "/go.mod"} + } + keep := make(map[module.Version]bool) + var mu sync.Mutex + reqs := &keepSumReqs{ + Reqs: &mvsReqs{buildList: buildList}, + visit: func(m module.Version) { + // If we build using a replacement module, keep the sum for the replacement, + // since that's the code we'll actually use during a build. + mu.Lock() + r := Replacement(m) + if r.Path == "" { + keep[modkey(m)] = true + } else { + keep[modkey(r)] = true + } + mu.Unlock() + }, + } + buildList, err := mvs.BuildList(Target, reqs) + if err != nil { + panic(fmt.Sprintf("unexpected error reloading build list: %v", err)) + } + + // Add entries for modules in the build list with paths that are prefixes of + // paths of loaded packages. We need to retain sums for modules needed to + // report ambiguous import errors. We use our re-derived build list, + // since the global build list may have been tidied. + if loaded != nil { + actualMods := make(map[string]module.Version) + for _, m := range buildList[1:] { + if r := Replacement(m); r.Path != "" { + actualMods[m.Path] = r + } else { + actualMods[m.Path] = m + } + } + for _, pkg := range loaded.pkgs { + if pkg.testOf != nil || pkg.inStd || module.CheckImportPath(pkg.path) != nil { + continue + } + for prefix := pkg.path; prefix != "."; prefix = path.Dir(prefix) { + if m, ok := actualMods[prefix]; ok { + keep[m] = true + } + } + } + } + + // Add entries for modules directly required by go.mod. + if addDirect { + for m := range index.require { + var kept module.Version + if r := Replacement(m); r.Path != "" { + kept = r + } else { + kept = m + } + keep[kept] = true + keep[module.Version{Path: kept.Path, Version: kept.Version + "/go.mod"}] = true + } + } + + return keep +} + +// keepSumReqs embeds another Reqs implementation. The Required method +// calls visit for each version in the module graph. +type keepSumReqs struct { + mvs.Reqs + visit func(module.Version) +} + +func (r *keepSumReqs) Required(m module.Version) ([]module.Version, error) { + r.visit(m) + return r.Reqs.Required(m) +} + +func TrimGoSum() { + // Don't retain sums for direct requirements in go.mod. When TrimGoSum is + // called, go.mod has not been updated, and it may contain requirements on + // modules deleted from the build list. + addDirect := false + modfetch.TrimGoSum(keepSums(addDirect)) +} diff --git a/libgo/go/cmd/go/internal/modload/list.go b/libgo/go/cmd/go/internal/modload/list.go index 9400793bcb2..3491f941cd3 100644 --- a/libgo/go/cmd/go/internal/modload/list.go +++ b/libgo/go/cmd/go/internal/modload/list.go @@ -5,47 +5,62 @@ package modload import ( + "context" "errors" "fmt" "os" + "runtime" "strings" "cmd/go/internal/base" "cmd/go/internal/cfg" "cmd/go/internal/modinfo" - "cmd/go/internal/par" "cmd/go/internal/search" "golang.org/x/mod/module" ) -func ListModules(args []string, listU, listVersions bool) []*modinfo.ModulePublic { - mods := listModules(args, listVersions) - if listU || listVersions { - var work par.Work +func ListModules(ctx context.Context, args []string, listU, listVersions, listRetracted bool) []*modinfo.ModulePublic { + mods := listModules(ctx, args, listVersions, listRetracted) + + type token struct{} + sem := make(chan token, runtime.GOMAXPROCS(0)) + if listU || listVersions || listRetracted { for _, m := range mods { - work.Add(m) + add := func(m *modinfo.ModulePublic) { + sem <- token{} + go func() { + if listU { + addUpdate(ctx, m) + } + if listVersions { + addVersions(ctx, m, listRetracted) + } + if listRetracted || listU { + addRetraction(ctx, m) + } + <-sem + }() + } + + add(m) if m.Replace != nil { - work.Add(m.Replace) + add(m.Replace) } } - work.Do(10, func(item interface{}) { - m := item.(*modinfo.ModulePublic) - if listU { - addUpdate(m) - } - if listVersions { - addVersions(m) - } - }) } + // Fill semaphore channel to wait for all tasks to finish. + for n := cap(sem); n > 0; n-- { + sem <- token{} + } + return mods } -func listModules(args []string, listVersions bool) []*modinfo.ModulePublic { - LoadBuildList() +func listModules(ctx context.Context, args []string, listVersions, listRetracted bool) []*modinfo.ModulePublic { + LoadAllModules(ctx) if len(args) == 0 { - return []*modinfo.ModulePublic{moduleInfo(buildList[0], true)} + return []*modinfo.ModulePublic{moduleInfo(ctx, buildList[0], true, listRetracted)} } var mods []*modinfo.ModulePublic @@ -71,7 +86,13 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic { } } - info, err := Query(path, vers, current, nil) + allowed := CheckAllowed + if IsRevisionQuery(vers) || listRetracted { + // Allow excluded and retracted versions if the user asked for a + // specific revision or used 'go list -retracted'. + allowed = nil + } + info, err := Query(ctx, path, vers, current, allowed) if err != nil { mods = append(mods, &modinfo.ModulePublic{ Path: path, @@ -80,7 +101,8 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic { }) continue } - mods = append(mods, moduleInfo(module.Version{Path: path, Version: info.Version}, false)) + mod := moduleInfo(ctx, module.Version{Path: path, Version: info.Version}, false, listRetracted) + mods = append(mods, mod) continue } @@ -105,7 +127,7 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic { matched = true if !matchedBuildList[i] { matchedBuildList[i] = true - mods = append(mods, moduleInfo(m, true)) + mods = append(mods, moduleInfo(ctx, m, true, listRetracted)) } } } @@ -115,9 +137,10 @@ func listModules(args []string, listVersions bool) []*modinfo.ModulePublic { // Don't make the user provide an explicit '@latest' when they're // explicitly asking what the available versions are. // Instead, resolve the module, even if it isn't an existing dependency. - info, err := Query(arg, "latest", "", nil) + info, err := Query(ctx, arg, "latest", "", nil) if err == nil { - mods = append(mods, moduleInfo(module.Version{Path: arg, Version: info.Version}, false)) + mod := moduleInfo(ctx, module.Version{Path: arg, Version: info.Version}, false, listRetracted) + mods = append(mods, mod) } else { mods = append(mods, &modinfo.ModulePublic{ Path: arg, diff --git a/libgo/go/cmd/go/internal/modload/load.go b/libgo/go/cmd/go/internal/modload/load.go index f5f74baf24e..90e990d46c8 100644 --- a/libgo/go/cmd/go/internal/modload/load.go +++ b/libgo/go/cmd/go/internal/modload/load.go @@ -4,63 +4,196 @@ package modload +// This file contains the module-mode package loader, as well as some accessory +// functions pertaining to the package import graph. +// +// There are two exported entry points into package loading — LoadPackages and +// ImportFromFiles — both implemented in terms of loadFromRoots, which itself +// manipulates an instance of the loader struct. +// +// Although most of the loading state is maintained in the loader struct, +// one key piece - the build list - is a global, so that it can be modified +// separate from the loading operation, such as during "go get" +// upgrades/downgrades or in "go mod" operations. +// TODO(#40775): It might be nice to make the loader take and return +// a buildList rather than hard-coding use of the global. +// +// Loading is an iterative process. On each iteration, we try to load the +// requested packages and their transitive imports, then try to resolve modules +// for any imported packages that are still missing. +// +// The first step of each iteration identifies a set of “root” packages. +// Normally the root packages are exactly those matching the named pattern +// arguments. However, for the "all" meta-pattern, the final set of packages is +// computed from the package import graph, and therefore cannot be an initial +// input to loading that graph. Instead, the root packages for the "all" pattern +// are those contained in the main module, and allPatternIsRoot parameter to the +// loader instructs it to dynamically expand those roots to the full "all" +// pattern as loading progresses. +// +// The pkgInAll flag on each loadPkg instance tracks whether that +// package is known to match the "all" meta-pattern. +// A package matches the "all" pattern if: +// - it is in the main module, or +// - it is imported by any test in the main module, or +// - it is imported by another package in "all", or +// - the main module specifies a go version ≤ 1.15, and the package is imported +// by a *test of* another package in "all". +// +// When we implement lazy loading, we will record the modules providing packages +// in "all" even when we are only loading individual packages, so we set the +// pkgInAll flag regardless of the whether the "all" pattern is a root. +// (This is necessary to maintain the “import invariant” described in +// https://golang.org/design/36460-lazy-module-loading.) +// +// Because "go mod vendor" prunes out the tests of vendored packages, the +// behavior of the "all" pattern with -mod=vendor in Go 1.11–1.15 is the same +// as the "all" pattern (regardless of the -mod flag) in 1.16+. +// The allClosesOverTests parameter to the loader indicates whether the "all" +// pattern should close over tests (as in Go 1.11–1.15) or stop at only those +// packages transitively imported by the packages and tests in the main module +// ("all" in Go 1.16+ and "go mod vendor" in Go 1.11+). +// +// Note that it is possible for a loaded package NOT to be in "all" even when we +// are loading the "all" pattern. For example, packages that are transitive +// dependencies of other roots named on the command line must be loaded, but are +// not in "all". (The mod_notall test illustrates this behavior.) +// Similarly, if the LoadTests flag is set but the "all" pattern does not close +// over test dependencies, then when we load the test of a package that is in +// "all" but outside the main module, the dependencies of that test will not +// necessarily themselves be in "all". (That configuration does not arise in Go +// 1.11–1.15, but it will be possible in Go 1.16+.) +// +// Loading proceeds from the roots, using a parallel work-queue with a limit on +// the amount of active work (to avoid saturating disks, CPU cores, and/or +// network connections). Each package is added to the queue the first time it is +// imported by another package. When we have finished identifying the imports of +// a package, we add the test for that package if it is needed. A test may be +// needed if: +// - the package matches a root pattern and tests of the roots were requested, or +// - the package is in the main module and the "all" pattern is requested +// (because the "all" pattern includes the dependencies of tests in the main +// module), or +// - the package is in "all" and the definition of "all" we are using includes +// dependencies of tests (as is the case in Go ≤1.15). +// +// After all available packages have been loaded, we examine the results to +// identify any requested or imported packages that are still missing, and if +// so, which modules we could add to the module graph in order to make the +// missing packages available. We add those to the module graph and iterate, +// until either all packages resolve successfully or we cannot identify any +// module that would resolve any remaining missing package. +// +// If the main module is “tidy” (that is, if "go mod tidy" is a no-op for it) +// and all requested packages are in "all", then loading completes in a single +// iteration. +// TODO(bcmills): We should also be able to load in a single iteration if the +// requested packages all come from modules that are themselves tidy, regardless +// of whether those packages are in "all". Today, that requires two iterations +// if those packages are not found in existing dependencies of the main module. + import ( "bytes" - "cmd/go/internal/base" - "cmd/go/internal/cfg" - "cmd/go/internal/imports" - "cmd/go/internal/modfetch" - "cmd/go/internal/mvs" - "cmd/go/internal/par" - "cmd/go/internal/search" - "cmd/go/internal/str" + "context" "errors" "fmt" "go/build" + "io/fs" "os" "path" pathpkg "path" "path/filepath" + "reflect" + "runtime" "sort" "strings" + "sync" + "sync/atomic" + + "cmd/go/internal/base" + "cmd/go/internal/cfg" + "cmd/go/internal/fsys" + "cmd/go/internal/imports" + "cmd/go/internal/modfetch" + "cmd/go/internal/mvs" + "cmd/go/internal/par" + "cmd/go/internal/search" + "cmd/go/internal/str" "golang.org/x/mod/module" ) -// buildList is the list of modules to use for building packages. -// It is initialized by calling ImportPaths, ImportFromFiles, -// LoadALL, or LoadBuildList, each of which uses loaded.load. -// -// Ideally, exactly ONE of those functions would be called, -// and exactly once. Most of the time, that's true. -// During "go get" it may not be. TODO(rsc): Figure out if -// that restriction can be established, or else document why not. -// -var buildList []module.Version - // loaded is the most recently-used package loader. // It holds details about individual packages. -// -// Note that loaded.buildList is only valid during a load operation; -// afterward, it is copied back into the global buildList, -// which should be used instead. var loaded *loader -// ImportPaths returns the set of packages matching the args (patterns), -// on the target platform. Modules may be added to the build list -// to satisfy new imports. -func ImportPaths(patterns []string) []*search.Match { - matches := ImportPathsQuiet(patterns, imports.Tags()) - search.WarnUnmatched(matches) - return matches +// PackageOpts control the behavior of the LoadPackages function. +type PackageOpts struct { + // Tags are the build tags in effect (as interpreted by the + // cmd/go/internal/imports package). + // If nil, treated as equivalent to imports.Tags(). + Tags map[string]bool + + // ResolveMissingImports indicates that we should attempt to add module + // dependencies as needed to resolve imports of packages that are not found. + // + // For commands that support the -mod flag, resolving imports may still fail + // if the flag is set to "readonly" (the default) or "vendor". + ResolveMissingImports bool + + // AllowPackage, if non-nil, is called after identifying the module providing + // each package. If AllowPackage returns a non-nil error, that error is set + // for the package, and the imports and test of that package will not be + // loaded. + // + // AllowPackage may be invoked concurrently by multiple goroutines, + // and may be invoked multiple times for a given package path. + AllowPackage func(ctx context.Context, path string, mod module.Version) error + + // LoadTests loads the test dependencies of each package matching a requested + // pattern. If ResolveMissingImports is also true, test dependencies will be + // resolved if missing. + LoadTests bool + + // UseVendorAll causes the "all" package pattern to be interpreted as if + // running "go mod vendor" (or building with "-mod=vendor"). + // + // This is a no-op for modules that declare 'go 1.16' or higher, for which this + // is the default (and only) interpretation of the "all" pattern in module mode. + UseVendorAll bool + + // AllowErrors indicates that LoadPackages should not terminate the process if + // an error occurs. + AllowErrors bool + + // SilenceErrors indicates that LoadPackages should not print errors + // that occur while loading packages. SilenceErrors implies AllowErrors. + SilenceErrors bool + + // SilenceUnmatchedWarnings suppresses the warnings normally emitted for + // patterns that did not match any packages. + SilenceUnmatchedWarnings bool } -// ImportPathsQuiet is like ImportPaths but does not warn about patterns with -// no matches. It also lets the caller specify a set of build tags to match -// packages. The build tags should typically be imports.Tags() or -// imports.AnyTags(); a nil map has no special meaning. -func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { - updateMatches := func(matches []*search.Match, iterating bool) { +// LoadPackages identifies the set of packages matching the given patterns and +// loads the packages in the import graph rooted at that set. +func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (matches []*search.Match, loadedPackages []string) { + LoadModFile(ctx) + if opts.Tags == nil { + opts.Tags = imports.Tags() + } + + patterns = search.CleanPatterns(patterns) + matches = make([]*search.Match, 0, len(patterns)) + allPatternIsRoot := false + for _, pattern := range patterns { + matches = append(matches, search.NewMatch(pattern)) + if pattern == "all" { + allPatternIsRoot = true + } + } + + updateMatches := func(ld *loader) { for _, m := range matches { switch { case m.IsLocal(): @@ -87,7 +220,7 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { // indicates that. ModRoot() - if !iterating { + if ld != nil { m.AddError(err) } continue @@ -100,19 +233,18 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { case strings.Contains(m.Pattern(), "..."): m.Errs = m.Errs[:0] - matchPackages(m, loaded.tags, includeStd, buildList) + matchPackages(ctx, m, opts.Tags, includeStd, buildList) case m.Pattern() == "all": - loaded.testAll = true - if iterating { - // Enumerate the packages in the main module. - // We'll load the dependencies as we find them. + if ld == nil { + // The initial roots are the packages in the main module. + // loadFromRoots will expand that to "all". m.Errs = m.Errs[:0] - matchPackages(m, loaded.tags, omitStd, []module.Version{Target}) + matchPackages(ctx, m, opts.Tags, omitStd, []module.Version{Target}) } else { // Starting with the packages in the main module, // enumerate the full list of "all". - m.Pkgs = loaded.computePatternAll(m.Pkgs) + m.Pkgs = ld.computePatternAll() } case m.Pattern() == "std" || m.Pattern() == "cmd": @@ -126,49 +258,71 @@ func ImportPathsQuiet(patterns []string, tags map[string]bool) []*search.Match { } } - InitMod() + loaded = loadFromRoots(loaderParams{ + PackageOpts: opts, - var matches []*search.Match - for _, pattern := range search.CleanPatterns(patterns) { - matches = append(matches, search.NewMatch(pattern)) - } + allClosesOverTests: index.allPatternClosesOverTests() && !opts.UseVendorAll, + allPatternIsRoot: allPatternIsRoot, - loaded = newLoader(tags) - loaded.load(func() []string { - var roots []string - updateMatches(matches, true) - for _, m := range matches { - roots = append(roots, m.Pkgs...) - } - return roots + listRoots: func() (roots []string) { + updateMatches(nil) + for _, m := range matches { + roots = append(roots, m.Pkgs...) + } + return roots + }, }) // One last pass to finalize wildcards. - updateMatches(matches, false) - checkMultiplePaths() - WriteGoMod() + updateMatches(loaded) - return matches -} + // Report errors, if any. + checkMultiplePaths() + for _, pkg := range loaded.pkgs { + if pkg.err != nil { + if pkg.flags.has(pkgInAll) { + if imErr := (*ImportMissingError)(nil); errors.As(pkg.err, &imErr) { + imErr.inAll = true + } else if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) { + sumErr.inAll = true + } + } -// 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 - if rep := Replacement(mod); rep.Path != "" { - src = rep + if !opts.SilenceErrors { + if opts.AllowErrors { + fmt.Fprintf(os.Stderr, "%s: %v\n", pkg.stackText(), pkg.err) + } else { + base.Errorf("%s: %v", pkg.stackText(), pkg.err) + } + } } - if prev, ok := firstPath[src]; !ok { - firstPath[src] = mod.Path - } else if prev != mod.Path { - base.Errorf("go: %s@%s used for two different module paths (%s and %s)", src.Path, src.Version, prev, mod.Path) + if !pkg.isTest() { + loadedPackages = append(loadedPackages, pkg.path) + } + } + if !opts.SilenceErrors { + // Also list errors in matching patterns (such as directory permission + // errors for wildcard patterns). + for _, match := range matches { + for _, err := range match.Errs { + if opts.AllowErrors { + fmt.Fprintf(os.Stderr, "%v\n", err) + } else { + base.Errorf("%v", err) + } + } } } base.ExitIfErrors() + + if !opts.SilenceUnmatchedWarnings { + search.WarnUnmatched(matches) + } + + // Success! Update go.mod (if needed) and return the results. + WriteGoMod() + sort.Strings(loadedPackages) + return matches, loadedPackages } // matchLocalDirs is like m.MatchDirs, but tries to avoid scanning directories @@ -217,11 +371,11 @@ func resolveLocalPackage(dir string) (string, error) { // If the named directory does not exist or contains no Go files, // the package does not exist. // Other errors may affect package loading, but not resolution. - if _, err := os.Stat(absDir); err != nil { + if _, err := fsys.Stat(absDir); err != nil { if os.IsNotExist(err) { // Canonicalize OS-specific errors to errDirectoryNotFound so that error // messages will be easier for users to search for. - return "", &os.PathError{Op: "stat", Path: absDir, Err: errDirectoryNotFound} + return "", &fs.PathError{Op: "stat", Path: absDir, Err: errDirectoryNotFound} } return "", err } @@ -307,7 +461,7 @@ var ( // pathInModuleCache returns the import path of the directory dir, // if dir is in the module cache copy of a module in our build list. func pathInModuleCache(dir string) string { - for _, m := range buildList[1:] { + tryMod := func(m module.Version) (string, bool) { var root string var err error if repl := Replacement(m); repl.Path != "" && repl.Version == "" { @@ -321,13 +475,26 @@ func pathInModuleCache(dir string) string { root, err = modfetch.DownloadDir(m) } if err != nil { - continue + return "", false } - if sub := search.InDir(dir, root); sub != "" { - sub = filepath.ToSlash(sub) - if !strings.Contains(sub, "/vendor/") && !strings.HasPrefix(sub, "vendor/") && !strings.Contains(sub, "@") { - return path.Join(m.Path, filepath.ToSlash(sub)) - } + + sub := search.InDir(dir, root) + if sub == "" { + return "", false + } + sub = filepath.ToSlash(sub) + if strings.Contains(sub, "/vendor/") || strings.HasPrefix(sub, "vendor/") || strings.Contains(sub, "@") { + return "", false + } + + return path.Join(m.Path, filepath.ToSlash(sub)), true + } + + for _, m := range buildList[1:] { + if importPath, ok := tryMod(m); ok { + // checkMultiplePaths ensures that a module can be used for at most one + // requirement, so this must be it. + return importPath } } return "" @@ -335,8 +502,8 @@ func pathInModuleCache(dir string) string { // ImportFromFiles adds modules to the build list as needed // to satisfy the imports in the named Go source files. -func ImportFromFiles(gofiles []string) { - InitMod() +func ImportFromFiles(ctx context.Context, gofiles []string) { + LoadModFile(ctx) tags := imports.Tags() imports, testImports, err := imports.ScanFiles(gofiles, tags) @@ -344,12 +511,17 @@ func ImportFromFiles(gofiles []string) { base.Fatalf("go: %v", err) } - loaded = newLoader(tags) - loaded.load(func() []string { - var roots []string - roots = append(roots, imports...) - roots = append(roots, testImports...) - return roots + loaded = loadFromRoots(loaderParams{ + PackageOpts: PackageOpts{ + Tags: tags, + ResolveMissingImports: true, + }, + allClosesOverTests: index.allPatternClosesOverTests(), + listRoots: func() (roots []string) { + roots = append(roots, imports...) + roots = append(roots, testImports...) + return roots + }, }) WriteGoMod() } @@ -357,9 +529,10 @@ func ImportFromFiles(gofiles []string) { // DirImportPath returns the effective import path for dir, // provided it is within the main module, or else returns ".". func DirImportPath(dir string) string { - if modRoot == "" { + if !HasModRoot() { return "." } + LoadModFile(context.TODO()) if !filepath.IsAbs(dir) { dir = filepath.Join(base.Cwd, dir) @@ -380,130 +553,20 @@ func DirImportPath(dir string) string { return "." } -// LoadBuildList loads and returns the build list from go.mod. -// The loading of the build list happens automatically in ImportPaths: -// LoadBuildList need only be called if ImportPaths is not -// (typically in commands that care about the module but -// no particular package). -func LoadBuildList() []module.Version { - InitMod() - ReloadBuildList() - WriteGoMod() - return buildList -} - -func ReloadBuildList() []module.Version { - loaded = newLoader(imports.Tags()) - loaded.load(func() []string { return nil }) - return buildList -} - -// LoadALL returns the set of all packages in the current module -// and their dependencies in any other modules, without filtering -// due to build tags, except "+build ignore". -// It adds modules to the build list as needed to satisfy new imports. -// This set is useful for deciding whether a particular import is needed -// anywhere in a module. -func LoadALL() []string { - return loadAll(true) -} - -// LoadVendor is like LoadALL but only follows test dependencies -// for tests in the main module. Tests in dependency modules are -// ignored completely. -// This set is useful for identifying the which packages to include in a vendor directory. -func LoadVendor() []string { - return loadAll(false) -} - -func loadAll(testAll bool) []string { - InitMod() - - loaded = newLoader(imports.AnyTags()) - loaded.isALL = true - loaded.testAll = testAll - if !testAll { - loaded.testRoots = true - } - all := TargetPackages("...") - loaded.load(func() []string { return all.Pkgs }) - checkMultiplePaths() - WriteGoMod() - - var paths []string - for _, pkg := range loaded.pkgs { - if pkg.err != nil { - base.Errorf("%s: %v", pkg.stackText(), pkg.err) - continue - } - paths = append(paths, pkg.path) - } - for _, err := range all.Errs { - base.Errorf("%v", err) - } - base.ExitIfErrors() - return paths -} - // TargetPackages returns the list of packages in the target (top-level) module // matching pattern, which may be relative to the working directory, under all // build tag settings. -func TargetPackages(pattern string) *search.Match { +func TargetPackages(ctx context.Context, pattern string) *search.Match { // TargetPackages is relative to the main module, so ensure that the main // module is a thing that can contain packages. + LoadModFile(ctx) ModRoot() m := search.NewMatch(pattern) - matchPackages(m, imports.AnyTags(), omitStd, []module.Version{Target}) + matchPackages(ctx, m, imports.AnyTags(), omitStd, []module.Version{Target}) return m } -// BuildList returns the module build list, -// typically constructed by a previous call to -// LoadBuildList or ImportPaths. -// The caller must not modify the returned list. -func BuildList() []module.Version { - return buildList -} - -// SetBuildList sets the module build list. -// The caller is responsible for ensuring that the list is valid. -// SetBuildList does not retain a reference to the original list. -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 @@ -558,12 +621,6 @@ func PackageImports(path string) (imports, testImports []string) { return imports, testImports } -// ModuleUsedDirectly reports whether the main module directly imports -// some package in the module with the given path. -func ModuleUsedDirectly(path string) bool { - return loaded.direct[path] -} - // Lookup returns the source directory, import path, and any loading error for // the package at path as imported from the package in parentDir. // Lookup requires that one of the Load functions in this package has already @@ -599,129 +656,193 @@ func Lookup(parentPath string, parentIsStd bool, path string) (dir, realPath str // the required packages for a particular build, // checking that the packages are available in the module set, // and updating the module set if needed. -// Loading is an iterative process: try to load all the needed packages, -// but if imports are missing, try to resolve those imports, and repeat. -// -// Although most of the loading state is maintained in the loader struct, -// one key piece - the build list - is a global, so that it can be modified -// separate from the loading operation, such as during "go get" -// upgrades/downgrades or in "go mod" operations. -// TODO(rsc): It might be nice to make the loader take and return -// a buildList rather than hard-coding use of the global. type loader struct { - tags map[string]bool // tags for scanDir - testRoots bool // include tests for roots - isALL bool // created with LoadALL - testAll bool // include tests for all packages - forceStdVendor bool // if true, load standard-library dependencies from the vendor subtree + loaderParams + + work *par.Queue // reset on each iteration roots []*loadPkg - pkgs []*loadPkg - work *par.Work // current work queue - pkgCache *par.Cache // map from string to *loadPkg + pkgCache *par.Cache // package path (string) → *loadPkg + pkgs []*loadPkg // transitive closure of loaded packages and tests; populated in buildStacks // computed at end of iterations - direct map[string]bool // imported directly by main module - goVersion map[string]string // go version recorded in each module + direct map[string]bool // imported directly by main module } -// LoadTests controls whether the loaders load tests of the root packages. -var LoadTests bool - -func newLoader(tags map[string]bool) *loader { - ld := new(loader) - ld.tags = tags - ld.testRoots = LoadTests +// loaderParams configure the packages loaded by, and the properties reported +// by, a loader instance. +type loaderParams struct { + PackageOpts - // Inside the "std" and "cmd" modules, we prefer to use the vendor directory - // unless the command explicitly changes the module graph. - if !targetInGorootSrc || (cfg.CmdName != "get" && !strings.HasPrefix(cfg.CmdName, "mod ")) { - ld.forceStdVendor = true - } + allClosesOverTests bool // Does the "all" pattern include the transitive closure of tests of packages in "all"? + allPatternIsRoot bool // Is the "all" pattern an additional root? - return ld + listRoots func() []string } func (ld *loader) reset() { + select { + case <-ld.work.Idle(): + default: + panic("loader.reset when not idle") + } + ld.roots = nil - ld.pkgs = nil - ld.work = new(par.Work) ld.pkgCache = new(par.Cache) + ld.pkgs = nil } // A loadPkg records information about a single loaded package. type loadPkg struct { - path string // import path + // Populated at construction time: + path string // import path + testOf *loadPkg + + // Populated at construction time and updated by (*loader).applyPkgFlags: + flags atomicLoadPkgFlags + + // Populated by (*loader).load: mod module.Version // module providing package dir string // directory containing source code - imports []*loadPkg // packages imported by this one err error // error loading package - stack *loadPkg // package importing this one in minimal import stack for this pkg - test *loadPkg // package with test imports, if we need test - testOf *loadPkg - testImports []string // test-only imports, saved for use by pkg.test. + imports []*loadPkg // packages imported by this one + testImports []string // test-only imports, saved for use by pkg.test. + inStd bool + + // Populated by (*loader).pkgTest: + testOnce sync.Once + test *loadPkg + + // Populated by postprocessing in (*loader).buildStacks: + stack *loadPkg // package importing this one in minimal import stack for this pkg +} + +// loadPkgFlags is a set of flags tracking metadata about a package. +type loadPkgFlags int8 + +const ( + // pkgInAll indicates that the package is in the "all" package pattern, + // regardless of whether we are loading the "all" package pattern. + // + // When the pkgInAll flag and pkgImportsLoaded flags are both set, the caller + // who set the last of those flags must propagate the pkgInAll marking to all + // of the imports of the marked package. + // + // A test is marked with pkgInAll if that test would promote the packages it + // imports to be in "all" (such as when the test is itself within the main + // module, or when ld.allClosesOverTests is true). + pkgInAll loadPkgFlags = 1 << iota + + // pkgIsRoot indicates that the package matches one of the root package + // patterns requested by the caller. + // + // If LoadTests is set, then when pkgIsRoot and pkgImportsLoaded are both set, + // the caller who set the last of those flags must populate a test for the + // package (in the pkg.test field). + // + // If the "all" pattern is included as a root, then non-test packages in "all" + // are also roots (and must be marked pkgIsRoot). + pkgIsRoot + + // pkgImportsLoaded indicates that the imports and testImports fields of a + // loadPkg have been populated. + pkgImportsLoaded +) + +// has reports whether all of the flags in cond are set in f. +func (f loadPkgFlags) has(cond loadPkgFlags) bool { + return f&cond == cond +} + +// An atomicLoadPkgFlags stores a loadPkgFlags for which individual flags can be +// added atomically. +type atomicLoadPkgFlags struct { + bits int32 +} + +// update sets the given flags in af (in addition to any flags already set). +// +// update returns the previous flag state so that the caller may determine which +// flags were newly-set. +func (af *atomicLoadPkgFlags) update(flags loadPkgFlags) (old loadPkgFlags) { + for { + old := atomic.LoadInt32(&af.bits) + new := old | int32(flags) + if new == old || atomic.CompareAndSwapInt32(&af.bits, old, new) { + return loadPkgFlags(old) + } + } +} + +// has reports whether all of the flags in cond are set in af. +func (af *atomicLoadPkgFlags) has(cond loadPkgFlags) bool { + return loadPkgFlags(atomic.LoadInt32(&af.bits))&cond == cond +} + +// isTest reports whether pkg is a test of another package. +func (pkg *loadPkg) isTest() bool { + return pkg.testOf != nil } var errMissing = errors.New("cannot find package") -// load attempts to load the build graph needed to process a set of root packages. -// The set of root packages is defined by the addRoots function, -// which must call add(path) with the import path of each root package. -func (ld *loader) load(roots func() []string) { +// loadFromRoots attempts to load the build graph needed to process a set of +// root packages and their dependencies. +// +// The set of root packages is returned by the params.listRoots function, and +// expanded to the full set of packages by tracing imports (and possibly tests) +// as needed. +func loadFromRoots(params loaderParams) *loader { + ld := &loader{ + loaderParams: params, + work: par.NewQueue(runtime.GOMAXPROCS(0)), + } + var err error - reqs := Reqs() + reqs := &mvsReqs{buildList: buildList} buildList, err = mvs.BuildList(Target, reqs) if err != nil { base.Fatalf("go: %v", err) } - added := make(map[string]bool) + addedModuleFor := make(map[string]bool) for { ld.reset() - if roots != nil { - // Note: the returned roots can change on each iteration, - // since the expansion of package patterns depends on the - // build list we're using. - for _, path := range roots() { - ld.work.Add(ld.pkg(path, true)) + + // Load the root packages and their imports. + // Note: the returned roots can change on each iteration, + // since the expansion of package patterns depends on the + // build list we're using. + inRoots := map[*loadPkg]bool{} + for _, path := range ld.listRoots() { + root := ld.pkg(path, pkgIsRoot) + if !inRoots[root] { + ld.roots = append(ld.roots, root) + inRoots[root] = true } } - ld.work.Do(10, ld.doPkg) + + // ld.pkg adds imported packages to the work queue and calls applyPkgFlags, + // which adds tests (and test dependencies) as needed. + // + // When all of the work in the queue has completed, we'll know that the + // transitive closure of dependencies has been loaded. + <-ld.work.Idle() + ld.buildStacks() - numAdded := 0 - haveMod := make(map[module.Version]bool) - for _, m := range buildList { - haveMod[m] = true - } - modAddedBy := make(map[module.Version]*loadPkg) - for _, pkg := range ld.pkgs { - if err, ok := pkg.err.(*ImportMissingError); ok && err.Module.Path != "" { - if err.newMissingVersion != "" { - base.Fatalf("go: %s: package provided by %s at latest version %s but not at required version %s", pkg.stackText(), err.Module.Path, err.Module.Version, err.newMissingVersion) - } - fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, err.Module.Path, err.Module.Version) - if added[pkg.path] { - base.Fatalf("go: %s: looping trying to add package", pkg.stackText()) - } - added[pkg.path] = true - numAdded++ - if !haveMod[err.Module] { - haveMod[err.Module] = true - modAddedBy[err.Module] = pkg - buildList = append(buildList, err.Module) - } - continue - } - // Leave other errors for Import or load.Packages to report. + + if !ld.ResolveMissingImports || (!HasModRoot() && !allowMissingModuleImports) { + // We've loaded as much as we can without resolving missing imports. + break } - base.ExitIfErrors() - if numAdded == 0 { + modAddedBy := ld.resolveMissingImports(addedModuleFor) + if len(modAddedBy) == 0 { break } // Recompute buildList with all our additions. - reqs = Reqs() + reqs = &mvsReqs{buildList: buildList} buildList, err = mvs.BuildList(Target, reqs) if err != nil { // If an error was found in a newly added module, report the package @@ -749,102 +870,287 @@ func (ld *loader) load(roots func() []string) { } } - // Add Go versions, computed during walk. - ld.goVersion = make(map[string]string) - for _, m := range buildList { - v, _ := reqs.(*mvsReqs).versions.Load(m) - ld.goVersion[m.Path], _ = v.(string) - } - - // Mix in direct markings (really, lack of indirect markings) - // from go.mod, unless we scanned the whole module - // and can therefore be sure we know better than go.mod. - if !ld.isALL && modFile != nil { + // If we didn't scan all of the imports from the main module, or didn't use + // imports.AnyTags, then we didn't necessarily load every package that + // contributes “direct” imports — so we can't safely mark existing + // dependencies as indirect-only. + // Conservatively mark those dependencies as direct. + if modFile != nil && (!ld.allPatternIsRoot || !reflect.DeepEqual(ld.Tags, imports.AnyTags())) { for _, r := range modFile.Require { if !r.Indirect { ld.direct[r.Mod.Path] = true } } } + + return ld } -// pkg returns the *loadPkg for path, creating and queuing it if needed. -// If the package should be tested, its test is created but not queued -// (the test is queued after processing pkg). -// If isRoot is true, the pkg is being queued as one of the roots of the work graph. -func (ld *loader) pkg(path string, isRoot bool) *loadPkg { - return ld.pkgCache.Do(path, func() interface{} { - pkg := &loadPkg{ - path: path, +// resolveMissingImports adds module dependencies to the global build list +// in order to resolve missing packages from pkgs. +// +// The newly-resolved packages are added to the addedModuleFor map, and +// resolveMissingImports returns a map from each newly-added module version to +// the first package for which that module was added. +func (ld *loader) resolveMissingImports(addedModuleFor map[string]bool) (modAddedBy map[module.Version]*loadPkg) { + var needPkgs []*loadPkg + for _, pkg := range ld.pkgs { + if pkg.err == nil { + continue } - if ld.testRoots && isRoot || ld.testAll { - test := &loadPkg{ - path: path, - testOf: pkg, - } - pkg.test = test + if pkg.isTest() { + // If we are missing a test, we are also missing its non-test version, and + // we should only add the missing import once. + continue + } + if !errors.As(pkg.err, new(*ImportMissingError)) { + // Leave other errors for Import or load.Packages to report. + continue + } + + needPkgs = append(needPkgs, pkg) + + pkg := pkg + ld.work.Add(func() { + pkg.mod, pkg.err = queryImport(context.TODO(), pkg.path) + }) + } + <-ld.work.Idle() + + modAddedBy = map[module.Version]*loadPkg{} + for _, pkg := range needPkgs { + if pkg.err != nil { + continue + } + + fmt.Fprintf(os.Stderr, "go: found %s in %s %s\n", pkg.path, pkg.mod.Path, pkg.mod.Version) + if addedModuleFor[pkg.path] { + // TODO(bcmills): This should only be an error if pkg.mod is the same + // version we already tried to add previously. + base.Fatalf("go: %s: looping trying to add package", pkg.stackText()) } - if isRoot { - ld.roots = append(ld.roots, pkg) + if modAddedBy[pkg.mod] == nil { + modAddedBy[pkg.mod] = pkg + buildList = append(buildList, pkg.mod) } - ld.work.Add(pkg) + } + + return modAddedBy +} + +// pkg locates the *loadPkg for path, creating and queuing it for loading if +// needed, and updates its state to reflect the given flags. +// +// The imports of the returned *loadPkg will be loaded asynchronously in the +// ld.work queue, and its test (if requested) will also be populated once +// imports have been resolved. When ld.work goes idle, all transitive imports of +// the requested package (and its test, if requested) will have been loaded. +func (ld *loader) pkg(path string, flags loadPkgFlags) *loadPkg { + if flags.has(pkgImportsLoaded) { + panic("internal error: (*loader).pkg called with pkgImportsLoaded flag set") + } + + pkg := ld.pkgCache.Do(path, func() interface{} { + pkg := &loadPkg{ + path: path, + } + ld.applyPkgFlags(pkg, flags) + + ld.work.Add(func() { ld.load(pkg) }) return pkg }).(*loadPkg) + + ld.applyPkgFlags(pkg, flags) + return pkg } -// doPkg processes a package on the work queue. -func (ld *loader) doPkg(item interface{}) { - // TODO: what about replacements? - pkg := item.(*loadPkg) - var imports []string - if pkg.testOf != nil { - pkg.dir = pkg.testOf.dir - pkg.mod = pkg.testOf.mod - imports = pkg.testOf.testImports - } else { - if strings.Contains(pkg.path, "@") { - // Leave for error during load. - return +// applyPkgFlags updates pkg.flags to set the given flags and propagate the +// (transitive) effects of those flags, possibly loading or enqueueing further +// packages as a result. +func (ld *loader) applyPkgFlags(pkg *loadPkg, flags loadPkgFlags) { + if flags == 0 { + return + } + + if flags.has(pkgInAll) && ld.allPatternIsRoot && !pkg.isTest() { + // This package matches a root pattern by virtue of being in "all". + flags |= pkgIsRoot + } + + old := pkg.flags.update(flags) + new := old | flags + if new == old || !new.has(pkgImportsLoaded) { + // We either didn't change the state of pkg, or we don't know anything about + // its dependencies yet. Either way, we can't usefully load its test or + // update its dependencies. + return + } + + if !pkg.isTest() { + // Check whether we should add (or update the flags for) a test for pkg. + // ld.pkgTest is idempotent and extra invocations are inexpensive, + // so it's ok if we call it more than is strictly necessary. + wantTest := false + switch { + case ld.allPatternIsRoot && pkg.mod == Target: + // We are loading the "all" pattern, which includes packages imported by + // tests in the main module. This package is in the main module, so we + // need to identify the imports of its test even if LoadTests is not set. + // + // (We will filter out the extra tests explicitly in computePatternAll.) + wantTest = true + + case ld.allPatternIsRoot && ld.allClosesOverTests && new.has(pkgInAll): + // This variant of the "all" pattern includes imports of tests of every + // package that is itself in "all", and pkg is in "all", so its test is + // also in "all" (as above). + wantTest = true + + case ld.LoadTests && new.has(pkgIsRoot): + // LoadTest explicitly requests tests of “the root packages”. + wantTest = true } - if build.IsLocalImport(pkg.path) || filepath.IsAbs(pkg.path) { - // Leave for error during load. - // (Module mode does not allow local imports.) - return + + if wantTest { + var testFlags loadPkgFlags + if pkg.mod == Target || (ld.allClosesOverTests && new.has(pkgInAll)) { + // Tests of packages in the main module are in "all", in the sense that + // they cause the packages they import to also be in "all". So are tests + // of packages in "all" if "all" closes over test dependencies. + testFlags |= pkgInAll + } + ld.pkgTest(pkg, testFlags) } + } - pkg.mod, pkg.dir, pkg.err = Import(pkg.path) - if pkg.dir == "" { - return + if new.has(pkgInAll) && !old.has(pkgInAll|pkgImportsLoaded) { + // We have just marked pkg with pkgInAll, or we have just loaded its + // imports, or both. Now is the time to propagate pkgInAll to the imports. + for _, dep := range pkg.imports { + ld.applyPkgFlags(dep, pkgInAll) } - if cfg.BuildContext.Compiler == "gccgo" && pkg.mod.Path == "" { - return + } +} + +// load loads an individual package. +func (ld *loader) load(pkg *loadPkg) { + if strings.Contains(pkg.path, "@") { + // Leave for error during load. + return + } + if build.IsLocalImport(pkg.path) || filepath.IsAbs(pkg.path) { + // Leave for error during load. + // (Module mode does not allow local imports.) + return + } + + if search.IsMetaPackage(pkg.path) { + pkg.err = &invalidImportError{ + importPath: pkg.path, + err: fmt.Errorf("%q is not an importable package; see 'go help packages'", pkg.path), + } + return + } + + pkg.mod, pkg.dir, pkg.err = importFromBuildList(context.TODO(), pkg.path, buildList) + if pkg.dir == "" { + return + } + if pkg.mod == Target { + // Go ahead and mark pkg as in "all". This provides the invariant that a + // package that is *only* imported by other packages in "all" is always + // marked as such before loading its imports. + // + // We don't actually rely on that invariant at the moment, but it may + // improve efficiency somewhat and makes the behavior a bit easier to reason + // about (by reducing churn on the flag bits of dependencies), and costs + // essentially nothing (these atomic flag ops are essentially free compared + // to scanning source code for imports). + ld.applyPkgFlags(pkg, pkgInAll) + } + if ld.AllowPackage != nil { + if err := ld.AllowPackage(context.TODO(), pkg.path, pkg.mod); err != nil { + pkg.err = err } + } - var testImports []string + pkg.inStd = (search.IsStandardImportPath(pkg.path) && search.InDir(pkg.dir, cfg.GOROOTsrc) != "") + + var imports, testImports []string + + if cfg.BuildContext.Compiler == "gccgo" && pkg.inStd { + // We can't scan standard packages for gccgo. + } else { var err error - imports, testImports, err = scanDir(pkg.dir, ld.tags) + imports, testImports, err = scanDir(pkg.dir, ld.Tags) if err != nil { pkg.err = err return } - if pkg.test != nil { - pkg.testImports = testImports - } } - inStd := (search.IsStandardImportPath(pkg.path) && search.InDir(pkg.dir, cfg.GOROOTsrc) != "") + pkg.imports = make([]*loadPkg, 0, len(imports)) + var importFlags loadPkgFlags + if pkg.flags.has(pkgInAll) { + importFlags = pkgInAll + } for _, path := range imports { - if inStd { + if pkg.inStd { + // Imports from packages in "std" and "cmd" should resolve using + // GOROOT/src/vendor even when "std" is not the main module. path = ld.stdVendor(pkg.path, path) } - pkg.imports = append(pkg.imports, ld.pkg(path, false)) + pkg.imports = append(pkg.imports, ld.pkg(path, importFlags)) } + pkg.testImports = testImports - // Now that pkg.dir, pkg.mod, pkg.testImports are set, we can queue pkg.test. - // TODO: All that's left is creating new imports. Why not just do it now? - if pkg.test != nil { - ld.work.Add(pkg.test) + ld.applyPkgFlags(pkg, pkgImportsLoaded) +} + +// pkgTest locates the test of pkg, creating it if needed, and updates its state +// to reflect the given flags. +// +// pkgTest requires that the imports of pkg have already been loaded (flagged +// with pkgImportsLoaded). +func (ld *loader) pkgTest(pkg *loadPkg, testFlags loadPkgFlags) *loadPkg { + if pkg.isTest() { + panic("pkgTest called on a test package") } + + createdTest := false + pkg.testOnce.Do(func() { + pkg.test = &loadPkg{ + path: pkg.path, + testOf: pkg, + mod: pkg.mod, + dir: pkg.dir, + err: pkg.err, + inStd: pkg.inStd, + } + ld.applyPkgFlags(pkg.test, testFlags) + createdTest = true + }) + + test := pkg.test + if createdTest { + test.imports = make([]*loadPkg, 0, len(pkg.testImports)) + var importFlags loadPkgFlags + if test.flags.has(pkgInAll) { + importFlags = pkgInAll + } + for _, path := range pkg.testImports { + if pkg.inStd { + path = ld.stdVendor(test.path, path) + } + test.imports = append(test.imports, ld.pkg(path, importFlags)) + } + pkg.testImports = nil + ld.applyPkgFlags(test, pkgImportsLoaded) + } else { + ld.applyPkgFlags(test, testFlags) + } + + return test } // stdVendor returns the canonical import path for the package with the given @@ -855,13 +1161,25 @@ func (ld *loader) stdVendor(parentPath, path string) string { } if str.HasPathPrefix(parentPath, "cmd") { - if ld.forceStdVendor || Target.Path != "cmd" { + if Target.Path != "cmd" { vendorPath := pathpkg.Join("cmd", "vendor", path) if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil { return vendorPath } } - } else if ld.forceStdVendor || Target.Path != "std" { + } else if Target.Path != "std" || str.HasPathPrefix(parentPath, "vendor") { + // If we are outside of the 'std' module, resolve imports from within 'std' + // to the vendor directory. + // + // Do the same for importers beginning with the prefix 'vendor/' even if we + // are *inside* of the 'std' module: the 'vendor/' packages that resolve + // globally from GOROOT/src/vendor (and are listed as part of 'go list std') + // are distinct from the real module dependencies, and cannot import + // internal packages from the real module. + // + // (Note that although the 'vendor/' packages match the 'std' *package* + // pattern, they are not part of the std *module*, and do not affect + // 'go mod tidy' and similar module commands when working within std.) vendorPath := pathpkg.Join("vendor", path) if _, err := os.Stat(filepath.Join(cfg.GOROOTsrc, filepath.FromSlash(vendorPath))); err == nil { return vendorPath @@ -874,30 +1192,13 @@ func (ld *loader) stdVendor(parentPath, path string) string { // computePatternAll returns the list of packages matching pattern "all", // starting with a list of the import paths for the packages in the main module. -func (ld *loader) computePatternAll(paths []string) []string { - seen := make(map[*loadPkg]bool) - var all []string - var walk func(*loadPkg) - walk = func(pkg *loadPkg) { - if seen[pkg] { - return - } - seen[pkg] = true - if pkg.testOf == nil { +func (ld *loader) computePatternAll() (all []string) { + for _, pkg := range ld.pkgs { + if pkg.flags.has(pkgInAll) && !pkg.isTest() { all = append(all, pkg.path) } - for _, p := range pkg.imports { - walk(p) - } - if p := pkg.test; p != nil { - walk(p) - } - } - for _, path := range paths { - walk(ld.pkg(path, false)) } sort.Strings(all) - return all } @@ -1019,7 +1320,7 @@ func (pkg *loadPkg) why() string { // Why returns the "go mod why" output stanza for the given package, // without the leading # comment. -// The package graph must have been loaded already, usually by LoadALL. +// The package graph must have been loaded already, usually by LoadPackages. // If there is no reason for the package to be in the current build, // Why returns an empty string. func Why(path string) string { diff --git a/libgo/go/cmd/go/internal/modload/modfile.go b/libgo/go/cmd/go/internal/modload/modfile.go index 9f4ec5a49fc..eb05e9f9c91 100644 --- a/libgo/go/cmd/go/internal/modload/modfile.go +++ b/libgo/go/cmd/go/internal/modload/modfile.go @@ -5,25 +5,45 @@ package modload import ( + "context" + "errors" + "fmt" + "path/filepath" + "strings" + "sync" + "unicode" + "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/lockedfile" + "cmd/go/internal/modfetch" + "cmd/go/internal/par" + "cmd/go/internal/trace" "golang.org/x/mod/modfile" "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) +// narrowAllVersionV is the Go version (plus leading "v") at which the +// module-module "all" pattern no longer closes over the dependencies of +// tests outside of the main module. +const narrowAllVersionV = "v1.16" +const go116EnableNarrowAll = true + 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 + data []byte + dataNeedsFix bool // true if fixVersion applied a change while parsing data + module module.Version + goVersionV string // GoVersion with "v" prefix + require map[module.Version]requireMeta + replace map[module.Version]module.Version + highestReplaced map[string]string // highest replaced version of each module path; empty string for wildcard-only replacements + exclude map[module.Version]bool } // index is the index of the go.mod file as of when it was last read or written. @@ -33,9 +53,179 @@ type requireMeta struct { indirect bool } -// Allowed reports whether module m is allowed (not excluded) by the main module's go.mod. -func Allowed(m module.Version) bool { - return index == nil || !index.exclude[m] +// CheckAllowed returns an error equivalent to ErrDisallowed if m is excluded by +// the main module's go.mod or retracted by its author. Most version queries use +// this to filter out versions that should not be used. +func CheckAllowed(ctx context.Context, m module.Version) error { + if err := CheckExclusions(ctx, m); err != nil { + return err + } + if err := CheckRetractions(ctx, m); err != nil { + return err + } + return nil +} + +// ErrDisallowed is returned by version predicates passed to Query and similar +// functions to indicate that a version should not be considered. +var ErrDisallowed = errors.New("disallowed module version") + +// CheckExclusions returns an error equivalent to ErrDisallowed if module m is +// excluded by the main module's go.mod file. +func CheckExclusions(ctx context.Context, m module.Version) error { + if index != nil && index.exclude[m] { + return module.VersionError(m, errExcluded) + } + return nil +} + +var errExcluded = &excludedError{} + +type excludedError struct{} + +func (e *excludedError) Error() string { return "excluded by go.mod" } +func (e *excludedError) Is(err error) bool { return err == ErrDisallowed } + +// CheckRetractions returns an error if module m has been retracted by +// its author. +func CheckRetractions(ctx context.Context, m module.Version) error { + if m.Version == "" { + // Main module, standard library, or file replacement module. + // Cannot be retracted. + return nil + } + + // Look up retraction information from the latest available version of + // the module. Cache retraction information so we don't parse the go.mod + // file repeatedly. + type entry struct { + retract []retraction + err error + } + path := m.Path + e := retractCache.Do(path, func() (v interface{}) { + ctx, span := trace.StartSpan(ctx, "checkRetractions "+path) + defer span.Done() + + if repl := Replacement(module.Version{Path: m.Path}); repl.Path != "" { + // All versions of the module were replaced with a local directory. + // Don't load retractions. + return &entry{nil, nil} + } + + // Find the latest version of the module. + // Ignore exclusions from the main module's go.mod. + const ignoreSelected = "" + var allowAll AllowedFunc + rev, err := Query(ctx, path, "latest", ignoreSelected, allowAll) + if err != nil { + return &entry{nil, err} + } + + // Load go.mod for that version. + // If the version is replaced, we'll load retractions from the replacement. + // + // If there's an error loading the go.mod, we'll return it here. + // These errors should generally be ignored by callers of checkRetractions, + // since they happen frequently when we're offline. These errors are not + // equivalent to ErrDisallowed, so they may be distinguished from + // retraction errors. + // + // We load the raw file here: the go.mod file may have a different module + // path that we expect if the module or its repository was renamed. + // We still want to apply retractions to other aliases of the module. + rm := module.Version{Path: path, Version: rev.Version} + if repl := Replacement(rm); repl.Path != "" { + rm = repl + } + summary, err := rawGoModSummary(rm) + if err != nil { + return &entry{nil, err} + } + return &entry{summary.retract, nil} + }).(*entry) + + if err := e.err; err != nil { + // Attribute the error to the version being checked, not the version from + // which the retractions were to be loaded. + var mErr *module.ModuleError + if errors.As(err, &mErr) { + err = mErr.Err + } + return &retractionLoadingError{m: m, err: err} + } + + var rationale []string + isRetracted := false + for _, r := range e.retract { + if semver.Compare(r.Low, m.Version) <= 0 && semver.Compare(m.Version, r.High) <= 0 { + isRetracted = true + if r.Rationale != "" { + rationale = append(rationale, r.Rationale) + } + } + } + if isRetracted { + return module.VersionError(m, &ModuleRetractedError{Rationale: rationale}) + } + return nil +} + +var retractCache par.Cache + +type ModuleRetractedError struct { + Rationale []string +} + +func (e *ModuleRetractedError) Error() string { + msg := "retracted by module author" + if len(e.Rationale) > 0 { + // This is meant to be a short error printed on a terminal, so just + // print the first rationale. + msg += ": " + ShortRetractionRationale(e.Rationale[0]) + } + return msg +} + +func (e *ModuleRetractedError) Is(err error) bool { + return err == ErrDisallowed +} + +type retractionLoadingError struct { + m module.Version + err error +} + +func (e *retractionLoadingError) Error() string { + return fmt.Sprintf("loading module retractions for %v: %v", e.m, e.err) +} + +func (e *retractionLoadingError) Unwrap() error { + return e.err +} + +// ShortRetractionRationale returns a retraction rationale string that is safe +// to print in a terminal. It returns hard-coded strings if the rationale +// is empty, too long, or contains non-printable characters. +func ShortRetractionRationale(rationale string) string { + const maxRationaleBytes = 500 + if i := strings.Index(rationale, "\n"); i >= 0 { + rationale = rationale[:i] + } + rationale = strings.TrimSpace(rationale) + if rationale == "" { + return "retracted by module author" + } + if len(rationale) > maxRationaleBytes { + return "(rationale omitted: too long)" + } + for _, r := range rationale { + if !unicode.IsGraphic(r) && !unicode.IsSpace(r) { + return "(rationale omitted: contains non-printable characters)" + } + } + // NOTE: the go.mod parser rejects invalid UTF-8, so we don't check that here. + return rationale } // Replacement returns the replacement for mod, if any, from go.mod. @@ -66,9 +256,11 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd i.module = modFile.Module.Mod } - i.goVersion = "" + i.goVersionV = "" if modFile.Go != nil { - i.goVersion = modFile.Go.Version + // We're going to use the semver package to compare Go versions, so go ahead + // and add the "v" prefix it expects once instead of every time. + i.goVersionV = "v" + modFile.Go.Version } i.require = make(map[module.Version]requireMeta, len(modFile.Require)) @@ -84,6 +276,14 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd i.replace[r.Old] = r.New } + i.highestReplaced = make(map[string]string) + for _, r := range modFile.Replace { + v, ok := i.highestReplaced[r.Old.Path] + if !ok || semver.Compare(r.Old.Version, v) > 0 { + i.highestReplaced[r.Old.Path] = r.Old.Version + } + } + i.exclude = make(map[module.Version]bool, len(modFile.Exclude)) for _, x := range modFile.Exclude { i.exclude[x.Mod] = true @@ -92,6 +292,23 @@ func indexModFile(data []byte, modFile *modfile.File, needsFix bool) *modFileInd return i } +// allPatternClosesOverTests reports whether the "all" pattern includes +// dependencies of tests outside the main module (as in Go 1.11–1.15). +// (Otherwise — as in Go 1.16+ — the "all" pattern includes only the packages +// transitively *imported by* the packages and tests in the main module.) +func (i *modFileIndex) allPatternClosesOverTests() bool { + if !go116EnableNarrowAll { + return true + } + if i != nil && semver.Compare(i.goVersionV, narrowAllVersionV) < 0 { + // The module explicitly predates the change in "all" for lazy loading, so + // continue to use the older interpretation. (If i == nil, we not in any + // module at all and should use the latest semantics.) + return true + } + return false +} + // 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, @@ -114,11 +331,11 @@ func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool { } if modFile.Go == nil { - if i.goVersion != "" { + if i.goVersionV != "" { return true } - } else if modFile.Go.Version != i.goVersion { - if i.goVersion == "" && cfg.BuildMod == "readonly" { + } else if "v"+modFile.Go.Version != i.goVersionV { + if i.goVersionV == "" && 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. @@ -162,3 +379,213 @@ func (i *modFileIndex) modFileIsDirty(modFile *modfile.File) bool { return false } + +// rawGoVersion records the Go version parsed from each module's go.mod file. +// +// If a module is replaced, the version of the replacement is keyed by the +// replacement module.Version, not the version being replaced. +var rawGoVersion sync.Map // map[module.Version]string + +// A modFileSummary is a summary of a go.mod file for which we do not need to +// retain complete information — for example, the go.mod file of a dependency +// module. +type modFileSummary struct { + module module.Version + goVersionV string // GoVersion with "v" prefix + require []module.Version + retract []retraction +} + +// A retraction consists of a retracted version interval and rationale. +// retraction is like modfile.Retract, but it doesn't point to the syntax tree. +type retraction struct { + modfile.VersionInterval + Rationale string +} + +// goModSummary returns a summary of the go.mod file for module m, +// taking into account any replacements for m, exclusions of its dependencies, +// and/or vendoring. +// +// m must be a version in the module graph, reachable from the Target module. +// In readonly mode, the go.sum file must contain an entry for m's go.mod file +// (or its replacement). goModSummary must not be called for the Target module +// itself, as its requirements may change. Use rawGoModSummary for other +// module versions. +// +// The caller must not modify the returned summary. +func goModSummary(m module.Version) (*modFileSummary, error) { + if m == Target { + panic("internal error: goModSummary called on the Target module") + } + + if cfg.BuildMod == "vendor" { + summary := &modFileSummary{ + module: module.Version{Path: m.Path}, + } + if vendorVersion[m.Path] != m.Version { + // This module is not vendored, so packages cannot be loaded from it and + // it cannot be relevant to the build. + return summary, nil + } + + // For every module other than the target, + // return the full list of modules from modules.txt. + readVendorList() + + // TODO(#36876): Load the "go" version from vendor/modules.txt and store it + // in rawGoVersion with the appropriate key. + + // We don't know what versions the vendored module actually relies on, + // so assume that it requires everything. + summary.require = vendorList + return summary, nil + } + + actual := Replacement(m) + if actual.Path == "" { + actual = m + } + if cfg.BuildMod == "readonly" && actual.Version != "" { + key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"} + if !modfetch.HaveSum(key) { + suggestion := fmt.Sprintf("; try 'go mod download %s' to add it", m.Path) + return nil, module.VersionError(actual, &sumMissingError{suggestion: suggestion}) + } + } + summary, err := rawGoModSummary(actual) + if err != nil { + return nil, err + } + + if actual.Version == "" { + // The actual module is a filesystem-local replacement, for which we have + // unfortunately not enforced any sort of invariants about module lines or + // matching module paths. Anything goes. + // + // TODO(bcmills): Remove this special-case, update tests, and add a + // release note. + } else { + if summary.module.Path == "" { + return nil, module.VersionError(actual, errors.New("parsing go.mod: missing module line")) + } + + // In theory we should only allow mpath to be unequal to m.Path here if the + // version that we fetched lacks an explicit go.mod file: if the go.mod file + // is explicit, then it should match exactly (to ensure that imports of other + // packages within the module are interpreted correctly). Unfortunately, we + // can't determine that information from the module proxy protocol: we'll have + // to leave that validation for when we load actual packages from within the + // module. + if mpath := summary.module.Path; mpath != m.Path && mpath != actual.Path { + return nil, module.VersionError(actual, fmt.Errorf(`parsing go.mod: + module declares its path as: %s + but was required as: %s`, mpath, m.Path)) + } + } + + if index != nil && len(index.exclude) > 0 { + // Drop any requirements on excluded versions. + // Don't modify the cached summary though, since we might need the raw + // summary separately. + haveExcludedReqs := false + for _, r := range summary.require { + if index.exclude[r] { + haveExcludedReqs = true + break + } + } + if haveExcludedReqs { + s := new(modFileSummary) + *s = *summary + s.require = make([]module.Version, 0, len(summary.require)) + for _, r := range summary.require { + if !index.exclude[r] { + s.require = append(s.require, r) + } + } + summary = s + } + } + return summary, nil +} + +// rawGoModSummary returns a new summary of the go.mod file for module m, +// ignoring all replacements that may apply to m and excludes that may apply to +// its dependencies. +// +// rawGoModSummary cannot be used on the Target module. +func rawGoModSummary(m module.Version) (*modFileSummary, error) { + if m == Target { + panic("internal error: rawGoModSummary called on the Target module") + } + + type cached struct { + summary *modFileSummary + err error + } + c := rawGoModSummaryCache.Do(m, func() interface{} { + summary := new(modFileSummary) + var f *modfile.File + if m.Version == "" { + // m is a replacement module with only a file path. + dir := m.Path + if !filepath.IsAbs(dir) { + dir = filepath.Join(ModRoot(), dir) + } + gomod := filepath.Join(dir, "go.mod") + + data, err := lockedfile.Read(gomod) + if err != nil { + return cached{nil, module.VersionError(m, fmt.Errorf("reading %s: %v", base.ShortPath(gomod), err))} + } + f, err = modfile.ParseLax(gomod, data, nil) + if err != nil { + return cached{nil, module.VersionError(m, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err))} + } + } else { + if !semver.IsValid(m.Version) { + // Disallow the broader queries supported by fetch.Lookup. + base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version) + } + + data, err := modfetch.GoMod(m.Path, m.Version) + if err != nil { + return cached{nil, err} + } + f, err = modfile.ParseLax("go.mod", data, nil) + if err != nil { + return cached{nil, module.VersionError(m, fmt.Errorf("parsing go.mod: %v", err))} + } + } + + if f.Module != nil { + summary.module = f.Module.Mod + } + if f.Go != nil && f.Go.Version != "" { + rawGoVersion.LoadOrStore(m, f.Go.Version) + summary.goVersionV = "v" + f.Go.Version + } + if len(f.Require) > 0 { + summary.require = make([]module.Version, 0, len(f.Require)) + for _, req := range f.Require { + summary.require = append(summary.require, req.Mod) + } + } + if len(f.Retract) > 0 { + summary.retract = make([]retraction, 0, len(f.Retract)) + for _, ret := range f.Retract { + summary.retract = append(summary.retract, retraction{ + VersionInterval: ret.VersionInterval, + Rationale: ret.Rationale, + }) + } + } + + return cached{summary, nil} + }).(cached) + + return c.summary, c.err +} + +var rawGoModSummaryCache par.Cache // module.Version → rawGoModSummary result diff --git a/libgo/go/cmd/go/internal/modload/mvs.go b/libgo/go/cmd/go/internal/modload/mvs.go index 5dd009d31df..167d6819b06 100644 --- a/libgo/go/cmd/go/internal/modload/mvs.go +++ b/libgo/go/cmd/go/internal/modload/mvs.go @@ -5,21 +5,13 @@ package modload import ( + "context" "errors" - "fmt" "os" - "path/filepath" "sort" - "sync" - "cmd/go/internal/base" - "cmd/go/internal/cfg" - "cmd/go/internal/lockedfile" "cmd/go/internal/modfetch" - "cmd/go/internal/mvs" - "cmd/go/internal/par" - "golang.org/x/mod/modfile" "golang.org/x/mod/module" "golang.org/x/mod/semver" ) @@ -28,133 +20,24 @@ import ( // with any exclusions or replacements applied internally. type mvsReqs struct { buildList []module.Version - cache par.Cache - versions sync.Map -} - -// Reqs returns the current module requirement graph. -// Future calls to SetBuildList do not affect the operation -// of the returned Reqs. -func Reqs() mvs.Reqs { - r := &mvsReqs{ - buildList: buildList, - } - return r } func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) { - type cached struct { - list []module.Version - err error - } - - c := r.cache.Do(mod, func() interface{} { - list, err := r.required(mod) - if err != nil { - return cached{nil, err} - } - for i, mv := range list { - 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 - } - } - list[i] = mv - } - - return cached{list, nil} - }).(cached) - - return c.list, c.err -} - -func (r *mvsReqs) modFileToList(f *modfile.File) []module.Version { - list := make([]module.Version, 0, len(f.Require)) - for _, r := range f.Require { - list = append(list, r.Mod) - } - return list -} - -// required returns a unique copy of the requirements of mod. -func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) { if mod == Target { - if modFile != nil && modFile.Go != nil { - r.versions.LoadOrStore(mod, modFile.Go.Version) - } - return append([]module.Version(nil), r.buildList[1:]...), nil - } - - if cfg.BuildMod == "vendor" { - // For every module other than the target, - // return the full list of modules from modules.txt. - readVendorList() - return append([]module.Version(nil), vendorList...), nil - } - - origPath := mod.Path - if repl := Replacement(mod); repl.Path != "" { - if repl.Version == "" { - // TODO: need to slip the new version into the tags list etc. - dir := repl.Path - if !filepath.IsAbs(dir) { - dir = filepath.Join(ModRoot(), dir) - } - gomod := filepath.Join(dir, "go.mod") - data, err := lockedfile.Read(gomod) - if err != nil { - return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err) - } - f, err := modfile.ParseLax(gomod, data, nil) - if err != nil { - return nil, fmt.Errorf("parsing %s: %v", base.ShortPath(gomod), err) - } - if f.Go != nil { - r.versions.LoadOrStore(mod, f.Go.Version) - } - return r.modFileToList(f), nil - } - mod = repl + // Use the build list as it existed when r was constructed, not the current + // global build list. + return r.buildList[1:], nil } if mod.Version == "none" { return nil, nil } - if !semver.IsValid(mod.Version) { - // Disallow the broader queries supported by fetch.Lookup. - base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", mod.Path, mod.Version) - } - - data, err := modfetch.GoMod(mod.Path, mod.Version) + summary, err := goModSummary(mod) if err != nil { return nil, err } - f, err := modfile.ParseLax("go.mod", data, nil) - if err != nil { - return nil, module.VersionError(mod, fmt.Errorf("parsing go.mod: %v", err)) - } - - if f.Module == nil { - return nil, module.VersionError(mod, errors.New("parsing go.mod: missing module line")) - } - if mpath := f.Module.Mod.Path; mpath != origPath && mpath != mod.Path { - return nil, module.VersionError(mod, fmt.Errorf(`parsing go.mod: - module declares its path as: %s - but was required as: %s`, mpath, origPath)) - } - if f.Go != nil { - r.versions.LoadOrStore(mod, f.Go.Version) - } - - return r.modFileToList(f), nil + return summary.require, nil } // Max returns the maximum of v1 and v2 according to semver.Compare. @@ -164,7 +47,7 @@ func (r *mvsReqs) required(mod module.Version) ([]module.Version, error) { // be chosen over other versions of the same module in the module dependency // graph. func (*mvsReqs) Max(v1, v2 string) string { - if v1 != "" && semver.Compare(v1, v2) == -1 { + if v1 != "" && (v2 == "" || semver.Compare(v1, v2) == -1) { return v2 } return v1 @@ -176,25 +59,50 @@ func (*mvsReqs) Upgrade(m module.Version) (module.Version, error) { return m, nil } -func versions(path string) ([]string, error) { +func versions(ctx context.Context, path string, allowed AllowedFunc) ([]string, error) { // Note: modfetch.Lookup and repo.Versions are cached, // so there's no need for us to add extra caching here. var versions []string err := modfetch.TryProxies(func(proxy string) error { - repo, err := modfetch.Lookup(proxy, path) - if err == nil { - versions, err = repo.Versions("") + repo, err := lookupRepo(proxy, path) + if err != nil { + return err + } + allVersions, err := repo.Versions("") + if err != nil { + return err } - return err + allowedVersions := make([]string, 0, len(allVersions)) + for _, v := range allVersions { + if err := allowed(ctx, module.Version{Path: path, Version: v}); err == nil { + allowedVersions = append(allowedVersions, v) + } else if !errors.Is(err, ErrDisallowed) { + return err + } + } + versions = allowedVersions + return nil }) return versions, err } // Previous returns the tagged version of m.Path immediately prior to // m.Version, or version "none" if no prior version is tagged. +// +// Since the version of Target is not found in the version list, +// it has no previous version. func (*mvsReqs) Previous(m module.Version) (module.Version, error) { - list, err := versions(m.Path) + // TODO(golang.org/issue/38714): thread tracing context through MVS. + + if m == Target { + return module.Version{Path: m.Path, Version: "none"}, nil + } + + list, err := versions(context.TODO(), m.Path, CheckAllowed) if err != nil { + if errors.Is(err, os.ErrNotExist) { + return module.Version{Path: m.Path, Version: "none"}, nil + } return module.Version{}, err } i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) >= 0 }) @@ -208,7 +116,8 @@ func (*mvsReqs) Previous(m module.Version) (module.Version, error) { // It is only used by the exclusion processing in the Required method, // not called directly by MVS. func (*mvsReqs) next(m module.Version) (module.Version, error) { - list, err := versions(m.Path) + // TODO(golang.org/issue/38714): thread tracing context through MVS. + list, err := versions(context.TODO(), m.Path, CheckAllowed) if err != nil { return module.Version{}, err } @@ -218,42 +127,3 @@ 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 - } - if r := Replacement(mod); r.Path != "" { - if r.Version == "" { - dir = r.Path - if !filepath.IsAbs(dir) { - dir = filepath.Join(ModRoot(), dir) - } - // Ensure that the replacement directory actually exists: - // dirInModule does not report errors for missing modules, - // so if we don't report the error now, later failures will be - // very mysterious. - if _, err := os.Stat(dir); err != nil { - if os.IsNotExist(err) { - // Semantically the module version itself “exists” — we just don't - // have its source code. Remove the equivalence to os.ErrNotExist, - // and make the message more concise while we're at it. - err = fmt.Errorf("replacement directory %s does not exist", r.Path) - } else { - err = fmt.Errorf("replacement directory %s: %w", r.Path, err) - } - return dir, true, module.VersionError(mod, err) - } - return dir, true, nil - } - mod = r - } - - dir, err = modfetch.Download(mod) - return dir, false, err -} diff --git a/libgo/go/cmd/go/internal/modload/mvs_test.go b/libgo/go/cmd/go/internal/modload/mvs_test.go new file mode 100644 index 00000000000..50e93c381fd --- /dev/null +++ b/libgo/go/cmd/go/internal/modload/mvs_test.go @@ -0,0 +1,31 @@ +// Copyright 2020 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 modload + +import ( + "testing" +) + +func TestReqsMax(t *testing.T) { + type testCase struct { + a, b, want string + } + reqs := new(mvsReqs) + for _, tc := range []testCase{ + {a: "v0.1.0", b: "v0.2.0", want: "v0.2.0"}, + {a: "v0.2.0", b: "v0.1.0", want: "v0.2.0"}, + {a: "", b: "v0.1.0", want: ""}, // "" is Target.Version + {a: "v0.1.0", b: "", want: ""}, + {a: "none", b: "v0.1.0", want: "v0.1.0"}, + {a: "v0.1.0", b: "none", want: "v0.1.0"}, + {a: "none", b: "", want: ""}, + {a: "", b: "none", want: ""}, + } { + max := reqs.Max(tc.a, tc.b) + if max != tc.want { + t.Errorf("(%T).Max(%q, %q) = %q; want %q", reqs, tc.a, tc.b, max, tc.want) + } + } +} diff --git a/libgo/go/cmd/go/internal/modload/query.go b/libgo/go/cmd/go/internal/modload/query.go index acc886bf213..e35e0fc16e2 100644 --- a/libgo/go/cmd/go/internal/modload/query.go +++ b/libgo/go/cmd/go/internal/modload/query.go @@ -5,19 +5,23 @@ package modload import ( + "context" "errors" "fmt" + "io/fs" "os" pathpkg "path" "path/filepath" + "sort" "strings" "sync" + "time" "cmd/go/internal/cfg" "cmd/go/internal/imports" "cmd/go/internal/modfetch" "cmd/go/internal/search" - "cmd/go/internal/str" + "cmd/go/internal/trace" "golang.org/x/mod/module" "golang.org/x/mod/semver" @@ -43,27 +47,43 @@ import ( // with non-prereleases preferred over prereleases. // - a repository commit identifier or tag, denoting that commit. // -// current denotes the current version of the module; it may be "" if the -// current version is unknown or should not be considered. If query is +// current denotes the currently-selected version of the module; it may be +// "none" if no version is currently selected, or "" if the currently-selected +// version is unknown or should not be considered. If query is // "upgrade" or "patch", current will be returned if it is a newer // semantic version or a chronologically later pseudo-version than the // version that would otherwise be chosen. This prevents accidental downgrades // from newer pre-release or development versions. // -// If the allowed function is non-nil, Query excludes any versions for which -// allowed returns false. +// The allowed function (which may be nil) is used to filter out unsuitable +// versions (see AllowedFunc documentation for details). If the query refers to +// a specific revision (for example, "master"; see IsRevisionQuery), and the +// revision is disallowed by allowed, Query returns the error. If the query +// does not refer to a specific revision (for example, "latest"), Query +// acts as if versions disallowed by allowed do not exist. // // If path is the path of the main module and the query is "latest", // Query returns Target.Version as the version. -func Query(path, query, current string, allowed func(module.Version) bool) (*modfetch.RevInfo, error) { +func Query(ctx context.Context, path, query, current string, allowed AllowedFunc) (*modfetch.RevInfo, error) { var info *modfetch.RevInfo err := modfetch.TryProxies(func(proxy string) (err error) { - info, err = queryProxy(proxy, path, query, current, allowed) + info, err = queryProxy(ctx, proxy, path, query, current, allowed) return err }) return info, err } +// AllowedFunc is used by Query and other functions to filter out unsuitable +// versions, for example, those listed in exclude directives in the main +// module's go.mod file. +// +// An AllowedFunc returns an error equivalent to ErrDisallowed for an unsuitable +// version. Any other error indicates the function was unable to determine +// whether the version should be allowed, for example, the function was unable +// to fetch or parse a go.mod file containing retractions. Typically, errors +// other than ErrDisallowd may be ignored. +type AllowedFunc func(context.Context, module.Version) error + var errQueryDisabled error = queryDisabledError{} type queryDisabledError struct{} @@ -75,138 +95,56 @@ func (queryDisabledError) Error() string { 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) { +func queryProxy(ctx context.Context, proxy, path, query, current string, allowed AllowedFunc) (*modfetch.RevInfo, error) { + ctx, span := trace.StartSpan(ctx, "modload.queryProxy "+path+" "+query) + defer span.Done() + + if current != "" && current != "none" && !semver.IsValid(current) { return nil, fmt.Errorf("invalid previous version %q", current) } if cfg.BuildMod == "vendor" { return nil, errQueryDisabled } if allowed == nil { - allowed = func(module.Version) bool { return true } + allowed = func(context.Context, module.Version) error { return nil } } - // Parse query to detect parse errors (and possibly handle query) - // before any network I/O. - badVersion := func(v string) (*modfetch.RevInfo, error) { - return nil, fmt.Errorf("invalid semantic version %q in range %q", v, query) - } - matchesMajor := func(v string) bool { - _, pathMajor, ok := module.SplitPathVersion(path) - if !ok { - return false + if path == Target.Path && (query == "upgrade" || query == "patch") { + if err := allowed(ctx, Target); err != nil { + return nil, fmt.Errorf("internal error: main module version is not allowed: %w", err) } - return module.CheckPathMajor(v, pathMajor) == nil + return &modfetch.RevInfo{Version: Target.Version}, 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 - mayUseLatest = true - case query == "upgrade": - ok = allowed - mayUseLatest = true - - case query == "patch": - if current == "" { - ok = allowed - mayUseLatest = true - } else { - prefix = semver.MajorMinor(current) - ok = func(m module.Version) bool { - return matchSemverPrefix(prefix, m.Version) && allowed(m) - } - } - - case strings.HasPrefix(query, "<="): - v := query[len("<="):] - if !semver.IsValid(v) { - return badVersion(v) - } - if isSemverPrefix(v) { - // Refuse to say whether <=v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3). - return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query) - } - 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("<"):] - if !semver.IsValid(v) { - return badVersion(v) - } - 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(">="):] - if !semver.IsValid(v) { - return badVersion(v) - } - ok = func(m module.Version) bool { - return semver.Compare(m.Version, v) >= 0 && allowed(m) - } - preferOlder = true - if !matchesMajor(v) { - preferIncompatible = true - } + if path == "std" || path == "cmd" { + return nil, fmt.Errorf("can't query specific version (%q) of standard-library module %q", query, path) + } - case strings.HasPrefix(query, ">"): - v := query[len(">"):] - if !semver.IsValid(v) { - return badVersion(v) - } - if isSemverPrefix(v) { - // Refuse to say whether >v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3). - return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query) - } - ok = func(m module.Version) bool { - return semver.Compare(m.Version, v) > 0 && allowed(m) - } - preferOlder = true - if !matchesMajor(v) { - preferIncompatible = true - } + repo, err := lookupRepo(proxy, path) + if err != nil { + return nil, err + } - 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 - } + // Parse query to detect parse errors (and possibly handle query) + // before any network I/O. + qm, err := newQueryMatcher(path, query, current, allowed) + if (err == nil && qm.canStat) || err == errRevQuery { + // Direct lookup of a commit identifier or complete (non-prefix) semantic + // version. - default: - // Direct lookup of semantic version or commit identifier. - // // If the identifier is not a canonical semver tag — including if it's a // semver tag with a +metadata suffix — then modfetch.Stat will populate // info.Version with a suitable pseudo-version. - info, err := modfetch.Stat(proxy, path, query) + info, err := repo.Stat(query) if err != nil { queryErr := err // The full query doesn't correspond to a tag. If it is a semantic version // with a +metadata suffix, see if there is a tag without that suffix: // semantic versioning defines them to be equivalent. - if vers := module.CanonicalVersion(query); vers != "" && vers != query { - info, err = modfetch.Stat(proxy, path, vers) - if !errors.Is(err, os.ErrNotExist) { + canonicalQuery := module.CanonicalVersion(query) + if canonicalQuery != "" && query != canonicalQuery { + info, err = repo.Stat(canonicalQuery) + if err != nil && !errors.Is(err, fs.ErrNotExist) { return info, err } } @@ -214,36 +152,20 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) return nil, queryErr } } - if !allowed(module.Version{Path: path, Version: info.Version}) { - return nil, fmt.Errorf("%s@%s excluded", path, info.Version) + if err := allowed(ctx, module.Version{Path: path, Version: info.Version}); errors.Is(err, ErrDisallowed) { + return nil, err } return info, nil - } - - if path == Target.Path { - if query != "latest" { - return nil, fmt.Errorf("can't query specific version (%q) for the main module (%s)", query, path) - } - if !allowed(Target) { - return nil, fmt.Errorf("internal error: main module version is not allowed") - } - return &modfetch.RevInfo{Version: Target.Version}, nil - } - - if str.HasPathPrefix(path, "std") || str.HasPathPrefix(path, "cmd") { - return nil, fmt.Errorf("explicit requirement on standard-library module %s not allowed", path) + } else if err != nil { + return nil, err } // Load versions and execute query. - repo, err := modfetch.Lookup(proxy, path) - if err != nil { - return nil, err - } - versions, err := repo.Versions(prefix) + versions, err := repo.Versions(qm.prefix) if err != nil { return nil, err } - releases, prereleases, err := filterVersions(path, versions, ok, preferIncompatible) + releases, prereleases, err := qm.filterVersions(ctx, versions) if err != nil { return nil, err } @@ -254,11 +176,30 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) return nil, err } - // For "upgrade" and "patch", make sure we don't accidentally downgrade - // from a newer prerelease or from a chronologically newer pseudoversion. - if current != "" && (query == "upgrade" || query == "patch") { + if (query == "upgrade" || query == "patch") && modfetch.IsPseudoVersion(current) && !rev.Time.IsZero() { + // Don't allow "upgrade" or "patch" to move from a pseudo-version + // to a chronologically older version or pseudo-version. + // + // If the current version is a pseudo-version from an untagged branch, it + // may be semantically lower than the "latest" release or the latest + // pseudo-version on the main branch. A user on such a version is unlikely + // to intend to “upgrade” to a version that already existed at that point + // in time. + // + // We do this only if the current version is a pseudo-version: if the + // version is tagged, the author of the dependency module has given us + // explicit information about their intended precedence of this version + // relative to other versions, and we shouldn't contradict that + // information. (For example, v1.0.1 might be a backport of a fix already + // incorporated into v1.1.0, in which case v1.0.1 would be chronologically + // newer but v1.1.0 is still an “upgrade”; or v1.0.2 might be a revert of + // an unsuccessful fix in v1.0.1, in which case the v1.0.2 commit may be + // older than the v1.0.1 commit despite the tag itself being newer.) currentTime, err := modfetch.PseudoVersionTime(current) - if semver.Compare(rev.Version, current) < 0 || (err == nil && rev.Time.Before(currentTime)) { + if err == nil && rev.Time.Before(currentTime) { + if err := allowed(ctx, module.Version{Path: path, Version: current}); errors.Is(err, ErrDisallowed) { + return nil, err + } return repo.Stat(current) } } @@ -266,7 +207,7 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) return rev, nil } - if preferOlder { + if qm.preferLower { if len(releases) > 0 { return lookup(releases[0]) } @@ -282,22 +223,44 @@ func queryProxy(proxy, path, query, current string, allowed func(module.Version) } } - if mayUseLatest { - // Special case for "latest": if no tags match, use latest commit in repo, - // provided it is not excluded. + if qm.mayUseLatest { latest, err := repo.Latest() if err == nil { - if allowed(module.Version{Path: path, Version: latest.Version}) { + if qm.allowsVersion(ctx, latest.Version) { return lookup(latest.Version) } - } else if !errors.Is(err, os.ErrNotExist) { + } else if !errors.Is(err, fs.ErrNotExist) { + return nil, err + } + } + + if (query == "upgrade" || query == "patch") && current != "" && current != "none" { + // "upgrade" and "patch" may stay on the current version if allowed. + if err := allowed(ctx, module.Version{Path: path, Version: current}); errors.Is(err, ErrDisallowed) { return nil, err } + return lookup(current) } return nil, &NoMatchingVersionError{query: query, current: current} } +// IsRevisionQuery returns true if vers is a version query that may refer to +// a particular version or revision in a repository like "v1.0.0", "master", +// or "0123abcd". IsRevisionQuery returns false if vers is a query that +// chooses from among available versions like "latest" or ">v1.0.0". +func IsRevisionQuery(vers string) bool { + if vers == "latest" || + vers == "upgrade" || + vers == "patch" || + strings.HasPrefix(vers, "<") || + strings.HasPrefix(vers, ">") || + (semver.IsValid(vers) && isSemverPrefix(vers)) { + return false + } + return true +} + // isSemverPrefix reports whether v is a semantic version prefix: v1 or v1.2 (not v1.2.3). // The caller is assumed to have checked that semver.IsValid(v) is true. func isSemverPrefix(v string) bool { @@ -316,25 +279,190 @@ func isSemverPrefix(v string) bool { return true } -// matchSemverPrefix reports whether the shortened semantic version p -// matches the full-width (non-shortened) semantic version v. -func matchSemverPrefix(p, v string) bool { - return len(v) > len(p) && v[len(p)] == '.' && v[:len(p)] == p && semver.Prerelease(v) == "" +type queryMatcher struct { + path string + prefix string + filter func(version string) bool + allowed AllowedFunc + canStat bool // if true, the query can be resolved by repo.Stat + preferLower bool // if true, choose the lowest matching version + mayUseLatest bool + preferIncompatible bool +} + +var errRevQuery = errors.New("query refers to a non-semver revision") + +// newQueryMatcher returns a new queryMatcher that matches the versions +// specified by the given query on the module with the given path. +// +// If the query can only be resolved by statting a non-SemVer revision, +// newQueryMatcher returns errRevQuery. +func newQueryMatcher(path string, query, current string, allowed AllowedFunc) (*queryMatcher, error) { + badVersion := func(v string) (*queryMatcher, error) { + return nil, fmt.Errorf("invalid semantic version %q in range %q", v, query) + } + + matchesMajor := func(v string) bool { + _, pathMajor, ok := module.SplitPathVersion(path) + if !ok { + return false + } + return module.CheckPathMajor(v, pathMajor) == nil + } + + qm := &queryMatcher{ + path: path, + allowed: allowed, + preferIncompatible: strings.HasSuffix(current, "+incompatible"), + } + + switch { + case query == "latest": + qm.mayUseLatest = true + + case query == "upgrade": + if current == "" || current == "none" { + qm.mayUseLatest = true + } else { + qm.mayUseLatest = modfetch.IsPseudoVersion(current) + qm.filter = func(mv string) bool { return semver.Compare(mv, current) >= 0 } + } + + case query == "patch": + if current == "none" { + return nil, &NoPatchBaseError{path} + } + if current == "" { + qm.mayUseLatest = true + } else { + qm.mayUseLatest = modfetch.IsPseudoVersion(current) + qm.prefix = semver.MajorMinor(current) + "." + qm.filter = func(mv string) bool { return semver.Compare(mv, current) >= 0 } + } + + case strings.HasPrefix(query, "<="): + v := query[len("<="):] + if !semver.IsValid(v) { + return badVersion(v) + } + if isSemverPrefix(v) { + // Refuse to say whether <=v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3). + return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query) + } + qm.filter = func(mv string) bool { return semver.Compare(mv, v) <= 0 } + if !matchesMajor(v) { + qm.preferIncompatible = true + } + + case strings.HasPrefix(query, "<"): + v := query[len("<"):] + if !semver.IsValid(v) { + return badVersion(v) + } + qm.filter = func(mv string) bool { return semver.Compare(mv, v) < 0 } + if !matchesMajor(v) { + qm.preferIncompatible = true + } + + case strings.HasPrefix(query, ">="): + v := query[len(">="):] + if !semver.IsValid(v) { + return badVersion(v) + } + qm.filter = func(mv string) bool { return semver.Compare(mv, v) >= 0 } + qm.preferLower = true + if !matchesMajor(v) { + qm.preferIncompatible = true + } + + case strings.HasPrefix(query, ">"): + v := query[len(">"):] + if !semver.IsValid(v) { + return badVersion(v) + } + if isSemverPrefix(v) { + // Refuse to say whether >v1.2 allows v1.2.3 (remember, @v1.2 might mean v1.2.3). + return nil, fmt.Errorf("ambiguous semantic version %q in range %q", v, query) + } + qm.filter = func(mv string) bool { return semver.Compare(mv, v) > 0 } + qm.preferLower = true + if !matchesMajor(v) { + qm.preferIncompatible = true + } + + case semver.IsValid(query): + if isSemverPrefix(query) { + qm.prefix = query + "." + // Do not allow the query "v1.2" to match versions lower than "v1.2.0", + // such as prereleases for that version. (https://golang.org/issue/31972) + qm.filter = func(mv string) bool { return semver.Compare(mv, query) >= 0 } + } else { + qm.canStat = true + qm.filter = func(mv string) bool { return semver.Compare(mv, query) == 0 } + qm.prefix = semver.Canonical(query) + } + if !matchesMajor(query) { + qm.preferIncompatible = true + } + + default: + return nil, errRevQuery + } + + return qm, nil +} + +// allowsVersion reports whether version v is allowed by the prefix, filter, and +// AllowedFunc of qm. +func (qm *queryMatcher) allowsVersion(ctx context.Context, v string) bool { + if qm.prefix != "" && !strings.HasPrefix(v, qm.prefix) { + return false + } + if qm.filter != nil && !qm.filter(v) { + return false + } + if qm.allowed != nil { + if err := qm.allowed(ctx, module.Version{Path: qm.path, Version: v}); errors.Is(err, ErrDisallowed) { + return false + } + } + return true } // filterVersions classifies versions into releases and pre-releases, filtering // out: -// 1. versions that do not satisfy the 'ok' predicate, and +// 1. versions that do not satisfy the 'allowed' 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) { +// +// If the allowed predicate returns an error not equivalent to ErrDisallowed, +// filterVersions returns that error. +func (qm *queryMatcher) filterVersions(ctx context.Context, versions []string) (releases, prereleases []string, err error) { + needIncompatible := qm.preferIncompatible + var lastCompatible string for _, v := range versions { - if !ok(module.Version{Path: path, Version: v}) { + if !qm.allowsVersion(ctx, v) { continue } - if !preferIncompatible { + if !needIncompatible { + // We're not yet sure whether we need to include +incomptaible versions. + // Keep track of the last compatible version we've seen, and use the + // presence (or absence) of a go.mod file in that version to decide: a + // go.mod file implies that the module author is supporting modules at a + // compatible version (and we should ignore +incompatible versions unless + // requested explicitly), while a lack of go.mod file implies the + // potential for legacy (pre-modules) versioning without semantic import + // paths (and thus *with* +incompatible versions). + // + // This isn't strictly accurate if the latest compatible version has been + // replaced by a local file path, because we do not allow file-path + // replacements without a go.mod file: the user would have needed to add + // one. However, replacing the last compatible version while + // simultaneously expecting to upgrade implicitly to a +incompatible + // version seems like an extreme enough corner case to ignore for now. + if !strings.HasSuffix(v, "+incompatible") { lastCompatible = v } else if lastCompatible != "" { @@ -342,19 +470,22 @@ func filterVersions(path string, versions []string, ok func(module.Version) bool // 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}) + ok, err := versionHasGoMod(ctx, module.Version{Path: qm.path, Version: lastCompatible}) if err != nil { return nil, nil, err } if ok { + // The last compatible version has a go.mod file, so that's the + // highest version we're willing to consider. Don't bother even + // looking at higher versions, because they're all +incompatible from + // here onward. 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 + needIncompatible = true } } @@ -374,34 +505,42 @@ type QueryResult struct { Packages []string } -// QueryPackage looks up the module(s) containing path at a revision matching -// query. The results are sorted by module path length in descending order. -// -// If the package is in the main module, QueryPackage considers only the main -// module and only the version "latest", without checking for other possible -// modules. -func QueryPackage(path, query string, allowed func(module.Version) bool) ([]QueryResult, error) { - m := search.NewMatch(path) - if m.IsLocal() || !m.IsLiteral() { - return nil, fmt.Errorf("pattern %s is not an importable package", path) +// QueryPackages is like QueryPattern, but requires that the pattern match at +// least one package and omits the non-package result (if any). +func QueryPackages(ctx context.Context, pattern, query string, current func(string) string, allowed AllowedFunc) ([]QueryResult, error) { + pkgMods, modOnly, err := QueryPattern(ctx, pattern, query, current, allowed) + + if len(pkgMods) == 0 && err == nil { + return nil, &PackageNotInModuleError{ + Mod: modOnly.Mod, + Replacement: Replacement(modOnly.Mod), + Query: query, + Pattern: pattern, + } } - return QueryPattern(path, query, allowed) + + return pkgMods, err } // QueryPattern looks up the module(s) containing at least one package matching // the given pattern at the given version. The results are sorted by module path -// length in descending order. +// length in descending order. If any proxy provides a non-empty set of candidate +// modules, no further proxies are tried. // -// QueryPattern queries modules with package paths up to the first "..." -// in the pattern. For the pattern "example.com/a/b.../c", QueryPattern would -// consider prefixes of "example.com/a". If multiple modules have versions -// that match the query and packages that match the pattern, QueryPattern -// picks the one with the longest module path. +// For wildcard patterns, QueryPattern looks in modules with package paths up to +// the first "..." in the pattern. For the pattern "example.com/a/b.../c", +// QueryPattern would consider prefixes of "example.com/a". // // If any matching package is in the main module, QueryPattern considers only // the main module and only the version "latest", without checking for other // possible modules. -func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]QueryResult, error) { +// +// QueryPattern always returns at least one QueryResult (which may be only +// modOnly) or a non-nil error. +func QueryPattern(ctx context.Context, pattern, query string, current func(string) string, allowed AllowedFunc) (pkgMods []QueryResult, modOnly *QueryResult, err error) { + ctx, span := trace.StartSpan(ctx, "modload.QueryPattern "+pattern+" "+query) + defer span.Done() + base := pattern firstError := func(m *search.Match) error { @@ -412,12 +551,16 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q } var match func(mod module.Version, root string, isLocal bool) *search.Match + matchPattern := search.MatchPattern(pattern) if i := strings.Index(pattern, "..."); i >= 0 { base = pathpkg.Dir(pattern[:i+3]) + if base == "." { + return nil, nil, &WildcardInFirstElementError{Pattern: pattern, Query: query} + } match = func(mod module.Version, root string, isLocal bool) *search.Match { m := search.NewMatch(pattern) - matchPackages(m, imports.AnyTags(), omitStd, []module.Version{mod}) + matchPackages(ctx, m, imports.AnyTags(), omitStd, []module.Version{mod}) return m } } else { @@ -436,23 +579,41 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q } } + var queryMatchesMainModule bool if HasModRoot() { m := match(Target, modRoot, true) if len(m.Pkgs) > 0 { - if query != "latest" { - return nil, fmt.Errorf("can't query specific version for package %s in the main module (%s)", pattern, Target.Path) + if query != "upgrade" && query != "patch" { + return nil, nil, &QueryMatchesPackagesInMainModuleError{ + Pattern: pattern, + Query: query, + Packages: m.Pkgs, + } } - if !allowed(Target) { - return nil, fmt.Errorf("internal error: package %s is in the main module (%s), but version is not allowed", pattern, Target.Path) + if err := allowed(ctx, Target); err != nil { + return nil, nil, fmt.Errorf("internal error: package %s is in the main module (%s), but version is not allowed: %w", pattern, Target.Path, err) } return []QueryResult{{ Mod: Target, Rev: &modfetch.RevInfo{Version: Target.Version}, Packages: m.Pkgs, - }}, nil + }}, nil, nil } if err := firstError(m); err != nil { - return nil, err + return nil, nil, err + } + + if matchPattern(Target.Path) { + queryMatchesMainModule = true + } + + if (query == "upgrade" || query == "patch") && queryMatchesMainModule { + if err := allowed(ctx, Target); err == nil { + modOnly = &QueryResult{ + Mod: Target, + Rev: &modfetch.RevInfo{Version: Target.Version}, + } + } } } @@ -461,29 +622,42 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q candidateModules = modulePrefixesExcludingTarget(base) ) if len(candidateModules) == 0 { - return nil, &PackageNotInModuleError{ - Mod: Target, - Query: query, - Pattern: pattern, + if modOnly != nil { + return nil, modOnly, nil + } else if queryMatchesMainModule { + return nil, nil, &QueryMatchesMainModuleError{ + Pattern: pattern, + Query: query, + } + } else { + return nil, nil, &PackageNotInModuleError{ + Mod: Target, + Query: query, + Pattern: pattern, + } } } - err := modfetch.TryProxies(func(proxy string) error { - queryModule := func(path string) (r QueryResult, err error) { - current := findCurrentVersion(path) + err = modfetch.TryProxies(func(proxy string) error { + queryModule := func(ctx context.Context, path string) (r QueryResult, err error) { + ctx, span := trace.StartSpan(ctx, "modload.QueryPattern.queryModule ["+proxy+"] "+path) + defer span.Done() + + pathCurrent := current(path) r.Mod.Path = path - r.Rev, err = queryProxy(proxy, path, query, current, allowed) + r.Rev, err = queryProxy(ctx, proxy, path, query, pathCurrent, allowed) if err != nil { return r, err } r.Mod.Version = r.Rev.Version - root, isLocal, err := fetch(r.Mod) + needSum := true + root, isLocal, err := fetch(ctx, r.Mod, needSum) if err != nil { return r, err } m := match(r.Mod, root, isLocal) r.Packages = m.Pkgs - if len(r.Packages) == 0 { + if len(r.Packages) == 0 && !matchPattern(path) { if err := firstError(m); err != nil { return r, err } @@ -497,12 +671,25 @@ func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]Q return r, nil } - var err error - results, err = queryPrefixModules(candidateModules, queryModule) + allResults, err := queryPrefixModules(ctx, candidateModules, queryModule) + results = allResults[:0] + for _, r := range allResults { + if len(r.Packages) == 0 { + modOnly = &r + } else { + results = append(results, r) + } + } return err }) - return results, err + if queryMatchesMainModule && len(results) == 0 && modOnly == nil && errors.Is(err, fs.ErrNotExist) { + return nil, nil, &QueryMatchesMainModuleError{ + Pattern: pattern, + Query: query, + } + } + return results[:len(results):len(results)], modOnly, err } // modulePrefixesExcludingTarget returns all prefixes of path that may plausibly @@ -528,21 +715,10 @@ func modulePrefixesExcludingTarget(path string) []string { return prefixes } -func findCurrentVersion(path string) string { - for _, m := range buildList { - if m.Path == path { - return m.Version - } - } - return "" -} - -type prefixResult struct { - QueryResult - err error -} +func queryPrefixModules(ctx context.Context, candidateModules []string, queryModule func(ctx context.Context, path string) (QueryResult, error)) (found []QueryResult, err error) { + ctx, span := trace.StartSpan(ctx, "modload.queryPrefixModules") + defer span.Done() -func queryPrefixModules(candidateModules []string, queryModule func(path string) (QueryResult, error)) (found []QueryResult, err error) { // If the path we're attempting is not in the module cache and we don't have a // fetch result cached either, we'll end up making a (potentially slow) // request to the proxy or (often even slower) the origin server. @@ -555,8 +731,9 @@ func queryPrefixModules(candidateModules []string, queryModule func(path string) var wg sync.WaitGroup wg.Add(len(candidateModules)) for i, p := range candidateModules { + ctx := trace.StartGoroutine(ctx) go func(p string, r *result) { - r.QueryResult, r.err = queryModule(p) + r.QueryResult, r.err = queryModule(ctx, p) wg.Done() }(p, &results[i]) } @@ -568,6 +745,7 @@ func queryPrefixModules(candidateModules []string, queryModule func(path string) var ( noPackage *PackageNotInModuleError noVersion *NoMatchingVersionError + noPatchBase *NoPatchBaseError notExistErr error ) for _, r := range results { @@ -584,8 +762,12 @@ func queryPrefixModules(candidateModules []string, queryModule func(path string) if noVersion == nil { noVersion = rErr } + case *NoPatchBaseError: + if noPatchBase == nil { + noPatchBase = rErr + } default: - if errors.Is(rErr, os.ErrNotExist) { + if errors.Is(rErr, fs.ErrNotExist) { if notExistErr == nil { notExistErr = rErr } @@ -615,6 +797,8 @@ func queryPrefixModules(candidateModules []string, queryModule func(path string) err = noPackage case noVersion != nil: err = noVersion + case noPatchBase != nil: + err = noPatchBase case notExistErr != nil: err = notExistErr default: @@ -628,7 +812,7 @@ func queryPrefixModules(candidateModules []string, queryModule func(path string) // A NoMatchingVersionError indicates that Query found a module at the requested // path, but not at any versions satisfying the query string and allow-function. // -// NOTE: NoMatchingVersionError MUST NOT implement Is(os.ErrNotExist). +// NOTE: NoMatchingVersionError MUST NOT implement Is(fs.ErrNotExist). // // If the module came from a proxy, that proxy had to return a successful status // code for the versions it knows about, and thus did not have the opportunity @@ -639,17 +823,39 @@ type NoMatchingVersionError struct { func (e *NoMatchingVersionError) Error() string { currentSuffix := "" - if (e.query == "upgrade" || e.query == "patch") && e.current != "" { + if (e.query == "upgrade" || e.query == "patch") && e.current != "" && e.current != "none" { currentSuffix = fmt.Sprintf(" (current version is %s)", e.current) } return fmt.Sprintf("no matching versions for query %q", e.query) + currentSuffix } +// A NoPatchBaseError indicates that Query was called with the query "patch" +// but with a current version of "" or "none". +type NoPatchBaseError struct { + path string +} + +func (e *NoPatchBaseError) Error() string { + return fmt.Sprintf(`can't query version "patch" of module %s: no existing version is required`, e.path) +} + +// A WildcardInFirstElementError indicates that a pattern passed to QueryPattern +// had a wildcard in its first path element, and therefore had no pattern-prefix +// modules to search in. +type WildcardInFirstElementError struct { + Pattern string + Query string +} + +func (e *WildcardInFirstElementError) Error() string { + return fmt.Sprintf("no modules to query for %s@%s because first path element contains a wildcard", e.Pattern, e.Query) +} + // A PackageNotInModuleError indicates that QueryPattern found a candidate // module at the requested version, but that module did not contain any packages // matching the requested pattern. // -// NOTE: PackageNotInModuleError MUST NOT implement Is(os.ErrNotExist). +// NOTE: PackageNotInModuleError MUST NOT implement Is(fs.ErrNotExist). // // If the module came from a proxy, that proxy had to return a successful status // code for the versions it knows about, and thus did not have the opportunity @@ -698,8 +904,9 @@ func (e *PackageNotInModuleError) ImportPath() string { } // ModuleHasRootPackage returns whether module m contains a package m.Path. -func ModuleHasRootPackage(m module.Version) (bool, error) { - root, isLocal, err := fetch(m) +func ModuleHasRootPackage(ctx context.Context, m module.Version) (bool, error) { + needSum := false + root, isLocal, err := fetch(ctx, m, needSum) if err != nil { return false, err } @@ -707,11 +914,202 @@ func ModuleHasRootPackage(m module.Version) (bool, error) { return ok, err } -func versionHasGoMod(m module.Version) (bool, error) { - root, _, err := fetch(m) +func versionHasGoMod(ctx context.Context, m module.Version) (bool, error) { + needSum := false + root, _, err := fetch(ctx, m, needSum) if err != nil { return false, err } fi, err := os.Stat(filepath.Join(root, "go.mod")) return err == nil && !fi.IsDir(), nil } + +// A versionRepo is a subset of modfetch.Repo that can report information about +// available versions, but cannot fetch specific source files. +type versionRepo interface { + ModulePath() string + Versions(prefix string) ([]string, error) + Stat(rev string) (*modfetch.RevInfo, error) + Latest() (*modfetch.RevInfo, error) +} + +var _ versionRepo = modfetch.Repo(nil) + +func lookupRepo(proxy, path string) (repo versionRepo, err error) { + err = module.CheckPath(path) + if err == nil { + repo = modfetch.Lookup(proxy, path) + } else { + repo = emptyRepo{path: path, err: err} + } + + if index == nil { + return repo, err + } + if _, ok := index.highestReplaced[path]; !ok { + return repo, err + } + + return &replacementRepo{repo: repo}, nil +} + +// An emptyRepo is a versionRepo that contains no versions. +type emptyRepo struct { + path string + err error +} + +var _ versionRepo = emptyRepo{} + +func (er emptyRepo) ModulePath() string { return er.path } +func (er emptyRepo) Versions(prefix string) ([]string, error) { return nil, nil } +func (er emptyRepo) Stat(rev string) (*modfetch.RevInfo, error) { return nil, er.err } +func (er emptyRepo) Latest() (*modfetch.RevInfo, error) { return nil, er.err } + +// A replacementRepo augments a versionRepo to include the replacement versions +// (if any) found in the main module's go.mod file. +// +// A replacementRepo suppresses "not found" errors for otherwise-nonexistent +// modules, so a replacementRepo should only be constructed for a module that +// actually has one or more valid replacements. +type replacementRepo struct { + repo versionRepo +} + +var _ versionRepo = (*replacementRepo)(nil) + +func (rr *replacementRepo) ModulePath() string { return rr.repo.ModulePath() } + +// Versions returns the versions from rr.repo augmented with any matching +// replacement versions. +func (rr *replacementRepo) Versions(prefix string) ([]string, error) { + repoVersions, err := rr.repo.Versions(prefix) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, err + } + + versions := repoVersions + if index != nil && len(index.replace) > 0 { + path := rr.ModulePath() + for m, _ := range index.replace { + if m.Path == path && strings.HasPrefix(m.Version, prefix) && m.Version != "" && !modfetch.IsPseudoVersion(m.Version) { + versions = append(versions, m.Version) + } + } + } + + if len(versions) == len(repoVersions) { // No replacement versions added. + return versions, nil + } + + sort.Slice(versions, func(i, j int) bool { + return semver.Compare(versions[i], versions[j]) < 0 + }) + uniq := versions[:1] + for _, v := range versions { + if v != uniq[len(uniq)-1] { + uniq = append(uniq, v) + } + } + return uniq, nil +} + +func (rr *replacementRepo) Stat(rev string) (*modfetch.RevInfo, error) { + info, err := rr.repo.Stat(rev) + if err == nil || index == nil || len(index.replace) == 0 { + return info, err + } + + v := module.CanonicalVersion(rev) + if v != rev { + // The replacements in the go.mod file list only canonical semantic versions, + // so a non-canonical version can't possibly have a replacement. + return info, err + } + + path := rr.ModulePath() + _, pathMajor, ok := module.SplitPathVersion(path) + if ok && pathMajor == "" { + if err := module.CheckPathMajor(v, pathMajor); err != nil && semver.Build(v) == "" { + v += "+incompatible" + } + } + + if r := Replacement(module.Version{Path: path, Version: v}); r.Path == "" { + return info, err + } + return rr.replacementStat(v) +} + +func (rr *replacementRepo) Latest() (*modfetch.RevInfo, error) { + info, err := rr.repo.Latest() + + if index != nil { + path := rr.ModulePath() + if v, ok := index.highestReplaced[path]; ok { + if v == "" { + // The only replacement is a wildcard that doesn't specify a version, so + // synthesize a pseudo-version with an appropriate major version and a + // timestamp below any real timestamp. That way, if the main module is + // used from within some other module, the user will be able to upgrade + // the requirement to any real version they choose. + if _, pathMajor, ok := module.SplitPathVersion(path); ok && len(pathMajor) > 0 { + v = modfetch.PseudoVersion(pathMajor[1:], "", time.Time{}, "000000000000") + } else { + v = modfetch.PseudoVersion("v0", "", time.Time{}, "000000000000") + } + } + + if err != nil || semver.Compare(v, info.Version) > 0 { + return rr.replacementStat(v) + } + } + } + + return info, err +} + +func (rr *replacementRepo) replacementStat(v string) (*modfetch.RevInfo, error) { + rev := &modfetch.RevInfo{Version: v} + if modfetch.IsPseudoVersion(v) { + rev.Time, _ = modfetch.PseudoVersionTime(v) + rev.Short, _ = modfetch.PseudoVersionRev(v) + } + return rev, nil +} + +// A QueryMatchesMainModuleError indicates that a query requests +// a version of the main module that cannot be satisfied. +// (The main module's version cannot be changed.) +type QueryMatchesMainModuleError struct { + Pattern string + Query string +} + +func (e *QueryMatchesMainModuleError) Error() string { + if e.Pattern == Target.Path { + return fmt.Sprintf("can't request version %q of the main module (%s)", e.Query, e.Pattern) + } + + return fmt.Sprintf("can't request version %q of pattern %q that includes the main module (%s)", e.Query, e.Pattern, Target.Path) +} + +// A QueryMatchesPackagesInMainModuleError indicates that a query cannot be +// satisfied because it matches one or more packages found in the main module. +type QueryMatchesPackagesInMainModuleError struct { + Pattern string + Query string + Packages []string +} + +func (e *QueryMatchesPackagesInMainModuleError) Error() string { + if len(e.Packages) > 1 { + return fmt.Sprintf("pattern %s matches %d packages in the main module, so can't request version %s", e.Pattern, len(e.Packages), e.Query) + } + + if search.IsMetaPackage(e.Pattern) || strings.Contains(e.Pattern, "...") { + return fmt.Sprintf("pattern %s matches package %s in the main module, so can't request version %s", e.Pattern, e.Packages[0], e.Query) + } + + return fmt.Sprintf("package %s is in the main module, so can't request version %s", e.Packages[0], e.Query) +} diff --git a/libgo/go/cmd/go/internal/modload/query_test.go b/libgo/go/cmd/go/internal/modload/query_test.go index 247e4c40d24..e225a0e71e7 100644 --- a/libgo/go/cmd/go/internal/modload/query_test.go +++ b/libgo/go/cmd/go/internal/modload/query_test.go @@ -5,8 +5,8 @@ package modload import ( + "context" "internal/testenv" - "io/ioutil" "log" "os" "path" @@ -26,7 +26,7 @@ func TestMain(m *testing.M) { func testMain(m *testing.M) int { cfg.GOPROXY = "direct" - dir, err := ioutil.TempDir("", "modload-test-") + dir, err := os.MkdirTemp("", "modload-test-") if err != nil { log.Fatal(err) } @@ -44,7 +44,7 @@ var ( queryRepoV3 = queryRepo + "/v3" // Empty version list (no semver tags), not actually empty. - emptyRepo = "vcs-test.golang.org/git/emptytest.git" + emptyRepoPath = "vcs-test.golang.org/git/emptytest.git" ) var queryTests = []struct { @@ -120,14 +120,14 @@ var queryTests = []struct { {path: queryRepo, query: "upgrade", current: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"}, {path: queryRepo, query: "upgrade", current: "v0.0.0-20190513201126-42abcb6df8ee", vers: "v0.0.0-20190513201126-42abcb6df8ee"}, {path: queryRepo, query: "upgrade", allow: "NOMATCH", err: `no matching versions for query "upgrade"`}, - {path: queryRepo, query: "upgrade", current: "v1.9.9", allow: "NOMATCH", err: `no matching versions for query "upgrade" (current version is v1.9.9)`}, + {path: queryRepo, query: "upgrade", current: "v1.9.9", allow: "NOMATCH", err: `vcs-test.golang.org/git/querytest.git@v1.9.9: disallowed module version`}, {path: queryRepo, query: "upgrade", current: "v1.99.99", err: `vcs-test.golang.org/git/querytest.git@v1.99.99: invalid version: unknown revision v1.99.99`}, {path: queryRepo, query: "patch", current: "", vers: "v1.9.9"}, {path: queryRepo, query: "patch", current: "v0.1.0", vers: "v0.1.2"}, {path: queryRepo, query: "patch", current: "v1.9.0", vers: "v1.9.9"}, {path: queryRepo, query: "patch", current: "v1.9.10-pre1", vers: "v1.9.10-pre1"}, {path: queryRepo, query: "patch", current: "v1.9.10-pre2+metadata", vers: "v1.9.10-pre2.0.20190513201126-42abcb6df8ee"}, - {path: queryRepo, query: "patch", current: "v1.99.99", err: `no matching versions for query "patch" (current version is v1.99.99)`}, + {path: queryRepo, query: "patch", current: "v1.99.99", err: `vcs-test.golang.org/git/querytest.git@v1.99.99: invalid version: unknown revision v1.99.99`}, {path: queryRepo, query: ">v1.9.9", vers: "v1.9.10-pre1"}, {path: queryRepo, query: ">v1.10.0", err: `no matching versions for query ">v1.10.0"`}, {path: queryRepo, query: ">=v1.10.0", err: `no matching versions for query ">=v1.10.0"`}, @@ -170,42 +170,46 @@ var queryTests = []struct { // That should prevent us from resolving any version for the /v3 path. {path: queryRepoV3, query: "latest", err: `no matching versions for query "latest"`}, - {path: emptyRepo, query: "latest", vers: "v0.0.0-20180704023549-7bb914627242"}, - {path: emptyRepo, query: ">v0.0.0", err: `no matching versions for query ">v0.0.0"`}, - {path: emptyRepo, query: "v0.0.0", err: `no matching versions for query ">v0.0.0"`}, + {path: emptyRepoPath, query: " 1 { + reason := "requires" + if isUpgrade != nil && isUpgrade(path[0], path[1]) { + reason = "updating to" + } + stack = append(stack, buildListErrorElem{ + m: path[0], + nextReason: reason, + }) + path = path[1:] + } + stack = append(stack, buildListErrorElem{m: path[0]}) + + return &BuildListError{ + Err: err, + stack: stack, + } +} + +// Module returns the module where the error occurred. If the module stack +// is empty, this returns a zero value. +func (e *BuildListError) Module() module.Version { + if len(e.stack) == 0 { + return module.Version{} + } + return e.stack[len(e.stack)-1].m +} + +func (e *BuildListError) Error() string { + b := &strings.Builder{} + stack := e.stack + + // Don't print modules at the beginning of the chain without a + // version. These always seem to be the main module or a + // synthetic module ("target@"). + for len(stack) > 0 && stack[0].m.Version == "" { + stack = stack[1:] + } + + if len(stack) == 0 { + b.WriteString(e.Err.Error()) + } else { + for _, elem := range stack[:len(stack)-1] { + fmt.Fprintf(b, "%s %s\n\t", elem.m, elem.nextReason) + } + // Ensure that the final module path and version are included as part of the + // error message. + m := stack[len(stack)-1].m + if mErr, ok := e.Err.(*module.ModuleError); ok { + actual := module.Version{Path: mErr.Path, Version: mErr.Version} + if v, ok := mErr.Err.(*module.InvalidVersionError); ok { + actual.Version = v.Version + } + if actual == m { + fmt.Fprintf(b, "%v", e.Err) + } else { + fmt.Fprintf(b, "%s (replaced by %s): %v", m, actual, mErr.Err) + } + } else { + fmt.Fprintf(b, "%v", module.VersionError(m, e.Err)) + } + } + return b.String() +} diff --git a/libgo/go/cmd/go/internal/mvs/mvs.go b/libgo/go/cmd/go/internal/mvs/mvs.go index 1f8eaa1f601..b630b610f10 100644 --- a/libgo/go/cmd/go/internal/mvs/mvs.go +++ b/libgo/go/cmd/go/internal/mvs/mvs.go @@ -9,7 +9,6 @@ package mvs import ( "fmt" "sort" - "strings" "sync" "sync/atomic" @@ -61,59 +60,6 @@ type Reqs interface { Previous(m module.Version) (module.Version, error) } -// BuildListError decorates an error that occurred gathering requirements -// while constructing a build list. BuildListError prints the chain -// of requirements to the module where the error occurred. -type BuildListError struct { - Err error - stack []buildListErrorElem -} - -type buildListErrorElem struct { - m module.Version - - // nextReason is the reason this module depends on the next module in the - // stack. Typically either "requires", or "upgraded to". - nextReason string -} - -// Module returns the module where the error occurred. If the module stack -// is empty, this returns a zero value. -func (e *BuildListError) Module() module.Version { - if len(e.stack) == 0 { - return module.Version{} - } - return e.stack[0].m -} - -func (e *BuildListError) Error() string { - b := &strings.Builder{} - stack := e.stack - - // Don't print modules at the beginning of the chain without a - // version. These always seem to be the main module or a - // synthetic module ("target@"). - for len(stack) > 0 && stack[len(stack)-1].m.Version == "" { - stack = stack[:len(stack)-1] - } - - for i := len(stack) - 1; i >= 1; i-- { - fmt.Fprintf(b, "%s@%s %s\n\t", stack[i].m.Path, stack[i].m.Version, stack[i].nextReason) - } - if len(stack) == 0 { - b.WriteString(e.Err.Error()) - } else { - // Ensure that the final module path and version are included as part of the - // error message. - if _, ok := e.Err.(*module.ModuleError); ok { - fmt.Fprintf(b, "%v", e.Err) - } else { - fmt.Fprintf(b, "%v", module.VersionError(stack[0].m, e.Err)) - } - } - return b.String() -} - // BuildList returns the build list for the target module. // // target is the root vertex of a module requirement graph. For cmd/go, this is @@ -162,19 +108,23 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m node := &modGraphNode{m: m} mu.Lock() modGraph[m] = node - if v, ok := min[m.Path]; !ok || reqs.Max(v, m.Version) != v { - min[m.Path] = m.Version + if m.Version != "none" { + if v, ok := min[m.Path]; !ok || reqs.Max(v, m.Version) != v { + min[m.Path] = m.Version + } } mu.Unlock() - required, err := reqs.Required(m) - if err != nil { - setErr(node, err) - return - } - node.required = required - for _, r := range node.required { - work.Add(r) + if m.Version != "none" { + required, err := reqs.Required(m) + if err != nil { + setErr(node, err) + return + } + node.required = required + for _, r := range node.required { + work.Add(r) + } } if upgrade != nil { @@ -202,18 +152,30 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m q = q[1:] if node.err != nil { - err := &BuildListError{ - Err: node.err, - stack: []buildListErrorElem{{m: node.m}}, - } + pathUpgrade := map[module.Version]module.Version{} + + // Construct the error path reversed (from the error to the main module), + // then reverse it to obtain the usual order (from the main module to + // the error). + errPath := []module.Version{node.m} for n, prev := neededBy[node], node; n != nil; n, prev = neededBy[n], n { - reason := "requires" if n.upgrade == prev.m { - reason = "updating to" + pathUpgrade[n.m] = prev.m } - err.stack = append(err.stack, buildListErrorElem{m: n.m, nextReason: reason}) + errPath = append(errPath, n.m) } - return nil, err + i, j := 0, len(errPath)-1 + for i < j { + errPath[i], errPath[j] = errPath[j], errPath[i] + i++ + j-- + } + + isUpgrade := func(from, to module.Version) bool { + return pathUpgrade[from] == to + } + + return nil, NewBuildListError(node.err, errPath, isUpgrade) } neighbors := node.required @@ -250,6 +212,9 @@ func buildList(target module.Version, reqs Reqs, upgrade func(module.Version) (m n := modGraph[module.Version{Path: path, Version: vers}] required := n.required for _, r := range required { + if r.Version == "none" { + continue + } v := min[r.Path] if r.Path != target.Path && reqs.Max(v, r.Version) != v { panic(fmt.Sprintf("mistake: version %q does not satisfy requirement %+v", v, r)) // TODO: Don't panic. @@ -370,16 +335,36 @@ func Upgrade(target module.Version, reqs Reqs, upgrade ...module.Version) ([]mod if err != nil { return nil, err } - // TODO: Maybe if an error is given, - // rerun with BuildList(upgrade[0], reqs) etc - // to find which ones are the buggy ones. + + pathInList := make(map[string]bool, len(list)) + for _, m := range list { + pathInList[m.Path] = true + } list = append([]module.Version(nil), list...) - list = append(list, upgrade...) - return BuildList(target, &override{target, list, reqs}) + + upgradeTo := make(map[string]string, len(upgrade)) + for _, u := range upgrade { + if !pathInList[u.Path] { + list = append(list, module.Version{Path: u.Path, Version: "none"}) + } + if prev, dup := upgradeTo[u.Path]; dup { + upgradeTo[u.Path] = reqs.Max(prev, u.Version) + } else { + upgradeTo[u.Path] = u.Version + } + } + + return buildList(target, &override{target, list, reqs}, func(m module.Version) (module.Version, error) { + if v, ok := upgradeTo[m.Path]; ok { + return module.Version{Path: m.Path, Version: v}, nil + } + return m, nil + }) } // Downgrade returns a build list for the target module -// in which the given additional modules are downgraded. +// in which the given additional modules are downgraded, +// potentially overriding the requirements of the target. // // The versions to be downgraded may be unreachable from reqs.Latest and // reqs.Previous, but the methods of reqs must otherwise handle such versions diff --git a/libgo/go/cmd/go/internal/mvs/mvs_test.go b/libgo/go/cmd/go/internal/mvs/mvs_test.go index 9a30a8c3ac0..721cd9635c8 100644 --- a/libgo/go/cmd/go/internal/mvs/mvs_test.go +++ b/libgo/go/cmd/go/internal/mvs/mvs_test.go @@ -54,7 +54,7 @@ build A: A B C D2 E2 name: cross1V A: B2 C D2 E1 -B1: +B1: B2: D1 C: D2 D1: E2 @@ -63,7 +63,7 @@ build A: A B2 C D2 E2 name: cross1U A: B1 C -B1: +B1: B2: D1 C: D2 D1: E2 @@ -72,7 +72,7 @@ build A: A B1 C D2 E1 upgrade A B2: A B2 C D2 E2 name: cross1R -A: B C +A: B C B: D2 C: D1 D1: E2 @@ -165,7 +165,7 @@ M: A1 B1 A1: X1 B1: X2 X1: I1 -X2: +X2: build M: M A1 B1 I1 X2 # Upgrade from B1 to B2 should not drop the transitive dep on D. @@ -229,28 +229,31 @@ E1: F1: downgrade A F1: A B1 E1 -name: down3 -A: +name: downcycle +A: A B2 +B2: A +B1: +downgrade A B1: A B1 # golang.org/issue/25542. name: noprev1 A: B4 C2 -B2.hidden: -C2: +B2.hidden: +C2: downgrade A B2.hidden: A B2.hidden C2 name: noprev2 A: B4 C2 -B2.hidden: -B1: -C2: +B2.hidden: +B1: +C2: downgrade A B2.hidden: A B2.hidden C2 name: noprev3 A: B4 C2 -B3: -B2.hidden: -C2: +B3: +B2.hidden: +C2: downgrade A B2.hidden: A B2.hidden C2 # Cycles involving the target. @@ -315,8 +318,15 @@ M: A1 B1 A1: X1 B1: X2 X1: I1 -X2: +X2: req M: A1 B1 + +name: reqnone +M: Anone B1 D1 E1 +B1: Cnone D1 +E1: Fnone +build M: M B1 D1 E1 +req M: B1 E1 ` func Test(t *testing.T) { @@ -331,6 +341,9 @@ func Test(t *testing.T) { for _, fn := range fns { fn(t) } + if len(fns) == 0 { + t.Errorf("no functions tested") + } }) } } @@ -478,9 +491,9 @@ func (r reqsMap) Max(v1, v2 string) string { } func (r reqsMap) Upgrade(m module.Version) (module.Version, error) { - var u module.Version + u := module.Version{Version: "none"} for k := range r { - if k.Path == m.Path && u.Version < k.Version && !strings.HasSuffix(k.Version, ".hidden") { + if k.Path == m.Path && r.Max(u.Version, k.Version) == k.Version && !strings.HasSuffix(k.Version, ".hidden") { u = k } } diff --git a/libgo/go/cmd/go/internal/par/queue.go b/libgo/go/cmd/go/internal/par/queue.go new file mode 100644 index 00000000000..180bc75e343 --- /dev/null +++ b/libgo/go/cmd/go/internal/par/queue.go @@ -0,0 +1,88 @@ +// Copyright 2020 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 par + +import "fmt" + +// Queue manages a set of work items to be executed in parallel. The number of +// active work items is limited, and excess items are queued sequentially. +type Queue struct { + maxActive int + st chan queueState +} + +type queueState struct { + active int // number of goroutines processing work; always nonzero when len(backlog) > 0 + backlog []func() + idle chan struct{} // if non-nil, closed when active becomes 0 +} + +// NewQueue returns a Queue that executes up to maxActive items in parallel. +// +// maxActive must be positive. +func NewQueue(maxActive int) *Queue { + if maxActive < 1 { + panic(fmt.Sprintf("par.NewQueue called with nonpositive limit (%d)", maxActive)) + } + + q := &Queue{ + maxActive: maxActive, + st: make(chan queueState, 1), + } + q.st <- queueState{} + return q +} + +// Add adds f as a work item in the queue. +// +// Add returns immediately, but the queue will be marked as non-idle until after +// f (and any subsequently-added work) has completed. +func (q *Queue) Add(f func()) { + st := <-q.st + if st.active == q.maxActive { + st.backlog = append(st.backlog, f) + q.st <- st + return + } + if st.active == 0 { + // Mark q as non-idle. + st.idle = nil + } + st.active++ + q.st <- st + + go func() { + for { + f() + + st := <-q.st + if len(st.backlog) == 0 { + if st.active--; st.active == 0 && st.idle != nil { + close(st.idle) + } + q.st <- st + return + } + f, st.backlog = st.backlog[0], st.backlog[1:] + q.st <- st + } + }() +} + +// Idle returns a channel that will be closed when q has no (active or enqueued) +// work outstanding. +func (q *Queue) Idle() <-chan struct{} { + st := <-q.st + defer func() { q.st <- st }() + + if st.idle == nil { + st.idle = make(chan struct{}) + if st.active == 0 { + close(st.idle) + } + } + + return st.idle +} diff --git a/libgo/go/cmd/go/internal/par/queue_test.go b/libgo/go/cmd/go/internal/par/queue_test.go new file mode 100644 index 00000000000..1331e65f98a --- /dev/null +++ b/libgo/go/cmd/go/internal/par/queue_test.go @@ -0,0 +1,79 @@ +// Copyright 2020 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 par + +import ( + "sync" + "testing" +) + +func TestQueueIdle(t *testing.T) { + q := NewQueue(1) + select { + case <-q.Idle(): + default: + t.Errorf("NewQueue(1) is not initially idle.") + } + + started := make(chan struct{}) + unblock := make(chan struct{}) + q.Add(func() { + close(started) + <-unblock + }) + + <-started + idle := q.Idle() + select { + case <-idle: + t.Errorf("NewQueue(1) is marked idle while processing work.") + default: + } + + close(unblock) + <-idle // Should be closed as soon as the Add callback returns. +} + +func TestQueueBacklog(t *testing.T) { + const ( + maxActive = 2 + totalWork = 3 * maxActive + ) + + q := NewQueue(maxActive) + t.Logf("q = NewQueue(%d)", maxActive) + + var wg sync.WaitGroup + wg.Add(totalWork) + started := make([]chan struct{}, totalWork) + unblock := make(chan struct{}) + for i := range started { + started[i] = make(chan struct{}) + i := i + q.Add(func() { + close(started[i]) + <-unblock + wg.Done() + }) + } + + for i, c := range started { + if i < maxActive { + <-c // Work item i should be started immediately. + } else { + select { + case <-c: + t.Errorf("Work item %d started before previous items finished.", i) + default: + } + } + } + + close(unblock) + for _, c := range started[maxActive:] { + <-c + } + wg.Wait() +} diff --git a/libgo/go/cmd/go/internal/renameio/renameio.go b/libgo/go/cmd/go/internal/renameio/renameio.go index d573cc690d2..9788171d6e2 100644 --- a/libgo/go/cmd/go/internal/renameio/renameio.go +++ b/libgo/go/cmd/go/internal/renameio/renameio.go @@ -8,6 +8,7 @@ package renameio import ( "bytes" "io" + "io/fs" "math/rand" "os" "path/filepath" @@ -24,18 +25,18 @@ func Pattern(filename string) string { return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix) } -// WriteFile is like ioutil.WriteFile, but first writes data to an arbitrary +// WriteFile is like os.WriteFile, but first writes data to an arbitrary // file in the same directory as filename, then renames it atomically to the // final name. // // That ensures that the final location, if it exists, is always a complete file. -func WriteFile(filename string, data []byte, perm os.FileMode) (err error) { +func WriteFile(filename string, data []byte, perm fs.FileMode) (err error) { return WriteToFile(filename, bytes.NewReader(data), perm) } // WriteToFile is a variant of WriteFile that accepts the data as an io.Reader // instead of a slice. -func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) { +func WriteToFile(filename string, data io.Reader, perm fs.FileMode) (err error) { f, err := tempFile(filepath.Dir(filename), filepath.Base(filename), perm) if err != nil { return err @@ -66,7 +67,7 @@ func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) return robustio.Rename(f.Name(), filename) } -// ReadFile is like ioutil.ReadFile, but on Windows retries spurious errors that +// ReadFile is like os.ReadFile, but on Windows retries spurious errors that // may occur if the file is concurrently replaced. // // Errors are classified heuristically and retries are bounded, so even this @@ -80,7 +81,7 @@ func ReadFile(filename string) ([]byte, error) { } // tempFile creates a new temporary file with given permission bits. -func tempFile(dir, prefix string, perm os.FileMode) (f *os.File, err error) { +func tempFile(dir, prefix string, perm fs.FileMode) (f *os.File, err error) { for i := 0; i < 10000; i++ { name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+patternSuffix) f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) diff --git a/libgo/go/cmd/go/internal/renameio/renameio_test.go b/libgo/go/cmd/go/internal/renameio/renameio_test.go index df8ddabdb82..5b2ed836242 100644 --- a/libgo/go/cmd/go/internal/renameio/renameio_test.go +++ b/libgo/go/cmd/go/internal/renameio/renameio_test.go @@ -10,7 +10,6 @@ import ( "encoding/binary" "errors" "internal/testenv" - "io/ioutil" "math/rand" "os" "path/filepath" @@ -30,7 +29,7 @@ func TestConcurrentReadsAndWrites(t *testing.T) { testenv.SkipFlaky(t, 33041) } - dir, err := ioutil.TempDir("", "renameio") + dir, err := os.MkdirTemp("", "renameio") if err != nil { t.Fatal(err) } @@ -144,10 +143,12 @@ func TestConcurrentReadsAndWrites(t *testing.T) { // 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. + case "darwin", "ios": + // The filesystem on certain versions of macOS (10.14) and iOS (affected + // versions TBD) occasionally fail with "no such file or directory" errors. + // See https://golang.org/issue/33041 and https://golang.org/issue/42066. + // The flake rate is fairly low, so ensure that at least 75% of attempts + // succeed. minReadSuccesses = attempts - (attempts / 4) } diff --git a/libgo/go/cmd/go/internal/renameio/umask_test.go b/libgo/go/cmd/go/internal/renameio/umask_test.go index d75d67c9a93..65e4fa587b7 100644 --- a/libgo/go/cmd/go/internal/renameio/umask_test.go +++ b/libgo/go/cmd/go/internal/renameio/umask_test.go @@ -7,7 +7,7 @@ package renameio import ( - "io/ioutil" + "io/fs" "os" "path/filepath" "syscall" @@ -15,7 +15,7 @@ import ( ) func TestWriteFileModeAppliesUmask(t *testing.T) { - dir, err := ioutil.TempDir("", "renameio") + dir, err := os.MkdirTemp("", "renameio") if err != nil { t.Fatalf("Failed to create temporary directory: %v", err) } @@ -36,7 +36,7 @@ func TestWriteFileModeAppliesUmask(t *testing.T) { t.Fatalf("Stat %q (looking for mode %#o): %s", file, mode, err) } - if fi.Mode()&os.ModePerm != 0640 { - t.Errorf("Stat %q: mode %#o want %#o", file, fi.Mode()&os.ModePerm, 0640) + if fi.Mode()&fs.ModePerm != 0640 { + t.Errorf("Stat %q: mode %#o want %#o", file, fi.Mode()&fs.ModePerm, 0640) } } diff --git a/libgo/go/cmd/go/internal/robustio/robustio.go b/libgo/go/cmd/go/internal/robustio/robustio.go index 76e47ad1ffa..ce3dbbde6db 100644 --- a/libgo/go/cmd/go/internal/robustio/robustio.go +++ b/libgo/go/cmd/go/internal/robustio/robustio.go @@ -22,7 +22,7 @@ func Rename(oldpath, newpath string) error { return rename(oldpath, newpath) } -// ReadFile is like ioutil.ReadFile, but on Windows retries errors that may +// ReadFile is like os.ReadFile, but on Windows retries errors that may // occur if the file is concurrently replaced. // // (See golang.org/issue/31247 and golang.org/issue/32188.) diff --git a/libgo/go/cmd/go/internal/robustio/robustio_flaky.go b/libgo/go/cmd/go/internal/robustio/robustio_flaky.go index d4cb7e6457f..5bd44bd3453 100644 --- a/libgo/go/cmd/go/internal/robustio/robustio_flaky.go +++ b/libgo/go/cmd/go/internal/robustio/robustio_flaky.go @@ -8,7 +8,6 @@ package robustio import ( "errors" - "io/ioutil" "math/rand" "os" "syscall" @@ -70,11 +69,11 @@ func rename(oldpath, newpath string) (err error) { }) } -// readFile is like ioutil.ReadFile, but retries ephemeral errors. +// readFile is like os.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) + b, err = os.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 diff --git a/libgo/go/cmd/go/internal/robustio/robustio_other.go b/libgo/go/cmd/go/internal/robustio/robustio_other.go index 907b5568587..6fe7b7e4e4e 100644 --- a/libgo/go/cmd/go/internal/robustio/robustio_other.go +++ b/libgo/go/cmd/go/internal/robustio/robustio_other.go @@ -7,7 +7,6 @@ package robustio import ( - "io/ioutil" "os" ) @@ -16,7 +15,7 @@ func rename(oldpath, newpath string) error { } func readFile(filename string) ([]byte, error) { - return ioutil.ReadFile(filename) + return os.ReadFile(filename) } func removeAll(path string) error { diff --git a/libgo/go/cmd/go/internal/run/run.go b/libgo/go/cmd/go/internal/run/run.go index 2edae38ccaa..99578b244c8 100644 --- a/libgo/go/cmd/go/internal/run/run.go +++ b/libgo/go/cmd/go/internal/run/run.go @@ -6,6 +6,7 @@ package run import ( + "context" "fmt" "os" "path" @@ -57,7 +58,7 @@ func printStderr(args ...interface{}) (int, error) { return fmt.Fprint(os.Stderr, args...) } -func runRun(cmd *base.Command, args []string) { +func runRun(ctx context.Context, cmd *base.Command, args []string) { work.BuildInit() var b work.Builder b.Init() @@ -76,9 +77,9 @@ func runRun(cmd *base.Command, args []string) { base.Fatalf("go run: cannot run *_test.go files (%s)", file) } } - p = load.GoFilesPackage(files) + p = load.GoFilesPackage(ctx, files) } else if len(args) > 0 && !strings.HasPrefix(args[0], "-") { - pkgs := load.PackagesAndErrors(args[:1]) + pkgs := load.PackagesAndErrors(ctx, args[:1]) if len(pkgs) == 0 { base.Fatalf("go run: no packages loaded from %s", args[0]) } @@ -140,12 +141,12 @@ func runRun(cmd *base.Command, args []string) { } a1 := b.LinkAction(work.ModeBuild, work.ModeBuild, p) a := &work.Action{Mode: "go run", Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}} - b.Do(a) + b.Do(ctx, a) } // buildRunProgram is the action for running a binary that has already // been compiled. We ignore exit status. -func buildRunProgram(b *work.Builder, a *work.Action) error { +func buildRunProgram(b *work.Builder, ctx context.Context, a *work.Action) error { cmdline := str.StringList(work.FindExecCmd(), a.Deps[0].Target, a.Args) if cfg.BuildN || cfg.BuildX { b.Showcmd("", "%s", strings.Join(cmdline, " ")) diff --git a/libgo/go/cmd/go/internal/search/search.go b/libgo/go/cmd/go/internal/search/search.go index 4efef24152b..18738cf59ec 100644 --- a/libgo/go/cmd/go/internal/search/search.go +++ b/libgo/go/cmd/go/internal/search/search.go @@ -7,8 +7,10 @@ package search import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "fmt" "go/build" + "io/fs" "os" "path" "path/filepath" @@ -127,7 +129,7 @@ func (m *Match) MatchPackages() { if m.pattern == "cmd" { root += "cmd" + string(filepath.Separator) } - err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { + err := fsys.Walk(root, func(path string, fi fs.FileInfo, err error) error { if err != nil { return err // Likely a permission error, which could interfere with matching. } @@ -153,8 +155,8 @@ func (m *Match) MatchPackages() { } if !fi.IsDir() { - if fi.Mode()&os.ModeSymlink != 0 && want { - if target, err := os.Stat(path); err == nil && target.IsDir() { + if fi.Mode()&fs.ModeSymlink != 0 && want { + if target, err := fsys.Stat(path); err == nil && target.IsDir() { fmt.Fprintf(os.Stderr, "warning: ignoring symlink %s\n", path) } } @@ -263,7 +265,7 @@ func (m *Match) MatchDirs() { } } - err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error { + err := fsys.Walk(dir, func(path string, fi fs.FileInfo, err error) error { if err != nil { return err // Likely a permission error, which could interfere with matching. } @@ -272,7 +274,7 @@ func (m *Match) MatchDirs() { } top := false if path == dir { - // filepath.Walk starts at dir and recurses. For the recursive case, + // Walk starts at dir and recurses. For the recursive case, // the path is the result of filepath.Join, which calls filepath.Clean. // The initial case is not Cleaned, though, so we do this explicitly. // @@ -293,7 +295,7 @@ func (m *Match) MatchDirs() { if !top && cfg.ModulesEnabled { // Ignore other modules found in subdirectories. - if fi, err := os.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() { + if fi, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() { return filepath.SkipDir } } diff --git a/libgo/go/cmd/go/internal/str/path.go b/libgo/go/cmd/go/internal/str/path.go index 95d91a3332e..51ab2af82b5 100644 --- a/libgo/go/cmd/go/internal/str/path.go +++ b/libgo/go/cmd/go/internal/str/path.go @@ -5,7 +5,6 @@ package str import ( - "path" "path/filepath" "strings" ) @@ -50,47 +49,3 @@ func HasFilePathPrefix(s, prefix string) bool { return s[len(prefix)] == filepath.Separator && s[:len(prefix)] == prefix } } - -// 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 -} diff --git a/libgo/go/cmd/go/internal/str/str_test.go b/libgo/go/cmd/go/internal/str/str_test.go new file mode 100644 index 00000000000..147ce1a63ef --- /dev/null +++ b/libgo/go/cmd/go/internal/str/str_test.go @@ -0,0 +1,27 @@ +// Copyright 2020 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 str + +import "testing" + +var foldDupTests = []struct { + list []string + f1, f2 string +}{ + {StringList("math/rand", "math/big"), "", ""}, + {StringList("math", "strings"), "", ""}, + {StringList("strings"), "", ""}, + {StringList("strings", "strings"), "strings", "strings"}, + {StringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"}, +} + +func TestFoldDup(t *testing.T) { + for _, tt := range foldDupTests { + f1, f2 := FoldDup(tt.list) + if f1 != tt.f1 || f2 != tt.f2 { + t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2) + } + } +} diff --git a/libgo/go/cmd/go/internal/test/flagdefs_test.go b/libgo/go/cmd/go/internal/test/flagdefs_test.go index 7562415298c..ab5440b3801 100644 --- a/libgo/go/cmd/go/internal/test/flagdefs_test.go +++ b/libgo/go/cmd/go/internal/test/flagdefs_test.go @@ -16,9 +16,14 @@ func TestPassFlagToTestIncludesAllTestFlags(t *testing.T) { return } name := strings.TrimPrefix(f.Name, "test.") - if name != "testlogfile" && !passFlagToTest[name] { - t.Errorf("passFlagToTest missing entry for %q (flag test.%s)", name, name) - t.Logf("(Run 'go generate cmd/go/internal/test' if it should be added.)") + switch name { + case "testlogfile", "paniconexit0": + // These are internal flags. + default: + if !passFlagToTest[name] { + t.Errorf("passFlagToTest missing entry for %q (flag test.%s)", name, name) + t.Logf("(Run 'go generate cmd/go/internal/test' if it should be added.)") + } } }) diff --git a/libgo/go/cmd/go/internal/test/genflags.go b/libgo/go/cmd/go/internal/test/genflags.go index 512fa1671ef..5e83d53980c 100644 --- a/libgo/go/cmd/go/internal/test/genflags.go +++ b/libgo/go/cmd/go/internal/test/genflags.go @@ -62,9 +62,10 @@ func testFlags() []string { } name := strings.TrimPrefix(f.Name, "test.") - if name == "testlogfile" { - // test.testlogfile is “for use only by cmd/go” - } else { + switch name { + case "testlogfile", "paniconexit0": + // These flags are only for use by cmd/go. + default: names = append(names, name) } }) diff --git a/libgo/go/cmd/go/internal/test/test.go b/libgo/go/cmd/go/internal/test/test.go index 77bfc11fe9a..50fe2dbf393 100644 --- a/libgo/go/cmd/go/internal/test/test.go +++ b/libgo/go/cmd/go/internal/test/test.go @@ -6,12 +6,13 @@ package test import ( "bytes" + "context" "crypto/sha256" "errors" "fmt" "go/build" "io" - "io/ioutil" + "io/fs" "os" "os/exec" "path" @@ -28,8 +29,8 @@ import ( "cmd/go/internal/cfg" "cmd/go/internal/load" "cmd/go/internal/lockedfile" - "cmd/go/internal/modload" "cmd/go/internal/str" + "cmd/go/internal/trace" "cmd/go/internal/work" "cmd/internal/test2json" ) @@ -148,6 +149,7 @@ In addition to the build flags, the flags handled by 'go test' itself are: -i Install packages that are dependencies of the test. Do not run the test. + The -i flag is deprecated. Compiled packages are cached automatically. -json Convert test output to JSON suitable for automated processing. @@ -565,18 +567,36 @@ var defaultVetFlags = []string{ // "-unusedresult", } -func runTest(cmd *base.Command, args []string) { - modload.LoadTests = true +func runTest(ctx context.Context, cmd *base.Command, args []string) { + load.ModResolveTests = true pkgArgs, testArgs = testFlags(args) + if cfg.DebugTrace != "" { + var close func() error + var err error + ctx, close, err = trace.Start(ctx, cfg.DebugTrace) + if err != nil { + base.Fatalf("failed to start trace: %v", err) + } + defer func() { + if err := close(); err != nil { + base.Fatalf("failed to stop trace: %v", err) + } + }() + } + + ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command")) + defer span.Done() + work.FindExecCmd() // initialize cached result work.BuildInit() work.VetFlags = testVet.flags work.VetExplicit = testVet.explicit - pkgs = load.PackagesForBuild(pkgArgs) + pkgs = load.PackagesAndErrors(ctx, pkgArgs) + load.CheckPackageErrors(pkgs) if len(pkgs) == 0 { base.Fatalf("no packages to test") } @@ -621,6 +641,7 @@ func runTest(cmd *base.Command, args []string) { b.Init() if cfg.BuildI { + fmt.Fprint(os.Stderr, "go test: -i flag is deprecated\n") cfg.BuildV = testV deps := make(map[string]bool) @@ -658,7 +679,9 @@ func runTest(cmd *base.Command, args []string) { sort.Strings(all) a := &work.Action{Mode: "go test -i"} - for _, p := range load.PackagesForBuild(all) { + pkgs := load.PackagesAndErrors(ctx, all) + load.CheckPackageErrors(pkgs) + for _, p := range pkgs { if cfg.BuildToolchainName == "gccgo" && p.Standard { // gccgo's standard library packages // can not be reinstalled. @@ -666,7 +689,7 @@ func runTest(cmd *base.Command, args []string) { } a.Deps = append(a.Deps, b.CompileAction(work.ModeInstall, work.ModeInstall, p)) } - b.Do(a) + b.Do(ctx, a) if !testC || a.Failed { return } @@ -683,7 +706,7 @@ func runTest(cmd *base.Command, args []string) { } // Select for coverage all dependencies matching the testCoverPaths patterns. - for _, p := range load.TestPackageList(pkgs) { + for _, p := range load.TestPackageList(ctx, pkgs) { haveMatch := false for i := range testCoverPaths { if match[i](p) { @@ -745,7 +768,7 @@ func runTest(cmd *base.Command, args []string) { ensureImport(p, "sync/atomic") } - buildTest, runTest, printTest, err := builderTest(&b, p) + buildTest, runTest, printTest, err := builderTest(&b, ctx, p) if err != nil { str := err.Error() str = strings.TrimPrefix(str, "\n") @@ -786,7 +809,7 @@ func runTest(cmd *base.Command, args []string) { } } - b.Do(root) + b.Do(ctx, root) } // ensures that package p imports the named package @@ -812,7 +835,7 @@ var windowsBadWords = []string{ "update", } -func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) { +func builderTest(b *work.Builder, ctx context.Context, p *load.Package) (buildAction, runAction, printAction *work.Action, err error) { if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 { build := b.CompileAction(work.ModeBuild, work.ModeBuild, p) run := &work.Action{Mode: "test run", Package: p, Deps: []*work.Action{build}} @@ -835,7 +858,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin DeclVars: declareCoverVars, } } - pmain, ptest, pxtest, err := load.TestPackagesFor(p, cover) + pmain, ptest, pxtest, err := load.TestPackagesFor(ctx, p, cover) if err != nil { return nil, nil, nil, err } @@ -863,7 +886,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin if !cfg.BuildN { // writeTestmain writes _testmain.go, // using the test description gathered in t. - if err := ioutil.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil { + if err := os.WriteFile(testDir+"_testmain.go", *pmain.Internal.TestmainGo, 0666); err != nil { return nil, nil, nil, err } } @@ -1068,7 +1091,7 @@ func (lockedStdout) Write(b []byte) (int, error) { } // builderRunTest is the action for running a test binary. -func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error { +func (c *runCache) builderRunTest(b *work.Builder, ctx context.Context, a *work.Action) error { if a.Failed { // We were unable to build the binary. a.Failed = false @@ -1145,7 +1168,8 @@ func (c *runCache) builderRunTest(b *work.Builder, a *work.Action) error { if !c.disableCache && len(execCmd) == 0 { testlogArg = []string{"-test.testlogfile=" + a.Objdir + "testlog.txt"} } - args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, testArgs) + panicArg := "-test.paniconexit0" + args := str.StringList(execCmd, a.Deps[0].BuiltTarget(), testlogArg, panicArg, testArgs) if testCoverProfile != "" { // Write coverage to temporary profile, for merging later. @@ -1539,13 +1563,18 @@ func hashOpen(name string) (cache.ActionID, error) { } hashWriteStat(h, info) if info.IsDir() { - names, err := ioutil.ReadDir(name) + files, err := os.ReadDir(name) if err != nil { fmt.Fprintf(h, "err %v\n", err) } - for _, f := range names { + for _, f := range files { fmt.Fprintf(h, "file %s ", f.Name()) - hashWriteStat(h, f) + finfo, err := f.Info() + if err != nil { + fmt.Fprintf(h, "err %v\n", err) + } else { + hashWriteStat(h, finfo) + } } } else if info.Mode().IsRegular() { // Because files might be very large, do not attempt @@ -1579,7 +1608,7 @@ func hashStat(name string) cache.ActionID { return h.Sum() } -func hashWriteStat(h io.Writer, info os.FileInfo) { +func hashWriteStat(h io.Writer, info fs.FileInfo) { fmt.Fprintf(h, "stat %d %x %v %v\n", info.Size(), uint64(info.Mode()), info.ModTime(), info.IsDir()) } @@ -1594,7 +1623,7 @@ func (c *runCache) saveOutput(a *work.Action) { } // See comment about two-level lookup in tryCacheWithID above. - testlog, err := ioutil.ReadFile(a.Objdir + "testlog.txt") + testlog, err := os.ReadFile(a.Objdir + "testlog.txt") if err != nil || !bytes.HasPrefix(testlog, testlogMagic) || testlog[len(testlog)-1] != '\n' { if cache.DebugTest { if err != nil { @@ -1645,7 +1674,7 @@ func coveragePercentage(out []byte) string { } // builderCleanTest is the action for cleaning up after a test. -func builderCleanTest(b *work.Builder, a *work.Action) error { +func builderCleanTest(b *work.Builder, ctx context.Context, a *work.Action) error { if cfg.BuildWork { return nil } @@ -1657,7 +1686,7 @@ func builderCleanTest(b *work.Builder, a *work.Action) error { } // builderPrintTest is the action for printing a test result. -func builderPrintTest(b *work.Builder, a *work.Action) error { +func builderPrintTest(b *work.Builder, ctx context.Context, a *work.Action) error { clean := a.Deps[0] run := clean.Deps[0] if run.TestOutput != nil { @@ -1668,7 +1697,7 @@ func builderPrintTest(b *work.Builder, a *work.Action) error { } // builderNoTest is the action for testing a package with no test files. -func builderNoTest(b *work.Builder, a *work.Action) error { +func builderNoTest(b *work.Builder, ctx context.Context, a *work.Action) error { var stdout io.Writer = os.Stdout if testJSON { json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp) @@ -1680,7 +1709,7 @@ func builderNoTest(b *work.Builder, a *work.Action) error { } // printExitStatus is the action for printing the exit status -func printExitStatus(b *work.Builder, a *work.Action) error { +func printExitStatus(b *work.Builder, ctx context.Context, a *work.Action) error { if !testJSON && len(pkgArgs) != 0 { if base.GetExitStatus() != 0 { fmt.Println("FAIL") diff --git a/libgo/go/cmd/go/internal/test/testflag.go b/libgo/go/cmd/go/internal/test/testflag.go index 4f0a8924f12..d2671ff5a79 100644 --- a/libgo/go/cmd/go/internal/test/testflag.go +++ b/libgo/go/cmd/go/internal/test/testflag.go @@ -212,6 +212,10 @@ func testFlags(args []string) (packageNames, passToTest []string) { } }) + // firstUnknownFlag helps us report an error when flags not known to 'go + // test' are used along with -i or -c. + firstUnknownFlag := "" + explicitArgs := make([]string, 0, len(args)) inPkgList := false afterFlagWithoutValue := false @@ -288,6 +292,10 @@ func testFlags(args []string) (packageNames, passToTest []string) { break } + if firstUnknownFlag == "" { + firstUnknownFlag = nd.RawArg + } + explicitArgs = append(explicitArgs, nd.RawArg) args = remainingArgs if !nd.HasValue { @@ -312,6 +320,14 @@ func testFlags(args []string) (packageNames, passToTest []string) { args = remainingArgs } + if firstUnknownFlag != "" && (testC || cfg.BuildI) { + buildFlag := "-c" + if !testC { + buildFlag = "-i" + } + fmt.Fprintf(os.Stderr, "flag %s is not a 'go test' flag (unknown flags cannot be used with %s)\n", firstUnknownFlag, buildFlag) + exitWithUsage() + } var injectedFlags []string if testJSON { diff --git a/libgo/go/cmd/go/internal/tool/tool.go b/libgo/go/cmd/go/internal/tool/tool.go index 930eecb63f1..7f4dc868021 100644 --- a/libgo/go/cmd/go/internal/tool/tool.go +++ b/libgo/go/cmd/go/internal/tool/tool.go @@ -6,6 +6,7 @@ package tool import ( + "context" "fmt" "os" "os/exec" @@ -48,7 +49,7 @@ func init() { CmdTool.Flag.BoolVar(&toolN, "n", false, "") } -func runTool(cmd *base.Command, args []string) { +func runTool(ctx context.Context, cmd *base.Command, args []string) { if len(args) == 0 { listTools() return diff --git a/libgo/go/cmd/go/internal/trace/trace.go b/libgo/go/cmd/go/internal/trace/trace.go new file mode 100644 index 00000000000..f108a2b6cae --- /dev/null +++ b/libgo/go/cmd/go/internal/trace/trace.go @@ -0,0 +1,206 @@ +// Copyright 2020 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 trace + +import ( + "cmd/internal/traceviewer" + "context" + "encoding/json" + "errors" + "os" + "strings" + "sync/atomic" + "time" +) + +// Constants used in event fields. +// See https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU +// for more details. +const ( + phaseDurationBegin = "B" + phaseDurationEnd = "E" + phaseFlowStart = "s" + phaseFlowEnd = "f" + + bindEnclosingSlice = "e" +) + +var traceStarted int32 + +func getTraceContext(ctx context.Context) (traceContext, bool) { + if atomic.LoadInt32(&traceStarted) == 0 { + return traceContext{}, false + } + v := ctx.Value(traceKey{}) + if v == nil { + return traceContext{}, false + } + return v.(traceContext), true +} + +// StartSpan starts a trace event with the given name. The Span ends when its Done method is called. +func StartSpan(ctx context.Context, name string) (context.Context, *Span) { + tc, ok := getTraceContext(ctx) + if !ok { + return ctx, nil + } + childSpan := &Span{t: tc.t, name: name, tid: tc.tid, start: time.Now()} + tc.t.writeEvent(&traceviewer.Event{ + Name: childSpan.name, + Time: float64(childSpan.start.UnixNano()) / float64(time.Microsecond), + TID: childSpan.tid, + Phase: phaseDurationBegin, + }) + ctx = context.WithValue(ctx, traceKey{}, traceContext{tc.t, tc.tid}) + return ctx, childSpan +} + +// StartGoroutine associates the context with a new Thread ID. The Chrome trace viewer associates each +// trace event with a thread, and doesn't expect events with the same thread id to happen at the +// same time. +func StartGoroutine(ctx context.Context) context.Context { + tc, ok := getTraceContext(ctx) + if !ok { + return ctx + } + return context.WithValue(ctx, traceKey{}, traceContext{tc.t, tc.t.getNextTID()}) +} + +// Flow marks a flow indicating that the 'to' span depends on the 'from' span. +// Flow should be called while the 'to' span is in progress. +func Flow(ctx context.Context, from *Span, to *Span) { + tc, ok := getTraceContext(ctx) + if !ok || from == nil || to == nil { + return + } + + id := tc.t.getNextFlowID() + tc.t.writeEvent(&traceviewer.Event{ + Name: from.name + " -> " + to.name, + Category: "flow", + ID: id, + Time: float64(from.end.UnixNano()) / float64(time.Microsecond), + Phase: phaseFlowStart, + TID: from.tid, + }) + tc.t.writeEvent(&traceviewer.Event{ + Name: from.name + " -> " + to.name, + Category: "flow", // TODO(matloob): Add Category to Flow? + ID: id, + Time: float64(to.start.UnixNano()) / float64(time.Microsecond), + Phase: phaseFlowEnd, + TID: to.tid, + BindPoint: bindEnclosingSlice, + }) +} + +type Span struct { + t *tracer + + name string + tid uint64 + start time.Time + end time.Time +} + +func (s *Span) Done() { + if s == nil { + return + } + s.end = time.Now() + s.t.writeEvent(&traceviewer.Event{ + Name: s.name, + Time: float64(s.end.UnixNano()) / float64(time.Microsecond), + TID: s.tid, + Phase: phaseDurationEnd, + }) +} + +type tracer struct { + file chan traceFile // 1-buffered + + nextTID uint64 + nextFlowID uint64 +} + +func (t *tracer) writeEvent(ev *traceviewer.Event) error { + f := <-t.file + defer func() { t.file <- f }() + var err error + if f.entries == 0 { + _, err = f.sb.WriteString("[\n") + } else { + _, err = f.sb.WriteString(",") + } + f.entries++ + if err != nil { + return nil + } + + if err := f.enc.Encode(ev); err != nil { + return err + } + + // Write event string to output file. + _, err = f.f.WriteString(f.sb.String()) + f.sb.Reset() + return err +} + +func (t *tracer) Close() error { + f := <-t.file + defer func() { t.file <- f }() + + _, firstErr := f.f.WriteString("]") + if err := f.f.Close(); firstErr == nil { + firstErr = err + } + return firstErr +} + +func (t *tracer) getNextTID() uint64 { + return atomic.AddUint64(&t.nextTID, 1) +} + +func (t *tracer) getNextFlowID() uint64 { + return atomic.AddUint64(&t.nextFlowID, 1) +} + +// traceKey is the context key for tracing information. It is unexported to prevent collisions with context keys defined in +// other packages. +type traceKey struct{} + +type traceContext struct { + t *tracer + tid uint64 +} + +// Start starts a trace which writes to the given file. +func Start(ctx context.Context, file string) (context.Context, func() error, error) { + atomic.StoreInt32(&traceStarted, 1) + if file == "" { + return nil, nil, errors.New("no trace file supplied") + } + f, err := os.Create(file) + if err != nil { + return nil, nil, err + } + t := &tracer{file: make(chan traceFile, 1)} + sb := new(strings.Builder) + t.file <- traceFile{ + f: f, + sb: sb, + enc: json.NewEncoder(sb), + } + ctx = context.WithValue(ctx, traceKey{}, traceContext{t: t}) + return ctx, t.Close, nil +} + +type traceFile struct { + f *os.File + sb *strings.Builder + enc *json.Encoder + entries int64 +} diff --git a/libgo/go/cmd/go/internal/txtar/archive.go b/libgo/go/cmd/go/internal/txtar/archive.go index c384f33bdf8..17966848771 100644 --- a/libgo/go/cmd/go/internal/txtar/archive.go +++ b/libgo/go/cmd/go/internal/txtar/archive.go @@ -34,7 +34,7 @@ package txtar import ( "bytes" "fmt" - "io/ioutil" + "os" "strings" ) @@ -66,7 +66,7 @@ func Format(a *Archive) []byte { // ParseFile parses the named file as an archive. func ParseFile(file string) (*Archive, error) { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err != nil { return nil, err } diff --git a/libgo/go/cmd/go/internal/get/discovery.go b/libgo/go/cmd/go/internal/vcs/discovery.go similarity index 99% rename from libgo/go/cmd/go/internal/get/discovery.go rename to libgo/go/cmd/go/internal/vcs/discovery.go index afa6ef455f9..327b44cb9af 100644 --- a/libgo/go/cmd/go/internal/get/discovery.go +++ b/libgo/go/cmd/go/internal/vcs/discovery.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. -package get +package vcs import ( "encoding/xml" diff --git a/libgo/go/cmd/go/internal/get/pkg_test.go b/libgo/go/cmd/go/internal/vcs/discovery_test.go similarity index 85% rename from libgo/go/cmd/go/internal/get/pkg_test.go rename to libgo/go/cmd/go/internal/vcs/discovery_test.go index fc6a179c2e1..eb99fdf64c1 100644 --- a/libgo/go/cmd/go/internal/get/pkg_test.go +++ b/libgo/go/cmd/go/internal/vcs/discovery_test.go @@ -2,35 +2,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package get +package vcs import ( - "cmd/go/internal/str" "reflect" "strings" "testing" ) -var foldDupTests = []struct { - list []string - f1, f2 string -}{ - {str.StringList("math/rand", "math/big"), "", ""}, - {str.StringList("math", "strings"), "", ""}, - {str.StringList("strings"), "", ""}, - {str.StringList("strings", "strings"), "strings", "strings"}, - {str.StringList("Rand", "rand", "math", "math/rand", "math/Rand"), "Rand", "rand"}, -} - -func TestFoldDup(t *testing.T) { - for _, tt := range foldDupTests { - f1, f2 := str.FoldDup(tt.list) - if f1 != tt.f1 || f2 != tt.f2 { - t.Errorf("foldDup(%q) = %q, %q, want %q, %q", tt.list, f1, f2, tt.f1, tt.f2) - } - } -} - var parseMetaGoImportsTests = []struct { in string mod ModuleMode diff --git a/libgo/go/cmd/go/internal/get/vcs.go b/libgo/go/cmd/go/internal/vcs/vcs.go similarity index 66% rename from libgo/go/cmd/go/internal/get/vcs.go rename to libgo/go/cmd/go/internal/vcs/vcs.go index fd37fcb76f2..4894ecdc356 100644 --- a/libgo/go/cmd/go/internal/get/vcs.go +++ b/libgo/go/cmd/go/internal/vcs/vcs.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. -package get +package vcs import ( "encoding/json" @@ -10,6 +10,7 @@ import ( "fmt" "internal/lazyregexp" "internal/singleflight" + "io/fs" "log" urlpkg "net/url" "os" @@ -21,29 +22,32 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/load" + "cmd/go/internal/search" + "cmd/go/internal/str" "cmd/go/internal/web" + + "golang.org/x/mod/module" ) // A vcsCmd describes how to use a version control system // like Mercurial, Git, or Subversion. -type vcsCmd struct { - name string - cmd string // name of binary to invoke command +type Cmd struct { + Name string + Cmd string // name of binary to invoke command - createCmd []string // commands to download a fresh copy of a repository - downloadCmd []string // commands to download updates into an existing repository + CreateCmd []string // commands to download a fresh copy of a repository + DownloadCmd []string // commands to download updates into an existing repository - tagCmd []tagCmd // commands to list tags - tagLookupCmd []tagCmd // commands to lookup tags before running tagSyncCmd - tagSyncCmd []string // commands to sync to specific tag - tagSyncDefault []string // commands to sync to default tag + TagCmd []tagCmd // commands to list tags + TagLookupCmd []tagCmd // commands to lookup tags before running tagSyncCmd + TagSyncCmd []string // commands to sync to specific tag + TagSyncDefault []string // commands to sync to default tag - scheme []string - pingCmd string + Scheme []string + PingCmd string - remoteRepo func(v *vcsCmd, rootDir string) (remoteRepo string, err error) - resolveRepo func(v *vcsCmd, rootDir, remoteRepo string) (realRepo string, err error) + RemoteRepo func(v *Cmd, rootDir string) (remoteRepo string, err error) + ResolveRepo func(v *Cmd, rootDir, remoteRepo string) (realRepo string, err error) } var defaultSecureScheme = map[string]bool{ @@ -54,7 +58,7 @@ var defaultSecureScheme = map[string]bool{ "ssh": true, } -func (v *vcsCmd) isSecure(repo string) bool { +func (v *Cmd) IsSecure(repo string) bool { u, err := urlpkg.Parse(repo) if err != nil { // If repo is not a URL, it's not secure. @@ -63,8 +67,8 @@ func (v *vcsCmd) isSecure(repo string) bool { return v.isSecureScheme(u.Scheme) } -func (v *vcsCmd) isSecureScheme(scheme string) bool { - switch v.cmd { +func (v *Cmd) isSecureScheme(scheme string) bool { + switch v.Cmd { case "git": // GIT_ALLOW_PROTOCOL is an environment variable defined by Git. It is a // colon-separated list of schemes that are allowed to be used with git @@ -89,7 +93,7 @@ type tagCmd struct { } // vcsList lists the known version control systems -var vcsList = []*vcsCmd{ +var vcsList = []*Cmd{ vcsHg, vcsGit, vcsSvn, @@ -97,11 +101,15 @@ var vcsList = []*vcsCmd{ vcsFossil, } +// vcsMod is a stub for the "mod" scheme. It's returned by +// repoRootForImportPathDynamic, but is otherwise not treated as a VCS command. +var vcsMod = &Cmd{Name: "mod"} + // vcsByCmd returns the version control system for the given // command name (hg, git, svn, bzr). -func vcsByCmd(cmd string) *vcsCmd { +func vcsByCmd(cmd string) *Cmd { for _, vcs := range vcsList { - if vcs.cmd == cmd { + if vcs.Cmd == cmd { return vcs } } @@ -109,31 +117,31 @@ func vcsByCmd(cmd string) *vcsCmd { } // vcsHg describes how to use Mercurial. -var vcsHg = &vcsCmd{ - name: "Mercurial", - cmd: "hg", +var vcsHg = &Cmd{ + Name: "Mercurial", + Cmd: "hg", - createCmd: []string{"clone -U -- {repo} {dir}"}, - downloadCmd: []string{"pull"}, + CreateCmd: []string{"clone -U -- {repo} {dir}"}, + DownloadCmd: []string{"pull"}, // We allow both tag and branch names as 'tags' // for selecting a version. This lets people have // a go.release.r60 branch and a go1 branch // and make changes in both, without constantly // editing .hgtags. - tagCmd: []tagCmd{ + TagCmd: []tagCmd{ {"tags", `^(\S+)`}, {"branches", `^(\S+)`}, }, - tagSyncCmd: []string{"update -r {tag}"}, - tagSyncDefault: []string{"update default"}, + TagSyncCmd: []string{"update -r {tag}"}, + TagSyncDefault: []string{"update default"}, - scheme: []string{"https", "http", "ssh"}, - pingCmd: "identify -- {scheme}://{repo}", - remoteRepo: hgRemoteRepo, + Scheme: []string{"https", "http", "ssh"}, + PingCmd: "identify -- {scheme}://{repo}", + RemoteRepo: hgRemoteRepo, } -func hgRemoteRepo(vcsHg *vcsCmd, rootDir string) (remoteRepo string, err error) { +func hgRemoteRepo(vcsHg *Cmd, rootDir string) (remoteRepo string, err error) { out, err := vcsHg.runOutput(rootDir, "paths default") if err != nil { return "", err @@ -142,45 +150,45 @@ func hgRemoteRepo(vcsHg *vcsCmd, rootDir string) (remoteRepo string, err error) } // vcsGit describes how to use Git. -var vcsGit = &vcsCmd{ - name: "Git", - cmd: "git", +var vcsGit = &Cmd{ + Name: "Git", + Cmd: "git", - createCmd: []string{"clone -- {repo} {dir}", "-go-internal-cd {dir} submodule update --init --recursive"}, - downloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"}, + CreateCmd: []string{"clone -- {repo} {dir}", "-go-internal-cd {dir} submodule update --init --recursive"}, + DownloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"}, - tagCmd: []tagCmd{ + TagCmd: []tagCmd{ // tags/xxx matches a git tag named xxx // origin/xxx matches a git branch named xxx on the default remote repository {"show-ref", `(?:tags|origin)/(\S+)$`}, }, - tagLookupCmd: []tagCmd{ + TagLookupCmd: []tagCmd{ {"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`}, }, - tagSyncCmd: []string{"checkout {tag}", "submodule update --init --recursive"}, + TagSyncCmd: []string{"checkout {tag}", "submodule update --init --recursive"}, // both createCmd and downloadCmd update the working dir. // No need to do more here. We used to 'checkout master' // but that doesn't work if the default branch is not named master. // DO NOT add 'checkout master' here. // See golang.org/issue/9032. - tagSyncDefault: []string{"submodule update --init --recursive"}, + TagSyncDefault: []string{"submodule update --init --recursive"}, - scheme: []string{"git", "https", "http", "git+ssh", "ssh"}, + Scheme: []string{"git", "https", "http", "git+ssh", "ssh"}, // Leave out the '--' separator in the ls-remote command: git 2.7.4 does not // support such a separator for that command, and this use should be safe // without it because the {scheme} value comes from the predefined list above. // See golang.org/issue/33836. - pingCmd: "ls-remote {scheme}://{repo}", + PingCmd: "ls-remote {scheme}://{repo}", - remoteRepo: gitRemoteRepo, + RemoteRepo: gitRemoteRepo, } // scpSyntaxRe matches the SCP-like addresses used by Git to access // repositories by SSH. var scpSyntaxRe = lazyregexp.New(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`) -func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error) { +func gitRemoteRepo(vcsGit *Cmd, rootDir string) (remoteRepo string, err error) { cmd := "config remote.origin.url" errParse := errors.New("unable to parse output of git " + cmd) errRemoteOriginNotFound := errors.New("remote origin not found") @@ -216,7 +224,7 @@ func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error // Iterate over insecure schemes too, because this function simply // reports the state of the repo. If we can't see insecure schemes then // we can't report the actual repo URL. - for _, s := range vcsGit.scheme { + for _, s := range vcsGit.Scheme { if repoURL.Scheme == s { return repoURL.String(), nil } @@ -225,27 +233,27 @@ func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error } // vcsBzr describes how to use Bazaar. -var vcsBzr = &vcsCmd{ - name: "Bazaar", - cmd: "bzr", +var vcsBzr = &Cmd{ + Name: "Bazaar", + Cmd: "bzr", - createCmd: []string{"branch -- {repo} {dir}"}, + CreateCmd: []string{"branch -- {repo} {dir}"}, // Without --overwrite bzr will not pull tags that changed. // Replace by --overwrite-tags after http://pad.lv/681792 goes in. - downloadCmd: []string{"pull --overwrite"}, + DownloadCmd: []string{"pull --overwrite"}, - tagCmd: []tagCmd{{"tags", `^(\S+)`}}, - tagSyncCmd: []string{"update -r {tag}"}, - tagSyncDefault: []string{"update -r revno:-1"}, + TagCmd: []tagCmd{{"tags", `^(\S+)`}}, + TagSyncCmd: []string{"update -r {tag}"}, + TagSyncDefault: []string{"update -r revno:-1"}, - scheme: []string{"https", "http", "bzr", "bzr+ssh"}, - pingCmd: "info -- {scheme}://{repo}", - remoteRepo: bzrRemoteRepo, - resolveRepo: bzrResolveRepo, + Scheme: []string{"https", "http", "bzr", "bzr+ssh"}, + PingCmd: "info -- {scheme}://{repo}", + RemoteRepo: bzrRemoteRepo, + ResolveRepo: bzrResolveRepo, } -func bzrRemoteRepo(vcsBzr *vcsCmd, rootDir string) (remoteRepo string, err error) { +func bzrRemoteRepo(vcsBzr *Cmd, rootDir string) (remoteRepo string, err error) { outb, err := vcsBzr.runOutput(rootDir, "config parent_location") if err != nil { return "", err @@ -253,7 +261,7 @@ func bzrRemoteRepo(vcsBzr *vcsCmd, rootDir string) (remoteRepo string, err error return strings.TrimSpace(string(outb)), nil } -func bzrResolveRepo(vcsBzr *vcsCmd, rootDir, remoteRepo string) (realRepo string, err error) { +func bzrResolveRepo(vcsBzr *Cmd, rootDir, remoteRepo string) (realRepo string, err error) { outb, err := vcsBzr.runOutput(rootDir, "info "+remoteRepo) if err != nil { return "", err @@ -287,22 +295,22 @@ func bzrResolveRepo(vcsBzr *vcsCmd, rootDir, remoteRepo string) (realRepo string } // vcsSvn describes how to use Subversion. -var vcsSvn = &vcsCmd{ - name: "Subversion", - cmd: "svn", +var vcsSvn = &Cmd{ + Name: "Subversion", + Cmd: "svn", - createCmd: []string{"checkout -- {repo} {dir}"}, - downloadCmd: []string{"update"}, + CreateCmd: []string{"checkout -- {repo} {dir}"}, + DownloadCmd: []string{"update"}, // There is no tag command in subversion. // The branch information is all in the path names. - scheme: []string{"https", "http", "svn", "svn+ssh"}, - pingCmd: "info -- {scheme}://{repo}", - remoteRepo: svnRemoteRepo, + Scheme: []string{"https", "http", "svn", "svn+ssh"}, + PingCmd: "info -- {scheme}://{repo}", + RemoteRepo: svnRemoteRepo, } -func svnRemoteRepo(vcsSvn *vcsCmd, rootDir string) (remoteRepo string, err error) { +func svnRemoteRepo(vcsSvn *Cmd, rootDir string) (remoteRepo string, err error) { outb, err := vcsSvn.runOutput(rootDir, "info") if err != nil { return "", err @@ -337,22 +345,22 @@ func svnRemoteRepo(vcsSvn *vcsCmd, rootDir string) (remoteRepo string, err error const fossilRepoName = ".fossil" // vcsFossil describes how to use Fossil (fossil-scm.org) -var vcsFossil = &vcsCmd{ - name: "Fossil", - cmd: "fossil", +var vcsFossil = &Cmd{ + Name: "Fossil", + Cmd: "fossil", - createCmd: []string{"-go-internal-mkdir {dir} clone -- {repo} " + filepath.Join("{dir}", fossilRepoName), "-go-internal-cd {dir} open .fossil"}, - downloadCmd: []string{"up"}, + CreateCmd: []string{"-go-internal-mkdir {dir} clone -- {repo} " + filepath.Join("{dir}", fossilRepoName), "-go-internal-cd {dir} open .fossil"}, + DownloadCmd: []string{"up"}, - tagCmd: []tagCmd{{"tag ls", `(.*)`}}, - tagSyncCmd: []string{"up tag:{tag}"}, - tagSyncDefault: []string{"up trunk"}, + TagCmd: []tagCmd{{"tag ls", `(.*)`}}, + TagSyncCmd: []string{"up tag:{tag}"}, + TagSyncDefault: []string{"up trunk"}, - scheme: []string{"https", "http"}, - remoteRepo: fossilRemoteRepo, + Scheme: []string{"https", "http"}, + RemoteRepo: fossilRemoteRepo, } -func fossilRemoteRepo(vcsFossil *vcsCmd, rootDir string) (remoteRepo string, err error) { +func fossilRemoteRepo(vcsFossil *Cmd, rootDir string) (remoteRepo string, err error) { out, err := vcsFossil.runOutput(rootDir, "remote-url") if err != nil { return "", err @@ -360,8 +368,8 @@ func fossilRemoteRepo(vcsFossil *vcsCmd, rootDir string) (remoteRepo string, err return strings.TrimSpace(string(out)), nil } -func (v *vcsCmd) String() string { - return v.name +func (v *Cmd) String() string { + return v.Name } // run runs the command line cmd in the given directory. @@ -371,24 +379,24 @@ func (v *vcsCmd) String() string { // If an error occurs, run prints the command line and the // command's combined stdout+stderr to standard error. // Otherwise run discards the command's output. -func (v *vcsCmd) run(dir string, cmd string, keyval ...string) error { +func (v *Cmd) run(dir string, cmd string, keyval ...string) error { _, err := v.run1(dir, cmd, keyval, true) return err } // runVerboseOnly is like run but only generates error output to standard error in verbose mode. -func (v *vcsCmd) runVerboseOnly(dir string, cmd string, keyval ...string) error { +func (v *Cmd) runVerboseOnly(dir string, cmd string, keyval ...string) error { _, err := v.run1(dir, cmd, keyval, false) return err } // runOutput is like run but returns the output of the command. -func (v *vcsCmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) { +func (v *Cmd) runOutput(dir string, cmd string, keyval ...string) ([]byte, error) { return v.run1(dir, cmd, keyval, true) } // run1 is the generalized implementation of run and runOutput. -func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) { +func (v *Cmd) run1(dir string, cmdline string, keyval []string, verbose bool) ([]byte, error) { m := make(map[string]string) for i := 0; i < len(keyval); i += 2 { m[keyval[i]] = keyval[i+1] @@ -401,9 +409,9 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) if len(args) >= 2 && args[0] == "-go-internal-mkdir" { var err error if filepath.IsAbs(args[1]) { - err = os.Mkdir(args[1], os.ModePerm) + err = os.Mkdir(args[1], fs.ModePerm) } else { - err = os.Mkdir(filepath.Join(dir, args[1]), os.ModePerm) + err = os.Mkdir(filepath.Join(dir, args[1]), fs.ModePerm) } if err != nil { return nil, err @@ -420,25 +428,25 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) args = args[2:] } - _, err := exec.LookPath(v.cmd) + _, err := exec.LookPath(v.Cmd) if err != nil { fmt.Fprintf(os.Stderr, "go: missing %s command. See https://golang.org/s/gogetcmd\n", - v.name) + v.Name) return nil, err } - cmd := exec.Command(v.cmd, args...) + cmd := exec.Command(v.Cmd, args...) cmd.Dir = dir cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) if cfg.BuildX { fmt.Fprintf(os.Stderr, "cd %s\n", dir) - fmt.Fprintf(os.Stderr, "%s %s\n", v.cmd, strings.Join(args, " ")) + fmt.Fprintf(os.Stderr, "%s %s\n", v.Cmd, strings.Join(args, " ")) } out, err := cmd.Output() if err != nil { if verbose || cfg.BuildV { - fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " ")) + fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.Cmd, strings.Join(args, " ")) if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { os.Stderr.Write(ee.Stderr) } else { @@ -449,15 +457,15 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool) return out, err } -// ping pings to determine scheme to use. -func (v *vcsCmd) ping(scheme, repo string) error { - return v.runVerboseOnly(".", v.pingCmd, "scheme", scheme, "repo", repo) +// Ping pings to determine scheme to use. +func (v *Cmd) Ping(scheme, repo string) error { + return v.runVerboseOnly(".", v.PingCmd, "scheme", scheme, "repo", repo) } -// create creates a new copy of repo in dir. +// Create creates a new copy of repo in dir. // The parent of dir must exist; dir must not. -func (v *vcsCmd) create(dir, repo string) error { - for _, cmd := range v.createCmd { +func (v *Cmd) Create(dir, repo string) error { + for _, cmd := range v.CreateCmd { if err := v.run(".", cmd, "dir", dir, "repo", repo); err != nil { return err } @@ -465,9 +473,9 @@ func (v *vcsCmd) create(dir, repo string) error { return nil } -// download downloads any new changes for the repo in dir. -func (v *vcsCmd) download(dir string) error { - for _, cmd := range v.downloadCmd { +// Download downloads any new changes for the repo in dir. +func (v *Cmd) Download(dir string) error { + for _, cmd := range v.DownloadCmd { if err := v.run(dir, cmd); err != nil { return err } @@ -475,10 +483,10 @@ func (v *vcsCmd) download(dir string) error { return nil } -// tags returns the list of available tags for the repo in dir. -func (v *vcsCmd) tags(dir string) ([]string, error) { +// Tags returns the list of available tags for the repo in dir. +func (v *Cmd) Tags(dir string) ([]string, error) { var tags []string - for _, tc := range v.tagCmd { + for _, tc := range v.TagCmd { out, err := v.runOutput(dir, tc.cmd) if err != nil { return nil, err @@ -493,12 +501,12 @@ func (v *vcsCmd) tags(dir string) ([]string, error) { // tagSync syncs the repo in dir to the named tag, // which either is a tag returned by tags or is v.tagDefault. -func (v *vcsCmd) tagSync(dir, tag string) error { - if v.tagSyncCmd == nil { +func (v *Cmd) TagSync(dir, tag string) error { + if v.TagSyncCmd == nil { return nil } if tag != "" { - for _, tc := range v.tagLookupCmd { + for _, tc := range v.TagLookupCmd { out, err := v.runOutput(dir, tc.cmd, "tag", tag) if err != nil { return err @@ -512,8 +520,8 @@ func (v *vcsCmd) tagSync(dir, tag string) error { } } - if tag == "" && v.tagSyncDefault != nil { - for _, cmd := range v.tagSyncDefault { + if tag == "" && v.TagSyncDefault != nil { + for _, cmd := range v.TagSyncDefault { if err := v.run(dir, cmd); err != nil { return err } @@ -521,7 +529,7 @@ func (v *vcsCmd) tagSync(dir, tag string) error { return nil } - for _, cmd := range v.tagSyncCmd { + for _, cmd := range v.TagSyncCmd { if err := v.run(dir, cmd, "tag", tag); err != nil { return err } @@ -532,7 +540,7 @@ 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 + pathPrefix 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) @@ -540,11 +548,11 @@ type vcsPath struct { schemelessRepo bool // if true, the repo pattern lacks a scheme } -// vcsFromDir inspects dir and its parents to determine the +// FromDir inspects dir and its parents to determine the // version control system and code repository to use. // On return, root is the import path // corresponding to the root of the repository. -func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) { +func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error) { // Clean and double-check that dir is in (a subdirectory of) srcRoot. dir = filepath.Clean(dir) srcRoot = filepath.Clean(srcRoot) @@ -552,13 +560,13 @@ func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) { return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot) } - var vcsRet *vcsCmd + var vcsRet *Cmd var rootRet string origDir := dir for len(dir) > len(srcRoot) { for _, vcs := range vcsList { - if _, err := os.Stat(filepath.Join(dir, "."+vcs.cmd)); err == nil { + if _, err := os.Stat(filepath.Join(dir, "."+vcs.Cmd)); err == nil { root := filepath.ToSlash(dir[len(srcRoot)+1:]) // Record first VCS we find, but keep looking, // to detect mistakes like one kind of VCS inside another. @@ -568,12 +576,12 @@ func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) { continue } // Allow .git inside .git, which can arise due to submodules. - if vcsRet == vcs && vcs.cmd == "git" { + if vcsRet == vcs && vcs.Cmd == "git" { continue } // Otherwise, we have one VCS inside a different VCS. return nil, "", fmt.Errorf("directory %q uses %s, but parent %q uses %s", - filepath.Join(srcRoot, rootRet), vcsRet.cmd, filepath.Join(srcRoot, root), vcs.cmd) + filepath.Join(srcRoot, rootRet), vcsRet.Cmd, filepath.Join(srcRoot, root), vcs.Cmd) } } @@ -587,15 +595,149 @@ func vcsFromDir(dir, srcRoot string) (vcs *vcsCmd, root string, err error) { } if vcsRet != nil { + if err := checkGOVCS(vcsRet, rootRet); err != nil { + return nil, "", err + } return vcsRet, rootRet, nil } return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir) } -// checkNestedVCS checks for an incorrectly-nested VCS-inside-VCS +// A govcsRule is a single GOVCS rule like private:hg|svn. +type govcsRule struct { + pattern string + allowed []string +} + +// A govcsConfig is a full GOVCS configuration. +type govcsConfig []govcsRule + +func parseGOVCS(s string) (govcsConfig, error) { + s = strings.TrimSpace(s) + if s == "" { + return nil, nil + } + var cfg govcsConfig + have := make(map[string]string) + for _, item := range strings.Split(s, ",") { + item = strings.TrimSpace(item) + if item == "" { + return nil, fmt.Errorf("empty entry in GOVCS") + } + i := strings.Index(item, ":") + if i < 0 { + return nil, fmt.Errorf("malformed entry in GOVCS (missing colon): %q", item) + } + pattern, list := strings.TrimSpace(item[:i]), strings.TrimSpace(item[i+1:]) + if pattern == "" { + return nil, fmt.Errorf("empty pattern in GOVCS: %q", item) + } + if list == "" { + return nil, fmt.Errorf("empty VCS list in GOVCS: %q", item) + } + if search.IsRelativePath(pattern) { + return nil, fmt.Errorf("relative pattern not allowed in GOVCS: %q", pattern) + } + if old := have[pattern]; old != "" { + return nil, fmt.Errorf("unreachable pattern in GOVCS: %q after %q", item, old) + } + have[pattern] = item + allowed := strings.Split(list, "|") + for i, a := range allowed { + a = strings.TrimSpace(a) + if a == "" { + return nil, fmt.Errorf("empty VCS name in GOVCS: %q", item) + } + allowed[i] = a + } + cfg = append(cfg, govcsRule{pattern, allowed}) + } + return cfg, nil +} + +func (c *govcsConfig) allow(path string, private bool, vcs string) bool { + for _, rule := range *c { + match := false + switch rule.pattern { + case "private": + match = private + case "public": + match = !private + default: + // Note: rule.pattern is known to be comma-free, + // so MatchPrefixPatterns is only matching a single pattern for us. + match = module.MatchPrefixPatterns(rule.pattern, path) + } + if !match { + continue + } + for _, allow := range rule.allowed { + if allow == vcs || allow == "all" { + return true + } + } + return false + } + + // By default, nothing is allowed. + return false +} + +var ( + govcs govcsConfig + govcsErr error + govcsOnce sync.Once +) + +// defaultGOVCS is the default setting for GOVCS. +// Setting GOVCS adds entries ahead of these but does not remove them. +// (They are appended to the parsed GOVCS setting.) +// +// The rationale behind allowing only Git and Mercurial is that +// these two systems have had the most attention to issues +// of being run as clients of untrusted servers. In contrast, +// Bazaar, Fossil, and Subversion have primarily been used +// in trusted, authenticated environments and are not as well +// scrutinized as attack surfaces. +// +// See golang.org/issue/41730 for details. +var defaultGOVCS = govcsConfig{ + {"private", []string{"all"}}, + {"public", []string{"git", "hg"}}, +} + +func checkGOVCS(vcs *Cmd, root string) error { + if vcs == vcsMod { + // Direct module (proxy protocol) fetches don't + // involve an external version control system + // and are always allowed. + return nil + } + + govcsOnce.Do(func() { + govcs, govcsErr = parseGOVCS(os.Getenv("GOVCS")) + govcs = append(govcs, defaultGOVCS...) + }) + if govcsErr != nil { + return govcsErr + } + + private := module.MatchPrefixPatterns(cfg.GOPRIVATE, root) + if !govcs.allow(root, private, vcs.Cmd) { + what := "public" + if private { + what = "private" + } + return fmt.Errorf("GOVCS disallows using %s for %s %s", vcs.Cmd, what, root) + } + + return nil +} + +// CheckNested checks for an incorrectly-nested VCS-inside-VCS // situation for dir, checking parents up until srcRoot. -func checkNestedVCS(vcs *vcsCmd, dir, srcRoot string) error { +func CheckNested(vcs *Cmd, dir, srcRoot string) error { if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator { return fmt.Errorf("directory %q is outside source root %q", dir, srcRoot) } @@ -603,17 +745,17 @@ func checkNestedVCS(vcs *vcsCmd, dir, srcRoot string) error { otherDir := dir for len(otherDir) > len(srcRoot) { for _, otherVCS := range vcsList { - if _, err := os.Stat(filepath.Join(otherDir, "."+otherVCS.cmd)); err == nil { + if _, err := os.Stat(filepath.Join(otherDir, "."+otherVCS.Cmd)); err == nil { // Allow expected vcs in original dir. if otherDir == dir && otherVCS == vcs { continue } // Allow .git inside .git, which can arise due to submodules. - if otherVCS == vcs && vcs.cmd == "git" { + if otherVCS == vcs && vcs.Cmd == "git" { continue } // Otherwise, we have one VCS inside a different VCS. - return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.cmd, otherDir, otherVCS.cmd) + return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.Cmd, otherDir, otherVCS.Cmd) } } // Move to parent. @@ -633,9 +775,7 @@ type RepoRoot struct { Repo string // repository URL, including scheme Root string // import path corresponding to root of repo IsCustom bool // defined by served tags (as opposed to hard-coded pattern) - VCS string // vcs type ("mod", "git", ...) - - vcs *vcsCmd // internal: vcs command access + VCS *Cmd } func httpPrefix(s string) string { @@ -662,7 +802,7 @@ func RepoRootForImportPath(importPath string, mod ModuleMode, security web.Secur if err == errUnknownSite { rr, err = repoRootForImportDynamic(importPath, mod, security) if err != nil { - err = load.ImportErrorf(importPath, "unrecognized import path %q: %v", importPath, err) + err = importErrorf(importPath, "unrecognized import path %q: %v", importPath, err) } } if err != nil { @@ -677,7 +817,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 = load.ImportErrorf(importPath, "cannot expand ... in %q", importPath) + err = importErrorf(importPath, "cannot expand ... in %q", importPath) } return rr, err } @@ -687,6 +827,20 @@ var errUnknownSite = errors.New("dynamic lookup required to find mapping") // repoRootFromVCSPaths attempts to map importPath to a repoRoot // using the mappings defined in vcsPaths. func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths []*vcsPath) (*RepoRoot, error) { + if str.HasPathPrefix(importPath, "example.net") { + // TODO(rsc): This should not be necessary, but it's required to keep + // tests like ../../testdata/script/mod_get_extra.txt from using the network. + // That script has everything it needs in the replacement set, but it is still + // doing network calls. + return nil, fmt.Errorf("no modules on example.net") + } + if importPath == "rsc.io" { + // This special case allows tests like ../../testdata/script/govcs.txt + // to avoid making any network calls. The module lookup for a path + // like rsc.io/nonexist.svn/foo needs to not make a network call for + // a lookup on rsc.io. + return nil, fmt.Errorf("rsc.io is not a module") + } // A common error is to use https://packagepath because that's what // hg and git require. Diagnose this helpfully. if prefix := httpPrefix(importPath); prefix != "" { @@ -695,20 +849,20 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths return nil, fmt.Errorf("%q not allowed in import path", prefix+"//") } for _, srv := range vcsPaths { - if !strings.HasPrefix(importPath, srv.prefix) { + if !str.HasPathPrefix(importPath, srv.pathPrefix) { continue } m := srv.regexp.FindStringSubmatch(importPath) if m == nil { - if srv.prefix != "" { - return nil, load.ImportErrorf(importPath, "invalid %s import path %q", srv.prefix, importPath) + if srv.pathPrefix != "" { + return nil, importErrorf(importPath, "invalid %s import path %q", srv.pathPrefix, importPath) } continue } // Build map of named subexpression matches for expand. match := map[string]string{ - "prefix": srv.prefix, + "prefix": srv.pathPrefix + "/", "import": importPath, } for i, name := range srv.regexp.SubexpNames() { @@ -731,19 +885,22 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths if vcs == nil { return nil, fmt.Errorf("unknown version control system %q", match["vcs"]) } + if err := checkGOVCS(vcs, match["root"]); err != nil { + return nil, err + } var repoURL string if !srv.schemelessRepo { repoURL = match["repo"] } else { - scheme := vcs.scheme[0] // default to first scheme + scheme := vcs.Scheme[0] // default to first scheme repo := match["repo"] - if vcs.pingCmd != "" { + if vcs.PingCmd != "" { // If we know how to test schemes, scan to find one. - for _, s := range vcs.scheme { + for _, s := range vcs.Scheme { if security == web.SecureOnly && !vcs.isSecureScheme(s) { continue } - if vcs.ping(s, repo) == nil { + if vcs.Ping(s, repo) == nil { scheme = s break } @@ -754,8 +911,7 @@ func repoRootFromVCSPaths(importPath string, security web.SecurityMode, vcsPaths rr := &RepoRoot{ Repo: repoURL, Root: match["root"], - VCS: vcs.cmd, - vcs: vcs, + VCS: vcs, } return rr, nil } @@ -846,17 +1002,25 @@ func repoRootForImportDynamic(importPath string, mod ModuleMode, security web.Se if err := validateRepoRoot(mmi.RepoRoot); err != nil { return nil, fmt.Errorf("%s: invalid repo root %q: %v", resp.URL, mmi.RepoRoot, err) } - vcs := vcsByCmd(mmi.VCS) - if vcs == nil && mmi.VCS != "mod" { - return nil, fmt.Errorf("%s: unknown vcs %q", resp.URL, mmi.VCS) + var vcs *Cmd + if mmi.VCS == "mod" { + vcs = vcsMod + } else { + vcs = vcsByCmd(mmi.VCS) + if vcs == nil { + return nil, fmt.Errorf("%s: unknown vcs %q", resp.URL, mmi.VCS) + } + } + + if err := checkGOVCS(vcs, mmi.Prefix); err != nil { + return nil, err } rr := &RepoRoot{ Repo: mmi.RepoRoot, Root: mmi.Prefix, IsCustom: true, - VCS: mmi.VCS, - vcs: vcs, + VCS: vcs, } return rr, nil } @@ -949,18 +1113,6 @@ type metaImport struct { Prefix, VCS, RepoRoot string } -// pathPrefix reports whether sub is a prefix of s, -// only considering entire path components. -func pathPrefix(s, sub string) bool { - // strings.HasPrefix is necessary but not sufficient. - if !strings.HasPrefix(s, sub) { - return false - } - // The remainder after the prefix must either be empty or start with a slash. - rem := s[len(sub):] - return rem == "" || rem[0] == '/' -} - // A ImportMismatchError is returned where metaImport/s are present // but none match our import path. type ImportMismatchError struct { @@ -984,7 +1136,7 @@ func matchGoImport(imports []metaImport, importPath string) (metaImport, error) errImportMismatch := ImportMismatchError{importPath: importPath} for i, im := range imports { - if !pathPrefix(importPath, im.Prefix) { + if !str.HasPathPrefix(importPath, im.Prefix) { errImportMismatch.mismatches = append(errImportMismatch.mismatches, im.Prefix) continue } @@ -1026,52 +1178,52 @@ func expand(match map[string]string, s string) string { var vcsPaths = []*vcsPath{ // Github { - prefix: "github.com/", - regexp: lazyregexp.New(`^(?Pgithub\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[\p{L}0-9_.\-]+)*$`), - vcs: "git", - repo: "https://{root}", - check: noVCSSuffix, + pathPrefix: "github.com", + regexp: lazyregexp.New(`^(?Pgithub\.com/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`), + vcs: "git", + repo: "https://{root}", + check: noVCSSuffix, }, // Bitbucket { - prefix: "bitbucket.org/", - regexp: lazyregexp.New(`^(?Pbitbucket\.org/(?P[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`), - repo: "https://{root}", - check: bitbucketVCS, + pathPrefix: "bitbucket.org", + regexp: lazyregexp.New(`^(?Pbitbucket\.org/(?P[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`), + repo: "https://{root}", + check: bitbucketVCS, }, // IBM DevOps Services (JazzHub) { - prefix: "hub.jazz.net/git/", - regexp: lazyregexp.New(`^(?Phub\.jazz\.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`), - vcs: "git", - repo: "https://{root}", - check: noVCSSuffix, + pathPrefix: "hub.jazz.net/git", + regexp: lazyregexp.New(`^(?Phub\.jazz\.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`), + vcs: "git", + repo: "https://{root}", + check: noVCSSuffix, }, // Git at Apache { - prefix: "git.apache.org/", - regexp: lazyregexp.New(`^(?Pgit\.apache\.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`), - vcs: "git", - repo: "https://{root}", + pathPrefix: "git.apache.org", + regexp: lazyregexp.New(`^(?Pgit\.apache\.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`), + vcs: "git", + repo: "https://{root}", }, // Git at OpenStack { - prefix: "git.openstack.org/", - regexp: lazyregexp.New(`^(?Pgit\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`), - vcs: "git", - repo: "https://{root}", + pathPrefix: "git.openstack.org", + regexp: lazyregexp.New(`^(?Pgit\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)(\.git)?(/[A-Za-z0-9_.\-]+)*$`), + vcs: "git", + repo: "https://{root}", }, // chiselapp.com for fossil { - prefix: "chiselapp.com/", - regexp: lazyregexp.New(`^(?Pchiselapp\.com/user/[A-Za-z0-9]+/repository/[A-Za-z0-9_.\-]+)$`), - vcs: "fossil", - repo: "https://{root}", + pathPrefix: "chiselapp.com", + regexp: lazyregexp.New(`^(?Pchiselapp\.com/user/[A-Za-z0-9]+/repository/[A-Za-z0-9_.\-]+)$`), + vcs: "fossil", + repo: "https://{root}", }, // General syntax for any server. @@ -1089,11 +1241,11 @@ var vcsPaths = []*vcsPath{ var vcsPathsAfterDynamic = []*vcsPath{ // Launchpad. See golang.org/issue/11436. { - prefix: "launchpad.net/", - regexp: lazyregexp.New(`^(?Plaunchpad\.net/((?P[A-Za-z0-9_.\-]+)(?P/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`), - vcs: "bzr", - repo: "https://{root}", - check: launchpadVCS, + pathPrefix: "launchpad.net", + regexp: lazyregexp.New(`^(?Plaunchpad\.net/((?P[A-Za-z0-9_.\-]+)(?P/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`), + vcs: "bzr", + repo: "https://{root}", + check: launchpadVCS, }, } @@ -1103,7 +1255,7 @@ var vcsPathsAfterDynamic = []*vcsPath{ func noVCSSuffix(match map[string]string) error { repo := match["repo"] for _, vcs := range vcsList { - if strings.HasSuffix(repo, "."+vcs.cmd) { + if strings.HasSuffix(repo, "."+vcs.Cmd) { return fmt.Errorf("invalid version control suffix in %s path", match["prefix"]) } } @@ -1133,7 +1285,7 @@ func bitbucketVCS(match map[string]string) error { // VCS it uses. See issue 5375. root := match["root"] for _, vcs := range []string{"git", "hg"} { - if vcsByCmd(vcs).ping("https", root) == nil { + if vcsByCmd(vcs).Ping("https", root) == nil { resp.SCM = vcs break } @@ -1180,3 +1332,32 @@ func launchpadVCS(match map[string]string) error { } return nil } + +// importError is a copy of load.importError, made to avoid a dependency cycle +// on cmd/go/internal/load. It just needs to satisfy load.ImportPathError. +type importError struct { + importPath string + err error +} + +func importErrorf(path, format string, args ...interface{}) error { + 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 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 +} diff --git a/libgo/go/cmd/go/internal/get/vcs_test.go b/libgo/go/cmd/go/internal/vcs/vcs_test.go similarity index 68% rename from libgo/go/cmd/go/internal/get/vcs_test.go rename to libgo/go/cmd/go/internal/vcs/vcs_test.go index 91800baa83d..c5c7a3283bc 100644 --- a/libgo/go/cmd/go/internal/get/vcs_test.go +++ b/libgo/go/cmd/go/internal/vcs/vcs_test.go @@ -2,20 +2,28 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package get +package vcs import ( "errors" "internal/testenv" - "io/ioutil" "os" "path" "path/filepath" + "strings" "testing" "cmd/go/internal/web" ) +func init() { + // GOVCS defaults to public:git|hg,private:all, + // which breaks many tests here - they can't use non-git, non-hg VCS at all! + // Change to fully permissive. + // The tests of the GOVCS setting itself are in ../../testdata/script/govcs.txt. + os.Setenv("GOVCS", "*:all") +} + // Test that RepoRootForImportPath determines the correct RepoRoot for a given importPath. // TODO(cmang): Add tests for SVN and BZR. func TestRepoRootForImportPath(t *testing.T) { @@ -28,30 +36,27 @@ func TestRepoRootForImportPath(t *testing.T) { { "github.com/golang/groupcache", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://github.com/golang/groupcache", }, }, - // Unicode letters in directories (issue 18660). + // Unicode letters in directories are not valid. { "github.com/user/unicode/испытание", - &RepoRoot{ - vcs: vcsGit, - Repo: "https://github.com/user/unicode", - }, + nil, }, // IBM DevOps Services tests { "hub.jazz.net/git/user1/pkgname", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://hub.jazz.net/git/user1/pkgname", }, }, { "hub.jazz.net/git/user1/pkgname/submodule/submodule/submodule", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://hub.jazz.net/git/user1/pkgname", }, }, @@ -92,7 +97,7 @@ func TestRepoRootForImportPath(t *testing.T) { { "hub.jazz.net/git/user/pkg.name", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://hub.jazz.net/git/user/pkg.name", }, }, @@ -105,7 +110,7 @@ func TestRepoRootForImportPath(t *testing.T) { { "git.openstack.org/openstack/swift", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.openstack.org/openstack/swift", }, }, @@ -115,14 +120,14 @@ func TestRepoRootForImportPath(t *testing.T) { { "git.openstack.org/openstack/swift.git", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.openstack.org/openstack/swift.git", }, }, { "git.openstack.org/openstack/swift/go/hummingbird", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.openstack.org/openstack/swift", }, }, @@ -151,21 +156,21 @@ func TestRepoRootForImportPath(t *testing.T) { { "git.apache.org/package-name.git", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.apache.org/package-name.git", }, }, { "git.apache.org/package-name_2.x.git/path/to/lib", &RepoRoot{ - vcs: vcsGit, + VCS: vcsGit, Repo: "https://git.apache.org/package-name_2.x.git", }, }, { "chiselapp.com/user/kyle/repository/fossilgg", &RepoRoot{ - vcs: vcsFossil, + VCS: vcsFossil, Repo: "https://chiselapp.com/user/kyle/repository/fossilgg", }, }, @@ -194,22 +199,22 @@ func TestRepoRootForImportPath(t *testing.T) { t.Errorf("RepoRootForImportPath(%q): %v", test.path, err) continue } - if got.vcs.name != want.vcs.name || got.Repo != want.Repo { - t.Errorf("RepoRootForImportPath(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.vcs, got.Repo, want.vcs, want.Repo) + if got.VCS.Name != want.VCS.Name || got.Repo != want.Repo { + t.Errorf("RepoRootForImportPath(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.VCS, got.Repo, want.VCS, want.Repo) } } } // Test that vcsFromDir correctly inspects a given directory and returns the right VCS and root. func TestFromDir(t *testing.T) { - tempDir, err := ioutil.TempDir("", "vcstest") + tempDir, err := os.MkdirTemp("", "vcstest") if err != nil { t.Fatal(err) } defer os.RemoveAll(tempDir) for j, vcs := range vcsList { - dir := filepath.Join(tempDir, "example.com", vcs.name, "."+vcs.cmd) + dir := filepath.Join(tempDir, "example.com", vcs.Name, "."+vcs.Cmd) if j&1 == 0 { err := os.MkdirAll(dir, 0755) if err != nil { @@ -228,24 +233,24 @@ func TestFromDir(t *testing.T) { } want := RepoRoot{ - vcs: vcs, - Root: path.Join("example.com", vcs.name), + VCS: vcs, + Root: path.Join("example.com", vcs.Name), } var got RepoRoot - got.vcs, got.Root, err = vcsFromDir(dir, tempDir) + got.VCS, got.Root, err = FromDir(dir, tempDir) if err != nil { t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err) continue } - if got.vcs.name != want.vcs.name || got.Root != want.Root { - t.Errorf("FromDir(%q, %q) = VCS(%s) Root(%s), want VCS(%s) Root(%s)", dir, tempDir, got.vcs, got.Root, want.vcs, want.Root) + if got.VCS.Name != want.VCS.Name || got.Root != want.Root { + t.Errorf("FromDir(%q, %q) = VCS(%s) Root(%s), want VCS(%s) Root(%s)", dir, tempDir, got.VCS, got.Root, want.VCS, want.Root) } } } func TestIsSecure(t *testing.T) { tests := []struct { - vcs *vcsCmd + vcs *Cmd url string secure bool }{ @@ -270,7 +275,7 @@ func TestIsSecure(t *testing.T) { } for _, test := range tests { - secure := test.vcs.isSecure(test.url) + secure := test.vcs.IsSecure(test.url) if secure != test.secure { t.Errorf("%s isSecure(%q) = %t; want %t", test.vcs, test.url, secure, test.secure) } @@ -279,7 +284,7 @@ func TestIsSecure(t *testing.T) { func TestIsSecureGitAllowProtocol(t *testing.T) { tests := []struct { - vcs *vcsCmd + vcs *Cmd url string secure bool }{ @@ -310,7 +315,7 @@ func TestIsSecureGitAllowProtocol(t *testing.T) { defer os.Unsetenv("GIT_ALLOW_PROTOCOL") os.Setenv("GIT_ALLOW_PROTOCOL", "https:foo") for _, test := range tests { - secure := test.vcs.isSecure(test.url) + secure := test.vcs.IsSecure(test.url) if secure != test.secure { t.Errorf("%s isSecure(%q) = %t; want %t", test.vcs, test.url, secure, test.secure) } @@ -476,3 +481,98 @@ func TestValidateRepoRoot(t *testing.T) { } } } + +var govcsTests = []struct { + govcs string + path string + vcs string + ok bool +}{ + {"private:all", "is-public.com/foo", "zzz", false}, + {"private:all", "is-private.com/foo", "zzz", true}, + {"public:all", "is-public.com/foo", "zzz", true}, + {"public:all", "is-private.com/foo", "zzz", false}, + {"public:all,private:none", "is-public.com/foo", "zzz", true}, + {"public:all,private:none", "is-private.com/foo", "zzz", false}, + {"*:all", "is-public.com/foo", "zzz", true}, + {"golang.org:git", "golang.org/x/text", "zzz", false}, + {"golang.org:git", "golang.org/x/text", "git", true}, + {"golang.org:zzz", "golang.org/x/text", "zzz", true}, + {"golang.org:zzz", "golang.org/x/text", "git", false}, + {"golang.org:zzz", "golang.org/x/text", "zzz", true}, + {"golang.org:zzz", "golang.org/x/text", "git", false}, + {"golang.org:git|hg", "golang.org/x/text", "hg", true}, + {"golang.org:git|hg", "golang.org/x/text", "git", true}, + {"golang.org:git|hg", "golang.org/x/text", "zzz", false}, + {"golang.org:all", "golang.org/x/text", "hg", true}, + {"golang.org:all", "golang.org/x/text", "git", true}, + {"golang.org:all", "golang.org/x/text", "zzz", true}, + {"other.xyz/p:none,golang.org/x:git", "other.xyz/p/x", "git", false}, + {"other.xyz/p:none,golang.org/x:git", "unexpected.com", "git", false}, + {"other.xyz/p:none,golang.org/x:git", "golang.org/x/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:git", "golang.org/x/text", "git", true}, + {"other.xyz/p:none,golang.org/x:zzz", "golang.org/x/text", "zzz", true}, + {"other.xyz/p:none,golang.org/x:zzz", "golang.org/x/text", "git", false}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/x/text", "hg", true}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/x/text", "git", true}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/x/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/x/text", "hg", true}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/x/text", "git", true}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/x/text", "zzz", true}, + {"other.xyz/p:none,golang.org/x:git", "golang.org/y/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:git", "golang.org/y/text", "git", false}, + {"other.xyz/p:none,golang.org/x:zzz", "golang.org/y/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:zzz", "golang.org/y/text", "git", false}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/y/text", "hg", false}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/y/text", "git", false}, + {"other.xyz/p:none,golang.org/x:git|hg", "golang.org/y/text", "zzz", false}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/y/text", "hg", false}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/y/text", "git", false}, + {"other.xyz/p:none,golang.org/x:all", "golang.org/y/text", "zzz", false}, +} + +func TestGOVCS(t *testing.T) { + for _, tt := range govcsTests { + cfg, err := parseGOVCS(tt.govcs) + if err != nil { + t.Errorf("parseGOVCS(%q): %v", tt.govcs, err) + continue + } + private := strings.HasPrefix(tt.path, "is-private") + ok := cfg.allow(tt.path, private, tt.vcs) + if ok != tt.ok { + t.Errorf("parseGOVCS(%q).allow(%q, %v, %q) = %v, want %v", + tt.govcs, tt.path, private, tt.vcs, ok, tt.ok) + } + } +} + +var govcsErrors = []struct { + s string + err string +}{ + {`,`, `empty entry in GOVCS`}, + {`,x`, `empty entry in GOVCS`}, + {`x,`, `malformed entry in GOVCS (missing colon): "x"`}, + {`x:y,`, `empty entry in GOVCS`}, + {`x`, `malformed entry in GOVCS (missing colon): "x"`}, + {`x:`, `empty VCS list in GOVCS: "x:"`}, + {`x:|`, `empty VCS name in GOVCS: "x:|"`}, + {`x:y|`, `empty VCS name in GOVCS: "x:y|"`}, + {`x:|y`, `empty VCS name in GOVCS: "x:|y"`}, + {`x:y,z:`, `empty VCS list in GOVCS: "z:"`}, + {`x:y,z:|`, `empty VCS name in GOVCS: "z:|"`}, + {`x:y,z:|w`, `empty VCS name in GOVCS: "z:|w"`}, + {`x:y,z:w|`, `empty VCS name in GOVCS: "z:w|"`}, + {`x:y,z:w||v`, `empty VCS name in GOVCS: "z:w||v"`}, + {`x:y,x:z`, `unreachable pattern in GOVCS: "x:z" after "x:y"`}, +} + +func TestGOVCSErrors(t *testing.T) { + for _, tt := range govcsErrors { + _, err := parseGOVCS(tt.s) + if err == nil || !strings.Contains(err.Error(), tt.err) { + t.Errorf("parseGOVCS(%s): err=%v, want %v", tt.s, err, tt.err) + } + } +} diff --git a/libgo/go/cmd/go/internal/version/version.go b/libgo/go/cmd/go/internal/version/version.go index a5b13653cd6..58cbd32e78d 100644 --- a/libgo/go/cmd/go/internal/version/version.go +++ b/libgo/go/cmd/go/internal/version/version.go @@ -7,8 +7,10 @@ package version import ( "bytes" + "context" "encoding/binary" "fmt" + "io/fs" "os" "path/filepath" "runtime" @@ -51,7 +53,7 @@ var ( versionV = CmdVersion.Flag.Bool("v", false, "") ) -func runVersion(cmd *base.Command, args []string) { +func runVersion(ctx context.Context, cmd *base.Command, args []string) { if len(args) == 0 { // If any of this command's flags were passed explicitly, error // out, because they only make sense with arguments. @@ -86,8 +88,15 @@ func runVersion(cmd *base.Command, args []string) { // scanDir scans a directory for executables to run scanFile on. func scanDir(dir string) { - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if info.Mode().IsRegular() || info.Mode()&os.ModeSymlink != 0 { + filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { + if d.Type().IsRegular() || d.Type()&fs.ModeSymlink != 0 { + info, err := d.Info() + if err != nil { + if *versionV { + fmt.Fprintf(os.Stderr, "%s: %v\n", path, err) + } + return nil + } scanFile(path, info, *versionV) } return nil @@ -95,7 +104,7 @@ func scanDir(dir string) { } // isExe reports whether the file should be considered executable. -func isExe(file string, info os.FileInfo) bool { +func isExe(file string, info fs.FileInfo) bool { if runtime.GOOS == "windows" { return strings.HasSuffix(strings.ToLower(file), ".exe") } @@ -106,8 +115,8 @@ func isExe(file string, info os.FileInfo) bool { // If mustPrint is true, scanFile will report any error reading file. // Otherwise (mustPrint is false, because scanFile is being called // by scanDir) scanFile prints nothing for non-Go executables. -func scanFile(file string, info os.FileInfo, mustPrint bool) { - if info.Mode()&os.ModeSymlink != 0 { +func scanFile(file string, info fs.FileInfo, mustPrint bool) { + if info.Mode()&fs.ModeSymlink != 0 { // Accept file symlinks only. i, err := os.Stat(file) if err != nil || !i.Mode().IsRegular() { @@ -118,6 +127,7 @@ func scanFile(file string, info os.FileInfo, mustPrint bool) { } info = i } + if !isExe(file, info) { if mustPrint { fmt.Fprintf(os.Stderr, "%s: not executable file\n", file) @@ -144,7 +154,7 @@ func scanFile(file string, info os.FileInfo, mustPrint bool) { fmt.Printf("%s: %s\n", file, vers) if *versionM && mod != "" { - fmt.Printf("\t%s\n", strings.Replace(mod[:len(mod)-1], "\n", "\n\t", -1)) + fmt.Printf("\t%s\n", strings.ReplaceAll(mod[:len(mod)-1], "\n", "\n\t")) } } diff --git a/libgo/go/cmd/go/internal/vet/vet.go b/libgo/go/cmd/go/internal/vet/vet.go index 4ec58de7854..4257c90c97a 100644 --- a/libgo/go/cmd/go/internal/vet/vet.go +++ b/libgo/go/cmd/go/internal/vet/vet.go @@ -6,11 +6,15 @@ package vet import ( + "context" + "fmt" + "path/filepath" + "cmd/go/internal/base" + "cmd/go/internal/cfg" "cmd/go/internal/load" - "cmd/go/internal/modload" + "cmd/go/internal/trace" "cmd/go/internal/work" - "path/filepath" ) // Break init loop. @@ -48,11 +52,28 @@ See also: go fmt, go fix. `, } -func runVet(cmd *base.Command, args []string) { - modload.LoadTests = true +func runVet(ctx context.Context, cmd *base.Command, args []string) { + load.ModResolveTests = true vetFlags, pkgArgs := vetFlags(args) + if cfg.DebugTrace != "" { + var close func() error + var err error + ctx, close, err = trace.Start(ctx, cfg.DebugTrace) + if err != nil { + base.Fatalf("failed to start trace: %v", err) + } + defer func() { + if err := close(); err != nil { + base.Fatalf("failed to stop trace: %v", err) + } + }() + } + + ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command")) + defer span.Done() + work.BuildInit() work.VetFlags = vetFlags if len(vetFlags) > 0 { @@ -66,7 +87,8 @@ func runVet(cmd *base.Command, args []string) { } } - pkgs := load.PackagesForBuild(pkgArgs) + pkgs := load.PackagesAndErrors(ctx, pkgArgs) + load.CheckPackageErrors(pkgs) if len(pkgs) == 0 { base.Fatalf("no packages to vet") } @@ -76,7 +98,7 @@ func runVet(cmd *base.Command, args []string) { root := &work.Action{Mode: "go vet"} for _, p := range pkgs { - _, ptest, pxtest, err := load.TestPackagesFor(p, nil) + _, ptest, pxtest, err := load.TestPackagesFor(ctx, p, nil) if err != nil { base.Errorf("%v", err) continue @@ -92,5 +114,5 @@ func runVet(cmd *base.Command, args []string) { root.Deps = append(root.Deps, b.VetAction(work.ModeBuild, work.ModeBuild, pxtest)) } } - b.Do(root) + b.Do(ctx, root) } diff --git a/libgo/go/cmd/go/internal/web/api.go b/libgo/go/cmd/go/internal/web/api.go index 570818843ba..9053b16b629 100644 --- a/libgo/go/cmd/go/internal/web/api.go +++ b/libgo/go/cmd/go/internal/web/api.go @@ -13,9 +13,8 @@ import ( "bytes" "fmt" "io" - "io/ioutil" + "io/fs" "net/url" - "os" "strings" "unicode" "unicode/utf8" @@ -56,7 +55,7 @@ func (e *HTTPError) Error() string { } if err := e.Err; err != nil { - if pErr, ok := e.Err.(*os.PathError); ok && strings.HasSuffix(e.URL, pErr.Path) { + if pErr, ok := e.Err.(*fs.PathError); ok && strings.HasSuffix(e.URL, pErr.Path) { // Remove the redundant copy of the path. err = pErr.Err } @@ -67,7 +66,7 @@ func (e *HTTPError) Error() string { } func (e *HTTPError) Is(target error) bool { - return target == os.ErrNotExist && (e.StatusCode == 404 || e.StatusCode == 410) + return target == fs.ErrNotExist && (e.StatusCode == 404 || e.StatusCode == 410) } func (e *HTTPError) Unwrap() error { @@ -87,7 +86,7 @@ func GetBytes(u *url.URL) ([]byte, error) { if err := resp.Err(); err != nil { return nil, err } - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("reading %s: %v", u.Redacted(), err) } @@ -130,7 +129,7 @@ func (r *Response) formatErrorDetail() string { } // Ensure that r.errorDetail has been populated. - _, _ = io.Copy(ioutil.Discard, r.Body) + _, _ = io.Copy(io.Discard, r.Body) s := r.errorDetail.buf.String() if !utf8.ValidString(s) { diff --git a/libgo/go/cmd/go/internal/web/file_test.go b/libgo/go/cmd/go/internal/web/file_test.go index 63394690453..3734df5c4e9 100644 --- a/libgo/go/cmd/go/internal/web/file_test.go +++ b/libgo/go/cmd/go/internal/web/file_test.go @@ -6,7 +6,7 @@ package web import ( "errors" - "io/ioutil" + "io/fs" "os" "path/filepath" "testing" @@ -15,7 +15,7 @@ import ( func TestGetFileURL(t *testing.T) { const content = "Hello, file!\n" - f, err := ioutil.TempFile("", "web-TestGetFileURL") + f, err := os.CreateTemp("", "web-TestGetFileURL") if err != nil { t.Fatal(err) } @@ -54,7 +54,7 @@ func TestGetNonexistentFile(t *testing.T) { } b, err := GetBytes(u) - if !errors.Is(err, os.ErrNotExist) { - t.Fatalf("GetBytes(%v) = %q, %v; want _, os.ErrNotExist", u, b, err) + if !errors.Is(err, fs.ErrNotExist) { + t.Fatalf("GetBytes(%v) = %q, %v; want _, fs.ErrNotExist", u, b, err) } } diff --git a/libgo/go/cmd/go/internal/web/http.go b/libgo/go/cmd/go/internal/web/http.go index e0509808d67..72fa2b2ca6a 100644 --- a/libgo/go/cmd/go/internal/web/http.go +++ b/libgo/go/cmd/go/internal/web/http.go @@ -80,6 +80,13 @@ func get(security SecurityMode, url *urlpkg.URL) (*Response, error) { return res, nil } + if url.Host == "localhost.localdev" { + return nil, fmt.Errorf("no such host localhost.localdev") + } + if os.Getenv("TESTGONETWORK") == "panic" && !strings.HasPrefix(url.Host, "127.0.0.1") && !strings.HasPrefix(url.Host, "0.0.0.0") { + panic("use of network: " + url.String()) + } + fetch := func(url *urlpkg.URL) (*urlpkg.URL, *http.Response, error) { // Note: The -v build flag does not mean "print logging information", // despite its historical misuse for this in GOPATH-based go get. diff --git a/libgo/go/cmd/go/internal/work/action.go b/libgo/go/cmd/go/internal/work/action.go index b87292811fd..53201211022 100644 --- a/libgo/go/cmd/go/internal/work/action.go +++ b/libgo/go/cmd/go/internal/work/action.go @@ -10,11 +10,11 @@ import ( "bufio" "bytes" "container/heap" + "context" "debug/elf" "encoding/json" "fmt" "internal/xcoff" - "io/ioutil" "os" "path/filepath" "runtime" @@ -26,6 +26,7 @@ import ( "cmd/go/internal/cache" "cmd/go/internal/cfg" "cmd/go/internal/load" + "cmd/go/internal/trace" "cmd/internal/buildid" ) @@ -64,13 +65,13 @@ type Builder struct { // An Action represents a single action in the action graph. type Action struct { - Mode string // description of action operation - Package *load.Package // the package this action works on - Deps []*Action // actions that must happen before this one - Func func(*Builder, *Action) error // the action itself (nil = no-op) - IgnoreFail bool // whether to run f even if dependencies fail - TestOutput *bytes.Buffer // test output buffer - Args []string // additional args for runProgram + Mode string // description of action operation + Package *load.Package // the package this action works on + Deps []*Action // actions that must happen before this one + Func func(*Builder, context.Context, *Action) error // the action itself (nil = no-op) + IgnoreFail bool // whether to run f even if dependencies fail + TestOutput *bytes.Buffer // test output buffer + Args []string // additional args for runProgram triggers []*Action // inverse of deps @@ -92,10 +93,12 @@ type Action struct { output []byte // output redirect buffer (nil means use b.Print) // Execution state. - pending int // number of deps yet to complete - priority int // relative execution priority - Failed bool // whether the action failed - json *actionJSON // action graph information + pending int // number of deps yet to complete + priority int // relative execution priority + Failed bool // whether the action failed + json *actionJSON // action graph information + nonGoOverlay map[string]string // map from non-.go source files to copied files in objdir. Nil if no overlay is used. + traceSpan *trace.Span } // BuildActionID returns the action ID section of a's build ID. @@ -250,7 +253,7 @@ func (b *Builder) Init() { if cfg.BuildN { b.WorkDir = "$WORK" } else { - tmp, err := ioutil.TempDir(cfg.Getenv("GOTMPDIR"), "go-build") + tmp, err := os.MkdirTemp(cfg.Getenv("GOTMPDIR"), "go-build") if err != nil { base.Fatalf("go: creating work dir: %v", err) } diff --git a/libgo/go/cmd/go/internal/work/build.go b/libgo/go/cmd/go/internal/work/build.go index 7146c9ce00e..7f2617cf1ce 100644 --- a/libgo/go/cmd/go/internal/work/build.go +++ b/libgo/go/cmd/go/internal/work/build.go @@ -5,23 +5,33 @@ package work import ( + "context" "errors" "fmt" "go/build" + "internal/goroot" "os" "os/exec" + "path" "path/filepath" "runtime" "strings" "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/load" + "cmd/go/internal/modfetch" + "cmd/go/internal/modload" "cmd/go/internal/search" + "cmd/go/internal/trace" + + "golang.org/x/mod/modfile" + "golang.org/x/mod/module" ) var CmdBuild = &base.Command{ - UsageLine: "go build [-o output] [-i] [build flags] [packages]", + UsageLine: "go build [-o output] [build flags] [packages]", Short: "compile packages and dependencies", Long: ` Build compiles the packages named by the import paths, @@ -44,10 +54,12 @@ serving only as a check that the packages can be built. The -o flag forces build to write the resulting executable or object to the named output file or directory, instead of the default behavior described -in the last two paragraphs. If the named output is a directory that exists, -then any resulting executables will be written to that directory. +in the last two paragraphs. If the named output is an existing directory or +ends with a slash or backslash, then any resulting executables +will be written to that directory. The -i flag installs the packages that are dependencies of the target. +The -i flag is deprecated. Compiled packages are cached automatically. The build flags are shared by the build, clean, get, install, list, run, and test commands: @@ -112,6 +124,17 @@ and test commands: 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". + -overlay file + read a JSON config file that provides an overlay for build operations. + The file is a JSON struct with a single field, named 'Replace', that + maps each disk file path (a string) to its backing file path, so that + a build will run as if the disk file path exists with the contents + given by the backing file paths, or as if the disk file path does not + exist if its backing file path is empty. Support for the -overlay flag + has some limitations:importantly, cgo files included from outside the + include path must be in the same directory as the Go package they are + included from, and overlays will not appear when binaries and tests are + run through go run and go test respectively. -pkgdir dir install and load all packages from dir instead of the usual locations. For example, when building with a non-standard configuration, @@ -238,13 +261,12 @@ const ( // AddBuildFlags adds the flags common to the build, clean, get, // install, list, run, and test commands. func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { + base.AddBuildFlagsNX(&cmd.Flag) cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "") - cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "") cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "") if mask&OmitVFlag == 0 { cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "") } - cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "") cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "") cmd.Flag.Var(buildCompiler{}, "compiler", "") @@ -252,10 +274,15 @@ func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { cmd.Flag.Var(&load.BuildGcflags, "gcflags", "") cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "") if mask&OmitModFlag == 0 { - cmd.Flag.StringVar(&cfg.BuildMod, "mod", "", "") + base.AddModFlag(&cmd.Flag) } if mask&OmitModCommonFlags == 0 { - AddModCommonFlags(cmd) + base.AddModCommonFlags(&cmd.Flag) + } else { + // Add the overlay flag even when we don't add the rest of the mod common flags. + // This only affects 'go get' in GOPATH mode, but add the flag anyway for + // consistency. + cmd.Flag.StringVar(&fsys.OverlayFile, "overlay", "", "") } cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "") cmd.Flag.Var(&load.BuildLdflags, "ldflags", "") @@ -270,13 +297,7 @@ func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) { // Undocumented, unstable debugging flags. 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", "", "") + cmd.Flag.StringVar(&cfg.DebugTrace, "debug-trace", "", "") } // tagsFlag is the implementation of the -tags flag. @@ -343,12 +364,13 @@ var pkgsFilter = func(pkgs []*load.Package) []*load.Package { return pkgs } var runtimeVersion = runtime.Version() -func runBuild(cmd *base.Command, args []string) { +func runBuild(ctx context.Context, cmd *base.Command, args []string) { BuildInit() var b Builder b.Init() - pkgs := load.PackagesForBuild(args) + pkgs := load.PackagesAndErrors(ctx, args) + load.CheckPackageErrors(pkgs) explicitO := len(cfg.BuildO) > 0 @@ -375,9 +397,10 @@ func runBuild(cmd *base.Command, args []string) { depMode := ModeBuild if cfg.BuildI { depMode = ModeInstall + fmt.Fprint(os.Stderr, "go build: -i flag is deprecated\n") } - pkgs = omitTestOnly(pkgsFilter(load.Packages(args))) + pkgs = omitTestOnly(pkgsFilter(pkgs)) // Special case -o /dev/null by not writing at all. if cfg.BuildO == os.DevNull { @@ -385,10 +408,13 @@ func runBuild(cmd *base.Command, args []string) { } if cfg.BuildO != "" { - // If the -o name exists and is a directory, then + // If the -o name exists and is a directory or + // ends with a slash or backslash, then // write all main packages to that directory. // Otherwise require only a single package be built. - if fi, err := os.Stat(cfg.BuildO); err == nil && fi.IsDir() { + if fi, err := os.Stat(cfg.BuildO); (err == nil && fi.IsDir()) || + strings.HasSuffix(cfg.BuildO, "/") || + strings.HasSuffix(cfg.BuildO, string(os.PathSeparator)) { if !explicitO { base.Fatalf("go build: build output %q already exists and is a directory", cfg.BuildO) } @@ -407,7 +433,7 @@ func runBuild(cmd *base.Command, args []string) { if len(a.Deps) == 0 { base.Fatalf("go build: no main packages to build") } - b.Do(a) + b.Do(ctx, a) return } if len(pkgs) > 1 { @@ -420,7 +446,7 @@ func runBuild(cmd *base.Command, args []string) { p.Stale = true // must build - not up to date p.StaleReason = "build -o flag in use" a := b.AutoAction(ModeInstall, depMode, p) - b.Do(a) + b.Do(ctx, a) return } @@ -431,11 +457,11 @@ func runBuild(cmd *base.Command, args []string) { if cfg.BuildBuildmode == "shared" { a = b.buildmodeShared(ModeBuild, depMode, args, pkgs, a) } - b.Do(a) + b.Do(ctx, a) } var CmdInstall = &base.Command{ - UsageLine: "go install [-i] [build flags] [packages]", + UsageLine: "go install [build flags] [packages]", Short: "compile and install packages and dependencies", Long: ` Install compiles and installs the packages named by the import paths. @@ -445,11 +471,39 @@ variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH environment variable is not set. Executables in $GOROOT are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN. +If the arguments have version suffixes (like @latest or @v1.0.0), "go install" +builds packages in module-aware mode, ignoring the go.mod file in the current +directory or any parent directory, if there is one. This is useful for +installing executables without affecting the dependencies of the main module. +To eliminate ambiguity about which module versions are used in the build, the +arguments must satisfy the following constraints: + +- Arguments must be package paths or package patterns (with "..." wildcards). + They must not be standard packages (like fmt), meta-patterns (std, cmd, + all), or relative or absolute file paths. +- All arguments must have the same version suffix. Different queries are not + allowed, even if they refer to the same version. +- All arguments must refer to packages in the same module at the same version. +- No module is considered the "main" module. If the module containing + packages named on the command line has a go.mod file, it must not contain + directives (replace and exclude) that would cause it to be interpreted + differently than if it were the main module. The module must not require + a higher version of itself. +- Package path arguments must refer to main packages. Pattern arguments + will only match main packages. + +If the arguments don't have version suffixes, "go install" may run in +module-aware mode or GOPATH mode, depending on the GO111MODULE environment +variable and the presence of a go.mod file. See 'go help modules' for details. +If module-aware mode is enabled, "go install" runs in the context of the main +module. + When module-aware mode is disabled, other packages are installed in the directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled, other packages are built and cached but not installed. The -i flag installs the dependencies of the named packages as well. +The -i flag is deprecated. Compiled packages are cached automatically. For more about the build flags, see 'go help build'. For more about specifying packages, see 'go help packages'. @@ -514,9 +568,61 @@ func libname(args []string, pkgs []*load.Package) (string, error) { return "lib" + libname + ".so", nil } -func runInstall(cmd *base.Command, args []string) { +func runInstall(ctx context.Context, cmd *base.Command, args []string) { + // TODO(golang.org/issue/41696): print a deprecation message for the -i flag + // whenever it's set (or just remove it). For now, we don't print a message + // if all named packages are in GOROOT. cmd/dist (run by make.bash) uses + // 'go install -i' when bootstrapping, and we don't want to show deprecation + // messages in that case. + for _, arg := range args { + if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) { + if cfg.BuildI { + fmt.Fprint(os.Stderr, "go install: -i flag is deprecated\n") + } + installOutsideModule(ctx, args) + return + } + } + BuildInit() - InstallPackages(args, load.PackagesForBuild(args)) + pkgs := load.PackagesAndErrors(ctx, args) + if cfg.ModulesEnabled && !modload.HasModRoot() { + haveErrors := false + allMissingErrors := true + for _, pkg := range pkgs { + if pkg.Error == nil { + continue + } + haveErrors = true + if missingErr := (*modload.ImportMissingError)(nil); !errors.As(pkg.Error, &missingErr) { + allMissingErrors = false + break + } + } + if haveErrors && allMissingErrors { + latestArgs := make([]string, len(args)) + for i := range args { + latestArgs[i] = args[i] + "@latest" + } + hint := strings.Join(latestArgs, " ") + base.Fatalf("go install: version is required when current directory is not in a module\n\tTry 'go install %s' to install the latest version", hint) + } + } + load.CheckPackageErrors(pkgs) + if cfg.BuildI { + allGoroot := true + for _, pkg := range pkgs { + if !pkg.Goroot { + allGoroot = false + break + } + } + if !allGoroot { + fmt.Fprint(os.Stderr, "go install: -i flag is deprecated\n") + } + } + + InstallPackages(ctx, args, pkgs) } // omitTestOnly returns pkgs with test-only packages removed. @@ -536,7 +642,10 @@ func omitTestOnly(pkgs []*load.Package) []*load.Package { return list } -func InstallPackages(patterns []string, pkgs []*load.Package) { +func InstallPackages(ctx context.Context, patterns []string, pkgs []*load.Package) { + ctx, span := trace.StartSpan(ctx, "InstallPackages "+strings.Join(patterns, " ")) + defer span.Done() + if cfg.GOBIN != "" && !filepath.IsAbs(cfg.GOBIN) { base.Fatalf("cannot install, GOBIN must be an absolute path") } @@ -605,7 +714,7 @@ func InstallPackages(patterns []string, pkgs []*load.Package) { a = b.buildmodeShared(ModeInstall, ModeInstall, patterns, pkgs, a) } - b.Do(a) + b.Do(ctx, a) base.ExitIfErrors() // Success. If this command is 'go install' with no arguments @@ -636,6 +745,157 @@ func InstallPackages(patterns []string, pkgs []*load.Package) { } } +// installOutsideModule implements 'go install pkg@version'. It builds and +// installs one or more main packages in module mode while ignoring any go.mod +// in the current directory or parent directories. +// +// See golang.org/issue/40276 for details and rationale. +func installOutsideModule(ctx context.Context, args []string) { + modload.ForceUseModules = true + modload.RootMode = modload.NoRoot + modload.AllowMissingModuleImports() + modload.Init() + + // Check that the arguments satisfy syntactic constraints. + var version string + for _, arg := range args { + if i := strings.Index(arg, "@"); i >= 0 { + version = arg[i+1:] + if version == "" { + base.Fatalf("go install %s: version must not be empty", arg) + } + break + } + } + patterns := make([]string, len(args)) + for i, arg := range args { + if !strings.HasSuffix(arg, "@"+version) { + base.Errorf("go install %s: all arguments must have the same version (@%s)", arg, version) + continue + } + p := arg[:len(arg)-len(version)-1] + switch { + case build.IsLocalImport(p): + base.Errorf("go install %s: argument must be a package path, not a relative path", arg) + case filepath.IsAbs(p): + base.Errorf("go install %s: argument must be a package path, not an absolute path", arg) + case search.IsMetaPackage(p): + base.Errorf("go install %s: argument must be a package path, not a meta-package", arg) + case path.Clean(p) != p: + base.Errorf("go install %s: argument must be a clean package path", arg) + case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p): + base.Errorf("go install %s: argument must not be a package in the standard library", arg) + default: + patterns[i] = p + } + } + base.ExitIfErrors() + BuildInit() + + // Query the module providing the first argument, load its go.mod file, and + // check that it doesn't contain directives that would cause it to be + // interpreted differently if it were the main module. + // + // If multiple modules match the first argument, accept the longest match + // (first result). It's possible this module won't provide packages named by + // later arguments, and other modules would. Let's not try to be too + // magical though. + allowed := modload.CheckAllowed + if modload.IsRevisionQuery(version) { + // Don't check for retractions if a specific revision is requested. + allowed = nil + } + noneSelected := func(path string) (version string) { return "none" } + qrs, err := modload.QueryPackages(ctx, patterns[0], version, noneSelected, allowed) + if err != nil { + base.Fatalf("go install %s: %v", args[0], err) + } + installMod := qrs[0].Mod + data, err := modfetch.GoMod(installMod.Path, installMod.Version) + if err != nil { + base.Fatalf("go install %s: %v", args[0], err) + } + f, err := modfile.Parse("go.mod", data, nil) + if err != nil { + base.Fatalf("go install %s: %s: %v", args[0], installMod, err) + } + directiveFmt := "go install %s: %s\n" + + "\tThe go.mod file for the module providing named packages contains one or\n" + + "\tmore %s directives. It must not contain directives that would cause\n" + + "\tit to be interpreted differently than if it were the main module." + if len(f.Replace) > 0 { + base.Fatalf(directiveFmt, args[0], installMod, "replace") + } + if len(f.Exclude) > 0 { + base.Fatalf(directiveFmt, args[0], installMod, "exclude") + } + + // Since we are in NoRoot mode, the build list initially contains only + // the dummy command-line-arguments module. Add a requirement on the + // module that provides the packages named on the command line. + if err := modload.EditBuildList(ctx, nil, []module.Version{installMod}); err != nil { + base.Fatalf("go install %s: %v", args[0], err) + } + + // Load packages for all arguments. Ignore non-main packages. + // Print a warning if an argument contains "..." and matches no main packages. + // PackagesAndErrors already prints warnings for patterns that don't match any + // packages, so be careful not to double print. + matchers := make([]func(string) bool, len(patterns)) + for i, p := range patterns { + if strings.Contains(p, "...") { + matchers[i] = search.MatchPattern(p) + } + } + + // TODO(golang.org/issue/40276): don't report errors loading non-main packages + // matched by a pattern. + pkgs := load.PackagesAndErrors(ctx, patterns) + load.CheckPackageErrors(pkgs) + mainPkgs := make([]*load.Package, 0, len(pkgs)) + mainCount := make([]int, len(patterns)) + nonMainCount := make([]int, len(patterns)) + for _, pkg := range pkgs { + if pkg.Name == "main" { + mainPkgs = append(mainPkgs, pkg) + for i := range patterns { + if matchers[i] != nil && matchers[i](pkg.ImportPath) { + mainCount[i]++ + } + } + } else { + for i := range patterns { + if matchers[i] == nil && patterns[i] == pkg.ImportPath { + base.Errorf("go install: package %s is not a main package", pkg.ImportPath) + } else if matchers[i] != nil && matchers[i](pkg.ImportPath) { + nonMainCount[i]++ + } + } + } + } + base.ExitIfErrors() + for i, p := range patterns { + if matchers[i] != nil && mainCount[i] == 0 && nonMainCount[i] > 0 { + fmt.Fprintf(os.Stderr, "go: warning: %q matched no main packages\n", p) + } + } + + // Check that named packages are all provided by the same module. + for _, pkg := range mainPkgs { + if pkg.Module == nil { + // Packages in std, cmd, and their vendored dependencies + // don't have this field set. + base.Errorf("go install: package %s not provided by module %s", pkg.ImportPath, installMod) + } else if pkg.Module.Path != installMod.Path || pkg.Module.Version != installMod.Version { + base.Errorf("go install: package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, installMod) + } + } + base.ExitIfErrors() + + // Build and install the packages. + InstallPackages(ctx, patterns, mainPkgs) +} + // ExecCmd is the command to use to run user binaries. // Normally it is empty, meaning run the binaries directly. // If cross-compiling and running on a remote system or diff --git a/libgo/go/cmd/go/internal/work/build_test.go b/libgo/go/cmd/go/internal/work/build_test.go index c33de2635dc..eaf2639e9e0 100644 --- a/libgo/go/cmd/go/internal/work/build_test.go +++ b/libgo/go/cmd/go/internal/work/build_test.go @@ -7,7 +7,7 @@ package work import ( "bytes" "fmt" - "io/ioutil" + "io/fs" "os" "path/filepath" "reflect" @@ -169,7 +169,7 @@ func TestSharedLibName(t *testing.T) { for _, data := range testData { func() { if data.rootedAt != "" { - tmpGopath, err := ioutil.TempDir("", "gopath") + tmpGopath, err := os.MkdirTemp("", "gopath") if err != nil { t.Fatal(err) } @@ -221,10 +221,8 @@ func pkgImportPath(pkgpath string) *load.Package { // See https://golang.org/issue/18878. func TestRespectSetgidDir(t *testing.T) { switch runtime.GOOS { - case "darwin": - if runtime.GOARCH == "arm64" { - t.Skip("can't set SetGID bit with chmod on iOS") - } + case "ios": + t.Skip("can't set SetGID bit with chmod on iOS") case "windows", "plan9": t.Skip("chown/chmod setgid are not supported on Windows or Plan 9") } @@ -239,7 +237,7 @@ func TestRespectSetgidDir(t *testing.T) { return cmdBuf.WriteString(fmt.Sprint(a...)) } - setgiddir, err := ioutil.TempDir("", "SetGroupID") + setgiddir, err := os.MkdirTemp("", "SetGroupID") if err != nil { t.Fatal(err) } @@ -255,13 +253,13 @@ func TestRespectSetgidDir(t *testing.T) { } // Change setgiddir's permissions to include the SetGID bit. - if err := os.Chmod(setgiddir, 0755|os.ModeSetgid); err != nil { + if err := os.Chmod(setgiddir, 0755|fs.ModeSetgid); err != nil { t.Fatal(err) } - pkgfile, err := ioutil.TempFile("", "pkgfile") + pkgfile, err := os.CreateTemp("", "pkgfile") if err != nil { - t.Fatalf("ioutil.TempFile(\"\", \"pkgfile\"): %v", err) + t.Fatalf("os.CreateTemp(\"\", \"pkgfile\"): %v", err) } defer os.Remove(pkgfile.Name()) defer pkgfile.Close() diff --git a/libgo/go/cmd/go/internal/work/buildid.go b/libgo/go/cmd/go/internal/work/buildid.go index 6613b6fe3f2..d76988145be 100644 --- a/libgo/go/cmd/go/internal/work/buildid.go +++ b/libgo/go/cmd/go/internal/work/buildid.go @@ -7,7 +7,6 @@ package work import ( "bytes" "fmt" - "io/ioutil" "os" "os/exec" "strings" @@ -15,6 +14,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cache" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/str" "cmd/internal/buildid" ) @@ -31,7 +31,7 @@ import ( // // actionID/[.../]contentID // -// where the actionID and contentID are prepared by hashToString below. +// where the actionID and contentID are prepared by buildid.HashToString below. // and are found by looking for the first or last slash. // Usually the buildID is simply actionID/contentID, but see below for an // exception. @@ -108,31 +108,6 @@ func contentID(buildID string) string { return buildID[strings.LastIndex(buildID, buildIDSeparator)+1:] } -// hashToString converts the hash h to a string to be recorded -// in package archives and binaries as part of the build ID. -// We use the first 96 bits of the hash and encode it in base64, -// resulting in a 16-byte string. Because this is only used for -// detecting the need to rebuild installed files (not for lookups -// in the object file cache), 96 bits are sufficient to drive the -// probability of a false "do not need to rebuild" decision to effectively zero. -// We embed two different hashes in archives and four in binaries, -// so cutting to 16 bytes is a significant savings when build IDs are displayed. -// (16*4+3 = 67 bytes compared to 64*4+3 = 259 bytes for the -// more straightforward option of printing the entire h in hex). -func hashToString(h [cache.HashSize]byte) string { - const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" - const chunks = 5 - var dst [chunks * 4]byte - for i := 0; i < chunks; i++ { - v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2]) - dst[4*i+0] = b64[(v>>18)&0x3F] - dst[4*i+1] = b64[(v>>12)&0x3F] - dst[4*i+2] = b64[(v>>6)&0x3F] - dst[4*i+3] = b64[v&0x3F] - } - return string(dst[:]) -} - // toolID returns the unique ID to use for the current copy of the // named tool (asm, compile, cover, link). // @@ -368,7 +343,7 @@ func (b *Builder) gccgoBuildIDFile(a *Action) (string, error) { } } - if err := ioutil.WriteFile(sfile, buf.Bytes(), 0666); err != nil { + if err := os.WriteFile(sfile, buf.Bytes(), 0666); err != nil { return "", err } @@ -400,11 +375,12 @@ func (b *Builder) buildID(file string) string { // fileHash returns the content hash of the named file. func (b *Builder) fileHash(file string) string { + file, _ = fsys.OverlayPath(file) sum, err := cache.FileHash(file) if err != nil { return "" } - return hashToString(sum) + return buildid.HashToString(sum) } // useCache tries to satisfy the action a, which has action ID actionHash, @@ -425,9 +401,9 @@ func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string) // 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 // the actionID half; if it also appeared in the input that would be like an - // engineered 96-bit partial SHA256 collision. + // engineered 120-bit partial SHA256 collision. a.actionID = actionHash - actionID := hashToString(actionHash) + actionID := buildid.HashToString(actionHash) if a.json != nil { a.json.ActionID = actionID } @@ -480,7 +456,7 @@ func (b *Builder) useCache(a *Action, actionHash cache.ActionID, target string) // build IDs of completed actions. oldBuildID := a.buildID a.buildID = id[1] + buildIDSeparator + id[2] - linkID := hashToString(b.linkActionID(a.triggers[0])) + linkID := buildid.HashToString(b.linkActionID(a.triggers[0])) if id[0] == linkID { // Best effort attempt to display output from the compile and link steps. // If it doesn't work, it doesn't work: reusing the cached binary is more @@ -654,7 +630,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error { if err != nil { return err } - newID := a.buildID[:strings.LastIndex(a.buildID, buildIDSeparator)] + buildIDSeparator + hashToString(hash) + newID := a.buildID[:strings.LastIndex(a.buildID, buildIDSeparator)] + buildIDSeparator + buildid.HashToString(hash) if len(newID) != len(a.buildID) { return fmt.Errorf("internal error: build ID length mismatch %q vs %q", a.buildID, newID) } @@ -670,7 +646,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error { } if rewrite { - w, err := os.OpenFile(target, os.O_WRONLY, 0) + w, err := os.OpenFile(target, os.O_RDWR, 0) if err != nil { return err } @@ -713,6 +689,7 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error { return err } a.Package.Export = c.OutputFile(outputID) + a.Package.BuildID = a.buildID } } } diff --git a/libgo/go/cmd/go/internal/work/exec.go b/libgo/go/cmd/go/internal/work/exec.go index 3898b2047c3..c0b69f9b9e5 100644 --- a/libgo/go/cmd/go/internal/work/exec.go +++ b/libgo/go/cmd/go/internal/work/exec.go @@ -8,12 +8,14 @@ package work import ( "bytes" + "cmd/go/internal/fsys" + "context" "encoding/json" "errors" "fmt" "internal/lazyregexp" "io" - "io/ioutil" + "io/fs" "log" "math/rand" "os" @@ -30,7 +32,9 @@ import ( "cmd/go/internal/cache" "cmd/go/internal/cfg" "cmd/go/internal/load" + "cmd/go/internal/modload" "cmd/go/internal/str" + "cmd/go/internal/trace" ) // actionList returns the list of actions in the dag rooted at root @@ -54,7 +58,10 @@ func actionList(root *Action) []*Action { } // do runs the action graph rooted at root. -func (b *Builder) Do(root *Action) { +func (b *Builder) Do(ctx context.Context, root *Action) { + ctx, span := trace.StartSpan(ctx, "exec.Builder.Do ("+root.Mode+" "+root.Target+")") + defer span.Done() + if !b.IsCmdList { // If we're doing real work, take time at the end to trim the cache. c := cache.Default() @@ -86,7 +93,7 @@ func (b *Builder) Do(root *Action) { base.Fatalf("go: refusing to write action graph to %v\n", file) } js := actionGraphJSON(root) - if err := ioutil.WriteFile(file, []byte(js), 0666); err != nil { + if err := os.WriteFile(file, []byte(js), 0666); err != nil { fmt.Fprintf(os.Stderr, "go: writing action graph: %v\n", err) base.SetExitStatus(1) } @@ -110,13 +117,24 @@ func (b *Builder) Do(root *Action) { // Handle runs a single action and takes care of triggering // any actions that are runnable as a result. - handle := func(a *Action) { + handle := func(ctx context.Context, a *Action) { if a.json != nil { a.json.TimeStart = time.Now() } var err error if a.Func != nil && (!a.Failed || a.IgnoreFail) { - err = a.Func(b, a) + // TODO(matloob): Better action descriptions + desc := "Executing action " + if a.Package != nil { + desc += "(" + a.Mode + " " + a.Package.Desc() + ")" + } + ctx, span := trace.StartSpan(ctx, desc) + a.traceSpan = span + for _, d := range a.Deps { + trace.Flow(ctx, d.traceSpan, a.traceSpan) + } + err = a.Func(b, ctx, a) + span.Done() } if a.json != nil { a.json.TimeDone = time.Now() @@ -164,6 +182,7 @@ func (b *Builder) Do(root *Action) { for i := 0; i < par; i++ { wg.Add(1) go func() { + ctx := trace.StartGoroutine(ctx) defer wg.Done() for { select { @@ -176,7 +195,7 @@ func (b *Builder) Do(root *Action) { b.exec.Lock() a := b.ready.pop() b.exec.Unlock() - handle(a) + handle(ctx, a) case <-base.Interrupted: base.SetExitStatus(1) return @@ -253,7 +272,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { fmt.Fprintf(h, "asm %q %q %q\n", b.toolID("asm"), forcedAsmflags, p.Internal.Asmflags) } - // GO386, GOARM, GOMIPS, etc. + // GOARM, GOMIPS, etc. key, val := cfg.GetArchEnv() fmt.Fprintf(h, "%s=%s\n", key, val) @@ -320,6 +339,7 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID { p.SysoFiles, p.SwigFiles, p.SwigCXXFiles, + p.EmbedFiles, ) for _, file := range inputFiles { fmt.Fprintf(h, "file %s %s\n", file, b.fileHash(filepath.Join(p.Dir, file))) @@ -386,7 +406,7 @@ const ( // build is the action for building a single package. // Note that any new influence on this logic must be reported in b.buildActionID above as well. -func (b *Builder) build(a *Action) (err error) { +func (b *Builder) build(ctx context.Context, a *Action) (err error) { p := a.Package bit := func(x uint32, b bool) uint32 { @@ -414,6 +434,7 @@ func (b *Builder) build(a *Action) (err error) { need &^= needBuild if b.NeedExport { p.Export = a.built + p.BuildID = a.buildID } if need&needCompiledGoFiles != 0 { if err := b.loadCachedSrcFiles(a); err == nil { @@ -516,6 +537,34 @@ func (b *Builder) build(a *Action) (err error) { } } + // Compute overlays for .c/.cc/.h/etc. and if there are any overlays + // put correct contents of all those files in the objdir, to ensure + // the correct headers are included. nonGoOverlay is the overlay that + // points from nongo files to the copied files in objdir. + nonGoFileLists := [][]string{a.Package.CFiles, a.Package.SFiles, a.Package.CXXFiles, a.Package.HFiles, a.Package.FFiles} +OverlayLoop: + for _, fs := range nonGoFileLists { + for _, f := range fs { + if _, ok := fsys.OverlayPath(mkAbs(p.Dir, f)); ok { + a.nonGoOverlay = make(map[string]string) + break OverlayLoop + } + } + } + if a.nonGoOverlay != nil { + for _, fs := range nonGoFileLists { + for i := range fs { + from := mkAbs(p.Dir, fs[i]) + opath, _ := fsys.OverlayPath(from) + dst := objdir + filepath.Base(fs[i]) + if err := b.copyFile(dst, opath, 0666, false); err != nil { + return err + } + a.nonGoOverlay[from] = dst + } + } + } + // Run SWIG on each .swig and .swigcxx file. // Each run will generate two files, a .go file and a .c or .cxx file. // The .go file will use import "C" and is to be processed by cgo. @@ -586,7 +635,7 @@ func (b *Builder) build(a *Action) (err error) { sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles) } else { for _, sfile := range sfiles { - data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile)) + data, err := os.ReadFile(filepath.Join(a.Package.Dir, sfile)) if err == nil { if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) || bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) || @@ -676,8 +725,28 @@ func (b *Builder) build(a *Action) (err error) { } } + // Prepare Go embed config if needed. + // Unlike the import config, it's okay for the embed config to be empty. + var embedcfg []byte + if len(p.Internal.Embed) > 0 { + var embed struct { + Patterns map[string][]string + Files map[string]string + } + embed.Patterns = p.Internal.Embed + embed.Files = make(map[string]string) + for _, file := range p.EmbedFiles { + embed.Files[file] = filepath.Join(p.Dir, file) + } + js, err := json.MarshalIndent(&embed, "", "\t") + if err != nil { + return fmt.Errorf("marshal embedcfg: %v", err) + } + embedcfg = js + } + if p.Internal.BuildInfo != "" && cfg.ModulesEnabled { - if err := b.writeFile(objdir+"_gomod_.go", load.ModInfoProg(p.Internal.BuildInfo, cfg.BuildToolchainName == "gccgo")); err != nil { + if err := b.writeFile(objdir+"_gomod_.go", modload.ModInfoProg(p.Internal.BuildInfo, cfg.BuildToolchainName == "gccgo")); err != nil { return err } gofiles = append(gofiles, objdir+"_gomod_.go") @@ -685,7 +754,7 @@ func (b *Builder) build(a *Action) (err error) { // Compile Go. objpkg := objdir + "_pkg_.a" - ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), symabis, len(sfiles) > 0, gofiles) + ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), embedcfg, symabis, len(sfiles) > 0, gofiles) if len(out) > 0 { output := b.processOutput(out) if p.Module != nil && !allowedVersion(p.Module.GoVersion) { @@ -698,7 +767,7 @@ func (b *Builder) build(a *Action) (err error) { } if err != nil { if p.Module != nil && !allowedVersion(p.Module.GoVersion) { - b.showOutput(a, a.Package.Dir, a.Package.Desc(), "note: module requires Go "+p.Module.GoVersion) + b.showOutput(a, a.Package.Dir, a.Package.Desc(), "note: module requires Go "+p.Module.GoVersion+"\n") } return err } @@ -906,12 +975,13 @@ func (b *Builder) loadCachedSrcFiles(a *Action) error { // vetConfig is the configuration passed to vet describing a single package. type vetConfig struct { - ID string // package ID (example: "fmt [fmt.test]") - Compiler string // compiler name (gc, gccgo) - Dir string // directory containing package - ImportPath string // canonical import path ("package path") - GoFiles []string // absolute paths to package source files - NonGoFiles []string // absolute paths to package non-Go files + ID string // package ID (example: "fmt [fmt.test]") + Compiler string // compiler name (gc, gccgo) + Dir string // directory containing package + ImportPath string // canonical import path ("package path") + GoFiles []string // absolute paths to package source files + NonGoFiles []string // absolute paths to package non-Go files + IgnoredFiles []string // absolute paths to ignored source files ImportMap map[string]string // map import path in source code to package path PackageFile map[string]string // map package path to .a file with export data @@ -935,20 +1005,23 @@ func buildVetConfig(a *Action, srcfiles []string) { } } + ignored := str.StringList(a.Package.IgnoredGoFiles, a.Package.IgnoredOtherFiles) + // Pass list of absolute paths to vet, // so that vet's error messages will use absolute paths, // so that we can reformat them relative to the directory // in which the go command is invoked. vcfg := &vetConfig{ - ID: a.Package.ImportPath, - Compiler: cfg.BuildToolchainName, - Dir: a.Package.Dir, - GoFiles: mkAbsFiles(a.Package.Dir, gofiles), - NonGoFiles: mkAbsFiles(a.Package.Dir, nongofiles), - ImportPath: a.Package.ImportPath, - ImportMap: make(map[string]string), - PackageFile: make(map[string]string), - Standard: make(map[string]bool), + ID: a.Package.ImportPath, + Compiler: cfg.BuildToolchainName, + Dir: a.Package.Dir, + GoFiles: mkAbsFiles(a.Package.Dir, gofiles), + NonGoFiles: mkAbsFiles(a.Package.Dir, nongofiles), + IgnoredFiles: mkAbsFiles(a.Package.Dir, ignored), + ImportPath: a.Package.ImportPath, + ImportMap: make(map[string]string), + PackageFile: make(map[string]string), + Standard: make(map[string]bool), } a.vetCfg = vcfg for i, raw := range a.Package.Internal.RawImports { @@ -993,7 +1066,7 @@ var VetFlags []string // VetExplicit records whether the vet flags were set explicitly on the command line. var VetExplicit bool -func (b *Builder) vet(a *Action) error { +func (b *Builder) vet(ctx context.Context, a *Action) error { // a.Deps[0] is the build of the package being vetted. // a.Deps[1] is the build of the "fmt" package. @@ -1036,17 +1109,28 @@ func (b *Builder) vet(a *Action) error { // This is OK as long as the packages that are farther down the // dependency tree turn on *more* analysis, as here. // (The unsafeptr check does not write any facts for use by - // later vet runs.) + // later vet runs, nor does unreachable.) if a.Package.Goroot && !VetExplicit && VetTool == "" { + // Turn off -unsafeptr checks. + // There's too much unsafe.Pointer code + // that vet doesn't like in low-level packages + // like runtime, sync, and reflect. // Note that $GOROOT/src/buildall.bash // does the same for the misc-compile trybots // and should be updated if these flags are // changed here. - // - // There's too much unsafe.Pointer code - // that vet doesn't like in low-level packages - // like runtime, sync, and reflect. vetFlags = []string{"-unsafeptr=false"} + + // Also turn off -unreachable checks during go test. + // During testing it is very common to make changes + // like hard-coded forced returns or panics that make + // code unreachable. It's unreasonable to insist on files + // not having any unreachable code during "go test". + // (buildall.bash still runs with -unreachable enabled + // for the overall whole-tree scan.) + if cfg.CmdName == "test" { + vetFlags = append(vetFlags, "-unreachable=false") + } } // Note: We could decide that vet should compute export data for @@ -1159,12 +1243,17 @@ func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) { fmt.Fprintf(h, "linkflags %q\n", p.Internal.Ldflags) } - // GO386, GOARM, GOMIPS, etc. + // GOARM, GOMIPS, etc. key, val := cfg.GetArchEnv() fmt.Fprintf(h, "%s=%s\n", key, val) - // The linker writes source file paths that say GOROOT_FINAL. - fmt.Fprintf(h, "GOROOT=%s\n", cfg.GOROOT_FINAL) + // The linker writes source file paths that say GOROOT_FINAL, but + // only if -trimpath is not specified (see ld() in gc.go). + gorootFinal := cfg.GOROOT_FINAL + if cfg.BuildTrimpath { + gorootFinal = trimPathGoRootFinal + } + fmt.Fprintf(h, "GOROOT=%s\n", gorootFinal) // GO_EXTLINK_ENABLED controls whether the external linker is used. fmt.Fprintf(h, "GO_EXTLINK_ENABLED=%s\n", cfg.Getenv("GO_EXTLINK_ENABLED")) @@ -1184,7 +1273,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) { +func (b *Builder) link(ctx context.Context, a *Action) (err error) { if b.useCache(a, b.linkActionID(a), a.Package.Target) || b.IsCmdList { return nil } @@ -1376,14 +1465,14 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, return } -func (b *Builder) installShlibname(a *Action) error { +func (b *Builder) installShlibname(ctx context.Context, a *Action) error { if err := allowInstall(a); err != nil { return err } // TODO: BuildN a1 := a.Deps[0] - err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666) + err := os.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666) if err != nil { return err } @@ -1425,7 +1514,7 @@ func (b *Builder) linkSharedActionID(a *Action) cache.ActionID { return h.Sum() } -func (b *Builder) linkShared(a *Action) (err error) { +func (b *Builder) linkShared(ctx context.Context, a *Action) (err error) { if b.useCache(a, b.linkSharedActionID(a), a.Target) || b.IsCmdList { return nil } @@ -1451,7 +1540,7 @@ func (b *Builder) linkShared(a *Action) (err error) { } // BuildInstallFunc is the action for installing a single package or executable. -func BuildInstallFunc(b *Builder, a *Action) (err error) { +func BuildInstallFunc(b *Builder, ctx context.Context, a *Action) (err error) { defer func() { if err != nil && err != errPrintedOutput { // a.Package == nil is possible for the go install -buildmode=shared @@ -1524,7 +1613,7 @@ func BuildInstallFunc(b *Builder, a *Action) (err error) { return err } - perm := os.FileMode(0666) + perm := fs.FileMode(0666) if a1.Mode == "link" { switch cfg.BuildBuildmode { case "c-archive", "c-shared", "plugin": @@ -1573,7 +1662,7 @@ func (b *Builder) cleanup(a *Action) { } // moveOrCopyFile is like 'mv src dst' or 'cp src dst'. -func (b *Builder) moveOrCopyFile(dst, src string, perm os.FileMode, force bool) error { +func (b *Builder) moveOrCopyFile(dst, src string, perm fs.FileMode, force bool) error { if cfg.BuildN { b.Showcmd("", "mv %s %s", src, dst) return nil @@ -1599,7 +1688,7 @@ func (b *Builder) moveOrCopyFile(dst, src string, perm os.FileMode, force bool) // we have to copy the file to retain the correct permissions. // https://golang.org/issue/18878 if fi, err := os.Stat(filepath.Dir(dst)); err == nil { - if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 { + if fi.IsDir() && (fi.Mode()&fs.ModeSetgid) != 0 { return b.copyFile(dst, src, perm, force) } } @@ -1634,7 +1723,7 @@ func (b *Builder) moveOrCopyFile(dst, src string, perm os.FileMode, force bool) } // copyFile is like 'cp src dst'. -func (b *Builder) copyFile(dst, src string, perm os.FileMode, force bool) error { +func (b *Builder) copyFile(dst, src string, perm fs.FileMode, force bool) error { if cfg.BuildN || cfg.BuildX { b.Showcmd("", "cp %s %s", src, dst) if cfg.BuildN { @@ -1700,11 +1789,11 @@ func (b *Builder) writeFile(file string, text []byte) error { if cfg.BuildN { return nil } - return ioutil.WriteFile(file, text, 0666) + return os.WriteFile(file, text, 0666) } // Install the cgo export header file, if there is one. -func (b *Builder) installHeader(a *Action) error { +func (b *Builder) installHeader(ctx context.Context, a *Action) error { src := a.Objdir + "_cgo_install.h" if _, err := os.Stat(src); os.IsNotExist(err) { // If the file does not exist, there are no exported @@ -1963,6 +2052,13 @@ func (b *Builder) runOut(a *Action, dir string, env []string, cmdargs ...interfa defer cleanup() cmd.Dir = dir cmd.Env = base.AppendPWD(os.Environ(), cmd.Dir) + + // Add the TOOLEXEC_IMPORTPATH environment variable for -toolexec tools. + // It doesn't really matter if -toolexec isn't being used. + if a != nil && a.Package != nil { + cmd.Env = append(cmd.Env, "TOOLEXEC_IMPORTPATH="+a.Package.ImportPath) + } + cmd.Env = append(cmd.Env, env...) start := time.Now() err := cmd.Run() @@ -2080,9 +2176,7 @@ func mkAbs(dir, f string) string { type toolchain interface { // gc runs the compiler in a specific directory on a set of files // and returns the name of the generated output file. - // - // TODO: This argument list is long. Consider putting it in a struct. - gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) + gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) // cc runs the toolchain's C compiler in a directory on a C file // to produce an output file. cc(b *Builder, a *Action, ofile, cfile string) error @@ -2122,7 +2216,7 @@ func (noToolchain) linker() string { return "" } -func (noToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) { +func (noToolchain) gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) { return "", nil, noCompiler() } @@ -2204,7 +2298,11 @@ func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []s } } - output, err := b.runOut(a, filepath.Dir(file), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(file)) + overlayPath := file + if p, ok := a.nonGoOverlay[overlayPath]; ok { + overlayPath = p + } + output, err := b.runOut(a, filepath.Dir(overlayPath), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(overlayPath)) if len(output) > 0 { // On FreeBSD 11, when we pass -g to clang 3.8 it // invokes its internal assembler with -dwarf-version=2. @@ -2247,7 +2345,8 @@ func (b *Builder) gccld(a *Action, p *load.Package, objdir, outfile string, flag cmdargs := []interface{}{cmd, "-o", outfile, objs, flags} dir := p.Dir - out, err := b.runOut(a, dir, b.cCompilerEnv(), cmdargs...) + out, err := b.runOut(a, base.Cwd, b.cCompilerEnv(), cmdargs...) + if len(out) > 0 { // Filter out useless linker warnings caused by bugs outside Go. // See also cmd/link/internal/ld's hostlink method. @@ -2403,7 +2502,7 @@ func (b *Builder) compilerCmd(compiler []string, incdir, workdir string) []strin // On OS X, some of the compilers behave as if -fno-common // is always set, and the Mach-O linker in 6l/8l assumes this. // See https://golang.org/issue/3253. - if cfg.Goos == "darwin" { + if cfg.Goos == "darwin" || cfg.Goos == "ios" { a = append(a, "-fno-common") } @@ -2445,7 +2544,7 @@ func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool { tmp := os.DevNull if runtime.GOOS == "windows" { - f, err := ioutil.TempFile(b.WorkDir, "") + f, err := os.CreateTemp(b.WorkDir, "") if err != nil { return false } @@ -2585,7 +2684,8 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...) } - // Allows including _cgo_export.h from .[ch] files in the package. + // Allows including _cgo_export.h, as well as the user's .h files, + // from .[ch] files in the package. cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", objdir) // cgo @@ -2642,7 +2742,23 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo cgoflags = append(cgoflags, "-exportheader="+objdir+"_cgo_install.h") } - if err := b.run(a, p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil { + execdir := p.Dir + + // Rewrite overlaid paths in cgo files. + // cgo adds //line and #line pragmas in generated files with these paths. + var trimpath []string + for i := range cgofiles { + path := mkAbs(p.Dir, cgofiles[i]) + if opath, ok := fsys.OverlayPath(path); ok { + cgofiles[i] = opath + trimpath = append(trimpath, opath+"=>"+path) + } + } + if len(trimpath) > 0 { + cgoflags = append(cgoflags, "-trimpath", strings.Join(trimpath, ";")) + } + + if err := b.run(a, execdir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil { return nil, nil, err } outGo = append(outGo, gofiles...) @@ -2735,7 +2851,7 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo continue } - src, err := ioutil.ReadFile(f) + src, err := os.ReadFile(f) if err != nil { return nil, nil, err } @@ -2811,7 +2927,7 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe return err } - linkobj := str.StringList(ofile, outObj, p.SysoFiles) + linkobj := str.StringList(ofile, outObj, mkAbsFiles(p.Dir, p.SysoFiles)) dynobj := objdir + "_cgo_.o" // we need to use -pie for Linux/ARM to get accurate imported sym @@ -2836,7 +2952,7 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe if p.Standard && p.ImportPath == "runtime/cgo" { cgoflags = []string{"-dynlinker"} // record path to dynamic linker } - return b.run(a, p.Dir, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags) + return b.run(a, base.Cwd, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags) } // Run SWIG on all SWIG input files. @@ -2965,14 +3081,14 @@ func (b *Builder) swigDoIntSize(objdir string) (intsize string, err error) { return "$INTBITS", nil } src := filepath.Join(b.WorkDir, "swig_intsize.go") - if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil { + if err = os.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil { return } srcs := []string{src} - p := load.GoFilesPackage(srcs) + p := load.GoFilesPackage(context.TODO(), srcs) - if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, "", false, srcs); e != nil { + if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, nil, "", false, srcs); e != nil { return "32", nil } return "64", nil @@ -3125,14 +3241,14 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) { return } - tf, err := ioutil.TempFile("", "args") + tf, err := os.CreateTemp("", "args") if err != nil { log.Fatalf("error writing long arguments to response file: %v", err) } cleanup = func() { os.Remove(tf.Name()) } var buf bytes.Buffer for _, arg := range cmd.Args[1:] { - fmt.Fprintf(&buf, "%s\n", arg) + fmt.Fprintf(&buf, "%s\n", encodeArg(arg)) } if _, err := tf.Write(buf.Bytes()); err != nil { tf.Close() @@ -3147,6 +3263,12 @@ func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) { return cleanup } +// Windows has a limit of 32 KB arguments. To be conservative and not worry +// about whether that includes spaces or not, just use 30 KB. Darwin's limit is +// less clear. The OS claims 256KB, but we've seen failures with arglen as +// small as 50KB. +const ArgLengthForResponseFile = (30 << 10) + func useResponseFile(path string, argLen int) bool { // Unless the program uses objabi.Flagparse, which understands // response files, don't use response files. @@ -3158,11 +3280,7 @@ func useResponseFile(path string, argLen int) bool { return false } - // Windows has a limit of 32 KB arguments. To be conservative and not - // worry about whether that includes spaces or not, just use 30 KB. - // Darwin's limit is less clear. The OS claims 256KB, but we've seen - // failures with arglen as small as 50KB. - if argLen > (30 << 10) { + if argLen > ArgLengthForResponseFile { return true } @@ -3175,3 +3293,25 @@ func useResponseFile(path string, argLen int) bool { return false } + +// encodeArg encodes an argument for response file writing. +func encodeArg(arg string) string { + // If there aren't any characters we need to reencode, fastpath out. + if !strings.ContainsAny(arg, "\\\n") { + return arg + } + var b strings.Builder + for _, r := range arg { + switch r { + case '\\': + b.WriteByte('\\') + b.WriteByte('\\') + case '\n': + b.WriteByte('\\') + b.WriteByte('n') + default: + b.WriteRune(r) + } + } + return b.String() +} diff --git a/libgo/go/cmd/go/internal/work/exec_test.go b/libgo/go/cmd/go/internal/work/exec_test.go new file mode 100644 index 00000000000..4eb762cb289 --- /dev/null +++ b/libgo/go/cmd/go/internal/work/exec_test.go @@ -0,0 +1,86 @@ +// 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 work + +import ( + "bytes" + "cmd/internal/objabi" + "fmt" + "math/rand" + "testing" + "time" + "unicode/utf8" +) + +func TestEncodeArgs(t *testing.T) { + t.Parallel() + tests := []struct { + arg, want string + }{ + {"", ""}, + {"hello", "hello"}, + {"hello\n", "hello\\n"}, + {"hello\\", "hello\\\\"}, + {"hello\nthere", "hello\\nthere"}, + {"\\\n", "\\\\\\n"}, + } + for _, test := range tests { + if got := encodeArg(test.arg); got != test.want { + t.Errorf("encodeArg(%q) = %q, want %q", test.arg, got, test.want) + } + } +} + +func TestEncodeDecode(t *testing.T) { + t.Parallel() + tests := []string{ + "", + "hello", + "hello\\there", + "hello\nthere", + "hello 中国", + "hello \n中\\国", + } + for _, arg := range tests { + if got := objabi.DecodeArg(encodeArg(arg)); got != arg { + t.Errorf("objabi.DecodeArg(encodeArg(%q)) = %q", arg, got) + } + } +} + +func TestEncodeDecodeFuzz(t *testing.T) { + if testing.Short() { + t.Skip("fuzz test is slow") + } + t.Parallel() + + nRunes := ArgLengthForResponseFile + 100 + rBuffer := make([]rune, nRunes) + buf := bytes.NewBuffer([]byte(string(rBuffer))) + + seed := time.Now().UnixNano() + t.Logf("rand seed: %v", seed) + rng := rand.New(rand.NewSource(seed)) + + for i := 0; i < 50; i++ { + // Generate a random string of runes. + buf.Reset() + for buf.Len() < ArgLengthForResponseFile+1 { + var r rune + for { + r = rune(rng.Intn(utf8.MaxRune + 1)) + if utf8.ValidRune(r) { + break + } + } + fmt.Fprintf(buf, "%c", r) + } + arg := buf.String() + + if got := objabi.DecodeArg(encodeArg(arg)); got != arg { + t.Errorf("[%d] objabi.DecodeArg(encodeArg(%q)) = %q [seed: %v]", i, arg, got, seed) + } + } +} diff --git a/libgo/go/cmd/go/internal/work/gc.go b/libgo/go/cmd/go/internal/work/gc.go index f1d08e02686..cc4e2b2b2b9 100644 --- a/libgo/go/cmd/go/internal/work/gc.go +++ b/libgo/go/cmd/go/internal/work/gc.go @@ -9,7 +9,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "log" "os" "path/filepath" @@ -18,6 +17,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/load" "cmd/go/internal/str" "cmd/internal/objabi" @@ -25,6 +25,9 @@ import ( "crypto/sha1" ) +// The 'path' used for GOROOT_FINAL when -trimpath is specified +const trimPathGoRootFinal = "go" + // The Go toolchain. type gcToolchain struct{} @@ -48,7 +51,7 @@ func pkgPath(a *Action) string { return ppath } -func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { +func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { p := a.Package objdir := a.Objdir if archive != "" { @@ -85,7 +88,11 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.FFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles) if p.Standard { switch p.ImportPath { - case "bytes", "internal/poll", "net", "os", "runtime/pprof", "runtime/trace", "sync", "syscall", "time": + case "bytes", "internal/poll", "net", "os": + fallthrough + case "runtime/metrics", "runtime/pprof", "runtime/trace": + fallthrough + case "sync", "syscall", "time": extFiles++ } } @@ -129,6 +136,12 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s } args = append(args, "-importcfg", objdir+"importcfg") } + if embedcfg != nil { + if err := b.writeFile(objdir+"embedcfg", embedcfg); err != nil { + return "", nil, err + } + args = append(args, "-embedcfg", objdir+"embedcfg") + } if ofile == archive { args = append(args, "-pack") } @@ -142,10 +155,26 @@ func (gcToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, s } for _, f := range gofiles { - args = append(args, mkAbs(p.Dir, f)) - } - - output, err = b.runOut(a, p.Dir, nil, args...) + f := mkAbs(p.Dir, f) + + // Handle overlays. Convert path names using OverlayPath + // so these paths can be handed directly to tools. + // Deleted files won't show up in when scanning directories earlier, + // so OverlayPath will never return "" (meaning a deleted file) here. + // TODO(#39958): Handle cases where the package directory + // doesn't exist on disk (this can happen when all the package's + // files are in an overlay): the code expects the package directory + // to exist and runs some tools in that directory. + // TODO(#39958): Process the overlays when the + // gofiles, cgofiles, cfiles, sfiles, and cxxfiles variables are + // created in (*Builder).build. Doing that requires rewriting the + // code that uses those values to expect absolute paths. + f, _ = fsys.OverlayPath(f) + + args = append(args, f) + } + + output, err = b.runOut(a, base.Cwd, nil, args...) return ofile, output, err } @@ -232,17 +261,63 @@ func (a *Action) trimpath() string { if len(objdir) > 1 && objdir[len(objdir)-1] == filepath.Separator { objdir = objdir[:len(objdir)-1] } - rewrite := objdir + "=>" + rewrite := "" - // For "go build -trimpath", rewrite package source directory - // to a file system-independent path (just the import path). + rewriteDir := a.Package.Dir if cfg.BuildTrimpath { if m := a.Package.Module; m != nil && m.Version != "" { - rewrite += ";" + a.Package.Dir + "=>" + m.Path + "@" + m.Version + strings.TrimPrefix(a.Package.ImportPath, m.Path) + rewriteDir = m.Path + "@" + m.Version + strings.TrimPrefix(a.Package.ImportPath, m.Path) } else { - rewrite += ";" + a.Package.Dir + "=>" + a.Package.ImportPath + rewriteDir = a.Package.ImportPath + } + rewrite += a.Package.Dir + "=>" + rewriteDir + ";" + } + + // Add rewrites for overlays. The 'from' and 'to' paths in overlays don't need to have + // same basename, so go from the overlay contents file path (passed to the compiler) + // to the path the disk path would be rewritten to. + + cgoFiles := make(map[string]bool) + for _, f := range a.Package.CgoFiles { + cgoFiles[f] = true + } + + // TODO(matloob): Higher up in the stack, when the logic for deciding when to make copies + // of c/c++/m/f/hfiles is consolidated, use the same logic that Build uses to determine + // whether to create the copies in objdir to decide whether to rewrite objdir to the + // package directory here. + var overlayNonGoRewrites string // rewrites for non-go files + hasCgoOverlay := false + if fsys.OverlayFile != "" { + for _, filename := range a.Package.AllFiles() { + path := filename + if !filepath.IsAbs(path) { + path = filepath.Join(a.Package.Dir, path) + } + base := filepath.Base(path) + isGo := strings.HasSuffix(filename, ".go") || strings.HasSuffix(filename, ".s") + isCgo := cgoFiles[filename] || !isGo + overlayPath, isOverlay := fsys.OverlayPath(path) + if isCgo && isOverlay { + hasCgoOverlay = true + } + if !isCgo && isOverlay { + rewrite += overlayPath + "=>" + filepath.Join(rewriteDir, base) + ";" + } else if isCgo { + // Generate rewrites for non-Go files copied to files in objdir. + if filepath.Dir(path) == a.Package.Dir { + // This is a file copied to objdir. + overlayNonGoRewrites += filepath.Join(objdir, base) + "=>" + filepath.Join(rewriteDir, base) + ";" + } + } else { + // Non-overlay Go files are covered by the a.Package.Dir rewrite rule above. + } } } + if hasCgoOverlay { + rewrite += overlayNonGoRewrites + } + rewrite += objdir + "=>" return rewrite } @@ -259,6 +334,21 @@ func asmArgs(a *Action, p *load.Package) []interface{} { } } } + if objabi.IsRuntimePackagePath(pkgpath) { + args = append(args, "-compiling-runtime") + if objabi.Regabi_enabled != 0 { + // In order to make it easier to port runtime assembly + // to the register ABI, we introduce a macro + // indicating the experiment is enabled. + // + // Note: a similar change also appears in + // cmd/dist/build.go. + // + // TODO(austin): Remove this once we commit to the + // register ABI (#40724). + args = append(args, "-D=GOEXPERIMENT_REGABI=1") + } + } if cfg.Goarch == "mips" || cfg.Goarch == "mipsle" { // Define GOMIPS_value from cfg.GOMIPS. @@ -279,9 +369,10 @@ func (gcToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) var ofiles []string for _, sfile := range sfiles { + overlayPath, _ := fsys.OverlayPath(mkAbs(p.Dir, sfile)) ofile := a.Objdir + sfile[:len(sfile)-len(".s")] + ".o" ofiles = append(ofiles, ofile) - args1 := append(args, "-o", ofile, mkAbs(p.Dir, sfile)) + args1 := append(args, "-o", ofile, overlayPath) if err := b.run(a, p.Dir, p.ImportPath, nil, args1...); err != nil { return nil, err } @@ -297,7 +388,8 @@ func (gcToolchain) symabis(b *Builder, a *Action, sfiles []string) (string, erro if p.ImportPath == "runtime/cgo" && strings.HasPrefix(sfile, "gcc_") { continue } - args = append(args, mkAbs(p.Dir, sfile)) + op, _ := fsys.OverlayPath(mkAbs(p.Dir, sfile)) + args = append(args, op) } // Supply an empty go_asm.h as if the compiler had been run. @@ -333,11 +425,11 @@ func toolVerify(a *Action, b *Builder, p *load.Package, newTool string, ofile st if err := b.run(a, p.Dir, p.ImportPath, nil, newArgs...); err != nil { return err } - data1, err := ioutil.ReadFile(ofile) + data1, err := os.ReadFile(ofile) if err != nil { return err } - data2, err := ioutil.ReadFile(ofile + ".new") + data2, err := os.ReadFile(ofile + ".new") if err != nil { return err } @@ -487,7 +579,7 @@ func pluginPath(a *Action) string { } fmt.Fprintf(h, "build ID: %s\n", buildID) for _, file := range str.StringList(p.GoFiles, p.CgoFiles, p.SFiles) { - data, err := ioutil.ReadFile(filepath.Join(p.Dir, file)) + data, err := os.ReadFile(filepath.Join(p.Dir, file)) if err != nil { base.Fatalf("go: %s", err) } @@ -560,7 +652,7 @@ func (gcToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string) env := []string{} if cfg.BuildTrimpath { - env = append(env, "GOROOT_FINAL=go") + env = append(env, "GOROOT_FINAL="+trimPathGoRootFinal) } return b.run(root, dir, root.Package.ImportPath, env, cfg.BuildToolexec, base.Tool("link"), "-o", out, "-importcfg", importcfg, ldflags, mainpkg) } diff --git a/libgo/go/cmd/go/internal/work/gccgo.go b/libgo/go/cmd/go/internal/work/gccgo.go index dbaff704468..793a333663f 100644 --- a/libgo/go/cmd/go/internal/work/gccgo.go +++ b/libgo/go/cmd/go/internal/work/gccgo.go @@ -6,7 +6,6 @@ package work import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -15,6 +14,7 @@ import ( "cmd/go/internal/base" "cmd/go/internal/cfg" + "cmd/go/internal/fsys" "cmd/go/internal/load" "cmd/go/internal/str" "cmd/internal/pkgpath" @@ -62,7 +62,7 @@ func checkGccgoBin() { base.Exit() } -func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { +func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg, embedcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { p := a.Package objdir := a.Objdir out := "_go_.o" @@ -93,13 +93,37 @@ 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") + + if b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") { + if cfg.BuildTrimpath { + args = append(args, "-ffile-prefix-map="+base.Cwd+"=.") + args = append(args, "-ffile-prefix-map="+b.WorkDir+"=/tmp/go-build") + } + if fsys.OverlayFile != "" { + for _, name := range gofiles { + absPath := mkAbs(p.Dir, name) + overlayPath, ok := fsys.OverlayPath(absPath) + if !ok { + continue + } + toPath := absPath + // gccgo only applies the last matching rule, so also handle the case where + // BuildTrimpath is true and the path is relative to base.Cwd. + if cfg.BuildTrimpath && str.HasFilePathPrefix(toPath, base.Cwd) { + toPath = "." + toPath[len(base.Cwd):] + } + args = append(args, "-ffile-prefix-map="+overlayPath+"="+toPath) + } + } } + args = append(args, a.Package.Internal.Gccgoflags...) for _, f := range gofiles { - args = append(args, mkAbs(p.Dir, f)) + f := mkAbs(p.Dir, f) + // Overlay files if necessary. + // See comment on gctoolchain.gc about overlay TODOs + f, _ = fsys.OverlayPath(f) + args = append(args, f) } output, err = b.runOut(a, p.Dir, nil, args) @@ -174,7 +198,7 @@ func (tools gccgoToolchain) asm(b *Builder, a *Action, sfiles []string) ([]strin base := filepath.Base(sfile) ofile := a.Objdir + base[:len(base)-len(".s")] + ".o" ofiles = append(ofiles, ofile) - sfile = mkAbs(p.Dir, sfile) + sfile, _ = fsys.OverlayPath(mkAbs(p.Dir, sfile)) defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch} if pkgpath := tools.gccgoCleanPkgpath(b, p); pkgpath != "" { defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath) @@ -246,7 +270,7 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string } readCgoFlags := func(flagsFile string) error { - flags, err := ioutil.ReadFile(flagsFile) + flags, err := os.ReadFile(flagsFile) if err != nil { return err } diff --git a/libgo/go/cmd/go/internal/work/init.go b/libgo/go/cmd/go/internal/work/init.go index c168364cd17..ba7c7c2fbb1 100644 --- a/libgo/go/cmd/go/internal/work/init.go +++ b/libgo/go/cmd/go/internal/work/init.go @@ -9,7 +9,8 @@ package work import ( "cmd/go/internal/base" "cmd/go/internal/cfg" - "cmd/go/internal/load" + "cmd/go/internal/fsys" + "cmd/go/internal/modload" "cmd/internal/objabi" "cmd/internal/sys" "flag" @@ -21,9 +22,12 @@ import ( ) func BuildInit() { - load.ModInit() + modload.Init() instrumentInit() buildModeInit() + if err := fsys.Init(base.Cwd); err != nil { + base.Fatalf("go: %v", err) + } // Make sure -pkgdir is absolute, because we run commands // in different directories. @@ -37,6 +41,13 @@ func BuildInit() { cfg.BuildPkgdir = p } + // Make sure CC and CXX are absolute paths + for _, key := range []string{"CC", "CXX"} { + if path := cfg.Getenv(key); !filepath.IsAbs(path) && path != "" && path != filepath.Base(path) { + base.Fatalf("go %s: %s environment variable is relative; must be absolute path: %s\n", flag.Args()[0], key, path) + } + } + // For each experiment that has been enabled in the toolchain, define a // build tag with the same name but prefixed by "goexperiment." which can be // used for compiling alternative files for the experiment. This allows @@ -68,7 +79,7 @@ func instrumentInit() { } if cfg.BuildRace { if !sys.RaceDetectorSupported(cfg.Goos, cfg.Goarch) { - fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0]) + fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, linux/ppc64le, linux/arm64, freebsd/amd64, netbsd/amd64, darwin/amd64, darwin/arm64, and windows/amd64\n", flag.Args()[0]) base.SetExitStatus(2) base.Exit() } @@ -121,7 +132,7 @@ func buildModeInit() { codegenArg = "-fPIC" } else { switch cfg.Goos { - case "darwin": + case "darwin", "ios": switch cfg.Goarch { case "arm64": codegenArg = "-shared" @@ -157,6 +168,9 @@ func buildModeInit() { ldBuildmode = "pie" case "windows": ldBuildmode = "pie" + case "ios": + codegenArg = "-shared" + ldBuildmode = "pie" case "darwin": switch cfg.Goarch { case "arm64": @@ -227,7 +241,8 @@ func buildModeInit() { if gccgo { codegenArg = "-fPIC" } else { - forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1") + forcedAsmflags = append(forcedAsmflags, "-D=GOBUILDMODE_shared=1", + "-linkshared") codegenArg = "-dynlink" forcedGcflags = append(forcedGcflags, "-linkshared") // TODO(mwhudson): remove -w when that gets fixed in linker. @@ -252,7 +267,7 @@ func buildModeInit() { switch cfg.BuildMod { case "": - // ok + // Behavior will be determined automatically, as if no flag were passed. case "readonly", "vendor", "mod": if !cfg.ModulesEnabled && !base.InGOFLAGS("-mod") { base.Fatalf("build flag -mod=%s only valid when using modules", cfg.BuildMod) diff --git a/libgo/go/cmd/go/internal/work/security.go b/libgo/go/cmd/go/internal/work/security.go index 0d9628241fd..36bbab37ee2 100644 --- a/libgo/go/cmd/go/internal/work/security.go +++ b/libgo/go/cmd/go/internal/work/security.go @@ -132,6 +132,7 @@ var validCompilerFlagsWithNextArg = []string{ "-U", "-I", "-framework", + "-include", "-isysroot", "-isystem", "--sysroot", @@ -177,7 +178,8 @@ var validLinkerFlags = []*lazyregexp.Regexp{ re(`-Wl,-Bdynamic`), re(`-Wl,-berok`), re(`-Wl,-Bstatic`), - re(`-WL,-O([^@,\-][^,]*)?`), + re(`-Wl,-Bsymbolic-functions`), + re(`-Wl,-O([^@,\-][^,]*)?`), re(`-Wl,-d[ny]`), re(`-Wl,--disable-new-dtags`), re(`-Wl,-e[=,][a-zA-Z0-9]*`), diff --git a/libgo/go/cmd/go/internal/work/security_test.go b/libgo/go/cmd/go/internal/work/security_test.go index aec9789185e..4f2e0eb21ab 100644 --- a/libgo/go/cmd/go/internal/work/security_test.go +++ b/libgo/go/cmd/go/internal/work/security_test.go @@ -65,6 +65,8 @@ var goodCompilerFlags = [][]string{ {"-I", "=/usr/include/libxml2"}, {"-I", "dir"}, {"-I", "$SYSROOT/dir"}, + {"-isystem", "/usr/include/mozjs-68"}, + {"-include", "/usr/include/mozjs-68/RequiredDefines.h"}, {"-framework", "Chocolate"}, {"-x", "c"}, {"-v"}, @@ -96,6 +98,7 @@ var badCompilerFlags = [][]string{ {"-I", "@foo"}, {"-I", "-foo"}, {"-I", "=@obj"}, + {"-include", "@foo"}, {"-framework", "-Caffeine"}, {"-framework", "@Home"}, {"-x", "--c"}, diff --git a/libgo/go/cmd/go/main.go b/libgo/go/cmd/go/main.go index 11913d6f063..c4af1955d12 100644 --- a/libgo/go/cmd/go/main.go +++ b/libgo/go/cmd/go/main.go @@ -7,6 +7,7 @@ package main import ( + "context" "flag" "fmt" "log" @@ -34,6 +35,7 @@ import ( "cmd/go/internal/run" "cmd/go/internal/test" "cmd/go/internal/tool" + "cmd/go/internal/trace" "cmd/go/internal/version" "cmd/go/internal/vet" "cmd/go/internal/work" @@ -73,10 +75,11 @@ func init() { modload.HelpModules, modget.HelpModuleGet, modfetch.HelpModuleAuth, - modfetch.HelpModulePrivate, help.HelpPackages, + modfetch.HelpPrivate, test.HelpTestflag, test.HelpTestfunc, + modget.HelpVCS, } } @@ -190,7 +193,10 @@ BigCmdLoop: cmd.Flag.Parse(args[1:]) args = cmd.Flag.Args() } - cmd.Run(cmd, args) + ctx := maybeStartTrace(context.Background()) + ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command")) + cmd.Run(ctx, cmd, args) + span.Done() base.Exit() return } @@ -212,3 +218,21 @@ func mainUsage() { help.PrintUsage(os.Stderr, base.Go) os.Exit(2) } + +func maybeStartTrace(pctx context.Context) context.Context { + if cfg.DebugTrace == "" { + return pctx + } + + ctx, close, err := trace.Start(pctx, cfg.DebugTrace) + if err != nil { + base.Fatalf("failed to start trace: %v", err) + } + base.AtExit(func() { + if err := close(); err != nil { + base.Fatalf("failed to stop trace: %v", err) + } + }) + + return ctx +} diff --git a/libgo/go/cmd/go/proxy_test.go b/libgo/go/cmd/go/proxy_test.go index 2a4d2935b38..e390c73a9cf 100644 --- a/libgo/go/cmd/go/proxy_test.go +++ b/libgo/go/cmd/go/proxy_test.go @@ -12,7 +12,7 @@ import ( "flag" "fmt" "io" - "io/ioutil" + "io/fs" "log" "net" "net/http" @@ -74,12 +74,12 @@ func StartProxy() { var modList []module.Version func readModList() { - infos, err := ioutil.ReadDir("testdata/mod") + files, err := os.ReadDir("testdata/mod") if err != nil { log.Fatal(err) } - for _, info := range infos { - name := info.Name() + for _, f := range files { + name := f.Name() if !strings.HasSuffix(name, ".txt") { continue } @@ -91,7 +91,7 @@ func readModList() { encPath := strings.ReplaceAll(name[:i], "_", "/") path, err := module.UnescapePath(encPath) if err != nil { - if encPath != "example.com/invalidpath/v1" { + if testing.Verbose() && encPath != "example.com/invalidpath/v1" { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) } continue @@ -131,11 +131,10 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { } path := r.URL.Path[len("/mod/"):] - // /mod/quiet/ does not print errors. - quiet := false - if strings.HasPrefix(path, "quiet/") { - path = path[len("quiet/"):] - quiet = true + // /mod/invalid returns faulty responses. + if strings.HasPrefix(path, "invalid/") { + w.Write([]byte("invalid")) + return } // Next element may opt into special behavior. @@ -214,7 +213,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { enc := path[:i] modPath, err := module.UnescapePath(enc) if err != nil { - if !quiet { + if testing.Verbose() { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) } http.NotFound(w, r) @@ -267,7 +266,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { enc, file := path[:i], path[i+len("/@v/"):] path, err := module.UnescapePath(enc) if err != nil { - if !quiet { + if testing.Verbose() { fmt.Fprintf(os.Stderr, "go proxy_test: %v\n", err) } http.NotFound(w, r) @@ -333,10 +332,10 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { a, err := readArchive(path, vers) if err != nil { - if !quiet { + if testing.Verbose() { fmt.Fprintf(os.Stderr, "go proxy: no archive %s %s: %v\n", path, vers, err) } - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { http.NotFound(w, r) } else { http.Error(w, "cannot load archive", 500) @@ -387,7 +386,7 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { }).(cached) if c.err != nil { - if !quiet { + if testing.Verbose() { fmt.Fprintf(os.Stderr, "go proxy: %v\n", c.err) } http.Error(w, c.err.Error(), 500) @@ -444,7 +443,7 @@ func readArchive(path, vers string) (*txtar.Archive, error) { return a }).(*txtar.Archive) if a == nil { - return nil, os.ErrNotExist + return nil, fs.ErrNotExist } return a, nil } @@ -471,13 +470,13 @@ func proxyGoSum(path, vers string) ([]byte, error) { } h1, err := dirhash.Hash1(names, func(name string) (io.ReadCloser, error) { data := files[name] - return ioutil.NopCloser(bytes.NewReader(data)), nil + return io.NopCloser(bytes.NewReader(data)), nil }) if err != nil { return nil, err } h1mod, err := dirhash.Hash1([]string{"go.mod"}, func(string) (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewReader(gomod)), nil + return io.NopCloser(bytes.NewReader(gomod)), nil }) 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 2e8f18a8972..dfaa40548e4 100644 --- a/libgo/go/cmd/go/script_test.go +++ b/libgo/go/cmd/go/script_test.go @@ -14,7 +14,7 @@ import ( "fmt" "go/build" "internal/testenv" - "io/ioutil" + "io/fs" "os" "os/exec" "path/filepath" @@ -22,6 +22,7 @@ import ( "runtime" "strconv" "strings" + "sync" "testing" "time" @@ -38,9 +39,7 @@ import ( // TestScript runs the tests in testdata/script/*.txt. func TestScript(t *testing.T) { testenv.MustHaveGoBuild(t) - if skipExternal { - t.Skipf("skipping external tests on %s/%s", runtime.GOOS, runtime.GOARCH) - } + testenv.SkipIfShortAndSlow(t) files, err := filepath.Glob("testdata/script/*.txt") if err != nil { @@ -135,12 +134,16 @@ func (ts *testScript) setup() { "GOSUMDB=" + testSumDBVerifierKey, "GONOPROXY=", "GONOSUMDB=", + "GOVCS=*:all", "PWD=" + ts.cd, tempEnvName() + "=" + filepath.Join(ts.workdir, "tmp"), "devnull=" + os.DevNull, "goversion=" + goVersion(ts), ":=" + string(os.PathListSeparator), } + if !testenv.HasExternalNetwork() { + ts.env = append(ts.env, "TESTGONETWORK=panic", "TESTGOVCS=panic") + } if runtime.GOOS == "plan9" { ts.env = append(ts.env, "path="+testBin+string(filepath.ListSeparator)+os.Getenv("path")) @@ -216,7 +219,7 @@ func (ts *testScript) run() { for _, f := range a.Files { name := ts.mkabs(ts.expand(f.Name, false)) ts.check(os.MkdirAll(filepath.Dir(name), 0777)) - ts.check(ioutil.WriteFile(name, f.Data, 0666)) + ts.check(os.WriteFile(name, f.Data, 0666)) } // With -v or -testwork, start log with full environment. @@ -296,6 +299,8 @@ Script: ok = os.Geteuid() == 0 case "symlink": ok = testenv.HasSymlink() + case "case-sensitive": + ok = isCaseSensitive(ts.t) default: if strings.HasPrefix(cond.tag, "exec:") { prog := cond.tag[len("exec:"):] @@ -364,6 +369,41 @@ Script: } } +var ( + onceCaseSensitive sync.Once + caseSensitive bool +) + +func isCaseSensitive(t *testing.T) bool { + onceCaseSensitive.Do(func() { + tmpdir, err := os.MkdirTemp("", "case-sensitive") + if err != nil { + t.Fatal("failed to create directory to determine case-sensitivity:", err) + } + defer os.RemoveAll(tmpdir) + + fcap := filepath.Join(tmpdir, "FILE") + if err := os.WriteFile(fcap, []byte{}, 0644); err != nil { + t.Fatal("error writing file to determine case-sensitivity:", err) + } + + flow := filepath.Join(tmpdir, "file") + _, err = os.ReadFile(flow) + switch { + case err == nil: + caseSensitive = false + return + case os.IsNotExist(err): + caseSensitive = true + return + default: + t.Fatal("unexpected error reading file when determining case-sensitivity:", err) + } + }) + + return caseSensitive +} + // scriptCmds are the script command implementations. // Keep list and the implementations below sorted by name. // @@ -409,9 +449,9 @@ func (ts *testScript) cmdAddcrlf(want simpleStatus, args []string) { for _, file := range args { file = ts.mkabs(file) - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) ts.check(err) - ts.check(ioutil.WriteFile(file, bytes.ReplaceAll(data, []byte("\n"), []byte("\r\n")), 0666)) + ts.check(os.WriteFile(file, bytes.ReplaceAll(data, []byte("\n"), []byte("\r\n")), 0666)) } } @@ -462,7 +502,7 @@ func (ts *testScript) cmdChmod(want simpleStatus, args []string) { ts.fatalf("usage: chmod perm paths...") } perm, err := strconv.ParseUint(args[0], 0, 32) - if err != nil || perm&uint64(os.ModePerm) != perm { + if err != nil || perm&uint64(fs.ModePerm) != perm { ts.fatalf("invalid mode: %s", args[0]) } for _, arg := range args[1:] { @@ -470,7 +510,7 @@ func (ts *testScript) cmdChmod(want simpleStatus, args []string) { if !filepath.IsAbs(path) { path = filepath.Join(ts.cd, arg) } - err := os.Chmod(path, os.FileMode(perm)) + err := os.Chmod(path, fs.FileMode(perm)) ts.check(err) } } @@ -516,12 +556,12 @@ func (ts *testScript) doCmdCmp(args []string, env, quiet bool) { } else if name1 == "stderr" { text1 = ts.stderr } else { - data, err := ioutil.ReadFile(ts.mkabs(name1)) + data, err := os.ReadFile(ts.mkabs(name1)) ts.check(err) text1 = string(data) } - data, err := ioutil.ReadFile(ts.mkabs(name2)) + data, err := os.ReadFile(ts.mkabs(name2)) ts.check(err) text2 = string(data) @@ -557,7 +597,7 @@ func (ts *testScript) cmdCp(want simpleStatus, args []string) { var ( src string data []byte - mode os.FileMode + mode fs.FileMode ) switch arg { case "stdout": @@ -573,14 +613,14 @@ func (ts *testScript) cmdCp(want simpleStatus, args []string) { info, err := os.Stat(src) ts.check(err) mode = info.Mode() & 0777 - data, err = ioutil.ReadFile(src) + data, err = os.ReadFile(src) ts.check(err) } targ := dst if dstDir { targ = filepath.Join(dst, filepath.Base(src)) } - err := ioutil.WriteFile(targ, data, mode) + err := os.WriteFile(targ, data, mode) switch want { case failure: if err == nil { @@ -856,7 +896,7 @@ func scriptMatch(ts *testScript, want simpleStatus, args []string, text, name st isGrep := name == "grep" if isGrep { name = args[1] // for error messages - data, err := ioutil.ReadFile(ts.mkabs(args[1])) + data, err := os.ReadFile(ts.mkabs(args[1])) ts.check(err) text = string(data) } @@ -1218,7 +1258,12 @@ func (ts *testScript) parse(line string) command { if cmd.name != "" { cmd.args = append(cmd.args, arg) - isRegexp = false // Commands take only one regexp argument, so no subsequent args are regexps. + // Commands take only one regexp argument (after the optional flags), + // so no subsequent args are regexps. Liberally assume an argument that + // starts with a '-' is a flag. + if len(arg) == 0 || arg[0] != '-' { + isRegexp = false + } return } diff --git a/libgo/go/cmd/go/testdata/addmod.go b/libgo/go/cmd/go/testdata/addmod.go index d9c3aab9c49..58376b7ed4a 100644 --- a/libgo/go/cmd/go/testdata/addmod.go +++ b/libgo/go/cmd/go/testdata/addmod.go @@ -22,7 +22,7 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" + "io/fs" "log" "os" "os/exec" @@ -57,7 +57,7 @@ func main() { log.SetFlags(0) var err error - tmpdir, err = ioutil.TempDir("", "addmod-") + tmpdir, err = os.MkdirTemp("", "addmod-") if err != nil { log.Fatal(err) } @@ -81,7 +81,7 @@ func main() { exitCode := 0 for _, arg := range flag.Args() { - if err := ioutil.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil { + if err := os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte("module m\n"), 0666); err != nil { fatalf("%v", err) } run(goCmd, "get", "-d", arg) @@ -97,13 +97,13 @@ func main() { continue } path, vers, dir := f[0], f[1], f[2] - mod, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod")) + mod, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".mod")) if err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 continue } - info, err := ioutil.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info")) + info, err := os.ReadFile(filepath.Join(gopath, "pkg/mod/cache/download", path, "@v", vers+".info")) if err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 @@ -121,13 +121,13 @@ func main() { {Name: ".info", Data: info}, } dir = filepath.Clean(dir) - err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if !info.Mode().IsRegular() { + err = filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { + if !info.Type().IsRegular() { return nil } name := info.Name() if name == "go.mod" || strings.HasSuffix(name, ".go") { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return err } @@ -143,7 +143,7 @@ func main() { data := txtar.Format(a) target := filepath.Join("mod", strings.ReplaceAll(path, "/", "_")+"_"+vers+".txt") - if err := ioutil.WriteFile(target, data, 0666); err != nil { + if err := os.WriteFile(target, data, 0666); err != nil { log.Printf("%s: %v", arg, err) exitCode = 1 continue diff --git a/libgo/go/cmd/go/testdata/savedir.go b/libgo/go/cmd/go/testdata/savedir.go index 48a63188607..d469c31a919 100644 --- a/libgo/go/cmd/go/testdata/savedir.go +++ b/libgo/go/cmd/go/testdata/savedir.go @@ -17,7 +17,7 @@ package main import ( "flag" "fmt" - "io/ioutil" + "io/fs" "log" "os" "path/filepath" @@ -48,7 +48,7 @@ func main() { a := new(txtar.Archive) dir = filepath.Clean(dir) - filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error { if path == dir { return nil } @@ -59,10 +59,10 @@ func main() { } return nil } - if !info.Mode().IsRegular() { + if !info.Type().IsRegular() { return nil } - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { log.Fatal(err) } diff --git a/libgo/go/cmd/go/testdata/script/README b/libgo/go/cmd/go/testdata/script/README index 76d66517183..d658cebfce0 100644 --- a/libgo/go/cmd/go/testdata/script/README +++ b/libgo/go/cmd/go/testdata/script/README @@ -85,6 +85,7 @@ should only run when the condition is satisfied. The available conditions are: - [link] for testenv.HasLink() - [root] for os.Geteuid() == 0 - [symlink] for testenv.HasSymlink() + - [case-sensitive] for whether the file system is case-sensitive - [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 diff --git a/libgo/go/cmd/go/testdata/script/build_GOTMPDIR.txt b/libgo/go/cmd/go/testdata/script/build_GOTMPDIR.txt index c93ca932cab..1073517c298 100644 --- a/libgo/go/cmd/go/testdata/script/build_GOTMPDIR.txt +++ b/libgo/go/cmd/go/testdata/script/build_GOTMPDIR.txt @@ -1,15 +1,50 @@ -env GO111MODULE=off -[short] skip - # Set GOCACHE to a clean directory to ensure that 'go build' has work to report. -env GOCACHE=$WORK/gocache +[!windows] env GOCACHE=$WORK/gocache +[windows] env GOCACHE=$WORK\gocache -# Build should use GOTMPDIR if set. -env GOTMPDIR=$WORK/my-favorite-tmpdir +# 'go build' should use GOTMPDIR if set. +[!windows] env GOTMPDIR=$WORK/my-favorite-tmpdir +[windows] env GOTMPDIR=$WORK\my-favorite-tmpdir mkdir $GOTMPDIR -go build -work hello.go +go build -x hello.go stderr ^WORK=.*my-favorite-tmpdir +# Make GOTMPDIR a regular file. This prevents the creation of work directories, +# so we can check that certain commands don't create them. +# This simulates running on a full disk or a read-only volume. +rm $GOTMPDIR +cp hello.go $GOTMPDIR # any file will do + +# 'go build' should fail if GOTMPDIR is read-only. +! go build -x . +stderr '^go: creating work dir: \w+ '$GOTMPDIR + +# 'go list' should only fail if it needs to build something. +go list -x . +! stderr 'creating work dir' +stdout m +go list -m all +stdout m +! go list -x -export . +stderr '^go: creating work dir: \w+ '$GOTMPDIR + +# 'go clean -cache' and 'go clean -modcache' should not fail. +go clean -x -cache +! stderr 'creating work dir' +go clean -x -modcache +! stderr 'creating work dir' + +# 'go env' should not fail for specific variables. +# Without arguments, it needs to initialize a builder to load cgo flags, and +# that uses a temporary directory. +! go env +stderr '^go: creating work dir: \w+ '$GOTMPDIR +go env GOROOT + +-- go.mod -- +module m + +go 1.15 -- hello.go -- package main func main() { println("hello") } diff --git a/libgo/go/cmd/go/testdata/script/build_trimpath.txt b/libgo/go/cmd/go/testdata/script/build_trimpath.txt index ad78bcf2b27..e1ea0a48b2a 100644 --- a/libgo/go/cmd/go/testdata/script/build_trimpath.txt +++ b/libgo/go/cmd/go/testdata/script/build_trimpath.txt @@ -9,6 +9,8 @@ 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 overlay.json $WORK/a/src/paths +cp overlay.json $WORK/b/src/paths cp go.mod $WORK/a/src/paths/ cp go.mod $WORK/b/src/paths/ @@ -43,6 +45,29 @@ go build -trimpath -o $WORK/paths-b.exe cmp -q $WORK/paths-a.exe $WORK/paths-b.exe +# Same sequence of tests but with overlays. +# 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 -overlay overlay.json -o $WORK/paths-dbg.exe ./overlaydir +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 -overlay overlay.json -trimpath -o $WORK/paths-a.exe ./overlaydir +exec $WORK/paths-a.exe $WORK/paths-a.exe +stdout 'binary contains module root: false' +stdout 'binary contains GOROOT: false' + +# Two binaries built from identical packages in different directories +# should be identical. +cd $WORK/b/src/paths +go build -overlay overlay.json -trimpath -o $WORK/paths-b.exe ./overlaydir +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 @@ -96,7 +121,6 @@ package main import ( "bytes" "fmt" - "io/ioutil" "log" "os" "os/exec" @@ -106,7 +130,7 @@ import ( func main() { exe := os.Args[1] - data, err := ioutil.ReadFile(exe) + data, err := os.ReadFile(exe) if err != nil { log.Fatal(err) } @@ -129,7 +153,8 @@ func check(data []byte, desc, dir string) { containsSlashDir := bytes.Contains(data, []byte(filepath.ToSlash(dir))) fmt.Printf("binary contains %s: %v\n", desc, containsDir || containsSlashDir) } - +-- overlay.json -- +{ "Replace": { "overlaydir/paths.go": "paths.go" } } -- go.mod -- module paths diff --git a/libgo/go/cmd/go/testdata/script/env_write.txt b/libgo/go/cmd/go/testdata/script/env_write.txt index 1cc08466c96..dc696524119 100644 --- a/libgo/go/cmd/go/testdata/script/env_write.txt +++ b/libgo/go/cmd/go/testdata/script/env_write.txt @@ -24,6 +24,16 @@ stdout GOARCH= stdout GOOS= stdout GOROOT= +# go env ignores invalid flag in GOFLAGS environment variable +env GOFLAGS='=true' +go env + +# checking errors +! go env -w +stderr 'go env -w: no KEY=VALUE arguments given' +! go env -u +stderr 'go env -u: no arguments given' + # go env -w changes default setting env root= [windows] env root=c: @@ -59,6 +69,8 @@ go env -u GOPATH stderr 'unknown go command variable GODEBUG' ! go env -w GOEXE=.bat stderr 'GOEXE cannot be modified' +! go env -w GOVERSION=customversion +stderr 'GOVERSION cannot be modified' ! go env -w GOENV=/env stderr 'GOENV can only be set using the OS environment' @@ -97,6 +109,50 @@ 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 rejects invalid GOTMPDIR values +! go env -w GOTMPDIR=x +stderr 'go env -w: GOTMPDIR must be an absolute path' + +# go env -w should accept absolute GOTMPDIR value +# and should not create it +[windows] go env -w GOTMPDIR=$WORK\x\y\z +[!windows] go env -w GOTMPDIR=$WORK/x/y/z +! exists $WORK/x/y/z +# we should be able to clear an env +go env -u GOTMPDIR +go env GOTMPDIR +stdout ^$ + +[windows] go env -w GOTMPDIR=$WORK\x\y\z +[!windows] go env -w GOTMPDIR=$WORK/x/y/z +go env -w GOTMPDIR= +go env GOTMPDIR +stdout ^$ + +# go env -w rejects relative CC values +[!windows] go env -w CC=/usr/bin/clang +go env -w CC=clang +[!windows] ! go env -w CC=./clang +[!windows] ! go env -w CC=bin/clang +[!windows] stderr 'go env -w: CC entry is relative; must be absolute path' + +[windows] go env -w CC=$WORK\bin\clang +[windows] ! go env -w CC=.\clang +[windows] ! go env -w CC=bin\clang +[windows] stderr 'go env -w: CC entry is relative; must be absolute path' + +# go env -w rejects relative CXX values +[!windows] go env -w CC=/usr/bin/cpp +go env -w CXX=cpp +[!windows] ! go env -w CXX=./cpp +[!windows] ! go env -w CXX=bin/cpp +[!windows] stderr 'go env -w: CXX entry is relative; must be absolute path' + +[windows] go env -w CXX=$WORK\bin\cpp +[windows] ! go env -w CXX=.\cpp +[windows] ! go env -w CXX=bin\cpp +[windows] stderr 'go env -w: CXX entry is relative; must be absolute path' + # go env -w/-u checks validity of GOOS/ARCH combinations [gccgo] skip env GOOS= diff --git a/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt b/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt index 5374493a439..f23cecefd3a 100644 --- a/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt +++ b/libgo/go/cmd/go/testdata/script/gcflags_patterns.txt @@ -63,6 +63,10 @@ stderr 'link.* -X=math.pi=3' go build -n -ldflags=-X=math.pi=3 stderr 'link.* -X=math.pi=3' +# cgo.a should not be a dependency of internally-linked go package +go build -ldflags='-linkmode=external -linkmode=internal' -n prog.go +! stderr 'packagefile .*runtime/cgo.a' + -- z1/z.go -- package z1 import _ "y" diff --git a/libgo/go/cmd/go/testdata/script/get_unicode.txt b/libgo/go/cmd/go/testdata/script/get_unicode.txt deleted file mode 100644 index d3b82bdf250..00000000000 --- a/libgo/go/cmd/go/testdata/script/get_unicode.txt +++ /dev/null @@ -1,40 +0,0 @@ -env GO111MODULE=off - -[!exec:git] skip -[short] skip - -# Construct a repository that imports a non-ASCII path. -cd $WORK/_origin/example.com/unicode -exec git init -exec git config user.name 'Nameless Gopher' -exec git config user.email 'nobody@golang.org' -exec git add unicode.go -exec git commit -m 'add unicode.go' - -# Clone the repo into GOPATH so that 'go get -u' can find it. -mkdir $GOPATH/src/example.com/unicode -cd $GOPATH/src/example.com/unicode -exec git clone $WORK/_origin/example.com/unicode . - -# Construct the imported repository. -cd $WORK/_origin/example.com/испытание -exec git init -exec git config user.name 'Nameless Gopher' -exec git config user.email 'nobody@golang.org' -exec git add испытание.go -exec git commit -m 'add испытание.go' - -# Clone that repo into GOPATH too. -mkdir $GOPATH/src/example.com/испытание -cd $GOPATH/src/example.com/испытание -exec git clone $WORK/_origin/example.com/испытание . - -# Upgrading the importer should pull from the non-ASCII repo. -cd $GOPATH -go get -u example.com/unicode - --- $WORK/_origin/example.com/unicode/unicode.go -- -package unicode -import _ "example.com/испытание" --- $WORK/_origin/example.com/испытание/испытание.go -- -package испытание diff --git a/libgo/go/cmd/go/testdata/script/gopath_moved_repo.txt b/libgo/go/cmd/go/testdata/script/gopath_moved_repo.txt index 869980da7c5..99d80bff5d9 100644 --- a/libgo/go/cmd/go/testdata/script/gopath_moved_repo.txt +++ b/libgo/go/cmd/go/testdata/script/gopath_moved_repo.txt @@ -45,7 +45,6 @@ package main import ( "bytes" - "io/ioutil" "log" "os" ) @@ -57,11 +56,11 @@ func main() { base := []byte(os.Args[1]) path := os.Args[2] - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { log.Fatal(err) } - err = ioutil.WriteFile(path, bytes.ReplaceAll(data, base, append(base, "XXX"...)), 0644) + err = os.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/link_syso_issue33139.txt b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt index 3030ee924ff..26034c96266 100644 --- a/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt +++ b/libgo/go/cmd/go/testdata/script/link_syso_issue33139.txt @@ -8,14 +8,13 @@ # See: https://github.com/golang/go/issues/8912 [linux] [ppc64] skip -# External linking is not supported on linux/riscv, linux/riscv64. -# See: https://github.com/golang/go/issues/36739 -[linux] [riscv] skip -[linux] [riscv64] skip - cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c go build -ldflags='-linkmode=external' ./cmd/main.go +-- go.mod -- +module m + +go 1.16 -- syso/objTest.s -- #include "textflag.h" @@ -37,7 +36,7 @@ void objTestImpl() { /* Empty */ } -- cmd/main.go -- package main -import "syso" +import "m/syso" func main() { syso.ObjTest() diff --git a/libgo/go/cmd/go/testdata/script/list_bad_import.txt b/libgo/go/cmd/go/testdata/script/list_bad_import.txt index b8f9d586f30..dbec35069c6 100644 --- a/libgo/go/cmd/go/testdata/script/list_bad_import.txt +++ b/libgo/go/cmd/go/testdata/script/list_bad_import.txt @@ -15,10 +15,11 @@ stdout 'incomplete' stdout 'bad dep: .*example.com[/\\]notfound' # Listing with -deps should also fail. -# BUG: Today, it does not. -# ! go list -deps example.com/direct -# stderr example.com[/\\]notfound -go list -deps example.com/direct +! go list -deps example.com/direct +stderr example.com[/\\]notfound + +# But -e -deps should succeed. +go list -e -deps example.com/direct stdout example.com/notfound @@ -31,10 +32,11 @@ stdout incomplete stdout 'bad dep: .*example.com[/\\]notfound' # Again, -deps should fail. -# BUG: Again, it does not. -# ! go list -deps example.com/indirect -# stderr example.com[/\\]notfound -go list -deps example.com/indirect +! go list -deps example.com/indirect +stderr example.com[/\\]notfound + +# But -deps -e should succeed. +go list -e -deps example.com/indirect stdout example.com/notfound diff --git a/libgo/go/cmd/go/testdata/script/list_test_err.txt b/libgo/go/cmd/go/testdata/script/list_test_err.txt index a174b5e9ad2..c6f1ecf4003 100644 --- a/libgo/go/cmd/go/testdata/script/list_test_err.txt +++ b/libgo/go/cmd/go/testdata/script/list_test_err.txt @@ -22,6 +22,9 @@ go list -e -test -deps -f '{{.ImportPath}} {{.Error | printf "%q"}}' syntaxerr stdout 'pkgdep ' stdout 'testdep_a ' stdout 'testdep_b ' +stdout 'syntaxerr ' +stdout 'syntaxerr \[syntaxerr.test\] ' +stdout 'syntaxerr_test \[syntaxerr.test\] ' stdout 'syntaxerr\.test "[^"]*expected declaration' ! stderr 'expected declaration' diff --git a/libgo/go/cmd/go/testdata/script/mod_auth.txt b/libgo/go/cmd/go/testdata/script/mod_auth.txt index 5bcbcd1a188..d8ea5867d6b 100644 --- a/libgo/go/cmd/go/testdata/script/mod_auth.txt +++ b/libgo/go/cmd/go/testdata/script/mod_auth.txt @@ -3,11 +3,12 @@ env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off +env GOVCS='*:off' # Without credentials, downloading a module from a path that requires HTTPS # basic auth should fail. env NETRC=$WORK/empty -! go list all +! go mod tidy stderr '^\tserver response: ACCESS DENIED, buddy$' stderr '^\tserver response: File\? What file\?$' 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 ec0d474382e..20199c1c2ca 100644 --- a/libgo/go/cmd/go/testdata/script/mod_bad_domain.txt +++ b/libgo/go/cmd/go/testdata/script/mod_bad_domain.txt @@ -2,22 +2,34 @@ env GO111MODULE=on # explicit get should report errors about bad names ! go get appengine -stderr '^go get appengine: package appengine is not in GOROOT \(.*\)$' +stderr '^go get: malformed module path "appengine": missing dot in first path element$' ! 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 -stderr 'cannot find package' +stderr '^useappengine[/\\]x.go:2:8: cannot find package$' ! go build ./usenonexistent -stderr 'cannot find module providing package nonexistent.rsc.io' +stderr '^usenonexistent[/\\]x.go:2:8: no required module provides package nonexistent.rsc.io; try ''go mod tidy'' to add it$' + + +# 'get -d' should be similarly definitive + +go get -d ./useappengine # TODO(#41315): This should fail. + # stderr '^useappengine[/\\]x.go:2:8: cannot find package$' + +! go get -d ./usenonexistent +stderr '^x/usenonexistent imports\n\tnonexistent.rsc.io: cannot find module providing package nonexistent.rsc.io$' + # go mod vendor and go mod tidy should ignore appengine imports. rm usenonexistent/x.go diff --git a/libgo/go/cmd/go/testdata/script/mod_bad_filenames.txt b/libgo/go/cmd/go/testdata/script/mod_bad_filenames.txt index 6e0c8bd3023..eb556f4c7cf 100644 --- a/libgo/go/cmd/go/testdata/script/mod_bad_filenames.txt +++ b/libgo/go/cmd/go/testdata/script/mod_bad_filenames.txt @@ -3,9 +3,9 @@ env GO111MODULE=on ! go get rsc.io/badfile1 rsc.io/badfile2 rsc.io/badfile3 rsc.io/badfile4 rsc.io/badfile5 ! stderr 'unzip.*badfile1' stderr 'unzip.*badfile2[\\/]@v[\\/]v1.0.0.zip:.*malformed file path "☺.go": invalid char ''☺''' -stderr 'unzip.*badfile3[\\/]@v[\\/]v1.0.0.zip: malformed file path "x\?y.go": invalid char ''\?''' -stderr 'unzip.*badfile4[\\/]@v[\\/]v1.0.0.zip: case-insensitive file name collision: "x/Y.go" and "x/y.go"' -stderr 'unzip.*badfile5[\\/]@v[\\/]v1.0.0.zip: case-insensitive file name collision: "x/y" and "x/Y"' +stderr 'unzip.*badfile3[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile3@v1.0.0[\\/]x\?y.go: malformed file path "x\?y.go": invalid char ''\?''' +stderr 'unzip.*badfile4[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile4@v1.0.0[\\/]x[\\/]y.go: case-insensitive file name collision: "x/Y.go" and "x/y.go"' +stderr 'unzip.*badfile5[\\/]@v[\\/]v1.0.0.zip: rsc.io[\\/]badfile5@v1.0.0[\\/]x[\\/]Y[\\/]zz[\\/]ww.go: case-insensitive file name collision: "x/y" and "x/Y"' -- go.mod -- module x 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 index 87a099b219c..cee055eabe9 100644 --- a/libgo/go/cmd/go/testdata/script/mod_build_info_err.txt +++ b/libgo/go/cmd/go/testdata/script/mod_build_info_err.txt @@ -1,8 +1,19 @@ # 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 list -e -mod=mod -deps -f '{{with .Error}}{{.Pos}}: {{.Err}}{{end}}' ./main +stdout '^bad[/\\]bad.go:3:8: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + +# TODO(#26909): This should include an import stack. +# (Today it includes only a file and line.) +! go build ./main +stderr '^bad[/\\]bad.go:3:8: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + +# TODO(#41688): This should include a file and line, and report the reason for the error.. +# (Today it includes only an import stack.) +! go get -d ./main +stderr '^m/main imports\n\tm/bad imports\n\t🐧.example.com/string: malformed import path "🐧.example.com/string": invalid char ''🐧''$' + -- go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/script/mod_case.txt b/libgo/go/cmd/go/testdata/script/mod_case.txt index ee818c2c07b..4a4698600f7 100644 --- a/libgo/go/cmd/go/testdata/script/mod_case.txt +++ b/libgo/go/cmd/go/testdata/script/mod_case.txt @@ -1,6 +1,6 @@ env GO111MODULE=on -go get rsc.io/QUOTE +go get -d go list -m all stdout '^rsc.io/quote v1.5.2' stdout '^rsc.io/QUOTE v1.5.2' @@ -9,7 +9,7 @@ go list -f 'DIR {{.Dir}} DEPS {{.Deps}}' rsc.io/QUOTE/QUOTE stdout 'DEPS.*rsc.io/quote' stdout 'DIR.*!q!u!o!t!e' -go get rsc.io/QUOTE@v1.5.3-PRE +go get -d rsc.io/QUOTE@v1.5.3-PRE go list -m all stdout '^rsc.io/QUOTE v1.5.3-PRE' @@ -18,3 +18,8 @@ stdout '!q!u!o!t!e@v1.5.3-!p!r!e' -- go.mod -- module x + +-- use.go -- +package use + +import _ "rsc.io/QUOTE/QUOTE" diff --git a/libgo/go/cmd/go/testdata/script/mod_case_cgo.txt b/libgo/go/cmd/go/testdata/script/mod_case_cgo.txt index 917bce92d88..f3d6aaa5abc 100644 --- a/libgo/go/cmd/go/testdata/script/mod_case_cgo.txt +++ b/libgo/go/cmd/go/testdata/script/mod_case_cgo.txt @@ -2,7 +2,9 @@ env GO111MODULE=on -go get rsc.io/CGO +go get -d rsc.io/CGO +[short] stop + go build rsc.io/CGO -- go.mod -- diff --git a/libgo/go/cmd/go/testdata/script/mod_concurrent.txt b/libgo/go/cmd/go/testdata/script/mod_concurrent.txt index e03e5e5edbe..8c215251587 100644 --- a/libgo/go/cmd/go/testdata/script/mod_concurrent.txt +++ b/libgo/go/cmd/go/testdata/script/mod_concurrent.txt @@ -1,6 +1,7 @@ env GO111MODULE=on # Concurrent builds should succeed, even if they need to download modules. +go get -d ./x ./y go build ./x & go build ./y wait diff --git a/libgo/go/cmd/go/testdata/script/mod_doc.txt b/libgo/go/cmd/go/testdata/script/mod_doc.txt index aac3db00be1..595ad679fc0 100644 --- a/libgo/go/cmd/go/testdata/script/mod_doc.txt +++ b/libgo/go/cmd/go/testdata/script/mod_doc.txt @@ -1,6 +1,7 @@ # go doc should find module documentation env GO111MODULE=on +env GOFLAGS=-mod=mod [short] skip # Check when module x is inside GOPATH/src. @@ -48,6 +49,7 @@ stderr '^doc: cannot find module providing package example.com/hello: module loo # path used in source code, not to the absolute path relative to GOROOT. cd $GOROOT/src +env GOFLAGS= go doc cryptobyte stdout '// import "golang.org/x/crypto/cryptobyte"' diff --git a/libgo/go/cmd/go/testdata/script/mod_domain_root.txt b/libgo/go/cmd/go/testdata/script/mod_domain_root.txt index e34cc29fa64..14745b5812c 100644 --- a/libgo/go/cmd/go/testdata/script/mod_domain_root.txt +++ b/libgo/go/cmd/go/testdata/script/mod_domain_root.txt @@ -2,7 +2,7 @@ # (example.com not example.com/something) env GO111MODULE=on -go build +go get -d -- go.mod -- module x diff --git a/libgo/go/cmd/go/testdata/script/mod_dot.txt b/libgo/go/cmd/go/testdata/script/mod_dot.txt index c220e99cedd..e5813206474 100644 --- a/libgo/go/cmd/go/testdata/script/mod_dot.txt +++ b/libgo/go/cmd/go/testdata/script/mod_dot.txt @@ -4,8 +4,12 @@ env GO111MODULE=on # in an empty directory should refer to the path '.' and should not attempt # to resolve an external module. cd dir +! go get +stderr '^go get: no package in current directory$' ! go get . -stderr 'go get \.: path .* is not a package in module rooted at .*[/\\]dir$' +stderr '^go get \.: no package in current directory$' +! go get ./subdir +stderr '^go get: \.[/\\]subdir \('$WORK'[/\\]gopath[/\\]src[/\\]dir[/\\]subdir\) is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src[/\\]dir$' ! go list ! stderr 'cannot find module providing package' stderr '^no Go files in '$WORK'[/\\]gopath[/\\]src[/\\]dir$' diff --git a/libgo/go/cmd/go/testdata/script/mod_download.txt b/libgo/go/cmd/go/testdata/script/mod_download.txt index 3573928a933..8a9faffe4e0 100644 --- a/libgo/go/cmd/go/testdata/script/mod_download.txt +++ b/libgo/go/cmd/go/testdata/script/mod_download.txt @@ -1,14 +1,15 @@ env GO111MODULE=on -env GOPROXY=$GOPROXY/quiet -# download with version should print nothing +# download with version should print nothing. +# It should not load retractions from the .mod file from the latest version. 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 exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.0.zip +! 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 # download of an invalid path should report the error [short] skip @@ -32,53 +33,59 @@ stdout '^\t"GoModSum": "h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe\+TKr0="' 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 - -# module loading will page in the info and mod files -go list -m all +# download query should have downloaded go.mod for the highest release version +# in order to find retractions when resolving the query '@<=v1.5.0'. 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 +# add to go.mod so we can test non-query downloads +go mod edit -require rsc.io/quote@v1.5.3-pre1 +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip + +# module loading will page in the info and mod files +go list -m -mod=mod all +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip + # download will fetch and unpack the zip file go mod download -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 -exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 # download repopulates deleted files and directories independently. -rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.info go mod download -exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info -rm $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.3-pre1.info +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod go mod download -exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod -rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.mod +rm $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip go mod download -exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip -rm -r $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +rm -r $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 go mod download -exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 +exists $GOPATH/pkg/mod/rsc.io/quote@v1.5.3-pre1 # download reports the locations of downloaded files go mod download -json stdout '^\t"Path": "rsc.io/quote"' -stdout '^\t"Version": "v1.5.2"' -stdout '^\t"Info": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.2.info"' -stdout '^\t"GoMod": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.2.mod"' -stdout '^\t"Zip": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.2.zip"' -stdout '^\t"Dir": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)rsc.io(\\\\|/)quote@v1.5.2"' +stdout '^\t"Version": "v1.5.3-pre1"' +stdout '^\t"Info": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.info"' +stdout '^\t"GoMod": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.mod"' +stdout '^\t"Zip": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)cache(\\\\|/)download(\\\\|/)rsc.io(\\\\|/)quote(\\\\|/)@v(\\\\|/)v1.5.3-pre1.zip"' +stdout '^\t"Dir": ".*(\\\\|/)pkg(\\\\|/)mod(\\\\|/)rsc.io(\\\\|/)quote@v1.5.3-pre1"' # download will follow replacements -go mod edit -require rsc.io/quote@v1.5.1 -replace rsc.io/quote@v1.5.1=rsc.io/quote@v1.5.3-pre1 +go mod edit -require rsc.io/quote@v1.5.1 -replace rsc.io/quote@v1.5.1=rsc.io/quote@v1.5.2 go mod download ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip -exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.3-pre1.zip +exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip # download will not follow replacements for explicit module queries go mod download -json rsc.io/quote@v1.5.1 @@ -86,19 +93,27 @@ exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.zip # download reports errors encountered when locating modules ! go mod download bad/path -stderr '^module bad/path: not a known dependency$' +stderr '^go mod download: module bad/path: not a known dependency$' ! go mod download bad/path@latest -stderr '^bad/path@latest: malformed module path "bad/path": missing dot in first path element$' +stderr '^go mod download: bad/path@latest: malformed module path "bad/path": missing dot in first path element$' ! go mod download rsc.io/quote@v1.999.999 -stderr '^rsc.io/quote@v1.999.999: reading .*/v1.999.999.info: 404 Not Found$' +stderr '^go mod download: 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 +# download main module produces a warning or 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' +! go mod download m@latest +stderr '^go mod download: m@latest: malformed module path "m": missing dot in first path element$' + +# download updates go.mod and populates go.sum +cd update +! exists go.sum +go mod download +grep '^rsc.io/sampler v1.3.0 ' go.sum +go list -m rsc.io/sampler +stdout '^rsc.io/sampler v1.3.0$' # allow go mod download without go.mod env GO111MODULE=auto @@ -115,3 +130,13 @@ stderr 'get '$GOPROXY -- go.mod -- module m + +-- update/go.mod -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.2.1 // older version than in build list +) diff --git a/libgo/go/cmd/go/testdata/script/mod_download_json.txt b/libgo/go/cmd/go/testdata/script/mod_download_json.txt index 01c35dd9937..9555adf8c4e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_download_json.txt +++ b/libgo/go/cmd/go/testdata/script/mod_download_json.txt @@ -1,10 +1,9 @@ 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' +stdout '"Error": ".*verifying (module|go.mod)' -- go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/script/mod_edit.txt b/libgo/go/cmd/go/testdata/script/mod_edit.txt index 898d8524acf..78485eb86ae 100644 --- a/libgo/go/cmd/go/testdata/script/mod_edit.txt +++ b/libgo/go/cmd/go/testdata/script/mod_edit.txt @@ -16,15 +16,19 @@ cmpenv go.mod $WORK/go.mod.init cmpenv go.mod $WORK/go.mod.init # go mod edits -go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' +go mod edit -droprequire=x.1 -require=x.1@v1.0.0 -require=x.2@v1.1.0 -droprequire=x.2 -exclude='x.1 @ v1.2.0' -exclude=x.1@v1.2.1 -replace=x.1@v1.3.0=y.1@v1.4.0 -replace='x.1@v1.4.0 = ../z' -retract=v1.6.0 -retract=[v1.1.0,v1.2.0] -retract=[v1.3.0,v1.4.0] -retract=v1.0.0 cmpenv go.mod $WORK/go.mod.edit1 -go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 +go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0] cmpenv go.mod $WORK/go.mod.edit2 # go mod edit -json go mod edit -json cmpenv stdout $WORK/go.mod.json +# go mod edit -json (retractions with rationales) +go mod edit -json $WORK/go.mod.retractrationale +cmp stdout $WORK/go.mod.retractrationale.json + # go mod edit -json (empty mod file) go mod edit -json $WORK/go.mod.empty cmp stdout $WORK/go.mod.empty.json @@ -40,11 +44,11 @@ cmpenv go.mod $WORK/go.mod.edit5 # go mod edit -fmt cp $WORK/go.mod.badfmt go.mod go mod edit -fmt -print # -print should avoid writing file -cmpenv stdout $WORK/go.mod.edit6 +cmpenv stdout $WORK/go.mod.goodfmt cmp go.mod $WORK/go.mod.badfmt go mod edit -fmt # without -print, should write file (and nothing to stdout) ! stdout . -cmpenv go.mod $WORK/go.mod.edit6 +cmpenv go.mod $WORK/go.mod.goodfmt # go mod edit -module cd $WORK/m @@ -84,6 +88,13 @@ replace ( x.1 v1.3.0 => y.1 v1.4.0 x.1 v1.4.0 => ../z ) + +retract ( + v1.6.0 + [v1.3.0, v1.4.0] + [v1.1.0, v1.2.0] + v1.0.0 +) -- $WORK/go.mod.edit2 -- module x.x/y/z @@ -93,6 +104,11 @@ exclude x.1 v1.2.0 replace x.1 v1.4.0 => ../z +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + require x.3 v1.99.0 -- $WORK/go.mod.json -- { @@ -122,6 +138,16 @@ require x.3 v1.99.0 "Path": "../z" } } + ], + "Retract": [ + { + "Low": "v1.6.0", + "High": "v1.6.0" + }, + { + "Low": "v1.3.0", + "High": "v1.4.0" + } ] } -- $WORK/go.mod.edit3 -- @@ -136,6 +162,11 @@ replace ( x.1 v1.4.0 => y.1/v2 v2.3.5 ) +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + require x.3 v1.99.0 -- $WORK/go.mod.edit4 -- module x.x/y/z @@ -146,6 +177,11 @@ exclude x.1 v1.2.0 replace x.1 => y.1/v2 v2.3.6 +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) + require x.3 v1.99.0 -- $WORK/go.mod.edit5 -- module x.x/y/z @@ -154,15 +190,10 @@ go $goversion exclude x.1 v1.2.0 -require x.3 v1.99.0 --- $WORK/go.mod.edit6 -- -module x.x/y/z - -go 1.10 - -exclude x.1 v1.2.0 - -replace x.1 => y.1/v2 v2.3.6 +retract ( + v1.6.0 + [v1.3.0, v1.4.0] +) require x.3 v1.99.0 -- $WORK/local/go.mod.edit -- @@ -183,10 +214,64 @@ exclude x.1 v1.2.0 replace x.1 => y.1/v2 v2.3.6 require x.3 v1.99.0 + +retract [ "v1.8.1" , "v1.8.2" ] +-- $WORK/go.mod.goodfmt -- +module x.x/y/z + +go 1.10 + +exclude x.1 v1.2.0 + +replace x.1 => y.1/v2 v2.3.6 + +require x.3 v1.99.0 + +retract [v1.8.1, v1.8.2] -- $WORK/m/go.mod.edit -- module x.x/y/z go $goversion +-- $WORK/go.mod.retractrationale -- +module x.x/y/z + +go 1.15 + +// a +retract v1.0.0 + +// b +retract ( + v1.0.1 + v1.0.2 // c +) +-- $WORK/go.mod.retractrationale.json -- +{ + "Module": { + "Path": "x.x/y/z" + }, + "Go": "1.15", + "Require": null, + "Exclude": null, + "Replace": null, + "Retract": [ + { + "Low": "v1.0.0", + "High": "v1.0.0", + "Rationale": "a" + }, + { + "Low": "v1.0.1", + "High": "v1.0.1", + "Rationale": "b" + }, + { + "Low": "v1.0.2", + "High": "v1.0.2", + "Rationale": "c" + } + ] +} -- $WORK/go.mod.empty -- -- $WORK/go.mod.empty.json -- { @@ -195,5 +280,6 @@ go $goversion }, "Require": null, "Exclude": null, - "Replace": null + "Replace": null, + "Retract": null } diff --git a/libgo/go/cmd/go/testdata/script/mod_enabled.txt b/libgo/go/cmd/go/testdata/script/mod_enabled.txt index 10fa103fad3..39f1ece8cb8 100644 --- a/libgo/go/cmd/go/testdata/script/mod_enabled.txt +++ b/libgo/go/cmd/go/testdata/script/mod_enabled.txt @@ -25,7 +25,7 @@ cd $GOPATH/foo/bar/baz go env GOMOD stdout foo[/\\]go.mod -# GO111MODULE unset should be equivalent to auto. +# GO111MODULE unset should be equivalent to on. env GO111MODULE= cd $GOPATH/src/x/y/z @@ -34,7 +34,7 @@ stdout $GOPATH[/\\]src[/\\]x[/\\]y[/\\]z[/\\]go.mod cd $GOPATH/src/x/y go env GOMOD -! stdout . +stdout 'NUL|/dev/null' # GO111MODULE=on should trigger everywhere env GO111MODULE=on diff --git a/libgo/go/cmd/go/testdata/script/mod_find.txt b/libgo/go/cmd/go/testdata/script/mod_find.txt index 7fbe9fb7fe6..9468acfd33d 100644 --- a/libgo/go/cmd/go/testdata/script/mod_find.txt +++ b/libgo/go/cmd/go/testdata/script/mod_find.txt @@ -19,6 +19,11 @@ go mod init stderr 'module example.com/x/y$' rm go.mod +# go mod init rejects a zero-length go.mod file +cp $devnull go.mod # can't use touch to create it because Windows +! go mod init +stderr 'go.mod already exists' + # Module path from Godeps/Godeps.json overrides GOPATH. cd $GOPATH/src/example.com/x/y/z go mod init diff --git a/libgo/go/cmd/go/testdata/script/mod_get_commit.txt b/libgo/go/cmd/go/testdata/script/mod_get_commit.txt index d108242c70e..4649491a532 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_commit.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_commit.txt @@ -1,5 +1,4 @@ env GO111MODULE=on -env GOPROXY=$GOPROXY/quiet [short] skip # @commit should resolve @@ -33,11 +32,11 @@ go install -x golang.org/x/text/language ! go get -d -x golang.org/x/text/foo@14c0d48 # get pseudo-version should record that version -go get rsc.io/quote@v0.0.0-20180214005840-23179ee8a569 +go get -d rsc.io/quote@v0.0.0-20180214005840-23179ee8a569 grep 'rsc.io/quote v0.0.0-20180214005840-23179ee8a569' go.mod # but as commit should record as v1.5.1 -go get rsc.io/quote@23179ee8 +go get -d rsc.io/quote@23179ee8 grep 'rsc.io/quote v1.5.1' go.mod # go mod edit -require does not interpret commits diff --git a/libgo/go/cmd/go/testdata/script/mod_get_downgrade.txt b/libgo/go/cmd/go/testdata/script/mod_get_downgrade.txt index ee9ac964751..a954c10344b 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_downgrade.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_downgrade.txt @@ -3,30 +3,33 @@ env GO111MODULE=on # downgrade sampler should downgrade quote cp go.mod.orig go.mod -go get rsc.io/sampler@v1.0.0 +go get -d rsc.io/sampler@v1.0.0 go list -m all stdout 'rsc.io/quote v1.4.0' stdout 'rsc.io/sampler v1.0.0' # downgrade sampler away should downgrade quote further -go get rsc.io/sampler@none +go get -d rsc.io/sampler@none go list -m all stdout 'rsc.io/quote v1.3.0' # downgrade should report inconsistencies and not change go.mod -go get rsc.io/quote@v1.5.1 +go get -d rsc.io/quote@v1.5.1 go list -m all stdout 'rsc.io/quote v1.5.1' stdout 'rsc.io/sampler v1.3.0' -! go get rsc.io/sampler@v1.0.0 rsc.io/quote@v1.5.2 golang.org/x/text@none -stderr 'go get: inconsistent versions:\n\trsc.io/quote@v1.5.2 requires golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c \(not golang.org/x/text@none\), rsc.io/sampler@v1.3.0 \(not rsc.io/sampler@v1.0.0\)' + +! go get -d rsc.io/sampler@v1.0.0 rsc.io/quote@v1.5.2 golang.org/x/text@none +stderr '^go get: rsc.io/quote@v1.5.2 requires rsc.io/sampler@v1.3.0, not rsc.io/sampler@v1.0.0$' +stderr '^go get: rsc.io/quote@v1.5.2 requires golang.org/x/text@v0.0.0-20170915032832-14c0d48ead0c, not golang.org/x/text@none$' + go list -m all stdout 'rsc.io/quote v1.5.1' stdout 'rsc.io/sampler v1.3.0' # go get -u args should limit upgrades cp go.mod.empty go.mod -go get -u rsc.io/quote@v1.4.0 rsc.io/sampler@v1.0.0 +go get -d -u rsc.io/quote@v1.4.0 rsc.io/sampler@v1.0.0 go list -m all stdout 'rsc.io/quote v1.4.0' stdout 'rsc.io/sampler v1.0.0' @@ -37,7 +40,7 @@ stdout 'rsc.io/sampler v1.0.0' cp go.mod.orig go.mod go list -m -versions example.com/latemigrate/v2 stdout v2.0.0 # proxy may serve incompatible versions -go get rsc.io/quote@none +go get -d rsc.io/quote@none go list -m all ! stdout 'example.com/latemigrate/v2' diff --git a/libgo/go/cmd/go/testdata/script/mod_get_incompatible.txt b/libgo/go/cmd/go/testdata/script/mod_get_incompatible.txt index b210715a5de..8000ee61481 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_incompatible.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_incompatible.txt @@ -1,15 +1,15 @@ env GO111MODULE=on -go list x +go get -d x go list -m all stdout 'rsc.io/breaker v2.0.0\+incompatible' cp go.mod2 go.mod -go get rsc.io/breaker@7307b30 +go get -d rsc.io/breaker@7307b30 go list -m all stdout 'rsc.io/breaker v2.0.0\+incompatible' -go get rsc.io/breaker@v2.0.0 +go get -d rsc.io/breaker@v2.0.0 go list -m all stdout 'rsc.io/breaker v2.0.0\+incompatible' diff --git a/libgo/go/cmd/go/testdata/script/mod_get_indirect.txt b/libgo/go/cmd/go/testdata/script/mod_get_indirect.txt index f25e170a499..e1cc1ab4115 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_indirect.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_indirect.txt @@ -27,7 +27,7 @@ grep 'golang.org/x/text v0.3.0 // indirect$' go.mod # indirect tag should be removed upon seeing direct import. cp $WORK/tmp/uselang.go x.go -go list +go get -d grep 'rsc.io/quote v1.5.2$' go.mod grep 'golang.org/x/text [v0-9a-f\.-]+$' go.mod diff --git a/libgo/go/cmd/go/testdata/script/mod_get_latest_pseudo.txt b/libgo/go/cmd/go/testdata/script/mod_get_latest_pseudo.txt index 825ee8cf896..241a0c2f0df 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_latest_pseudo.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_latest_pseudo.txt @@ -5,6 +5,6 @@ env GO111MODULE=on go mod init m -go list example.com/notags +go get -d example.com/notags go list -m all stdout '^example.com/notags v0.0.0-20190507143103-cc8cbe209b64$' diff --git a/libgo/go/cmd/go/testdata/script/mod_get_main.txt b/libgo/go/cmd/go/testdata/script/mod_get_main.txt index 408a5b51c84..50b2fee9ae1 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_main.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_main.txt @@ -3,13 +3,13 @@ cp go.mod.orig go.mod # relative and absolute paths must be within the main module. ! go get -d .. -stderr '^go get \.\.: path '$WORK'[/\\]gopath is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src$' +stderr '^go get: \.\. \('$WORK'[/\\]gopath\) is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' ! go get -d $WORK -stderr '^go get '$WORK': path '$WORK' is not a package in module rooted at '$WORK'[/\\]gopath[/\\]src$' +stderr '^go get: '$WORK' is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' ! go get -d ../... -stderr '^go get: pattern \.\./\.\.\.: directory prefix \.\. outside available modules$' +stderr '^go get: \.\./\.\.\. \('$WORK'[/\\]gopath([/\\]...)?\) is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' ! go get -d $WORK/... -stderr '^go get: pattern '$WORK'[/\\]\.\.\.: directory prefix \.\.[/\\]\.\. outside available modules$' +stderr '^go get: '$WORK'[/\\]\.\.\. is not within module rooted at '$WORK'[/\\]gopath[/\\]src$' # @patch and @latest within the main module refer to the current version. # The main module won't be upgraded, but missing dependencies will be added. @@ -22,21 +22,25 @@ go get -d rsc.io/x@patch grep 'rsc.io/quote v1.5.2' go.mod cp go.mod.orig go.mod -# The main module cannot be updated to @latest, which is a specific version. -! go get -d rsc.io/x@latest -stderr '^go get rsc.io/x@latest: can.t request explicit version of path in main module$' - -# The main module cannot be updated to a specific version. -! go get -d rsc.io/x@v0.1.0 -stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$' -! go get -d rsc.io/x@v0.1.0 -stderr '^go get rsc.io/x@v0.1.0: can.t request explicit version of path in main module$' # Upgrading a package pattern not contained in the main module should not # attempt to upgrade the main module. go get -d rsc.io/quote/...@v1.5.1 grep 'rsc.io/quote v1.5.1' go.mod + +# The main module cannot be updated to a specific version. +! go get -d rsc.io@v0.1.0 +stderr '^go get: can''t request version "v0.1.0" of the main module \(rsc.io\)$' + +# A package in the main module can't be upgraded either. +! go get -d rsc.io/x@v0.1.0 +stderr '^go get: package rsc.io/x is in the main module, so can''t request version v0.1.0$' + +# Nor can a pattern matching packages in the main module. +! go get -d rsc.io/x/...@latest +stderr '^go get: pattern rsc.io/x/... matches package rsc.io/x in the main module, so can''t request version latest$' + -- go.mod.orig -- module rsc.io diff --git a/libgo/go/cmd/go/testdata/script/mod_get_moved.txt b/libgo/go/cmd/go/testdata/script/mod_get_moved.txt index edc41cf9488..8430a737c40 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_moved.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_moved.txt @@ -1,5 +1,4 @@ env GO111MODULE=on -env GOPROXY=$GOPROXY/quiet [short] skip # A 'go get' that worked at a previous version should continue to work at that version, @@ -10,7 +9,7 @@ go list -m all stdout 'example.com/split v1.0.0' # A 'go get' that simultaneously upgrades away conflicting package defitions is not ambiguous. -go get example.com/split/subpkg@v1.1.0 +go get -d example.com/split/subpkg@v1.1.0 # A 'go get' without an upgrade should find the package. rm go.mod @@ -29,7 +28,9 @@ go list -m all stdout 'example.com/join/subpkg v1.0.0' # A 'go get' that simultaneously upgrades away conflicting package definitions is not ambiguous. -go get example.com/join/subpkg@v1.1.0 +# (A wildcard pattern applies to both packages and modules, +# because we define wildcard matching to apply after version resolution.) +go get -d example.com/join/subpkg/...@v1.1.0 # A 'go get' without an upgrade should find the package. rm go.mod 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 5c197bb0b82..f71620c1bcb 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_newcycle.txt @@ -11,5 +11,4 @@ go mod init m cmp stderr stderr-expected -- stderr-expected -- -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) +go get: 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_none.txt b/libgo/go/cmd/go/testdata/script/mod_get_none.txt index 5aec209f59f..b358f05af36 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_none.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_none.txt @@ -3,10 +3,10 @@ env GO111MODULE=on go mod init example.com/foo # 'go get bar@none' should be a no-op if module bar is not active. -go get example.com/bar@none +go get -d example.com/bar@none go list -m all ! stdout example.com/bar -go get example.com/bar@none +go get -d example.com/bar@none go list -m all ! stdout example.com/bar 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 8adc4b0c065..aee4374dc8a 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_patterns.txt @@ -10,21 +10,27 @@ 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 found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x...' +stderr 'go get: 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 found \(v1.5.2\), but does not contain packages matching rsc.io/quote/x/...' +stderr 'go get: 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 -# be upgraded, even if the module path matches the pattern. +# be upgraded, even if the module path is a prefix of the pattern. cp go.mod.orig go.mod go mod edit -require example.com/nest@v1.0.0 go get -d example.com/nest/sub/y... grep 'example.com/nest/sub v1.0.0' go.mod grep 'example.com/nest v1.0.0' go.mod +# However, if the pattern matches the module path itself, the module +# should be upgraded even if it contains no matching packages. +go get -d example.com/n...t +grep 'example.com/nest v1.1.0' go.mod +grep 'example.com/nest/sub v1.0.0' go.mod + -- go.mod.orig -- module m diff --git a/libgo/go/cmd/go/testdata/script/mod_get_test.txt b/libgo/go/cmd/go/testdata/script/mod_get_test.txt index 3680ca273d9..23722bd4e4d 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_test.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_test.txt @@ -2,7 +2,7 @@ env GO111MODULE=on # By default, 'go get' should ignore tests cp go.mod.empty go.mod -go get m/a +go get -d m/a ! grep rsc.io/quote go.mod # 'go get -t' should consider test dependencies of the named package. 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 index 7b5d90c50b5..3b38d8ba7d3 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_trailing_slash.txt @@ -1,3 +1,6 @@ +# Populate go.sum +go mod download + # 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 diff --git a/libgo/go/cmd/go/testdata/script/mod_get_upgrade.txt b/libgo/go/cmd/go/testdata/script/mod_get_upgrade.txt index 6a14dfdc45d..eeb6d6f6af6 100644 --- a/libgo/go/cmd/go/testdata/script/mod_get_upgrade.txt +++ b/libgo/go/cmd/go/testdata/script/mod_get_upgrade.txt @@ -1,6 +1,6 @@ env GO111MODULE=on -go get rsc.io/quote@v1.5.1 +go get -d rsc.io/quote@v1.5.1 go list -m all stdout 'rsc.io/quote v1.5.1' grep 'rsc.io/quote v1.5.1$' go.mod diff --git a/libgo/go/cmd/go/testdata/script/mod_go_version.txt b/libgo/go/cmd/go/testdata/script/mod_go_version.txt index 37f173531b6..97d9975e680 100644 --- a/libgo/go/cmd/go/testdata/script/mod_go_version.txt +++ b/libgo/go/cmd/go/testdata/script/mod_go_version.txt @@ -8,12 +8,19 @@ go build sub.1 go build subver.1 ! stderr 'module requires' ! go build badsub.1 -stderr 'module requires Go 1.11111' +stderr '^note: module requires Go 1.11111$' go build versioned.1 go mod edit -require versioned.1@v1.1.0 ! go build versioned.1 -stderr 'module requires Go 1.99999' +stderr '^note: module requires Go 1.99999$' + +[short] stop + +# The message should be printed even if the compiler emits no output. +go build -o $WORK/nooutput.exe nooutput.go +! go build -toolexec=$WORK/nooutput.exe versioned.1 +stderr '^# versioned.1\nnote: module requires Go 1.99999$' -- go.mod -- module m @@ -71,3 +78,33 @@ go 1.99999 -- versioned2/x.go -- package x invalid syntax + +-- nooutput.go -- +// +build ignore + +package main + +import ( + "bytes" + "os" + "os/exec" + "strings" +) + +func main() { + stderr := new(bytes.Buffer) + stdout := new(bytes.Buffer) + + cmd := exec.Command(os.Args[1], os.Args[2:]...) + cmd.Stderr = stderr + cmd.Stdout = stdout + + err := cmd.Run() + if strings.HasPrefix(os.Args[2], "-V") { + os.Stderr.Write(stderr.Bytes()) + os.Stdout.Write(stdout.Bytes()) + } + if err != nil { + os.Exit(1) + } +} diff --git a/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt b/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt index 948496241e9..3a133663ec7 100644 --- a/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt +++ b/libgo/go/cmd/go/testdata/script/mod_gobuild_import.txt @@ -19,7 +19,7 @@ exec $WORK/testimport$GOEXE other/x/y/z/w . stdout w2.go ! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . -stderr 'cannot find module providing package gobuild.example.com/x/y/z/w' +stderr 'no required module provides package gobuild.example.com/x/y/z/w; try ''go get -d gobuild.example.com/x/y/z/w'' to add it' cd z exec $WORK/testimport$GOEXE other/x/y/z/w . diff --git a/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt b/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt index a9e0ca40108..204786969f5 100644 --- a/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt +++ b/libgo/go/cmd/go/testdata/script/mod_gonoproxy.txt @@ -7,26 +7,32 @@ env dbname=localhost.localdev/sumdb # disagree with sumdb fails cp go.mod.orig go.mod env GOSUMDB=$sumdb' '$proxy/sumdb-wrong -! go get rsc.io/quote +! go get -d rsc.io/quote stderr 'SECURITY ERROR' # GONOSUMDB bypasses sumdb, for rsc.io/quote, rsc.io/sampler, golang.org/x/text env GONOSUMDB='*/quote,*/*mple*,golang.org/x' -go get rsc.io/quote +go get -d rsc.io/quote rm go.sum env GOPRIVATE='*/quote,*/*mple*,golang.org/x' env GONOPROXY=none # that is, proxy all despite GOPRIVATE -go get rsc.io/quote +go get -d rsc.io/quote + +# Download .info files needed for 'go list -m all' later. +# TODO(#42723): either 'go list -m' should not read these files, +# or 'go get' and 'go mod tidy' should download them. +go list -m all +stdout '^golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c$' # When GOPROXY is not empty but contains no entries, an error should be reported. env GOPROXY=',' -! go get golang.org/x/text +! go get -d golang.org/x/text stderr '^go get golang.org/x/text: GOPROXY list is not the empty string, but contains no entries$' # When GOPROXY=off, fetching modules not matched by GONOPROXY fails. env GONOPROXY=*/fortune env GOPROXY=off -! go get golang.org/x/text +! go get -d golang.org/x/text stderr '^go get golang.org/x/text: module lookup disabled by GOPROXY=off$' # GONOPROXY bypasses proxy @@ -34,13 +40,13 @@ stderr '^go get golang.org/x/text: module lookup disabled by GOPROXY=off$' [!exec:git] skip env GOPRIVATE=none env GONOPROXY='*/fortune' -! go get rsc.io/fortune # does not exist in real world, only on test proxy +! go get -d rsc.io/fortune # does not exist in real world, only on test proxy stderr 'git ls-remote' env GOSUMDB= env GONOPROXY= env GOPRIVATE='*/x' -go get golang.org/x/text +go get -d golang.org/x/text go list -m all ! stdout 'text.*v0.0.0-2017' # should not have the version from the proxy diff --git a/libgo/go/cmd/go/testdata/script/mod_gopkg_unstable.txt b/libgo/go/cmd/go/testdata/script/mod_gopkg_unstable.txt index 9d288a64d45..5ad9106378f 100644 --- a/libgo/go/cmd/go/testdata/script/mod_gopkg_unstable.txt +++ b/libgo/go/cmd/go/testdata/script/mod_gopkg_unstable.txt @@ -12,7 +12,7 @@ go list env GOPROXY=direct env GOSUMDB=off -go get gopkg.in/macaroon-bakery.v2-unstable/bakery +go get -d gopkg.in/macaroon-bakery.v2-unstable/bakery go list -m all stdout 'gopkg.in/macaroon-bakery.v2-unstable v2.0.0-[0-9]+-[0-9a-f]+$' diff --git a/libgo/go/cmd/go/testdata/script/mod_import.txt b/libgo/go/cmd/go/testdata/script/mod_import.txt index 3985b43144c..28358b5b0c5 100644 --- a/libgo/go/cmd/go/testdata/script/mod_import.txt +++ b/libgo/go/cmd/go/testdata/script/mod_import.txt @@ -1,7 +1,7 @@ env GO111MODULE=on # latest rsc.io/quote should be v1.5.2 not v1.5.3-pre1 -go list +go get -d go list -m all stdout 'rsc.io/quote v1.5.2' 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 index f582569798b..66f79faa6d9 100644 --- a/libgo/go/cmd/go/testdata/script/mod_in_testdata_dir.txt +++ b/libgo/go/cmd/go/testdata/script/mod_in_testdata_dir.txt @@ -8,8 +8,8 @@ env GO111MODULE=on cd $WORK/testdata go mod init testdata.tld/foo -# Building a package within that module should resolve its dependencies. -go build +# Getting a package within that module should resolve its dependencies. +go get -d grep 'rsc.io/quote' go.mod # Tidying the module should preserve those dependencies. @@ -26,7 +26,7 @@ exists vendor/rsc.io/quote cd $WORK/_ignored go mod init testdata.tld/foo -go build +go get grep 'rsc.io/quote' go.mod go mod tidy diff --git a/libgo/go/cmd/go/testdata/script/mod_indirect.txt b/libgo/go/cmd/go/testdata/script/mod_indirect.txt index 87a3f0b10f7..6ea1cae98bc 100644 --- a/libgo/go/cmd/go/testdata/script/mod_indirect.txt +++ b/libgo/go/cmd/go/testdata/script/mod_indirect.txt @@ -1,6 +1,6 @@ env GO111MODULE=on -# golang.org/issue/31248: module requirements imposed by dependency versions +# golang.org/issue/31248: required modules imposed by dependency versions # older than the selected version must still be taken into account. env GOFLAGS=-mod=readonly diff --git a/libgo/go/cmd/go/testdata/script/mod_init_dep.txt b/libgo/go/cmd/go/testdata/script/mod_init_dep.txt index 755076eae80..f8cf1d563ab 100644 --- a/libgo/go/cmd/go/testdata/script/mod_init_dep.txt +++ b/libgo/go/cmd/go/testdata/script/mod_init_dep.txt @@ -1,24 +1,14 @@ env GO111MODULE=on +env GOFLAGS=-mod=mod # modconv uses git directly to examine what old 'go get' would [!net] skip [!exec:git] skip -# go build should populate go.mod from Gopkg.lock -cp go.mod1 go.mod -go build +# go mod init should populate go.mod from Gopkg.lock +go mod init x stderr 'copying requirements from Gopkg.lock' go list -m all -! stderr 'copying requirements from Gopkg.lock' -stdout 'rsc.io/sampler v1.0.0' - -# go list should populate go.mod from Gopkg.lock -cp go.mod1 go.mod -go list -stderr 'copying requirements from Gopkg.lock' -go list -! stderr 'copying requirements from Gopkg.lock' -go list -m all stdout 'rsc.io/sampler v1.0.0' # test dep replacement @@ -26,9 +16,6 @@ cd y go mod init cmpenv go.mod go.mod.replace --- go.mod1 -- -module x - -- x.go -- package x @@ -54,4 +41,4 @@ go $goversion replace z v1.0.0 => rsc.io/quote v1.0.0 -require rsc.io/quote v1.0.0 \ No newline at end of file +require rsc.io/quote v1.0.0 diff --git a/libgo/go/cmd/go/testdata/script/mod_init_path.txt b/libgo/go/cmd/go/testdata/script/mod_init_path.txt index 637c29f4bcd..ccdfc923175 100644 --- a/libgo/go/cmd/go/testdata/script/mod_init_path.txt +++ b/libgo/go/cmd/go/testdata/script/mod_init_path.txt @@ -1,7 +1,7 @@ env GO111MODULE=on ! go mod init . -stderr 'malformed import path' +stderr '^go: invalid module path "\.": is a local import path$' cd x go mod init example.com/x diff --git a/libgo/go/cmd/go/testdata/script/mod_install_versioned.txt b/libgo/go/cmd/go/testdata/script/mod_install_versioned.txt index 03986d06a0a..c6bce418b4f 100644 --- a/libgo/go/cmd/go/testdata/script/mod_install_versioned.txt +++ b/libgo/go/cmd/go/testdata/script/mod_install_versioned.txt @@ -1,9 +1,11 @@ env GO111MODULE=on +go get -d rsc.io/fortune go list -f '{{.Target}}' rsc.io/fortune ! stdout fortune@v1 stdout 'fortune(\.exe)?$' +go get -d rsc.io/fortune/v2 go list -f '{{.Target}}' rsc.io/fortune/v2 ! stdout v2 stdout 'fortune(\.exe)?$' diff --git a/libgo/go/cmd/go/testdata/script/mod_internal.txt b/libgo/go/cmd/go/testdata/script/mod_internal.txt index 1193d528ece..687269d18f6 100644 --- a/libgo/go/cmd/go/testdata/script/mod_internal.txt +++ b/libgo/go/cmd/go/testdata/script/mod_internal.txt @@ -3,30 +3,34 @@ env GO111MODULE=on # golang.org/x/internal should be importable from other golang.org/x modules. go mod edit -module=golang.org/x/anything -go build . +go get -d . # ...and their tests... go test stdout PASS # ...but that should not leak into other modules. +go get -d ./baddep ! go build ./baddep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' # Internal packages in the standard library should not leak into modules. +go get -d ./fromstd ! go build ./fromstd stderr 'use of internal package internal/testenv not allowed' # Dependencies should be able to use their own internal modules... go mod edit -module=golang.org/notx -go build ./throughdep +go get -d ./throughdep # ... but other modules should not, even if they have transitive dependencies. +go get -d . ! go build . stderr 'use of internal package golang.org/x/.* not allowed' # And transitive dependencies still should not leak. +go get -d ./baddep ! go build ./baddep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' @@ -34,15 +38,17 @@ stderr 'use of internal package golang.org/x/.* not allowed' # Replacing an internal module should keep it internal to the same paths. go mod edit -module=golang.org/notx go mod edit -replace golang.org/x/internal=./replace/golang.org/notx/internal -go build ./throughdep +go get -d ./throughdep +go get -d ./baddep ! go build ./baddep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' go mod edit -replace golang.org/x/internal=./vendor/golang.org/x/internal -go build ./throughdep +go get -d ./throughdep +go get -d ./baddep ! go build ./baddep stderr golang.org[/\\]notx[/\\]useinternal stderr 'use of internal package golang.org/x/.* not allowed' diff --git a/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt b/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt index 7e1bc9ea4f9..43b95643561 100644 --- a/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt +++ b/libgo/go/cmd/go/testdata/script/mod_invalid_version.txt @@ -4,6 +4,7 @@ env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off +env GOFLAGS=-mod=mod # Regression test for golang.org/issue/27173: if the user (or go.mod file) # requests a pseudo-version that does not match both the module path and commit @@ -18,7 +19,7 @@ cp go.mod.orig go.mod go mod edit -require golang.org/x/text@14c0d48ead0c cd outside ! go list -m golang.org/x/text -stderr 'go: example.com@v0.0.0: parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3' +stderr 'go: example.com@v0.0.0 \(replaced by \./\..\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "14c0d48ead0c" invalid: must be of the form v1.2.3' cd .. go list -m golang.org/x/text stdout 'golang.org/x/text v0.1.1-0.20170915032832-14c0d48ead0c' @@ -46,7 +47,7 @@ cp go.mod.orig go.mod go mod edit -require golang.org/x/text@v2.1.1-0.20170915032832-14c0d48ead0c cd outside ! go list -m golang.org/x/text -stderr 'go: example.com@v0.0.0: parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2' +stderr 'go: example.com@v0.0.0 \(replaced by \./\.\.\): parsing ../go.mod: '$WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2' cd .. ! go list -m golang.org/x/text stderr $WORK'/gopath/src/go.mod:5: require golang.org/x/text: version "v2.1.1-0.20170915032832-14c0d48ead0c" invalid: should be v0 or v1, not v2' @@ -221,7 +222,7 @@ stdout 'github.com/pierrec/lz4 v2.0.5\+incompatible' # not resolve to a pseudo-version with a different major version. cp go.mod.orig go.mod ! go get -d github.com/pierrec/lz4@v2.0.8 -stderr 'go get github.com/pierrec/lz4@v2.0.8: github.com/pierrec/lz4@v2.0.8: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2' +stderr 'go get: github.com/pierrec/lz4@v2.0.8: invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v2' # An invalid +incompatible suffix for a canonical version should error out, # not resolve to a pseudo-version. diff --git a/libgo/go/cmd/go/testdata/script/mod_issue35317.txt b/libgo/go/cmd/go/testdata/script/mod_issue35317.txt index 92416a54e47..b1852ab0319 100644 --- a/libgo/go/cmd/go/testdata/script/mod_issue35317.txt +++ b/libgo/go/cmd/go/testdata/script/mod_issue35317.txt @@ -5,4 +5,4 @@ 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 +go get -d 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.txt b/libgo/go/cmd/go/testdata/script/mod_list.txt index 17b33fcc7bf..1ba6d7c910e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list.txt @@ -2,12 +2,12 @@ env GO111MODULE=on [short] skip # list {{.Dir}} shows main module and go.mod but not not-yet-downloaded dependency dir. -go list -m -f '{{.Path}} {{.Main}} {{.GoMod}} {{.Dir}}' all +go list -mod=mod -m -f '{{.Path}} {{.Main}} {{.GoMod}} {{.Dir}}' all stdout '^x true .*[\\/]src[\\/]go.mod .*[\\/]src$' stdout '^rsc.io/quote false .*[\\/]v1.5.2.mod $' # list {{.Dir}} shows dependency after download (and go list without -m downloads it) -go list -f '{{.Dir}}' rsc.io/quote +go list -mod=mod -f '{{.Dir}}' rsc.io/quote stdout '.*mod[\\/]rsc.io[\\/]quote@v1.5.2$' # downloaded dependencies are read-only @@ -20,7 +20,7 @@ go clean -modcache # list {{.Dir}} shows replaced directories cp go.mod2 go.mod -go list -f {{.Dir}} rsc.io/quote +go list -mod=mod -f {{.Dir}} rsc.io/quote go list -m -f '{{.Path}} {{.Version}} {{.Dir}}{{with .Replace}} {{.GoMod}} => {{.Version}} {{.Dir}} {{.GoMod}}{{end}}' all stdout 'mod[\\/]rsc.io[\\/]quote@v1.5.1' stdout 'v1.3.0.*mod[\\/]rsc.io[\\/]sampler@v1.3.1 .*[\\/]v1.3.1.mod => v1.3.1.*sampler@v1.3.1 .*[\\/]v1.3.1.mod' @@ -30,7 +30,7 @@ go list std stdout ^math/big # rsc.io/quote/buggy should be listable as a package -go list rsc.io/quote/buggy +go list -mod=mod rsc.io/quote/buggy # rsc.io/quote/buggy should not be listable as a module go list -m -e -f '{{.Error.Err}}' nonexist rsc.io/quote/buggy diff --git a/libgo/go/cmd/go/testdata/script/mod_list_bad_import.txt b/libgo/go/cmd/go/testdata/script/mod_list_bad_import.txt index 8a66e0b72a0..3cd50b0de25 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_bad_import.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_bad_import.txt @@ -12,10 +12,11 @@ stdout 'incomplete' stdout 'bad dep: .*example.com/notfound' # Listing with -deps should also fail. -# BUG: Today, it does not. -# ! go list -deps example.com/direct -# stderr example.com/notfound -go list -deps example.com/direct +! go list -deps example.com/direct +stderr example.com/notfound + +# But -e -deps should succeed. +go list -e -deps example.com/direct stdout example.com/notfound @@ -28,16 +29,17 @@ stdout incomplete stdout 'bad dep: .*example.com/notfound' # Again, -deps should fail. -# BUG: Again, it does not. -# ! go list -deps example.com/indirect -# stderr example.com/notfound -go list -deps example.com/indirect +! go list -deps example.com/indirect +stderr example.com/notfound + +# But -e -deps should succeed. +go list -e -deps example.com/indirect stdout example.com/notfound # Listing the missing dependency directly should fail outright... ! go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound -stderr 'cannot find module providing package example.com/notfound' +stderr 'no required module provides package example.com/notfound; try ''go get -d example.com/notfound'' to add it' ! stdout error ! stdout incomplete 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 6653435a06e..1adab8f027d 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_dir.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_dir.txt @@ -2,6 +2,9 @@ # go list with path to directory should work +# populate go.sum +go get -d + env GO111MODULE=off go list -f '{{.ImportPath}}' $GOROOT/src/math stdout ^math$ @@ -29,3 +32,5 @@ require rsc.io/quote v1.5.2 -- x.go -- package x + +import _ "rsc.io/quote" diff --git a/libgo/go/cmd/go/testdata/script/mod_list_direct.txt b/libgo/go/cmd/go/testdata/script/mod_list_direct.txt index 8f858711897..62a472f475e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_direct.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_direct.txt @@ -10,7 +10,7 @@ env GOSUMDB=off # For a while, (*modfetch.codeRepo).Stat was not checking for a go.mod file, # which would produce a hard error at the subsequent call to GoMod. -go list all +go get -d -- go.mod -- module example.com diff --git a/libgo/go/cmd/go/testdata/script/mod_list_pseudo.txt b/libgo/go/cmd/go/testdata/script/mod_list_pseudo.txt index 3a10b3a0407..056c0931285 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_pseudo.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_pseudo.txt @@ -10,30 +10,25 @@ go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha go mod download github.com/dmitshur-test/modtest5@v0.5.0-alpha.0.20190619023908-3da23a9deb9e cmp $GOPATH/pkg/mod/cache/download/github.com/dmitshur-test/modtest5/@v/list $WORK/modtest5.list +env GOSUMDB=off # don't verify go.mod files when loading retractions env GOPROXY=file:///$GOPATH/pkg/mod/cache/download env GOPATH=$WORK/gopath2 mkdir $GOPATH -go list -m -json github.com/dmitshur-test/modtest5@latest -cmp stdout $WORK/modtest5.json +go list -m -f '{{.Path}} {{.Version}} {{.Time.Format "2006-01-02"}}' github.com/dmitshur-test/modtest5@latest +stdout '^github.com/dmitshur-test/modtest5 v0.5.0-alpha 2019-06-18$' # If the module proxy contains only pseudo-versions, 'latest' should stat # the version with the most recent timestamp — not the highest semantic # version — and return its metadata. env GOPROXY=file:///$WORK/tinyproxy -go list -m -json dmitri.shuralyov.com/test/modtest3@latest -cmp stdout $WORK/modtest3.json +go list -m -f '{{.Path}} {{.Version}} {{.Time.Format "2006-01-02"}}' dmitri.shuralyov.com/test/modtest3@latest +stdout '^dmitri.shuralyov.com/test/modtest3 v0.0.0-20181023043359-a85b471d5412 2018-10-22$' -- $WORK/modtest5.list -- v0.0.0-20190619020302-197a620e0c9a v0.5.0-alpha v0.5.0-alpha.0.20190619023908-3da23a9deb9e --- $WORK/modtest5.json -- -{ - "Path": "github.com/dmitshur-test/modtest5", - "Version": "v0.5.0-alpha", - "Time": "2019-06-18T19:04:46-07:00" -} -- $WORK/tinyproxy/dmitri.shuralyov.com/test/modtest3/@v/list -- v0.1.0-0.20161023043300-000000000000 v0.0.0-20181023043359-a85b471d5412 @@ -42,9 +37,3 @@ v0.0.0-20181023043359-a85b471d5412 "Version": "v0.0.0-20181023043359-a85b471d5412", "Time": "2018-10-22T21:33:59-07:00" } --- $WORK/modtest3.json -- -{ - "Path": "dmitri.shuralyov.com/test/modtest3", - "Version": "v0.0.0-20181023043359-a85b471d5412", - "Time": "2018-10-22T21:33:59-07:00" -} diff --git a/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt b/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt index cad7fe25280..f2f2d2b2bb2 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_replace_dir.txt @@ -2,8 +2,11 @@ # module within the module cache. # Verifies golang.org/issue/29548 -env GO111MODULE=on -go mod download rsc.io/quote@v1.5.1 rsc.io/quote@v1.5.2 +# Populate go.sum and download dependencies. +go get -d + +# Ensure v1.5.2 is also in the cache so we can list it. +go mod download rsc.io/quote@v1.5.2 ! go list $GOPATH/pkg/mod/rsc.io/quote@v1.5.2 stderr '^directory ..[/\\]pkg[/\\]mod[/\\]rsc.io[/\\]quote@v1.5.2 outside available modules$' @@ -17,3 +20,8 @@ module example.com/quoter require rsc.io/quote v1.5.2 replace rsc.io/quote => rsc.io/quote v1.5.1 + +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/libgo/go/cmd/go/testdata/script/mod_list_std.txt b/libgo/go/cmd/go/testdata/script/mod_list_std.txt index 76a3b00d1c9..baf7908ab93 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_std.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_std.txt @@ -6,8 +6,13 @@ env GOPROXY=off # Outside of GOROOT, our vendored packages should be reported as part of the standard library. go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' std cmd -stdout ^vendor/golang.org/x/net/http2/hpack +stdout ^vendor/golang\.org/x/net/http2/hpack stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm +! stdout ^golang\.org/x/ + +# The dependencies of those packages should also be vendored. +go list -deps vendor/golang.org/x/crypto/chacha20 +stdout ^vendor/golang\.org/x/crypto/internal/subtle # cmd/... should match the same packages it used to match in GOPATH mode. go list cmd/... @@ -23,40 +28,57 @@ stdout ^bytes$ ! stdout ^builtin$ ! stdout ^cmd/ ! stdout ^vendor/ +! stdout ^golang\.org/x/ + +# Vendored dependencies should appear with their 'vendor/' paths in std (they're +# in GOROOT/src, but not in the 'std' module following the usual module-boundary +# rules). -# Within the std module, listing ./... should omit the 'std' prefix: -# the package paths should be the same via ./... or the 'std' meta-pattern. -# TODO(golang.org/issue/30241): Make that work. -# Today, they are listed in 'std' but not './...'. cd $GOROOT/src -go list ./... -! stdout ^vendor/golang.org/x # TODO: should be included, or should be omitted from 'std'. -cp stdout $WORK/listdot.txt go list std -stdout ^vendor/golang.org/x # TODO: remove vendor/ prefix -# TODO: cmp stdout $WORK/listdot.txt +stdout ^vendor/golang.org/x/net/http2/hpack +! stdout ^golang\.org/x + +# The dependencies of packages with an explicit 'vendor/' prefix should +# still themselves resolve to vendored packages. +go list -deps vendor/golang.org/x/crypto/chacha20 +stdout ^vendor/golang.org/x/crypto/internal/subtle +! stdout ^golang\.org/x + +# Within the std module, the dependencies of the non-vendored packages within +# std should appear to come from modules, but they should be loaded from the +# vendor directory (just like ordinary vendored module dependencies). go list all -stdout ^vendor/golang.org/x # TODO: remove vendor/ prefix. +stdout ^golang.org/x/ ! stdout ^std/ +! stdout ^cmd/ +! stdout ^vendor/ +go list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' std +! stdout ^vendor/golang.org/x/net/http2/hpack +stdout ^golang.org/x/net/http2/hpack -# Within the std module, the vendored dependencies of std should appear -# to come from the actual modules. -# TODO(golang.org/issue/30241): Make that work. -# Today, they still have the vendor/ prefix. -go list std -stdout ^vendor/golang.org/x/net/http2/hpack # TODO -! stdout ^golang.org/x/net/http2/hpack # TODO +go list -f '{{.Dir}}' golang.org/x/net/http2/hpack +stdout $GOROOT[/\\]src[/\\]vendor -go list -deps -f '{{if not .Standard}}{{.ImportPath}}{{end}}' std -# ! stdout ^vendor/golang.org/x/net/http2/hpack # TODO -! stdout ^golang.org/x/net/http2/hpack # TODO +# Within the std module, the packages within the module should omit the 'std/' +# prefix (they retain their own identities), but should respect normal module +# boundaries (vendored packages are not included in the module, even though they +# are included in the 'std' pattern). + +go list ./... +stdout ^bytes$ +! stdout ^builtin$ +! stdout ^cmd/ +! stdout ^vendor/ +! stdout ^golang\.org/x/ # Within std, the vendored dependencies of cmd should still appear to be part of cmd. + go list -f '{{if .Standard}}{{.ImportPath}}{{end}}' cmd stdout ^cmd/vendor/golang\.org/x/arch/x86/x86asm diff --git a/libgo/go/cmd/go/testdata/script/mod_list_test.txt b/libgo/go/cmd/go/testdata/script/mod_list_test.txt index a99e4f36cd5..f697af6c92c 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_test.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_test.txt @@ -3,9 +3,19 @@ env GO111MODULE=on # go list -compiled -test must handle test-only packages # golang.org/issue/27097. go list -compiled -test +stdout -count=4 '^.' # 4 lines stdout '^m$' stdout '^m\.test$' stdout '^m \[m\.test\]$' +stdout '^m_test \[m\.test\]$' + +# https://golang.org/issue/39974: test packages should have the Module field populated. +go list -test -f '{{.ImportPath}}{{with .Module}}: {{.Path}}{{end}}' +stdout -count=4 '^.' # 4 lines +stdout '^m: m$' +stdout '^m\.test: m$' +stdout '^m \[m\.test\]: m$' +stdout '^m_test \[m\.test\]: m$' -- go.mod -- module m @@ -14,3 +24,7 @@ module m package x import "testing" func Test(t *testing.T) {} +-- x_x_test.go -- +package x_test +import "testing" +func Test(t *testing.T) {} 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 474df0dc269..0cef04b89ad 100644 --- a/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt +++ b/libgo/go/cmd/go/testdata/script/mod_list_upgrade.txt @@ -1,5 +1,9 @@ env GO111MODULE=on +# Populate go.sum +go list -m -mod=mod all + +# Check for upgrades. go list -m -u all stdout 'rsc.io/quote v1.2.0 \[v1\.5\.2\]' 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 67d9a1584f5..c0c382bfa63 100644 --- a/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt +++ b/libgo/go/cmd/go/testdata/script/mod_load_badchain.txt @@ -28,10 +28,10 @@ cmp stderr list-expected # Try listing a package that imports a package # in a module without a requirement. go mod edit -droprequire example.com/badchain/a -! go list m/use +! go list -mod=mod m/use cmp stderr list-missing-expected -! go list -test m/testuse +! go list -mod=mod -test m/testuse cmp stderr list-missing-test-expected -- go.mod.orig -- @@ -40,6 +40,19 @@ module m go 1.13 require example.com/badchain/a v1.0.0 +-- go.sum -- +example.com/badchain/a v1.0.0 h1:iJDLiHLmpQgr9Zrv+44UqywAE2IG6WkHnH4uG08vf+s= +example.com/badchain/a v1.0.0/go.mod h1:6/gnCYHdVrs6mUgatUYUSbuHxEY+/yWedmTggLz23EI= +example.com/badchain/a v1.1.0 h1:cPxQpsOjaIrn05yDfl4dFFgGSbjYmytLqtIIBfTsEqA= +example.com/badchain/a v1.1.0/go.mod h1:T15b2BEK+RY7h7Lr2dgS38p1pgH5/t7Kf5nQXBlcW/A= +example.com/badchain/b v1.0.0 h1:kjDVlBxpjQavYxHE7ECCyyXhfwsfhWIqvghfRgPktSA= +example.com/badchain/b v1.0.0/go.mod h1:sYsH934pMc3/A2vQZh019qrWmp4+k87l3O0VFUYqL+I= +example.com/badchain/b v1.1.0 h1:iEALV+DRN62FArnYylBR4YwCALn/hCdITvhdagHa0L4= +example.com/badchain/b v1.1.0/go.mod h1:mlCgKO7lRZ+ijwMFIBFRPCGt5r5oqCcHdhSSE0VL4uY= +example.com/badchain/c v1.0.0 h1:lOeUHQKR7SboSH7Bj6eIDWoNHaDQXI0T2GfaH2x9fNA= +example.com/badchain/c v1.0.0/go.mod h1:4U3gzno17SaQ2koSVNxITu9r60CeLSgye9y4/5LnfOE= +example.com/badchain/c v1.1.0 h1:VtTg1g7fOutWKHQf+ag04KLRpdMGSfQ9s9tagVtGW14= +example.com/badchain/c v1.1.0/go.mod h1:tyoJj5qh+qtb48sflwdVvk4R+OjPQEY2UJOoibsVLPk= -- use/use.go -- package use @@ -56,14 +69,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 +go get: example.com/badchain/a@v1.0.0 updating to + 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: module declares its path as: badchain.example.com/c diff --git a/libgo/go/cmd/go/testdata/script/mod_load_badmod.txt b/libgo/go/cmd/go/testdata/script/mod_load_badmod.txt index 68c8b3792bd..fa22e1808b7 100644 --- a/libgo/go/cmd/go/testdata/script/mod_load_badmod.txt +++ b/libgo/go/cmd/go/testdata/script/mod_load_badmod.txt @@ -1,14 +1,13 @@ # Unknown lines should be ignored in dependency go.mod files. -env GO111MODULE=on -go list -m all +go list -m -mod=mod all # ... and in replaced dependency go.mod files. cp go.mod go.mod.usesub -go list -m all +go list -m -mod=mod all # ... but not in the main module. cp go.mod.bad go.mod -! go list -m all +! go list -m -mod=mod all stderr 'unknown directive: hello' -- go.mod -- diff --git a/libgo/go/cmd/go/testdata/script/mod_load_badzip.txt b/libgo/go/cmd/go/testdata/script/mod_load_badzip.txt index c5ba18e9f06..65374d2a6d1 100644 --- a/libgo/go/cmd/go/testdata/script/mod_load_badzip.txt +++ b/libgo/go/cmd/go/testdata/script/mod_load_badzip.txt @@ -5,10 +5,8 @@ env GO111MODULE=on stderr 'zip for rsc.io/badzip@v1.0.0 has unexpected file rsc.io/badzip@v1.0.0.txt' ! grep rsc.io/badzip go.mod -# TODO(golang.org/issue/31730): 'go build' should print the error below if the -# requirement is not present. go mod edit -require rsc.io/badzip@v1.0.0 -! go build rsc.io/badzip +! go build -mod=mod rsc.io/badzip stderr 'zip for rsc.io/badzip@v1.0.0 has unexpected file rsc.io/badzip@v1.0.0.txt' -- go.mod -- 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 319ff855872..9c250e7d1c4 100644 --- a/libgo/go/cmd/go/testdata/script/mod_missingpkg_prerelease.txt +++ b/libgo/go/cmd/go/testdata/script/mod_missingpkg_prerelease.txt @@ -1,7 +1,7 @@ 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 list -mod=mod -deps use.go +stderr '^use.go:4:2: package example.com/missingpkg/deprecated provided by example.com/missingpkg at latest version v1.0.0 but not at required version v1.0.1-beta$' -- go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/script/mod_modinfo.txt b/libgo/go/cmd/go/testdata/script/mod_modinfo.txt index 731f53c6721..c56ed919f5a 100644 --- a/libgo/go/cmd/go/testdata/script/mod_modinfo.txt +++ b/libgo/go/cmd/go/testdata/script/mod_modinfo.txt @@ -9,6 +9,7 @@ env GO111MODULE=on cd x go mod edit -require=rsc.io/quote@v1.5.2 go mod edit -replace=rsc.io/quote@v1.5.2=rsc.io/quote@v1.0.0 +go mod tidy # populate go.sum # Build a binary and ensure that it can output its own debug info. # The debug info should be accessible before main starts (golang.org/issue/29628). @@ -71,7 +72,6 @@ package main import ( "bytes" "encoding/hex" - "io/ioutil" "log" "os" @@ -79,7 +79,7 @@ import ( ) func main() { - b, err := ioutil.ReadFile(os.Args[0]) + b, err := os.ReadFile(os.Args[0]) if err != nil { log.Fatal(err) } diff --git a/libgo/go/cmd/go/testdata/script/mod_multirepo.txt b/libgo/go/cmd/go/testdata/script/mod_multirepo.txt index 7f977e80f6e..0f335a11f0f 100644 --- a/libgo/go/cmd/go/testdata/script/mod_multirepo.txt +++ b/libgo/go/cmd/go/testdata/script/mod_multirepo.txt @@ -7,6 +7,7 @@ go list -deps -f {{.Dir}} # v2 import should use a downloaded module # both without an explicit go.mod entry ... cp tmp/use_v2.go x.go +go get -d . go list -deps -f {{.Dir}} stdout 'pkg[\\/]mod[\\/]rsc.io[\\/]quote[\\/]v2@v2.0.1$' diff --git a/libgo/go/cmd/go/testdata/script/mod_off.txt b/libgo/go/cmd/go/testdata/script/mod_off.txt index cada6deb1dd..a73a58d4d0c 100644 --- a/libgo/go/cmd/go/testdata/script/mod_off.txt +++ b/libgo/go/cmd/go/testdata/script/mod_off.txt @@ -4,7 +4,7 @@ env GO111MODULE=off # GO111MODULE=off when outside of GOPATH will fatal # with an error message, even with some source code in the directory and a go.mod. ! go mod init -stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules''' +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' ! go mod graph stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' ! go mod verify @@ -16,7 +16,7 @@ stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' mkdir z cd z ! go mod init -stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules''' +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' ! go mod graph stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' ! go mod verify diff --git a/libgo/go/cmd/go/testdata/script/mod_off_init.txt b/libgo/go/cmd/go/testdata/script/mod_off_init.txt index 1339c8aef96..2aec0b3ed54 100644 --- a/libgo/go/cmd/go/testdata/script/mod_off_init.txt +++ b/libgo/go/cmd/go/testdata/script/mod_off_init.txt @@ -2,4 +2,4 @@ # ignored anyway due to GO111MODULE=off. env GO111MODULE=off ! go mod init -stderr 'go mod init: modules disabled by GO111MODULE=off; see ''go help modules''' +stderr 'go: modules disabled by GO111MODULE=off; see ''go help modules''' diff --git a/libgo/go/cmd/go/testdata/script/mod_outside.txt b/libgo/go/cmd/go/testdata/script/mod_outside.txt index 03ef576168c..8f01b5d2426 100644 --- a/libgo/go/cmd/go/testdata/script/mod_outside.txt +++ b/libgo/go/cmd/go/testdata/script/mod_outside.txt @@ -39,6 +39,11 @@ stdout '^fmt$' go list ./needmod/needmod.go stdout 'command-line-arguments' +# 'go list' on a package from a module should fail. +! go list example.com/printversion +stderr '^no required module provides package example.com/printversion: working directory is not part of a module$' + + # 'go list -m' with an explicit version should resolve that version. go list -m example.com/version@latest stdout 'example.com/version v1.1.0' @@ -69,10 +74,9 @@ go clean -n ! stdout . ! stderr . -# 'go mod graph' should not display anything, since there are no active modules. -go mod graph -! stdout . -! stderr . +# 'go mod graph' should fail, since there's no module graph. +! go mod graph +stderr 'cannot find main module' # 'go mod why' should fail, since there is no main module to depend on anything. ! go mod why -m example.com/version @@ -126,12 +130,12 @@ 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 -stderr 'go get all: cannot match "all": working directory is not part of a module' +stderr 'go get: 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. ! go get -d example.com/printversion@v1.0.0 example.com/version@none -stderr 'inconsistent versions' +stderr '^go get: example.com/printversion@v1.0.0 requires example.com/version@v1.0.0, not example.com/version@none$' # 'go get -d' should download and extract the source code needed to build the requested version. rm -r $GOPATH/pkg/mod/example.com @@ -152,7 +156,7 @@ stderr 'cannot find main module' # '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' +stderr '^needmod[/\\]needmod.go:10:2: no required module provides 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 @@ -175,21 +179,26 @@ go doc fmt # 'go doc' should fail for a package path outside a module. ! go doc example.com/version -stderr 'doc: cannot find module providing package example.com/version: working directory is not part of a module' +stderr 'doc: no required module provides 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' with a version should succeed if all constraints are met. +# See mod_install_pkg_version. +rm $GOPATH/bin +go install example.com/printversion@v0.1.0 +exists $GOPATH/bin/printversion$GOEXE # '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' +stderr '^go install: version is required when current directory is not in a module\n\tTry ''go install example.com/printversion@latest'' to install the latest version$' # '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' +stderr 'needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module' +# 'go install' should succeed with a package in GOROOT. +go install cmd/addr2line +! stderr . # 'go run' with a verison should fail due to syntax. ! go run example.com/printversion@v1.0.0 @@ -197,12 +206,12 @@ 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' +stderr '^no required module provides 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' +stderr '^needmod[/\\]needmod.go:10:2: no required module provides package example.com/version: working directory is not part of a module$' # 'go fmt' should be able to format files outside of a module. @@ -220,7 +229,7 @@ stdout 'main is example.com/printversion v0.1.0' stdout 'using example.com/version v1.1.0' # 'go get' of a versioned binary should build and install the latest version -# using its minimal module requirements, ignoring replacements and exclusions. +# using its minimal required modules, ignoring replacements and exclusions. go get example.com/printversion exec ../bin/printversion stdout 'path is example.com/printversion' diff --git a/libgo/go/cmd/go/testdata/script/mod_permissions.txt b/libgo/go/cmd/go/testdata/script/mod_permissions.txt index 11fb4754f83..2d32dcd10fd 100644 --- a/libgo/go/cmd/go/testdata/script/mod_permissions.txt +++ b/libgo/go/cmd/go/testdata/script/mod_permissions.txt @@ -12,7 +12,7 @@ chmod 0640 go.mod chmod 0604 go.sum go mod edit -module=golang.org/issue/34634 -go build . +go get -d cmp go.mod go.mod.want cmp go.sum go.sum.want diff --git a/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt b/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt index 849cf2c4764..89129f4fe23 100644 --- a/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt +++ b/libgo/go/cmd/go/testdata/script/mod_proxy_list.txt @@ -3,34 +3,34 @@ env proxy=$GOPROXY # Proxy that can't serve should fail. env GOPROXY=$proxy/404 -! go get rsc.io/quote@v1.0.0 +! go get -d rsc.io/quote@v1.0.0 stderr '404 Not Found' # get should walk down the proxy list past 404 and 410 responses. env GOPROXY=$proxy/404,$proxy/410,$proxy -go get rsc.io/quote@v1.1.0 +go get -d rsc.io/quote@v1.1.0 # get should not walk past other 4xx errors if proxies are separated with ','. env GOPROXY=$proxy/403,$proxy -! go get rsc.io/quote@v1.2.0 +! go get -d rsc.io/quote@v1.2.0 stderr 'reading.*/403/rsc.io/.*: 403 Forbidden' # get should not walk past non-4xx errors if proxies are separated with ','. env GOPROXY=$proxy/500,$proxy -! go get rsc.io/quote@v1.3.0 +! go get -d rsc.io/quote@v1.3.0 stderr 'reading.*/500/rsc.io/.*: 500 Internal Server Error' # get should walk past other 4xx errors if proxies are separated with '|'. env GOPROXY=$proxy/403|https://0.0.0.0|$proxy -go get rsc.io/quote@v1.2.0 +go get -d rsc.io/quote@v1.2.0 # get should walk past non-4xx errors if proxies are separated with '|'. env GOPROXY=$proxy/500|https://0.0.0.0|$proxy -go get rsc.io/quote@v1.3.0 +go get -d rsc.io/quote@v1.3.0 # get should return the final error if that's all we have. env GOPROXY=$proxy/404,$proxy/410 -! go get rsc.io/quote@v1.4.0 +! go get -d rsc.io/quote@v1.4.0 stderr 'reading.*/410/rsc.io/.*: 410 Gone' -- go.mod -- diff --git a/libgo/go/cmd/go/testdata/script/mod_query.txt b/libgo/go/cmd/go/testdata/script/mod_query.txt index e87ca302f0c..e10185709d9 100644 --- a/libgo/go/cmd/go/testdata/script/mod_query.txt +++ b/libgo/go/cmd/go/testdata/script/mod_query.txt @@ -1,5 +1,10 @@ env GO111MODULE=on +# Populate go.sum. +# TODO(golang.org/issue/41297): we shouldn't need go.sum. None of the commands +# below depend on the build list. +go mod download + go list -m -versions rsc.io/quote stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$' @@ -30,3 +35,8 @@ stdout 'no matching versions for query ">v1.5.3"' -- go.mod -- module x require rsc.io/quote v1.0.0 + +-- use.go -- +package use + +import _ "rsc.io/quote" diff --git a/libgo/go/cmd/go/testdata/script/mod_query_empty.txt b/libgo/go/cmd/go/testdata/script/mod_query_empty.txt index 4d8259b40f1..f8b6e3e97ed 100644 --- a/libgo/go/cmd/go/testdata/script/mod_query_empty.txt +++ b/libgo/go/cmd/go/testdata/script/mod_query_empty.txt @@ -8,7 +8,7 @@ go mod download example.com/join@v1.1.0 env GOPROXY=file:///$WORK/badproxy cp go.mod.orig go.mod ! go get -d example.com/join/subpkg -stderr 'go get example.com/join/subpkg: example.com/join/subpkg@v0.0.0-20190624000000-123456abcdef: .*' +stderr 'go get: example.com/join/subpkg@v0.0.0-20190624000000-123456abcdef: .*' # If @v/list is empty, the 'go' command should still try to resolve # other module paths. @@ -40,7 +40,7 @@ env GOPROXY=file:///$WORK/gatekeeper chmod 0000 $WORK/gatekeeper/example.com/join/subpkg/@latest cp go.mod.orig go.mod ! go get -d example.com/join/subpkg -stderr 'go get example.com/join/subpkg: module example.com/join/subpkg: (invalid character .+|reading file://.*/gatekeeper/example.com/join/subpkg/@latest: .+)' +stderr 'go get: module example.com/join/subpkg: (invalid response from proxy ".+": invalid character .+|reading file://.*/gatekeeper/example.com/join/subpkg/@latest: .+)' -- go.mod.orig -- module example.com/othermodule diff --git a/libgo/go/cmd/go/testdata/script/mod_query_exclude.txt b/libgo/go/cmd/go/testdata/script/mod_query_exclude.txt index 1ae0d17844a..b0019694119 100644 --- a/libgo/go/cmd/go/testdata/script/mod_query_exclude.txt +++ b/libgo/go/cmd/go/testdata/script/mod_query_exclude.txt @@ -1,24 +1,43 @@ env GO111MODULE=on -env GOPROXY=$GOPROXY/quiet + +# list excluded version +go list -modfile=go.exclude.mod -m rsc.io/quote@v1.5.0 +stdout '^rsc.io/quote v1.5.0$' + +# list versions should not print excluded versions +go list -m -versions rsc.io/quote +stdout '\bv1.5.0\b' +go list -modfile=go.exclude.mod -m -versions rsc.io/quote +! stdout '\bv1.5.0\b' + +# list query with excluded version +go list -m rsc.io/quote@>=v1.5 +stdout '^rsc.io/quote v1.5.0$' +go list -modfile=go.exclude.mod -m rsc.io/quote@>=v1.5 +stdout '^rsc.io/quote v1.5.1$' # get excluded version -cp go.mod1 go.mod -! go get rsc.io/quote@v1.5.0 -stderr 'rsc.io/quote@v1.5.0 excluded' +cp go.exclude.mod go.exclude.mod.orig +! go get -modfile=go.exclude.mod -d rsc.io/quote@v1.5.0 +stderr '^go get: rsc.io/quote@v1.5.0: excluded by go.mod$' # get non-excluded version -cp go.mod1 go.mod -go get rsc.io/quote@v1.5.1 +cp go.exclude.mod.orig go.exclude.mod +go get -modfile=go.exclude.mod -d rsc.io/quote@v1.5.1 stderr 'rsc.io/quote v1.5.1' -# get range with excluded version -cp go.mod1 go.mod -go get rsc.io/quote@>=v1.5 -go list -m ...quote +# get query with excluded version +cp go.exclude.mod.orig go.exclude.mod +go get -modfile=go.exclude.mod -d rsc.io/quote@>=v1.5 +go list -modfile=go.exclude.mod -m ...quote stdout 'rsc.io/quote v1.5.[1-9]' --- go.mod1 -- +-- go.mod -- module x + +-- go.exclude.mod -- +module x + exclude rsc.io/quote v1.5.0 -- x.go -- diff --git a/libgo/go/cmd/go/testdata/script/mod_readonly.txt b/libgo/go/cmd/go/testdata/script/mod_readonly.txt index ac581264f1f..ca8cd6e0689 100644 --- a/libgo/go/cmd/go/testdata/script/mod_readonly.txt +++ b/libgo/go/cmd/go/testdata/script/mod_readonly.txt @@ -10,17 +10,16 @@ stderr '^x.go:2:8: cannot find module providing package rsc\.io/quote: import lo ! stderr '\(\)' # If we don't have a reason for -mod=readonly, don't log an empty one. cmp go.mod go.mod.empty -# -mod=readonly should be set implicitly if the go.mod file is read-only -chmod 0400 go.mod +# -mod=readonly should be set by default. env GOFLAGS= ! go list all -stderr '^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\.\)$' +stderr '^x.go:2:8: no required module provides package rsc\.io/quote; try ''go mod tidy'' to add it$' +cmp go.mod go.mod.empty -chmod 0600 go.mod env GOFLAGS=-mod=readonly # update go.mod - go get allowed -go get rsc.io/quote +go get -d rsc.io/quote grep rsc.io/quote go.mod # update go.mod - go mod tidy allowed @@ -42,24 +41,50 @@ go list -m all # -mod=readonly should reject inconsistent go.mod files # (ones that would be rewritten). -go mod edit -require rsc.io/sampler@v1.2.0 +go get -d rsc.io/sampler@v1.2.0 +go mod edit -require rsc.io/quote@v1.5.2 cp go.mod go.mod.inconsistent ! go list stderr 'go: updates to go.mod needed, disabled by -mod=readonly' cmp go.mod go.mod.inconsistent +# We get a different message when -mod=readonly is used by default. +env GOFLAGS= +! go list +stderr '^go: updates to go.mod needed; try ''go mod tidy'' first$' + # 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 +cmp go.mod go.mod.nogo # Nor should it reject files with redundant (not incorrect) # requirements. cp go.mod.redundant go.mod go list all +cmp go.mod go.mod.redundant cp go.mod.indirect go.mod go list all +cmp go.mod go.mod.indirect + + +# If we identify a missing package as a dependency of some other package in the +# main module, we should suggest 'go mod tidy' instead of resolving it. + +cp go.mod.untidy go.mod +! go list all +stderr '^x.go:2:8: no required module provides package rsc.io/quote; try ''go mod tidy'' to add it$' + +! go list -deps . +stderr '^x.go:2:8: no required module provides package rsc.io/quote; try ''go mod tidy'' to add it$' + +# However, if we didn't see an import from the main module, we should suggest +# 'go get -d' instead, because we don't know whether 'go mod tidy' would add it. +! go list rsc.io/quote +stderr '^no required module provides package rsc.io/quote; try ''go get -d rsc.io/quote'' to add it$' + -- go.mod -- module m @@ -96,3 +121,11 @@ require ( rsc.io/sampler v1.3.0 // indirect rsc.io/testonly v1.0.0 // indirect ) +-- go.mod.untidy -- +module m + +go 1.20 + +require ( + rsc.io/sampler v1.3.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 c21f1720021..dc9667f1d0d 100644 --- a/libgo/go/cmd/go/testdata/script/mod_replace.txt +++ b/libgo/go/cmd/go/testdata/script/mod_replace.txt @@ -4,7 +4,7 @@ env GO111MODULE=on cp go.mod go.mod.orig # Make sure the test builds without replacement. -go build -o a1.exe . +go build -mod=mod -o a1.exe . exec ./a1.exe stdout 'Don''t communicate by sharing memory' @@ -32,7 +32,7 @@ stderr 'rsc.io/quote/v3@v3.0.0 used for two different module paths \(not-rsc.io/ # Modules that do not (yet) exist upstream can be replaced too. cp go.mod.orig go.mod go mod edit -replace=not-rsc.io/quote/v3@v3.1.0=./local/rsc.io/quote/v3 -go build -o a5.exe ./usenewmodule +go build -mod=mod -o a5.exe ./usenewmodule ! stderr 'finding not-rsc.io/quote/v3' grep 'not-rsc.io/quote/v3 v3.1.0' go.mod exec ./a5.exe diff --git a/libgo/go/cmd/go/testdata/script/mod_replace_gopkgin.txt b/libgo/go/cmd/go/testdata/script/mod_replace_gopkgin.txt index 28c1196284d..df752d9716e 100644 --- a/libgo/go/cmd/go/testdata/script/mod_replace_gopkgin.txt +++ b/libgo/go/cmd/go/testdata/script/mod_replace_gopkgin.txt @@ -11,6 +11,7 @@ env GO111MODULE=on env GOPROXY=direct env GOSUMDB=off +env GOFLAGS=-mod=mod # Replacing gopkg.in/[…].vN with a repository with a root go.mod file # specifying […].vN and a compatible version should succeed, even if @@ -34,7 +35,7 @@ go list -m gopkg.in/src-d/go-git.v4 # A mismatched gopkg.in path should not be able to replace a different major version. cd ../3-to-gomod-4 ! go list -m gopkg.in/src-d/go-git.v3 -stderr '^go: gopkg\.in/src-d/go-git\.v3@v3.0.0-20190801152248-0d1a009cbb60: invalid version: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$' +stderr '^go: gopkg\.in/src-d/go-git\.v3@v3\.2\.0 \(replaced by gopkg\.in/src-d/go-git\.v3@v3\.0\.0-20190801152248-0d1a009cbb60\): version "v3\.0\.0-20190801152248-0d1a009cbb60" invalid: go\.mod has non-\.\.\.\.v3 module path "gopkg\.in/src-d/go-git\.v4" at revision 0d1a009cbb60$' -- 4-to-4/go.mod -- module golang.org/issue/34254 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 54b1a124485..2add31f71c1 100644 --- a/libgo/go/cmd/go/testdata/script/mod_replace_import.txt +++ b/libgo/go/cmd/go/testdata/script/mod_replace_import.txt @@ -1,12 +1,12 @@ env GO111MODULE=on -# 'go list -mod=readonly' should not add requirements even if they can be -# resolved locally. +# 'go list' should not add requirements even if they can be resolved locally. cp go.mod go.mod.orig -! go list -mod=readonly all +! go list all cmp go.mod go.mod.orig # 'go list' should resolve imports using replacements. +go get -d go list all stdout 'example.com/a/b$' stdout 'example.com/x/v3$' @@ -25,10 +25,11 @@ 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. +# TODO(#26909): Ideally these errors should include line numbers for the imports within the main module. cd fail -! go list all -stderr '^m.go:4:2: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' -stderr '^m.go:5:2: nonexist@v0.1.0: replacement directory ../nonexist does not exist$' +! go mod tidy +stderr '^localhost.fail imports\n\tw: module w@latest found \(v0.0.0-00010101000000-000000000000, replaced by ../w\), but does not contain package w$' +stderr '^localhost.fail imports\n\tnonexist: nonexist@v0.1.0: replacement directory ../nonexist does not exist$' -- go.mod -- module example.com/m diff --git a/libgo/go/cmd/go/testdata/script/mod_require_exclude.txt b/libgo/go/cmd/go/testdata/script/mod_require_exclude.txt index 60f7e3fa913..9156d4ce5d5 100644 --- a/libgo/go/cmd/go/testdata/script/mod_require_exclude.txt +++ b/libgo/go/cmd/go/testdata/script/mod_require_exclude.txt @@ -1,16 +1,51 @@ # build with no newer version to satisfy exclude env GO111MODULE=on -! go list -m all -stderr 'no newer version available' +cp go.mod go.mod.orig + +# With the selected version excluded, commands that query that version without +# updating go.mod should fail. + +! go list -mod=readonly -m all +stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$' +stderr '^go: updates to go.mod needed, disabled by -mod=readonly$' +! stdout '^rsc.io/sampler v1.99.99' +cmp go.mod go.mod.orig + +! go list -mod=vendor -m rsc.io/sampler +stderr '^go: ignoring requirement on excluded version rsc.io/sampler v1\.99\.99$' +stderr '^go list -m: module rsc.io/sampler: can''t resolve module using the vendor directory\n\t\(Use -mod=mod or -mod=readonly to bypass\.\)$' +! stdout '^rsc.io/sampler v1.99.99' +cmp go.mod go.mod.orig + +# With the selected version excluded, commands that load only modules should +# drop the excluded module. + +go list -m -mod=mod all +stderr '^go: dropping requirement on excluded version rsc.io/sampler v1\.99\.99$' +stdout '^x$' +! stdout '^rsc.io/sampler' +cmp go.mod go.moddrop + +# With the latest version excluded, 'go list' should resolve needed packages +# from the next-highest version. + +cp go.mod.orig go.mod +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +stderr '^go: dropping requirement on excluded version rsc.io/sampler v1\.99\.99$' +stdout '^x $' +! stdout '^rsc.io/sampler v1.99.99' +stdout '^rsc.io/sampler v1.3.0' # build with newer version available cp go.mod2 go.mod -go list -m all +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +stderr '^go: dropping requirement on excluded version rsc.io/quote v1\.5\.1$' stdout 'rsc.io/quote v1.5.2' # build with excluded newer version cp go.mod3 go.mod -go list -m all +go list -mod=mod -f '{{with .Module}}{{.Path}} {{.Version}}{{end}}' all +! stderr '^go: dropping requirement' stdout 'rsc.io/quote v1.5.1' -- x.go -- @@ -19,15 +54,28 @@ import _ "rsc.io/quote" -- go.mod -- module x -exclude rsc.io/sampler latest -require rsc.io/sampler latest +go 1.13 + +exclude rsc.io/sampler v1.99.99 +require rsc.io/sampler v1.99.99 +-- go.moddrop -- +module x + +go 1.13 + +exclude rsc.io/sampler v1.99.99 -- go.mod2 -- module x + +go 1.13 + exclude rsc.io/quote v1.5.1 require rsc.io/quote v1.5.1 - -- go.mod3 -- module x + +go 1.13 + exclude rsc.io/quote v1.5.2 require rsc.io/quote v1.5.1 diff --git a/libgo/go/cmd/go/testdata/script/mod_retention.txt b/libgo/go/cmd/go/testdata/script/mod_retention.txt index 1d83e6c07e8..a4441c4b3c7 100644 --- a/libgo/go/cmd/go/testdata/script/mod_retention.txt +++ b/libgo/go/cmd/go/testdata/script/mod_retention.txt @@ -7,7 +7,7 @@ env GO111MODULE=on # Control case: verify that go.mod.tidy is actually tidy. cp go.mod.tidy go.mod -go list all +go list -mod=mod all cmp go.mod go.mod.tidy @@ -35,7 +35,7 @@ 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 +go list -mod=mod all cmp go.mod go.mod.tidy # "// indirect" comments should be added if appropriate. @@ -63,7 +63,7 @@ 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 +go list -mod=mod all cmpenv go.mod go.mod.currentgo diff --git a/libgo/go/cmd/go/testdata/script/mod_std_vendor.txt b/libgo/go/cmd/go/testdata/script/mod_std_vendor.txt index 5986cff5946..fb954d74edb 100644 --- a/libgo/go/cmd/go/testdata/script/mod_std_vendor.txt +++ b/libgo/go/cmd/go/testdata/script/mod_std_vendor.txt @@ -37,12 +37,10 @@ stderr 'use of vendored package' # When run within the 'std' module, 'go list -test' should report vendored # transitive dependencies at their original module paths. -# TODO(golang.org/issue/30241): Make that work. -# Today, they're standard packages as long as they exist. cd $GOROOT/src go list -test -f '{{range .Deps}}{{.}}{{"\n"}}{{end}}' net/http -stdout ^vendor/golang.org/x/net/http2/hpack # TODO: remove vendor/ prefix -! stdout ^golang.org/x/net/http2/hpack +stdout ^golang.org/x/net/http2/hpack +! stdout ^vendor/golang.org/x/net/http2/hpack -- go.mod -- module m diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb.txt index caf97e9699f..9a688e1461c 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb.txt @@ -9,12 +9,18 @@ env dbname=localhost.localdev/sumdb cp go.mod.orig go.mod env GOSUMDB=$sumdb' '$proxy/sumdb-wrong ! go get -d rsc.io/quote -stderr 'go get rsc.io/quote: rsc.io/quote@v1.5.2: verifying module: checksum mismatch' +stderr 'go get: 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.' ! go get -d rsc.io/sampler ! go get -d golang.org/x/text + +go mod edit -require rsc.io/quote@v1.5.2 +! go mod tidy +stderr 'go: rsc.io/quote@v1.5.2: verifying go.mod: checksum mismatch' +stderr 'SECURITY ERROR\n' + rm go.sum # switching to truthful sumdb detects timeline inconsistency 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 6108c0a5d36..22fcbf3de84 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 @@ -13,7 +13,7 @@ env GOPATH=$WORK/gopath1 [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 '^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.*)' +stderr '^go get: 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_sumdb_golang.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_golang.txt index 40a07fc7e9f..cc0b0da474a 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_golang.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_golang.txt @@ -9,7 +9,7 @@ env GOPROXY=https://proxy.golang.org go env GOSUMDB stdout '^sum.golang.org$' -# download direct from github +# Download direct from github. [!net] skip [!exec:git] skip env GOSUMDB=sum.golang.org @@ -17,11 +17,13 @@ env GOPROXY=direct go get -d rsc.io/quote@v1.5.2 cp go.sum saved.sum -# download from proxy.golang.org with go.sum entry already +# Download from proxy.golang.org with go.sum entry already. +# Use 'go list' instead of 'go get' since the latter may download extra go.mod +# files not listed in go.sum. go clean -modcache env GOSUMDB= env GOPROXY= -go get -x -d rsc.io/quote@v1.5.2 +go list -x -deps rsc.io/quote ! stderr github stderr proxy.golang.org/rsc.io/quote ! stderr sum.golang.org/tile @@ -32,7 +34,7 @@ cmp go.sum saved.sum # Should use the checksum database to validate new go.sum lines, # but not need to fetch any new data from the proxy. rm go.sum -go get -x -d rsc.io/quote@v1.5.2 +go list -mod=mod -x rsc.io/quote ! stderr github ! stderr proxy.golang.org/rsc.io/quote stderr sum.golang.org/tile @@ -43,7 +45,7 @@ cmp go.sum saved.sum env TESTGOPROXY404=1 go clean -modcache rm go.sum -go get -x -d rsc.io/quote@v1.5.2 +go list -mod=mod -x rsc.io/quote stderr 'proxy.golang.org.*404 testing' stderr github.com/rsc cmp go.sum saved.sum diff --git a/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt b/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt index 7bbc3f9e196..70b8e3fc446 100644 --- a/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt +++ b/libgo/go/cmd/go/testdata/script/mod_sumdb_proxy.txt @@ -17,14 +17,12 @@ rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum # direct access fails (because localhost.localdev does not exist) -# The text of the error message is hard to predict because some DNS servers -# will resolve unknown domains like localhost.localdev to a real IP -# to serve ads. +# web.get is providing the error message - there's no actual network access. cp go.mod.orig go.mod env GOSUMDB=$sumdb env GOPROXY=direct ! go get -d rsc.io/fortune@v1.0.0 -stderr 'verifying.*localhost.localdev' +stderr 'verifying module: rsc.io/fortune@v1.0.0: .*: no such host localhost.localdev' rm $GOPATH/pkg/mod/cache/download/sumdb rm go.sum diff --git a/libgo/go/cmd/go/testdata/script/mod_symlink.txt b/libgo/go/cmd/go/testdata/script/mod_symlink.txt index 49bece2b84d..dbc23fb8f09 100644 --- a/libgo/go/cmd/go/testdata/script/mod_symlink.txt +++ b/libgo/go/cmd/go/testdata/script/mod_symlink.txt @@ -1,16 +1,19 @@ env GO111MODULE=on [!symlink] skip -# 'go list' should resolve modules of imported packages. +# 'go get -d' should resolve modules of imported packages. +go get -d go list -deps -f '{{.Module}}' . stdout golang.org/x/text +go get -d ./subpkg go list -deps -f '{{.Module}}' ./subpkg stdout golang.org/x/text # Create a copy of the module using symlinks in src/links. mkdir links symlink links/go.mod -> $GOPATH/src/go.mod +symlink links/go.sum -> $GOPATH/src/go.sum symlink links/issue.go -> $GOPATH/src/issue.go mkdir links/subpkg symlink links/subpkg/issue.go -> $GOPATH/src/subpkg/issue.go diff --git a/libgo/go/cmd/go/testdata/script/mod_test.txt b/libgo/go/cmd/go/testdata/script/mod_test.txt index 8f2da2f2a5b..50f00355c17 100644 --- a/libgo/go/cmd/go/testdata/script/mod_test.txt +++ b/libgo/go/cmd/go/testdata/script/mod_test.txt @@ -1,4 +1,5 @@ env GO111MODULE=on +env GOFLAGS=-mod=mod [short] skip # TODO(bcmills): Convert the 'go test' calls below to 'go list -test' once 'go diff --git a/libgo/go/cmd/go/testdata/script/mod_test_cached.txt b/libgo/go/cmd/go/testdata/script/mod_test_cached.txt index ffd573c02a9..3da4358fa14 100644 --- a/libgo/go/cmd/go/testdata/script/mod_test_cached.txt +++ b/libgo/go/cmd/go/testdata/script/mod_test_cached.txt @@ -51,26 +51,25 @@ bar package foo_test import ( - "io/ioutil" "os" "path/filepath" "testing" ) func TestWriteTmp(t *testing.T) { - dir, err := ioutil.TempDir("", "") + dir, err := os.MkdirTemp("", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(dir) - err = ioutil.WriteFile(filepath.Join(dir, "x"), nil, 0666) + err = os.WriteFile(filepath.Join(dir, "x"), nil, 0666) if err != nil { t.Fatal(err) } } func TestReadTestdata(t *testing.T) { - _, err := ioutil.ReadFile("testdata/foo.txt") + _, err := os.ReadFile("testdata/foo.txt") if err != nil { t.Fatal(err) } 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 c3158f8610e..dd994388910 100644 --- a/libgo/go/cmd/go/testdata/script/mod_tidy_replace.txt +++ b/libgo/go/cmd/go/testdata/script/mod_tidy_replace.txt @@ -1,4 +1,5 @@ env GO111MODULE=on +env GOFLAGS=-mod=mod [short] skip # golang.org/issue/30166: 'go mod tidy' should not crash if a replaced module is @@ -34,7 +35,7 @@ grep 'golang.org/x/text' go.mod # 'go get' and 'go mod tidy' should follow the requirements of the replacements, # not the originals, even if that results in a set of versions that are # misleading or redundant without those replacements. -go get rsc.io/sampler@v1.2.0 +go get -d rsc.io/sampler@v1.2.0 go mod tidy go list -m all stdout 'rsc.io/quote/v3 v3.0.0' diff --git a/libgo/go/cmd/go/testdata/script/mod_upgrade_patch.txt b/libgo/go/cmd/go/testdata/script/mod_upgrade_patch.txt index 3939e54c1bf..8b34f8bf27d 100644 --- a/libgo/go/cmd/go/testdata/script/mod_upgrade_patch.txt +++ b/libgo/go/cmd/go/testdata/script/mod_upgrade_patch.txt @@ -2,12 +2,18 @@ env GO111MODULE=on [short] skip # Initially, we are at v1.0.0 for all dependencies. +go get -d cp go.mod go.mod.orig go list -m all stdout '^patch.example.com/direct v1.0.0' stdout '^patch.example.com/indirect v1.0.0' ! stdout '^patch.example.com/depofdirectpatch' +# @patch should be rejected for modules not already in the build list. +! go get -d patch.example.com/depofdirectpatch@patch +stderr '^go get: can''t query version "patch" of module patch.example.com/depofdirectpatch: no existing version is required$' +cmp go.mod.orig go.mod + # get -u=patch, with no arguments, should patch-update all dependencies # of the package in the current directory, pulling in transitive dependencies # and also patching those. @@ -18,7 +24,7 @@ stdout '^patch.example.com/direct v1.0.1' stdout '^patch.example.com/indirect v1.0.1' stdout '^patch.example.com/depofdirectpatch v1.0.0' -# 'get all@patch' should be equivalent to 'get -u=patch all' +# 'get all@patch' should patch the modules that provide packages in 'all'. cp go.mod.orig go.mod go get -d all@patch go list -m all @@ -26,6 +32,15 @@ stdout '^patch.example.com/direct v1.0.1' stdout '^patch.example.com/indirect v1.0.1' stdout '^patch.example.com/depofdirectpatch v1.0.0' +# ...but 'all@patch' should fail if any of the affected modules do not already +# have a selected version. +cp go.mod.orig go.mod +go mod edit -droprequire=patch.example.com/direct +cp go.mod go.mod.dropped +! go get -d all@patch +stderr '^go get all@patch: can''t query version "patch" of module patch.example.com/direct: no existing version is required$' +cmp go.mod.dropped go.mod + # Requesting the direct dependency with -u=patch but without an explicit version # should patch-update it and its dependencies. cp go.mod.orig go.mod @@ -68,10 +83,10 @@ stdout '^patch.example.com/direct v1.1.0' stdout '^patch.example.com/indirect v1.0.1' ! stdout '^patch.example.com/depofdirectpatch' -# Standard-library packages cannot be upgraded explicitly. +# Standard library packages cannot be upgraded explicitly. cp go.mod.orig go.mod ! go get cmd/vet@patch -stderr 'cannot use pattern .* with explicit version' +stderr 'go get: can''t request explicit version "patch" of standard library package cmd/vet$' # However, standard-library packages without explicit versions are fine. go get -d -u=patch -d cmd/go @@ -84,6 +99,7 @@ go get -d example.com/noroot@patch go list -m all stdout '^example.com/noroot v1.0.1$' + -- go.mod -- module x diff --git a/libgo/go/cmd/go/testdata/script/mod_vcs_missing.txt b/libgo/go/cmd/go/testdata/script/mod_vcs_missing.txt index a755935b53e..f8be43cf4c6 100644 --- a/libgo/go/cmd/go/testdata/script/mod_vcs_missing.txt +++ b/libgo/go/cmd/go/testdata/script/mod_vcs_missing.txt @@ -5,14 +5,14 @@ env GO111MODULE=on env GOPROXY=direct cd empty -! go list launchpad.net/gocheck +! go get -d launchpad.net/gocheck stderr '"bzr": executable file not found' cd .. # 1.11 used to give the cryptic error "cannot find module for path" here, but # only for a main package. cd main -! go build +! go build -mod=mod stderr '"bzr": executable file not found' cd .. diff --git a/libgo/go/cmd/go/testdata/script/mod_vendor_auto.txt b/libgo/go/cmd/go/testdata/script/mod_vendor_auto.txt index 53120dcfa1f..1b362eda0bd 100644 --- a/libgo/go/cmd/go/testdata/script/mod_vendor_auto.txt +++ b/libgo/go/cmd/go/testdata/script/mod_vendor_auto.txt @@ -177,7 +177,7 @@ 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 get -d example.com/version@v1.1.0 ! go list -f {{.Dir}} -tags tools all stderr '^go: inconsistent vendoring' 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 0c359cea6e9..3b8eec0119b 100644 --- a/libgo/go/cmd/go/testdata/script/mod_vendor_build.txt +++ b/libgo/go/cmd/go/testdata/script/mod_vendor_build.txt @@ -1,13 +1,16 @@ env GO111MODULE=on [short] skip +# Populate go.mod and go.sum. +go mod tidy + # initial conditions: using sampler v1.3.0, not listed in go.mod. go list -deps stdout rsc.io/sampler ! grep 'rsc.io/sampler v1.3.0' go.mod # update to v1.3.1, now indirect in go.mod. -go get rsc.io/sampler@v1.3.1 +go get -d rsc.io/sampler@v1.3.1 grep 'rsc.io/sampler v1.3.1 // indirect' go.mod cp go.mod go.mod.good diff --git a/libgo/go/cmd/go/testdata/script/mod_verify.txt b/libgo/go/cmd/go/testdata/script/mod_verify.txt index 646bc62bb70..43812d069f6 100644 --- a/libgo/go/cmd/go/testdata/script/mod_verify.txt +++ b/libgo/go/cmd/go/testdata/script/mod_verify.txt @@ -12,20 +12,18 @@ go mod verify ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip # With bad go.sum, sync (which must download) fails. -# Even if the bad sum is in the old legacy go.modverify file. rm go.sum -cp go.sum.bad go.modverify +cp go.sum.bad go.sum ! go mod tidy stderr 'checksum mismatch' ! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip -# With good go.sum, sync works (and moves go.modverify to go.sum). +# With good go.sum, sync works. rm go.sum -cp go.sum.good go.modverify +cp go.sum.good go.sum go mod tidy exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.1.0.zip exists $GOPATH/pkg/mod/rsc.io/quote@v1.1.0/quote.go -! exists go.modverify # go.sum should have the new checksum for go.mod grep '^rsc.io/quote v1.1.0/go.mod ' go.sum @@ -58,7 +56,7 @@ go mod tidy # Packages below module root should not be mentioned in go.sum. rm go.sum go mod edit -droprequire rsc.io/quote -go list rsc.io/quote/buggy # re-resolves import path and updates go.mod +go get -d rsc.io/quote/buggy grep '^rsc.io/quote v1.5.2/go.mod ' go.sum ! grep buggy go.sum diff --git a/libgo/go/cmd/go/testdata/script/mod_why.txt b/libgo/go/cmd/go/testdata/script/mod_why.txt index 10a4f9fbea7..b3036fa8304 100644 --- a/libgo/go/cmd/go/testdata/script/mod_why.txt +++ b/libgo/go/cmd/go/testdata/script/mod_why.txt @@ -1,6 +1,10 @@ env GO111MODULE=on [short] skip +# Populate go.sum. +go mod tidy +cp go.mod go.mod.orig + go list -test all stdout rsc.io/quote stdout golang.org/x/text/language @@ -17,7 +21,7 @@ cmp stdout why-text-module.txt go mod why rsc.io/testonly cmp stdout why-testonly.txt -# why a module used only in tests? +# why a module used only in a test of a dependency? go mod why -m rsc.io/testonly cmp stdout why-testonly.txt @@ -41,6 +45,14 @@ cmp stdout why-both.txt go mod why -m rsc.io/quote rsc.io/sampler cmp stdout why-both-module.txt +# package in a module that isn't even in the module graph +# (https://golang.org/issue/26977) +go mod why rsc.io/fortune +cmp stdout why-missing.txt + +# None of these command should have changed the go.mod file. +cmp go.mod go.mod.orig + -- go.mod -- module mymodule require rsc.io/quote v1.5.2 @@ -113,3 +125,6 @@ mymodule/y mymodule/y.test rsc.io/quote rsc.io/sampler +-- why-missing.txt -- +# rsc.io/fortune +(main module does not need package rsc.io/fortune) diff --git a/libgo/go/cmd/go/testdata/script/modfile_flag.txt b/libgo/go/cmd/go/testdata/script/modfile_flag.txt index f05bf03fbf0..0ad08808178 100644 --- a/libgo/go/cmd/go/testdata/script/modfile_flag.txt +++ b/libgo/go/cmd/go/testdata/script/modfile_flag.txt @@ -37,10 +37,10 @@ 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 . +go list -mod=mod . grep rsc.io/quote go.alt.mod -go build -n . -go test -n . +go build -n -mod=mod . +go test -n -mod=mod . go get -d rsc.io/quote diff --git a/libgo/go/cmd/go/testdata/script/sum_readonly.txt b/libgo/go/cmd/go/testdata/script/sum_readonly.txt deleted file mode 100644 index 8aa61166acf..00000000000 --- a/libgo/go/cmd/go/testdata/script/sum_readonly.txt +++ /dev/null @@ -1,29 +0,0 @@ -# Test that go.sum does not get updated when -mod=readonly flag is set -env GO111MODULE=on - -go get -d rsc.io/quote -go mod tidy - -# go.sum != dirty; -mod=readonly -go list -mod=readonly - -# dirty up go.sum by removing it. -rm go.sum - -# go.sum == dirty; -mod=readonly -! go list -mod=readonly - -stderr 'go: updates to go.sum needed, disabled by -mod=readonly' - --- go.mod -- -module m - --- main.go -- - -package main - -import "rsc.io/quote" - -func main() { - println(quote.Hello()) -} \ 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 index 57602e91dc1..50486e19090 100644 --- a/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt +++ b/libgo/go/cmd/go/testdata/script/test_cache_inputs.txt @@ -137,7 +137,7 @@ exit 0 package testcache import ( - "io/ioutil" + "io" "os" "testing" ) @@ -159,7 +159,7 @@ func TestOddFileContent(t *testing.T) { if err != nil { t.Fatal(err) } - data, err := ioutil.ReadAll(f) + data, err := io.ReadAll(f) f.Close() if err != nil { t.Fatal(err) diff --git a/libgo/go/cmd/go/testdata/script/test_compile_tempfile.txt b/libgo/go/cmd/go/testdata/script/test_compile_tempfile.txt index 912410814f4..05f721a8007 100644 --- a/libgo/go/cmd/go/testdata/script/test_compile_tempfile.txt +++ b/libgo/go/cmd/go/testdata/script/test_compile_tempfile.txt @@ -1,7 +1,7 @@ [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. +# its name can be reserved using os.CreateTemp or the 'mktemp` command. go build -o empty-file$GOEXE main.go diff --git a/libgo/go/cmd/go/testdata/script/test_generated_main.txt b/libgo/go/cmd/go/testdata/script/test_generated_main.txt index 75ffa9cde2c..2e991a5797f 100644 --- a/libgo/go/cmd/go/testdata/script/test_generated_main.txt +++ b/libgo/go/cmd/go/testdata/script/test_generated_main.txt @@ -12,7 +12,6 @@ package x import ( "os" "path/filepath" - "io/ioutil" "regexp" "testing" ) @@ -23,7 +22,7 @@ func Test(t *testing.T) { t.Fatal(err) } testmainPath := filepath.Join(filepath.Dir(exePath), "_testmain.go") - source, err := ioutil.ReadFile(testmainPath) + source, err := os.ReadFile(testmainPath) if err != nil { t.Fatal(err) } diff --git a/libgo/go/cmd/go/testdata/script/version.txt b/libgo/go/cmd/go/testdata/script/version.txt index 87cb6befe93..8615a4aac59 100644 --- a/libgo/go/cmd/go/testdata/script/version.txt +++ b/libgo/go/cmd/go/testdata/script/version.txt @@ -20,6 +20,7 @@ env GO111MODULE=on [short] skip # Check that 'go version' and 'go version -m' work on a binary built in module mode. +go get -d rsc.io/fortune go build -o fortune.exe rsc.io/fortune go version fortune.exe stdout '^fortune.exe: .+' diff --git a/libgo/go/cmd/go/testdata/script/vet_flags.txt b/libgo/go/cmd/go/testdata/script/vet_flags.txt index b55dada4dc6..8002367e6f2 100644 --- a/libgo/go/cmd/go/testdata/script/vet_flags.txt +++ b/libgo/go/cmd/go/testdata/script/vet_flags.txt @@ -5,21 +5,25 @@ env GO111MODULE=on # Issue 35837: "go vet - " should use the requested # analyzers, not the default analyzers for 'go test'. -go vet -n -unreachable=false encoding/binary -stderr '-unreachable=false' +go vet -n -buildtags=false runtime +stderr '-buildtags=false' ! stderr '-unsafeptr=false' # Issue 37030: "go vet " without other flags should disable the # unsafeptr check by default. -go vet -n encoding/binary +go vet -n runtime stderr '-unsafeptr=false' ! stderr '-unreachable=false' # However, it should be enabled if requested explicitly. -go vet -n -unsafeptr encoding/binary +go vet -n -unsafeptr runtime stderr '-unsafeptr' ! stderr '-unsafeptr=false' +# -unreachable is disabled during test but on during plain vet. +go test -n runtime +stderr '-unreachable=false' + # A flag terminator should be allowed before the package list. go vet -n -- . @@ -63,10 +67,10 @@ stderr '[/\\]vet'$GOEXE'["]? .* -errorsas .* ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' # "go test" on a standard package should by default disable an explicit list. go test -x -run=none encoding/binary -stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' go test -x -vet= -run=none encoding/binary -stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' +stderr '[/\\]vet'$GOEXE'["]? -unsafeptr=false -unreachable=false ["]?\$WORK[/\\][^ ]*[/\\]vet\.cfg' # Both should allow users to override via the -vet flag. go test -x -vet=unreachable -run=none . diff --git a/libgo/go/cmd/gofmt/gofmt.go b/libgo/go/cmd/gofmt/gofmt.go index 8c56af75596..2793c2c2a43 100644 --- a/libgo/go/cmd/gofmt/gofmt.go +++ b/libgo/go/cmd/gofmt/gofmt.go @@ -14,7 +14,7 @@ import ( "go/scanner" "go/token" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "runtime" @@ -73,7 +73,7 @@ func initParserMode() { } } -func isGoFile(f os.FileInfo) bool { +func isGoFile(f fs.DirEntry) bool { // ignore non-Go files name := f.Name() return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") @@ -81,7 +81,7 @@ func isGoFile(f os.FileInfo) bool { // If in == nil, the source is the contents of the file with the given filename. func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error { - var perm os.FileMode = 0644 + var perm fs.FileMode = 0644 if in == nil { f, err := os.Open(filename) if err != nil { @@ -96,7 +96,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error perm = fi.Mode().Perm() } - src, err := ioutil.ReadAll(in) + src, err := io.ReadAll(in) if err != nil { return err } @@ -136,7 +136,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error if err != nil { return err } - err = ioutil.WriteFile(filename, res, perm) + err = os.WriteFile(filename, res, perm) if err != nil { os.Rename(bakname, filename) return err @@ -163,7 +163,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error return err } -func visitFile(path string, f os.FileInfo, err error) error { +func visitFile(path string, f fs.DirEntry, err error) error { if err == nil && isGoFile(f) { err = processFile(path, nil, os.Stdout, false) } @@ -176,7 +176,7 @@ func visitFile(path string, f os.FileInfo, err error) error { } func walkDir(path string) { - filepath.Walk(path, visitFile) + filepath.WalkDir(path, visitFile) } func main() { @@ -275,9 +275,9 @@ const chmodSupported = runtime.GOOS != "windows" // backupFile writes data to a new file named filename with permissions perm, // with ") pkgdef = []byte("__.PKGDEF") goobject = []byte("go object ") @@ -109,7 +106,7 @@ func ReadFile(name string) (id string, err error) { // in cmd/go/internal/work/exec.go. func readGccgoArchive(name string, f *os.File) (string, error) { bad := func() (string, error) { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + return "", &fs.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} } off := int64(8) @@ -167,7 +164,7 @@ func readGccgoArchive(name string, f *os.File) (string, error) { // in cmd/go/internal/work/exec.go. func readGccgoBigArchive(name string, f *os.File) (string, error) { bad := func() (string, error) { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + return "", &fs.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} } // Read fixed-length header. @@ -309,13 +306,38 @@ func readRaw(name string, data []byte) (id string, err error) { j := bytes.Index(data[i+len(goBuildPrefix):], goBuildEnd) if j < 0 { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + return "", &fs.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} } quoted := data[i+len(goBuildPrefix)-1 : i+len(goBuildPrefix)+j+1] id, err = strconv.Unquote(string(quoted)) if err != nil { - return "", &os.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} + return "", &fs.PathError{Op: "parse", Path: name, Err: errBuildIDMalformed} } return id, nil } + +// HashToString converts the hash h to a string to be recorded +// in package archives and binaries as part of the build ID. +// We use the first 120 bits of the hash (5 chunks of 24 bits each) and encode +// it in base64, resulting in a 20-byte string. Because this is only used for +// detecting the need to rebuild installed files (not for lookups +// in the object file cache), 120 bits are sufficient to drive the +// probability of a false "do not need to rebuild" decision to effectively zero. +// We embed two different hashes in archives and four in binaries, +// so cutting to 20 bytes is a significant savings when build IDs are displayed. +// (20*4+3 = 83 bytes compared to 64*4+3 = 259 bytes for the +// more straightforward option of printing the entire h in base64). +func HashToString(h [32]byte) string { + const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" + const chunks = 5 + var dst [chunks * 4]byte + for i := 0; i < chunks; i++ { + v := uint32(h[3*i])<<16 | uint32(h[3*i+1])<<8 | uint32(h[3*i+2]) + dst[4*i+0] = b64[(v>>18)&0x3F] + dst[4*i+1] = b64[(v>>12)&0x3F] + dst[4*i+2] = b64[(v>>6)&0x3F] + dst[4*i+3] = b64[v&0x3F] + } + return string(dst[:]) +} diff --git a/libgo/go/cmd/internal/buildid/buildid_test.go b/libgo/go/cmd/internal/buildid/buildid_test.go index 904c2c6f377..e832f9987e5 100644 --- a/libgo/go/cmd/internal/buildid/buildid_test.go +++ b/libgo/go/cmd/internal/buildid/buildid_test.go @@ -11,6 +11,7 @@ import ( "io/ioutil" "os" "reflect" + "strings" "testing" ) @@ -146,3 +147,33 @@ func TestFindAndHash(t *testing.T) { } } } + +func TestExcludedReader(t *testing.T) { + const s = "0123456789abcdefghijklmn" + tests := []struct { + start, end int64 // excluded range + results []string // expected results of reads + }{ + {12, 15, []string{"0123456789", "ab\x00\x00\x00fghij", "klmn"}}, // within one read + {8, 21, []string{"01234567\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "\x00lmn"}}, // across multiple reads + {10, 20, []string{"0123456789", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", "klmn"}}, // a whole read + {0, 5, []string{"\x00\x00\x00\x00\x0056789", "abcdefghij", "klmn"}}, // start + {12, 24, []string{"0123456789", "ab\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00"}}, // end + } + p := make([]byte, 10) + for _, test := range tests { + r := &excludedReader{strings.NewReader(s), 0, test.start, test.end} + for _, res := range test.results { + n, err := r.Read(p) + if err != nil { + t.Errorf("read failed: %v", err) + } + if n != len(res) { + t.Errorf("unexpected number of bytes read: want %d, got %d", len(res), n) + } + if string(p[:n]) != res { + t.Errorf("unexpected bytes: want %q, got %q", res, p[:n]) + } + } + } +} diff --git a/libgo/go/cmd/internal/buildid/note.go b/libgo/go/cmd/internal/buildid/note.go index 2d26ea9961c..f5b6fc565f3 100644 --- a/libgo/go/cmd/internal/buildid/note.go +++ b/libgo/go/cmd/internal/buildid/note.go @@ -11,6 +11,7 @@ import ( "encoding/binary" "fmt" "io" + "io/fs" "os" ) @@ -96,7 +97,7 @@ func readELF(name string, f *os.File, data []byte) (buildid string, err error) { ef, err := elf.NewFile(bytes.NewReader(data)) if err != nil { - return "", &os.PathError{Path: name, Op: "parse", Err: err} + return "", &fs.PathError{Path: name, Op: "parse", Err: err} } var gnu string for _, p := range ef.Progs { @@ -181,13 +182,13 @@ func readMacho(name string, f *os.File, data []byte) (buildid string, err error) mf, err := macho.NewFile(f) if err != nil { - return "", &os.PathError{Path: name, Op: "parse", Err: err} + return "", &fs.PathError{Path: name, Op: "parse", Err: err} } sect := mf.Section("__text") if sect == nil { // Every binary has a __text section. Something is wrong. - return "", &os.PathError{Path: name, Op: "parse", Err: fmt.Errorf("cannot find __text section")} + return "", &fs.PathError{Path: name, Op: "parse", Err: fmt.Errorf("cannot find __text section")} } // It should be in the first few bytes, but read a lot just in case, diff --git a/libgo/go/cmd/internal/buildid/rewrite.go b/libgo/go/cmd/internal/buildid/rewrite.go index 5be54552a6d..a7928959c48 100644 --- a/libgo/go/cmd/internal/buildid/rewrite.go +++ b/libgo/go/cmd/internal/buildid/rewrite.go @@ -6,7 +6,9 @@ package buildid import ( "bytes" + "cmd/internal/codesign" "crypto/sha256" + "debug/macho" "fmt" "io" ) @@ -26,6 +28,11 @@ func FindAndHash(r io.Reader, id string, bufSize int) (matches []int64, hash [32 zeros := make([]byte, len(id)) idBytes := []byte(id) + // For Mach-O files, we want to exclude the code signature. + // The code signature contains hashes of the whole file (except the signature + // itself), including the buildid. So the buildid cannot contain the signature. + r = excludeMachoCodeSignature(r) + // The strategy is to read the file through buf, looking for id, // but we need to worry about what happens if id is broken up // and returned in parts by two different reads. @@ -87,5 +94,69 @@ func Rewrite(w io.WriterAt, pos []int64, id string) error { return err } } + + // Update Mach-O code signature, if any. + if f, cmd, ok := findMachoCodeSignature(w); ok { + if codesign.Size(int64(cmd.Dataoff), "a.out") == int64(cmd.Datasize) { + // Update the signature if the size matches, so we don't need to + // fix up headers. Binaries generated by the Go linker should have + // the expected size. Otherwise skip. + text := f.Segment("__TEXT") + cs := make([]byte, cmd.Datasize) + codesign.Sign(cs, w.(io.Reader), "a.out", int64(cmd.Dataoff), int64(text.Offset), int64(text.Filesz), f.Type == macho.TypeExec) + if _, err := w.WriteAt(cs, int64(cmd.Dataoff)); err != nil { + return err + } + } + } + return nil } + +func excludeMachoCodeSignature(r io.Reader) io.Reader { + _, cmd, ok := findMachoCodeSignature(r) + if !ok { + return r + } + return &excludedReader{r, 0, int64(cmd.Dataoff), int64(cmd.Dataoff + cmd.Datasize)} +} + +// excludedReader wraps an io.Reader. Reading from it returns the bytes from +// the underlying reader, except that when the byte offset is within the +// range between start and end, it returns zero bytes. +type excludedReader struct { + r io.Reader + off int64 // current offset + start, end int64 // the range to be excluded (read as zero) +} + +func (r *excludedReader) Read(p []byte) (int, error) { + n, err := r.r.Read(p) + if n > 0 && r.off+int64(n) > r.start && r.off < r.end { + cstart := r.start - r.off + if cstart < 0 { + cstart = 0 + } + cend := r.end - r.off + if cend > int64(n) { + cend = int64(n) + } + zeros := make([]byte, cend-cstart) + copy(p[cstart:cend], zeros) + } + r.off += int64(n) + return n, err +} + +func findMachoCodeSignature(r interface{}) (*macho.File, codesign.CodeSigCmd, bool) { + ra, ok := r.(io.ReaderAt) + if !ok { + return nil, codesign.CodeSigCmd{}, false + } + f, err := macho.NewFile(ra) + if err != nil { + return nil, codesign.CodeSigCmd{}, false + } + cmd, ok := codesign.FindCodeSigCmd(f) + return f, cmd, ok +} diff --git a/libgo/go/cmd/internal/codesign/codesign.go b/libgo/go/cmd/internal/codesign/codesign.go new file mode 100644 index 00000000000..0517a10640a --- /dev/null +++ b/libgo/go/cmd/internal/codesign/codesign.go @@ -0,0 +1,268 @@ +// Copyright 2020 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 codesign provides basic functionalities for +// ad-hoc code signing of Mach-O files. +// +// This is not a general tool for code-signing. It is made +// specifically for the Go toolchain. It uses the same +// ad-hoc signing algorithm as the Darwin linker. +package codesign + +import ( + "crypto/sha256" + "debug/macho" + "encoding/binary" + "io" +) + +// Code signature layout. +// +// The code signature is a block of bytes that contains +// a SuperBlob, which contains one or more Blobs. For ad-hoc +// signing, a single CodeDirectory Blob suffices. +// +// A SuperBlob starts with its header (the binary representation +// of the SuperBlob struct), followed by a list of (in our case, +// one) Blobs (offset and size). A CodeDirectory Blob starts +// with its head (the binary representation of CodeDirectory struct), +// followed by the identifier (as a C string) and the hashes, at +// the corresponding offsets. +// +// The signature data must be included in the __LINKEDIT segment. +// In the Mach-O file header, an LC_CODE_SIGNATURE load command +// points to the data. + +const ( + pageSizeBits = 12 + pageSize = 1 << pageSizeBits +) + +const LC_CODE_SIGNATURE = 0x1d + +// Constants and struct layouts are from +// https://opensource.apple.com/source/xnu/xnu-4903.270.47/osfmk/kern/cs_blobs.h + +const ( + CSMAGIC_REQUIREMENT = 0xfade0c00 // single Requirement blob + CSMAGIC_REQUIREMENTS = 0xfade0c01 // Requirements vector (internal requirements) + CSMAGIC_CODEDIRECTORY = 0xfade0c02 // CodeDirectory blob + CSMAGIC_EMBEDDED_SIGNATURE = 0xfade0cc0 // embedded form of signature data + CSMAGIC_DETACHED_SIGNATURE = 0xfade0cc1 // multi-arch collection of embedded signatures + + CSSLOT_CODEDIRECTORY = 0 // slot index for CodeDirectory +) + +const ( + CS_HASHTYPE_SHA1 = 1 + CS_HASHTYPE_SHA256 = 2 + CS_HASHTYPE_SHA256_TRUNCATED = 3 + CS_HASHTYPE_SHA384 = 4 +) + +const ( + CS_EXECSEG_MAIN_BINARY = 0x1 // executable segment denotes main binary + CS_EXECSEG_ALLOW_UNSIGNED = 0x10 // allow unsigned pages (for debugging) + CS_EXECSEG_DEBUGGER = 0x20 // main binary is debugger + CS_EXECSEG_JIT = 0x40 // JIT enabled + CS_EXECSEG_SKIP_LV = 0x80 // skip library validation + CS_EXECSEG_CAN_LOAD_CDHASH = 0x100 // can bless cdhash for execution + CS_EXECSEG_CAN_EXEC_CDHASH = 0x200 // can execute blessed cdhash +) + +type Blob struct { + typ uint32 // type of entry + offset uint32 // offset of entry + // data follows +} + +func (b *Blob) put(out []byte) []byte { + out = put32be(out, b.typ) + out = put32be(out, b.offset) + return out +} + +const blobSize = 2 * 4 + +type SuperBlob struct { + magic uint32 // magic number + length uint32 // total length of SuperBlob + count uint32 // number of index entries following + // blobs []Blob +} + +func (s *SuperBlob) put(out []byte) []byte { + out = put32be(out, s.magic) + out = put32be(out, s.length) + out = put32be(out, s.count) + return out +} + +const superBlobSize = 3 * 4 + +type CodeDirectory struct { + magic uint32 // magic number (CSMAGIC_CODEDIRECTORY) + length uint32 // total length of CodeDirectory blob + version uint32 // compatibility version + flags uint32 // setup and mode flags + hashOffset uint32 // offset of hash slot element at index zero + identOffset uint32 // offset of identifier string + nSpecialSlots uint32 // number of special hash slots + nCodeSlots uint32 // number of ordinary (code) hash slots + codeLimit uint32 // limit to main image signature range + hashSize uint8 // size of each hash in bytes + hashType uint8 // type of hash (cdHashType* constants) + _pad1 uint8 // unused (must be zero) + pageSize uint8 // log2(page size in bytes); 0 => infinite + _pad2 uint32 // unused (must be zero) + scatterOffset uint32 + teamOffset uint32 + _pad3 uint32 + codeLimit64 uint64 + execSegBase uint64 + execSegLimit uint64 + execSegFlags uint64 + // data follows +} + +func (c *CodeDirectory) put(out []byte) []byte { + out = put32be(out, c.magic) + out = put32be(out, c.length) + out = put32be(out, c.version) + out = put32be(out, c.flags) + out = put32be(out, c.hashOffset) + out = put32be(out, c.identOffset) + out = put32be(out, c.nSpecialSlots) + out = put32be(out, c.nCodeSlots) + out = put32be(out, c.codeLimit) + out = put8(out, c.hashSize) + out = put8(out, c.hashType) + out = put8(out, c._pad1) + out = put8(out, c.pageSize) + out = put32be(out, c._pad2) + out = put32be(out, c.scatterOffset) + out = put32be(out, c.teamOffset) + out = put32be(out, c._pad3) + out = put64be(out, c.codeLimit64) + out = put64be(out, c.execSegBase) + out = put64be(out, c.execSegLimit) + out = put64be(out, c.execSegFlags) + return out +} + +const codeDirectorySize = 13*4 + 4 + 4*8 + +// CodeSigCmd is Mach-O LC_CODE_SIGNATURE load command. +type CodeSigCmd struct { + Cmd uint32 // LC_CODE_SIGNATURE + Cmdsize uint32 // sizeof this command (16) + Dataoff uint32 // file offset of data in __LINKEDIT segment + Datasize uint32 // file size of data in __LINKEDIT segment +} + +func FindCodeSigCmd(f *macho.File) (CodeSigCmd, bool) { + get32 := f.ByteOrder.Uint32 + for _, l := range f.Loads { + data := l.Raw() + cmd := get32(data) + if cmd == LC_CODE_SIGNATURE { + return CodeSigCmd{ + cmd, + get32(data[4:]), + get32(data[8:]), + get32(data[12:]), + }, true + } + } + return CodeSigCmd{}, false +} + +func put32be(b []byte, x uint32) []byte { binary.BigEndian.PutUint32(b, x); return b[4:] } +func put64be(b []byte, x uint64) []byte { binary.BigEndian.PutUint64(b, x); return b[8:] } +func put8(b []byte, x uint8) []byte { b[0] = x; return b[1:] } +func puts(b, s []byte) []byte { n := copy(b, s); return b[n:] } + +// Size computes the size of the code signature. +// id is the identifier used for signing (a field in CodeDirectory blob, which +// has no significance in ad-hoc signing). +func Size(codeSize int64, id string) int64 { + nhashes := (codeSize + pageSize - 1) / pageSize + idOff := int64(codeDirectorySize) + hashOff := idOff + int64(len(id)+1) + cdirSz := hashOff + nhashes*sha256.Size + return int64(superBlobSize+blobSize) + cdirSz +} + +// Sign generates an ad-hoc code signature and writes it to out. +// out must have length at least Size(codeSize, id). +// data is the file content without the signature, of size codeSize. +// textOff and textSize is the file offset and size of the text segment. +// isMain is true if this is a main executable. +// id is the identifier used for signing (a field in CodeDirectory blob, which +// has no significance in ad-hoc signing). +func Sign(out []byte, data io.Reader, id string, codeSize, textOff, textSize int64, isMain bool) { + nhashes := (codeSize + pageSize - 1) / pageSize + idOff := int64(codeDirectorySize) + hashOff := idOff + int64(len(id)+1) + sz := Size(codeSize, id) + + // emit blob headers + sb := SuperBlob{ + magic: CSMAGIC_EMBEDDED_SIGNATURE, + length: uint32(sz), + count: 1, + } + blob := Blob{ + typ: CSSLOT_CODEDIRECTORY, + offset: superBlobSize + blobSize, + } + cdir := CodeDirectory{ + magic: CSMAGIC_CODEDIRECTORY, + length: uint32(sz) - (superBlobSize + blobSize), + version: 0x20400, + flags: 0x20002, // adhoc | linkerSigned + hashOffset: uint32(hashOff), + identOffset: uint32(idOff), + nCodeSlots: uint32(nhashes), + codeLimit: uint32(codeSize), + hashSize: sha256.Size, + hashType: CS_HASHTYPE_SHA256, + pageSize: uint8(pageSizeBits), + execSegBase: uint64(textOff), + execSegLimit: uint64(textSize), + } + if isMain { + cdir.execSegFlags = CS_EXECSEG_MAIN_BINARY + } + + outp := out + outp = sb.put(outp) + outp = blob.put(outp) + outp = cdir.put(outp) + + // emit the identifier + outp = puts(outp, []byte(id+"\000")) + + // emit hashes + var buf [pageSize]byte + h := sha256.New() + p := 0 + for p < int(codeSize) { + n, err := io.ReadFull(data, buf[:]) + if err == io.EOF { + break + } + if err != nil && err != io.ErrUnexpectedEOF { + panic(err) + } + if p+n > int(codeSize) { + n = int(codeSize) - p + } + p += n + h.Reset() + h.Write(buf[:n]) + b := h.Sum(nil) + outp = puts(outp, b[:]) + } +} diff --git a/libgo/go/cmd/internal/objabi/doc.go b/libgo/go/cmd/internal/objabi/doc.go deleted file mode 100644 index 08e922b11fb..00000000000 --- a/libgo/go/cmd/internal/objabi/doc.go +++ /dev/null @@ -1,122 +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. - -// NOTE: There are *three* independent implementations of this object -// file format in the Go source tree: -// -// - cmd/internal/goobj/read.go (used by cmd/addr2line, cmd/nm, cmd/objdump, cmd/pprof) -// - cmd/internal/obj/objfile.go (used by cmd/asm and cmd/compile) -// - cmd/link/internal/objfile.go (used by cmd/link) -// -// When changing the object file format, remember to change all three. - -// Originally, Go object files were Plan 9 object files, but no longer. -// Now they are more like standard object files, in that each symbol is defined -// by an associated memory image (bytes) and a list of relocations to apply -// during linking. We do not (yet?) use a standard file format, however. -// For now, the format is chosen to be as simple as possible to read and write. -// It may change for reasons of efficiency, or we may even switch to a -// standard file format if there are compelling benefits to doing so. -// See golang.org/s/go13linker for more background. -// -// The file format is: -// -// - 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: -// - total data length -// - total number of relocations -// - total number of pcdata -// - total number of automatics -// - total number of funcdata -// - total number of files -// - data, the content of the defined symbols -// - sequence of defined symbols -// - byte 0xff (marks end of sequence) -// - magic footer: "\xffgo114ld" -// -// All integers are stored in a zigzag varint format. -// See golang.org/s/go12symtab for a definition. -// -// Data blocks and strings are both stored as an integer -// followed by that many bytes. -// -// A symbol reference is a string name followed by an ABI or -1 for static. -// -// A symbol points to other symbols using an index into the symbol -// reference sequence. Index 0 corresponds to a nil symbol pointer. -// In the symbol layout described below "symref index" stands for this -// index. -// -// Each symbol is laid out as the following fields: -// -// - byte 0xfe (sanity check for synchronization) -// - type [byte] -// - name & ABI [symref index] -// - flags [int] -// 1<<0 dupok -// 1<<1 local -// 1<<2 add to typelink table -// - size [int] -// - gotype [symref index] -// - p [data block] -// - nr [int] -// - r [nr relocations, sorted by off] -// -// If type == STEXT, there are a few more fields: -// -// - args [int] -// - locals [int] -// - nosplit [int] -// - flags [int] -// 1<<0 leaf -// 1<<1 C function -// 1<<2 function may call reflect.Type.Method -// 1<<3 function compiled with -shared -// - nlocal [int] -// - local [nlocal automatics] -// - pcln [pcln table] -// -// Each relocation has the encoding: -// -// - off [int] -// - siz [int] -// - type [int] -// - add [int] -// - sym [symref index] -// -// Each local has the encoding: -// -// - asym [symref index] -// - offset [int] -// - type [int] -// - gotype [symref index] -// -// The pcln table has the encoding: -// -// - pcsp [data block] -// - pcfile [data block] -// - pcline [data block] -// - pcinline [data block] -// - npcdata [int] -// - pcdata [npcdata data blocks] -// - nfuncdata [int] -// - funcdata [nfuncdata symref index] -// - funcdatasym [nfuncdata ints] -// - nfile [int] -// - file [nfile symref index] -// - ninlinedcall [int] -// - inlinedcall [ninlinedcall int symref int symref] -// -// The file layout and meaning of type integers are architecture-independent. -// -// TODO(rsc): The file format is good for a first pass but needs work. -// - There are SymID in the object file that should really just be strings. -package objabi diff --git a/libgo/go/cmd/internal/objabi/flag.go b/libgo/go/cmd/internal/objabi/flag.go index 79ad2ccf748..3fd73f3c576 100644 --- a/libgo/go/cmd/internal/objabi/flag.go +++ b/libgo/go/cmd/internal/objabi/flag.go @@ -5,6 +5,7 @@ package objabi import ( + "bytes" "flag" "fmt" "io" @@ -59,6 +60,9 @@ func expandArgs(in []string) (out []string) { log.Fatal(err) } args := strings.Split(strings.TrimSpace(strings.Replace(string(slurp), "\r", "", -1)), "\n") + for i, arg := range args { + args[i] = DecodeArg(arg) + } out = append(out, expandArgs(args)...) } else if out != nil { out = append(out, s) @@ -160,3 +164,38 @@ func (f fn1) Set(s string) error { } func (f fn1) String() string { return "" } + +// DecodeArg decodes an argument. +// +// This function is public for testing with the parallel encoder. +func DecodeArg(arg string) string { + // If no encoding, fastpath out. + if !strings.ContainsAny(arg, "\\\n") { + return arg + } + + // We can't use strings.Builder as this must work at bootstrap. + var b bytes.Buffer + var wasBS bool + for _, r := range arg { + if wasBS { + switch r { + case '\\': + b.WriteByte('\\') + case 'n': + b.WriteByte('\n') + default: + // This shouldn't happen. The only backslashes that reach here + // should encode '\n' and '\\' exclusively. + panic("badly formatted input") + } + } else if r == '\\' { + wasBS = true + continue + } else { + b.WriteRune(r) + } + wasBS = false + } + return b.String() +} diff --git a/libgo/go/cmd/internal/objabi/flag_test.go b/libgo/go/cmd/internal/objabi/flag_test.go new file mode 100644 index 00000000000..935b9c21931 --- /dev/null +++ b/libgo/go/cmd/internal/objabi/flag_test.go @@ -0,0 +1,26 @@ +// Copyright 2020 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 objabi + +import "testing" + +func TestDecodeArg(t *testing.T) { + t.Parallel() + tests := []struct { + arg, want string + }{ + {"", ""}, + {"hello", "hello"}, + {"hello\\n", "hello\n"}, + {"hello\\nthere", "hello\nthere"}, + {"hello\\\\there", "hello\\there"}, + {"\\\\\\n", "\\\n"}, + } + for _, test := range tests { + if got := DecodeArg(test.arg); got != test.want { + t.Errorf("decodoeArg(%q) = %q, want %q", test.arg, got, test.want) + } + } +} diff --git a/libgo/go/cmd/internal/objabi/funcdata.go b/libgo/go/cmd/internal/objabi/funcdata.go index d5bacb5900b..faa2863325d 100644 --- a/libgo/go/cmd/internal/objabi/funcdata.go +++ b/libgo/go/cmd/internal/objabi/funcdata.go @@ -11,17 +11,15 @@ package objabi // ../../../runtime/symtab.go. const ( - PCDATA_RegMapIndex = 0 // if !go115ReduceLiveness - PCDATA_UnsafePoint = 0 // if go115ReduceLiveness + PCDATA_UnsafePoint = 0 PCDATA_StackMapIndex = 1 PCDATA_InlTreeIndex = 2 FUNCDATA_ArgsPointerMaps = 0 FUNCDATA_LocalsPointerMaps = 1 - FUNCDATA_RegPointerMaps = 2 // if !go115ReduceLiveness - FUNCDATA_StackObjects = 3 - FUNCDATA_InlTree = 4 - FUNCDATA_OpenCodedDeferInfo = 5 + FUNCDATA_StackObjects = 2 + FUNCDATA_InlTree = 3 + FUNCDATA_OpenCodedDeferInfo = 4 // ArgsSizeUnknown is set in Func.argsize to mark all functions // whose argument size is unknown (C vararg functions, and @@ -32,11 +30,6 @@ const ( // Special PCDATA values. const ( - // PCDATA_RegMapIndex values. - // - // Only if !go115ReduceLiveness. - PCDATA_RegMapUnsafe = -2 // Unsafe for async preemption - // PCDATA_UnsafePoint values. PCDATA_UnsafePointSafe = -1 // Safe for async preemption PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption diff --git a/libgo/go/cmd/internal/objabi/funcid.go b/libgo/go/cmd/internal/objabi/funcid.go index 0fda1db1789..1d098ee1725 100644 --- a/libgo/go/cmd/internal/objabi/funcid.go +++ b/libgo/go/cmd/internal/objabi/funcid.go @@ -4,11 +4,6 @@ package objabi -import ( - "strconv" - "strings" -) - // A FuncID identifies particular functions that need to be treated // specially by the runtime. // Note that in some situations involving plugins, there may be multiple @@ -31,7 +26,7 @@ const ( FuncID_gcBgMarkWorker FuncID_systemstack_switch FuncID_systemstack - FuncID_cgocallback_gofunc + FuncID_cgocallback FuncID_gogo FuncID_externalthreadhandler FuncID_debugCallV1 @@ -44,7 +39,10 @@ const ( // Get the function ID for the named function in the named file. // The function should be package-qualified. -func GetFuncID(name, file string) FuncID { +func GetFuncID(name string, isWrapper bool) FuncID { + if isWrapper { + return FuncID_wrapper + } switch name { case "runtime.main": return FuncID_runtime_main @@ -72,8 +70,8 @@ func GetFuncID(name, file string) FuncID { return FuncID_systemstack_switch case "runtime.systemstack": return FuncID_systemstack - case "runtime.cgocallback_gofunc": - return FuncID_cgocallback_gofunc + case "runtime.cgocallback": + return FuncID_cgocallback case "runtime.gogo": return FuncID_gogo case "runtime.externalthreadhandler": @@ -98,17 +96,5 @@ func GetFuncID(name, file string) FuncID { // Don't show in the call stack (used when invoking defer functions) return FuncID_wrapper } - if file == "" { - return FuncID_wrapper - } - if strings.HasPrefix(name, "runtime.call") { - if _, err := strconv.Atoi(name[12:]); err == nil { - // runtime.callXX reflect call wrappers. - return FuncID_wrapper - } - } - if strings.HasSuffix(name, "-fm") { - return FuncID_wrapper - } return FuncID_normal } diff --git a/libgo/go/cmd/internal/objabi/head.go b/libgo/go/cmd/internal/objabi/head.go index 95b8db3809b..48ff292307f 100644 --- a/libgo/go/cmd/internal/objabi/head.go +++ b/libgo/go/cmd/internal/objabi/head.go @@ -54,7 +54,7 @@ func (h *HeadType) Set(s string) error { switch s { case "aix": *h = Haix - case "darwin": + case "darwin", "ios": *h = Hdarwin case "dragonfly": *h = Hdragonfly diff --git a/libgo/go/cmd/internal/objabi/line.go b/libgo/go/cmd/internal/objabi/line.go index 178c8363d95..0733b65138d 100644 --- a/libgo/go/cmd/internal/objabi/line.go +++ b/libgo/go/cmd/internal/objabi/line.go @@ -37,25 +37,36 @@ func AbsFile(dir, file, rewrites string) string { abs = filepath.Join(dir, file) } + abs, rewritten := ApplyRewrites(abs, rewrites) + if !rewritten && hasPathPrefix(abs, GOROOT) { + abs = "$GOROOT" + abs[len(GOROOT):] + } + + if abs == "" { + abs = "??" + } + return abs +} + +// ApplyRewrites returns the filename for file in the given directory, +// as rewritten by the rewrites argument. +// +// The rewrites argument is a ;-separated list of rewrites. +// Each rewrite is of the form "prefix" or "prefix=>replace", +// where prefix must match a leading sequence of path elements +// and is either removed entirely or replaced by the replacement. +func ApplyRewrites(file, rewrites string) (string, bool) { start := 0 for i := 0; i <= len(rewrites); i++ { if i == len(rewrites) || rewrites[i] == ';' { - if new, ok := applyRewrite(abs, rewrites[start:i]); ok { - abs = new - goto Rewritten + if new, ok := applyRewrite(file, rewrites[start:i]); ok { + return new, true } start = i + 1 } } - if hasPathPrefix(abs, GOROOT) { - abs = "$GOROOT" + abs[len(GOROOT):] - } -Rewritten: - if abs == "" { - abs = "??" - } - return abs + return file, false } // applyRewrite applies the rewrite to the path, diff --git a/libgo/go/cmd/internal/objabi/path.go b/libgo/go/cmd/internal/objabi/path.go index 2a42179a368..fd1c9981c69 100644 --- a/libgo/go/cmd/internal/objabi/path.go +++ b/libgo/go/cmd/internal/objabi/path.go @@ -39,3 +39,25 @@ func PathToPrefix(s string) string { return string(p) } + +// IsRuntimePackagePath examines 'pkgpath' and returns TRUE if it +// belongs to the collection of "runtime-related" packages, including +// "runtime" itself, "reflect", "syscall", and the +// "runtime/internal/*" packages. The compiler and/or assembler in +// some cases need to be aware of when they are building such a +// package, for example to enable features such as ABI selectors in +// assembly sources. +func IsRuntimePackagePath(pkgpath string) bool { + rval := false + switch pkgpath { + case "runtime": + rval = true + case "reflect": + rval = true + case "syscall": + rval = true + default: + rval = strings.HasPrefix(pkgpath, "runtime/internal") + } + return rval +} diff --git a/libgo/go/cmd/internal/objabi/reloctype.go b/libgo/go/cmd/internal/objabi/reloctype.go index f029a3c396d..649f6901944 100644 --- a/libgo/go/cmd/internal/objabi/reloctype.go +++ b/libgo/go/cmd/internal/objabi/reloctype.go @@ -89,6 +89,17 @@ const ( // should be linked into the final binary, even if there are no other // direct references. (This is used for types reachable by reflection.) R_USETYPE + // R_USEIFACE marks a type is converted to an interface in the function this + // relocation is applied to. The target is a type descriptor. + // This is a marker relocation (0-sized), for the linker's reachabililty + // analysis. + R_USEIFACE + // R_USEIFACEMETHOD marks an interface method that is used in the function + // this relocation is applied to. The target is an interface type descriptor. + // The addend is the offset of the method in the type descriptor. + // This is a marker relocation (0-sized), for the linker's reachabililty + // analysis. + R_USEIFACEMETHOD // R_METHODOFF resolves to a 32-bit offset from the beginning of the section // holding the data being relocated to the referenced symbol. // It is a variant of R_ADDROFF used when linking from the uncommonType of a @@ -145,6 +156,9 @@ const ( // R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address. R_ARM64_LDST8 + // R_ARM64_LDST16 sets a LD/ST immediate value to bits [11:1] of a local address. + R_ARM64_LDST16 + // R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address. R_ARM64_LDST32 @@ -212,6 +226,14 @@ const ( // AUIPC + S-type instruction pair. R_RISCV_PCREL_STYPE + // R_RISCV_TLS_IE_ITYPE resolves a 32-bit TLS initial-exec TOC offset + // address using an AUIPC + I-type instruction pair. + R_RISCV_TLS_IE_ITYPE + + // R_RISCV_TLS_IE_STYPE resolves a 32-bit TLS initial-exec TOC offset + // address using an AUIPC + S-type instruction pair. + R_RISCV_TLS_IE_STYPE + // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. // TODO(mundaym): remove once variants can be serialized - see issue 14218. R_PCRELDBL diff --git a/libgo/go/cmd/internal/objabi/reloctype_string.go b/libgo/go/cmd/internal/objabi/reloctype_string.go index 83dfe71e071..658a44f8b81 100644 --- a/libgo/go/cmd/internal/objabi/reloctype_string.go +++ b/libgo/go/cmd/internal/objabi/reloctype_string.go @@ -4,9 +4,75 @@ package objabi import "strconv" -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" +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[R_ADDR-1] + _ = x[R_ADDRPOWER-2] + _ = x[R_ADDRARM64-3] + _ = x[R_ADDRMIPS-4] + _ = x[R_ADDROFF-5] + _ = x[R_WEAKADDROFF-6] + _ = x[R_SIZE-7] + _ = x[R_CALL-8] + _ = x[R_CALLARM-9] + _ = x[R_CALLARM64-10] + _ = x[R_CALLIND-11] + _ = x[R_CALLPOWER-12] + _ = x[R_CALLMIPS-13] + _ = x[R_CALLRISCV-14] + _ = x[R_CONST-15] + _ = x[R_PCREL-16] + _ = x[R_TLS_LE-17] + _ = x[R_TLS_IE-18] + _ = x[R_GOTOFF-19] + _ = x[R_PLT0-20] + _ = x[R_PLT1-21] + _ = x[R_PLT2-22] + _ = x[R_USEFIELD-23] + _ = x[R_USETYPE-24] + _ = x[R_USEIFACE-25] + _ = x[R_USEIFACEMETHOD-26] + _ = x[R_METHODOFF-27] + _ = x[R_POWER_TOC-28] + _ = x[R_GOTPCREL-29] + _ = x[R_JMPMIPS-30] + _ = x[R_DWARFSECREF-31] + _ = x[R_DWARFFILEREF-32] + _ = x[R_ARM64_TLS_LE-33] + _ = x[R_ARM64_TLS_IE-34] + _ = x[R_ARM64_GOTPCREL-35] + _ = x[R_ARM64_GOT-36] + _ = x[R_ARM64_PCREL-37] + _ = x[R_ARM64_LDST8-38] + _ = x[R_ARM64_LDST16-39] + _ = x[R_ARM64_LDST32-40] + _ = x[R_ARM64_LDST64-41] + _ = x[R_ARM64_LDST128-42] + _ = x[R_POWER_TLS_LE-43] + _ = x[R_POWER_TLS_IE-44] + _ = x[R_POWER_TLS-45] + _ = x[R_ADDRPOWER_DS-46] + _ = x[R_ADDRPOWER_GOT-47] + _ = x[R_ADDRPOWER_PCREL-48] + _ = x[R_ADDRPOWER_TOCREL-49] + _ = x[R_ADDRPOWER_TOCREL_DS-50] + _ = x[R_RISCV_PCREL_ITYPE-51] + _ = x[R_RISCV_PCREL_STYPE-52] + _ = x[R_RISCV_TLS_IE_ITYPE-53] + _ = x[R_RISCV_TLS_IE_STYPE-54] + _ = x[R_PCRELDBL-55] + _ = x[R_ADDRMIPSU-56] + _ = x[R_ADDRMIPSTLS-57] + _ = x[R_ADDRCUOFF-58] + _ = x[R_WASMIMPORT-59] + _ = x[R_XCOFFREF-60] +} + +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_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_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_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_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, 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} +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, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 425, 440, 454, 468, 479, 493, 508, 525, 543, 564, 583, 602, 622, 642, 652, 663, 676, 687, 699, 709} func (i RelocType) String() string { i -= 1 diff --git a/libgo/go/cmd/internal/objabi/symkind.go b/libgo/go/cmd/internal/objabi/symkind.go index 374aaa6514a..6c991121e72 100644 --- a/libgo/go/cmd/internal/objabi/symkind.go +++ b/libgo/go/cmd/internal/objabi/symkind.go @@ -56,7 +56,12 @@ const ( // Thread-local data that is initially all 0s STLSBSS // Debugging data - SDWARFINFO + SDWARFCUINFO + SDWARFCONST + SDWARFFCN + SDWARFABSFCN + SDWARFTYPE + SDWARFVAR SDWARFRANGE SDWARFLOC SDWARFLINES diff --git a/libgo/go/cmd/internal/objabi/symkind_string.go b/libgo/go/cmd/internal/objabi/symkind_string.go index 919a666e7b1..1b1c394038a 100644 --- a/libgo/go/cmd/internal/objabi/symkind_string.go +++ b/libgo/go/cmd/internal/objabi/symkind_string.go @@ -16,17 +16,22 @@ func _() { _ = x[SBSS-5] _ = x[SNOPTRBSS-6] _ = x[STLSBSS-7] - _ = x[SDWARFINFO-8] - _ = x[SDWARFRANGE-9] - _ = x[SDWARFLOC-10] - _ = x[SDWARFLINES-11] - _ = x[SABIALIAS-12] - _ = x[SLIBFUZZER_EXTRA_COUNTER-13] + _ = x[SDWARFCUINFO-8] + _ = x[SDWARFCONST-9] + _ = x[SDWARFFCN-10] + _ = x[SDWARFABSFCN-11] + _ = x[SDWARFTYPE-12] + _ = x[SDWARFVAR-13] + _ = x[SDWARFRANGE-14] + _ = x[SDWARFLOC-15] + _ = x[SDWARFLINES-16] + _ = x[SABIALIAS-17] + _ = x[SLIBFUZZER_EXTRA_COUNTER-18] } -const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER" +const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFCUINFOSDWARFCONSTSDWARFFCNSDWARFABSFCNSDWARFTYPESDWARFVARSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER" -var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72, 81, 92, 101, 125} +var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 63, 74, 83, 95, 105, 114, 125, 134, 145, 154, 178} func (i SymKind) String() string { if i >= SymKind(len(_SymKind_index)-1) { diff --git a/libgo/go/cmd/internal/objabi/util.go b/libgo/go/cmd/internal/objabi/util.go index 30d9ac51366..d9cf4955f2f 100644 --- a/libgo/go/cmd/internal/objabi/util.go +++ b/libgo/go/cmd/internal/objabi/util.go @@ -25,7 +25,6 @@ var ( GOARCH = envOr("GOARCH", defaultGOARCH) GOOS = envOr("GOOS", defaultGOOS) GO386 = envOr("GO386", defaultGO386) - GOAMD64 = goamd64() GOARM = goarm() GOMIPS = gomips() GOMIPS64 = gomips64() @@ -37,17 +36,16 @@ var ( const ( ElfRelocOffset = 256 - MachoRelocOffset = 2048 // reserve enough space for ELF relocations - Go115AMD64 = "alignedjumps" // Should be "alignedjumps" or "normaljumps"; this replaces environment variable introduced in CL 219357. + MachoRelocOffset = 2048 // reserve enough space for ELF relocations ) -// TODO(1.16): assuming no issues in 1.15 release, remove this and related constant. -func goamd64() string { - return Go115AMD64 -} - func goarm() int { - switch v := envOr("GOARM", defaultGOARM); v { + def := defaultGOARM + if GOOS == "android" && GOARCH == "arm" { + // Android arm devices always support GOARM=7. + def = "7" + } + switch v := envOr("GOARM", def); v { case "5": return 5 case "6": @@ -131,12 +129,16 @@ func init() { addexp(f) } } -} -func Framepointer_enabled(goos, goarch string) bool { - return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && (goos == "linux" || goos == "darwin")) + // regabi is only supported on amd64. + if GOARCH != "amd64" { + Regabi_enabled = 0 + } } +// Note: must agree with runtime.framepointer_enabled. +var Framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin" || GOOS == "ios") + func addexp(s string) { // Could do general integer parsing here, but the runtime copy doesn't yet. v := 1 @@ -159,10 +161,10 @@ func addexp(s string) { } var ( - framepointer_enabled int = 1 Fieldtrack_enabled int Preemptibleloops_enabled int Staticlockranking_enabled int + Regabi_enabled int ) // Toolchain experiments. @@ -174,9 +176,9 @@ var exper = []struct { val *int }{ {"fieldtrack", &Fieldtrack_enabled}, - {"framepointer", &framepointer_enabled}, {"preemptibleloops", &Preemptibleloops_enabled}, {"staticlockranking", &Staticlockranking_enabled}, + {"regabi", &Regabi_enabled}, } var defaultExpstring = Expstring() diff --git a/libgo/go/cmd/internal/sys/supported.go b/libgo/go/cmd/internal/sys/supported.go index c27b3b986d8..ef7c017bd4a 100644 --- a/libgo/go/cmd/internal/sys/supported.go +++ b/libgo/go/cmd/internal/sys/supported.go @@ -13,7 +13,9 @@ func RaceDetectorSupported(goos, goarch string) bool { switch goos { case "linux": return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" - case "darwin", "freebsd", "netbsd", "windows": + case "darwin": + return goarch == "amd64" || goarch == "arm64" + case "freebsd", "netbsd", "windows": return goarch == "amd64" default: return false @@ -32,13 +34,14 @@ func MSanSupported(goos, goarch string) bool { } // MustLinkExternal reports whether goos/goarch requires external linking. +// (This is the opposite of internal/testenv.CanInternalLink. Keep them in sync.) func MustLinkExternal(goos, goarch string) bool { switch goos { case "android": if goarch != "arm64" { return true } - case "darwin": + case "ios": if goarch == "arm64" { return true } @@ -69,7 +72,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { 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/amd64", "darwin/arm64", "windows/amd64", "windows/386": return true } @@ -83,10 +86,11 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { case "pie": switch platform { - case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x", + case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/riscv64", "linux/s390x", "android/amd64", "android/arm", "android/arm64", "android/386", "freebsd/amd64", - "darwin/amd64", + "darwin/amd64", "darwin/arm64", + "ios/amd64", "ios/arm64", "aix/ppc64", "windows/386", "windows/amd64", "windows/arm": return true @@ -104,7 +108,7 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { 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", + "darwin/amd64", "darwin/arm64", "freebsd/amd64": return true } @@ -114,3 +118,14 @@ func BuildModeSupported(compiler, buildmode, goos, goarch string) bool { return false } } + +func InternalLinkPIESupported(goos, goarch string) bool { + switch goos + "/" + goarch { + case "darwin/amd64", "darwin/arm64", + "linux/amd64", "linux/arm64", + "android/arm64", + "windows-amd64", "windows-386", "windows-arm": + return true + } + return false +} diff --git a/libgo/go/cmd/internal/sys/supported_test.go b/libgo/go/cmd/internal/sys/supported_test.go new file mode 100644 index 00000000000..1217814af5b --- /dev/null +++ b/libgo/go/cmd/internal/sys/supported_test.go @@ -0,0 +1,18 @@ +// Copyright 2020 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 sys + +import ( + "internal/testenv" + "runtime" + "testing" +) + +func TestMustLinkExternalMatchesTestenv(t *testing.T) { + // MustLinkExternal and testenv.CanInternalLink are the exact opposite. + if b := MustLinkExternal(runtime.GOOS, runtime.GOARCH); b != !testenv.CanInternalLink() { + t.Fatalf("MustLinkExternal() == %v, testenv.CanInternalLink() == %v, don't match", b, testenv.CanInternalLink()) + } +} diff --git a/libgo/go/cmd/internal/traceviewer/format.go b/libgo/go/cmd/internal/traceviewer/format.go new file mode 100644 index 00000000000..871477447f1 --- /dev/null +++ b/libgo/go/cmd/internal/traceviewer/format.go @@ -0,0 +1,38 @@ +// Copyright 2020 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 traceviewer provides definitions of the JSON data structures +// used by the Chrome trace viewer. +// +// The official description of the format is in this file: +// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview +package traceviewer + +type Data struct { + Events []*Event `json:"traceEvents"` + Frames map[string]Frame `json:"stackFrames"` + TimeUnit string `json:"displayTimeUnit"` +} + +type Event struct { + Name string `json:"name,omitempty"` + Phase string `json:"ph"` + Scope string `json:"s,omitempty"` + Time float64 `json:"ts"` + Dur float64 `json:"dur,omitempty"` + PID uint64 `json:"pid"` + TID uint64 `json:"tid"` + ID uint64 `json:"id,omitempty"` + BindPoint string `json:"bp,omitempty"` + Stack int `json:"sf,omitempty"` + EndStack int `json:"esf,omitempty"` + Arg interface{} `json:"args,omitempty"` + Cname string `json:"cname,omitempty"` + Category string `json:"cat,omitempty"` +} + +type Frame struct { + Name string `json:"name"` + Parent int `json:"parent,omitempty"` +} diff --git a/libgo/go/cmd/vendor/modules.txt b/libgo/go/cmd/vendor/modules.txt new file mode 100644 index 00000000000..4e47f41855e --- /dev/null +++ b/libgo/go/cmd/vendor/modules.txt @@ -0,0 +1,91 @@ +# github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2 +## explicit +github.com/google/pprof/driver +github.com/google/pprof/internal/binutils +github.com/google/pprof/internal/driver +github.com/google/pprof/internal/elfexec +github.com/google/pprof/internal/graph +github.com/google/pprof/internal/measurement +github.com/google/pprof/internal/plugin +github.com/google/pprof/internal/report +github.com/google/pprof/internal/symbolizer +github.com/google/pprof/internal/symbolz +github.com/google/pprof/internal/transport +github.com/google/pprof/profile +github.com/google/pprof/third_party/d3 +github.com/google/pprof/third_party/d3flamegraph +github.com/google/pprof/third_party/svgpan +# github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 +github.com/ianlancetaylor/demangle +# golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff +## explicit +golang.org/x/arch/arm/armasm +golang.org/x/arch/arm64/arm64asm +golang.org/x/arch/ppc64/ppc64asm +golang.org/x/arch/x86/x86asm +# golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 +## explicit +golang.org/x/crypto/ed25519 +golang.org/x/crypto/ed25519/internal/edwards25519 +golang.org/x/crypto/ssh/terminal +# golang.org/x/mod v0.4.0 +## explicit +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/sys v0.0.0-20201204225414-ed752295db88 +## explicit +golang.org/x/sys/internal/unsafeheader +golang.org/x/sys/unix +golang.org/x/sys/windows +# golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11 +## explicit +golang.org/x/tools/go/analysis +golang.org/x/tools/go/analysis/internal/analysisflags +golang.org/x/tools/go/analysis/internal/facts +golang.org/x/tools/go/analysis/passes/asmdecl +golang.org/x/tools/go/analysis/passes/assign +golang.org/x/tools/go/analysis/passes/atomic +golang.org/x/tools/go/analysis/passes/bools +golang.org/x/tools/go/analysis/passes/buildtag +golang.org/x/tools/go/analysis/passes/cgocall +golang.org/x/tools/go/analysis/passes/composite +golang.org/x/tools/go/analysis/passes/copylock +golang.org/x/tools/go/analysis/passes/ctrlflow +golang.org/x/tools/go/analysis/passes/errorsas +golang.org/x/tools/go/analysis/passes/framepointer +golang.org/x/tools/go/analysis/passes/httpresponse +golang.org/x/tools/go/analysis/passes/ifaceassert +golang.org/x/tools/go/analysis/passes/inspect +golang.org/x/tools/go/analysis/passes/internal/analysisutil +golang.org/x/tools/go/analysis/passes/loopclosure +golang.org/x/tools/go/analysis/passes/lostcancel +golang.org/x/tools/go/analysis/passes/nilfunc +golang.org/x/tools/go/analysis/passes/printf +golang.org/x/tools/go/analysis/passes/shift +golang.org/x/tools/go/analysis/passes/stdmethods +golang.org/x/tools/go/analysis/passes/stringintconv +golang.org/x/tools/go/analysis/passes/structtag +golang.org/x/tools/go/analysis/passes/testinggoroutine +golang.org/x/tools/go/analysis/passes/tests +golang.org/x/tools/go/analysis/passes/unmarshal +golang.org/x/tools/go/analysis/passes/unreachable +golang.org/x/tools/go/analysis/passes/unsafeptr +golang.org/x/tools/go/analysis/passes/unusedresult +golang.org/x/tools/go/analysis/unitchecker +golang.org/x/tools/go/ast/astutil +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/tools/internal/analysisinternal +golang.org/x/tools/internal/lsp/fuzzy +# golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 +golang.org/x/xerrors +golang.org/x/xerrors/internal diff --git a/libgo/go/cmd/vet/main.go b/libgo/go/cmd/vet/main.go index 6381de840c0..d50c45d691e 100644 --- a/libgo/go/cmd/vet/main.go +++ b/libgo/go/cmd/vet/main.go @@ -14,6 +14,7 @@ import ( "golang.org/x/tools/go/analysis/passes/composite" "golang.org/x/tools/go/analysis/passes/copylock" "golang.org/x/tools/go/analysis/passes/errorsas" + "golang.org/x/tools/go/analysis/passes/framepointer" "golang.org/x/tools/go/analysis/passes/httpresponse" "golang.org/x/tools/go/analysis/passes/ifaceassert" "golang.org/x/tools/go/analysis/passes/loopclosure" @@ -24,6 +25,7 @@ import ( "golang.org/x/tools/go/analysis/passes/stdmethods" "golang.org/x/tools/go/analysis/passes/stringintconv" "golang.org/x/tools/go/analysis/passes/structtag" + "golang.org/x/tools/go/analysis/passes/testinggoroutine" "golang.org/x/tools/go/analysis/passes/tests" "golang.org/x/tools/go/analysis/passes/unmarshal" "golang.org/x/tools/go/analysis/passes/unreachable" @@ -44,6 +46,7 @@ func main() { composite.Analyzer, copylock.Analyzer, errorsas.Analyzer, + framepointer.Analyzer, httpresponse.Analyzer, ifaceassert.Analyzer, loopclosure.Analyzer, @@ -55,6 +58,7 @@ func main() { stringintconv.Analyzer, structtag.Analyzer, tests.Analyzer, + testinggoroutine.Analyzer, unmarshal.Analyzer, unreachable.Analyzer, unsafeptr.Analyzer, diff --git a/libgo/go/cmd/vet/vet_test.go b/libgo/go/cmd/vet/vet_test.go index 66732ad6f64..4c8dd3cc496 100644 --- a/libgo/go/cmd/vet/vet_test.go +++ b/libgo/go/cmd/vet/vet_test.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "internal/testenv" - "io/ioutil" "log" "os" "os/exec" @@ -33,7 +32,7 @@ func TestMain(m *testing.M) { } func testMain(m *testing.M) int { - dir, err := ioutil.TempDir("", "vet_test") + dir, err := os.MkdirTemp("", "vet_test") if err != nil { fmt.Fprintln(os.Stderr, err) return 1 @@ -349,7 +348,7 @@ var ( func wantedErrors(file, short string) (errs []wantedError) { cache := make(map[string]*regexp.Regexp) - src, err := ioutil.ReadFile(file) + src, err := os.ReadFile(file) if err != nil { log.Fatal(err) } diff --git a/libgo/go/compress/bzip2/bzip2.go b/libgo/go/compress/bzip2/bzip2.go index c40129b9820..0d8c286c167 100644 --- a/libgo/go/compress/bzip2/bzip2.go +++ b/libgo/go/compress/bzip2/bzip2.go @@ -29,8 +29,8 @@ type reader struct { setupDone bool // true if we have parsed the bzip2 header. blockSize int // blockSize in bytes, i.e. 900 * 1000. eof bool - c [256]uint // the `C' array for the inverse BWT. - tt []uint32 // mirrors the `tt' array in the bzip2 source and contains the P array in the upper 24 bits. + c [256]uint // the ``C'' array for the inverse BWT. + tt []uint32 // mirrors the ``tt'' array in the bzip2 source and contains the P array in the upper 24 bits. tPos uint32 // Index of the next output byte in tt. preRLE []uint32 // contains the RLE data still to be processed. @@ -447,11 +447,11 @@ func (bz2 *reader) readBlock() (err error) { // inverseBWT implements the inverse Burrows-Wheeler transform as described in // http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-124.pdf, section 4.2. -// In that document, origPtr is called `I' and c is the `C' array after the +// In that document, origPtr is called ``I'' and c is the ``C'' array after the // first pass over the data. It's an argument here because we merge the first // pass with the Huffman decoding. // -// This also implements the `single array' method from the bzip2 source code +// This also implements the ``single array'' method from the bzip2 source code // which leaves the output, still shuffled, in the bottom 8 bits of tt with the // index of the next byte in the top 24-bits. The index of the first byte is // returned. diff --git a/libgo/go/compress/bzip2/bzip2_test.go b/libgo/go/compress/bzip2/bzip2_test.go index c432bb5226f..e6065cb43fd 100644 --- a/libgo/go/compress/bzip2/bzip2_test.go +++ b/libgo/go/compress/bzip2/bzip2_test.go @@ -9,7 +9,7 @@ import ( "encoding/hex" "fmt" "io" - "io/ioutil" + "os" "testing" ) @@ -22,7 +22,7 @@ func mustDecodeHex(s string) []byte { } func mustLoadFile(f string) []byte { - b, err := ioutil.ReadFile(f) + b, err := os.ReadFile(f) if err != nil { panic(err) } @@ -133,7 +133,7 @@ func TestReader(t *testing.T) { for i, v := range vectors { rd := NewReader(bytes.NewReader(v.input)) - buf, err := ioutil.ReadAll(rd) + buf, err := io.ReadAll(rd) if fail := bool(err != nil); fail != v.fail { if fail { @@ -220,7 +220,7 @@ var ( func benchmarkDecode(b *testing.B, compressed []byte) { // Determine the uncompressed size of testfile. - uncompressedSize, err := io.Copy(ioutil.Discard, NewReader(bytes.NewReader(compressed))) + uncompressedSize, err := io.Copy(io.Discard, NewReader(bytes.NewReader(compressed))) if err != nil { b.Fatal(err) } @@ -231,7 +231,7 @@ func benchmarkDecode(b *testing.B, compressed []byte) { for i := 0; i < b.N; i++ { r := bytes.NewReader(compressed) - io.Copy(ioutil.Discard, NewReader(r)) + io.Copy(io.Discard, NewReader(r)) } } diff --git a/libgo/go/compress/flate/deflate_test.go b/libgo/go/compress/flate/deflate_test.go index 8a22b8e6f92..66f71112afa 100644 --- a/libgo/go/compress/flate/deflate_test.go +++ b/libgo/go/compress/flate/deflate_test.go @@ -10,8 +10,8 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" "math/rand" + "os" "reflect" "runtime/debug" "sync" @@ -157,7 +157,7 @@ func TestVeryLongSparseChunk(t *testing.T) { if testing.Short() { t.Skip("skipping sparse chunk during short test") } - w, err := NewWriter(ioutil.Discard, 1) + w, err := NewWriter(io.Discard, 1) if err != nil { t.Errorf("NewWriter: %v", err) return @@ -294,7 +294,7 @@ func testSync(t *testing.T, level int, input []byte, name string) { // stream should work for ordinary reader too r = NewReader(buf1) - out, err = ioutil.ReadAll(r) + out, err = io.ReadAll(r) if err != nil { t.Errorf("testSync: read: %s", err) return @@ -322,7 +322,7 @@ func testToFromWithLevelAndLimit(t *testing.T, level int, input []byte, name str t.Logf("level: %d, size:%.2f%%, %d b\n", level, float64(buffer.Len()*100)/float64(limit), buffer.Len()) } r := NewReader(&buffer) - out, err := ioutil.ReadAll(r) + out, err := io.ReadAll(r) if err != nil { t.Errorf("read: %s", err) return @@ -387,7 +387,7 @@ func TestDeflateInflateString(t *testing.T) { t.Skip("skipping in short mode") } for _, test := range deflateInflateStringTests { - gold, err := ioutil.ReadFile(test.filename) + gold, err := os.ReadFile(test.filename) if err != nil { t.Error(err) } @@ -415,7 +415,7 @@ func TestReaderDict(t *testing.T) { w.Close() r := NewReaderDict(&b, []byte(dict)) - data, err := ioutil.ReadAll(r) + data, err := io.ReadAll(r) if err != nil { t.Fatal(err) } @@ -456,7 +456,7 @@ func TestRegression2508(t *testing.T) { t.Logf("test disabled with -short") return } - w, err := NewWriter(ioutil.Discard, 1) + w, err := NewWriter(io.Discard, 1) if err != nil { t.Fatalf("NewWriter: %v", err) } @@ -475,7 +475,7 @@ func TestWriterReset(t *testing.T) { if testing.Short() && level > 1 { break } - w, err := NewWriter(ioutil.Discard, level) + w, err := NewWriter(io.Discard, level) if err != nil { t.Fatalf("NewWriter: %v", err) } @@ -487,9 +487,9 @@ func TestWriterReset(t *testing.T) { for i := 0; i < n; i++ { w.Write(buf) } - w.Reset(ioutil.Discard) + w.Reset(io.Discard) - wref, err := NewWriter(ioutil.Discard, level) + wref, err := NewWriter(io.Discard, level) if err != nil { t.Fatalf("NewWriter: %v", err) } @@ -654,7 +654,7 @@ func TestBestSpeed(t *testing.T) { } r := NewReader(buf) - got, err := ioutil.ReadAll(r) + got, err := io.ReadAll(r) if err != nil { t.Errorf("i=%d, firstN=%d, flush=%t: ReadAll: %v", i, firstN, flush, err) continue @@ -685,7 +685,7 @@ func (w *failWriter) Write(b []byte) (int, error) { func TestWriterPersistentError(t *testing.T) { t.Parallel() - d, err := ioutil.ReadFile("testdata/Isaac.Newton-Opticks.txt") + d, err := os.ReadFile("testdata/Isaac.Newton-Opticks.txt") if err != nil { t.Fatalf("ReadFile: %v", err) } @@ -881,7 +881,7 @@ func TestBestSpeedMaxMatchOffset(t *testing.T) { } r := NewReader(buf) - dst, err := ioutil.ReadAll(r) + dst, err := io.ReadAll(r) r.Close() if err != nil { report("ReadAll: ", err) @@ -968,7 +968,7 @@ func TestMaxStackSize(t *testing.T) { wg.Add(1) go func(level int) { defer wg.Done() - zw, err := NewWriter(ioutil.Discard, level) + zw, err := NewWriter(io.Discard, level) if err != nil { t.Errorf("level %d, NewWriter() = %v, want nil", level, err) } @@ -978,7 +978,7 @@ func TestMaxStackSize(t *testing.T) { if err := zw.Close(); err != nil { t.Errorf("level %d, Close() = %v, want nil", level, err) } - zw.Reset(ioutil.Discard) + zw.Reset(io.Discard) }(level) } } diff --git a/libgo/go/compress/flate/dict_decoder.go b/libgo/go/compress/flate/dict_decoder.go index 71c75a065ea..3b59d483511 100644 --- a/libgo/go/compress/flate/dict_decoder.go +++ b/libgo/go/compress/flate/dict_decoder.go @@ -160,10 +160,8 @@ func (dd *dictDecoder) tryWriteCopy(dist, length int) int { srcPos := dstPos - dist // Copy possibly overlapping section before destination position. -loop: - dstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos]) - if dstPos < endPos { - goto loop // Avoid for-loop so that this function can be inlined + for dstPos < endPos { + dstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos]) } dd.wrPos = dstPos diff --git a/libgo/go/compress/flate/flate_test.go b/libgo/go/compress/flate/flate_test.go index 1e45077bd5b..23f4c47b037 100644 --- a/libgo/go/compress/flate/flate_test.go +++ b/libgo/go/compress/flate/flate_test.go @@ -12,7 +12,6 @@ import ( "bytes" "encoding/hex" "io" - "io/ioutil" "strings" "testing" ) @@ -243,7 +242,7 @@ func TestStreams(t *testing.T) { if err != nil { t.Fatal(err) } - data, err = ioutil.ReadAll(NewReader(bytes.NewReader(data))) + data, err = io.ReadAll(NewReader(bytes.NewReader(data))) if tc.want == "fail" { if err == nil { t.Errorf("#%d (%s): got nil error, want non-nil", i, tc.desc) @@ -266,7 +265,7 @@ func TestTruncatedStreams(t *testing.T) { for i := 0; i < len(data)-1; i++ { r := NewReader(strings.NewReader(data[:i])) - _, err := io.Copy(ioutil.Discard, r) + _, err := io.Copy(io.Discard, r) if err != io.ErrUnexpectedEOF { t.Errorf("io.Copy(%d) on truncated stream: got %v, want %v", i, err, io.ErrUnexpectedEOF) } diff --git a/libgo/go/compress/flate/huffman_bit_writer.go b/libgo/go/compress/flate/huffman_bit_writer.go index f111f9f592c..b3ae76d0821 100644 --- a/libgo/go/compress/flate/huffman_bit_writer.go +++ b/libgo/go/compress/flate/huffman_bit_writer.go @@ -75,7 +75,8 @@ type huffmanBitWriter struct { writer io.Writer // Data waiting to be written is bytes[0:nbytes] - // and then the low nbits of bits. + // and then the low nbits of bits. Data is always written + // sequentially into the bytes array. bits uint64 nbits uint bytes [bufferSize]byte @@ -105,7 +106,6 @@ func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter { func (w *huffmanBitWriter) reset(writer io.Writer) { w.writer = writer w.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil - w.bytes = [bufferSize]byte{} } func (w *huffmanBitWriter) flush() { diff --git a/libgo/go/compress/flate/huffman_bit_writer_test.go b/libgo/go/compress/flate/huffman_bit_writer_test.go index 882d3abec18..a57799cae02 100644 --- a/libgo/go/compress/flate/huffman_bit_writer_test.go +++ b/libgo/go/compress/flate/huffman_bit_writer_test.go @@ -8,7 +8,6 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -38,7 +37,7 @@ func TestBlockHuff(t *testing.T) { } func testBlockHuff(t *testing.T, in, out string) { - all, err := ioutil.ReadFile(in) + all, err := os.ReadFile(in) if err != nil { t.Error(err) return @@ -49,7 +48,7 @@ func testBlockHuff(t *testing.T, in, out string) { bw.flush() got := buf.Bytes() - want, err := ioutil.ReadFile(out) + want, err := os.ReadFile(out) if err != nil && !*update { t.Error(err) return @@ -60,7 +59,7 @@ func testBlockHuff(t *testing.T, in, out string) { if *update { if in != out { t.Logf("Updating %q", out) - if err := ioutil.WriteFile(out, got, 0666); err != nil { + if err := os.WriteFile(out, got, 0666); err != nil { t.Error(err) } return @@ -70,7 +69,7 @@ func testBlockHuff(t *testing.T, in, out string) { } t.Errorf("%q != %q (see %q)", in, out, in+".got") - if err := ioutil.WriteFile(in+".got", got, 0666); err != nil { + if err := os.WriteFile(in+".got", got, 0666); err != nil { t.Error(err) } return @@ -85,7 +84,7 @@ func testBlockHuff(t *testing.T, in, out string) { got = buf.Bytes() if !bytes.Equal(got, want) { t.Errorf("after reset %q != %q (see %q)", in, out, in+".reset.got") - if err := ioutil.WriteFile(in+".reset.got", got, 0666); err != nil { + if err := os.WriteFile(in+".reset.got", got, 0666); err != nil { t.Error(err) } return @@ -186,7 +185,7 @@ func testBlock(t *testing.T, test huffTest, ttype string) { if *update { if test.input != "" { t.Logf("Updating %q", test.want) - input, err := ioutil.ReadFile(test.input) + input, err := os.ReadFile(test.input) if err != nil { t.Error(err) return @@ -216,12 +215,12 @@ func testBlock(t *testing.T, test huffTest, ttype string) { if test.input != "" { t.Logf("Testing %q", test.want) - input, err := ioutil.ReadFile(test.input) + input, err := os.ReadFile(test.input) if err != nil { t.Error(err) return } - want, err := ioutil.ReadFile(test.want) + want, err := os.ReadFile(test.want) if err != nil { t.Error(err) return @@ -233,7 +232,7 @@ func testBlock(t *testing.T, test huffTest, ttype string) { got := buf.Bytes() if !bytes.Equal(got, want) { t.Errorf("writeBlock did not yield expected result for file %q with input. See %q", test.want, test.want+".got") - if err := ioutil.WriteFile(test.want+".got", got, 0666); err != nil { + if err := os.WriteFile(test.want+".got", got, 0666); err != nil { t.Error(err) } } @@ -247,7 +246,7 @@ func testBlock(t *testing.T, test huffTest, ttype string) { got = buf.Bytes() if !bytes.Equal(got, want) { t.Errorf("reset: writeBlock did not yield expected result for file %q with input. See %q", test.want, test.want+".reset.got") - if err := ioutil.WriteFile(test.want+".reset.got", got, 0666); err != nil { + if err := os.WriteFile(test.want+".reset.got", got, 0666); err != nil { t.Error(err) } return @@ -256,7 +255,7 @@ func testBlock(t *testing.T, test huffTest, ttype string) { testWriterEOF(t, "wb", test, true) } t.Logf("Testing %q", test.wantNoInput) - wantNI, err := ioutil.ReadFile(test.wantNoInput) + wantNI, err := os.ReadFile(test.wantNoInput) if err != nil { t.Error(err) return @@ -268,7 +267,7 @@ func testBlock(t *testing.T, test huffTest, ttype string) { got := buf.Bytes() if !bytes.Equal(got, wantNI) { t.Errorf("writeBlock did not yield expected result for file %q with input. See %q", test.wantNoInput, test.wantNoInput+".got") - if err := ioutil.WriteFile(test.want+".got", got, 0666); err != nil { + if err := os.WriteFile(test.want+".got", got, 0666); err != nil { t.Error(err) } } else if got[0]&1 == 1 { @@ -286,7 +285,7 @@ func testBlock(t *testing.T, test huffTest, ttype string) { got = buf.Bytes() if !bytes.Equal(got, wantNI) { t.Errorf("reset: writeBlock did not yield expected result for file %q without input. See %q", test.want, test.want+".reset.got") - if err := ioutil.WriteFile(test.want+".reset.got", got, 0666); err != nil { + if err := os.WriteFile(test.want+".reset.got", got, 0666); err != nil { t.Error(err) } return @@ -325,7 +324,7 @@ func testWriterEOF(t *testing.T, ttype string, test huffTest, useInput bool) { var input []byte if useInput { var err error - input, err = ioutil.ReadFile(test.input) + input, err = os.ReadFile(test.input) if err != nil { t.Error(err) return diff --git a/libgo/go/compress/flate/inflate_test.go b/libgo/go/compress/flate/inflate_test.go index 951decd7754..9575be1cf27 100644 --- a/libgo/go/compress/flate/inflate_test.go +++ b/libgo/go/compress/flate/inflate_test.go @@ -7,7 +7,6 @@ package flate import ( "bytes" "io" - "io/ioutil" "strings" "testing" ) @@ -57,7 +56,7 @@ func TestReaderTruncated(t *testing.T) { for i, v := range vectors { r := strings.NewReader(v.input) zr := NewReader(r) - b, err := ioutil.ReadAll(zr) + b, err := io.ReadAll(zr) if err != io.ErrUnexpectedEOF { t.Errorf("test %d, error mismatch: got %v, want io.ErrUnexpectedEOF", i, err) } diff --git a/libgo/go/compress/flate/reader_test.go b/libgo/go/compress/flate/reader_test.go index e39d7f0f97e..41380be8710 100644 --- a/libgo/go/compress/flate/reader_test.go +++ b/libgo/go/compress/flate/reader_test.go @@ -7,7 +7,7 @@ package flate import ( "bytes" "io" - "io/ioutil" + "os" "runtime" "strings" "testing" @@ -16,7 +16,7 @@ import ( func TestNlitOutOfRange(t *testing.T) { // Trying to decode this bogus flate data, which has a Huffman table // with nlit=288, should not panic. - io.Copy(ioutil.Discard, NewReader(strings.NewReader( + io.Copy(io.Discard, NewReader(strings.NewReader( "\xfc\xfe\x36\xe7\x5e\x1c\xef\xb3\x55\x58\x77\xb6\x56\xb5\x43\xf4"+ "\x6f\xf2\xd2\xe6\x3d\x99\xa0\x85\x8c\x48\xeb\xf8\xda\x83\x04\x2a"+ "\x75\xc4\xf8\x0f\x12\x11\xb9\xb4\x4b\x09\xa0\xbe\x8b\x91\x4c"))) @@ -54,7 +54,7 @@ func BenchmarkDecode(b *testing.B) { runtime.GC() b.StartTimer() for i := 0; i < b.N; i++ { - io.Copy(ioutil.Discard, NewReader(bytes.NewReader(buf1))) + io.Copy(io.Discard, NewReader(bytes.NewReader(buf1))) } }) } @@ -80,7 +80,7 @@ var sizes = []struct { func doBench(b *testing.B, f func(b *testing.B, buf []byte, level, n int)) { for _, suite := range suites { - buf, err := ioutil.ReadFile(suite.file) + buf, err := os.ReadFile(suite.file) if err != nil { b.Fatal(err) } diff --git a/libgo/go/compress/flate/writer_test.go b/libgo/go/compress/flate/writer_test.go index 881cb71cc3a..c413735cd2c 100644 --- a/libgo/go/compress/flate/writer_test.go +++ b/libgo/go/compress/flate/writer_test.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "math/rand" "runtime" "testing" @@ -27,14 +26,14 @@ func BenchmarkEncode(b *testing.B) { copy(buf1[i:], buf0) } buf0 = nil - w, err := NewWriter(ioutil.Discard, level) + w, err := NewWriter(io.Discard, level) if err != nil { b.Fatal(err) } runtime.GC() b.StartTimer() for i := 0; i < b.N; i++ { - w.Reset(ioutil.Discard) + w.Reset(io.Discard) w.Write(buf1) w.Close() } @@ -96,7 +95,7 @@ func TestWriteError(t *testing.T) { t.Fatal("Level", l, "Expected an error on close") } - w.Reset(ioutil.Discard) + w.Reset(io.Discard) n2, err = w.Write([]byte{1, 2, 3, 4, 5, 6}) if err != nil { t.Fatal("Level", l, "Got unexpected error after reset:", err) @@ -206,7 +205,7 @@ func TestDeflateFast_Reset(t *testing.T) { w.Close() for ; offset <= 256; offset *= 2 { - w, err := NewWriter(ioutil.Discard, level) + w, err := NewWriter(io.Discard, level) if err != nil { t.Fatalf("NewWriter: level %d: %v", level, err) } diff --git a/libgo/go/compress/gzip/gunzip_test.go b/libgo/go/compress/gzip/gunzip_test.go index 1b014041692..17c23e8a9be 100644 --- a/libgo/go/compress/gzip/gunzip_test.go +++ b/libgo/go/compress/gzip/gunzip_test.go @@ -9,7 +9,6 @@ import ( "compress/flate" "encoding/base64" "io" - "io/ioutil" "os" "strings" "testing" @@ -430,7 +429,7 @@ func TestIssue6550(t *testing.T) { defer gzip.Close() done := make(chan bool, 1) go func() { - _, err := io.Copy(ioutil.Discard, gzip) + _, err := io.Copy(io.Discard, gzip) if err == nil { t.Errorf("Copy succeeded") } else { @@ -467,7 +466,7 @@ Found: const hello = "hello world\n" r.Multistream(false) - data, err := ioutil.ReadAll(&r) + data, err := io.ReadAll(&r) if string(data) != hello || err != nil { t.Fatalf("first stream = %q, %v, want %q, %v", string(data), err, hello, nil) } @@ -476,7 +475,7 @@ Found: t.Fatalf("second reset: %v", err) } r.Multistream(false) - data, err = ioutil.ReadAll(&r) + data, err = io.ReadAll(&r) if string(data) != hello || err != nil { t.Fatalf("second stream = %q, %v, want %q, %v", string(data), err, hello, nil) } @@ -507,7 +506,7 @@ func TestTruncatedStreams(t *testing.T) { } continue } - _, err = io.Copy(ioutil.Discard, r) + _, err = io.Copy(io.Discard, r) if ferr, ok := err.(*flate.ReadError); ok { err = ferr.Err } diff --git a/libgo/go/compress/gzip/gzip_test.go b/libgo/go/compress/gzip/gzip_test.go index f18c5cb4547..12c8e182078 100644 --- a/libgo/go/compress/gzip/gzip_test.go +++ b/libgo/go/compress/gzip/gzip_test.go @@ -8,7 +8,6 @@ import ( "bufio" "bytes" "io" - "io/ioutil" "reflect" "testing" "time" @@ -29,7 +28,7 @@ func TestEmpty(t *testing.T) { if want := (Header{OS: 255}); !reflect.DeepEqual(r.Header, want) { t.Errorf("Header mismatch:\ngot %#v\nwant %#v", r.Header, want) } - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { t.Fatalf("ReadAll: %v", err) } @@ -62,7 +61,7 @@ func TestRoundTrip(t *testing.T) { if err != nil { t.Fatalf("NewReader: %v", err) } - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { t.Fatalf("ReadAll: %v", err) } @@ -147,7 +146,7 @@ func TestLatin1RoundTrip(t *testing.T) { t.Errorf("NewReader: %v", err) continue } - _, err = ioutil.ReadAll(r) + _, err = io.ReadAll(r) if err != nil { t.Errorf("ReadAll: %v", err) continue @@ -217,7 +216,7 @@ func TestConcat(t *testing.T) { if err != nil { t.Fatal(err) } - data, err := ioutil.ReadAll(r) + data, err := io.ReadAll(r) if string(data) != "hello world\n" || err != nil { t.Fatalf("ReadAll = %q, %v, want %q, nil", data, err, "hello world") } diff --git a/libgo/go/compress/gzip/issue14937_test.go b/libgo/go/compress/gzip/issue14937_test.go index 7a19672d578..20da0b6824a 100644 --- a/libgo/go/compress/gzip/issue14937_test.go +++ b/libgo/go/compress/gzip/issue14937_test.go @@ -2,6 +2,7 @@ package gzip import ( "internal/testenv" + "io/fs" "os" "path/filepath" "runtime" @@ -30,7 +31,7 @@ func TestGZIPFilesHaveZeroMTimes(t *testing.T) { t.Fatal("error evaluating GOROOT: ", err) } var files []string - err = filepath.Walk(goroot, func(path string, info os.FileInfo, err error) error { + err = filepath.WalkDir(goroot, func(path string, info fs.DirEntry, err error) error { if err != nil { return err } diff --git a/libgo/go/compress/lzw/reader_test.go b/libgo/go/compress/lzw/reader_test.go index 98bbfbb763e..d1eb76d0425 100644 --- a/libgo/go/compress/lzw/reader_test.go +++ b/libgo/go/compress/lzw/reader_test.go @@ -8,8 +8,8 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "math" + "os" "runtime" "strconv" "strings" @@ -206,7 +206,7 @@ func TestNoLongerSavingPriorExpansions(t *testing.T) { in = append(in, 0x80, 0xff, 0x0f, 0x08) r := NewReader(bytes.NewReader(in), LSB, 8) - nDecoded, err := io.Copy(ioutil.Discard, r) + nDecoded, err := io.Copy(io.Discard, r) if err != nil { t.Fatalf("Copy: %v", err) } @@ -218,7 +218,7 @@ func TestNoLongerSavingPriorExpansions(t *testing.T) { } func BenchmarkDecoder(b *testing.B) { - buf, err := ioutil.ReadFile("../testdata/e.txt") + buf, err := os.ReadFile("../testdata/e.txt") if err != nil { b.Fatal(err) } @@ -246,7 +246,7 @@ func BenchmarkDecoder(b *testing.B) { runtime.GC() b.StartTimer() for i := 0; i < b.N; i++ { - io.Copy(ioutil.Discard, NewReader(bytes.NewReader(buf1), LSB, 8)) + io.Copy(io.Discard, NewReader(bytes.NewReader(buf1), LSB, 8)) } }) } diff --git a/libgo/go/compress/lzw/writer_test.go b/libgo/go/compress/lzw/writer_test.go index 4979f8b3521..1a5dbcae93f 100644 --- a/libgo/go/compress/lzw/writer_test.go +++ b/libgo/go/compress/lzw/writer_test.go @@ -8,7 +8,6 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" "math" "os" "runtime" @@ -67,8 +66,8 @@ func testFile(t *testing.T, fn string, order Order, litWidth int) { defer lzwr.Close() // Compare the two. - b0, err0 := ioutil.ReadAll(golden) - b1, err1 := ioutil.ReadAll(lzwr) + b0, err0 := io.ReadAll(golden) + b1, err1 := io.ReadAll(lzwr) if err0 != nil { t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0) return @@ -107,7 +106,7 @@ func TestWriter(t *testing.T) { } func TestWriterReturnValues(t *testing.T) { - w := NewWriter(ioutil.Discard, LSB, 8) + w := NewWriter(io.Discard, LSB, 8) n, err := w.Write([]byte("asdf")) if n != 4 || err != nil { t.Errorf("got %d, %v, want 4, nil", n, err) @@ -115,7 +114,7 @@ func TestWriterReturnValues(t *testing.T) { } func TestSmallLitWidth(t *testing.T) { - w := NewWriter(ioutil.Discard, LSB, 2) + w := NewWriter(io.Discard, LSB, 2) if _, err := w.Write([]byte{0x03}); err != nil { t.Fatalf("write a byte < 1<<2: %v", err) } @@ -125,7 +124,7 @@ func TestSmallLitWidth(t *testing.T) { } func BenchmarkEncoder(b *testing.B) { - buf, err := ioutil.ReadFile("../testdata/e.txt") + buf, err := os.ReadFile("../testdata/e.txt") if err != nil { b.Fatal(err) } @@ -148,7 +147,7 @@ func BenchmarkEncoder(b *testing.B) { b.Run(fmt.Sprint("1e", e), func(b *testing.B) { b.SetBytes(int64(n)) for i := 0; i < b.N; i++ { - w := NewWriter(ioutil.Discard, LSB, 8) + w := NewWriter(io.Discard, LSB, 8) w.Write(buf1) w.Close() } diff --git a/libgo/go/compress/zlib/writer_test.go b/libgo/go/compress/zlib/writer_test.go index d5019740783..f0b38880a6d 100644 --- a/libgo/go/compress/zlib/writer_test.go +++ b/libgo/go/compress/zlib/writer_test.go @@ -9,7 +9,6 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" "os" "testing" ) @@ -34,7 +33,7 @@ func testFileLevelDict(t *testing.T, fn string, level int, d string) { return } defer golden.Close() - b0, err0 := ioutil.ReadAll(golden) + b0, err0 := io.ReadAll(golden) if err0 != nil { t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err0) return @@ -74,7 +73,7 @@ func testLevelDict(t *testing.T, fn string, b0 []byte, level int, d string) { defer zlibr.Close() // Compare the decompressed data. - b1, err1 := ioutil.ReadAll(zlibr) + b1, err1 := io.ReadAll(zlibr) if err1 != nil { t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err1) return @@ -95,7 +94,7 @@ func testFileLevelDictReset(t *testing.T, fn string, level int, dict []byte) { var b0 []byte var err error if fn != "" { - b0, err = ioutil.ReadFile(fn) + b0, err = os.ReadFile(fn) if err != nil { t.Errorf("%s (level=%d): %v", fn, level, err) return diff --git a/libgo/go/crypto/cipher/xor_arm64.go b/libgo/go/crypto/cipher/xor_arm64.go new file mode 100644 index 00000000000..762e4861989 --- /dev/null +++ b/libgo/go/crypto/cipher/xor_arm64.go @@ -0,0 +1,31 @@ +// Copyright 2020 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 cipher + +// xorBytes xors the bytes in a and b. The destination should have enough +// space, otherwise xorBytes will panic. Returns the number of bytes xor'd. +func xorBytes(dst, a, b []byte) int { + n := len(a) + if len(b) < n { + n = len(b) + } + if n == 0 { + return 0 + } + // make sure dst has enough space + _ = dst[n-1] + + xorBytesARM64(&dst[0], &a[0], &b[0], n) + return n +} + +func xorWords(dst, a, b []byte) { + xorBytes(dst, a, b) +} + +//go:noescape +func xorBytesARM64(dst, a, b *byte, n int) diff --git a/libgo/go/crypto/cipher/xor_generic.go b/libgo/go/crypto/cipher/xor_generic.go index 86abbb744ae..b80a1b90f56 100644 --- a/libgo/go/crypto/cipher/xor_generic.go +++ b/libgo/go/crypto/cipher/xor_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,!ppc64,!ppc64le +// -build !amd64,!ppc64,!ppc64le,!arm64 package cipher diff --git a/libgo/go/crypto/des/block.go b/libgo/go/crypto/des/block.go index 3e3fe06c023..cc2888e2c76 100644 --- a/libgo/go/crypto/des/block.go +++ b/libgo/go/crypto/des/block.go @@ -127,7 +127,7 @@ func permuteInitialBlock(block uint64) uint64 { b2 = (block & 0xff00ff00) block ^= b1<<32 ^ b2 ^ b1<<8 ^ b2<<24 // exchange b0 b4 with b3 b7 - // block is now b1 b3 b5 b7 b0 b2 b4 b7, the permutation: + // block is now b1 b3 b5 b7 b0 b2 b4 b6, the permutation: // ... 8 // ... 24 // ... 40 diff --git a/libgo/go/crypto/dsa/dsa.go b/libgo/go/crypto/dsa/dsa.go index 43826bcb559..a83359996dc 100644 --- a/libgo/go/crypto/dsa/dsa.go +++ b/libgo/go/crypto/dsa/dsa.go @@ -5,6 +5,12 @@ // Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3. // // The DSA operations in this package are not implemented using constant-time algorithms. +// +// Deprecated: DSA is a legacy algorithm, and modern alternatives such as +// Ed25519 (implemented by package crypto/ed25519) should be used instead. Keys +// with 1024-bit moduli (L1024N160 parameters) are cryptographically weak, while +// bigger keys are not widely supported. Note that FIPS 186-5 no longer approves +// DSA for signature generation. package dsa import ( diff --git a/libgo/go/crypto/ecdsa/ecdsa_s390x.go b/libgo/go/crypto/ecdsa/ecdsa_s390x.go index dcbbef32c71..de51cabb6d7 100644 --- a/libgo/go/crypto/ecdsa/ecdsa_s390x.go +++ b/libgo/go/crypto/ecdsa/ecdsa_s390x.go @@ -43,26 +43,29 @@ func canUseKDSA(c elliptic.Curve) (functionCode uint64, blockSize int, ok bool) return 0, 0, false // A mismatch } -// 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 +func hashToBytes(dst, hash []byte, c elliptic.Curve) { + l := len(dst) + if n := c.Params().N.BitLen(); n == l*8 { + // allocation free path for curves with a length that is a whole number of bytes + if len(hash) >= l { + // truncate hash + copy(dst, hash[:l]) + return + } + // pad hash with leading zeros + p := l - len(hash) + for i := 0; i < p; i++ { + dst[i] = 0 + } + copy(dst[p:], hash) + return } - copy(dst[nz:size], src[:size-nz]) - return + // TODO(mundaym): avoid hashToInt call here + hashToInt(hash, c).FillBytes(dst) } func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash []byte) (r, s *big.Int, err error) { if functionCode, blockSize, ok := canUseKDSA(c); ok { - e := hashToInt(hash, c) for { var k *big.Int k, err = randFieldElement(c, *csprng) @@ -91,17 +94,12 @@ func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash // different curves and is set by canUseKDSA function. var params [4096]byte - startingOffset := 2 * blockSize // Set the starting location for copying // Copy content into the parameter block. In the sign case, // we copy hashed message, private key and random number into - // the parameter block. Since those are consecutive components in the parameter - // block, we use a for loop here. - for i, v := range []*big.Int{e, priv.D, k} { - startPosition := startingOffset + i*blockSize - endPosition := startPosition + blockSize - zeroExtendAndCopy(params[startPosition:endPosition], v.Bytes(), blockSize) - } - + // the parameter block. + hashToBytes(params[2*blockSize:3*blockSize], hash, c) + priv.D.FillBytes(params[3*blockSize : 4*blockSize]) + k.FillBytes(params[4*blockSize : 5*blockSize]) // Convert verify function code into a sign function code by adding 8. // We also need to set the 'deterministic' bit in the function code, by // adding 128, in order to stop the instruction using its own random number @@ -126,7 +124,6 @@ func sign(priv *PrivateKey, csprng *cipher.StreamReader, c elliptic.Curve, hash func verify(pub *PublicKey, c elliptic.Curve, hash []byte, r, s *big.Int) bool { if functionCode, blockSize, ok := canUseKDSA(c); ok { - e := hashToInt(hash, c) // The parameter block looks like the following for verify: // +---------------------+ // | Signature(R) | @@ -151,13 +148,11 @@ func verify(pub *PublicKey, c elliptic.Curve, hash []byte, r, s *big.Int) bool { // Copy content into the parameter block. In the verify case, // we copy signature (r), signature(s), hashed message, public key x component, // and public key y component into the parameter block. - // Since those are consecutive components in the parameter block, we use a for loop here. - for i, v := range []*big.Int{r, s, e, pub.X, pub.Y} { - startPosition := i * blockSize - endPosition := startPosition + blockSize - zeroExtendAndCopy(params[startPosition:endPosition], v.Bytes(), blockSize) - } - + r.FillBytes(params[0*blockSize : 1*blockSize]) + s.FillBytes(params[1*blockSize : 2*blockSize]) + hashToBytes(params[2*blockSize:3*blockSize], hash, c) + pub.X.FillBytes(params[3*blockSize : 4*blockSize]) + pub.Y.FillBytes(params[4*blockSize : 5*blockSize]) return kdsa(functionCode, ¶ms) == 0 } return verifyGeneric(pub, c, hash, r, s) diff --git a/libgo/go/crypto/ed25519/internal/edwards25519/edwards25519.go b/libgo/go/crypto/ed25519/internal/edwards25519/edwards25519.go index fd03c252af4..b091481b773 100644 --- a/libgo/go/crypto/ed25519/internal/edwards25519/edwards25519.go +++ b/libgo/go/crypto/ed25519/internal/edwards25519/edwards25519.go @@ -722,7 +722,7 @@ func (p *ExtendedGroupElement) FromBytes(s *[32]byte) bool { FeOne(&p.Z) FeSquare(&u, &p.Y) FeMul(&v, &u, &d) - FeSub(&u, &u, &p.Z) // y = y^2-1 + FeSub(&u, &u, &p.Z) // u = y^2-1 FeAdd(&v, &v, &p.Z) // v = dy^2+1 FeSquare(&v3, &v) diff --git a/libgo/go/crypto/hmac/hmac.go b/libgo/go/crypto/hmac/hmac.go index a6ba71c2756..cdda33c2cba 100644 --- a/libgo/go/crypto/hmac/hmac.go +++ b/libgo/go/crypto/hmac/hmac.go @@ -120,6 +120,8 @@ func (h *hmac) Reset() { } // New returns a new HMAC hash using the given hash.Hash type and key. +// New functions like sha256.New from crypto/sha256 can be used as h. +// h must return a new Hash every time it is called. // Note that unlike other hash implementations in the standard library, // the returned Hash does not implement encoding.BinaryMarshaler // or encoding.BinaryUnmarshaler. @@ -127,6 +129,19 @@ func New(h func() hash.Hash, key []byte) hash.Hash { hm := new(hmac) hm.outer = h() hm.inner = h() + unique := true + func() { + defer func() { + // The comparison might panic if the underlying types are not comparable. + _ = recover() + }() + if hm.outer == hm.inner { + unique = false + } + }() + if !unique { + panic("crypto/hmac: hash generation function does not produce unique values") + } blocksize := hm.inner.BlockSize() hm.ipad = make([]byte, blocksize) hm.opad = make([]byte, blocksize) diff --git a/libgo/go/crypto/hmac/hmac_test.go b/libgo/go/crypto/hmac/hmac_test.go index 453bfb3b7fd..25e67d7fe53 100644 --- a/libgo/go/crypto/hmac/hmac_test.go +++ b/libgo/go/crypto/hmac/hmac_test.go @@ -556,6 +556,17 @@ func TestHMAC(t *testing.T) { } } +func TestNonUniqueHash(t *testing.T) { + sha := sha256.New() + defer func() { + err := recover() + if err == nil { + t.Error("expected panic when calling New with a non-unique hash generation function") + } + }() + New(func() hash.Hash { return sha }, []byte("bytes")) +} + // justHash implements just the hash.Hash methods and nothing else type justHash struct { hash.Hash @@ -587,8 +598,8 @@ func BenchmarkHMACSHA256_1K(b *testing.B) { b.SetBytes(int64(len(buf))) for i := 0; i < b.N; i++ { h.Write(buf) - h.Reset() mac := h.Sum(nil) + h.Reset() buf[0] = mac[0] } } @@ -600,7 +611,18 @@ func BenchmarkHMACSHA256_32(b *testing.B) { b.SetBytes(int64(len(buf))) for i := 0; i < b.N; i++ { h.Write(buf) + mac := h.Sum(nil) h.Reset() + buf[0] = mac[0] + } +} + +func BenchmarkNewWriteSum(b *testing.B) { + buf := make([]byte, 32) + b.SetBytes(int64(len(buf))) + for i := 0; i < b.N; i++ { + h := New(sha256.New, make([]byte, 32)) + h.Write(buf) mac := h.Sum(nil) buf[0] = mac[0] } diff --git a/libgo/go/crypto/md5/gen.go b/libgo/go/crypto/md5/gen.go index a11f22059fa..1468924cbc0 100644 --- a/libgo/go/crypto/md5/gen.go +++ b/libgo/go/crypto/md5/gen.go @@ -15,8 +15,8 @@ import ( "bytes" "flag" "go/format" - "io/ioutil" "log" + "os" "strings" "text/template" ) @@ -37,7 +37,7 @@ func main() { if err != nil { log.Fatal(err) } - err = ioutil.WriteFile(*filename, data, 0644) + err = os.WriteFile(*filename, data, 0644) if err != nil { log.Fatal(err) } diff --git a/libgo/go/crypto/rand/eagain.go b/libgo/go/crypto/rand/eagain.go index fbe7475edc1..360b215d9a9 100644 --- a/libgo/go/crypto/rand/eagain.go +++ b/libgo/go/crypto/rand/eagain.go @@ -7,7 +7,7 @@ package rand import ( - "os" + "io/fs" "syscall" ) @@ -18,7 +18,7 @@ func init() { // unixIsEAGAIN reports whether err is a syscall.EAGAIN wrapped in a PathError. // See golang.org/issue/9205 func unixIsEAGAIN(err error) bool { - if pe, ok := err.(*os.PathError); ok { + if pe, ok := err.(*fs.PathError); ok { if errno, ok := pe.Err.(syscall.Errno); ok && errno == syscall.EAGAIN { return true } diff --git a/libgo/go/crypto/rand/rand.go b/libgo/go/crypto/rand/rand.go index a5ccd19de32..fddd1147e6e 100644 --- a/libgo/go/crypto/rand/rand.go +++ b/libgo/go/crypto/rand/rand.go @@ -14,7 +14,7 @@ import "io" // On Linux and FreeBSD, Reader uses getrandom(2) if available, /dev/urandom otherwise. // On OpenBSD, Reader uses getentropy(2). // On other Unix-like systems, Reader reads from /dev/urandom. -// On Windows systems, Reader uses the CryptGenRandom API. +// On Windows systems, Reader uses the RtlGenRandom API. // On Wasm, Reader uses the Web Crypto API. var Reader io.Reader @@ -23,7 +23,3 @@ var Reader io.Reader func Read(b []byte) (n int, err error) { return io.ReadFull(Reader, b) } - -func warnBlocked() { - println("crypto/rand: blocked for 60 seconds waiting to read random data from the kernel") -} diff --git a/libgo/go/crypto/rand/rand_unix.go b/libgo/go/crypto/rand/rand_unix.go index 9c7023af69d..9ff4d35844e 100644 --- a/libgo/go/crypto/rand/rand_unix.go +++ b/libgo/go/crypto/rand/rand_unix.go @@ -47,6 +47,10 @@ type devReader struct { // urandom-style randomness. var altGetRandom func([]byte) (ok bool) +func warnBlocked() { + println("crypto/rand: blocked for 60 seconds waiting to read random data from the kernel") +} + func (r *devReader) Read(b []byte) (n int, err error) { if atomic.CompareAndSwapInt32(&r.used, 0, 1) { // First use of randomness. Start timer to warn about diff --git a/libgo/go/crypto/rand/rand_windows.go b/libgo/go/crypto/rand/rand_windows.go index 78a4ed6d67b..8b2c960906a 100644 --- a/libgo/go/crypto/rand/rand_windows.go +++ b/libgo/go/crypto/rand/rand_windows.go @@ -9,48 +9,24 @@ package rand import ( "os" - "sync" - "sync/atomic" "syscall" - "time" ) -// Implemented by using Windows CryptoAPI 2.0. - func init() { Reader = &rngReader{} } -// A rngReader satisfies reads by reading from the Windows CryptGenRandom API. -type rngReader struct { - used int32 // atomic; whether this rngReader has been used - prov syscall.Handle - mu sync.Mutex -} +type rngReader struct{} func (r *rngReader) Read(b []byte) (n int, err error) { - if atomic.CompareAndSwapInt32(&r.used, 0, 1) { - // First use of randomness. Start timer to warn about - // being blocked on entropy not being available. - t := time.AfterFunc(60*time.Second, warnBlocked) - defer t.Stop() - } - r.mu.Lock() - if r.prov == 0 { - const provType = syscall.PROV_RSA_FULL - const flags = syscall.CRYPT_VERIFYCONTEXT | syscall.CRYPT_SILENT - err := syscall.CryptAcquireContext(&r.prov, nil, nil, provType, flags) - if err != nil { - r.mu.Unlock() - return 0, os.NewSyscallError("CryptAcquireContext", err) - } - } - r.mu.Unlock() + // RtlGenRandom only accepts 2**32-1 bytes at a time, so truncate. + inputLen := uint32(len(b)) - if len(b) == 0 { + if inputLen == 0 { return 0, nil } - err = syscall.CryptGenRandom(r.prov, uint32(len(b)), &b[0]) + + err = syscall.RtlGenRandom(&b[0], inputLen) if err != nil { - return 0, os.NewSyscallError("CryptGenRandom", err) + return 0, os.NewSyscallError("RtlGenRandom", err) } - return len(b), nil + return int(inputLen), nil } diff --git a/libgo/go/crypto/tls/cipher_suites.go b/libgo/go/crypto/tls/cipher_suites.go index ea16ef95bf0..9a356758fbf 100644 --- a/libgo/go/crypto/tls/cipher_suites.go +++ b/libgo/go/crypto/tls/cipher_suites.go @@ -160,7 +160,7 @@ type cipherSuite struct { // flags is a bitmask of the suite* values, above. flags int cipher func(key, iv []byte, isRead bool) interface{} - mac func(version uint16, macKey []byte) macFunction + mac func(key []byte) hash.Hash aead func(key, fixedNonce []byte) aead } @@ -247,24 +247,15 @@ func cipherAES(key, iv []byte, isRead bool) interface{} { return cipher.NewCBCEncrypter(block, iv) } -// macSHA1 returns a macFunction for the given protocol version. -func macSHA1(version uint16, key []byte) macFunction { - return tls10MAC{h: hmac.New(newConstantTimeHash(sha1.New), key)} +// macSHA1 returns a SHA-1 based constant time MAC. +func macSHA1(key []byte) hash.Hash { + return hmac.New(newConstantTimeHash(sha1.New), key) } -// macSHA256 returns a SHA-256 based MAC. These are only supported in TLS 1.2 -// so the given version is ignored. -func macSHA256(version uint16, key []byte) macFunction { - return tls10MAC{h: hmac.New(sha256.New, key)} -} - -type macFunction interface { - // Size returns the length of the MAC. - Size() int - // MAC appends the MAC of (seq, header, data) to out. The extra data is fed - // into the MAC after obtaining the result to normalize timing. The result - // is only valid until the next invocation of MAC as the buffer is reused. - MAC(seq, header, data, extra []byte) []byte +// macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and +// is currently only used in disabled-by-default cipher suites. +func macSHA256(key []byte) hash.Hash { + return hmac.New(sha256.New, key) } type aead interface { @@ -412,26 +403,14 @@ func newConstantTimeHash(h func() hash.Hash) func() hash.Hash { } // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3. -type tls10MAC struct { - h hash.Hash - buf []byte -} - -func (s tls10MAC) Size() int { - return s.h.Size() -} - -// MAC is guaranteed to take constant time, as long as -// len(seq)+len(header)+len(data)+len(extra) is constant. extra is not fed into -// the MAC, but is only provided to make the timing profile constant. -func (s tls10MAC) MAC(seq, header, data, extra []byte) []byte { - s.h.Reset() - s.h.Write(seq) - s.h.Write(header) - s.h.Write(data) - res := s.h.Sum(s.buf[:0]) +func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte { + h.Reset() + h.Write(seq) + h.Write(header) + h.Write(data) + res := h.Sum(out) if extra != nil { - s.h.Write(extra) + h.Write(extra) } return res } diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go index e8d009137ac..5b68742975c 100644 --- a/libgo/go/crypto/tls/common.go +++ b/libgo/go/crypto/tls/common.go @@ -7,6 +7,7 @@ package tls import ( "bytes" "container/list" + "context" "crypto" "crypto/ecdsa" "crypto/ed25519" @@ -20,6 +21,8 @@ import ( "internal/cpu" "io" "net" + "runtime" + "sort" "strings" "sync" "time" @@ -228,9 +231,6 @@ type ConnectionState struct { CipherSuite uint16 // NegotiatedProtocol is the application protocol negotiated with ALPN. - // - // Note that on the client side, this is currently not guaranteed to be from - // Config.NextProtos. NegotiatedProtocol string // NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation. @@ -294,10 +294,26 @@ func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, le type ClientAuthType int const ( + // NoClientCert indicates that no client certificate should be requested + // during the handshake, and if any certificates are sent they will not + // be verified. NoClientCert ClientAuthType = iota + // RequestClientCert indicates that a client certificate should be requested + // during the handshake, but does not require that the client send any + // certificates. RequestClientCert + // RequireAnyClientCert indicates that a client certificate should be requested + // during the handshake, and that at least one certificate is required to be + // sent by the client, but that certificate is not required to be valid. RequireAnyClientCert + // VerifyClientCertIfGiven indicates that a client certificate should be requested + // during the handshake, but does not require that the client sends a + // certificate. If the client does send a certificate it is required to be + // valid. VerifyClientCertIfGiven + // RequireAndVerifyClientCert indicates that a client certificate should be requested + // during the handshake, and that at least one valid certificate is required + // to be sent by the client. RequireAndVerifyClientCert ) @@ -428,6 +444,16 @@ type ClientHelloInfo struct { // config is embedded by the GetCertificate or GetConfigForClient caller, // for use with SupportsCertificate. config *Config + + // ctx is the context of the handshake that is in progress. + ctx context.Context +} + +// Context returns the context of the handshake that is in progress. +// This context is a child of the context passed to HandshakeContext, +// if any, and is canceled when the handshake concludes. +func (c *ClientHelloInfo) Context() context.Context { + return c.ctx } // CertificateRequestInfo contains information from a server's @@ -446,6 +472,16 @@ type CertificateRequestInfo struct { // Version is the TLS version that was negotiated for this connection. Version uint16 + + // ctx is the context of the handshake that is in progress. + ctx context.Context +} + +// Context returns the context of the handshake that is in progress. +// This context is a child of the context passed to HandshakeContext, +// if any, and is canceled when the handshake concludes. +func (c *CertificateRequestInfo) Context() context.Context { + return c.ctx } // RenegotiationSupport enumerates the different levels of support for TLS @@ -727,9 +763,12 @@ func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) { // ticket, and the lifetime we set for tickets we send. const maxSessionTicketLifetime = 7 * 24 * time.Hour -// Clone returns a shallow clone of c. It is safe to clone a Config that is +// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is // being used concurrently by a TLS client or server. func (c *Config) Clone() *Config { + if c == nil { + return nil + } c.mutex.RLock() defer c.mutex.RUnlock() return &Config{ @@ -1244,7 +1283,9 @@ func (c *Config) BuildNameToCertificate() { if err != nil { continue } - if len(x509Cert.Subject.CommonName) > 0 { + // If SANs are *not* present, some clients will consider the certificate + // valid for the name in the Common Name. + if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 { c.NameToCertificate[x509Cert.Subject.CommonName] = cert } for _, san := range x509Cert.DNSNames { @@ -1415,21 +1456,21 @@ func defaultCipherSuitesTLS13() []uint16 { return varDefaultCipherSuitesTLS13 } +var ( + hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ + hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL + // Keep in sync with crypto/aes/cipher_s390x.go. + hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) + + hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 || + runtime.GOARCH == "arm64" && hasGCMAsmARM64 || + runtime.GOARCH == "s390x" && hasGCMAsmS390X +) + func initDefaultCipherSuites() { var topCipherSuites []uint16 - // Check the cpu flags for each platform that has optimized GCM implementations. - // Worst case, these variables will just all be false. - var ( - hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ - hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL - // Keep in sync with crypto/aes/cipher_s390x.go. - hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) - - hasGCMAsm = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X - ) - - if hasGCMAsm { + if hasAESGCMHardwareSupport { // If AES-GCM hardware is provided then prioritise AES-GCM // cipher suites. topCipherSuites = []uint16{ @@ -1492,3 +1533,51 @@ func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlg } return false } + +var aesgcmCiphers = map[uint16]bool{ + // 1.2 + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true, + // 1.3 + TLS_AES_128_GCM_SHA256: true, + TLS_AES_256_GCM_SHA384: true, +} + +var nonAESGCMAEADCiphers = map[uint16]bool{ + // 1.2 + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: true, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true, + // 1.3 + TLS_CHACHA20_POLY1305_SHA256: true, +} + +// aesgcmPreferred returns whether the first valid cipher in the preference list +// is an AES-GCM cipher, implying the peer has hardware support for it. +func aesgcmPreferred(ciphers []uint16) bool { + for _, cID := range ciphers { + c := cipherSuiteByID(cID) + if c == nil { + c13 := cipherSuiteTLS13ByID(cID) + if c13 == nil { + continue + } + return aesgcmCiphers[cID] + } + return aesgcmCiphers[cID] + } + return false +} + +// deprioritizeAES reorders cipher preference lists by rearranging +// adjacent AEAD ciphers such that AES-GCM based ciphers are moved +// after other AEAD ciphers. It returns a fresh slice. +func deprioritizeAES(ciphers []uint16) []uint16 { + reordered := make([]uint16, len(ciphers)) + copy(reordered, ciphers) + sort.SliceStable(reordered, func(i, j int) bool { + return nonAESGCMAEADCiphers[reordered[i]] && aesgcmCiphers[reordered[j]] + }) + return reordered +} diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go index edcfecf81d7..969f357834c 100644 --- a/libgo/go/crypto/tls/conn.go +++ b/libgo/go/crypto/tls/conn.go @@ -8,11 +8,13 @@ package tls import ( "bytes" + "context" "crypto/cipher" "crypto/subtle" "crypto/x509" "errors" "fmt" + "hash" "io" "net" "sync" @@ -26,7 +28,7 @@ type Conn struct { // constant conn net.Conn isClient bool - handshakeFn func() error // (*Conn).clientHandshake or serverHandshake + handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake // handshakeStatus is 1 if the connection is currently transferring // application data (i.e. is not currently processing a handshake). @@ -86,15 +88,14 @@ type Conn struct { clientFinished [12]byte serverFinished [12]byte - clientProtocol string - clientProtocolFallback bool + // clientProtocol is the negotiated ALPN protocol. + clientProtocol string // input/output in, out halfConn rawInput bytes.Buffer // raw input, starting with a record header input bytes.Reader // application data waiting to be read, from rawInput.Next hand bytes.Buffer // handshake data waiting to be read - outBuf []byte // scratch buffer used by out.encrypt buffering bool // whether records are buffered in sendBuf sendBuf []byte // a buffer of records waiting to be sent @@ -155,31 +156,32 @@ func (c *Conn) SetWriteDeadline(t time.Time) error { type halfConn struct { sync.Mutex - err error // first permanent error - version uint16 // protocol version - cipher interface{} // cipher algorithm - mac macFunction - seq [8]byte // 64-bit sequence number - additionalData [13]byte // to avoid allocs; interface method args escape + err error // first permanent error + version uint16 // protocol version + cipher interface{} // cipher algorithm + mac hash.Hash + seq [8]byte // 64-bit sequence number + + scratchBuf [13]byte // to avoid allocs; interface method args escape nextCipher interface{} // next encryption state - nextMac macFunction // next MAC algorithm + nextMac hash.Hash // next MAC algorithm trafficSecret []byte // current TLS 1.3 traffic secret } -type permamentError struct { +type permanentError struct { err net.Error } -func (e *permamentError) Error() string { return e.err.Error() } -func (e *permamentError) Unwrap() error { return e.err } -func (e *permamentError) Timeout() bool { return e.err.Timeout() } -func (e *permamentError) Temporary() bool { return false } +func (e *permanentError) Error() string { return e.err.Error() } +func (e *permanentError) Unwrap() error { return e.err } +func (e *permanentError) Timeout() bool { return e.err.Timeout() } +func (e *permanentError) Temporary() bool { return false } func (hc *halfConn) setErrorLocked(err error) error { if e, ok := err.(net.Error); ok { - hc.err = &permamentError{err: e} + hc.err = &permanentError{err: e} } else { hc.err = err } @@ -188,7 +190,7 @@ func (hc *halfConn) setErrorLocked(err error) error { // prepareCipherSpec sets the encryption and MAC states // that a subsequent changeCipherSpec will use. -func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) { +func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac hash.Hash) { hc.version = version hc.nextCipher = cipher hc.nextMac = mac @@ -350,15 +352,14 @@ func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) { } payload = payload[explicitNonceLen:] - additionalData := hc.additionalData[:] + var additionalData []byte if hc.version == VersionTLS13 { additionalData = record[:recordHeaderLen] } else { - copy(additionalData, hc.seq[:]) - copy(additionalData[8:], record[:3]) + additionalData = append(hc.scratchBuf[:0], hc.seq[:]...) + additionalData = append(additionalData, record[:3]...) n := len(payload) - c.Overhead() - additionalData[11] = byte(n >> 8) - additionalData[12] = byte(n) + additionalData = append(additionalData, byte(n>>8), byte(n)) } var err error @@ -424,7 +425,7 @@ func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) { record[3] = byte(n >> 8) record[4] = byte(n) remoteMAC := payload[n : n+macSize] - localMAC := hc.mac.MAC(hc.seq[0:], record[:recordHeaderLen], payload[:n], payload[n+macSize:]) + localMAC := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload[:n], payload[n+macSize:]) // This is equivalent to checking the MACs and paddingGood // separately, but in constant-time to prevent distinguishing @@ -460,7 +461,7 @@ func sliceForAppend(in []byte, n int) (head, tail []byte) { } // encrypt encrypts payload, adding the appropriate nonce and/or MAC, and -// appends it to record, which contains the record header. +// appends it to record, which must already contain the record header. func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) { if hc.cipher == nil { return append(record, payload...), nil @@ -477,7 +478,7 @@ func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, err // an 8 bytes nonce but its nonces must be unpredictable (see RFC // 5246, Appendix F.3), forcing us to use randomness. That's not // 3DES' biggest problem anyway because the birthday bound on block - // collision is reached first due to its simlarly small block size + // collision is reached first due to its similarly small block size // (see the Sweet32 attack). copy(explicitNonce, hc.seq[:]) } else { @@ -487,14 +488,10 @@ func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, err } } - var mac []byte - if hc.mac != nil { - mac = hc.mac.MAC(hc.seq[:], record[:recordHeaderLen], payload, nil) - } - var dst []byte switch c := hc.cipher.(type) { case cipher.Stream: + mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil) record, dst = sliceForAppend(record, len(payload)+len(mac)) c.XORKeyStream(dst[:len(payload)], payload) c.XORKeyStream(dst[len(payload):], mac) @@ -518,11 +515,12 @@ func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, err record = c.Seal(record[:recordHeaderLen], nonce, record[recordHeaderLen:], record[:recordHeaderLen]) } else { - copy(hc.additionalData[:], hc.seq[:]) - copy(hc.additionalData[8:], record) - record = c.Seal(record, nonce, payload, hc.additionalData[:]) + additionalData := append(hc.scratchBuf[:0], hc.seq[:]...) + additionalData = append(additionalData, record[:recordHeaderLen]...) + record = c.Seal(record, nonce, payload, additionalData) } case cbcMode: + mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil) blockSize := c.BlockSize() plaintextLen := len(payload) + len(mac) paddingLen := blockSize - plaintextLen%blockSize @@ -928,9 +926,28 @@ func (c *Conn) flush() (int, error) { return n, err } +// outBufPool pools the record-sized scratch buffers used by writeRecordLocked. +var outBufPool = sync.Pool{ + New: func() interface{} { + return new([]byte) + }, +} + // writeRecordLocked writes a TLS record with the given type and payload to the // connection and updates the record layer state. func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) { + outBufPtr := outBufPool.Get().(*[]byte) + outBuf := *outBufPtr + defer func() { + // You might be tempted to simplify this by just passing &outBuf to Put, + // but that would make the local copy of the outBuf slice header escape + // to the heap, causing an allocation. Instead, we keep around the + // pointer to the slice header returned by Get, which is already on the + // heap, and overwrite and return that. + *outBufPtr = outBuf + outBufPool.Put(outBufPtr) + }() + var n int for len(data) > 0 { m := len(data) @@ -938,8 +955,8 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) { m = maxPayload } - _, c.outBuf = sliceForAppend(c.outBuf[:0], recordHeaderLen) - c.outBuf[0] = byte(typ) + _, outBuf = sliceForAppend(outBuf[:0], recordHeaderLen) + outBuf[0] = byte(typ) vers := c.vers if vers == 0 { // Some TLS servers fail if the record version is @@ -950,17 +967,17 @@ func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) { // See RFC 8446, Section 5.1. vers = VersionTLS12 } - c.outBuf[1] = byte(vers >> 8) - c.outBuf[2] = byte(vers) - c.outBuf[3] = byte(m >> 8) - c.outBuf[4] = byte(m) + outBuf[1] = byte(vers >> 8) + outBuf[2] = byte(vers) + outBuf[3] = byte(m >> 8) + outBuf[4] = byte(m) var err error - c.outBuf, err = c.out.encrypt(c.outBuf, data[:m], c.config.rand()) + outBuf, err = c.out.encrypt(outBuf, data[:m], c.config.rand()) if err != nil { return n, err } - if _, err := c.write(c.outBuf); err != nil { + if _, err := c.write(outBuf); err != nil { return n, err } n += m @@ -1070,17 +1087,21 @@ func (c *Conn) readHandshake() (interface{}, error) { } var ( - errClosed = errors.New("tls: use of closed connection") errShutdown = errors.New("tls: protocol is shutdown") ) // Write writes data to the connection. +// +// As Write calls Handshake, in order to prevent indefinite blocking a deadline +// must be set for both Read and Write before Write is called when the handshake +// has not yet completed. See SetDeadline, SetReadDeadline, and +// SetWriteDeadline. func (c *Conn) Write(b []byte) (int, error) { // interlock with Close below for { x := atomic.LoadInt32(&c.activeCall) if x&1 != 0 { - return 0, errClosed + return 0, net.ErrClosed } if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) { break @@ -1170,7 +1191,7 @@ func (c *Conn) handleRenegotiation() error { defer c.handshakeMutex.Unlock() atomic.StoreUint32(&c.handshakeStatus, 0) - if c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil { + if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil { c.handshakes++ } return c.handshakeErr @@ -1233,8 +1254,12 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error { return nil } -// Read can be made to time out and return a net.Error with Timeout() == true -// after a fixed time limit; see SetDeadline and SetReadDeadline. +// Read reads data from the connection. +// +// As Read calls Handshake, in order to prevent indefinite blocking a deadline +// must be set for both Read and Write before Read is called when the handshake +// has not yet completed. See SetDeadline, SetReadDeadline, and +// SetWriteDeadline. func (c *Conn) Read(b []byte) (int, error) { if err := c.Handshake(); err != nil { return 0, err @@ -1285,7 +1310,7 @@ func (c *Conn) Close() error { for { x = atomic.LoadInt32(&c.activeCall) if x&1 != 0 { - return errClosed + return net.ErrClosed } if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) { break @@ -1302,9 +1327,10 @@ func (c *Conn) Close() error { } var alertErr error - if c.handshakeComplete() { - alertErr = c.closeNotify() + if err := c.closeNotify(); err != nil { + alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err) + } } if err := c.conn.Close(); err != nil { @@ -1331,8 +1357,12 @@ func (c *Conn) closeNotify() error { defer c.out.Unlock() if !c.closeNotifySent { + // Set a Write Deadline to prevent possibly blocking forever. + c.SetWriteDeadline(time.Now().Add(time.Second * 5)) c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify) c.closeNotifySent = true + // Any subsequent writes will fail. + c.SetWriteDeadline(time.Now()) } return c.closeNotifyErr } @@ -1344,8 +1374,61 @@ func (c *Conn) closeNotify() error { // first Read or Write will call it automatically. // // For control over canceling or setting a timeout on a handshake, use -// the Dialer's DialContext method. +// HandshakeContext or the Dialer's DialContext method instead. func (c *Conn) Handshake() error { + return c.HandshakeContext(context.Background()) +} + +// HandshakeContext runs the client or server handshake +// protocol if it has not yet been run. +// +// The provided Context must be non-nil. If the context is canceled before +// the handshake is complete, the handshake is interrupted and an error is returned. +// Once the handshake has completed, cancellation of the context will not affect the +// connection. +// +// Most uses of this package need not call HandshakeContext explicitly: the +// first Read or Write will call it automatically. +func (c *Conn) HandshakeContext(ctx context.Context) error { + // Delegate to unexported method for named return + // without confusing documented signature. + return c.handshakeContext(ctx) +} + +func (c *Conn) handshakeContext(ctx context.Context) (ret error) { + handshakeCtx, cancel := context.WithCancel(ctx) + // Note: defer this before starting the "interrupter" goroutine + // so that we can tell the difference between the input being canceled and + // this cancellation. In the former case, we need to close the connection. + defer cancel() + + // Start the "interrupter" goroutine, if this context might be canceled. + // (The background context cannot). + // + // The interrupter goroutine waits for the input context to be done and + // closes the connection if this happens before the function returns. + if ctx.Done() != nil { + done := make(chan struct{}) + interruptRes := make(chan error, 1) + defer func() { + close(done) + if ctxErr := <-interruptRes; ctxErr != nil { + // Return context error to user. + ret = ctxErr + } + }() + go func() { + select { + case <-handshakeCtx.Done(): + // Close the connection, discarding the error + _ = c.conn.Close() + interruptRes <- handshakeCtx.Err() + case <-done: + interruptRes <- nil + } + }() + } + c.handshakeMutex.Lock() defer c.handshakeMutex.Unlock() @@ -1359,7 +1442,7 @@ func (c *Conn) Handshake() error { c.in.Lock() defer c.in.Unlock() - c.handshakeErr = c.handshakeFn() + c.handshakeErr = c.handshakeFn(handshakeCtx) if c.handshakeErr == nil { c.handshakes++ } else { @@ -1388,7 +1471,7 @@ func (c *Conn) connectionStateLocked() ConnectionState { state.Version = c.vers state.NegotiatedProtocol = c.clientProtocol state.DidResume = c.didResume - state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback + state.NegotiatedProtocolIsMutual = true state.ServerName = c.serverName state.CipherSuite = c.cipherSuite state.PeerCertificates = c.peerCertificates diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go index 46b0a770d53..92e33e71690 100644 --- a/libgo/go/crypto/tls/handshake_client.go +++ b/libgo/go/crypto/tls/handshake_client.go @@ -6,6 +6,7 @@ package tls import ( "bytes" + "context" "crypto" "crypto/ecdsa" "crypto/ed25519" @@ -14,6 +15,7 @@ import ( "crypto/x509" "errors" "fmt" + "hash" "io" "net" "strings" @@ -23,6 +25,7 @@ import ( type clientHandshakeState struct { c *Conn + ctx context.Context serverHello *serverHelloMsg hello *clientHelloMsg suite *cipherSuite @@ -133,7 +136,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) { return hello, params, nil } -func (c *Conn) clientHandshake() (err error) { +func (c *Conn) clientHandshake(ctx context.Context) (err error) { if c.config == nil { c.config = defaultConfig() } @@ -197,6 +200,7 @@ func (c *Conn) clientHandshake() (err error) { if c.vers == VersionTLS13 { hs := &clientHandshakeStateTLS13{ c: c, + ctx: ctx, serverHello: serverHello, hello: hello, ecdheParams: ecdheParams, @@ -211,6 +215,7 @@ func (c *Conn) clientHandshake() (err error) { hs := &clientHandshakeState{ c: c, + ctx: ctx, serverHello: serverHello, hello: hello, session: session, @@ -539,7 +544,7 @@ func (hs *clientHandshakeState) doFullHandshake() error { certRequested = true hs.finishedHash.Write(certReq.marshal()) - cri := certificateRequestInfoFromMsg(c.vers, certReq) + cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq) if chainToSend, err = c.getClientCertificate(cri); err != nil { c.sendAlert(alertInternalError) return err @@ -647,12 +652,12 @@ func (hs *clientHandshakeState) establishKeys() error { clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) var clientCipher, serverCipher interface{} - var clientHash, serverHash macFunction + var clientHash, serverHash hash.Hash if hs.suite.cipher != nil { clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */) - clientHash = hs.suite.mac(c.vers, clientMAC) + clientHash = hs.suite.mac(clientMAC) serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */) - serverHash = hs.suite.mac(c.vers, serverMAC) + serverHash = hs.suite.mac(serverMAC) } else { clientCipher = hs.suite.aead(clientKey, clientIV) serverCipher = hs.suite.aead(serverKey, serverIV) @@ -700,18 +705,18 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) { } } - clientDidALPN := len(hs.hello.alpnProtocols) > 0 - serverHasALPN := len(hs.serverHello.alpnProtocol) > 0 - - if !clientDidALPN && serverHasALPN { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: server advertised unrequested ALPN extension") - } - - if serverHasALPN { + if hs.serverHello.alpnProtocol != "" { + if len(hs.hello.alpnProtocols) == 0 { + c.sendAlert(alertUnsupportedExtension) + return false, errors.New("tls: server advertised unrequested ALPN extension") + } + if mutualProtocol([]string{hs.serverHello.alpnProtocol}, hs.hello.alpnProtocols) == "" { + c.sendAlert(alertUnsupportedExtension) + return false, errors.New("tls: server selected unadvertised ALPN protocol") + } c.clientProtocol = hs.serverHello.alpnProtocol - c.clientProtocolFallback = false } + c.scts = hs.serverHello.scts if !hs.serverResumedSession() { @@ -879,10 +884,11 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error { // certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS // <= 1.2 CertificateRequest, making an effort to fill in missing information. -func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo { +func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo { cri := &CertificateRequestInfo{ AcceptableCAs: certReq.certificateAuthorities, Version: vers, + ctx: ctx, } var rsaAvail, ecAvail bool @@ -967,20 +973,17 @@ func clientSessionCacheKey(serverAddr net.Addr, config *Config) string { return serverAddr.String() } -// mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol -// given list of possible protocols and a list of the preference order. The -// first list must not be empty. It returns the resulting protocol and flag -// indicating if the fallback case was reached. -func mutualProtocol(protos, preferenceProtos []string) (string, bool) { +// mutualProtocol finds the mutual ALPN protocol given list of possible +// protocols and a list of the preference order. +func mutualProtocol(protos, preferenceProtos []string) string { for _, s := range preferenceProtos { for _, c := range protos { if s == c { - return s, false + return s } } } - - return protos[0], true + return "" } // hostnameInSNI converts name into an appropriate hostname for SNI. diff --git a/libgo/go/crypto/tls/handshake_client_test.go b/libgo/go/crypto/tls/handshake_client_test.go index 12b0254123e..8889e2c8c33 100644 --- a/libgo/go/crypto/tls/handshake_client_test.go +++ b/libgo/go/crypto/tls/handshake_client_test.go @@ -6,6 +6,7 @@ package tls import ( "bytes" + "context" "crypto/rsa" "crypto/x509" "encoding/base64" @@ -20,6 +21,7 @@ import ( "os/exec" "path/filepath" "reflect" + "runtime" "strconv" "strings" "testing" @@ -2511,3 +2513,37 @@ func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) { serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps) } } + +func TestClientHandshakeContextCancellation(t *testing.T) { + c, s := localPipe(t) + serverConfig := testConfig.Clone() + serverErr := make(chan error, 1) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer close(serverErr) + defer s.Close() + conn := Server(s, serverConfig) + _, err := conn.readClientHello(ctx) + cancel() + serverErr <- err + }() + cli := Client(c, testConfig) + err := cli.HandshakeContext(ctx) + if err == nil { + t.Fatal("Client handshake did not error when the context was canceled") + } + if err != context.Canceled { + t.Errorf("Unexpected client handshake error: %v", err) + } + if err := <-serverErr; err != nil { + t.Errorf("Unexpected server error: %v", err) + } + if runtime.GOARCH == "wasm" { + t.Skip("conn.Close does not error as expected when called multiple times on WASM") + } + err = cli.Close() + if err == nil { + t.Error("Client connection was not closed when the context was canceled") + } +} diff --git a/libgo/go/crypto/tls/handshake_client_tls13.go b/libgo/go/crypto/tls/handshake_client_tls13.go index 9c61105cf73..be37c681c6d 100644 --- a/libgo/go/crypto/tls/handshake_client_tls13.go +++ b/libgo/go/crypto/tls/handshake_client_tls13.go @@ -6,6 +6,7 @@ package tls import ( "bytes" + "context" "crypto" "crypto/hmac" "crypto/rsa" @@ -17,6 +18,7 @@ import ( type clientHandshakeStateTLS13 struct { c *Conn + ctx context.Context serverHello *serverHelloMsg hello *clientHelloMsg ecdheParams ecdheParameters @@ -394,11 +396,17 @@ func (hs *clientHandshakeStateTLS13) readServerParameters() error { } hs.transcript.Write(encryptedExtensions.marshal()) - if len(encryptedExtensions.alpnProtocol) != 0 && len(hs.hello.alpnProtocols) == 0 { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: server advertised unrequested ALPN extension") + if encryptedExtensions.alpnProtocol != "" { + if len(hs.hello.alpnProtocols) == 0 { + c.sendAlert(alertUnsupportedExtension) + return errors.New("tls: server advertised unrequested ALPN extension") + } + if mutualProtocol([]string{encryptedExtensions.alpnProtocol}, hs.hello.alpnProtocols) == "" { + c.sendAlert(alertUnsupportedExtension) + return errors.New("tls: server selected unadvertised ALPN protocol") + } + c.clientProtocol = encryptedExtensions.alpnProtocol } - c.clientProtocol = encryptedExtensions.alpnProtocol return nil } @@ -549,6 +557,7 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { AcceptableCAs: hs.certReq.certificateAuthorities, SignatureSchemes: hs.certReq.supportedSignatureAlgorithms, Version: c.vers, + ctx: hs.ctx, }) if err != nil { return err diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go index 16d3e643f0b..5a572a9db10 100644 --- a/libgo/go/crypto/tls/handshake_server.go +++ b/libgo/go/crypto/tls/handshake_server.go @@ -5,6 +5,7 @@ package tls import ( + "context" "crypto" "crypto/ecdsa" "crypto/ed25519" @@ -13,6 +14,7 @@ import ( "crypto/x509" "errors" "fmt" + "hash" "io" "sync/atomic" "time" @@ -22,6 +24,7 @@ import ( // It's discarded once the handshake has completed. type serverHandshakeState struct { c *Conn + ctx context.Context clientHello *clientHelloMsg hello *serverHelloMsg suite *cipherSuite @@ -36,8 +39,8 @@ type serverHandshakeState struct { } // serverHandshake performs a TLS handshake as a server. -func (c *Conn) serverHandshake() error { - clientHello, err := c.readClientHello() +func (c *Conn) serverHandshake(ctx context.Context) error { + clientHello, err := c.readClientHello(ctx) if err != nil { return err } @@ -45,6 +48,7 @@ func (c *Conn) serverHandshake() error { if c.vers == VersionTLS13 { hs := serverHandshakeStateTLS13{ c: c, + ctx: ctx, clientHello: clientHello, } return hs.handshake() @@ -52,6 +56,7 @@ func (c *Conn) serverHandshake() error { hs := serverHandshakeState{ c: c, + ctx: ctx, clientHello: clientHello, } return hs.handshake() @@ -123,7 +128,7 @@ func (hs *serverHandshakeState) handshake() error { } // readClientHello reads a ClientHello message and selects the protocol version. -func (c *Conn) readClientHello() (*clientHelloMsg, error) { +func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) { msg, err := c.readHandshake() if err != nil { return nil, err @@ -137,7 +142,7 @@ func (c *Conn) readClientHello() (*clientHelloMsg, error) { var configForClient *Config originalConfig := c.config if c.config.GetConfigForClient != nil { - chi := clientHelloInfo(c, clientHello) + chi := clientHelloInfo(ctx, c, clientHello) if configForClient, err = c.config.GetConfigForClient(chi); err != nil { c.sendAlert(alertInternalError) return nil, err @@ -213,13 +218,13 @@ func (hs *serverHandshakeState) processClientHello() error { } if len(hs.clientHello.alpnProtocols) > 0 { - if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback { + if selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); selectedProto != "" { hs.hello.alpnProtocol = selectedProto c.clientProtocol = selectedProto } } - hs.cert, err = c.config.getCertificate(clientHelloInfo(c, hs.clientHello)) + hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello)) if err != nil { if err == errNoCertificates { c.sendAlert(alertUnrecognizedName) @@ -298,9 +303,23 @@ func (hs *serverHandshakeState) pickCipherSuite() error { if c.config.PreferServerCipherSuites { preferenceList = c.config.cipherSuites() supportedList = hs.clientHello.cipherSuites + + // If the client does not seem to have hardware support for AES-GCM, + // and the application did not specify a cipher suite preference order, + // prefer other AEAD ciphers even if we prioritized AES-GCM ciphers + // by default. + if c.config.CipherSuites == nil && !aesgcmPreferred(hs.clientHello.cipherSuites) { + preferenceList = deprioritizeAES(preferenceList) + } } else { preferenceList = hs.clientHello.cipherSuites supportedList = c.config.cipherSuites() + + // If we don't have hardware support for AES-GCM, prefer other AEAD + // ciphers even if the client prioritized AES-GCM. + if !hasAESGCMHardwareSupport { + preferenceList = deprioritizeAES(preferenceList) + } } hs.suite = selectCipherSuite(preferenceList, supportedList, hs.cipherSuiteOk) @@ -641,13 +660,13 @@ func (hs *serverHandshakeState) establishKeys() error { keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) var clientCipher, serverCipher interface{} - var clientHash, serverHash macFunction + var clientHash, serverHash hash.Hash if hs.suite.aead == nil { clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) - clientHash = hs.suite.mac(c.vers, clientMAC) + clientHash = hs.suite.mac(clientMAC) serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) - serverHash = hs.suite.mac(c.vers, serverMAC) + serverHash = hs.suite.mac(serverMAC) } else { clientCipher = hs.suite.aead(clientKey, clientIV) serverCipher = hs.suite.aead(serverKey, serverIV) @@ -813,7 +832,7 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error { return nil } -func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { +func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { supportedVersions := clientHello.supportedVersions if len(clientHello.supportedVersions) == 0 { supportedVersions = supportedVersionsFromMax(clientHello.vers) @@ -829,5 +848,6 @@ func clientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { SupportedVersions: supportedVersions, Conn: c.conn, config: c.config, + ctx: ctx, } } diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go index a7a53243129..ad851b6edf0 100644 --- a/libgo/go/crypto/tls/handshake_server_test.go +++ b/libgo/go/crypto/tls/handshake_server_test.go @@ -6,6 +6,7 @@ package tls import ( "bytes" + "context" "crypto" "crypto/elliptic" "crypto/x509" @@ -17,9 +18,12 @@ import ( "os" "os/exec" "path/filepath" + "runtime" "strings" "testing" "time" + + "golang.org/x/crypto/curve25519" ) func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) { @@ -36,10 +40,12 @@ func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessa cli.writeRecord(recordTypeHandshake, m.marshal()) c.Close() }() + ctx := context.Background() conn := Server(s, serverConfig) - ch, err := conn.readClientHello() + ch, err := conn.readClientHello(ctx) hs := serverHandshakeState{ c: conn, + ctx: ctx, clientHello: ch, } if err == nil { @@ -852,7 +858,7 @@ func TestHandshakeServerX25519(t *testing.T) { test := &serverTest{ name: "X25519", - command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256", "-curves", "X25519"}, + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519"}, config: config, } runServerTestTLS12(t, test) @@ -865,7 +871,7 @@ func TestHandshakeServerP256(t *testing.T) { test := &serverTest{ name: "P256", - command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256", "-curves", "P-256"}, + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "P-256"}, config: config, } runServerTestTLS12(t, test) @@ -878,7 +884,7 @@ func TestHandshakeServerHelloRetryRequest(t *testing.T) { test := &serverTest{ name: "HelloRetryRequest", - command: []string{"openssl", "s_client", "-no_ticket", "-curves", "X25519:P-256"}, + command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519:P-256"}, config: config, } runServerTestTLS13(t, test) @@ -892,7 +898,7 @@ func TestHandshakeServerALPN(t *testing.T) { name: "ALPN", // Note that this needs OpenSSL 1.0.2 because that is the first // version that supports the -alpn flag. - command: []string{"openssl", "s_client", "-alpn", "proto2,proto1"}, + command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, config: config, validate: func(state ConnectionState) error { // The server's preferences should override the client. @@ -914,7 +920,7 @@ func TestHandshakeServerALPNNoMatch(t *testing.T) { name: "ALPN-NoMatch", // Note that this needs OpenSSL 1.0.2 because that is the first // version that supports the -alpn flag. - command: []string{"openssl", "s_client", "-alpn", "proto2,proto1"}, + command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, config: config, validate: func(state ConnectionState) error { // Rather than reject the connection, Go doesn't select @@ -1067,12 +1073,12 @@ func TestServerResumption(t *testing.T) { testIssue := &serverTest{ name: "IssueTicket", - command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-sess_out", sessionFilePath}, + command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_out", sessionFilePath}, wait: true, } testResume := &serverTest{ name: "Resume", - command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-sess_in", sessionFilePath}, + command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath}, validate: func(state ConnectionState) error { if !state.DidResume { return errors.New("did not resume") @@ -1091,9 +1097,10 @@ func TestServerResumption(t *testing.T) { config.CurvePreferences = []CurveID{CurveP256} testResumeHRR := &serverTest{ - name: "Resume-HelloRetryRequest", - command: []string{"openssl", "s_client", "-curves", "X25519:P-256", "-sess_in", sessionFilePath}, - config: config, + name: "Resume-HelloRetryRequest", + command: []string{"openssl", "s_client", "-curves", "X25519:P-256", "-cipher", "AES128-SHA", "-ciphersuites", + "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath}, + config: config, validate: func(state ConnectionState) error { if !state.DidResume { return errors.New("did not resume") @@ -1113,13 +1120,13 @@ func TestServerResumptionDisabled(t *testing.T) { testIssue := &serverTest{ name: "IssueTicketPreDisable", - command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-sess_out", sessionFilePath}, + command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_out", sessionFilePath}, config: config, wait: true, } testResume := &serverTest{ name: "ResumeDisabled", - command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-sess_in", sessionFilePath}, + command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath}, config: config, validate: func(state ConnectionState) error { if state.DidResume { @@ -1157,7 +1164,7 @@ func TestFallbackSCSV(t *testing.T) { func TestHandshakeServerExportKeyingMaterial(t *testing.T) { test := &serverTest{ name: "ExportKeyingMaterial", - command: []string{"openssl", "s_client"}, + command: []string{"openssl", "s_client", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, config: testConfig.Clone(), validate: func(state ConnectionState) error { if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil { @@ -1176,7 +1183,7 @@ func TestHandshakeServerExportKeyingMaterial(t *testing.T) { func TestHandshakeServerRSAPKCS1v15(t *testing.T) { test := &serverTest{ name: "RSA-RSAPKCS1v15", - command: []string{"openssl", "s_client", "-no_ticket", "-sigalgs", "rsa_pkcs1_sha256"}, + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-sigalgs", "rsa_pkcs1_sha256"}, } runServerTestTLS12(t, test) } @@ -1187,14 +1194,14 @@ func TestHandshakeServerRSAPSS(t *testing.T) { // that case. See Issue 29793. test := &serverTest{ name: "RSA-RSAPSS", - command: []string{"openssl", "s_client", "-no_ticket", "-sigalgs", "rsa_pss_rsae_sha512:rsa_pss_rsae_sha256"}, + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-sigalgs", "rsa_pss_rsae_sha512:rsa_pss_rsae_sha256"}, } runServerTestTLS12(t, test) runServerTestTLS13(t, test) test = &serverTest{ name: "RSA-RSAPSS-TooSmall", - command: []string{"openssl", "s_client", "-no_ticket", "-sigalgs", "rsa_pss_rsae_sha512"}, + command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-sigalgs", "rsa_pss_rsae_sha512"}, expectHandshakeErrorIncluding: "peer doesn't support any of the certificate's signature algorithms", } runServerTestTLS13(t, test) @@ -1209,7 +1216,7 @@ func TestHandshakeServerEd25519(t *testing.T) { test := &serverTest{ name: "Ed25519", - command: []string{"openssl", "s_client", "-no_ticket"}, + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"}, config: config, } runServerTestTLS12(t, test) @@ -1349,7 +1356,7 @@ func TestClientAuth(t *testing.T) { test := &serverTest{ name: "ClientAuthRequestedNotGiven", - command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA"}, + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256"}, config: config, } runServerTestTLS12(t, test) @@ -1357,7 +1364,7 @@ func TestClientAuth(t *testing.T) { test = &serverTest{ name: "ClientAuthRequestedAndGiven", - command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-cert", certPath, "-key", keyPath, "-client_sigalgs", "rsa_pss_rsae_sha256"}, config: config, expectedPeerCerts: []string{clientCertificatePEM}, @@ -1367,7 +1374,7 @@ func TestClientAuth(t *testing.T) { test = &serverTest{ name: "ClientAuthRequestedAndECDSAGiven", - command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-cert", ecdsaCertPath, "-key", ecdsaKeyPath}, config: config, expectedPeerCerts: []string{clientECDSACertificatePEM}, @@ -1377,7 +1384,7 @@ func TestClientAuth(t *testing.T) { test = &serverTest{ name: "ClientAuthRequestedAndEd25519Given", - command: []string{"openssl", "s_client", "-no_ticket", + command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-cert", ed25519CertPath, "-key", ed25519KeyPath}, config: config, expectedPeerCerts: []string{clientEd25519CertificatePEM}, @@ -1418,9 +1425,11 @@ func TestSNIGivenOnFailure(t *testing.T) { c.Close() }() conn := Server(s, serverConfig) - ch, err := conn.readClientHello() + ctx := context.Background() + ch, err := conn.readClientHello(ctx) hs := serverHandshakeState{ c: conn, + ctx: ctx, clientHello: ch, } if err == nil { @@ -1673,3 +1682,306 @@ func TestMultipleCertificates(t *testing.T) { t.Errorf("expected RSA certificate, got %v", got) } } + +func TestServerHandshakeContextCancellation(t *testing.T) { + c, s := localPipe(t) + clientConfig := testConfig.Clone() + clientErr := make(chan error, 1) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + defer close(clientErr) + defer c.Close() + clientHello := &clientHelloMsg{ + vers: VersionTLS10, + random: make([]byte, 32), + cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA}, + compressionMethods: []uint8{compressionNone}, + } + cli := Client(c, clientConfig) + _, err := cli.writeRecord(recordTypeHandshake, clientHello.marshal()) + cancel() + clientErr <- err + }() + conn := Server(s, testConfig) + err := conn.HandshakeContext(ctx) + if err == nil { + t.Fatal("Server handshake did not error when the context was canceled") + } + if err != context.Canceled { + t.Errorf("Unexpected server handshake error: %v", err) + } + if err := <-clientErr; err != nil { + t.Errorf("Unexpected client error: %v", err) + } + if runtime.GOARCH == "wasm" { + t.Skip("conn.Close does not error as expected when called multiple times on WASM") + } + err = conn.Close() + if err == nil { + t.Error("Server connection was not closed when the context was canceled") + } +} + +func TestAESCipherReordering(t *testing.T) { + currentAESSupport := hasAESGCMHardwareSupport + defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }() + + tests := []struct { + name string + clientCiphers []uint16 + serverHasAESGCM bool + preferServerCipherSuites bool + serverCiphers []uint16 + expectedCipher uint16 + }{ + { + name: "server has hardware AES, client doesn't (pick ChaCha)", + clientCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA, + }, + serverHasAESGCM: true, + preferServerCipherSuites: true, + expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + }, + { + name: "server strongly prefers AES-GCM, client doesn't (pick AES-GCM)", + clientCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA, + }, + serverHasAESGCM: true, + preferServerCipherSuites: true, + serverCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_RSA_WITH_AES_128_CBC_SHA, + }, + expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + { + name: "client prefers AES-GCM, server doesn't have hardware AES (pick ChaCha)", + clientCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_RSA_WITH_AES_128_CBC_SHA, + }, + serverHasAESGCM: false, + expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + }, + { + name: "client prefers AES-GCM, server has hardware AES (pick AES-GCM)", + clientCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_RSA_WITH_AES_128_CBC_SHA, + }, + serverHasAESGCM: true, + expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + { + name: "client prefers AES-GCM and sends GREASE, server has hardware AES (pick AES-GCM)", + clientCiphers: []uint16{ + 0x0A0A, // GREASE value + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_RSA_WITH_AES_128_CBC_SHA, + }, + serverHasAESGCM: true, + expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + { + name: "client prefers AES-GCM and doesn't support ChaCha, server doesn't have hardware AES (pick AES-GCM)", + clientCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA, + }, + serverHasAESGCM: false, + expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + { + name: "client prefers AES-GCM and AES-CBC over ChaCha, server doesn't have hardware AES (pick AES-GCM)", + clientCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + }, + serverHasAESGCM: false, + expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + { + name: "client prefers AES-GCM over ChaCha and sends GREASE, server doesn't have hardware AES (pick ChaCha)", + clientCiphers: []uint16{ + 0x0A0A, // GREASE value + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_RSA_WITH_AES_128_CBC_SHA, + }, + serverHasAESGCM: false, + expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + }, + { + name: "client supports multiple AES-GCM, server doesn't have hardware AES and doesn't support ChaCha (pick corrent AES-GCM)", + clientCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + serverHasAESGCM: false, + serverCiphers: []uint16{ + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }, + expectedCipher: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + hasAESGCMHardwareSupport = tc.serverHasAESGCM + initDefaultCipherSuites() + hs := &serverHandshakeState{ + c: &Conn{ + config: &Config{ + PreferServerCipherSuites: tc.preferServerCipherSuites, + CipherSuites: tc.serverCiphers, + }, + vers: VersionTLS12, + }, + clientHello: &clientHelloMsg{ + cipherSuites: tc.clientCiphers, + vers: VersionTLS12, + }, + ecdheOk: true, + rsaSignOk: true, + rsaDecryptOk: true, + } + + err := hs.pickCipherSuite() + if err != nil { + t.Errorf("pickCipherSuite failed: %s", err) + } + + if tc.expectedCipher != hs.suite.id { + t.Errorf("unexpected cipher chosen: want %d, got %d", tc.expectedCipher, hs.suite.id) + } + }) + } +} + +func TestAESCipherReordering13(t *testing.T) { + currentAESSupport := hasAESGCMHardwareSupport + defer func() { hasAESGCMHardwareSupport = currentAESSupport; initDefaultCipherSuites() }() + + tests := []struct { + name string + clientCiphers []uint16 + serverHasAESGCM bool + preferServerCipherSuites bool + expectedCipher uint16 + }{ + { + name: "server has hardware AES, client doesn't (pick ChaCha)", + clientCiphers: []uint16{ + TLS_CHACHA20_POLY1305_SHA256, + TLS_AES_128_GCM_SHA256, + }, + serverHasAESGCM: true, + preferServerCipherSuites: true, + expectedCipher: TLS_CHACHA20_POLY1305_SHA256, + }, + { + name: "neither server nor client have hardware AES (pick ChaCha)", + clientCiphers: []uint16{ + TLS_CHACHA20_POLY1305_SHA256, + TLS_AES_128_GCM_SHA256, + }, + serverHasAESGCM: false, + preferServerCipherSuites: true, + expectedCipher: TLS_CHACHA20_POLY1305_SHA256, + }, + { + name: "client prefers AES, server doesn't have hardware, prefer server ciphers (pick ChaCha)", + clientCiphers: []uint16{ + TLS_AES_128_GCM_SHA256, + TLS_CHACHA20_POLY1305_SHA256, + }, + serverHasAESGCM: false, + preferServerCipherSuites: true, + expectedCipher: TLS_CHACHA20_POLY1305_SHA256, + }, + { + name: "client prefers AES and sends GREASE, server doesn't have hardware, prefer server ciphers (pick ChaCha)", + clientCiphers: []uint16{ + 0x0A0A, // GREASE value + TLS_AES_128_GCM_SHA256, + TLS_CHACHA20_POLY1305_SHA256, + }, + serverHasAESGCM: false, + preferServerCipherSuites: true, + expectedCipher: TLS_CHACHA20_POLY1305_SHA256, + }, + { + name: "client prefers AES, server doesn't (pick ChaCha)", + clientCiphers: []uint16{ + TLS_AES_128_GCM_SHA256, + TLS_CHACHA20_POLY1305_SHA256, + }, + serverHasAESGCM: false, + expectedCipher: TLS_CHACHA20_POLY1305_SHA256, + }, + { + name: "client prefers AES, server has hardware AES (pick AES)", + clientCiphers: []uint16{ + TLS_AES_128_GCM_SHA256, + TLS_CHACHA20_POLY1305_SHA256, + }, + serverHasAESGCM: true, + expectedCipher: TLS_AES_128_GCM_SHA256, + }, + { + name: "client prefers AES and sends GREASE, server has hardware AES (pick AES)", + clientCiphers: []uint16{ + 0x0A0A, // GREASE value + TLS_AES_128_GCM_SHA256, + TLS_CHACHA20_POLY1305_SHA256, + }, + serverHasAESGCM: true, + expectedCipher: TLS_AES_128_GCM_SHA256, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + hasAESGCMHardwareSupport = tc.serverHasAESGCM + initDefaultCipherSuites() + hs := &serverHandshakeStateTLS13{ + c: &Conn{ + config: &Config{ + PreferServerCipherSuites: tc.preferServerCipherSuites, + }, + vers: VersionTLS13, + }, + clientHello: &clientHelloMsg{ + cipherSuites: tc.clientCiphers, + supportedVersions: []uint16{VersionTLS13}, + compressionMethods: []uint8{compressionNone}, + keyShares: []keyShare{{group: X25519, data: curve25519.Basepoint}}, + }, + } + + err := hs.processClientHello() + if err != nil { + t.Errorf("pickCipherSuite failed: %s", err) + } + + if tc.expectedCipher != hs.suite.id { + t.Errorf("unexpected cipher chosen: want %d, got %d", tc.expectedCipher, hs.suite.id) + } + }) + } +} diff --git a/libgo/go/crypto/tls/handshake_server_tls13.go b/libgo/go/crypto/tls/handshake_server_tls13.go index 92d55e0293a..c7837d2955d 100644 --- a/libgo/go/crypto/tls/handshake_server_tls13.go +++ b/libgo/go/crypto/tls/handshake_server_tls13.go @@ -6,6 +6,7 @@ package tls import ( "bytes" + "context" "crypto" "crypto/hmac" "crypto/rsa" @@ -23,6 +24,7 @@ const maxClientPSKIdentities = 5 type serverHandshakeStateTLS13 struct { c *Conn + ctx context.Context clientHello *clientHelloMsg hello *serverHelloMsg sentDummyCCS bool @@ -151,9 +153,22 @@ func (hs *serverHandshakeStateTLS13) processClientHello() error { if c.config.PreferServerCipherSuites { preferenceList = defaultCipherSuitesTLS13() supportedList = hs.clientHello.cipherSuites + + // If the client does not seem to have hardware support for AES-GCM, + // prefer other AEAD ciphers even if we prioritized AES-GCM ciphers + // by default. + if !aesgcmPreferred(hs.clientHello.cipherSuites) { + preferenceList = deprioritizeAES(preferenceList) + } } else { preferenceList = hs.clientHello.cipherSuites supportedList = defaultCipherSuitesTLS13() + + // If we don't have hardware support for AES-GCM, prefer other AEAD + // ciphers even if the client prioritized AES-GCM. + if !hasAESGCMHardwareSupport { + preferenceList = deprioritizeAES(preferenceList) + } } for _, suiteID := range preferenceList { hs.suite = mutualCipherSuiteTLS13(supportedList, suiteID) @@ -361,7 +376,7 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error { return c.sendAlert(alertMissingExtension) } - certificate, err := c.config.getCertificate(clientHelloInfo(c, hs.clientHello)) + certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello)) if err != nil { if err == errNoCertificates { c.sendAlert(alertUnrecognizedName) @@ -553,7 +568,7 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error { encryptedExtensions := new(encryptedExtensionsMsg) if len(hs.clientHello.alpnProtocols) > 0 { - if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback { + if selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); selectedProto != "" { encryptedExtensions.alpnProtocol = selectedProto c.clientProtocol = selectedProto } diff --git a/libgo/go/crypto/tls/handshake_test.go b/libgo/go/crypto/tls/handshake_test.go index f55cd16ca81..d9ff9fe948f 100644 --- a/libgo/go/crypto/tls/handshake_test.go +++ b/libgo/go/crypto/tls/handshake_test.go @@ -13,7 +13,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "net" "os" "os/exec" @@ -86,7 +85,7 @@ func checkOpenSSLVersion() error { println("to update the test data.") println("") println("Configure it with:") - println("./Configure enable-weak-ssl-ciphers") + println("./Configure enable-weak-ssl-ciphers no-shared") println("and then add the apps/ directory at the front of your PATH.") println("***********************************************") @@ -224,7 +223,7 @@ func parseTestData(r io.Reader) (flows [][]byte, err error) { // tempFile creates a temp file containing contents and returns its path. func tempFile(contents string) string { - file, err := ioutil.TempFile("", "go-tls-test") + file, err := os.CreateTemp("", "go-tls-test") if err != nil { panic("failed to create temp file: " + err.Error()) } @@ -403,7 +402,7 @@ func testHandshake(t *testing.T, clientConfig, serverConfig *Config) (serverStat } defer cli.Close() clientState = cli.ConnectionState() - buf, err := ioutil.ReadAll(cli) + buf, err := io.ReadAll(cli) if err != nil { t.Errorf("failed to call cli.Read: %v", err) } diff --git a/libgo/go/crypto/tls/link_test.go b/libgo/go/crypto/tls/link_test.go index c1fb57e70e2..8c392ff7c48 100644 --- a/libgo/go/crypto/tls/link_test.go +++ b/libgo/go/crypto/tls/link_test.go @@ -7,7 +7,6 @@ package tls import ( "bytes" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -41,19 +40,6 @@ func main() {} "type.crypto/tls.serverHandshakeState", }, }, - { - name: "only_conn", - program: `package main -import "crypto/tls" -var c = new(tls.Conn) -func main() {} -`, - want: []string{"tls.(*Conn)"}, - bad: []string{ - "type.crypto/tls.clientHandshakeState", - "type.crypto/tls.serverHandshakeState", - }, - }, { name: "client_and_server", program: `package main @@ -90,7 +76,7 @@ func main() { tls.Dial("", "", nil) } exeFile := filepath.Join(tmpDir, "x.exe") for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if err := ioutil.WriteFile(goFile, []byte(tt.program), 0644); err != nil { + if err := os.WriteFile(goFile, []byte(tt.program), 0644); err != nil { t.Fatal(err) } os.Remove(exeFile) diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN index d9e7e837664..d73866210df 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN @@ -1,22 +1,19 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 d1 01 00 00 cd 03 03 50 99 a9 e9 80 |...........P....| -00000010 87 f1 0a 5a bc 9d a6 53 6d 08 36 4a 79 f8 48 c3 |...Z...Sm.6Jy.H.| -00000020 fe c1 b4 02 d9 66 b2 cc f9 8d d4 00 00 38 c0 2c |.....f.......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.....=.<| -00000060 00 35 00 2f 00 ff 01 00 00 6c 00 0b 00 04 03 00 |.5./.....l......| -00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| -00000080 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 72 6f |...#.........pro| -00000090 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 00 17 |to2.proto1......| -000000a0 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| -000000b0 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................| -000000c0 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| -000000d0 04 02 05 02 06 02 |......| +00000000 16 03 01 00 9d 01 00 00 99 03 03 53 49 69 68 95 |...........SIih.| +00000010 b9 7b 2a 84 d2 03 93 d4 33 e7 b7 7e bc b5 97 b0 |.{*.....3..~....| +00000020 4f 4f 6c d0 96 43 aa c8 6f da 90 00 00 04 cc a8 |OOl..C..o.......| +00000030 00 ff 01 00 00 6c 00 0b 00 04 03 00 01 02 00 0a |.....l..........| +00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#| +00000050 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.| +00000060 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........| +00000070 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| +00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000090 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| +000000a0 06 02 |..| >>> Flow 2 (server to client) 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..| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......| 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| @@ -59,38 +56,37 @@ 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 cb 03 45 70 |..._X.;t......Ep| -000002e0 f5 51 af d7 cf db 26 79 d1 57 c2 06 4c 49 e6 ea |.Q....&y.W..LI..| -000002f0 e7 f4 b8 2c 23 52 8a 1f bd 8e a3 9e 79 d4 8e 66 |...,#R......y..f| -00000300 ee 92 39 97 cc ec 46 03 76 f9 59 b7 2e 6f e4 88 |..9...F.v.Y..o..| -00000310 fd 39 65 59 88 c2 7e 7a bc de 86 49 98 45 a6 44 |.9eY..~z...I.E.D| -00000320 82 41 19 94 53 3d 34 4b 73 52 5a af b2 3d 92 5e |.A..S=4KsRZ..=.^| -00000330 f3 5b e8 fa 23 a7 71 5c 64 1b 43 bb bd 8e 01 2a |.[..#.q\d.C....*| -00000340 59 2d 3b 73 0f b9 3d 02 9a 09 4a fc 0e 4b 65 07 |Y-;s..=...J..Ke.| -00000350 82 f9 e1 ad ec 64 27 a4 07 60 c7 32 16 03 03 00 |.....d'..`.2....| +000002d0 ed 90 99 5f 58 cb 3b 74 08 04 00 80 3b cd 7a 99 |..._X.;t....;.z.| +000002e0 3f bf 03 5a 26 21 90 db b4 8d 3b 69 14 82 1c ae |?..Z&!....;i....| +000002f0 7d 72 8f 4e eb ff c4 f0 13 fa 6f 69 48 e7 6d 3d |}r.N......oiH.m=| +00000300 fc b3 1c 54 60 54 cf 83 48 1d a3 50 55 28 3f 2c |...T`T..H..PU(?,| +00000310 db d3 dc c7 d9 58 74 de eb 5e 21 26 2f 32 c6 b2 |.....Xt..^!&/2..| +00000320 be 1b 08 fa d6 9f 3b b0 2b e8 c2 36 2f 9d c1 35 |......;.+..6/..5| +00000330 c1 54 4b 37 5f ff 99 4f c1 e4 ad 69 a0 c8 52 d3 |.TK7_..O...i..R.| +00000340 01 23 0d 57 17 08 7c 07 9a 3a 6d c8 87 5d 7e 09 |.#.W..|..:m..]~.| +00000350 7b 03 f9 5e de 83 4d 13 89 08 72 96 16 03 03 00 |{..^..M...r.....| 00000360 04 0e 00 00 00 |.....| >>> Flow 3 (client to server) -00000000 16 03 03 00 25 10 00 00 21 20 f6 5d 24 8e fc 1c |....%...! .]$...| -00000010 39 bb 01 fc 23 ef f4 86 8b aa 2c 39 2a a1 4d e6 |9...#.....,9*.M.| -00000020 7c 21 74 cc ed 2c 9b 4b f2 01 14 03 03 00 01 01 ||!t..,.K........| -00000030 16 03 03 00 28 96 9c a6 78 4b 94 24 e2 31 5a 25 |....(...xK.$.1Z%| -00000040 68 5e 6a 51 03 5d 9d cf 45 b1 78 17 0b bf ff c6 |h^jQ.]..E.x.....| -00000050 72 5b e9 f0 a1 b1 46 ab a5 e1 3f 4d 67 |r[....F...?Mg| +00000000 16 03 03 00 25 10 00 00 21 20 fb eb 44 09 0e 62 |....%...! ..D..b| +00000010 b0 ce d8 1f c5 f9 46 31 1e 1d e8 fb 02 5f 34 3b |......F1....._4;| +00000020 c1 6f 9a 38 6a 46 d2 cd a0 53 14 03 03 00 01 01 |.o.8jF...S......| +00000030 16 03 03 00 20 88 73 90 39 bc 9b 02 e4 c0 35 f0 |.... .s.9.....5.| +00000040 ef 40 b0 08 ca b9 bd 25 6b cd 03 7d ec 58 73 65 |.@.....%k..}.Xse| +00000050 d5 89 f2 f1 70 |....p| >>> Flow 4 (server to client) 00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 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 51 ed 14 ef 68 ca 42 c5 4c 4a f5 b1 |o...Q...h.B.LJ..| -00000040 56 86 3e f2 10 79 9e f3 a0 ed 07 6d 09 fc 77 63 |V.>..y.....m..wc| -00000050 86 68 42 99 7b 13 c3 35 cf 5b a6 3a fa aa c2 ec |.hB.{..5.[.:....| -00000060 80 a2 27 e4 97 24 07 48 2c 70 30 fc d6 49 38 16 |..'..$.H,p0..I8.| -00000070 60 d5 b0 4c ec 4b 74 48 03 2a 5e fb 14 43 6c 5f |`..L.KtH.*^..Cl_| -00000080 35 9c 1b a8 7d 62 f8 42 68 27 cb 6d 15 38 e7 8e |5...}b.Bh'.m.8..| -00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -000000a0 00 00 00 8d 7a 5a 66 3b c9 fe 51 c2 71 ef a5 8b |....zZf;..Q.q...| -000000b0 42 7d 79 33 4e 6d 66 12 cc e7 46 4f c3 30 12 8f |B}y3Nmf...FO.0..| -000000c0 0c 57 60 17 03 03 00 25 00 00 00 00 00 00 00 01 |.W`....%........| -000000d0 83 aa 62 fe a3 73 ed 67 87 c0 19 1c fa f0 2c 26 |..b..s.g......,&| -000000e0 4b 16 44 9c a7 f8 c3 e1 ba 6a 85 8f 84 15 03 03 |K.D......j......| -000000f0 00 1a 00 00 00 00 00 00 00 02 a8 b3 b2 dd 4b a6 |..............K.| -00000100 ba 05 dc 8f ac 98 ae 01 10 60 9a 62 |.........`.b| +00000030 6f e0 18 83 51 ed 14 ef 68 ca 42 c5 4c cd 0b 21 |o...Q...h.B.L..!| +00000040 a5 29 ef 62 07 a5 11 b9 1f 4e 54 c3 66 4c 1e d3 |.).b.....NT.fL..| +00000050 1a 00 52 34 67 2b af 73 02 5f c9 6c 7c 6e ba f2 |..R4g+.s._.l|n..| +00000060 e6 38 bd 23 97 3f 80 6a 3b 8e bb 98 29 49 38 16 |.8.#.?.j;...)I8.| +00000070 77 74 2a a1 c7 36 80 de c9 91 cd b2 7d bc 6c 64 |wt*..6......}.ld| +00000080 6c 06 57 22 d1 f2 51 5f 84 ad 30 85 3a c0 4f e7 |l.W"..Q_..0.:.O.| +00000090 14 03 03 00 01 01 16 03 03 00 20 32 71 5a d3 94 |.......... 2qZ..| +000000a0 d5 17 e4 8c 3a 78 d1 48 4e 1b f5 83 36 f1 5a 38 |....:x.HN...6.Z8| +000000b0 e4 b5 6d ab 46 89 e0 24 74 87 80 17 03 03 00 1d |..m.F..$t.......| +000000c0 69 4c a6 24 67 79 18 59 92 4f 9a d0 2d 1d 57 e0 |iL.$gy.Y.O..-.W.| +000000d0 ec 0c 00 25 6f 2f 3a be 8a aa 80 94 ac 15 03 03 |...%o/:.........| +000000e0 00 12 ef 86 3e 93 42 bb 72 f1 1b 90 df 9a d3 ed |....>.B.r.......| +000000f0 d8 74 35 23 |.t5#| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch index 589189ca844..fdfb1754637 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch @@ -1,22 +1,19 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 d1 01 00 00 cd 03 03 44 a5 b9 48 dd |...........D..H.| -00000010 ca 91 9a c6 72 06 b3 dd a7 95 18 c6 95 0b f2 32 |....r..........2| -00000020 84 37 78 12 0f 66 c7 6e e6 61 81 00 00 38 c0 2c |.7x..f.n.a...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.....=.<| -00000060 00 35 00 2f 00 ff 01 00 00 6c 00 0b 00 04 03 00 |.5./.....l......| -00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| -00000080 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 72 6f |...#.........pro| -00000090 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 00 17 |to2.proto1......| -000000a0 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| -000000b0 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................| -000000c0 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................| -000000d0 04 02 05 02 06 02 |......| +00000000 16 03 01 00 9d 01 00 00 99 03 03 7f fc 15 86 d1 |................| +00000010 83 09 78 47 8d cd 7b 88 b3 86 52 27 bc da bc 8d |..xG..{...R'....| +00000020 0e 5d 35 44 21 17 7b d9 67 b9 fb 00 00 04 cc a8 |.]5D!.{.g.......| +00000030 00 ff 01 00 00 6c 00 0b 00 04 03 00 01 02 00 0a |.....l..........| +00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#| +00000050 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.| +00000060 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........| +00000070 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| +00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000090 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| +000000a0 06 02 |..| >>> Flow 2 (server to client) 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..| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......| 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............| @@ -58,38 +55,37 @@ 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 1d |......_X.;t.....| -000002d0 ae 16 b9 7e 58 bb d5 1b 9e 51 09 a2 d1 a8 3f 1d |...~X....Q....?.| -000002e0 f4 09 72 a5 c6 cc 9a 53 46 1c 9f 58 36 cd 91 39 |..r....SF..X6..9| -000002f0 44 ca 56 da 50 77 d5 56 10 14 45 ad 98 b8 2f 44 |D.V.Pw.V..E.../D| -00000300 33 ae a9 b1 b6 a6 2a ab 0a 0a 39 75 2c 4d 4c 51 |3.....*...9u,MLQ| -00000310 71 07 83 bf ad 8b 37 c5 59 dd 8f d7 b8 85 2e 04 |q.....7.Y.......| -00000320 9e 39 e6 e5 a5 48 9a 24 63 b3 a7 46 73 b2 5c 10 |.9...H.$c..Fs.\.| -00000330 cc 4c e5 55 dd 97 b0 42 4e 8b fb 0d cd 47 e9 09 |.L.U...BN....G..| -00000340 20 88 96 5e 76 0d 9b b1 91 3f 27 a1 f3 0d 77 16 | ..^v....?'...w.| +000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 b8 |......_X.;t.....| +000002d0 a8 88 ac 85 ea 59 ac f1 41 e8 2d a2 76 3c 3b 4f |.....Y..A.-.v<;O| +000002e0 58 90 b7 03 74 4b 7a a7 5a 65 ea 08 9c cf e9 4d |X...tKz.Ze.....M| +000002f0 b4 8a ef f3 e1 d8 0a 83 0f 50 29 0b 59 77 90 e9 |.........P).Yw..| +00000300 f3 e8 ca 6c b5 da e5 2b 95 47 e7 ed ff d6 3b 30 |...l...+.G....;0| +00000310 45 61 2c af 5c 8c 4c df bd c4 dc 28 dd d2 31 fa |Ea,.\.L....(..1.| +00000320 be 65 2b a4 cd 7c 41 29 4c 99 07 97 5c 2a 3c a7 |.e+..|A)L...\*<.| +00000330 4d 9c ed 72 eb a1 a4 9e db eb a0 cf c7 c2 b1 3b |M..r...........;| +00000340 5a d9 f8 f8 8e d5 07 81 f6 65 aa 0d 4f 4d 11 16 |Z........e..OM..| 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 89 8e 03 11 92 ab |....%...! ......| -00000010 51 f5 d7 dc 27 87 fd 38 eb 45 3d cc 75 1a 1e 07 |Q...'..8.E=.u...| -00000020 d6 0f 2b 92 df 5a 7c 24 30 56 14 03 03 00 01 01 |..+..Z|$0V......| -00000030 16 03 03 00 28 fa 24 69 6d 65 2f 34 35 47 9b 83 |....(.$ime/45G..| -00000040 65 0f fd c1 33 61 1d 47 cf ec 87 6f 48 71 63 7d |e...3a.G...oHqc}| -00000050 e8 aa bc 2e cd 7d 2e 4b d5 0f 4f 66 14 |.....}.K..Of.| +00000000 16 03 03 00 25 10 00 00 21 20 5f d2 13 b1 79 f6 |....%...! _...y.| +00000010 f3 2a 21 f5 89 a3 22 29 73 30 14 60 1d 1e 77 8a |.*!...")s0.`..w.| +00000020 f4 1a 92 3f b0 04 06 98 1a 1e 14 03 03 00 01 01 |...?............| +00000030 16 03 03 00 20 63 10 89 c0 c0 56 37 40 8c e8 5e |.... c....V7@..^| +00000040 7f f0 f0 e3 a0 8e d5 20 33 5f dd c3 16 e8 eb 6c |....... 3_.....l| +00000050 c3 a8 75 6d dc |..um.| >>> Flow 4 (server to client) 00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 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 51 ed 14 ef 68 ca 42 c5 4c 60 05 16 |o...Q...h.B.L`..| -00000040 33 5b f7 bd 83 9c 69 80 c2 fe 5c 73 32 05 67 97 |3[....i...\s2.g.| -00000050 fd 6b 3a d3 b4 6d a5 5e 18 c0 1e ba d5 2c 44 ad |.k:..m.^.....,D.| -00000060 54 24 65 be 14 90 ab 6d a1 de d1 98 1e 49 38 16 |T$e....m.....I8.| -00000070 f0 fe 8d 49 6d e1 5a 6d 10 30 26 64 5f 10 ad ab |...Im.Zm.0&d_...| -00000080 d7 c9 3a bc 6a 3f 32 78 4b fe f1 38 08 2c 15 e7 |..:.j?2xK..8.,..| -00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -000000a0 00 00 00 e9 3d 4c 8b 59 78 8c 49 77 08 3b c1 de |....=L.Yx.Iw.;..| -000000b0 4c 78 9a d7 c6 1a 66 fb 43 de bd cb 8b ca a2 32 |Lx....f.C......2| -000000c0 a2 26 1e 17 03 03 00 25 00 00 00 00 00 00 00 01 |.&.....%........| -000000d0 47 c9 3a 0d 8d 8b d1 b7 66 17 8e 83 31 02 ed 51 |G.:.....f...1..Q| -000000e0 e8 cb 1d 4a 42 d6 f9 ee b8 6d fd d0 4b 15 03 03 |...JB....m..K...| -000000f0 00 1a 00 00 00 00 00 00 00 02 f3 00 56 6d fc 23 |............Vm.#| -00000100 49 bb 65 00 b0 ae cd c7 62 ac 47 1f |I.e.....b.G.| +00000030 6f e0 18 83 51 ed 14 ef 68 ca 42 c5 4c e3 f1 12 |o...Q...h.B.L...| +00000040 a1 17 a6 ee 99 af e8 06 65 d0 6d c1 4f ce 92 7c |........e.m.O..|| +00000050 40 df 41 c1 90 e3 e0 d8 a1 95 da 38 25 26 ea b5 |@.A........8%&..| +00000060 ca a9 42 5f 8c 55 d4 d2 73 a6 a2 b6 22 49 38 16 |..B_.U..s..."I8.| +00000070 ec 70 52 f9 c0 12 18 9e 9b 4d e3 6d 49 b7 3b c0 |.pR......M.mI.;.| +00000080 e9 53 9d 06 96 fc a9 06 8c 2a 7a c5 7d 48 47 ef |.S.......*z.}HG.| +00000090 14 03 03 00 01 01 16 03 03 00 20 19 27 38 37 bf |.......... .'87.| +000000a0 07 4e 2f 77 b9 73 4b dd c8 f8 4c c5 f1 35 86 2b |.N/w.sK...L..5.+| +000000b0 97 7e 0f 89 4b bf db 81 76 8a 41 17 03 03 00 1d |.~..K...v.A.....| +000000c0 6d b8 c3 eb b1 5a f3 06 97 04 61 fc 82 74 5d a0 |m....Z....a..t].| +000000d0 73 57 75 6e 66 53 3e 12 5e 0d 60 31 52 15 03 03 |sWunfS>.^.`1R...| +000000e0 00 12 e4 93 fb 7b cb ee d6 70 ac af 5f 8b 82 9b |.....{...p.._...| +000000f0 e5 0b 68 9c |..h.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven index 31776532f14..3d1ceaf9038 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven @@ -1,60 +1,58 @@ >>> Flow 1 (client to server) -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 |................| -00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....| -00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................| -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 |............| +00000000 16 03 01 00 6d 01 00 00 69 03 03 b0 00 44 aa 86 |....m...i....D..| +00000010 30 87 8e 3f f1 89 9a 4a f6 4c 3b 11 f3 4f e9 9f |0..?...J.L;..O..| +00000020 00 22 47 82 26 57 c7 d0 f9 59 6f 00 00 04 00 2f |."G.&W...Yo..../| +00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........| +00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| +00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| +00000070 06 02 |..| >>> Flow 2 (server to client) -00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| +00000000 16 03 03 00 31 02 00 00 2d 03 03 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 01 00 00 2f 00 00 |...DOWNGRD.../..| -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 |...........| +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 23 0d 00 00 1f 02 01 40 |;.......#......@| +000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................| +000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................| +000002c0 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| @@ -89,40 +87,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 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...| +00000210 03 03 00 86 10 00 00 82 00 80 10 ab 2f 0f b9 29 |............/..)| +00000220 9f 26 36 09 00 96 9a 3d 2a 01 50 03 f3 d6 ac fc |.&6....=*.P.....| +00000230 40 76 96 d0 e6 a6 67 89 24 b0 56 80 58 5e 6d 03 |@v....g.$.V.X^m.| +00000240 e3 0f dc 61 d1 de 25 95 8a 54 9f 5b 3e f2 31 dd |...a..%..T.[>.1.| +00000250 14 2a e2 de 7b 70 66 b5 ed 95 d9 cc 6f c0 b3 a1 |.*..{pf.....o...| +00000260 bb 41 b2 0f 7d e8 ce b5 11 eb 99 e2 ce c0 33 bc |.A..}.........3.| +00000270 6a 67 10 84 d2 dd ac 15 8f 8e aa 2b 1a 7b ca d3 |jg.........+.{..| +00000280 bb 4b 92 c4 b9 2b 08 c1 0d b2 cf 96 63 64 9d 12 |.K...+......cd..| +00000290 a6 93 cd 21 3b bc 8e 94 72 76 16 03 03 00 93 0f |...!;...rv......| +000002a0 00 00 8f 04 03 00 8b 30 81 88 02 42 00 d5 05 54 |.......0...B...T| +000002b0 b2 68 a5 04 d6 3c 7b 7d c1 be e3 d1 b4 25 42 d6 |.h...<{}.....%B.| +000002c0 2a 3a 2e ea 73 0d 57 ba 0f 96 78 66 c2 c5 d7 57 |*:..s.W...xf...W| +000002d0 79 9c 22 8b 76 e9 45 ff ef 92 e9 43 3e b8 8b b4 |y.".v.E....C>...| +000002e0 cf 3f 67 aa 70 d1 e8 a2 1c a8 3d 24 a2 78 02 42 |.?g.p.....=$.x.B| +000002f0 01 b2 17 64 66 2f 2e 0d 2d b9 1d 67 45 de 48 9e |...df/..-..gE.H.| +00000300 32 f2 1f 79 38 39 b8 bb 8b 7f 82 e9 46 fd 9b 1b |2..y89......F...| +00000310 b3 dd a4 9c 15 b2 a2 88 4c f7 42 a2 62 92 c0 d0 |........L.B.b...| +00000320 a1 78 aa 8b 2d 78 4f 02 5a f7 eb ca c7 34 fc b6 |.x..-xO.Z....4..| +00000330 6c 6e 14 03 03 00 01 01 16 03 03 00 40 bd 47 9b |ln..........@.G.| +00000340 ce 31 2c 09 d3 a8 2c bb 28 0c e8 bd 01 a9 54 34 |.1,...,.(.....T4| +00000350 a5 74 af e0 d2 38 f3 1b fa d0 2b a6 39 24 ae de |.t...8....+.9$..| +00000360 0a cf 4b c0 a2 3b bf 80 23 71 0a 60 ca 94 b7 23 |..K..;..#q.`...#| +00000370 80 e3 89 89 42 74 0b a1 c6 f6 d2 c0 79 |....Bt......y| >>> 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 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.....@| +00000010 00 00 00 00 00 00 00 00 00 00 00 54 52 4a 33 9e |...........TRJ3.| +00000020 bb 59 7e 21 03 a6 23 bd 68 18 43 b5 c5 c5 37 a2 |.Y~!..#.h.C...7.| +00000030 6f ac 8c 78 c5 cf 8f e6 01 df 17 53 45 6f 1a e0 |o..x.......SEo..| +00000040 9c 4a 3d 2c cb 0d 55 7d 32 81 ec 17 03 03 00 40 |.J=,..U}2......@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -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*.| +00000060 ba 75 93 00 86 1c bc 66 9e 27 2f 2b 5a 68 0e 44 |.u.....f.'/+Zh.D| +00000070 81 15 0d 67 e6 ee 7a 43 08 78 93 71 91 00 56 0e |...g..zC.x.q..V.| +00000080 c6 e1 73 4b af 2f e6 e0 92 4d e5 35 ea 53 7c 45 |..sK./...M.5.S|E| 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 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.| +000000a0 00 00 00 00 00 8d 7e 99 bb 93 bd 5d ba 31 b0 0d |......~....].1..| +000000b0 1f 76 95 50 7c 1e 24 62 9d 05 65 3f ee b7 c2 24 |.v.P|.$b..e?...$| +000000c0 13 60 43 69 3a |.`Ci:| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given index d535cb4d751..1c3b08f06fa 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given @@ -1,74 +1,58 @@ >>> Flow 1 (client to server) -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.....=.<| -00000060 00 35 00 2f 00 ff 01 00 00 66 00 00 00 0e 00 0c |.5./.....f......| -00000070 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....| -00000080 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................| -00000090 00 19 00 18 00 16 00 00 00 17 00 00 00 0d 00 30 |...............0| -000000a0 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -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 |................| +00000000 16 03 01 00 6d 01 00 00 69 03 03 aa ad c9 dc 56 |....m...i......V| +00000010 79 2e da 42 a6 b2 9e 0a 85 a6 1b e0 5e cd 4e f5 |y..B........^.N.| +00000020 93 93 0c d5 62 a8 53 17 10 f7 e6 00 00 04 00 2f |....b.S......../| +00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........| +00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| +00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| +00000070 06 02 |..| >>> Flow 2 (server to client) -00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| +00000000 16 03 03 00 31 02 00 00 2d 03 03 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 01 00 c0 30 00 00 |...DOWNGRD...0..| -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 |............| +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 23 0d 00 00 1f 02 01 40 |;.......#......@| +000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................| +000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................| +000002c0 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............| @@ -90,23 +74,36 @@ 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 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?.`....| +00000140 08 16 03 03 00 86 10 00 00 82 00 80 14 f2 ac 22 |..............."| +00000150 fb 0b f8 03 a7 cf 23 d5 ea 9f b0 f2 64 ae 41 fe |......#.....d.A.| +00000160 33 f7 54 69 f5 41 b7 c1 91 6d 2b 3e 14 2a f6 c8 |3.Ti.A...m+>.*..| +00000170 96 45 00 28 13 f5 2f de 35 f9 64 89 5c 99 3e 89 |.E.(../.5.d.\.>.| +00000180 06 ff 59 56 69 db 5f 6e 02 84 dd 1c 44 7b 86 e8 |..YVi._n....D{..| +00000190 e3 d9 03 f1 16 9e 06 23 00 43 91 ec a9 dd da a4 |.......#.C......| +000001a0 ac fe 5b f8 62 f9 76 19 38 83 54 b4 8c 0b 02 f0 |..[.b.v.8.T.....| +000001b0 fa 7a 8e 2e da 9d e1 4a c6 51 92 9b f6 4b a1 31 |.z.....J.Q...K.1| +000001c0 c9 64 b2 a6 9a 01 52 86 b3 7a 43 17 16 03 03 00 |.d....R..zC.....| +000001d0 48 0f 00 00 44 08 07 00 40 29 35 71 34 aa b1 f1 |H...D...@)5q4...| +000001e0 64 08 4e 06 43 db 00 f7 f5 98 8e b6 51 d7 c4 b5 |d.N.C.......Q...| +000001f0 2b fa 56 8b bd 7b 18 f2 81 e9 2f 81 82 d8 90 e7 |+.V..{..../.....| +00000200 5b bc 72 7e f7 97 43 df cd 07 bf 7b ae 60 08 8b |[.r~..C....{.`..| +00000210 0a 71 c5 bf f0 7a 3e cc 0b 14 03 03 00 01 01 16 |.q...z>.........| +00000220 03 03 00 40 85 4f e0 c0 f3 3e a4 51 68 d6 ec 1b |...@.O...>.Qh...| +00000230 f1 4b 3e 0e 13 84 87 e3 3c 9a 5f 67 75 3a ad 08 |.K>.....<._gu:..| +00000240 be 29 15 b0 1f 62 27 fd d8 dd 58 b1 65 e7 e2 db |.)...b'...X.e...| +00000250 fe 55 a5 2d 2e 71 59 07 ad 12 12 80 12 bb 26 36 |.U.-.qY.......&6| +00000260 93 fb ea b1 |....| >>> 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 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 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 |................| -00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....| -00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................| -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 |............| +00000000 16 03 01 00 6d 01 00 00 69 03 03 e7 7e 1f 56 df |....m...i...~.V.| +00000010 f1 1b e5 92 47 3b fb 25 a6 57 7d 13 47 08 f0 0f |....G;.%.W}.G...| +00000020 5b 64 64 00 d3 25 33 e5 a5 5b e3 00 00 04 00 2f |[dd..%3..[...../| +00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........| +00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| +00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| +00000070 06 02 |..| >>> Flow 2 (server to client) -00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| +00000000 16 03 03 00 31 02 00 00 2d 03 03 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 01 00 00 2f 00 00 |...DOWNGRD.../..| -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 |...........| +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 23 0d 00 00 1f 02 01 40 |;.......#......@| +000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................| +000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................| +000002c0 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.......\.| @@ -88,40 +86,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 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..| +00000200 e5 35 16 03 03 00 86 10 00 00 82 00 80 7f 38 c9 |.5............8.| +00000210 56 ed de 7d a6 2c dc cc 24 61 ea d3 8a fc b8 18 |V..}.,..$a......| +00000220 b8 e5 50 3e c3 d1 ca cf f7 0c d9 9b 22 d8 6d 0f |..P>........".m.| +00000230 71 e7 dd 7c 24 84 c6 f1 6a ac a0 3d ea d7 65 24 |q..|$...j..=..e$| +00000240 d7 3a 17 d5 b7 ec f7 03 bc 58 3a 01 d5 08 27 25 |.:.......X:...'%| +00000250 b9 2f 3b 96 cb d5 7c 12 20 f4 f1 91 58 13 fb 50 |./;...|. ...X..P| +00000260 f8 d5 5c e4 43 85 e8 41 37 3e ff fa a6 64 92 4d |..\.C..A7>...d.M| +00000270 bd d4 96 59 bd 94 f1 95 21 ad 75 1e 0d a2 8d 30 |...Y....!.u....0| +00000280 a3 82 f4 56 0f ba 5d 40 32 7f 0c 5f 5a 16 03 03 |...V..]@2.._Z...| +00000290 00 88 0f 00 00 84 08 04 00 80 39 b4 f4 68 e9 96 |..........9..h..| +000002a0 01 53 95 31 26 fa 3c 70 46 9f ba 62 b4 37 ea a6 |.S.1&..Gy..^p| +000002f0 30 8c 11 3f 27 43 4f 5d 81 89 83 39 9d fe 0c c3 |0..?'CO]...9....| +00000300 af 40 8d 2a 41 bf 57 67 7a df b4 89 29 10 9a 84 |.@.*A.Wgz...)...| +00000310 ff 8c 2f 58 1a 0a b9 62 4e 8e 14 03 03 00 01 01 |../X...bN.......| +00000320 16 03 03 00 40 7c 7a 79 ae 84 60 b8 95 83 30 78 |....@|zy..`...0x| +00000330 e9 6e 02 36 52 85 5a 6a a7 b5 f5 6d 4d a9 09 9d |.n.6R.Zj...mM...| +00000340 43 9d 46 da d0 cf 75 25 49 e1 79 0b 23 2d 85 c2 |C.F...u%I.y.#-..| +00000350 fd 5d 90 08 f5 75 81 ab 01 a0 f4 93 12 87 fb e3 |.]...u..........| +00000360 9b 99 4d fa c5 |..M..| >>> 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 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...}.?.....@| +00000010 00 00 00 00 00 00 00 00 00 00 00 48 61 67 c0 1e |...........Hag..| +00000020 09 79 82 cc 55 60 fa e5 bd 1a 1d 14 d3 25 e6 4b |.y..U`.......%.K| +00000030 b7 a6 47 64 01 65 12 b3 37 42 1a 13 d9 90 12 7e |..Gd.e..7B.....~| +00000040 ea d8 30 39 e2 25 5e 9a 05 61 11 17 03 03 00 40 |..09.%^..a.....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -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..).?| +00000060 cf c5 73 08 e9 15 25 b6 d8 e3 fa 0c a1 25 33 75 |..s...%......%3u| +00000070 8a 2e 66 03 c2 2d 50 c7 e1 10 b4 2a 0c 88 87 90 |..f..-P....*....| +00000080 04 4a 80 26 85 4b fd 9a 4f 0e b1 2c f0 18 57 f5 |.J.&.K..O..,..W.| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -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 |.*...| +000000a0 00 00 00 00 00 ce e0 a1 71 be 3d 1e b0 bd 06 4c |........q.=....L| +000000b0 1f 5b 10 8d 77 18 e0 c5 81 c9 4e 1b 3b 96 f6 6d |.[..w.....N.;..m| +000000c0 88 03 53 54 30 |..ST0| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given index b38cb416f62..8efbc912d95 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given @@ -1,60 +1,58 @@ >>> Flow 1 (client to server) -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 |................| -00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....| -00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................| -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 |............| +00000000 16 03 01 00 6d 01 00 00 69 03 03 4c 65 99 ab e0 |....m...i..Le...| +00000010 4b 0a 08 f5 06 20 f9 3d 96 4f 05 e3 58 6f 41 50 |K.... .=.O..XoAP| +00000020 c1 5f e8 a8 0a 5f 8f f2 de 7f 16 00 00 04 00 2f |._..._........./| +00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........| +00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| +00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| +00000070 06 02 |..| >>> Flow 2 (server to client) -00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| +00000000 16 03 03 00 31 02 00 00 2d 03 03 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 01 00 00 2f 00 00 |...DOWNGRD.../..| -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 |...........| +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 23 0d 00 00 1f 02 01 40 |;.......#......@| +000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................| +000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................| +000002c0 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.......\.| @@ -88,40 +86,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 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..| +00000300 9a 2a 39 e8 fe aa aa ee e3 00 a3 a8 1e 75 4a 21 |.*9..........uJ!| +00000310 b4 ad 24 8f ee e8 30 85 b1 28 14 03 03 00 01 01 |..$...0..(......| +00000320 16 03 03 00 40 71 47 13 68 49 74 9c 2a 81 35 94 |....@qG.hIt.*.5.| +00000330 52 f6 44 44 67 3b 62 e1 ef 34 18 e7 8a 56 71 88 |R.DDg;b..4...Vq.| +00000340 83 7e 67 28 20 18 b1 c5 8a c8 8b 6a fe ee bf da |.~g( ......j....| +00000350 5f 6e cd fa a8 5c af 5c 3c 83 80 78 f3 fe 1b dc |_n...\.\<..x....| +00000360 95 fe 22 16 82 |.."..| >>> 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 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+%....@| +00000010 00 00 00 00 00 00 00 00 00 00 00 20 f7 51 8f 23 |........... .Q.#| +00000020 08 8d 67 5d 12 06 b0 48 81 2d 0c ba 88 03 88 31 |..g]...H.-.....1| +00000030 d0 ab 63 0d 9f 28 60 21 0a a3 58 47 c2 04 cc f1 |..c..(`!..XG....| +00000040 50 0d 88 b2 e5 54 50 26 e6 6e ed 17 03 03 00 40 |P....TP&.n.....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -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..;.| +00000060 fa 4d e5 00 14 2c 65 82 5d 1b bf 99 6a 54 16 98 |.M...,e.]...jT..| +00000070 ef 55 15 00 f9 c4 3e 61 88 83 63 fd 60 66 f1 87 |.U....>a..c.`f..| +00000080 fa c4 45 ae de b8 0a 36 75 f5 b2 b6 f5 d8 9b df |..E....6u.......| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -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 |.....| +000000a0 00 00 00 00 00 54 cc c0 15 e5 6d 62 4d 13 54 e8 |.....T....mbM.T.| +000000b0 fa cf 76 a6 de d6 48 f8 0d ef 30 b7 12 05 cf 75 |..v...H...0....u| +000000c0 8b 00 9e d5 63 |....c| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven index 6f7c2884214..a81c1731535 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven @@ -1,87 +1,85 @@ >>> Flow 1 (client to server) -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 |................| -00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....| -00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................| -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 |............| +00000000 16 03 01 00 6d 01 00 00 69 03 03 be a7 a4 6c f7 |....m...i.....l.| +00000010 f6 b4 f2 64 5d 0e 36 b6 05 f5 f1 c9 fe 3c c2 8e |...d].6......<..| +00000020 c4 b7 18 68 b9 0c 1d 51 50 2f 1e 00 00 04 00 2f |...h...QP/...../| +00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........| +00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| +00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| +00000070 06 02 |..| >>> Flow 2 (server to client) -00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| +00000000 16 03 03 00 31 02 00 00 2d 03 03 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 01 00 00 2f 00 00 |...DOWNGRD.../..| -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 |...........| +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 23 0d 00 00 1f 02 01 40 |;.......#......@| +000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................| +000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................| +000002c0 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 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 |.!| +00000010 86 10 00 00 82 00 80 a9 b6 12 e2 84 71 62 7a 20 |............qbz | +00000020 63 80 99 c6 ee f7 61 f9 74 d6 0b ab 31 74 69 ca |c.....a.t...1ti.| +00000030 94 20 9e 1b 0e 52 45 c4 f4 b3 cb fb a4 07 61 6f |. ...RE.......ao| +00000040 a1 5a 84 4c 4f f6 4a e4 bc c5 c2 b0 ee 8a 30 5b |.Z.LO.J.......0[| +00000050 10 e0 ed d3 4c b7 32 8c ed 3f 89 a7 a7 95 60 86 |....L.2..?....`.| +00000060 97 1a ae ab 2f 5c e6 6d 1b c3 35 bd f5 c1 f0 1a |..../\.m..5.....| +00000070 d4 70 e5 00 f2 d4 d1 20 6a 82 db e7 52 ca 88 e5 |.p..... j...R...| +00000080 2d cc 79 0c f6 09 84 65 f0 30 41 67 10 0a 48 d1 |-.y....e.0Ag..H.| +00000090 09 3e 56 7a aa 57 bc 14 03 03 00 01 01 16 03 03 |.>Vz.W..........| +000000a0 00 40 e6 0a 91 5f 30 f8 52 75 94 8e ab 82 ec 1d |.@..._0.Ru......| +000000b0 b7 a1 1c 18 1a aa 1c f8 73 93 0e 20 ad 68 a7 65 |........s.. .h.e| +000000c0 86 c9 f5 90 f9 b2 fd d1 32 94 52 6e 82 9b b9 45 |........2.Rn...E| +000000d0 97 52 4b 1e c2 31 a6 2e c8 b3 1a 62 22 83 8f df |.RK..1.....b"...| +000000e0 d7 06 |..| >>> 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 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....@| +00000010 00 00 00 00 00 00 00 00 00 00 00 b0 2c 61 79 87 |............,ay.| +00000020 59 d4 9e 4d e7 56 4a 34 ba 78 d5 06 98 a2 92 35 |Y..M.VJ4.x.....5| +00000030 a1 fc 57 5a 6e d3 0f 44 08 1c a1 7b 3c d3 f1 86 |..WZn..D...{<...| +00000040 a2 04 04 5e 1b 7c 00 4f 51 71 73 17 03 03 00 40 |...^.|.OQqs....@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -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....]....| +00000060 aa 5c 1a 9a 70 bc b3 fb 70 07 0b 24 cb 95 84 61 |.\..p...p..$...a| +00000070 96 ed d8 97 2f d6 79 51 ed cd 67 44 e5 d4 a3 57 |..../.yQ..gD...W| +00000080 95 f6 c8 31 a8 95 c2 07 a4 ce 1c fc 4a dc 93 d9 |...1........J...| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -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...| +000000a0 00 00 00 00 00 ae dd c4 f4 04 d3 b1 1a 8a 56 f7 |..............V.| +000000b0 73 c9 d5 aa 6c 59 d7 66 77 34 64 2d 19 79 13 80 |s...lY.fw4d-.y..| +000000c0 98 60 6d f4 d9 |.`m..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-Ed25519 b/libgo/go/crypto/tls/testdata/Server-TLSv12-Ed25519 index 6d8b28b82a6..dd34592811f 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-Ed25519 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-Ed25519 @@ -1,21 +1,17 @@ >>> Flow 1 (client to server) -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.....=.<| -00000060 00 35 00 2f 00 ff 01 00 00 66 00 00 00 0e 00 0c |.5./.....f......| -00000070 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....| -00000080 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................| -00000090 00 19 00 18 00 16 00 00 00 17 00 00 00 0d 00 30 |...............0| -000000a0 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -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 |................| +00000000 16 03 01 00 85 01 00 00 81 03 03 f0 8d 1b 90 67 |...............g| +00000010 3b 23 46 ac f7 79 f2 f9 e8 90 98 b3 52 b2 55 2a |;#F..y......R.U*| +00000020 fb 0f 1e dd 4f b3 75 4b 9b 88 0e 00 00 04 cc a9 |....O.uK........| +00000030 00 ff 01 00 00 54 00 0b 00 04 03 00 01 02 00 0a |.....T..........| +00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000050 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 |.........0......| +00000060 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| +00000070 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................| +00000080 03 02 02 02 04 02 05 02 06 02 |..........| >>> Flow 2 (server to client) 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...,..| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a9 00 00 |...DOWNGRD......| 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..| @@ -39,25 +35,24 @@ 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.<...| +000001a0 cf c2 ed 90 99 5f 58 cb 3b 74 08 07 00 40 1f 56 |....._X.;t...@.V| +000001b0 21 8a 44 04 69 65 ee f8 93 52 4c f0 49 42 57 4c |!.D.ie...RL.IBWL| +000001c0 5b f5 1a ef 43 ad 39 93 03 a3 64 84 da e5 82 32 |[...C.9...d....2| +000001d0 fc 77 12 61 f3 f4 2c d8 61 9e 86 01 1f c0 a0 98 |.w.a..,.a.......| +000001e0 94 a3 7f 15 75 c8 e6 2f 20 bd af 7c be 0e 16 03 |....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 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.| +00000040 71 a7 13 f5 3a 8a cd 86 34 8b 7e 41 b5 2a 1b 03 |q...:...4.~A.*..| +00000050 29 77 b3 b2 da |)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 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.| +00000000 14 03 03 00 01 01 16 03 03 00 20 54 5a ff 09 7d |.......... TZ..}| +00000010 46 04 40 62 c5 63 71 85 c7 b4 6c 09 ee 15 71 6b |F.@b.cq...l...qk| +00000020 60 3b 00 3d 46 47 13 a5 f7 15 16 17 03 03 00 1d |`;.=FG..........| +00000030 13 8d 00 50 58 d0 2a 47 a8 d8 de 87 d4 3e ff ee |...PX.*G.....>..| +00000040 f1 4d 6b 25 94 6f 01 7b 70 ee 53 d9 be 15 03 03 |.Mk%.o.{p.S.....| +00000050 00 12 13 ea 17 69 00 0e 2b ae 21 a9 5e 0a 41 2d |.....i..+.!.^.A-| +00000060 1b 73 f0 2d |.s.-| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial index c9f0c5c0fc6..e01c32c4287 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial @@ -1,21 +1,17 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 bd 01 00 00 b9 03 03 7e 75 ea 1f ec |...........~u...| -00000010 47 ee de 51 9d 11 00 77 5b 1b fb 7e 05 22 0a 7a |G..Q...w[..~.".z| -00000020 74 bc 6a d1 8a 67 03 a1 ae c9 23 00 00 38 c0 2c |t.j..g....#..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.....=.<| -00000060 00 35 00 2f 00 ff 01 00 00 58 00 0b 00 04 03 00 |.5./.....X......| -00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................| -00000080 00 18 00 23 00 00 00 16 00 00 00 17 00 00 00 0d |...#............| -00000090 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............| -000000a0 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| -000000b0 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................| -000000c0 06 02 |..| +00000000 16 03 01 00 89 01 00 00 85 03 03 9a d9 fe da 40 |...............@| +00000010 cf 8b ed 11 09 8e 3f 29 4b 0d 46 ff fc f6 56 2c |......?)K.F...V,| +00000020 a8 e7 16 84 8a a4 e9 44 89 97 0b 00 00 04 cc a8 |.......D........| +00000030 00 ff 01 00 00 58 00 0b 00 04 03 00 01 02 00 0a |.....X..........| +00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#| +00000050 00 00 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e |.............0..| +00000060 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................| +00000070 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................| +00000080 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |..............| >>> Flow 2 (server to client) 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..| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......| 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............| @@ -57,38 +53,37 @@ 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 d9 |......_X.;t.....| -000002d0 5f d9 85 1f 13 34 60 85 c8 eb 27 79 14 ed 84 77 |_....4`...'y...w| -000002e0 98 60 72 ce ee b9 92 87 50 4b 4a f8 25 7f 8d 92 |.`r.....PKJ.%...| -000002f0 16 2a 19 65 96 b4 30 af fd 1b fe 1c 02 1f f4 77 |.*.e..0........w| -00000300 6f 63 53 7c 54 a0 89 5d e9 32 b3 a9 5f e6 4b 60 |ocS|T..].2.._.K`| -00000310 8b b1 c8 d2 61 8b 19 59 f3 5a b4 e2 71 16 b8 32 |....a..Y.Z..q..2| -00000320 1f 8c 74 e2 4e 17 56 7e 69 01 39 8c c1 cf c7 0b |..t.N.V~i.9.....| -00000330 56 c6 f6 c0 37 7b 3d 65 48 40 6b a0 67 e6 cd 70 |V...7{=eH@k.g..p| -00000340 ce 8c 73 d4 e9 ba c0 04 18 b3 37 06 71 66 72 16 |..s.......7.qfr.| +000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 89 |......_X.;t.....| +000002d0 f8 62 c5 1a ba 78 74 da 6f 96 76 00 0f 6b a9 fb |.b...xt.o.v..k..| +000002e0 83 d4 52 c0 80 0b 81 02 e3 b0 07 c2 9d ff b4 cc |..R.............| +000002f0 ea 2e c7 82 91 35 74 ef 1e 9a ba 78 3e 60 6c 86 |.....5t....x>`l.| +00000300 1d b0 14 52 84 84 70 ce 66 22 31 66 e2 53 04 bd |...R..p.f"1f.S..| +00000310 4d 2b 5e 86 8b 79 dc 17 7a 4f bc 62 5a 21 a1 f6 |M+^..y..zO.bZ!..| +00000320 46 1a 12 aa 7a 98 25 02 97 a8 9c 71 a4 4a 5b 28 |F...z.%....q.J[(| +00000330 c8 11 6a 5f f1 b3 13 a7 f2 26 12 59 02 fa 28 e2 |..j_.....&.Y..(.| +00000340 ba 8c c0 cd 50 c6 60 db 69 9a a1 92 12 26 23 16 |....P.`.i....&#.| 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 d5 13 c6 90 e0 4a |....%...! .....J| -00000010 25 2f 5d cd 02 d8 fd 14 61 78 dd fc 42 57 ce bd |%/].....ax..BW..| -00000020 e0 47 b8 cf 42 59 1c 7f 1f 1e 14 03 03 00 01 01 |.G..BY..........| -00000030 16 03 03 00 28 96 2c 78 25 ee 20 88 53 69 57 96 |....(.,x%. .SiW.| -00000040 d9 d2 53 6c 5b 5b e9 db 7d 0a 7c f9 16 27 43 df |..Sl[[..}.|..'C.| -00000050 a9 e2 a6 e5 be c5 e9 d5 ff df 66 6b 81 |..........fk.| +00000000 16 03 03 00 25 10 00 00 21 20 ba 1b c8 ae 22 78 |....%...! ...."x| +00000010 84 ba d8 1c b3 87 52 f0 bf 13 76 2b a5 47 37 13 |......R...v+.G7.| +00000020 30 89 01 13 1a cb 63 ea b3 37 14 03 03 00 01 01 |0.....c..7......| +00000030 16 03 03 00 20 ac d7 79 45 e6 65 1d 20 1a 95 5e |.... ..yE.e. ..^| +00000040 68 f7 0f ee 8c 3f 3d 0b bc 58 31 aa 46 d7 e3 00 |h....?=..X1.F...| +00000050 7b 10 8c 01 5d |{...]| >>> Flow 4 (server to client) 00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 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 51 ed 14 ef 68 ca 42 c5 4c c7 ea d3 |o...Q...h.B.L...| -00000040 9f e6 77 db 30 96 5c e3 bc f8 b7 c7 74 9d 0e 97 |..w.0.\.....t...| -00000050 cf 3c ec 76 c8 9e ad 0c 49 86 9e 4f 4d 56 ce 95 |.<.v....I..OMV..| -00000060 7f 75 79 aa dd 8e 66 8f 1f d8 01 2d c1 49 38 16 |.uy...f....-.I8.| -00000070 b3 7a 6b 8d 3d ba 2b 81 4c 1c 75 c3 06 bb 8c 1e |.zk.=.+.L.u.....| -00000080 df 59 35 29 5b d1 54 cc 5c 6b 37 74 29 19 0f 8b |.Y5)[.T.\k7t)...| -00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....| -000000a0 00 00 00 c7 19 9a c9 cc 16 3b 8f b7 52 de 4c ab |.........;..R.L.| -000000b0 90 83 b1 b5 60 0d c0 49 c4 28 f7 1d 1f e9 e0 b1 |....`..I.(......| -000000c0 21 a1 49 17 03 03 00 25 00 00 00 00 00 00 00 01 |!.I....%........| -000000d0 46 fe 03 14 ad 32 d5 ff 89 1f 08 15 6b 44 4f 2d |F....2......kDO-| -000000e0 5e d6 f1 35 d9 c4 c4 cc bf 5a 26 df a6 15 03 03 |^..5.....Z&.....| -000000f0 00 1a 00 00 00 00 00 00 00 02 4f 7b 8e 22 3c 85 |..........O{."<.| -00000100 5c 41 f5 17 0d dd c8 41 b5 ef 5a 4c |\A.....A..ZL| +00000030 6f e0 18 83 51 ed 14 ef 68 ca 42 c5 4c f8 79 c6 |o...Q...h.B.L.y.| +00000040 80 85 74 9c 35 6f 4e 9d 60 0b a2 28 b0 45 b6 f6 |..t.5oN.`..(.E..| +00000050 71 a3 f6 a6 95 71 cd 1e 53 e9 58 9f 94 18 ac d6 |q....q..S.X.....| +00000060 6b 03 ba ac b4 4f c2 02 cc 1c 5b 88 84 49 38 16 |k....O....[..I8.| +00000070 d9 5e b8 11 ab c6 f8 a7 9d 5d 58 99 b1 b6 8a be |.^.......]X.....| +00000080 4e 9e 40 3d 00 22 11 25 c7 51 8e cb d2 10 d4 7d |N.@=.".%.Q.....}| +00000090 14 03 03 00 01 01 16 03 03 00 20 ff 4b 1e 87 3e |.......... .K..>| +000000a0 05 5c b4 3e e4 b9 5c 47 f0 a2 0b 67 47 89 c6 48 |.\.>..\G...gG..H| +000000b0 d5 e3 73 d2 00 44 56 e4 8d b6 fb 17 03 03 00 1d |..s..DV.........| +000000c0 58 28 94 02 c2 a9 99 3d b6 0b de 9c fd 52 61 bf |X(.....=.....Ra.| +000000d0 55 c0 12 7f be a8 52 98 d7 99 a5 d0 60 15 03 03 |U.....R.....`...| +000000e0 00 12 26 44 ad f0 a7 56 e5 23 6f 1b 7a 7e f8 e4 |..&D...V.#o.z~..| +000000f0 42 49 5d 1d |BI].| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket index 73d01585eb6..f70c75993c1 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 71 01 00 00 6d 03 03 60 fd 9b 74 aa |....q...m..`..t.| -00000010 16 9f 07 32 7e 57 d0 91 86 ea 59 b7 f3 38 bb 4f |...2~W....Y..8.O| -00000020 7f 2c 36 eb 67 21 57 f2 12 2b 38 00 00 04 00 2f |.,6.g!W..+8..../| +00000000 16 03 01 00 71 01 00 00 6d 03 03 3d 21 91 3a 4e |....q...m..=!.:N| +00000010 8e cd 65 eb 0f 1c ae 2a 58 40 4c 38 22 c9 46 2c |..e....*X@L8".F,| +00000020 b8 cd dd 38 ad c6 4b a7 60 a9 56 00 00 04 00 2f |...8..K.`.V..../| 00000030 00 ff 01 00 00 40 00 23 00 00 00 16 00 00 00 17 |.....@.#........| 00000040 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| 00000050 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................| @@ -52,40 +52,40 @@ 00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| 000002a0 00 |.| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 2c d6 6d 84 0c |...........,.m..| -00000010 d9 ef 52 bb cc 0b 41 47 d7 64 c7 a6 b0 fa 3c 6f |..R...AG.d......p..S..| +00000060 2c 7e a9 42 25 e5 3a e2 55 3f 19 57 6b 83 43 6a |,~.B%.:.U?.Wk.Cj| +00000070 93 34 2c 6e cb 4e 9d 25 8b 4d 7d d7 cc e1 16 59 |.4,n.N.%.M}....Y| +00000080 2a 95 60 e4 31 0e df 7f cb 9d b7 14 03 03 00 01 |*.`.1...........| +00000090 01 16 03 03 00 40 28 33 df 69 4f 4c 48 b1 fb 8d |.....@(3.iOLH...| +000000a0 3f 3c d2 81 7c 33 cf 21 6a f7 d6 43 82 22 5b de |?<..|3.!j..C."[.| +000000b0 46 7f 7b e2 39 23 bd 39 fa 03 bd 11 9d a8 a2 84 |F.{.9#.9........| +000000c0 4a 90 1a ab e1 b4 23 9f 72 d0 97 9e 05 5c 47 2b |J.....#.r....\G+| +000000d0 7a 53 bb ec a0 07 |zS....| >>> Flow 4 (server to client) 00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 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 51 ed 14 ef 68 ca 42 c5 4c 92 cc 13 |o,..Q...h.B.L...| -00000040 05 4e 15 de 98 0a 74 d5 a9 2e 80 89 98 89 72 39 |.N....t.......r9| -00000050 5f fe 49 56 66 ac 4d 73 b1 5b 4b 81 db 25 a7 5b |_.IVf.Ms.[K..%.[| -00000060 54 5b 10 13 3d 96 71 d7 b7 23 53 ea 62 49 38 16 |T[..=.q..#S.bI8.| -00000070 cc 4f 0d 9d 80 99 6e 0f 01 b3 d7 e4 8a 75 d1 b6 |.O....n......u..| -00000080 7b 74 80 b2 b8 06 a9 71 6b 31 2a fd cf 6e 44 dc |{t.....qk1*..nD.| +00000030 6f 2c 9f 83 51 ed 14 ef 68 ca 42 c5 4c 75 5e a5 |o,..Q...h.B.Lu^.| +00000040 6f d2 49 61 e4 fb 83 46 7c 4c ab f9 c6 d1 3c 9e |o.Ia...F|L....<.| +00000050 5b 8d d8 bc c0 a5 2d 84 db 24 dd a0 16 60 1d 87 |[.....-..$...`..| +00000060 a0 52 88 25 6c c6 8e 5b 71 0f 74 c3 48 49 38 16 |.R.%l..[q.t.HI8.| +00000070 92 8c de 77 bd 8a 2b 45 4d 58 86 40 b1 d6 0f 99 |...w..+EMX.@....| +00000080 de 27 41 b2 41 27 aa fe 26 e9 24 91 2a 00 ff 08 |.'A.A'..&.$.*...| 00000090 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -000000a0 00 00 00 00 00 00 00 00 00 00 00 76 c4 85 3d 05 |...........v..=.| -000000b0 60 a2 b3 ce 38 7f 1c f9 e3 19 87 b0 e1 af 08 b7 |`...8...........| -000000c0 15 90 50 b9 51 85 c4 88 90 52 cd 6d b6 69 ee b5 |..P.Q....R.m.i..| -000000d0 36 a8 0c 61 c4 78 09 6a 49 4d e9 17 03 03 00 40 |6..a.x.jIM.....@| +000000a0 00 00 00 00 00 00 00 00 00 00 00 fc cd 6b 01 90 |.............k..| +000000b0 7b 0c 31 54 a0 3a 8b f7 ba 45 e7 e0 df 9a 59 6d |{.1T.:...E....Ym| +000000c0 83 b6 b2 c8 93 d8 d9 b6 fe 19 56 51 75 a3 ea 0e |..........VQu...| +000000d0 f4 4b 64 27 66 fc 19 7b 7e 13 e7 17 03 03 00 40 |.Kd'f..{~......@| 000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -000000f0 76 31 e3 05 f8 b3 05 ca e2 55 84 b9 15 85 5d 4a |v1.......U....]J| -00000100 83 a5 76 db b0 5f b9 65 b4 21 3e 00 36 9a e8 d7 |..v.._.e.!>.6...| -00000110 02 81 23 83 19 13 c8 9c cd 02 ae 10 b9 cf 75 96 |..#...........u.| +000000f0 c2 1b 6f f1 1e 05 1b 8a 19 16 67 00 0f dc a8 a2 |..o.......g.....| +00000100 00 56 49 0a bb c5 df 7e 96 0c 5c db a0 f4 3e b4 |.VI....~..\...>.| +00000110 30 3e b6 f0 16 dd d4 ed c9 de 64 49 00 9b 51 dc |0>........dI..Q.| 00000120 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -00000130 00 00 00 00 00 f9 ae b4 16 27 75 dc 72 4d 39 0e |.........'u.rM9.| -00000140 ba 1f 31 b2 39 ec 99 36 bc 41 34 03 54 9b de 7b |..1.9..6.A4.T..{| -00000150 4b 65 ef 99 a6 |Ke...| +00000130 00 00 00 00 00 e1 9d 08 1a 2e 9a 0f 84 6d 4e e5 |.............mN.| +00000140 2c 50 b9 28 5d 88 ea bb 48 4d af 26 7f 82 0b 56 |,P.(]...HM.&...V| +00000150 c5 87 71 2a e7 |..q*.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable index c50fbcedf7e..8cb57f5e951 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 71 01 00 00 6d 03 03 98 eb fe 13 a7 |....q...m.......| -00000010 81 d8 8b 0b c6 78 c3 44 ce f7 7b 63 d1 7c 61 4d |.....x.D..{c.|aM| -00000020 be fe 52 5f c0 24 88 c2 85 d1 40 00 00 04 00 2f |..R_.$....@..../| +00000000 16 03 01 00 71 01 00 00 6d 03 03 e1 40 35 c8 5c |....q...m...@5.\| +00000010 71 63 3f 5a 00 42 e6 3e 64 62 b8 c4 e7 e7 ba 98 |qc?Z.B.>db......| +00000020 d8 fa 2c b5 65 f7 50 db 43 d9 70 00 00 04 00 2f |..,.e.P.C.p..../| 00000030 00 ff 01 00 00 40 00 23 00 00 00 16 00 00 00 17 |.....@.#........| 00000040 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........| 00000050 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................| @@ -52,40 +52,40 @@ 00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........| 000002a0 00 |.| >>> Flow 3 (client to server) -00000000 16 03 03 00 86 10 00 00 82 00 80 11 4c a1 a0 ba |............L...| -00000010 12 83 63 98 3c 1a 5d df a2 01 b6 6c 05 ec a1 1e |..c.<.]....l....| -00000020 dc a5 6b b9 97 c3 76 51 06 45 4b 74 9e 1b 61 0f |..k...vQ.EKt..a.| -00000030 9e d3 c7 db 7f d3 ee 23 1a 32 66 0f 2f 2c d3 52 |.......#.2f./,.R| -00000040 e0 ec cc 31 71 d4 e6 2b b6 95 78 0b eb c9 70 b1 |...1q..+..x...p.| -00000050 77 09 6f 8d 6d 8d 1b d7 b2 38 96 d3 f0 a2 94 37 |w.o.m....8.....7| -00000060 14 ed d8 d6 b5 1e bc 71 b2 35 68 76 5b 10 dc 8f |.......q.5hv[...| -00000070 de 9d 1d b5 59 d0 f1 04 70 9b 74 a9 af 7f b6 6b |....Y...p.t....k| -00000080 de 29 5a fd 8f 95 cd 2c d6 b9 18 14 03 03 00 01 |.)Z....,........| -00000090 01 16 03 03 00 40 02 70 cb 83 3c 42 32 58 9f 05 |.....@.p..>> Flow 4 (server to client) 00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P| 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 51 ed 14 ef 68 ca 42 c5 4c 3e 73 fe |o,..Q...h.B.L>s.| -00000040 72 ef 06 25 96 ef 3d 89 51 22 e3 10 57 02 e5 69 |r..%..=.Q"..W..i| -00000050 aa d0 6d ad 66 b3 4c 07 fc ba a4 1e 3a ad a2 3b |..m.f.L.....:..;| -00000060 40 f7 7d 9a 11 8e a0 9e 54 c5 7c 53 7d 49 38 16 |@.}.....T.|S}I8.| -00000070 43 a6 1b 37 8e aa 02 78 25 9b 06 54 13 54 de 6a |C..7...x%..T.T.j| -00000080 ae 62 72 97 47 1d f8 0a 32 c3 86 93 0e 64 cc 04 |.br.G...2....d..| +00000030 6f 2c 9f 83 51 ed 14 ef 68 ca 42 c5 4c 20 33 6c |o,..Q...h.B.L 3l| +00000040 01 97 a5 69 44 bf 8f ea db 83 05 fb ef cc 51 1f |...iD.........Q.| +00000050 0b 4d 44 77 89 11 cf c8 38 16 67 ea a2 3e 8b 2a |.MDw....8.g..>.*| +00000060 18 f2 f7 25 ce e0 d8 4c 93 31 b0 59 23 49 38 16 |...%...L.1.Y#I8.| +00000070 3a f9 63 9e 61 21 1b ab 67 09 6a 23 07 8e d0 4a |:.c.a!..g.j#...J| +00000080 19 78 9c 1e 60 40 a7 83 c5 9a 48 41 35 c4 e9 63 |.x..`@....HA5..c| 00000090 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....| -000000a0 00 00 00 00 00 00 00 00 00 00 00 ac 24 92 7d 6c |............$.}l| -000000b0 d5 fe a8 a7 b7 45 fe 58 f6 13 02 ed de c8 ba 44 |.....E.X.......D| -000000c0 18 59 1e f9 06 82 2f 42 22 62 5a 82 4d 70 9a c3 |.Y..../B"bZ.Mp..| -000000d0 41 55 b0 66 ae e2 b1 1d d9 38 0a 17 03 03 00 40 |AU.f.....8.....@| +000000a0 00 00 00 00 00 00 00 00 00 00 00 b8 46 07 9e 14 |............F...| +000000b0 85 ba 6d e0 f1 f5 99 43 80 9a 54 6b 33 1e 4f c1 |..m....C..Tk3.O.| +000000c0 88 b7 3d 60 04 d4 e9 b0 b2 6d c4 1a ca 3b 9f 83 |..=`.....m...;..| +000000d0 28 5f ea b2 54 e4 11 78 69 de 1a 17 03 03 00 40 |(_..T..xi......@| 000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -000000f0 bd 16 9e 9c f2 9b 0d f8 f1 42 ba f3 38 64 69 ac |.........B..8di.| -00000100 4a c9 25 d7 03 0b ec 8f 53 14 26 68 da b7 43 34 |J.%.....S.&h..C4| -00000110 18 cd 66 dc 36 5e f5 16 ca 18 78 37 89 8a d5 9d |..f.6^....x7....| +000000f0 55 34 ad ae 9b 37 df cd 88 ae fc 6a ac c5 cf 16 |U4...7.....j....| +00000100 ec f1 bc 22 1e d2 c1 52 5e a2 e7 d2 6e 37 7a 29 |..."...R^...n7z)| +00000110 c8 b9 d4 7d 81 63 1a f0 53 d9 10 fd 4f 3d 1c dd |...}.c..S...O=..| 00000120 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -00000130 00 00 00 00 00 64 f9 5c df db 60 b7 22 15 77 29 |.....d.\..`.".w)| -00000140 33 6f 93 22 81 c4 e5 71 af 27 60 e5 76 5f a6 f6 |3o."...q.'`.v_..| -00000150 e0 73 87 9f ed |.s...| +00000130 00 00 00 00 00 8f f2 11 0d 93 99 83 29 d4 10 a4 |............)...| +00000140 7c bb 26 7b 24 f1 15 3a 9b 81 0e cb 0a 51 4b 39 ||.&{$..:.....QK9| +00000150 69 1d e5 38 5e |i..8^| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 index 0e9be7fbdb0..b193771e4ea 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 @@ -1,18 +1,14 @@ >>> Flow 1 (client to server) -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./.....:....| -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 04 01 |......| +00000000 16 03 01 00 59 01 00 00 55 03 03 60 c3 e9 6a 99 |....Y...U..`..j.| +00000010 72 7a 1c b9 1e 10 4b 9a 82 d5 ea b9 b0 6f 1e 05 |rz....K......o..| +00000020 74 a4 35 bb 71 c7 d2 56 87 b8 69 00 00 04 cc a8 |t.5.q..V..i.....| +00000030 00 ff 01 00 00 28 00 0b 00 04 03 00 01 02 00 0a |.....(..........| +00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000050 00 00 00 17 00 00 00 0d 00 04 00 02 04 01 |..............| >>> Flow 2 (server to client) 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..| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......| 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 |..............?.| @@ -54,29 +50,28 @@ 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......| +000002c0 90 99 5f 58 cb 3b 74 04 01 00 80 4e c9 fd 39 89 |.._X.;t....N..9.| +000002d0 52 c1 6b ba 3b c9 02 35 89 e8 e3 f8 41 15 ee 6d |R.k.;..5....A..m| +000002e0 f6 08 6d 1a 47 aa 3b 5c 1d 9b 42 9b 50 85 af 56 |..m.G.;\..B.P..V| +000002f0 a3 99 78 84 7f 06 91 97 e9 33 0d 1d 9b 17 ce 3b |..x......3.....;| +00000300 30 f2 d0 10 1c b6 e2 7d fd b3 e1 bc 14 7a 1a 96 |0......}.....z..| +00000310 be b9 dc 0d 29 33 84 5f d1 77 91 0a a1 f2 2b cc |....)3._.w....+.| +00000320 dc 5e 9b f9 8b e3 34 d2 bd f3 46 b4 0d 97 de 44 |.^....4...F....D| +00000330 aa 83 10 82 bd ca 83 27 d0 40 a7 b1 64 15 dd 84 |.......'.@..d...| +00000340 5f 3c d9 62 42 0d 8f a6 19 0f b1 16 03 03 00 04 |_<.bB...........| 00000350 0e 00 00 00 |....| >>> Flow 3 (client to server) -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| +00000000 16 03 03 00 25 10 00 00 21 20 82 3a 50 41 f7 b1 |....%...! .:PA..| +00000010 0f 97 ba 38 04 db f3 a6 ec 8b d1 db 06 c1 84 89 |...8............| +00000020 a0 53 84 92 27 a2 53 e8 5d 21 14 03 03 00 01 01 |.S..'.S.]!......| +00000030 16 03 03 00 20 7d 80 6d 7f a9 28 d6 0d 50 d6 b4 |.... }.m..(..P..| +00000040 24 d3 92 f8 0b 8e 6b d8 7c 64 9e 6c 87 a9 8e 37 |$.....k.|d.l...7| +00000050 9e 1b 0b 2d a5 |...-.| >>> 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 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| +00000000 14 03 03 00 01 01 16 03 03 00 20 e4 58 cf fb 81 |.......... .X...| +00000010 be dd 5b 98 97 bd bd 6a f0 76 92 b6 bb 2c 8f a3 |..[....j.v...,..| +00000020 e5 52 5b 1d f4 17 7b 2a a8 40 26 17 03 03 00 1d |.R[...{*.@&.....| +00000030 58 ef 4f 1d 98 0f 3d 59 88 df 6e ac c9 37 43 d5 |X.O...=Y..n..7C.| +00000040 f5 58 b3 7a 62 a3 7d 26 a2 a2 80 23 ef 15 03 03 |.X.zb.}&...#....| +00000050 00 12 05 b8 57 6a 80 71 b6 a4 58 94 15 f4 2f 0c |....Wj.q..X.../.| +00000060 8e 76 b2 aa |.v..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS index 465d8db01f6..af4c069fade 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS @@ -1,18 +1,14 @@ >>> Flow 1 (client to server) -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 06 |......| +00000000 16 03 01 00 5b 01 00 00 57 03 03 e0 83 fd ef f8 |....[...W.......| +00000010 cb 41 23 14 36 21 07 eb 4e 01 7d 80 63 e4 b9 45 |.A#.6!..N.}.c..E| +00000020 f0 84 72 71 9b ac 60 49 6c 70 74 00 00 04 cc a8 |..rq..`Ilpt.....| +00000030 00 ff 01 00 00 2a 00 0b 00 04 03 00 01 02 00 0a |.....*..........| +00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000050 00 00 00 17 00 00 00 0d 00 06 00 04 08 06 08 04 |................| >>> Flow 2 (server to client) 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..| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......| 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 |..............?.| @@ -51,5 +47,31 @@ 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 |(| +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 58 d3 5f 28 bc |.._X.;t....X._(.| +000002d0 50 79 b9 3d f1 ac a1 af 52 cd d3 fd e7 75 47 c3 |Py.=....R....uG.| +000002e0 65 3a 6f 62 22 c2 b5 cc 2b 22 f3 5d 3f b5 b6 9e |e:ob"...+".]?...| +000002f0 57 bf c7 4e 08 bd fb 5a 17 13 09 1a e9 6c b6 ce |W..N...Z.....l..| +00000300 b2 0e 88 ae ba a3 a0 b5 2c ff 51 b5 87 95 14 09 |........,.Q.....| +00000310 6d 9c 73 3f f0 c7 40 6b 4c ca 40 96 d6 44 96 d0 |m.s?..@kL.@..D..| +00000320 6f b1 a0 1c 4f 66 cc 9b 4f 85 98 3c 03 68 e3 a8 |o...Of..O..<.h..| +00000330 5b 28 04 fb 1e be 9e 2a 66 c1 6e f1 2e a4 20 08 |[(.....*f.n... .| +00000340 7e 11 78 7b fc c4 43 af 2a b4 8b 16 03 03 00 04 |~.x{..C.*.......| +00000350 0e 00 00 00 |....| +>>> Flow 3 (client to server) +00000000 16 03 03 00 25 10 00 00 21 20 e2 54 7d 82 d2 8d |....%...! .T}...| +00000010 b8 d6 87 17 ec 2a 64 4e 15 6b b0 b3 01 66 b0 7d |.....*dN.k...f.}| +00000020 73 20 9f cb 30 9d 3c 27 ac 13 14 03 03 00 01 01 |s ..0.<'........| +00000030 16 03 03 00 20 fa a0 b7 eb ef 49 97 d5 da f0 9d |.... .....I.....| +00000040 85 a6 e6 67 f3 30 e8 f0 82 3a 7a c4 3f 76 f6 c5 |...g.0...:z.?v..| +00000050 8f d3 a5 65 f3 |...e.| +>>> Flow 4 (server to client) +00000000 14 03 03 00 01 01 16 03 03 00 20 6b cf 58 e1 52 |.......... k.X.R| +00000010 e3 2c 05 e6 a3 05 c1 36 02 f0 90 63 bb 86 0f 54 |.,.....6...c...T| +00000020 61 d7 1a 31 7d bd 08 00 22 71 09 17 03 03 00 1d |a..1}..."q......| +00000030 4a 8e 05 28 e3 77 31 43 be ac 32 c6 af f2 7b 1c |J..(.w1C..2...{.| +00000040 ab 11 7f 32 5a 6a eb 76 ac c6 eb f1 dc 15 03 03 |...2Zj.v........| +00000050 00 12 3a f1 ee a3 6f bf 9b 9e 5e b8 20 76 84 bc |..:...o...^. v..| +00000060 1e 2e a0 87 |....| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume b/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume index e8205b743d7..456fe2a17d1 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume @@ -1,18 +1,18 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 12 01 00 01 0e 03 03 3e 4f b2 97 44 |...........>O..D| -00000010 64 a4 e1 33 32 21 98 ea c1 8c 3f 7b 5f 47 e6 54 |d..32!....?{_G.T| -00000020 bf f1 a9 fd fb 5c 1e c9 23 7a 12 20 42 f6 4f a1 |.....\..#z. B.O.| -00000030 85 90 ad 50 2b 3b 24 f7 2e 48 1f 2d 5b 0d fe 77 |...P+;$..H.-[..w| -00000040 07 2b cb e9 03 23 d9 24 04 05 4e 26 00 04 00 2f |.+...#.$..N&.../| +00000000 16 03 01 01 12 01 00 01 0e 03 03 90 27 78 df 71 |............'x.q| +00000010 d3 0e ce 1d de ec d2 1b 70 e0 89 da 98 a9 45 3e |........p.....E>| +00000020 9c ee 93 90 8f 61 d0 a3 b4 a4 5a 20 9d cd d4 81 |.....a....Z ....| +00000030 e2 c0 59 81 21 bc 9f 2a 84 3e 91 15 3e b9 c0 a1 |..Y.!..*.>..>...| +00000040 e0 6b 73 9c 45 53 03 ad b9 e6 c2 77 00 04 00 2f |.ks.ES.....w.../| 00000050 00 ff 01 00 00 c1 00 23 00 81 50 46 ad c1 db a8 |.......#..PF....| 00000060 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 00 |8.{+....B>......| 00000070 00 00 00 00 00 00 00 00 00 00 94 6f 2c 9f 83 51 |...........o,..Q| -00000080 ed 14 ef 68 ca 42 c5 4c 92 cc 13 05 4e 15 de 98 |...h.B.L....N...| -00000090 0a 74 d5 a9 2e 80 89 98 89 72 39 5f fe 49 56 66 |.t.......r9_.IVf| -000000a0 ac 4d 73 b1 5b 4b 81 db 25 a7 5b 54 5b 10 13 3d |.Ms.[K..%.[T[..=| -000000b0 96 71 d7 b7 23 53 ea 62 49 38 16 cc 4f 0d 9d 80 |.q..#S.bI8..O...| -000000c0 99 6e 0f 01 b3 d7 e4 8a 75 d1 b6 7b 74 80 b2 b8 |.n......u..{t...| -000000d0 06 a9 71 6b 31 2a fd cf 6e 44 dc 00 16 00 00 00 |..qk1*..nD......| +00000080 ed 14 ef 68 ca 42 c5 4c 75 5e a5 6f d2 49 61 e4 |...h.B.Lu^.o.Ia.| +00000090 fb 83 46 7c 4c ab f9 c6 d1 3c 9e 5b 8d d8 bc c0 |..F|L....<.[....| +000000a0 a5 2d 84 db 24 dd a0 16 60 1d 87 a0 52 88 25 6c |.-..$...`...R.%l| +000000b0 c6 8e 5b 71 0f 74 c3 48 49 38 16 92 8c de 77 bd |..[q.t.HI8....w.| +000000c0 8a 2b 45 4d 58 86 40 b1 d6 0f 99 de 27 41 b2 41 |.+EMX.@.....'A.A| +000000d0 27 aa fe 26 e9 24 91 2a 00 ff 08 00 16 00 00 00 |'..&.$.*........| 000000e0 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 |......0.........| 000000f0 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 |................| 00000100 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 |................| @@ -20,27 +20,27 @@ >>> Flow 2 (server to client) 00000000 16 03 03 00 51 02 00 00 4d 03 03 00 00 00 00 00 |....Q...M.......| 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 42 f6 4f a1 |...DOWNGRD. B.O.| -00000030 85 90 ad 50 2b 3b 24 f7 2e 48 1f 2d 5b 0d fe 77 |...P+;$..H.-[..w| -00000040 07 2b cb e9 03 23 d9 24 04 05 4e 26 00 2f 00 00 |.+...#.$..N&./..| +00000020 00 00 00 44 4f 57 4e 47 52 44 01 20 9d cd d4 81 |...DOWNGRD. ....| +00000030 e2 c0 59 81 21 bc 9f 2a 84 3e 91 15 3e b9 c0 a1 |..Y.!..*.>..>...| +00000040 e0 6b 73 9c 45 53 03 ad b9 e6 c2 77 00 2f 00 00 |.ks.ES.....w./..| 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 dc 9b ca 90 7b f0 70 bc 17 76 9c fb a7 74 49 |.....{.p..v...tI| -00000080 0c 9f 3c 31 76 77 9b af 6a e0 00 a6 54 81 4a d5 |..<1vw..j...T.J.| -00000090 de fa 75 cb d6 b4 b2 6c bc f4 30 7a a1 56 0a f5 |..u....l..0z.V..| -000000a0 5c |\| +00000070 00 57 8e 5f 0a f6 3f 3b 43 f1 33 bc ef 5e c6 8d |.W._..?;C.3..^..| +00000080 86 92 58 58 71 51 e8 54 57 96 5f bd 36 3a 9f d3 |..XXqQ.TW._.6:..| +00000090 e9 27 01 bf fb 6a 05 57 de 2d db b2 79 38 72 95 |.'...j.W.-..y8r.| +000000a0 fd |.| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 16 03 03 00 40 cb 74 dc ec f5 |..........@.t...| -00000010 ad ab c5 8e dc da 50 89 28 7b cc 0f 06 87 9a 19 |......P.({......| -00000020 dd 4e 40 38 1d 8f 95 6f 0e 62 5f cb 7c db ab 24 |.N@8...o.b_.|..$| -00000030 df 03 ef 7c 83 12 0e 3d 25 e8 de cf d0 aa 0e 91 |...|...=%.......| -00000040 20 9b 38 39 4e 39 70 3c 0a ce c8 | .89N9p<...| +00000000 14 03 03 00 01 01 16 03 03 00 40 6d 3c 76 31 a4 |..........@m.5v...K.| +00000020 01 f8 a8 83 0c eb 58 f7 d6 93 c6 b6 40 0e c8 24 |......X.....@..$| +00000030 46 58 0c 79 4a c6 b4 15 65 1e 9c bd ff 51 4d d0 |FX.yJ...e....QM.| +00000040 44 66 fe c0 98 d5 26 11 98 cf 52 |Df....&...R| >>> 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 d1 5b 42 2c 10 9b 48 97 cf 8e 69 |......[B,..H...i| -00000020 a4 b4 62 65 d9 f1 1f 86 07 f1 6c cd 5b 18 6e c7 |..be......l.[.n.| -00000030 8d 57 20 3d f9 3f 68 1b 12 7b 29 13 b9 8d fe 7b |.W =.?h..{)....{| -00000040 ad 52 22 c4 94 15 03 03 00 30 00 00 00 00 00 00 |.R"......0......| -00000050 00 00 00 00 00 00 00 00 00 00 31 ae ae 06 b7 2c |..........1....,| -00000060 5f a4 fc 8f a6 33 2b 42 1a f5 d5 b9 ad a4 fc a0 |_....3+B........| -00000070 bc e9 c8 5d 4d 26 83 38 ca 57 |...]M&.8.W| +00000010 00 00 00 00 00 4e 8e bd e5 c8 d4 1a 14 00 f1 ed |.....N..........| +00000020 c4 88 b3 5c 92 b9 ad 8a 68 d4 f3 85 1b 02 25 aa |...\....h.....%.| +00000030 a0 65 49 08 0d 2a b4 0a 64 eb ea ab 06 73 08 ca |.eI..*..d....s..| +00000040 62 c9 56 45 a9 15 03 03 00 30 00 00 00 00 00 00 |b.VE.....0......| +00000050 00 00 00 00 00 00 00 00 00 00 60 51 ae 81 79 6d |..........`Q..ym| +00000060 91 95 02 42 30 3f c4 3c 2b fc 74 47 a7 a9 17 22 |...B0?.<+.tG..."| +00000070 88 26 6d 18 b9 8f ad 43 e3 b0 |.&m....C..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled b/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled index 2adf5862096..339fd9a0f2f 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled +++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ResumeDisabled @@ -1,94 +1,91 @@ >>> Flow 1 (client to server) -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 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 |........| +00000000 16 03 01 01 12 01 00 01 0e 03 03 b8 aa 9b e6 98 |................| +00000010 be 93 d6 03 f2 cd 62 23 76 dd 74 6c 48 ac 9a f6 |......b#v.tlH...| +00000020 f3 27 62 93 6e 99 b2 0d 54 af b7 20 2d 20 97 9a |.'b.n...T.. - ..| +00000030 c8 88 50 65 95 2a 02 8f 7b 47 77 6d 3c 49 ba a9 |..Pe.*..{Gwm......| +00000070 00 00 00 00 00 00 00 00 00 00 94 6f 2c 9f 83 51 |...........o,..Q| +00000080 ed 14 ef 68 ca 42 c5 4c 20 33 6c 01 97 a5 69 44 |...h.B.L 3l...iD| +00000090 bf 8f ea db 83 05 fb ef cc 51 1f 0b 4d 44 77 89 |.........Q..MDw.| +000000a0 11 cf c8 38 16 67 ea a2 3e 8b 2a 18 f2 f7 25 ce |...8.g..>.*...%.| +000000b0 e0 d8 4c 93 31 b0 59 23 49 38 16 3a f9 63 9e 61 |..L.1.Y#I8.:.c.a| +000000c0 21 1b ab 67 09 6a 23 07 8e d0 4a 19 78 9c 1e 60 |!..g.j#...J.x..`| +000000d0 40 a7 83 c5 9a 48 41 35 c4 e9 63 00 16 00 00 00 |@....HA5..c.....| +000000e0 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 |......0.........| +000000f0 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 |................| +00000100 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 |................| +00000110 02 04 02 05 02 06 02 |.......| >>> Flow 2 (server to client) -00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......| +00000000 16 03 03 00 31 02 00 00 2d 03 03 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 01 00 00 2f 00 00 |...DOWNGRD.../..| -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 |...| +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 |;............| >>> Flow 3 (client to server) -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 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.$:$....@| +00000010 00 00 00 00 00 00 00 00 00 00 00 67 e1 22 17 24 |...........g.".$| +00000020 95 b4 e5 62 59 15 56 4a af e4 82 76 ad b7 48 81 |...bY.VJ...v..H.| +00000030 cf 55 d1 75 cd 36 86 0d 9d 15 24 4b 84 23 bc 98 |.U.u.6....$K.#..| +00000040 8e c4 62 57 ab 96 0c 27 5d 1c 07 17 03 03 00 40 |..bW...']......@| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -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..| +00000060 c9 b2 0e 04 40 43 26 92 91 45 e3 63 d7 49 09 3e |....@C&..E.c.I.>| +00000070 03 45 e3 d6 af a2 d8 d9 61 36 e5 95 83 75 66 fa |.E......a6...uf.| +00000080 90 c2 80 53 a2 d5 31 aa b1 2a da 45 a9 b3 aa 1f |...S..1..*.E....| 00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........| -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.| +000000a0 00 00 00 00 00 c4 52 cf b9 f6 0f e2 30 ba 90 18 |......R.....0...| +000000b0 0c 76 c2 ee 4c 78 fb c2 cb 34 7f cb 35 15 5e b0 |.v..Lx...4..5.^.| +000000c0 17 70 cb 76 8a |.p.v.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-ALPN b/libgo/go/crypto/tls/testdata/Server-TLSv13-ALPN index 4ac9f1d7d4e..df8dd4508ab 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-ALPN +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-ALPN @@ -1,104 +1,100 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 f8 01 00 00 f4 03 03 65 16 78 26 cc |...........e.x&.| -00000010 27 bc 06 a0 4c f5 a3 e3 cd c2 f0 42 8c 61 0e e9 |'...L......B.a..| -00000020 8b 2b 52 ca a3 07 d6 58 96 4f f1 20 c3 7f e3 22 |.+R....X.O. ..."| -00000030 2c 27 94 91 ab cc e5 56 b1 31 fb eb ed b4 84 3e |,'.....V.1.....>| -00000040 ae 93 6e 6e a9 5c d2 47 6e 5b 0c 43 00 08 13 02 |..nn.\.Gn[.C....| -00000050 13 03 13 01 00 ff 01 00 00 a3 00 00 00 0e 00 0c |................| -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 23 00 00 00 10 00 10 00 0e 06 70 |.....#.........p| -00000090 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 |roto2.proto1....| -000000a0 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 06 03 |................| -000000b0 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| -000000c0 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 2d 00 |.......+......-.| -000000d0 02 01 01 00 33 00 26 00 24 00 1d 00 20 76 1d a9 |....3.&.$... v..| -000000e0 43 43 a4 98 96 39 59 80 b0 7e 13 29 2a ea 53 e7 |CC...9Y..~.)*.S.| -000000f0 34 73 7a 10 0c f5 b0 92 b1 ab e2 26 17 |4sz........&.| +00000000 16 03 01 00 e2 01 00 00 de 03 03 8e d2 a1 8f ea |................| +00000010 e3 7d 5f 7c 70 74 c3 7e 5f 06 bb 21 35 28 38 7a |.}_|pt.~_..!5(8z| +00000020 7f 00 11 86 6e ac 19 38 7f d4 88 20 33 3a b2 14 |....n..8... 3:..| +00000030 c2 4e 6a 39 71 24 81 21 27 21 2d b7 3d bc 5e 97 |.Nj9q$.!'!-.=.^.| +00000040 f8 ed 55 83 be 9a d3 27 b5 e0 0e bd 00 04 13 03 |..U....'........| +00000050 00 ff 01 00 00 91 00 0b 00 04 03 00 01 02 00 0a |................| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#| +00000070 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.| +00000080 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........| +00000090 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................| +000000a0 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +000000b0 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.| +000000c0 26 00 24 00 1d 00 20 89 4d b8 22 62 39 22 e6 5a |&.$... .M."b9".Z| +000000d0 b1 86 ea c9 d9 d1 77 c9 12 c3 62 e1 8e 17 cb ab |......w...b.....| +000000e0 91 83 d8 af 9b be 0a |.......| >>> 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 c3 7f e3 22 |........... ..."| -00000030 2c 27 94 91 ab cc e5 56 b1 31 fb eb ed b4 84 3e |,'.....V.1.....>| -00000040 ae 93 6e 6e a9 5c d2 47 6e 5b 0c 43 13 02 00 00 |..nn.\.Gn[.C....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 33 3a b2 14 |........... 3:..| +00000030 c2 4e 6a 39 71 24 81 21 27 21 2d b7 3d bc 5e 97 |.Nj9q$.!'!-.=.^.| +00000040 f8 ed 55 83 be 9a d3 27 b5 e0 0e bd 13 03 00 00 |..U....'........| 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 24 1a dd ed 59 79 84 |.........$...Yy.| -00000090 d6 2e 17 81 75 e0 ee b3 98 8c 04 a3 ea 7c 46 f0 |....u........|F.| -000000a0 76 58 78 5a 37 99 a6 32 ad c6 5a 5a 3a ce 17 03 |vXxZ7..2..ZZ:...| -000000b0 03 02 6d 31 3b 00 34 ef 22 53 8a 31 f5 88 fb 3f |..m1;.4."S.1...?| -000000c0 e4 72 a8 20 65 ef be c6 78 84 4e 93 6a 8a fa 01 |.r. e...x.N.j...| -000000d0 10 b0 dd 0e 7d 8f 07 b8 da 29 4b 0a 5b 32 de cf |....}....)K.[2..| -000000e0 31 66 04 9c c6 d8 ab f0 07 f0 aa c3 b6 3e bf d4 |1f...........>..| -000000f0 0e 53 5d a4 4f aa 19 cf f4 3d 60 5b 19 ec e3 e2 |.S].O....=`[....| -00000100 71 1b 54 20 48 41 68 32 f5 28 06 e2 b7 29 89 c3 |q.T HAh2.(...)..| -00000110 d5 eb 07 f3 49 fb 0b f5 81 0a f2 65 70 24 a9 bc |....I......ep$..| -00000120 6b e7 70 58 7c f2 0a 91 3e f4 26 ea 1a 22 15 24 |k.pX|...>.&..".$| -00000130 5a 28 43 89 ac 1c 9b 39 1a 93 ec 32 5e ba cb f4 |Z(C....9...2^...| -00000140 57 a1 ca 03 8e 2e 0b 96 e7 7f e5 c5 30 22 ec fd |W...........0"..| -00000150 fe 6d 5f 01 e9 7a 5e b3 68 67 ee e9 23 d5 72 46 |.m_..z^.hg..#.rF| -00000160 77 05 b7 27 26 78 fe f9 cc c8 c2 fe a8 4e 93 04 |w..'&x.......N..| -00000170 56 bc 64 f1 55 ff 92 8d cb 81 46 cb 2d db 9b 41 |V.d.U.....F.-..A| -00000180 59 76 0c b5 65 7a e1 09 2f b6 3b d4 92 87 7c a6 |Yv..ez../.;...|.| -00000190 06 d7 37 aa db bc 07 12 a4 2e 38 be 97 83 80 80 |..7.......8.....| -000001a0 86 05 3a 4b 89 25 7f ef 5e 54 42 4a 89 99 f2 95 |..:K.%..^TBJ....| -000001b0 70 92 fb ac 2f ae b4 1f a0 5c 8c bf 45 2d 54 91 |p.../....\..E-T.| -000001c0 01 88 d5 9b a3 da af 67 1c ce 2e 9c 05 4c 68 d8 |.......g.....Lh.| -000001d0 b5 ee 98 06 a4 18 c8 c0 2d 7c bf 6e e2 eb 0d aa |........-|.n....| -000001e0 5b c6 f8 27 ad 3a 1a cf ac 35 f4 55 41 3c e0 8c |[..'.:...5.UA<..| -000001f0 3e 26 56 95 33 c4 f1 05 5a e7 9d 6e 33 90 d1 37 |>&V.3...Z..n3..7| -00000200 03 77 1f 76 1a 35 43 c1 a4 8c 5a 68 f5 bc 6c 7a |.w.v.5C...Zh..lz| -00000210 43 27 37 cd d9 55 76 69 bd 78 47 4e 2e 25 96 e6 |C'7..Uvi.xGN.%..| -00000220 8f 46 a3 70 ff b8 55 f2 66 46 2c 59 ad b9 b7 9a |.F.p..U.fF,Y....| -00000230 a1 dc a4 8b 2b fa 14 17 dd bf 46 c6 9a ef 50 54 |....+.....F...PT| -00000240 6e b8 d3 d7 13 d4 74 dd a5 ef 16 5f 2a fa ea 9b |n.....t...._*...| -00000250 59 7c 41 f8 6d 00 b5 01 9d c8 35 34 1e 1c 3f 64 |Y|A.m.....54..?d| -00000260 6a da 1e c4 64 4d e5 2e c7 28 f8 14 70 e6 72 4b |j...dM...(..p.rK| -00000270 ab 8a 22 5e 2b 5c aa b3 02 72 80 0c 80 11 cd 18 |.."^+\...r......| -00000280 b8 e1 8c 54 54 72 fd 68 71 66 ef bc 3e 03 ca a4 |...TTr.hqf..>...| -00000290 ae f4 ad 7b 29 08 ff 49 07 09 bc a1 cd e3 14 69 |...{)..I.......i| -000002a0 47 0e b0 c0 a8 89 3a 7b 71 e5 ba 32 36 e8 b5 0a |G.....:{q..26...| -000002b0 9e f6 9f 6f 12 89 f5 36 5c 96 28 e1 2d 6b b3 06 |...o...6\.(.-k..| -000002c0 d6 68 d3 99 f4 3d 27 b2 61 df 75 29 a0 24 8a ba |.h...='.a.u).$..| -000002d0 48 c4 5c 8c 36 21 3a 3e bf 92 4f 73 cc bd a1 b1 |H.\.6!:>..Os....| -000002e0 e7 00 c6 05 94 1e 8e 73 d3 52 aa 4d 02 40 3b 50 |.......s.R.M.@;P| -000002f0 5f f0 37 b6 61 43 9f 39 63 64 ad 37 12 97 2a 0c |_.7.aC.9cd.7..*.| -00000300 5e d9 20 e0 78 da f3 80 d8 29 ea b3 c5 52 55 cc |^. .x....)...RU.| -00000310 3d e0 91 b7 f8 f9 b0 29 5a b3 e9 65 04 31 5c 6c |=......)Z..e.1\l| -00000320 17 03 03 00 99 7d d6 2e 45 d8 e2 5b f8 c1 21 86 |.....}..E..[..!.| -00000330 8a 31 78 88 5d 61 ca 8c e5 23 07 d7 85 da cb 04 |.1x.]a...#......| -00000340 be c3 24 2b 27 42 bb a1 1e 4f 8b bb a2 5d 3b 1e |..$+'B...O...];.| -00000350 8a 64 f0 2a 2f 79 51 cc 1b 34 99 b6 33 75 31 c9 |.d.*/yQ..4..3u1.| -00000360 2e ea 70 ef 97 c4 bb 4c ec aa cf 11 6c 88 96 c4 |..p....L....l...| -00000370 9b b9 df b9 ef 10 bb 36 65 1f 8d 7e 22 e8 67 80 |.......6e..~".g.| -00000380 80 6e 2b 34 94 a4 5f b1 5d 88 11 2e bf 22 f9 fe |.n+4.._.]...."..| -00000390 be 76 e8 86 da 40 76 8c 9c 40 b6 b4 50 41 92 f5 |.v...@v..@..PA..| -000003a0 ce 8c bd 13 ea f0 6f 56 c2 1c c6 ed 08 33 71 36 |......oV.....3q6| -000003b0 a4 16 b6 ca bf ba 0e 65 b0 a2 2b 35 39 c7 17 03 |.......e..+59...| -000003c0 03 00 45 3b 7a 67 26 15 b4 9b 0f ba 61 5d d0 4c |..E;zg&.....a].L| -000003d0 60 27 29 03 fb da 90 ea 0c 64 22 24 ac 60 74 02 |`')......d"$.`t.| -000003e0 0e 99 e0 e1 55 35 da c2 75 19 82 0c fa f8 f0 09 |....U5..u.......| -000003f0 35 1e ca de d1 e1 17 8e d2 f7 fb f9 94 d1 03 fb |5...............| -00000400 b5 8a 32 f6 8f 02 5f fa 17 03 03 00 a3 21 96 04 |..2..._......!..| -00000410 46 58 eb 83 db 06 a7 ba f2 9e 5c 8a 35 0d 87 78 |FX........\.5..x| -00000420 29 17 4f 7a 95 21 1f b4 f3 fa bb de 93 b7 e7 1c |).Oz.!..........| -00000430 24 40 06 6b 9f b5 12 49 36 39 01 b9 17 cb 5c 99 |$@.k...I69....\.| -00000440 93 71 dc 8f c5 54 c0 dd ff 36 92 24 cd b3 ac 40 |.q...T...6.$...@| -00000450 c0 57 76 c3 2a a0 d3 07 af 00 4b df c5 f9 34 77 |.Wv.*.....K...4w| -00000460 ed cc 14 e1 50 bf 41 1e b5 39 5d 92 a8 e4 f5 a6 |....P.A..9].....| -00000470 b2 12 08 56 b6 43 cf dc eb a9 0e 9e 0e 8a 97 63 |...V.C.........c| -00000480 f8 92 a8 1b 74 f3 65 60 6a f3 f0 e7 54 fd d3 08 |....t.e`j...T...| -00000490 20 ce b4 16 ab c9 e1 7a 49 9c bf d6 3a a7 2b 5c | ......zI...:.+\| -000004a0 1b 1c a7 89 f3 6a 6d 3d 0a 07 16 b4 c1 c2 4b 2e |.....jm=......K.| +00000080 03 03 00 01 01 17 03 03 00 24 60 9e a3 43 47 75 |.........$`..CGu| +00000090 d2 38 11 fd 9d da a5 f6 65 de 3c 2a 3d a9 46 7e |.8......e.<*=.F~| +000000a0 50 c8 52 a1 7d e6 95 a7 4b 48 b7 35 e7 a7 17 03 |P.R.}...KH.5....| +000000b0 03 02 6d b8 30 43 88 03 d4 6c cf c6 45 80 b2 6c |..m.0C...l..E..l| +000000c0 52 d7 1e 08 de 0b 6e 7a 27 c8 2c 59 d4 03 41 24 |R.....nz'.,Y..A$| +000000d0 e3 4a e1 d3 85 68 de 23 f6 c4 3a bb 45 ae b1 ac |.J...h.#..:.E...| +000000e0 8b b3 22 7d e7 a6 7c e3 07 68 b1 9c 97 6a d3 e4 |.."}..|..h...j..| +000000f0 5d 0a 73 a3 16 ad e4 7f b9 d7 0a b7 7c 48 bb f2 |].s.........|H..| +00000100 ed 49 61 f7 cb 5e ea d2 d9 a3 73 ea a7 4f a3 10 |.Ia..^....s..O..| +00000110 f7 3e 8f ce b9 56 a0 88 54 52 59 1f f3 55 2b 15 |.>...V..TRY..U+.| +00000120 df fd fa 85 9e 20 ff 72 f3 26 6a 2c 1f 11 a8 3d |..... .r.&j,...=| +00000130 8e 66 75 aa 90 fc 9f 9f a7 67 8f ac 98 54 19 04 |.fu......g...T..| +00000140 c9 1f 48 f7 ed 8f 13 0a f9 6c 9b f8 e9 0a c5 a9 |..H......l......| +00000150 f2 ef 5b 65 a1 ad 40 e4 e7 ff c1 ff e9 d6 ab 5c |..[e..@........\| +00000160 f8 f1 7b 4d 39 33 1d 68 d3 38 20 10 c4 3b 7a 9f |..{M93.h.8 ..;z.| +00000170 fe 55 1d 83 5c 8f 67 d0 bb 5f 32 80 b2 91 38 0a |.U..\.g.._2...8.| +00000180 71 bb b4 3a 10 1c 98 f9 d4 19 7c 7d d5 f7 4b 0a |q..:......|}..K.| +00000190 02 2f bd 0b f9 ff 28 b2 2d ba dd 7f 0d 51 a2 4c |./....(.-....Q.L| +000001a0 51 92 1e e9 47 51 ae 1a d0 66 9c ef 0a 02 dc 69 |Q...GQ...f.....i| +000001b0 95 79 2b b0 8f 7b a2 3d 57 cf 5c 7e b4 0a 91 34 |.y+..{.=W.\~...4| +000001c0 e6 d0 0d 93 1b 6c 61 9e 58 12 47 5f 3a ec 67 19 |.....la.X.G_:.g.| +000001d0 d8 fb 44 43 4d cd 4e ad 1d bc f2 05 66 42 3f 3f |..DCM.N.....fB??| +000001e0 85 5d 93 56 8e ca 62 47 38 ee d2 0e 81 8b 71 7d |.].V..bG8.....q}| +000001f0 d8 cf 6e 4b 61 80 fe 28 34 f4 f1 58 06 36 2a 40 |..nKa..(4..X.6*@| +00000200 93 98 3d d0 9c 69 6f 6a 3a 40 b9 8c 2e 71 5d 52 |..=..ioj:@...q]R| +00000210 66 5d 55 45 e7 38 b7 ce 74 c2 1c ae 2e 4a 03 86 |f]UE.8..t....J..| +00000220 d4 15 c3 40 d9 58 b7 ba ed 84 fd 20 35 a4 1c c6 |...@.X..... 5...| +00000230 8a 50 7a 0c 87 53 d7 2d 4b 5b 7d 23 79 8f 66 f8 |.Pz..S.-K[}#y.f.| +00000240 72 05 72 7b 7d 7a 64 97 8d da c9 dd 23 6a 44 b6 |r.r{}zd.....#jD.| +00000250 e1 99 e4 45 76 a5 53 d8 1b 54 a0 b9 9e ec 0e d3 |...Ev.S..T......| +00000260 91 1b 5e c0 a7 c8 3a 34 22 f9 58 7d da 2b f4 fd |..^...:4".X}.+..| +00000270 2b 9a 9e 26 20 6f d3 9d e9 48 a1 62 70 fe 06 04 |+..& o...H.bp...| +00000280 c2 63 f7 c4 a2 b9 74 28 a8 b3 f9 f0 a1 2a 46 0c |.c....t(.....*F.| +00000290 f5 6b cc 7e b4 c0 47 eb 00 96 6a 3d 32 58 e0 0a |.k.~..G...j=2X..| +000002a0 59 01 3c 42 45 a7 76 6d 78 05 1f 2c db a4 08 5b |Y....c...f/| +00000470 24 2a 06 1b f3 91 a7 7c dd d9 b5 1f b3 9e 7f ce |$*.....|........| +00000480 db 96 cd 2e 36 69 f0 94 0c 5f e8 0b 15 6a 38 40 |....6i..._...j8@| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 90 6e 35 6d 4e |..........E.n5mN| -00000010 3b 8a 39 88 85 99 ac 05 fe 2c e3 a8 31 46 4e c2 |;.9......,..1FN.| -00000020 ea fe a2 ff 41 5b 64 77 bc 0c 6d 72 f7 c8 f3 07 |....A[dw..mr....| -00000030 ce 29 c2 6e 7c b5 88 13 35 f8 c0 90 98 ab 0f f9 |.).n|...5.......| -00000040 e2 8e 57 7e 23 7b 57 17 b6 13 11 9e 52 67 44 26 |..W~#{W.....RgD&| +00000000 14 03 03 00 01 01 17 03 03 00 35 32 39 09 c6 64 |..........529..d| +00000010 aa 86 b7 a7 37 6c fa ef 66 01 d4 de e6 35 8d 31 |....7l..f....5.1| +00000020 68 71 f3 27 56 fd 7f 7b cf c8 3c d1 44 ff e0 c7 |hq.'V..{..<.D...| +00000030 78 b7 6c c8 ac 01 0e ee e1 78 b9 dd 1a e1 a9 b6 |x.l......x......| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 98 55 d6 42 d5 d4 01 c9 be 70 27 |......U.B.....p'| -00000010 9e 5a d5 7d fc 41 1e ec fe fd d5 0f 01 16 56 82 |.Z.}.A........V.| -00000020 13 13 c7 17 03 03 00 13 bb 71 20 65 f8 af 42 ea |.........q e..B.| -00000030 42 73 b8 24 d8 dc 79 7c 71 32 35 |Bs.$..y|q25| +00000000 17 03 03 00 1e da e7 79 04 f5 65 2e f6 c3 c3 b9 |.......y..e.....| +00000010 34 37 14 8f c2 32 cb 81 58 bc cf d0 3b 08 f0 61 |47...2..X...;..a| +00000020 b3 ae b4 17 03 03 00 13 e3 32 09 02 e0 29 5e 4a |.........2...)^J| +00000030 9b 36 a9 b0 65 e9 2c 1d fb ad 50 |.6..e.,...P| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch b/libgo/go/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch index 84c38acbeb0..0b5dc9b1c63 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch @@ -1,104 +1,100 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 f8 01 00 00 f4 03 03 b6 62 6e 7c 66 |............bn|f| -00000010 e0 73 6f bc ce d7 e3 5c 3a 39 c5 c9 5e f3 8f 76 |.so....\:9..^..v| -00000020 f0 ed 0e 30 fd 80 a0 79 74 fd d4 20 6b 6e f8 9d |...0...yt.. kn..| -00000030 30 1b ee fa 7c 5f 64 e0 da 81 26 7a 85 d2 f9 79 |0...|_d...&z...y| -00000040 e7 09 71 f8 2a 4c 41 74 02 a9 0c d2 00 08 13 02 |..q.*LAt........| -00000050 13 03 13 01 00 ff 01 00 00 a3 00 00 00 0e 00 0c |................| -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 23 00 00 00 10 00 10 00 0e 06 70 |.....#.........p| -00000090 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 |roto2.proto1....| -000000a0 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 06 03 |................| -000000b0 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| -000000c0 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 2d 00 |.......+......-.| -000000d0 02 01 01 00 33 00 26 00 24 00 1d 00 20 8d 7d e2 |....3.&.$... .}.| -000000e0 55 da a7 1b 29 fc a4 d3 b0 62 51 43 d9 d6 cd 79 |U...)....bQC...y| -000000f0 a4 f9 3c f2 4e 03 87 1f 38 29 35 c3 36 |..<.N...8)5.6| +00000000 16 03 01 00 e2 01 00 00 de 03 03 ea ab 77 e1 48 |.............w.H| +00000010 64 70 23 5c af b3 a7 3d 60 93 a0 30 0a 8c 98 61 |dp#\...=`..0...a| +00000020 3a ab bc a9 11 c1 2f f5 ed d7 63 20 d4 29 26 9d |:...../...c .)&.| +00000030 64 37 72 d1 2c 7d 09 3b 94 67 f9 1c 19 c3 7e 17 |d7r.,}.;.g....~.| +00000040 ec 80 5f 09 38 c1 15 4d 59 45 5c c3 00 04 13 03 |.._.8..MYE\.....| +00000050 00 ff 01 00 00 91 00 0b 00 04 03 00 01 02 00 0a |................| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#| +00000070 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.| +00000080 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........| +00000090 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................| +000000a0 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +000000b0 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.| +000000c0 26 00 24 00 1d 00 20 68 64 e8 c1 4a c5 d5 b8 91 |&.$... hd..J....| +000000d0 a0 20 c7 aa 8a 41 90 d6 d0 5e ed 6c ed e4 77 aa |. ...A...^.l..w.| +000000e0 ec 33 93 e3 d5 b7 55 |.3....U| >>> 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 6b 6e f8 9d |........... kn..| -00000030 30 1b ee fa 7c 5f 64 e0 da 81 26 7a 85 d2 f9 79 |0...|_d...&z...y| -00000040 e7 09 71 f8 2a 4c 41 74 02 a9 0c d2 13 02 00 00 |..q.*LAt........| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 d4 29 26 9d |........... .)&.| +00000030 64 37 72 d1 2c 7d 09 3b 94 67 f9 1c 19 c3 7e 17 |d7r.,}.;.g....~.| +00000040 ec 80 5f 09 38 c1 15 4d 59 45 5c c3 13 03 00 00 |.._.8..MYE\.....| 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 4c a1 99 6c 86 b8 |..........L..l..| -00000090 1a 1a eb ec 89 37 bf 5a ae 87 3c 81 ce cf b2 49 |.....7.Z..<....I| -000000a0 66 17 03 03 02 6d 40 06 a4 17 6a 48 78 76 a5 63 |f....m@...jHxv.c| -000000b0 82 c4 5b e9 6e dc 54 de 95 12 15 a7 3d 83 94 4d |..[.n.T.....=..M| -000000c0 57 26 82 ea f3 d5 e1 4a d7 6e dc 27 f6 02 1c 16 |W&.....J.n.'....| -000000d0 21 68 c5 32 ff 02 e9 b5 44 2c f4 e9 4d b2 9d 3d |!h.2....D,..M..=| -000000e0 34 e1 6a db 73 61 eb 5c 00 e9 e8 00 bc 82 2a 17 |4.j.sa.\......*.| -000000f0 25 f7 c4 09 2f 6c 3e c6 09 5a 33 61 49 df 4d 47 |%.../l>..Z3aI.MG| -00000100 95 16 c5 6e a4 b3 94 44 4c 8b 5d d6 2c c9 26 a1 |...n...DL.].,.&.| -00000110 01 e8 cc 20 9c 19 d3 3e eb d5 7c 97 4e 1e af 7b |... ...>..|.N..{| -00000120 68 0e 7b eb bb 91 81 60 a2 c8 37 96 84 f2 cd fe |h.{....`..7.....| -00000130 7f 22 7f 7f 22 6a c7 23 68 79 48 ae 35 47 27 4b |.".."j.#hyH.5G'K| -00000140 c0 ce e7 9c 7f 23 fd 44 e1 a5 da 9f 61 94 46 1f |.....#.D....a.F.| -00000150 6c ea b9 50 53 c2 35 70 d4 77 d7 2d d5 54 fb d7 |l..PS.5p.w.-.T..| -00000160 90 4b f9 bb 98 67 cc 5b 97 56 ef ff 5d c9 08 9c |.K...g.[.V..]...| -00000170 26 cd cf ba 51 6f a5 f4 20 34 83 85 ef 71 98 1b |&...Qo.. 4...q..| -00000180 dd 41 f9 51 f3 59 77 d7 b5 f5 98 40 fd 78 ef b6 |.A.Q.Yw....@.x..| -00000190 47 8c 27 e3 c8 ae 9d c3 47 92 dc 97 23 82 2f 80 |G.'.....G...#./.| -000001a0 2f 0f 17 17 17 f1 49 ec c3 1c 73 02 38 b3 a6 6d |/.....I...s.8..m| -000001b0 89 5f 55 30 ea 10 5d fe a7 6e 88 fb cc fd 9a 01 |._U0..]..n......| -000001c0 10 f8 4e 6a 7f ba 62 ab 15 85 7a 8d fc de 92 f7 |..Nj..b...z.....| -000001d0 91 9a d8 dc f3 de 3e 36 19 45 44 8c d7 03 67 c8 |......>6.ED...g.| -000001e0 14 24 09 33 1b f3 2f 2d a6 a5 9a 6c e2 04 da 4b |.$.3../-...l...K| -000001f0 18 13 57 12 83 86 46 8f af 35 f4 0a 1b 09 1c 25 |..W...F..5.....%| -00000200 bb 1e 22 fb 71 48 3f 34 47 d4 52 ec 3c 81 dd 5b |..".qH?4G.R.<..[| -00000210 0d a0 b4 74 a7 60 5f 60 14 ee d3 08 54 92 45 42 |...t.`_`....T.EB| -00000220 52 82 8d 54 84 ee c0 1d a7 a9 b4 a0 13 82 75 cd |R..T..........u.| -00000230 f6 a7 bc aa 0a e9 0a c5 36 ea 6f c1 8b 56 22 81 |........6.o..V".| -00000240 0a 8e 81 3d bf 34 f4 cc 80 02 d2 01 b5 2c b8 6b |...=.4.......,.k| -00000250 4b e8 06 06 cf e1 69 50 59 ea b2 a5 b0 06 96 02 |K.....iPY.......| -00000260 0e 45 8c 8c 46 ae 24 a0 80 92 75 46 7b cd 9e de |.E..F.$...uF{...| -00000270 a2 a0 d5 f4 68 ef 34 82 37 08 64 62 e8 eb 41 a4 |....h.4.7.db..A.| -00000280 32 a8 d4 c3 ee 16 67 2c 47 08 ef 23 c7 27 4a 21 |2.....g,G..#.'J!| -00000290 5c 66 36 93 6c 8c 8c fd 04 9a d9 84 e0 be 45 50 |\f6.l.........EP| -000002a0 0c 42 a2 d3 ba 5a 92 14 86 75 d2 33 6f 8b 69 a3 |.B...Z...u.3o.i.| -000002b0 b2 da 7e 19 e0 a6 0d 8e cb 21 bf f6 fa 5c 41 de |..~......!...\A.| -000002c0 d8 56 f7 d0 53 66 54 d2 5c e7 b5 20 af 0d 01 5a |.V..SfT.\.. ...Z| -000002d0 09 d0 ed 7f f1 1d d7 32 55 a8 c2 5a ba d8 e1 46 |.......2U..Z...F| -000002e0 fb 32 39 8b 8c 94 73 44 85 64 d6 c7 9f 6a d5 4e |.29...sD.d...j.N| -000002f0 fc 16 a2 10 cb 06 43 10 da a5 b2 71 e7 04 a6 3f |......C....q...?| -00000300 83 79 2c cb 2e 40 ab c8 53 18 11 95 3a f5 b9 b7 |.y,..@..S...:...| -00000310 df 99 d7 17 03 03 00 99 c0 29 f3 15 df b1 dc 36 |.........).....6| -00000320 a9 78 21 ed ba 5a 85 11 51 23 3f e9 b4 b3 bb b3 |.x!..Z..Q#?.....| -00000330 27 92 8e 9c a0 f8 b3 38 35 ef 9f bf 2b 31 82 cd |'......85...+1..| -00000340 de 3a 0c 0c b1 09 65 77 00 4c af 8c fe ff 2c 75 |.:....ew.L....,u| -00000350 62 48 13 96 63 5c 73 00 13 1f ef 27 f5 b2 4c fe |bH..c\s....'..L.| -00000360 8e 2a ff ab 94 68 5e 7c 02 19 d5 f3 68 07 b8 a1 |.*...h^|....h...| -00000370 2a 48 fc 4e ad b9 1c 95 13 d9 19 9d 47 7f 07 4d |*H.N........G..M| -00000380 b8 75 79 e7 da 6f 46 3e eb 27 c4 6f da ab bb fd |.uy..oF>.'.o....| -00000390 0a 04 08 15 c4 45 c4 1a 09 db 48 ca 3d 8e 63 af |.....E....H.=.c.| -000003a0 d8 0d 6b a2 04 22 eb 6d ed bf b6 45 d2 c8 b9 ee |..k..".m...E....| -000003b0 02 17 03 03 00 45 5c ef 9a 1c 12 95 25 da 79 21 |.....E\.....%.y!| -000003c0 6c 74 a2 64 cf bf aa cd 53 a4 43 48 d7 f3 b2 35 |lt.d....S.CH...5| -000003d0 da f2 0e d4 1c 14 23 63 8f 7a e5 5a 98 46 71 ad |......#c.z.Z.Fq.| -000003e0 19 a2 8f 22 b1 c5 93 89 0b 7f cd 38 09 9a ea f1 |...".......8....| -000003f0 51 6b 46 0f 8b 00 8d c2 1a 97 de 17 03 03 00 a3 |QkF.............| -00000400 32 88 68 5e f9 90 07 5d 4d 04 3d 1d 26 ac a2 1b |2.h^...]M.=.&...| -00000410 54 d0 37 7c 9f e7 8f ee c5 a6 bc b6 a9 78 08 40 |T.7|.........x.@| -00000420 f3 07 2f f5 b4 1f 08 c6 af 2d 4f 2e 87 4e 5f 95 |../......-O..N_.| -00000430 c9 b7 42 3a b5 ef ff 43 41 05 7c 7d 64 3f 56 ec |..B:...CA.|}d?V.| -00000440 ee b6 04 61 0a 56 79 77 5f 1c be e2 24 a2 cb 81 |...a.Vyw_...$...| -00000450 96 6f 95 6e a7 5a 2c 9e a0 e6 30 e5 f7 02 ff 10 |.o.n.Z,...0.....| -00000460 33 28 6e d7 ec 34 98 bf 26 2e 56 1d 99 e9 50 94 |3(n..4..&.V...P.| -00000470 71 be 0e 05 d3 86 95 db b9 4f 42 80 8a 12 2e ff |q........OB.....| -00000480 b6 be 81 f2 6f 4c 6a 00 a0 b8 53 c7 d7 fa 94 c6 |....oLj...S.....| -00000490 b2 b5 80 4b 3e e9 88 42 36 52 23 ca e4 48 b6 03 |...K>..B6R#..H..| -000004a0 13 7d 69 |.}i| +00000080 03 03 00 01 01 17 03 03 00 17 c0 d3 a2 c3 42 b4 |..............B.| +00000090 39 f1 b6 f1 0a ac f3 76 dd 36 15 eb d7 3b 3f 63 |9......v.6...;?c| +000000a0 0b 17 03 03 02 6d f2 02 6d 15 de 46 b3 30 ef 57 |.....m..m..F.0.W| +000000b0 e5 a3 35 11 5c c3 b4 2e ad 74 ca db d2 90 eb b4 |..5.\....t......| +000000c0 ba 14 7e b0 65 68 e8 31 76 2a 28 e4 be bb d1 c3 |..~.eh.1v*(.....| +000000d0 45 cb ba 07 eb 27 d9 5e 4a 45 52 10 62 f0 8f b2 |E....'.^JER.b...| +000000e0 7c ad 0f 63 5c 39 f7 6e f2 68 3e bc fd ec fe fa ||..c\9.n.h>.....| +000000f0 9b ba 45 96 2b 94 27 34 2c 78 c8 5f 40 e3 f9 20 |..E.+.'4,x._@.. | +00000100 51 15 3d dc 70 d1 50 7c 26 6b 51 3f 47 61 0b e6 |Q.=.p.P|&kQ?Ga..| +00000110 04 ee 49 19 27 f0 91 c5 0f 15 0a 90 a6 0c 14 f2 |..I.'...........| +00000120 2f f1 42 28 be a0 7a ce 16 14 bf ff 34 34 a8 d8 |/.B(..z.....44..| +00000130 61 e6 26 6a 00 62 a0 82 53 c6 27 30 89 81 8d fb |a.&j.b..S.'0....| +00000140 9e 97 bc a0 ce 2f a1 e2 bf 9e fe d2 cc 11 4e 00 |...../........N.| +00000150 89 d1 e8 3b ab 58 e4 66 0a 87 00 b1 c1 a0 2d b0 |...;.X.f......-.| +00000160 96 b3 13 9b d3 c0 16 6b 87 e8 e3 9e 6c 30 1b 67 |.......k....l0.g| +00000170 c1 53 a5 4b 55 44 4e 27 6e ea 7c 7d 9f 44 b4 ca |.S.KUDN'n.|}.D..| +00000180 15 6f e5 d1 7f 18 e4 12 66 2d d5 a2 47 0c 73 26 |.o......f-..G.s&| +00000190 b0 bf 93 5b 46 9c 3f 78 69 05 a1 38 0f 61 ea d6 |...[F.?xi..8.a..| +000001a0 61 97 80 c5 72 be 6d be 2d e5 a2 9e d8 b3 bf 8d |a...r.m.-.......| +000001b0 a4 53 ba 6d fe c8 8d ac c1 4a 6e 76 bf 72 1e 5a |.S.m.....Jnv.r.Z| +000001c0 0a 51 f3 c8 1f 11 91 36 f0 f5 ba 68 e8 69 c3 77 |.Q.....6...h.i.w| +000001d0 52 63 dc b3 93 80 0d fd 9a 7d 7f f8 47 f8 62 2a |Rc.......}..G.b*| +000001e0 3d 4f 1b 46 9f cb 07 b6 96 00 b1 08 e7 32 50 41 |=O.F.........2PA| +000001f0 83 da 20 c2 b0 c0 33 33 3f f2 f9 84 f0 64 9f 37 |.. ...33?....d.7| +00000200 4b b6 7b ab 2e e9 50 8b 6a 61 da 12 51 54 13 25 |K.{...P.ja..QT.%| +00000210 46 5d 90 06 ef 88 4e be 64 67 80 02 1f 25 9c 28 |F]....N.dg...%.(| +00000220 07 b3 24 2b 10 81 c1 72 7c 94 97 b3 5a 16 bc cf |..$+...r|...Z...| +00000230 52 44 41 2c d7 ba e9 9f 4c d7 28 e6 b7 bb b0 fd |RDA,....L.(.....| +00000240 17 b2 0b 83 33 ed 2f c7 2d 42 37 fd 0a d0 4b c7 |....3./.-B7...K.| +00000250 97 61 17 d6 cd cd 0f e0 0d dd ab 40 fb 00 4d 81 |.a.........@..M.| +00000260 da 7d 1d 0e 48 d9 a7 6c ba 2a 21 49 18 0f a4 7c |.}..H..l.*!I...|| +00000270 af 0d 1b ca 94 f1 6c 78 59 ad 50 e4 1c 7b 37 45 |......lxY.P..{7E| +00000280 e8 1b 73 ad 96 8d 98 d6 07 26 07 fd a8 e6 8c 39 |..s......&.....9| +00000290 f1 5a 10 ef 04 97 fe d3 be cb f2 c1 5b 27 e8 d0 |.Z..........['..| +000002a0 f9 b3 16 b9 82 6d e8 be 54 c7 cf 44 a4 8a fd 75 |.....m..T..D...u| +000002b0 96 2a f1 65 2b d3 8f f5 86 a3 bf 12 74 c1 e4 d8 |.*.e+.......t...| +000002c0 a9 db c9 43 05 07 b1 51 dc 20 29 d0 c0 9a 6d 10 |...C...Q. )...m.| +000002d0 83 5f 87 a6 ab 03 58 43 1f 35 1c af dd 37 10 1b |._....XC.5...7..| +000002e0 16 50 52 e5 3c f5 3c ae 4f 92 7e dc 47 2e b3 9c |.PR.<.<.O.~.G...| +000002f0 1f d2 a0 31 8b 32 21 35 52 af bd f1 0b 2c 4e 6f |...1.2!5R....,No| +00000300 59 32 d8 db d6 9f b8 bd bc a0 3b 77 41 43 46 fb |Y2........;wACF.| +00000310 2b 0e 82 17 03 03 00 99 0a 63 cd 1f fa 90 4d 95 |+........c....M.| +00000320 17 d8 81 36 5c 62 17 33 6c 8d 9d 9f 26 3e 3a 2f |...6\b.3l...&>:/| +00000330 65 84 23 56 46 25 f6 1c dd ea 6f 21 b4 05 d8 19 |e.#VF%....o!....| +00000340 a3 c9 4b b1 03 78 39 32 00 97 6c d5 6e e3 ff 45 |..K..x92..l.n..E| +00000350 ac 2a 10 71 21 ad d3 b9 73 b7 77 0e a8 79 fd 50 |.*.q!...s.w..y.P| +00000360 a9 f1 41 39 2d 05 3d 92 3c 69 0a d7 7d 11 da f0 |..A9-.=...&..K| +00000450 a6 ce 93 36 ea a1 fd d9 78 61 a3 0e 08 72 da 03 |...6....xa...r..| +00000460 5d 0c 27 48 75 61 25 ef 77 39 39 e5 8e 87 2e 86 |].'Hua%.w99.....| +00000470 d5 70 d3 3b f4 b4 75 b1 44 d1 5f fe 9c d8 18 7d |.p.;..u.D._....}| +00000480 f9 89 20 |.. | >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 1d 07 22 a7 34 |..........E..".4| -00000010 0d a7 a0 e5 8c ed 58 d4 5c 39 d2 96 43 73 eb 8c |......X.\9..Cs..| -00000020 5f c1 0c 90 67 6f ae b1 ae ee 6c dd cd 47 31 83 |_...go....l..G1.| -00000030 be b1 f2 50 ec 31 54 ba 21 82 c4 bd aa 51 0a 7a |...P.1T.!....Q.z| -00000040 0d 25 18 68 00 18 8b 51 c3 ca ae b1 fa 20 e0 0b |.%.h...Q..... ..| +00000000 14 03 03 00 01 01 17 03 03 00 35 a8 ab 13 71 ec |..........5...q.| +00000010 af a7 4a 48 65 6d 02 ea 8a 0f d1 4d 2a 97 b6 11 |..JHem.....M*...| +00000020 6d 53 5f be a4 b3 a7 20 d4 d3 aa 90 62 30 26 3f |mS_.... ....b0&?| +00000030 be c8 ed fc 6f 44 cc a5 3a 7f 4d 95 51 ed dc 80 |....oD..:.M.Q...| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 1a 08 af cf 27 80 23 d8 94 0a fe |.........'.#....| -00000010 44 1c 78 f2 76 ac 9b 90 db 5c b6 8d c0 73 36 62 |D.x.v....\...s6b| -00000020 82 5d 8a 17 03 03 00 13 1a 2b 70 c9 14 dc c8 df |.].......+p.....| -00000030 e2 01 4e 69 e8 d7 13 0c 94 96 75 |..Ni......u| +00000000 17 03 03 00 1e 6a f5 e4 df 1b 2a 5a 87 68 b1 a7 |.....j....*Z.h..| +00000010 1d b8 ef 04 b4 ac b9 50 b3 95 1c 12 d7 44 ca 46 |.......P.....D.F| +00000020 ea 26 2a 17 03 03 00 13 a4 6b 4d 27 81 62 b0 3c |.&*......kM'.b.<| +00000030 d0 be d1 34 46 4c 7b 6c 71 24 d8 |...4FL{lq$.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven b/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven index 214ae5eed8d..0b6eaf43810 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven @@ -1,184 +1,179 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e0 01 00 00 dc 03 03 1f e8 63 15 2c |.............c.,| -00000010 85 dc 46 b7 52 88 cf 82 24 70 b9 7b 22 01 51 ee |..F.R...$p.{".Q.| -00000020 2a ff db 20 62 ba e2 18 4e 86 3f 20 d3 f9 0f d8 |*.. b...N.? ....| -00000030 85 5c 17 5e 95 e9 7a 7e cb 56 ac 85 3e 75 8f d8 |.\.^..z~.V..>u..| -00000040 8f 25 be 59 be a7 18 db b7 5e 19 23 00 08 13 02 |.%.Y.....^.#....| -00000050 13 03 13 01 00 ff 01 00 00 8b 00 00 00 0e 00 0c |................| -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 1e |................| -00000090 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -000000a0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 00 2b |...............+| -000000b0 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 |......-.....3.&.| -000000c0 24 00 1d 00 20 8d 8e c0 53 e4 17 29 9f 59 9e 80 |$... ...S..).Y..| -000000d0 1f 4a 99 4b 9d 59 3f 84 93 06 68 6e 45 86 2f 4d |.J.K.Y?...hnE./M| -000000e0 04 f5 ba 3e 42 |...>B| +00000000 16 03 01 00 ca 01 00 00 c6 03 03 54 78 64 8e b6 |...........Txd..| +00000010 69 c6 1c 8a 69 eb 09 ef 32 59 f9 9f 63 ac 6e 66 |i...i...2Y..c.nf| +00000020 97 b4 bb b7 71 27 60 52 af c4 64 20 26 de 8d 3e |....q'`R..d &..>| +00000030 90 5b c8 96 b5 10 a3 e4 67 f3 39 fb f5 b7 df 50 |.[......g.9....P| +00000040 2b 8f 2d cb a5 c4 0a c9 28 1b c3 21 00 04 13 01 |+.-.....(..!....| +00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................| +00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| +00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......| +000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 65 |-.....3.&.$... e| +000000b0 42 a2 bd 1e e0 0a 52 2d 7a 1e f0 37 86 db 9e c6 |B.....R-z..7....| +000000c0 d6 cd ff 7b 71 f3 4c a3 23 44 2d 94 60 93 0b |...{q.L.#D-.`..| >>> 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 d3 f9 0f d8 |........... ....| -00000030 85 5c 17 5e 95 e9 7a 7e cb 56 ac 85 3e 75 8f d8 |.\.^..z~.V..>u..| -00000040 8f 25 be 59 be a7 18 db b7 5e 19 23 13 02 00 00 |.%.Y.....^.#....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 26 de 8d 3e |........... &..>| +00000030 90 5b c8 96 b5 10 a3 e4 67 f3 39 fb f5 b7 df 50 |.[......g.9....P| +00000040 2b 8f 2d cb a5 c4 0a c9 28 1b c3 21 13 01 00 00 |+.-.....(..!....| 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 cb a2 26 d8 e7 e0 |............&...| -00000090 72 cd 3d 39 f6 67 25 78 a3 ce bf 0e 62 bf 2e 2a |r.=9.g%x....b..*| -000000a0 b5 17 03 03 00 3e 3e b3 0c 6d 79 88 e8 74 87 a5 |.....>>..my..t..| -000000b0 ab a1 db 4b 11 d9 15 16 49 a7 ef a5 69 f0 8e 2e |...K....I...i...| -000000c0 a3 6c 38 f0 ea 6d 0b fd 4c 78 ea 55 ec e7 48 de |.l8..m..Lx.U..H.| -000000d0 87 01 3d de 13 5b 59 7f b3 15 4a 7d 40 30 d8 9c |..=..[Y...J}@0..| -000000e0 55 06 54 2d 17 03 03 02 6d 28 a4 e3 bf 71 d5 93 |U.T-....m(...q..| -000000f0 50 e1 e7 96 02 28 f1 2f 6d 78 1f b9 7f 1a 8c a4 |P....(./mx......| -00000100 65 03 15 fb a7 ef f5 91 66 44 00 28 6a 17 46 9c |e.......fD.(j.F.| -00000110 e7 90 f9 d5 78 f1 a4 fd 9b 54 09 dc 6e 83 0f 65 |....x....T..n..e| -00000120 96 51 e1 69 e0 05 7f d4 d6 04 03 fd b8 6b 9c 12 |.Q.i.........k..| -00000130 02 af 03 9b 02 42 7b ce e0 81 51 91 3a 01 be a4 |.....B{...Q.:...| -00000140 72 ef 27 c3 3e f1 8e 5d 3a 9e 46 4c 25 13 98 c2 |r.'.>..]:.FL%...| -00000150 5c 75 3f b2 30 7c de da b6 56 4e 7a 2c c3 1d 6f |\u?.0|...VNz,..o| -00000160 7a 6e 0d da d2 df a6 df 47 12 6d af 3f d7 66 ad |zn......G.m.?.f.| -00000170 54 19 b3 7f 1b 92 5c e6 79 36 ab d9 99 db 1d f9 |T.....\.y6......| -00000180 e8 13 b4 e9 85 fb ba 9a 7b f3 eb 28 e5 e3 f1 0e |........{..(....| -00000190 dc 95 b2 db f3 e4 77 6d a5 43 14 4c f4 af 0a e4 |......wm.C.L....| -000001a0 5d bf 1d f4 ef 72 9f c0 74 55 e5 93 e0 7c f0 9a |]....r..tU...|..| -000001b0 01 1d e8 43 5d c1 24 6f 75 46 44 f0 bc 15 b6 6b |...C].$ouFD....k| -000001c0 7b cd 6d cc 38 06 10 34 ae be 7c b1 24 da 71 58 |{.m.8..4..|.$.qX| -000001d0 b2 81 1f ea 28 18 73 75 79 d5 eb ef 0c 33 b8 1c |....(.suy....3..| -000001e0 14 e9 00 b8 12 f7 b2 9f b1 f3 a8 23 63 b3 29 49 |...........#c.)I| -000001f0 0e 84 b8 60 1c c2 32 c5 fd 59 de 88 e2 55 93 0f |...`..2..Y...U..| -00000200 63 e6 a7 02 3e 01 0e 5f df b4 03 f8 a9 d0 96 03 |c...>.._........| -00000210 5c ea e0 6f 5d 1d 30 41 c7 ec 6a 94 d3 6c ff b7 |\..o].0A..j..l..| -00000220 1b eb b8 0d 2f df 90 2e f8 f5 d2 3a c6 8c 47 98 |..../......:..G.| -00000230 ad 39 13 f2 4d 2f a5 9d 4b 58 f7 bc 92 d6 b1 ca |.9..M/..KX......| -00000240 6a a5 c5 64 62 1c 76 21 be b5 ca 25 04 e4 16 b3 |j..db.v!...%....| -00000250 26 90 42 b8 b8 61 4a da a3 12 5d f7 74 e6 f1 95 |&.B..aJ...].t...| -00000260 5d d4 3a 17 fc 33 b1 2a 35 eb 69 16 7e d0 8f 66 |].:..3.*5.i.~..f| -00000270 ca b1 62 0f 85 d1 b3 f9 b6 cf dc 86 61 0e 34 8a |..b.........a.4.| -00000280 a0 69 fc 59 6b fc 3d 6d 7a 19 46 6f 8a 3d 16 56 |.i.Yk.=mz.Fo.=.V| -00000290 ac 5d ed 05 57 25 2d 85 78 67 bc 50 a3 34 87 3f |.]..W%-.xg.P.4.?| -000002a0 e7 ae 0d f0 17 67 2a 08 42 92 1f 25 0e 9c 22 e3 |.....g*.B..%..".| -000002b0 3f 7f dc 91 52 9e d3 01 39 0f 47 55 26 f3 f2 ce |?...R...9.GU&...| -000002c0 75 7d 33 f2 a2 9a 03 70 c0 e7 32 90 a7 50 8c b0 |u}3....p..2..P..| -000002d0 ab fa b5 ef 25 ae e3 7e 94 99 a9 3f 83 a7 16 5e |....%..~...?...^| -000002e0 67 b4 a0 1e 5b f7 10 49 cb 33 73 4d 92 26 49 8d |g...[..I.3sM.&I.| -000002f0 63 fc 5b b5 1b a4 1a 97 10 09 5f e0 75 73 50 be |c.[......._.usP.| -00000300 d5 6a 62 80 3a 3f c7 94 89 51 f0 c6 fa 38 2e 79 |.jb.:?...Q...8.y| -00000310 3c 0b 63 bc 7e 6e 2a ed c6 c5 d5 bc bc 00 31 e3 |<.c.~n*.......1.| -00000320 5c 2b b7 88 ff 8f ef a7 34 7e c7 3e 3f 16 e6 75 |\+......4~.>?..u| -00000330 c8 1b 70 4a 2f 18 81 c3 d3 81 63 e8 31 f4 42 f8 |..pJ/.....c.1.B.| -00000340 02 2d 2e fb d5 65 60 93 df b5 d4 c8 8e 55 29 b3 |.-...e`......U).| -00000350 72 01 86 19 10 3d 17 03 03 00 99 e9 b1 32 d5 5f |r....=.......2._| -00000360 59 fb 7f 80 0e 70 2e 1a 76 ae dd 7f 84 ee 86 69 |Y....p..v......i| -00000370 37 a6 31 f2 83 78 8d 90 98 eb 43 96 22 9f ba 34 |7.1..x....C."..4| -00000380 09 e3 78 c9 5f 5a f0 0b 51 58 c9 8e 63 b7 04 88 |..x._Z..QX..c...| -00000390 74 a2 1c c9 da f3 9e 30 c0 c7 a9 da f4 43 d5 a2 |t......0.....C..| -000003a0 b7 c4 aa 33 5f be f9 e2 68 d6 73 f2 3d ae 1b e5 |...3_...h.s.=...| -000003b0 5b b5 7d ce cb 9d 72 a2 2d bc 30 35 43 a1 3f 53 |[.}...r.-.05C.?S| -000003c0 43 61 a3 4e 6e 90 8c 8a 78 b5 35 74 98 51 d2 33 |Ca.Nn...x.5t.Q.3| -000003d0 3a 9f c5 39 79 6d 5d fe ce 5e e2 dc 12 56 ac 56 |:..9ym]..^...V.V| -000003e0 0b 6c 86 3c 85 cb 12 18 46 dd ed 53 04 9a 88 34 |.l.<....F..S...4| -000003f0 84 df b0 cf 17 03 03 00 45 f6 a8 20 67 5a d1 87 |........E.. gZ..| -00000400 ac e4 d7 95 d0 8b 8f 96 cd b6 12 7d eb 3c 28 21 |...........}.<(!| -00000410 5a 7d 53 86 9e 55 cd 9b 24 1a c3 c7 6a 30 84 6f |Z}S..U..$...j0.o| -00000420 f7 96 ac 29 b5 ee 5d 66 32 c6 52 13 79 32 67 27 |...)..]f2.R.y2g'| -00000430 6b 5b bc 54 1e 28 b2 73 5f 5d 4d 6f 11 fc |k[.T.(.s_]Mo..| +00000080 03 03 00 01 01 17 03 03 00 17 f1 7c 16 5a 86 b4 |...........|.Z..| +00000090 13 82 93 fa ba 07 35 24 03 f5 24 25 cc 2d c8 e5 |......5$..$%.-..| +000000a0 6c 17 03 03 00 3e cb 02 08 06 a3 75 03 c6 5d d9 |l....>.....u..].| +000000b0 9c 66 ad db 29 6d 93 a6 53 c6 38 7f 9c 56 1e b1 |.f..)m..S.8..V..| +000000c0 f5 a8 77 19 43 c3 93 5e 67 dc 80 db 1b c8 30 b2 |..w.C..^g.....0.| +000000d0 04 85 6e 5c 8f 3a 4a f2 d2 aa 17 c7 d3 ea 29 f2 |..n\.:J.......).| +000000e0 09 08 49 90 17 03 03 02 6d dd 26 0f f5 1b 6b 11 |..I.....m.&...k.| +000000f0 1c c7 e9 87 bf de 58 08 e4 bc a6 49 98 fd bf 87 |......X....I....| +00000100 31 35 59 c1 88 5a 8c 0d e7 42 47 b6 cb ec 3c 6f |15Y..Z...BG...| +00000160 16 e6 ff be 29 a3 60 13 f8 8c 82 6c 84 dd c1 c8 |....).`....l....| +00000170 8b a2 bf e5 70 03 c3 a4 92 3d 99 a8 fc 92 15 e4 |....p....=......| +00000180 1d 13 7d b5 1f d3 a6 76 1c 8c 9f 9f e7 87 b4 fb |..}....v........| +00000190 25 b8 cf 83 0a 3b bd c7 e8 30 d4 15 6f ae d5 b9 |%....;...0..o...| +000001a0 da 3b c6 3f 0c 06 7a 78 e6 ac ca 64 cb 34 cc 7b |.;.?..zx...d.4.{| +000001b0 46 78 ec e2 22 9e 31 39 63 a7 7b 1d d6 c2 4b 91 |Fx..".19c.{...K.| +000001c0 45 fa 95 54 ef 9b b3 2e 55 83 77 c8 cf 15 b5 34 |E..T....U.w....4| +000001d0 11 4c 92 36 22 54 3d 2f b0 cb 28 7f 2b 1e b1 3f |.L.6"T=/..(.+..?| +000001e0 38 4a 4a d6 e8 a1 e6 e0 4f 20 ab 04 6f 6b 00 5e |8JJ.....O ..ok.^| +000001f0 d4 16 42 ab a5 04 67 9b 89 45 78 8b ea 0e 7d c8 |..B...g..Ex...}.| +00000200 24 d5 fb 83 c7 13 25 b7 1b 6f 3f 2a 2e cf bb 71 |$.....%..o?*...q| +00000210 11 48 5d e6 98 5e ca dd f7 6d dc 93 b1 51 1e 99 |.H]..^...m...Q..| +00000220 b9 e0 4c 39 c8 82 d8 9f 8d 70 25 78 5b b1 85 1d |..L9.....p%x[...| +00000230 cb 75 31 61 c3 ad d5 c1 d5 1f 26 06 60 5f cd eb |.u1a......&.`_..| +00000240 ee 4c 99 43 02 b9 e5 f5 99 98 94 cf 14 1c ad 54 |.L.C...........T| +00000250 20 a9 d3 73 f2 3f bc a1 25 39 8b ff c4 e0 ee 8b | ..s.?..%9......| +00000260 ba ec fc b0 c2 42 4c 5a 30 9c 26 1b f0 f2 da 94 |.....BLZ0.&.....| +00000270 26 69 55 0e fb 84 a0 58 95 43 08 6c 87 82 93 02 |&iU....X.C.l....| +00000280 cf 27 99 94 a3 ae 9f 08 d0 6e f2 a8 e8 29 fc a8 |.'.......n...)..| +00000290 67 d3 20 37 83 5d 8a 12 0a 57 10 bf 30 5a e1 05 |g. 7.]...W..0Z..| +000002a0 30 e0 b7 7b 47 7e a6 07 cc 9a dd 6d e8 11 89 c7 |0..{G~.....m....| +000002b0 7d 98 c3 6d 83 9f 1b f4 ff ca 31 c8 39 7b c2 fb |}..m......1.9{..| +000002c0 69 dc ee eb ab e2 39 72 35 6b 22 e4 84 2f 1d 58 |i.....9r5k"../.X| +000002d0 07 b0 9e 3e 69 ca ff 17 44 d6 e4 a8 56 6a 24 35 |...>i...D...Vj$5| +000002e0 08 39 42 41 da 76 4b 4f 00 ce 41 58 4e 70 d5 b6 |.9BA.vKO..AXNp..| +000002f0 50 b4 88 91 47 4a 89 04 ef e8 14 2e cf e3 9d 36 |P...GJ.........6| +00000300 c0 b5 2b 8e 42 2f 4b 95 39 55 6f 5a 23 5b 5e 05 |..+.B/K.9UoZ#[^.| +00000310 f0 34 70 c0 f7 92 54 e2 5c 52 20 b0 c1 2a 9a cb |.4p...T.\R ..*..| +00000320 3a 32 0e 93 77 96 f2 6a d8 f7 bc 7c d8 40 4e 5e |:2..w..j...|.@N^| +00000330 37 1c 8b aa 75 89 94 51 da 19 72 80 86 c8 3d bd |7...u..Q..r...=.| +00000340 fd 7d 06 13 bb 54 a1 0b 46 58 07 e5 35 b3 f3 ff |.}...T..FX..5...| +00000350 8a 98 9d e6 e8 05 17 03 03 00 99 5a 63 3c ff cc |...........Zc<..| +00000360 a0 ec 5f 52 4d 28 96 80 22 f7 8c a7 ad b7 1f 4a |.._RM(.."......J| +00000370 8c 46 79 06 31 96 46 f9 f0 57 8c c4 5b f9 71 61 |.Fy.1.F..W..[.qa| +00000380 34 0d 3e 78 67 05 1c 93 a7 a2 cd ea ce e5 a2 6e |4.>xg..........n| +00000390 37 4f 16 a4 e4 4c 60 d5 5a 37 f1 2a bf ce 2f 80 |7O...L`.Z7.*../.| +000003a0 ea 65 e6 25 03 fc 2b 17 3f a4 71 3f 04 46 2b f7 |.e.%..+.?.q?.F+.| +000003b0 12 b0 a6 f3 fc 8d cf 5e 95 85 84 88 e4 db 46 a4 |.......^......F.| +000003c0 f2 3a a5 27 44 3d a2 03 b3 65 af 1f e3 44 aa 02 |.:.'D=...e...D..| +000003d0 0f 39 eb 3d 0e 2a ae 0c 1b ed 84 df 8d e3 a2 1d |.9.=.*..........| +000003e0 6d 55 bf d6 13 f6 00 da 93 a7 fc b1 50 79 2c a9 |mU..........Py,.| +000003f0 93 cb 7d 70 17 03 03 00 35 9e b7 c2 c6 29 a9 43 |..}p....5....).C| +00000400 3f df 06 80 31 ac d9 f7 3b cd 14 16 a0 85 ca e6 |?...1...;.......| +00000410 34 70 e3 fc af 1c 94 9b 87 b3 17 6c a4 83 64 2c |4p.........l..d,| +00000420 6e 26 4c e9 ab 79 a9 c8 1d d4 1c 96 2c f2 |n&L..y......,.| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 02 1e 60 1c a1 8d ec |...........`....| -00000010 40 73 af df e0 a2 e8 c7 0d f5 f3 8c 5b 9e 58 f0 |@s..........[.X.| -00000020 5d 77 d8 d1 42 bd 30 e4 0d f5 5f b6 68 89 0f bb |]w..B.0..._.h...| -00000030 73 ff dc 9b 77 b6 c9 f2 3c a8 5a 95 43 f6 53 22 |s...w...<.Z.C.S"| -00000040 f3 96 7c 48 b6 df d2 ed a1 39 00 f1 c5 20 5d bd |..|H.....9... ].| -00000050 bd 27 4b d7 5f d7 7e 57 3c 22 84 cf 6f 2c 85 4f |.'K._.~W<"..o,.O| -00000060 50 8e 71 0c 70 cb e9 3b 52 31 12 ac 0e 1c d0 0c |P.q.p..;R1......| -00000070 a5 c7 20 83 77 95 b5 0d 2f b8 f9 51 83 17 d1 9b |.. .w.../..Q....| -00000080 69 ca 0a 9c e1 8e 1d 3d 95 2b 10 56 24 47 e0 6e |i......=.+.V$G.n| -00000090 ba 56 94 c9 a8 b5 62 b4 4d da 70 73 e0 a0 0b 15 |.V....b.M.ps....| -000000a0 60 22 f4 3f a3 e4 c6 86 a9 a3 dd db 5b 69 5c ce |`".?........[i\.| -000000b0 99 14 6a 93 8e c7 21 ff 99 4d da 25 3b 87 3a ae |..j...!..M.%;.:.| -000000c0 7d 9b 9a 06 6f e4 36 02 64 07 d4 43 84 5b 6f 98 |}...o.6.d..C.[o.| -000000d0 6c ec 6b 77 92 17 75 2e ea c5 02 ab ce 8c c2 9a |l.kw..u.........| -000000e0 18 e7 90 05 da 68 5a c9 d8 22 8c d2 de 17 b5 87 |.....hZ.."......| -000000f0 a1 74 e9 bc 54 07 36 ef 61 1f 3a 43 51 15 2a 98 |.t..T.6.a.:CQ.*.| -00000100 53 84 89 d4 90 a7 f0 a6 e4 35 6c 70 9b f5 a4 51 |S........5lp...Q| -00000110 b4 69 9c 58 10 df cc 50 04 46 43 0a c5 9d ca f1 |.i.X...P.FC.....| -00000120 23 2c a5 1e 6c d6 36 82 21 1f db 9a ae 55 f2 77 |#,..l.6.!....U.w| -00000130 ad 13 e8 97 24 3c c9 c1 a5 b2 18 3c a6 cf ab c6 |....$<.....<....| -00000140 05 88 06 e1 23 fb b7 85 a6 e8 57 38 6d 58 22 b8 |....#.....W8mX".| -00000150 02 c6 0d 40 22 10 cd da dc 21 ef 6b ae 6c 5d c5 |...@"....!.k.l].| -00000160 8e 62 a7 21 be 7c b7 47 60 af 55 e7 db 6f 47 59 |.b.!.|.G`.U..oGY| -00000170 62 dd f2 f6 62 9b cd 2c 46 ec b8 05 47 d4 f9 8d |b...b..,F...G...| -00000180 ee 89 09 f6 d0 ac 8d 4f 27 d1 f7 4e cb aa 55 0b |.......O'..N..U.| -00000190 be 64 ed 69 45 7c 0a b5 95 5c b3 63 c4 1c ff 12 |.d.iE|...\.c....| -000001a0 de ad 11 f9 d4 de d4 94 d7 cb 31 55 21 51 09 12 |..........1U!Q..| -000001b0 33 20 df 64 4f 57 f3 da 68 24 20 f7 df 9d b3 4c |3 .dOW..h$ ....L| -000001c0 7f b1 c4 5a 85 d2 95 bd 98 e8 05 7b 20 f1 34 97 |...Z.......{ .4.| -000001d0 6e 73 ed 5d 5f 97 56 a6 9a 6f e7 91 27 be b2 d9 |ns.]_.V..o..'...| -000001e0 ef 48 9b 3d d8 80 e1 e1 d5 46 de 6c 83 7d 16 24 |.H.=.....F.l.}.$| -000001f0 03 f0 a1 29 fd 8e a7 db 63 88 51 e3 ac 5d a6 c9 |...)....c.Q..]..| -00000200 19 e4 a4 40 0f 92 1b 4c 3b 9d 4a fc b2 cf c5 62 |...@...L;.J....b| -00000210 db 72 d2 9e f8 c0 00 ab fe af ac 66 46 8d b7 8e |.r.........fF...| -00000220 dc ab 07 c4 87 09 0e 9b 04 17 03 03 00 a4 7b 67 |..............{g| -00000230 11 bf bb 27 7d c0 ab f4 14 a8 44 a1 e1 b1 ba 0c |...'}.....D.....| -00000240 4c d0 4e 9d 74 5f dd 60 bb c9 33 ad 29 91 a7 a0 |L.N.t_.`..3.)...| -00000250 18 61 44 25 bf a1 45 e2 9b 24 93 20 45 0b 2a 09 |.aD%..E..$. E.*.| -00000260 07 75 4d ad 1a 04 34 df 7b 1b c8 f7 e7 fc 4e 99 |.uM...4.{.....N.| -00000270 27 97 d5 9a 7f 63 39 00 5c ed ba a4 5b 9b 44 72 |'....c9.\...[.Dr| -00000280 cb 3e 80 68 9a 78 e9 bc 12 35 94 9d b2 1c 34 f6 |.>.h.x...5....4.| -00000290 ce c7 cf 61 5e a9 c2 21 79 e9 e3 4c e8 e5 dc fe |...a^..!y..L....| -000002a0 e2 1d 7a 2b c3 dd 15 f8 e5 0e 20 6f 99 fd ea ef |..z+...... o....| -000002b0 a1 a4 be a9 28 1a d0 f8 3e 0a c2 76 6b 24 b1 56 |....(...>..vk$.V| -000002c0 0f 52 25 f6 56 65 96 92 4f 07 71 9d 25 25 99 2c |.R%.Ve..O.q.%%.,| -000002d0 dc 04 17 03 03 00 45 c5 e8 b3 d0 ca 89 02 da 08 |......E.........| -000002e0 73 57 9c a6 49 de da b3 e7 92 59 8e 25 29 45 8b |sW..I.....Y.%)E.| -000002f0 fb 56 b6 53 dd d1 59 6c 5f 39 7a d4 d8 e6 db e3 |.V.S..Yl_9z.....| -00000300 60 8c a4 8a 81 2b a5 26 a7 21 89 e9 8a f7 fe 39 |`....+.&.!.....9| -00000310 44 a2 bd 1c 49 18 47 b9 69 ef 1c 74 |D...I.G.i..t| +00000000 14 03 03 00 01 01 17 03 03 02 1e 08 6d ee 1c 88 |............m...| +00000010 63 86 93 3e 73 8e 87 6f 51 8b d3 d2 91 c5 cb 55 |c..>s..oQ......U| +00000020 2d 7c 9f 32 d8 0a ab e5 53 95 4b 0c 22 12 23 56 |-|.2....S.K.".#V| +00000030 07 ce 1b e1 46 f7 46 84 cb 47 83 62 4a 16 39 44 |....F.F..G.bJ.9D| +00000040 bf 58 25 6e f1 22 d0 ea 06 d8 da 44 91 bb 27 41 |.X%n.".....D..'A| +00000050 1f 6e 46 89 88 93 a7 0a 60 8f 1a e5 31 19 5c 27 |.nF.....`...1.\'| +00000060 a3 f6 8c 1b ee 5b 2b 21 c4 64 c7 d9 92 7b e9 ca |.....[+!.d...{..| +00000070 e0 16 29 d0 64 32 95 a8 8f a8 24 cc 56 c6 3e 7d |..).d2....$.V.>}| +00000080 1b f6 06 a6 fa d6 dc 79 38 60 4f 6f b7 e1 10 ab |.......y8`Oo....| +00000090 21 14 8e e1 90 95 6d b6 f3 ca 86 1a dd 32 c5 33 |!.....m......2.3| +000000a0 e1 fc 8c da 77 02 54 88 73 f3 72 71 c6 58 ad 1a |....w.T.s.rq.X..| +000000b0 10 b8 15 c3 69 f1 cc 71 b6 ea 7e b7 81 4b de 7b |....i..q..~..K.{| +000000c0 77 87 24 e0 c0 39 5c 5b 17 ad 7c 59 53 43 cf 7e |w.$..9\[..|YSC.~| +000000d0 cb 70 4d 51 f1 7e 8c 2b 19 61 13 75 bf 25 df 80 |.pMQ.~.+.a.u.%..| +000000e0 f2 fa cd 70 8d db eb bc 38 ae 6a 0c ad ef d2 e2 |...p....8.j.....| +000000f0 f0 f1 02 97 ce 37 8b 8f 9e bd 4f 92 40 e7 8f 9f |.....7....O.@...| +00000100 26 b7 cd ef cf 57 28 2f 12 cc 69 e1 be f2 59 c6 |&....W(/..i...Y.| +00000110 be dc 51 9a 67 be 4a f1 97 f9 7a d9 01 05 1f d0 |..Q.g.J...z.....| +00000120 2b 96 5b b5 4d 1d c1 2e 99 7e eb e3 20 92 b0 f8 |+.[.M....~.. ...| +00000130 ac 9f c1 e3 10 cd b1 e9 05 46 15 3c c2 fb ce 27 |.........F.<...'| +00000140 5e f1 47 e7 d8 ca 89 0e 77 37 86 6c c9 d4 e3 ae |^.G.....w7.l....| +00000150 1e 6e 63 4f 5c 2d aa a0 88 7c 35 47 87 e8 40 22 |.ncO\-...|5G..@"| +00000160 f8 45 2f 57 b4 e8 e1 95 45 58 02 53 3c 19 b5 92 |.E/W....EX.S<...| +00000170 73 55 fd 49 31 ec db dc 4c 6f 6f a7 9a 90 89 83 |sU.I1...Loo.....| +00000180 08 97 53 5a c6 6c 23 75 cd 68 37 54 2c 00 d3 56 |..SZ.l#u.h7T,..V| +00000190 5e 24 87 7b 92 a9 61 73 1e 84 31 0e ff d7 f2 fb |^$.{..as..1.....| +000001a0 62 5e f9 27 35 18 bb ca b2 c2 d7 5c bf 7f 6d 36 |b^.'5......\..m6| +000001b0 fa e6 02 4a d0 fa bd b8 c0 d0 2f 0c 27 6b 49 92 |...J....../.'kI.| +000001c0 20 54 01 ea 3c d2 07 f1 2e d6 e3 a3 a3 bd 1d 33 | T..<..........3| +000001d0 90 ee 26 ad a6 5c ee c7 de 4d e8 fc d2 b5 5a b5 |..&..\...M....Z.| +000001e0 7c 6f c5 61 23 11 20 eb 0f 7c b7 0a cc 8c 65 b7 ||o.a#. ..|....e.| +000001f0 e2 87 16 10 b0 fd 40 75 78 d1 3c 70 54 66 b8 cb |......@ux.>> Flow 4 (server to client) -00000000 17 03 03 02 a8 a1 f1 48 20 d7 51 ae a0 ec 04 30 |.......H .Q....0| -00000010 d3 98 bc b4 87 14 5a 73 c1 57 d9 9b b8 54 c0 cc |......Zs.W...T..| -00000020 e9 25 20 5a 1a 49 2c 3c 5d 0b a5 47 8e 58 df 3e |.% Z.I,<]..G.X.>| -00000030 44 d8 c7 68 5e e6 cd 78 41 ad 8b e2 83 5e fa 1b |D..h^..xA....^..| -00000040 05 93 18 fa c1 df 18 d0 b1 52 bc db ee f7 49 a8 |.........R....I.| -00000050 d8 fd 9c a9 f7 cd a2 b8 61 2b 09 f0 7e 03 e6 18 |........a+..~...| -00000060 7f 6b fc c8 5f 01 50 21 c9 99 94 7f 31 a8 0e 60 |.k.._.P!....1..`| -00000070 ec 21 63 b0 e7 90 0b ca 27 55 80 e2 6f 1d 6e e2 |.!c.....'U..o.n.| -00000080 47 54 a5 81 fd 65 da 31 7c 70 bf 8b 37 b7 53 fc |GT...e.1|p..7.S.| -00000090 fd 2d 46 79 69 7b aa a5 29 a2 11 ac 3c ab 20 29 |.-Fyi{..)...<. )| -000000a0 51 8d 30 da 9a 1d 0f 32 d8 3d 2a 06 0c 59 b9 5e |Q.0....2.=*..Y.^| -000000b0 fe 28 09 d6 49 7f 7c 9c 33 66 91 8e a9 b0 9c 38 |.(..I.|.3f.....8| -000000c0 94 db 68 f0 a1 60 ce 3d 95 49 3f 0a ba b1 15 f2 |..h..`.=.I?.....| -000000d0 61 e5 a0 91 72 71 28 af 43 54 0d 75 71 f9 6e 2f |a...rq(.CT.uq.n/| -000000e0 3c 6a fd 2f 96 5d a1 bc 5f 88 9f 3f 9f e3 80 94 |4..I..| -000002a0 b4 6e 11 4f 41 14 ee d8 2a 55 d9 88 1c 17 03 03 |.n.OA...*U......| -000002b0 00 1e 0b 7a 66 33 ad ae 08 ab 8e 75 dd e8 4b a1 |...zf3.....u..K.| -000002c0 ff 16 5d 43 c6 24 cc d9 0b 6e 71 a3 5e 18 03 94 |..]C.$...nq.^...| -000002d0 17 03 03 00 13 7c 2a ec 24 22 fd 49 16 b6 4f a1 |.....|*.$".I..O.| -000002e0 84 54 bf 3e a8 78 af 64 |.T.>.x.d| +00000000 17 03 03 02 98 07 3b b6 4e c1 7e 84 44 a0 5d 3c |......;.N.~.D.]<| +00000010 b8 45 37 1e bf 0f 43 cf d6 11 c7 0d d9 a4 25 7b |.E7...C.......%{| +00000020 27 fa 6e e1 9c 24 5f e5 f9 12 e8 a1 33 2e cc 24 |'.n..$_.....3..$| +00000030 43 3b ac e3 bd f2 7b 1d 66 70 eb 31 21 7f 3e 5e |C;....{.fp.1!.>^| +00000040 09 7a 29 8f 43 43 cb c4 6d 70 a7 51 1c 0f dc 21 |.z).CC..mp.Q...!| +00000050 e9 4c f5 16 8f 35 e8 5b ae 7f e0 47 e7 d4 53 66 |.L...5.[...G..Sf| +00000060 b2 cc ef 44 b7 3e 34 2b 32 a9 e6 89 b9 c6 f6 56 |...D.>4+2......V| +00000070 97 b3 78 37 3c 89 2f 35 8e a5 c7 ae c4 92 91 69 |..x7<./5.......i| +00000080 50 ae ee c9 7b 7a 3a 10 ce 1c 68 fd 09 57 3d 92 |P...{z:...h..W=.| +00000090 52 42 0e 4e 91 12 b4 fd e4 59 d4 1e 5a c7 25 b3 |RB.N.....Y..Z.%.| +000000a0 dd a1 dd 7d 7d 92 08 52 ec 85 15 c7 b6 60 70 fb |...}}..R.....`p.| +000000b0 76 6b 42 da 84 8e e5 a9 cb a4 b1 76 89 51 93 55 |vkB........v.Q.U| +000000c0 f3 92 aa cc 04 3b 78 97 ed 10 88 d8 77 d1 32 35 |.....;x.....w.25| +000000d0 93 82 a4 1d ca 47 df c8 72 93 10 90 e0 75 2d 3f |.....G..r....u-?| +000000e0 b0 6a 3d 9e b6 20 1d 0a 2a 03 66 be 18 18 d3 25 |.j=.. ..*.f....%| +000000f0 47 a2 ab 67 08 44 24 cb 94 29 8a f7 8b 8e ca a0 |G..g.D$..)......| +00000100 20 71 d0 af 87 5b e1 d9 5d e0 0c 70 13 3d 82 42 | q...[..]..p.=.B| +00000110 b3 b8 fb 5e 1d f1 58 88 ea 11 67 28 49 11 d4 27 |...^..X...g(I..'| +00000120 05 87 e4 b1 21 15 d1 3a 6a df ee 6d 40 7c 3f 8c |....!..:j..m@|?.| +00000130 7e cd 7b 0c 0e ef fd 17 29 29 f8 03 98 8e 76 ac |~.{.....))....v.| +00000140 23 e2 81 30 8b c7 7b 9b 5a 78 f7 6a 53 32 5c bd |#..0..{.Zx.jS2\.| +00000150 d7 42 cb 77 f5 1d ea 03 74 9f ec 1d 1b 68 72 aa |.B.w....t....hr.| +00000160 9f e0 7d 58 2f 26 47 6b 2d e4 1f 78 f4 ab d3 ae |..}X/&Gk-..x....| +00000170 51 6c 2a 35 0a 6f 9a c8 2b 75 ff 69 3e 4b 61 bc |Ql*5.o..+u.i>Ka.| +00000180 03 29 60 04 8b 53 9f ae e4 00 7f 88 7a d4 70 b8 |.)`..S......z.p.| +00000190 65 83 87 96 5d ef f1 b2 e8 7e 0e af 0b 2c 07 dd |e...]....~...,..| +000001a0 a9 0e f8 c3 9b 59 aa cf 74 02 5e 46 8c cb 3d ee |.....Y..t.^F..=.| +000001b0 72 67 7c 46 37 29 78 d8 80 6e 42 16 b7 a8 59 35 |rg|F7)x..nB...Y5| +000001c0 cb 36 ce 73 50 80 d2 35 7a 69 b9 f3 14 73 04 e7 |.6.sP..5zi...s..| +000001d0 ec dd 92 80 b0 f6 b7 51 28 15 56 c4 bb 83 00 86 |.......Q(.V.....| +000001e0 9e 21 e7 bd 91 33 15 d4 aa da 8a 07 eb 2e d9 48 |.!...3.........H| +000001f0 c3 71 1a da be 6f 00 45 bd 08 a3 70 17 d5 c0 1a |.q...o.E...p....| +00000200 74 87 5a 95 60 aa 1d ce 0e e1 46 57 85 8c e0 ae |t.Z.`.....FW....| +00000210 98 1a f9 83 7f ec 04 bd 90 dc 51 4f 7e d2 52 28 |..........QO~.R(| +00000220 ca 33 f6 60 4a 0c e4 7d b3 93 4f 70 7a ce d3 3e |.3.`J..}..Opz..>| +00000230 0a dd 50 b0 17 0a 2e db 2c ad 3d 86 d3 e6 60 07 |..P.....,.=...`.| +00000240 43 61 9c a0 ff 45 37 9a 60 3d c5 f7 4d 27 fc b4 |Ca...E7.`=..M'..| +00000250 9a 05 1c 0a ae 08 9d d9 5c 15 09 c9 8e 24 bb e2 |........\....$..| +00000260 ec a1 a7 27 f0 42 97 a9 af ed 25 fd 5f f1 2a 4d |...'.B....%._.*M| +00000270 ac ab 9c a5 7d 28 6b c8 36 ec 0c 12 5b eb fa 64 |....}(k.6...[..d| +00000280 83 74 13 6e 44 5a 23 38 f0 a6 22 3e f9 88 f1 0d |.t.nDZ#8..">....| +00000290 2a 55 b8 bf aa 87 de a4 7f 8b ba 52 23 17 03 03 |*U.........R#...| +000002a0 00 1e fb 80 15 2b ff db 63 29 a7 77 ef 1e 82 28 |.....+..c).w...(| +000002b0 8d d5 f0 5b 5d 42 8e 34 f9 64 5c 47 eb c3 10 4c |...[]B.4.d\G...L| +000002c0 17 03 03 00 13 a1 8b 9e d8 57 0e 04 96 7c b4 83 |.........W...|..| +000002d0 70 a2 20 03 ee 28 23 c7 |p. ..(#.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given b/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given index 7a8d6d03070..d80b76fc6c7 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given @@ -1,154 +1,149 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e0 01 00 00 dc 03 03 f4 33 e3 f1 5d |............3..]| -00000010 94 d0 5e 26 62 41 72 76 29 ff 09 d9 ba 11 e0 f1 |..^&bArv).......| -00000020 cb 58 56 ba 7d 37 44 09 31 86 b4 20 88 9f f1 76 |.XV.}7D.1.. ...v| -00000030 f4 fe 3c 7b 4e 77 fb bb 58 76 90 f2 d7 32 21 07 |..<{Nw..Xv...2!.| -00000040 d8 bf da 67 93 ba 8f e8 e4 e2 48 c3 00 08 13 02 |...g......H.....| -00000050 13 03 13 01 00 ff 01 00 00 8b 00 00 00 0e 00 0c |................| -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 1e |................| -00000090 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -000000a0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 00 2b |...............+| -000000b0 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 |......-.....3.&.| -000000c0 24 00 1d 00 20 72 9a 7f b9 89 71 2f ab 7d 09 a7 |$... r....q/.}..| -000000d0 8e eb 17 07 21 41 01 3f d0 3e eb ae 5e 6a 05 4c |....!A.?.>..^j.L| -000000e0 74 c3 bb a2 35 |t...5| +00000000 16 03 01 00 ca 01 00 00 c6 03 03 3d 6d 5a b0 92 |...........=mZ..| +00000010 7b 62 6d 14 22 f5 08 70 77 4a 80 fa 69 1a 1c 92 |{bm."..pwJ..i...| +00000020 4c d3 e5 ca 3a d0 ee 33 40 c8 64 20 e5 a7 f1 57 |L...:..3@.d ...W| +00000030 39 32 e3 9f 7c 33 58 16 61 58 29 44 aa e4 50 b1 |92..|3X.aX)D..P.| +00000040 37 c5 59 27 f2 d5 b8 6e 01 24 c2 6b 00 04 13 01 |7.Y'...n.$.k....| +00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................| +00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| +00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......| +000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 cb |-.....3.&.$... .| +000000b0 da f4 03 da e7 6f e5 2b 25 c0 cb cf 52 0a fb af |.....o.+%...R...| +000000c0 8a 87 4c 2b 88 e4 1a b3 a0 34 30 fb 9d 4e 0e |..L+.....40..N.| >>> 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 88 9f f1 76 |........... ...v| -00000030 f4 fe 3c 7b 4e 77 fb bb 58 76 90 f2 d7 32 21 07 |..<{Nw..Xv...2!.| -00000040 d8 bf da 67 93 ba 8f e8 e4 e2 48 c3 13 02 00 00 |...g......H.....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 e5 a7 f1 57 |........... ...W| +00000030 39 32 e3 9f 7c 33 58 16 61 58 29 44 aa e4 50 b1 |92..|3X.aX)D..P.| +00000040 37 c5 59 27 f2 d5 b8 6e 01 24 c2 6b 13 01 00 00 |7.Y'...n.$.k....| 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 5c 89 3f 32 3d 88 |..........\.?2=.| -00000090 9e 8a a3 d1 ae 90 75 c1 20 15 cf 41 9d 95 94 76 |......u. ..A...v| -000000a0 08 17 03 03 00 3e 7c a9 ca b7 2f 71 e0 4c b9 0d |.....>|.../q.L..| -000000b0 82 cd be 73 2f fe d2 21 d9 b3 63 fc 53 e0 ff 13 |...s/..!..c.S...| -000000c0 39 40 98 a5 7a ee ae 0b c2 bc 90 ca b6 69 8f 48 |9@..z........i.H| -000000d0 b8 5d 8f 41 62 d6 ad 92 c5 cd 40 bd 77 1c 6c 23 |.].Ab.....@.w.l#| -000000e0 5d 20 ce 87 17 03 03 02 6d cc 94 31 f8 57 e9 18 |] ......m..1.W..| -000000f0 04 31 82 f4 53 17 8d 2d 1d f9 58 15 ad 1b 5c bd |.1..S..-..X...\.| -00000100 39 85 02 37 87 c7 00 5f 0f df fd 2c cc b3 be ce |9..7..._...,....| -00000110 d1 4d 08 7f a7 5c 12 3f e7 99 67 48 0f c4 11 9e |.M...\.?..gH....| -00000120 52 06 a1 ae 8e 6c 9a 80 02 9e 88 1c 70 59 19 40 |R....l......pY.@| -00000130 d8 9b 01 35 76 f1 2f cf ba 2a ba 8c 56 90 d2 98 |...5v./..*..V...| -00000140 e9 f2 53 60 71 55 ef ca 96 8a 45 ee 6f 6e 99 e6 |..S`qU....E.on..| -00000150 57 a4 9e c4 b6 fa c4 41 fe 72 b0 2b 69 8c f0 d7 |W......A.r.+i...| -00000160 ea 27 73 b6 a6 8a bc 3c 5f c9 a3 e3 78 ae 04 4c |.'s....<_...x..L| -00000170 a5 2f b5 ac 58 63 06 a2 c5 44 99 2f 97 d7 c5 d7 |./..Xc...D./....| -00000180 4c ea 01 cb c7 f9 11 0e 6d 27 33 13 57 97 b1 7b |L.......m'3.W..{| -00000190 50 48 b2 89 f6 ee 67 36 87 22 3e cb 61 2e d7 ff |PH....g6.">.a...| -000001a0 99 c7 19 79 ff d8 af 66 95 f3 19 01 f7 67 67 47 |...y...f.....ggG| -000001b0 a8 c1 c5 56 78 4f 7d 54 63 53 7f ad 2d 35 57 91 |...VxO}TcS..-5W.| -000001c0 17 3f b3 b4 ce 69 9f d3 8e 50 eb 2d f4 dc c8 87 |.?...i...P.-....| -000001d0 49 4a 45 88 55 ab e3 8b 75 ac d2 7d 39 d0 ea a9 |IJE.U...u..}9...| -000001e0 32 9c 44 9e 81 2c 9e fc 2c 4f 2d b2 b1 30 de 2a |2.D..,..,O-..0.*| -000001f0 40 22 da d0 f3 3f d6 9e 51 14 d2 84 41 20 d3 f0 |@"...?..Q...A ..| -00000200 58 b5 ba 68 62 12 d1 4a ab 37 72 4e 56 8e 80 0f |X..hb..J.7rNV...| -00000210 0d 85 e7 1c 91 d3 1e ee 73 d0 9e 1b 6f 1b 53 1b |........s...o.S.| -00000220 c2 28 5b 9b ef 20 e3 c2 aa 4b 87 26 d9 5e 52 ef |.([.. ...K.&.^R.| -00000230 79 9d c8 4b b1 38 eb 46 73 85 ac 0b 96 34 22 61 |y..K.8.Fs....4"a| -00000240 cc cd 11 9e fb 30 b9 b7 4f 09 17 79 98 83 09 65 |.....0..O..y...e| -00000250 81 de af b1 2e f1 15 0c 4a bd fd 65 da 7b 7c 00 |........J..e.{|.| -00000260 98 fd 2f 97 de 1c e9 05 16 de b2 50 d2 5c e1 cd |../........P.\..| -00000270 19 ef d3 48 5c 03 dd ca b5 62 ce 17 b4 3c 2d e9 |...H\....b...<-.| -00000280 a8 78 6c b9 10 9c d9 2f 89 b1 7e 32 05 f7 6d d3 |.xl..../..~2..m.| -00000290 1c 30 10 1b 30 dc 17 7c c7 52 cf 93 18 b9 4f b1 |.0..0..|.R....O.| -000002a0 cd 05 e5 73 e6 00 b5 d0 42 98 cd cd 14 54 b0 01 |...s....B....T..| -000002b0 92 49 a9 e4 12 27 f9 67 df 3b b3 e9 08 d3 f6 53 |.I...'.g.;.....S| -000002c0 a7 5b 71 9f 96 3b 7e ca ac c6 81 a2 14 66 64 bf |.[q..;~......fd.| -000002d0 ff 0f 8d 5f 23 63 6e 39 7e 9c 83 3f e8 4c db d6 |..._#cn9~..?.L..| -000002e0 91 6d 47 8d 54 f3 bd 44 de e8 13 9b fd 84 5c 97 |.mG.T..D......\.| -000002f0 81 a2 c6 33 d8 d9 4e ce 8d b6 35 2f e3 a2 3a 52 |...3..N...5/..:R| -00000300 2f 6a fa 1a 22 42 07 19 41 55 5a 20 ac 12 d8 13 |/j.."B..AUZ ....| -00000310 4c 2e 41 34 81 c7 0d 83 d1 5d 3f f9 02 e6 43 69 |L.A4.....]?...Ci| -00000320 b6 08 95 fb 8a fc 27 cc d7 61 52 82 89 a3 bb 84 |......'..aR.....| -00000330 e4 53 a4 b8 96 cb 8c 53 c0 4d 16 95 a9 d1 70 23 |.S.....S.M....p#| -00000340 52 5e 7e f6 01 a3 1e 45 28 53 18 23 a0 df ab ee |R^~....E(S.#....| -00000350 2f 09 4c 02 8e dc 17 03 03 00 99 b4 38 62 ca 65 |/.L.........8b.e| -00000360 1c cf 0a ed d7 d9 65 f4 db d2 53 7b f2 bf 2a 98 |......e...S{..*.| -00000370 72 e8 2d 51 41 c2 b7 af 5e 84 40 23 64 51 16 bc |r.-QA...^.@#dQ..| -00000380 cd 3a f4 78 c2 01 c1 4f ba 6f 4a 60 c4 06 76 df |.:.x...O.oJ`..v.| -00000390 f7 19 7a aa b0 22 91 95 11 b0 07 32 50 30 be 6a |..z..".....2P0.j| -000003a0 ec 6b 94 49 8b b7 04 35 32 8f b2 71 42 9e d8 e3 |.k.I...52..qB...| -000003b0 c8 33 32 27 63 d1 fb 6f 21 9b f6 08 aa 6f be 56 |.32'c..o!....o.V| -000003c0 3c a0 77 af 7c b9 e2 a6 51 27 12 fc b3 81 c0 d7 |<.w.|...Q'......| -000003d0 53 58 94 b5 2b 34 ff 06 59 42 2e c4 aa 44 07 46 |SX..+4..YB...D.F| -000003e0 8e af 4d d8 11 d8 56 f1 4c cb 2f aa 87 99 2e 08 |..M...V.L./.....| -000003f0 9a 4a e5 11 17 03 03 00 45 a6 e5 85 12 20 f0 6d |.J......E.... .m| -00000400 2a d0 45 c0 8a f2 12 f9 61 20 ed 30 91 2d a1 a9 |*.E.....a .0.-..| -00000410 33 6f 2a 70 46 64 b0 2c 79 19 f4 11 0b 7e 3b c0 |3o*pFd.,y....~;.| -00000420 bb e8 21 bc f6 ab 09 de ef 16 17 65 32 0a 80 47 |..!........e2..G| -00000430 25 cd 0b 93 8c 14 e2 1e 1e ff 24 61 6d 4a |%.........$amJ| +00000080 03 03 00 01 01 17 03 03 00 17 2d 8b 08 3c eb 5e |..........-..<.^| +00000090 e6 d7 8e 9a 11 d0 e1 a3 3f 88 cc 83 49 e3 af 50 |........?...I..P| +000000a0 66 17 03 03 00 3e 24 ba 0e 2f d7 51 a9 52 5d 51 |f....>$../.Q.R]Q| +000000b0 a4 7d b6 dc 5c 43 2e d8 58 5e 72 f1 86 98 15 b8 |.}..\C..X^r.....| +000000c0 db 0a 48 0a 06 c4 ad 36 41 84 f1 89 36 e9 24 da |..H....6A...6.$.| +000000d0 05 5a dc 82 02 a1 3d 39 ae 4c 7e d9 7b 43 1f 2c |.Z....=9.L~.{C.,| +000000e0 06 71 a0 2f 17 03 03 02 6d 48 44 6b d1 65 fb e1 |.q./....mHDk.e..| +000000f0 fb 96 00 e5 ad c6 60 e2 b5 f6 bf 7c b7 f4 6f 0e |......`....|..o.| +00000100 db a2 4b f7 cd d7 73 29 f8 af 23 5d d4 55 df 37 |..K...s)..#].U.7| +00000110 b7 62 38 d0 95 5c f1 48 32 5f cb fa 67 18 20 7f |.b8..\.H2_..g. .| +00000120 b7 0f ac fc 64 b7 b0 7b 4b 1f 65 1d 2a 94 8d 76 |....d..{K.e.*..v| +00000130 b4 30 3b ee 44 a5 f6 74 5b 7e bd a7 bb b2 d8 d6 |.0;.D..t[~......| +00000140 ac c6 1f b4 88 34 85 7e 89 2c 2e 0d bf 6c 16 0c |.....4.~.,...l..| +00000150 ce 35 57 13 29 55 60 20 86 21 20 c0 46 bc 9e dd |.5W.)U` .! .F...| +00000160 8a a0 41 60 b5 a9 16 cc 66 cb 4a ba 58 e0 70 d1 |..A`....f.J.X.p.| +00000170 a5 b4 eb ac 54 7e 95 11 00 f0 70 63 af 56 57 99 |....T~....pc.VW.| +00000180 68 57 b4 5b aa db f1 08 2e c0 fb df 93 b8 4a f8 |hW.[..........J.| +00000190 2e 04 b3 2c 2b f9 47 09 a1 5f a3 3e 97 eb d4 d5 |...,+.G.._.>....| +000001a0 df ec d1 9e 05 5e 10 b0 2b 7e 0e b4 c8 e1 e3 50 |.....^..+~.....P| +000001b0 29 19 8b 3c f7 d0 95 30 ae 4c e4 60 c8 13 09 15 |)..<...0.L.`....| +000001c0 b7 80 f3 ad a0 06 6b a7 b7 4a c4 6d 65 09 21 d3 |......k..J.me.!.| +000001d0 3b 56 dc ce f5 d3 fa 93 e9 03 8e 0c c9 47 21 89 |;V...........G!.| +000001e0 7f 39 23 f8 aa 68 f6 b4 82 50 1f b8 46 5d 26 dc |.9#..h...P..F]&.| +000001f0 b1 1f e5 e5 6b ad ad 0d d8 55 b7 8b 7a f8 5d fc |....k....U..z.].| +00000200 bd 74 a4 15 72 33 1b a7 3b 8c 09 55 d9 fd 21 bf |.t..r3..;..U..!.| +00000210 cd dd 67 d2 0c d0 bd 9b de 52 e3 5f 4d 54 c0 6c |..g......R._MT.l| +00000220 bd 93 ae 66 55 4b e9 75 6b db cd 6b 80 33 f4 b7 |...fUK.uk..k.3..| +00000230 61 9e e4 5d 75 b5 44 26 79 b5 da bf af 54 8c 40 |a..]u.D&y....T.@| +00000240 23 99 32 60 2a 76 b3 0a 46 37 c9 85 1c fe e9 a1 |#.2`*v..F7......| +00000250 a3 e8 61 67 04 eb 3e e8 2b d3 12 75 87 04 67 40 |..ag..>.+..u..g@| +00000260 19 63 c5 ef 75 d0 39 63 a0 c3 ae 3c b1 88 34 db |.c..u.9c...<..4.| +00000270 c7 29 0c 33 c8 40 c0 b0 e6 76 44 cc 99 4f 2b a6 |.).3.@...vD..O+.| +00000280 b3 e1 28 69 6c 41 74 55 53 a9 87 06 9a cb 14 5d |..(ilAtUS......]| +00000290 ec 74 77 e2 a0 ce 54 02 ba f8 04 2c 84 9a de 2b |.tw...T....,...+| +000002a0 dc 02 32 01 ad 96 5c a0 87 3c 55 dd ee 4d cb fd |..2...\..>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 01 50 ff 2c 08 a6 b9 |..........P.,...| -00000010 a0 6d 5f 39 45 8f 85 d5 95 80 60 2c 9c 13 3f f3 |.m_9E.....`,..?.| -00000020 e4 e8 c4 34 4d 2f 58 78 a6 51 57 5b 12 85 95 57 |...4M/Xx.QW[...W| -00000030 a3 04 01 5c f1 01 a0 ae 4f 46 1d c9 ab 92 c3 43 |...\....OF.....C| -00000040 89 a9 e8 8a 5b e4 eb d9 29 4a bd 80 4a b7 bb 63 |....[...)J..J..c| -00000050 07 ca 14 47 af 5f 21 dc 85 6b 04 64 aa d3 61 4b |...G._!..k.d..aK| -00000060 5b 76 c9 ec 37 71 d8 fe 86 5a 12 a7 0d c3 a3 98 |[v..7q...Z......| -00000070 09 a9 6f 03 2b a1 e2 43 35 be 9c 34 b5 4e 0c 05 |..o.+..C5..4.N..| -00000080 fa 64 d8 9e 37 36 83 08 be ba 4d 30 2a d5 9f 43 |.d..76....M0*..C| -00000090 38 92 af 63 56 1e df 03 51 86 e9 26 5e 28 97 ff |8..cV...Q..&^(..| -000000a0 cf 91 6d fe cc a1 02 1a 34 a7 5d d2 25 20 5b ae |..m.....4.].% [.| -000000b0 ef 9e fe 0f ef 5d 74 f4 f5 14 54 47 33 f9 15 5d |.....]t...TG3..]| -000000c0 6f 85 d8 16 ed 3b 1e 3e c5 72 2f 17 65 98 5c 4c |o....;.>.r/.e.\L| -000000d0 84 c2 f4 44 6b c2 3d 04 5c 81 ef ec b8 40 e6 cb |...Dk.=.\....@..| -000000e0 20 87 3c 3b b9 38 92 5e 48 dd 20 fe e9 a8 e6 9b | .<;.8.^H. .....| -000000f0 14 2b e7 d3 77 b7 44 ed c7 eb cb 0c c8 d6 db 06 |.+..w.D.........| -00000100 3c c7 7f a3 09 b4 00 5c 93 10 79 76 0e 45 f6 d2 |<......\..yv.E..| -00000110 8b c0 91 91 7a 2d 17 e6 10 95 a2 9a df c4 da 85 |....z-..........| -00000120 88 66 f4 bb 9b d5 0f 32 f2 f2 dc a6 16 b5 e9 4d |.f.....2.......M| -00000130 f3 43 17 77 f5 51 ca 57 b8 db d1 f4 8a 22 b2 ec |.C.w.Q.W....."..| -00000140 22 27 cb 22 b8 c1 9a 17 63 01 e7 5d 2a 2b ad 03 |"'."....c..]*+..| -00000150 65 be 0d 55 c5 aa 46 31 95 df 47 17 03 03 00 59 |e..U..F1..G....Y| -00000160 d1 98 94 ed e8 1e fb 74 04 5c 11 9b eb 11 29 20 |.......t.\....) | -00000170 05 39 94 9f c8 e1 2f a5 2d 91 23 69 ca 15 34 8b |.9..../.-.#i..4.| -00000180 d7 3c 60 62 3e ae 7f fc 15 14 f1 51 a0 0d 06 30 |.<`b>......Q...0| -00000190 e7 09 8a ca 60 51 77 6d 31 b5 ac fe a1 40 ca 0c |....`Qwm1....@..| -000001a0 78 13 69 18 eb 65 41 72 c1 e9 7c dd 31 db fd 53 |x.i..eAr..|.1..S| -000001b0 16 b8 82 9e 9f b9 46 68 1c 17 03 03 00 45 46 f7 |......Fh.....EF.| -000001c0 f1 53 9c 4b 79 76 09 10 00 b6 c0 4c c4 b2 cc 4a |.S.Kyv.....L...J| -000001d0 55 41 29 28 bd b6 54 1c 56 ec 85 75 c0 52 11 ce |UA)(..T.V..u.R..| -000001e0 93 67 61 a8 52 2c 77 5d b0 b1 6b e2 02 93 65 f4 |.ga.R,w]..k...e.| -000001f0 3b d9 65 c5 5f 2b 13 c2 09 c1 c1 5d 83 8a cb 6b |;.e._+.....]...k| -00000200 db 40 e3 |.@.| +00000000 14 03 03 00 01 01 17 03 03 01 50 d8 03 a6 37 13 |..........P...7.| +00000010 5f fb 65 9f 33 33 79 ae 89 c3 de ea 4b 55 e2 b3 |_.e.33y.....KU..| +00000020 13 07 0d 95 c6 f7 79 74 ad 8a 42 dd 78 55 a5 01 |......yt..B.xU..| +00000030 69 f2 11 cf 72 de 85 04 56 78 9c ba 21 77 b8 76 |i...r...Vx..!w.v| +00000040 e3 58 23 3d 2b 8a ee a4 5c 52 60 4b 50 0d c4 83 |.X#=+...\R`KP...| +00000050 a1 8d 06 82 68 99 34 65 7a 7b 55 8e 46 04 47 55 |....h.4ez{U.F.GU| +00000060 4d 42 02 41 b6 e4 dd a4 33 6a 04 97 e6 4a 80 3a |MB.A....3j...J.:| +00000070 e1 7e 0a a5 4f 0c f9 de 7a 91 96 4f 6a 6a 8a 4b |.~..O...z..Ojj.K| +00000080 fd 24 b9 bf e7 d5 5a 27 17 18 45 77 1d e2 c9 ea |.$....Z'..Ew....| +00000090 23 57 c4 e1 30 9e de d2 bd 0c 28 59 dc a1 12 d9 |#W..0.....(Y....| +000000a0 ee 2e 43 4b 83 fc d7 6c a4 e7 47 c4 14 c1 1f ee |..CK...l..G.....| +000000b0 79 60 26 86 73 5c ec c9 c0 ec f9 c9 38 98 2d ba |y`&.s\......8.-.| +000000c0 10 83 1b fe 8f cf 59 77 f0 60 fe c0 d0 7e 0f 2d |......Yw.`...~.-| +000000d0 69 04 dd 79 49 c5 b1 d9 9b 48 ad de 55 cf d3 47 |i..yI....H..U..G| +000000e0 9b eb 64 ae ed cb b0 48 78 a9 27 24 b8 8d 53 36 |..d....Hx.'$..S6| +000000f0 b7 0f 82 1c ee 11 4b 5a 98 1d 21 73 b4 f4 06 ce |......KZ..!s....| +00000100 50 bc 36 27 e1 87 70 04 68 1b 30 3a 86 68 b3 71 |P.6'..p.h.0:.h.q| +00000110 8c 57 69 60 d6 a8 bd fa 13 46 2b 52 00 dc 45 53 |.Wi`.....F+R..ES| +00000120 06 79 5b 96 78 69 d0 a8 cd 2d 39 8c 11 12 9f 65 |.y[.xi...-9....e| +00000130 72 01 5e b4 c5 df bc 9d a2 7f 00 a7 cc 95 3b 0b |r.^...........;.| +00000140 09 05 19 9f a5 b7 dd 48 3f ab f1 aa 36 da 70 96 |.......H?...6.p.| +00000150 0f f9 f3 bc 80 84 09 a3 76 92 56 17 03 03 00 59 |........v.V....Y| +00000160 4a ba a9 1c c7 f6 ef 77 8e cc 9a 8c 51 9f 43 1e |J......w....Q.C.| +00000170 ec 8f f3 33 93 eb 81 db 06 03 97 fd 3f b2 e0 e5 |...3........?...| +00000180 e7 73 b2 2c 2c f0 c0 a4 51 18 10 79 4e 30 96 3a |.s.,,...Q..yN0.:| +00000190 d8 26 b1 a0 f4 1b e6 12 fe 74 58 68 97 45 1e 85 |.&.......tXh.E..| +000001a0 3a db 04 a6 12 5d ba 19 e4 f6 b1 17 f3 04 75 f2 |:....]........u.| +000001b0 ea 04 db 6c d4 d8 d5 cc fb 17 03 03 00 35 1d c5 |...l.........5..| +000001c0 cd 92 9c 80 3a ec 3c 06 3e 12 ed 7a 82 23 ab 18 |....:.<.>..z.#..| +000001d0 67 4a 92 7d 30 e4 57 7b 25 34 a1 54 46 41 b7 60 |gJ.}0.W{%4.TFA.`| +000001e0 69 cf a2 61 7a 59 6f b3 78 6f 41 0f 7d 9b 4f 00 |i..azYo.xoA.}.O.| +000001f0 91 c7 93 |...| >>> Flow 4 (server to client) -00000000 17 03 03 01 da 0d f9 80 98 7a 44 ce b5 d0 2d 10 |.........zD...-.| -00000010 54 40 c8 5a e4 28 ba df 18 61 f5 d7 84 a5 38 d2 |T@.Z.(...a....8.| -00000020 d5 81 76 0e 81 d1 da 9e 99 24 81 7b 5a d0 d5 44 |..v......$.{Z..D| -00000030 df db 71 ee 84 67 f8 74 db 60 77 17 41 1f 90 1e |..q..g.t.`w.A...| -00000040 53 1c e2 bf dc d1 b9 4e 50 5b 13 76 93 e5 9b 7a |S......NP[.v...z| -00000050 98 48 36 7d fa a8 76 69 49 e4 e9 c4 00 ad 85 c3 |.H6}..viI.......| -00000060 cf 02 3e 57 90 9b 38 e0 d8 0e 23 c9 f9 34 15 6f |..>W..8...#..4.o| -00000070 9f b5 fe 5b 08 f9 87 11 36 7e d6 29 f0 99 ee e0 |...[....6~.)....| -00000080 4a ec 6a ff 6d 57 26 6d 8c 73 3f f6 1e 25 49 38 |J.j.mW&m.s?..%I8| -00000090 0c f1 dd 6a 32 90 2f 72 74 fd 33 6e 6a cb f3 b4 |...j2./rt.3nj...| -000000a0 35 ed 54 44 10 8c 2e 4d 9a 9d 83 e9 27 3e 03 d4 |5.TD...M....'>..| -000000b0 8c 10 c2 54 99 5c ab 59 ab b6 cd 39 10 4e 74 ba |...T.\.Y...9.Nt.| -000000c0 84 96 6f be 53 44 27 16 9f 64 36 63 61 75 ab 56 |..o.SD'..d6cau.V| -000000d0 c8 27 4c 31 ed cb 46 32 f6 50 f0 00 1c e3 57 40 |.'L1..F2.P....W@| -000000e0 d5 68 6e 4a 4b 9b 8e 57 ab d3 a4 c5 f5 f5 92 7e |.hnJK..W.......~| -000000f0 ac 67 a7 67 e9 e0 74 66 d9 00 53 0f 4f 96 73 4d |.g.g..tf..S.O.sM| -00000100 74 7e 47 9b fa 17 72 55 7e f3 a2 88 ad 07 dc 18 |t~G...rU~.......| -00000110 b2 26 29 6f 70 cc 35 72 af 81 c2 65 5c 88 3a c7 |.&)op.5r...e\.:.| -00000120 d1 45 73 91 9d 1f f8 85 ee 89 dc af 6e 80 97 a0 |.Es.........n...| -00000130 d9 32 19 dc 15 2a d5 86 46 ae 7d ba b3 e6 3d 81 |.2...*..F.}...=.| -00000140 65 b4 69 82 a8 9c 0f 26 63 a6 9c f2 3d ce 0f 79 |e.i....&c...=..y| -00000150 a8 08 d3 2b c0 e1 9e c7 ef 1a ca 98 95 d6 c3 d5 |...+............| -00000160 9c d6 ee 0b 12 98 4f 82 2f 98 df 47 6e 7a 04 94 |......O./..Gnz..| -00000170 5d ae c5 51 a5 d5 21 d4 a6 f7 e7 3a bd 51 53 24 |]..Q..!....:.QS$| -00000180 b8 a6 ed 5b 34 30 1d 4a 19 40 c1 cf 5f 21 3a 95 |...[40.J.@.._!:.| -00000190 ee 82 db 5f c8 54 87 da 45 df ff f3 51 b5 43 03 |..._.T..E...Q.C.| -000001a0 ee c5 84 27 c2 51 1c 23 8c 87 c4 d3 79 e7 5b 44 |...'.Q.#....y.[D| -000001b0 8f 2e be 2a 86 22 9a 7c 50 c4 09 c7 2f d6 cd d8 |...*.".|P.../...| -000001c0 b3 d5 d2 e3 33 89 89 04 5f f3 46 34 40 60 91 c2 |....3..._.F4@`..| -000001d0 35 e1 3c 39 17 62 fb 99 32 b9 9a be 66 3a 36 17 |5.<9.b..2...f:6.| -000001e0 03 03 00 1e 2a 22 40 15 e6 80 93 5f 27 1a a1 39 |....*"@...._'..9| -000001f0 d4 b1 a0 b0 e8 d6 46 1d d7 91 06 67 2a 81 a8 65 |......F....g*..e| -00000200 57 ad 17 03 03 00 13 11 e9 c2 d1 66 5e 3f 41 14 |W..........f^?A.| -00000210 82 14 88 58 57 82 2d 0e ba 8b |...XW.-...| +00000000 17 03 03 01 ca 52 99 bb 74 e8 8e ab 48 c6 03 1d |.....R..t...H...| +00000010 f9 9a a8 be e4 b1 dc b9 8d e5 a8 11 2b d6 54 63 |............+.Tc| +00000020 6f 0d dc 6e d7 55 c8 af 3c 88 c4 3e ab 30 ab b9 |o..n.U..<..>.0..| +00000030 69 94 75 60 0f 75 77 e1 b1 29 09 9f db c1 74 43 |i.u`.uw..)....tC| +00000040 92 2a 55 b9 ae 71 12 79 b9 4d ba 82 84 96 b1 01 |.*U..q.y.M......| +00000050 14 b5 9c 5d 0c fe eb cc a6 44 e5 0b 93 1c 8d 45 |...].....D.....E| +00000060 d8 aa 7c 1b d1 47 5a 36 46 f8 f5 82 c7 fe 2b f3 |..|..GZ6F.....+.| +00000070 46 17 9f 0c 03 df cd dd 0a 38 77 28 45 45 f2 3c |F........8w(EE.<| +00000080 06 1d 88 1b 55 d8 8f 70 9b a8 bb 37 a8 41 81 a6 |....U..p...7.A..| +00000090 a7 f4 28 c1 f1 d2 8b ba 98 0e 35 92 88 ac cb b6 |..(.......5.....| +000000a0 25 dd 5e 62 d5 e7 e9 da 4f 0e 55 b4 36 4d 09 20 |%.^b....O.U.6M. | +000000b0 73 ef b3 6c 4c 6d c6 6a e9 f3 f8 28 74 0d 50 b0 |s..lLm.j...(t.P.| +000000c0 ad 75 f7 c5 fb eb bc 06 6b 07 23 80 70 87 8e a8 |.u......k.#.p...| +000000d0 3e 66 87 07 53 8e 19 bb 3f 94 f1 9e 4b 05 f6 55 |>f..S...?...K..U| +000000e0 34 3b d0 14 36 32 66 6a 62 8a ec 22 a1 82 0a 95 |4;..62fjb.."....| +000000f0 95 b6 85 0c 2c c4 b4 3e 00 59 2a 1e c6 03 4b 2a |....,..>.Y*...K*| +00000100 e4 06 d5 29 e5 a1 e1 57 b0 a1 45 1b b7 0c 12 3f |...)...W..E....?| +00000110 0d 31 1a b2 ef 3d 90 73 3a 39 28 00 8a 0d e0 20 |.1...=.s:9(.... | +00000120 83 a7 32 b8 02 d0 9f 90 f3 b3 ca df 36 ae d4 f8 |..2.........6...| +00000130 c4 4b 82 06 13 04 66 e7 01 63 4e e8 80 b8 52 c0 |.K....f..cN...R.| +00000140 8c a4 5b 3f b9 85 48 ac 01 f0 b6 ee db 73 d0 62 |..[?..H......s.b| +00000150 e2 05 e7 71 7e 87 4b 7b cf d0 a1 77 eb 38 64 85 |...q~.K{...w.8d.| +00000160 5c 3d af fc e3 17 46 e7 c5 71 c9 63 bf 03 ae 35 |\=....F..q.c...5| +00000170 7b 60 61 5d 5a 7b 57 88 79 82 55 68 45 a1 59 bc |{`a]Z{W.y.UhE.Y.| +00000180 e5 3b 5a 31 32 5c 24 13 e3 fc b7 53 41 76 1d 24 |.;Z12\$....SAv.$| +00000190 7f 08 89 c6 f0 b9 57 3a 4d 91 66 66 e4 57 33 51 |......W:M.ff.W3Q| +000001a0 1d b9 1e c5 68 9a 6a 74 1e c3 16 de 15 92 e3 d0 |....h.jt........| +000001b0 0a 64 a4 64 e8 c4 a5 9c 55 30 a9 c3 b0 53 72 54 |.d.d....U0...SrT| +000001c0 75 d7 a0 7a 54 85 6e 9a 4d ff 9f 13 3c b9 42 17 |u..zT.n.M...<.B.| +000001d0 03 03 00 1e 6f 06 3f 1c da f6 55 50 05 de 38 9d |....o.?...UP..8.| +000001e0 07 00 bb 28 32 a5 3f 04 22 4c 6e f2 ea 3a e0 cc |...(2.?."Ln..:..| +000001f0 5d 5b 17 03 03 00 13 3b b8 7c df 14 b4 ba fa 6e |][.....;.|.....n| +00000200 2e 61 d6 6b bf b5 ad c2 35 73 |.a.k....5s| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven b/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven index 97fd482c32c..800f99916c0 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven @@ -1,180 +1,177 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 c6 01 00 00 c2 03 03 51 9e 53 ed 5f |...........Q.S._| -00000010 cd 05 55 f2 c7 47 8c e9 90 25 c7 71 4f 73 45 3b |..U..G...%.qOsE;| -00000020 03 bf 42 bd 5a 4a b9 56 ef ba e0 20 04 08 64 e1 |..B.ZJ.V... ..d.| -00000030 9d db 92 a5 4e 0c 6e 90 71 c3 ed 51 c6 23 f5 6e |....N.n.q..Q.#.n| -00000040 64 55 94 28 37 54 58 00 23 a0 53 56 00 08 13 02 |dU.(7TX.#.SV....| -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 2b 33 eb 7b ec |..3.&.$... +3.{.| -000000b0 b5 04 57 a0 f4 f8 3c 19 f2 8f 81 11 b0 2e 91 88 |..W...<.........| -000000c0 d8 be ba f3 6f 5a 80 db a3 e6 1e |....oZ.....| +00000000 16 03 01 00 ca 01 00 00 c6 03 03 c8 2f b4 54 5b |............/.T[| +00000010 11 8a 88 a9 a2 9b bf 66 f2 b4 e5 fb 32 af d6 dd |.......f....2...| +00000020 6c 6c 99 4f d6 48 cd eb 63 6e 1d 20 bb 0a 48 2e |ll.O.H..cn. ..H.| +00000030 45 4e 86 2d ae d6 fb 3e 0c 3e 9f a3 17 4a e3 39 |EN.-...>.>...J.9| +00000040 58 a7 92 92 cb 30 03 0d be b5 79 a5 00 04 13 01 |X....0....y.....| +00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................| +00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| +00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......| +000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 f0 |-.....3.&.$... .| +000000b0 8e 19 a6 04 b7 f1 b0 cd a1 28 bb 10 60 30 92 dc |.........(..`0..| +000000c0 bc 7a 1c fc a7 f4 dc 01 2e 88 f3 0e 80 82 71 |.z............q| >>> 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 04 08 64 e1 |........... ..d.| -00000030 9d db 92 a5 4e 0c 6e 90 71 c3 ed 51 c6 23 f5 6e |....N.n.q..Q.#.n| -00000040 64 55 94 28 37 54 58 00 23 a0 53 56 13 02 00 00 |dU.(7TX.#.SV....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 bb 0a 48 2e |........... ..H.| +00000030 45 4e 86 2d ae d6 fb 3e 0c 3e 9f a3 17 4a e3 39 |EN.-...>.>...J.9| +00000040 58 a7 92 92 cb 30 03 0d be b5 79 a5 13 01 00 00 |X....0....y.....| 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 69 01 91 62 e2 e7 |..........i..b..| -00000090 ee 89 ea b5 55 95 a2 3e 69 09 0a 11 85 42 e8 fd |....U..>i....B..| -000000a0 c5 17 03 03 00 3e 2d 4a 1f 1b 45 7a f5 bf f8 50 |.....>-J..Ez...P| -000000b0 b7 90 b7 19 24 8c c6 da 49 79 83 f4 52 10 ed 5d |....$...Iy..R..]| -000000c0 fa 26 91 28 13 bc a9 c2 f9 6b 4c e9 f7 79 cb 87 |.&.(.....kL..y..| -000000d0 1d ac a4 7a d9 84 25 e8 68 27 67 7f 85 f9 e1 3e |...z..%.h'g....>| -000000e0 04 2c fe aa 17 03 03 02 6d ca f8 97 e5 6f f8 f7 |.,......m....o..| -000000f0 1a 8b a1 c2 81 b5 a4 f3 6d d9 83 30 00 6b 4a 92 |........m..0.kJ.| -00000100 99 0c c1 71 69 c6 57 0b c6 09 8c dd 17 19 14 4f |...qi.W........O| -00000110 7f 22 f1 d1 28 13 6c b7 e7 89 d7 4b b2 cd 56 e4 |."..(.l....K..V.| -00000120 b6 b8 7c ca 18 41 43 e7 74 ef 39 c6 b9 dd 3f 23 |..|..AC.t.9...?#| -00000130 62 fa 59 70 1c 7c ff e9 41 d0 04 fe ae f4 25 75 |b.Yp.|..A.....%u| -00000140 0f b1 cf b9 b0 bb 95 50 be 9a be 9a 7a 1c 03 3b |.......P....z..;| -00000150 ae 01 ee 91 aa f6 7a 47 40 67 f4 1b 5b 86 36 58 |......zG@g..[.6X| -00000160 88 0f 68 1a 9d cd 1a e1 aa 3e 61 77 67 fd 5a aa |..h......>awg.Z.| -00000170 96 b9 8f cd fe 28 68 ed 25 0f 7f 8a a1 31 24 44 |.....(h.%....1$D| -00000180 bd 4a 03 e8 f8 cc 63 d1 fc 12 eb c0 47 4c 30 1e |.J....c.....GL0.| -00000190 82 77 4d 45 50 03 d4 2c 0b a3 d7 af 0c 7e 61 68 |.wMEP..,.....~ah| -000001a0 98 c0 5f cf b9 54 75 be 76 08 9e 68 07 62 96 8c |.._..Tu.v..h.b..| -000001b0 b8 24 0e b9 c4 2a 27 72 72 de 00 d1 38 a5 42 8b |.$...*'rr...8.B.| -000001c0 38 23 78 9e 68 c2 d6 62 db 82 5a 46 5b 57 19 a4 |8#x.h..b..ZF[W..| -000001d0 11 00 7c e9 14 56 79 ea ac 24 26 c0 d4 16 45 8c |..|..Vy..$&...E.| -000001e0 28 ca 88 6f 72 f3 f8 18 26 3f 00 e5 62 c2 9f 67 |(..or...&?..b..g| -000001f0 46 9f 99 f1 61 af b7 b0 05 42 59 13 5b 0f 0d a7 |F...a....BY.[...| -00000200 bc 9e 7e 3f 6e 24 74 bf 93 a0 9d 09 89 a8 a6 4d |..~?n$t........M| -00000210 07 5d aa 24 2c 86 e5 80 7f 4b a3 c3 02 41 8b e5 |.].$,....K...A..| -00000220 56 7a be 9f 5f b0 9d 41 51 e6 b8 d8 67 66 df 89 |Vz.._..AQ...gf..| -00000230 00 07 83 06 8b 5b 84 e6 8a 92 3c de 1f 4c 2b bc |.....[....<..L+.| -00000240 9d 7f ec e8 c3 0e ee 4a 80 2c e4 f0 d7 84 b3 a8 |.......J.,......| -00000250 7d c7 f5 91 b9 91 43 14 45 77 a4 84 f7 a6 72 f0 |}.....C.Ew....r.| -00000260 cd a2 7f 12 b6 e2 6f d3 93 5a d9 c8 39 4b 95 29 |......o..Z..9K.)| -00000270 2a be 4c dd a5 82 ec da ee 98 c9 0f 10 18 e4 da |*.L.............| -00000280 f4 3f 33 86 11 e4 5c 36 05 07 02 d1 21 5d 48 5f |.?3...\6....!]H_| -00000290 8b ec b1 33 25 65 ef 33 d4 87 6e f9 cf f8 e4 79 |...3%e.3..n....y| -000002a0 f8 23 82 10 1e 5e c5 e7 60 82 6d b5 57 3c 54 f3 |.#...^..`.m.W.Oq.n| -00000370 b0 04 89 76 d0 4e be 85 cc b1 dc c6 f0 ba 0c a8 |...v.N..........| -00000380 81 86 0d 8d bf d0 93 c5 3a 28 a8 ac df f9 7c eb |........:(....|.| -00000390 10 4b bc dc 1b a7 4d f9 25 b3 09 9a 80 6f 83 0e |.K....M.%....o..| -000003a0 9d 62 a9 6e 33 d8 85 96 78 3d f1 1f b7 6b 87 f7 |.b.n3...x=...k..| -000003b0 30 dd 09 ea 06 f3 cc 7a 82 96 e8 f7 cd f2 99 7f |0......z........| -000003c0 53 da dd ab b6 f2 da 94 94 cf b1 6f 21 e2 7b 9f |S..........o!.{.| -000003d0 90 ab 18 fc 61 84 d6 97 87 a0 14 2e cf 02 42 74 |....a.........Bt| -000003e0 68 a0 5b cc 1a 63 fc 4e e0 a9 ca 59 89 ae fc ef |h.[..c.N...Y....| -000003f0 41 54 65 cf 17 03 03 00 45 ba bb ae e4 a3 04 5c |ATe.....E......\| -00000400 30 19 79 ff 6a b5 0c dc ab c8 cd e5 bf 2d 9c 3e |0.y.j........-.>| -00000410 44 98 1b cd bb 2a 08 10 75 ab b9 d1 62 a5 e1 21 |D....*..u...b..!| -00000420 51 32 75 38 89 67 83 3b 3f f5 e7 71 53 8f 2f d0 |Q2u8.g.;?..qS./.| -00000430 81 98 cb 75 b2 99 40 bf 01 a0 bb 0b b0 0e |...u..@.......| +00000080 03 03 00 01 01 17 03 03 00 17 1a 9d c2 a8 12 c1 |................| +00000090 c3 97 41 bd 1f 6e 48 98 36 4b 13 cd b9 9f 70 34 |..A..nH.6K....p4| +000000a0 60 17 03 03 00 3e f8 19 ab 88 f7 15 07 97 72 ec |`....>........r.| +000000b0 41 6c 0a 64 b3 26 4a 56 21 20 d7 9c a2 84 06 ab |Al.d.&JV! ......| +000000c0 cb e6 99 1b 45 ce ca e7 c6 57 04 c9 3a 76 84 97 |....E....W..:v..| +000000d0 fe a3 be 60 b2 2c 53 31 ab cd 49 d5 fc 59 80 69 |...`.,S1..I..Y.i| +000000e0 38 d3 66 32 17 03 03 02 6d 8f 8b 7a 7d 78 d3 4b |8.f2....m..z}x.K| +000000f0 98 1e 0b 05 38 60 58 d0 0a 7a f8 a7 70 53 67 ce |....8`X..z..pSg.| +00000100 ea ed 86 3e 79 9d 37 66 b2 61 be 34 bf 15 5a d8 |...>y.7f.a.4..Z.| +00000110 4e fb 52 62 8d e2 ae e9 58 b9 bc f9 e9 75 81 16 |N.Rb....X....u..| +00000120 af fa 92 c3 aa ac d2 2c 7b c2 21 2f b0 0d e9 53 |.......,{.!/...S| +00000130 d3 e3 ec d5 e7 95 23 83 d9 b1 ff 25 55 47 6a 1c |......#....%UGj.| +00000140 97 37 84 9a ce 67 15 63 0f ff 24 63 af 43 8a 7d |.7...g.c..$c.C.}| +00000150 46 63 bb 33 67 7a de 86 b4 6a 70 2d 6a 7f 82 c2 |Fc.3gz...jp-j...| +00000160 24 3c e1 0f a9 7f 93 76 d2 c9 e2 56 d3 cb b9 17 |$<.....v...V....| +00000170 97 2f 8a 25 40 dc 35 e4 00 3a 3f 2b 1e 09 1b f2 |./.%@.5..:?+....| +00000180 12 2a 76 c0 2e cd 17 06 32 a9 f8 08 70 3f 06 fa |.*v.....2...p?..| +00000190 c7 1b c4 50 4f b8 1e 0f 6f 6a 3a ba f6 28 1b d0 |...PO...oj:..(..| +000001a0 a7 34 a5 8c 02 fe 35 4f b4 97 45 96 48 bc b9 0d |.4....5O..E.H...| +000001b0 c9 2f df bd c1 8b 19 44 33 12 90 2c d2 99 09 36 |./.....D3..,...6| +000001c0 97 3f 29 56 30 77 15 df 15 c9 b1 26 9c f4 6a 59 |.?)V0w.....&..jY| +000001d0 00 3e d8 28 74 19 6c 38 6c 68 63 16 ab cb f0 3d |.>.(t.l8lhc....=| +000001e0 ce 30 f6 9c 06 00 06 cc 5a 8e 78 73 af 53 a4 e6 |.0......Z.xs.S..| +000001f0 49 10 5b 9d 4d f3 7d 48 f0 5d 87 27 d8 7e 58 a6 |I.[.M.}H.].'.~X.| +00000200 86 51 a0 d6 e8 82 20 6b d3 f9 99 4d 11 b7 49 ad |.Q.... k...M..I.| +00000210 f9 1a 1b f5 cd 81 81 bd 51 76 a4 5a 5f 35 7a 52 |........Qv.Z_5zR| +00000220 12 1b 73 f6 f3 1d cf 93 7a 8e a0 1d 4c f3 b2 f5 |..s.....z...L...| +00000230 16 00 57 21 2f c6 85 af 8c 8b f9 bd 2a f1 ee 15 |..W!/.......*...| +00000240 ec ee 80 b9 8b 0a 50 36 cb 53 fd ca 53 b4 0e 96 |......P6.S..S...| +00000250 7b db e6 93 f7 9e 8d e4 6a d5 ff e3 74 31 76 3a |{.......j...t1v:| +00000260 a8 de ce 06 97 3d 4e 91 c5 cd 85 06 c9 a6 02 91 |.....=N.........| +00000270 f9 36 33 8d 28 23 54 f5 c3 f0 b2 1a a1 6b b7 c6 |.63.(#T......k..| +00000280 d1 c3 31 ad d6 6f 0c 44 e4 34 d8 26 b6 ff 06 6f |..1..o.D.4.&...o| +00000290 f3 56 19 46 8d f3 75 c2 d9 69 4a 5b ff 3a b8 1d |.V.F..u..iJ[.:..| +000002a0 86 a9 6f 45 dc 3a e4 aa 9b 7d 3a 5a 50 ad c6 f6 |..oE.:...}:ZP...| +000002b0 8c e3 0e ca b6 7a 99 e7 4b 58 26 c2 18 95 14 a4 |.....z..KX&.....| +000002c0 f9 ae 79 4f f6 c0 f8 0e d4 52 fb 3c 5d a2 30 9c |..yO.....R.<].0.| +000002d0 ea d9 8d f4 27 4c 6f 7a 02 45 8f ca 8c b1 bc d2 |....'Loz.E......| +000002e0 c5 dc 8b 09 d7 c4 0f ea f6 51 be f7 cd 01 1e 78 |.........Q.....x| +000002f0 a1 37 4a 88 ae 5f c5 79 9c e2 4d c9 74 e7 2e 18 |.7J.._.y..M.t...| +00000300 86 e8 62 3f 6c 39 73 eb c2 e2 54 0c 13 ca f6 57 |..b?l9s...T....W| +00000310 20 92 6a 1d 03 28 d0 53 6f 6e cb 57 da 33 20 1a | .j..(.Son.W.3 .| +00000320 c8 3d 09 73 5f 28 14 6f 4c 16 8c 41 cd 44 ad df |.=.s_(.oL..A.D..| +00000330 77 08 0f f1 3c 4c 2b 37 03 60 9d 07 85 e7 66 f7 |w........55.BL...| +00000400 3e 26 15 0a f1 c3 a6 ab 94 a3 72 bd c7 04 22 bc |>&........r...".| +00000410 67 32 15 16 23 f5 50 97 bc 7f ab f8 ef f0 02 7d |g2..#.P........}| +00000420 2d 76 01 18 72 18 77 c1 f5 9b e9 e9 97 8d |-v..r.w.......| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 02 11 25 5d 22 6c 20 |...........%]"l | -00000010 8a 8e d3 aa 97 5a 96 46 a0 69 a3 5c 0f d4 ad c0 |.....Z.F.i.\....| -00000020 6f e4 6f df 99 28 d3 e1 bd ce a5 8c 69 6a c4 9b |o.o..(......ij..| -00000030 a5 eb e2 d8 db a4 1d ea 55 ff be c2 14 dc 63 74 |........U.....ct| -00000040 b8 4d 44 aa 87 65 5c 1e a2 10 8c 0f ae 0c 0e 76 |.MD..e\........v| -00000050 89 4c 05 65 c5 19 e3 d4 d1 eb 9e e5 2d 8a 62 ae |.L.e........-.b.| -00000060 55 d6 a3 37 46 9b 3c 4c ad d0 82 7e 0a 36 48 38 |U..7F.4a.| -00000130 a6 1e 18 45 1a c5 1c 8a aa ad cd 67 bf 37 30 46 |...E.......g.70F| -00000140 37 eb 13 1f c2 6a 7f 39 47 b8 91 a4 c9 9e 70 7c |7....j.9G.....p|| -00000150 73 62 69 7b c1 30 99 97 d3 34 2f 83 84 3d de a8 |sbi{.0...4/..=..| -00000160 dc b5 ce d4 69 ff 5e a8 b8 31 05 e0 6b 3b 14 93 |....i.^..1..k;..| -00000170 10 11 51 ae e6 29 df 54 34 30 01 6c 46 24 76 3a |..Q..).T40.lF$v:| -00000180 dd 24 f1 84 d3 27 a7 45 9a 19 4a 09 63 7b 00 6d |.$...'.E..J.c{.m| -00000190 b8 11 72 06 e4 8a aa b2 3b 08 eb 17 ae 88 18 18 |..r.....;.......| -000001a0 51 8f fb 80 5f 01 2a 2c bc 47 10 cf da d1 ec 11 |Q..._.*,.G......| -000001b0 34 6d fd d0 c1 c0 a7 26 f3 3a 2e 43 7f 3a 63 eb |4m.....&.:.C.:c.| -000001c0 7b e4 a5 c8 23 ff 6b 7a e9 8e 70 c4 9d 39 b4 3c |{...#.kz..p..9.<| -000001d0 4d 40 bc 1e ff e4 7d 47 13 54 64 e7 98 7f cd df |M@....}G.Td.....| -000001e0 90 89 19 89 92 8c 39 1b 5c 53 4b c2 7b 38 5c 5a |......9.\SK.{8\Z| -000001f0 01 e3 2f f9 a3 f5 a2 c0 79 ff 99 a9 89 40 91 40 |../.....y....@.@| -00000200 4e 96 73 15 f5 16 bd ac be e3 ef fa 8a b8 df bf |N.s.............| -00000210 ec 86 3b 67 93 59 45 6a b8 ce a1 04 17 03 03 00 |..;g.YEj........| -00000220 99 21 d2 f9 b5 d7 ca 07 c4 b9 f7 80 87 c4 ce 95 |.!..............| -00000230 8f fa f0 a9 c6 99 89 93 18 50 b6 1b 4c ae ff e7 |.........P..L...| -00000240 2b 29 81 14 20 6a 13 bc 7f 6c b2 6f e4 09 b7 96 |+).. j...l.o....| -00000250 49 93 37 2b 1d 7e 16 3f b0 bd 22 dd 0f 04 71 29 |I.7+.~.?.."...q)| -00000260 38 eb dc a8 85 48 68 17 59 72 0b f2 4f 78 4c 30 |8....Hh.Yr..OxL0| -00000270 db bf 60 a0 56 80 be aa 80 fd ab 87 55 2e 49 6d |..`.V.......U.Im| -00000280 47 38 b9 b1 b4 c2 05 09 16 28 e5 89 dd f1 3d 32 |G8.......(....=2| -00000290 83 66 fb ca de 37 9c ed 74 2a 7b a1 3a 50 0c 4d |.f...7..t*{.:P.M| -000002a0 4c 44 bd 3b 3a 76 33 1c e1 46 91 95 02 a7 b7 a3 |LD.;:v3..F......| -000002b0 9b 3b 9c 19 0a b5 5d 81 32 66 17 03 03 00 45 b6 |.;....].2f....E.| -000002c0 a2 53 eb aa 3c 74 29 1c 36 1e 9f fb 30 c9 48 5c |.S...|| +00000000 14 03 03 00 01 01 17 03 03 02 11 4b 29 10 c9 7b |...........K)..{| +00000010 98 9a fa ce 7a 17 a4 7d 15 5f 97 4f 40 67 37 f0 |....z..}._.O@g7.| +00000020 0b 2d ca 62 77 23 ab 78 d7 9f b6 1d 5c 64 fb 68 |.-.bw#.x....\d.h| +00000030 70 5f 21 df e1 55 3b e3 bb 8e 61 31 11 ba 2b eb |p_!..U;...a1..+.| +00000040 de 78 39 5c 31 62 a3 fb 9a 57 a4 50 34 43 76 55 |.x9\1b...W.P4CvU| +00000050 ae f9 36 b1 35 ee 2b 8d ab c2 70 52 b0 8c d6 1b |..6.5.+...pR....| +00000060 fe 0f fc 5e 79 c3 cf ab d3 9a 81 af 63 2c b3 f7 |...^y.......c,..| +00000070 a6 b7 13 c4 70 22 fa 56 6d 77 cb d1 bf a5 9e c8 |....p".Vmw......| +00000080 74 83 80 f9 9a 19 f3 a3 94 15 72 7c 55 0e 21 47 |t.........r|U.!G| +00000090 2b a2 d3 b8 74 e1 07 37 7f 12 f6 ad ba 71 e5 ca |+...t..7.....q..| +000000a0 17 42 2b 78 9e 90 7d 28 b1 f4 dd 7d b8 69 dd c6 |.B+x..}(...}.i..| +000000b0 eb 3d 93 45 06 ac 5d fe 02 18 b8 f3 8c e4 4e 97 |.=.E..].......N.| +000000c0 05 8b 36 94 cb 0f 66 64 ed a8 50 22 ba c8 a7 23 |..6...fd..P"...#| +000000d0 7d f9 d5 4f d5 27 83 f3 b6 09 3f 4f 69 92 6d be |}..O.'....?Oi.m.| +000000e0 4a 30 02 d2 d5 e6 14 d4 21 e2 c8 5b cb 08 1e 9a |J0......!..[....| +000000f0 28 f7 f4 13 8c 58 9b 69 2c 55 3d 78 f2 ce 93 89 |(....X.i,U=x....| +00000100 2f 62 56 ea a3 21 96 f6 e7 ee a4 3d d8 7d 86 4d |/bV..!.....=.}.M| +00000110 79 c9 3b c8 cf ea a0 6b 5f 29 8c ed c2 d6 73 27 |y.;....k_)....s'| +00000120 a0 35 bb 2b 8b 6c 4e 59 74 e5 84 c4 d2 1a f1 0d |.5.+.lNYt.......| +00000130 5c 36 33 f7 42 d6 08 c3 f8 5b ea 27 a1 cc b9 72 |\63.B....[.'...r| +00000140 d5 b9 4e 17 36 b3 05 29 50 da 52 bc 23 f7 82 82 |..N.6..)P.R.#...| +00000150 c0 67 2b 80 a2 7f e2 ec b9 12 bb dc b6 04 b6 4f |.g+............O| +00000160 87 15 16 13 de c4 1c 04 71 33 ba d7 a7 da f1 f5 |........q3......| +00000170 77 c6 4e 8e b2 65 a1 6c a8 c2 5b a1 f5 da 49 6c |w.N..e.l..[...Il| +00000180 85 ee 21 8d 10 6b 82 bf 0c 0f 7e 33 8b 5e 44 5b |..!..k....~3.^D[| +00000190 70 db bc 76 40 a0 5c 02 f6 8a 9b de aa a4 b2 94 |p..v@.\.........| +000001a0 d0 e0 b7 60 af df ad 3d e3 17 a9 60 e0 d9 a8 3e |...`...=...`...>| +000001b0 c6 06 9b ad 97 0b dc 21 16 9d 42 29 74 a1 f5 03 |.......!..B)t...| +000001c0 d4 15 0d ee fd fa 6b 85 12 2f 8c 26 fd 96 ce 85 |......k../.&....| +000001d0 a5 b7 ba bb ac 8a 6d 54 f5 fd e6 6c 32 24 a9 e7 |......mT...l2$..| +000001e0 1a 11 bf 4d cb f9 18 9a b8 1e a6 e4 1f 61 b1 ce |...M.........a..| +000001f0 1c ca 5d 81 e7 84 e0 a9 4e c7 f9 5d 71 72 76 4b |..].....N..]qrvK| +00000200 65 ca 3a a4 4d d8 ec 82 aa 33 80 bb 15 48 2d 7c |e.:.M....3...H-|| +00000210 4e 5e d2 ec 13 1a e7 03 d5 29 95 80 17 03 03 00 |N^.......)......| +00000220 99 60 a2 43 34 23 c0 a4 4c 0a 18 c5 27 96 2f 7c |.`.C4#..L...'./|| +00000230 af 2b 2c 36 f2 9b cf 93 e7 3e 79 3b 20 d4 3b 60 |.+,6.....>y; .;`| +00000240 a2 ef af 36 d5 45 d4 20 89 be 80 1d 1e ca f7 19 |...6.E. ........| +00000250 35 8f 26 3f be c0 a2 f6 c6 85 a3 88 76 cd 06 f9 |5.&?........v...| +00000260 4f ff 54 79 6c ac 33 71 31 90 70 36 eb 9c c1 b4 |O.Tyl.3q1.p6....| +00000270 4a c8 3a 52 85 2b be 4a 19 8a 24 fd 6f 08 47 19 |J.:R.+.J..$.o.G.| +00000280 84 88 a0 48 f6 17 80 f8 fe 9e 21 68 e1 75 17 14 |...H......!h.u..| +00000290 d4 e2 3a e2 de 9d 19 56 ad cc 33 13 f3 52 b2 1b |..:....V..3..R..| +000002a0 f4 65 04 05 79 9f 3e 14 fb 1f 9c d1 c4 53 c0 93 |.e..y.>......S..| +000002b0 49 ad 3c 2e de c1 b4 fe be b3 17 03 03 00 35 32 |I.<...........52| +000002c0 81 98 1a 6c 38 ca 67 64 c5 30 0b 81 7d fd a1 b9 |...l8.gd.0..}...| +000002d0 2e af 41 1d e9 b7 31 17 d8 08 ce d5 f6 12 4d da |..A...1.......M.| +000002e0 fc db fb e1 fa 5b cd 70 12 e7 bb 26 dd 53 9c 43 |.....[.p...&.S.C| +000002f0 02 06 1f 70 |...p| >>> Flow 4 (server to client) -00000000 17 03 03 02 9b fe 23 52 d0 ff dd ef e2 10 c1 70 |......#R.......p| -00000010 a1 c1 ac d6 e7 30 63 41 07 d5 04 ef 11 ee e7 57 |.....0cA.......W| -00000020 81 14 5b 81 9d 35 3f 73 be 44 15 6b ed 8c b7 e0 |..[..5?s.D.k....| -00000030 59 2c d7 0b 0c aa 7a 18 6a da d6 90 19 64 54 d5 |Y,....z.j....dT.| -00000040 30 73 cf 0e c8 d1 8a 69 a6 68 a4 ce 61 2f c8 4a |0s.....i.h..a/.J| -00000050 58 81 42 1c 5f ee b3 fc 05 66 bf d0 14 45 8f ab |X.B._....f...E..| -00000060 da 82 fe 86 da 1f b0 f6 d5 12 14 1e 78 d0 1c e8 |............x...| -00000070 e7 a3 5e af e6 71 42 45 70 4c 95 4a 16 a0 0e a4 |..^..qBEpL.J....| -00000080 27 6b c4 53 35 63 2a 19 76 d7 e0 7c 92 a2 89 df |'k.S5c*.v..|....| -00000090 be 1f 5d 03 24 06 de 3e d9 c0 12 91 d4 3d 86 a7 |..].$..>.....=..| -000000a0 b6 8b ed 31 e5 81 cc 5e 76 72 25 15 ba 78 54 ab |...1...^vr%..xT.| -000000b0 5b a1 a7 68 e6 44 3f a3 f5 e9 3d 10 ed b5 21 f5 |[..h.D?...=...!.| -000000c0 02 fd 48 cc 9f 1a 2c 4e 47 4b 37 39 5a 8b 42 32 |..H...,NGK79Z.B2| -000000d0 69 52 e6 ae ba 80 80 af 8d 67 d1 38 bb bb 97 55 |iR.......g.8...U| -000000e0 2a 69 28 ef c5 8e 49 fc 87 7a 45 64 57 cf 76 01 |*i(...I..zEdW.v.| -000000f0 94 57 a2 11 13 5e 99 05 6c 7c 52 97 fb 4c 81 09 |.W...^..l|R..L..| -00000100 68 5d c6 91 ef cc 0f 77 71 ac 55 53 d8 2d cb 26 |h].....wq.US.-.&| -00000110 d5 0e c9 36 70 83 85 dd 7d 7e 0d 22 24 26 91 ec |...6p...}~."$&..| -00000120 3d b0 e1 c3 62 22 a9 09 a2 e4 ba e4 4d 53 ec c1 |=...b"......MS..| -00000130 56 c5 b5 92 9a 33 00 f6 21 2c a3 9e 78 85 8e 65 |V....3..!,..x..e| -00000140 24 e5 ad b6 02 26 4d 03 8d 02 62 3c b0 16 3c 2e |$....&M...b<..<.| -00000150 c2 4a 10 11 45 93 2b 96 87 d0 8e 22 43 ca ad 7f |.J..E.+...."C...| -00000160 fe ac db 12 e1 9d e0 ff 03 93 d1 90 cc 9c 27 19 |..............'.| -00000170 1b c5 ba 62 39 55 38 17 44 76 d4 2a 63 54 47 c9 |...b9U8.Dv.*cTG.| -00000180 de db f0 59 ee 6e ed 26 11 93 07 15 eb 03 98 87 |...Y.n.&........| -00000190 bd 15 98 29 14 8b 7a 6c b2 08 6d 86 35 64 0f 4e |...)..zl..m.5d.N| -000001a0 73 e3 60 86 8a 3a 68 0f e8 74 07 78 1d c2 96 fe |s.`..:h..t.x....| -000001b0 b9 0c 4b 0b 31 39 8b 9e 9d 86 57 5e 5c f6 fc 7b |..K.19....W^\..{| -000001c0 fc bd 9b 01 6e a2 33 c4 0a 00 89 22 13 45 2b e2 |....n.3....".E+.| -000001d0 6b 9c 1e 35 b7 df 9e 27 3b 38 26 e4 60 c7 ee a5 |k..5...';8&.`...| -000001e0 9e c2 24 38 ee 3d 44 79 07 77 bc a9 bc 4a 4c 7d |..$8.=Dy.w...JL}| -000001f0 9f d9 e8 9c 91 88 75 92 98 74 a0 e1 ef be 66 3c |......u..t....f<| -00000200 77 be 3f 1c 24 4d 96 49 23 a3 cd 80 60 9a b0 5b |w.?.$M.I#...`..[| -00000210 fa f2 79 54 0d cb 08 7b 52 93 1c 8d ba 18 f3 ce |..yT...{R.......| -00000220 5b 3f c8 c4 4c 12 00 9f 1f 9c 57 d9 16 d5 a2 05 |[?..L.....W.....| -00000230 c3 fa 4e 6d 7e 78 d5 99 33 0f 07 60 1a e9 58 aa |..Nm~x..3..`..X.| -00000240 37 57 4b a4 1c 20 99 29 4c 52 af 1f 02 64 01 87 |7WK.. .)LR...d..| -00000250 a1 fe 73 09 fa ff 04 f6 91 23 0c 56 16 08 16 ba |..s......#.V....| -00000260 3c bb a9 c4 b2 a1 f6 93 45 c0 1a b7 43 9d e2 d5 |<.......E...C...| -00000270 ea dc d1 03 ec 32 83 55 00 59 40 2e 41 8f 52 0e |.....2.U.Y@.A.R.| -00000280 51 22 e9 39 07 04 40 82 ee e8 f9 4a a3 83 63 b6 |Q".9..@....J..c.| -00000290 2e 9a e8 d2 21 04 dd c0 8f a0 e8 33 55 87 3c f3 |....!......3U.<.| -000002a0 17 03 03 00 1e 17 c1 06 2e 7b c7 3e a7 12 4f e2 |.........{.>..O.| -000002b0 96 ac 58 bc 0b 22 95 47 19 5e e0 35 f2 53 0f 78 |..X..".G.^.5.S.x| -000002c0 1d db 93 17 03 03 00 13 9a da 86 87 00 57 0a a0 |.............W..| -000002d0 e6 4f 26 1a e8 9c 5a 5d 89 19 9a |.O&...Z]...| +00000000 17 03 03 02 8b 8e b1 29 40 b6 53 bc 89 c7 87 69 |.......)@.S....i| +00000010 4c 6d 5b 61 d9 ba 5b 96 22 ac 57 71 58 f8 0e ea |Lm[a..[.".WqX...| +00000020 81 ea bf f9 34 6d a0 ce 1f d2 97 52 62 2b 9e f7 |....4m.....Rb+..| +00000030 03 28 96 56 c0 a1 0e 69 7c 98 13 e5 91 8c 48 5f |.(.V...i|.....H_| +00000040 4e 78 87 14 38 f8 fa 3c 17 97 f9 de 38 3b cf 0f |Nx..8..<....8;..| +00000050 d9 dd 41 0a bb 65 ca a7 0b fd a5 11 c2 c3 6a b8 |..A..e........j.| +00000060 5a e1 68 a1 8d f8 35 9d c6 e1 3e e1 03 a9 06 ee |Z.h...5...>.....| +00000070 1f 92 ca b5 f4 df 3e e5 69 63 9e a2 ea 5e b8 d9 |......>.ic...^..| +00000080 26 31 9e 25 de a8 ea 44 1a c0 86 0b 38 75 04 dc |&1.%...D....8u..| +00000090 2d 37 ad 40 e3 2f d1 b0 9e 9e 64 57 8b 31 20 d6 |-7.@./....dW.1 .| +000000a0 16 64 fd 1b c1 01 58 af 4b 88 49 23 7a f6 a2 15 |.d....X.K.I#z...| +000000b0 ca 02 4b d6 6d 7c f8 7a c9 c0 0d 32 6e 1d 83 ca |..K.m|.z...2n...| +000000c0 47 e5 6f 86 a0 f7 8b 50 1d 91 ec fa 2b 4a 72 f7 |G.o....P....+Jr.| +000000d0 a0 09 f1 65 fb 81 32 d2 a0 be 18 07 9f 5d 89 98 |...e..2......]..| +000000e0 08 09 a6 1d 9a 5a 10 67 81 58 82 00 9d 01 48 a8 |.....Z.g.X....H.| +000000f0 5b df 54 b3 cd 84 87 e0 41 e6 1e 47 46 33 56 0c |[.T.....A..GF3V.| +00000100 67 82 b9 bc 28 68 f3 5b 51 a8 c0 0e 43 14 62 bb |g...(h.[Q...C.b.| +00000110 8a bd 3f 4d d6 33 c4 76 4f c1 06 f8 9b bf 64 41 |..?M.3.vO.....dA| +00000120 6c e5 40 8d 93 4a 6b 6f fe 72 6b db ac 35 b4 fc |l.@..Jko.rk..5..| +00000130 84 13 fa 8a 7d 35 e3 73 12 eb 1a 5f a9 e2 28 53 |....}5.s..._..(S| +00000140 0c 6d 41 ec 4b 76 f5 d9 48 2a c2 85 2a 1f 7d 61 |.mA.Kv..H*..*.}a| +00000150 f6 1f 27 ef 47 c9 c7 b3 19 5c 07 d5 18 ec fd 3e |..'.G....\.....>| +00000160 78 41 cb a4 3a 47 22 cf 7e 7e 17 be 27 c4 90 ce |xA..:G".~~..'...| +00000170 2a cb cd ed 0f a3 bf 1e 4c 62 7a 80 ff 21 38 c5 |*.......Lbz..!8.| +00000180 c2 37 9f 62 4b d8 c0 9e df ae 3c 69 cd 25 f5 65 |.7.bK.....>> Flow 1 (client to server) -00000000 16 03 01 00 e0 01 00 00 dc 03 03 a7 91 25 cb c3 |.............%..| -00000010 c2 53 ec 92 0f e7 4c 06 3a 35 ee c9 09 f1 6a 94 |.S....L.:5....j.| -00000020 27 bf 12 7d f8 e5 c3 1a 45 dc a0 20 c8 75 ac df |'..}....E.. .u..| -00000030 fc 9f f5 43 eb ee 5a d8 94 3a f8 10 2d 42 d4 fd |...C..Z..:..-B..| -00000040 2c 80 9f 13 73 c9 02 77 32 c0 50 59 00 08 13 02 |,...s..w2.PY....| -00000050 13 03 13 01 00 ff 01 00 00 8b 00 00 00 0e 00 0c |................| -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 1e |................| -00000090 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -000000a0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 00 2b |...............+| -000000b0 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 |......-.....3.&.| -000000c0 24 00 1d 00 20 ab 7a fe 9c a7 15 e8 53 6d 6e be |$... .z.....Smn.| -000000d0 8b 1f 25 bb f9 6c 15 4c ca 78 c0 b6 b1 20 ab 03 |..%..l.L.x... ..| -000000e0 3d 09 06 cc 49 |=...I| +00000000 16 03 01 00 ca 01 00 00 c6 03 03 15 b6 db 09 24 |...............$| +00000010 50 ea d6 f7 ae d7 32 2f 72 25 23 db 11 ad 6f c1 |P.....2/r%#...o.| +00000020 5d 62 af e7 93 63 1a 8b f3 82 80 20 5f 15 2e 86 |]b...c..... _...| +00000030 86 2c 2e 2f 82 11 3c d2 9f 00 32 d4 3d 05 04 fa |.,./..<...2.=...| +00000040 36 41 8d dc 30 ce a6 2b 6e d4 3c 9c 00 04 13 01 |6A..0..+n.<.....| +00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................| +00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| +00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......| +000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 98 |-.....3.&.$... .| +000000b0 b7 40 03 d8 a3 4c 9e 16 82 77 16 9b c1 17 3a 2a |.@...L...w....:*| +000000c0 fc 25 73 5d 2d 5c dc 15 78 36 12 7a 28 f2 0e |.%s]-\..x6.z(..| >>> 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 c8 75 ac df |........... .u..| -00000030 fc 9f f5 43 eb ee 5a d8 94 3a f8 10 2d 42 d4 fd |...C..Z..:..-B..| -00000040 2c 80 9f 13 73 c9 02 77 32 c0 50 59 13 02 00 00 |,...s..w2.PY....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 5f 15 2e 86 |........... _...| +00000030 86 2c 2e 2f 82 11 3c d2 9f 00 32 d4 3d 05 04 fa |.,./..<...2.=...| +00000040 36 41 8d dc 30 ce a6 2b 6e d4 3c 9c 13 01 00 00 |6A..0..+n.<.....| 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 c2 3f e2 45 30 ec |...........?.E0.| -00000090 10 bf f7 4e 69 42 22 e6 80 64 0a a2 29 07 c6 92 |...NiB"..d..)...| -000000a0 4c 17 03 03 00 3e d1 75 9b 8c a1 3f 5d b3 11 da |L....>.u...?]...| -000000b0 27 79 d3 9c 7f 54 9b 37 ce 02 b4 60 f6 44 0e cb |'y...T.7...`.D..| -000000c0 c3 07 b9 bf 4e 77 7c 4b ba f7 2c e3 4c 43 a4 f1 |....Nw|K..,.LC..| -000000d0 ba ec 0f 7b e5 7a 59 ef 8e e6 68 1e 1c ce d3 11 |...{.zY...h.....| -000000e0 f9 b1 69 32 17 03 03 02 6d aa e1 b7 df 0e 6a 54 |..i2....m.....jT| -000000f0 41 c5 aa 05 24 fd 4a 1b 8a 05 4f e7 48 29 48 35 |A...$.J...O.H)H5| -00000100 66 42 f8 1d 23 9b 68 f4 b6 cf 94 16 af e1 82 93 |fB..#.h.........| -00000110 30 d5 02 3b e4 aa a9 d7 b2 9c 7f 7f 3c a2 be 0d |0..;........<...| -00000120 85 96 14 64 1a 6d ff 95 ab 36 1c d1 2b ed a9 89 |...d.m...6..+...| -00000130 c8 b8 a3 e5 45 e7 18 5a 18 00 c4 d8 96 64 d1 74 |....E..Z.....d.t| -00000140 1a cb ba ec 9a f4 2d 81 8b 3a 77 e6 57 cc 3a 2b |......-..:w.W.:+| -00000150 b8 05 82 bf 59 92 3b 92 04 e8 a6 f2 6a 94 c1 46 |....Y.;.....j..F| -00000160 bd 79 2e 99 7f 7b ea 32 f9 ac b6 90 78 b9 db c8 |.y...{.2....x...| -00000170 ce 9a e4 88 65 11 8a 03 79 43 d2 81 ce d0 f8 0d |....e...yC......| -00000180 64 8e 8b ef bc 2f 34 87 cf 4e e5 22 44 1f 55 82 |d..../4..N."D.U.| -00000190 ab 25 61 df 0f bd e2 ad 73 06 ae e6 08 8d f3 23 |.%a.....s......#| -000001a0 d6 c6 d4 ea e2 22 b9 eb 75 bd 49 58 8f f4 f6 3b |....."..u.IX...;| -000001b0 92 e6 a4 18 ba 6d 50 77 65 69 27 ee 82 0f ca 57 |.....mPwei'....W| -000001c0 db c7 69 e9 7d 6a ff 30 66 e9 8b 6f 10 20 05 fb |..i.}j.0f..o. ..| -000001d0 53 a7 01 5f d9 8d 11 e5 c2 cb 37 6a 93 a5 26 a3 |S.._......7j..&.| -000001e0 e2 1b 45 b3 7f 6f e5 32 52 8e 26 f7 88 d6 de b6 |..E..o.2R.&.....| -000001f0 75 32 a1 95 54 e8 65 38 9d ee 80 e7 7f 6f d8 2d |u2..T.e8.....o.-| -00000200 5f 29 60 c8 89 00 e6 05 06 b4 c0 b0 e5 ad ed 74 |_)`............t| -00000210 77 93 30 92 82 06 45 b9 0e e3 1e 09 12 bb f8 16 |w.0...E.........| -00000220 59 31 a8 51 17 e7 a8 d8 82 44 a0 d6 31 d2 a7 d1 |Y1.Q.....D..1...| -00000230 54 97 c0 49 62 60 82 79 6a 3c 5a b5 92 aa aa f0 |T..Ib`.yj...v.#.A| -000002d0 0f 9e 99 7d eb 73 a2 4d 46 49 71 8e fe ab 5c 3d |...}.s.MFIq...\=| -000002e0 ae fb 1d c8 f0 d1 fc 93 99 96 35 f8 7c 8e ab ea |..........5.|...| -000002f0 96 eb ea ab f1 e5 71 4e ce fc 4d 38 23 31 86 57 |......qN..M8#1.W| -00000300 ac e6 31 55 97 f5 57 b3 58 e9 5a 62 d6 5a 61 a0 |..1U..W.X.Zb.Za.| -00000310 3b a8 0c a5 66 df dc 62 27 e1 5b 10 80 5a 6a 39 |;...f..b'.[..Zj9| -00000320 7f 83 5c 27 84 6e 95 d4 b6 c4 3e aa 06 a5 bf 81 |..\'.n....>.....| -00000330 9d 69 05 c1 c0 e6 b4 e1 81 ff 0d 30 9a 7a 00 a3 |.i.........0.z..| -00000340 ac a0 e8 f0 54 1d bf 53 9c 4b 10 50 0a 6f c9 a1 |....T..S.K.P.o..| -00000350 9b e2 15 e4 e8 3a 17 03 03 00 99 8a 93 9f 65 05 |.....:........e.| -00000360 9d e6 76 d8 25 0d 1a 6f bc 4c 9f f3 97 23 f3 5b |..v.%..o.L...#.[| -00000370 bf 18 13 35 75 de a6 84 d4 d8 b1 ef 5c d4 f0 17 |...5u.......\...| -00000380 8a 3c c7 f4 00 67 ae ec 65 fa 63 4d 23 86 bf ee |.<...g..e.cM#...| -00000390 73 0a 84 d8 32 d6 cd 6d da 02 64 77 16 f8 96 4b |s...2..m..dw...K| -000003a0 ab a8 9f cd 0d ad be de 66 bf 24 24 26 47 38 d3 |........f.$$&G8.| -000003b0 7e 28 1c 87 98 26 ca d3 ec e6 3a a8 0c 89 19 b5 |~(...&....:.....| -000003c0 71 8d f3 f8 d5 07 c5 f4 75 f2 c5 17 11 3d d3 d6 |q.......u....=..| -000003d0 16 e2 ee e9 c9 4c 43 c0 bf 10 fa a2 ff a1 fa 07 |.....LC.........| -000003e0 db 17 d2 d0 6f 56 cf 67 6c 20 32 42 43 ad 18 a2 |....oV.gl 2BC...| -000003f0 9d 39 d9 e2 17 03 03 00 45 ba 62 93 44 21 7f 7b |.9......E.b.D!.{| -00000400 8c 16 13 4a fe b3 e8 dc 13 70 d7 b4 36 8d 2d e1 |...J.....p..6.-.| -00000410 aa 64 37 b9 8c 15 b4 f4 e7 00 12 94 f1 11 a5 04 |.d7.............| -00000420 71 5c d6 ec ab e3 62 15 53 95 8e da f1 a1 c8 22 |q\....b.S......"| -00000430 cf 02 e5 15 85 b2 35 48 a1 11 67 aa 70 1a |......5H..g.p.| +00000080 03 03 00 01 01 17 03 03 00 17 14 12 e8 30 75 5a |.............0uZ| +00000090 a4 27 7d 83 2e 51 0e 48 14 7b 53 0c 65 24 71 c5 |.'}..Q.H.{S.e$q.| +000000a0 44 17 03 03 00 3e 34 38 ac c0 b5 05 e1 03 e1 a3 |D....>48........| +000000b0 d3 42 ec e3 94 96 e7 a3 05 d8 44 ca 1d 89 b6 6f |.B........D....o| +000000c0 52 ce 3c 7d 61 f1 b4 a2 83 31 ab cf e7 ca 53 57 |R.<}a....1....SW| +000000d0 b8 eb f4 7a 8a 7c ce 31 fe a4 b6 c7 a5 ed f2 2d |...z.|.1.......-| +000000e0 da 36 d6 49 17 03 03 02 6d 2c b4 e1 f3 87 4e c7 |.6.I....m,....N.| +000000f0 ab db ea fa 0d 31 20 f2 1e 63 1d 10 bd 61 98 a2 |.....1 ..c...a..| +00000100 50 8d 12 0d c8 5c f8 e4 97 9c 5f f3 47 f4 60 a5 |P....\...._.G.`.| +00000110 59 16 a2 27 06 94 80 93 af 1e 9d c0 9a 23 20 bf |Y..'.........# .| +00000120 a4 5a 26 2c 37 86 d8 8a b7 e2 bd e2 4f ab 53 65 |.Z&,7.......O.Se| +00000130 bd 34 2c 1a 88 72 bf 8f 20 0c e2 51 0f ea 3f 47 |.4,..r.. ..Q..?G| +00000140 dc 0e cd 21 3c d0 cc 7d 38 b8 b9 1b 20 67 83 a9 |...!<..}8... g..| +00000150 af 4c f7 7b c0 d9 00 5c 66 e3 d7 2e 3b 6a b5 9c |.L.{...\f...;j..| +00000160 6e f6 ed 96 25 3c ce ea db fa 85 ba e2 d8 4c 95 |n...%<........L.| +00000170 92 06 0a 38 19 7f 52 30 2b ef fc 23 c6 b3 e5 d1 |...8..R0+..#....| +00000180 83 2e 56 65 d6 ef 06 3a 71 d6 39 e9 16 62 65 78 |..Ve...:q.9..bex| +00000190 59 c1 9f 7f 99 be c2 b9 0b 56 0a db 26 ec 16 15 |Y........V..&...| +000001a0 be 27 cb bb cf 4a 9c a1 fd 5c 7d 5d c6 df a2 ed |.'...J...\}]....| +000001b0 f1 70 74 03 40 7c 8f af ea 3c 6a c7 c6 30 98 4c |.pt.@|...>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 19 44 2e d9 de 51 |...........D...Q| -00000010 eb 6f 4d a5 6e f7 ca 7e e2 54 88 5c 10 82 95 25 |.oM.n..~.T.\...%| -00000020 ef 79 ab ae 17 03 03 00 45 a6 6e 3e 2c b9 c6 97 |.y......E.n>,...| -00000030 6d 91 e5 a9 05 d8 d9 aa 69 b9 26 8c 51 24 37 4a |m.......i.&.Q$7J| -00000040 b7 80 c5 4f 8f bc f5 34 c2 e6 e0 e6 56 c7 af 0a |...O...4....V...| -00000050 4a d0 6d 98 76 c3 92 02 c3 82 58 44 fb f8 91 76 |J.m.v.....XD...v| -00000060 df 57 6f 28 3e 84 6e 61 be 74 53 2c 9a 8e |.Wo(>.na.tS,..| +00000000 14 03 03 00 01 01 17 03 03 00 19 83 88 d2 c3 d4 |................| +00000010 a8 98 6c 8f fa 1b 52 a5 83 58 e3 62 89 3e 22 a3 |..l...R..X.b.>".| +00000020 37 b8 ee 13 17 03 03 00 35 b5 5f aa fd ca 85 74 |7.......5._....t| +00000030 ee c6 06 d9 2e d8 4f 7d 87 a2 b7 20 80 a5 3b 97 |......O}... ..;.| +00000040 41 bc 80 20 af b5 c4 66 26 2e 39 fd 81 e0 1a a0 |A.. ...f&.9.....| +00000050 6f c3 08 d0 23 c2 27 49 91 58 77 15 2d 49 |o...#.'I.Xw.-I| >>> Flow 4 (server to client) -00000000 17 03 03 00 a3 5e 44 99 71 b2 70 5b 36 d3 17 a9 |.....^D.q.p[6...| -00000010 eb 0b 02 b2 28 54 9d f7 3d f2 c4 d0 18 e1 fb 62 |....(T..=......b| -00000020 e2 8a 37 b7 98 2a 98 39 c0 9d 5a 3c 53 99 31 79 |..7..*.9..Z>> Flow 1 (client to server) -00000000 16 03 01 00 e0 01 00 00 dc 03 03 d8 00 36 18 75 |.............6.u| -00000010 c8 be 9e c0 c2 8c 7d 8b b5 e7 f3 ab 31 0f 5e af |......}.....1.^.| -00000020 f2 3c d6 e5 93 26 78 2f 94 19 23 20 8e b2 d2 08 |.<...&x/..# ....| -00000030 7e 69 f5 38 73 13 2f 6d ba ec ea 29 54 64 32 a0 |~i.8s./m...)Td2.| -00000040 42 b8 d8 d4 2f 34 db 2f 55 25 54 3f 00 08 13 02 |B.../4./U%T?....| -00000050 13 03 13 01 00 ff 01 00 00 8b 00 00 00 0e 00 0c |................| -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 1e |................| -00000090 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -000000a0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 00 2b |...............+| -000000b0 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 |......-.....3.&.| -000000c0 24 00 1d 00 20 39 4b 85 87 27 a7 4c f3 5d 60 0e |$... 9K..'.L.]`.| -000000d0 27 d9 31 11 0f 9a fc a8 66 14 e5 57 72 3c c5 2b |'.1.....f..Wr<.+| -000000e0 01 e0 bb 26 29 |...&)| +00000000 16 03 01 00 ca 01 00 00 c6 03 03 a1 5b 14 56 ac |............[.V.| +00000010 3f 2b b0 8e e9 0b ae 7e f7 3b 3b 20 90 b6 e4 06 |?+.....~.;; ....| +00000020 c2 b9 71 88 e4 4c 01 28 41 b3 e8 20 49 01 f7 fc |..q..L.(A.. I...| +00000030 ce 52 3e f4 58 60 56 7d 36 21 ba 23 87 21 f7 36 |.R>.X`V}6!.#.!.6| +00000040 48 88 22 78 26 37 27 a4 fc 7a 8b ea 00 04 13 03 |H."x&7'..z......| +00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................| +00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| +00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......| +000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 f4 |-.....3.&.$... .| +000000b0 2c db e8 c0 9e 7d 52 f6 fa 33 fe f7 9a 66 ca 5f |,....}R..3...f._| +000000c0 a3 28 e9 80 21 28 b8 ef e9 9f 1e 26 9c cf 0f |.(..!(.....&...| >>> 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 8e b2 d2 08 |........... ....| -00000030 7e 69 f5 38 73 13 2f 6d ba ec ea 29 54 64 32 a0 |~i.8s./m...)Td2.| -00000040 42 b8 d8 d4 2f 34 db 2f 55 25 54 3f 13 02 00 00 |B.../4./U%T?....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 49 01 f7 fc |........... I...| +00000030 ce 52 3e f4 58 60 56 7d 36 21 ba 23 87 21 f7 36 |.R>.X`V}6!.#.!.6| +00000040 48 88 22 78 26 37 27 a4 fc 7a 8b ea 13 03 00 00 |H."x&7'..z......| 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 34 9b a4 9b 55 78 |..........4...Ux| -00000090 ad 94 a9 7b 1b 4a 5f 40 23 34 5d 98 87 74 f7 b3 |...{.J_@#4]..t..| -000000a0 6d 17 03 03 01 50 8d 3f 8c 8d 12 99 a9 bd 78 42 |m....P.?......xB| -000000b0 cc 8f 26 bf e2 55 12 32 8f 2b 0c c1 e1 13 e4 c0 |..&..U.2.+......| -000000c0 20 06 4a ce c9 e5 3d 3a ce d8 86 fc 9a 6d 47 59 | .J...=:.....mGY| -000000d0 ba 11 70 08 1d f5 3f f4 5d 15 66 7e 8c ea 73 12 |..p...?.].f~..s.| -000000e0 19 4f 65 29 10 f7 d2 da b7 7d c5 bd a2 ec 2c 19 |.Oe).....}....,.| -000000f0 fb a9 c5 d3 eb b2 bc 73 f6 73 e3 ae 95 4f 77 3c |.......s.s...Ow<| -00000100 62 e6 4b 46 a9 d3 36 0c 8a 6e a6 e6 a5 1c 8d 9d |b.KF..6..n......| -00000110 2c a0 76 c1 f6 ed bf 99 64 fe bc 03 62 8e 89 ac |,.v.....d...b...| -00000120 0c 74 56 f4 09 aa 4e f5 fd 89 8f 68 9e ac b2 c8 |.tV...N....h....| -00000130 e1 d4 e0 cd 9c a8 0a 2b 11 61 fc fc 16 fd cf 09 |.......+.a......| -00000140 cd 7c bc cd 3f ce 60 f8 7a 71 f1 1b b9 2b a1 93 |.|..?.`.zq...+..| -00000150 60 1b d1 90 5b 5f bc 57 26 17 c6 e1 a4 6b 4f a4 |`...[_.W&....kO.| -00000160 4e b2 58 57 c0 f2 61 1c c9 5c 72 57 3d b2 03 07 |N.XW..a..\rW=...| -00000170 22 a7 25 d2 2f 06 4d 55 18 26 06 bb 26 5e 58 a6 |".%./.MU.&..&^X.| -00000180 e1 91 86 bd 02 22 f5 e7 af 6d c1 06 19 a6 fc 0d |....."...m......| -00000190 20 68 0e 05 ba 09 56 8d 43 33 9b 04 79 62 66 f0 | h....V.C3..ybf.| -000001a0 7c 01 4d 74 86 23 64 e7 c5 6b 10 f5 61 6c c1 83 ||.Mt.#d..k..al..| -000001b0 7a 02 f8 1e 4c 11 e3 81 90 75 a1 ff dd 63 af 07 |z...L....u...c..| -000001c0 c6 c2 54 22 79 61 1f 2d 01 84 76 38 ee 5b dd 93 |..T"ya.-..v8.[..| -000001d0 34 4d 06 dc 6f d1 5d cd c7 31 e0 56 37 06 ea f3 |4M..o.]..1.V7...| -000001e0 ca e2 00 86 17 73 58 b1 63 f0 91 03 a3 f7 b4 21 |.....sX.c......!| -000001f0 ca 31 60 c4 a6 b6 17 03 03 00 59 25 ed f6 65 f5 |.1`.......Y%..e.| -00000200 19 ba 78 3d 2d fb 86 3a 22 8b 9a 00 c1 3b ac 38 |..x=-..:"....;.8| -00000210 cd ad c1 b7 14 91 fc e0 84 c0 ed 4a 86 ca 49 eb |...........J..I.| -00000220 a9 f2 9f dd a3 74 aa f0 a9 e4 fb 18 38 51 0a 10 |.....t......8Q..| -00000230 13 8e ff a9 d2 3e 68 05 8f 82 5a c7 30 a5 02 f6 |.....>h...Z.0...| -00000240 d3 38 6e e3 e4 b3 4d ca c1 83 b2 e3 19 26 3a c2 |.8n...M......&:.| -00000250 26 5f 38 d1 17 03 03 00 45 df 7e cc 71 f0 9e ca |&_8.....E.~.q...| -00000260 00 9a 64 b4 ab 3a b8 50 b9 cd e9 eb 5b be 88 3b |..d..:.P....[..;| -00000270 66 cf 15 98 5e 63 0c ad e3 0c 40 83 87 6e 3e 01 |f...^c....@..n>.| -00000280 a3 78 03 75 cd 93 0e 7d d3 dc f2 f0 ed 3f 12 8d |.x.u...}.....?..| -00000290 fc c5 c3 c8 36 f2 82 fe dc 69 02 26 84 8b 17 03 |....6....i.&....| -000002a0 03 00 a3 d7 77 67 0e 4c d9 19 f8 bd 86 6e 1c aa |....wg.L.....n..| -000002b0 16 ab 1b 48 21 f2 85 3e c9 22 4b fd 21 8e b5 fa |...H!..>."K.!...| -000002c0 43 34 85 86 56 38 d3 4f ec 9f 25 79 eb bb fe d0 |C4..V8.O..%y....| -000002d0 69 98 05 1c c8 37 51 cf cc 77 bc f1 e7 dc 9c c3 |i....7Q..w......| -000002e0 d9 0b 3f 74 27 46 1e f3 7c 26 7e a4 6b ef c2 40 |..?t'F..|&~.k..@| -000002f0 5b 23 de b6 ec 80 79 3b 8f d5 56 d4 ea 44 30 7e |[#....y;..V..D0~| -00000300 73 2b 09 44 32 5c b9 2c 04 6e 94 50 32 61 80 93 |s+.D2\.,.n.P2a..| -00000310 41 b6 83 73 19 a0 b4 ee b1 8b 23 a1 36 9c 5c 33 |A..s......#.6.\3| -00000320 89 87 cd ef 8a 58 c7 51 a5 31 9c 8e 60 7a 6a ce |.....X.Q.1..`zj.| -00000330 5f 7e 13 43 ee 44 8d b7 2c 81 da 3d c6 c6 d2 18 |_~.C.D..,..=....| -00000340 aa 85 22 63 d7 bd |.."c..| +00000080 03 03 00 01 01 17 03 03 00 17 f9 df 7b 4f f9 a1 |............{O..| +00000090 f7 78 eb 10 59 5c 4f ed 42 09 08 10 0f c7 a4 81 |.x..Y\O.B.......| +000000a0 8b 17 03 03 01 50 38 d7 96 35 05 7d 3d 3a 60 02 |.....P8..5.}=:`.| +000000b0 bf 93 37 f2 60 3e 64 cb 1a 6f 9c 69 af 06 ca 70 |..7.`>d..o.i...p| +000000c0 94 e2 d1 7f 4a 5d c7 57 0e 11 c7 4e 24 c6 ba 57 |....J].W...N$..W| +000000d0 9f d7 67 3a 0a 8b 93 08 d4 de c5 be 62 79 61 2a |..g:........bya*| +000000e0 3d 4e 57 f9 98 e5 4f 5e 5a 74 52 5b a4 d0 07 ae |=NW...O^ZtR[....| +000000f0 8c 2a cb 50 dd b3 76 ab 3a 61 5b 55 83 8e 37 8d |.*.P..v.:a[U..7.| +00000100 39 e5 4f 58 7e 7a bc 80 26 f6 0f 47 8f 11 55 77 |9.OX~z..&..G..Uw| +00000110 24 b1 a7 06 d8 d2 30 82 0d 99 39 04 5f 97 d8 1d |$.....0...9._...| +00000120 99 67 99 89 f0 ee 4f 18 8b 49 24 d3 6a d0 65 c9 |.g....O..I$.j.e.| +00000130 01 a2 48 54 8b d2 bb 56 d4 0a 73 62 88 fa 70 4e |..HT...V..sb..pN| +00000140 7f dd 59 5b 14 7b 28 02 07 75 01 4d 41 ab 1d 7e |..Y[.{(..u.MA..~| +00000150 ef 24 42 ee 85 7f fa 5f 9e f0 9f f2 7f 92 00 52 |.$B...._.......R| +00000160 ca 73 8a 73 c6 d7 13 f5 9d 31 6f 76 75 db e7 53 |.s.s.....1ovu..S| +00000170 4d 44 40 8f 47 be bd 0e 71 13 d0 f7 f2 72 67 3a |MD@.G...q....rg:| +00000180 de b8 da b0 1d 84 85 d0 c2 c4 8d 16 87 68 c7 98 |.............h..| +00000190 40 0a 92 c8 fb 8a 3a e4 7b 34 43 47 b7 4f 28 8e |@.....:.{4CG.O(.| +000001a0 11 01 98 88 b6 cd ca aa d4 dc 52 5d f9 cf 55 bb |..........R]..U.| +000001b0 f3 13 f2 ce dc 67 74 a7 4d 5e 65 6f 18 cd 82 4e |.....gt.M^eo...N| +000001c0 fc 80 2c 14 17 99 08 6d 59 b3 3f 38 00 52 a2 a3 |..,....mY.?8.R..| +000001d0 c1 98 84 15 91 82 3f e9 47 82 12 a0 94 dc 19 9e |......?.G.......| +000001e0 2e b7 25 79 30 b9 81 d6 9f 33 8e 49 80 7a 4c a2 |..%y0....3.I.zL.| +000001f0 b7 9a e6 17 2c 06 17 03 03 00 59 97 c7 4b ac c3 |....,.....Y..K..| +00000200 ed b3 bd 82 7a c2 45 a0 18 70 7b 88 fe 8b fd 6b |....z.E..p{....k| +00000210 83 f2 dd 77 15 74 9c f0 a6 27 22 bf ee 25 53 07 |...w.t...'"..%S.| +00000220 81 95 3c 91 b3 89 3c ca f9 5b c7 cf bb 32 55 f8 |..<...<..[...2U.| +00000230 3c 76 70 f6 11 ca 5d 92 aa 78 9e 8a 2f ab e0 6f |>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 03 21 4e 7f 71 |..........E.!N.q| -00000010 cf b4 fa 18 34 06 57 62 51 99 3d 4a da 52 36 54 |....4.WbQ.=J.R6T| -00000020 5b 22 2b 66 90 c1 8a 21 ec 5e 8b 3c 40 7a 18 0e |["+f...!.^.<@z..| -00000030 b5 82 c1 14 e5 9e 15 72 16 f2 fc 15 cb dd f1 e8 |.......r........| -00000040 7c 03 5e ba c9 96 86 11 ec 88 44 97 24 a5 b2 5a ||.^.......D.$..Z| +00000000 14 03 03 00 01 01 17 03 03 00 35 19 fa 19 c0 ce |..........5.....| +00000010 09 87 c2 06 69 56 2a 0a a7 9c 79 76 03 1b 70 5e |....iV*...yv..p^| +00000020 56 2d d4 a1 09 e3 99 f7 a9 7a e5 ba 3e 17 8b b2 |V-.......z..>...| +00000030 fe da 70 81 d9 30 83 27 b1 da 2e df da 94 75 72 |..p..0.'......ur| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 4b 9e 56 c2 1a a7 67 94 04 eb b0 |.....K.V...g....| -00000010 48 87 44 38 7d f2 c7 b7 6c 1b a5 40 bb 1a 94 22 |H.D8}...l..@..."| -00000020 a2 f0 9e 17 03 03 00 13 64 42 12 84 e4 d8 64 fd |........dB....d.| -00000030 8c 70 ff f5 43 4d 57 39 b2 d3 1e |.p..CMW9...| +00000000 17 03 03 00 1e 83 53 ed 09 07 d3 87 ab 37 a2 08 |......S......7..| +00000010 a8 50 66 87 97 54 04 38 4b a6 25 f8 ab 75 ac 39 |.Pf..T.8K.%..u.9| +00000020 52 e2 8d 17 03 03 00 13 86 58 ef 44 c1 59 5e 2e |R........X.D.Y^.| +00000030 e4 2e df 93 6e 52 76 58 c1 9d 2a |....nRvX..*| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial index 078739c7502..8267ca0f9e1 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial @@ -1,103 +1,99 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e4 01 00 00 e0 03 03 40 53 50 a3 f5 |...........@SP..| -00000010 3a 20 4f 16 ef 9c a4 1c a3 10 1d 93 cb ea 1f 69 |: O............i| -00000020 6b aa 50 ae a8 01 7e 65 d9 7b 5c 20 8c 9b cc d4 |k.P...~e.{\ ....| -00000030 6b 07 4d 1e d9 69 d2 d8 a0 a0 d5 b7 75 d8 e3 d8 |k.M..i......u...| -00000040 c4 ac f7 d2 6f e5 f5 8f 46 9a bf 85 00 08 13 02 |....o...F.......| -00000050 13 03 13 01 00 ff 01 00 00 8f 00 00 00 0e 00 0c |................| -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 23 00 00 00 16 00 00 00 17 00 00 |.....#..........| -00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................| -000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................| -000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....| -000000c0 33 00 26 00 24 00 1d 00 20 81 67 45 ec b4 08 4d |3.&.$... .gE...M| -000000d0 a6 50 79 b4 d4 a9 d1 35 51 2b db 8d b7 e7 7c 3c |.Py....5Q+....|<| -000000e0 fd 0f 4b 47 87 e1 bb fb 2d |..KG....-| +00000000 16 03 01 00 ce 01 00 00 ca 03 03 26 86 8d 61 97 |...........&..a.| +00000010 6c da 93 d7 43 5c b3 0c 06 5c c2 cb e0 89 46 9f |l...C\...\....F.| +00000020 cc b0 a3 cf 41 3d cf 7a 9e 02 bc 20 a6 33 fe 0b |....A=.z... .3..| +00000030 90 24 8b ed 69 48 86 9b d2 1a 5c 04 66 52 4f 5d |.$..iH....\.fRO]| +00000040 a4 24 6b d2 84 08 c0 48 a9 55 ef 0c 00 04 13 03 |.$k....H.U......| +00000050 00 ff 01 00 00 7d 00 0b 00 04 03 00 01 02 00 0a |.....}..........| +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 00 0d 00 1e 00 1c |................| +00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................| +00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..| +000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.| +000000b0 1d 00 20 b9 ab 39 93 6b 9f aa 46 0a 61 c6 f8 58 |.. ..9.k..F.a..X| +000000c0 45 26 16 6f b6 cb 42 52 e8 24 ab cc a4 2d b6 7a |E&.o..BR.$...-.z| +000000d0 a5 90 67 |..g| >>> 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 8c 9b cc d4 |........... ....| -00000030 6b 07 4d 1e d9 69 d2 d8 a0 a0 d5 b7 75 d8 e3 d8 |k.M..i......u...| -00000040 c4 ac f7 d2 6f e5 f5 8f 46 9a bf 85 13 02 00 00 |....o...F.......| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 a6 33 fe 0b |........... .3..| +00000030 90 24 8b ed 69 48 86 9b d2 1a 5c 04 66 52 4f 5d |.$..iH....\.fRO]| +00000040 a4 24 6b d2 84 08 c0 48 a9 55 ef 0c 13 03 00 00 |.$k....H.U......| 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 d2 bf e0 2f ba e9 |............./..| -00000090 84 f5 8b 96 93 ac de 94 3b 92 03 ca db 43 f4 55 |........;....C.U| -000000a0 12 17 03 03 02 6d 54 36 b6 78 fb bf 9f 36 02 78 |.....mT6.x...6.x| -000000b0 b3 92 50 c9 ab 85 b6 57 69 18 10 c1 fe da d4 05 |..P....Wi.......| -000000c0 89 db 62 bd 83 b0 82 38 29 5f ce 53 88 2d f2 cd |..b....8)_.S.-..| -000000d0 6a d7 1d c0 c5 03 e7 e4 4b ec eb bf 95 8e d5 9b |j.......K.......| -000000e0 65 45 09 52 ef 29 60 7b 22 61 6f ca 1b 3d 30 a4 |eE.R.)`{"ao..=0.| -000000f0 c4 c4 06 55 39 5e 3a ef a2 62 61 35 6c c4 fc 8b |...U9^:..ba5l...| -00000100 19 dc c1 b0 8d dd ba d0 9e 87 65 1c 8d 73 6c 82 |..........e..sl.| -00000110 e4 45 e9 a9 53 94 20 ba 19 7e 4e 7e fb 14 dc 5d |.E..S. ..~N~...]| -00000120 86 19 0b fe f8 9c 7e 61 8e 17 e6 59 12 c2 e0 6a |......~a...Y...j| -00000130 52 c0 25 05 30 c8 f7 d6 54 69 15 ca c9 8e 96 1d |R.%.0...Ti......| -00000140 42 55 1f 9a 9b 03 95 af 74 05 be 5e 51 35 8b 1f |BU......t..^Q5..| -00000150 24 0a 13 03 90 fc c0 c4 22 c3 f0 8a f2 60 a8 ff |$......."....`..| -00000160 7b 04 48 10 3e 42 da e5 c2 7b 72 9c e1 d6 b5 56 |{.H.>B...{r....V| -00000170 f7 69 ce 46 67 33 e4 d3 e5 61 43 b2 57 e8 b2 43 |.i.Fg3...aC.W..C| -00000180 84 ac 75 15 d1 cb 70 53 99 1c 29 9a 21 bb c0 d3 |..u...pS..).!...| -00000190 66 8a be 16 b1 67 1b 60 d3 2f c6 a3 7e f3 3b 4f |f....g.`./..~.;O| -000001a0 78 4d ec 1f 9f 6d 46 1c 43 2f 50 ad 44 75 93 49 |xM...mF.C/P.Du.I| -000001b0 e2 29 c4 be aa 22 51 f1 17 1a 20 97 8a 23 06 2c |.)..."Q... ..#.,| -000001c0 93 b6 9d 11 5a 55 34 d9 f1 a4 c6 5b 84 f6 bb 0c |....ZU4....[....| -000001d0 a0 7c a2 25 47 df a6 22 c8 df e5 ae 74 1c f3 db |.|.%G.."....t...| -000001e0 3c 04 6f fa 86 76 c9 be ae 2a e0 64 65 d2 8f 9a |<.o..v...*.de...| -000001f0 7b a2 38 4d 74 8d 44 ad ef c1 12 0b ca 64 6c b5 |{.8Mt.D......dl.| -00000200 13 03 2c b4 6a e8 78 ba 57 d5 ef 9a d1 1d 7e 92 |..,.j.x.W.....~.| -00000210 58 52 78 c2 c5 e2 f8 e9 2d 06 28 88 19 d4 19 7b |XRx.....-.(....{| -00000220 7f 41 ea ed f9 9e 14 f1 9b 3f dc f7 bc 35 20 ca |.A.......?...5 .| -00000230 fc 8f b8 df ee ef 83 50 c4 41 91 ae 83 4b bd d1 |.......P.A...K..| -00000240 00 e1 3f 70 5d cb 40 a6 77 70 cd 9a 09 5b 05 14 |..?p].@.wp...[..| -00000250 83 b9 7c 8d 1c e1 7f 6e 41 1a b9 8c 70 2a 95 01 |..|....nA...p*..| -00000260 ef 19 0c 59 7d 47 b4 64 7b 91 5e 9b 02 c5 ed ee |...Y}G.d{.^.....| -00000270 d4 9b ad 12 70 d1 d9 6b 02 26 b5 48 4e 23 bb 61 |....p..k.&.HN#.a| -00000280 ae c7 82 74 a9 68 59 b1 66 07 b8 e3 93 0f 2c 9f |...t.hY.f.....,.| -00000290 8d 8d f1 e8 3f b7 2c 64 90 4f 88 7f 41 78 66 ba |....?.,d.O..Axf.| -000002a0 26 eb 1c 8b 70 47 f5 78 cb fe 66 34 6f 74 b1 98 |&...pG.x..f4ot..| -000002b0 ca 12 f5 91 8c cb 15 85 eb 77 ad af 76 f8 3f 3f |.........w..v.??| -000002c0 cb 86 82 fe 1e 78 1e d3 16 c2 b7 e6 a6 2b a0 6c |.....x.......+.l| -000002d0 da 99 3f dd 3b 0b 10 3b 16 bd d9 4f 45 c3 12 b5 |..?.;..;...OE...| -000002e0 14 1b 53 33 56 c1 f4 7c 4a 47 b9 c2 b0 bd 4e 78 |..S3V..|JG....Nx| -000002f0 e1 6f 76 05 d1 e3 af 01 f8 b4 e6 23 12 11 cf 43 |.ov........#...C| -00000300 91 9d eb be d8 6b 9c d2 fd 3b b5 3b 8c 52 4e 12 |.....k...;.;.RN.| -00000310 df 26 42 17 03 03 00 99 fc fb 50 ba e0 83 07 bb |.&B.......P.....| -00000320 13 4f 7c 1e 5f 35 e5 2f b9 c0 40 cb 51 9a 38 a6 |.O|._5./..@.Q.8.| -00000330 bf 1a 22 e3 ea 8b 5e 30 e0 b2 2b 40 aa 76 62 bc |.."...^0..+@.vb.| -00000340 c5 e3 3c f3 2a 10 2e 35 58 2b 5e c1 56 da 78 a9 |..<.*..5X+^.V.x.| -00000350 57 b5 46 1f d8 ad 59 3c 5a b8 37 be 66 86 d0 ad |W.F...Y..]_V| -000003b0 05 17 03 03 00 45 81 1e e7 bb e8 81 f4 41 12 af |.....E.......A..| -000003c0 fb f0 8f bd d0 d6 b3 10 a5 1e d6 0c f7 aa 01 15 |................| -000003d0 9d 30 5b 65 e1 fd 3e 72 3d 43 62 21 02 0e ec da |.0[e..>r=Cb!....| -000003e0 ec 74 2c e2 22 84 c9 90 18 71 f8 ef db 3f 05 d6 |.t,."....q...?..| -000003f0 91 09 46 c2 5c 2b f7 03 39 2b 3e 17 03 03 00 a3 |..F.\+..9+>.....| -00000400 53 cc 75 04 8c c5 25 70 1f 4b 9c 04 92 af 1a 3f |S.u...%p.K.....?| -00000410 26 1e 00 98 fa e3 c2 25 63 ca d4 03 fd 6c 94 a0 |&......%c....l..| -00000420 0a 87 5f 68 63 52 72 25 69 3f 21 66 f6 a6 00 2a |.._hcRr%i?!f...*| -00000430 25 e3 1e 95 f3 bd a8 22 bc 9a 74 f0 41 5d b1 30 |%......"..t.A].0| -00000440 36 ff 13 09 d9 69 7f 16 35 11 34 0e 65 2e e7 52 |6....i..5.4.e..R| -00000450 b4 6e a1 dc 06 fe a3 3e 3b eb 79 fe d0 e1 e8 76 |.n.....>;.y....v| -00000460 e2 0e 49 78 c3 cf c5 31 ce 7f 9b d6 c5 6d 3f 7b |..Ix...1.....m?{| -00000470 79 9a 5d a7 c3 3b 58 eb a2 43 55 c6 42 7a a8 34 |y.]..;X..CU.Bz.4| -00000480 6e c9 47 aa 5e 44 4a bd 4b 89 28 ab ac 5a 95 dc |n.G.^DJ.K.(..Z..| -00000490 96 99 28 dc 29 04 10 f3 8c 49 45 b7 29 69 3d 9e |..(.)....IE.)i=.| -000004a0 dd fe 4a |..J| +00000080 03 03 00 01 01 17 03 03 00 17 e9 4c 8a ed 0c af |...........L....| +00000090 04 d2 18 14 38 48 c1 71 da 59 db 46 f4 00 0d 19 |....8H.q.Y.F....| +000000a0 1e 17 03 03 02 6d e0 d2 7b bf 0a 51 48 a9 67 46 |.....m..{..QH.gF| +000000b0 25 3b 07 e9 68 da 4d cf 47 31 0f 7d ad 4e 0d 6d |%;..h.M.G1.}.N.m| +000000c0 c3 ad 03 61 4a c0 ae 06 4d b7 84 29 1b 44 49 26 |...aJ...M..).DI&| +000000d0 f4 99 fc 58 1e 5b f0 15 ee be 19 c3 b3 23 20 f0 |...X.[.......# .| +000000e0 7a 10 e4 ab c8 00 f6 e4 93 d6 b3 2a fd 14 10 c9 |z..........*....| +000000f0 72 b2 21 ba 93 50 08 4e d2 1f 3f 64 68 73 3c c7 |r.!..P.N..?dhs<.| +00000100 11 3c f5 84 61 b0 2c 84 42 0c ef a9 03 a2 74 aa |.<..a.,.B.....t.| +00000110 3b 07 e0 d5 f5 c4 d1 a8 8e f5 64 0e 52 41 b1 4d |;.........d.RA.M| +00000120 aa 43 0d f3 6b 0c 19 36 66 fe 4c 73 cd 52 03 2f |.C..k..6f.Ls.R./| +00000130 61 f1 9d 23 12 e2 b9 69 d9 48 92 07 1b 5d 6f 28 |a..#...i.H...]o(| +00000140 e1 96 39 d8 59 19 9d 9c bf 99 3a af 03 68 bd 34 |..9.Y.....:..h.4| +00000150 38 04 9d 8c 9a bf 75 67 74 dd 9c eb 89 13 6d 55 |8.....ugt.....mU| +00000160 b4 c4 17 11 05 54 d7 f9 d7 5a ed ec d5 15 31 5e |.....T...Z....1^| +00000170 2f ed 69 fa 99 23 57 e3 62 98 35 27 17 34 e1 c4 |/.i..#W.b.5'.4..| +00000180 3c 95 3f 69 de 01 aa a9 66 55 4a 40 3a f1 4f 19 |<.?i....fUJ@:.O.| +00000190 02 2f df 51 0c 69 ec 48 7a 60 f7 72 5e f6 f0 4d |./.Q.i.Hz`.r^..M| +000001a0 a1 b2 7a 06 df 69 a1 19 42 29 56 5c 67 99 3d 0e |..z..i..B)V\g.=.| +000001b0 5d da df 7b 93 8e 9a 26 6e 2e 09 c4 30 40 ad a9 |]..{...&n...0@..| +000001c0 ee 4b bd 21 41 b6 cb fc 97 0f fc a2 cf 26 31 d6 |.K.!A........&1.| +000001d0 d6 77 96 4e c6 a2 fd 5a 0e cb d5 31 a6 21 e8 76 |.w.N...Z...1.!.v| +000001e0 a2 48 4d 43 d4 c9 18 b2 21 cc 13 13 84 f2 c2 cf |.HMC....!.......| +000001f0 60 8f 2e 36 39 8a a8 26 03 1d 51 24 b4 08 c5 5d |`..69..&..Q$...]| +00000200 96 b9 4a 46 02 41 1f 59 ea 47 a9 37 bc a0 c4 70 |..JF.A.Y.G.7...p| +00000210 26 d6 8c 11 62 45 1d 92 5d ea 39 cd af af 13 38 |&...bE..].9....8| +00000220 85 ca a8 74 1a 09 07 f2 7c d6 49 0d 2d ad 1c 9f |...t....|.I.-...| +00000230 db 8b 56 91 45 51 32 db ca 9c f4 d2 72 09 8a fe |..V.EQ2.....r...| +00000240 98 9e a8 b5 b2 49 9c 0b e9 3a 42 d0 53 e0 20 6c |.....I...:B.S. l| +00000250 e3 07 36 ef cc 85 56 fd b4 6e ff d2 7c 96 52 27 |..6...V..n..|.R'| +00000260 46 c9 3c b3 bf fb 16 0b 61 54 09 9c ac 3b 18 5f |F.<.....aT...;._| +00000270 5a 01 4b 25 67 22 ef 19 86 a3 3a 80 f0 12 f5 60 |Z.K%g"....:....`| +00000280 4c 77 cf bd a9 e8 a1 19 d4 8c e1 a8 b2 b8 19 b8 |Lw..............| +00000290 98 85 c3 da 1a b8 4d 6e 1f 35 73 28 32 3c a0 44 |......Mn.5s(2<.D| +000002a0 c9 77 46 b8 c6 54 4d 80 67 72 58 c4 e3 0b f3 6c |.wF..TM.grX....l| +000002b0 43 eb e2 89 f1 30 cc 90 b4 e9 b8 ec e2 5f c1 31 |C....0......._.1| +000002c0 a2 de 9d e9 fe 9c fe b0 83 b7 aa e9 2e 62 35 89 |.............b5.| +000002d0 90 0d 36 79 8f 23 bb 7a ae dc db db 1c c3 96 5d |..6y.#.z.......]| +000002e0 7c 06 e9 1c ee 82 58 46 7c 1b 90 9d cf 2d 31 54 ||.....XF|....-1T| +000002f0 96 94 58 dc 95 26 85 c7 f4 c9 9c 2b 8a 2f ae b3 |..X..&.....+./..| +00000300 70 10 bf f1 0e 66 ef f1 1c 66 da 6c 52 d8 6e aa |p....f...f.lR.n.| +00000310 3a 14 d8 17 03 03 00 99 69 45 ee c3 c9 b3 4d 9a |:.......iE....M.| +00000320 01 00 70 27 54 8c 12 bb 74 67 e8 88 07 ac 4e ab |..p'T...tg....N.| +00000330 b1 41 f4 65 ee 3b 06 87 79 5d 9b 1d 70 df 2f f7 |.A.e.;..y]..p./.| +00000340 e0 88 45 2b a1 b9 ca 67 88 65 65 33 51 41 c0 b2 |..E+...g.ee3QA..| +00000350 da 6a 7a 7c bf 42 58 8d ae 7b 24 d0 8a f7 47 c0 |.jz|.BX..{$...G.| +00000360 a9 45 da 24 82 03 a1 65 03 7c 3c 2a bf 48 e2 0d |.E.$...e.|<*.H..| +00000370 fa cc 3f 00 53 63 5d f9 b4 a1 00 d2 a7 3c 81 64 |..?.Sc]......<.d| +00000380 8a d5 90 4f b9 58 2b 1e 1d a7 7e ad 3e 8f d4 4a |...O.X+...~.>..J| +00000390 7b 66 b7 4e 68 04 ac 66 24 6e 76 ed f4 5c aa 52 |{f.Nh..f$nv..\.R| +000003a0 3d f8 f5 ea d0 0a 74 ba 39 da 21 e0 f1 03 80 cd |=.....t.9.!.....| +000003b0 5b 17 03 03 00 35 7b 1f 6e 37 6c 15 5b 1b f7 ea |[....5{.n7l.[...| +000003c0 bf 03 68 5f 15 1f e7 99 a8 64 f1 60 3d e0 b6 5e |..h_.....d.`=..^| +000003d0 c1 60 18 61 e5 ea dc ab b5 d3 5f 10 1b 5c 3a 1b |.`.a......_..\:.| +000003e0 c5 fe a6 d3 fc 45 6b db b1 27 60 17 03 03 00 93 |.....Ek..'`.....| +000003f0 e3 f1 5f f1 18 a6 ab 67 88 e4 5a f9 fd 71 77 4b |.._....g..Z..qwK| +00000400 6c 0d 98 ef 71 72 2a aa d2 0a 2d 72 ac 40 57 2d |l...qr*...-r.@W-| +00000410 73 ad 77 cd 01 19 19 be e7 49 d4 6a aa 97 f9 40 |s.w......I.j...@| +00000420 b1 85 cc bb 5c 57 1a 17 a8 48 65 d3 4d e9 a9 29 |....\W...He.M..)| +00000430 4b 08 6b b3 33 2c 97 d0 89 0a 50 e2 66 06 c6 63 |K.k.3,....P.f..c| +00000440 c3 6f 8d 5e ab a4 af 7a 6a 5e 25 8d 4a 17 ea aa |.o.^...zj^%.J...| +00000450 67 8a ad af c3 1e d6 47 db a5 b5 db 32 1b 83 f8 |g......G....2...| +00000460 2d f9 bc 99 28 07 0d d0 fe 34 bf 52 ae 59 27 40 |-...(....4.R.Y'@| +00000470 cd 0e 4d 4d 12 28 21 01 30 38 b1 c3 df 63 e9 9e |..MM.(!.08...c..| +00000480 34 91 84 |4..| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 3f e6 f9 73 13 |..........E?..s.| -00000010 98 fa c1 e1 84 7a 0c 10 eb 9a bf 2b df c1 44 26 |.....z.....+..D&| -00000020 36 1a 95 02 b4 12 67 7c e2 7d f3 1e 54 79 7b 51 |6.....g|.}..Ty{Q| -00000030 e6 13 94 cb 00 cc 25 fb 6e 8a 35 4e f0 f0 95 34 |......%.n.5N...4| -00000040 53 fd 7e 37 d2 a8 0a 71 a7 2d 8d 58 2e ae 27 34 |S.~7...q.-.X..'4| +00000000 14 03 03 00 01 01 17 03 03 00 35 1d d8 d0 a8 ec |..........5.....| +00000010 04 45 13 43 a1 72 38 4e 54 85 7a a2 17 dc eb 39 |.E.C.r8NT.z....9| +00000020 36 7d 50 25 5f d3 0d 7f c3 a7 75 93 e9 1e 17 0a |6}P%_.....u.....| +00000030 a3 d7 a8 74 23 98 5e 3a 3a 4c 2c d3 78 b4 04 48 |...t#.^::L,.x..H| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 07 34 2c 55 6a c5 14 e7 0a 51 94 |......4,Uj....Q.| -00000010 74 ad e1 c0 4d e8 1c 3e ad 3e 8e 71 e5 60 9c d8 |t...M..>.>.q.`..| -00000020 6a 44 ac 17 03 03 00 13 09 9e 97 ff 3d b8 f1 a6 |jD..........=...| -00000030 5d f9 8f b0 65 93 31 6b 9d 81 76 |]...e.1k..v| +00000000 17 03 03 00 1e 53 e2 0d f2 62 e8 be 84 e0 33 1a |.....S...b....3.| +00000010 56 bc 45 f9 0b 69 63 72 03 f3 34 c6 72 d8 f9 c4 |V.E..icr..4.r...| +00000020 ba 53 3d 17 03 03 00 13 11 b5 0d 7f d4 e7 51 90 |.S=...........Q.| +00000030 39 be 2b d8 d6 7c e8 12 ea 61 83 |9.+..|...a.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest b/libgo/go/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest index 96a5488c730..95eefd29bee 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest @@ -1,129 +1,123 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 da 01 00 00 d6 03 03 ab e7 6d 22 09 |.............m".| -00000010 bf 08 ef a1 7e 7c 8d ea fd a5 39 43 62 84 67 a8 |....~|....9Cb.g.| -00000020 df b1 a1 3a d7 37 dc 0d ef 27 54 20 20 f3 5b 41 |...:.7...'T .[A| -00000030 67 3e 30 d8 8e 2d 0f a1 c2 df 86 48 8c 05 bb d7 |g>0..-.....H....| -00000040 73 30 80 86 cf 2c 85 d1 2a fe 21 36 00 08 13 02 |s0...,..*.!6....| -00000050 13 03 13 01 00 ff 01 00 00 85 00 00 00 0e 00 0c |................| -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 06 00 04 00 1d 00 17 00 16 |................| -00000080 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................| -00000090 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| -000000a0 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......| -000000b0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 1a |-.....3.&.$... .| -000000c0 ae 88 dd 6c 7c 4c fb e5 65 ca 8e 63 a1 97 4c d3 |...l|L..e..c..L.| -000000d0 33 ff 00 95 db 0b ce 67 62 26 78 27 52 f0 5c |3......gb&x'R.\| +00000000 16 03 01 00 c4 01 00 00 c0 03 03 16 5e f5 e2 4e |............^..N| +00000010 27 ce 8e 88 0b e9 13 6d 12 a6 6d 27 c9 ab 95 47 |'......m..m'...G| +00000020 6f 9d 5d a0 92 64 35 c1 b6 70 90 20 ff 47 6f 67 |o.]..d5..p. .Gog| +00000030 69 49 88 2a 84 69 79 48 fe cc 92 db 6e 9e ab 47 |iI.*.iyH....n..G| +00000040 8e 47 10 58 db ad 22 8e da bb 86 e6 00 04 13 03 |.G.X..".........| +00000050 00 ff 01 00 00 73 00 0b 00 04 03 00 01 02 00 0a |.....s..........| +00000060 00 06 00 04 00 1d 00 17 00 16 00 00 00 17 00 00 |................| +00000070 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................| +00000080 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................| +00000090 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....| +000000a0 33 00 26 00 24 00 1d 00 20 7e a4 de 34 df 01 99 |3.&.$... ~..4...| +000000b0 37 77 f7 de 6a e2 79 e7 63 eb 86 6c 62 61 fd b0 |7w..j.y.c..lba..| +000000c0 c6 95 04 c8 63 29 cd 32 00 |....c).2.| >>> Flow 2 (server to client) 00000000 16 03 03 00 58 02 00 00 54 03 03 cf 21 ad 74 e5 |....X...T...!.t.| 00000010 9a 61 11 be 1d 8c 02 1e 65 b8 91 c2 a2 11 16 7a |.a......e......z| -00000020 bb 8c 5e 07 9e 09 e2 c8 a8 33 9c 20 20 f3 5b 41 |..^......3. .[A| -00000030 67 3e 30 d8 8e 2d 0f a1 c2 df 86 48 8c 05 bb d7 |g>0..-.....H....| -00000040 73 30 80 86 cf 2c 85 d1 2a fe 21 36 13 02 00 00 |s0...,..*.!6....| +00000020 bb 8c 5e 07 9e 09 e2 c8 a8 33 9c 20 ff 47 6f 67 |..^......3. .Gog| +00000030 69 49 88 2a 84 69 79 48 fe cc 92 db 6e 9e ab 47 |iI.*.iyH....n..G| +00000040 8e 47 10 58 db ad 22 8e da bb 86 e6 13 03 00 00 |.G.X..".........| 00000050 0c 00 2b 00 02 03 04 00 33 00 02 00 17 14 03 03 |..+.....3.......| 00000060 00 01 01 |...| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 16 03 03 00 fb 01 00 00 f7 03 |................| -00000010 03 ab e7 6d 22 09 bf 08 ef a1 7e 7c 8d ea fd a5 |...m".....~|....| -00000020 39 43 62 84 67 a8 df b1 a1 3a d7 37 dc 0d ef 27 |9Cb.g....:.7...'| -00000030 54 20 20 f3 5b 41 67 3e 30 d8 8e 2d 0f a1 c2 df |T .[Ag>0..-....| -00000040 86 48 8c 05 bb d7 73 30 80 86 cf 2c 85 d1 2a fe |.H....s0...,..*.| -00000050 21 36 00 08 13 02 13 03 13 01 00 ff 01 00 00 a6 |!6..............| -00000060 00 00 00 0e 00 0c 00 00 09 31 32 37 2e 30 2e 30 |.........127.0.0| -00000070 2e 31 00 0b 00 04 03 00 01 02 00 0a 00 06 00 04 |.1..............| -00000080 00 1d 00 17 00 16 00 00 00 17 00 00 00 0d 00 1e |................| -00000090 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................| -000000a0 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 00 2b |...............+| -000000b0 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 47 00 |......-.....3.G.| -000000c0 45 00 17 00 41 04 22 3e 1f 4b 0f 2e f4 af bf 6c |E...A.">.K.....l| -000000d0 d7 35 69 72 23 00 3f 16 6a 8e 00 3e 2b 8f f8 60 |.5ir#.?.j..>+..`| -000000e0 17 e8 e8 80 f3 28 5d cd 1f f7 99 88 59 01 a5 d7 |.....(].....Y...| -000000f0 34 d0 d9 38 5b 73 3e d6 3c c8 9e 39 8f 45 d0 37 |4..8[s>.<..9.E.7| -00000100 aa 5b 8e 59 2f 0c |.[.Y/.| +00000000 14 03 03 00 01 01 16 03 03 00 e5 01 00 00 e1 03 |................| +00000010 03 16 5e f5 e2 4e 27 ce 8e 88 0b e9 13 6d 12 a6 |..^..N'......m..| +00000020 6d 27 c9 ab 95 47 6f 9d 5d a0 92 64 35 c1 b6 70 |m'...Go.]..d5..p| +00000030 90 20 ff 47 6f 67 69 49 88 2a 84 69 79 48 fe cc |. .GogiI.*.iyH..| +00000040 92 db 6e 9e ab 47 8e 47 10 58 db ad 22 8e da bb |..n..G.G.X.."...| +00000050 86 e6 00 04 13 03 00 ff 01 00 00 94 00 0b 00 04 |................| +00000060 03 00 01 02 00 0a 00 06 00 04 00 1d 00 17 00 16 |................| +00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................| +00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................| +00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......| +000000a0 2d 00 02 01 01 00 33 00 47 00 45 00 17 00 41 04 |-.....3.G.E...A.| +000000b0 ca c3 69 88 b3 ed f4 ad 7f 9c 03 6c 7a 44 55 d6 |..i........lzDU.| +000000c0 68 1d a4 27 67 57 d7 27 08 27 e8 b9 c9 32 49 a2 |h..'gW.'.'...2I.| +000000d0 e4 f6 c2 f2 62 bd 74 67 77 f9 26 27 ee d7 a7 f0 |....b.tgw.&'....| +000000e0 9c 9a 41 cd 8b bf 76 25 df ff 5a 9f 4e f5 41 95 |..A...v%..Z.N.A.| >>> Flow 4 (server to client) 00000000 16 03 03 00 9b 02 00 00 97 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 20 f3 5b 41 |........... .[A| -00000030 67 3e 30 d8 8e 2d 0f a1 c2 df 86 48 8c 05 bb d7 |g>0..-.....H....| -00000040 73 30 80 86 cf 2c 85 d1 2a fe 21 36 13 02 00 00 |s0...,..*.!6....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 ff 47 6f 67 |........... .Gog| +00000030 69 49 88 2a 84 69 79 48 fe cc 92 db 6e 9e ab 47 |iI.*.iyH....n..G| +00000040 8e 47 10 58 db ad 22 8e da bb 86 e6 13 03 00 00 |.G.X..".........| 00000050 4f 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |O.+.....3.E...A.| 00000060 1e 18 37 ef 0d 19 51 88 35 75 71 b5 e5 54 5b 12 |..7...Q.5uq..T[.| 00000070 2e 8f 09 67 fd a7 24 20 3e b2 56 1c ce 97 28 5e |...g..$ >.V...(^| 00000080 f8 2b 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 32 42 |.+-O....lK[.V.2B| 00000090 e9 58 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc 5a 89 |.X..I..h.A.Vk.Z.| -000000a0 17 03 03 00 17 4c 08 ad d8 7f 86 a1 1f b2 dc 89 |.....L..........| -000000b0 38 bf d4 75 ff 9e db 74 59 3c 86 5c 17 03 03 02 |8..u...tY<.\....| -000000c0 6d f3 65 9c 3b 80 4f c0 c4 a6 e5 e1 32 49 06 13 |m.e.;.O.....2I..| -000000d0 b8 60 18 50 c4 1c 38 f7 1a 42 89 49 14 40 4c fc |.`.P..8..B.I.@L.| -000000e0 7c 3c 2b 70 2d 8b e7 99 f8 2e 1d 50 c8 b3 8b cd ||<+p-......P....| -000000f0 59 a8 f7 89 4d 93 c6 1e f9 94 e3 69 25 92 48 61 |Y...M......i%.Ha| -00000100 06 4a 89 f5 4b 57 93 a7 20 23 0b bb e5 00 8a 43 |.J..KW.. #.....C| -00000110 fb 98 29 08 df 32 89 1a d6 87 f0 97 dc 8b f5 3f |..)..2.........?| -00000120 e2 54 32 2e 23 04 c4 87 0a 0f 99 ef c5 28 64 13 |.T2.#........(d.| -00000130 6c 62 29 e1 3a 21 84 bb 56 f9 92 24 58 75 48 8b |lb).:!..V..$XuH.| -00000140 25 59 9f e1 a5 aa ee 44 3e 64 e5 af ac 0e 6e 18 |%Y.....D>d....n.| -00000150 6e dc 43 87 4d bd 26 1e c1 0a 5f 8b a7 2d 8c cc |n.C.M.&..._..-..| -00000160 94 25 60 59 33 ef 38 93 a3 d1 63 5b 9b ae 10 2f |.%`Y3.8...c[.../| -00000170 63 af 27 32 35 b8 db 75 e8 e6 19 09 8e f3 b1 4d |c.'25..u.......M| -00000180 b6 8a 83 6c 88 41 3a d9 1e da ad b3 06 3b ba 41 |...l.A:......;.A| -00000190 f9 fd 23 46 a5 9e 8a 11 31 d9 f6 8c 56 32 eb a8 |..#F....1...V2..| -000001a0 7f c1 0a d1 78 c7 46 cb b5 f7 3f 7e 56 39 75 45 |....x.F...?~V9uE| -000001b0 5b fb 84 b4 16 28 14 4c 45 9d f4 8d 65 38 5d 93 |[....(.LE...e8].| -000001c0 53 ab 5e ae bc 9c 73 4b cb d2 85 cd d8 a7 00 67 |S.^...sK.......g| -000001d0 f8 0c c3 81 0b fc 5b f8 74 4f 6a 2f 3c 57 68 22 |......[.tOj/......,b..x.L| -00000450 99 cb 38 ad ef a4 00 42 51 04 3b b8 4b 06 89 ee |..8....BQ.;.K...| -00000460 33 48 3e c7 72 9c de f2 e4 23 5f 76 33 db cb 92 |3H>.r....#_v3...| -00000470 92 b0 90 ea 25 4f 05 68 b3 8e 59 9c 36 8b 1b b0 |....%O.h..Y.6...| -00000480 02 73 96 bf e6 fe 80 2c 32 26 ac 91 33 af cd 86 |.s.....,2&..3...| -00000490 57 cc de d3 a2 eb 9e 43 ea 5b d4 56 f0 1b 95 3b |W......C.[.V...;| -000004a0 a1 da 33 21 cb 0b 48 92 35 73 0c 33 01 c4 6d 79 |..3!..H.5s.3..my| -000004b0 7a bb 39 a1 32 3a 85 18 9f 91 a7 e1 42 0a |z.9.2:......B.| +000000a0 17 03 03 00 17 c0 07 64 56 b1 bb f8 bf 36 6b df |.......dV....6k.| +000000b0 e9 ee 72 cc 79 45 f5 8c b8 0c b3 5d 17 03 03 02 |..r.yE.....]....| +000000c0 6d 2e ab b5 84 4f d7 9e 4e 0d 6e a0 42 c1 f0 a6 |m....O..N.n.B...| +000000d0 62 a3 26 eb 9d 9a 42 a5 5d 1f 59 ad 37 a9 8a af |b.&...B.].Y.7...| +000000e0 0d 7b 8f 5a d1 d5 d8 bc 15 5b 0d 0e d2 a9 bb 14 |.{.Z.....[......| +000000f0 56 ed 30 4e 9b aa f9 5a 66 7d 4c 41 8e 6d 58 90 |V.0N...Zf}LA.mX.| +00000100 52 4a f2 78 72 59 34 aa 58 7e 0c 44 1e bc 84 d8 |RJ.xrY4.X~.D....| +00000110 50 17 bd aa 8c 4c d0 c5 e7 69 32 b8 c3 d6 e6 f9 |P....L...i2.....| +00000120 70 93 99 1c 75 1b 13 f2 85 e0 b5 07 1b d8 5a 31 |p...u.........Z1| +00000130 0a 1a 2e 97 86 ff 75 a1 db 45 b2 47 68 ed 88 d9 |......u..E.Gh...| +00000140 fe 31 c9 c0 5e 37 f2 62 37 f7 01 81 11 07 a7 0f |.1..^7.b7.......| +00000150 44 ec 17 3a 4a 38 b3 91 9f 77 6f f9 58 9e 9c 12 |D..:J8...wo.X...| +00000160 6e 54 4c de 43 58 46 a5 f6 c7 58 7e df 33 d7 91 |nTL.CXF...X~.3..| +00000170 e5 cb 9e 28 9d 7f a7 8a bd be 01 48 b7 b1 1e e2 |...(.......H....| +00000180 7a 80 aa f9 cd 3f 62 0d a0 a0 63 0c ca 4b 5f a8 |z....?b...c..K_.| +00000190 a9 5f 42 ac 44 57 67 b2 0f 5a b5 bb 59 a9 56 bd |._B.DWg..Z..Y.V.| +000001a0 28 3c fb 5e 43 33 61 43 7b 60 48 7d 27 67 6a 06 |(<.^C3aC{`H}'gj.| +000001b0 ac 0d db e4 d2 d4 b8 fa fb e8 32 f3 22 83 3a 63 |..........2.".:c| +000001c0 f6 73 02 62 e0 d5 8a d2 61 a5 bf e1 2d 10 59 93 |.s.b....a...-.Y.| +000001d0 55 60 be 32 ce 5c d5 5a f0 54 21 7d 8a 02 23 cf |U`.2.\.Z.T!}..#.| +000001e0 38 2b 2b 67 50 22 72 f7 f7 bf 20 c2 34 df ae 3a |8++gP"r... .4..:| +000001f0 44 b0 a6 2a 51 79 6f b1 7b ff d7 77 45 83 a9 fa |D..*Qyo.{..wE...| +00000200 bf 3c de 34 e8 6a 33 74 6c 24 0b 85 39 ea 7c 13 |.<.4.j3tl$..9.|.| +00000210 43 26 13 1b 61 56 85 0a 08 83 04 45 5f 5a 36 df |C&..aV.....E_Z6.| +00000220 17 c0 59 e9 92 d8 6b 78 66 1f 43 a0 99 f8 4b b1 |..Y...kxf.C...K.| +00000230 f0 8d 25 6f 0f 2e c7 f9 4d bb 79 74 b8 95 e6 b7 |..%o....M.yt....| +00000240 41 0c de 2a d3 7e fc 0f 18 87 2d 21 dd 8d 5f 20 |A..*.~....-!.._ | +00000250 4c 88 cb 63 f4 9c 07 64 14 02 0c 19 46 32 e5 1e |L..c...d....F2..| +00000260 85 84 4a 71 b8 a5 50 92 ca 72 fe f4 9c 69 05 d4 |..Jq..P..r...i..| +00000270 93 22 38 c1 09 e2 da 49 17 e8 e1 b3 f9 42 ee bf |."8....I.....B..| +00000280 ea 40 b2 00 af b9 a8 f9 97 8e ef de 41 de 01 87 |.@..........A...| +00000290 cc 13 23 64 8c a1 10 9a 91 38 9b cb fb 0b 04 66 |..#d.....8.....f| +000002a0 fb 4b e3 77 e7 da 7a 75 5c 66 20 7e dc 22 a9 e6 |.K.w..zu\f ~."..| +000002b0 6a 27 06 ed 3c fc 4c 30 ed f0 31 92 b2 eb a1 f3 |j'..<.L0..1.....| +000002c0 a4 fd 83 20 37 62 71 95 ff 7c 65 e8 88 aa e7 c7 |... 7bq..|e.....| +000002d0 3f 17 9c 94 6f 1a d9 c8 ac 00 8d ec 30 22 98 85 |?...o.......0"..| +000002e0 da cc 69 41 f4 3a 66 1b e6 4c 38 62 8d 37 dc a1 |..iA.:f..L8b.7..| +000002f0 08 cf 88 d4 26 7f 47 33 54 d8 aa d6 c5 02 fc 72 |....&.G3T......r| +00000300 ff 50 19 9f 4a 0e 8b c8 32 6d 8e 15 e4 f1 ed 2e |.P..J...2m......| +00000310 43 cb 9f 8c 7a 0e e1 a2 79 e2 f9 52 12 e4 2f a9 |C...z...y..R../.| +00000320 c1 c5 0b 1f c2 21 c5 2e 21 de 3e 76 29 db 17 03 |.....!..!.>v)...| +00000330 03 00 99 8a ee 54 88 93 d0 4b a0 31 18 ed 83 ff |.....T...K.1....| +00000340 2c 44 78 ab 88 ea 72 d2 2a 27 71 a9 a1 ba 26 a5 |,Dx...r.*'q...&.| +00000350 9a 9b 64 92 e8 c9 f8 02 47 b9 9f 53 95 a8 ad 5b |..d.....G..S...[| +00000360 bd 81 17 87 69 0c 77 c1 0e d7 cb 5b 9f 2d 36 86 |....i.w....[.-6.| +00000370 f5 fc 6d ba d8 f5 63 dd e4 f5 0a 61 8d b2 a9 bb |..m...c....a....| +00000380 a5 a5 d6 41 d4 aa db 46 79 56 02 51 f4 ac d3 57 |...A...FyV.Q...W| +00000390 57 b4 53 71 9f fe ea a6 76 f3 0f ca 39 93 f3 34 |W.Sq....v...9..4| +000003a0 c6 96 96 09 8e 12 04 cc 1e 82 9f 78 6b 1c a2 fc |...........xk...| +000003b0 0c 9d c6 00 3c 33 3a 92 c5 ce 96 15 50 1a 75 6d |....<3:.....P.um| +000003c0 85 ec b6 64 12 2b eb 3a 52 8f 6d 35 17 03 03 00 |...d.+.:R.m5....| +000003d0 35 7f 2b 30 fa e0 92 25 a2 1b 11 f8 cd 04 0d 57 |5.+0...%.......W| +000003e0 01 42 cf e9 0c 92 7f d1 fd fa 26 61 0d 85 d7 d5 |.B........&a....| +000003f0 3c fd cf 73 98 dc 88 a2 76 63 59 82 45 2d e3 bc |<..s....vcY.E-..| +00000400 a2 c0 0b 83 41 75 17 03 03 00 93 f3 17 09 b2 e8 |....Au..........| +00000410 53 11 9b 3e 3a 10 a0 e6 58 04 81 82 cb eb a5 19 |S..>:...X.......| +00000420 0f a3 25 e2 eb ab 7c 07 2b e6 22 19 30 aa fc a6 |..%...|.+.".0...| +00000430 bd c4 7d 69 33 38 2b 58 55 5b a7 27 29 86 af d5 |..}i38+XU[.')...| +00000440 f9 5a b4 85 ad a0 73 ab f7 61 3f 2e 66 53 f5 8f |.Z....s..a?.fS..| +00000450 c7 09 4b 01 99 d0 68 93 32 d1 2e 8f 89 e5 e1 ea |..K...h.2.......| +00000460 ba f2 fb 07 ee 58 7c 28 ff 59 1d d7 f7 b3 e2 56 |.....X|(.Y.....V| +00000470 98 56 cd 9d d1 4f 26 7e 77 0d a0 c1 92 c5 a0 83 |.V...O&~w.......| +00000480 c9 7c d8 7d a8 91 d3 ae 71 41 1d 06 33 68 b8 52 |.|.}....qA..3h.R| +00000490 ad 84 a7 21 80 8f e5 c6 37 11 da 6c 5a 3a |...!....7..lZ:| >>> Flow 5 (client to server) -00000000 17 03 03 00 45 b7 e2 1a d9 6a aa c1 54 e3 9a 42 |....E....j..T..B| -00000010 11 cd 13 c2 dc 5a b0 fa e3 62 09 a1 4b 9a a1 b3 |.....Z...b..K...| -00000020 84 7b 63 29 69 47 5c bf ca c6 36 2f ae e0 2f 6e |.{c)iG\...6/../n| -00000030 1b 42 c4 c9 65 17 e8 bd c4 97 5b e4 5f 27 86 d2 |.B..e.....[._'..| -00000040 1f 97 1f 68 9a 1f ee 09 04 82 |...h......| +00000000 17 03 03 00 35 28 34 b9 16 07 9a c1 82 ad 9f b7 |....5(4.........| +00000010 78 fa 1a d0 1f 57 98 95 37 86 cf 1d 67 19 47 48 |x....W..7...g.GH| +00000020 e9 ab fe 0c ff 26 c6 78 88 1a ad 75 48 63 4b 6e |.....&.x...uHcKn| +00000030 72 4a 44 4f 27 b6 9d 56 b6 43 |rJDO'..V.C| >>> Flow 6 (server to client) -00000000 17 03 03 00 1e ed fb 39 62 34 b9 5d a3 db 30 fe |.......9b4.]..0.| -00000010 ed 5e 92 77 44 7e fb 77 84 5e 54 6b 11 7c 27 99 |.^.wD~.w.^Tk.|'.| -00000020 80 66 a5 17 03 03 00 13 9b 78 92 3b 84 3d cb 69 |.f.......x.;.=.i| -00000030 86 2b d1 db cc 91 d3 00 55 43 2f |.+......UC/| +00000000 17 03 03 00 1e d9 1f 35 86 22 7e 10 f1 8d e5 82 |.......5."~.....| +00000010 f2 f6 88 81 a3 66 da 6a 1e 2f 94 94 16 02 2a 52 |.....f.j./....*R| +00000020 69 8b bb 17 03 03 00 13 3c 87 88 8c c0 78 64 18 |i.......<....xd.| +00000030 9a 9e 07 fd ac d7 2d 5d ab bf a8 |......-]...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-IssueTicket b/libgo/go/crypto/tls/testdata/Server-TLSv13-IssueTicket index 1a8b3846997..fa1f80181ae 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-IssueTicket +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-IssueTicket @@ -1,103 +1,99 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e4 01 00 00 e0 03 03 26 46 4d 2d 7d |...........&FM-}| -00000010 5c dc ef fb 2b 8b f7 15 4b ba 8b 1a 26 da f6 9b |\...+...K...&...| -00000020 e6 3c c6 8c a0 f9 6c 60 f6 11 81 20 53 f8 00 fb |.<....l`... S...| -00000030 8b be ff 98 74 c9 d9 3d aa 40 4d 0e 05 96 f9 30 |....t..=.@M....0| -00000040 d6 f5 7b f1 bc 31 18 30 5f 24 03 a8 00 08 13 02 |..{..1.0_$......| -00000050 13 03 13 01 00 ff 01 00 00 8f 00 00 00 0e 00 0c |................| -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 23 00 00 00 16 00 00 00 17 00 00 |.....#..........| -00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................| -000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................| -000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....| -000000c0 33 00 26 00 24 00 1d 00 20 b6 ad 52 4d 37 b1 eb |3.&.$... ..RM7..| -000000d0 1e 57 2b a8 5d e7 43 b9 a0 98 47 8b ff 40 a9 14 |.W+.].C...G..@..| -000000e0 9e 23 26 c7 47 a7 cb f6 47 |.#&.G...G| +00000000 16 03 01 00 ce 01 00 00 ca 03 03 bb e2 a4 a5 7e |...............~| +00000010 63 65 5c a5 7f 3f 13 a1 9d 5f 53 3c d2 b1 84 bd |ce\..?..._S<....| +00000020 51 0c 9a 14 e8 8a 5a 53 b8 27 88 20 e7 04 4d dc |Q.....ZS.'. ..M.| +00000030 76 f3 7f bd 00 ce 46 d2 a6 58 26 99 02 91 88 bf |v.....F..X&.....| +00000040 b5 6b 56 2b b6 bc 51 b2 e4 cd 82 8d 00 04 13 01 |.kV+..Q.........| +00000050 00 ff 01 00 00 7d 00 0b 00 04 03 00 01 02 00 0a |.....}..........| +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 00 0d 00 1e 00 1c |................| +00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................| +00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..| +000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.| +000000b0 1d 00 20 b2 99 9c bb d1 4c c7 61 5f aa bf 2f 06 |.. .....L.a_../.| +000000c0 a3 50 e7 49 7d 11 ae 68 9b b0 be be 82 6d 27 29 |.P.I}..h.....m')| +000000d0 89 4c 4a |.LJ| >>> 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 53 f8 00 fb |........... S...| -00000030 8b be ff 98 74 c9 d9 3d aa 40 4d 0e 05 96 f9 30 |....t..=.@M....0| -00000040 d6 f5 7b f1 bc 31 18 30 5f 24 03 a8 13 02 00 00 |..{..1.0_$......| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 e7 04 4d dc |........... ..M.| +00000030 76 f3 7f bd 00 ce 46 d2 a6 58 26 99 02 91 88 bf |v.....F..X&.....| +00000040 b5 6b 56 2b b6 bc 51 b2 e4 cd 82 8d 13 01 00 00 |.kV+..Q.........| 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 b9 4a b7 2a b5 48 |...........J.*.H| -00000090 bc ba 18 3e 1a 99 bd fa 0d fc 2a 5d 52 93 b5 97 |...>......*]R...| -000000a0 5c 17 03 03 02 6d 30 8f 19 00 1c fa 90 a7 6c 08 |\....m0.......l.| -000000b0 6f 5a e8 d8 e0 3e 81 30 f1 11 85 7e 35 47 b3 d0 |oZ...>.0...~5G..| -000000c0 48 95 ce af e6 2f fc 22 0a 5f 56 bd 1c 7d 8c 48 |H..../."._V..}.H| -000000d0 f3 ad b7 5b 2e 4b d8 d1 16 46 7a ba c3 71 02 3c |...[.K...Fz..q.<| -000000e0 54 75 b8 92 02 b1 b9 cc 15 c4 fa d1 2d ba 0d 9f |Tu..........-...| -000000f0 65 a1 78 0d 8f d6 1c be fa 42 1f d7 48 1a 8e 11 |e.x......B..H...| -00000100 64 4c 12 ef bd 65 9d b4 31 18 4f 2a 77 c4 1f 1b |dL...e..1.O*w...| -00000110 90 90 37 ea 59 aa 05 bf 45 04 fb e8 a9 3f f9 11 |..7.Y...E....?..| -00000120 f9 25 95 fc d4 8e 5c 84 19 f3 4c e4 05 c3 db 8c |.%....\...L.....| -00000130 07 f9 b3 b0 6d ce d3 14 aa 78 17 f9 2f 14 1b bc |....m....x../...| -00000140 4b 23 29 f1 2e 7c 3b 71 9b cf 0b d5 02 48 5e ce |K#)..|;q.....H^.| -00000150 9c 43 dd 29 17 42 0b 9d 0e a7 a7 93 e1 37 cc 97 |.C.).B.......7..| -00000160 df 0f 2d d3 f7 01 08 34 5f bd ad 12 12 6f 87 56 |..-....4_....o.V| -00000170 4e 99 16 f6 6e 61 5c f0 0e 30 0b d5 38 37 70 97 |N...na\..0..87p.| -00000180 ed e1 79 74 00 cc 55 be a9 32 7d 72 50 27 42 c9 |..yt..U..2}rP'B.| -00000190 99 64 ea bd 3e c8 4f b0 cc 31 ef 10 57 9f c1 02 |.d..>.O..1..W...| -000001a0 ca db f6 d6 53 94 d2 83 57 71 e9 06 7a dd 46 3b |....S...Wq..z.F;| -000001b0 b1 2c f8 87 1c 8b 8a 04 05 2f d0 32 54 9a 80 33 |.,......./.2T..3| -000001c0 b2 95 e5 62 71 e9 1a 3b ea 64 ee 81 29 c4 ea 53 |...bq..;.d..)..S| -000001d0 de 6b 27 b1 04 48 27 ba 7f 28 aa 9e 15 82 49 a9 |.k'..H'..(....I.| -000001e0 43 3d d3 33 82 50 a9 4e 38 ed 8d f8 e8 0e 11 ab |C=.3.P.N8.......| -000001f0 8b 6e 63 e9 c1 cf ee 45 4f a0 62 e7 2e 00 b8 61 |.nc....EO.b....a| -00000200 2a 29 5e 04 e2 81 11 b3 64 f3 b5 b0 ec ae 63 6c |*)^.....d.....cl| -00000210 27 56 ac f2 09 d3 a4 c8 18 4a 55 c8 ff fd 8b 42 |'V.......JU....B| -00000220 63 00 3a c9 25 40 b7 8d 17 f3 95 76 7b 01 cf bc |c.:.%@.....v{...| -00000230 9b a7 4c 03 4a 7d 3c 54 16 8f 84 ca 2f 1a f5 12 |..L.J}.| -00000330 f1 1e 11 c7 72 f5 65 b4 03 38 f2 48 16 a9 20 31 |....r.e..8.H.. 1| -00000340 c2 52 4c 33 92 70 45 91 19 f4 5c 08 77 49 af 25 |.RL3.pE...\.wI.%| -00000350 8e b5 bd 3f e3 93 dc e6 26 b0 8a 30 69 f1 86 17 |...?....&..0i...| -00000360 72 31 66 87 2f d4 42 70 4c e0 58 61 6e b2 38 0b |r1f./.BpL.Xan.8.| -00000370 13 ad 32 83 14 81 d4 af dd 9f 17 09 af 3b 64 78 |..2..........;dx| -00000380 c8 63 da 05 70 47 54 f9 c6 f5 f8 e6 97 e1 d0 87 |.c..pGT.........| -00000390 aa 5a e7 5b d3 a3 b3 ce be 56 30 e7 4d ad 43 bd |.Z.[.....V0.M.C.| -000003a0 5e 88 9a ef 34 78 06 eb 6f 8f 04 39 47 6a c2 3d |^...4x..o..9Gj.=| -000003b0 ba 17 03 03 00 45 89 37 db 55 b2 9e 6e 31 a0 9b |.....E.7.U..n1..| -000003c0 97 51 27 13 b0 7e 2e 85 4a 9b 72 b0 fe c5 e4 12 |.Q'..~..J.r.....| -000003d0 fd ea 29 d5 bb ae a2 24 e2 0d b4 cd 28 92 5c 88 |..)....$....(.\.| -000003e0 98 b4 e4 8e a8 46 c6 a0 0e c0 73 ba f7 62 3a 43 |.....F....s..b:C| -000003f0 1a c7 d3 4b 5b 47 7b 44 8b bb 7b 17 03 03 00 a3 |...K[G{D..{.....| -00000400 f1 5f 26 2b 1c 99 6d 1d 55 bc a7 2f ae c8 3a ed |._&+..m.U../..:.| -00000410 5a 16 3c 83 e8 d4 18 7e 84 fa ba 21 0f 30 b0 05 |Z.<....~...!.0..| -00000420 ec 45 92 53 80 7a 78 d4 9e e0 02 e9 11 74 a6 e2 |.E.S.zx......t..| -00000430 87 7e 43 26 c0 18 46 6b 28 e5 f4 92 89 5c 0d b5 |.~C&..Fk(....\..| -00000440 8d 90 55 4f 3b 0a f4 ba 1b fb 60 54 46 23 03 28 |..UO;.....`TF#.(| -00000450 6e c3 3b 4d 69 62 65 d5 4e 95 46 c9 f2 8d ae f9 |n.;Mibe.N.F.....| -00000460 53 a6 65 da ca 1e b7 f7 80 a8 97 97 ca 38 14 a5 |S.e..........8..| -00000470 34 81 e2 68 12 fb 45 90 c2 f9 c9 70 fe 28 b8 b5 |4..h..E....p.(..| -00000480 6c 1d 2c d4 07 69 1d eb 1f 4b df ba ca 5e e0 65 |l.,..i...K...^.e| -00000490 ad ee be 41 02 78 23 19 b9 ea 1d 65 20 43 0e 3d |...A.x#....e C.=| -000004a0 11 03 b3 |...| +00000080 03 03 00 01 01 17 03 03 00 17 c6 67 93 be 69 04 |...........g..i.| +00000090 58 4f 1d 93 b6 5c 1c 10 8a 91 d0 c0 db 0b d1 0a |XO...\..........| +000000a0 d1 17 03 03 02 6d da d6 28 74 c7 60 d6 02 3e 28 |.....m..(t.`..>(| +000000b0 29 17 50 b9 01 4b 9b 93 07 9d 09 f0 17 05 e0 88 |).P..K..........| +000000c0 53 ec c3 28 f7 a6 4e 9b 80 a3 fd 20 db 97 51 6a |S..(..N.... ..Qj| +000000d0 b1 7a 6d 93 26 61 c8 9c 6d 37 65 94 b4 74 a0 60 |.zm.&a..m7e..t.`| +000000e0 b1 a1 38 4c eb 5e a9 c4 bd d4 29 ee e9 e3 ab 56 |..8L.^....)....V| +000000f0 68 67 57 da b3 3d 85 bd 26 67 e1 52 83 a6 69 14 |hgW..=..&g.R..i.| +00000100 3b 30 31 c7 71 83 fa 62 13 ea a3 a5 de 4b 32 3f |;01.q..b.....K2?| +00000110 c6 48 0b 96 cd 4b da 96 6d e2 31 88 ca 96 5f 63 |.H...K..m.1..._c| +00000120 cb 39 37 d8 fa 8f 1f b9 e2 c5 6b ae 60 05 5b ed |.97.......k.`.[.| +00000130 e0 5d 83 fa 2b 22 f4 e8 33 27 48 e7 c4 3d 54 22 |.]..+"..3'H..=T"| +00000140 5a 60 a9 7a 0d 9b 42 e2 50 28 0e 6c 13 16 a1 51 |Z`.z..B.P(.l...Q| +00000150 60 81 8f 80 e2 1b 53 24 62 78 b7 0a 4a 9b 2f a7 |`.....S$bx..J./.| +00000160 97 b3 ba e5 34 0d 76 a6 0e ea ec 91 f0 9c a9 6d |....4.v........m| +00000170 57 47 ef a3 c4 7a 62 a8 1f c0 1a d7 ea 31 90 20 |WG...zb......1. | +00000180 76 13 ae f1 24 9d 60 9f 30 9f 2b 2a 2f 0a 39 6c |v...$.`.0.+*/.9l| +00000190 7a 47 fe 11 1c 78 42 a1 1c ed c3 cd d2 6a cd 4f |zG...xB......j.O| +000001a0 66 1b 51 d4 43 4e 45 23 15 48 e4 84 3e 89 a3 55 |f.Q.CNE#.H..>..U| +000001b0 7e b0 a6 c2 1c cd eb cf 88 6b e7 d2 07 25 ef 37 |~........k...%.7| +000001c0 e1 8a a5 b9 03 7e 70 73 9c 23 1a 62 07 56 db ed |.....~ps.#.b.V..| +000001d0 93 e3 8a 91 8b 90 74 14 14 cc ff 9e ea e5 45 dd |......t.......E.| +000001e0 a6 2d dc e6 cb 8c 59 33 91 da e6 5c b4 73 4f 36 |.-....Y3...\.sO6| +000001f0 f1 3c d9 6e ba 2c c4 51 de 4f 8a 69 62 c4 db b1 |.<.n.,.Q.O.ib...| +00000200 9e 67 7a 5f 01 7b b7 b2 55 b1 14 c0 46 d1 43 16 |.gz_.{..U...F.C.| +00000210 a0 70 84 7e b8 a3 04 ce e3 e0 0e 5e 5f 3f 95 7a |.p.~.......^_?.z| +00000220 ef 79 8d 50 84 cd 02 f1 e0 e5 f9 26 cf 7a f9 da |.y.P.......&.z..| +00000230 a3 7d 22 31 4d 61 82 f6 ff fd 69 23 07 53 07 df |.}"1Ma....i#.S..| +00000240 5a eb 50 86 28 44 24 06 9b 21 ef ef 78 bc 67 13 |Z.P.(D$..!..x.g.| +00000250 c5 27 d8 18 db c7 fa d5 a6 0c 40 09 e3 e5 17 0c |.'........@.....| +00000260 61 ae bc 48 98 ab 7b 57 82 f7 87 a5 4b 96 25 77 |a..H..{W....K.%w| +00000270 e4 59 53 d1 d3 7b 55 08 e0 1a 5d 9b 0f 2e 6f cd |.YS..{U...]...o.| +00000280 96 9d 19 09 07 84 08 c1 cf bd 99 af 80 52 c0 f7 |.............R..| +00000290 0c 50 85 14 7c fd cb 61 01 05 ee 92 60 bb ac 4c |.P..|..a....`..L| +000002a0 b4 37 48 dc b1 34 9d 26 3a fd dc ae 21 2f d3 51 |.7H..4.&:...!/.Q| +000002b0 84 c3 0e 8f e1 b4 fb 0b 2e 3b 51 a9 e8 c2 d9 d9 |.........;Q.....| +000002c0 6b a5 af 90 30 97 a2 32 9a a3 9d 5d b3 75 c6 48 |k...0..2...].u.H| +000002d0 4b ee a3 23 85 98 a5 b5 00 fd c5 3a 27 65 9e d0 |K..#.......:'e..| +000002e0 19 a8 5a 8c 8b eb 49 c6 58 16 9a 88 67 54 82 a9 |..Z...I.X...gT..| +000002f0 29 0a 98 82 e4 f8 f0 c9 17 a6 81 91 1b c1 2a b7 |).............*.| +00000300 de c3 8b 2d a6 55 1f 61 89 90 84 15 c8 33 6e cb |...-.U.a.....3n.| +00000310 5c f4 e2 17 03 03 00 99 49 e0 38 43 34 61 b9 37 |\.......I.8C4a.7| +00000320 2c 3e d5 c7 8c d7 9b a6 6c 8e ef a6 28 13 3c 79 |,>......l...(..p[Nk..R...h.| +00000340 a0 07 ac c1 17 6e d1 11 76 1d d7 1e e2 26 3e 76 |.....n..v....&>v| +00000350 2b f9 a4 55 67 0b 9c cd db ab 71 1a 84 33 74 eb |+..Ug.....q..3t.| +00000360 b1 4b 26 d8 e8 1c 84 2b 62 c7 70 27 16 fb 16 ae |.K&....+b.p'....| +00000370 9d 72 3a 42 c1 cb cd c8 d0 dd 9c f0 51 2e 33 c1 |.r:B........Q.3.| +00000380 46 35 56 ad 3b ea be 6e 14 4d 05 d1 6d 85 93 86 |F5V.;..n.M..m...| +00000390 cc 6a 1c bf 03 cf 8f 92 c9 18 74 e0 66 0a b6 9a |.j........t.f...| +000003a0 38 ac 1a 73 f4 e0 70 ec 93 61 67 9f b8 12 6f 1f |8..s..p..ag...o.| +000003b0 17 17 03 03 00 35 59 6b 86 a8 cc 89 c6 fa 4f 95 |.....5Yk......O.| +000003c0 25 b6 90 08 ac bf 9f d5 c9 3c 6c e5 cd 0d 14 00 |%........>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 88 0d 45 f0 61 |..........E..E.a| -00000010 a3 d0 7b 33 9e 17 c5 c3 6f 8f f6 67 b8 03 65 5f |..{3....o..g..e_| -00000020 bf 94 e9 1d 58 eb 4d 12 68 8a 96 42 6f 08 08 b8 |....X.M.h..Bo...| -00000030 be ce 2c f0 c4 00 d4 22 e6 94 09 05 f2 a7 77 0f |..,...."......w.| -00000040 48 e9 5c 6c e9 b2 9a d6 ff 48 2b 08 9a ea 23 1a |H.\l.....H+...#.| +00000000 14 03 03 00 01 01 17 03 03 00 35 74 1e 4a 56 2c |..........5t.JV,| +00000010 fc 14 0b 66 ab 2f 56 5b fd 33 fe c2 a4 df 0b 62 |...f./V[.3.....b| +00000020 63 11 40 67 d2 11 1b 53 c5 b9 1e 0e 20 83 85 b0 |c.@g...S.... ...| +00000030 3a 81 79 bc a7 9f 49 ab 22 bd 10 8d 3e c9 95 79 |:.y...I."...>..y| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 2a f5 09 7f 7b 5f 8a ff d3 cc 16 |.....*...{_.....| -00000010 d1 d3 38 76 5c f7 e3 ee f3 72 b5 92 8e f9 bf 37 |..8v\....r.....7| -00000020 7e dc 61 17 03 03 00 13 66 ba 9e ff 3a 9f 25 74 |~.a.....f...:.%t| -00000030 44 35 70 f4 cf ae dc b0 3c 28 44 |D5p.....<(D| +00000000 17 03 03 00 1e a4 83 3b 61 a1 00 d5 56 84 4c 83 |.......;a...V.L.| +00000010 0a 8c 86 13 0c e7 95 71 aa 48 e0 d2 5f 11 5f 45 |.......q.H.._._E| +00000020 41 7a 10 17 03 03 00 13 ca 8b f5 38 e5 5f e0 8a |Az.........8._..| +00000030 e3 08 ba 7d 06 f6 b3 b4 6f e9 2b |...}....o.+| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable b/libgo/go/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable index ed3f55ad372..a939822efcb 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable @@ -1,103 +1,99 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 e4 01 00 00 e0 03 03 4a ec fd a5 c5 |...........J....| -00000010 ef 77 88 18 25 40 50 c8 24 60 45 85 e6 3e 55 86 |.w..%@P.$`E..>U.| -00000020 d1 ea 0e 5f 0b d1 66 7a 1c 90 ad 20 a3 63 23 52 |..._..fz... .c#R| -00000030 d8 c8 f6 79 20 04 8d 07 eb 2f 78 a3 1a 0d 58 af |...y ..../x...X.| -00000040 70 3c ef 4b 90 43 42 67 57 39 bf fa 00 08 13 02 |p<.K.CBgW9......| -00000050 13 03 13 01 00 ff 01 00 00 8f 00 00 00 0e 00 0c |................| -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 23 00 00 00 16 00 00 00 17 00 00 |.....#..........| -00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................| -000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................| -000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....| -000000c0 33 00 26 00 24 00 1d 00 20 23 61 a3 8f f6 41 bc |3.&.$... #a...A.| -000000d0 08 52 ef 97 01 0e ba 95 f4 33 b6 8d 15 d0 ff ed |.R.......3......| -000000e0 a4 d1 84 23 3b f3 ef 3a 2d |...#;..:-| +00000000 16 03 01 00 ce 01 00 00 ca 03 03 cd 51 e4 0b ee |............Q...| +00000010 9c 83 0f a1 bd 1a c8 b4 94 17 5e 17 fb 63 43 31 |..........^..cC1| +00000020 89 86 03 fa 82 d4 bb c5 ba 9d 60 20 a1 0b c7 9c |..........` ....| +00000030 b0 3f d9 7a 52 bd c0 3f cd c5 21 54 40 a5 60 73 |.?.zR..?..!T@.`s| +00000040 fd ff 07 99 75 59 0d f3 bd 57 f6 81 00 04 13 01 |....uY...W......| +00000050 00 ff 01 00 00 7d 00 0b 00 04 03 00 01 02 00 0a |.....}..........| +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 00 0d 00 1e 00 1c |................| +00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................| +00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..| +000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.| +000000b0 1d 00 20 04 16 08 0b 67 76 58 60 4a 32 c2 ea 1b |.. ....gvX`J2...| +000000c0 4a 54 fa 55 9b 39 d8 80 c4 eb 42 cc 1a 84 fe d7 |JT.U.9....B.....| +000000d0 0a 0d 43 |..C| >>> 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 a3 63 23 52 |........... .c#R| -00000030 d8 c8 f6 79 20 04 8d 07 eb 2f 78 a3 1a 0d 58 af |...y ..../x...X.| -00000040 70 3c ef 4b 90 43 42 67 57 39 bf fa 13 02 00 00 |p<.K.CBgW9......| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 a1 0b c7 9c |........... ....| +00000030 b0 3f d9 7a 52 bd c0 3f cd c5 21 54 40 a5 60 73 |.?.zR..?..!T@.`s| +00000040 fd ff 07 99 75 59 0d f3 bd 57 f6 81 13 01 00 00 |....uY...W......| 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 80 72 6f c7 2d 22 |...........ro.-"| -00000090 40 51 35 22 9b 97 51 33 60 fa c1 2c d3 0f 25 6a |@Q5"..Q3`..,..%j| -000000a0 4d 17 03 03 02 6d f3 3a 89 a6 9a 1f 2b f4 1a 48 |M....m.:....+..H| -000000b0 e9 bd ef da 9d 7b f0 6c 61 ca 21 82 1b 30 6f 60 |.....{.la.!..0o`| -000000c0 01 72 24 4f ea 66 ef 3b 35 b7 ae d9 45 c9 2a 00 |.r$O.f.;5...E.*.| -000000d0 99 da 50 ae ac 8f 77 a4 e7 b4 de f6 c8 dd b8 f3 |..P...w.........| -000000e0 bc cb 7c c8 cf 2f 63 61 66 16 7f 7f 61 2c 52 c9 |..|../caf...a,R.| -000000f0 8f af 0d e2 55 d7 a4 ed 7e 12 b0 0d ec e9 a4 47 |....U...~......G| -00000100 03 e6 fa d1 6b 2f e3 22 a8 f5 c5 e6 e6 78 63 a1 |....k/.".....xc.| -00000110 b7 00 98 04 e8 fd ff 67 62 dc 89 f4 0d 97 93 4e |.......gb......N| -00000120 85 ec e0 68 f0 04 94 02 49 95 f9 08 99 30 37 d8 |...h....I....07.| -00000130 ad 31 52 1d 1d 23 09 9e 7a 97 45 d3 95 2f 03 2d |.1R..#..z.E../.-| -00000140 64 f7 5b cb 53 f5 89 ef 45 90 72 38 33 aa 62 1e |d.[.S...E.r83.b.| -00000150 b8 3e 00 b2 7f 89 0b 3a e6 17 93 ac 19 7d 09 bd |.>.....:.....}..| -00000160 ca ca 83 87 33 f9 f0 63 f3 4e 7b 47 56 0d cb b5 |....3..c.N{GV...| -00000170 90 81 88 cd 02 78 bf 96 64 c0 ba 58 b5 06 18 04 |.....x..d..X....| -00000180 d9 14 8b 92 74 81 76 b3 23 d9 ad 4c 8b 73 61 36 |....t.v.#..L.sa6| -00000190 64 d9 b6 2e 98 7e 7f d4 14 6e 4c a4 b4 71 35 5b |d....~...nL..q5[| -000001a0 4d e7 10 a8 b3 bb 40 5d 9f de 67 bb ae 0c 97 8b |M.....@]..g.....| -000001b0 25 cf cb aa 13 44 9f cb ff 2e 1c 54 ca de cb 13 |%....D.....T....| -000001c0 f9 c7 0e 49 9d d0 b3 d5 0e 29 3c 50 b9 2b 56 1f |...I.....).1{........| -00000430 06 d6 19 09 44 c2 8f 7c ef bd ea 06 a6 8f 38 42 |....D..|......8B| -00000440 1b a1 be 12 1f 72 38 49 96 e4 74 2f 42 19 2c 55 |.....r8I..t/B.,U| -00000450 16 45 a9 e0 a8 76 6d 36 68 84 fd 0e 40 44 df 93 |.E...vm6h...@D..| -00000460 ae 12 79 78 4c ec 72 16 fe 54 c0 14 ac 47 ed 88 |..yxL.r..T...G..| -00000470 78 98 c8 cb ca 49 de fd 12 e1 96 d0 c7 89 ee 89 |x....I..........| -00000480 df d5 71 98 8a 42 7e 3e 24 5a 64 44 19 96 cc e4 |..q..B~>$ZdD....| -00000490 9c f2 8e 52 8b 1d 39 15 af c7 cd 54 d9 84 01 ef |...R..9....T....| -000004a0 fc ac 54 |..T| +00000080 03 03 00 01 01 17 03 03 00 17 ec 4d 41 82 de 4f |...........MA..O| +00000090 c6 cf 1e 56 06 65 0e a4 e7 66 34 1d 89 59 b3 c2 |...V.e...f4..Y..| +000000a0 0a 17 03 03 02 6d 00 e1 17 f1 b3 5e a7 14 b3 f8 |.....m.....^....| +000000b0 3a ab 85 d4 80 75 69 01 6c 91 3f 79 ab 8f 51 e0 |:....ui.l.?y..Q.| +000000c0 f6 a5 65 ab 7e 72 e5 83 99 b2 cb cd f9 5f 27 db |..e.~r......._'.| +000000d0 90 70 9c c1 e5 6d 80 3e 59 7c 4d fa f1 23 8a a7 |.p...m.>Y|M..#..| +000000e0 f4 81 22 32 5b e2 4e d0 eb ab bd 96 05 42 05 5c |.."2[.N......B.\| +000000f0 20 5c 8a 3e ca fd b8 aa dd f2 c4 3e dc 7e a5 ab | \.>.......>.~..| +00000100 95 a4 20 03 0e 41 9b 14 55 91 1b 9c 3b 17 bc 2a |.. ..A..U...;..*| +00000110 60 c0 ee b1 78 e9 37 c4 65 ef 8c 29 ec d9 10 81 |`...x.7.e..)....| +00000120 a0 1d c9 ac cf e5 36 90 88 d3 70 6d 59 66 61 a8 |......6...pmYfa.| +00000130 18 79 ad d8 c7 3e 1f a5 db dc b5 21 83 b0 ae 16 |.y...>.....!....| +00000140 ce 8e 98 d4 8e 28 c1 d3 d2 ef 51 35 45 41 a7 b4 |.....(....Q5EA..| +00000150 e1 15 bb 32 10 aa b1 27 be 53 5e 96 ef 0b bd 2f |...2...'.S^..../| +00000160 81 66 18 f4 8b 9a cc be 67 c1 32 e3 c0 ea e5 c0 |.f......g.2.....| +00000170 76 2c 36 7f 91 11 13 c1 a4 04 7e 8e 7b 60 a5 3d |v,6.......~.{`.=| +00000180 fa 3c d8 68 9a 7e 4b 23 3d 18 1b a3 34 a9 81 a4 |.<.h.~K#=...4...| +00000190 00 09 cd 56 eb f2 29 9f 17 8d 48 4d 21 a2 4e ec |...V..)...HM!.N.| +000001a0 f0 a0 8d b1 ed d6 c7 01 d0 8e 2f 25 65 9f ac eb |........../%e...| +000001b0 44 09 f2 75 db 37 a3 94 cb 70 29 59 37 97 71 63 |D..u.7...p)Y7.qc| +000001c0 9b fa 0f 0f 33 75 0a 60 4f 78 97 9e 6a 2c 4b df |....3u.`Ox..j,K.| +000001d0 54 cc c0 ac 57 4c f3 3a e3 79 01 b9 c3 8c 37 d2 |T...WL.:.y....7.| +000001e0 8f d9 e7 cd 33 5a 0c bb 43 7e 39 5f 63 9f a5 11 |....3Z..C~9_c...| +000001f0 f5 6e e0 95 1f 09 03 56 0f ec b9 7d 08 31 c5 57 |.n.....V...}.1.W| +00000200 fa a6 57 15 6c 6b 91 d4 9f 5d c2 40 8b 3d 3a 57 |..W.lk...].@.=:W| +00000210 c2 64 55 bd 88 bb 5e 24 7f fe 79 0c 88 f3 a7 1c |.dU...^$..y.....| +00000220 f8 20 6f ba d6 ec fc b2 04 2a d7 b7 17 5e 4c 2e |. o......*...^L.| +00000230 24 cd 1b 8a 04 fe 21 e0 5b 90 ec f4 30 df bf fe |$.....!.[...0...| +00000240 a8 f9 2b 40 c1 23 15 f2 44 87 9a aa 30 80 70 27 |..+@.#..D...0.p'| +00000250 80 6f 90 08 b5 47 2e 01 ea 77 3a ba a4 4b 77 8a |.o...G...w:..Kw.| +00000260 12 b4 4e e1 a6 04 8a 01 31 60 27 35 bf 76 de 09 |..N.....1`'5.v..| +00000270 aa 8a c4 c4 21 31 9f eb c2 92 05 be a1 b5 24 eb |....!1........$.| +00000280 71 24 55 f9 aa 5c 62 59 49 bf 42 4c 69 01 4f f7 |q$U..\bYI.BLi.O.| +00000290 b6 27 14 d4 cc 40 80 13 9b 8b 30 55 1f 32 c1 ee |.'...@....0U.2..| +000002a0 51 bd 71 f7 63 3f c2 00 90 60 dc 13 0f 62 c3 06 |Q.q.c?...`...b..| +000002b0 80 f6 4f cc 44 71 d7 5c 2e 18 82 45 ca 80 b7 0e |..O.Dq.\...E....| +000002c0 0c 6f 75 1b 23 cb 86 c1 2d 1e 1b 02 2a 15 fa c7 |.ou.#...-...*...| +000002d0 b2 af 80 5c 48 c2 b7 12 59 a3 e4 3c ed df 26 d0 |...\H...Y..<..&.| +000002e0 85 9b 5a 2d 7b 66 e6 c4 b3 fe cd 4d 72 4d fb da |..Z-{f.....MrM..| +000002f0 1c 0d 5c fb 2f 8a e3 70 98 ee 95 9c 12 1a fa c7 |..\./..p........| +00000300 94 7a 8e ca 4d a4 bb 2f 70 3b 67 95 fb 23 fb 8f |.z..M../p;g..#..| +00000310 8c 77 4c 17 03 03 00 99 8a 72 14 c7 82 18 d7 ed |.wL......r......| +00000320 c7 5d 32 df 44 91 6b 40 3e 0b eb a1 74 da d9 3a |.]2.D.k@>...t..:| +00000330 3c 7a 2e 7a 73 3b 63 72 33 c4 c5 27 29 33 f5 30 |..~b`| +00000480 5d 0a 82 |]..| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 a6 fe 34 ee 91 |..........E..4..| -00000010 b0 c5 35 55 cf 70 3f d4 5d 06 76 28 c3 b5 a9 26 |..5U.p?.].v(...&| -00000020 38 18 ed bb bb bb be e7 4b 6d 61 3e 8f 65 e9 e3 |8.......Kma>.e..| -00000030 b6 4f 5d 50 46 2c 81 a8 fd 47 aa c8 c4 e8 f9 a4 |.O]PF,...G......| -00000040 e7 c7 f0 c5 fa e3 9c b7 be 09 c9 37 c1 7f 1c ff |...........7....| +00000000 14 03 03 00 01 01 17 03 03 00 35 35 fd 9a 7d 02 |..........55..}.| +00000010 fb b2 eb fa 51 27 3e 80 ab 60 f6 a1 54 31 13 2f |....Q'>..`..T1./| +00000020 02 b9 19 ac 68 be 25 69 b3 c4 48 87 42 75 b0 93 |....h.%i..H.Bu..| +00000030 66 3e 2e 0b 79 4f 0b 3a 59 ef 89 83 65 c9 10 9b |f>..yO.:Y...e...| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 1b 5e f2 20 7a 1c 27 36 12 e7 9a |......^. z.'6...| -00000010 05 9f fb 12 38 df 1d a0 3e 90 9a 42 4d ca 3a 54 |....8...>..BM.:T| -00000020 db 2c f0 17 03 03 00 13 b1 e4 a6 eb ad 47 ba 4c |.,...........G.L| -00000030 38 2c ee ee f9 a5 8a 41 2f ce 3d |8,.....A/.=| +00000000 17 03 03 00 1e 58 0f 73 e3 ba ff d3 19 0d 89 c9 |.....X.s........| +00000010 94 8a fb 24 02 58 2a 2c eb 69 29 4e 57 d3 d2 5e |...$.X*,.i)NW..^| +00000020 ba b2 75 17 03 03 00 13 9c 5c 46 44 71 dc 68 b8 |..u......\FDq.h.| +00000030 39 cc e1 fd 2d 2a a1 a9 50 6c af |9...-*..Pl.| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-P256 b/libgo/go/crypto/tls/testdata/Server-TLSv13-P256 index 86085b05612..dd8e0f49ce8 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-P256 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-P256 @@ -1,106 +1,102 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 f9 01 00 00 f5 03 03 3f 2f 76 da 5e |...........?/v.^| -00000010 bc ca 96 5b e3 c5 ff 45 18 e9 dc 7e b3 e8 97 f5 |...[...E...~....| -00000020 d1 d5 19 c0 4d a4 5d ce 34 1b e4 20 5f fe 5f 0c |....M.].4.. _._.| -00000030 88 92 65 b9 c6 ac 7f 3e dc a3 f7 ad e2 21 08 41 |..e....>.....!.A| -00000040 f8 36 e4 61 67 71 69 56 7f 6b d1 fc 00 08 13 02 |.6.agqiV.k......| -00000050 13 03 13 01 00 ff 01 00 00 a4 00 00 00 0e 00 0c |................| -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 04 00 02 00 17 00 16 00 00 |................| -00000080 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 06 03 |................| -00000090 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| -000000a0 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 2d 00 |.......+......-.| -000000b0 02 01 01 00 33 00 47 00 45 00 17 00 41 04 d3 57 |....3.G.E...A..W| -000000c0 de 53 6a 81 d5 e8 c2 68 cd 05 90 9b 0e b2 7e 5d |.Sj....h......~]| -000000d0 43 4c 66 f1 28 53 53 00 1a a5 9b b3 ae e0 3e b7 |CLf.(SS.......>.| -000000e0 72 4b 29 c6 2d 96 39 3a 1c a2 ef 04 96 22 df ea |rK).-.9:....."..| -000000f0 15 f5 ff bb 36 ed 3a 3f 67 55 ba 48 10 45 |....6.:?gU.H.E| +00000000 16 03 01 00 e3 01 00 00 df 03 03 c8 5f 11 a2 29 |............_..)| +00000010 7b c3 b7 72 5e ba e1 c5 83 45 c8 87 e1 51 27 d9 |{..r^....E...Q'.| +00000020 33 0e 68 e0 71 76 9e 8f 4e f4 da 20 da fd c6 1d |3.h.qv..N.. ....| +00000030 46 55 42 89 0a 80 e0 d3 e4 dd db 7d b1 3a 76 a3 |FUB........}.:v.| +00000040 5b d9 2a c7 f1 1a 3b 0b 8c 24 dd 4d 00 04 13 03 |[.*...;..$.M....| +00000050 00 ff 01 00 00 92 00 0b 00 04 03 00 01 02 00 0a |................| +00000060 00 04 00 02 00 17 00 16 00 00 00 17 00 00 00 0d |................| +00000070 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................| +00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000090 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.| +000000a0 47 00 45 00 17 00 41 04 04 48 71 9f a6 06 17 16 |G.E...A..Hq.....| +000000b0 04 d2 b4 e7 6b 5c cf d8 9f ca 64 a7 39 9e 1a 22 |....k\....d.9.."| +000000c0 aa fc b5 4c d9 d3 b3 37 e3 d4 e1 3b 5b 00 74 df |...L...7...;[.t.| +000000d0 df e5 29 8f 7c f7 6b 02 f0 e7 fb 9b 43 6a 41 fb |..).|.k.....CjA.| +000000e0 77 5b c2 6e 99 48 69 78 |w[.n.Hix| >>> Flow 2 (server to client) 00000000 16 03 03 00 9b 02 00 00 97 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 5f fe 5f 0c |........... _._.| -00000030 88 92 65 b9 c6 ac 7f 3e dc a3 f7 ad e2 21 08 41 |..e....>.....!.A| -00000040 f8 36 e4 61 67 71 69 56 7f 6b d1 fc 13 02 00 00 |.6.agqiV.k......| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 da fd c6 1d |........... ....| +00000030 46 55 42 89 0a 80 e0 d3 e4 dd db 7d b1 3a 76 a3 |FUB........}.:v.| +00000040 5b d9 2a c7 f1 1a 3b 0b 8c 24 dd 4d 13 03 00 00 |[.*...;..$.M....| 00000050 4f 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |O.+.....3.E...A.| 00000060 1e 18 37 ef 0d 19 51 88 35 75 71 b5 e5 54 5b 12 |..7...Q.5uq..T[.| 00000070 2e 8f 09 67 fd a7 24 20 3e b2 56 1c ce 97 28 5e |...g..$ >.V...(^| 00000080 f8 2b 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 32 42 |.+-O....lK[.V.2B| 00000090 e9 58 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc 5a 89 |.X..I..h.A.Vk.Z.| -000000a0 14 03 03 00 01 01 17 03 03 00 17 e2 0e 2c fc 9b |.............,..| -000000b0 61 70 e2 5f b9 e5 a5 ad ce fb df fa be ae 9a 5b |ap._...........[| -000000c0 cc 99 17 03 03 02 6d 87 74 85 83 f2 51 98 a5 75 |......m.t...Q..u| -000000d0 09 f0 6d 0f dd 16 a7 12 12 fb ec 98 6e 56 a4 ed |..m.........nV..| -000000e0 94 18 6b 28 6b ef 80 bd 28 3b f4 ee 05 80 d2 ff |..k(k...(;......| -000000f0 2f d4 6b b5 d3 b6 91 61 b7 8e 1b db 60 cf f5 4b |/.k....a....`..K| -00000100 3b 68 78 4a 09 2d a3 49 c0 8a 06 e5 2c 62 08 5d |;hxJ.-.I....,b.]| -00000110 c4 5d 03 04 5e 3e 25 9d 30 24 af b0 a3 2e 8c 65 |.]..^>%.0$.....e| -00000120 fb 6f 34 94 e9 d9 d6 34 0e a9 44 8a 9e b7 1a 13 |.o4....4..D.....| -00000130 26 b7 b2 16 c2 79 05 e8 0e 99 bd 7a cc c8 83 a4 |&....y.....z....| -00000140 60 1d cb 5c 02 8a 1f b7 4f c4 2d cd 96 e4 7b 39 |`..\....O.-...{9| -00000150 5a 45 60 30 82 9f 8f 30 56 11 7b 0d 6e 7e 95 54 |ZE`0...0V.{.n~.T| -00000160 d0 ac 09 8e 3b 49 14 de d3 8b a1 e4 4d f7 65 8d |....;I......M.e.| -00000170 88 46 71 7a 29 ea 05 b4 66 e6 76 db b7 7d 56 ce |.Fqz)...f.v..}V.| -00000180 e0 ba 47 b5 75 c1 14 42 7e af 87 f3 94 bf 75 e3 |..G.u..B~.....u.| -00000190 ee 54 ea 4c 8c 69 fd 63 01 1c 0e 38 84 e6 04 c3 |.T.L.i.c...8....| -000001a0 a8 3d 42 18 87 a2 f0 b4 4d ef 29 8d 48 01 b9 f4 |.=B.....M.).H...| -000001b0 8b 1e b1 72 bf e4 9a 6d 80 d7 c2 e0 a7 a7 0a 3f |...r...m.......?| -000001c0 45 f4 72 94 56 19 6b f3 4c 3e a6 1e 87 cd d3 a2 |E.r.V.k.L>......| -000001d0 49 b6 e7 56 b9 dd 2b f6 66 0a 6a 55 75 63 f9 c3 |I..V..+.f.jUuc..| -000001e0 d2 a6 ea a0 04 09 6b 75 eb 77 6b 9e 4b a4 6d f5 |......ku.wk.K.m.| -000001f0 44 01 37 ee 21 15 f7 3e 6e 6f fc dc be 44 43 26 |D.7.!..>no...DC&| -00000200 dd 7a ab 13 67 58 8d cb 02 78 b9 71 07 22 12 d2 |.z..gX...x.q."..| -00000210 cf 87 50 ff 04 d9 7a f2 73 8c 77 9e 5b 17 b2 aa |..P...z.s.w.[...| -00000220 2a db b2 a2 f4 5b c4 0d e2 84 a3 fe 4d b1 02 26 |*....[......M..&| -00000230 7d ba 76 2a 0e d1 87 52 c7 5f 97 07 fd b7 25 1b |}.v*...R._....%.| -00000240 2a 52 0d 30 59 84 73 a0 d7 db 75 6d 74 05 a2 3b |*R.0Y.s...umt..;| -00000250 91 69 f3 a3 43 bc 44 f9 ce f4 85 a1 38 5a e2 55 |.i..C.D.....8Z.U| -00000260 f6 e8 e2 ca 3b c2 fd 39 0f f4 ae 86 08 24 d4 c7 |....;..9.....$..| -00000270 10 44 c0 bf 9b 47 d9 da 07 52 4d 88 71 d4 14 69 |.D...G...RM.q..i| -00000280 66 8b cc 44 09 1b 90 b0 a5 7c 96 3c 94 99 cd c2 |f..D.....|.<....| -00000290 ca 0b af 53 c0 31 a2 5a df 54 76 e4 af 66 5d ff |...S.1.Z.Tv..f].| -000002a0 7c 21 c9 06 b8 d9 7e 1f 46 97 c8 ea e0 90 f2 db ||!....~.F.......| -000002b0 9b 52 04 a8 91 20 15 c8 fc 24 09 d7 f9 48 20 dc |.R... ...$...H .| -000002c0 18 22 d1 e2 19 3d 53 dd e4 21 db 8c 87 7d d7 bf |."...=S..!...}..| -000002d0 f7 93 a6 a5 81 b5 53 59 15 a8 80 2e 3b 4f b0 d4 |......SY....;O..| -000002e0 f3 66 56 14 6e a1 6b 3e 75 b1 8e fa 0d 52 96 b1 |.fV.n.k>u....R..| -000002f0 08 b1 b0 ce 0c c6 0a 5e 54 0f a3 5a cd 6c db 6a |.......^T..Z.l.j| -00000300 0a 6a 52 11 b5 97 7b 67 e3 3e 84 22 76 3a f1 96 |.jR...{g.>."v:..| -00000310 70 bf 9c a6 62 03 30 a7 69 46 ec 9a 61 1e 37 6f |p...b.0.iF..a.7o| -00000320 7d 24 d6 6c 8a e5 72 3a 0a ef e8 d3 d6 fe 28 c8 |}$.l..r:......(.| -00000330 60 ff d7 2e 17 03 03 00 99 ca f3 5e cb 8c b2 0b |`..........^....| -00000340 87 4e 59 89 38 f5 f1 3c c4 e1 6a 11 2d f3 ef 7d |.NY.8..<..j.-..}| -00000350 b6 85 ff bb 84 8f cb db 7f 02 50 23 93 db b3 0a |..........P#....| -00000360 2c 32 cb ed 08 ae 6a 3e 30 b8 a5 c2 9c 85 0c 87 |,2....j>0.......| -00000370 44 68 8b 47 31 75 a0 c3 2c 32 2e 61 40 da 4b 0a |Dh.G1u..,2.a@.K.| -00000380 07 ef 2b 6b fa 2f 66 87 ff f1 0e 5e b0 db 44 3d |..+k./f....^..D=| -00000390 3c fc a7 94 17 f3 0b a5 50 68 7b 65 48 8e 78 ce |<.......Ph{eH.x.| -000003a0 d7 71 fa ae 58 50 62 33 98 b2 a2 27 b1 e0 66 fb |.q..XPb3...'..f.| -000003b0 65 6a 94 21 38 e8 40 aa 4f d7 02 31 45 e8 d3 e0 |ej.!8.@.O..1E...| -000003c0 5f 66 d4 2f 26 9f b2 72 b7 bc 43 ce f1 2a 0e 61 |_f./&..r..C..*.a| -000003d0 f1 91 17 03 03 00 45 c0 25 ac 1e 0b 4e 2c 61 9c |......E.%...N,a.| -000003e0 c7 80 f1 f7 bf d4 c6 a9 29 3f 0c 08 8d f0 70 7c |........)?....p|| -000003f0 6f 96 2c 3e 32 7f a6 10 17 19 81 49 2d a7 f7 3f |o.,>2......I-..?| -00000400 04 20 7d 52 c2 e8 cc 61 b2 16 5b 8b 3e 1a a9 2f |. }R...a..[.>../| -00000410 9c 5e a7 74 88 3d 8a c8 90 df 9a 17 17 03 03 00 |.^.t.=..........| -00000420 a3 cf b5 d2 52 49 27 95 5f dd 9b 37 ed 74 7b 17 |....RI'._..7.t{.| -00000430 8b 7f f3 67 3c 91 2f 1e b6 17 4f ba a7 b1 92 99 |...g<./...O.....| -00000440 32 32 7e 72 95 90 a0 92 08 c3 da 30 31 85 ee bb |22~r.......01...| -00000450 8f 8d d4 d8 c5 28 19 10 71 f0 b3 15 45 86 e0 09 |.....(..q...E...| -00000460 ee e4 96 a0 90 c5 df 81 8f d1 38 b2 e0 33 95 3b |..........8..3.;| -00000470 33 9d e0 3e 93 3d 6a 12 60 44 43 9e b0 5c 16 82 |3..>.=j.`DC..\..| -00000480 92 b8 84 0e 56 19 b9 b6 eb 3c 37 3e 9b ee 2a 6a |....V....<7>..*j| -00000490 13 4a bb 3d 78 21 79 0e 6f cc 34 89 91 95 03 a6 |.J.=x!y.o.4.....| -000004a0 19 e2 81 37 a6 9d 30 28 42 da f4 69 4e 42 4b e4 |...7..0(B..iNBK.| -000004b0 ca 23 c5 1e 56 24 cc ba b0 85 21 ef 44 04 cb d8 |.#..V$....!.D...| -000004c0 aa cd 5d 55 |..]U| +000000a0 14 03 03 00 01 01 17 03 03 00 17 81 b8 e3 25 04 |..............%.| +000000b0 6c d8 f6 7c 04 a1 2c 8b 1f 0d cb de 29 1b e1 a3 |l..|..,.....)...| +000000c0 6f 8c 17 03 03 02 6d 81 db bc b4 f8 02 f3 c5 4e |o.....m........N| +000000d0 9e f7 5f 55 54 3e 25 a9 2f 03 06 62 2f 1e 7e d4 |.._UT>%./..b/.~.| +000000e0 19 27 88 1e ac f2 44 87 29 84 08 69 2f 5d a3 ca |.'....D.)..i/]..| +000000f0 de 8f 98 ad 25 6b c5 94 62 34 44 95 bc 17 ed e6 |....%k..b4D.....| +00000100 fe 89 9c ef 46 c9 cb ee 16 d4 42 b6 d3 50 7b 3a |....F.....B..P{:| +00000110 51 d8 20 23 02 3e 69 a8 1a 80 eb bf 7c 82 2b 1f |Q. #.>i.....|.+.| +00000120 10 5a 30 85 dd bc ff 65 4d c6 4f 7b bc 3d 64 e2 |.Z0....eM.O{.=d.| +00000130 93 2a 05 a0 af de b1 41 48 85 db 98 c9 a9 96 5c |.*.....AH......\| +00000140 64 a4 70 2e f9 4e de 38 9f 48 f7 eb 6e 14 42 3f |d.p..N.8.H..n.B?| +00000150 9f 86 0f 2d 70 6a 30 96 1c dd c6 11 28 6f 86 b6 |...-pj0.....(o..| +00000160 da bb 5b 76 c8 56 18 4a 67 bf 59 db 56 46 f0 c7 |..[v.V.Jg.Y.VF..| +00000170 80 2b 0f 0c 8a 02 58 a1 13 aa 2e 5d 61 e2 d5 23 |.+....X....]a..#| +00000180 3c 1c 75 06 e4 e4 e1 39 eb 65 6a ff 38 21 28 c9 |<.u....9.ej.8!(.| +00000190 c5 8b a5 12 21 18 2a 59 e7 4e 66 53 be d3 49 97 |....!.*Y.NfS..I.| +000001a0 f9 b1 7d e2 75 44 37 38 36 35 af 78 27 f4 74 e0 |..}.uD7865.x'.t.| +000001b0 45 ca fd 79 3c 39 65 00 46 58 4b 8b db f9 6e c0 |E..y<9e.FXK...n.| +000001c0 69 ec 1e 25 87 66 e1 b8 d8 cc 16 5b 16 9e 90 2e |i..%.f.....[....| +000001d0 16 0c 8f 25 04 cf 40 c8 50 dd c4 63 19 8f f1 76 |...%..@.P..c...v| +000001e0 5e fa 24 1d 8a d2 c1 d4 98 49 48 f0 e6 fa f3 6e |^.$......IH....n| +000001f0 63 0b a5 7a 2f f2 f0 47 0b c0 89 9f 7b 9f ef 48 |c..z/..G....{..H| +00000200 df fd 38 5d a9 71 ce 0c 3c 6f 88 0b 1b d3 93 8c |..8].q....| +00000250 96 5a 3c 97 8e 7b 47 b8 f0 58 16 12 05 69 69 a1 |.Z<..{G..X...ii.| +00000260 36 7b ff dd 92 60 26 e2 f9 53 4c 3a 25 ac 88 dd |6{...`&..SL:%...| +00000270 9a 81 7c 1f 58 27 33 14 68 44 06 e2 01 14 94 99 |..|.X'3.hD......| +00000280 00 05 8f 64 47 ca 95 fa 92 57 a9 1a 53 d5 47 52 |...dG....W..S.GR| +00000290 e8 c4 aa eb 0a f5 1b a9 09 72 92 37 f5 8d 90 b8 |.........r.7....| +000002a0 4b 08 7f 55 19 2d a7 d8 7b d9 ba 7f 5e 56 bb 80 |K..U.-..{...^V..| +000002b0 c7 d0 49 99 ae ce 2f a4 f0 ab d1 bd ba f3 0f 85 |..I.../.........| +000002c0 f1 68 c1 9d 2a 37 ff de a4 0a 6f 58 27 1d 1d 2b |.h..*7....oX'..+| +000002d0 87 9d 52 d3 70 37 a6 03 cd 77 61 9b 56 64 49 62 |..R.p7...wa.VdIb| +000002e0 ef a1 ed fe 75 1a 61 4a 58 01 d6 80 2f ab ab fc |....u.aJX.../...| +000002f0 b2 49 1f 51 b7 51 29 c1 a1 39 fc f4 0a 9b 0d 76 |.I.Q.Q)..9.....v| +00000300 c6 d0 89 c9 8f 88 e9 ec 13 90 78 4f 0c f5 c9 7e |..........xO...~| +00000310 d5 b3 13 ad 35 6d 53 d0 88 50 e8 47 15 a0 ca fc |....5mS..P.G....| +00000320 5f 6e 98 23 46 6a 69 84 3c a9 3f eb d1 05 f5 97 |_n.#Fji.<.?.....| +00000330 11 39 7f 39 17 03 03 00 99 84 8e 37 a9 57 78 12 |.9.9.......7.Wx.| +00000340 8e 9a e7 8e 45 ee 55 61 66 24 ed 5a 36 19 e3 1c |....E.Uaf$.Z6...| +00000350 22 3b 8b c0 4b c9 cd 2c 4c 17 d2 a9 40 2c 02 40 |";..K..,L...@,.@| +00000360 74 ba 11 de a5 d4 01 11 ae 9d 71 76 4c f0 87 0f |t.........qvL...| +00000370 5e 75 c0 67 c0 33 e7 3e 9b d3 a4 21 e8 40 a6 9f |^u.g.3.>...!.@..| +00000380 d8 24 a7 d7 c1 99 cc 8d 33 10 91 0a 41 a6 05 1c |.$......3...A...| +00000390 85 4c c5 a8 c9 dd 74 d0 5c 67 2e 2a 50 4e 30 c7 |.L....t.\g.*PN0.| +000003a0 bb fa f8 65 ee 48 23 f5 c5 d3 a1 ec 4d 3f ac 4b |...e.H#.....M?.K| +000003b0 ef 1e 8d 84 07 b9 69 2a 34 51 73 ba fb b5 7d 64 |......i*4Qs...}d| +000003c0 1f fc 0e c8 33 d9 77 5e 41 00 65 25 ea 75 75 c9 |....3.w^A.e%.uu.| +000003d0 2b 03 17 03 03 00 35 54 c2 06 55 7c 6f 92 8a d2 |+.....5T..U|o...| +000003e0 d5 35 0c 4b 0d df cb d7 6e 5d 64 e1 2e cf 50 b8 |.5.K....n]d...P.| +000003f0 d8 04 9a f4 ce 69 d3 ac bb 47 cd 57 ac 07 aa 40 |.....i...G.W...@| +00000400 e3 fc 01 bc d6 a1 0e 16 4e 6b 04 cc 17 03 03 00 |........Nk......| +00000410 93 b2 c3 64 29 13 07 75 b4 c4 84 f7 0e 99 d9 9f |...d)..u........| +00000420 8d 5b fd 26 07 42 48 33 3a ab 6f 7d 07 8b f6 8a |.[.&.BH3:.o}....| +00000430 22 a4 ce 64 0f 69 ea 61 95 70 6d d3 f8 5f 8b ad |"..d.i.a.pm.._..| +00000440 02 43 94 41 51 f4 f8 0b 52 fc 58 c1 23 5e 22 a7 |.C.AQ...R.X.#^".| +00000450 74 49 a1 46 e8 29 ab d6 ae 02 a4 7b e4 23 f1 89 |tI.F.).....{.#..| +00000460 1c b1 74 86 92 1b 6a 7c 2f 55 2b 89 f6 01 fc e2 |..t...j|/U+.....| +00000470 d6 15 b9 b1 64 1c 4a af f8 fe 3e e0 76 0f cf 08 |....d.J...>.v...| +00000480 e1 2c db f6 1c 77 6f e4 a4 80 ad 13 74 3d 02 52 |.,...wo.....t=.R| +00000490 a1 ff 3e 85 1d d3 77 bc f2 48 73 1c 45 09 62 34 |..>...w..Hs.E.b4| +000004a0 80 09 21 41 |..!A| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 43 65 76 31 fa |..........ECev1.| -00000010 2c a7 2e 96 92 82 cf eb 91 3d 8b eb 01 d3 af da |,........=......| -00000020 67 ea 4d 75 47 8f 42 34 7a 2d 0a b0 d1 4c 08 c0 |g.MuG.B4z-...L..| -00000030 c7 76 7e 99 93 4a 06 b2 d9 95 df f9 c1 29 25 e6 |.v~..J.......)%.| -00000040 24 6d ea 73 00 24 36 a9 62 30 9d a4 aa 6c 2f c8 |$m.s.$6.b0...l/.| +00000000 14 03 03 00 01 01 17 03 03 00 35 ab dd 69 66 c8 |..........5..if.| +00000010 f9 eb e6 e6 b0 a9 9b 10 1d fc ad 89 ad 4d f5 2b |.............M.+| +00000020 e4 d7 12 5b 1c 1e 81 12 df 24 ba ea 6b 3e 6f 82 |...[.....$..k>o.| +00000030 dd 2f 38 a1 65 07 55 6a 4f 8e 99 5d 4f 35 b8 5d |./8.e.UjO..]O5.]| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 6e bb 52 84 cf a6 71 d5 b9 ac c2 |.....n.R...q....| -00000010 29 1a 0b db be a4 bb bd 6c f4 2e c8 eb f0 bb eb |).......l.......| -00000020 d3 f8 69 17 03 03 00 13 19 ad 85 21 63 f6 38 df |..i........!c.8.| -00000030 35 41 af 12 75 63 e8 fa 38 5e 50 |5A..uc..8^P| +00000000 17 03 03 00 1e e5 f4 e6 14 79 8c b9 a9 77 6b c9 |.........y...wk.| +00000010 ff ad 60 f3 03 cf 48 19 19 71 6c 85 da 92 cb 79 |..`...H..ql....y| +00000020 2b 20 41 17 03 03 00 13 69 de ca 08 9c cf 70 37 |+ A.....i.....p7| +00000030 5e fc 32 31 1c 93 d1 e4 01 f3 c6 |^.21.......| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS b/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS index 8151fd4d27e..db53ebbc5f1 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS @@ -1,16 +1,97 @@ >>> Flow 1 (client to server) -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 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| +00000000 16 03 01 00 b2 01 00 00 ae 03 03 4d a5 7b 2c da |...........M.{,.| +00000010 67 11 9d 4d a0 92 2a 96 6c 85 ef 8c 52 0a 31 cf |g..M..*.l...R.1.| +00000020 43 23 3e 8d 67 63 9b 7e 84 94 17 20 a2 a1 87 c6 |C#>.gc.~... ....| +00000030 5e 64 34 75 da ac ee ba d4 d8 8f 2a a6 55 9f 4f |^d4u.......*.U.O| +00000040 48 38 5a 29 61 a4 ef 7d 1d 74 a7 71 00 04 13 03 |H8Z)a..}.t.q....| +00000050 00 ff 01 00 00 61 00 0b 00 04 03 00 01 02 00 0a |.....a..........| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000070 00 00 00 17 00 00 00 0d 00 06 00 04 08 06 08 04 |................| +00000080 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.| +00000090 26 00 24 00 1d 00 20 16 5e 23 ca e7 24 31 81 c2 |&.$... .^#..$1..| +000000a0 78 21 3a ee 8a f3 61 8a 46 a0 56 ee a9 ed 82 3a |x!:...a.F.V....:| +000000b0 87 b7 4a 0a 03 fe 59 |..J...Y| >>> Flow 2 (server to client) -00000000 15 03 03 00 02 02 28 |......(| +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 a2 a1 87 c6 |........... ....| +00000030 5e 64 34 75 da ac ee ba d4 d8 8f 2a a6 55 9f 4f |^d4u.......*.U.O| +00000040 48 38 5a 29 61 a4 ef 7d 1d 74 a7 71 13 03 00 00 |H8Z)a..}.t.q....| +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 f8 7a 9c bc 58 8d |...........z..X.| +00000090 ce cd ff e6 ae 2d c2 e0 40 33 4e c4 ec f5 90 dd |.....-..@3N.....| +000000a0 ba 17 03 03 02 6d f3 65 a1 b4 fe ef 40 37 72 fa |.....m.e....@7r.| +000000b0 a5 b8 10 ad 32 e3 08 e1 ac bb 14 f2 34 bf 25 19 |....2.......4.%.| +000000c0 aa 2d 1a 78 cc 26 2f 5c 0b 7e 13 73 36 85 92 96 |.-.x.&/\.~.s6...| +000000d0 0a 7a 27 f5 35 86 f1 ea 1a 5f 5c 3a 90 28 63 6a |.z'.5...._\:.(cj| +000000e0 b3 7c e0 56 32 10 55 67 59 e0 65 d6 11 ef 7c 50 |.|.V2.UgY.e...|P| +000000f0 0b 9e 88 0a 61 96 93 cf 05 51 47 33 c3 5c e3 82 |....a....QG3.\..| +00000100 01 6d f1 f7 5c dc df b2 61 7c d7 9f de b4 3e c0 |.m..\...a|....>.| +00000110 6d b5 52 39 3b f6 33 c2 03 65 2b 66 39 ed d6 f0 |m.R9;.3..e+f9...| +00000120 83 46 61 db fc 27 a5 8a 68 d6 8a 85 5d 3f b1 46 |.Fa..'..h...]?.F| +00000130 a2 3a 32 37 1f e0 76 a6 79 7f eb b2 81 52 e7 e0 |.:27..v.y....R..| +00000140 4f b2 db 48 7d 20 61 52 d4 22 2a b7 81 2f da 5b |O..H} aR."*../.[| +00000150 f6 e8 0a a6 91 b5 d1 f5 6b 5e 2b ad fd 70 cd a1 |........k^+..p..| +00000160 f8 4d 73 31 3d 2a 49 d3 2e 6b b3 31 95 61 09 08 |.Ms1=*I..k.1.a..| +00000170 c5 f9 eb db 42 b0 e1 5d 47 00 3e 7e 80 31 c6 d2 |....B..]G.>~.1..| +00000180 37 dc 68 d7 36 05 ad 8a a4 05 87 7a 1c 12 f6 ab |7.h.6......z....| +00000190 0e e1 5b 29 b1 1c 16 20 29 75 5a b0 59 24 59 df |..[)... )uZ.Y$Y.| +000001a0 62 fe f2 26 ad ab bf 2b 25 d7 9e db 04 f6 26 96 |b..&...+%.....&.| +000001b0 f7 5f 2c ff 2e 6d 85 c7 58 c8 15 9c d0 7d dd 8e |._,..m..X....}..| +000001c0 1a 39 fc 3d 62 58 47 ce 83 7a ff fc 45 98 02 3d |.9.=bXG..z..E..=| +000001d0 aa 37 b7 5e a7 7b 8e fa f2 05 8b 61 7f 04 08 f5 |.7.^.{.....a....| +000001e0 af 1d 6e 55 18 d2 12 2e bd 8a 80 3d cb e6 0f cd |..nU.......=....| +000001f0 3c d8 a5 38 db ee 07 c6 3b 75 55 c2 ee 2e 6a a3 |<..8....;uU...j.| +00000200 fa 54 ce e3 45 92 c0 b9 8c 10 3d 2f 86 cb a5 c9 |.T..E.....=/....| +00000210 af 37 f7 f6 6c 3e 4b 15 04 bd 46 98 31 5a b9 8c |.7..l>K...F.1Z..| +00000220 ec 67 0d 97 9d 26 56 65 9c a7 74 bb 88 45 dc 4e |.g...&Ve..t..E.N| +00000230 ce 70 a1 fc ce fc a7 d4 e1 7d a7 43 82 a6 e2 30 |.p.......}.C...0| +00000240 e2 94 88 e5 1a 05 c5 28 06 14 7b 29 75 f9 4d 2c |.......(..{)u.M,| +00000250 bb 54 ee f5 17 4e 2a bf 04 e6 38 f2 cf ed ab a2 |.T...N*...8.....| +00000260 ef ae ac 3d 80 5e 03 71 74 70 0c 68 93 ca ea 93 |...=.^.qtp.h....| +00000270 e5 b1 d1 18 80 98 0e c6 e8 f5 65 87 e7 9a 33 1d |..........e...3.| +00000280 e6 3d e2 28 82 19 2a 9d 5f 1a a2 74 fa 27 8b d0 |.=.(..*._..t.'..| +00000290 09 9a ba 1b c5 a6 4c 3b c3 02 12 61 a1 8a 20 d3 |......L;...a.. .| +000002a0 a4 3c 3b aa f2 08 de e0 de 07 9f a0 13 b4 e8 23 |.<;............#| +000002b0 d3 a5 ff 12 74 55 29 3a 57 f5 14 b3 af e6 28 ed |....tU):W.....(.| +000002c0 b1 60 9c 6b 7d 55 a1 58 50 ab 42 71 5d 0e dc 76 |.`.k}U.XP.Bq]..v| +000002d0 87 cd a1 d3 e4 26 25 c4 c1 23 1e 3b 31 13 3d f8 |.....&%..#.;1.=.| +000002e0 b2 1b a8 07 f6 68 83 b4 7e 94 ca 84 95 55 38 d1 |.....h..~....U8.| +000002f0 eb af 19 83 90 4a ab 0a 8d f6 48 9a 25 fa 59 97 |.....J....H.%.Y.| +00000300 3c 5f 6a 2d 68 ec 29 d5 53 b4 9a 97 ea 59 fe 74 |<_j-h.).S....Y.t| +00000310 81 0e b9 17 03 03 00 99 12 25 df 91 85 91 ac c0 |.........%......| +00000320 60 4e 6e ed c4 b2 f0 f3 8b 66 53 75 11 07 29 d6 |`Nn......fSu..).| +00000330 1f 01 81 60 de 5f b7 6b 5e 39 c8 ea f1 f8 2a 94 |...`._.k^9....*.| +00000340 dd b6 c5 a9 31 be 87 a7 aa a9 64 03 16 40 df ef |....1.....d..@..| +00000350 37 ac 66 4c 19 f1 60 d5 b4 88 93 a7 42 ac e3 81 |7.fL..`.....B...| +00000360 c8 88 3f e2 30 a0 ff b7 d5 19 fc f2 72 a7 97 a8 |..?.0.......r...| +00000370 31 ce 20 be 90 bc f5 8a 24 31 b1 c6 2b 2a ad c5 |1. .....$1..+*..| +00000380 7a 34 69 eb a7 86 53 61 a1 88 4f 58 2a 65 a2 18 |z4i...Sa..OX*e..| +00000390 7a 93 81 c6 bd c7 bc 84 5b ff 85 aa ff fc 68 50 |z.......[.....hP| +000003a0 cb 57 37 54 a7 0f 2e 64 82 53 b7 dc ea c2 e3 49 |.W7T...d.S.....I| +000003b0 fd 17 03 03 00 35 da 2a 8c 37 83 a5 a0 d4 06 c4 |.....5.*.7......| +000003c0 ff f3 85 6f e4 11 1f 37 0f 06 35 45 e9 51 43 6f |...o...7..5E.QCo| +000003d0 d2 a4 cb b7 ad f0 66 1c 20 40 c3 14 32 c0 57 71 |......f. @..2.Wq| +000003e0 d3 8c 9c 7f 5b e6 50 a1 c2 e5 62 17 03 03 00 93 |....[.P...b.....| +000003f0 30 b8 ab dc 3b df 60 aa b1 d2 25 5a 60 da b6 c8 |0...;.`...%Z`...| +00000400 22 88 93 79 25 44 56 aa ec 93 e8 01 11 bf 69 ad |"..y%DV.......i.| +00000410 b2 c9 43 67 33 aa 6d ae 73 a3 95 2b f0 86 ed a2 |..Cg3.m.s..+....| +00000420 db df e3 dc 9b 16 1d 8d fc 2f a5 c4 41 d0 86 2f |........./..A../| +00000430 cc a1 a1 ce 9a e5 e6 c8 a2 d1 a8 b2 a4 15 9c 69 |...............i| +00000440 38 5a fa fd de d4 02 95 24 67 1b 61 76 1f c4 65 |8Z......$g.av..e| +00000450 01 fc 36 2d ef 2d 0f 8e f0 5a 6d 04 07 b8 26 18 |..6-.-...Zm...&.| +00000460 90 fc 82 1b 99 68 b0 13 7f 6e a1 9b c4 2a f3 b8 |.....h...n...*..| +00000470 0b 6a 44 cd 04 e8 20 96 6d f5 48 cb 71 8a 04 10 |.jD... .m.H.q...| +00000480 b8 8d 56 |..V| +>>> Flow 3 (client to server) +00000000 14 03 03 00 01 01 17 03 03 00 35 54 e5 3f f8 77 |..........5T.?.w| +00000010 59 e3 8b 02 0b 80 8d 59 12 22 23 09 cb d9 93 67 |Y......Y."#....g| +00000020 c7 35 b4 45 a0 54 49 fd 65 b5 ff e6 3e 3c b9 bf |.5.E.TI.e...><..| +00000030 26 ca df 86 db a4 66 b5 3e 1f 36 69 a5 99 2b ed |&.....f.>.6i..+.| +>>> Flow 4 (server to client) +00000000 17 03 03 00 1e e3 b4 3e 81 ff 1a 36 f8 11 53 64 |.......>...6..Sd| +00000010 b9 28 4e 68 de ee 9c b6 4d 71 21 fa 85 56 30 ad |.(Nh....Mq!..V0.| +00000020 e9 c2 27 17 03 03 00 13 3d b8 13 b0 5f df 5a 05 |..'.....=..._.Z.| +00000030 85 cf eb 48 86 fb c5 a0 67 f7 ee |...H....g..| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall b/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall index 94f5818ce15..6d27e9074c0 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall @@ -1,16 +1,15 @@ >>> 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-| +00000000 16 03 01 00 b0 01 00 00 ac 03 03 15 df ef fb ff |................| +00000010 00 89 4d bf 59 d2 30 f1 f3 e7 20 24 c6 06 ba a4 |..M.Y.0... $....| +00000020 28 b4 ba 3d 00 f2 18 9b 98 a3 f2 20 7e d9 d0 58 |(..=....... ~..X| +00000030 50 25 90 2d f0 af 72 66 fb f8 54 33 6e d4 2b f0 |P%.-..rf..T3n.+.| +00000040 0f 1a ea dc 9e 08 34 ed 68 a8 d8 bd 00 04 13 03 |......4.h.......| +00000050 00 ff 01 00 00 5f 00 0b 00 04 03 00 01 02 00 0a |....._..........| +00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| +00000070 00 00 00 17 00 00 00 0d 00 04 00 02 08 06 00 2b |...............+| +00000080 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 |......-.....3.&.| +00000090 24 00 1d 00 20 6e 42 98 d4 04 32 d1 21 0f 64 c9 |$... nB...2.!.d.| +000000a0 b7 f2 b2 52 6f 2b b7 b1 95 4b 57 85 7b 69 d9 63 |...Ro+...KW.{i.c| +000000b0 19 48 d2 1c 1e |.H...| >>> Flow 2 (server to client) 00000000 15 03 03 00 02 02 28 |......(| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-Resume b/libgo/go/crypto/tls/testdata/Server-TLSv13-Resume index fa10f3e0c43..091ffc33478 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-Resume +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-Resume @@ -1,66 +1,60 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 a4 01 00 01 a0 03 03 92 e8 fa 14 82 |................| -00000010 03 7c cd fe 01 82 55 99 8b fd 04 ff 88 82 98 c9 |.|....U.........| -00000020 72 18 3b 2e 0a de fc a4 44 9f 1d 20 c0 df df c9 |r.;.....D.. ....| -00000030 1d ed 19 9e 2d ce 57 f6 95 54 67 76 77 64 c7 f4 |....-.W..Tgvwd..| -00000040 ad 18 7d d8 58 6f 08 30 a5 a4 50 cd 00 08 13 02 |..}.Xo.0..P.....| -00000050 13 03 13 01 00 ff 01 00 01 4f 00 00 00 0e 00 0c |.........O......| -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 23 00 00 00 16 00 00 00 17 00 00 |.....#..........| -00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................| -000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................| -000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....| -000000c0 33 00 26 00 24 00 1d 00 20 94 44 cd ce 27 a8 43 |3.&.$... .D..'.C| -000000d0 8a ef cd ef d4 74 d4 e4 62 82 00 e6 46 96 e5 aa |.....t..b...F...| -000000e0 d1 44 8a 55 6b d7 25 06 6f 00 29 00 bc 00 87 00 |.D.Uk.%.o.).....| -000000f0 81 50 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 |.PF....8.{+....B| -00000100 3e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |>...............| -00000110 00 94 68 2c a3 81 51 ed 14 ef 68 ca 42 c5 4c 1f |..h,..Q...h.B.L.| -00000120 90 bf 3c 07 2b e5 52 22 a0 c0 46 db cb f6 b9 a0 |..<.+.R"..F.....| -00000130 b5 56 b0 d6 7f 03 b7 2d 9f a5 2a 25 8e 65 d2 b9 |.V.....-..*%.e..| -00000140 6a f3 e4 7e 79 d7 3d cc b2 3d b6 24 a9 31 82 49 |j..~y.=..=.$.1.I| -00000150 38 16 92 f0 49 97 e2 07 e2 cd 1c 77 d3 e0 00 de |8...I......w....| -00000160 56 11 17 40 00 63 13 00 48 39 8e fd 09 96 08 f3 |V..@.c..H9......| -00000170 81 7c 00 00 00 00 00 31 30 a4 22 35 6e 4a 09 af |.|.....10."5nJ..| -00000180 08 22 97 92 e0 8a eb c0 e0 28 32 f4 8f ed 1e 02 |.".......(2.....| -00000190 a9 b3 43 de f3 04 cb 7b db 01 51 88 46 02 c1 4b |..C....{..Q.F..K| -000001a0 ec fa a8 05 42 a4 00 ae ed |....B....| +00000000 16 03 01 01 6e 01 00 01 6a 03 03 b6 39 89 61 fd |....n...j...9.a.| +00000010 11 84 b3 4b a9 18 23 b2 35 3d 82 85 75 5c e2 f3 |...K..#.5=..u\..| +00000020 c9 f4 b0 2f 05 fb 5a 90 da 73 38 20 7f 06 81 e5 |.../..Z..s8 ....| +00000030 d0 10 08 d1 b0 3c 3c 4b 28 39 34 9a 56 ca 47 4a |.....<.....| +000000f0 00 00 00 00 00 00 00 00 00 00 00 94 68 2c a3 82 |............h,..| +00000100 51 ed 14 ef 68 ca 42 c5 5c ab 26 c2 91 a9 01 83 |Q...h.B.\.&.....| +00000110 13 26 8f 62 7c 89 c0 a2 b5 9b 6d 4f a4 c9 e2 49 |.&.b|.....mO...I| +00000120 34 03 2c b2 7d d9 af eb 1a 99 76 3c a5 ef 70 78 |4.,.}.....v<..px| +00000130 59 58 1c 45 80 c5 f1 b8 91 b2 54 71 3f bf 4f 2a |YX.E......Tq?.O*| +00000140 b2 9d 9d 6f 6f 1c f1 3c 6c e6 a2 73 00 00 00 00 |...oo..>> Flow 2 (server to client) 00000000 16 03 03 00 80 02 00 00 7c 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 c0 df df c9 |........... ....| -00000030 1d ed 19 9e 2d ce 57 f6 95 54 67 76 77 64 c7 f4 |....-.W..Tgvwd..| -00000040 ad 18 7d d8 58 6f 08 30 a5 a4 50 cd 13 02 00 00 |..}.Xo.0..P.....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 7f 06 81 e5 |........... ....| +00000030 d0 10 08 d1 b0 3c 3c 4b 28 39 34 9a 56 ca 47 4a |.....<%..v.| -00000120 6e 92 0d 6b 88 c7 54 46 51 bf 86 a4 f4 11 d3 e8 |n..k..TFQ.......| -00000130 29 54 16 31 b2 44 4b 45 5d 3f 97 d9 33 10 ef 92 |)T.1.DKE]?..3...| -00000140 e5 aa 3b 2d 3d 36 ef 85 04 2d 17 66 2a 00 ea 87 |..;-=6...-.f*...| -00000150 9a 95 5e 54 1b 01 f8 5d 34 96 83 cf 28 d4 24 ed |..^T...]4...(.$.| -00000160 c6 9b da 7a 1c d4 a3 5a 53 bb 2f cf 56 f3 ef 99 |...z...ZS./.V...| -00000170 40 e2 34 31 ca 55 c9 7a 02 47 14 8b 7e 04 5a ff |@.41.U.z.G..~.Z.| -00000180 17 f7 95 f0 46 e0 ce cf 8f b0 9f 6b 51 96 d5 f7 |....F......kQ...| -00000190 0b 33 e2 0a 62 4e 05 28 66 |.3..bN.(f| +00000090 18 d7 0c 38 47 21 c2 8e 01 fe e7 1f 35 ee 7f 8f |...8G!......5...| +000000a0 04 10 7a 06 61 1f 4d 17 03 03 00 35 b3 38 29 ce |..z.a.M....5.8).| +000000b0 18 2b 22 5e 01 4d 07 04 87 65 68 85 9d 10 e9 9e |.+"^.M...eh.....| +000000c0 5a a8 a5 cb 8d f9 48 fe 1b 17 30 04 be 55 92 ce |Z.....H...0..U..| +000000d0 74 9b 8e 9c 6b 77 5d 09 ca 58 8e c0 ac 85 3b 4e |t...kw]..X....;N| +000000e0 0b 17 03 03 00 93 90 64 70 a6 d7 20 8e 50 6d b7 |.......dp.. .Pm.| +000000f0 53 3d ed eb 85 e0 2f fe a2 88 84 3d 26 8a 18 65 |S=..../....=&..e| +00000100 d1 c0 d2 c4 66 2a 2e 8c 06 5f 46 ee fe 36 f7 00 |....f*..._F..6..| +00000110 57 3f 95 b3 36 47 0c 1a 78 c4 e3 d6 c1 ae 2f 96 |W?..6G..x...../.| +00000120 f0 e6 5e 61 86 d7 c1 d7 cc d2 a6 19 0c 29 f5 19 |..^a.........)..| +00000130 d5 5e 75 6f 8b 49 4b 0b e9 c9 3c 69 87 ab b7 1d |.^uo.IK...>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 66 00 e2 3f 07 |..........Ef..?.| -00000010 02 a4 1d 71 27 2a fe c7 00 1e 2d bc 50 b6 bc 35 |...q'*....-.P..5| -00000020 22 c4 a4 d8 a1 5f fa 10 d7 48 c8 20 94 50 b1 ae |"...._...H. .P..| -00000030 47 8c 62 26 15 79 33 6b 06 0d 19 67 7e 22 7c a5 |G.b&.y3k...g~"|.| -00000040 ca 05 c9 ae c8 66 6b ca 8e f7 7c 35 de 5e c3 25 |.....fk...|5.^.%| +00000000 14 03 03 00 01 01 17 03 03 00 35 69 08 b0 a0 71 |..........5i...q| +00000010 1f 95 45 c4 b2 11 43 a9 b5 da ba 11 0a 2b 24 49 |..E...C......+$I| +00000020 ac 3d 8e ec 32 c9 7f 3e cc 1b fc 9a 68 d0 22 cb |.=..2..>....h.".| +00000030 37 0e 8f fe 4f 75 1a 62 44 20 60 c2 64 de 48 6d |7...Ou.bD `.d.Hm| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 6a 89 ce e3 1d 13 60 f3 8b 26 97 |.....j.....`..&.| -00000010 3e 5d 9f a8 47 c9 74 f5 66 ad 75 87 57 ec ef b1 |>]..G.t.f.u.W...| -00000020 66 da f0 17 03 03 00 13 95 bd 2d ef d5 30 c1 1b |f.........-..0..| -00000030 bd 54 3d f6 16 02 28 78 a4 4a 24 |.T=...(x.J$| +00000000 17 03 03 00 1e d5 71 aa 53 2d 55 b7 76 11 45 b0 |......q.S-U.v.E.| +00000010 f3 de f7 f1 78 0b 10 3f 49 7f ea 83 17 2e b9 50 |....x..?I......P| +00000020 ec d2 0f 17 03 03 00 13 0a 22 58 66 d8 f7 ad fc |........."Xf....| +00000030 9c f2 da d1 ae 02 f8 99 d2 26 63 |.........&c| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest b/libgo/go/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest index 2e1cbaf1354..d0aa66a5810 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest @@ -1,106 +1,96 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 9e 01 00 01 9a 03 03 75 28 78 ec 6f |...........u(x.o| -00000010 3d d0 60 09 8e 23 dd 91 67 4b e4 2f b0 b7 93 60 |=.`..#..gK./...`| -00000020 3a 4f 92 38 6b 5e 67 ab 49 f4 b8 20 46 e8 0a c4 |:O.8k^g.I.. F...| -00000030 bd 13 ce 09 13 27 a4 5d a4 3b e2 9b 9d ff 17 30 |.....'.].;.....0| -00000040 96 e3 06 1a d6 c6 04 9c f3 9a 15 76 00 08 13 02 |...........v....| -00000050 13 03 13 01 00 ff 01 00 01 49 00 00 00 0e 00 0c |.........I......| -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 06 00 04 00 1d 00 17 00 23 |...............#| -00000080 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................| -00000090 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................| -000000a0 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..| -000000b0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.| -000000c0 1d 00 20 a0 26 2f f2 a2 ca d0 ff 0d 5d 9e cc 84 |.. .&/......]...| -000000d0 52 51 07 86 4c 28 44 4e 65 7e 0c a1 9d 50 9c 77 |RQ..L(DNe~...P.w| -000000e0 8a 54 48 00 29 00 bc 00 87 00 81 50 46 ad c1 db |.TH.)......PF...| -000000f0 a8 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 |.8.{+....B>.....| -00000100 00 00 00 00 00 00 00 00 00 00 00 94 68 2c a3 81 |............h,..| -00000110 51 ed 14 ef 68 ca 42 c5 4c 1f 90 bf 3c 07 2b e5 |Q...h.B.L...<.+.| -00000120 52 22 a0 c0 46 db cb f6 b9 a0 b5 56 b0 d6 7f 03 |R"..F......V....| -00000130 b7 2d 9f a5 2a 25 8e 65 d2 b9 6a f3 e4 7e 79 d7 |.-..*%.e..j..~y.| -00000140 3d cc b2 3d b6 24 a9 31 82 49 38 16 92 f0 49 97 |=..=.$.1.I8...I.| -00000150 e2 07 e2 cd 1c 77 d3 e0 00 de 56 11 17 40 00 63 |.....w....V..@.c| -00000160 13 00 48 39 8e fd 09 96 08 f3 81 7c 00 00 00 00 |..H9.......|....| -00000170 00 31 30 da 3c 92 3d 0f 55 c9 9e bb 99 c6 e0 ac |.10.<.=.U.......| -00000180 fe 5a 3a 94 7e d6 2a 0a 81 c0 be 8a 4e 1d da 5e |.Z:.~.*.....N..^| -00000190 31 80 97 2d 2a 6a fc 96 03 d2 aa 07 45 f1 78 33 |1..-*j......E.x3| -000001a0 c4 1d 1c |...| +00000000 16 03 01 01 68 01 00 01 64 03 03 a0 27 b0 af b0 |....h...d...'...| +00000010 15 2c ed 88 b2 e8 c5 67 2e db 0d 29 13 64 bb 58 |.,.....g...).d.X| +00000020 3b 71 67 a9 47 65 8a 3c 09 44 29 20 46 fe 89 4b |;qg.Ge.<.D) F..K| +00000030 f3 1d ed 40 2d 5c 1b 23 26 f5 72 6f d1 b4 77 f5 |...@-\.#&.ro..w.| +00000040 1a 9f d1 98 34 46 fe 89 0b 2d c1 f9 00 04 13 01 |....4F...-......| +00000050 00 ff 01 00 01 17 00 0b 00 04 03 00 01 02 00 0a |................| +00000060 00 06 00 04 00 1d 00 17 00 23 00 00 00 16 00 00 |.........#......| +00000070 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 06 03 |................| +00000080 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| +00000090 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 2d 00 |.......+......-.| +000000a0 02 01 01 00 33 00 26 00 24 00 1d 00 20 8c 7b 61 |....3.&.$... .{a| +000000b0 71 c8 0b 1a 17 14 d9 eb 21 38 e6 2f c0 40 e9 2d |q.......!8./.@.-| +000000c0 3c 91 c5 4e 9d bb dd af 40 bc 91 38 74 00 29 00 |<..N....@..8t.).| +000000d0 9c 00 77 00 71 50 46 ad c1 db a8 38 86 7b 2b bb |..w.qPF....8.{+.| +000000e0 fd d0 c3 42 3e 00 00 00 00 00 00 00 00 00 00 00 |...B>...........| +000000f0 00 00 00 00 00 94 68 2c a3 82 51 ed 14 ef 68 ca |......h,..Q...h.| +00000100 42 c5 5c ab 26 c2 91 a9 01 83 13 26 8f 62 7c 89 |B.\.&......&.b|.| +00000110 c0 a2 b5 9b 6d 4f a4 c9 e2 49 34 03 2c b2 7d d9 |....mO...I4.,.}.| +00000120 af eb 1a 99 76 3c a5 ef 70 78 59 58 1c 45 80 c5 |....v<..pxYX.E..| +00000130 f1 b8 91 b2 54 71 3f bf 4f 2a b2 9d 9d 6f 6f 1c |....Tq?.O*...oo.| +00000140 f1 3c 6c e6 a2 73 00 00 00 00 00 21 20 7b 6e 44 |.>> Flow 2 (server to client) 00000000 16 03 03 00 58 02 00 00 54 03 03 cf 21 ad 74 e5 |....X...T...!.t.| 00000010 9a 61 11 be 1d 8c 02 1e 65 b8 91 c2 a2 11 16 7a |.a......e......z| -00000020 bb 8c 5e 07 9e 09 e2 c8 a8 33 9c 20 46 e8 0a c4 |..^......3. F...| -00000030 bd 13 ce 09 13 27 a4 5d a4 3b e2 9b 9d ff 17 30 |.....'.].;.....0| -00000040 96 e3 06 1a d6 c6 04 9c f3 9a 15 76 13 02 00 00 |...........v....| +00000020 bb 8c 5e 07 9e 09 e2 c8 a8 33 9c 20 46 fe 89 4b |..^......3. F..K| +00000030 f3 1d ed 40 2d 5c 1b 23 26 f5 72 6f d1 b4 77 f5 |...@-\.#&.ro..w.| +00000040 1a 9f d1 98 34 46 fe 89 0b 2d c1 f9 13 01 00 00 |....4F...-......| 00000050 0c 00 2b 00 02 03 04 00 33 00 02 00 17 14 03 03 |..+.....3.......| 00000060 00 01 01 |...| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 16 03 03 01 bf 01 00 01 bb 03 |................| -00000010 03 75 28 78 ec 6f 3d d0 60 09 8e 23 dd 91 67 4b |.u(x.o=.`..#..gK| -00000020 e4 2f b0 b7 93 60 3a 4f 92 38 6b 5e 67 ab 49 f4 |./...`:O.8k^g.I.| -00000030 b8 20 46 e8 0a c4 bd 13 ce 09 13 27 a4 5d a4 3b |. F........'.].;| -00000040 e2 9b 9d ff 17 30 96 e3 06 1a d6 c6 04 9c f3 9a |.....0..........| -00000050 15 76 00 08 13 02 13 03 13 01 00 ff 01 00 01 6a |.v.............j| -00000060 00 00 00 0e 00 0c 00 00 09 31 32 37 2e 30 2e 30 |.........127.0.0| -00000070 2e 31 00 0b 00 04 03 00 01 02 00 0a 00 06 00 04 |.1..............| -00000080 00 1d 00 17 00 23 00 00 00 16 00 00 00 17 00 00 |.....#..........| -00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................| -000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................| -000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....| -000000c0 33 00 47 00 45 00 17 00 41 04 79 db 79 c8 0b 77 |3.G.E...A.y.y..w| -000000d0 8b 37 30 65 85 ce 72 49 ab a1 cb 6a 06 00 a6 65 |.70e..rI...j...e| -000000e0 22 51 63 63 16 45 7b 85 ee c3 2e 09 25 d9 a3 49 |"Qcc.E{.....%..I| -000000f0 91 07 35 c4 b6 61 23 9c 91 c1 03 07 ad a2 77 02 |..5..a#.......w.| -00000100 61 93 05 cf 74 36 7a 66 ad 24 00 29 00 bc 00 87 |a...t6zf.$.)....| -00000110 00 81 50 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 |..PF....8.{+....| -00000120 42 3e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |B>..............| -00000130 00 00 94 68 2c a3 81 51 ed 14 ef 68 ca 42 c5 4c |...h,..Q...h.B.L| -00000140 1f 90 bf 3c 07 2b e5 52 22 a0 c0 46 db cb f6 b9 |...<.+.R"..F....| -00000150 a0 b5 56 b0 d6 7f 03 b7 2d 9f a5 2a 25 8e 65 d2 |..V.....-..*%.e.| -00000160 b9 6a f3 e4 7e 79 d7 3d cc b2 3d b6 24 a9 31 82 |.j..~y.=..=.$.1.| -00000170 49 38 16 92 f0 49 97 e2 07 e2 cd 1c 77 d3 e0 00 |I8...I......w...| -00000180 de 56 11 17 40 00 63 13 00 48 39 8e fd 09 96 08 |.V..@.c..H9.....| -00000190 f3 81 7c 00 00 00 00 00 31 30 e0 ac 7a 74 d9 50 |..|.....10..zt.P| -000001a0 c1 3b 1b 67 7b 5a 74 b0 39 db dd 92 6f 75 38 31 |.;.g{Zt.9...ou81| -000001b0 10 f4 98 dc ad af eb ac ef 11 0d 96 48 01 f8 10 |............H...| -000001c0 d6 e1 68 bf 88 a3 33 b9 9a b9 |..h...3...| +00000000 14 03 03 00 01 01 16 03 03 01 89 01 00 01 85 03 |................| +00000010 03 a0 27 b0 af b0 15 2c ed 88 b2 e8 c5 67 2e db |..'....,.....g..| +00000020 0d 29 13 64 bb 58 3b 71 67 a9 47 65 8a 3c 09 44 |.).d.X;qg.Ge.<.D| +00000030 29 20 46 fe 89 4b f3 1d ed 40 2d 5c 1b 23 26 f5 |) F..K...@-\.#&.| +00000040 72 6f d1 b4 77 f5 1a 9f d1 98 34 46 fe 89 0b 2d |ro..w.....4F...-| +00000050 c1 f9 00 04 13 01 00 ff 01 00 01 38 00 0b 00 04 |...........8....| +00000060 03 00 01 02 00 0a 00 06 00 04 00 1d 00 17 00 23 |...............#| +00000070 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................| +00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................| +00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..| +000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 47 00 45 00 |....-.....3.G.E.| +000000b0 17 00 41 04 6e 14 0d ac 3f 1a 2a 36 54 4f ec 9d |..A.n...?.*6TO..| +000000c0 da 5b 93 12 42 eb 58 11 1b 4c 5c 39 a2 32 b8 5b |.[..B.X..L\9.2.[| +000000d0 41 13 51 05 88 fe 45 d2 01 ef 8d 14 bc 96 de d3 |A.Q...E.........| +000000e0 1c e3 eb 0c a0 a7 a3 7c 1c b1 9e 38 c2 dc f6 35 |.......|...8...5| +000000f0 7b 5b 08 2e 00 29 00 9c 00 77 00 71 50 46 ad c1 |{[...)...w.qPF..| +00000100 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 |..8.{+....B>....| +00000110 00 00 00 00 00 00 00 00 00 00 00 00 94 68 2c a3 |.............h,.| +00000120 82 51 ed 14 ef 68 ca 42 c5 5c ab 26 c2 91 a9 01 |.Q...h.B.\.&....| +00000130 83 13 26 8f 62 7c 89 c0 a2 b5 9b 6d 4f a4 c9 e2 |..&.b|.....mO...| +00000140 49 34 03 2c b2 7d d9 af eb 1a 99 76 3c a5 ef 70 |I4.,.}.....v<..p| +00000150 78 59 58 1c 45 80 c5 f1 b8 91 b2 54 71 3f bf 4f |xYX.E......Tq?.O| +00000160 2a b2 9d 9d 6f 6f 1c f1 3c 6c e6 a2 73 00 00 00 |*...oo..>> Flow 4 (server to client) 00000000 16 03 03 00 a1 02 00 00 9d 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 46 e8 0a c4 |........... F...| -00000030 bd 13 ce 09 13 27 a4 5d a4 3b e2 9b 9d ff 17 30 |.....'.].;.....0| -00000040 96 e3 06 1a d6 c6 04 9c f3 9a 15 76 13 02 00 00 |...........v....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 46 fe 89 4b |........... F..K| +00000030 f3 1d ed 40 2d 5c 1b 23 26 f5 72 6f d1 b4 77 f5 |...@-\.#&.ro..w.| +00000040 1a 9f d1 98 34 46 fe 89 0b 2d c1 f9 13 01 00 00 |....4F...-......| 00000050 55 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |U.+.....3.E...A.| 00000060 1e 18 37 ef 0d 19 51 88 35 75 71 b5 e5 54 5b 12 |..7...Q.5uq..T[.| 00000070 2e 8f 09 67 fd a7 24 20 3e b2 56 1c ce 97 28 5e |...g..$ >.V...(^| 00000080 f8 2b 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 32 42 |.+-O....lK[.V.2B| 00000090 e9 58 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc 5a 89 |.X..I..h.A.Vk.Z.| -000000a0 00 29 00 02 00 00 17 03 03 00 17 48 f2 b1 a7 11 |.).........H....| -000000b0 68 36 e4 67 b8 e8 d0 6d b8 76 fa 4b 7e bc d0 63 |h6.g...m.v.K~..c| -000000c0 6a 8c 17 03 03 00 45 49 37 80 89 e3 4d b5 60 4a |j.....EI7...M.`J| -000000d0 7c 52 a0 f5 e9 32 85 ad 8a 59 0b 27 66 c7 2f ec ||R...2...Y.'f./.| -000000e0 55 7f 2c 9b 1e ef 0a 11 e1 72 1f 72 b2 10 9f 3f |U.,......r.r...?| -000000f0 bb 51 8f d0 fe e8 62 fd 93 e4 0d e1 57 7f 3a 3c |.Q....b.....W.:<| -00000100 22 b4 ca 20 04 cd 65 94 44 df 1a 1c 17 03 03 00 |".. ..e.D.......| -00000110 a3 38 02 96 5e c2 6d ad 2d 17 79 63 15 bd 06 af |.8..^.m.-.yc....| -00000120 e3 ae 5a 94 66 b5 2d 12 d1 bc 9c 16 56 ac 71 fe |..Z.f.-.....V.q.| -00000130 d7 af 1f 27 9a 22 1a d2 de da 90 ca d5 7f 79 d1 |...'."........y.| -00000140 8a 6e c6 76 e7 76 b4 cc 9b d5 b5 ed b5 b2 9d 4e |.n.v.v.........N| -00000150 f8 88 a0 b1 14 91 8b 6b d9 b8 5d 34 61 8a a3 b3 |.......k..]4a...| -00000160 c8 db e9 c9 8d a7 53 d8 46 f0 bd 4b 30 bf 49 3d |......S.F..K0.I=| -00000170 cc 42 d3 fb b7 f3 ad 78 5b 01 38 5d c3 22 d0 51 |.B.....x[.8].".Q| -00000180 cb a3 d9 fe 61 f9 4a ee 7d 89 8b 88 22 2b 9b fe |....a.J.}..."+..| -00000190 19 cd 17 b7 9e 81 57 f6 cb 14 29 cb 3b 87 0e 83 |......W...).;...| -000001a0 5a 84 7c 13 2d c8 d4 a7 6a db 1d 10 c6 04 ed 0d |Z.|.-...j.......| -000001b0 1d d7 06 bb |....| +000000a0 00 29 00 02 00 00 17 03 03 00 17 ea 86 30 48 65 |.)...........0He| +000000b0 cf a6 d4 9d af f7 75 d4 d3 dd af 79 ce 3a 42 5b |......u....y.:B[| +000000c0 68 7a 17 03 03 00 35 ef d6 22 53 ec 3c 27 84 c7 |hz....5.."S.<'..| +000000d0 7f b2 81 8e 3e 70 51 25 95 b4 6a 79 01 15 60 c0 |....>pQ%..jy..`.| +000000e0 39 eb 5b 90 7b 50 f5 3b 50 64 d2 b2 d6 c7 72 cf |9.[.{P.;Pd....r.| +000000f0 35 f3 25 1c 86 4b 69 ab 6e 50 86 2e 17 03 03 00 |5.%..Ki.nP......| +00000100 93 66 5a c1 de c6 92 96 95 92 48 90 e7 0f e1 08 |.fZ.......H.....| +00000110 25 b2 72 a5 7f c5 17 6e 70 5d 6e 68 78 32 72 8d |%.r....np]nhx2r.| +00000120 3a fa 7a 66 76 26 10 9e f9 92 ca 3b a7 6c 6c fa |:.zfv&.....;.ll.| +00000130 72 d1 22 f4 b0 b9 2a 90 bd ce 58 e4 ff 1d 88 99 |r."...*...X.....| +00000140 a4 8d f9 10 af c8 35 cd c4 6f 99 cd 9e 6c 95 b1 |......5..o...l..| +00000150 b7 6e a4 48 9e 75 f1 d3 c0 b3 27 f1 61 83 ea 13 |.n.H.u....'.a...| +00000160 06 7f 37 38 f1 31 9e 71 5a 97 15 b5 46 63 44 e8 |..78.1.qZ...FcD.| +00000170 f4 a1 fc 81 5d f4 c7 65 be 76 da 79 bd fb e4 e6 |....]..e.v.y....| +00000180 68 de ce f3 32 6b 0c ee 19 18 75 33 77 f2 34 3d |h...2k....u3w.4=| +00000190 9e c3 da b7 |....| >>> Flow 5 (client to server) -00000000 17 03 03 00 45 44 0b 11 40 bf 4b b4 2b 12 76 b3 |....ED..@.K.+.v.| -00000010 e4 59 b3 91 bb 45 21 b3 78 aa dc 76 66 dd d6 3c |.Y...E!.x..vf..<| -00000020 21 cf 32 5c 37 85 ef fb c7 53 cb 55 9c a5 40 0a |!.2\7....S.U..@.| -00000030 9d f8 aa b4 e3 e4 51 bf d8 cb 15 44 f0 02 19 52 |......Q....D...R| -00000040 62 73 82 f2 c2 ae d2 03 0e dc |bs........| +00000000 17 03 03 00 35 59 51 fe aa 0a 69 ef d5 0e ee e3 |....5YQ...i.....| +00000010 0e 21 f7 e0 80 88 a0 da 23 7a 38 7f 73 e1 da e9 |.!......#z8.s...| +00000020 7c 02 73 5e f2 64 e5 60 0e c6 d5 9e 7a 45 c2 0b ||.s^.d.`....zE..| +00000030 6f 08 46 46 5b f1 5b 67 5d 42 |o.FF[.[g]B| >>> Flow 6 (server to client) -00000000 17 03 03 00 1e fe e8 25 be 32 b9 ce db 3d 36 54 |.......%.2...=6T| -00000010 78 7c 70 50 0e 8e f4 04 ec a9 2e 88 7b e5 23 23 |x|pP........{.##| -00000020 72 f4 04 17 03 03 00 13 cc 7c 8e 1b 85 30 16 57 |r........|...0.W| -00000030 b0 39 6a 3a b3 ee 57 82 17 03 c9 |.9j:..W....| +00000000 17 03 03 00 1e 3c a5 86 73 ea 62 44 ee 3b 45 a2 |.....<..s.bD.;E.| +00000010 2a 57 ed 27 0e 65 40 48 23 10 7f ff 27 e5 4e d1 |*W.'.e@H#...'.N.| +00000020 99 9a e1 17 03 03 00 13 1e 78 1a 08 4b 24 1b fc |.........x..K$..| +00000030 78 e5 ab fd 8f bf 53 26 f9 b7 c0 |x.....S&...| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-ResumeDisabled b/libgo/go/crypto/tls/testdata/Server-TLSv13-ResumeDisabled index 1ba7ca1578b..9f14b602bdc 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-ResumeDisabled +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-ResumeDisabled @@ -1,104 +1,99 @@ >>> Flow 1 (client to server) -00000000 16 03 01 01 a4 01 00 01 a0 03 03 96 06 be 39 9a |..............9.| -00000010 6b 71 35 ab f4 2a d2 66 4d 8f 2c 86 c9 b6 7b e1 |kq5..*.fM.,...{.| -00000020 85 55 81 f5 90 49 20 c9 d7 5d ea 20 a2 da 4f 31 |.U...I ..]. ..O1| -00000030 a6 7a bd 07 5d 24 2e 88 1c 88 0e 19 1e 33 51 51 |.z..]$.......3QQ| -00000040 a1 14 df d7 70 b5 62 6d 28 a8 5f 0e 00 08 13 02 |....p.bm(._.....| -00000050 13 03 13 01 00 ff 01 00 01 4f 00 00 00 0e 00 0c |.........O......| -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 23 00 00 00 16 00 00 00 17 00 00 |.....#..........| -00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................| -000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................| -000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....| -000000c0 33 00 26 00 24 00 1d 00 20 6d b7 14 7e 1b 7e c5 |3.&.$... m..~.~.| -000000d0 2b 54 1e 88 bd 64 23 49 84 31 73 f0 b8 55 6c 23 |+T...d#I.1s..Ul#| -000000e0 9e 77 b9 c5 53 a5 7f 1d 15 00 29 00 bc 00 87 00 |.w..S.....).....| -000000f0 81 50 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 |.PF....8.{+....B| -00000100 3e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |>...............| -00000110 00 94 68 2c a3 81 51 ed 14 ef 68 ca 42 c5 4c e2 |..h,..Q...h.B.L.| -00000120 e9 ab 5a 10 63 08 88 5d 47 1a 77 c1 7c 72 14 12 |..Z.c..]G.w.|r..| -00000130 24 5f 79 c4 ce 1a 7c 08 bf 81 6d 0e 55 e6 2d 0d |$_y...|...m.U.-.| -00000140 00 68 79 bc 2d ea f4 19 fd 43 ef 51 3f b5 5f 49 |.hy.-....C.Q?._I| -00000150 38 16 e0 74 43 a4 e9 95 f6 6d eb bf 6d e2 57 79 |8..tC....m..m.Wy| -00000160 7a 6e 53 12 bd a2 e0 32 98 1d 4e cb ae 72 1f 4c |znS....2..N..r.L| -00000170 38 4c 00 00 00 00 00 31 30 b6 c5 6e 26 02 64 56 |8L.....10..n&.dV| -00000180 65 ab 95 9c 16 62 d0 c5 57 41 c7 4c 78 72 44 c7 |e....b..WA.LxrD.| -00000190 4f a4 dc e1 d3 ef 49 af 7d a1 e5 ce 6f 22 f9 ec |O.....I.}...o"..| -000001a0 f4 b3 e4 32 e3 99 b0 85 39 |...2....9| +00000000 16 03 01 01 6e 01 00 01 6a 03 03 0f 31 f0 17 d6 |....n...j...1...| +00000010 3e ee f6 b9 14 05 57 cb 41 0b a4 6a 2f 70 9e 69 |>.....W.A..j/p.i| +00000020 09 2a eb ec 9a f4 47 61 09 43 09 20 d2 5d cf 57 |.*....Ga.C. .].W| +00000030 b8 81 3c a5 0a 77 50 0a c3 88 79 7a dc d0 2f 8a |..<..wP...yz../.| +00000040 08 ea 5f 53 54 a6 ff 43 d2 03 55 0e 00 04 13 01 |.._ST..C..U.....| +00000050 00 ff 01 00 01 1d 00 0b 00 04 03 00 01 02 00 0a |................| +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 00 0d 00 1e 00 1c |................| +00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................| +00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..| +000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.| +000000b0 1d 00 20 b4 ef 07 d4 1b 0e a1 42 ee f1 f3 84 3e |.. .......B....>| +000000c0 9f fe bb a6 af 59 9d 04 96 03 1b 43 1a b8 f7 7f |.....Y.....C....| +000000d0 44 64 60 00 29 00 9c 00 77 00 71 50 46 ad c1 db |Dd`.)...w.qPF...| +000000e0 a8 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 |.8.{+....B>.....| +000000f0 00 00 00 00 00 00 00 00 00 00 00 94 68 2c a3 82 |............h,..| +00000100 51 ed 14 ef 68 ca 42 c5 5c 90 6b 88 83 a9 b3 63 |Q...h.B.\.k....c| +00000110 7c 1c 04 ce dd be 5a 26 ef 4e 37 52 ea 9a 45 6b ||.....Z&.N7R..Ek| +00000120 ea 89 a5 26 7d c3 ea 67 db 99 76 3c e5 52 89 d0 |...&}..g..v<.R..| +00000130 4b 46 41 2e 62 5c ce a8 2e 9a 67 e9 52 f0 40 d2 |KFA.b\....g.R.@.| +00000140 f1 0e ab 02 0f 54 c8 0b 5e 91 8f 8b 00 00 00 00 |.....T..^.......| +00000150 00 21 20 e0 71 35 06 a0 30 9f bf 5a 6e f3 14 fd |.! .q5..0..Zn...| +00000160 34 0b 6d d5 36 08 82 8f d0 79 cc f3 74 7c a9 a5 |4.m.6....y..t|..| +00000170 c3 81 27 |..'| >>> 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 a2 da 4f 31 |........... ..O1| -00000030 a6 7a bd 07 5d 24 2e 88 1c 88 0e 19 1e 33 51 51 |.z..]$.......3QQ| -00000040 a1 14 df d7 70 b5 62 6d 28 a8 5f 0e 13 02 00 00 |....p.bm(._.....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 d2 5d cf 57 |........... .].W| +00000030 b8 81 3c a5 0a 77 50 0a c3 88 79 7a dc d0 2f 8a |..<..wP...yz../.| +00000040 08 ea 5f 53 54 a6 ff 43 d2 03 55 0e 13 01 00 00 |.._ST..C..U.....| 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 5a 35 3d 19 9b a7 |..........Z5=...| -00000090 a4 45 2c c3 09 ae 85 be 08 fe 1d e2 9a 5d 7a 4b |.E,..........]zK| -000000a0 8e 17 03 03 02 6d 87 db fb 18 21 96 c7 2b fb ff |.....m....!..+..| -000000b0 89 b9 25 f6 0d 89 0f b4 17 bb 17 e1 ba 95 b7 cd |..%.............| -000000c0 c2 75 b5 8b d8 64 ff 7c dc e2 97 32 0c 2f e0 9f |.u...d.|...2./..| -000000d0 db b9 ef 14 9d cc e4 68 44 f7 0a 55 d2 b1 a0 f7 |.......hD..U....| -000000e0 fc de a5 99 f0 5d 0c 60 7b c3 25 85 f6 79 8f e6 |.....].`{.%..y..| -000000f0 cd 43 1c 43 d9 cd 28 ea ce 10 1c 16 68 b8 d7 3d |.C.C..(.....h..=| -00000100 b4 d4 db b4 bf 76 f8 45 23 d8 9f d1 be d1 bd db |.....v.E#.......| -00000110 9c 45 dd 28 3b 68 22 57 6c b7 65 fc 5e 66 f6 cb |.E.(;h"Wl.e.^f..| -00000120 a2 88 bd 96 e4 00 b5 85 ae 00 95 b9 da 42 16 c9 |.............B..| -00000130 c9 63 c2 67 ec 22 65 6e 66 0e cf de 68 ad e7 87 |.c.g."enf...h...| -00000140 ae 63 b4 e9 1c c0 2f 1e 79 7e a3 3f 6d 2b 68 c1 |.c..../.y~.?m+h.| -00000150 e8 60 cd 26 e0 05 de fa 7b 77 45 71 d8 f9 03 d7 |.`.&....{wEq....| -00000160 d3 50 51 15 cf fc 39 fa 07 19 28 5e e8 2d 31 00 |.PQ...9...(^.-1.| -00000170 2a e1 a4 21 31 83 4e 7d 51 e7 53 eb 33 22 51 fe |*..!1.N}Q.S.3"Q.| -00000180 15 04 e9 3d 73 89 3b 56 3f c6 ec 6e 0a 71 68 a6 |...=s.;V?..n.qh.| -00000190 76 f3 f1 aa 4e d0 9f 85 45 3f 7b aa ae ad 42 b9 |v...N...E?{...B.| -000001a0 07 64 ab ad 03 b1 33 78 93 f0 49 95 65 fb 81 8c |.d....3x..I.e...| -000001b0 04 ee e7 f3 2c 0a 99 51 e5 ef 05 14 d3 93 37 2b |....,..Q......7+| -000001c0 73 96 81 6f f5 9b a3 9a 20 95 5c 13 fc 97 3e c0 |s..o.... .\...>.| -000001d0 87 e4 ec 00 84 0b f2 09 29 63 dd 54 03 ce e0 43 |........)c.T...C| -000001e0 e9 16 a0 98 32 3e fa 58 1d 81 1e 56 ef 64 ff f7 |....2>.X...V.d..| -000001f0 b0 aa fc 5f 8c 89 48 76 ef d2 f1 d0 9c 16 f9 57 |..._..Hv.......W| -00000200 ac a6 4a a4 a8 75 ae fc 4b 9f ef 3c 28 a5 0c c1 |..J..u..K..<(...| -00000210 c8 72 82 bf e9 93 f2 42 00 0a 49 5d be c7 09 91 |.r.....B..I]....| -00000220 29 40 5e a6 ad ae 9c 69 6f d8 33 53 0a 50 5b 48 |)@^....io.3S.P[H| -00000230 7d d7 7e 1e 3b d3 ec e6 cf fe 1e 6a 27 a2 83 35 |}.~.;......j'..5| -00000240 28 13 2f 00 e5 29 c3 10 46 53 a1 17 15 59 5d 74 |(./..)..FS...Y]t| -00000250 f5 7c fa a5 71 34 32 75 48 e6 2c 1d 90 e8 c1 87 |.|..q42uH.,.....| -00000260 50 ac 17 27 b8 f7 a9 8e 59 58 d6 b8 d9 ef b6 57 |P..'....YX.....W| -00000270 b8 13 41 d0 eb 80 1c 48 66 1d 41 a5 b5 0d 12 17 |..A....Hf.A.....| -00000280 52 96 62 29 0e 4a 09 b4 50 b8 37 c3 8f 85 67 27 |R.b).J..P.7...g'| -00000290 d9 6f 33 11 95 ca 0a 36 75 ef 15 45 81 d3 ad 7d |.o3....6u..E...}| -000002a0 1a ff a7 0c 47 21 37 24 27 ce 42 68 5f 5d 7c fe |....G!7$'.Bh_]|.| -000002b0 0c f2 0b 81 ea f9 25 c9 99 c2 56 72 54 bd 2f 4c |......%...VrT./L| -000002c0 40 17 f0 54 a0 6e 1d 14 80 9c 3c d3 f9 81 0d 9d |@..T.n....<.....| -000002d0 e1 47 55 24 e4 62 0e 14 0d 46 3f 52 1b ef ab 45 |.GU$.b...F?R...E| -000002e0 d8 86 c7 ef aa e2 ea e6 5e 2e d8 89 33 46 a0 d0 |........^...3F..| -000002f0 39 e2 cc 13 1d 62 11 ae c0 73 71 b8 ef 4b 43 71 |9....b...sq..KCq| -00000300 dd 14 42 09 c9 10 4e bc b9 93 78 d6 83 02 40 c0 |..B...N...x...@.| -00000310 62 56 40 17 03 03 00 99 6e 03 4b 38 20 98 d7 3e |bV@.....n.K8 ..>| -00000320 52 33 e0 be 26 9b 38 4c 7f 2b c1 cc 84 22 7e 86 |R3..&.8L.+..."~.| -00000330 1d 39 f6 0a c0 ff e9 d9 4d 81 24 26 8d e1 c5 c0 |.9......M.$&....| -00000340 78 18 59 e0 6a ac 35 ad a0 6d 32 09 63 75 88 10 |x.Y.j.5..m2.cu..| -00000350 2b 6b d1 36 ea f9 03 41 a9 a7 26 82 38 37 aa 81 |+k.6...A..&.87..| -00000360 a1 7a 81 5c 0b db 63 32 06 e7 cb a8 1c 0a ff be |.z.\..c2........| -00000370 a2 e5 00 42 59 61 78 40 2e e2 85 0a ad 6b ea ae |...BYax@.....k..| -00000380 17 5a 92 f6 d3 8e 97 a2 18 a5 28 8a 41 1d 70 26 |.Z........(.A.p&| -00000390 bc d8 e7 38 ba c5 68 b9 ae f9 c6 27 bc 5b 3b 9f |...8..h....'.[;.| -000003a0 db ae 38 84 6f 18 3c e6 1d 30 cb 57 b1 95 63 1d |..8.o.<..0.W..c.| -000003b0 ef 17 03 03 00 45 40 43 00 0c 81 0a ed cf 35 9d |.....E@C......5.| -000003c0 45 0f 2b 66 ad b6 bd f9 72 9f 77 aa 87 9a 4f 9a |E.+f....r.w...O.| -000003d0 f4 1b 08 bd 33 aa f7 dc f1 78 58 d7 53 aa 82 12 |....3....xX.S...| -000003e0 b1 f7 c2 dd 8b 0d 90 81 e9 a9 7b 7c 17 52 fe ab |..........{|.R..| -000003f0 e4 94 06 d4 44 b4 7d 81 61 97 6b |....D.}.a.k| +00000080 03 03 00 01 01 17 03 03 00 17 df 85 83 6b 9d e0 |.............k..| +00000090 8d b4 da b1 f2 c7 ff c1 13 33 d4 53 b8 92 bf 83 |.........3.S....| +000000a0 6c 17 03 03 02 6d 6b 0f f6 15 41 46 aa 92 06 af |l....mk...AF....| +000000b0 c9 a2 73 c5 31 64 c1 cd 3a e5 e6 9a d9 04 f4 01 |..s.1d..:.......| +000000c0 d5 0e d6 30 e2 7a 6d 0c 23 d5 4b b1 70 58 c8 ca |...0.zm.#.K.pX..| +000000d0 5d 1f c9 7c 76 f8 f9 90 b0 f6 05 f6 85 d2 10 b6 |]..|v...........| +000000e0 bb b1 49 07 8a ba 9b d8 1a f4 48 18 f5 c5 90 f1 |..I.......H.....| +000000f0 a7 24 cd 3b ab 2f 49 28 fa 3c 64 80 50 a6 38 d9 |.$.;./I(..H2..| +00000170 37 13 08 f2 cc cb bb f5 55 d5 7d 97 5e 6a df 11 |7.......U.}.^j..| +00000180 33 fd 34 65 99 c2 40 7b a3 7a 04 92 63 ad 19 9d |3.4e..@{.z..c...| +00000190 02 2a 6f d1 c8 f7 e1 d1 0f a1 c3 5b 81 70 b0 e5 |.*o........[.p..| +000001a0 97 a4 b2 76 c5 9b 55 f5 da 2d 53 d2 49 4b a7 6a |...v..U..-S.IK.j| +000001b0 0f 0f c8 d6 a5 00 83 52 fb 12 c6 6b 98 51 a3 4e |.......R...k.Q.N| +000001c0 86 39 ab 7e 76 1f 31 b5 5e 50 53 1b 21 af 7f a0 |.9.~v.1.^PS.!...| +000001d0 b9 3c cf 59 19 c7 c8 b6 ef d7 4f e5 ea 5e bc 67 |.<.Y......O..^.g| +000001e0 00 47 97 50 85 15 54 19 eb de b8 11 0e 39 9a b0 |.G.P..T......9..| +000001f0 be cd db d9 53 88 9c 78 e8 b9 5e 12 4b 30 63 d5 |....S..x..^.K0c.| +00000200 eb 48 d1 d4 95 94 58 61 9c 53 ad 97 bd 45 3a 09 |.H....Xa.S...E:.| +00000210 d0 83 a7 ba 8c 64 87 42 b7 e1 fa 1b 32 58 8b de |.....d.B....2X..| +00000220 70 34 34 6d fb 0f a0 27 c3 8b 69 61 43 30 24 b2 |p44m...'..iaC0$.| +00000230 32 4b ca 6c 0b ea f7 4b df e5 5f 3d 06 ea 0d 31 |2K.l...K.._=...1| +00000240 4a c6 19 44 61 a1 5b 45 ee 9b ea 69 42 8f 35 86 |J..Da.[E...iB.5.| +00000250 09 c7 83 51 32 e6 7b 45 bb fb 11 1f 4d 3f b8 10 |...Q2.{E....M?..| +00000260 6a 0c 52 4c fd 20 62 0f 75 26 8a 65 67 e9 7e 56 |j.RL. b.u&.eg.~V| +00000270 f4 ed 01 67 9e 27 0d 39 98 b4 97 44 50 f6 26 11 |...g.'.9...DP.&.| +00000280 3c e4 40 17 5c f1 eb 85 1f 13 f9 8d 22 66 2d 2e |<.@.\......."f-.| +00000290 3b f8 eb 08 7d df f6 ba 7b ec 15 34 04 e2 6d aa |;...}...{..4..m.| +000002a0 e2 1c 5a e6 e8 4f 00 0c 07 1b dd 6e 07 03 ed 6d |..Z..O.....n...m| +000002b0 df c0 7d ed 05 84 bb ad 0c 1f df 8b 8d 0a ad 33 |..}............3| +000002c0 90 38 44 db 8a 32 9f 9d b3 ae 2e 92 d6 ab d3 25 |.8D..2.........%| +000002d0 12 32 2d 6e a9 17 0d c9 f9 79 25 17 f0 62 1b 91 |.2-n.....y%..b..| +000002e0 ad d5 2d ec 0d ea cd c4 86 77 04 92 ab a8 8d ea |..-......w......| +000002f0 ce fc 13 7b a0 ca 32 96 50 49 99 dd 25 d7 73 93 |...{..2.PI..%.s.| +00000300 f2 00 72 ca 31 07 fd 7e 12 8a 8b 76 51 4e fe 30 |..r.1..~...vQN.0| +00000310 4d 5c 65 17 03 03 00 99 5b 19 25 c3 5a 4d f0 bd |M\e.....[.%.ZM..| +00000320 71 0e 48 63 61 bb 55 6b d3 26 81 25 cf ea 45 e6 |q.Hca.Uk.&.%..E.| +00000330 52 e4 4e c9 5a a8 c2 e2 72 97 51 8a 38 c6 8d 27 |R.N.Z...r.Q.8..'| +00000340 8d df 09 ce 37 87 a6 41 cb c4 bd 6d 19 ef 56 1a |....7..A...m..V.| +00000350 e8 79 df ad 76 9e a6 92 e3 da b3 a6 0d 9f 6f 6f |.y..v.........oo| +00000360 3f 76 0b 62 b4 cf 2c 5b 24 65 bd c1 90 bb 88 ec |?v.b..,[$e......| +00000370 8b 0c 7d 6b 42 38 26 78 62 5c b0 21 74 95 5f fe |..}kB8&xb\.!t._.| +00000380 68 7d 31 8c 5f f5 dc a4 f0 23 6b 75 be 70 ea b3 |h}1._....#ku.p..| +00000390 19 cc 83 9b 8a f6 cb cc 04 2e 66 b5 77 bb 11 68 |..........f.w..h| +000003a0 56 85 0c b1 b8 b1 4e ed ca bd ea 3c 91 38 8a 63 |V.....N....<.8.c| +000003b0 f3 17 03 03 00 35 06 2f 99 10 0c 41 cf 70 d2 aa |.....5./...A.p..| +000003c0 f9 74 e7 3a cb bb 77 1c e6 5c bf f9 3f 02 df af |.t.:..w..\..?...| +000003d0 ba 08 fa f7 42 60 ad de 65 62 2e 54 5f 35 90 4f |....B`..eb.T_5.O| +000003e0 9c b1 34 3d 5d f5 6e 04 d8 5a 50 |..4=].n..ZP| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 0e e9 bb 83 d4 |..........E.....| -00000010 41 da c6 75 69 c2 5c 74 0c 86 c7 b9 08 2f 35 da |A..ui.\t...../5.| -00000020 19 6f cf 43 a4 23 2f fe 59 5d 0f 1f 1e 0f ca e4 |.o.C.#/.Y]......| -00000030 7f 4e 7d bc ce 77 76 f2 ce 1c c4 e8 4e a9 80 a8 |.N}..wv.....N...| -00000040 72 16 5b 3c 97 8f 55 cb 76 cf fa 02 29 41 af 6d |r.[<..U.v...)A.m| +00000000 14 03 03 00 01 01 17 03 03 00 35 7e dc fc 3f 66 |..........5~..?f| +00000010 cb ed 57 e3 5c 83 19 22 31 18 cb eb d5 b8 d2 3c |..W.\.."1......<| +00000020 6c 10 1f be 5c 04 cf 88 6b ec 04 3d aa 0d 15 68 |l...\...k..=...h| +00000030 e4 42 bb c9 86 12 ef f7 90 c4 f5 41 39 56 62 d0 |.B.........A9Vb.| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e f2 5e b6 bd bc c3 c2 58 fe 90 e9 |......^.....X...| -00000010 07 07 a2 ab 66 41 f7 c4 1f 48 48 01 c9 38 d2 c7 |....fA...HH..8..| -00000020 c0 ab b5 17 03 03 00 13 db 6e 0e f9 4a 94 12 a3 |.........n..J...| -00000030 2a 86 3f d1 a7 ac c3 58 20 0d 09 |*.?....X ..| +00000000 17 03 03 00 1e ee b9 1c 7b 56 61 76 91 40 90 11 |........{Vav.@..| +00000010 61 4a 0c 46 60 e2 c1 a7 dd 0c a1 0d da 65 98 3e |aJ.F`........e.>| +00000020 30 62 98 17 03 03 00 13 27 7a 29 e5 53 f1 9b 41 |0b......'z).S..A| +00000030 7a 19 ec cd 29 0e 04 57 90 59 7e |z...)..W.Y~| diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv13-X25519 b/libgo/go/crypto/tls/testdata/Server-TLSv13-X25519 index 244651268a6..0160c5aea7a 100644 --- a/libgo/go/crypto/tls/testdata/Server-TLSv13-X25519 +++ b/libgo/go/crypto/tls/testdata/Server-TLSv13-X25519 @@ -1,102 +1,98 @@ >>> Flow 1 (client to server) -00000000 16 03 01 00 d8 01 00 00 d4 03 03 3d 42 5b bc 55 |...........=B[.U| -00000010 6c e3 e9 9a db 07 85 ca 18 fb f3 e0 56 18 b5 39 |l...........V..9| -00000020 9d 43 91 41 38 a0 ea c1 eb db ec 20 ca b8 c3 6e |.C.A8...... ...n| -00000030 c8 78 18 88 ab cf c3 cb 7e ff 7d e5 7e d5 55 94 |.x......~.}.~.U.| -00000040 f8 b2 01 ad 8c 95 82 f0 8e d8 61 8e 00 08 13 02 |..........a.....| -00000050 13 03 13 01 00 ff 01 00 00 83 00 00 00 0e 00 0c |................| -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 04 00 02 00 1d 00 16 00 00 |................| -00000080 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 06 03 |................| -00000090 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................| -000000a0 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 2d 00 |.......+......-.| -000000b0 02 01 01 00 33 00 26 00 24 00 1d 00 20 e8 82 c0 |....3.&.$... ...| -000000c0 e9 dc b5 e1 3f 74 c9 42 e9 98 d1 1b fb 68 52 5d |....?t.B.....hR]| -000000d0 3e c1 65 56 6c 12 2b 3b ad 02 7c 80 42 |>.eVl.+;..|.B| +00000000 16 03 01 00 c2 01 00 00 be 03 03 cb 53 78 a8 58 |............Sx.X| +00000010 de 5b 75 c2 c5 b3 ac fa c3 6e 85 a7 e5 a3 a4 ca |.[u......n......| +00000020 1f 82 95 38 fa 79 4c e2 c8 66 8a 20 be 7a 94 d6 |...8.yL..f. .z..| +00000030 f4 82 e2 2f 3b 2c e4 5f ae c2 8b be d1 2f b6 67 |.../;,._...../.g| +00000040 9e 78 7a 51 86 1f c1 d9 8f 43 2f 78 00 04 13 03 |.xzQ.....C/x....| +00000050 00 ff 01 00 00 71 00 0b 00 04 03 00 01 02 00 0a |.....q..........| +00000060 00 04 00 02 00 1d 00 16 00 00 00 17 00 00 00 0d |................| +00000070 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................| +00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................| +00000090 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.| +000000a0 26 00 24 00 1d 00 20 7f 3e a2 2e 2f 88 8a e1 f3 |&.$... .>../....| +000000b0 6a a4 47 d7 6d b7 3c 02 c4 bb f6 de 41 38 50 74 |j.G.m.<.....A8Pt| +000000c0 29 21 f5 fe 9f 0b 6f |)!....o| >>> 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 ca b8 c3 6e |........... ...n| -00000030 c8 78 18 88 ab cf c3 cb 7e ff 7d e5 7e d5 55 94 |.x......~.}.~.U.| -00000040 f8 b2 01 ad 8c 95 82 f0 8e d8 61 8e 13 02 00 00 |..........a.....| +00000020 00 00 00 00 00 00 00 00 00 00 00 20 be 7a 94 d6 |........... .z..| +00000030 f4 82 e2 2f 3b 2c e4 5f ae c2 8b be d1 2f b6 67 |.../;,._...../.g| +00000040 9e 78 7a 51 86 1f c1 d9 8f 43 2f 78 13 03 00 00 |.xzQ.....C/x....| 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 09 03 3f 82 c1 8c |............?...| -00000090 42 42 8d be 40 51 f5 ba 5d b8 60 d9 87 0f d5 ca |BB..@Q..].`.....| -000000a0 3d 17 03 03 02 6d 95 e6 a7 87 7a 4a fb 68 16 3b |=....m....zJ.h.;| -000000b0 38 cb b0 7c 97 39 1e 00 46 7b 2c 32 00 02 6c 34 |8..|.9..F{,2..l4| -000000c0 de df 5a 3d 11 1b bc 28 d4 c1 05 fc 0c ca 28 e3 |..Z=...(......(.| -000000d0 90 c7 ad 88 43 45 12 fd 43 f5 be 7d 46 f8 d2 ec |....CE..C..}F...| -000000e0 00 8e 06 6f 09 0d ce 84 15 5a e7 59 1c f7 10 d4 |...o.....Z.Y....| -000000f0 2d 37 f2 71 a7 11 7e cb 3b 75 ec 8f d1 7a 8c d0 |-7.q..~.;u...z..| -00000100 f0 b1 18 aa 2f 3b e8 18 ff ae 0f 63 6b 41 3e 4a |..../;.....ckA>J| -00000110 04 56 72 1b e0 60 74 a2 ef 1d 81 61 eb 94 56 25 |.Vr..`t....a..V%| -00000120 e6 46 03 9a 2f 57 85 ca 3a f4 17 81 e3 cf 6c 2e |.F../W..:.....l.| -00000130 63 66 48 0f 5f f7 7b 5a 55 25 4b cc 24 c9 71 dd |cfH._.{ZU%K.$.q.| -00000140 42 32 d8 77 6f c5 69 bb 6b c5 c9 51 cb 37 97 ae |B2.wo.i.k..Q.7..| -00000150 c3 a3 87 5c 50 e1 f3 19 84 d6 9a 7c 56 0d 63 cc |...\P......|V.c.| -00000160 57 66 17 c8 a6 e2 f0 31 bb 20 3b 7e 9e 4e 30 fe |Wf.....1. ;~.N0.| -00000170 1e 22 07 71 29 76 c0 a2 7e da 3c 1d 04 31 f8 54 |.".q)v..~.<..1.T| -00000180 95 3a 84 71 d8 6b ed 43 e9 ad e9 45 c9 72 ad 0e |.:.q.k.C...E.r..| -00000190 8d 02 21 a6 89 6f 4b 83 5f fd 7f ff 3e cb d0 f7 |..!..oK._...>...| -000001a0 d3 94 54 7a 82 47 d3 8f 21 2f 1b f8 bf 95 e9 34 |..Tz.G..!/.....4| -000001b0 cd 06 d6 77 04 c8 57 49 df 0a c0 84 c7 ec 86 ed |...w..WI........| -000001c0 75 ca 33 56 b4 e8 d3 7c 45 e7 b4 c8 92 9a 73 c8 |u.3V...|E.....s.| -000001d0 eb 30 df 76 d2 61 70 9a 31 c5 a1 d8 4f 3a 1f dc |.0.v.ap.1...O:..| -000001e0 df 3d 85 9f b8 48 ed 78 aa 9e c1 ba 07 84 30 ec |.=...H.x......0.| -000001f0 e5 83 1c 63 47 53 2c 06 85 40 a9 78 ea 4e a0 e3 |...cGS,..@.x.N..| -00000200 2f 7d 67 39 38 c2 80 66 ff 62 8e 68 1f 67 17 b8 |/}g98..f.b.h.g..| -00000210 6b af 3c cc 81 46 5a 83 bf 1e ed 65 0e 81 05 fa |k.<..FZ....e....| -00000220 ac 06 df 63 4e af 9e 02 7f 16 2b 5f b4 0a 5e d9 |...cN.....+_..^.| -00000230 e5 d1 39 4a 42 d5 34 43 9b 32 ba d8 b7 ad c8 b0 |..9JB.4C.2......| -00000240 38 81 6f 93 8e 5e ee b7 86 75 d8 f4 bb 15 33 5e |8.o..^...u....3^| -00000250 a8 39 e4 ee 7f ef 15 7b ec e1 d7 95 31 e1 83 db |.9.....{....1...| -00000260 00 34 2e 22 02 59 33 2a a6 b5 73 f7 04 4d f5 40 |.4.".Y3*..s..M.@| -00000270 b7 97 97 33 a0 e2 c3 cf 4b 0a bd 27 84 a1 bb 0b |...3....K..'....| -00000280 2c 59 bd 3e 2c 82 48 b6 a5 b8 a9 20 00 37 8a 8e |,Y.>,.H.... .7..| -00000290 f8 f2 4e e2 16 5c fb bf 92 94 37 6a 82 b8 b1 35 |..N..\....7j...5| -000002a0 4f 77 9e dd 78 1a 07 85 42 3d de fc dc 7f 8c f4 |Ow..x...B=......| -000002b0 fa 30 de 15 a4 dd c2 08 d5 3d 08 f4 a8 0f f0 df |.0.......=......| -000002c0 6c 18 40 65 49 ce ce 78 99 5c bc 96 f2 02 2a 1b |l.@eI..x.\....*.| -000002d0 5f e7 3d 50 ea 9c b4 39 84 33 05 df 3d 1c 3c f7 |_.=P...9.3..=.<.| -000002e0 3e 55 b6 08 1b 51 b2 87 2b bb 0e 78 1d 7c 19 16 |>U...Q..+..x.|..| -000002f0 1f 8c ab 6c 56 2b 08 8b 57 2e f9 90 d9 50 a1 30 |...lV+..W....P.0| -00000300 14 05 54 26 3b 03 0c 46 ec b3 bd c7 eb ce b7 d7 |..T&;..F........| -00000310 31 64 40 17 03 03 00 99 d5 7d 3d d2 c0 c4 23 6b |1d@......}=...#k| -00000320 2c 1b 87 70 62 8c c5 63 6b 34 5b 69 e6 2d 61 7a |,..pb..ck4[i.-az| -00000330 7f 8d 36 96 68 30 71 4b 5c 60 3a dc 28 58 80 ef |..6.h0qK\`:.(X..| -00000340 09 60 e0 fd 64 d4 fb e5 d3 2f 0a 03 52 78 e4 0b |.`..d..../..Rx..| -00000350 c8 03 d2 0d 13 36 19 46 50 41 ee 07 44 f8 cc 0b |.....6.FPA..D...| -00000360 53 f9 42 0d 75 88 6f d0 52 02 67 22 bf df 4b a3 |S.B.u.o.R.g"..K.| -00000370 0a 43 10 54 27 53 49 5d b3 41 37 df 5b 22 7b b4 |.C.T'SI].A7.["{.| -00000380 52 21 c7 55 bd 99 a9 0a 0e 46 07 99 b0 38 dc 53 |R!.U.....F...8.S| -00000390 0e f2 76 82 d9 15 35 62 bb 6d 87 10 a9 91 74 ad |..v...5b.m....t.| -000003a0 b6 8e 4f 22 b8 72 05 5e de 06 e4 de 70 b3 7b 72 |..O".r.^....p.{r| -000003b0 3e 17 03 03 00 45 ae 7c de bb a6 79 ca fd 6c fa |>....E.|...y..l.| -000003c0 26 8b b2 6a eb 40 c0 b0 a7 98 e8 7a 0c e9 ea b3 |&..j.@.....z....| -000003d0 30 5f b7 fd 52 85 c8 56 93 dc 3a b0 e8 bd 5a d1 |0_..R..V..:...Z.| -000003e0 2d 94 87 27 c9 4c 57 66 35 bb e7 a5 d2 bf fd 27 |-..'.LWf5......'| -000003f0 f7 bd e1 8c a7 50 35 64 cc d5 26 17 03 03 00 a3 |.....P5d..&.....| -00000400 0d a3 74 9e 7e 5c bf d9 cb 27 e0 d2 c6 25 bd 29 |..t.~\...'...%.)| -00000410 49 23 76 24 91 a8 d0 58 28 60 1d 68 75 ec f8 05 |I#v$...X(`.hu...| -00000420 18 dd 0d b3 a8 27 98 82 78 81 e1 ee 03 69 8f 26 |.....'..x....i.&| -00000430 00 94 59 63 ef 9b c9 24 0f c8 99 97 64 4c a3 41 |..Yc...$....dL.A| -00000440 71 71 88 55 cd a2 61 e9 47 ed 9b e0 5b a8 f9 dc |qq.U..a.G...[...| -00000450 e6 25 8a 1d e8 18 12 1a 3c b7 d6 86 cc 4b 9f 70 |.%......<....K.p| -00000460 93 53 cf 8e d2 98 99 74 2a 37 96 07 a9 d5 bd 8e |.S.....t*7......| -00000470 eb 09 01 a4 4d 46 c8 7b ab 2c 2d 25 7c fc 89 e6 |....MF.{.,-%|...| -00000480 ac 23 92 98 de 38 1b e4 70 b3 ee 95 9b 83 03 ce |.#...8..p.......| -00000490 bb 17 df 13 1d 5a 9f be 55 3f dc 28 4b 43 4e fd |.....Z..U?.(KCN.| -000004a0 74 00 19 |t..| +00000080 03 03 00 01 01 17 03 03 00 17 fb 0e 8b 72 0d 35 |.............r.5| +00000090 97 db e2 2e b8 20 be 96 27 6b cd ab 6b 24 5b c4 |..... ..'k..k$[.| +000000a0 e9 17 03 03 02 6d 3a 21 03 ea 45 e9 4e f1 19 1e |.....m:!..E.N...| +000000b0 33 37 04 5b 3e db 54 f0 27 6f c7 96 78 50 01 46 |37.[>.T.'o..xP.F| +000000c0 d1 8b 8f 79 70 21 9d 62 97 b9 bf 6d 14 e5 82 f4 |...yp!.b...m....| +000000d0 ad 89 90 77 12 1f 61 8e 1d 94 d3 27 0f 0e eb 77 |...w..a....'...w| +000000e0 8d b2 2f fb 58 b4 ee 88 19 91 47 d1 3d 10 9e 4a |../.X.....G.=..J| +000000f0 1e 41 b9 c6 41 8f 59 11 7f e0 ac e7 b9 d5 be 40 |.A..A.Y........@| +00000100 cc aa bc ab 56 5a 2b a9 c9 cf df c0 dc 8f d2 9d |....VZ+.........| +00000110 59 a7 88 36 98 2e 87 c6 1d af 26 a1 e8 08 2d bd |Y..6......&...-.| +00000120 9b 5b 1c 4e 22 d2 a1 7c 4d 0b 0f af da 5d fe f7 |.[.N"..|M....]..| +00000130 83 4d f6 54 c1 fe 03 73 6d c9 17 02 6b 78 09 91 |.M.T...sm...kx..| +00000140 aa 61 9a 93 04 66 fa 6b e8 2e d7 18 d2 4d 6e 25 |.a...f.k.....Mn%| +00000150 c3 01 2f a5 0e 1b da a1 64 67 e5 a5 c0 5b ef ec |../.....dg...[..| +00000160 83 5a d3 0e 44 b7 d5 97 9c c7 c4 94 b4 4b 01 e6 |.Z..D........K..| +00000170 48 28 21 cb 04 10 be b0 3b 53 df 15 47 12 67 ea |H(!.....;S..G.g.| +00000180 24 65 a1 ce 0b af 05 5b c9 95 bf 28 2e 55 3c 21 |$e.....[...(.UT.,..?.......| +000002b0 71 6a d6 0f 53 5e ea 92 53 e3 dd 96 be 38 61 74 |qj..S^..S....8at| +000002c0 5d 74 ac c4 8c 72 c6 82 dc f4 22 fb 5c 64 0f 33 |]t...r....".\d.3| +000002d0 b3 31 a1 a9 e0 6d 96 14 0b e1 00 7d 42 44 45 02 |.1...m.....}BDE.| +000002e0 42 63 a1 15 14 73 b6 e4 18 a7 30 9e e0 df a9 ba |Bc...s....0.....| +000002f0 44 72 64 ea 06 a4 a1 46 58 07 b1 a8 48 dc ea 73 |Drd....FX...H..s| +00000300 35 d8 98 de 6c 13 93 bb 7a 64 fb df bf 93 cb 65 |5...l...zd.....e| +00000310 a4 1a 3a 17 03 03 00 99 41 8d 8b b5 97 ae 6a fb |..:.....A.....j.| +00000320 28 ae 10 17 a7 a7 bd a2 a2 54 61 33 ea 5c 3d 82 |(........Ta3.\=.| +00000330 6c 7d fe 3e 3b 6f 92 6b 6a 0a ee fe 85 90 67 59 |l}.>;o.kj.....gY| +00000340 df d9 fc c0 4a 9a 5b ae 57 29 5d fb ff 74 28 f1 |....J.[.W)]..t(.| +00000350 27 f4 ab ee f9 e8 04 cf 2b 62 4d a8 6a 4f ac 85 |'.......+bM.jO..| +00000360 ec a5 18 d7 88 74 9e 3e ea 79 8e 5d df f8 8a 1c |.....t.>.y.]....| +00000370 10 1b 1d d3 4a cf 2a 56 f2 ca 90 1f 37 2c cc b7 |....J.*V....7,..| +00000380 31 91 fb d7 7f bb 07 e2 ec 84 8a 6f 08 a1 7e 2e |1..........o..~.| +00000390 62 8a 5c b9 76 d3 68 e5 d0 b8 73 92 86 80 e5 af |b.\.v.h...s.....| +000003a0 b4 ef 13 ea 3c 09 2a 3f 7e be 16 72 1c 46 a0 29 |....<.*?~..r.F.)| +000003b0 0a 17 03 03 00 35 a7 10 63 c4 a1 7f 26 17 ba b7 |.....5..c...&...| +000003c0 e3 86 6e 52 36 00 8e 68 84 dc 51 8d a6 0c 21 ba |..nR6..h..Q...!.| +000003d0 c3 d9 84 49 ed 57 78 98 68 be 78 a6 d1 f0 67 ac |...I.Wx.h.x...g.| +000003e0 65 9e d2 d8 f3 b9 58 27 24 57 83 17 03 03 00 93 |e.....X'$W......| +000003f0 00 54 de 7f 11 18 1d 12 83 10 77 b2 e9 fd a7 a4 |.T........w.....| +00000400 46 c4 1c 15 0d 24 e0 94 f8 ff 84 19 45 ad 52 c8 |F....$......E.R.| +00000410 85 0b c5 4a a7 6d a1 b0 12 cb 13 58 f6 44 a3 e2 |...J.m.....X.D..| +00000420 b8 7a b5 8c 8f 8a 47 76 ef cb 2d 7b 6e 75 81 39 |.z....Gv..-{nu.9| +00000430 3e 12 e8 b5 c6 2d cb e0 fd ac af 58 5a 01 70 32 |>....-.....XZ.p2| +00000440 0e 12 32 95 10 70 94 28 ec 9b 50 e5 78 c4 b7 75 |..2..p.(..P.x..u| +00000450 97 4a 54 97 bb 30 e6 19 8a 86 87 d7 50 02 8f a8 |.JT..0......P...| +00000460 1b 97 d6 e7 bf 25 66 9a 5a cd 5c 84 33 42 f1 72 |.....%f.Z.\.3B.r| +00000470 d2 44 f1 64 e1 3d 38 b7 7a 32 e3 e8 9a 49 19 90 |.D.d.=8.z2...I..| +00000480 00 2b f6 |.+.| >>> Flow 3 (client to server) -00000000 14 03 03 00 01 01 17 03 03 00 45 b0 11 eb 24 17 |..........E...$.| -00000010 1c a4 d5 68 80 b2 21 4b 6d 12 fd 67 c9 8a a8 87 |...h..!Km..g....| -00000020 27 e9 39 fd 9f 5f e4 ce 82 4f 9f 8d 2f d3 b9 04 |'.9.._...O../...| -00000030 d0 a8 00 33 5c 58 3f 75 be d5 8b ff 9a e4 30 cb |...3\X?u......0.| -00000040 4b e2 4d d3 0a e8 3f bb 89 98 1e 87 25 0f 4e 67 |K.M...?.....%.Ng| +00000000 14 03 03 00 01 01 17 03 03 00 35 9d c7 a1 4d 5f |..........5...M_| +00000010 7f 3a 04 b0 cf de 09 d5 84 c1 8f 9b 85 a6 a0 53 |.:.............S| +00000020 c3 aa 19 5e a0 b2 a2 f1 22 f2 51 e0 25 c5 49 57 |...^....".Q.%.IW| +00000030 52 de ad 75 ec e4 e3 36 84 78 22 c8 6c 80 88 8c |R..u...6.x".l...| >>> Flow 4 (server to client) -00000000 17 03 03 00 1e 1e 07 ae 09 4a 05 7b ee f6 ce a5 |.........J.{....| -00000010 18 11 76 89 e8 67 ed 22 41 d2 a3 b6 cc bc c8 e9 |..v..g."A.......| -00000020 73 02 7c 17 03 03 00 13 c2 87 1e 19 ea 01 63 5a |s.|...........cZ| -00000030 aa 72 b2 95 f0 05 08 71 95 0c 75 |.r.....q..u| +00000000 17 03 03 00 1e 3f 0d f6 84 47 21 4e 37 7b df eb |.....?...G!N7{..| +00000010 eb 38 af a5 ec b9 b6 20 24 f5 1a 1e 25 77 92 82 |.8..... $...%w..| +00000020 97 88 9f 17 03 03 00 13 e2 80 d8 e1 2a bf d5 e3 |............*...| +00000030 bc b7 82 2f 50 2c e5 b9 4b 8c d6 |.../P,..K..| diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go index 454aa0bbbc0..19884f96e7d 100644 --- a/libgo/go/crypto/tls/tls.go +++ b/libgo/go/crypto/tls/tls.go @@ -22,10 +22,9 @@ import ( "encoding/pem" "errors" "fmt" - "io/ioutil" "net" + "os" "strings" - "time" ) // Server returns a new TLS server side connection @@ -116,28 +115,16 @@ func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (* } func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) { - // We want the Timeout and Deadline values from dialer to cover the - // whole process: TCP connection and TLS handshake. This means that we - // also need to start our own timers now. - timeout := netDialer.Timeout - - if !netDialer.Deadline.IsZero() { - deadlineTimeout := time.Until(netDialer.Deadline) - if timeout == 0 || deadlineTimeout < timeout { - timeout = deadlineTimeout - } + if netDialer.Timeout != 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout) + defer cancel() } - // hsErrCh is non-nil if we might not wait for Handshake to complete. - var hsErrCh chan error - if timeout != 0 || ctx.Done() != nil { - hsErrCh = make(chan error, 2) - } - if timeout != 0 { - timer := time.AfterFunc(timeout, func() { - hsErrCh <- timeoutError{} - }) - defer timer.Stop() + if !netDialer.Deadline.IsZero() { + var cancel context.CancelFunc + ctx, cancel = context.WithDeadline(ctx, netDialer.Deadline) + defer cancel() } rawConn, err := netDialer.DialContext(ctx, network, addr) @@ -164,34 +151,10 @@ func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, conf } conn := Client(rawConn, config) - - if hsErrCh == nil { - err = conn.Handshake() - } else { - go func() { - hsErrCh <- conn.Handshake() - }() - - select { - case <-ctx.Done(): - err = ctx.Err() - case err = <-hsErrCh: - if err != nil { - // If the error was due to the context - // closing, prefer the context's error, rather - // than some random network teardown error. - if e := ctx.Err(); e != nil { - err = e - } - } - } - } - - if err != nil { + if err := conn.HandshakeContext(ctx); err != nil { rawConn.Close() return nil, err } - return conn, nil } @@ -259,11 +222,11 @@ func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Con // form a certificate chain. On successful return, Certificate.Leaf will // be nil because the parsed form of the certificate is not retained. func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) { - certPEMBlock, err := ioutil.ReadFile(certFile) + certPEMBlock, err := os.ReadFile(certFile) if err != nil { return Certificate{}, err } - keyPEMBlock, err := ioutil.ReadFile(keyFile) + keyPEMBlock, err := os.ReadFile(keyFile) if err != nil { return Certificate{}, err } diff --git a/libgo/go/crypto/tls/tls_test.go b/libgo/go/crypto/tls/tls_test.go index 198423414b9..9995538871e 100644 --- a/libgo/go/crypto/tls/tls_test.go +++ b/libgo/go/crypto/tls/tls_test.go @@ -14,7 +14,6 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" "math" "net" "os" @@ -569,8 +568,8 @@ func TestConnCloseBreakingWrite(t *testing.T) { } <-closeReturned - if err := tconn.Close(); err != errClosed { - t.Errorf("Close error = %v; want errClosed", err) + if err := tconn.Close(); err != net.ErrClosed { + t.Errorf("Close error = %v; want net.ErrClosed", err) } } @@ -594,7 +593,7 @@ func TestConnCloseWrite(t *testing.T) { } defer srv.Close() - data, err := ioutil.ReadAll(srv) + data, err := io.ReadAll(srv) if err != nil { return err } @@ -635,7 +634,7 @@ func TestConnCloseWrite(t *testing.T) { return fmt.Errorf("CloseWrite error = %v; want errShutdown", err) } - data, err := ioutil.ReadAll(conn) + data, err := io.ReadAll(conn) if err != nil { return err } @@ -698,7 +697,7 @@ func TestWarningAlertFlood(t *testing.T) { } defer srv.Close() - _, err = ioutil.ReadAll(srv) + _, err = io.ReadAll(srv) if err == nil { return errors.New("unexpected lack of error from server") } @@ -841,6 +840,13 @@ func TestCloneNonFuncFields(t *testing.T) { } } +func TestCloneNilConfig(t *testing.T) { + var config *Config + if cc := config.Clone(); cc != nil { + t.Fatalf("Clone with nil should return nil, got: %+v", cc) + } +} + // changeImplConn is a net.Conn which can change its Write and Close // methods. type changeImplConn struct { diff --git a/libgo/go/crypto/x509/cert_pool.go b/libgo/go/crypto/x509/cert_pool.go index 59ec4b68947..bcc5db3b703 100644 --- a/libgo/go/crypto/x509/cert_pool.go +++ b/libgo/go/crypto/x509/cert_pool.go @@ -5,43 +5,89 @@ package x509 import ( + "bytes" + "crypto/sha256" "encoding/pem" "errors" "runtime" + "sync" ) +type sum224 [sha256.Size224]byte + // CertPool is a set of certificates. type CertPool struct { - bySubjectKeyId map[string][]int - byName map[string][]int - certs []*Certificate + byName map[string][]int // cert.RawSubject => index into lazyCerts + + // lazyCerts contains funcs that return a certificate, + // lazily parsing/decompressing it as needed. + lazyCerts []lazyCert + + // haveSum maps from sum224(cert.Raw) to true. It's used only + // for AddCert duplicate detection, to avoid CertPool.contains + // calls in the AddCert path (because the contains method can + // call getCert and otherwise negate savings from lazy getCert + // funcs). + haveSum map[sum224]bool +} + +// lazyCert is minimal metadata about a Cert and a func to retrieve it +// in its normal expanded *Certificate form. +type lazyCert struct { + // rawSubject is the Certificate.RawSubject value. + // It's the same as the CertPool.byName key, but in []byte + // form to make CertPool.Subjects (as used by crypto/tls) do + // fewer allocations. + rawSubject []byte + + // getCert returns the certificate. + // + // It is not meant to do network operations or anything else + // where a failure is likely; the func is meant to lazily + // parse/decompress data that is already known to be good. The + // error in the signature primarily is meant for use in the + // case where a cert file existed on local disk when the program + // started up is deleted later before it's read. + getCert func() (*Certificate, error) } // NewCertPool returns a new, empty CertPool. func NewCertPool() *CertPool { return &CertPool{ - bySubjectKeyId: make(map[string][]int), - byName: make(map[string][]int), + byName: make(map[string][]int), + haveSum: make(map[sum224]bool), + } +} + +// len returns the number of certs in the set. +// A nil set is a valid empty set. +func (s *CertPool) len() int { + if s == nil { + return 0 } + return len(s.lazyCerts) +} + +// cert returns cert index n in s. +func (s *CertPool) cert(n int) (*Certificate, error) { + return s.lazyCerts[n].getCert() } func (s *CertPool) copy() *CertPool { p := &CertPool{ - bySubjectKeyId: make(map[string][]int, len(s.bySubjectKeyId)), - byName: make(map[string][]int, len(s.byName)), - certs: make([]*Certificate, len(s.certs)), - } - for k, v := range s.bySubjectKeyId { - indexes := make([]int, len(v)) - copy(indexes, v) - p.bySubjectKeyId[k] = indexes + byName: make(map[string][]int, len(s.byName)), + lazyCerts: make([]lazyCert, len(s.lazyCerts)), + haveSum: make(map[sum224]bool, len(s.haveSum)), } for k, v := range s.byName { indexes := make([]int, len(v)) copy(indexes, v) p.byName[k] = indexes } - copy(p.certs, s.certs) + for k := range s.haveSum { + p.haveSum[k] = true + } + copy(p.lazyCerts, s.lazyCerts) return p } @@ -70,19 +116,44 @@ func SystemCertPool() (*CertPool, error) { } // findPotentialParents returns the indexes of certificates in s which might -// have signed cert. The caller must not modify the returned slice. -func (s *CertPool) findPotentialParents(cert *Certificate) []int { +// have signed cert. +func (s *CertPool) findPotentialParents(cert *Certificate) []*Certificate { if s == nil { return nil } - var candidates []int - if len(cert.AuthorityKeyId) > 0 { - candidates = s.bySubjectKeyId[string(cert.AuthorityKeyId)] + // consider all candidates where cert.Issuer matches cert.Subject. + // when picking possible candidates the list is built in the order + // of match plausibility as to save cycles in buildChains: + // AKID and SKID match + // AKID present, SKID missing / AKID missing, SKID present + // AKID and SKID don't match + var matchingKeyID, oneKeyID, mismatchKeyID []*Certificate + for _, c := range s.byName[string(cert.RawIssuer)] { + candidate, err := s.cert(c) + if err != nil { + continue + } + kidMatch := bytes.Equal(candidate.SubjectKeyId, cert.AuthorityKeyId) + switch { + case kidMatch: + matchingKeyID = append(matchingKeyID, candidate) + case (len(candidate.SubjectKeyId) == 0 && len(cert.AuthorityKeyId) > 0) || + (len(candidate.SubjectKeyId) > 0 && len(cert.AuthorityKeyId) == 0): + oneKeyID = append(oneKeyID, candidate) + default: + mismatchKeyID = append(mismatchKeyID, candidate) + } } - if len(candidates) == 0 { - candidates = s.byName[string(cert.RawIssuer)] + + found := len(matchingKeyID) + len(oneKeyID) + len(mismatchKeyID) + if found == 0 { + return nil } + candidates := make([]*Certificate, 0, found) + candidates = append(candidates, matchingKeyID...) + candidates = append(candidates, oneKeyID...) + candidates = append(candidates, mismatchKeyID...) return candidates } @@ -90,15 +161,7 @@ func (s *CertPool) contains(cert *Certificate) bool { if s == nil { return false } - - candidates := s.byName[string(cert.RawSubject)] - for _, c := range candidates { - if s.certs[c].Equal(cert) { - return true - } - } - - return false + return s.haveSum[sha256.Sum224(cert.Raw)] } // AddCert adds a certificate to a pool. @@ -106,21 +169,32 @@ func (s *CertPool) AddCert(cert *Certificate) { if cert == nil { panic("adding nil Certificate to CertPool") } + s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*Certificate, error) { + return cert, nil + }) +} + +// addCertFunc adds metadata about a certificate to a pool, along with +// a func to fetch that certificate later when needed. +// +// The rawSubject is Certificate.RawSubject and must be non-empty. +// The getCert func may be called 0 or more times. +func (s *CertPool) addCertFunc(rawSum224 sum224, rawSubject string, getCert func() (*Certificate, error)) { + if getCert == nil { + panic("getCert can't be nil") + } // Check that the certificate isn't being added twice. - if s.contains(cert) { + if s.haveSum[rawSum224] { return } - n := len(s.certs) - s.certs = append(s.certs, cert) - - if len(cert.SubjectKeyId) > 0 { - keyId := string(cert.SubjectKeyId) - s.bySubjectKeyId[keyId] = append(s.bySubjectKeyId[keyId], n) - } - name := string(cert.RawSubject) - s.byName[name] = append(s.byName[name], n) + s.haveSum[rawSum224] = true + s.lazyCerts = append(s.lazyCerts, lazyCert{ + rawSubject: []byte(rawSubject), + getCert: getCert, + }) + s.byName[rawSubject] = append(s.byName[rawSubject], len(s.lazyCerts)-1) } // AppendCertsFromPEM attempts to parse a series of PEM encoded certificates. @@ -140,24 +214,35 @@ func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) { continue } - cert, err := ParseCertificate(block.Bytes) + certBytes := block.Bytes + cert, err := ParseCertificate(certBytes) if err != nil { continue } - - s.AddCert(cert) + var lazyCert struct { + sync.Once + v *Certificate + } + s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*Certificate, error) { + lazyCert.Do(func() { + // This can't fail, as the same bytes already parsed above. + lazyCert.v, _ = ParseCertificate(certBytes) + certBytes = nil + }) + return lazyCert.v, nil + }) ok = true } - return + return ok } // Subjects returns a list of the DER-encoded subjects of // all of the certificates in the pool. func (s *CertPool) Subjects() [][]byte { - res := make([][]byte, len(s.certs)) - for i, c := range s.certs { - res[i] = c.RawSubject + res := make([][]byte, s.len()) + for i, lc := range s.lazyCerts { + res[i] = lc.rawSubject } return res } diff --git a/libgo/go/crypto/x509/internal/macos/corefoundation.go b/libgo/go/crypto/x509/internal/macos/corefoundation.go index 359694fabf2..9b776d4b857 100644 --- a/libgo/go/crypto/x509/internal/macos/corefoundation.go +++ b/libgo/go/crypto/x509/internal/macos/corefoundation.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,amd64 +// +build darwin,!ios // Package macOS provides cgo-less wrappers for Core Foundation and // Security.framework, similarly to how package syscall provides access to @@ -16,6 +16,10 @@ import ( "unsafe" ) +// Core Foundation linker flags for the external linker. See Issue 42459. +//go:cgo_ldflag "-framework" +//go:cgo_ldflag "CoreFoundation" + // CFRef is an opaque reference to a Core Foundation object. It is a pointer, // but to memory not owned by Go, so not an unsafe.Pointer. type CFRef uintptr diff --git a/libgo/go/crypto/x509/internal/macos/security.go b/libgo/go/crypto/x509/internal/macos/security.go index 64fe2063901..5e39e936666 100644 --- a/libgo/go/crypto/x509/internal/macos/security.go +++ b/libgo/go/crypto/x509/internal/macos/security.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,amd64 +// +build darwin,!ios package macOS @@ -12,6 +12,10 @@ import ( "unsafe" ) +// Security.framework linker flags for the external linker. See Issue 42459. +//go:cgo_ldflag "-framework" +//go:cgo_ldflag "Security" + // Based on https://opensource.apple.com/source/Security/Security-59306.41.2/base/Security.h type SecTrustSettingsResult int32 diff --git a/libgo/go/crypto/x509/name_constraints_test.go b/libgo/go/crypto/x509/name_constraints_test.go index 5469e28de24..3826c82c380 100644 --- a/libgo/go/crypto/x509/name_constraints_test.go +++ b/libgo/go/crypto/x509/name_constraints_test.go @@ -14,7 +14,6 @@ import ( "encoding/hex" "encoding/pem" "fmt" - "io/ioutil" "math/big" "net" "net/url" @@ -1941,7 +1940,7 @@ func TestConstraintCases(t *testing.T) { // Skip tests with CommonName set because OpenSSL will try to match it // against name constraints, while we ignore it when it's not hostname-looking. if !test.noOpenSSL && testNameConstraintsAgainstOpenSSL && test.leaf.cn == "" { - output, err := testChainAgainstOpenSSL(leafCert, intermediatePool, rootPool) + output, err := testChainAgainstOpenSSL(t, leafCert, intermediatePool, rootPool) if err == nil && len(test.expectedError) > 0 { t.Errorf("#%d: unexpectedly succeeded against OpenSSL", i) if debugOpenSSLFailure { @@ -1993,7 +1992,7 @@ func TestConstraintCases(t *testing.T) { pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}) return buf.String() } - t.Errorf("#%d: root:\n%s", i, certAsPEM(rootPool.certs[0])) + t.Errorf("#%d: root:\n%s", i, certAsPEM(rootPool.mustCert(t, 0))) t.Errorf("#%d: leaf:\n%s", i, certAsPEM(leafCert)) } @@ -2005,7 +2004,7 @@ func TestConstraintCases(t *testing.T) { } func writePEMsToTempFile(certs []*Certificate) *os.File { - file, err := ioutil.TempFile("", "name_constraints_test") + file, err := os.CreateTemp("", "name_constraints_test") if err != nil { panic("cannot create tempfile") } @@ -2019,10 +2018,10 @@ func writePEMsToTempFile(certs []*Certificate) *os.File { return file } -func testChainAgainstOpenSSL(leaf *Certificate, intermediates, roots *CertPool) (string, error) { +func testChainAgainstOpenSSL(t *testing.T, leaf *Certificate, intermediates, roots *CertPool) (string, error) { args := []string{"verify", "-no_check_time"} - rootsFile := writePEMsToTempFile(roots.certs) + rootsFile := writePEMsToTempFile(allCerts(t, roots)) if debugOpenSSLFailure { println("roots file:", rootsFile.Name()) } else { @@ -2030,8 +2029,8 @@ func testChainAgainstOpenSSL(leaf *Certificate, intermediates, roots *CertPool) } args = append(args, "-CAfile", rootsFile.Name()) - if len(intermediates.certs) > 0 { - intermediatesFile := writePEMsToTempFile(intermediates.certs) + if intermediates.len() > 0 { + intermediatesFile := writePEMsToTempFile(allCerts(t, intermediates)) if debugOpenSSLFailure { println("intermediates file:", intermediatesFile.Name()) } else { diff --git a/libgo/go/crypto/x509/pem_decrypt.go b/libgo/go/crypto/x509/pem_decrypt.go index 93d1e4a922d..781cb3de834 100644 --- a/libgo/go/crypto/x509/pem_decrypt.go +++ b/libgo/go/crypto/x509/pem_decrypt.go @@ -95,7 +95,12 @@ func (c rfc1423Algo) deriveKey(password, salt []byte) []byte { return out } -// IsEncryptedPEMBlock returns if the PEM block is password encrypted. +// IsEncryptedPEMBlock returns whether the PEM block is password encrypted +// according to RFC 1423. +// +// Deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by +// design. Since it does not authenticate the ciphertext, it is vulnerable to +// padding oracle attacks that can let an attacker recover the plaintext. func IsEncryptedPEMBlock(b *pem.Block) bool { _, ok := b.Headers["DEK-Info"] return ok @@ -104,14 +109,18 @@ func IsEncryptedPEMBlock(b *pem.Block) bool { // IncorrectPasswordError is returned when an incorrect password is detected. var IncorrectPasswordError = errors.New("x509: decryption password incorrect") -// DecryptPEMBlock takes a password encrypted PEM block and the password used to -// encrypt it and returns a slice of decrypted DER encoded bytes. It inspects -// the DEK-Info header to determine the algorithm used for decryption. If no -// DEK-Info header is present, an error is returned. If an incorrect password -// is detected an IncorrectPasswordError is returned. Because of deficiencies -// in the encrypted-PEM format, it's not always possible to detect an incorrect -// password. In these cases no error will be returned but the decrypted DER -// bytes will be random noise. +// DecryptPEMBlock takes a PEM block encrypted according to RFC 1423 and the +// password used to encrypt it and returns a slice of decrypted DER encoded +// bytes. It inspects the DEK-Info header to determine the algorithm used for +// decryption. If no DEK-Info header is present, an error is returned. If an +// incorrect password is detected an IncorrectPasswordError is returned. Because +// of deficiencies in the format, it's not always possible to detect an +// incorrect password. In these cases no error will be returned but the +// decrypted DER bytes will be random noise. +// +// Deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by +// design. Since it does not authenticate the ciphertext, it is vulnerable to +// padding oracle attacks that can let an attacker recover the plaintext. func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) { dek, ok := b.Headers["DEK-Info"] if !ok { @@ -178,8 +187,12 @@ func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) { } // EncryptPEMBlock returns a PEM block of the specified type holding the -// given DER-encoded data encrypted with the specified algorithm and -// password. +// given DER encoded data encrypted with the specified algorithm and +// password according to RFC 1423. +// +// Deprecated: Legacy PEM encryption as specified in RFC 1423 is insecure by +// design. Since it does not authenticate the ciphertext, it is vulnerable to +// padding oracle attacks that can let an attacker recover the plaintext. func EncryptPEMBlock(rand io.Reader, blockType string, data, password []byte, alg PEMCipher) (*pem.Block, error) { ciph := cipherByKey(alg) if ciph == nil { diff --git a/libgo/go/crypto/x509/root.go b/libgo/go/crypto/x509/root.go index da5e91b91cc..ac92915128d 100644 --- a/libgo/go/crypto/x509/root.go +++ b/libgo/go/crypto/x509/root.go @@ -4,7 +4,7 @@ package x509 -//go:generate go run root_darwin_ios_gen.go -version 55161.80.1 +//go:generate go run root_ios_gen.go -version 55161.140.3 import "sync" diff --git a/libgo/go/crypto/x509/root_aix.go b/libgo/go/crypto/x509/root_aix.go index 6d427739a43..4d50a134738 100644 --- a/libgo/go/crypto/x509/root_aix.go +++ b/libgo/go/crypto/x509/root_aix.go @@ -8,3 +8,9 @@ package x509 var certFiles = []string{ "/var/ssl/certs/ca-bundle.crt", } + +// Possible directories with certificate files; stop after successfully +// reading at least one file from a directory. +var certDirectories = []string{ + "/var/ssl/certs", +} diff --git a/libgo/go/crypto/x509/root_bsd.go b/libgo/go/crypto/x509/root_bsd.go index 13719338910..f04b6bd0d66 100644 --- a/libgo/go/crypto/x509/root_bsd.go +++ b/libgo/go/crypto/x509/root_bsd.go @@ -13,3 +13,10 @@ var certFiles = []string{ "/usr/local/share/certs/ca-root-nss.crt", // DragonFly "/etc/openssl/certs/ca-certificates.crt", // NetBSD } + +// Possible directories with certificate files; stop after successfully +// reading at least one file from a directory. +var certDirectories = []string{ + "/usr/local/share/certs", // FreeBSD + "/etc/openssl/certs", // NetBSD +} diff --git a/libgo/go/crypto/x509/root_cgo_darwin_amd64.go b/libgo/go/crypto/x509/root_cgo_darwin_amd64.go deleted file mode 100644 index 15c72cc0c83..00000000000 --- a/libgo/go/crypto/x509/root_cgo_darwin_amd64.go +++ /dev/null @@ -1,322 +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 !ios - -package x509 - -// This cgo implementation exists only to support side-by-side testing by -// TestSystemRoots. It can be removed once we are confident in the no-cgo -// implementation. - -/* -#cgo CFLAGS: -mmacosx-version-min=10.11 -#cgo LDFLAGS: -framework CoreFoundation -framework Security - -#include -#include - -#include -#include - -static Boolean isSSLPolicy(SecPolicyRef policyRef) { - if (!policyRef) { - return false; - } - CFDictionaryRef properties = SecPolicyCopyProperties(policyRef); - if (properties == NULL) { - return false; - } - Boolean isSSL = false; - CFTypeRef value = NULL; - if (CFDictionaryGetValueIfPresent(properties, kSecPolicyOid, (const void **)&value)) { - isSSL = CFEqual(value, kSecPolicyAppleSSL); - } - CFRelease(properties); - return isSSL; -} - -// sslTrustSettingsResult obtains the final kSecTrustSettingsResult value -// for a certificate in the user or admin domain, combining usage constraints -// for the SSL SecTrustSettingsPolicy, ignoring SecTrustSettingsKeyUsage and -// kSecTrustSettingsAllowedError. -// https://developer.apple.com/documentation/security/1400261-sectrustsettingscopytrustsetting -static SInt32 sslTrustSettingsResult(SecCertificateRef cert) { - CFArrayRef trustSettings = NULL; - OSStatus err = SecTrustSettingsCopyTrustSettings(cert, kSecTrustSettingsDomainUser, &trustSettings); - - // According to Apple's SecTrustServer.c, "user trust settings overrule admin trust settings", - // but the rules of the override are unclear. Let's assume admin trust settings are applicable - // if and only if user trust settings fail to load or are NULL. - if (err != errSecSuccess || trustSettings == NULL) { - if (trustSettings != NULL) CFRelease(trustSettings); - err = SecTrustSettingsCopyTrustSettings(cert, kSecTrustSettingsDomainAdmin, &trustSettings); - } - - // > no trust settings [...] means "this certificate must be verified to a known trusted certificate” - // (Should this cause a fallback from user to admin domain? It's unclear.) - if (err != errSecSuccess || trustSettings == NULL) { - if (trustSettings != NULL) CFRelease(trustSettings); - return kSecTrustSettingsResultUnspecified; - } - - // > An empty trust settings array means "always trust this certificate” with an - // > overall trust setting for the certificate of kSecTrustSettingsResultTrustRoot. - if (CFArrayGetCount(trustSettings) == 0) { - CFRelease(trustSettings); - return kSecTrustSettingsResultTrustRoot; - } - - // kSecTrustSettingsResult is defined as CFSTR("kSecTrustSettingsResult"), - // but the Go linker's internal linking mode can't handle CFSTR relocations. - // Create our own dynamic string instead and release it below. - CFStringRef _kSecTrustSettingsResult = CFStringCreateWithCString( - NULL, "kSecTrustSettingsResult", kCFStringEncodingUTF8); - CFStringRef _kSecTrustSettingsPolicy = CFStringCreateWithCString( - NULL, "kSecTrustSettingsPolicy", kCFStringEncodingUTF8); - CFStringRef _kSecTrustSettingsPolicyString = CFStringCreateWithCString( - NULL, "kSecTrustSettingsPolicyString", kCFStringEncodingUTF8); - - CFIndex m; SInt32 result = 0; - for (m = 0; m < CFArrayGetCount(trustSettings); m++) { - CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, m); - - // First, check if this trust setting is constrained to a non-SSL policy. - SecPolicyRef policyRef; - if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsPolicy, (const void**)&policyRef)) { - if (!isSSLPolicy(policyRef)) { - continue; - } - } - - if (CFDictionaryContainsKey(tSetting, _kSecTrustSettingsPolicyString)) { - // Restricted to a hostname, not a root. - continue; - } - - CFNumberRef cfNum; - if (CFDictionaryGetValueIfPresent(tSetting, _kSecTrustSettingsResult, (const void**)&cfNum)) { - CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result); - } else { - // > If this key is not present, a default value of - // > kSecTrustSettingsResultTrustRoot is assumed. - result = kSecTrustSettingsResultTrustRoot; - } - - // If multiple dictionaries match, we are supposed to "OR" them, - // the semantics of which are not clear. Since TrustRoot and TrustAsRoot - // are mutually exclusive, Deny should probably override, and Invalid and - // Unspecified be overridden, approximate this by stopping at the first - // TrustRoot, TrustAsRoot or Deny. - if (result == kSecTrustSettingsResultTrustRoot) { - break; - } else if (result == kSecTrustSettingsResultTrustAsRoot) { - break; - } else if (result == kSecTrustSettingsResultDeny) { - break; - } - } - - // If trust settings are present, but none of them match the policy... - // the docs don't tell us what to do. - // - // "Trust settings for a given use apply if any of the dictionaries in the - // certificate’s trust settings array satisfies the specified use." suggests - // that it's as if there were no trust settings at all, so we should probably - // fallback to the admin trust settings. TODO. - if (result == 0) { - result = kSecTrustSettingsResultUnspecified; - } - - CFRelease(_kSecTrustSettingsPolicy); - CFRelease(_kSecTrustSettingsPolicyString); - CFRelease(_kSecTrustSettingsResult); - CFRelease(trustSettings); - - return result; -} - -// isRootCertificate reports whether Subject and Issuer match. -static Boolean isRootCertificate(SecCertificateRef cert, CFErrorRef *errRef) { - CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, errRef); - if (*errRef != NULL) { - return false; - } - CFDataRef issuerName = SecCertificateCopyNormalizedIssuerContent(cert, errRef); - if (*errRef != NULL) { - CFRelease(subjectName); - return false; - } - Boolean equal = CFEqual(subjectName, issuerName); - CFRelease(subjectName); - CFRelease(issuerName); - return equal; -} - -// CopyPEMRoots fetches the system's list of trusted X.509 root certificates -// for the kSecTrustSettingsPolicy SSL. -// -// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root -// certificates of the system. On failure, the function returns -1. -// Additionally, it fills untrustedPemRoots with certs that must be removed from pemRoots. -// -// Note: The CFDataRef returned in pemRoots and untrustedPemRoots must -// be released (using CFRelease) after we've consumed its content. -static int CopyPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots, bool debugDarwinRoots) { - int i; - - if (debugDarwinRoots) { - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultInvalid = %d\n", kSecTrustSettingsResultInvalid); - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultTrustRoot = %d\n", kSecTrustSettingsResultTrustRoot); - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultTrustAsRoot = %d\n", kSecTrustSettingsResultTrustAsRoot); - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultDeny = %d\n", kSecTrustSettingsResultDeny); - fprintf(stderr, "crypto/x509: kSecTrustSettingsResultUnspecified = %d\n", kSecTrustSettingsResultUnspecified); - } - - // Get certificates from all domains, not just System, this lets - // the user add CAs to their "login" keychain, and Admins to add - // to the "System" keychain - SecTrustSettingsDomain domains[] = { kSecTrustSettingsDomainSystem, - kSecTrustSettingsDomainAdmin, kSecTrustSettingsDomainUser }; - - int numDomains = sizeof(domains)/sizeof(SecTrustSettingsDomain); - if (pemRoots == NULL || untrustedPemRoots == NULL) { - return -1; - } - - CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0); - CFMutableDataRef combinedUntrustedData = CFDataCreateMutable(kCFAllocatorDefault, 0); - for (i = 0; i < numDomains; i++) { - int j; - CFArrayRef certs = NULL; - OSStatus err = SecTrustSettingsCopyCertificates(domains[i], &certs); - if (err != noErr) { - continue; - } - - CFIndex numCerts = CFArrayGetCount(certs); - for (j = 0; j < numCerts; j++) { - SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, j); - if (cert == NULL) { - continue; - } - - SInt32 result; - if (domains[i] == kSecTrustSettingsDomainSystem) { - // Certs found in the system domain are always trusted. If the user - // configures "Never Trust" on such a cert, it will also be found in the - // admin or user domain, causing it to be added to untrustedPemRoots. The - // Go code will then clean this up. - result = kSecTrustSettingsResultTrustRoot; - } else { - result = sslTrustSettingsResult(cert); - if (debugDarwinRoots) { - CFErrorRef errRef = NULL; - CFStringRef summary = SecCertificateCopyShortDescription(NULL, cert, &errRef); - if (errRef != NULL) { - fprintf(stderr, "crypto/x509: SecCertificateCopyShortDescription failed\n"); - CFRelease(errRef); - continue; - } - - CFIndex length = CFStringGetLength(summary); - CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; - char *buffer = malloc(maxSize); - if (CFStringGetCString(summary, buffer, maxSize, kCFStringEncodingUTF8)) { - fprintf(stderr, "crypto/x509: %s returned %d\n", buffer, (int)result); - } - free(buffer); - CFRelease(summary); - } - } - - CFMutableDataRef appendTo; - // > Note the distinction between the results kSecTrustSettingsResultTrustRoot - // > and kSecTrustSettingsResultTrustAsRoot: The former can only be applied to - // > root (self-signed) certificates; the latter can only be applied to - // > non-root certificates. - if (result == kSecTrustSettingsResultTrustRoot) { - CFErrorRef errRef = NULL; - if (!isRootCertificate(cert, &errRef) || errRef != NULL) { - if (errRef != NULL) CFRelease(errRef); - continue; - } - - appendTo = combinedData; - } else if (result == kSecTrustSettingsResultTrustAsRoot) { - CFErrorRef errRef = NULL; - if (isRootCertificate(cert, &errRef) || errRef != NULL) { - if (errRef != NULL) CFRelease(errRef); - continue; - } - - appendTo = combinedData; - } else if (result == kSecTrustSettingsResultDeny) { - appendTo = combinedUntrustedData; - } else if (result == kSecTrustSettingsResultUnspecified) { - // Certificates with unspecified trust should probably be added to a pool of - // intermediates for chain building, or checked for transitive trust and - // added to the root pool (which is an imprecise approximation because it - // cuts chains short) but we don't support either at the moment. TODO. - continue; - } else { - continue; - } - - CFDataRef data = NULL; - err = SecItemExport(cert, kSecFormatX509Cert, kSecItemPemArmour, NULL, &data); - if (err != noErr) { - continue; - } - if (data != NULL) { - CFDataAppendBytes(appendTo, CFDataGetBytePtr(data), CFDataGetLength(data)); - CFRelease(data); - } - } - CFRelease(certs); - } - *pemRoots = combinedData; - *untrustedPemRoots = combinedUntrustedData; - return 0; -} -*/ -import "C" -import ( - "errors" - "unsafe" -) - -func init() { - loadSystemRootsWithCgo = _loadSystemRootsWithCgo -} - -func _loadSystemRootsWithCgo() (*CertPool, error) { - var data, untrustedData C.CFDataRef - err := C.CopyPEMRoots(&data, &untrustedData, C.bool(debugDarwinRoots)) - if err == -1 { - return nil, errors.New("crypto/x509: failed to load darwin system roots with cgo") - } - defer C.CFRelease(C.CFTypeRef(data)) - defer C.CFRelease(C.CFTypeRef(untrustedData)) - - buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data))) - roots := NewCertPool() - roots.AppendCertsFromPEM(buf) - - if C.CFDataGetLength(untrustedData) == 0 { - return roots, nil - } - - buf = C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(untrustedData)), C.int(C.CFDataGetLength(untrustedData))) - untrustedRoots := NewCertPool() - untrustedRoots.AppendCertsFromPEM(buf) - - trustedRoots := NewCertPool() - for _, c := range roots.certs { - if !untrustedRoots.contains(c) { - trustedRoots.AddCert(c) - } - } - return trustedRoots, nil -} diff --git a/libgo/go/crypto/x509/root_darwin_amd64.go b/libgo/go/crypto/x509/root_darwin.go similarity index 98% rename from libgo/go/crypto/x509/root_darwin_amd64.go rename to libgo/go/crypto/x509/root_darwin.go index ce88de025ec..c9ea7e80f37 100644 --- a/libgo/go/crypto/x509/root_darwin_amd64.go +++ b/libgo/go/crypto/x509/root_darwin.go @@ -20,10 +20,6 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate return nil, nil } -// loadSystemRootsWithCgo is set in root_cgo_darwin_amd64.go when cgo is -// available, and is only used for testing. -var loadSystemRootsWithCgo func() (*CertPool, error) - func loadSystemRoots() (*CertPool, error) { var trustedRoots []*Certificate untrustedRoots := make(map[string]bool) diff --git a/libgo/go/crypto/x509/root_darwin_ios.go b/libgo/go/crypto/x509/root_ios.go similarity index 96% rename from libgo/go/crypto/x509/root_darwin_ios.go rename to libgo/go/crypto/x509/root_ios.go index 5ecc4911b35..cb3529d6d53 100644 --- a/libgo/go/crypto/x509/root_darwin_ios.go +++ b/libgo/go/crypto/x509/root_ios.go @@ -1,7 +1,7 @@ -// Code generated by root_darwin_ios_gen.go -version 55161.80.1; DO NOT EDIT. +// Code generated by root_ios_gen.go -version 55161.140.3; DO NOT EDIT. // Update the version in root.go and regenerate with "go generate". -// +build darwin,arm64 darwin,amd64,ios +// +build ios // +build !x509omitbundledroots package x509 @@ -10,9 +10,6 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate return nil, nil } -// loadSystemRootsWithCgo is not available on iOS. -var loadSystemRootsWithCgo func() (*CertPool, error) - func loadSystemRoots() (*CertPool, error) { p := NewCertPool() p.AppendCertsFromPEM([]byte(systemRootsPEM)) @@ -561,33 +558,6 @@ Hld2j383LS4CXN1jyfJxuCZA3xWNdUQ/eb3mHZnhQyw+rW++uaT+DjUZUWOxw961 kj5ReAFziqQjyqSI8R5cH0EWLX6VCqrpiUGYGxrdyyC/R14MJsVVNU3GMIuZZxTH CR+6R8faAQmHJEKVvRNgGQrv6n8Obs3BREM6StXj -----END CERTIFICATE----- -# "ApplicationCA2 Root" -# 12 6B F0 1C 10 94 D2 F0 CA 2E 35 23 80 B3 C7 24 -# 29 45 46 CC C6 55 97 BE F7 F1 2D 8A 17 1F 19 84 ------BEGIN CERTIFICATE----- -MIID9zCCAt+gAwIBAgILMTI1MzcyODI4MjgwDQYJKoZIhvcNAQELBQAwWDELMAkG -A1UEBhMCSlAxHDAaBgNVBAoTE0phcGFuZXNlIEdvdmVybm1lbnQxDTALBgNVBAsT -BEdQS0kxHDAaBgNVBAMTE0FwcGxpY2F0aW9uQ0EyIFJvb3QwHhcNMTMwMzEyMTUw -MDAwWhcNMzMwMzEyMTUwMDAwWjBYMQswCQYDVQQGEwJKUDEcMBoGA1UEChMTSmFw -YW5lc2UgR292ZXJubWVudDENMAsGA1UECxMER1BLSTEcMBoGA1UEAxMTQXBwbGlj -YXRpb25DQTIgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKaq -rSVl1gAR1uh6dqr05rRL88zDUrSNrKZPtZJxb0a11a2LEiIXJc5F6BR6hZrkIxCo -+rFnUOVtR+BqiRPjrq418fRCxQX3TZd+PCj8sCaRHoweOBqW3FhEl2LjMsjRFUFN -dZh4vqtoqV7tR76kuo6hApfek3SZbWe0BSXulMjtqqS6MmxCEeu+yxcGkOGThchk -KM4fR8fAXWDudjbcMztR63vPctgPeKgZggiQPhqYjY60zxU2pm7dt+JNQCBT2XYq -0HisifBPizJtROouurCp64ndt295D6uBbrjmiykLWa+2SQ1RLKn9nShjZrhwlXOa -2Po7M7xCQhsyrLEy+z0CAwEAAaOBwTCBvjAdBgNVHQ4EFgQUVqesqgIdsqw9kA6g -by5Bxnbne9owDgYDVR0PAQH/BAQDAgEGMHwGA1UdEQR1MHOkcTBvMQswCQYDVQQG -EwJKUDEYMBYGA1UECgwP5pel5pys5Zu95pS/5bqcMRswGQYDVQQLDBLmlL/lupzo -qo3oqLzln7rnm6QxKTAnBgNVBAMMIOOCouODl+ODquOCseODvOOCt+ODp+ODs0NB -MiBSb290MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAH+aCXWs -B9FydC53VzDCBJzUgKaD56WgG5/+q/OAvdVKo6GPtkxgEefK4WCB10jBIFmlYTKL -nZ6X02aD2mUuWD7b5S+lzYxzplG+WCigeVxpL0PfY7KJR8q73rk0EWOgDiUX5Yf0 -HbCwpc9BqHTG6FPVQvSCLVMJEWgmcZR1E02qdog8dLHW40xPYsNJTE5t8XB+w3+m -Bcx4m+mB26jIx1ye/JKSLaaX8ji1bnOVDMA/zqaUMLX6BbfeniCq/BNkyYq6ZO/i -Y+TYmK5rtT6mVbgzPixy+ywRAPtbFi+E0hOe+gXFwctyTiLdhMpLvNIthhoEdlkf -SUJiOxMfFui61/0= ------END CERTIFICATE----- # "Atos TrustedRoot 2011" # F3 56 BE A2 44 B7 A9 1E B3 5D 53 CA 9A D7 86 4A # CE 01 8E 2D 35 D5 F8 F9 6D DF 68 A6 F4 1A A4 74 @@ -2032,35 +2002,6 @@ nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== -----END CERTIFICATE----- # "Entrust.net Certification Authority (2048)" -# D1 C3 39 EA 27 84 EB 87 0F 93 4F C5 63 4E 4A A9 -# AD 55 05 01 64 01 F2 64 65 D3 7A 57 46 63 35 9F ------BEGIN CERTIFICATE----- -MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy -MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 -LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp -YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG -A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq -K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe -sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX -MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT -XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ -HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH -4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA -vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G -CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA -WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo -oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ -h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18 -f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN -B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy -vUxFnmG6v4SBkgPR0ml8xQ== ------END CERTIFICATE----- -# "Entrust.net Certification Authority (2048)" # 6D C4 71 72 E0 1C BC B0 BF 62 58 0D 89 5F E2 B8 # AC 9A D4 F8 73 80 1E 0C 10 B9 C8 37 D2 1E B1 77 -----BEGIN CERTIFICATE----- @@ -2378,22 +2319,6 @@ Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE----- # "GlobalSign" -# BE C9 49 11 C2 95 56 76 DB 6C 0A 55 09 86 D7 6E -# 3B A0 05 66 7C 44 2C 97 62 B4 FB B7 73 DE 22 8C ------BEGIN CERTIFICATE----- -MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk -MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH -bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX -DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD -QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ -FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw -DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F -uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX -kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs -ewv4n4Q= ------END CERTIFICATE----- -# "GlobalSign" # 17 9F BC 14 8A 3D D0 0F D2 4E A1 34 58 CC 43 BF # A7 F5 9C 81 82 D7 83 A5 13 F6 EB EC 10 0C 89 24 -----BEGIN CERTIFICATE----- @@ -2410,6 +2335,22 @@ KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg 515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO xwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- +# "GlobalSign" +# BE C9 49 11 C2 95 56 76 DB 6C 0A 55 09 86 D7 6E +# 3B A0 05 66 7C 44 2C 97 62 B4 FB B7 73 DE 22 8C +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- # "GlobalSign Root CA" # EB D4 10 40 E4 BB 3E C7 42 C9 E3 81 D3 1E F2 A4 # 1A 48 B6 68 5C 96 E7 CE F3 C1 DF 6C D4 33 1C 99 @@ -3095,6 +3036,24 @@ ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= -----END CERTIFICATE----- +# "OISTE WISeKey Global Root GC CA" +# 85 60 F9 1C 36 24 DA BA 95 70 B5 FE A0 DB E3 6F +# F1 1A 83 23 BE 94 86 85 4F B3 F3 4A 55 71 19 8D +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- # "OpenTrust Root CA G1" # 56 C7 71 28 D9 8C 18 D9 1B 4C FD FF BC 25 EE 91 # 03 D4 75 8E A2 AB AD 82 6A 90 F3 45 7D 46 0E B4 @@ -4113,41 +4072,6 @@ Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- -# "SwissSign Gold Root CA - G3" -# 7A F6 EA 9F 75 3A 1E 70 9B D6 4D 0B EB 86 7C 11 -# E8 C2 95 A5 6E 24 A6 E0 47 14 59 DC CD AA 15 58 ------BEGIN CERTIFICATE----- -MIIFejCCA2KgAwIBAgIJAN7E8kTzHab8MA0GCSqGSIb3DQEBCwUAMEoxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJDAiBgNVBAMTG1N3aXNzU2ln -biBHb2xkIFJvb3QgQ0EgLSBHMzAeFw0wOTA4MDQxMzMxNDdaFw0zNzA4MDQxMzMx -NDdaMEoxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJDAiBgNV -BAMTG1N3aXNzU2lnbiBHb2xkIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEB -BQADggIPADCCAgoCggIBAMPon8hlWp1nG8FFl7S0h0NbYWCAnvJ/XvlnRN1E+qu1 -q3f/KhlMzm/Ej0Gf4OLNcuDR1FJhQQkKvwpw++CDaWEpytsimlul5t0XlbBvhI46 -PmRaQfsbWPz9Kz6ypOasyYK8zvaV+Jd37Sb2WK6eJ+IPg+zFNljIe8/Vh6GphxoT -Z2EBbaZpnOKQ8StoZfPosHz8gj3erdgKAAlEeROc8P5udXvCvLNZAQt8xdUt8L// -bVfSSYHrtLNQrFv5CxUVjGn/ozkB7fzc3CeXjnuL1Wqm1uAdX80Bkeb1Ipi6LgkY -OG8TqIHS+yE35y20YueBkLDGeVm3Z3X+vo87+jbsr63ST3Q2AeVXqyMEzEpel89+ -xu+MzJUjaY3LOMcZ9taKABQeND1v2gwLw7qX/BFLUmE+vzNnUxC/eBsJwke6Hq9Y -9XWBf71W8etW19lpDAfpNzGwEhwy71bZvnorfL3TPbxqM006PFAQhyfHegpnU9t/ -gJvoniP6+Qg6i6GONFpIM19k05eGBxl9iJTOKnzFat+vvKmfzTqmurtU+X+P388O -WsStmryzOndzg0yTPJBotXxQlRHIgl6UcdBBGPvJxmXszom2ziKzEVs/4J0+Gxho -DaoDoWdZv2udvPjyZS+aQTpF2F7QNmxvOx5jtI6YTBPbIQ6fe+3qoKpxw+ujoNIl -AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBRclwZGNKvfMMV8xQ1VcWYwtWCPnjAfBgNVHSMEGDAWgBRclwZGNKvfMMV8 -xQ1VcWYwtWCPnjANBgkqhkiG9w0BAQsFAAOCAgEAd0tN3uqFSqssJ9ZFx/FfIMFb -YO0Hy6Iz3DbPx5TxBsfV2s/NrYQ+/xJIf0HopWZXMMQd5KcaLy1Cwe9Gc7LV9Vr9 -Dnpr0sgxow1IlldlY1UYwPzkisyYhlurDIonN/ojaFlcJtehwcK5Tiz/KV7mlAu+ -zXJPleiP9ve4Pl7Oz54RyawDKUiKqbamNLmsQP/EtnM3scd/qVHbSypHX0AkB4gG -tySz+3/3sIsz+r8jdaNc/qplGsK+8X2BdwOBsY3XlQ16PEKYt4+pfVDh31IGmqBS -VHiDB2FSCTdeipynxlHRXGPRhNzC29L6Wxg2fWa81CiXL3WWHIQHrIuOUxG+JCGq -Z/LBrYic07B4Z3j101gDIApdIPG152XMDiDj1d/mLxkrhWjBBCbPj+0FU6HdBw7r -QSbHtKksW+NpPWbAYhvAqobAN8MxBIZwOb5rXyFAQaB/5dkPOEtwX0n4hbgrLqof -k0FD+PuydDwfS1dbt9RRoZJKzr4Qou7YFCJ7uUG9jemIqdGPAxpg/z+HiaCZJyJm -sD5onnKIUTidEz5FbQXlRrVz7UOGsRQKHrzaDb8eJFxmjw6+of3G62m8Q3nXA3b5 -3IeZuJjEzX9tEPkQvixC/pwpTYNrCr21jsRIiv0hB6aAfR+b6au9gmFECnEnX22b -kJ6u/zYks2gD1pWMa3M= ------END CERTIFICATE----- # "SwissSign Platinum CA - G2" # 3B 22 2E 56 67 11 E9 92 30 0D C0 B1 5A B9 47 3D # AF DE F8 C8 4D 0C EF 7D 33 17 B4 C1 82 1D 14 36 @@ -4184,41 +4108,6 @@ DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== -----END CERTIFICATE----- -# "SwissSign Platinum Root CA - G3" -# 59 B3 82 9F 1F F4 43 34 49 58 FA E8 BF F6 21 B6 -# 84 C8 48 CF BF 7E AD 6B 63 A6 CA 50 F2 79 4F 89 ------BEGIN CERTIFICATE----- -MIIFgTCCA2mgAwIBAgIIIj+pFyDegZQwDQYJKoZIhvcNAQELBQAwTjELMAkGA1UE -BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEoMCYGA1UEAxMfU3dpc3NTaWdu -IFBsYXRpbnVtIFJvb3QgQ0EgLSBHMzAeFw0wOTA4MDQxMzM0MDRaFw0zNzA4MDQx -MzM0MDRaME4xCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxKDAm -BgNVBAMTH1N3aXNzU2lnbiBQbGF0aW51bSBSb290IENBIC0gRzMwggIiMA0GCSqG -SIb3DQEBAQUAA4ICDwAwggIKAoICAQCUoO8TG59EIBvNxaoiu9nyUj56Wlh35o2h -K8ncpPPksxOUAGKbHPJDUEOBfq8wNkmsGIkMGEW4PsdUbePYmllriholqba1Dbd9 -I/BffagHqfc+hi7IAU3c5jbtHeU3B2kSS+OD0QQcJPAfcHHnGe1zSG6VKxW2VuYC -31bpm/rqpu7gwsO64MzGyHvXbzqVmzqPvlss0qmgOD7WiOGxYhOO3KswZ82oaqZj -K4Kwy8c9Tu1y9n2rMk5lAusPmXT4HBoojA5FAJMsFJ9txxue9orce3jjtJRHHU0F -bYR6kFSynot1woDfhzk/n/tIVAeNoCn1+WBfWnLou5ugQuAIADSjFTwT49YaawKy -lCGjnUG8KmtOMzumlDj8PccrM7MuKwZ0rJsQb8VORfddoVYDLA1fer0e3h13kGva -pS2KTOnfQfTnS+x9lUKfTKkJD0OIPz2T5yv0ekjaaMTdEoAxGl0kVCamJCGzTK3a -Fwg2AlfGnIZwyXXJnnxh2HjmuegUafkcECgSXUt1ULo80GdwVVVWS/s9HNjbeU2X -37ie2xcs1TUHuFCp9473Vv96Z0NPINnKZtY4YEvulDHWDaJIm/80aZTGNfWWiO+q -ZsyBputMU/8ydKe2nZhXtLomqfEzM2J+OrADEVf/3G8RI60+xgrQzFS3LcKTHeXC -pozH2O9T9wIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUVio/kFj0F1oUstcIG4VbVGpUGigwHwYDVR0jBBgwFoAUVio/ -kFj0F1oUstcIG4VbVGpUGigwDQYJKoZIhvcNAQELBQADggIBAGztiudDqHknm7jP -hz5kOBiMEUKShjfgWMMb7gQu94TsgxBoDH94LZzCl442ThbYDuprSK1Pnl0NzA2p -PhiFfsxomTk11tifhsEy+01lsyIUS8iFZtoX/3GRrJxWV95xLFZCv/jNDvCi0//S -IhX70HgKfuGwWs6ON9upnueVz2PyLA3S+m/zyNX7ALf3NWcQ03tS7BAy+L/dXsmm -gqTxsL8dLt0l5L1N8DWpkQFH+BAClFvrPusNutUdYyylLqvn4x6j7kuqX7FmAbSC -WvlGS8fx+N8svv113ZY4mjc6bqXmMhVus5DAOYp0pZWgvg0uiXnNKVaOw15XUcQF -bwRVj4HpTL1ZRssqvE3JHfLGTwXkyAQN925P2sM6nNLC9enGJHoUPhxCMKgCRTGp -/FCp3NyGOA9bkz9/CE5qDSc6EHlWwxW4PgaG9tlwZ691eoviWMzGdU8yVcVsFAko -O/KV5GreLCgHraB9Byjd1Fqj6aZ8E4yZC1J429nR3z5aQ3Z/RmBTws3ndkd8Vc20 -OWQQW5VLNV1EgyTV4C4kDMGAbmkAgAZ3CmaCEAxRbzeJV9vzTOW4ue4jZpdgt1Ld -2Zb7uoo7oE3OXvBETJDMIU8bOphrjjGD+YMIUssZwTVr7qEVW4g/bazyNJJTpjAq -E9fmhqhd2ULSx52peovL3+6iMcLl ------END CERTIFICATE----- # "SwissSign Silver CA - G2" # BE 6C 4D A2 BB B9 BA 59 B6 F3 93 97 68 37 42 46 # C3 C0 05 99 3F A9 8F 02 0D 1D ED BE D4 8A 81 D5 @@ -4255,41 +4144,6 @@ OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- -# "SwissSign Silver Root CA - G3" -# 1E 49 AC 5D C6 9E 86 D0 56 5D A2 C1 30 5C 41 93 -# 30 B0 B7 81 BF EC 50 E5 4A 1B 35 AF 7F DD D5 01 ------BEGIN CERTIFICATE----- -MIIFfjCCA2agAwIBAgIJAKqIsFoLsXabMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV -BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxJjAkBgNVBAMTHVN3aXNzU2ln -biBTaWx2ZXIgUm9vdCBDQSAtIEczMB4XDTA5MDgwNDEzMTkxNFoXDTM3MDgwNDEz -MTkxNFowTDELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEmMCQG -A1UEAxMdU3dpc3NTaWduIFNpbHZlciBSb290IENBIC0gRzMwggIiMA0GCSqGSIb3 -DQEBAQUAA4ICDwAwggIKAoICAQC+h5sF5nF8Um9t7Dep6bPczF9/01DqIZsE8D2/ -vo7JpRQWMhDPmfzscK1INmckDBcy1inlSjmxN+umeAxsbxnKTvdR2hro+iE4bJWc -L9aLzDsCm78mmxFFtrg0Wh2mVEhSyJ14cc5ISsyneIPcaKtmHncH0zYYCNfUbWD4 -8HnTMzYJkmO3BJr1p5baRa90GvyC46hbDjo/UleYfrycjMHAslrfxH7+DKZUdoN+ -ut3nKvRKNk+HZS6lujmNWWEp89OOJHCMU5sRpUcHsnUFXA2E2UTZzckmRFduAn2V -AdSrJIbuPXD7V/qwKRTQnfLFl8sJyvHyPefYS5bpiC+eR1GKVGWYSNIS5FR3DAfm -vluc8d0Dfo2E/L7JYtX8yTroibVfwgVSYfCcPuwuTYxykY7IQ8GiKF71gCTc4i+H -O1MA5cvwsnyNeRmgiM14+MWKWnflBqzdSt7mcG6+r771sasOCLDboD+Uxb4Subx7 -J3m1MildrsUgI5IDe1Q5sIkiVG0S48N46jpA/aSTrOktiDzbpkdmTN/YF+0W3hrW -10Fmvx2A8aTgZBEpXgwnBWLr5cQEYtHEnwxqVdZYOJxmD537q1SAmZzsSdaCn9pF -1j9TBgO3/R/shn104KS06DK2qgcj+O8kQZ5jMHj0VN2O8Fo4jhJ/eMdvAlYhM864 -uK1pVQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd -BgNVHQ4EFgQUoYxFkwoSYwunV18ySn3hIee3PmYwHwYDVR0jBBgwFoAUoYxFkwoS -YwunV18ySn3hIee3PmYwDQYJKoZIhvcNAQELBQADggIBAIeuYW1IOCrGHNxKLoR4 -ScAjKkW4NU3RBfq5BTPEZL3brVQWKrA+DVoo2qYagHMMxEFvr7g0tnfUW44dC4tG -kES1s+5JGInBSzSzhzV0op5FZ+1FcWa2uaElc9fCrIj70h2na9rAWubYWWQ0l2Ug -MTMDT86tCZ6u6cI+GHW0MyUSuwXsULpxQOK93ohGBSGEi6MrHuswMIm/EfVcRPiR -i0tZRQswDcoMT29jvgT+we3gh/7IzVa/5dyOetTWKU6A26ubP45lByL3RM2WHy3H -9Qm2mHD/ONxQFRGEO3+p8NgkVMgXjCsTSdaZf0XRD46/aXI3Uwf05q79Wz55uQbN -uIF4tE2g0DW65K7/00m8Ne1jxrP846thWgW2C+T/qSq+31ROwktcaNqjMqLJTVcY -UzRZPGaZ1zwCeKdMcdC/2/HEPOcB5gTyRPZIJjAzybEBGesC8cwh+joCMBedyF+A -P90lrAKb4xfevcqSFNJSgVPm6vwwZzKpYvaTFxUHMV4PG2n19Km3fC2z7YREMkco -BzuGaUWpxzaWkHJ02BKmcyPRTrm2ejrEKaFQBhG52fQmbmIIEiAW8AFXF9QFNmeX -61H5/zMkDAUPVr/vPRxSjoreaQ9aH/DVAzFEs5LG6nWorrvHYAOImP/HBIRSkIbh -tJOpUC/o69I2rDBgp9ADE7UK ------END CERTIFICATE----- # "Symantec Class 1 Public Primary Certification Authority - G6" # 9D 19 0B 2E 31 45 66 68 5B E8 A8 89 E2 7A A8 C7 # D7 AE 1D 8A AD DB A3 C1 EC F9 D2 48 63 CD 34 B9 diff --git a/libgo/go/crypto/x509/root_darwin_ios_gen.go b/libgo/go/crypto/x509/root_ios_gen.go similarity index 88% rename from libgo/go/crypto/x509/root_darwin_ios_gen.go rename to libgo/go/crypto/x509/root_ios_gen.go index 7a42466e5f0..8bc6e7d9c47 100644 --- a/libgo/go/crypto/x509/root_darwin_ios_gen.go +++ b/libgo/go/crypto/x509/root_ios_gen.go @@ -4,7 +4,7 @@ // +build ignore -// Generates root_darwin_ios.go. +// Generates root_ios.go. // // As of iOS 13, there is no API for querying the system trusted X.509 root // certificates. @@ -27,9 +27,9 @@ import ( "fmt" "go/format" "io" - "io/ioutil" "log" "net/http" + "os" "path" "sort" "strings" @@ -37,7 +37,7 @@ import ( ) func main() { - var output = flag.String("output", "root_darwin_ios.go", "file name to write") + var output = flag.String("output", "root_ios.go", "file name to write") var version = flag.String("version", "", "security_certificates version") flag.Parse() if *version == "" { @@ -81,7 +81,7 @@ func main() { continue } - der, err := ioutil.ReadAll(tr) + der, err := io.ReadAll(tr) if err != nil { log.Fatal(err) } @@ -124,7 +124,11 @@ func main() { if strings.ToLower(certName(certs[i])) != strings.ToLower(certName(certs[j])) { return strings.ToLower(certName(certs[i])) < strings.ToLower(certName(certs[j])) } - return certs[i].NotBefore.Before(certs[j].NotBefore) + if !certs[i].NotBefore.Equal(certs[j].NotBefore) { + return certs[i].NotBefore.Before(certs[j].NotBefore) + } + fi, fj := sha256.Sum256(certs[i].Raw), sha256.Sum256(certs[j].Raw) + return bytes.Compare(fi[:], fj[:]) < 0 }) out := new(bytes.Buffer) @@ -151,15 +155,15 @@ func main() { if err != nil { log.Fatal(err) } - if err := ioutil.WriteFile(*output, source, 0644); err != nil { + if err := os.WriteFile(*output, source, 0644); err != nil { log.Fatal(err) } } -const header = `// Code generated by root_darwin_ios_gen.go -version %s; DO NOT EDIT. +const header = `// Code generated by root_ios_gen.go -version %s; DO NOT EDIT. // Update the version in root.go and regenerate with "go generate". -// +build darwin,arm64 darwin,amd64,ios +// +build ios // +build !x509omitbundledroots package x509 @@ -168,9 +172,6 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate return nil, nil } -// loadSystemRootsWithCgo is not available on iOS. -var loadSystemRootsWithCgo func() (*CertPool, error) - func loadSystemRoots() (*CertPool, error) { p := NewCertPool() p.AppendCertsFromPEM([]byte(systemRootsPEM)) diff --git a/libgo/go/crypto/x509/root_js.go b/libgo/go/crypto/x509/root_js.go index 70abb73f99c..4e537a4fe5e 100644 --- a/libgo/go/crypto/x509/root_js.go +++ b/libgo/go/crypto/x509/root_js.go @@ -8,3 +8,7 @@ package x509 // Possible certificate files; stop after finding one. var certFiles = []string{} + +// Possible directories with certificate files; stop after successfully +// reading at least one file from a directory. +var certDirectories = []string{} diff --git a/libgo/go/crypto/x509/root_linux.go b/libgo/go/crypto/x509/root_linux.go index 267775dc5f0..ad6ce5cae79 100644 --- a/libgo/go/crypto/x509/root_linux.go +++ b/libgo/go/crypto/x509/root_linux.go @@ -13,3 +13,11 @@ var certFiles = []string{ "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7 "/etc/ssl/cert.pem", // Alpine Linux } + +// Possible directories with certificate files; stop after successfully +// reading at least one file from a directory. +var certDirectories = []string{ + "/etc/ssl/certs", // SLES10/SLES11, https://golang.org/issue/12139 + "/etc/pki/tls/certs", // Fedora/RHEL + "/system/etc/security/cacerts", // Android +} diff --git a/libgo/go/crypto/x509/root_omit.go b/libgo/go/crypto/x509/root_omit.go index 175d71643b2..0055b3b8627 100644 --- a/libgo/go/crypto/x509/root_omit.go +++ b/libgo/go/crypto/x509/root_omit.go @@ -24,6 +24,3 @@ func loadSystemRoots() (*CertPool, error) { func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { return nil, nil } - -// loadSystemRootsWithCgo is not available on iOS. -var loadSystemRootsWithCgo func() (*CertPool, error) diff --git a/libgo/go/crypto/x509/root_plan9.go b/libgo/go/crypto/x509/root_plan9.go index 09f0e230339..2dc4aaf5d7a 100644 --- a/libgo/go/crypto/x509/root_plan9.go +++ b/libgo/go/crypto/x509/root_plan9.go @@ -7,7 +7,6 @@ package x509 import ( - "io/ioutil" "os" ) @@ -24,7 +23,7 @@ func loadSystemRoots() (*CertPool, error) { roots := NewCertPool() var bestErr error for _, file := range certFiles { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err == nil { roots.AppendCertsFromPEM(data) return roots, nil diff --git a/libgo/go/crypto/x509/root_solaris.go b/libgo/go/crypto/x509/root_solaris.go index e6d4e613994..97c19139e3e 100644 --- a/libgo/go/crypto/x509/root_solaris.go +++ b/libgo/go/crypto/x509/root_solaris.go @@ -10,3 +10,9 @@ var certFiles = []string{ "/etc/ssl/certs/ca-certificates.crt", // Joyent SmartOS "/etc/ssl/cacert.pem", // OmniOS } + +// Possible directories with certificate files; stop after successfully +// reading at least one file from a directory. +var certDirectories = []string{ + "/etc/certs/CA", +} diff --git a/libgo/go/crypto/x509/root_unix.go b/libgo/go/crypto/x509/root_unix.go index 5fefe550fb2..3d096633869 100644 --- a/libgo/go/crypto/x509/root_unix.go +++ b/libgo/go/crypto/x509/root_unix.go @@ -7,23 +7,12 @@ package x509 import ( - "io/ioutil" + "io/fs" "os" "path/filepath" "strings" ) -// Possible directories with certificate files; stop after successfully -// reading at least one file from a directory. -var certDirectories = []string{ - "/etc/ssl/certs", // SLES10/SLES11, https://golang.org/issue/12139 - "/system/etc/security/cacerts", // Android - "/usr/local/share/certs", // FreeBSD - "/etc/pki/tls/certs", // Fedora/RHEL - "/etc/openssl/certs", // NetBSD - "/var/ssl/certs", // AIX -} - const ( // certFileEnv is the environment variable which identifies where to locate // the SSL certificate file. If set this overrides the system default. @@ -50,7 +39,7 @@ func loadSystemRoots() (*CertPool, error) { var firstErr error for _, file := range files { - data, err := ioutil.ReadFile(file) + data, err := os.ReadFile(file) if err == nil { roots.AppendCertsFromPEM(data) break @@ -78,31 +67,31 @@ func loadSystemRoots() (*CertPool, error) { continue } for _, fi := range fis { - data, err := ioutil.ReadFile(directory + "/" + fi.Name()) + data, err := os.ReadFile(directory + "/" + fi.Name()) if err == nil { roots.AppendCertsFromPEM(data) } } } - if len(roots.certs) > 0 || firstErr == nil { + if roots.len() > 0 || firstErr == nil { return roots, nil } return nil, firstErr } -// readUniqueDirectoryEntries is like ioutil.ReadDir but omits +// readUniqueDirectoryEntries is like os.ReadDir but omits // symlinks that point within the directory. -func readUniqueDirectoryEntries(dir string) ([]os.FileInfo, error) { - fis, err := ioutil.ReadDir(dir) +func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) { + files, err := os.ReadDir(dir) if err != nil { return nil, err } - uniq := fis[:0] - for _, fi := range fis { - if !isSameDirSymlink(fi, dir) { - uniq = append(uniq, fi) + uniq := files[:0] + for _, f := range files { + if !isSameDirSymlink(f, dir) { + uniq = append(uniq, f) } } return uniq, nil @@ -110,10 +99,10 @@ func readUniqueDirectoryEntries(dir string) ([]os.FileInfo, error) { // isSameDirSymlink reports whether fi in dir is a symlink with a // target not containing a slash. -func isSameDirSymlink(fi os.FileInfo, dir string) bool { - if fi.Mode()&os.ModeSymlink == 0 { +func isSameDirSymlink(f fs.DirEntry, dir string) bool { + if f.Type()&fs.ModeSymlink == 0 { return false } - target, err := os.Readlink(filepath.Join(dir, fi.Name())) + target, err := os.Readlink(filepath.Join(dir, f.Name())) return err == nil && !strings.Contains(target, "/") } diff --git a/libgo/go/crypto/x509/root_unix_test.go b/libgo/go/crypto/x509/root_unix_test.go index 5a8015429c0..878ed7c2faf 100644 --- a/libgo/go/crypto/x509/root_unix_test.go +++ b/libgo/go/crypto/x509/root_unix_test.go @@ -9,7 +9,6 @@ package x509 import ( "bytes" "fmt" - "io/ioutil" "os" "path/filepath" "reflect" @@ -113,15 +112,15 @@ func TestEnvVars(t *testing.T) { // Verify that the returned certs match, otherwise report where the mismatch is. for i, cn := range tc.cns { - if i >= len(r.certs) { + if i >= r.len() { t.Errorf("missing cert %v @ %v", cn, i) - } else if r.certs[i].Subject.CommonName != cn { - fmt.Printf("%#v\n", r.certs[0].Subject) - t.Errorf("unexpected cert common name %q, want %q", r.certs[i].Subject.CommonName, cn) + } else if r.mustCert(t, i).Subject.CommonName != cn { + fmt.Printf("%#v\n", r.mustCert(t, 0).Subject) + t.Errorf("unexpected cert common name %q, want %q", r.mustCert(t, i).Subject.CommonName, cn) } } - if len(r.certs) > len(tc.cns) { - t.Errorf("got %v certs, which is more than %v wanted", len(r.certs), len(tc.cns)) + if r.len() > len(tc.cns) { + t.Errorf("got %v certs, which is more than %v wanted", r.len(), len(tc.cns)) } }) } @@ -147,7 +146,7 @@ func TestLoadSystemCertsLoadColonSeparatedDirs(t *testing.T) { os.Setenv(certFileEnv, origFile) }() - tmpDir, err := ioutil.TempDir(os.TempDir(), "x509-issue35325") + tmpDir, err := os.MkdirTemp(os.TempDir(), "x509-issue35325") if err != nil { t.Fatalf("Failed to create temporary directory: %v", err) } @@ -166,7 +165,7 @@ func TestLoadSystemCertsLoadColonSeparatedDirs(t *testing.T) { t.Fatalf("Failed to create certificate dir: %v", err) } certOutFile := filepath.Join(certDir, "cert.crt") - if err := ioutil.WriteFile(certOutFile, []byte(certPEM), 0655); err != nil { + if err := os.WriteFile(certOutFile, []byte(certPEM), 0655); err != nil { t.Fatalf("Failed to write certificate to file: %v", err) } certDirs = append(certDirs, certDir) @@ -197,7 +196,8 @@ func TestLoadSystemCertsLoadColonSeparatedDirs(t *testing.T) { strCertPool := func(p *CertPool) string { return string(bytes.Join(p.Subjects(), []byte("\n"))) } - if !reflect.DeepEqual(gotPool, wantPool) { + + if !certPoolEqual(gotPool, wantPool) { g, w := strCertPool(gotPool), strCertPool(wantPool) t.Fatalf("Mismatched certPools\nGot:\n%s\n\nWant:\n%s", g, w) } diff --git a/libgo/go/crypto/x509/root_windows.go b/libgo/go/crypto/x509/root_windows.go index 1e0f3acb670..1e9be80b7dd 100644 --- a/libgo/go/crypto/x509/root_windows.go +++ b/libgo/go/crypto/x509/root_windows.go @@ -38,7 +38,11 @@ func createStoreContext(leaf *Certificate, opts *VerifyOptions) (*syscall.CertCo } if opts.Intermediates != nil { - for _, intermediate := range opts.Intermediates.certs { + for i := 0; i < opts.Intermediates.len(); i++ { + intermediate, err := opts.Intermediates.cert(i) + if err != nil { + return nil, err + } ctx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &intermediate.Raw[0], uint32(len(intermediate.Raw))) if err != nil { return nil, err @@ -151,6 +155,44 @@ func init() { } } +func verifyChain(c *Certificate, chainCtx *syscall.CertChainContext, opts *VerifyOptions) (chain []*Certificate, err error) { + err = checkChainTrustStatus(c, chainCtx) + if err != nil { + return nil, err + } + + if opts != nil && len(opts.DNSName) > 0 { + err = checkChainSSLServerPolicy(c, chainCtx, opts) + if err != nil { + return nil, err + } + } + + chain, err = extractSimpleChain(chainCtx.Chains, int(chainCtx.ChainCount)) + if err != nil { + return nil, err + } + if len(chain) == 0 { + return nil, errors.New("x509: internal error: system verifier returned an empty chain") + } + + // Mitigate CVE-2020-0601, where the Windows system verifier might be + // tricked into using custom curve parameters for a trusted root, by + // double-checking all ECDSA signatures. If the system was tricked into + // using spoofed parameters, the signature will be invalid for the correct + // ones we parsed. (We don't support custom curves ourselves.) + for i, parent := range chain[1:] { + if parent.PublicKeyAlgorithm != ECDSA { + continue + } + if err := parent.CheckSignature(chain[i].SignatureAlgorithm, + chain[i].RawTBSCertificate, chain[i].Signature); err != nil { + return nil, err + } + } + return chain, nil +} + // systemVerify is like Verify, except that it uses CryptoAPI calls // to build certificate chains and verify them. func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { @@ -198,67 +240,41 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate verifyTime = &ft } - // CertGetCertificateChain will traverse Windows's root stores - // in an attempt to build a verified certificate chain. Once - // it has found a verified chain, it stops. MSDN docs on - // CERT_CHAIN_CONTEXT: - // - // When a CERT_CHAIN_CONTEXT is built, the first simple chain - // begins with an end certificate and ends with a self-signed - // certificate. If that self-signed certificate is not a root - // or otherwise trusted certificate, an attempt is made to - // build a new chain. CTLs are used to create the new chain - // beginning with the self-signed certificate from the original - // chain as the end certificate of the new chain. This process - // continues building additional simple chains until the first - // self-signed certificate is a trusted certificate or until - // an additional simple chain cannot be built. - // - // The result is that we'll only get a single trusted chain to - // return to our caller. - var chainCtx *syscall.CertChainContext - err = syscall.CertGetCertificateChain(syscall.Handle(0), storeCtx, verifyTime, storeCtx.Store, para, 0, 0, &chainCtx) - if err != nil { - return nil, err - } - defer syscall.CertFreeCertificateChain(chainCtx) + // The default is to return only the highest quality chain, + // setting this flag will add additional lower quality contexts. + // These are returned in the LowerQualityChains field. + const CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS = 0x00000080 - err = checkChainTrustStatus(c, chainCtx) + // CertGetCertificateChain will traverse Windows's root stores in an attempt to build a verified certificate chain + var topCtx *syscall.CertChainContext + err = syscall.CertGetCertificateChain(syscall.Handle(0), storeCtx, verifyTime, storeCtx.Store, para, CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS, 0, &topCtx) if err != nil { return nil, err } + defer syscall.CertFreeCertificateChain(topCtx) - if opts != nil && len(opts.DNSName) > 0 { - err = checkChainSSLServerPolicy(c, chainCtx, opts) - if err != nil { - return nil, err - } + chain, topErr := verifyChain(c, topCtx, opts) + if topErr == nil { + chains = append(chains, chain) } - chain, err := extractSimpleChain(chainCtx.Chains, int(chainCtx.ChainCount)) - if err != nil { - return nil, err - } - if len(chain) < 1 { - return nil, errors.New("x509: internal error: system verifier returned an empty chain") - } + if lqCtxCount := topCtx.LowerQualityChainCount; lqCtxCount > 0 { + lqCtxs := (*[1 << 20]*syscall.CertChainContext)(unsafe.Pointer(topCtx.LowerQualityChains))[:lqCtxCount:lqCtxCount] - // Mitigate CVE-2020-0601, where the Windows system verifier might be - // tricked into using custom curve parameters for a trusted root, by - // double-checking all ECDSA signatures. If the system was tricked into - // using spoofed parameters, the signature will be invalid for the correct - // ones we parsed. (We don't support custom curves ourselves.) - for i, parent := range chain[1:] { - if parent.PublicKeyAlgorithm != ECDSA { - continue - } - if err := parent.CheckSignature(chain[i].SignatureAlgorithm, - chain[i].RawTBSCertificate, chain[i].Signature); err != nil { - return nil, err + for _, ctx := range lqCtxs { + chain, err := verifyChain(c, ctx, opts) + if err == nil { + chains = append(chains, chain) + } } } - return [][]*Certificate{chain}, nil + if len(chains) == 0 { + // Return the error from the highest quality context. + return nil, topErr + } + + return chains, nil } func loadSystemRoots() (*CertPool, error) { diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go index cb8d8f872dd..46afb2698a9 100644 --- a/libgo/go/crypto/x509/verify.go +++ b/libgo/go/crypto/x509/verify.go @@ -187,6 +187,8 @@ func (se SystemRootsError) Error() string { return msg } +func (se SystemRootsError) Unwrap() error { return se.Err } + // errNotParsed is returned when a certificate without ASN.1 contents is // verified. Platform-specific verification needs the ASN.1 contents. var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate") @@ -759,11 +761,13 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e if len(c.Raw) == 0 { return nil, errNotParsed } - if opts.Intermediates != nil { - for _, intermediate := range opts.Intermediates.certs { - if len(intermediate.Raw) == 0 { - return nil, errNotParsed - } + for i := 0; i < opts.Intermediates.len(); i++ { + c, err := opts.Intermediates.cert(i) + if err != nil { + return nil, fmt.Errorf("crypto/x509: error fetching intermediate: %w", err) + } + if len(c.Raw) == 0 { + return nil, errNotParsed } } @@ -889,11 +893,11 @@ func (c *Certificate) buildChains(cache map[*Certificate][][]*Certificate, curre } } - for _, rootNum := range opts.Roots.findPotentialParents(c) { - considerCandidate(rootCertificate, opts.Roots.certs[rootNum]) + for _, root := range opts.Roots.findPotentialParents(c) { + considerCandidate(rootCertificate, root) } - for _, intermediateNum := range opts.Intermediates.findPotentialParents(c) { - considerCandidate(intermediateCertificate, opts.Intermediates.certs[intermediateNum]) + for _, intermediate := range opts.Intermediates.findPotentialParents(c) { + considerCandidate(intermediateCertificate, intermediate) } if len(chains) > 0 { diff --git a/libgo/go/crypto/x509/verify_test.go b/libgo/go/crypto/x509/verify_test.go index 76d1ab9a474..8e0a7bef475 100644 --- a/libgo/go/crypto/x509/verify_test.go +++ b/libgo/go/crypto/x509/verify_test.go @@ -284,18 +284,6 @@ var verifyTests = []verifyTest{ errorCallback: expectHostnameError("certificate is valid for"), }, - { - // The issuer name in the leaf doesn't exactly match the - // subject name in the root. Go does not perform - // canonicalization and so should reject this. See issue 14955. - name: "IssuerSubjectMismatch", - leaf: issuerSubjectMatchLeaf, - roots: []string{issuerSubjectMatchRoot}, - currentTime: 1475787715, - systemSkip: true, // does not chain to a system root - - errorCallback: expectSubjectIssuerMismatcthError, - }, { // An X.509 v1 certificate should not be accepted as an // intermediate. @@ -430,6 +418,20 @@ var verifyTests = []verifyTest{ {"Acme LLC", "Acme Co"}, }, }, + { + // When there are two parents, one with a incorrect subject but matching SKID + // and one with a correct subject but missing SKID, the latter should be + // considered as a possible parent. + leaf: leafMatchingAKIDMatchingIssuer, + roots: []string{rootMatchingSKIDMismatchingSubject, rootMismatchingSKIDMatchingSubject}, + currentTime: 1550000000, + dnsName: "example", + systemSkip: true, + + expectedChains: [][]string{ + {"Leaf", "Root B"}, + }, + }, } func expectHostnameError(msg string) func(*testing.T, error) { @@ -474,12 +476,6 @@ func expectHashError(t *testing.T, err error) { } } -func expectSubjectIssuerMismatcthError(t *testing.T, err error) { - if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != NameMismatch { - t.Fatalf("error was not a NameMismatch: %v", err) - } -} - func expectNameConstraintsError(t *testing.T, err error) { if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != CANotAuthorizedForThisName { t.Fatalf("error was not a CANotAuthorizedForThisName: %v", err) @@ -554,34 +550,55 @@ func testVerify(t *testing.T, test verifyTest, useSystemRoots bool) { } } - if len(chains) != len(test.expectedChains) { - t.Errorf("wanted %d chains, got %d", len(test.expectedChains), len(chains)) + doesMatch := func(expectedChain []string, chain []*Certificate) bool { + if len(chain) != len(expectedChain) { + return false + } + + for k, cert := range chain { + if !strings.Contains(nameToKey(&cert.Subject), expectedChain[k]) { + return false + } + } + return true } - // We check that each returned chain matches a chain from - // expectedChains but an entry in expectedChains can't match - // two chains. - seenChains := make([]bool, len(chains)) -NextOutputChain: - for _, chain := range chains { - TryNextExpected: - for j, expectedChain := range test.expectedChains { - if seenChains[j] { - continue + // Every expected chain should match 1 returned chain + for _, expectedChain := range test.expectedChains { + nChainMatched := 0 + for _, chain := range chains { + if doesMatch(expectedChain, chain) { + nChainMatched++ } - if len(chain) != len(expectedChain) { - continue + } + + if nChainMatched != 1 { + t.Errorf("Got %v matches instead of %v for expected chain %v", nChainMatched, 1, expectedChain) + for _, chain := range chains { + if doesMatch(expectedChain, chain) { + t.Errorf("\t matched %v", chainToDebugString(chain)) + } } - for k, cert := range chain { - if !strings.Contains(nameToKey(&cert.Subject), expectedChain[k]) { - continue TryNextExpected + } + } + + // Every returned chain should match 1 expected chain (or <2 if testing against the system) + for _, chain := range chains { + nMatched := 0 + for _, expectedChain := range test.expectedChains { + if doesMatch(expectedChain, chain) { + nMatched++ + } + } + // Allow additional unknown chains if systemLax is set + if nMatched == 0 && test.systemLax == false || nMatched > 1 { + t.Errorf("Got %v matches for chain %v", nMatched, chainToDebugString(chain)) + for _, expectedChain := range test.expectedChains { + if doesMatch(expectedChain, chain) { + t.Errorf("\t matched %v", expectedChain) } } - // we matched - seenChains[j] = true - continue NextOutputChain } - t.Errorf("no expected chain matched %s", chainToDebugString(chain)) } } @@ -1615,6 +1632,36 @@ ssWvTAveakIwEgYDVR0RBAswCYIHZXhhbXBsZTAKBggqhkjOPQQDAgNHADBEAiBk ZZMqeJS7JldLx91sPUArY5A= -----END CERTIFICATE-----` +const rootMatchingSKIDMismatchingSubject = `-----BEGIN CERTIFICATE----- +MIIBQjCB6aADAgECAgEAMAoGCCqGSM49BAMCMBExDzANBgNVBAMTBlJvb3QgQTAe +Fw0wOTExMTAyMzAwMDBaFw0xOTExMDgyMzAwMDBaMBExDzANBgNVBAMTBlJvb3Qg +QTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPK4p1uXq2aAeDtKDHIokg2rTcPM +2gq3N9Y96wiW6/7puBK1+INEW//cO9x6FpzkcsHw/TriAqy4sck/iDAvf9WjMjAw +MA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAMBgNVHQ4EBQQDAQID +MAoGCCqGSM49BAMCA0gAMEUCIQDgtAp7iVHxMnKxZPaLQPC+Tv2r7+DJc88k2SKH +MPs/wQIgFjjNvBoQEl7vSHTcRGCCcFMdlN4l0Dqc9YwGa9fyrQs= +-----END CERTIFICATE-----` + +const rootMismatchingSKIDMatchingSubject = `-----BEGIN CERTIFICATE----- +MIIBNDCB26ADAgECAgEAMAoGCCqGSM49BAMCMBExDzANBgNVBAMTBlJvb3QgQjAe +Fw0wOTExMTAyMzAwMDBaFw0xOTExMDgyMzAwMDBaMBExDzANBgNVBAMTBlJvb3Qg +QjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABI1YRFcIlkWzm9BdEVrIsEQJ2dT6 +qiW8/WV9GoIhmDtX9SEDHospc0Cgm+TeD2QYW2iMrS5mvNe4GSw0Jezg/bOjJDAi +MA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNI +ADBFAiEAukWOiuellx8bugRiwCS5XQ6IOJ1SZcjuZxj76WojwxkCIHqa71qNw8FM +DtA5yoL9M2pDFF6ovFWnaCe+KlzSwAW/ +-----END CERTIFICATE-----` + +const leafMatchingAKIDMatchingIssuer = `-----BEGIN CERTIFICATE----- +MIIBNTCB26ADAgECAgEAMAoGCCqGSM49BAMCMBExDzANBgNVBAMTBlJvb3QgQjAe +Fw0wOTExMTAyMzAwMDBaFw0xOTExMDgyMzAwMDBaMA8xDTALBgNVBAMTBExlYWYw +WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASNWERXCJZFs5vQXRFayLBECdnU+qol +vP1lfRqCIZg7V/UhAx6LKXNAoJvk3g9kGFtojK0uZrzXuBksNCXs4P2zoyYwJDAO +BgNVHSMEBzAFgAMBAgMwEgYDVR0RBAswCYIHZXhhbXBsZTAKBggqhkjOPQQDAgNJ +ADBGAiEAnV9XV7a4h0nfJB8pWv+pBUXRlRFA2uZz3mXEpee8NYACIQCWa+wL70GL +ePBQCV1F9sE2q4ZrnsT9TZoNrSe/bMDjzA== +-----END CERTIFICATE-----` + var unknownAuthorityErrorTests = []struct { cert string expected string @@ -1979,3 +2026,11 @@ func TestSystemRootsError(t *testing.T) { t.Errorf("error was not SystemRootsError: %v", err) } } + +func TestSystemRootsErrorUnwrap(t *testing.T) { + var err1 = errors.New("err1") + err := SystemRootsError{Err: err1} + if !errors.Is(err, err1) { + t.Error("errors.Is failed, wanted success") + } +} diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 8ce57fb1ec3..60dfac741b8 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -14,9 +14,6 @@ import ( "crypto/elliptic" "crypto/rsa" "crypto/sha1" - _ "crypto/sha1" - _ "crypto/sha256" - _ "crypto/sha512" "crypto/x509/pkix" "encoding/asn1" "encoding/pem" @@ -29,7 +26,13 @@ import ( "strconv" "strings" "time" - "unicode/utf8" + "unicode" + + // Explicitly import these for their crypto.RegisterHash init side-effects. + // Keep these as blank imports, even if they're imported above. + _ "crypto/sha1" + _ "crypto/sha256" + _ "crypto/sha512" "golang.org/x/crypto/cryptobyte" cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" @@ -160,10 +163,6 @@ type dsaAlgorithmParameters struct { P, Q, G *big.Int } -type dsaSignature struct { - R, S *big.Int -} - type validity struct { NotBefore, NotAfter time.Time } @@ -183,14 +182,15 @@ type SignatureAlgorithm int const ( UnknownSignatureAlgorithm SignatureAlgorithm = iota - MD2WithRSA - MD5WithRSA + + MD2WithRSA // Unsupported. + MD5WithRSA // Only supported for signing, not verification. SHA1WithRSA SHA256WithRSA SHA384WithRSA SHA512WithRSA - DSAWithSHA1 - DSAWithSHA256 + DSAWithSHA1 // Unsupported. + DSAWithSHA256 // Unsupported. ECDSAWithSHA1 ECDSAWithSHA256 ECDSAWithSHA384 @@ -224,7 +224,7 @@ type PublicKeyAlgorithm int const ( UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota RSA - DSA + DSA // Unsupported. ECDSA Ed25519 ) @@ -352,6 +352,19 @@ var signatureAlgorithmDetails = []struct { {PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */}, } +// hashToPSSParameters contains the DER encoded RSA PSS parameters for the +// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3. +// The parameters contain the following values: +// * hashAlgorithm contains the associated hash identifier with NULL parameters +// * maskGenAlgorithm always contains the default mgf1SHA1 identifier +// * saltLength contains the length of the associated hash +// * trailerField always contains the default trailerFieldBC value +var hashToPSSParameters = map[crypto.Hash]asn1.RawValue{ + crypto.SHA256: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}}, + crypto.SHA384: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}}, + crypto.SHA512: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}}, +} + // pssParameters reflects the parameters in an AlgorithmIdentifier that // specifies RSA PSS. See RFC 3447, Appendix A.2.3. type pssParameters struct { @@ -364,51 +377,6 @@ type pssParameters struct { TrailerField int `asn1:"optional,explicit,tag:3,default:1"` } -// rsaPSSParameters returns an asn1.RawValue suitable for use as the Parameters -// in an AlgorithmIdentifier that specifies RSA PSS. -func rsaPSSParameters(hashFunc crypto.Hash) asn1.RawValue { - var hashOID asn1.ObjectIdentifier - - switch hashFunc { - case crypto.SHA256: - hashOID = oidSHA256 - case crypto.SHA384: - hashOID = oidSHA384 - case crypto.SHA512: - hashOID = oidSHA512 - } - - params := pssParameters{ - Hash: pkix.AlgorithmIdentifier{ - Algorithm: hashOID, - Parameters: asn1.NullRawValue, - }, - MGF: pkix.AlgorithmIdentifier{ - Algorithm: oidMGF1, - }, - SaltLength: hashFunc.Size(), - TrailerField: 1, - } - - mgf1Params := pkix.AlgorithmIdentifier{ - Algorithm: hashOID, - Parameters: asn1.NullRawValue, - } - - var err error - params.MGF.Parameters.FullBytes, err = asn1.Marshal(mgf1Params) - if err != nil { - panic(err) - } - - serialized, err := asn1.Marshal(params) - if err != nil { - panic(err) - } - - return asn1.RawValue{FullBytes: serialized} -} - func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm { if ai.Algorithm.Equal(oidSignatureEd25519) { // RFC 8410, Section 3 @@ -878,28 +846,6 @@ func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey } else { return rsa.VerifyPKCS1v15(pub, hashType, signed, signature) } - case *dsa.PublicKey: - if pubKeyAlgo != DSA { - return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) - } - dsaSig := new(dsaSignature) - if rest, err := asn1.Unmarshal(signature, dsaSig); err != nil { - return err - } else if len(rest) != 0 { - return errors.New("x509: trailing data after DSA signature") - } - 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") - } - return case *ecdsa.PublicKey: if pubKeyAlgo != ECDSA { return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) @@ -1118,17 +1064,29 @@ func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddre err = forEachSAN(value, func(tag int, data []byte) error { switch tag { case nameTypeEmail: - emailAddresses = append(emailAddresses, string(data)) + email := string(data) + if err := isIA5String(email); err != nil { + return errors.New("x509: SAN rfc822Name is malformed") + } + emailAddresses = append(emailAddresses, email) case nameTypeDNS: - dnsNames = append(dnsNames, string(data)) + name := string(data) + if err := isIA5String(name); err != nil { + return errors.New("x509: SAN dNSName is malformed") + } + dnsNames = append(dnsNames, string(name)) case nameTypeURI: - uri, err := url.Parse(string(data)) + uriStr := string(data) + if err := isIA5String(uriStr); err != nil { + return errors.New("x509: SAN uniformResourceIdentifier is malformed") + } + uri, err := url.Parse(uriStr) if err != nil { - return fmt.Errorf("x509: cannot parse URI %q: %s", string(data), err) + return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err) } if len(uri.Host) > 0 { if _, ok := domainToReverseLabels(uri.Host); !ok { - return fmt.Errorf("x509: cannot parse URI %q: invalid domain", string(data)) + return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr) } } uris = append(uris, uri) @@ -1380,36 +1338,17 @@ func parseCertificate(in *certificate) (*Certificate, error) { if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 { switch e.Id[3] { case 15: - // RFC 5280, 4.2.1.3 - var usageBits asn1.BitString - if rest, err := asn1.Unmarshal(e.Value, &usageBits); err != nil { + out.KeyUsage, err = parseKeyUsageExtension(e.Value) + if err != nil { return nil, err - } else if len(rest) != 0 { - return nil, errors.New("x509: trailing data after X.509 KeyUsage") } - - var usage int - for i := 0; i < 9; i++ { - if usageBits.At(i) != 0 { - usage |= 1 << uint(i) - } - } - out.KeyUsage = KeyUsage(usage) - case 19: - // RFC 5280, 4.2.1.9 - var constraints basicConstraints - if rest, err := asn1.Unmarshal(e.Value, &constraints); err != nil { + out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(e.Value) + if err != nil { return nil, err - } else if len(rest) != 0 { - return nil, errors.New("x509: trailing data after X.509 BasicConstraints") } - out.BasicConstraintsValid = true - out.IsCA = constraints.IsCA - out.MaxPathLen = constraints.MaxPathLen out.MaxPathLenZero = out.MaxPathLen == 0 - // TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285) case 17: out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value) if err != nil { @@ -1472,52 +1411,20 @@ func parseCertificate(in *certificate) (*Certificate, error) { out.AuthorityKeyId = a.Id case 37: - // RFC 5280, 4.2.1.12. Extended Key Usage - - // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } - // - // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId - // - // KeyPurposeId ::= OBJECT IDENTIFIER - - var keyUsage []asn1.ObjectIdentifier - if rest, err := asn1.Unmarshal(e.Value, &keyUsage); err != nil { + out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value) + if err != nil { return nil, err - } else if len(rest) != 0 { - return nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage") } - - for _, u := range keyUsage { - if extKeyUsage, ok := extKeyUsageFromOID(u); ok { - out.ExtKeyUsage = append(out.ExtKeyUsage, extKeyUsage) - } else { - out.UnknownExtKeyUsage = append(out.UnknownExtKeyUsage, u) - } - } - case 14: - // RFC 5280, 4.2.1.2 - var keyid []byte - if rest, err := asn1.Unmarshal(e.Value, &keyid); err != nil { + out.SubjectKeyId, err = parseSubjectKeyIdExtension(e.Value) + if err != nil { return nil, err - } else if len(rest) != 0 { - return nil, errors.New("x509: trailing data after X.509 key-id") } - out.SubjectKeyId = keyid - case 32: - // RFC 5280 4.2.1.4: Certificate Policies - var policies []policyInformation - if rest, err := asn1.Unmarshal(e.Value, &policies); err != nil { + out.PolicyIdentifiers, err = parseCertificatePoliciesExtension(e.Value) + if err != nil { return nil, err - } else if len(rest) != 0 { - return nil, errors.New("x509: trailing data after X.509 certificate policies") } - out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, len(policies)) - for i, policy := range policies { - out.PolicyIdentifiers[i] = policy.Policy - } - default: // Unknown extensions are recorded if critical. unhandled = true @@ -1555,6 +1462,87 @@ func parseCertificate(in *certificate) (*Certificate, error) { return out, nil } +// parseKeyUsageExtension parses id-ce-keyUsage (2.5.29.15) from RFC 5280 +// Section 4.2.1.3 +func parseKeyUsageExtension(ext []byte) (KeyUsage, error) { + var usageBits asn1.BitString + if rest, err := asn1.Unmarshal(ext, &usageBits); err != nil { + return 0, err + } else if len(rest) != 0 { + return 0, errors.New("x509: trailing data after X.509 KeyUsage") + } + + var usage int + for i := 0; i < 9; i++ { + if usageBits.At(i) != 0 { + usage |= 1 << uint(i) + } + } + return KeyUsage(usage), nil +} + +// parseBasicConstraintsExtension parses id-ce-basicConstraints (2.5.29.19) +// from RFC 5280 Section 4.2.1.9 +func parseBasicConstraintsExtension(ext []byte) (isCA bool, maxPathLen int, err error) { + var constraints basicConstraints + if rest, err := asn1.Unmarshal(ext, &constraints); err != nil { + return false, 0, err + } else if len(rest) != 0 { + return false, 0, errors.New("x509: trailing data after X.509 BasicConstraints") + } + + // TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285) + return constraints.IsCA, constraints.MaxPathLen, nil +} + +// parseExtKeyUsageExtension parses id-ce-extKeyUsage (2.5.29.37) from +// RFC 5280 Section 4.2.1.12 +func parseExtKeyUsageExtension(ext []byte) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) { + var keyUsage []asn1.ObjectIdentifier + if rest, err := asn1.Unmarshal(ext, &keyUsage); err != nil { + return nil, nil, err + } else if len(rest) != 0 { + return nil, nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage") + } + + var extKeyUsages []ExtKeyUsage + var unknownUsages []asn1.ObjectIdentifier + for _, u := range keyUsage { + if extKeyUsage, ok := extKeyUsageFromOID(u); ok { + extKeyUsages = append(extKeyUsages, extKeyUsage) + } else { + unknownUsages = append(unknownUsages, u) + } + } + return extKeyUsages, unknownUsages, nil +} + +// parseSubjectKeyIdExtension parses id-ce-subjectKeyIdentifier (2.5.29.14) +// from RFC 5280 Section 4.2.1.2 +func parseSubjectKeyIdExtension(ext []byte) ([]byte, error) { + var keyid []byte + if rest, err := asn1.Unmarshal(ext, &keyid); err != nil { + return nil, err + } else if len(rest) != 0 { + return nil, errors.New("x509: trailing data after X.509 key-id") + } + return keyid, nil +} + +func parseCertificatePoliciesExtension(ext []byte) ([]asn1.ObjectIdentifier, error) { + var policies []policyInformation + if rest, err := asn1.Unmarshal(ext, &policies); err != nil { + return nil, err + } else if len(rest) != 0 { + return nil, errors.New("x509: trailing data after X.509 certificate policies") + } + oids := make([]asn1.ObjectIdentifier, len(policies)) + for i, policy := range policies { + oids[i] = policy.Policy + } + return oids, nil +} + // ParseCertificate parses a single certificate from the given ASN.1 DER data. func ParseCertificate(asn1Data []byte) (*Certificate, error) { var cert certificate @@ -1658,9 +1646,15 @@ func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) boo func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) (derBytes []byte, err error) { var rawValues []asn1.RawValue for _, name := range dnsNames { + if err := isIA5String(name); err != nil { + return nil, err + } rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)}) } for _, email := range emailAddresses { + if err := isIA5String(email); err != nil { + return nil, err + } rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)}) } for _, rawIP := range ipAddresses { @@ -1672,14 +1666,19 @@ func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris [ rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip}) } for _, uri := range uris { - rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uri.String())}) + uriStr := uri.String() + if err := isIA5String(uriStr); err != nil { + return nil, err + } + rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uriStr)}) } return asn1.Marshal(rawValues) } func isIA5String(s string) error { for _, r := range s { - if r >= utf8.RuneSelf { + // Per RFC5280 "IA5String is limited to the set of ASCII characters" + if r > unicode.MaxASCII { return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s) } } @@ -1687,67 +1686,32 @@ func isIA5String(s string) error { return nil } -func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte, subjectKeyId []byte) (ret []pkix.Extension, err error) { +func buildCertExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte, subjectKeyId []byte) (ret []pkix.Extension, err error) { ret = make([]pkix.Extension, 10 /* maximum number of elements. */) n := 0 if template.KeyUsage != 0 && !oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) { - ret[n].Id = oidExtensionKeyUsage - ret[n].Critical = true - - var a [2]byte - a[0] = reverseBitsInAByte(byte(template.KeyUsage)) - a[1] = reverseBitsInAByte(byte(template.KeyUsage >> 8)) - - l := 1 - if a[1] != 0 { - l = 2 - } - - bitString := a[:l] - ret[n].Value, err = asn1.Marshal(asn1.BitString{Bytes: bitString, BitLength: asn1BitLength(bitString)}) + ret[n], err = marshalKeyUsage(template.KeyUsage) if err != nil { - return + return nil, err } n++ } if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) && !oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) { - ret[n].Id = oidExtensionExtendedKeyUsage - - var oids []asn1.ObjectIdentifier - for _, u := range template.ExtKeyUsage { - if oid, ok := oidFromExtKeyUsage(u); ok { - oids = append(oids, oid) - } else { - panic("internal error") - } - } - - oids = append(oids, template.UnknownExtKeyUsage...) - - ret[n].Value, err = asn1.Marshal(oids) + ret[n], err = marshalExtKeyUsage(template.ExtKeyUsage, template.UnknownExtKeyUsage) if err != nil { - return + return nil, err } n++ } if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) { - // Leaving MaxPathLen as zero indicates that no maximum path - // length is desired, unless MaxPathLenZero is set. A value of - // -1 causes encoding/asn1 to omit the value as desired. - maxPathLen := template.MaxPathLen - if maxPathLen == 0 && !template.MaxPathLenZero { - maxPathLen = -1 - } - ret[n].Id = oidExtensionBasicConstraints - ret[n].Value, err = asn1.Marshal(basicConstraints{template.IsCA, maxPathLen}) - ret[n].Critical = true + ret[n], err = marshalBasicConstraints(template.IsCA, template.MaxPathLen, template.MaxPathLenZero) if err != nil { - return + return nil, err } n++ } @@ -1809,14 +1773,9 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId if len(template.PolicyIdentifiers) > 0 && !oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) { - ret[n].Id = oidExtensionCertificatePolicies - policies := make([]policyInformation, len(template.PolicyIdentifiers)) - for i, policy := range template.PolicyIdentifiers { - policies[i].Policy = policy - } - ret[n].Value, err = asn1.Marshal(policies) + ret[n], err = marshalCertificatePolicies(template.PolicyIdentifiers) if err != nil { - return + return nil, err } n++ } @@ -1949,6 +1908,141 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId return append(ret[:n], template.ExtraExtensions...), nil } +func marshalKeyUsage(ku KeyUsage) (pkix.Extension, error) { + ext := pkix.Extension{Id: oidExtensionKeyUsage, Critical: true} + + var a [2]byte + a[0] = reverseBitsInAByte(byte(ku)) + a[1] = reverseBitsInAByte(byte(ku >> 8)) + + l := 1 + if a[1] != 0 { + l = 2 + } + + bitString := a[:l] + var err error + ext.Value, err = asn1.Marshal(asn1.BitString{Bytes: bitString, BitLength: asn1BitLength(bitString)}) + if err != nil { + return ext, err + } + return ext, nil +} + +func marshalExtKeyUsage(extUsages []ExtKeyUsage, unknownUsages []asn1.ObjectIdentifier) (pkix.Extension, error) { + ext := pkix.Extension{Id: oidExtensionExtendedKeyUsage} + + oids := make([]asn1.ObjectIdentifier, len(extUsages)+len(unknownUsages)) + for i, u := range extUsages { + if oid, ok := oidFromExtKeyUsage(u); ok { + oids[i] = oid + } else { + return ext, errors.New("x509: unknown extended key usage") + } + } + + copy(oids[len(extUsages):], unknownUsages) + + var err error + ext.Value, err = asn1.Marshal(oids) + if err != nil { + return ext, err + } + return ext, nil +} + +func marshalBasicConstraints(isCA bool, maxPathLen int, maxPathLenZero bool) (pkix.Extension, error) { + ext := pkix.Extension{Id: oidExtensionBasicConstraints, Critical: true} + // Leaving MaxPathLen as zero indicates that no maximum path + // length is desired, unless MaxPathLenZero is set. A value of + // -1 causes encoding/asn1 to omit the value as desired. + if maxPathLen == 0 && !maxPathLenZero { + maxPathLen = -1 + } + var err error + ext.Value, err = asn1.Marshal(basicConstraints{isCA, maxPathLen}) + if err != nil { + return ext, nil + } + return ext, nil +} + +func marshalCertificatePolicies(policyIdentifiers []asn1.ObjectIdentifier) (pkix.Extension, error) { + ext := pkix.Extension{Id: oidExtensionCertificatePolicies} + policies := make([]policyInformation, len(policyIdentifiers)) + for i, policy := range policyIdentifiers { + policies[i].Policy = policy + } + var err error + ext.Value, err = asn1.Marshal(policies) + if err != nil { + return ext, err + } + return ext, nil +} + +func buildCSRExtensions(template *CertificateRequest) ([]pkix.Extension, error) { + var ret []pkix.Extension + + if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) && + !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) { + sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs) + if err != nil { + return nil, err + } + + ret = append(ret, pkix.Extension{ + Id: oidExtensionSubjectAltName, + Value: sanBytes, + }) + } + + if template.KeyUsage != 0 && + !oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) { + ext, err := marshalKeyUsage(template.KeyUsage) + if err != nil { + return nil, err + } + ret = append(ret, ext) + } + + if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) && + !oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) { + ext, err := marshalExtKeyUsage(template.ExtKeyUsage, template.UnknownExtKeyUsage) + if err != nil { + return nil, err + } + ret = append(ret, ext) + } + + if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) { + ext, err := marshalBasicConstraints(template.IsCA, template.MaxPathLen, template.MaxPathLenZero) + if err != nil { + return nil, err + } + ret = append(ret, ext) + } + + if len(template.SubjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) { + skidBytes, err := asn1.Marshal(template.SubjectKeyId) + if err != nil { + return nil, err + } + ret = append(ret, pkix.Extension{Id: oidExtensionSubjectKeyId, Value: skidBytes}) + } + + if len(template.PolicyIdentifiers) > 0 && + !oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) { + ext, err := marshalCertificatePolicies(template.PolicyIdentifiers) + if err != nil { + return nil, err + } + ret = append(ret, ext) + } + + return append(ret, template.ExtraExtensions...), nil +} + func subjectBytes(cert *Certificate) ([]byte, error) { if len(cert.RawSubject) > 0 { return cert.RawSubject, nil @@ -2016,7 +2110,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori return } if requestedSigAlgo.isRSAPSS() { - sigAlgo.Parameters = rsaPSSParameters(hashFunc) + sigAlgo.Parameters = hashToPSSParameters[hashFunc] } found = true break @@ -2135,7 +2229,7 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv subjectKeyId = h[:] } - extensions, err := buildExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId) + extensions, err := buildCertExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId) if err != nil { return } @@ -2179,12 +2273,26 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv return } - return asn1.Marshal(certificate{ + signedCert, err := asn1.Marshal(certificate{ nil, c, signatureAlgorithm, asn1.BitString{Bytes: signature, BitLength: len(signature) * 8}, }) + if err != nil { + return nil, err + } + + // Check the signature to ensure the crypto.Signer behaved correctly. + // We skip this check if the signature algorithm is MD5WithRSA as we + // only support this algorithm for signing, and not verification. + if sigAlg := getSignatureAlgorithmFromAI(signatureAlgorithm); sigAlg != MD5WithRSA { + if err := checkSignature(sigAlg, c.Raw, signature, key.Public()); err != nil { + return nil, fmt.Errorf("x509: signature over certificate returned by signer is invalid: %w", err) + } + } + + return signedCert, nil } // pemCRLPrefix is the magic string that indicates that we have a PEM encoded @@ -2297,6 +2405,7 @@ type CertificateRequest struct { Version int Signature []byte SignatureAlgorithm SignatureAlgorithm + KeyUsage KeyUsage PublicKeyAlgorithm PublicKeyAlgorithm PublicKey interface{} @@ -2329,6 +2438,37 @@ type CertificateRequest struct { EmailAddresses []string IPAddresses []net.IP URIs []*url.URL + + ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages. + UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package. + + // BasicConstraintsValid indicates whether IsCA, MaxPathLen, + // and MaxPathLenZero are valid. + BasicConstraintsValid bool + IsCA bool + + // MaxPathLen and MaxPathLenZero indicate the presence and + // value of the BasicConstraints' "pathLenConstraint". + // + // When parsing a certificate, a positive non-zero MaxPathLen + // means that the field was specified, -1 means it was unset, + // and MaxPathLenZero being true mean that the field was + // explicitly set to zero. The case of MaxPathLen==0 with MaxPathLenZero==false + // should be treated equivalent to -1 (unset). + // + // When generating a certificate, an unset pathLenConstraint + // can be requested with either MaxPathLen == -1 or using the + // zero value for both MaxPathLen and MaxPathLenZero. + MaxPathLen int + // MaxPathLenZero indicates that BasicConstraintsValid==true + // and MaxPathLen==0 should be interpreted as an actual + // maximum path length of zero. Otherwise, that combination is + // interpreted as MaxPathLen not being set. + MaxPathLenZero bool + + SubjectKeyId []byte + + PolicyIdentifiers []asn1.ObjectIdentifier } // These structures reflect the ASN.1 structure of X.509 certificate @@ -2426,6 +2566,15 @@ func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error) // - EmailAddresses // - IPAddresses // - URIs +// - KeyUsage +// - ExtKeyUsage +// - UnknownExtKeyUsage +// - BasicConstraintsValid +// - IsCA +// - MaxPathLen +// - MaxPathLenZero +// - SubjectKeyId +// - PolicyIdentifiers // - ExtraExtensions // - Attributes (deprecated) // @@ -2456,23 +2605,11 @@ func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv return nil, err } - var extensions []pkix.Extension - - if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) && - !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) { - sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs) - if err != nil { - return nil, err - } - - extensions = append(extensions, pkix.Extension{ - Id: oidExtensionSubjectAltName, - Value: sanBytes, - }) + extensions, err := buildCSRExtensions(template) + if err != nil { + return nil, err } - extensions = append(extensions, template.ExtraExtensions...) - // Make a copy of template.Attributes because we may alter it below. attributes := make([]pkix.AttributeTypeAndValueSET, 0, len(template.Attributes)) for _, attr := range template.Attributes { @@ -2656,11 +2793,36 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error } for _, extension := range out.Extensions { - if extension.Id.Equal(oidExtensionSubjectAltName) { + switch { + case extension.Id.Equal(oidExtensionSubjectAltName): out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(extension.Value) if err != nil { return nil, err } + case extension.Id.Equal(oidExtensionKeyUsage): + out.KeyUsage, err = parseKeyUsageExtension(extension.Value) + case extension.Id.Equal(oidExtensionExtendedKeyUsage): + out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(extension.Value) + if err != nil { + return nil, err + } + case extension.Id.Equal(oidExtensionBasicConstraints): + out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(extension.Value) + if err != nil { + return nil, err + } + out.BasicConstraintsValid = true + out.MaxPathLenZero = out.MaxPathLen == 0 + case extension.Id.Equal(oidExtensionSubjectKeyId): + out.SubjectKeyId, err = parseSubjectKeyIdExtension(extension.Value) + if err != nil { + return nil, err + } + case extension.Id.Equal(oidExtensionCertificatePolicies): + out.PolicyIdentifiers, err = parseCertificatePoliciesExtension(extension.Value) + if err != nil { + return nil, err + } } } diff --git a/libgo/go/crypto/x509/x509_test.go b/libgo/go/crypto/x509/x509_test.go index 840f535e552..65d105db344 100644 --- a/libgo/go/crypto/x509/x509_test.go +++ b/libgo/go/crypto/x509/x509_test.go @@ -22,6 +22,7 @@ import ( "encoding/pem" "fmt" "internal/testenv" + "io" "math/big" "net" "net/url" @@ -988,51 +989,8 @@ func TestVerifyCertificateWithDSASignature(t *testing.T) { t.Fatalf("Failed to parse certificate: %s", err) } // test cert is self-signed - if err = cert.CheckSignatureFrom(cert); err != nil { - t.Fatalf("DSA Certificate verification failed: %s", err) - } -} - -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) + if err = cert.CheckSignatureFrom(cert); err == nil { + t.Fatalf("Expected error verifying DSA certificate") } } @@ -2002,7 +1960,7 @@ func TestSystemCertPool(t *testing.T) { if err != nil { t.Fatal(err) } - if !reflect.DeepEqual(a, b) { + if !certPoolEqual(a, b) { t.Fatal("two calls to SystemCertPool had different results") } if ok := b.AppendCertsFromPEM([]byte(` @@ -2702,3 +2660,348 @@ func TestCreateRevocationList(t *testing.T) { }) } } + +func TestRSAPSAParameters(t *testing.T) { + generateParams := func(hashFunc crypto.Hash) []byte { + var hashOID asn1.ObjectIdentifier + + switch hashFunc { + case crypto.SHA256: + hashOID = oidSHA256 + case crypto.SHA384: + hashOID = oidSHA384 + case crypto.SHA512: + hashOID = oidSHA512 + } + + params := pssParameters{ + Hash: pkix.AlgorithmIdentifier{ + Algorithm: hashOID, + Parameters: asn1.NullRawValue, + }, + MGF: pkix.AlgorithmIdentifier{ + Algorithm: oidMGF1, + }, + SaltLength: hashFunc.Size(), + TrailerField: 1, + } + + mgf1Params := pkix.AlgorithmIdentifier{ + Algorithm: hashOID, + Parameters: asn1.NullRawValue, + } + + var err error + params.MGF.Parameters.FullBytes, err = asn1.Marshal(mgf1Params) + if err != nil { + t.Fatalf("failed to marshal MGF parameters: %s", err) + } + + serialized, err := asn1.Marshal(params) + if err != nil { + t.Fatalf("failed to marshal parameters: %s", err) + } + + return serialized + } + + for h, params := range hashToPSSParameters { + generated := generateParams(h) + if !bytes.Equal(params.FullBytes, generated) { + t.Errorf("hardcoded parameters for %s didn't match generated parameters: got (generated) %x, wanted (hardcoded) %x", h, generated, params.FullBytes) + } + } +} + +func TestUnknownExtKey(t *testing.T) { + const errorContains = "unknown extended key usage" + + template := &Certificate{ + SerialNumber: big.NewInt(10), + DNSNames: []string{"foo"}, + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsage(-1)}, + } + signer, err := rsa.GenerateKey(rand.Reader, 1024) + if err != nil { + t.Errorf("failed to generate key for TestUnknownExtKey") + } + + _, err = CreateCertificate(rand.Reader, template, template, signer.Public(), signer) + if !strings.Contains(err.Error(), errorContains) { + t.Errorf("expected error containing %q, got %s", errorContains, err) + } +} + +func TestIA5SANEnforcement(t *testing.T) { + k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatalf("ecdsa.GenerateKey failed: %s", err) + } + + testURL, err := url.Parse("https://example.com/") + if err != nil { + t.Fatalf("url.Parse failed: %s", err) + } + testURL.RawQuery = "∞" + + marshalTests := []struct { + name string + template *Certificate + expectedError string + }{ + { + name: "marshal: unicode dNSName", + template: &Certificate{ + SerialNumber: big.NewInt(0), + DNSNames: []string{"∞"}, + }, + expectedError: "x509: \"∞\" cannot be encoded as an IA5String", + }, + { + name: "marshal: unicode rfc822Name", + template: &Certificate{ + SerialNumber: big.NewInt(0), + EmailAddresses: []string{"∞"}, + }, + expectedError: "x509: \"∞\" cannot be encoded as an IA5String", + }, + { + name: "marshal: unicode uniformResourceIdentifier", + template: &Certificate{ + SerialNumber: big.NewInt(0), + URIs: []*url.URL{testURL}, + }, + expectedError: "x509: \"https://example.com/?∞\" cannot be encoded as an IA5String", + }, + } + + for _, tc := range marshalTests { + t.Run(tc.name, func(t *testing.T) { + _, err := CreateCertificate(rand.Reader, tc.template, tc.template, k.Public(), k) + if err == nil { + t.Errorf("expected CreateCertificate to fail with template: %v", tc.template) + } else if err.Error() != tc.expectedError { + t.Errorf("unexpected error: got %q, want %q", err.Error(), tc.expectedError) + } + }) + } + + unmarshalTests := []struct { + name string + cert string + expectedError string + }{ + { + name: "unmarshal: unicode dNSName", + cert: "308201083081aea003020102020100300a06082a8648ce3d04030230003022180f30303031303130313030303030305a180f30303031303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d0301070342000424bcc48180d8d9db794028f2575ebe3cac79f04d7b0d0151c5292e588aac3668c495f108c626168462e0668c9705e08a211dd103a659d2684e0adf8c2bfd47baa315301330110603551d110101ff040730058203e2889e300a06082a8648ce3d04030203490030460221008ac7827ac326a6ee0fa70b2afe99af575ec60b975f820f3c25f60fff43fbccd0022100bffeed93556722d43d13e461d5b3e33efc61f6349300327d3a0196cb6da501c2", + expectedError: "x509: SAN dNSName is malformed", + }, + { + name: "unmarshal: unicode rfc822Name", + cert: "308201083081aea003020102020100300a06082a8648ce3d04030230003022180f30303031303130313030303030305a180f30303031303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d0301070342000405cb4c4ba72aac980f7b11b0285191425e29e196ce7c5df1c83f56886566e517f196657cc1b73de89ab84ce503fd634e2f2af88fde24c63ca536dc3a5eed2665a315301330110603551d110101ff040730058103e2889e300a06082a8648ce3d0403020349003046022100ed1431cd4b9bb03d88d1511a0ec128a51204375764c716280dc36e2a60142c8902210088c96d25cfaf97eea851ff17d87bb6fe619d6546656e1739f35c3566051c3d0f", + expectedError: "x509: SAN rfc822Name is malformed", + }, + { + name: "unmarshal: unicode uniformResourceIdentifier", + cert: "3082011b3081c3a003020102020100300a06082a8648ce3d04030230003022180f30303031303130313030303030305a180f30303031303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d03010703420004ce0a79b511701d9188e1ea76bcc5907f1db51de6cc1a037b803f256e8588145ca409d120288bfeb4e38f3088104674d374b35bb91fc80d768d1d519dbe2b0b5aa32a302830260603551d110101ff041c301a861868747470733a2f2f6578616d706c652e636f6d2f3fe2889e300a06082a8648ce3d0403020347003044022044f4697779fd1dae1e382d2452413c5c5ca67851e267d6bc64a8d164977c172c0220505015e657637aa1945d46e7650b6f59b968fc1508ca8b152c99f782446dfc81", + expectedError: "x509: SAN uniformResourceIdentifier is malformed", + }, + } + + for _, tc := range unmarshalTests { + der, err := hex.DecodeString(tc.cert) + if err != nil { + t.Fatalf("failed to decode test cert: %s", err) + } + _, err = ParseCertificate(der) + if err == nil { + t.Error("expected CreateCertificate to fail") + } else if err.Error() != tc.expectedError { + t.Errorf("unexpected error: got %q, want %q", err.Error(), tc.expectedError) + } + } +} + +func BenchmarkCreateCertificate(b *testing.B) { + template := &Certificate{ + SerialNumber: big.NewInt(10), + DNSNames: []string{"example.com"}, + } + tests := []struct { + name string + gen func() crypto.Signer + }{ + { + name: "RSA 2048", + gen: func() crypto.Signer { + k, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + b.Fatalf("failed to generate test key: %s", err) + } + return k + }, + }, + { + name: "ECDSA P256", + gen: func() crypto.Signer { + k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + b.Fatalf("failed to generate test key: %s", err) + } + return k + }, + }, + } + + for _, tc := range tests { + k := tc.gen() + b.ResetTimer() + b.Run(tc.name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, err := CreateCertificate(rand.Reader, template, template, k.Public(), k) + if err != nil { + b.Fatalf("failed to create certificate: %s", err) + } + } + }) + } +} + +type brokenSigner struct { + pub crypto.PublicKey +} + +func (bs *brokenSigner) Public() crypto.PublicKey { + return bs.pub +} + +func (bs *brokenSigner) Sign(_ io.Reader, _ []byte, _ crypto.SignerOpts) ([]byte, error) { + return []byte{1, 2, 3}, nil +} + +func TestCreateCertificateBrokenSigner(t *testing.T) { + template := &Certificate{ + SerialNumber: big.NewInt(10), + DNSNames: []string{"example.com"}, + } + k, err := rsa.GenerateKey(rand.Reader, 1024) + if err != nil { + t.Fatalf("failed to generate test key: %s", err) + } + expectedErr := "x509: signature over certificate returned by signer is invalid: crypto/rsa: verification error" + _, err = CreateCertificate(rand.Reader, template, template, k.Public(), &brokenSigner{k.Public()}) + if err == nil { + t.Fatal("expected CreateCertificate to fail with a broken signer") + } else if err.Error() != expectedErr { + t.Fatalf("CreateCertificate returned an unexpected error: got %q, want %q", err, expectedErr) + } +} + +func TestCreateCertificateMD5(t *testing.T) { + template := &Certificate{ + SerialNumber: big.NewInt(10), + DNSNames: []string{"example.com"}, + SignatureAlgorithm: MD5WithRSA, + } + k, err := rsa.GenerateKey(rand.Reader, 1024) + if err != nil { + t.Fatalf("failed to generate test key: %s", err) + } + _, err = CreateCertificate(rand.Reader, template, template, k.Public(), &brokenSigner{k.Public()}) + if err != nil { + t.Fatalf("CreateCertificate failed when SignatureAlgorithm = MD5WithRSA: %s", err) + } +} + +func (s *CertPool) mustCert(t *testing.T, n int) *Certificate { + c, err := s.lazyCerts[n].getCert() + if err != nil { + t.Fatalf("failed to load cert %d: %v", n, err) + } + return c +} + +func allCerts(t *testing.T, p *CertPool) []*Certificate { + all := make([]*Certificate, p.len()) + for i := range all { + all[i] = p.mustCert(t, i) + } + return all +} + +// certPoolEqual reports whether a and b are equal, except for the +// function pointers. +func certPoolEqual(a, b *CertPool) bool { + if (a != nil) != (b != nil) { + return false + } + if a == nil { + return true + } + if !reflect.DeepEqual(a.byName, b.byName) || + len(a.lazyCerts) != len(b.lazyCerts) { + return false + } + for i := range a.lazyCerts { + la, lb := a.lazyCerts[i], b.lazyCerts[i] + if !bytes.Equal(la.rawSubject, lb.rawSubject) { + return false + } + ca, err := la.getCert() + if err != nil { + panic(err) + } + cb, err := la.getCert() + if err != nil { + panic(err) + } + if !ca.Equal(cb) { + return false + } + } + + return true +} + +func TestCertificateRequestRoundtripFields(t *testing.T) { + in := &CertificateRequest{ + KeyUsage: KeyUsageCertSign, + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageAny}, + UnknownExtKeyUsage: []asn1.ObjectIdentifier{{1, 2, 3}}, + BasicConstraintsValid: true, + IsCA: true, + MaxPathLen: 0, + MaxPathLenZero: true, + SubjectKeyId: []byte{1, 2, 3}, + PolicyIdentifiers: []asn1.ObjectIdentifier{{1, 2, 3}}, + } + out := marshalAndParseCSR(t, in) + + if in.KeyUsage != out.KeyUsage { + t.Fatalf("Unexpected KeyUsage: got %v, want %v", out.KeyUsage, in.KeyUsage) + } + if !reflect.DeepEqual(in.ExtKeyUsage, out.ExtKeyUsage) { + t.Fatalf("Unexpected ExtKeyUsage: got %v, want %v", out.ExtKeyUsage, in.ExtKeyUsage) + } + if !reflect.DeepEqual(in.UnknownExtKeyUsage, out.UnknownExtKeyUsage) { + t.Fatalf("Unexpected UnknownExtKeyUsage: got %v, want %v", out.UnknownExtKeyUsage, in.UnknownExtKeyUsage) + } + if in.BasicConstraintsValid != out.BasicConstraintsValid { + t.Fatalf("Unexpected BasicConstraintsValid: got %v, want %v", out.BasicConstraintsValid, in.BasicConstraintsValid) + } + if in.IsCA != out.IsCA { + t.Fatalf("Unexpected IsCA: got %v, want %v", out.IsCA, in.IsCA) + } + if in.MaxPathLen != out.MaxPathLen { + t.Fatalf("Unexpected MaxPathLen: got %v, want %v", out.MaxPathLen, in.MaxPathLen) + } + if in.MaxPathLenZero != out.MaxPathLenZero { + t.Fatalf("Unexpected MaxPathLenZero: got %v, want %v", out.MaxPathLenZero, in.MaxPathLenZero) + } + if !reflect.DeepEqual(in.SubjectKeyId, out.SubjectKeyId) { + t.Fatalf("Unexpected SubjectKeyId: got %v, want %v", out.SubjectKeyId, in.SubjectKeyId) + } + if !reflect.DeepEqual(in.PolicyIdentifiers, out.PolicyIdentifiers) { + t.Fatalf("Unexpected PolicyIdentifiers: got %v, want %v", out.PolicyIdentifiers, in.PolicyIdentifiers) + } +} diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go index b3d0653f5c6..726aadb8990 100644 --- a/libgo/go/database/sql/sql.go +++ b/libgo/go/database/sql/sql.go @@ -434,7 +434,7 @@ type DB struct { maxIdleTimeClosed int64 // Total number of connections closed due to idle time. maxLifetimeClosed int64 // Total number of connections closed due to max connection lifetime limit. - stop func() // stop cancels the connection opener and the session resetter. + stop func() // stop cancels the connection opener. } // connReuseStrategy determines how (*DB).conn returns database connections. @@ -869,6 +869,13 @@ func (db *DB) maxIdleConnsLocked() int { } func (db *DB) shortestIdleTimeLocked() time.Duration { + if db.maxIdleTime <= 0 { + return db.maxLifetime + } + if db.maxLifetime <= 0 { + return db.maxIdleTime + } + min := db.maxIdleTime if min > db.maxLifetime { min = db.maxLifetime @@ -1134,7 +1141,7 @@ func (db *DB) connectionOpener(ctx context.Context) { // Open one new connection func (db *DB) openNewConnection(ctx context.Context) { - // maybeOpenNewConnctions has already executed db.numOpen++ before it sent + // maybeOpenNewConnections has already executed db.numOpen++ before it sent // on db.openerCh. This function must execute db.numOpen-- if the // connection fails or is closed before returning. ci, err := db.connector.Connect(ctx) @@ -2080,10 +2087,10 @@ func (tx *Tx) isDone() bool { // that has already been committed or rolled back. var ErrTxDone = errors.New("sql: transaction has already been committed or rolled back") -// closeLocked returns the connection to the pool and +// close returns the connection to the pool and // must only be called by Tx.rollback or Tx.Commit while -// closemu is Locked and tx already canceled. -func (tx *Tx) closeLocked(err error) { +// tx is already canceled and won't be executed concurrently. +func (tx *Tx) close(err error) { tx.releaseConn(err) tx.dc = nil tx.txi = nil @@ -2157,7 +2164,7 @@ func (tx *Tx) Commit() error { // to ensure no other connection has an active query. tx.cancel() tx.closemu.Lock() - defer tx.closemu.Unlock() + tx.closemu.Unlock() var err error withLock(tx.dc, func() { @@ -2166,7 +2173,7 @@ func (tx *Tx) Commit() error { if err != driver.ErrBadConn { tx.closePrepared() } - tx.closeLocked(err) + tx.close(err) return err } @@ -2189,7 +2196,7 @@ func (tx *Tx) rollback(discardConn bool) error { // to ensure no other connection has an active query. tx.cancel() tx.closemu.Lock() - defer tx.closemu.Unlock() + tx.closemu.Unlock() var err error withLock(tx.dc, func() { @@ -2201,7 +2208,7 @@ func (tx *Tx) rollback(discardConn bool) error { if discardConn { err = driver.ErrBadConn } - tx.closeLocked(err) + tx.close(err) return err } @@ -3110,6 +3117,9 @@ func rowsColumnInfoSetupConnLocked(rowsi driver.Rows) []*ColumnType { // "select cursor(select * from my_table) from dual", into a // *Rows value that can itself be scanned from. The parent // select query will close any cursor *Rows if the parent *Rows is closed. +// +// If any of the first arguments implementing Scanner returns an error, +// that error will be wrapped in the returned error func (rs *Rows) Scan(dest ...interface{}) error { rs.closemu.RLock() @@ -3133,7 +3143,7 @@ func (rs *Rows) Scan(dest ...interface{}) error { for i, sv := range rs.lastcols { err := convertAssignRows(dest[i], sv, rs) if err != nil { - return fmt.Errorf(`sql: Scan error on column index %d, name %q: %v`, i, rs.rowsi.Columns()[i], err) + return fmt.Errorf(`sql: Scan error on column index %d, name %q: %w`, i, rs.rowsi.Columns()[i], err) } } return nil diff --git a/libgo/go/database/sql/sql_test.go b/libgo/go/database/sql/sql_test.go index 5727f0d8aa6..c968852adee 100644 --- a/libgo/go/database/sql/sql_test.go +++ b/libgo/go/database/sql/sql_test.go @@ -2810,6 +2810,34 @@ func TestTxCannotCommitAfterRollback(t *testing.T) { } } +// Issue 40985 transaction statement deadlock while context cancel. +func TestTxStmtDeadlock(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Millisecond) + defer cancel() + tx, err := db.BeginTx(ctx, nil) + if err != nil { + t.Fatal(err) + } + + stmt, err := tx.Prepare("SELECT|people|name,age|age=?") + if err != nil { + t.Fatal(err) + } + // Run number of stmt queries to reproduce deadlock from context cancel + for i := 0; i < 1e3; i++ { + // Encounter any close related errors (e.g. ErrTxDone, stmt is closed) + // is expected due to context cancel. + _, err = stmt.Query(1) + if err != nil { + break + } + } + _ = tx.Rollback() +} + // Issue32530 encounters an issue where a connection may // expire right after it comes out of a used connection pool // even when a new connection is requested. @@ -2860,20 +2888,26 @@ func TestConnExpiresFreshOutOfPool(t *testing.T) { waitingForConn := make(chan struct{}) go func() { + defer close(afterPutConn) + conn, err := db.conn(ctx, alwaysNewConn) - if err != nil { - t.Fatal(err) + if err == nil { + db.putConn(conn, err, false) + } else { + t.Errorf("db.conn: %v", err) } - db.putConn(conn, err, false) - close(afterPutConn) }() go func() { + defer close(waitingForConn) + for { + if t.Failed() { + return + } db.mu.Lock() ct := len(db.connRequests) db.mu.Unlock() if ct > 0 { - close(waitingForConn) return } time.Sleep(10 * time.Millisecond) @@ -2882,6 +2916,10 @@ func TestConnExpiresFreshOutOfPool(t *testing.T) { <-waitingForConn + if t.Failed() { + return + } + offsetMu.Lock() if ec.expired { offset = 11 * time.Second @@ -4149,6 +4187,41 @@ func TestQueryExecContextOnly(t *testing.T) { } } +type alwaysErrScanner struct{} + +var errTestScanWrap = errors.New("errTestScanWrap") + +func (alwaysErrScanner) Scan(interface{}) error { + return errTestScanWrap +} + +// Issue 38099: Ensure that Rows.Scan properly wraps underlying errors. +func TestRowsScanProperlyWrapsErrors(t *testing.T) { + db := newTestDB(t, "people") + defer closeDB(t, db) + + rows, err := db.Query("SELECT|people|age|") + if err != nil { + t.Fatalf("Query: %v", err) + } + + var res alwaysErrScanner + + for rows.Next() { + err = rows.Scan(&res) + if err == nil { + t.Fatal("expecting back an error") + } + if !errors.Is(err, errTestScanWrap) { + t.Fatalf("errors.Is mismatch\n%v\nWant: %v", err, errTestScanWrap) + } + // Ensure that error substring matching still correctly works. + if !strings.Contains(err.Error(), errTestScanWrap.Error()) { + t.Fatalf("Error %v does not contain %v", err, errTestScanWrap) + } + } +} + // badConn implements a bad driver.Conn, for TestBadDriver. // The Exec method panics. type badConn struct{} diff --git a/libgo/go/debug/dwarf/const.go b/libgo/go/debug/dwarf/const.go index b11bf90c37a..c60709199b0 100644 --- a/libgo/go/debug/dwarf/const.go +++ b/libgo/go/debug/dwarf/const.go @@ -461,3 +461,15 @@ const ( utSplitCompile = 0x05 utSplitType = 0x06 ) + +// Opcodes for DWARFv5 debug_rnglists section. +const ( + rleEndOfList = 0x0 + rleBaseAddressx = 0x1 + rleStartxEndx = 0x2 + rleStartxLength = 0x3 + rleOffsetPair = 0x4 + rleBaseAddress = 0x5 + rleStartEnd = 0x6 + rleStartLength = 0x7 +) diff --git a/libgo/go/debug/dwarf/dwarf5ranges_test.go b/libgo/go/debug/dwarf/dwarf5ranges_test.go new file mode 100644 index 00000000000..8bc50bcab69 --- /dev/null +++ b/libgo/go/debug/dwarf/dwarf5ranges_test.go @@ -0,0 +1,41 @@ +// Copyright 2020 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 dwarf + +import ( + "encoding/binary" + "os" + "reflect" + "testing" +) + +func TestDwarf5Ranges(t *testing.T) { + rngLists, err := os.ReadFile("testdata/debug_rnglists") + if err != nil { + t.Fatalf("could not read test data: %v", err) + } + + d := &Data{} + d.order = binary.LittleEndian + if err := d.AddSection(".debug_rnglists", rngLists); err != nil { + t.Fatal(err) + } + u := &unit{ + asize: 8, + vers: 5, + is64: true, + } + ret, err := d.dwarf5Ranges(u, nil, 0x5fbd, 0xc, [][2]uint64{}) + if err != nil { + t.Fatalf("could not read rnglist: %v", err) + } + t.Logf("%#v", ret) + + tgt := [][2]uint64{{0x0000000000006712, 0x000000000000679f}, {0x00000000000067af}, {0x00000000000067b3}} + + if reflect.DeepEqual(ret, tgt) { + t.Errorf("expected %#v got %#x", tgt, ret) + } +} diff --git a/libgo/go/debug/dwarf/entry.go b/libgo/go/debug/dwarf/entry.go index 01f2190db7c..3fc73b8ead2 100644 --- a/libgo/go/debug/dwarf/entry.go +++ b/libgo/go/debug/dwarf/entry.go @@ -423,6 +423,47 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry Children: a.children, Field: make([]Field, len(a.field)), } + + // If we are currently parsing the compilation unit, + // we can't evaluate Addrx or Strx until we've seen the + // relevant base entry. + type delayed struct { + idx int + off uint64 + fmt format + } + var delay []delayed + + resolveStrx := func(strBase, off uint64) string { + off += strBase + 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)) + is64, _ := b.format.dwarf64() + if is64 { + off = b1.uint64() + } else { + off = uint64(b1.uint32()) + } + if b1.err != nil { + b.err = b1.err + return "" + } + 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 val + } + for i := range e.Field { e.Field[i].Attr = a.field[i].attr e.Field[i].Class = a.field[i].class @@ -453,38 +494,31 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry case formAddrx4: off = uint64(b.uint32()) } - if len(b.dwarf.addr) == 0 { + if b.dwarf.addr == nil { 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. + var addrBase int64 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") + addrBase, _ = cu.Val(AttrAddrBase).(int64) + } else if a.tag == TagCompileUnit { + delay = append(delay, delayed{i, off, formAddrx}) + break } - 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 + var err error + val, err = b.dwarf.debugAddr(b.format, uint64(addrBase), off) + if err != nil { + if b.err == nil { + b.err = err + } return nil } @@ -621,38 +655,16 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry // compilation unit. This won't work if the // program uses Reader.Seek to skip over the // unit. Not much we can do about that. + var strBase int64 if cu != nil { - cuOff, ok := cu.Val(AttrStrOffsetsBase).(int64) - if ok { - off += uint64(cuOff) - } + strBase, _ = cu.Val(AttrStrOffsetsBase).(int64) + } else if a.tag == TagCompileUnit { + delay = append(delay, delayed{i, off, formStrx}) + break } - if uint64(int(off)) != off { - b.error("DW_FORM_strx offset out of range") - } + val = resolveStrx(uint64(strBase), off) - 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 { @@ -699,11 +711,32 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry case formRnglistx: val = b.uint() } + e.Field[i].Val = val } if b.err != nil { return nil } + + for _, del := range delay { + switch del.fmt { + case formAddrx: + addrBase, _ := e.Val(AttrAddrBase).(int64) + val, err := b.dwarf.debugAddr(b.format, uint64(addrBase), del.off) + if err != nil { + b.err = err + return nil + } + e.Field[del.idx].Val = val + case formStrx: + strBase, _ := e.Val(AttrStrOffsetsBase).(int64) + e.Field[del.idx].Val = resolveStrx(uint64(strBase), del.off) + if b.err != nil { + return nil + } + } + } + return e } @@ -717,6 +750,7 @@ type Reader struct { d *Data err error unit int + lastUnit bool // set if last entry returned by Next is TagCompileUnit/TagPartialUnit lastChildren bool // .Children of last entry returned by Next lastSibling Offset // .Val(AttrSibling) of last entry returned by Next cu *Entry // current compilation unit @@ -774,13 +808,18 @@ func (r *Reader) Seek(off Offset) { // maybeNextUnit advances to the next unit if this one is finished. func (r *Reader) maybeNextUnit() { for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) { - r.unit++ - u := &r.d.unit[r.unit] - r.b = makeBuf(r.d, u, "info", u.off, u.data) - r.cu = nil + r.nextUnit() } } +// nextUnit advances to the next unit. +func (r *Reader) nextUnit() { + r.unit++ + u := &r.d.unit[r.unit] + r.b = makeBuf(r.d, u, "info", u.off, u.data) + r.cu = nil +} + // Next reads the next entry from the encoded entry stream. // It returns nil, nil when it reaches the end of the section. // It returns an error if the current offset is invalid or the data at the @@ -799,12 +838,14 @@ func (r *Reader) Next() (*Entry, error) { r.err = r.b.err return nil, r.err } + r.lastUnit = false if e != nil { r.lastChildren = e.Children if r.lastChildren { r.lastSibling, _ = e.Val(AttrSibling).(Offset) } if e.Tag == TagCompileUnit || e.Tag == TagPartialUnit { + r.lastUnit = true r.cu = e } } else { @@ -830,6 +871,11 @@ func (r *Reader) SkipChildren() { return } + if r.lastUnit && r.unit+1 < len(r.d.unit) { + r.nextUnit() + return + } + for { e, err := r.Next() if err != nil || e == nil || e.Tag == 0 { @@ -874,6 +920,7 @@ func (r *Reader) SeekPC(pc uint64) (*Entry, error) { r.err = nil r.lastChildren = false r.unit = unit + r.cu = nil u := &r.d.unit[unit] r.b = makeBuf(r.d, u, "info", u.off, u.data) e, err := r.Next() @@ -922,53 +969,186 @@ func (d *Data) Ranges(e *Entry) ([][2]uint64, error) { ret = append(ret, [2]uint64{low, high}) } - ranges, rangesOK := e.Val(AttrRanges).(int64) - if rangesOK && d.ranges != nil { - // The initial base address is the lowpc attribute - // of the enclosing compilation unit. - // Although DWARF specifies the lowpc attribute, - // comments in gdb/dwarf2read.c say that some versions - // of GCC use the entrypc attribute, so we check that too. - var cu *Entry - if e.Tag == TagCompileUnit { - cu = e - } else { - i := d.offsetToUnit(e.Offset) - if i == -1 { - return nil, errors.New("no unit for entry") + var u *unit + if uidx := d.offsetToUnit(e.Offset); uidx >= 0 && uidx < len(d.unit) { + u = &d.unit[uidx] + } + + if u != nil && u.vers >= 5 && d.rngLists != nil { + // DWARF version 5 and later + field := e.AttrField(AttrRanges) + if field == nil { + return ret, nil + } + switch field.Class { + case ClassRangeListPtr: + ranges, rangesOK := field.Val.(int64) + if !rangesOK { + return ret, nil } - u := &d.unit[i] - b := makeBuf(d, u, "info", u.off, u.data) - cu = b.entry(nil, u.atable, u.base, u.vers) - if b.err != nil { - return nil, b.err + cu, base, err := d.baseAddressForEntry(e) + if err != nil { + return nil, err } + return d.dwarf5Ranges(u, cu, base, ranges, ret) + + case ClassRngList: + // TODO: support DW_FORM_rnglistx + return ret, nil + + default: + return ret, nil + } + } + + // DWARF version 2 through 4 + ranges, rangesOK := e.Val(AttrRanges).(int64) + if rangesOK && d.ranges != nil { + _, base, err := d.baseAddressForEntry(e) + if err != nil { + return nil, err } + return d.dwarf2Ranges(u, base, ranges, ret) + } + + return ret, nil +} - var base uint64 - if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK { - base = cuEntry - } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK { - base = cuLow +// baseAddressForEntry returns the initial base address to be used when +// looking up the range list of entry e. +// DWARF specifies that this should be the lowpc attribute of the enclosing +// compilation unit, however comments in gdb/dwarf2read.c say that some +// versions of GCC use the entrypc attribute, so we check that too. +func (d *Data) baseAddressForEntry(e *Entry) (*Entry, uint64, error) { + var cu *Entry + if e.Tag == TagCompileUnit { + cu = e + } else { + i := d.offsetToUnit(e.Offset) + if i == -1 { + return nil, 0, errors.New("no unit for entry") + } + u := &d.unit[i] + b := makeBuf(d, u, "info", u.off, u.data) + cu = b.entry(nil, u.atable, u.base, u.vers) + if b.err != nil { + return nil, 0, b.err } + } - u := &d.unit[d.offsetToUnit(e.Offset)] - buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:]) - for len(buf.data) > 0 { - low = buf.addr() - high = buf.addr() + if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK { + return cu, cuEntry, nil + } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK { + return cu, cuLow, nil + } - if low == 0 && high == 0 { - break + return cu, 0, nil +} + +func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) { + buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:]) + for len(buf.data) > 0 { + low := buf.addr() + high := buf.addr() + + if low == 0 && high == 0 { + break + } + + if low == ^uint64(0)>>uint((8-u.addrsize())*8) { + base = high + } else { + ret = append(ret, [2]uint64{base + low, base + high}) + } + } + + return ret, nil +} + +// dwarf5Ranges interpets a debug_rnglists sequence, see DWARFv5 section +// 2.17.3 (page 53). +func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) { + var addrBase int64 + if cu != nil { + addrBase, _ = cu.Val(AttrAddrBase).(int64) + } + + buf := makeBuf(d, u, "rnglists", 0, d.rngLists) + buf.skip(int(ranges)) + for { + opcode := buf.uint8() + switch opcode { + case rleEndOfList: + if buf.err != nil { + return nil, buf.err + } + return ret, nil + + case rleBaseAddressx: + baseIdx := buf.uint() + var err error + base, err = d.debugAddr(u, uint64(addrBase), baseIdx) + if err != nil { + return nil, err } - if low == ^uint64(0)>>uint((8-u.addrsize())*8) { - base = high - } else { - ret = append(ret, [2]uint64{base + low, base + high}) + case rleStartxEndx: + startIdx := buf.uint() + endIdx := buf.uint() + + start, err := d.debugAddr(u, uint64(addrBase), startIdx) + if err != nil { + return nil, err + } + end, err := d.debugAddr(u, uint64(addrBase), endIdx) + if err != nil { + return nil, err + } + ret = append(ret, [2]uint64{start, end}) + + case rleStartxLength: + startIdx := buf.uint() + len := buf.uint() + start, err := d.debugAddr(u, uint64(addrBase), startIdx) + if err != nil { + return nil, err } + ret = append(ret, [2]uint64{start, start + len}) + + case rleOffsetPair: + off1 := buf.uint() + off2 := buf.uint() + ret = append(ret, [2]uint64{base + off1, base + off2}) + + case rleBaseAddress: + base = buf.addr() + + case rleStartEnd: + start := buf.addr() + end := buf.addr() + ret = append(ret, [2]uint64{start, end}) + + case rleStartLength: + start := buf.addr() + len := buf.uint() + ret = append(ret, [2]uint64{start, start + len}) } } +} - return ret, nil +// debugAddr returns the address at idx in debug_addr +func (d *Data) debugAddr(format dataFormat, addrBase, idx uint64) (uint64, error) { + off := idx*uint64(format.addrsize()) + addrBase + + if uint64(int(off)) != off { + return 0, errors.New("offset out of range") + } + + b := makeBuf(d, format, "addr", 0, d.addr) + b.skip(int(off)) + val := b.addr() + if b.err != nil { + return 0, b.err + } + return val, nil } diff --git a/libgo/go/debug/dwarf/entry_test.go b/libgo/go/debug/dwarf/entry_test.go index 4c9aad21f31..b54f8b4f8da 100644 --- a/libgo/go/debug/dwarf/entry_test.go +++ b/libgo/go/debug/dwarf/entry_test.go @@ -7,6 +7,7 @@ package dwarf_test import ( . "debug/dwarf" "encoding/binary" + "path/filepath" "reflect" "testing" ) @@ -54,6 +55,20 @@ func TestReaderSeek(t *testing.T) { {0x400611, nil}, } testRanges(t, "testdata/line-gcc.elf", want) + + want = []wantRange{ + {0x401122, [][2]uint64{{0x401122, 0x401166}}}, + {0x401165, [][2]uint64{{0x401122, 0x401166}}}, + {0x401166, [][2]uint64{{0x401166, 0x401179}}}, + } + testRanges(t, "testdata/line-gcc-dwarf5.elf", want) + + want = []wantRange{ + {0x401130, [][2]uint64{{0x401130, 0x40117e}}}, + {0x40117d, [][2]uint64{{0x401130, 0x40117e}}}, + {0x40117e, nil}, + } + testRanges(t, "testdata/line-clang-dwarf5.elf", want) } func TestRangesSection(t *testing.T) { @@ -96,44 +111,72 @@ func testRanges(t *testing.T, name string, want []wantRange) { } func TestReaderRanges(t *testing.T) { - d := elfData(t, "testdata/line-gcc.elf") - - subprograms := []struct { + type subprograms []struct { name string ranges [][2]uint64 + } + tests := []struct { + filename string + subprograms subprograms }{ - {"f1", [][2]uint64{{0x40059d, 0x4005e7}}}, - {"main", [][2]uint64{{0x4005e7, 0x400601}}}, - {"f2", [][2]uint64{{0x400601, 0x400611}}}, + { + "testdata/line-gcc.elf", + subprograms{ + {"f1", [][2]uint64{{0x40059d, 0x4005e7}}}, + {"main", [][2]uint64{{0x4005e7, 0x400601}}}, + {"f2", [][2]uint64{{0x400601, 0x400611}}}, + }, + }, + { + "testdata/line-gcc-dwarf5.elf", + subprograms{ + {"main", [][2]uint64{{0x401147, 0x401166}}}, + {"f1", [][2]uint64{{0x401122, 0x401147}}}, + {"f2", [][2]uint64{{0x401166, 0x401179}}}, + }, + }, + { + "testdata/line-clang-dwarf5.elf", + subprograms{ + {"main", [][2]uint64{{0x401130, 0x401144}}}, + {"f1", [][2]uint64{{0x401150, 0x40117e}}}, + {"f2", [][2]uint64{{0x401180, 0x401197}}}, + }, + }, } - r := d.Reader() - i := 0 - for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() { - if entry.Tag != TagSubprogram { - continue - } + for _, test := range tests { + d := elfData(t, test.filename) + subprograms := test.subprograms - if i > len(subprograms) { - t.Fatalf("too many subprograms (expected at most %d)", i) - } + r := d.Reader() + i := 0 + for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() { + if entry.Tag != TagSubprogram { + continue + } - if got := entry.Val(AttrName).(string); got != subprograms[i].name { - t.Errorf("subprogram %d name is %s, expected %s", i, got, subprograms[i].name) - } - ranges, err := d.Ranges(entry) - if err != nil { - t.Errorf("subprogram %d: %v", i, err) - continue - } - if !reflect.DeepEqual(ranges, subprograms[i].ranges) { - t.Errorf("subprogram %d ranges are %x, expected %x", i, ranges, subprograms[i].ranges) + if i > len(subprograms) { + t.Fatalf("%s: too many subprograms (expected at most %d)", test.filename, i) + } + + if got := entry.Val(AttrName).(string); got != subprograms[i].name { + t.Errorf("%s: subprogram %d name is %s, expected %s", test.filename, i, got, subprograms[i].name) + } + ranges, err := d.Ranges(entry) + if err != nil { + t.Errorf("%s: subprogram %d: %v", test.filename, i, err) + continue + } + if !reflect.DeepEqual(ranges, subprograms[i].ranges) { + t.Errorf("%s: subprogram %d ranges are %x, expected %x", test.filename, i, ranges, subprograms[i].ranges) + } + i++ } - i++ - } - if i < len(subprograms) { - t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms)) + if i < len(subprograms) { + t.Errorf("%s: saw only %d subprograms, expected %d", test.filename, i, len(subprograms)) + } } } @@ -209,3 +252,44 @@ func Test64Bit(t *testing.T) { } } } + +func TestUnitIteration(t *testing.T) { + // Iterate over all ELF test files we have and ensure that + // we get the same set of compilation units skipping (method 0) + // and not skipping (method 1) CU children. + files, err := filepath.Glob(filepath.Join("testdata", "*.elf")) + if err != nil { + t.Fatal(err) + } + for _, file := range files { + t.Run(file, func(t *testing.T) { + d := elfData(t, file) + var units [2][]interface{} + for method := range units { + for r := d.Reader(); ; { + ent, err := r.Next() + if err != nil { + t.Fatal(err) + } + if ent == nil { + break + } + if ent.Tag == TagCompileUnit { + units[method] = append(units[method], ent.Val(AttrName)) + } + if method == 0 { + if ent.Tag != TagCompileUnit { + t.Fatalf("found unexpected tag %v on top level", ent.Tag) + } + r.SkipChildren() + } + } + } + t.Logf("skipping CUs: %v", units[0]) + t.Logf("not-skipping CUs: %v", units[1]) + if !reflect.DeepEqual(units[0], units[1]) { + t.Fatal("set of CUs differ") + } + }) + } +} diff --git a/libgo/go/debug/dwarf/line.go b/libgo/go/debug/dwarf/line.go index 7692f055521..c4937ca7dd8 100644 --- a/libgo/go/debug/dwarf/line.go +++ b/libgo/go/debug/dwarf/line.go @@ -814,7 +814,11 @@ func pathJoin(dirname, filename string) string { // Drives are the same. Ignore drive on filename. } if !(strings.HasSuffix(dirname, "/") || strings.HasSuffix(dirname, `\`)) && dirname != "" { - dirname += `\` + sep := `\` + if strings.HasPrefix(dirname, "/") { + sep = `/` + } + dirname += sep } return drive + dirname + filename } diff --git a/libgo/go/debug/dwarf/line_test.go b/libgo/go/debug/dwarf/line_test.go index 1fd9b19b035..b13818e8b50 100644 --- a/libgo/go/debug/dwarf/line_test.go +++ b/libgo/go/debug/dwarf/line_test.go @@ -341,6 +341,14 @@ var joinTests = []joinTest{ {`\\host\share\`, `foo\bar`, `\\host\share\foo\bar`}, {`//host/share/`, `foo/bar`, `//host/share/foo/bar`}, + // Note: the Go compiler currently emits DWARF line table paths + // with '/' instead of '\' (see issues #19784, #36495). These + // tests are to cover cases that might come up for Windows Go + // binaries. + {`c:/workdir/go/src/x`, `y.go`, `c:/workdir/go/src/x/y.go`}, + {`d:/some/thing/`, `b.go`, `d:/some/thing/b.go`}, + {`e:\blah\`, `foo.c`, `e:\blah\foo.c`}, + // The following are "best effort". We shouldn't see relative // base directories in DWARF, but these test that pathJoin // doesn't fail miserably if it sees one. diff --git a/libgo/go/debug/dwarf/open.go b/libgo/go/debug/dwarf/open.go index d6d4f78b27f..b1a4d3a3a35 100644 --- a/libgo/go/debug/dwarf/open.go +++ b/libgo/go/debug/dwarf/open.go @@ -7,7 +7,10 @@ // http://dwarfstd.org/doc/dwarf-2.0.0.pdf package dwarf -import "encoding/binary" +import ( + "encoding/binary" + "errors" +) // Data represents the DWARF debugging information // loaded from an executable file (for example, an ELF or Mach-O executable). @@ -26,6 +29,7 @@ type Data struct { addr []byte lineStr []byte strOffsets []byte + rngLists []byte // parsed data abbrevCache map[uint64]abbrevTable @@ -36,6 +40,8 @@ type Data struct { unit []unit } +var errSegmentSelector = errors.New("non-zero segment_selector size not supported") + // New returns a new Data object initialized from the given parameters. // Rather than calling this function directly, clients should typically use // the DWARF method of the File type of the appropriate package debug/elf, @@ -108,6 +114,7 @@ func (d *Data) AddTypes(name string, types []byte) error { // 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 { + var err error switch name { case ".debug_addr": d.addr = contents @@ -115,7 +122,9 @@ func (d *Data) AddSection(name string, contents []byte) error { d.lineStr = contents case ".debug_str_offsets": d.strOffsets = contents + case ".debug_rnglists": + d.rngLists = contents } // Just ignore names that we don't yet support. - return nil + return err } diff --git a/libgo/go/debug/dwarf/testdata/debug_rnglists b/libgo/go/debug/dwarf/testdata/debug_rnglists new file mode 100644 index 0000000000000000000000000000000000000000..985ec6c9f283def17ebab9f5b6049794c04c011a GIT binary patch literal 23 dcmWe;U|?Wn-~f^g3@lgq9`Un$;{V3a000{{1Oos7 literal 0 HcmV?d00001 diff --git a/libgo/go/debug/dwarf/testdata/line-clang-dwarf5.elf b/libgo/go/debug/dwarf/testdata/line-clang-dwarf5.elf new file mode 100644 index 0000000000000000000000000000000000000000..7b80c9c5dad459bfc283da9cdda1629494169c30 GIT binary patch literal 18384 zcmeHPeQX@X6`$R`J74VN?AU~uB;W;XnzZL8xBW|8Fk+k?- zB9l04va%89#iWp#Xdm$n~le5;qSDpfrPS#j1BVhJV#rkk=M*PrWdOyA=fJSFqar3 zPPoqjj<-+bUy4!KM@4zH;=(8%f{W&|u1tEox2G!;@64pL#p%xJzTVE>o?sytT+7>i z8B_rK)Ryf#*^eJOzv?&Roj1St^3OBcfz(ff+wZvs>y33le`te*_Ea48N77Nb+|YJH zJsmdnC6kD0u40APubMstdbNr@o64uNW|A2O1SDn@%xK;;CZp*rLmA`I%eD*;^$!?p zgKLB9z;0qPmlbvfI+S^vC1}M8km$M;SELtVUb`rBZj;7Sc#SDWsJLj;W2}f;HH|0h z;EZi`$&G*;0XG6}1l$O?5pW~mM!=1L8-f452ojJjpHKw0Ad2}hV zGa+E5Wd{NCeq-ApW2chA#Rl0FDkn9jQ+yM=F+liuPM&{ml8A=8ux7VNcs2U>B>0=-B3<^^Cw&6p!+;%-<;ax+sFNSvx&0YwPg=hb{ zQ$N(HgZkFtH6P(MJa+@&^phVc=F0BhH@30i*}o0XzCAemdbo7i%lgbINx$(A#q)S= z@7Npue0Xp8&aeS3W_YD}AE>zMyfW^|jer{gHv(=1+z7Z4a3kPGz>R<#0XG6}1pbdA zAi>kUR3ekf)x#cmrLsYXw&63$%jQa@?*i`u9tR!=ei(TByQR`|zz2c93ETv}7#{dN z0{nX5?*li1E2N$O*cs^7uWd@OLa~7yb+)6Kl@Ip^cge&s%~pNn?&2^z!qF` zYKL9JLRY6^B;x$y8w?{ct-i7R{kKU@MZ(%@5TK7K+{*{p+M`yN+h5j@0ZUo#2{HG(J!t+_AIq^O;?LqL}P^85cgUy)6Q%i*GX}07mgiP-@uM{%w zv5?4*U%bbR`!XcT_gEtHD;iH-__&nAL`cZ|oo$eh3z^+RHU85p=pT|Jl>Pe-$AcL?4w4s~{~TO*PzmWgI3 z)P0G3A)U*rHwHt&?#}KWm8HRtmq|QY5_Bpn1xlH1hcoJBejh;Er7-Uph>C>Ua%q=W zl05Q}eLhLq4KgIB7D*m7U|x^c`wDQ`_{ujOe`fc7upXrsidKKS4u7zgffPo>PFph|(;J}G`YTET&h7%AD4(s5+9*seX!hszb`|%_k_rYQLg#^$H z9B6+Oj!)3OYL%|t5)7IZyi{!?Z0;oqeoE!o$~9!o@fTECG$J|f%ViRB>;z#&z+ zzITHj{m^<4ZISlDAyw%oUju!$`dia%fYC6>@2!LF(Hi!(;&2S?CDzOyxmtr%B~>f; zC)}iELBBl%dWkLUx6ccEXaD~**Dw4XeZc)J?9ce@qZ#6cZ#^PWoL31w4gY}TbO-2F zm;jvpzYX+Fpm+BF%h8X#a2&V}^}?r}-Bd%rNBDP^n*_aTcOcS5&@Yu+*=on{@qX0f zQwvq&mN0#DIs$r(!%;E)@wpyyeg#Jp^us=fpC{2?4zMZFpF!kg2tS(8<5~{sXP`$v z&iMRV*wgfj((PGu5iA|4D?w=k0FY}$zC^U?iAB5UUNvt&LxnK0tT z$;tfyu}KD4niZzBrh#<|CUFurjLoCrZ4o1~eGnEXMkOZBjKMwI!`p@iDs%W(f}nyA zAB~7EJm`a?%-Ax#qdz=s?AW~d*2tJK7VaO8pjZBFVXRQ(wa0aik-$Zk`1nxMD!(vv ze2M7HMx^xtB6zO&8WCbz$Qh|LY+cqHL!-9qVlV)@rxS6+jic+uuOys9nFq<bgw-W11f{`obTS=-Qgh%7PC;IPLOxAdUz7u!O>}YGJYeB$0I^k*EN#8}c+l?Vj;}@xWAz{bU`t+P|sFI=JPP`6! zyk|k>(|rxUVgaapx{u*^_!$KG1GpzZ_>iJ;i;%!m`<-~!^7mo=1UBVFC zh_R#caZ7@<3l20T{BcqKae=4%ENF}5jQ^dW!+RWrr*-z6z*Bitf3hR~1;FDy6Ow5? zeo^36$VYP4-_kO6FC_4q5T4fUt>Qw3gdvqr^`Z7ZAn^Udj_&*D0#9~`$2r}Je;9Na z6Y|f*Jcd&y60HL)X<`4Hg$z4h6?j$PRRRhw)a0H$;=t29stLoBjtfS3a{EmOp7tM} zX3K)^Z;`zS3yFN4hec5QX`R4S%LMzTot*e%kZH%y{~v*c8n%NW?Zo3c(2l2l&u-NM zYM5ywx_+cO0SR1di|#hRKN1UBr#;EUp95^84NvH(jiuz;! zN1}4+I{pcCXhL|}m(6vdHLjs5iSWe#0@-#v(=-bZvY2YI@|keN-+>%Ep4OYHz}G6D z9A1C~`l9;N`Yj~zR1Vo=S$6sd2&fb0;fX7dptRj|LO6Wfu7tGHwy_3Y z>9&ARTmpY(4g8Y=|KTO@YXsie{>Rr^!0*(+Q#*QUl)vc)3t0YL3qOP-w*xisVS!&w zhBfdzYT(lXuU`T`F7VFw|4`s@ey|hO-_D(FMEg*Wg?dR0?Cl`pT7mi_%?mg_Qs1=@ e*4e+o;xAG`BGVzl-l{tOk2hO@yaV76*}niox8D;0 literal 0 HcmV?d00001 diff --git a/libgo/go/debug/dwarf/testdata/line-gcc-dwarf5.elf b/libgo/go/debug/dwarf/testdata/line-gcc-dwarf5.elf new file mode 100644 index 0000000000000000000000000000000000000000..34ce17cc426b5b552404c8055136f5797e887603 GIT binary patch literal 18040 zcmeHPe~cVe9e*=(d$;9!+q+&{4hnQyODw|e-IcbKmTPD4N4tmD7E22SEyLdJ-tFSv zZnHZJS46BH0vBv45tE`2&=}MBkN!cBXd=`$EhdnZh(@Evf&~i{IEWCUh4u4&^S*nt zb9)hEG%?OgX1+f^@5guE&U-WS-hQQjaFecSf|D*b2$HO3ORC(n5Fd6+QR&u-Mq!C% zVyUQyrVfWCEks?8XPTTnsN<^5^g$KigoE)Wn?Ov zT{GcA#41^+_Az}+6~L7JD&?63Mlvl)m>yC%rd}Myra9`mH*aupOik796^b&BM8cU0 zXDS@ild3$X98YRC9miCD$8-x4$rcgOC(qNAd?{V`s*@ysu1OM6tBMXvNeHHl`y6mo z&rg~-?Auj&v&CgfwU4P1MMpL>v}RRDHrbxd=A$cRyBDA$)TcIY z-6_6w_L}z&oyxw@dC{W>?rM7NQ2fc4UZ;9f9VkEYp+x>1e$w+nwojS}Grxv2#io{? zE~{C?U+gJ4MPb`$=CECK5(UQ|OJs6_WNPIav3YQyr`KK?T^U^sztORLPWjoCovvD< zp%rbAIo_oUGjqtgOqDsc(UKh1kK0a)4?TK{3#T^Al57Lc)Yc#c5eOm>L?DPj5P={9 zK?H&b1Q7@#@V^^@_{7<8{DIJ09YVyv{;Z>yPsS&Xg^yMmR9^iGOyx^Y<2-MP1&-u2 z*B4_X6|Rc}x0)I64xY zx8xp~y_BEs!~;gWo6b(_)1;?r%z1_s z@<9K&_@U!{q4%_j{&U*Im(R_)`|QDkyN{BSEc?t0$kOHLkx6o{IljO9n-L+-{Pg2; z8HjmH_EDCx8wdAy-**L=8wMtS6Wcj3`F?CiZ1UXB`2O~BsIMQq>?68HXRZejYZ}(09C01VWr})HCEq?VMOK;G%`~2?M7h=0(x5R9eA?QlVYg~0z zspKF95eOm>L?DPj5P={9K?H&b1Q7@#5JVt|!2eSOG<*e2r?S~R8m%oh*2h8VoAQFG za{2q9t3Z>WNzj9!i{34lp9ftJdKUC%(7E_9=zv}U`Vy!EO5bBCX?JcH+IX|Jcy2@Z zpw`e#-zDkW{&Vk?%a@Y_Qf*)N8z%Wa4`2TFxEyjPjx=;8sE9OginLujuknuXKC$t_ z^`E(N`7%-yZWoRo)caCW#3If2>b*_%x1u5t$v%!_Gwe%1EB2eG?T4V=1beI3zSXt& zK}Qew7VNvp-Vxjuru^{OC*|YHuGIfE!t2WY1+L-s@jk=m z-rjZQioVoPCXq9{IpUu5GL1uMESSYa)#~) zI6^{`&PE4>i)oSdeK=~BRQEL)^iXIJgcc%Dk`Mc!+M}VmP$uVy`jIZ7X-$lmFAJpo z0Xh$rMugEotp3oDmJxOJl$rieRy2GM%y)2v=`=^^Vc9oyt^N;?#RLwj>D{2Ztmz}* zsHXlllBec^wYmn{q@ZcxUlGw8o|01iucZ|FC5YkHS__9>c5PHz-N;Iz8TJ00wMT`v zN*LjFOSSclS2qr{>gbmGa?#khq0zuv1fxZ}G|~!oaim3?-_VTCUKbS`FEAqO8eIUX zt+u=Hs}3m`LSG-%kf-!;?RQ?F;es`2+CVEY;iY1rwS#_%+H_g^%(9H>EZt(OGNnSr zS8y2El0q^0d!z|xxmN|h9xa&~Dvfp|??@CzI-FF|NhX|xz>!a1$~`%ZAeSk=>sACvyX?gS9Ki)ZkJWK@?WdM z%BZJYzAOuoZAkl>ZXnleJ~wKXa>dMOE|oN?AJ%FQc0EvYhH1-!+1quM`k9&SV@@fT z>K;wyQiaSg#6)2@-Rq+&W>aH^~As;B{#)(oc;1tA+q>VKXPkIKFuueX6) z$uZsXsw8iqOPr~xud9q3UXXzwB99l<`ufVaQmtJS*|* zc{bwLUtFzFk|8dcp~rm(`;p!)`werU&_$Ej=exeR3rqcvefp(J&+{*81X7<}ZOa09L|AEYBWG22T3sj8GT` zZ9AE_N3;2%MAl9^`9jf7l*Ywyer!)R<)o6)&e|UKNG6xD6NN%zubs*{g}q{=kQhtZ z$H7X1_KsN3U_a$5cNY#9OS1L?lSbNgXjxTT3sZ6; zHDf2D&&wt+cLO5wt=f% z6y@e*hV4BW!0e%7QDrYDDz?32ORtKKh!*#bVHN}G6kM8S4l|BaVULLB@=hu`nkz+z zN*Qb#%_Nm7)-!+!(5R5MbfTCR(d6D7@^h(Ea4ol|3dKx5S0&i6p{@x6C~i;I5mDKY zsFNB8PrU-Ryo_Nql~(;AodlL87vXjY7r{I-PK;%SQEDD};S`kxxS1g!B8q-FhVF*S z((D(wL~azFSc#e3NS^t`&`=?DJ4@8fm`AA8kMG|gG=kzMhcUrThjmLbyr0`Yl9I1C zeF_3SFEO6ydAxslxz`yy-;Y?m28D>g&Jg+^e@TM%)-HYz6zfy}k!B9*Y&-33Yh3EGnTt3%_ z+kcP3_oxi{{fenB6#Ee#qw|dT9e|GN#qWaz&!3v1MB?{0t~9g%Ov2#Bn+k6#yvaaC zl^SD}n;r)7;(1)Nl*4z)=t+!Y)wjWT@jQ<|-Qs%idnEQ(VPR1`0gmt-|H^#dgc6D0 zi@DOw_8*49i=W>2?;_|ehd24le+ot~o}V9fnJ&sAqbKq8XVtS{Xzr`JOXWF({};gT z&oa~JfyHd4g6H{RTNFwp_H(6anf1Sgf%*=Y&+|zB--VN^{@lM9$Jg;?V9AB?{CqP- zuX>Q!&y{AD{~8QleC0W)(?ysJRFunS`VRD7JkS43g`cf_&h~vUlo!{Z=Tn^u&*iW` zmE}!;gFrgvUNJGAU$e1+@k|Xc%(D;CZ7RcCy-M(Y-}$rPf28mvy~_v2};lV3-W$5*<*-?^l6_WRO&o^<~Bjnj)Jq&HkrIWyi%E5H4U7uH3sa)oi# taZQL+CBB|~U#0sCUwg2XbZVW;zQhG7i%-O}LT&t$*SLUQAHXMye*hNQ!F~V$ literal 0 HcmV?d00001 diff --git a/libgo/go/debug/elf/elf.go b/libgo/go/debug/elf/elf.go index 96a67ce7327..2b777eabac7 100644 --- a/libgo/go/debug/elf/elf.go +++ b/libgo/go/debug/elf/elf.go @@ -745,18 +745,51 @@ func (i CompressionType) GoString() string { return stringName(uint32(i), compre type ProgType int const ( - PT_NULL ProgType = 0 /* Unused entry. */ - PT_LOAD ProgType = 1 /* Loadable segment. */ - PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */ - PT_INTERP ProgType = 3 /* Pathname of interpreter. */ - PT_NOTE ProgType = 4 /* Auxiliary information. */ - PT_SHLIB ProgType = 5 /* Reserved (not used). */ - PT_PHDR ProgType = 6 /* Location of program header itself. */ - PT_TLS ProgType = 7 /* Thread local storage segment */ - PT_LOOS ProgType = 0x60000000 /* First OS-specific. */ - PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */ - PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */ - PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */ + PT_NULL ProgType = 0 /* Unused entry. */ + PT_LOAD ProgType = 1 /* Loadable segment. */ + PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */ + PT_INTERP ProgType = 3 /* Pathname of interpreter. */ + PT_NOTE ProgType = 4 /* Auxiliary information. */ + PT_SHLIB ProgType = 5 /* Reserved (not used). */ + PT_PHDR ProgType = 6 /* Location of program header itself. */ + PT_TLS ProgType = 7 /* Thread local storage segment */ + + PT_LOOS ProgType = 0x60000000 /* First OS-specific. */ + + PT_GNU_EH_FRAME ProgType = 0x6474e550 /* Frame unwind information */ + PT_GNU_STACK ProgType = 0x6474e551 /* Stack flags */ + PT_GNU_RELRO ProgType = 0x6474e552 /* Read only after relocs */ + PT_GNU_PROPERTY ProgType = 0x6474e553 /* GNU property */ + PT_GNU_MBIND_LO ProgType = 0x6474e555 /* Mbind segments start */ + PT_GNU_MBIND_HI ProgType = 0x6474f554 /* Mbind segments finish */ + + PT_PAX_FLAGS ProgType = 0x65041580 /* PAX flags */ + + PT_OPENBSD_RANDOMIZE ProgType = 0x65a3dbe6 /* Random data */ + PT_OPENBSD_WXNEEDED ProgType = 0x65a3dbe7 /* W^X violations */ + PT_OPENBSD_BOOTDATA ProgType = 0x65a41be6 /* Boot arguments */ + + PT_SUNW_EH_FRAME ProgType = 0x6474e550 /* Frame unwind information */ + PT_SUNWSTACK ProgType = 0x6ffffffb /* Stack segment */ + + PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */ + + PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */ + + PT_ARM_ARCHEXT ProgType = 0x70000000 /* Architecture compatibility */ + PT_ARM_EXIDX ProgType = 0x70000001 /* Exception unwind tables */ + + PT_AARCH64_ARCHEXT ProgType = 0x70000000 /* Architecture compatibility */ + PT_AARCH64_UNWIND ProgType = 0x70000001 /* Exception unwind tables */ + + PT_MIPS_REGINFO ProgType = 0x70000000 /* Register usage */ + PT_MIPS_RTPROC ProgType = 0x70000001 /* Runtime procedures */ + PT_MIPS_OPTIONS ProgType = 0x70000002 /* Options */ + PT_MIPS_ABIFLAGS ProgType = 0x70000003 /* ABI flags */ + + PT_S390_PGSTE ProgType = 0x70000000 /* 4k page table size */ + + PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */ ) var ptStrings = []intName{ @@ -769,8 +802,19 @@ var ptStrings = []intName{ {6, "PT_PHDR"}, {7, "PT_TLS"}, {0x60000000, "PT_LOOS"}, + {0x6474e550, "PT_GNU_EH_FRAME"}, + {0x6474e551, "PT_GNU_STACK"}, + {0x6474e552, "PT_GNU_RELRO"}, + {0x6474e553, "PT_GNU_PROPERTY"}, + {0x65041580, "PT_PAX_FLAGS"}, + {0x65a3dbe6, "PT_OPENBSD_RANDOMIZE"}, + {0x65a3dbe7, "PT_OPENBSD_WXNEEDED"}, + {0x65a41be6, "PT_OPENBSD_BOOTDATA"}, + {0x6ffffffb, "PT_SUNWSTACK"}, {0x6fffffff, "PT_HIOS"}, {0x70000000, "PT_LOPROC"}, + // We don't list the processor-dependent ProgTypes, + // as the values overlap. {0x7fffffff, "PT_HIPROC"}, } @@ -837,15 +881,114 @@ const ( the interpretation of the d_un union as follows: even == 'd_ptr', even == 'd_val' or none */ - DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */ - DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */ - DT_LOOS DynTag = 0x6000000d /* First OS-specific */ - DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */ - DT_VERSYM DynTag = 0x6ffffff0 - DT_VERNEED DynTag = 0x6ffffffe - DT_VERNEEDNUM DynTag = 0x6fffffff - DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */ - DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */ + DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */ + DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */ + DT_SYMTAB_SHNDX DynTag = 34 /* Address of SHT_SYMTAB_SHNDX section. */ + + DT_LOOS DynTag = 0x6000000d /* First OS-specific */ + DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */ + + DT_VALRNGLO DynTag = 0x6ffffd00 + DT_GNU_PRELINKED DynTag = 0x6ffffdf5 + DT_GNU_CONFLICTSZ DynTag = 0x6ffffdf6 + DT_GNU_LIBLISTSZ DynTag = 0x6ffffdf7 + DT_CHECKSUM DynTag = 0x6ffffdf8 + DT_PLTPADSZ DynTag = 0x6ffffdf9 + DT_MOVEENT DynTag = 0x6ffffdfa + DT_MOVESZ DynTag = 0x6ffffdfb + DT_FEATURE DynTag = 0x6ffffdfc + DT_POSFLAG_1 DynTag = 0x6ffffdfd + DT_SYMINSZ DynTag = 0x6ffffdfe + DT_SYMINENT DynTag = 0x6ffffdff + DT_VALRNGHI DynTag = 0x6ffffdff + + DT_ADDRRNGLO DynTag = 0x6ffffe00 + DT_GNU_HASH DynTag = 0x6ffffef5 + DT_TLSDESC_PLT DynTag = 0x6ffffef6 + DT_TLSDESC_GOT DynTag = 0x6ffffef7 + DT_GNU_CONFLICT DynTag = 0x6ffffef8 + DT_GNU_LIBLIST DynTag = 0x6ffffef9 + DT_CONFIG DynTag = 0x6ffffefa + DT_DEPAUDIT DynTag = 0x6ffffefb + DT_AUDIT DynTag = 0x6ffffefc + DT_PLTPAD DynTag = 0x6ffffefd + DT_MOVETAB DynTag = 0x6ffffefe + DT_SYMINFO DynTag = 0x6ffffeff + DT_ADDRRNGHI DynTag = 0x6ffffeff + + DT_VERSYM DynTag = 0x6ffffff0 + DT_RELACOUNT DynTag = 0x6ffffff9 + DT_RELCOUNT DynTag = 0x6ffffffa + DT_FLAGS_1 DynTag = 0x6ffffffb + DT_VERDEF DynTag = 0x6ffffffc + DT_VERDEFNUM DynTag = 0x6ffffffd + DT_VERNEED DynTag = 0x6ffffffe + DT_VERNEEDNUM DynTag = 0x6fffffff + + DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */ + + DT_MIPS_RLD_VERSION DynTag = 0x70000001 + DT_MIPS_TIME_STAMP DynTag = 0x70000002 + DT_MIPS_ICHECKSUM DynTag = 0x70000003 + DT_MIPS_IVERSION DynTag = 0x70000004 + DT_MIPS_FLAGS DynTag = 0x70000005 + DT_MIPS_BASE_ADDRESS DynTag = 0x70000006 + DT_MIPS_MSYM DynTag = 0x70000007 + DT_MIPS_CONFLICT DynTag = 0x70000008 + DT_MIPS_LIBLIST DynTag = 0x70000009 + DT_MIPS_LOCAL_GOTNO DynTag = 0x7000000a + DT_MIPS_CONFLICTNO DynTag = 0x7000000b + DT_MIPS_LIBLISTNO DynTag = 0x70000010 + DT_MIPS_SYMTABNO DynTag = 0x70000011 + DT_MIPS_UNREFEXTNO DynTag = 0x70000012 + DT_MIPS_GOTSYM DynTag = 0x70000013 + DT_MIPS_HIPAGENO DynTag = 0x70000014 + DT_MIPS_RLD_MAP DynTag = 0x70000016 + DT_MIPS_DELTA_CLASS DynTag = 0x70000017 + DT_MIPS_DELTA_CLASS_NO DynTag = 0x70000018 + DT_MIPS_DELTA_INSTANCE DynTag = 0x70000019 + DT_MIPS_DELTA_INSTANCE_NO DynTag = 0x7000001a + DT_MIPS_DELTA_RELOC DynTag = 0x7000001b + DT_MIPS_DELTA_RELOC_NO DynTag = 0x7000001c + DT_MIPS_DELTA_SYM DynTag = 0x7000001d + DT_MIPS_DELTA_SYM_NO DynTag = 0x7000001e + DT_MIPS_DELTA_CLASSSYM DynTag = 0x70000020 + DT_MIPS_DELTA_CLASSSYM_NO DynTag = 0x70000021 + DT_MIPS_CXX_FLAGS DynTag = 0x70000022 + DT_MIPS_PIXIE_INIT DynTag = 0x70000023 + DT_MIPS_SYMBOL_LIB DynTag = 0x70000024 + DT_MIPS_LOCALPAGE_GOTIDX DynTag = 0x70000025 + DT_MIPS_LOCAL_GOTIDX DynTag = 0x70000026 + DT_MIPS_HIDDEN_GOTIDX DynTag = 0x70000027 + DT_MIPS_PROTECTED_GOTIDX DynTag = 0x70000028 + DT_MIPS_OPTIONS DynTag = 0x70000029 + DT_MIPS_INTERFACE DynTag = 0x7000002a + DT_MIPS_DYNSTR_ALIGN DynTag = 0x7000002b + DT_MIPS_INTERFACE_SIZE DynTag = 0x7000002c + DT_MIPS_RLD_TEXT_RESOLVE_ADDR DynTag = 0x7000002d + DT_MIPS_PERF_SUFFIX DynTag = 0x7000002e + DT_MIPS_COMPACT_SIZE DynTag = 0x7000002f + DT_MIPS_GP_VALUE DynTag = 0x70000030 + DT_MIPS_AUX_DYNAMIC DynTag = 0x70000031 + DT_MIPS_PLTGOT DynTag = 0x70000032 + DT_MIPS_RWPLT DynTag = 0x70000034 + DT_MIPS_RLD_MAP_REL DynTag = 0x70000035 + + DT_PPC_GOT DynTag = 0x70000000 + DT_PPC_OPT DynTag = 0x70000001 + + DT_PPC64_GLINK DynTag = 0x70000000 + DT_PPC64_OPD DynTag = 0x70000001 + DT_PPC64_OPDSZ DynTag = 0x70000002 + DT_PPC64_OPT DynTag = 0x70000003 + + DT_SPARC_REGISTER DynTag = 0x70000001 + + DT_AUXILIARY DynTag = 0x7ffffffd + DT_USED DynTag = 0x7ffffffe + DT_FILTER DynTag = 0x7fffffff + + DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */ ) var dtStrings = []intName{ @@ -883,13 +1026,49 @@ var dtStrings = []intName{ {32, "DT_ENCODING"}, {32, "DT_PREINIT_ARRAY"}, {33, "DT_PREINIT_ARRAYSZ"}, + {34, "DT_SYMTAB_SHNDX"}, {0x6000000d, "DT_LOOS"}, {0x6ffff000, "DT_HIOS"}, + {0x6ffffd00, "DT_VALRNGLO"}, + {0x6ffffdf5, "DT_GNU_PRELINKED"}, + {0x6ffffdf6, "DT_GNU_CONFLICTSZ"}, + {0x6ffffdf7, "DT_GNU_LIBLISTSZ"}, + {0x6ffffdf8, "DT_CHECKSUM"}, + {0x6ffffdf9, "DT_PLTPADSZ"}, + {0x6ffffdfa, "DT_MOVEENT"}, + {0x6ffffdfb, "DT_MOVESZ"}, + {0x6ffffdfc, "DT_FEATURE"}, + {0x6ffffdfd, "DT_POSFLAG_1"}, + {0x6ffffdfe, "DT_SYMINSZ"}, + {0x6ffffdff, "DT_SYMINENT"}, + {0x6ffffdff, "DT_VALRNGHI"}, + {0x6ffffe00, "DT_ADDRRNGLO"}, + {0x6ffffef5, "DT_GNU_HASH"}, + {0x6ffffef6, "DT_TLSDESC_PLT"}, + {0x6ffffef7, "DT_TLSDESC_GOT"}, + {0x6ffffef8, "DT_GNU_CONFLICT"}, + {0x6ffffef9, "DT_GNU_LIBLIST"}, + {0x6ffffefa, "DT_CONFIG"}, + {0x6ffffefb, "DT_DEPAUDIT"}, + {0x6ffffefc, "DT_AUDIT"}, + {0x6ffffefd, "DT_PLTPAD"}, + {0x6ffffefe, "DT_MOVETAB"}, + {0x6ffffeff, "DT_SYMINFO"}, + {0x6ffffeff, "DT_ADDRRNGHI"}, {0x6ffffff0, "DT_VERSYM"}, + {0x6ffffff9, "DT_RELACOUNT"}, + {0x6ffffffa, "DT_RELCOUNT"}, + {0x6ffffffb, "DT_FLAGS_1"}, + {0x6ffffffc, "DT_VERDEF"}, + {0x6ffffffd, "DT_VERDEFNUM"}, {0x6ffffffe, "DT_VERNEED"}, {0x6fffffff, "DT_VERNEEDNUM"}, {0x70000000, "DT_LOPROC"}, - {0x7fffffff, "DT_HIPROC"}, + // We don't list the processor-dependent DynTags, + // as the values overlap. + {0x7ffffffd, "DT_AUXILIARY"}, + {0x7ffffffe, "DT_USED"}, + {0x7fffffff, "DT_FILTER"}, } func (i DynTag) String() string { return stringName(uint32(i), dtStrings, false) } diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go index 48178d480d7..b4091670f9d 100644 --- a/libgo/go/debug/elf/file.go +++ b/libgo/go/debug/elf/file.go @@ -634,23 +634,14 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error { } } -// relocSymbolTargetOK decides whether we should try to apply a +// canApplyRelocation reports 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 +// 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). +func canApplyRelocation(sym *Symbol) bool { + return sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE } func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error { @@ -676,8 +667,7 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -690,13 +680,13 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val64 := val + uint64(rela.Addend) + val64 := sym.Value + 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 } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -802,8 +792,7 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -816,13 +805,13 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val64 := uint64(val) + uint64(rela.Addend) + val64 := sym.Value + 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 } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -853,8 +842,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -863,7 +851,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error { if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 { continue } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -894,8 +882,7 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -904,13 +891,13 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val64 := val + uint64(rela.Addend) + val64 := sym.Value + 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 } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -986,8 +973,7 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -996,13 +982,13 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val64 := val + uint64(rela.Addend) + val64 := sym.Value + 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 } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -1033,8 +1019,7 @@ func (f *File) applyRelocationsRISCV(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -1043,7 +1028,7 @@ func (f *File) applyRelocationsRISCV(dst []byte, rels []byte) error { if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 { continue } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -1074,8 +1059,7 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -1084,13 +1068,13 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val64 := val + uint64(rela.Addend) + val64 := sym.Value + 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 } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -1121,8 +1105,7 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -1131,13 +1114,13 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val64 := val + uint64(rela.Addend) + val64 := sym.Value + 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 } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } @@ -1208,8 +1191,7 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error { continue } sym := &symbols[symNo-1] - needed, val := relocSymbolTargetOK(sym) - if !needed { + if !canApplyRelocation(sym) { continue } @@ -1218,13 +1200,13 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error { if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { continue } - val64 := val + uint64(rela.Addend) + val64 := sym.Value + 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 } - val32 := uint32(val) + uint32(rela.Addend) + val32 := uint32(sym.Value) + uint32(rela.Addend) f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32) } } diff --git a/libgo/go/debug/elf/file_test.go b/libgo/go/debug/elf/file_test.go index b13d13ebf09..4c6fdeece9c 100644 --- a/libgo/go/debug/elf/file_test.go +++ b/libgo/go/debug/elf/file_test.go @@ -293,6 +293,7 @@ func decompress(gz string) (io.ReaderAt, error) { type relocationTestEntry struct { entryNumber int entry *dwarf.Entry + pcRanges [][2]uint64 } type relocationTest struct { @@ -304,367 +305,481 @@ var relocationTests = []relocationTest{ { "testdata/go-relocation-test-gcc441-x86-64.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x6}}, + }, }, }, { "testdata/go-relocation-test-gcc441-x86.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x5}}, + }, }, }, { "testdata/go-relocation-test-gcc424-x86-64.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x6}}, + }, }, }, { "testdata/go-relocation-test-gcc482-aarch64.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x24}}, + }, }, }, { "testdata/go-relocation-test-gcc492-arm.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x28}}, + }, }, }, { "testdata/go-relocation-test-clang-arm.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(48), Class: dwarf.ClassConstant}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x30), Class: dwarf.ClassConstant}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x30}}, + }, }, }, { "testdata/go-relocation-test-gcc5-ppc.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x44}}, + }, }, }, { "testdata/go-relocation-test-gcc482-ppc64le.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x24}}, + }, }, }, { "testdata/go-relocation-test-gcc492-mips64.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x64}}, + }, }, }, { "testdata/go-relocation-test-gcc531-s390x.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(58), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x3a), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x3a}}, + }, }, }, { "testdata/go-relocation-test-gcc620-sparc64.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x2c}}, + }, }, }, { "testdata/go-relocation-test-gcc492-mipsle.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x58}}, + }, }, }, { "testdata/go-relocation-test-gcc540-mips.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x5c}}, + }, }, }, { "testdata/go-relocation-test-gcc493-mips64le.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x64}}, + }, }, }, { "testdata/go-relocation-test-gcc720-riscv64.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, }, - }}, + pcRanges: [][2]uint64{{0x0, 0x2c}}, + }, }, }, { "testdata/go-relocation-test-clang-x86.obj", []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + }, }, - }}, + }, }, }, { "testdata/gcc-amd64-openbsd-debug-with-rela.obj", []relocationTestEntry{ - {203, &dwarf.Entry{ - Offset: 0xc62, - Tag: dwarf.TagMember, - Children: false, - Field: []dwarf.Field{ - {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString}, - {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, - {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc}, + { + entryNumber: 203, + entry: &dwarf.Entry{ + Offset: 0xc62, + Tag: dwarf.TagMember, + Children: false, + Field: []dwarf.Field{ + {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString}, + {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, + {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc}, + }, }, - }}, - {204, &dwarf.Entry{ - Offset: 0xc70, - Tag: dwarf.TagMember, - Children: false, - Field: []dwarf.Field{ - {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString}, - {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, - {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc}, + }, + { + entryNumber: 204, + entry: &dwarf.Entry{ + Offset: 0xc70, + Tag: dwarf.TagMember, + Children: false, + Field: []dwarf.Field{ + {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString}, + {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, + {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc}, + }, }, - }}, + }, + }, + }, + { + "testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64", + []relocationTestEntry{ + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr}, + {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, + }, + pcRanges: [][2]uint64{ + {0x765, 0x777}, + {0x7e1, 0x7ec}, + }, + }, + }, + }, + { + "testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64", + []relocationTestEntry{ + { + entry: &dwarf.Entry{ + Offset: 0xb, + Tag: dwarf.TagCompileUnit, + Children: true, + Field: []dwarf.Field{ + {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString}, + {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, + {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString}, + {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, + {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr}, + {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress}, + {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, + }, + }, + pcRanges: [][2]uint64{ + {0x765, 0x777}, + {0x7e1, 0x7ec}, + }, + }, }, }, } func TestDWARFRelocations(t *testing.T) { - for i, test := range relocationTests { - f, err := Open(test.file) - if err != nil { - t.Error(err) - continue - } - dwarf, err := f.DWARF() - if err != nil { - t.Error(err) - continue - } - for _, testEntry := range test.entries { - reader := dwarf.Reader() - for j := 0; j < testEntry.entryNumber; j++ { - entry, err := reader.Next() - if entry == nil || err != nil { - t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err) - continue - } + for _, test := range relocationTests { + test := test + t.Run(test.file, func(t *testing.T) { + t.Parallel() + f, err := Open(test.file) + if err != nil { + t.Fatal(err) } - entry, err := reader.Next() + dwarf, err := f.DWARF() if err != nil { - t.Error(err) - continue + t.Fatal(err) } - if !reflect.DeepEqual(testEntry.entry, entry) { - t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry) - continue + reader := dwarf.Reader() + idx := 0 + for _, testEntry := range test.entries { + if testEntry.entryNumber < idx { + t.Fatalf("internal test error: %d < %d", testEntry.entryNumber, idx) + } + for ; idx < testEntry.entryNumber; idx++ { + entry, err := reader.Next() + if entry == nil || err != nil { + t.Fatalf("Failed to skip to entry %d: %v", testEntry.entryNumber, err) + } + } + entry, err := reader.Next() + idx++ + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(testEntry.entry, entry) { + t.Errorf("entry %d mismatch: got:%#v want:%#v", testEntry.entryNumber, entry, testEntry.entry) + } + pcRanges, err := dwarf.Ranges(entry) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(testEntry.pcRanges, pcRanges) { + t.Errorf("entry %d: PC range mismatch: got:%#v want:%#v", testEntry.entryNumber, pcRanges, testEntry.pcRanges) + } } - } + }) } } @@ -784,7 +899,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", "plan9", "windows": + case "aix", "android", "darwin", "ios", "js", "plan9", "windows": t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS) } _ = net.ResolveIPAddr // force dynamic linkage diff --git a/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64 b/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64 new file mode 100644 index 0000000000000000000000000000000000000000..c013f3e081c7ecf1056be3457332be97ffa0f31c GIT binary patch literal 5696 zcmbtXOK%%h6u#q$lN2Xzl0uvEl7S+MkcUzzEssLl(4>KshX^krbUU%fj=>&>@wiPu zKsP{zSdxc`~{Y=L1IF7ZXOA^M!ZX$!t11uVl3F&Pg*gRBVN@DUO~dpg8&p{SG_B zXUL44q911}ajpC7d|;eO=f?7ml3Tv2{KT$FXM*Cp;5qm2cFT8{?kU|>x@q^qj!9=~ zWM=xkqr06Q)RCe=-NKFnh4s)LQ!3q8a%qZ++bO$1q+!7*SVlavg*WQg3-oo(t=vQB z&+<6^CPyO0ykk23cHCNR2i01)9#nflEpBzgo>wC>wKQS26)+rk(kYHTRCJyx6v#vI zdaA-Cx>q>GZJ(lwgqPFzZ%U4F)+WYAM$gIq+QVKc!6%mVNO|Io!tD6)9C5iGJT!n% z0PlqG{HS@#%s>1@W%jm%X*5-;owy$chnqndM6DVX{iwEbcde+)2*;xjs4|z&@;Ejoz<;pg&M4xMn9~Xj^7GRZN-lUp>$f}6odQa zKQYFtxGlfyiWN;MxVziUNmR3hv~r2u+ism${#WMoK5jj zvzl`lxMthneihe=am{6eb>E1WOx{$vX3XewGi`U=RC3No*Obk7nR^^xaNw@AR(^Vxdo2faAUP=aNB8o_eOw9y#0pE zZ-46wzSj%1UZ1ITXo4Ewvyj~sgb5i+PPxzbH{XF4$ z{oiU_M9<}a&J`3_I)1(pT*uqDggZI$!|#Ox-Pn4+{7n2Qo;Mj6=HXAmEA-Xrej-$I z;&2z?6ZFw>_&Yh6Ds0{_*AhQ3IuDB<9p?`cUeTSQ@-u`_7A8zZ#eakFsm%Vxx&1**-xR*S2i_)}`>FZo39pFHtoefQ>$3pz zwJ7ez{YHZ>ym}A?%~mfCA{%#Xt=$djHn6tdwas>S*>Br=+>LtH@2{C!w?kKE9Mrvo zcO2NCPqK|x*s^{U`Rg_a<7nM9BEJ*ZdcV_ICrPGci5YL8Zh0%)jodmp%7}ZhAH~Mb zFFtbg$fA8@Ztn48OLpnV(Zyqyi0#&L&DMJTq-Vx1ES<3bj(O?CERT4JFF|92x*z+H zBwj7wcQZ5diwj3*?S5~+cYvyyWu;Nu>~zDlV7aw=uWMKQuukrh`!dr$_m~*Vy`G4Z zyVP3hgFW`}11#sxVL3K-&DPd@9)aI(y%cQhknwu!9lFNJ#!+flkgKnURB1f6ab&z^ z*!NBaQIB3b8w!@{qM+?F(RfKuz14Q?HM_C#;$V$_d%>z7`Eg+7wPZYA>Xe+WVu~P7 zQg%UY^Q3w-Y~xV`btozb3zqv$V)|i|!cB^;u+c@{UtW%aQz*4tVSs!RK`11HN}Y)> zg!uolSCN<>Wa;zV4BjR9Uvy5Kb3JXbgv$_arW*u<9`6_E`30R#>?51_e8{$scMkOU zUkV-Cfjy-3cn?8ek;ZiY1vc|ak9QOFUkefKCy!UcF#g9xk82e71@!u6*U!86l^*Y~ zbMik=9j|nTrU~{brN?^>dh}OhgY^S`Qt8jgK%n#xDy5yGvqF>=c zCh7Iy_ae8i=l`PUU(aYci@w4#Fvw@Pft&-{ujX_U(--|mT=V`$ c>}K^9IruNA233(>l==E!$5U@*B~V544_DUSr~m)} literal 0 HcmV?d00001 diff --git a/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64 b/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64 new file mode 100644 index 0000000000000000000000000000000000000000..51e03aa7b0d6010410a31d6594540b07c0b3b6c5 GIT binary patch literal 7680 zcmbVQQEVJX8J@lM*$#FtXD3aZ7OGR45Vz&FuG_RpO45s+#CCC-RB;Oxp!NE0eZF$H zXZH3Iy9kIXrSeOq6d^&R2r8i3-6AwJV122{6Lkh|Z;-NesBDGTZ|K0yP z&&};Y#7KAl%s2n{|Ns0mJF~OjKeKo?V_6EtRwos=t_&tf2_1V-QL3bls$KLysSYbv z8=zlFx=lH6CmoQ(qQ@}vP;QGJ+NK1LW7B!2-j>*b?8loIBapDOQ&Q27_gXg5gamI? zDjAVxoNK~^1n-Vibbq26_sq*YK!UeVD#!)<(|OCng9L9vDtVD65AzNQUR&~_^Vm1? zd~XPv=~5q`gcd7KIuqPyu;BiyuO$rbCrUZ{;M2=YJqX%4P7w$$Co%h)Tj_(!X z>2aEInQg>5H#>X0FnQWvsd+)+nDdM?Rebu$<4H|@nOI3a5_MmK85e6GOMAq$F72O^ zOa?P-@gf=h8vR|APF-ZaLoI7>_6-uI6YB<}_P1k=9M?1N*5hnidmm;r^X{@57|7Ow zNM(mF6ObMLF8vQ$gI7olU7|m0JT`5{Yu!-Rm~|+(d&JH?l6!UEn3bpXopG!e_uIMS zBQJ~`8#%mxVfUCdK2)0c(ae5pHwBVa=v&yGp=CXAP>qb79I+`y*s$1*)l(dy^=WP={l{A(t$9l|+V!ZmUiXXTX2mbI{Bl%l1}&#d%H%1pc4ROd zd(6s?ekE(Yp2?7f>;dXR677eq?2ccdi-^3P-lt+IYa>58G<;2-uY+ur3T$FZPv!D& zXJ&T}o+VxGhaMbYDM0U>=y_rFlA3$@)xzx4&nK&?P;5l)z&}y-13#>lsp*B~wG$gh zpDRB1Y@t{!6jy_0(Q9o6<+ZRGG~2CWJGfj6D#gfKsrxPURMc4SpA~XgR;%rxtQuY| zP~|l*>@20rvQ9C$fBcV!iU*ofY?>8w-)1$N9+D6BhgP^Y^_cs0qCcR_{W!t1YD?ct zJ9Y+@xeq7$!^+%e6MTnSPuUD?^|{XZDyCy$tI^K9cjG%%TB>Z7Q|7*z_|25R?2#NiyUX@gg2kB zd!#?kd6RJ=55rU`#6G(J7Gu13-5w-7pE6$=!pAec&)1WTcbkq|FU59x?SGZ z;bWOSs$e`XEyBmO=NhoWzu z8`lXR%k-}2n}ip{rY?R*c@Gtx>3U| z*P8(yC9Yd(y48Af#jCrOs2R3guf3tl%?6#fkzaA1fA+|9x{|wE3u>+xhTf*@2T{1G zRzt7hyOnmMu}KuI<&tL9rP}vMce`~fWJn{oA}@@TJGXd#=G3Bl{_NR{XO`ThQ!|Ta zTvDvpR?2R<)s7=m?!wYJcYDl~2p;hgpP7478hn_-DzjqIYQm6 z<%(0c+GqwzgOW*ot){!?1r;(EAGVr*j+iu7S}h^R2XQhPXI?(dbPf*F(H)vw-tc$? zUcL6F-yKjq{pV$!JwdH$`hCVPF;spac!n@ugTSwA_z?|%Ps5LC_|FA@oUkbke_zud z)9~MD_;C&Yz2F?@mo)run!ax5?;5V#8ItFa?YyAbIUqQXm-mTJlQi5f3ciCder*SS zT+@GsaOCGj!TGg?^?|>n>Ff5dYWSq4e?!9$Yxpk&XZt(`*vGz1kFnxd@6eA6_Hp3v z#VFyj?=a5sqe$9lhgRw#fF!X^!OmUjD~M#AIVifFy#Pt#Ud_6Ew&Jyn=Z*_-zR_?& z48SiYaOX{f@rMOtaY*Wn<4(=c6B^Eb`C`O{*Dx1zT#E_ZiH9#lT)v)&4lYe~#lX?N zYT$fp;&Lq!v0siA<)l>1e7>&XJio~Q=LKgQ`de8+aMKRIhj20V=M%Um4+8h#@uh`2 zk+*+~qP|Y_aUnLugY!{2t<45qL`X(qBG*u>YzEY+9F|e2oNCZ^F8N`L?rU8Qm-<4# z?y;iO;yu$@uSZU`83`8o8&qxi>t5(ZzAHCBJT@b?C_V9(@8IZj zeBop%j7!=UJ|w5w#)3#xQNN}w@T3s##nx}<+)CG;7AQ#-r@LdS&miu`wu?{f5{Kl>Gaeo7!zaZ#^ZRmy18l8`O z9{AWlz(bsnM-4vigWwm$nHj&pYR=%}-U$9}QG|bU{I3Zg`ybwa!PoaBHpTn6US6RF zV$0k5Xv^e$9)%k_)FN^{(-+? z@UIyDJtR&Hz%T6iR7o5Eyo~>r@Ok{azrZi@vMw0n$EOLz-`RIakBbqGdW$f9{J5us z&wH<4%=vqVI+-u&?%d}w|A-eh(1zTijZmgfCv01g26w|{|EJdy^sIA zOceaEe}+u|%Ywl_zE8maB=zeBe8^u?C)dHpiwF4d4;$b?eqiwNy#su6y@3aN?^7i$ z|G0O-KaZck`GF6d@6U`Oe(>O*y1EMZ0RKpp|He1<&Gq|d;xje{gCgPI{Ne&WBAq)CX{A}nN&>vE&|fxzb!Awm{*SfQTmzr zJJiSjhWKAI{DTj;(8vEL;(u8b*?)n4;3I$2;vaE}y1FC&uL2NB>T!Xb5x&43;md|@ z+651aCkRN(-v#;jvn+}n|6}ws<7az#mk`xh{8;>dAmjKVp?Fte1&p812U)5Ncgh8M Zarui8u+dbU<~05-iJ!j@>BVTO{{Um6#jpSX literal 0 HcmV?d00001 diff --git a/libgo/go/debug/elf/testdata/multiple-code-sections.c b/libgo/go/debug/elf/testdata/multiple-code-sections.c new file mode 100644 index 00000000000..03b9d53ab96 --- /dev/null +++ b/libgo/go/debug/elf/testdata/multiple-code-sections.c @@ -0,0 +1,28 @@ +// Copyright 2020 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 with: +// gcc -g multiple-code-sections.c -Wl,--emit-relocs -Wl,--discard-none -Wl,-zmax-page-size=1 -fno-asynchronous-unwind-tables -o go-relocation-test-gcc930-ranges-with-rela-x86-64 +// gcc -g multiple-code-sections.c -Wl,-zmax-page-size=1 -fno-asynchronous-unwind-tables -o go-relocation-test-gcc930-ranges-no-rela-x86-64 +// Strip with: +// strip --only-keep-debug \ +// --remove-section=.eh_frame \ +// --remove-section=.eh_frame_hdr \ +// --remove-section=.shstrtab \ +// --remove-section=.strtab \ +// --remove-section=.symtab \ +// --remove-section=.note.gnu.build-id \ +// --remove-section=.note.ABI-tag \ +// --remove-section=.dynamic \ +// --remove-section=.gnu.hash \ +// --remove-section=.interp \ +// --remove-section=.rodata +__attribute__((section(".separate_section"))) // To get GCC to emit a DW_AT_ranges attribute for the CU. +int func(void) { + return 0; +} + +int main(int argc, char *argv[]) { + return 0; +} diff --git a/libgo/go/debug/gosym/pclntab.go b/libgo/go/debug/gosym/pclntab.go index 7e54a943510..a72f9847d7c 100644 --- a/libgo/go/debug/gosym/pclntab.go +++ b/libgo/go/debug/gosym/pclntab.go @@ -14,6 +14,16 @@ import ( "sync" ) +// version of the pclntab +type version int + +const ( + verUnknown version = iota + ver11 + ver12 + ver116 +) + // A LineTable is a data structure mapping program counters to line numbers. // // In Go 1.1 and earlier, each function (represented by a Func) had its own LineTable, @@ -32,18 +42,30 @@ type LineTable struct { PC uint64 Line int - // Go 1.2 state - mu sync.Mutex - go12 int // is this in Go 1.2 format? -1 no, 0 unknown, 1 yes - binary binary.ByteOrder - quantum uint32 - ptrsize uint32 - functab []byte - nfunctab uint32 - filetab []byte - nfiletab uint32 - fileMap map[string]uint32 - strings map[uint32]string // interned substrings of Data, keyed by offset + // This mutex is used to keep parsing of pclntab synchronous. + mu sync.Mutex + + // Contains the version of the pclntab section. + version version + + // Go 1.2/1.16 state + binary binary.ByteOrder + quantum uint32 + ptrsize uint32 + funcnametab []byte + cutab []byte + funcdata []byte + functab []byte + nfunctab uint32 + filetab []byte + pctab []byte // points to the pctables. + nfiletab uint32 + funcNames map[uint32]string // cache the function names + strings map[uint32]string // interned substrings of Data, keyed by offset + // fileMap varies depending on the version of the object file. + // For ver12, it maps the name to the index in the file table. + // For ver116, it maps the name to the offset in filetab. + fileMap map[string]uint32 } // NOTE(rsc): This is wrong for GOARCH=arm, which uses a quantum of 4, @@ -124,7 +146,7 @@ func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 { // Text must be the start address of the // corresponding text segment. func NewLineTable(data []byte, text uint64) *LineTable { - return &LineTable{Data: data, PC: text, Line: 0, strings: make(map[uint32]string)} + return &LineTable{Data: data, PC: text, Line: 0, funcNames: make(map[uint32]string), strings: make(map[uint32]string)} } // Go 1.2 symbol table format. @@ -140,11 +162,12 @@ func NewLineTable(data []byte, text uint64) *LineTable { // isGo12 reports whether this is a Go 1.2 (or later) symbol table. func (t *LineTable) isGo12() bool { - t.go12Init() - return t.go12 == 1 + t.parsePclnTab() + return t.version >= ver12 } const go12magic = 0xfffffffb +const go116magic = 0xfffffffa // uintptr returns the pointer-sized value encoded at b. // The pointer size is dictated by the table being read. @@ -155,49 +178,86 @@ func (t *LineTable) uintptr(b []byte) uint64 { return t.binary.Uint64(b) } -// go12init initializes the Go 1.2 metadata if t is a Go 1.2 symbol table. -func (t *LineTable) go12Init() { +// parsePclnTab parses the pclntab, setting the version. +func (t *LineTable) parsePclnTab() { t.mu.Lock() defer t.mu.Unlock() - if t.go12 != 0 { + if t.version != verUnknown { return } + // Note that during this function, setting the version is the last thing we do. + // If we set the version too early, and parsing failed (likely as a panic on + // slice lookups), we'd have a mistaken version. + // + // Error paths through this code will default the version to 1.1. + t.version = ver11 + defer func() { - // If we panic parsing, assume it's not a Go 1.2 symbol table. + // If we panic parsing, assume it's a Go 1.1 pclntab. recover() }() // Check header: 4-byte magic, two zeros, pc quantum, pointer size. - t.go12 = -1 // not Go 1.2 until proven otherwise if len(t.Data) < 16 || t.Data[4] != 0 || t.Data[5] != 0 || (t.Data[6] != 1 && t.Data[6] != 2 && t.Data[6] != 4) || // pc quantum (t.Data[7] != 4 && t.Data[7] != 8) { // pointer size return } - switch uint32(go12magic) { - case binary.LittleEndian.Uint32(t.Data): - t.binary = binary.LittleEndian - case binary.BigEndian.Uint32(t.Data): - t.binary = binary.BigEndian + var possibleVersion version + leMagic := binary.LittleEndian.Uint32(t.Data) + beMagic := binary.BigEndian.Uint32(t.Data) + switch { + case leMagic == go12magic: + t.binary, possibleVersion = binary.LittleEndian, ver12 + case beMagic == go12magic: + t.binary, possibleVersion = binary.BigEndian, ver12 + case leMagic == go116magic: + t.binary, possibleVersion = binary.LittleEndian, ver116 + case beMagic == go116magic: + t.binary, possibleVersion = binary.BigEndian, ver116 default: return } + // quantum and ptrSize are the same between 1.2 and 1.16 t.quantum = uint32(t.Data[6]) t.ptrsize = uint32(t.Data[7]) - t.nfunctab = uint32(t.uintptr(t.Data[8:])) - t.functab = t.Data[8+t.ptrsize:] - functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize - fileoff := t.binary.Uint32(t.functab[functabsize:]) - t.functab = t.functab[:functabsize] - t.filetab = t.Data[fileoff:] - t.nfiletab = t.binary.Uint32(t.filetab) - t.filetab = t.filetab[:t.nfiletab*4] - - t.go12 = 1 // so far so good + switch possibleVersion { + case ver116: + t.nfunctab = uint32(t.uintptr(t.Data[8:])) + t.nfiletab = uint32(t.uintptr(t.Data[8+t.ptrsize:])) + offset := t.uintptr(t.Data[8+2*t.ptrsize:]) + t.funcnametab = t.Data[offset:] + offset = t.uintptr(t.Data[8+3*t.ptrsize:]) + t.cutab = t.Data[offset:] + offset = t.uintptr(t.Data[8+4*t.ptrsize:]) + t.filetab = t.Data[offset:] + offset = t.uintptr(t.Data[8+5*t.ptrsize:]) + t.pctab = t.Data[offset:] + offset = t.uintptr(t.Data[8+6*t.ptrsize:]) + t.funcdata = t.Data[offset:] + t.functab = t.Data[offset:] + functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize + t.functab = t.functab[:functabsize] + case ver12: + t.nfunctab = uint32(t.uintptr(t.Data[8:])) + t.funcdata = t.Data + t.funcnametab = t.Data + t.functab = t.Data[8+t.ptrsize:] + t.pctab = t.Data + functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize + fileoff := t.binary.Uint32(t.functab[functabsize:]) + t.functab = t.functab[:functabsize] + t.filetab = t.Data[fileoff:] + t.nfiletab = t.binary.Uint32(t.filetab) + t.filetab = t.filetab[:t.nfiletab*4] + default: + panic("unreachable") + } + t.version = possibleVersion } // go12Funcs returns a slice of Funcs derived from the Go 1.2 pcln table. @@ -213,13 +273,13 @@ func (t *LineTable) go12Funcs() []Func { f := &funcs[i] f.Entry = t.uintptr(t.functab[2*i*int(t.ptrsize):]) f.End = t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):]) - info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):] + info := t.funcdata[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):] f.LineTable = t f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:])) f.Sym = &Sym{ Value: f.Entry, Type: 'T', - Name: t.string(t.binary.Uint32(info[t.ptrsize:])), + Name: t.funcName(t.binary.Uint32(info[t.ptrsize:])), GoType: 0, Func: f, } @@ -241,7 +301,7 @@ func (t *LineTable) findFunc(pc uint64) []byte { m := nf / 2 fm := f[2*t.ptrsize*m:] if t.uintptr(fm) <= pc && pc < t.uintptr(fm[2*t.ptrsize:]) { - return t.Data[t.uintptr(fm[t.ptrsize:]):] + return t.funcdata[t.uintptr(fm[t.ptrsize:]):] } else if pc < t.uintptr(fm) { nf = m } else { @@ -268,17 +328,33 @@ func (t *LineTable) readvarint(pp *[]byte) uint32 { return v } -// string returns a Go string found at off. -func (t *LineTable) string(off uint32) string { +// funcName returns the name of the function found at off. +func (t *LineTable) funcName(off uint32) string { + if s, ok := t.funcNames[off]; ok { + return s + } + i := bytes.IndexByte(t.funcnametab[off:], 0) + s := string(t.funcnametab[off : off+uint32(i)]) + t.funcNames[off] = s + return s +} + +// stringFrom returns a Go string found at off from a position. +func (t *LineTable) stringFrom(arr []byte, off uint32) string { if s, ok := t.strings[off]; ok { return s } - i := bytes.IndexByte(t.Data[off:], 0) - s := string(t.Data[off : off+uint32(i)]) + i := bytes.IndexByte(arr[off:], 0) + s := string(arr[off : off+uint32(i)]) t.strings[off] = s return s } +// string returns a Go string found at off. +func (t *LineTable) string(off uint32) string { + return t.stringFrom(t.funcdata, off) +} + // step advances to the next pc, value pair in the encoded table. func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool { uvdelta := t.readvarint(p) @@ -301,7 +377,7 @@ func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool { // off is the offset to the beginning of the pc-value table, // and entry is the start PC for the corresponding function. func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 { - p := t.Data[off:] + p := t.pctab[off:] val := int32(-1) pc := entry @@ -319,21 +395,25 @@ func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 { // to file number. Since most functions come from a single file, these // are usually short and quick to scan. If a file match is found, then the // code goes to the expense of looking for a simultaneous line number match. -func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32) uint64 { +func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32, cutab []byte) uint64 { if filetab == 0 || linetab == 0 { return 0 } - fp := t.Data[filetab:] - fl := t.Data[linetab:] + fp := t.pctab[filetab:] + fl := t.pctab[linetab:] fileVal := int32(-1) filePC := entry lineVal := int32(-1) linePC := entry fileStartPC := filePC for t.step(&fp, &filePC, &fileVal, filePC == entry) { - if fileVal == filenum && fileStartPC < filePC { - // fileVal is in effect starting at fileStartPC up to + fileIndex := fileVal + if t.version == ver116 { + fileIndex = int32(t.binary.Uint32(cutab[fileVal*4:])) + } + if fileIndex == filenum && fileStartPC < filePC { + // fileIndex is in effect starting at fileStartPC up to // but not including filePC, and it's the file we want. // Run the PC table looking for a matching line number // or until we reach filePC. @@ -388,13 +468,24 @@ func (t *LineTable) go12PCToFile(pc uint64) (file string) { entry := t.uintptr(f) filetab := t.binary.Uint32(f[t.ptrsize+4*4:]) fno := t.pcvalue(filetab, entry, pc) - if fno <= 0 { + if t.version == ver12 { + if fno <= 0 { + return "" + } + return t.string(t.binary.Uint32(t.filetab[4*fno:])) + } + // Go ≥ 1.16 + if fno < 0 { // 0 is valid for ≥ 1.16 return "" } - return t.string(t.binary.Uint32(t.filetab[4*fno:])) + cuoff := t.binary.Uint32(f[t.ptrsize+7*4:]) + if fnoff := t.binary.Uint32(t.cutab[(cuoff+uint32(fno))*4:]); fnoff != ^uint32(0) { + return t.stringFrom(t.filetab, fnoff) + } + return "" } -// go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2 pcln table. +// go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2/1.16 pcln table. func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) { defer func() { if recover() != nil { @@ -403,20 +494,25 @@ func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) { }() t.initFileMap() - filenum := t.fileMap[file] - if filenum == 0 { + filenum, ok := t.fileMap[file] + if !ok { return 0 } // Scan all functions. // If this turns out to be a bottleneck, we could build a map[int32][]int32 // mapping file number to a list of functions with code from that file. + var cutab []byte for i := uint32(0); i < t.nfunctab; i++ { - f := t.Data[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):] + f := t.funcdata[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):] entry := t.uintptr(f) filetab := t.binary.Uint32(f[t.ptrsize+4*4:]) linetab := t.binary.Uint32(f[t.ptrsize+5*4:]) - pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line)) + if t.version == ver116 { + cuoff := t.binary.Uint32(f[t.ptrsize+7*4:]) * 4 + cutab = t.cutab[cuoff:] + } + pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line), cutab) if pc != 0 { return pc } @@ -434,9 +530,18 @@ func (t *LineTable) initFileMap() { } m := make(map[string]uint32) - for i := uint32(1); i < t.nfiletab; i++ { - s := t.string(t.binary.Uint32(t.filetab[4*i:])) - m[s] = i + if t.version == ver12 { + for i := uint32(1); i < t.nfiletab; i++ { + s := t.string(t.binary.Uint32(t.filetab[4*i:])) + m[s] = i + } + } else { + var pos uint32 + for i := uint32(0); i < t.nfiletab; i++ { + s := t.stringFrom(t.filetab, pos) + m[s] = pos + pos += uint32(len(s) + 1) + } } t.fileMap = m } diff --git a/libgo/go/debug/gosym/pclntab_test.go b/libgo/go/debug/gosym/pclntab_test.go index 6baa53defd1..7347139b5df 100644 --- a/libgo/go/debug/gosym/pclntab_test.go +++ b/libgo/go/debug/gosym/pclntab_test.go @@ -5,9 +5,11 @@ package gosym import ( + "bytes" + "compress/gzip" "debug/elf" "internal/testenv" - "io/ioutil" + "io" "os" "os/exec" "path/filepath" @@ -28,7 +30,7 @@ func dotest(t *testing.T) { t.Skipf("skipping on non-AMD64 system %s", runtime.GOARCH) } var err error - pclineTempDir, err = ioutil.TempDir("", "pclinetest") + pclineTempDir, err = os.MkdirTemp("", "pclinetest") if err != nil { t.Fatal(err) } @@ -264,3 +266,51 @@ func TestPCLine(t *testing.T) { off = pc + 1 - text.Addr } } + +// Test that we can parse a pclntab from 1.15. +// The file was compiled in /tmp/hello.go: +// [BEGIN] +// package main +// +// func main() { +// println("hello") +// } +// [END] +func Test115PclnParsing(t *testing.T) { + zippedDat, err := os.ReadFile("testdata/pcln115.gz") + if err != nil { + t.Fatal(err) + } + var gzReader *gzip.Reader + gzReader, err = gzip.NewReader(bytes.NewBuffer(zippedDat)) + if err != nil { + t.Fatal(err) + } + var dat []byte + dat, err = io.ReadAll(gzReader) + if err != nil { + t.Fatal(err) + } + const textStart = 0x1001000 + pcln := NewLineTable(dat, textStart) + var tab *Table + tab, err = NewTable(nil, pcln) + if err != nil { + t.Fatal(err) + } + var f *Func + var pc uint64 + pc, f, err = tab.LineToPC("/tmp/hello.go", 3) + if err != nil { + t.Fatal(err) + } + if pcln.version != ver12 { + t.Fatal("Expected pcln to parse as an older version") + } + if pc != 0x105c280 { + t.Fatalf("expect pc = 0x105c280, got 0x%x", pc) + } + if f.Name != "main.main" { + t.Fatalf("expected to parse name as main.main, got %v", f.Name) + } +} diff --git a/libgo/go/debug/pe/file_test.go b/libgo/go/debug/pe/file_test.go index d96cd30904e..58deff14502 100644 --- a/libgo/go/debug/pe/file_test.go +++ b/libgo/go/debug/pe/file_test.go @@ -8,7 +8,6 @@ import ( "bytes" "debug/dwarf" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -354,7 +353,7 @@ func testDWARF(t *testing.T, linktype int) { } testenv.MustHaveGoRun(t) - tmpdir, err := ioutil.TempDir("", "TestDWARF") + tmpdir, err := os.MkdirTemp("", "TestDWARF") if err != nil { t.Fatal(err) } @@ -473,7 +472,7 @@ func TestBSSHasZeros(t *testing.T) { t.Skip("skipping test: gcc is missing") } - tmpdir, err := ioutil.TempDir("", "TestBSSHasZeros") + tmpdir, err := os.MkdirTemp("", "TestBSSHasZeros") if err != nil { t.Fatal(err) } @@ -492,7 +491,7 @@ main(void) return 0; } ` - err = ioutil.WriteFile(srcpath, []byte(src), 0644) + err = os.WriteFile(srcpath, []byte(src), 0644) if err != nil { t.Fatal(err) } @@ -597,14 +596,14 @@ func TestBuildingWindowsGUI(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("skipping windows only test") } - tmpdir, err := ioutil.TempDir("", "TestBuildingWindowsGUI") + tmpdir, err := os.MkdirTemp("", "TestBuildingWindowsGUI") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpdir) src := filepath.Join(tmpdir, "a.go") - err = ioutil.WriteFile(src, []byte(`package main; func main() {}`), 0644) + err = os.WriteFile(src, []byte(`package main; func main() {}`), 0644) if err != nil { t.Fatal(err) } @@ -684,7 +683,7 @@ func TestInvalidOptionalHeaderMagic(t *testing.T) { 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") + data, err := os.ReadFile("testdata/gcc-amd64-mingw-obj") if err != nil { t.Fatal(err) } diff --git a/libgo/go/embed/embed.go b/libgo/go/embed/embed.go new file mode 100644 index 00000000000..29e0adf1a63 --- /dev/null +++ b/libgo/go/embed/embed.go @@ -0,0 +1,406 @@ +// Copyright 2020 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 embed provides access to files embedded in the running Go program. +// +// Go source files that import "embed" can use the //go:embed directive +// to initialize a variable of type string, []byte, or FS with the contents of +// files read from the package directory or subdirectories at compile time. +// +// For example, here are three ways to embed a file named hello.txt +// and then print its contents at run time: +// +// import "embed" +// +// //go:embed hello.txt +// var s string +// print(s) +// +// //go:embed hello.txt +// var b []byte +// print(string(b)) +// +// //go:embed hello.txt +// var f embed.FS +// data, _ := f.ReadFile("hello.txt") +// print(string(data)) +// +// Directives +// +// A //go:embed directive above a variable declaration specifies which files to embed, +// using one or more path.Match patterns. +// +// The directive must immediately precede a line containing the declaration of a single variable. +// Only blank lines and ‘//’ line comments are permitted between the directive and the declaration. +// +// The variable must be of type string, []byte, or FS exactly. Named types or type aliases +// derived from those types are not allowed. +// +// For example: +// +// package server +// +// import "embed" +// +// // content holds our static web server content. +// //go:embed image/* template/* +// //go:embed html/index.html +// var content embed.FS +// +// The Go build system will recognize the directives and arrange for the declared variable +// (in the example above, content) to be populated with the matching files from the file system. +// +// The //go:embed directive accepts multiple space-separated patterns for brevity, +// but it can also be repeated, to avoid very long lines when there are many patterns. +// The patterns are interpreted relative to the package directory containing the source file. +// The path separator is a forward slash, even on Windows systems. +// To allow for naming files with spaces in their names, patterns can be written +// as Go double-quoted or back-quoted string literals. +// +// If a pattern names a directory, all files in the subtree rooted at that directory are +// embedded (recursively), except that files with names beginning with ‘.’ or ‘_’ +// are excluded. So the variable in the above example is almost equivalent to: +// +// // content is our static web server content. +// //go:embed image template html/index.html +// var content embed.FS +// +// The difference is that ‘image/*’ embeds ‘image/.tempfile’ while ‘image’ does not. +// +// The //go:embed directive can be used with both exported and unexported variables, +// depending on whether the package wants to make the data available to other packages. +// Similarly, it can be used with both global and function-local variables, +// depending on what is more convenient in context. +// +// Patterns must not match files outside the package's module, such as ‘.git/*’ or symbolic links. +// Matches for empty directories are ignored. After that, each pattern in a //go:embed line +// must match at least one file or non-empty directory. +// +// Patterns must not contain ‘.’ or ‘..’ path elements nor begin with a leading slash. +// To match everything in the current directory, use ‘*’ instead of ‘.’. +// +// If any patterns are invalid or have invalid matches, the build will fail. +// +// Strings and Bytes +// +// The //go:embed line for a variable of type string or []byte can have only a single pattern, +// and that pattern can match only a single file. The string or []byte is initialized with +// the contents of that file. +// +// The //go:embed directive requires importing "embed", even when using a string or []byte. +// In source files that don't refer to embed.FS, use a blank import (import _ "embed"). +// +// File Systems +// +// For embedding a single file, a variable of type string or []byte is often best. +// The FS type enables embedding a tree of files, such as a directory of static +// web server content, as in the example above. +// +// FS implements the io/fs package's FS interface, so it can be used with any package that +// understands file systems, including net/http, text/template, and html/template. +// +// For example, given the content variable in the example above, we can write: +// +// http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(content)))) +// +// template.ParseFS(content, "*.tmpl") +// +// Tools +// +// To support tools that analyze Go packages, the patterns found in //go:embed lines +// are available in “go list” output. See the EmbedPatterns, TestEmbedPatterns, +// and XTestEmbedPatterns fields in the “go help list” output. +// +package embed + +import ( + "errors" + "io" + "io/fs" + "time" +) + +// An FS is a read-only collection of files, usually initialized with a //go:embed directive. +// When declared without a //go:embed directive, an FS is an empty file system. +// +// An FS is a read-only value, so it is safe to use from multiple goroutines +// simultaneously and also safe to assign values of type FS to each other. +// +// FS implements fs.FS, so it can be used with any package that understands +// file system interfaces, including net/http, text/template, and html/template. +// +// See the package documentation for more details about initializing an FS. +type FS struct { + // The compiler knows the layout of this struct. + // See cmd/compile/internal/gc's initEmbed. + // + // The files list is sorted by name but not by simple string comparison. + // Instead, each file's name takes the form "dir/elem" or "dir/elem/". + // The optional trailing slash indicates that the file is itself a directory. + // The files list is sorted first by dir (if dir is missing, it is taken to be ".") + // and then by base, so this list of files: + // + // p + // q/ + // q/r + // q/s/ + // q/s/t + // q/s/u + // q/v + // w + // + // is actually sorted as: + // + // p # dir=. elem=p + // q/ # dir=. elem=q + // w/ # dir=. elem=w + // q/r # dir=q elem=r + // q/s/ # dir=q elem=s + // q/v # dir=q elem=v + // q/s/t # dir=q/s elem=t + // q/s/u # dir=q/s elem=u + // + // This order brings directory contents together in contiguous sections + // of the list, allowing a directory read to use binary search to find + // the relevant sequence of entries. + files *[]file +} + +// split splits the name into dir and elem as described in the +// comment in the FS struct above. isDir reports whether the +// final trailing slash was present, indicating that name is a directory. +func split(name string) (dir, elem string, isDir bool) { + if name[len(name)-1] == '/' { + isDir = true + name = name[:len(name)-1] + } + i := len(name) - 1 + for i >= 0 && name[i] != '/' { + i-- + } + if i < 0 { + return ".", name, isDir + } + return name[:i], name[i+1:], isDir +} + +// trimSlash trims a trailing slash from name, if present, +// returning the possibly shortened name. +func trimSlash(name string) string { + if len(name) > 0 && name[len(name)-1] == '/' { + return name[:len(name)-1] + } + return name +} + +var ( + _ fs.ReadDirFS = FS{} + _ fs.ReadFileFS = FS{} +) + +// A file is a single file in the FS. +// It implements fs.FileInfo and fs.DirEntry. +type file struct { + // The compiler knows the layout of this struct. + // See cmd/compile/internal/gc's initEmbed. + name string + data string + hash [16]byte // truncated SHA256 hash +} + +var ( + _ fs.FileInfo = (*file)(nil) + _ fs.DirEntry = (*file)(nil) +) + +func (f *file) Name() string { _, elem, _ := split(f.name); return elem } +func (f *file) Size() int64 { return int64(len(f.data)) } +func (f *file) ModTime() time.Time { return time.Time{} } +func (f *file) IsDir() bool { _, _, isDir := split(f.name); return isDir } +func (f *file) Sys() interface{} { return nil } +func (f *file) Type() fs.FileMode { return f.Mode().Type() } +func (f *file) Info() (fs.FileInfo, error) { return f, nil } + +func (f *file) Mode() fs.FileMode { + if f.IsDir() { + return fs.ModeDir | 0555 + } + return 0444 +} + +// dotFile is a file for the root directory, +// which is omitted from the files list in a FS. +var dotFile = &file{name: "./"} + +// lookup returns the named file, or nil if it is not present. +func (f FS) lookup(name string) *file { + if !fs.ValidPath(name) { + // The compiler should never emit a file with an invalid name, + // so this check is not strictly necessary (if name is invalid, + // we shouldn't find a match below), but it's a good backstop anyway. + return nil + } + if name == "." { + return dotFile + } + + // Binary search to find where name would be in the list, + // and then check if name is at that position. + dir, elem, _ := split(name) + files := *f.files + i := sortSearch(len(files), func(i int) bool { + idir, ielem, _ := split(files[i].name) + return idir > dir || idir == dir && ielem >= elem + }) + if i < len(files) && trimSlash(files[i].name) == name { + return &files[i] + } + return nil +} + +// readDir returns the list of files corresponding to the directory dir. +func (f FS) readDir(dir string) []file { + // Binary search to find where dir starts and ends in the list + // and then return that slice of the list. + files := *f.files + i := sortSearch(len(files), func(i int) bool { + idir, _, _ := split(files[i].name) + return idir >= dir + }) + j := sortSearch(len(files), func(j int) bool { + jdir, _, _ := split(files[j].name) + return jdir > dir + }) + return files[i:j] +} + +// Open opens the named file for reading and returns it as an fs.File. +func (f FS) Open(name string) (fs.File, error) { + file := f.lookup(name) + if file == nil { + return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist} + } + if file.IsDir() { + return &openDir{file, f.readDir(name), 0}, nil + } + return &openFile{file, 0}, nil +} + +// ReadDir reads and returns the entire named directory. +func (f FS) ReadDir(name string) ([]fs.DirEntry, error) { + file, err := f.Open(name) + if err != nil { + return nil, err + } + dir, ok := file.(*openDir) + if !ok { + return nil, &fs.PathError{Op: "read", Path: name, Err: errors.New("not a directory")} + } + list := make([]fs.DirEntry, len(dir.files)) + for i := range list { + list[i] = &dir.files[i] + } + return list, nil +} + +// ReadFile reads and returns the content of the named file. +func (f FS) ReadFile(name string) ([]byte, error) { + file, err := f.Open(name) + if err != nil { + return nil, err + } + ofile, ok := file.(*openFile) + if !ok { + return nil, &fs.PathError{Op: "read", Path: name, Err: errors.New("is a directory")} + } + return []byte(ofile.f.data), nil +} + +// An openFile is a regular file open for reading. +type openFile struct { + f *file // the file itself + offset int64 // current read offset +} + +func (f *openFile) Close() error { return nil } +func (f *openFile) Stat() (fs.FileInfo, error) { return f.f, nil } + +func (f *openFile) Read(b []byte) (int, error) { + if f.offset >= int64(len(f.f.data)) { + return 0, io.EOF + } + if f.offset < 0 { + return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid} + } + n := copy(b, f.f.data[f.offset:]) + f.offset += int64(n) + return n, nil +} + +func (f *openFile) Seek(offset int64, whence int) (int64, error) { + switch whence { + case 0: + // offset += 0 + case 1: + offset += f.offset + case 2: + offset += int64(len(f.f.data)) + } + if offset < 0 || offset > int64(len(f.f.data)) { + return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid} + } + f.offset = offset + return offset, nil +} + +// An openDir is a directory open for reading. +type openDir struct { + f *file // the directory file itself + files []file // the directory contents + offset int // the read offset, an index into the files slice +} + +func (d *openDir) Close() error { return nil } +func (d *openDir) Stat() (fs.FileInfo, error) { return d.f, nil } + +func (d *openDir) Read([]byte) (int, error) { + return 0, &fs.PathError{Op: "read", Path: d.f.name, Err: errors.New("is a directory")} +} + +func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) { + n := len(d.files) - d.offset + if count > 0 && n > count { + n = count + } + if n == 0 { + if count <= 0 { + return nil, nil + } + return nil, io.EOF + } + list := make([]fs.DirEntry, n) + for i := range list { + list[i] = &d.files[d.offset+i] + } + d.offset += n + return list, nil +} + +// sortSearch is like sort.Search, avoiding an import. +func sortSearch(n int, f func(int) bool) int { + // Define f(-1) == false and f(n) == true. + // Invariant: f(i-1) == false, f(j) == true. + i, j := 0, n + for i < j { + h := int(uint(i+j) >> 1) // avoid overflow when computing h + // i ≤ h < j + if !f(h) { + i = h + 1 // preserves f(i-1) == false + } else { + j = h // preserves f(j) == true + } + } + // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i. + return i +} diff --git a/libgo/go/embed/internal/embedtest/concurrency.txt b/libgo/go/embed/internal/embedtest/concurrency.txt new file mode 100644 index 00000000000..0814741261d --- /dev/null +++ b/libgo/go/embed/internal/embedtest/concurrency.txt @@ -0,0 +1 @@ +Concurrency is not parallelism. diff --git a/libgo/go/embed/internal/embedtest/embed_test.go b/libgo/go/embed/internal/embedtest/embed_test.go new file mode 100644 index 00000000000..c6a7bea7a33 --- /dev/null +++ b/libgo/go/embed/internal/embedtest/embed_test.go @@ -0,0 +1,124 @@ +// Copyright 2020 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 embedtest + +import ( + "embed" + "reflect" + "testing" + "testing/fstest" +) + +//go:embed testdata/h*.txt +//go:embed c*.txt testdata/g*.txt +var global embed.FS + +//go:embed c*txt +var concurrency string + +//go:embed testdata/g*.txt +var glass []byte + +func testFiles(t *testing.T, f embed.FS, name, data string) { + t.Helper() + d, err := f.ReadFile(name) + if err != nil { + t.Error(err) + return + } + if string(d) != data { + t.Errorf("read %v = %q, want %q", name, d, data) + } +} + +func testString(t *testing.T, s, name, data string) { + t.Helper() + if s != data { + t.Errorf("%v = %q, want %q", name, s, data) + } +} + +func testDir(t *testing.T, f embed.FS, name string, expect ...string) { + t.Helper() + dirs, err := f.ReadDir(name) + if err != nil { + t.Error(err) + return + } + var names []string + for _, d := range dirs { + name := d.Name() + if d.IsDir() { + name += "/" + } + names = append(names, name) + } + if !reflect.DeepEqual(names, expect) { + t.Errorf("readdir %v = %v, want %v", name, names, expect) + } +} + +func TestGlobal(t *testing.T) { + testFiles(t, global, "concurrency.txt", "Concurrency is not parallelism.\n") + testFiles(t, global, "testdata/hello.txt", "hello, world\n") + testFiles(t, global, "testdata/glass.txt", "I can eat glass and it doesn't hurt me.\n") + + if err := fstest.TestFS(global, "concurrency.txt", "testdata/hello.txt"); err != nil { + t.Fatal(err) + } + + testString(t, concurrency, "concurrency", "Concurrency is not parallelism.\n") + testString(t, string(glass), "glass", "I can eat glass and it doesn't hurt me.\n") +} + +func TestLocal(t *testing.T) { + //go:embed testdata/k*.txt + var local embed.FS + testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n") + + //go:embed testdata/k*.txt + var s string + testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n") + + //go:embed testdata/h*.txt + var b []byte + testString(t, string(b), "local variable b", "hello, world\n") +} + +func TestDir(t *testing.T) { + //go:embed testdata + var all embed.FS + + testFiles(t, all, "testdata/hello.txt", "hello, world\n") + testFiles(t, all, "testdata/i/i18n.txt", "internationalization\n") + testFiles(t, all, "testdata/i/j/k/k8s.txt", "kubernetes\n") + testFiles(t, all, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n") + + testDir(t, all, ".", "testdata/") + testDir(t, all, "testdata/i", "i18n.txt", "j/") + testDir(t, all, "testdata/i/j", "k/") + testDir(t, all, "testdata/i/j/k", "k8s.txt") +} + +func TestHidden(t *testing.T) { + //go:embed testdata + var dir embed.FS + + //go:embed testdata/* + var star embed.FS + + t.Logf("//go:embed testdata") + + testDir(t, dir, "testdata", + "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt") + + t.Logf("//go:embed testdata/*") + + testDir(t, star, "testdata", + ".hidden/", "_hidden/", "ascii.txt", "glass.txt", "hello.txt", "i/", "ken.txt") + + testDir(t, star, "testdata/.hidden", + "fortune.txt", "more/") // but not .more or _more +} diff --git a/libgo/go/embed/internal/embedtest/embedx_test.go b/libgo/go/embed/internal/embedtest/embedx_test.go new file mode 100644 index 00000000000..20d5a28c11d --- /dev/null +++ b/libgo/go/embed/internal/embedtest/embedx_test.go @@ -0,0 +1,106 @@ +// Copyright 2020 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 embedtest_test + +import ( + "embed" + "os" + "testing" +) + +var ( + global2 = global + concurrency2 = concurrency + glass2 = glass + sbig2 = sbig + bbig2 = bbig +) + +//go:embed testdata/*.txt +var global embed.FS + +//go:embed c*txt +var concurrency string + +//go:embed testdata/g*.txt +var glass []byte + +//go:embed testdata/ascii.txt +var sbig string + +//go:embed testdata/ascii.txt +var bbig []byte + +func testFiles(t *testing.T, f embed.FS, name, data string) { + t.Helper() + d, err := f.ReadFile(name) + if err != nil { + t.Error(err) + return + } + if string(d) != data { + t.Errorf("read %v = %q, want %q", name, d, data) + } +} + +func testString(t *testing.T, s, name, data string) { + t.Helper() + if s != data { + t.Errorf("%v = %q, want %q", name, s, data) + } +} + +func TestXGlobal(t *testing.T) { + testFiles(t, global, "testdata/hello.txt", "hello, world\n") + testString(t, concurrency, "concurrency", "Concurrency is not parallelism.\n") + testString(t, string(glass), "glass", "I can eat glass and it doesn't hurt me.\n") + testString(t, concurrency2, "concurrency2", "Concurrency is not parallelism.\n") + testString(t, string(glass2), "glass2", "I can eat glass and it doesn't hurt me.\n") + + big, err := os.ReadFile("testdata/ascii.txt") + if err != nil { + t.Fatal(err) + } + testString(t, sbig, "sbig", string(big)) + testString(t, sbig2, "sbig2", string(big)) + testString(t, string(bbig), "bbig", string(big)) + testString(t, string(bbig2), "bbig", string(big)) + + if t.Failed() { + return + } + + // Could check &glass[0] == &glass2[0] but also want to make sure write does not fault + // (data must not be in read-only memory). + old := glass[0] + glass[0]++ + if glass2[0] != glass[0] { + t.Fatalf("glass and glass2 do not share storage") + } + glass[0] = old + + // Could check &bbig[0] == &bbig2[0] but also want to make sure write does not fault + // (data must not be in read-only memory). + old = bbig[0] + bbig[0]++ + if bbig2[0] != bbig[0] { + t.Fatalf("bbig and bbig2 do not share storage") + } + bbig[0] = old +} + +func TestXLocal(t *testing.T) { + //go:embed testdata/*o.txt + var local embed.FS + testFiles(t, local, "testdata/hello.txt", "hello, world\n") + + //go:embed testdata/k*.txt + var s string + testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n") + + //go:embed testdata/h*.txt + var b []byte + testString(t, string(b), "local variable b", "hello, world\n") +} diff --git a/libgo/go/embed/internal/embedtest/testdata/.hidden/.more/tip.txt b/libgo/go/embed/internal/embedtest/testdata/.hidden/.more/tip.txt new file mode 100644 index 00000000000..71b9c6955de --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/.hidden/.more/tip.txt @@ -0,0 +1 @@ +#define struct union /* Great space saver */ diff --git a/libgo/go/embed/internal/embedtest/testdata/.hidden/_more/tip.txt b/libgo/go/embed/internal/embedtest/testdata/.hidden/_more/tip.txt new file mode 100644 index 00000000000..71b9c6955de --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/.hidden/_more/tip.txt @@ -0,0 +1 @@ +#define struct union /* Great space saver */ diff --git a/libgo/go/embed/internal/embedtest/testdata/.hidden/fortune.txt b/libgo/go/embed/internal/embedtest/testdata/.hidden/fortune.txt new file mode 100644 index 00000000000..31f2013f94a --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/.hidden/fortune.txt @@ -0,0 +1,2 @@ +WARNING: terminal is not fully functional + - (press RETURN) diff --git a/libgo/go/embed/internal/embedtest/testdata/.hidden/more/tip.txt b/libgo/go/embed/internal/embedtest/testdata/.hidden/more/tip.txt new file mode 100644 index 00000000000..71b9c6955de --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/.hidden/more/tip.txt @@ -0,0 +1 @@ +#define struct union /* Great space saver */ diff --git a/libgo/go/embed/internal/embedtest/testdata/_hidden/fortune.txt b/libgo/go/embed/internal/embedtest/testdata/_hidden/fortune.txt new file mode 100644 index 00000000000..31f2013f94a --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/_hidden/fortune.txt @@ -0,0 +1,2 @@ +WARNING: terminal is not fully functional + - (press RETURN) diff --git a/libgo/go/embed/internal/embedtest/testdata/ascii.txt b/libgo/go/embed/internal/embedtest/testdata/ascii.txt new file mode 100644 index 00000000000..0cfebf6e9cd --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/ascii.txt @@ -0,0 +1,25 @@ + !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmn +!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmno +"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnop +#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopq +$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqr +%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrs +&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrst +'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstu +()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuv +)*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvw +*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwx ++,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy +,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz +-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{ +./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{| +/0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} +0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} +123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} ! +23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !" +3456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"# +456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$ +56789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$% +6789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%& +789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&' +89:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'( diff --git a/libgo/go/embed/internal/embedtest/testdata/glass.txt b/libgo/go/embed/internal/embedtest/testdata/glass.txt new file mode 100644 index 00000000000..8350baf4373 --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/glass.txt @@ -0,0 +1 @@ +I can eat glass and it doesn't hurt me. diff --git a/libgo/go/embed/internal/embedtest/testdata/hello.txt b/libgo/go/embed/internal/embedtest/testdata/hello.txt new file mode 100644 index 00000000000..4b5fa63702d --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/hello.txt @@ -0,0 +1 @@ +hello, world diff --git a/libgo/go/embed/internal/embedtest/testdata/i/i18n.txt b/libgo/go/embed/internal/embedtest/testdata/i/i18n.txt new file mode 100644 index 00000000000..5ee27c63b67 --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/i/i18n.txt @@ -0,0 +1 @@ +internationalization diff --git a/libgo/go/embed/internal/embedtest/testdata/i/j/k/k8s.txt b/libgo/go/embed/internal/embedtest/testdata/i/j/k/k8s.txt new file mode 100644 index 00000000000..807e21be4c0 --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/i/j/k/k8s.txt @@ -0,0 +1 @@ +kubernetes diff --git a/libgo/go/embed/internal/embedtest/testdata/ken.txt b/libgo/go/embed/internal/embedtest/testdata/ken.txt new file mode 100644 index 00000000000..bb2598132ef --- /dev/null +++ b/libgo/go/embed/internal/embedtest/testdata/ken.txt @@ -0,0 +1 @@ +If a program is too slow, it must have a loop. diff --git a/libgo/go/encoding/ascii85/ascii85_test.go b/libgo/go/encoding/ascii85/ascii85_test.go index 1a3a87a596d..c6371039426 100644 --- a/libgo/go/encoding/ascii85/ascii85_test.go +++ b/libgo/go/encoding/ascii85/ascii85_test.go @@ -7,7 +7,6 @@ package ascii85 import ( "bytes" "io" - "io/ioutil" "strings" "testing" ) @@ -118,7 +117,7 @@ func TestDecode(t *testing.T) { func TestDecoder(t *testing.T) { for _, p := range pairs { decoder := NewDecoder(strings.NewReader(p.encoded)) - dbuf, err := ioutil.ReadAll(decoder) + dbuf, err := io.ReadAll(decoder) if err != nil { t.Fatal("Read failed", err) } @@ -187,7 +186,7 @@ func TestBig(t *testing.T) { if err != nil { t.Fatalf("Encoder.Close() = %v want nil", err) } - decoded, err := ioutil.ReadAll(NewDecoder(encoded)) + decoded, err := io.ReadAll(NewDecoder(encoded)) if err != nil { t.Fatalf("io.ReadAll(NewDecoder(...)): %v", err) } @@ -205,7 +204,7 @@ func TestBig(t *testing.T) { func TestDecoderInternalWhitespace(t *testing.T) { s := strings.Repeat(" ", 2048) + "z" - decoded, err := ioutil.ReadAll(NewDecoder(strings.NewReader(s))) + decoded, err := io.ReadAll(NewDecoder(strings.NewReader(s))) if err != nil { t.Errorf("Decode gave error %v", err) } diff --git a/libgo/go/encoding/asn1/asn1.go b/libgo/go/encoding/asn1/asn1.go index d809dde2781..7c260b49d90 100644 --- a/libgo/go/encoding/asn1/asn1.go +++ b/libgo/go/encoding/asn1/asn1.go @@ -851,53 +851,37 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam offset += t.length // We deal with the structures defined in this package first. - switch fieldType { - case rawValueType: - result := RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]} - v.Set(reflect.ValueOf(result)) + switch v := v.Addr().Interface().(type) { + case *RawValue: + *v = RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]} return - case objectIdentifierType: - newSlice, err1 := parseObjectIdentifier(innerBytes) - v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice))) - if err1 == nil { - reflect.Copy(v, reflect.ValueOf(newSlice)) - } - err = err1 + case *ObjectIdentifier: + *v, err = parseObjectIdentifier(innerBytes) return - case bitStringType: - bs, err1 := parseBitString(innerBytes) - if err1 == nil { - v.Set(reflect.ValueOf(bs)) - } - err = err1 + case *BitString: + *v, err = parseBitString(innerBytes) return - case timeType: - var time time.Time - var err1 error + case *time.Time: if universalTag == TagUTCTime { - time, err1 = parseUTCTime(innerBytes) - } else { - time, err1 = parseGeneralizedTime(innerBytes) - } - if err1 == nil { - v.Set(reflect.ValueOf(time)) + *v, err = parseUTCTime(innerBytes) + return } - err = err1 + *v, err = parseGeneralizedTime(innerBytes) return - case enumeratedType: + case *Enumerated: parsedInt, err1 := parseInt32(innerBytes) if err1 == nil { - v.SetInt(int64(parsedInt)) + *v = Enumerated(parsedInt) } err = err1 return - case flagType: - v.SetBool(true) + case *Flag: + *v = true return - case bigIntType: + case **big.Int: parsedInt, err1 := parseBigInt(innerBytes) if err1 == nil { - v.Set(reflect.ValueOf(parsedInt)) + *v = parsedInt } err = err1 return @@ -1035,7 +1019,8 @@ func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) { // Unmarshal parses the DER-encoded ASN.1 data structure b // and uses the reflect package to fill in an arbitrary value pointed at by val. // Because Unmarshal uses the reflect package, the structs -// being written to must use upper case field names. +// being written to must use upper case field names. If val +// is nil or not a pointer, Unmarshal returns an error. // // After parsing b, any bytes that were leftover and not used to fill // val will be returned in rest. When parsing a SEQUENCE into a struct, @@ -1085,9 +1070,10 @@ func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) { // If the type of the first field of a structure is RawContent then the raw // ASN1 contents of the struct will be stored in it. // -// If the type name of a slice element ends with "SET" then it's treated as if -// the "set" tag was set on it. This can be used with nested slices where a -// struct tag cannot be given. +// If the name of a slice type ends with "SET" then it's treated as if +// the "set" tag was set on it. This results in interpreting the type as a +// SET OF x rather than a SEQUENCE OF x. This can be used with nested slices +// where a struct tag cannot be given. // // Other ASN.1 types are not supported; if it encounters them, // Unmarshal returns a parse error. @@ -1095,11 +1081,31 @@ func Unmarshal(b []byte, val interface{}) (rest []byte, err error) { return UnmarshalWithParams(b, val, "") } +// An invalidUnmarshalError describes an invalid argument passed to Unmarshal. +// (The argument to Unmarshal must be a non-nil pointer.) +type invalidUnmarshalError struct { + Type reflect.Type +} + +func (e *invalidUnmarshalError) Error() string { + if e.Type == nil { + return "asn1: Unmarshal recipient value is nil" + } + + if e.Type.Kind() != reflect.Ptr { + return "asn1: Unmarshal recipient value is non-pointer " + e.Type.String() + } + return "asn1: Unmarshal recipient value is nil " + e.Type.String() +} + // UnmarshalWithParams allows field parameters to be specified for the // top-level element. The form of the params is the same as the field tags. func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err error) { - v := reflect.ValueOf(val).Elem() - offset, err := parseField(v, b, 0, parseFieldParameters(params)) + v := reflect.ValueOf(val) + if v.Kind() != reflect.Ptr || v.IsNil() { + return nil, &invalidUnmarshalError{reflect.TypeOf(val)} + } + offset, err := parseField(v.Elem(), b, 0, parseFieldParameters(params)) if err != nil { return nil, err } diff --git a/libgo/go/encoding/asn1/asn1_test.go b/libgo/go/encoding/asn1/asn1_test.go index 8daae97faad..8985538468e 100644 --- a/libgo/go/encoding/asn1/asn1_test.go +++ b/libgo/go/encoding/asn1/asn1_test.go @@ -518,6 +518,29 @@ func TestUnmarshal(t *testing.T) { } } +func TestUnmarshalWithNilOrNonPointer(t *testing.T) { + tests := []struct { + b []byte + v interface{} + want string + }{ + {b: []byte{0x05, 0x00}, v: nil, want: "asn1: Unmarshal recipient value is nil"}, + {b: []byte{0x05, 0x00}, v: RawValue{}, want: "asn1: Unmarshal recipient value is non-pointer asn1.RawValue"}, + {b: []byte{0x05, 0x00}, v: (*RawValue)(nil), want: "asn1: Unmarshal recipient value is nil *asn1.RawValue"}, + } + + for _, test := range tests { + _, err := Unmarshal(test.b, test.v) + if err == nil { + t.Errorf("Unmarshal expecting error, got nil") + continue + } + if g, w := err.Error(), test.want; g != w { + t.Errorf("InvalidUnmarshalError mismatch\nGot: %q\nWant: %q", g, w) + } + } +} + type Certificate struct { TBSCertificate TBSCertificate SignatureAlgorithm AlgorithmIdentifier diff --git a/libgo/go/encoding/asn1/common.go b/libgo/go/encoding/asn1/common.go index e2aa8bd9c57..1c712e1eff4 100644 --- a/libgo/go/encoding/asn1/common.go +++ b/libgo/go/encoding/asn1/common.go @@ -92,7 +92,16 @@ type fieldParameters struct { // parseFieldParameters will parse it into a fieldParameters structure, // ignoring unknown parts of the string. func parseFieldParameters(str string) (ret fieldParameters) { - for _, part := range strings.Split(str, ",") { + var part string + for len(str) > 0 { + // This loop uses IndexByte and explicit slicing + // instead of strings.Split(str, ",") to reduce allocations. + i := strings.IndexByte(str, ',') + if i < 0 { + part, str = str, "" + } else { + part, str = str[:i], str[i+1:] + } switch { case part == "optional": ret.optional = true diff --git a/libgo/go/encoding/asn1/marshal_test.go b/libgo/go/encoding/asn1/marshal_test.go index 529052285f5..e3a7d8ff007 100644 --- a/libgo/go/encoding/asn1/marshal_test.go +++ b/libgo/go/encoding/asn1/marshal_test.go @@ -376,3 +376,31 @@ func TestSetEncoderSETSliceSuffix(t *testing.T) { t.Errorf("Unexpected SET content. got: %s, want: %s", resultSet, expectedOrder) } } + +func BenchmarkUnmarshal(b *testing.B) { + b.ReportAllocs() + + type testCase struct { + in []byte + out interface{} + } + var testData []testCase + for _, test := range unmarshalTestData { + pv := reflect.New(reflect.TypeOf(test.out).Elem()) + inCopy := make([]byte, len(test.in)) + copy(inCopy, test.in) + outCopy := pv.Interface() + + testData = append(testData, testCase{ + in: inCopy, + out: outCopy, + }) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, testCase := range testData { + _, _ = Unmarshal(testCase.in, testCase.out) + } + } +} diff --git a/libgo/go/encoding/base32/base32_test.go b/libgo/go/encoding/base32/base32_test.go index 0b611db0b24..8fb22b90781 100644 --- a/libgo/go/encoding/base32/base32_test.go +++ b/libgo/go/encoding/base32/base32_test.go @@ -8,7 +8,6 @@ import ( "bytes" "errors" "io" - "io/ioutil" "strings" "testing" ) @@ -361,9 +360,9 @@ func TestBig(t *testing.T) { if err != nil { t.Fatalf("Encoder.Close() = %v want nil", err) } - decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded)) + decoded, err := io.ReadAll(NewDecoder(StdEncoding, encoded)) if err != nil { - t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err) + t.Fatalf("io.ReadAll(NewDecoder(...)): %v", err) } if !bytes.Equal(raw, decoded) { @@ -428,14 +427,14 @@ LNEBUWIIDFON2CA3DBMJXXE5LNFY== encodedShort := strings.ReplaceAll(encoded, "\n", "") dec := NewDecoder(StdEncoding, strings.NewReader(encoded)) - res1, err := ioutil.ReadAll(dec) + res1, err := io.ReadAll(dec) if err != nil { t.Errorf("ReadAll failed: %v", err) } dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort)) var res2 []byte - res2, err = ioutil.ReadAll(dec) + res2, err = io.ReadAll(dec) if err != nil { t.Errorf("ReadAll failed: %v", err) } @@ -619,7 +618,7 @@ func TestBufferedDecodingSameError(t *testing.T) { }() decoder := NewDecoder(StdEncoding, pr) - _, err := ioutil.ReadAll(decoder) + _, err := io.ReadAll(decoder) if err != testcase.expected { t.Errorf("Expected %v, got %v; case %s %+v", testcase.expected, err, testcase.prefix, chunks) @@ -718,7 +717,7 @@ func TestDecodeReadAll(t *testing.T) { encoded = strings.ReplaceAll(encoded, "=", "") } - decReader, err := ioutil.ReadAll(NewDecoder(encoding, strings.NewReader(encoded))) + decReader, err := io.ReadAll(NewDecoder(encoding, strings.NewReader(encoded))) if err != nil { t.Errorf("NewDecoder error: %v", err) } diff --git a/libgo/go/encoding/base64/base64_test.go b/libgo/go/encoding/base64/base64_test.go index c2c9478a437..51047402bd4 100644 --- a/libgo/go/encoding/base64/base64_test.go +++ b/libgo/go/encoding/base64/base64_test.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "reflect" "runtime/debug" "strings" @@ -324,9 +323,9 @@ func TestBig(t *testing.T) { if err != nil { t.Fatalf("Encoder.Close() = %v want nil", err) } - decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded)) + decoded, err := io.ReadAll(NewDecoder(StdEncoding, encoded)) if err != nil { - t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err) + t.Fatalf("io.ReadAll(NewDecoder(...)): %v", err) } if !bytes.Equal(raw, decoded) { @@ -403,7 +402,7 @@ func TestDecoderIssue3577(t *testing.T) { }) errc := make(chan error, 1) go func() { - _, err := ioutil.ReadAll(d) + _, err := io.ReadAll(d) errc <- err }() select { @@ -436,14 +435,14 @@ bqbPb06551Y4 encodedShort := strings.ReplaceAll(encoded, "\n", "") dec := NewDecoder(StdEncoding, strings.NewReader(encoded)) - res1, err := ioutil.ReadAll(dec) + res1, err := io.ReadAll(dec) if err != nil { t.Errorf("ReadAll failed: %v", err) } dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort)) var res2 []byte - res2, err = ioutil.ReadAll(dec) + res2, err = io.ReadAll(dec) if err != nil { t.Errorf("ReadAll failed: %v", err) } @@ -517,14 +516,14 @@ func TestDecoderRaw(t *testing.T) { // Through reader. Used to fail. r := NewDecoder(RawURLEncoding, bytes.NewReader([]byte(source))) - dec2, err := ioutil.ReadAll(io.LimitReader(r, 100)) + dec2, err := io.ReadAll(io.LimitReader(r, 100)) if err != nil || !bytes.Equal(dec2, want) { t.Errorf("reading NewDecoder(RawURLEncoding, %q) = %x, %v, want %x, nil", source, dec2, err, want) } // Should work with padding. r = NewDecoder(URLEncoding, bytes.NewReader([]byte(source+"=="))) - dec3, err := ioutil.ReadAll(r) + dec3, err := io.ReadAll(r) if err != nil || !bytes.Equal(dec3, want) { t.Errorf("reading NewDecoder(URLEncoding, %q) = %x, %v, want %x, nil", source+"==", dec3, err, want) } diff --git a/libgo/go/encoding/binary/binary.go b/libgo/go/encoding/binary/binary.go index a99ca019949..a31149979da 100644 --- a/libgo/go/encoding/binary/binary.go +++ b/libgo/go/encoding/binary/binary.go @@ -306,7 +306,7 @@ func Write(w io.Writer, order ByteOrder, data interface{}) error { case uint8: bs[0] = v case []uint8: - bs = v // TODO(josharian): avoid allocating bs in this case? + bs = v case *int16: order.PutUint16(bs, uint16(*v)) case int16: diff --git a/libgo/go/encoding/binary/binary_test.go b/libgo/go/encoding/binary/binary_test.go index aeb4212ec2e..83af89e8a7c 100644 --- a/libgo/go/encoding/binary/binary_test.go +++ b/libgo/go/encoding/binary/binary_test.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "math" "reflect" "strings" @@ -524,7 +523,7 @@ func BenchmarkWriteStruct(b *testing.B) { b.SetBytes(int64(Size(&s))) b.ResetTimer() for i := 0; i < b.N; i++ { - Write(ioutil.Discard, BigEndian, &s) + Write(io.Discard, BigEndian, &s) } } @@ -706,3 +705,27 @@ func BenchmarkWriteSlice1000Float32s(b *testing.B) { } b.StopTimer() } + +func BenchmarkReadSlice1000Uint8s(b *testing.B) { + bsr := &byteSliceReader{} + slice := make([]uint8, 1000) + buf := make([]byte, len(slice)) + b.SetBytes(int64(len(buf))) + b.ResetTimer() + for i := 0; i < b.N; i++ { + bsr.remain = buf + Read(bsr, BigEndian, slice) + } +} + +func BenchmarkWriteSlice1000Uint8s(b *testing.B) { + slice := make([]uint8, 1000) + buf := new(bytes.Buffer) + var w io.Writer = buf + b.SetBytes(1000) + b.ResetTimer() + for i := 0; i < b.N; i++ { + buf.Reset() + Write(w, BigEndian, slice) + } +} diff --git a/libgo/go/encoding/binary/varint.go b/libgo/go/encoding/binary/varint.go index 38af61075c8..1fa325dec7f 100644 --- a/libgo/go/encoding/binary/varint.go +++ b/libgo/go/encoding/binary/varint.go @@ -62,7 +62,7 @@ func Uvarint(buf []byte) (uint64, int) { var s uint for i, b := range buf { if b < 0x80 { - if i > 9 || i == 9 && b > 1 { + if i >= MaxVarintLen64 || i == MaxVarintLen64-1 && b > 1 { return 0, -(i + 1) // overflow } return x | uint64(b)< 1 { + if i == MaxVarintLen64-1 && b > 1 { return x, overflow } return x | uint64(b)< startDetectingCyclesAfter { + // We're a large number of nested ptrEncoder.encode calls deep; + // start checking if we've run into a pointer cycle. + ptr := v.Pointer() + 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) + } e.WriteByte('{') // Extract and sort the keys. @@ -801,6 +813,7 @@ func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { me.elemEnc(e, v.MapIndex(kv.v), opts) } e.WriteByte('}') + e.ptrLevel-- } func newMapEncoder(t reflect.Type) encoderFunc { @@ -857,7 +870,23 @@ func (se sliceEncoder) 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. + // Here we use a struct to memorize the pointer to the first element of the slice + // and its length. + ptr := struct { + ptr uintptr + len int + }{v.Pointer(), v.Len()} + 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) + } se.arrayEnc(e, v, opts) + e.ptrLevel-- } func newSliceEncoder(t reflect.Type) encoderFunc { @@ -946,7 +975,7 @@ func isValidTag(s string) bool { } for _, c := range s { switch { - case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): + case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c): // Backslash and quote chars are reserved, but // otherwise any punctuation chars are allowed // in a tag name. diff --git a/libgo/go/encoding/json/encode_test.go b/libgo/go/encoding/json/encode_test.go index 7290eca06f0..42bb09d5cde 100644 --- a/libgo/go/encoding/json/encode_test.go +++ b/libgo/go/encoding/json/encode_test.go @@ -183,7 +183,15 @@ type PointerCycleIndirect struct { Ptrs []interface{} } -var pointerCycleIndirect = &PointerCycleIndirect{} +type RecursiveSlice []RecursiveSlice + +var ( + pointerCycleIndirect = &PointerCycleIndirect{} + mapCycle = make(map[string]interface{}) + sliceCycle = []interface{}{nil} + sliceNoCycle = []interface{}{nil, nil} + recursiveSliceCycle = []RecursiveSlice{nil} +) func init() { ptr := &SamePointerNoCycle{} @@ -192,6 +200,14 @@ func init() { pointerCycle.Ptr = pointerCycle pointerCycleIndirect.Ptrs = []interface{}{pointerCycleIndirect} + + mapCycle["x"] = mapCycle + sliceCycle[0] = sliceCycle + sliceNoCycle[1] = sliceNoCycle[:1] + for i := startDetectingCyclesAfter; i > 0; i-- { + sliceNoCycle = []interface{}{sliceNoCycle} + } + recursiveSliceCycle[0] = recursiveSliceCycle } func TestSamePointerNoCycle(t *testing.T) { @@ -200,12 +216,21 @@ func TestSamePointerNoCycle(t *testing.T) { } } +func TestSliceNoCycle(t *testing.T) { + if _, err := Marshal(sliceNoCycle); err != nil { + t.Fatalf("unexpected error: %v", err) + } +} + var unsupportedValues = []interface{}{ math.NaN(), math.Inf(-1), math.Inf(1), pointerCycle, pointerCycleIndirect, + mapCycle, + sliceCycle, + recursiveSliceCycle, } func TestUnsupportedValues(t *testing.T) { diff --git a/libgo/go/encoding/json/stream_test.go b/libgo/go/encoding/json/stream_test.go index c9e5334337d..c284f2d9650 100644 --- a/libgo/go/encoding/json/stream_test.go +++ b/libgo/go/encoding/json/stream_test.go @@ -7,7 +7,6 @@ package json import ( "bytes" "io" - "io/ioutil" "log" "net" "net/http" @@ -215,7 +214,7 @@ func TestDecoderBuffered(t *testing.T) { if m.Name != "Gopher" { t.Errorf("Name = %q; want Gopher", m.Name) } - rest, err := ioutil.ReadAll(d.Buffered()) + rest, err := io.ReadAll(d.Buffered()) if err != nil { t.Fatal(err) } @@ -318,7 +317,7 @@ func BenchmarkEncoderEncode(b *testing.B) { v := &T{"foo", "bar"} b.RunParallel(func(pb *testing.PB) { for pb.Next() { - if err := NewEncoder(ioutil.Discard).Encode(v); err != nil { + if err := NewEncoder(io.Discard).Encode(v); err != nil { b.Fatal(err) } } diff --git a/libgo/go/encoding/json/tagkey_test.go b/libgo/go/encoding/json/tagkey_test.go index f77c49c7647..bbb4e6a28d2 100644 --- a/libgo/go/encoding/json/tagkey_test.go +++ b/libgo/go/encoding/json/tagkey_test.go @@ -41,7 +41,7 @@ type percentSlashTag struct { } type punctuationTag struct { - V string `json:"!#$%&()*+-./:<=>?@[]^_{|}~"` // https://golang.org/issue/3546 + V string `json:"!#$%&()*+-./:;<=>?@[]^_{|}~ "` // https://golang.org/issue/3546 } type dashTag struct { @@ -90,7 +90,7 @@ var structTagObjectKeyTests = []struct { {badFormatTag{"Orfevre"}, "Orfevre", "Y"}, {badCodeTag{"Reliable Man"}, "Reliable Man", "Z"}, {percentSlashTag{"brut"}, "brut", "text/html%"}, - {punctuationTag{"Union Rags"}, "Union Rags", "!#$%&()*+-./:<=>?@[]^_{|}~"}, + {punctuationTag{"Union Rags"}, "Union Rags", "!#$%&()*+-./:;<=>?@[]^_{|}~ "}, {spaceTag{"Perreddu"}, "Perreddu", "With space"}, {unicodeTag{"Loukanikos"}, "Loukanikos", "Ελλάδα"}, } diff --git a/libgo/go/encoding/pem/pem_test.go b/libgo/go/encoding/pem/pem_test.go index 8515b46498d..b2b6b15e736 100644 --- a/libgo/go/encoding/pem/pem_test.go +++ b/libgo/go/encoding/pem/pem_test.go @@ -6,7 +6,7 @@ package pem import ( "bytes" - "io/ioutil" + "io" "reflect" "strings" "testing" @@ -271,7 +271,7 @@ func BenchmarkEncode(b *testing.B) { data := &Block{Bytes: make([]byte, 65536)} b.SetBytes(int64(len(data.Bytes))) for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, data) + Encode(io.Discard, data) } } diff --git a/libgo/go/encoding/xml/marshal.go b/libgo/go/encoding/xml/marshal.go index 0554b0d204e..d8a04a95a25 100644 --- a/libgo/go/encoding/xml/marshal.go +++ b/libgo/go/encoding/xml/marshal.go @@ -345,8 +345,11 @@ func (p *printer) createAttrPrefix(url string) string { if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") { prefix = "_" } - if strings.HasPrefix(prefix, "xml") { - // xmlanything is reserved. + // xmlanything is reserved and any variant of it regardless of + // case should be matched, so: + // (('X'|'x') ('M'|'m') ('L'|'l')) + // See Section 2.3 of https://www.w3.org/TR/REC-xml/ + if len(prefix) >= 3 && strings.EqualFold(prefix[:3], "xml") { prefix = "_" + prefix } if p.attrNS[prefix] != "" { diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go index 31309ef2ca8..d2e5137afd7 100644 --- a/libgo/go/encoding/xml/marshal_test.go +++ b/libgo/go/encoding/xml/marshal_test.go @@ -2283,6 +2283,30 @@ var encodeTokenTests = []struct { }}, }, want: ``, +}, { + desc: "reserved namespace prefix -- all lower case", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"http://www.w3.org/2001/xmlSchema-instance", "nil"}, "true"}, + }}, + }, + want: ``, +}, { + desc: "reserved namespace prefix -- all upper case", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"http://www.w3.org/2001/XMLSchema-instance", "nil"}, "true"}, + }}, + }, + want: ``, +}, { + desc: "reserved namespace prefix -- all mixed case", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"http://www.w3.org/2001/XmLSchema-instance", "nil"}, "true"}, + }}, + }, + want: ``, }} func TestEncodeToken(t *testing.T) { diff --git a/libgo/go/errors/errors.go b/libgo/go/errors/errors.go index d923ad4b703..f2fabacd4e9 100644 --- a/libgo/go/errors/errors.go +++ b/libgo/go/errors/errors.go @@ -27,30 +27,30 @@ // second. It reports whether it finds a match. It should be used in preference to // simple equality checks: // -// if errors.Is(err, os.ErrExist) +// if errors.Is(err, fs.ErrExist) // // is preferable to // -// if err == os.ErrExist +// if err == fs.ErrExist // -// because the former will succeed if err wraps os.ErrExist. +// because the former will succeed if err wraps fs.ErrExist. // // As unwraps its first argument sequentially looking for an error that can be // assigned to its second argument, which must be a pointer. If it succeeds, it // performs the assignment and returns true. Otherwise, it returns false. The form // -// var perr *os.PathError +// var perr *fs.PathError // if errors.As(err, &perr) { // fmt.Println(perr.Path) // } // // is preferable to // -// if perr, ok := err.(*os.PathError); ok { +// if perr, ok := err.(*fs.PathError); ok { // fmt.Println(perr.Path) // } // -// because the former will succeed if err wraps an *os.PathError. +// because the former will succeed if err wraps an *fs.PathError. package errors // New returns an error that formats as the given text. diff --git a/libgo/go/errors/wrap.go b/libgo/go/errors/wrap.go index b82ca34b46f..7928fe673ee 100644 --- a/libgo/go/errors/wrap.go +++ b/libgo/go/errors/wrap.go @@ -32,9 +32,9 @@ func Unwrap(err error) error { // An error type might provide an Is method so it can be treated as equivalent // to an existing error. For example, if MyError defines // -// func (m MyError) Is(target error) bool { return target == os.ErrExist } +// func (m MyError) Is(target error) bool { return target == fs.ErrExist } // -// then Is(MyError{}, os.ErrExist) returns true. See syscall.Errno.Is for +// then Is(MyError{}, fs.ErrExist) returns true. See syscall.Errno.Is for // an example in the standard library. func Is(err, target error) bool { if target == nil { diff --git a/libgo/go/errors/wrap_test.go b/libgo/go/errors/wrap_test.go index 4a4a732c9be..6f66e99c4a2 100644 --- a/libgo/go/errors/wrap_test.go +++ b/libgo/go/errors/wrap_test.go @@ -7,6 +7,7 @@ package errors_test import ( "errors" "fmt" + "io/fs" "os" "reflect" "testing" @@ -61,7 +62,7 @@ type poser struct { f func(error) bool } -var poserPathErr = &os.PathError{Op: "poser"} +var poserPathErr = &fs.PathError{Op: "poser"} func (p *poser) Error() string { return p.msg } func (p *poser) Is(err error) bool { return p.f(err) } @@ -71,7 +72,7 @@ func (p *poser) As(err interface{}) bool { *x = p case *errorT: *x = errorT{"poser"} - case **os.PathError: + case **fs.PathError: *x = poserPathErr default: return false @@ -81,7 +82,7 @@ func (p *poser) As(err interface{}) bool { func TestAs(t *testing.T) { var errT errorT - var errP *os.PathError + var errP *fs.PathError var timeout interface{ Timeout() bool } var p *poser _, errF := os.Open("non-existing") @@ -240,7 +241,7 @@ func (errorUncomparable) Is(target error) bool { func ExampleIs() { if _, err := os.Open("non-existing"); err != nil { - if errors.Is(err, os.ErrNotExist) { + if errors.Is(err, fs.ErrNotExist) { fmt.Println("file does not exist") } else { fmt.Println(err) @@ -253,7 +254,7 @@ func ExampleIs() { func ExampleAs() { if _, err := os.Open("non-existing"); err != nil { - var pathError *os.PathError + var pathError *fs.PathError if errors.As(err, &pathError) { fmt.Println("Failed at path:", pathError.Path) } else { diff --git a/libgo/go/flag/example_func_test.go b/libgo/go/flag/example_func_test.go new file mode 100644 index 00000000000..7c30c5e7132 --- /dev/null +++ b/libgo/go/flag/example_func_test.go @@ -0,0 +1,41 @@ +// Copyright 2020 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 flag_test + +import ( + "errors" + "flag" + "fmt" + "net" + "os" +) + +func ExampleFunc() { + fs := flag.NewFlagSet("ExampleFunc", flag.ContinueOnError) + fs.SetOutput(os.Stdout) + var ip net.IP + fs.Func("ip", "`IP address` to parse", func(s string) error { + ip = net.ParseIP(s) + if ip == nil { + return errors.New("could not parse IP") + } + return nil + }) + fs.Parse([]string{"-ip", "127.0.0.1"}) + fmt.Printf("{ip: %v, loopback: %t}\n\n", ip, ip.IsLoopback()) + + // 256 is not a valid IPv4 component + fs.Parse([]string{"-ip", "256.0.0.1"}) + fmt.Printf("{ip: %v, loopback: %t}\n\n", ip, ip.IsLoopback()) + + // Output: + // {ip: 127.0.0.1, loopback: true} + // + // invalid value "256.0.0.1" for flag -ip: could not parse IP + // Usage of ExampleFunc: + // -ip IP address + // IP address to parse + // {ip: , loopback: false} +} diff --git a/libgo/go/flag/flag.go b/libgo/go/flag/flag.go index 286bba68739..a8485f034f3 100644 --- a/libgo/go/flag/flag.go +++ b/libgo/go/flag/flag.go @@ -278,6 +278,12 @@ func (d *durationValue) Get() interface{} { return time.Duration(*d) } func (d *durationValue) String() string { return (*time.Duration)(d).String() } +type funcValue func(string) error + +func (f funcValue) Set(s string) error { return f(s) } + +func (f funcValue) String() string { return "" } + // Value is the interface to the dynamic value stored in a flag. // (The default value is represented as a string.) // @@ -296,7 +302,7 @@ type Value interface { // Getter is an interface that allows the contents of a Value to be retrieved. // It wraps the Value interface, rather than being part of it, because it // appeared after Go 1 and its compatibility rules. All Value types provided -// by this package satisfy the Getter interface. +// by this package satisfy the Getter interface, except the type used by Func. type Getter interface { Value Get() interface{} @@ -830,6 +836,20 @@ func Duration(name string, value time.Duration, usage string) *time.Duration { return CommandLine.Duration(name, value, usage) } +// Func defines a flag with the specified name and usage string. +// Each time the flag is seen, fn is called with the value of the flag. +// If fn returns a non-nil error, it will be treated as a flag value parsing error. +func (f *FlagSet) Func(name, usage string, fn func(string) error) { + f.Var(funcValue(fn), name, usage) +} + +// Func defines a flag with the specified name and usage string. +// Each time the flag is seen, fn is called with the value of the flag. +// If fn returns a non-nil error, it will be treated as a flag value parsing error. +func Func(name, usage string, fn func(string) error) { + CommandLine.Func(name, usage, fn) +} + // Var defines a flag with the specified name and usage string. The type and // value of the flag are represented by the first argument, of type Value, which // typically holds a user-defined implementation of Value. For instance, the diff --git a/libgo/go/flag/flag_test.go b/libgo/go/flag/flag_test.go index a01a5e4cea2..06cab79405a 100644 --- a/libgo/go/flag/flag_test.go +++ b/libgo/go/flag/flag_test.go @@ -10,7 +10,6 @@ import ( "fmt" "internal/testenv" "io" - "io/ioutil" "os" "os/exec" "runtime" @@ -38,6 +37,7 @@ func TestEverything(t *testing.T) { String("test_string", "0", "string value") Float64("test_float64", 0, "float64 value") Duration("test_duration", 0, "time.Duration value") + Func("test_func", "func value", func(string) error { return nil }) m := make(map[string]*Flag) desired := "0" @@ -52,6 +52,8 @@ func TestEverything(t *testing.T) { ok = true case f.Name == "test_duration" && f.Value.String() == desired+"s": ok = true + case f.Name == "test_func" && f.Value.String() == "": + ok = true } if !ok { t.Error("Visit: bad value", f.Value.String(), "for", f.Name) @@ -59,7 +61,7 @@ func TestEverything(t *testing.T) { } } VisitAll(visitor) - if len(m) != 8 { + if len(m) != 9 { t.Error("VisitAll misses some flags") for k, v := range m { t.Log(k, *v) @@ -82,9 +84,10 @@ func TestEverything(t *testing.T) { Set("test_string", "1") Set("test_float64", "1") Set("test_duration", "1s") + Set("test_func", "1") desired = "1" Visit(visitor) - if len(m) != 8 { + if len(m) != 9 { t.Error("Visit fails after set") for k, v := range m { t.Log(k, *v) @@ -257,6 +260,48 @@ func TestUserDefined(t *testing.T) { } } +func TestUserDefinedFunc(t *testing.T) { + var flags FlagSet + flags.Init("test", ContinueOnError) + var ss []string + flags.Func("v", "usage", func(s string) error { + ss = append(ss, s) + return nil + }) + if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil { + t.Error(err) + } + if len(ss) != 3 { + t.Fatal("expected 3 args; got ", len(ss)) + } + expect := "[1 2 3]" + if got := fmt.Sprint(ss); got != expect { + t.Errorf("expected value %q got %q", expect, got) + } + // test usage + var buf strings.Builder + flags.SetOutput(&buf) + flags.Parse([]string{"-h"}) + if usage := buf.String(); !strings.Contains(usage, "usage") { + t.Errorf("usage string not included: %q", usage) + } + // test Func error + flags = *NewFlagSet("test", ContinueOnError) + flags.Func("v", "usage", func(s string) error { + return fmt.Errorf("test error") + }) + // flag not set, so no error + if err := flags.Parse(nil); err != nil { + t.Error(err) + } + // flag set, expect error + if err := flags.Parse([]string{"-v", "1"}); err == nil { + t.Error("expected error; got none") + } else if errMsg := err.Error(); !strings.Contains(errMsg, "test error") { + t.Errorf(`error should contain "test error"; got %q`, errMsg) + } +} + func TestUserDefinedForCommandLine(t *testing.T) { const help = "HELP" var result string @@ -499,7 +544,7 @@ func TestGetters(t *testing.T) { func TestParseError(t *testing.T) { for _, typ := range []string{"bool", "int", "int64", "uint", "uint64", "float64", "duration"} { fs := NewFlagSet("parse error test", ContinueOnError) - fs.SetOutput(ioutil.Discard) + fs.SetOutput(io.Discard) _ = fs.Bool("bool", false, "") _ = fs.Int("int", 0, "") _ = fs.Int64("int64", 0, "") @@ -530,7 +575,7 @@ func TestRangeError(t *testing.T) { } for _, arg := range bad { fs := NewFlagSet("parse error test", ContinueOnError) - fs.SetOutput(ioutil.Discard) + fs.SetOutput(io.Discard) _ = fs.Int("int", 0, "") _ = fs.Int64("int64", 0, "") _ = fs.Uint("uint", 0, "") diff --git a/libgo/go/fmt/doc.go b/libgo/go/fmt/doc.go index a7115809d3d..d05ee519c3d 100644 --- a/libgo/go/fmt/doc.go +++ b/libgo/go/fmt/doc.go @@ -150,7 +150,8 @@ concrete value that it holds, and printing continues with the next rule. 2. If an operand implements the Formatter interface, it will - be invoked. Formatter provides fine control of formatting. + be invoked. In this case the interpretation of verbs and flags is + controlled by that implementation. 3. If the %v verb is used with the # flag (%#v) and the operand implements the GoStringer interface, that will be invoked. diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go index 550c196c703..e52e5dbb397 100644 --- a/libgo/go/fmt/fmt_test.go +++ b/libgo/go/fmt/fmt_test.go @@ -290,11 +290,11 @@ var fmtTests = []struct { {"%q", '\U00000e00', `'\u0e00'`}, {"%q", '\U0010ffff', `'\U0010ffff'`}, // Runes that are not valid. - {"%q", int32(-1), "%!q(int32=-1)"}, + {"%q", int32(-1), `'�'`}, {"%q", 0xDC80, `'�'`}, - {"%q", rune(0x110000), "%!q(int32=1114112)"}, - {"%q", int64(0xFFFFFFFFF), "%!q(int64=68719476735)"}, - {"%q", uint64(0xFFFFFFFFF), "%!q(uint64=68719476735)"}, + {"%q", rune(0x110000), `'�'`}, + {"%q", int64(0xFFFFFFFFF), `'�'`}, + {"%q", uint64(0xFFFFFFFFF), `'�'`}, // width {"%5s", "abc", " abc"}, diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go index 595869140a1..8bc225f5484 100644 --- a/libgo/go/fmt/print.go +++ b/libgo/go/fmt/print.go @@ -47,11 +47,11 @@ type State interface { Flag(c int) bool } -// Formatter is the interface implemented by values with a custom formatter. -// The implementation of Format may call Sprint(f) or Fprint(f) etc. -// to generate its output. +// Formatter is implemented by any value that has a Format method. +// The implementation controls how State and rune are interpreted, +// and may call Sprint(f) or Fprint(f) etc. to generate its output. type Formatter interface { - Format(f State, c rune) + Format(f State, verb rune) } // Stringer is implemented by any value that has a String method, @@ -388,11 +388,7 @@ func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) { case 'c': p.fmt.fmtC(v) case 'q': - if v <= utf8.MaxRune { - p.fmt.fmtQc(v) - } else { - p.badVerb(verb) - } + p.fmt.fmtQc(v) case 'U': p.fmt.fmtUnicode(v) default: diff --git a/libgo/go/go.mod b/libgo/go/go.mod new file mode 100644 index 00000000000..4ae14eea5cb --- /dev/null +++ b/libgo/go/go.mod @@ -0,0 +1,10 @@ +module std + +go 1.16 + +require ( + golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 + golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 + golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect + golang.org/x/text v0.3.4 // indirect +) diff --git a/libgo/go/go/ast/ast.go b/libgo/go/go/ast/ast.go index 81c64589d04..300966a3263 100644 --- a/libgo/go/go/ast/ast.go +++ b/libgo/go/go/ast/ast.go @@ -57,6 +57,11 @@ type Decl interface { // Comments // A Comment node represents a single //-style or /*-style comment. +// +// The Text field contains the comment text without carriage returns (\r) that +// may have been present in the source. Because a comment's end position is +// computed using len(Text), the position reported by End() does not match the +// true source end position for comments containing carriage returns. type Comment struct { Slash token.Pos // position of "/" starting the comment Text string // comment text (excluding '\n' for //-style comments) @@ -285,6 +290,12 @@ type ( } // A BasicLit node represents a literal of basic type. + // + // Note that for the CHAR and STRING kinds, the literal is stored + // with its quotes. For example, for a double-quoted STRING, the + // first and the last rune in the Value field will be ". The + // Unquote and UnquoteChar functions in the strconv package can be + // used to unquote STRING and CHAR values, respectively. BasicLit struct { ValuePos token.Pos // literal position Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING diff --git a/libgo/go/go/ast/commentmap_test.go b/libgo/go/go/ast/commentmap_test.go index e372eab745b..38c62b01ab9 100644 --- a/libgo/go/go/ast/commentmap_test.go +++ b/libgo/go/go/ast/commentmap_test.go @@ -140,4 +140,31 @@ func TestCommentMap(t *testing.T) { } } -// TODO(gri): add tests for Filter. +func TestFilter(t *testing.T) { + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, "", src, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + cmap := NewCommentMap(fset, f, f.Comments) + + // delete variable declaration + for i, decl := range f.Decls { + if gen, ok := decl.(*GenDecl); ok && gen.Tok == token.VAR { + copy(f.Decls[i:], f.Decls[i+1:]) + f.Decls = f.Decls[:len(f.Decls)-1] + break + } + } + + // check if comments are filtered correctly + cc := cmap.Filter(f) + for n, list := range cc { + key := fmt.Sprintf("%2d: %T", fset.Position(n.Pos()).Line, n) + got := ctext(list) + want := res[key] + if key == "25: *ast.GenDecl" || got != want { + t.Errorf("%s: got %q; want %q", key, got, want) + } + } +} diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go index ff5195d8122..0a800f601d4 100644 --- a/libgo/go/go/build/build.go +++ b/libgo/go/go/build/build.go @@ -10,11 +10,11 @@ import ( "fmt" "go/ast" "go/doc" - "go/parser" "go/token" "internal/goroot" "internal/goversion" "io" + "io/fs" "io/ioutil" "os" "os/exec" @@ -98,10 +98,10 @@ type Context struct { // filepath.EvalSymlinks. HasSubdir func(root, dir string) (rel string, ok bool) - // ReadDir returns a slice of os.FileInfo, sorted by Name, + // ReadDir returns a slice of fs.FileInfo, sorted by Name, // describing the content of the named directory. // If ReadDir is nil, Import uses ioutil.ReadDir. - ReadDir func(dir string) ([]os.FileInfo, error) + ReadDir func(dir string) ([]fs.FileInfo, error) // OpenFile opens a file (not a directory) for reading. // If OpenFile is nil, Import uses os.Open. @@ -183,7 +183,7 @@ func hasSubdir(root, dir string) (rel string, ok bool) { } // readDir calls ctxt.ReadDir (if not nil) or else ioutil.ReadDir. -func (ctxt *Context) readDir(path string) ([]os.FileInfo, error) { +func (ctxt *Context) readDir(path string) ([]fs.FileInfo, error) { if f := ctxt.ReadDir; f != nil { return f(path) } @@ -411,19 +411,20 @@ type Package struct { BinaryOnly bool // cannot be rebuilt from source (has //go:binary-only-package comment) // Source files - GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) - CgoFiles []string // .go source files that import "C" - IgnoredGoFiles []string // .go source files ignored for this build - InvalidGoFiles []string // .go source files with detected problems (parse error, wrong package name, and so on) - CFiles []string // .c source files - CXXFiles []string // .cc, .cpp and .cxx source files - MFiles []string // .m (Objective-C) source files - HFiles []string // .h, .hh, .hpp and .hxx source files - FFiles []string // .f, .F, .for and .f90 Fortran source files - SFiles []string // .s source files - SwigFiles []string // .swig files - SwigCXXFiles []string // .swigcxx files - SysoFiles []string // .syso system object files to add to archive + GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) + CgoFiles []string // .go source files that import "C" + IgnoredGoFiles []string // .go source files ignored for this build (including ignored _test.go files) + InvalidGoFiles []string // .go source files with detected problems (parse error, wrong package name, and so on) + IgnoredOtherFiles []string // non-.go source files ignored for this build + CFiles []string // .c source files + CXXFiles []string // .cc, .cpp and .cxx source files + MFiles []string // .m (Objective-C) source files + HFiles []string // .h, .hh, .hpp and .hxx source files + FFiles []string // .f, .F, .for and .f90 Fortran source files + SFiles []string // .s source files + SwigFiles []string // .swig files + SwigCXXFiles []string // .swigcxx files + SysoFiles []string // .syso system object files to add to archive // Cgo directives CgoCFLAGS []string // Cgo CFLAGS directives @@ -433,17 +434,26 @@ type Package struct { CgoLDFLAGS []string // Cgo LDFLAGS directives CgoPkgConfig []string // Cgo pkg-config directives - // Dependency information - Imports []string // import paths from GoFiles, CgoFiles - ImportPos map[string][]token.Position // line information for Imports - // Test information - TestGoFiles []string // _test.go files in package + TestGoFiles []string // _test.go files in package + XTestGoFiles []string // _test.go files outside package + + // Dependency information + Imports []string // import paths from GoFiles, CgoFiles + ImportPos map[string][]token.Position // line information for Imports TestImports []string // import paths from TestGoFiles TestImportPos map[string][]token.Position // line information for TestImports - XTestGoFiles []string // _test.go files outside package XTestImports []string // import paths from XTestGoFiles XTestImportPos map[string][]token.Position // line information for XTestImports + + // //go:embed patterns found in Go source files + // For example, if a source file says + // //go:embed a* b.c + // then the list will contain those two strings as separate entries. + // (See package embed for more details about //go:embed.) + EmbedPatterns []string // patterns from GoFiles, CgoFiles + TestEmbedPatterns []string // patterns from TestGoFiles + XTestEmbedPatterns []string // patterns from XTestGoFiles } // IsCommand reports whether the package is considered a @@ -786,6 +796,7 @@ Found: var badGoError error var Sfiles []string // files with ".S"(capital S)/.sx(capital s equivalent for case insensitive filesystems) var firstFile, firstCommentFile string + var embeds, testEmbeds, xTestEmbeds []string imported := make(map[string][]token.Position) testImported := make(map[string][]token.Position) xTestImported := make(map[string][]token.Position) @@ -795,6 +806,12 @@ Found: if d.IsDir() { continue } + if d.Mode()&fs.ModeSymlink != 0 { + if ctxt.isDir(ctxt.joinPath(p.Dir, d.Name())) { + // Symlinks to directories are not source files. + continue + } + } name := d.Name() ext := nameExt(name) @@ -806,60 +823,43 @@ Found: p.InvalidGoFiles = append(p.InvalidGoFiles, name) } - match, data, filename, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly) + info, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly, fset) if err != nil { badFile(err) continue } - if !match { - if ext == ".go" { + if info == nil { + if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") { + // not due to build constraints - don't report + } else if ext == ".go" { p.IgnoredGoFiles = append(p.IgnoredGoFiles, name) + } else if fileListForExt(p, ext) != nil { + p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, name) } continue } + data, filename := info.header, info.name // Going to save the file. For non-Go files, can stop here. switch ext { - case ".c": - p.CFiles = append(p.CFiles, name) - continue - case ".cc", ".cpp", ".cxx": - p.CXXFiles = append(p.CXXFiles, name) - continue - case ".m": - p.MFiles = append(p.MFiles, name) - continue - case ".h", ".hh", ".hpp", ".hxx": - p.HFiles = append(p.HFiles, name) - continue - case ".f", ".F", ".for", ".f90": - p.FFiles = append(p.FFiles, name) - continue - case ".s": - p.SFiles = append(p.SFiles, name) - continue + case ".go": + // keep going case ".S", ".sx": + // special case for cgo, handled at end Sfiles = append(Sfiles, name) continue - case ".swig": - p.SwigFiles = append(p.SwigFiles, name) - continue - case ".swigcxx": - p.SwigCXXFiles = append(p.SwigCXXFiles, name) - continue - case ".syso": - // binary objects to add to package archive - // Likely of the form foo_windows.syso, but - // the name was vetted above with goodOSArchFile. - p.SysoFiles = append(p.SysoFiles, name) + default: + if list := fileListForExt(p, ext); list != nil { + *list = append(*list, name) + } continue } - pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments) - if err != nil { - badFile(err) + if info.parseErr != nil { + badFile(info.parseErr) continue } + pf := info.parsed pkg := pf.Name.Name if pkg == "documentation" { @@ -906,48 +906,23 @@ 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) - if !ok { - continue - } - for _, dspec := range d.Specs { - spec, ok := dspec.(*ast.ImportSpec) - if !ok { + for _, imp := range info.imports { + if imp.path == "C" { + if isTest { + badFile(fmt.Errorf("use of cgo in test %s not supported", filename)) continue } - quoted := spec.Path.Value - path, err := strconv.Unquote(quoted) - if err != nil { - panic(fmt.Sprintf("%s: parser returned invalid quoted string: <%s>", filename, quoted)) - } - fileImports = append(fileImports, importPos{path, spec.Pos()}) - if path == "C" { - if isTest { - badFile(fmt.Errorf("use of cgo in test %s not supported", filename)) - } else { - cg := spec.Doc - if cg == nil && len(d.Specs) == 1 { - cg = d.Doc - } - if cg != nil { - if err := ctxt.saveCgo(filename, p, cg); err != nil { - badFile(err) - } - } - isCgo = true + isCgo = true + if imp.doc != nil { + if err := ctxt.saveCgo(filename, p, imp.doc); err != nil { + badFile(err) } } } } - var fileList *[]string + var fileList, embedList *[]string var importMap map[string][]token.Position switch { case isCgo: @@ -955,6 +930,7 @@ Found: if ctxt.CgoEnabled { fileList = &p.CgoFiles importMap = imported + embedList = &embeds } else { // Ignore imports from cgo files if cgo is disabled. fileList = &p.IgnoredGoFiles @@ -962,19 +938,25 @@ Found: case isXTest: fileList = &p.XTestGoFiles importMap = xTestImported + embedList = &xTestEmbeds case isTest: fileList = &p.TestGoFiles importMap = testImported + embedList = &testEmbeds default: fileList = &p.GoFiles importMap = imported + embedList = &embeds } *fileList = append(*fileList, name) if importMap != nil { - for _, imp := range fileImports { + for _, imp := range info.imports { importMap[imp.path] = append(importMap[imp.path], fset.Position(imp.pos)) } } + if embedList != nil { + *embedList = append(*embedList, info.embeds...) + } } for tag := range allTags { @@ -982,6 +964,10 @@ Found: } sort.Strings(p.AllTags) + p.EmbedPatterns = uniq(embeds) + p.TestEmbedPatterns = uniq(testEmbeds) + p.XTestEmbedPatterns = uniq(xTestEmbeds) + p.Imports, p.ImportPos = cleanImports(imported) p.TestImports, p.TestImportPos = cleanImports(testImported) p.XTestImports, p.XTestImportPos = cleanImports(xTestImported) @@ -992,6 +978,9 @@ Found: if len(p.CgoFiles) > 0 { p.SFiles = append(p.SFiles, Sfiles...) sort.Strings(p.SFiles) + } else { + p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, Sfiles...) + sort.Strings(p.IgnoredOtherFiles) } if badGoError != nil { @@ -1003,6 +992,46 @@ Found: return p, pkgerr } +func fileListForExt(p *Package, ext string) *[]string { + switch ext { + case ".c": + return &p.CFiles + case ".cc", ".cpp", ".cxx": + return &p.CXXFiles + case ".m": + return &p.MFiles + case ".h", ".hh", ".hpp", ".hxx": + return &p.HFiles + case ".f", ".F", ".for", ".f90": + return &p.FFiles + case ".s", ".S", ".sx": + return &p.SFiles + case ".swig": + return &p.SwigFiles + case ".swigcxx": + return &p.SwigCXXFiles + case ".syso": + return &p.SysoFiles + } + return nil +} + +func uniq(list []string) []string { + if list == nil { + return nil + } + out := make([]string, len(list)) + copy(out, list) + sort.Strings(out) + uniq := out[:0] + for _, x := range out { + if len(uniq) == 0 || uniq[len(uniq)-1] != x { + uniq = append(uniq, x) + } + } + return uniq +} + var errNoModules = errors.New("not using modules") // importGo checks whether it can use the go command to find the directory for path. @@ -1068,9 +1097,9 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) } } - // Unless GO111MODULE=on, look to see if there is a go.mod. + // If GO111MODULE=auto, look to see if there is a go.mod. // Since go1.13, it doesn't matter if we're inside GOPATH. - if go111Module != "on" { + if go111Module == "auto" { var ( parent string err error @@ -1090,9 +1119,14 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) } } for { - info, err := os.Stat(filepath.Join(parent, "go.mod")) - if err == nil && !info.IsDir() { - break + if f, err := ctxt.openFile(ctxt.joinPath(parent, "go.mod")); err == nil { + buf := make([]byte, 100) + _, err := f.Read(buf) + f.Close() + if err == nil || err == io.EOF { + // go.mod exists and is readable (is a file, not a directory). + break + } } d := filepath.Dir(parent) if len(d) >= len(parent) { @@ -1294,22 +1328,46 @@ func parseWord(data []byte) (word, rest []byte) { // MatchFile considers the name of the file and may use ctxt.OpenFile to // read some or all of the file's content. func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) { - match, _, _, err = ctxt.matchFile(dir, name, nil, nil) - return + info, err := ctxt.matchFile(dir, name, nil, nil, nil) + return info != nil, err +} + +var dummyPkg Package + +// fileInfo records information learned about a file included in a build. +type fileInfo struct { + name string // full name including dir + header []byte + fset *token.FileSet + parsed *ast.File + parseErr error + imports []fileImport + embeds []string + embedErr error +} + +type fileImport struct { + path string + pos token.Pos + doc *ast.CommentGroup } // matchFile determines whether the file with the given name in the given directory // should be included in the package being constructed. -// It returns the data read from the file. +// If the file should be included, matchFile returns a non-nil *fileInfo (and a nil error). +// Non-nil errors are reserved for unexpected problems. +// // If name denotes a Go program, matchFile reads until the end of the -// imports (and returns that data) even though it only considers text -// until the first non-comment. +// imports and returns that section of the file in the fileInfo's header field, +// even though it only considers text until the first non-comment +// for +build lines. +// // If allTags is non-nil, matchFile records any encountered build tag // by setting allTags[tag] = true. -func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binaryOnly *bool) (match bool, data []byte, filename string, err error) { +func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binaryOnly *bool, fset *token.FileSet) (*fileInfo, error) { if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") { - return + return nil, nil } i := strings.LastIndex(name, ".") @@ -1319,53 +1377,53 @@ func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binary ext := name[i:] if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles { - return + return nil, nil } - switch ext { - 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 - match = true - return - default: + if ext != ".go" && fileListForExt(&dummyPkg, ext) == nil { // skip - return + return nil, nil } - filename = ctxt.joinPath(dir, name) - f, err := ctxt.openFile(filename) + info := &fileInfo{name: ctxt.joinPath(dir, name), fset: fset} + if ext == ".syso" { + // binary, no reading + return info, nil + } + + f, err := ctxt.openFile(info.name) if err != nil { - return + return nil, err } - if strings.HasSuffix(filename, ".go") { - data, err = readImports(f, false, nil) - if strings.HasSuffix(filename, "_test.go") { + if strings.HasSuffix(name, ".go") { + err = readGoInfo(f, info) + if strings.HasSuffix(name, "_test.go") { binaryOnly = nil // ignore //go:binary-only-package comments in _test.go files } } else { binaryOnly = nil // ignore //go:binary-only-package comments in non-Go sources - data, err = readComments(f) + info.header, err = readComments(f) } f.Close() if err != nil { - err = fmt.Errorf("read %s: %v", filename, err) - return + return nil, fmt.Errorf("read %s: %v", info.name, err) } // Look for +build comments to accept or reject the file. - var sawBinaryOnly bool - if !ctxt.shouldBuild(data, allTags, &sawBinaryOnly) && !ctxt.UseAllFiles { - return + ok, sawBinaryOnly, err := ctxt.shouldBuild(info.header, allTags) + if err != nil { + return nil, err + } + if !ok && !ctxt.UseAllFiles { + return nil, nil } if binaryOnly != nil && sawBinaryOnly { *binaryOnly = true } - match = true - return + + return info, nil } func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) { @@ -1387,7 +1445,25 @@ func ImportDir(dir string, mode ImportMode) (*Package, error) { return Default.ImportDir(dir, mode) } -var slashslash = []byte("//") +var ( + bSlashSlash = []byte(slashSlash) + bStarSlash = []byte(starSlash) + bSlashStar = []byte(slashStar) + + goBuildComment = []byte("//go:build") + + errGoBuildWithoutBuild = errors.New("//go:build comment without // +build comment") + errMultipleGoBuild = errors.New("multiple //go:build comments") // unused in Go 1.(N-1) +) + +func isGoBuildComment(line []byte) bool { + if !bytes.HasPrefix(line, goBuildComment) { + return false + } + line = bytes.TrimSpace(line) + rest := line[len(goBuildComment):] + return len(rest) == 0 || len(bytes.TrimSpace(rest)) < len(rest) +} // Special comment denoting a binary-only package. // See https://golang.org/design/2775-binary-only-packages @@ -1407,37 +1483,24 @@ var binaryOnlyComment = []byte("//go:binary-only-package") // // marks the file as applicable only on Windows and Linux. // -// If shouldBuild finds a //go:binary-only-package comment in the file, -// it sets *binaryOnly to true. Otherwise it does not change *binaryOnly. +// For each build tag it consults, shouldBuild sets allTags[tag] = true. // -func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool, binaryOnly *bool) bool { - sawBinaryOnly := false +// shouldBuild reports whether the file should be built +// and whether a //go:binary-only-package comment was found. +func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool) (shouldBuild, binaryOnly bool, err error) { // Pass 1. Identify leading run of // comments and blank lines, // which must be followed by a blank line. - end := 0 - p := content - for len(p) > 0 { - line := p - if i := bytes.IndexByte(line, '\n'); i >= 0 { - line, p = line[:i], p[i+1:] - } else { - p = p[len(p):] - } - line = bytes.TrimSpace(line) - if len(line) == 0 { // Blank line - end = len(content) - len(p) - continue - } - if !bytes.HasPrefix(line, slashslash) { // Not comment line - break - } + // Also identify any //go:build comments. + content, goBuild, sawBinaryOnly, err := parseFileHeader(content) + if err != nil { + return false, false, err } - content = content[:end] - // Pass 2. Process each line in the run. - p = content - allok := true + // Pass 2. Process each +build line in the run. + p := content + shouldBuild = true + sawBuild := false for len(p) > 0 { line := p if i := bytes.IndexByte(line, '\n'); i >= 0 { @@ -1446,17 +1509,15 @@ func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool, binary p = p[len(p):] } line = bytes.TrimSpace(line) - if !bytes.HasPrefix(line, slashslash) { + if !bytes.HasPrefix(line, bSlashSlash) { continue } - if bytes.Equal(line, binaryOnlyComment) { - sawBinaryOnly = true - } - line = bytes.TrimSpace(line[len(slashslash):]) + line = bytes.TrimSpace(line[len(bSlashSlash):]) if len(line) > 0 && line[0] == '+' { // Looks like a comment +line. f := strings.Fields(string(line)) if f[0] == "+build" { + sawBuild = true ok := false for _, tok := range f[1:] { if ctxt.match(tok, allTags) { @@ -1464,17 +1525,84 @@ func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool, binary } } if !ok { - allok = false + shouldBuild = false } } } } - if binaryOnly != nil && sawBinaryOnly { - *binaryOnly = true + if goBuild != nil && !sawBuild { + return false, false, errGoBuildWithoutBuild } - return allok + return shouldBuild, sawBinaryOnly, nil +} + +func parseFileHeader(content []byte) (trimmed, goBuild []byte, sawBinaryOnly bool, err error) { + end := 0 + p := content + ended := false // found non-blank, non-// line, so stopped accepting // +build lines + inSlashStar := false // in /* */ comment + +Lines: + for len(p) > 0 { + line := p + if i := bytes.IndexByte(line, '\n'); i >= 0 { + line, p = line[:i], p[i+1:] + } else { + p = p[len(p):] + } + line = bytes.TrimSpace(line) + if len(line) == 0 && !ended { // Blank line + // Remember position of most recent blank line. + // When we find the first non-blank, non-// line, + // this "end" position marks the latest file position + // where a // +build line can appear. + // (It must appear _before_ a blank line before the non-blank, non-// line. + // Yes, that's confusing, which is part of why we moved to //go:build lines.) + // Note that ended==false here means that inSlashStar==false, + // since seeing a /* would have set ended==true. + end = len(content) - len(p) + continue Lines + } + if !bytes.HasPrefix(line, slashSlash) { // Not comment line + ended = true + } + + if !inSlashStar && isGoBuildComment(line) { + if false && goBuild != nil { // enabled in Go 1.N + return nil, nil, false, errMultipleGoBuild + } + goBuild = line + } + if !inSlashStar && bytes.Equal(line, binaryOnlyComment) { + sawBinaryOnly = true + } + + Comments: + for len(line) > 0 { + if inSlashStar { + if i := bytes.Index(line, starSlash); i >= 0 { + inSlashStar = false + line = bytes.TrimSpace(line[i+len(starSlash):]) + continue Comments + } + continue Lines + } + if bytes.HasPrefix(line, bSlashSlash) { + continue Lines + } + if bytes.HasPrefix(line, bSlashStar) { + inSlashStar = true + line = bytes.TrimSpace(line[len(bSlashStar):]) + continue Comments + } + // Found non-comment text. + break Lines + } + } + + return content[:end], goBuild, sawBinaryOnly, nil } // saveCgo saves the information from the #cgo lines in the import "C" comment. @@ -1750,6 +1878,9 @@ func (ctxt *Context) match(name string, allTags map[string]bool) bool { if ctxt.GOOS == "illumos" && name == "solaris" { return true } + if ctxt.GOOS == "ios" && name == "darwin" { + return true + } // other tags for _, tag := range ctxt.BuildTags { @@ -1777,7 +1908,10 @@ func (ctxt *Context) match(name string, allTags map[string]bool) bool { // name_$(GOARCH)_test.* // name_$(GOOS)_$(GOARCH)_test.* // -// An exception: if GOOS=android, then files with GOOS=linux are also matched. +// Exceptions: +// if GOOS=android, then files with GOOS=linux are also matched. +// if GOOS=illumos, then files with GOOS=solaris are also matched. +// if GOOS=ios, then files with GOOS=darwin are also matched. func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool { if dot := strings.Index(name, "."); dot != -1 { name = name[:dot] diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go index efdd7cfb8b4..649b08c7196 100644 --- a/libgo/go/go/build/build_test.go +++ b/libgo/go/go/build/build_test.go @@ -8,7 +8,6 @@ import ( "flag" "internal/testenv" "io" - "io/ioutil" "os" "path/filepath" "reflect" @@ -121,7 +120,7 @@ func TestMultiplePackageImport(t *testing.T) { func TestLocalDirectory(t *testing.T) { t.Skip("does not work with gccgo") - if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + if runtime.GOOS == "ios" { t.Skipf("skipping on %s/%s, no valid GOROOT", runtime.GOOS, runtime.GOARCH) } @@ -139,48 +138,178 @@ func TestLocalDirectory(t *testing.T) { } } -func TestShouldBuild(t *testing.T) { - const file1 = "// +build tag1\n\n" + - "package main\n" - want1 := map[string]bool{"tag1": true} - - const file2 = "// +build cgo\n\n" + - "// This package implements parsing of tags like\n" + - "// +build tag1\n" + - "package build" - want2 := map[string]bool{"cgo": true} - - const file3 = "// Copyright The Go Authors.\n\n" + - "package build\n\n" + - "// shouldBuild checks tags given by lines of the form\n" + - "// +build tag\n" + - "func shouldBuild(content []byte)\n" - want3 := map[string]bool{} - - ctx := &Context{BuildTags: []string{"tag1"}} - m := map[string]bool{} - if !ctx.shouldBuild([]byte(file1), m, nil) { - t.Errorf("shouldBuild(file1) = false, want true") - } - if !reflect.DeepEqual(m, want1) { - t.Errorf("shouldBuild(file1) tags = %v, want %v", m, want1) - } - - m = map[string]bool{} - if ctx.shouldBuild([]byte(file2), m, nil) { - t.Errorf("shouldBuild(file2) = true, want false") - } - if !reflect.DeepEqual(m, want2) { - t.Errorf("shouldBuild(file2) tags = %v, want %v", m, want2) - } +var shouldBuildTests = []struct { + name string + content string + tags map[string]bool + binaryOnly bool + shouldBuild bool + err error +}{ + { + name: "Yes", + content: "// +build yes\n\n" + + "package main\n", + tags: map[string]bool{"yes": true}, + shouldBuild: true, + }, + { + name: "Or", + content: "// +build no yes\n\n" + + "package main\n", + tags: map[string]bool{"yes": true, "no": true}, + shouldBuild: true, + }, + { + name: "And", + content: "// +build no,yes\n\n" + + "package main\n", + tags: map[string]bool{"yes": true, "no": true}, + shouldBuild: false, + }, + { + name: "Cgo", + content: "// +build cgo\n\n" + + "// Copyright The Go Authors.\n\n" + + "// This package implements parsing of tags like\n" + + "// +build tag1\n" + + "package build", + tags: map[string]bool{"cgo": true}, + shouldBuild: false, + }, + { + name: "AfterPackage", + content: "// Copyright The Go Authors.\n\n" + + "package build\n\n" + + "// shouldBuild checks tags given by lines of the form\n" + + "// +build tag\n" + + "func shouldBuild(content []byte)\n", + tags: map[string]bool{}, + shouldBuild: true, + }, + { + name: "TooClose", + content: "// +build yes\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: true, + }, + { + name: "TooCloseNo", + content: "// +build no\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: true, + }, + { + name: "BinaryOnly", + content: "//go:binary-only-package\n" + + "// +build yes\n" + + "package main\n", + tags: map[string]bool{}, + binaryOnly: true, + shouldBuild: true, + }, + { + name: "ValidGoBuild", + content: "// +build yes\n\n" + + "//go:build no\n" + + "package main\n", + tags: map[string]bool{"yes": true}, + shouldBuild: true, + }, + { + name: "MissingBuild", + content: "//go:build no\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: false, + err: errGoBuildWithoutBuild, + }, + { + name: "MissingBuild2", + content: "/* */\n" + + "// +build yes\n\n" + + "//go:build no\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: false, + err: errGoBuildWithoutBuild, + }, + { + name: "MissingBuild2", + content: "/*\n" + + "// +build yes\n\n" + + "*/\n" + + "//go:build no\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: false, + err: errGoBuildWithoutBuild, + }, + { + name: "Comment1", + content: "/*\n" + + "//go:build no\n" + + "*/\n\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: true, + }, + { + name: "Comment2", + content: "/*\n" + + "text\n" + + "*/\n\n" + + "//go:build no\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: false, + err: errGoBuildWithoutBuild, + }, + { + name: "Comment3", + content: "/*/*/ /* hi *//* \n" + + "text\n" + + "*/\n\n" + + "//go:build no\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: false, + err: errGoBuildWithoutBuild, + }, + { + name: "Comment4", + content: "/**///go:build no\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: true, + }, + { + name: "Comment5", + content: "/**/\n" + + "//go:build no\n" + + "package main\n", + tags: map[string]bool{}, + shouldBuild: false, + err: errGoBuildWithoutBuild, + }, +} - m = map[string]bool{} - ctx = &Context{BuildTags: nil} - if !ctx.shouldBuild([]byte(file3), m, nil) { - t.Errorf("shouldBuild(file3) = false, want true") - } - if !reflect.DeepEqual(m, want3) { - t.Errorf("shouldBuild(file3) tags = %v, want %v", m, want3) +func TestShouldBuild(t *testing.T) { + for _, tt := range shouldBuildTests { + t.Run(tt.name, func(t *testing.T) { + ctx := &Context{BuildTags: []string{"yes"}} + tags := map[string]bool{} + shouldBuild, binaryOnly, err := ctx.shouldBuild([]byte(tt.content), tags) + if shouldBuild != tt.shouldBuild || binaryOnly != tt.binaryOnly || !reflect.DeepEqual(tags, tt.tags) || err != tt.err { + t.Errorf("mismatch:\n"+ + "have shouldBuild=%v, binaryOnly=%v, tags=%v, err=%v\n"+ + "want shouldBuild=%v, binaryOnly=%v, tags=%v, err=%v", + shouldBuild, binaryOnly, tags, err, + tt.shouldBuild, tt.binaryOnly, tt.tags, tt.err) + } + }) } } @@ -252,7 +381,7 @@ func TestMatchFile(t *testing.T) { func TestImportCmd(t *testing.T) { t.Skip("does not work with gccgo") - if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + if runtime.GOOS == "ios" { t.Skipf("skipping on %s/%s, no valid GOROOT", runtime.GOOS, runtime.GOARCH) } @@ -326,7 +455,7 @@ func TestImportDirNotExist(t *testing.T) { testenv.MustHaveGoBuild(t) // really must just have source ctxt := Default - emptyDir, err := ioutil.TempDir("", t.Name()) + emptyDir, err := os.MkdirTemp("", t.Name()) if err != nil { t.Fatal(err) } @@ -464,7 +593,7 @@ func TestImportPackageOutsideModule(t *testing.T) { // 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") + gopath, err := os.MkdirTemp("", "gobuild-notmodule") if err != nil { t.Fatal(err) } @@ -472,7 +601,7 @@ func TestImportPackageOutsideModule(t *testing.T) { 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 { + if err := os.WriteFile(filepath.Join(gopath, "src/example.com/p/p.go"), []byte("package p"), 0666); err != nil { t.Fatal(err) } @@ -484,11 +613,13 @@ func TestImportPackageOutsideModule(t *testing.T) { ctxt.GOPATH = gopath ctxt.Dir = filepath.Join(gopath, "src/example.com/p") - want := "cannot find module providing package" + want := "working directory is not part of a module" 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) + } else { + t.Logf(`ctxt.Import("example.com/p", _, FindOnly): %v`, err) } } @@ -526,12 +657,12 @@ func TestIssue23594(t *testing.T) { // Verifies golang.org/issue/34752. func TestMissingImportErrorRepetition(t *testing.T) { testenv.MustHaveGoBuild(t) // need 'go list' internally - tmp, err := ioutil.TempDir("", "") + tmp, err := os.MkdirTemp("", "") 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 { + if err := os.WriteFile(filepath.Join(tmp, "go.mod"), []byte("module m"), 0666); err != nil { t.Fatal(err) } defer os.Setenv("GO111MODULE", os.Getenv("GO111MODULE")) @@ -549,9 +680,16 @@ func TestMissingImportErrorRepetition(t *testing.T) { 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") + + // Also don't count instances in suggested "go get" or similar commands + // (see https://golang.org/issue/41576). The suggested command typically + // follows a semicolon. + errStr = strings.SplitN(errStr, ";", 2)[0] + 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) } diff --git a/libgo/go/go/build/deps_test.go b/libgo/go/go/build/deps_test.go index fa8ecf10f42..56942c0fd2b 100644 --- a/libgo/go/go/build/deps_test.go +++ b/libgo/go/go/build/deps_test.go @@ -11,12 +11,11 @@ import ( "bytes" "fmt" "internal/testenv" - "io/ioutil" + "io/fs" "os" "path/filepath" "runtime" "sort" - "strconv" "strings" "testing" ) @@ -99,10 +98,16 @@ var depsRules = ` RUNTIME < io; + syscall !< io; reflect !< sort; + RUNTIME, unicode/utf8 + < path; + + unicode !< path; + # SYSCALL is RUNTIME plus the packages necessary for basic system calls. - RUNTIME, unicode/utf8, unicode/utf16, io + RUNTIME, unicode/utf8, unicode/utf16 < internal/syscall/windows/sysdll, syscall/js < syscall < internal/syscall/unix, internal/syscall/windows, internal/syscall/windows/registry @@ -116,6 +121,9 @@ var depsRules = ` < context < TIME; + TIME, io, path, sort + < io/fs; + # MATH is RUNTIME plus the basic math packages. RUNTIME < math @@ -129,6 +137,9 @@ var depsRules = ` MATH < math/rand; + MATH + < runtime/metrics; + MATH, unicode/utf8 < strconv; @@ -137,7 +148,7 @@ var depsRules = ` # STR is basic string and buffer manipulation. RUNTIME, io, unicode/utf8, unicode/utf16, unicode < bytes, strings - < bufio, path; + < bufio; bufio, path, strconv < STR; @@ -145,7 +156,7 @@ var depsRules = ` # OS is basic OS access, including helpers (path/filepath, os/exec, etc). # OS includes string routines, but those must be layered above package os. # OS does not include reflection. - TIME, io, sort + io/fs < internal/testlog < internal/poll < os @@ -155,7 +166,9 @@ var depsRules = ` os/signal, STR < path/filepath - < io/ioutil, os/exec + < io/ioutil, os/exec; + + io/ioutil, os/exec, os/signal < OS; reflect !< OS; @@ -318,7 +331,6 @@ var depsRules = ` # so large dependencies must be kept out. # This is a long-looking list but most of these # are small with few dependencies. - # math/rand should probably be removed at some point. CGO, golang.org/x/net/dns/dnsmessage, golang.org/x/net/lif, @@ -327,11 +339,11 @@ var depsRules = ` internal/poll, internal/singleflight, internal/race, - math/rand, os < net; fmt, unicode !< net; + math/rand !< net; # net uses runtime instead # NET is net plus net-helper packages. FMT, net @@ -382,7 +394,7 @@ var depsRules = ` CGO, net !< CRYPTO-MATH; # TLS, Prince of Dependencies. - CGO, CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem + CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem < golang.org/x/crypto/internal/subtle < golang.org/x/crypto/chacha20 < golang.org/x/crypto/poly1305 @@ -449,7 +461,7 @@ var depsRules = ` OS, compress/gzip, regexp < internal/profile; - html/template, internal/profile, net/http, runtime/pprof, runtime/trace + html, internal/profile, net/http, runtime/pprof, runtime/trace < net/http/pprof; # RPC @@ -457,14 +469,19 @@ var depsRules = ` < net/rpc < net/rpc/jsonrpc; + # System Information + internal/cpu, sync + < internal/sysinfo; + # Test-only log - < testing/iotest; + < testing/iotest + < testing/fstest; FMT, flag, math/rand < testing/quick; - FMT, flag, runtime/debug, runtime/trace + FMT, flag, runtime/debug, runtime/trace, internal/sysinfo < testing; internal/testlog, runtime/pprof, regexp @@ -479,7 +496,7 @@ var depsRules = ` CGO, OS, fmt < os/signal/internal/pty; - NET, testing + NET, testing, math/rand < golang.org/x/net/nettest; FMT, container/heap, math/rand @@ -492,8 +509,8 @@ func listStdPkgs(goroot string) ([]string, error) { var pkgs []string src := filepath.Join(goroot, "src") + string(filepath.Separator) - walkFn := func(path string, fi os.FileInfo, err error) error { - if err != nil || !fi.IsDir() || path == src { + walkFn := func(path string, d fs.DirEntry, err error) error { + if err != nil || !d.IsDir() || path == src { return nil } @@ -510,7 +527,7 @@ func listStdPkgs(goroot string) ([]string, error) { pkgs = append(pkgs, strings.TrimPrefix(name, "vendor/")) return nil } - if err := filepath.Walk(src, walkFn); err != nil { + if err := filepath.WalkDir(src, walkFn); err != nil { return nil, err } return pkgs, nil @@ -579,7 +596,7 @@ func findImports(pkg string) ([]string, error) { vpkg = "vendor/" + pkg } dir := filepath.Join(Default.GOROOT, "src", vpkg) - files, err := ioutil.ReadDir(dir) + files, err := os.ReadDir(dir) if err != nil { return nil, err } @@ -594,24 +611,22 @@ func findImports(pkg string) ([]string, error) { if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") { continue } - f, err := os.Open(filepath.Join(dir, name)) + var info fileInfo + info.name = filepath.Join(dir, name) + f, err := os.Open(info.name) if err != nil { return nil, err } - var imp []string - data, err := readImports(f, false, &imp) + err = readGoInfo(f, &info) f.Close() if err != nil { return nil, fmt.Errorf("reading %v: %v", name, err) } - if bytes.Contains(data, buildIgnore) { + if bytes.Contains(info.header, buildIgnore) { continue } - for _, quoted := range imp { - path, err := strconv.Unquote(quoted) - if err != nil { - continue - } + for _, imp := range info.imports { + path := imp.path if !haveImport[path] { haveImport[path] = true imports = append(imports, path) diff --git a/libgo/go/go/build/read.go b/libgo/go/go/build/read.go index 29b8cdc7867..6806a51c247 100644 --- a/libgo/go/go/build/read.go +++ b/libgo/go/go/build/read.go @@ -7,7 +7,13 @@ package build import ( "bufio" "errors" + "fmt" + "go/ast" + "go/parser" "io" + "strconv" + "strings" + "unicode" "unicode/utf8" ) @@ -57,6 +63,29 @@ func (r *importReader) readByte() byte { return c } +// readByteNoBuf is like readByte but doesn't buffer the byte. +// It exhausts r.buf before reading from r.b. +func (r *importReader) readByteNoBuf() byte { + if len(r.buf) > 0 { + c := r.buf[0] + r.buf = r.buf[1:] + return c + } + c, err := r.b.ReadByte() + if err == nil && c == 0 { + err = errNUL + } + if err != nil { + if err == io.EOF { + r.eof = true + } else if r.err == nil { + r.err = err + } + c = 0 + } + return c +} + // peekByte returns the next byte from the input reader but does not advance beyond it. // If skipSpace is set, peekByte skips leading spaces and comments. func (r *importReader) peekByte(skipSpace bool) byte { @@ -117,6 +146,74 @@ func (r *importReader) nextByte(skipSpace bool) byte { return c } +var goEmbed = []byte("go:embed") + +// findEmbed advances the input reader to the next //go:embed comment. +// It reports whether it found a comment. +// (Otherwise it found an error or EOF.) +func (r *importReader) findEmbed(first bool) bool { + // The import block scan stopped after a non-space character, + // so the reader is not at the start of a line on the first call. + // After that, each //go:embed extraction leaves the reader + // at the end of a line. + startLine := !first + var c byte + for r.err == nil && !r.eof { + c = r.readByteNoBuf() + Reswitch: + switch c { + default: + startLine = false + + case '\n': + startLine = true + + case ' ', '\t': + // leave startLine alone + + case '/': + c = r.readByteNoBuf() + switch c { + default: + startLine = false + goto Reswitch + + case '*': + var c1 byte + for (c != '*' || c1 != '/') && r.err == nil { + if r.eof { + r.syntaxError() + } + c, c1 = c1, r.readByteNoBuf() + } + startLine = false + + case '/': + if startLine { + // Try to read this as a //go:embed comment. + for i := range goEmbed { + c = r.readByteNoBuf() + if c != goEmbed[i] { + goto SkipSlashSlash + } + } + c = r.readByteNoBuf() + if c == ' ' || c == '\t' { + // Found one! + return true + } + } + SkipSlashSlash: + for c != '\n' && r.err == nil && !r.eof { + c = r.readByteNoBuf() + } + startLine = true + } + } + } + return false +} + // readKeyword reads the given keyword from the input. // If the keyword is not present, readKeyword records a syntax error. func (r *importReader) readKeyword(kw string) { @@ -147,15 +244,11 @@ func (r *importReader) readIdent() { // readString reads a quoted string literal from the input. // If an identifier is not present, readString records a syntax error. -func (r *importReader) readString(save *[]string) { +func (r *importReader) readString() { switch r.nextByte(true) { case '`': - start := len(r.buf) - 1 for r.err == nil { if r.nextByte(false) == '`' { - if save != nil { - *save = append(*save, string(r.buf[start:])) - } break } if r.eof { @@ -163,13 +256,9 @@ func (r *importReader) readString(save *[]string) { } } case '"': - start := len(r.buf) - 1 for r.err == nil { c := r.nextByte(false) if c == '"' { - if save != nil { - *save = append(*save, string(r.buf[start:])) - } break } if r.eof || c == '\n' { @@ -186,17 +275,17 @@ func (r *importReader) readString(save *[]string) { // readImport reads an import clause - optional identifier followed by quoted string - // from the input. -func (r *importReader) readImport(imports *[]string) { +func (r *importReader) readImport() { c := r.peekByte(true) if c == '.' { r.peek = 0 } else if isIdent(c) { r.readIdent() } - r.readString(imports) + r.readString() } -// readComments is like ioutil.ReadAll, except that it only reads the leading +// readComments is like io.ReadAll, except that it only reads the leading // block of comments in the file. func readComments(f io.Reader) ([]byte, error) { r := &importReader{b: bufio.NewReader(f)} @@ -208,9 +297,14 @@ func readComments(f io.Reader) ([]byte, error) { return r.buf, r.err } -// readImports is like ioutil.ReadAll, except that it expects a Go file as input -// and stops reading the input once the imports have completed. -func readImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) { +// readGoInfo expects a Go file as input and reads the file up to and including the import section. +// It records what it learned in *info. +// If info.fset is non-nil, readGoInfo parses the file and sets info.parsed, info.parseErr, +// info.imports, info.embeds, and info.embedErr. +// +// It only returns an error if there are problems reading the file, +// not for syntax errors in the file itself. +func readGoInfo(f io.Reader, info *fileInfo) error { r := &importReader{b: bufio.NewReader(f)} r.readKeyword("package") @@ -220,28 +314,162 @@ func readImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte if r.peekByte(true) == '(' { r.nextByte(false) for r.peekByte(true) != ')' && r.err == nil { - r.readImport(imports) + r.readImport() } r.nextByte(false) } else { - r.readImport(imports) + r.readImport() } } + info.header = r.buf + // If we stopped successfully before EOF, we read a byte that told us we were done. // Return all but that last byte, which would cause a syntax error if we let it through. if r.err == nil && !r.eof { - return r.buf[:len(r.buf)-1], nil + info.header = r.buf[:len(r.buf)-1] } // If we stopped for a syntax error, consume the whole file so that // we are sure we don't change the errors that go/parser returns. - if r.err == errSyntax && !reportSyntaxError { + if r.err == errSyntax { r.err = nil for r.err == nil && !r.eof { r.readByte() } + info.header = r.buf + } + if r.err != nil { + return r.err + } + + if info.fset == nil { + return nil + } + + // Parse file header & record imports. + info.parsed, info.parseErr = parser.ParseFile(info.fset, info.name, info.header, parser.ImportsOnly|parser.ParseComments) + if info.parseErr != nil { + return nil + } + + hasEmbed := false + for _, decl := range info.parsed.Decls { + d, ok := decl.(*ast.GenDecl) + if !ok { + continue + } + for _, dspec := range d.Specs { + spec, ok := dspec.(*ast.ImportSpec) + if !ok { + continue + } + quoted := spec.Path.Value + path, err := strconv.Unquote(quoted) + if err != nil { + return fmt.Errorf("parser returned invalid quoted string: <%s>", quoted) + } + if path == "embed" { + hasEmbed = true + } + + doc := spec.Doc + if doc == nil && len(d.Specs) == 1 { + doc = d.Doc + } + info.imports = append(info.imports, fileImport{path, spec.Pos(), doc}) + } } - return r.buf, r.err + // If the file imports "embed", + // we have to look for //go:embed comments + // in the remainder of the file. + // The compiler will enforce the mapping of comments to + // declared variables. We just need to know the patterns. + // If there were //go:embed comments earlier in the file + // (near the package statement or imports), the compiler + // will reject them. They can be (and have already been) ignored. + if hasEmbed { + var line []byte + for first := true; r.findEmbed(first); first = false { + line = line[:0] + for { + c := r.readByteNoBuf() + if c == '\n' || r.err != nil || r.eof { + break + } + line = append(line, c) + } + // Add args if line is well-formed. + // Ignore badly-formed lines - the compiler will report them when it finds them, + // and we can pretend they are not there to help go list succeed with what it knows. + args, err := parseGoEmbed(string(line)) + if err == nil { + info.embeds = append(info.embeds, args...) + } + } + } + + return nil +} + +// parseGoEmbed parses the text following "//go:embed" to extract the glob patterns. +// It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings. +// There is a copy of this code in cmd/compile/internal/gc/noder.go as well. +func parseGoEmbed(args string) ([]string, error) { + var list []string + for args = strings.TrimSpace(args); args != ""; args = strings.TrimSpace(args) { + var path string + Switch: + switch args[0] { + default: + i := len(args) + for j, c := range args { + if unicode.IsSpace(c) { + i = j + break + } + } + path = args[:i] + args = args[i:] + + case '`': + i := strings.Index(args[1:], "`") + if i < 0 { + return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args) + } + path = args[1 : 1+i] + args = args[1+i+1:] + + case '"': + i := 1 + for ; i < len(args); i++ { + if args[i] == '\\' { + i++ + continue + } + if args[i] == '"' { + q, err := strconv.Unquote(args[:i+1]) + if err != nil { + return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args[:i+1]) + } + path = q + args = args[i+1:] + break Switch + } + } + if i >= len(args) { + return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args) + } + } + + if args != "" { + r, _ := utf8.DecodeRuneInString(args) + if !unicode.IsSpace(r) { + return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args) + } + } + list = append(list, path) + } + return list, nil } diff --git a/libgo/go/go/build/read_test.go b/libgo/go/go/build/read_test.go index 8636533f697..9264d2606f1 100644 --- a/libgo/go/go/build/read_test.go +++ b/libgo/go/go/build/read_test.go @@ -5,7 +5,9 @@ package build import ( + "go/token" "io" + "reflect" "strings" "testing" ) @@ -13,12 +15,12 @@ import ( const quote = "`" type readTest struct { - // Test input contains ℙ where readImports should stop. + // Test input contains ℙ where readGoInfo should stop. in string err string } -var readImportsTests = []readTest{ +var readGoInfoTests = []readTest{ { `package p`, "", @@ -37,15 +39,15 @@ var readImportsTests = []readTest{ }, { `package p - + // comment - + import "x" import _ "x" import a "x" - + /* comment */ - + import ( "x" /* comment */ _ "x" @@ -59,7 +61,7 @@ var readImportsTests = []readTest{ import () import()import()import() import();import();import() - + ℙvar x = 1 `, "", @@ -85,7 +87,7 @@ var readCommentsTests = []readTest{ /* bar */ /* quux */ // baz - + /*/ zot */ // asdf @@ -127,8 +129,12 @@ func testRead(t *testing.T, tests []readTest, read func(io.Reader) ([]byte, erro } } -func TestReadImports(t *testing.T) { - testRead(t, readImportsTests, func(r io.Reader) ([]byte, error) { return readImports(r, true, nil) }) +func TestReadGoInfo(t *testing.T) { + testRead(t, readGoInfoTests, func(r io.Reader) ([]byte, error) { + var info fileInfo + err := readGoInfo(r, &info) + return info.header, err + }) } func TestReadComments(t *testing.T) { @@ -202,11 +208,6 @@ var readFailuresTests = []readTest{ }, } -func TestReadFailures(t *testing.T) { - // Errors should be reported (true arg to readImports). - testRead(t, readFailuresTests, func(r io.Reader) ([]byte, error) { return readImports(r, true, nil) }) -} - func TestReadFailuresIgnored(t *testing.T) { // Syntax errors should not be reported (false arg to readImports). // Instead, entire file should be the output and no error. @@ -219,5 +220,63 @@ func TestReadFailuresIgnored(t *testing.T) { tt.err = "" } } - testRead(t, tests, func(r io.Reader) ([]byte, error) { return readImports(r, false, nil) }) + testRead(t, tests, func(r io.Reader) ([]byte, error) { + var info fileInfo + err := readGoInfo(r, &info) + return info.header, err + }) +} + +var readEmbedTests = []struct { + in string + out []string +}{ + { + "package p\n", + nil, + }, + { + "package p\nimport \"embed\"\nvar i int\n//go:embed x y z\nvar files embed.FS", + []string{"x", "y", "z"}, + }, + { + "package p\nimport \"embed\"\nvar i int\n//go:embed x \"\\x79\" `z`\nvar files embed.FS", + []string{"x", "y", "z"}, + }, + { + "package p\nimport \"embed\"\nvar i int\n//go:embed x y\n//go:embed z\nvar files embed.FS", + []string{"x", "y", "z"}, + }, + { + "package p\nimport \"embed\"\nvar i int\n\t //go:embed x y\n\t //go:embed z\n\t var files embed.FS", + []string{"x", "y", "z"}, + }, + { + "package p\nimport \"embed\"\n//go:embed x y z\nvar files embed.FS", + []string{"x", "y", "z"}, + }, + { + "package p\n//go:embed x y z\n", // no import, no scan + nil, + }, + { + "package p\n//go:embed x y z\nvar files embed.FS", // no import, no scan + nil, + }, +} + +func TestReadEmbed(t *testing.T) { + fset := token.NewFileSet() + for i, tt := range readEmbedTests { + var info fileInfo + info.fset = fset + err := readGoInfo(strings.NewReader(tt.in), &info) + if err != nil { + t.Errorf("#%d: %v", i, err) + continue + } + if !reflect.DeepEqual(info.embeds, tt.out) { + t.Errorf("#%d: embeds=%v, want %v", i, info.embeds, tt.out) + } + } } diff --git a/libgo/go/go/build/syslist.go b/libgo/go/go/build/syslist.go index d72649b8b41..4f5e96c044d 100644 --- a/libgo/go/go/build/syslist.go +++ b/libgo/go/go/build/syslist.go @@ -7,5 +7,5 @@ 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 goosList = "aix android darwin dragonfly freebsd hurd illumos ios 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/syslist_test.go b/libgo/go/go/build/syslist_test.go index 7973ff4ee5f..2b7b4c71aaa 100644 --- a/libgo/go/go/build/syslist_test.go +++ b/libgo/go/go/build/syslist_test.go @@ -17,7 +17,7 @@ var ( ) func anotherOS() string { - if thisOS != "darwin" { + if thisOS != "darwin" && thisOS != "ios" { return "darwin" } return "linux" diff --git a/libgo/go/go/constant/value.go b/libgo/go/go/constant/value.go index 08bcb3bf871..46414423f2d 100644 --- a/libgo/go/go/constant/value.go +++ b/libgo/go/go/constant/value.go @@ -66,6 +66,11 @@ type Value interface { // The spec requires at least 256 bits; typical implementations use 512 bits. const prec = 512 +// TODO(gri) Consider storing "error" information in an unknownVal so clients +// can provide better error messages. For instance, if a number is +// too large (incl. infinity), that could be recorded in unknownVal. +// See also #20583 and #42695 for use cases. + type ( unknownVal struct{} boolVal bool @@ -297,10 +302,16 @@ func makeFloat(x *big.Float) Value { if x.Sign() == 0 { return floatVal0 } + if x.IsInf() { + return unknownVal{} + } return floatVal{x} } func makeComplex(re, im Value) Value { + if re.Kind() == Unknown || im.Kind() == Unknown { + return unknownVal{} + } return complexVal{re, im} } @@ -359,16 +370,13 @@ func MakeUint64(x uint64) Value { } // MakeFloat64 returns the Float value for x. +// If x is -0.0, the result is 0.0. // If x is not finite, the result is an Unknown. func MakeFloat64(x float64) Value { if math.IsInf(x, 0) || math.IsNaN(x) { return unknownVal{} } - // convert -0 to 0 - if x == 0 { - return int64Val(0) - } - return ratVal{newRat().SetFloat64(x)} + return ratVal{newRat().SetFloat64(x + 0)} // convert -0 to 0 } // MakeFromLiteral returns the corresponding integer, floating-point, @@ -583,11 +591,11 @@ func Make(x interface{}) Value { case int64: return int64Val(x) case *big.Int: - return intVal{x} + return makeInt(x) case *big.Rat: - return ratVal{x} + return makeRat(x) case *big.Float: - return floatVal{x} + return makeFloat(x) default: return unknownVal{} } diff --git a/libgo/go/go/constant/value_test.go b/libgo/go/go/constant/value_test.go index a319039fc6e..286677407d9 100644 --- a/libgo/go/go/constant/value_test.go +++ b/libgo/go/go/constant/value_test.go @@ -7,6 +7,7 @@ package constant import ( "fmt" "go/token" + "math" "math/big" "strings" "testing" @@ -82,6 +83,11 @@ var floatTests = []string{ `1_2_3.123 = 123.123`, `0123.01_23 = 123.0123`, + `1e-1000000000 = 0`, + `1e+1000000000 = ?`, + `6e5518446744 = ?`, + `-6e5518446744 = ?`, + // hexadecimal floats `0x0.p+0 = 0.`, `0Xdeadcafe.p-10 = 0xdeadcafe/1024`, @@ -117,6 +123,11 @@ var imagTests = []string{ `0.e+1i = 0i`, `123.E-1_0i = 123e-10i`, `01_23.e123i = 123e123i`, + + `1e-1000000000i = 0i`, + `1e+1000000000i = ?`, + `6e5518446744i = ?`, + `-6e5518446744i = ?`, } func testNumbers(t *testing.T, kind token.Token, tests []string) { @@ -129,21 +140,32 @@ func testNumbers(t *testing.T, kind token.Token, tests []string) { x := MakeFromLiteral(a[0], kind, 0) var y Value - if i := strings.Index(a[1], "/"); i >= 0 && kind == token.FLOAT { - n := MakeFromLiteral(a[1][:i], token.INT, 0) - d := MakeFromLiteral(a[1][i+1:], token.INT, 0) - y = BinaryOp(n, token.QUO, d) + if a[1] == "?" { + y = MakeUnknown() } else { - y = MakeFromLiteral(a[1], kind, 0) + if i := strings.Index(a[1], "/"); i >= 0 && kind == token.FLOAT { + n := MakeFromLiteral(a[1][:i], token.INT, 0) + d := MakeFromLiteral(a[1][i+1:], token.INT, 0) + y = BinaryOp(n, token.QUO, d) + } else { + y = MakeFromLiteral(a[1], kind, 0) + } + if y.Kind() == Unknown { + panic(fmt.Sprintf("invalid test case: %s %d", test, y.Kind())) + } } xk := x.Kind() yk := y.Kind() - if xk != yk || xk == Unknown { + if xk != yk { t.Errorf("%s: got kind %d != %d", test, xk, yk) continue } + if yk == Unknown { + continue + } + if !Compare(x, token.EQL, y) { t.Errorf("%s: %s != %s", test, x, y) } @@ -200,6 +222,7 @@ var opTests = []string{ `1i * 1i = -1`, `? * 0 = ?`, `0 * ? = ?`, + `0 * 1e+1000000000 = ?`, `0 / 0 = "division_by_zero"`, `10 / 2 = 5`, @@ -207,6 +230,7 @@ var opTests = []string{ `5i / 3i = 5/3`, `? / 0 = ?`, `0 / ? = ?`, + `0 * 1e+1000000000i = ?`, `0 % 0 = "runtime_error:_integer_divide_by_zero"`, // TODO(gri) should be the same as for / `10 % 3 = 1`, @@ -597,18 +621,68 @@ func TestUnknown(t *testing.T) { } } +func TestMakeFloat64(t *testing.T) { + var zero float64 + for _, arg := range []float64{ + -math.MaxFloat32, + -10, + -0.5, + -zero, + zero, + 1, + 10, + 123456789.87654321e-23, + 1e10, + math.MaxFloat64, + } { + val := MakeFloat64(arg) + if val.Kind() != Float { + t.Errorf("%v: got kind = %d; want %d", arg, val.Kind(), Float) + } + + // -0.0 is mapped to 0.0 + got, exact := Float64Val(val) + if !exact || math.Float64bits(got) != math.Float64bits(arg+0) { + t.Errorf("%v: got %v (exact = %v)", arg, got, exact) + } + } + + // infinity + for sign := range []int{-1, 1} { + arg := math.Inf(sign) + val := MakeFloat64(arg) + if val.Kind() != Unknown { + t.Errorf("%v: got kind = %d; want %d", arg, val.Kind(), Unknown) + } + } +} + +type makeTestCase struct { + kind Kind + arg, want interface{} +} + +func dup(k Kind, x interface{}) makeTestCase { return makeTestCase{k, x, x} } + func TestMake(t *testing.T) { - for _, want := range []interface{}{ - false, - "hello", - int64(1), - big.NewInt(10), - big.NewFloat(2.0), - big.NewRat(1, 3), + for _, test := range []makeTestCase{ + {Bool, false, false}, + {String, "hello", "hello"}, + + {Int, int64(1), int64(1)}, + {Int, big.NewInt(10), int64(10)}, + {Int, new(big.Int).Lsh(big.NewInt(1), 62), int64(1 << 62)}, + dup(Int, new(big.Int).Lsh(big.NewInt(1), 63)), + + {Float, big.NewFloat(0), floatVal0.val}, + dup(Float, big.NewFloat(2.0)), + dup(Float, big.NewRat(1, 3)), } { - got := Val(Make(want)) - if got != want { - t.Errorf("got %v; want %v", got, want) + val := Make(test.arg) + got := Val(val) + if val.Kind() != test.kind || got != test.want { + t.Errorf("got %v (%T, kind = %d); want %v (%T, kind = %d)", + got, got, val.Kind(), test.want, test.want, test.kind) } } } diff --git a/libgo/go/go/doc/comment.go b/libgo/go/go/doc/comment.go index da33f21612f..92131a3b83f 100644 --- a/libgo/go/go/doc/comment.go +++ b/libgo/go/go/doc/comment.go @@ -487,7 +487,7 @@ func (l *lineWrapper) write(text string) { l.out.Write(nl) l.n = 0 l.pendSpace = 0 - needsPrefix = isComment + needsPrefix = isComment && !strings.HasPrefix(f, "//") } if l.n == 0 { l.out.Write([]byte(l.indent)) diff --git a/libgo/go/go/doc/comment_test.go b/libgo/go/go/doc/comment_test.go index 101f4462878..6d1b209e1e1 100644 --- a/libgo/go/go/doc/comment_test.go +++ b/libgo/go/go/doc/comment_test.go @@ -152,6 +152,17 @@ A very long line of 46 char for line wrapping. */`, text: `. /* A very long line of 46 char for line . wrapping. A very long line of 46 char . for line wrapping. */ +`, + }, + { + in: `A line of 36 char for line wrapping. +//Another line starting with //`, + out: []block{ + {opPara, []string{"A line of 36 char for line wrapping.\n", + "//Another line starting with //"}}, + }, + text: `. A line of 36 char for line wrapping. +. //Another line starting with // `, }, } diff --git a/libgo/go/go/doc/doc_test.go b/libgo/go/go/doc/doc_test.go index f1e612c18bf..cbdca62aa1d 100644 --- a/libgo/go/go/doc/doc_test.go +++ b/libgo/go/go/doc/doc_test.go @@ -12,7 +12,7 @@ import ( "go/parser" "go/printer" "go/token" - "io/ioutil" + "io/fs" "os" "path/filepath" "regexp" @@ -66,7 +66,7 @@ func indentFmt(indent, s string) string { return indent + strings.ReplaceAll(s, "\n", "\n"+indent) + end } -func isGoFile(fi os.FileInfo) bool { +func isGoFile(fi fs.FileInfo) bool { name := fi.Name() return !fi.IsDir() && len(name) > 0 && name[0] != '.' && // ignore .files @@ -86,7 +86,7 @@ func test(t *testing.T, mode Mode) { if err != nil { t.Fatal(err) } - filter = func(fi os.FileInfo) bool { + filter = func(fi fs.FileInfo) bool { return isGoFile(fi) && rx.MatchString(fi.Name()) } } @@ -127,7 +127,7 @@ func test(t *testing.T, mode Mode) { // update golden file if necessary golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode)) if *update { - err := ioutil.WriteFile(golden, got, 0644) + err := os.WriteFile(golden, got, 0644) if err != nil { t.Error(err) } @@ -135,7 +135,7 @@ func test(t *testing.T, mode Mode) { } // get golden file - want, err := ioutil.ReadFile(golden) + want, err := os.ReadFile(golden) if err != nil { t.Error(err) continue diff --git a/libgo/go/go/doc/example.go b/libgo/go/go/doc/example.go index ebf81189b5b..125fd530b13 100644 --- a/libgo/go/go/doc/example.go +++ b/libgo/go/go/doc/example.go @@ -486,7 +486,7 @@ func classifyExamples(p *Package, examples []*Example) { ids[f.Name] = &f.Examples } for _, m := range t.Methods { - if !token.IsExported(m.Name) || m.Level != 0 { // avoid forwarded methods from embedding + if !token.IsExported(m.Name) { continue } ids[strings.TrimPrefix(m.Recv, "*")+"_"+m.Name] = &m.Examples diff --git a/libgo/go/go/doc/example_test.go b/libgo/go/go/doc/example_test.go index 32db3cd7da7..7c96f0300a8 100644 --- a/libgo/go/go/doc/example_test.go +++ b/libgo/go/go/doc/example_test.go @@ -563,6 +563,7 @@ type ( type2 int Embed struct { Type1 } + Uembed struct { type2 } ) func Func1() {} @@ -575,6 +576,8 @@ func (Type1) Func1_Foo() {} func (Type1) Func1_foo() {} func (Type1) func2() {} +func (type2) Func1() {} + type ( Conflict int Conflict_Conflict int @@ -633,7 +636,9 @@ 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 ExampleEmbed_Func1() {} // invalid - no support for forwarded methods from embedding exported type +func ExampleUembed_Func1() {} // methods from embedding unexported types are OK +func ExampleUembed_Func1_suffix() {} func ExampleConflict_Conflict() {} // ambiguous with either Conflict or Conflict_Conflict type func ExampleConflict_conflict() {} // ambiguous with either Conflict or Conflict_conflict type @@ -683,6 +688,8 @@ func ExampleConflict_conflict_suffix() {} // ambiguous with either Conflict or C "Type1.Func1_Foo": {"", "suffix"}, "Type1.Func1_foo": {"", "suffix"}, + "Uembed.Func1": {"", "suffix"}, + // These are implementation dependent due to the ambiguous parsing. "Conflict_Conflict": {"", "suffix"}, "Conflict_conflict": {"", "suffix"}, diff --git a/libgo/go/go/doc/headscan.go b/libgo/go/go/doc/headscan.go index 3f782cc1b4b..fe26a0ea842 100644 --- a/libgo/go/go/doc/headscan.go +++ b/libgo/go/go/doc/headscan.go @@ -23,6 +23,7 @@ import ( "go/parser" "go/token" "internal/lazyregexp" + "io/fs" "os" "path/filepath" "runtime" @@ -39,7 +40,7 @@ var html_h = lazyregexp.New(`

`) const html_endh = "

\n" -func isGoFile(fi os.FileInfo) bool { +func isGoFile(fi fs.FileInfo) bool { return strings.HasSuffix(fi.Name(), ".go") && !strings.HasSuffix(fi.Name(), "_test.go") } @@ -68,8 +69,8 @@ func main() { flag.Parse() fset := token.NewFileSet() nheadings := 0 - err := filepath.Walk(*root, func(path string, fi os.FileInfo, err error) error { - if !fi.IsDir() { + err := filepath.WalkDir(*root, func(path string, info fs.DirEntry, err error) error { + if !info.IsDir() { return nil } pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments) diff --git a/libgo/go/go/format/benchmark_test.go b/libgo/go/go/format/benchmark_test.go index 7bd45c0e95b..ac19aa3bf5d 100644 --- a/libgo/go/go/format/benchmark_test.go +++ b/libgo/go/go/format/benchmark_test.go @@ -12,7 +12,7 @@ import ( "flag" "fmt" "go/format" - "io/ioutil" + "os" "testing" ) @@ -67,7 +67,7 @@ func BenchmarkFormat(b *testing.B) { if *debug { filename := t.name + ".src" - err := ioutil.WriteFile(filename, data, 0660) + err := os.WriteFile(filename, data, 0660) if err != nil { b.Fatalf("couldn't write %s: %v", filename, err) } diff --git a/libgo/go/go/format/format_test.go b/libgo/go/go/format/format_test.go index 58e088ede31..27f4c74cdf9 100644 --- a/libgo/go/go/format/format_test.go +++ b/libgo/go/go/format/format_test.go @@ -9,7 +9,7 @@ import ( "go/ast" "go/parser" "go/token" - "io/ioutil" + "os" "strings" "testing" ) @@ -38,7 +38,7 @@ func diff(t *testing.T, dst, src []byte) { } func TestNode(t *testing.T) { - src, err := ioutil.ReadFile(testfile) + src, err := os.ReadFile(testfile) if err != nil { t.Fatal(err) } @@ -96,7 +96,7 @@ func TestNodeNoModify(t *testing.T) { } func TestSource(t *testing.T) { - src, err := ioutil.ReadFile(testfile) + src, err := os.ReadFile(testfile) if err != nil { t.Fatal(err) } diff --git a/libgo/go/go/importer/importer_test.go b/libgo/go/go/importer/importer_test.go index ff6e12c0da5..0f5121d8021 100644 --- a/libgo/go/go/importer/importer_test.go +++ b/libgo/go/go/importer/importer_test.go @@ -8,7 +8,6 @@ import ( "go/token" "internal/testenv" "io" - "io/ioutil" "os" "os/exec" "runtime" @@ -52,7 +51,7 @@ func TestForCompiler(t *testing.T) { mathBigInt := pkg.Scope().Lookup("Int") posn := fset.Position(mathBigInt.Pos()) // "$GOROOT/src/math/big/int.go:25:1" filename := strings.Replace(posn.Filename, "$GOROOT", runtime.GOROOT(), 1) - data, err := ioutil.ReadFile(filename) + data, err := os.ReadFile(filename) if err != nil { t.Fatalf("can't read file containing declaration of math/big.Int: %v", err) } diff --git a/libgo/go/go/internal/gccgoimporter/importer.go b/libgo/go/go/internal/gccgoimporter/importer.go index 391477d5a73..1570a1c0680 100644 --- a/libgo/go/go/internal/gccgoimporter/importer.go +++ b/libgo/go/go/internal/gccgoimporter/importer.go @@ -221,7 +221,7 @@ func GetImporter(searchpaths []string, initmap map[*types.Package]InitData) Impo // Excluded for now: Standard gccgo doesn't support this import format currently. // case goimporterMagic: // var data []byte - // data, err = ioutil.ReadAll(reader) + // data, err = io.ReadAll(reader) // if err != nil { // return // } diff --git a/libgo/go/go/internal/gccgoimporter/importer_test.go b/libgo/go/go/internal/gccgoimporter/importer_test.go index a74a4568680..35240c8fe68 100644 --- a/libgo/go/go/internal/gccgoimporter/importer_test.go +++ b/libgo/go/go/internal/gccgoimporter/importer_test.go @@ -7,7 +7,6 @@ package gccgoimporter import ( "go/types" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -97,6 +96,7 @@ var importerTests = [...]importerTest{ {pkgpath: "issue30628", name: "Apple", want: "type Apple struct{hey sync.RWMutex; x int; RQ [517]struct{Count uintptr; NumBytes uintptr; Last uintptr}}"}, {pkgpath: "issue31540", name: "S", gccgoVersion: 7, want: "type S struct{b int; map[Y]Z}"}, {pkgpath: "issue34182", name: "T1", want: "type T1 struct{f *T2}"}, + {pkgpath: "notinheap", name: "S", want: "type S struct{}"}, } func TestGoxImporter(t *testing.T) { @@ -149,7 +149,7 @@ func TestObjImporter(t *testing.T) { } t.Logf("gccgo version %d.%d", major, minor) - tmpdir, err := ioutil.TempDir("", "TestObjImporter") + tmpdir, err := os.MkdirTemp("", "TestObjImporter") if err != nil { t.Fatal(err) } @@ -158,7 +158,7 @@ func TestObjImporter(t *testing.T) { initmap := make(map[*types.Package]InitData) imp := GetImporter([]string{tmpdir}, initmap) - artmpdir, err := ioutil.TempDir("", "TestObjImporter") + artmpdir, err := os.MkdirTemp("", "TestObjImporter") if err != nil { t.Fatal(err) } diff --git a/libgo/go/go/internal/gccgoimporter/testdata/notinheap.go b/libgo/go/go/internal/gccgoimporter/testdata/notinheap.go new file mode 100644 index 00000000000..b1ac967227b --- /dev/null +++ b/libgo/go/go/internal/gccgoimporter/testdata/notinheap.go @@ -0,0 +1,4 @@ +package notinheap + +//go:notinheap +type S struct{} diff --git a/libgo/go/go/internal/gccgoimporter/testdata/notinheap.gox b/libgo/go/go/internal/gccgoimporter/testdata/notinheap.gox new file mode 100644 index 00000000000..cc438e75e0b --- /dev/null +++ b/libgo/go/go/internal/gccgoimporter/testdata/notinheap.gox @@ -0,0 +1,7 @@ +v3; +package notinheap +pkgpath notinheap +init notinheap ~notinheap +types 3 2 30 18 +type 1 "S" notinheap +type 2 struct { } diff --git a/libgo/go/go/internal/gcimporter/gcimporter.go b/libgo/go/go/internal/gcimporter/gcimporter.go index fda15eaaaed..b74daca2463 100644 --- a/libgo/go/go/internal/gcimporter/gcimporter.go +++ b/libgo/go/go/internal/gcimporter/gcimporter.go @@ -12,7 +12,6 @@ import ( "go/token" "go/types" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -147,7 +146,7 @@ func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDi case "$$B\n": var data []byte - data, err = ioutil.ReadAll(buf) + data, err = io.ReadAll(buf) if err != nil { break } diff --git a/libgo/go/go/internal/gcimporter/gcimporter_test.go b/libgo/go/go/internal/gcimporter/gcimporter_test.go index 663753a18a0..3c76aafde39 100644 --- a/libgo/go/go/internal/gcimporter/gcimporter_test.go +++ b/libgo/go/go/internal/gcimporter/gcimporter_test.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "internal/testenv" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -66,7 +65,7 @@ const maxTime = 30 * time.Second func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) { dirname := filepath.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH, dir) - list, err := ioutil.ReadDir(dirname) + list, err := os.ReadDir(dirname) if err != nil { t.Fatalf("testDir(%s): %s", dirname, err) } @@ -94,7 +93,7 @@ func testDir(t *testing.T, dir string, endTime time.Time) (nimports int) { } func mktmpdir(t *testing.T) string { - tmpdir, err := ioutil.TempDir("", "gcimporter_test") + tmpdir, err := os.MkdirTemp("", "gcimporter_test") if err != nil { t.Fatal("mktmpdir:", err) } @@ -144,7 +143,7 @@ func TestVersionHandling(t *testing.T) { } const dir = "./testdata/versions" - list, err := ioutil.ReadDir(dir) + list, err := os.ReadDir(dir) if err != nil { t.Fatal(err) } @@ -199,7 +198,7 @@ func TestVersionHandling(t *testing.T) { // create file with corrupted export data // 1) read file - data, err := ioutil.ReadFile(filepath.Join(dir, name)) + data, err := os.ReadFile(filepath.Join(dir, name)) if err != nil { t.Fatal(err) } @@ -216,7 +215,7 @@ func TestVersionHandling(t *testing.T) { // 4) write the file pkgpath += "_corrupted" filename := filepath.Join(corruptdir, pkgpath) + ".a" - ioutil.WriteFile(filename, data, 0666) + os.WriteFile(filename, data, 0666) // test that importing the corrupted file results in an error _, err = Import(fset, make(map[string]*types.Package), pkgpath, corruptdir, nil) diff --git a/libgo/go/go/internal/gcimporter/support.go b/libgo/go/go/internal/gcimporter/support.go index 2de7cacd2d9..b8bb14dc490 100644 --- a/libgo/go/go/internal/gcimporter/support.go +++ b/libgo/go/go/internal/gcimporter/support.go @@ -17,7 +17,10 @@ func errorf(format string, args ...interface{}) { panic(fmt.Sprintf(format, args...)) } -const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go +// deltaNewFile is a magic line delta offset indicating a new file. +// We use -64 because it is rare; see issue 20080 and CL 41619. +// -64 is the smallest int that fits in a single byte as a varint. +const deltaNewFile = -64 // Synthesize a token.Pos type fakeFileSet struct { diff --git a/libgo/go/go/internal/srcimporter/srcimporter.go b/libgo/go/go/internal/srcimporter/srcimporter.go index 3a2ca9aba81..d8aae4a80de 100644 --- a/libgo/go/go/internal/srcimporter/srcimporter.go +++ b/libgo/go/go/internal/srcimporter/srcimporter.go @@ -14,7 +14,6 @@ import ( "go/token" "go/types" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -200,7 +199,7 @@ func (p *Importer) parseFiles(dir string, filenames []string) ([]*ast.File, erro } func (p *Importer) cgo(bp *build.Package) (*ast.File, error) { - tmpdir, err := ioutil.TempDir("", "srcimporter") + tmpdir, err := os.MkdirTemp("", "srcimporter") if err != nil { return nil, err } diff --git a/libgo/go/go/internal/srcimporter/srcimporter_test.go b/libgo/go/go/internal/srcimporter/srcimporter_test.go index 102ac43f945..05b12f1636b 100644 --- a/libgo/go/go/internal/srcimporter/srcimporter_test.go +++ b/libgo/go/go/internal/srcimporter/srcimporter_test.go @@ -10,7 +10,6 @@ import ( "go/token" "go/types" "internal/testenv" - "io/ioutil" "os" "path" "path/filepath" @@ -59,7 +58,7 @@ func walkDir(t *testing.T, path string, endTime time.Time) (int, bool) { return 0, false } - list, err := ioutil.ReadDir(filepath.Join(runtime.GOROOT(), "src", path)) + list, err := os.ReadDir(filepath.Join(runtime.GOROOT(), "src", path)) if err != nil { t.Fatalf("walkDir %s failed (%v)", path, err) } diff --git a/libgo/go/go/parser/error_test.go b/libgo/go/go/parser/error_test.go index 9b79097acf6..358a844f65a 100644 --- a/libgo/go/go/parser/error_test.go +++ b/libgo/go/go/parser/error_test.go @@ -25,7 +25,7 @@ package parser import ( "go/scanner" "go/token" - "io/ioutil" + "os" "path/filepath" "regexp" "strings" @@ -174,13 +174,13 @@ func checkErrors(t *testing.T, filename string, input interface{}) { } func TestErrors(t *testing.T) { - list, err := ioutil.ReadDir(testdata) + list, err := os.ReadDir(testdata) if err != nil { t.Fatal(err) } - for _, fi := range list { - name := fi.Name() - if !fi.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".src") { + for _, d := range list { + name := d.Name() + if !d.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".src") { checkErrors(t, filepath.Join(testdata, name), nil) } } diff --git a/libgo/go/go/parser/interface.go b/libgo/go/go/parser/interface.go index 54f9d7b80ac..56ff5fefb4f 100644 --- a/libgo/go/go/parser/interface.go +++ b/libgo/go/go/parser/interface.go @@ -12,7 +12,7 @@ import ( "go/ast" "go/token" "io" - "io/ioutil" + "io/fs" "os" "path/filepath" "strings" @@ -35,11 +35,11 @@ func readSource(filename string, src interface{}) ([]byte, error) { return s.Bytes(), nil } case io.Reader: - return ioutil.ReadAll(s) + return io.ReadAll(s) } return nil, errors.New("invalid source") } - return ioutil.ReadFile(filename) + return os.ReadFile(filename) } // A Mode value is a set of flags (or 0). @@ -123,7 +123,7 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) // directory specified by path and returns a map of package name -> package // AST with all the packages found. // -// If filter != nil, only the files with os.FileInfo entries passing through +// If filter != nil, only the files with fs.FileInfo entries passing through // the filter (and ending in ".go") are considered. The mode bits are passed // to ParseFile unchanged. Position information is recorded in fset, which // must not be nil. @@ -132,30 +132,40 @@ func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) // returned. If a parse error occurred, a non-nil but incomplete map and the // first error encountered are returned. // -func ParseDir(fset *token.FileSet, path string, filter func(os.FileInfo) bool, mode Mode) (pkgs map[string]*ast.Package, first error) { - list, err := ioutil.ReadDir(path) +func ParseDir(fset *token.FileSet, path string, filter func(fs.FileInfo) bool, mode Mode) (pkgs map[string]*ast.Package, first error) { + list, err := os.ReadDir(path) if err != nil { return nil, err } pkgs = make(map[string]*ast.Package) for _, d := range list { - if strings.HasSuffix(d.Name(), ".go") && (filter == nil || filter(d)) { - filename := filepath.Join(path, d.Name()) - if src, err := ParseFile(fset, filename, nil, mode); err == nil { - name := src.Name.Name - pkg, found := pkgs[name] - if !found { - pkg = &ast.Package{ - Name: name, - Files: make(map[string]*ast.File), - } - pkgs[name] = pkg + if d.IsDir() || !strings.HasSuffix(d.Name(), ".go") { + continue + } + if filter != nil { + info, err := d.Info() + if err != nil { + return nil, err + } + if !filter(info) { + continue + } + } + filename := filepath.Join(path, d.Name()) + if src, err := ParseFile(fset, filename, nil, mode); err == nil { + name := src.Name.Name + pkg, found := pkgs[name] + if !found { + pkg = &ast.Package{ + Name: name, + Files: make(map[string]*ast.File), } - pkg.Files[filename] = src - } else if first == nil { - first = err + pkgs[name] = pkg } + pkg.Files[filename] = src + } else if first == nil { + first = err } } diff --git a/libgo/go/go/parser/parser_test.go b/libgo/go/go/parser/parser_test.go index 25a374eeefc..a4f882d3688 100644 --- a/libgo/go/go/parser/parser_test.go +++ b/libgo/go/go/parser/parser_test.go @@ -9,7 +9,7 @@ import ( "fmt" "go/ast" "go/token" - "os" + "io/fs" "strings" "testing" ) @@ -40,7 +40,7 @@ func nameFilter(filename string) bool { return false } -func dirFilter(f os.FileInfo) bool { return nameFilter(f.Name()) } +func dirFilter(f fs.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[::]" @@ -82,6 +82,14 @@ func TestParseDir(t *testing.T) { } } +func TestIssue42951(t *testing.T) { + path := "./testdata/issue42951" + _, err := ParseDir(token.NewFileSet(), path, nil, 0) + if err != nil { + t.Errorf("ParseDir(%s): %v", path, err) + } +} + func TestParseExpr(t *testing.T) { // just kicking the tires: // a valid arithmetic expression diff --git a/libgo/go/go/parser/performance_test.go b/libgo/go/go/parser/performance_test.go index f2732c0e2b1..f81bcee969b 100644 --- a/libgo/go/go/parser/performance_test.go +++ b/libgo/go/go/parser/performance_test.go @@ -6,14 +6,14 @@ package parser import ( "go/token" - "io/ioutil" + "os" "testing" ) var src = readFile("parser.go") func readFile(filename string) []byte { - data, err := ioutil.ReadFile(filename) + data, err := os.ReadFile(filename) if err != nil { panic(err) } diff --git a/libgo/go/go/parser/testdata/issue42951/not_a_file.go/invalid.go b/libgo/go/go/parser/testdata/issue42951/not_a_file.go/invalid.go new file mode 100644 index 00000000000..bb698be11cd --- /dev/null +++ b/libgo/go/go/parser/testdata/issue42951/not_a_file.go/invalid.go @@ -0,0 +1 @@ +This file should not be parsed by ParseDir. diff --git a/libgo/go/go/printer/performance_test.go b/libgo/go/go/printer/performance_test.go index 2e67154e6b4..e655fa13ee3 100644 --- a/libgo/go/go/printer/performance_test.go +++ b/libgo/go/go/printer/performance_test.go @@ -12,8 +12,8 @@ import ( "go/ast" "go/parser" "io" - "io/ioutil" "log" + "os" "testing" ) @@ -29,7 +29,7 @@ func testprint(out io.Writer, file *ast.File) { func initialize() { const filename = "testdata/parser.go" - src, err := ioutil.ReadFile(filename) + src, err := os.ReadFile(filename) if err != nil { log.Fatalf("%s", err) } @@ -53,6 +53,6 @@ func BenchmarkPrint(b *testing.B) { initialize() } for i := 0; i < b.N; i++ { - testprint(ioutil.Discard, testfile) + testprint(io.Discard, testfile) } } diff --git a/libgo/go/go/printer/printer_test.go b/libgo/go/go/printer/printer_test.go index b64bc6bfb7d..45e501115ac 100644 --- a/libgo/go/go/printer/printer_test.go +++ b/libgo/go/go/printer/printer_test.go @@ -13,7 +13,7 @@ import ( "go/parser" "go/token" "io" - "io/ioutil" + "os" "path/filepath" "testing" "time" @@ -119,7 +119,7 @@ func diff(aname, bname string, a, b []byte) error { } func runcheck(t *testing.T, source, golden string, mode checkMode) { - src, err := ioutil.ReadFile(source) + src, err := os.ReadFile(source) if err != nil { t.Error(err) return @@ -133,14 +133,14 @@ func runcheck(t *testing.T, source, golden string, mode checkMode) { // update golden files if necessary if *update { - if err := ioutil.WriteFile(golden, res, 0644); err != nil { + if err := os.WriteFile(golden, res, 0644); err != nil { t.Error(err) } return } // get golden - gld, err := ioutil.ReadFile(golden) + gld, err := os.ReadFile(golden) if err != nil { t.Error(err) return @@ -552,7 +552,7 @@ func TestBaseIndent(t *testing.T) { // are not indented (because their values must not change) and make // this test fail. const filename = "printer.go" - src, err := ioutil.ReadFile(filename) + src, err := os.ReadFile(filename) if err != nil { panic(err) // error in test } @@ -639,7 +639,7 @@ func (l *limitWriter) Write(buf []byte) (n int, err error) { func TestWriteErrors(t *testing.T) { t.Parallel() const filename = "printer.go" - src, err := ioutil.ReadFile(filename) + src, err := os.ReadFile(filename) if err != nil { panic(err) // error in test } diff --git a/libgo/go/go/scanner/scanner_test.go b/libgo/go/go/scanner/scanner_test.go index 9d3bbbbb24e..ab4c2dd9623 100644 --- a/libgo/go/go/scanner/scanner_test.go +++ b/libgo/go/go/scanner/scanner_test.go @@ -6,7 +6,6 @@ package scanner import ( "go/token" - "io/ioutil" "os" "path/filepath" "runtime" @@ -893,7 +892,7 @@ func BenchmarkScan(b *testing.B) { func BenchmarkScanFile(b *testing.B) { b.StopTimer() const filename = "scanner.go" - src, err := ioutil.ReadFile(filename) + src, err := os.ReadFile(filename) if err != nil { panic(err) } diff --git a/libgo/go/go/token/position.go b/libgo/go/go/token/position.go index d0dbc2998f7..a21f5fd0560 100644 --- a/libgo/go/go/token/position.go +++ b/libgo/go/go/token/position.go @@ -150,12 +150,12 @@ func (f *File) AddLine(offset int) { // func (f *File) MergeLine(line int) { if line < 1 { - panic("illegal line number (line numbering starts at 1)") + panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line)) } f.mutex.Lock() defer f.mutex.Unlock() if line >= len(f.lines) { - panic("illegal line number") + panic(fmt.Sprintf("invalid line number %d (should be < %d)", line, len(f.lines))) } // To merge the line numbered with the line numbered , // we need to remove the entry in lines corresponding to the line @@ -217,12 +217,12 @@ func (f *File) SetLinesForContent(content []byte) { // LineStart panics if the 1-based line number is invalid. func (f *File) LineStart(line int) Pos { if line < 1 { - panic("illegal line number (line numbering starts at 1)") + panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line)) } f.mutex.Lock() defer f.mutex.Unlock() if line > len(f.lines) { - panic("illegal line number") + panic(fmt.Sprintf("invalid line number %d (should be < %d)", line, len(f.lines))) } return Pos(f.base + f.lines[line-1]) } @@ -267,7 +267,7 @@ func (f *File) AddLineColumnInfo(offset int, filename string, line, column int) // func (f *File) Pos(offset int) Pos { if offset > f.size { - panic("illegal file offset") + panic(fmt.Sprintf("invalid file offset %d (should be <= %d)", offset, f.size)) } return Pos(f.base + offset) } @@ -278,7 +278,7 @@ func (f *File) Pos(offset int) Pos { // func (f *File) Offset(p Pos) int { if int(p) < f.base || int(p) > f.base+f.size { - panic("illegal Pos value") + panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d[)", p, f.base, f.base+f.size)) } return int(p) - f.base } @@ -346,7 +346,7 @@ func (f *File) position(p Pos, adjusted bool) (pos Position) { func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) { if p != NoPos { if int(p) < f.base || int(p) > f.base+f.size { - panic("illegal Pos value") + panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d[)", p, f.base, f.base+f.size)) } pos = f.position(p, adjusted) } @@ -430,8 +430,11 @@ func (s *FileSet) AddFile(filename string, base, size int) *File { if base < 0 { base = s.base } - if base < s.base || size < 0 { - panic("illegal base or size") + if base < s.base { + panic(fmt.Sprintf("invalid base %d (should be >= %d)", base, s.base)) + } + if size < 0 { + panic(fmt.Sprintf("invalid size %d (should be >= 0)", size)) } // base >= s.base && size >= 0 f := &File{set: s, name: filename, base: base, size: size, lines: []int{0}} diff --git a/libgo/go/go/types/api.go b/libgo/go/go/types/api.go index 2e2e08dce62..acd1899c39d 100644 --- a/libgo/go/go/types/api.go +++ b/libgo/go/go/types/api.go @@ -44,6 +44,15 @@ type Error struct { Pos token.Pos // error position Msg string // error message Soft bool // if set, error is "soft" + + // go116code is a future API, unexported as the set of error codes is large + // and likely to change significantly during experimentation. Tools wishing + // to preview this feature may read go116code using reflection (see + // errorcodes_test.go), but beware that there is no guarantee of future + // compatibility. + go116code errorCode + go116start token.Pos + go116end token.Pos } // Error returns an error string formatted as follows: @@ -372,7 +381,8 @@ func AssertableTo(V *Interface, T Type) bool { // AssignableTo reports whether a value of type V is assignable to a variable of type T. func AssignableTo(V, T Type) bool { x := operand{mode: value, typ: V} - return x.assignableTo(nil, T, nil) // check not needed for non-constant x + ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x + return ok } // ConvertibleTo reports whether a value of type V is convertible to a value of type T. diff --git a/libgo/go/go/types/api_test.go b/libgo/go/go/types/api_test.go index 36296125414..ea1ae1ea54b 100644 --- a/libgo/go/go/types/api_test.go +++ b/libgo/go/go/types/api_test.go @@ -1234,6 +1234,50 @@ func F(){ } } +func TestConvertibleTo(t *testing.T) { + for _, test := range []struct { + v, t Type + want bool + }{ + {Typ[Int], Typ[Int], true}, + {Typ[Int], Typ[Float32], true}, + {newDefined(Typ[Int]), Typ[Int], true}, + {newDefined(new(Struct)), new(Struct), true}, + {newDefined(Typ[Int]), new(Struct), false}, + {Typ[UntypedInt], Typ[Int], true}, + // Untyped string values are not permitted by the spec, so the below + // behavior is undefined. + {Typ[UntypedString], Typ[String], true}, + } { + if got := ConvertibleTo(test.v, test.t); got != test.want { + t.Errorf("ConvertibleTo(%v, %v) = %t, want %t", test.v, test.t, got, test.want) + } + } +} + +func TestAssignableTo(t *testing.T) { + for _, test := range []struct { + v, t Type + want bool + }{ + {Typ[Int], Typ[Int], true}, + {Typ[Int], Typ[Float32], false}, + {newDefined(Typ[Int]), Typ[Int], false}, + {newDefined(new(Struct)), new(Struct), true}, + {Typ[UntypedBool], Typ[Bool], true}, + {Typ[UntypedString], Typ[Bool], false}, + // Neither untyped string nor untyped numeric assignments arise during + // normal type checking, so the below behavior is technically undefined by + // the spec. + {Typ[UntypedString], Typ[String], true}, + {Typ[UntypedInt], Typ[Int], true}, + } { + if got := AssignableTo(test.v, test.t); got != test.want { + t.Errorf("AssignableTo(%v, %v) = %t, want %t", test.v, test.t, got, test.want) + } + } +} + func TestIdentical_issue15173(t *testing.T) { // Identical should allow nil arguments and be symmetric. for _, test := range []struct { diff --git a/libgo/go/go/types/assignments.go b/libgo/go/go/types/assignments.go index 34a9d7843d9..616564b567d 100644 --- a/libgo/go/go/types/assignments.go +++ b/libgo/go/go/types/assignments.go @@ -7,6 +7,7 @@ package types import ( + "errors" "go/ast" "go/token" ) @@ -33,18 +34,33 @@ func (check *Checker) assignment(x *operand, T Type, context string) { // spec: "If an untyped constant is assigned to a variable of interface // type or the blank identifier, the constant is first converted to type // bool, rune, int, float64, complex128 or string respectively, depending - // on whether the value is a boolean, rune, integer, floating-point, complex, - // or string constant." + // on whether the value is a boolean, rune, integer, floating-point, + // complex, or string constant." if T == nil || IsInterface(T) { if T == nil && x.typ == Typ[UntypedNil] { - check.errorf(x.pos(), "use of untyped nil in %s", context) + check.errorf(x, _UntypedNil, "use of untyped nil in %s", context) x.mode = invalid return } target = Default(x.typ) } - check.convertUntyped(x, target) - if x.mode == invalid { + if err := check.canConvertUntyped(x, target); err != nil { + msg := check.sprintf("cannot use %s as %s value in %s", x, target, context) + code := _IncompatibleAssign + var ierr Error + if errors.As(err, &ierr) { + // Preserve these inner errors, as they are informative. + switch ierr.go116code { + case _TruncatedFloat: + msg += " (truncated)" + code = ierr.go116code + case _NumericOverflow: + msg += " (overflows)" + code = ierr.go116code + } + } + check.error(x, code, msg) + x.mode = invalid return } } @@ -57,11 +73,12 @@ func (check *Checker) assignment(x *operand, T Type, context string) { return } - if reason := ""; !x.assignableTo(check, T, &reason) { + reason := "" + if ok, code := x.assignableTo(check, T, &reason); !ok { if reason != "" { - check.errorf(x.pos(), "cannot use %s as %s value in %s: %s", x, T, context, reason) + check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, reason) } else { - check.errorf(x.pos(), "cannot use %s as %s value in %s", x, T, context) + check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context) } x.mode = invalid } @@ -77,7 +94,7 @@ func (check *Checker) initConst(lhs *Const, x *operand) { // rhs must be a constant if x.mode != constant_ { - check.errorf(x.pos(), "%s is not constant", x) + check.errorf(x, _InvalidConstInit, "%s is not constant", x) if lhs.typ == nil { lhs.typ = Typ[Invalid] } @@ -112,7 +129,7 @@ func (check *Checker) initVar(lhs *Var, x *operand, context string) Type { if isUntyped(typ) { // convert untyped types to default types if typ == Typ[UntypedNil] { - check.errorf(x.pos(), "use of untyped nil in %s", context) + check.errorf(x, _UntypedNil, "use of untyped nil in %s", context) lhs.typ = Typ[Invalid] return nil } @@ -186,11 +203,11 @@ func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type { var op operand check.expr(&op, sel.X) if op.mode == mapindex { - check.errorf(z.pos(), "cannot assign to struct field %s in map", ExprString(z.expr)) + check.errorf(&z, _UnaddressableFieldAssign, "cannot assign to struct field %s in map", ExprString(z.expr)) return nil } } - check.errorf(z.pos(), "cannot assign to %s", &z) + check.errorf(&z, _UnassignableOperand, "cannot assign to %s", &z) return nil } @@ -219,10 +236,10 @@ func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) } check.useGetter(get, r) if returnPos.IsValid() { - check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r) + check.errorf(atPos(returnPos), _WrongResultCount, "wrong number of return values (want %d, got %d)", l, r) return } - check.errorf(rhs[0].Pos(), "cannot initialize %d variables with %d values", l, r) + check.errorf(rhs[0], _WrongAssignCount, "cannot initialize %d variables with %d values", l, r) return } @@ -257,7 +274,7 @@ func (check *Checker) assignVars(lhs, rhs []ast.Expr) { } if l != r { check.useGetter(get, r) - check.errorf(rhs[0].Pos(), "cannot assign %d values to %d variables", r, l) + check.errorf(rhs[0], _WrongAssignCount, "cannot assign %d values to %d variables", r, l) return } @@ -278,7 +295,7 @@ func (check *Checker) assignVars(lhs, rhs []ast.Expr) { } } -func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) { +func (check *Checker) shortVarDecl(pos positioner, lhs, rhs []ast.Expr) { top := len(check.delayed) scope := check.scope @@ -298,7 +315,7 @@ func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) { if alt, _ := alt.(*Var); alt != nil { obj = alt } else { - check.errorf(lhs.Pos(), "cannot assign to %s", lhs) + check.errorf(lhs, _UnassignableOperand, "cannot assign to %s", lhs) } check.recordUse(ident, alt) } else { @@ -311,7 +328,7 @@ func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) { } } else { check.useLHS(lhs) - check.errorf(lhs.Pos(), "cannot declare %s", lhs) + check.invalidAST(lhs, "cannot declare %s", lhs) } if obj == nil { obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable @@ -335,6 +352,6 @@ func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) { check.declare(scope, nil, obj, scopePos) // recordObject already called } } else { - check.softErrorf(pos, "no new variables on left side of :=") + check.softErrorf(pos, _NoNewVar, "no new variables on left side of :=") } } diff --git a/libgo/go/go/types/builtins.go b/libgo/go/go/types/builtins.go index a445ebf1c6b..fd35f786769 100644 --- a/libgo/go/go/types/builtins.go +++ b/libgo/go/go/types/builtins.go @@ -21,7 +21,9 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // append is the only built-in that permits the use of ... for the last argument bin := predeclaredFuncs[id] if call.Ellipsis.IsValid() && id != _Append { - check.invalidOp(call.Ellipsis, "invalid use of ... with built-in %s", bin.name) + check.invalidOp(atPos(call.Ellipsis), + _InvalidDotDotDot, + "invalid use of ... with built-in %s", bin.name) check.use(call.Args...) return } @@ -68,7 +70,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b msg = "too many" } if msg != "" { - check.invalidOp(call.Rparen, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs) + check.invalidOp(inNode(call, call.Rparen), _WrongArgCount, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs) return } } @@ -85,7 +87,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b if s, _ := S.Underlying().(*Slice); s != nil { T = s.elem } else { - check.invalidArg(x.pos(), "%s is not a slice", x) + check.invalidArg(x, _InvalidAppend, "%s is not a slice", x) return } @@ -95,23 +97,25 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // spec: "As a special case, append also accepts a first argument assignable // to type []byte with a second argument of string type followed by ... . // This form appends the bytes of the string. - if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check, NewSlice(universeByte), nil) { - arg(x, 1) - if x.mode == invalid { - return - } - if isString(x.typ) { - if check.Types != nil { - sig := makeSig(S, S, x.typ) - sig.variadic = true - check.recordBuiltinType(call.Fun, sig) + if nargs == 2 && call.Ellipsis.IsValid() { + if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok { + arg(x, 1) + if x.mode == invalid { + return } - x.mode = value - x.typ = S - break + if isString(x.typ) { + if check.Types != nil { + sig := makeSig(S, S, x.typ) + sig.variadic = true + check.recordBuiltinType(call.Fun, sig) + } + x.mode = value + x.typ = S + break + } + alist = append(alist, *x) + // fallthrough } - alist = append(alist, *x) - // fallthrough } // check general case by creating custom signature @@ -175,7 +179,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b } if mode == invalid && typ != Typ[Invalid] { - check.invalidArg(x.pos(), "%s for %s", x, bin.name) + code := _InvalidCap + if id == _Len { + code = _InvalidLen + } + check.invalidArg(x, code, "%s for %s", x, bin.name) return } @@ -190,11 +198,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // close(c) c, _ := x.typ.Underlying().(*Chan) if c == nil { - check.invalidArg(x.pos(), "%s is not a channel", x) + check.invalidArg(x, _InvalidClose, "%s is not a channel", x) return } if c.dir == RecvOnly { - check.invalidArg(x.pos(), "%s must not be a receive-only channel", x) + check.invalidArg(x, _InvalidClose, "%s must not be a receive-only channel", x) return } @@ -258,13 +266,13 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // both argument types must be identical if !check.identical(x.typ, y.typ) { - check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ) + check.invalidArg(x, _InvalidComplex, "mismatched types %s and %s", x.typ, y.typ) return } // the argument types must be of floating-point type if !isFloat(x.typ) { - check.invalidArg(x.pos(), "arguments have type %s, expected floating-point", x.typ) + check.invalidArg(x, _InvalidComplex, "arguments have type %s, expected floating-point", x.typ) return } @@ -318,12 +326,12 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b } if dst == nil || src == nil { - check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y) + check.invalidArg(x, _InvalidCopy, "copy expects slice arguments; found %s and %s", x, &y) return } 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) + check.invalidArg(x, _InvalidCopy, "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src) return } @@ -337,7 +345,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // delete(m, k) m, _ := x.typ.Underlying().(*Map) if m == nil { - check.invalidArg(x.pos(), "%s is not a map", x) + check.invalidArg(x, _InvalidDelete, "%s is not a map", x) return } arg(x, 1) // k @@ -345,8 +353,8 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b return } - if !x.assignableTo(check, m.key, nil) { - check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key) + if ok, code := x.assignableTo(check, m.key, nil); !ok { + check.invalidArg(x, code, "%s is not assignable to %s", x, m.key) return } @@ -382,7 +390,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // the argument must be of complex type if !isComplex(x.typ) { - check.invalidArg(x.pos(), "argument has type %s, expected complex type", x.typ) + code := _InvalidImag + if id == _Real { + code = _InvalidReal + } + check.invalidArg(x, code, "argument has type %s, expected complex type", x.typ) return } @@ -434,11 +446,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b case *Map, *Chan: min = 1 default: - check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0) + check.invalidArg(arg0, _InvalidMake, "cannot make %s; type must be slice, map, or channel", arg0) return } if nargs < min || min+1 < nargs { - check.errorf(call.Pos(), "%v expects %d or %d arguments; found %d", call, min, min+1, nargs) + check.errorf(call, _WrongArgCount, "%v expects %d or %d arguments; found %d", call, min, min+1, nargs) return } types := []Type{T} @@ -451,7 +463,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b } } if len(sizes) == 2 && sizes[0] > sizes[1] { - check.invalidArg(call.Args[1].Pos(), "length and capacity swapped") + check.invalidArg(call.Args[1], _SwappedMakeArgs, "length and capacity swapped") // safe to continue } x.mode = value @@ -549,7 +561,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b arg0 := call.Args[0] selx, _ := unparen(arg0).(*ast.SelectorExpr) if selx == nil { - check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0) + check.invalidArg(arg0, _BadOffsetofSyntax, "%s is not a selector expression", arg0) check.use(arg0) return } @@ -564,18 +576,18 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b 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) + check.invalidArg(x, _MissingFieldOrMethod, "%s has no single field %s", base, sel) return case *Func: // TODO(gri) Using derefStructPtr may result in methods being found // that don't actually exist. An error either way, but the error // message is confusing. See: https://play.golang.org/p/al75v23kUy , // but go/types reports: "invalid argument: x.m is a method value". - check.invalidArg(arg0.Pos(), "%s is a method value", arg0) + check.invalidArg(arg0, _InvalidOffsetof, "%s is a method value", arg0) return } if indirect { - check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base) + check.invalidArg(x, _InvalidOffsetof, "field %s is embedded via a pointer in %s", sel, base) return } @@ -605,15 +617,15 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b // The result of assert is the value of pred if there is no error. // Note: assert is only available in self-test mode. if x.mode != constant_ || !isBoolean(x.typ) { - check.invalidArg(x.pos(), "%s is not a boolean constant", x) + check.invalidArg(x, _Test, "%s is not a boolean constant", x) return } if x.val.Kind() != constant.Bool { - check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x) + check.errorf(x, _Test, "internal error: value of %s should be a boolean constant", x) return } if !constant.BoolVal(x.val) { - check.errorf(call.Pos(), "%v failed", call) + check.errorf(call, _Test, "%v failed", call) // compile-time assertion failure - safe to continue } // result is constant - no need to record signature @@ -633,7 +645,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b x1 := x for _, arg := range call.Args { check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T)) - check.dump("%v: %s", x1.pos(), x1) + check.dump("%v: %s", x1.Pos(), x1) x1 = &t // use incoming x only for first argument } // trace is only available in test mode - no need to record signature diff --git a/libgo/go/go/types/call.go b/libgo/go/go/types/call.go index be4cfdf9eb4..6765b17bf34 100644 --- a/libgo/go/go/types/call.go +++ b/libgo/go/go/types/call.go @@ -29,15 +29,19 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { x.mode = invalid switch n := len(e.Args); n { case 0: - check.errorf(e.Rparen, "missing argument in conversion to %s", T) + check.errorf(inNode(e, e.Rparen), _WrongArgCount, "missing argument in conversion to %s", T) case 1: check.expr(x, e.Args[0]) if x.mode != invalid { + if e.Ellipsis.IsValid() { + check.errorf(e.Args[0], _BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T) + break + } check.conversion(x, T) } default: check.use(e.Args...) - check.errorf(e.Args[n-1].Pos(), "too many arguments in conversion to %s", T) + check.errorf(e.Args[n-1], _WrongArgCount, "too many arguments in conversion to %s", T) } x.expr = e return conversion @@ -60,7 +64,7 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { sig, _ := x.typ.Underlying().(*Signature) if sig == nil { - check.invalidOp(x.pos(), "cannot call non-function %s", x) + check.invalidOp(x, _InvalidCall, "cannot call non-function %s", x) x.mode = invalid x.expr = e return statement @@ -231,13 +235,13 @@ func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, if call.Ellipsis.IsValid() { // last argument is of the form x... if !sig.variadic { - check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun) + check.errorf(atPos(call.Ellipsis), _NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun) check.useGetter(arg, n) return } if len(call.Args) == 1 && n > 1 { // f()... is not permitted if f() is multi-valued - check.errorf(call.Ellipsis, "cannot use ... with %d-valued %s", n, call.Args[0]) + check.errorf(atPos(call.Ellipsis), _InvalidDotDotDotOperand, "cannot use ... with %d-valued %s", n, call.Args[0]) check.useGetter(arg, n) return } @@ -263,7 +267,7 @@ func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, n++ } if n < sig.params.Len() { - check.errorf(call.Rparen, "too few arguments in call to %s", call.Fun) + check.errorf(inNode(call, call.Rparen), _WrongArgCount, "too few arguments in call to %s", call.Fun) // ok to continue } } @@ -291,18 +295,18 @@ func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token } } default: - check.errorf(x.pos(), "too many arguments") + check.errorf(x, _WrongArgCount, "too many arguments") return } if ellipsis.IsValid() { - // argument is of the form x... and x is single-valued if i != n-1 { - check.errorf(ellipsis, "can only use ... with matching parameter") + check.errorf(atPos(ellipsis), _MisplacedDotDotDot, "can only use ... with matching parameter") return } + // argument is of the form x... and x is single-valued if _, ok := x.typ.Underlying().(*Slice); !ok && x.typ != Typ[UntypedNil] { // see issue #18268 - check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ) + check.errorf(x, _InvalidDotDotDotOperand, "cannot use %s as parameter of type %s", x, typ) return } } else if sig.variadic && i >= n-1 { @@ -365,7 +369,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { } } if exp == nil { - check.errorf(e.Sel.Pos(), "%s not declared by package C", sel) + check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package C", sel) goto Error } check.objDecl(exp, nil) @@ -373,12 +377,12 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { exp = pkg.scope.Lookup(sel) if exp == nil { if !pkg.fake { - check.errorf(e.Sel.Pos(), "%s not declared by package %s", sel, pkg.name) + check.errorf(e.Sel, _UndeclaredImportedName, "%s not declared by package %s", sel, pkg.name) } goto Error } if !exp.Exported() { - check.errorf(e.Sel.Pos(), "%s not exported by package %s", sel, pkg.name) + check.errorf(e.Sel, _UnexportedName, "%s not exported by package %s", sel, pkg.name) // ok to continue } } @@ -431,9 +435,9 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { switch { case index != nil: // TODO(gri) should provide actual type where the conflict happens - check.errorf(e.Sel.Pos(), "ambiguous selector %s.%s", x.expr, sel) + check.errorf(e.Sel, _AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel) case indirect: - check.errorf(e.Sel.Pos(), "cannot call pointer method %s on %s", sel, x.typ) + check.errorf(e.Sel, _InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ) default: // Check if capitalization of sel matters and provide better error // message in that case. @@ -445,11 +449,11 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { changeCase = string(unicode.ToUpper(r)) + sel[1:] } if obj, _, _ = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil { - check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no field or method %s, but does have %s)", x.expr, sel, x.typ, sel, changeCase) + check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no field or method %s, but does have %s)", x.expr, sel, x.typ, sel, changeCase) break } } - check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no field or method %s)", x.expr, sel, x.typ, sel) + check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no field or method %s)", x.expr, sel, x.typ, sel) } goto Error } @@ -464,7 +468,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { m, _ := obj.(*Func) if m == nil { // TODO(gri) should check if capitalization of sel matters and provide better error message in that case - check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel) + check.errorf(e.Sel, _MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel) goto Error } diff --git a/libgo/go/go/types/check.go b/libgo/go/go/types/check.go index 007babdf9d6..280792e838e 100644 --- a/libgo/go/go/types/check.go +++ b/libgo/go/go/types/check.go @@ -46,6 +46,7 @@ type context struct { scope *Scope // top-most scope for lookups pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval) iota constant.Value // value of iota in a constant declaration; nil otherwise + errpos positioner // if set, identifier position of a constant with inherited initializer sig *Signature // function signature if inside a function; nil otherwise isPanic map[*ast.CallExpr]bool // set of panic call expressions (used for termination check) hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions @@ -85,8 +86,8 @@ type Checker struct { // information collected during type-checking of a set of package files // (initialized by Files, valid only for the duration of check.Files; // maps and lists are allocated on demand) - files []*ast.File // package files - unusedDotImports map[*Scope]map[*Package]token.Pos // positions of unused dot-imported packages for each file scope + files []*ast.File // package files + unusedDotImports map[*Scope]map[*Package]*ast.ImportSpec // unused dot-imported packages firstErr error // first error encountered methods map[*TypeName][]*Func // maps package scope type names to associated non-blank (non-interface) methods @@ -105,18 +106,18 @@ type Checker struct { // addUnusedImport adds the position of a dot-imported package // pkg to the map of dot imports for the given file scope. -func (check *Checker) addUnusedDotImport(scope *Scope, pkg *Package, pos token.Pos) { +func (check *Checker) addUnusedDotImport(scope *Scope, pkg *Package, spec *ast.ImportSpec) { mm := check.unusedDotImports if mm == nil { - mm = make(map[*Scope]map[*Package]token.Pos) + mm = make(map[*Scope]map[*Package]*ast.ImportSpec) check.unusedDotImports = mm } m := mm[scope] if m == nil { - m = make(map[*Package]token.Pos) + m = make(map[*Package]*ast.ImportSpec) mm[scope] = m } - m[pkg] = pos + m[pkg] = spec } // addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists @@ -217,7 +218,7 @@ func (check *Checker) initFiles(files []*ast.File) { if name != "_" { pkg.name = name } else { - check.errorf(file.Name.Pos(), "invalid package name _") + check.errorf(file.Name, _BlankPkgName, "invalid package name _") } fallthrough @@ -225,7 +226,7 @@ func (check *Checker) initFiles(files []*ast.File) { check.files = append(check.files, file) default: - check.errorf(file.Package, "package %s; expected %s", name, pkg.name) + check.errorf(atPos(file.Package), _MismatchedPkgName, "package %s; expected %s", name, pkg.name) // ignore this file } } diff --git a/libgo/go/go/types/check_test.go b/libgo/go/go/types/check_test.go index 89122d75fff..ce31dab68bb 100644 --- a/libgo/go/go/types/check_test.go +++ b/libgo/go/go/types/check_test.go @@ -33,7 +33,8 @@ import ( "go/scanner" "go/token" "internal/testenv" - "io/ioutil" + "os" + "path/filepath" "regexp" "strings" "testing" @@ -93,11 +94,6 @@ var tests = [][]string{ {"testdata/issues.src"}, {"testdata/blank.src"}, {"testdata/issue25008b.src", "testdata/issue25008a.src"}, // order (b before a) is crucial! - {"testdata/issue26390.src"}, // stand-alone test to ensure case is triggered - {"testdata/issue23203a.src"}, - {"testdata/issue23203b.src"}, - {"testdata/issue28251.src"}, - {"testdata/issue6977.src"}, } var fset = token.NewFileSet() @@ -157,7 +153,7 @@ func errMap(t *testing.T, testname string, files []*ast.File) map[string][]strin for _, file := range files { filename := fset.Position(file.Package).Filename - src, err := ioutil.ReadFile(filename) + src, err := os.ReadFile(filename) if err != nil { t.Fatalf("%s: could not read %s", testname, filename) } @@ -259,7 +255,7 @@ func checkFiles(t *testing.T, testfiles []string) { // typecheck and collect typechecker errors var conf Config // special case for importC.src - if len(testfiles) == 1 && testfiles[0] == "testdata/importC.src" { + if len(testfiles) == 1 && strings.HasSuffix(testfiles[0], "importC.src") { conf.FakeImportC = true } conf.Importer = importer.Default() @@ -283,6 +279,17 @@ func checkFiles(t *testing.T, testfiles []string) { return } + for _, err := range errlist { + err, ok := err.(Error) + if !ok { + continue + } + code := readCode(err) + if code == 0 { + t.Errorf("missing error code: %v", err) + } + } + // match and eliminate errors; // we are expecting the following errors errmap := errMap(t, pkgName, files) @@ -316,3 +323,27 @@ func TestCheck(t *testing.T) { checkFiles(t, files) } } + +func TestFixedBugs(t *testing.T) { testDir(t, "fixedbugs") } + +func testDir(t *testing.T, dir string) { + testenv.MustHaveGoBuild(t) + + dirs, err := os.ReadDir(dir) + if err != nil { + t.Fatal(err) + } + + for _, d := range dirs { + testname := filepath.Base(d.Name()) + testname = strings.TrimSuffix(testname, filepath.Ext(testname)) + t.Run(testname, func(t *testing.T) { + filename := filepath.Join(dir, d.Name()) + if d.IsDir() { + t.Errorf("skipped directory %q", filename) + return + } + checkFiles(t, []string{filename}) + }) + } +} diff --git a/libgo/go/go/types/conversions.go b/libgo/go/go/types/conversions.go index 4a6bddb24c1..1cab1cc70f0 100644 --- a/libgo/go/go/types/conversions.go +++ b/libgo/go/go/types/conversions.go @@ -6,7 +6,10 @@ package types -import "go/constant" +import ( + "go/constant" + "unicode" +) // Conversion type-checks the conversion T(x). // The result is in x. @@ -21,14 +24,11 @@ func (check *Checker) conversion(x *operand, T Type) { case representableConst(x.val, check, t, &x.val): ok = true case isInteger(x.typ) && isString(t): - codepoint := int64(-1) - if i, ok := constant.Int64Val(x.val); ok { - codepoint = i + codepoint := unicode.ReplacementChar + if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune { + codepoint = rune(i) } - // If codepoint < 0 the absolute value is too large (or unknown) for - // conversion. This is the same as converting any other out-of-range - // value - let string(codepoint) do the work. - x.val = constant.MakeString(string(rune(codepoint))) + x.val = constant.MakeString(string(codepoint)) ok = true } case x.convertibleTo(check, T): @@ -38,7 +38,7 @@ func (check *Checker) conversion(x *operand, T Type) { } if !ok { - check.errorf(x.pos(), "cannot convert %s to %s", x, T) + check.errorf(x, _InvalidConversion, "cannot convert %s to %s", x, T) x.mode = invalid return } @@ -81,7 +81,7 @@ func (check *Checker) conversion(x *operand, T Type) { // exported API call, i.e., when all methods have been type-checked. func (x *operand) convertibleTo(check *Checker, T Type) bool { // "x is assignable to T" - if x.assignableTo(check, T, nil) { + if ok, _ := x.assignableTo(check, T, nil); ok { return true } diff --git a/libgo/go/go/types/decl.go b/libgo/go/go/types/decl.go index 5c0e611c519..1f0bc358a26 100644 --- a/libgo/go/go/types/decl.go +++ b/libgo/go/go/types/decl.go @@ -15,7 +15,7 @@ func (check *Checker) reportAltDecl(obj Object) { // 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", obj.Name()) // secondary error, \t indented + check.errorf(obj, _DuplicateDecl, "\tother declaration of %s", obj.Name()) // secondary error, \t indented } } @@ -26,7 +26,7 @@ func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token // binding." if obj.Name() != "_" { if alt := scope.Insert(obj); alt != nil { - check.errorf(obj.Pos(), "%s redeclared in this block", obj.Name()) + check.errorf(obj, _DuplicateDecl, "%s redeclared in this block", obj.Name()) check.reportAltDecl(alt) return } @@ -183,7 +183,7 @@ func (check *Checker) objDecl(obj Object, def *Named) { switch obj := obj.(type) { case *Const: check.decl = d // new package-level const decl - check.constDecl(obj, d.typ, d.init) + check.constDecl(obj, d.typ, d.init, d.inherited) case *Var: check.decl = d // new package-level var decl check.varDecl(obj, d.lhs, d.typ, d.init) @@ -357,16 +357,16 @@ func (check *Checker) cycleError(cycle []Object) { // 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()) + check.errorf(obj, _InvalidDeclCycle, "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 + check.errorf(obj, _InvalidDeclCycle, "\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()) + check.errorf(obj, _InvalidDeclCycle, "\t%s", obj.Name()) } // firstInSrc reports the index of the object with the "smallest" @@ -381,12 +381,90 @@ func firstInSrc(path []Object) int { return fst } -func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { +type ( + decl interface { + node() ast.Node + } + + importDecl struct{ spec *ast.ImportSpec } + constDecl struct { + spec *ast.ValueSpec + iota int + typ ast.Expr + init []ast.Expr + inherited bool + } + varDecl struct{ spec *ast.ValueSpec } + typeDecl struct{ spec *ast.TypeSpec } + funcDecl struct{ decl *ast.FuncDecl } +) + +func (d importDecl) node() ast.Node { return d.spec } +func (d constDecl) node() ast.Node { return d.spec } +func (d varDecl) node() ast.Node { return d.spec } +func (d typeDecl) node() ast.Node { return d.spec } +func (d funcDecl) node() ast.Node { return d.decl } + +func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) { + for _, d := range decls { + check.walkDecl(d, f) + } +} + +func (check *Checker) walkDecl(d ast.Decl, f func(decl)) { + switch d := d.(type) { + case *ast.BadDecl: + // ignore + case *ast.GenDecl: + var last *ast.ValueSpec // last ValueSpec with type or init exprs seen + for iota, s := range d.Specs { + switch s := s.(type) { + case *ast.ImportSpec: + f(importDecl{s}) + case *ast.ValueSpec: + switch d.Tok { + case token.CONST: + // determine which initialization expressions to use + inherited := true + switch { + case s.Type != nil || len(s.Values) > 0: + last = s + inherited = false + case last == nil: + last = new(ast.ValueSpec) // make sure last exists + inherited = false + } + check.arityMatch(s, last) + f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited}) + case token.VAR: + check.arityMatch(s, nil) + f(varDecl{s}) + default: + check.invalidAST(s, "invalid token %s", d.Tok) + } + case *ast.TypeSpec: + f(typeDecl{s}) + default: + check.invalidAST(s, "unknown ast.Spec node %T", s) + } + } + case *ast.FuncDecl: + f(funcDecl{d}) + default: + check.invalidAST(d, "unknown ast.Decl node %T", d) + } +} + +func (check *Checker) constDecl(obj *Const, typ, init ast.Expr, inherited bool) { assert(obj.typ == nil) // use the correct value of iota - defer func(iota constant.Value) { check.iota = iota }(check.iota) + defer func(iota constant.Value, errpos positioner) { + check.iota = iota + check.errpos = errpos + }(check.iota, check.errpos) check.iota = obj.val + check.errpos = nil // provide valid constant value under all circumstances obj.val = constant.MakeUnknown() @@ -398,7 +476,7 @@ func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { // don't report an error if the type is an invalid C (defined) type // (issue #22090) if t.Underlying() != Typ[Invalid] { - check.errorf(typ.Pos(), "invalid constant type %s", t) + check.errorf(typ, _InvalidConstType, "invalid constant type %s", t) } obj.typ = Typ[Invalid] return @@ -409,6 +487,15 @@ func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) { // check initialization var x operand if init != nil { + if inherited { + // The initialization expression is inherited from a previous + // constant declaration, and (error) positions refer to that + // expression and not the current constant declaration. Use + // the constant identifier position for any errors during + // init expression evaluation since that is all we have + // (see issues #42991, #42992). + check.errpos = atPos(obj.pos) + } check.expr(&x, init) } check.initConst(obj, &x) @@ -624,9 +711,9 @@ func (check *Checker) addMethodDecls(obj *TypeName) { if alt := mset.insert(m); alt != nil { switch alt.(type) { case *Var: - check.errorf(m.pos, "field and method with the same name %s", m.name) + check.errorf(m, _DuplicateFieldAndMethod, "field and method with the same name %s", m.name) case *Func: - check.errorf(m.pos, "method %s already declared for %s", m.name, obj) + check.errorf(m, _DuplicateMethod, "method %s already declared for %s", m.name, obj) default: unreachable() } @@ -651,7 +738,7 @@ func (check *Checker) funcDecl(obj *Func, decl *declInfo) { fdecl := decl.fdecl check.funcType(sig, fdecl.Recv, fdecl.Type) if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) { - check.errorf(fdecl.Pos(), "func init must have no arguments and no return values") + check.errorf(fdecl, _InvalidInitSig, "func init must have no arguments and no return values") // ok to continue } @@ -664,133 +751,105 @@ func (check *Checker) funcDecl(obj *Func, decl *declInfo) { } } -func (check *Checker) declStmt(decl ast.Decl) { +func (check *Checker) declStmt(d ast.Decl) { pkg := check.pkg - switch d := decl.(type) { - case *ast.BadDecl: - // ignore - - case *ast.GenDecl: - var last *ast.ValueSpec // last ValueSpec with type or init exprs seen - for iota, spec := range d.Specs { - switch s := spec.(type) { - case *ast.ValueSpec: - switch d.Tok { - case token.CONST: - top := len(check.delayed) - - // determine which init exprs to use - switch { - case s.Type != nil || len(s.Values) > 0: - last = s - case last == nil: - last = new(ast.ValueSpec) // make sure last exists - } + check.walkDecl(d, func(d decl) { + switch d := d.(type) { + case constDecl: + top := len(check.delayed) - // declare all constants - lhs := make([]*Const, len(s.Names)) - for i, name := range s.Names { - obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) - lhs[i] = obj + // declare all constants + lhs := make([]*Const, len(d.spec.Names)) + for i, name := range d.spec.Names { + obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota))) + lhs[i] = obj - var init ast.Expr - if i < len(last.Values) { - init = last.Values[i] - } + var init ast.Expr + if i < len(d.init) { + init = d.init[i] + } - check.constDecl(obj, last.Type, init) - } + check.constDecl(obj, d.typ, init, d.inherited) + } - check.arityMatch(s, last) + // process function literals in init expressions before scope changes + check.processDelayed(top) - // process function literals in init expressions before scope changes - check.processDelayed(top) + // spec: "The scope of a constant or variable identifier declared + // inside a function begins at the end of the ConstSpec or VarSpec + // (ShortVarDecl for short variable declarations) and ends at the + // end of the innermost containing block." + scopePos := d.spec.End() + for i, name := range d.spec.Names { + check.declare(check.scope, name, lhs[i], scopePos) + } - // spec: "The scope of a constant or variable identifier declared - // inside a function begins at the end of the ConstSpec or VarSpec - // (ShortVarDecl for short variable declarations) and ends at the - // end of the innermost containing block." - scopePos := s.End() - for i, name := range s.Names { - check.declare(check.scope, name, lhs[i], scopePos) - } + case varDecl: + top := len(check.delayed) - case token.VAR: - top := len(check.delayed) + lhs0 := make([]*Var, len(d.spec.Names)) + for i, name := range d.spec.Names { + lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) + } - lhs0 := make([]*Var, len(s.Names)) - for i, name := range s.Names { - lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) + // initialize all variables + for i, obj := range lhs0 { + var lhs []*Var + var init ast.Expr + switch len(d.spec.Values) { + case len(d.spec.Names): + // lhs and rhs match + init = d.spec.Values[i] + case 1: + // rhs is expected to be a multi-valued expression + lhs = lhs0 + init = d.spec.Values[0] + default: + if i < len(d.spec.Values) { + init = d.spec.Values[i] } - - // initialize all variables - for i, obj := range lhs0 { - var lhs []*Var - var init ast.Expr - switch len(s.Values) { - case len(s.Names): - // lhs and rhs match - init = s.Values[i] - case 1: - // rhs is expected to be a multi-valued expression - lhs = lhs0 - init = s.Values[0] - default: - if i < len(s.Values) { - init = s.Values[i] - } - } - check.varDecl(obj, lhs, s.Type, init) - if len(s.Values) == 1 { - // If we have a single lhs variable we are done either way. - // If we have a single rhs expression, it must be a multi- - // valued expression, in which case handling the first lhs - // variable will cause all lhs variables to have a type - // assigned, and we are done as well. - if debug { - for _, obj := range lhs0 { - assert(obj.typ != nil) - } - } - break + } + check.varDecl(obj, lhs, d.spec.Type, init) + if len(d.spec.Values) == 1 { + // If we have a single lhs variable we are done either way. + // If we have a single rhs expression, it must be a multi- + // valued expression, in which case handling the first lhs + // variable will cause all lhs variables to have a type + // assigned, and we are done as well. + if debug { + for _, obj := range lhs0 { + assert(obj.typ != nil) } } - - check.arityMatch(s, nil) - - // process function literals in init expressions before scope changes - check.processDelayed(top) - - // declare all variables - // (only at this point are the variable scopes (parents) set) - scopePos := s.End() // see constant declarations - for i, name := range s.Names { - // see constant declarations - check.declare(check.scope, name, lhs0[i], scopePos) - } - - default: - check.invalidAST(s.Pos(), "invalid token %s", d.Tok) + break } + } - case *ast.TypeSpec: - obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) - // spec: "The scope of a type identifier declared inside a function - // begins at the identifier in the TypeSpec and ends at the end of - // the innermost containing block." - scopePos := s.Name.Pos() - check.declare(check.scope, s.Name, obj, scopePos) - // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl) - obj.setColor(grey + color(check.push(obj))) - check.typeDecl(obj, s.Type, nil, s.Assign.IsValid()) - check.pop().setColor(black) - default: - check.invalidAST(s.Pos(), "const, type, or var declaration expected") + // process function literals in init expressions before scope changes + check.processDelayed(top) + + // declare all variables + // (only at this point are the variable scopes (parents) set) + scopePos := d.spec.End() // see constant declarations + for i, name := range d.spec.Names { + // see constant declarations + check.declare(check.scope, name, lhs0[i], scopePos) } - } - default: - check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) - } + case typeDecl: + obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil) + // spec: "The scope of a type identifier declared inside a function + // begins at the identifier in the TypeSpec and ends at the end of + // the innermost containing block." + scopePos := d.spec.Name.Pos() + check.declare(check.scope, d.spec.Name, obj, scopePos) + // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl) + obj.setColor(grey + color(check.push(obj))) + check.typeDecl(obj, d.spec.Type, nil, d.spec.Assign.IsValid()) + check.pop().setColor(black) + default: + check.invalidAST(d.node(), "unknown ast.Decl node %T", d.node()) + } + }) } diff --git a/libgo/go/go/types/errorcodes.go b/libgo/go/go/types/errorcodes.go new file mode 100644 index 00000000000..c01a12c346d --- /dev/null +++ b/libgo/go/go/types/errorcodes.go @@ -0,0 +1,1366 @@ +// Copyright 2020 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 types + +type errorCode int + +// This file defines the error codes that can be produced during type-checking. +// Collectively, these codes provide an identifier that may be used to +// implement special handling for certain types of errors. +// +// Error codes should be fine-grained enough that the exact nature of the error +// can be easily determined, but coarse enough that they are not an +// implementation detail of the type checking algorithm. As a rule-of-thumb, +// errors should be considered equivalent if there is a theoretical refactoring +// of the type checker in which they are emitted in exactly one place. For +// example, the type checker emits different error messages for "too many +// arguments" and "too few arguments", but one can imagine an alternative type +// checker where this check instead just emits a single "wrong number of +// arguments", so these errors should have the same code. +// +// Error code names should be as brief as possible while retaining accuracy and +// distinctiveness. In most cases names should start with an adjective +// describing the nature of the error (e.g. "invalid", "unused", "misplaced"), +// and end with a noun identifying the relevant language object. For example, +// "_DuplicateDecl" or "_InvalidSliceExpr". For brevity, naming follows the +// convention that "bad" implies a problem with syntax, and "invalid" implies a +// problem with types. + +const ( + _ errorCode = iota + + // _Test is reserved for errors that only apply while in self-test mode. + _Test + + /* package names */ + + // _BlankPkgName occurs when a package name is the blank identifier "_". + // + // Per the spec: + // "The PackageName must not be the blank identifier." + _BlankPkgName + + // _MismatchedPkgName occurs when a file's package name doesn't match the + // package name already established by other files. + _MismatchedPkgName + + // _InvalidPkgUse occurs when a package identifier is used outside of a + // selector expression. + // + // Example: + // import "fmt" + // + // var _ = fmt + _InvalidPkgUse + + /* imports */ + + // _BadImportPath occurs when an import path is not valid. + _BadImportPath + + // _BrokenImport occurs when importing a package fails. + // + // Example: + // import "amissingpackage" + _BrokenImport + + // _ImportCRenamed occurs when the special import "C" is renamed. "C" is a + // pseudo-package, and must not be renamed. + // + // Example: + // import _ "C" + _ImportCRenamed + + // _UnusedImport occurs when an import is unused. + // + // Example: + // import "fmt" + // + // func main() {} + _UnusedImport + + /* initialization */ + + // _InvalidInitCycle occurs when an invalid cycle is detected within the + // initialization graph. + // + // Example: + // var x int = f() + // + // func f() int { return x } + _InvalidInitCycle + + /* decls */ + + // _DuplicateDecl occurs when an identifier is declared multiple times. + // + // Example: + // var x = 1 + // var x = 2 + _DuplicateDecl + + // _InvalidDeclCycle occurs when a declaration cycle is not valid. + // + // Example: + // import "unsafe" + // + // type T struct { + // a [n]int + // } + // + // var n = unsafe.Sizeof(T{}) + _InvalidDeclCycle + + // _InvalidTypeCycle occurs when a cycle in type definitions results in a + // type that is not well-defined. + // + // Example: + // import "unsafe" + // + // type T [unsafe.Sizeof(T{})]int + _InvalidTypeCycle + + /* decls > const */ + + // _InvalidConstInit occurs when a const declaration has a non-constant + // initializer. + // + // Example: + // var x int + // const _ = x + _InvalidConstInit + + // _InvalidConstVal occurs when a const value cannot be converted to its + // target type. + // + // TODO(findleyr): this error code and example are not very clear. Consider + // removing it. + // + // Example: + // const _ = 1 << "hello" + _InvalidConstVal + + // _InvalidConstType occurs when the underlying type in a const declaration + // is not a valid constant type. + // + // Example: + // const c *int = 4 + _InvalidConstType + + /* decls > var (+ other variable assignment codes) */ + + // _UntypedNil occurs when the predeclared (untyped) value nil is used to + // initialize a variable declared without an explicit type. + // + // Example: + // var x = nil + _UntypedNil + + // _WrongAssignCount occurs when the number of values on the right-hand side + // of an assignment or or initialization expression does not match the number + // of variables on the left-hand side. + // + // Example: + // var x = 1, 2 + _WrongAssignCount + + // _UnassignableOperand occurs when the left-hand side of an assignment is + // not assignable. + // + // Example: + // func f() { + // const c = 1 + // c = 2 + // } + _UnassignableOperand + + // _NoNewVar occurs when a short variable declaration (':=') does not declare + // new variables. + // + // Example: + // func f() { + // x := 1 + // x := 2 + // } + _NoNewVar + + // _MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does + // not have single-valued left-hand or right-hand side. + // + // Per the spec: + // "In assignment operations, both the left- and right-hand expression lists + // must contain exactly one single-valued expression" + // + // Example: + // func f() int { + // x, y := 1, 2 + // x, y += 1 + // return x + y + // } + _MultiValAssignOp + + // _InvalidIfaceAssign occurs when a value of type T is used as an + // interface, but T does not implement a method of the expected interface. + // + // Example: + // type I interface { + // f() + // } + // + // type T int + // + // var x I = T(1) + _InvalidIfaceAssign + + // _InvalidChanAssign occurs when a chan assignment is invalid. + // + // Per the spec, a value x is assignable to a channel type T if: + // "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." + // + // Example: + // type T1 chan int + // type T2 chan int + // + // var x T1 + // // Invalid assignment because both types are named + // var _ T2 = x + _InvalidChanAssign + + // _IncompatibleAssign occurs when the type of the right-hand side expression + // in an assignment cannot be assigned to the type of the variable being + // assigned. + // + // Example: + // var x []int + // var _ int = x + _IncompatibleAssign + + // _UnaddressableFieldAssign occurs when trying to assign to a struct field + // in a map value. + // + // Example: + // func f() { + // m := make(map[string]struct{i int}) + // m["foo"].i = 42 + // } + _UnaddressableFieldAssign + + /* decls > type (+ other type expression codes) */ + + // _NotAType occurs when the identifier used as the underlying type in a type + // declaration or the right-hand side of a type alias does not denote a type. + // + // Example: + // var S = 2 + // + // type T S + _NotAType + + // _InvalidArrayLen occurs when an array length is not a constant value. + // + // Example: + // var n = 3 + // var _ = [n]int{} + _InvalidArrayLen + + // _BlankIfaceMethod occurs when a method name is '_'. + // + // Per the spec: + // "The name of each explicitly specified method must be unique and not + // blank." + // + // Example: + // type T interface { + // _(int) + // } + _BlankIfaceMethod + + // _IncomparableMapKey occurs when a map key type does not support the == and + // != operators. + // + // Per the spec: + // "The comparison operators == and != must be fully defined for operands of + // the key type; thus the key type must not be a function, map, or slice." + // + // Example: + // var x map[T]int + // + // type T []int + _IncomparableMapKey + + // _InvalidIfaceEmbed occurs when a non-interface type is embedded in an + // interface. + // + // Example: + // type T struct {} + // + // func (T) m() + // + // type I interface { + // T + // } + _InvalidIfaceEmbed + + // _InvalidPtrEmbed occurs when an embedded field is of the pointer form *T, + // and T itself is itself a pointer, an unsafe.Pointer, or an interface. + // + // Per the spec: + // "An embedded field must be specified as a type name T or as a pointer to + // a non-interface type name *T, and T itself may not be a pointer type." + // + // Example: + // type T *int + // + // type S struct { + // *T + // } + _InvalidPtrEmbed + + /* decls > func and method */ + + // _BadRecv occurs when a method declaration does not have exactly one + // receiver parameter. + // + // Example: + // func () _() {} + _BadRecv + + // _InvalidRecv occurs when a receiver type expression is not of the form T + // or *T, or T is a pointer type. + // + // Example: + // type T struct {} + // + // func (**T) m() {} + _InvalidRecv + + // _DuplicateFieldAndMethod occurs when an identifier appears as both a field + // and method name. + // + // Example: + // type T struct { + // m int + // } + // + // func (T) m() {} + _DuplicateFieldAndMethod + + // _DuplicateMethod occurs when two methods on the same receiver type have + // the same name. + // + // Example: + // type T struct {} + // func (T) m() {} + // func (T) m(i int) int { return i } + _DuplicateMethod + + /* decls > special */ + + // _InvalidBlank occurs when a blank identifier is used as a value or type. + // + // Per the spec: + // "The blank identifier may appear as an operand only on the left-hand side + // of an assignment." + // + // Example: + // var x = _ + _InvalidBlank + + // _InvalidIota occurs when the predeclared identifier iota is used outside + // of a constant declaration. + // + // Example: + // var x = iota + _InvalidIota + + // _MissingInitBody occurs when an init function is missing its body. + // + // Example: + // func init() + _MissingInitBody + + // _InvalidInitSig occurs when an init function declares parameters or + // results. + // + // Example: + // func init() int { return 1 } + _InvalidInitSig + + // _InvalidInitDecl occurs when init is declared as anything other than a + // function. + // + // Example: + // var init = 1 + _InvalidInitDecl + + // _InvalidMainDecl occurs when main is declared as anything other than a + // function, in a main package. + _InvalidMainDecl + + /* exprs */ + + // _TooManyValues occurs when a function returns too many values for the + // expression context in which it is used. + // + // Example: + // func ReturnTwo() (int, int) { + // return 1, 2 + // } + // + // var x = ReturnTwo() + _TooManyValues + + // _NotAnExpr occurs when a type expression is used where a value expression + // is expected. + // + // Example: + // type T struct {} + // + // func f() { + // T + // } + _NotAnExpr + + /* exprs > const */ + + // _TruncatedFloat occurs when a float constant is truncated to an integer + // value. + // + // Example: + // var _ int = 98.6 + _TruncatedFloat + + // _NumericOverflow occurs when a numeric constant overflows its target type. + // + // Example: + // var x int8 = 1000 + _NumericOverflow + + /* exprs > operation */ + + // _UndefinedOp occurs when an operator is not defined for the type(s) used + // in an operation. + // + // Example: + // var c = "a" - "b" + _UndefinedOp + + // _MismatchedTypes occurs when operand types are incompatible in a binary + // operation. + // + // Example: + // var a = "hello" + // var b = 1 + // var c = a - b + _MismatchedTypes + + // _DivByZero occurs when a division operation is provable at compile + // time to be a division by zero. + // + // Example: + // const divisor = 0 + // var x int = 1/divisor + _DivByZero + + // _NonNumericIncDec occurs when an increment or decrement operator is + // applied to a non-numeric value. + // + // Example: + // func f() { + // var c = "c" + // c++ + // } + _NonNumericIncDec + + /* exprs > ptr */ + + // _UnaddressableOperand occurs when the & operator is applied to an + // unaddressable expression. + // + // Example: + // var x = &1 + _UnaddressableOperand + + // _InvalidIndirection occurs when a non-pointer value is indirected via the + // '*' operator. + // + // Example: + // var x int + // var y = *x + _InvalidIndirection + + /* exprs > [] */ + + // _NonIndexableOperand occurs when an index operation is applied to a value + // that cannot be indexed. + // + // Example: + // var x = 1 + // var y = x[1] + _NonIndexableOperand + + // _InvalidIndex occurs when an index argument is not of integer type, + // negative, or out-of-bounds. + // + // Example: + // var s = [...]int{1,2,3} + // var x = s[5] + // + // Example: + // var s = []int{1,2,3} + // var _ = s[-1] + // + // Example: + // var s = []int{1,2,3} + // var i string + // var _ = s[i] + _InvalidIndex + + // _SwappedSliceIndices occurs when constant indices in a slice expression + // are decreasing in value. + // + // Example: + // var _ = []int{1,2,3}[2:1] + _SwappedSliceIndices + + /* operators > slice */ + + // _NonSliceableOperand occurs when a slice operation is applied to a value + // whose type is not sliceable, or is unaddressable. + // + // Example: + // var x = [...]int{1, 2, 3}[:1] + // + // Example: + // var x = 1 + // var y = 1[:1] + _NonSliceableOperand + + // _InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is + // applied to a string. + // + // Example: + // var s = "hello" + // var x = s[1:2:3] + _InvalidSliceExpr + + /* exprs > shift */ + + // _InvalidShiftCount occurs when the right-hand side of a shift operation is + // either non-integer, negative, or too large. + // + // Example: + // var ( + // x string + // y int = 1 << x + // ) + _InvalidShiftCount + + // _InvalidShiftOperand occurs when the shifted operand is not an integer. + // + // Example: + // var s = "hello" + // var x = s << 2 + _InvalidShiftOperand + + /* exprs > chan */ + + // _InvalidReceive occurs when there is a channel receive from a value that + // is either not a channel, or is a send-only channel. + // + // Example: + // func f() { + // var x = 1 + // <-x + // } + _InvalidReceive + + // _InvalidSend occurs when there is a channel send to a value that is not a + // channel, or is a receive-only channel. + // + // Example: + // func f() { + // var x = 1 + // x <- "hello!" + // } + _InvalidSend + + /* exprs > literal */ + + // _DuplicateLitKey occurs when an index is duplicated in a slice, array, or + // map literal. + // + // Example: + // var _ = []int{0:1, 0:2} + // + // Example: + // var _ = map[string]int{"a": 1, "a": 2} + _DuplicateLitKey + + // _MissingLitKey occurs when a map literal is missing a key expression. + // + // Example: + // var _ = map[string]int{1} + _MissingLitKey + + // _InvalidLitIndex occurs when the key in a key-value element of a slice or + // array literal is not an integer constant. + // + // Example: + // var i = 0 + // var x = []string{i: "world"} + _InvalidLitIndex + + // _OversizeArrayLit occurs when an array literal exceeds its length. + // + // Example: + // var _ = [2]int{1,2,3} + _OversizeArrayLit + + // _MixedStructLit occurs when a struct literal contains a mix of positional + // and named elements. + // + // Example: + // var _ = struct{i, j int}{i: 1, 2} + _MixedStructLit + + // _InvalidStructLit occurs when a positional struct literal has an incorrect + // number of values. + // + // Example: + // var _ = struct{i, j int}{1,2,3} + _InvalidStructLit + + // _MissingLitField occurs when a struct literal refers to a field that does + // not exist on the struct type. + // + // Example: + // var _ = struct{i int}{j: 2} + _MissingLitField + + // _DuplicateLitField occurs when a struct literal contains duplicated + // fields. + // + // Example: + // var _ = struct{i int}{i: 1, i: 2} + _DuplicateLitField + + // _UnexportedLitField occurs when a positional struct literal implicitly + // assigns an unexported field of an imported type. + _UnexportedLitField + + // _InvalidLitField occurs when a field name is not a valid identifier. + // + // Example: + // var _ = struct{i int}{1: 1} + _InvalidLitField + + // _UntypedLit occurs when a composite literal omits a required type + // identifier. + // + // Example: + // type outer struct{ + // inner struct { i int } + // } + // + // var _ = outer{inner: {1}} + _UntypedLit + + // _InvalidLit occurs when a composite literal expression does not match its + // type. + // + // Example: + // type P *struct{ + // x int + // } + // var _ = P {} + _InvalidLit + + /* exprs > selector */ + + // _AmbiguousSelector occurs when a selector is ambiguous. + // + // Example: + // type E1 struct { i int } + // type E2 struct { i int } + // type T struct { E1; E2 } + // + // var x T + // var _ = x.i + _AmbiguousSelector + + // _UndeclaredImportedName occurs when a package-qualified identifier is + // undeclared by the imported package. + // + // Example: + // import "go/types" + // + // var _ = types.NotAnActualIdentifier + _UndeclaredImportedName + + // _UnexportedName occurs when a selector refers to an unexported identifier + // of an imported package. + // + // Example: + // import "reflect" + // + // type _ reflect.flag + _UnexportedName + + // _UndeclaredName occurs when an identifier is not declared in the current + // scope. + // + // Example: + // var x T + _UndeclaredName + + // _MissingFieldOrMethod occurs when a selector references a field or method + // that does not exist. + // + // Example: + // type T struct {} + // + // var x = T{}.f + _MissingFieldOrMethod + + /* exprs > ... */ + + // _BadDotDotDotSyntax occurs when a "..." occurs in a context where it is + // not valid. + // + // Example: + // var _ = map[int][...]int{0: {}} + _BadDotDotDotSyntax + + // _NonVariadicDotDotDot occurs when a "..." is used on the final argument to + // a non-variadic function. + // + // Example: + // func printArgs(s []string) { + // for _, a := range s { + // println(a) + // } + // } + // + // func f() { + // s := []string{"a", "b", "c"} + // printArgs(s...) + // } + _NonVariadicDotDotDot + + // _MisplacedDotDotDot occurs when a "..." is used somewhere other than the + // final argument to a function call. + // + // Example: + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func f() { + // a := []int{1,2,3} + // printArgs(0, a...) + // } + _MisplacedDotDotDot + + // _InvalidDotDotDotOperand occurs when a "..." operator is applied to a + // single-valued operand. + // + // Example: + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func f() { + // a := 1 + // printArgs(a...) + // } + // + // Example: + // func args() (int, int) { + // return 1, 2 + // } + // + // func printArgs(args ...int) { + // for _, a := range args { + // println(a) + // } + // } + // + // func g() { + // printArgs(args()...) + // } + _InvalidDotDotDotOperand + + // _InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in + // function. + // + // Example: + // var s = []int{1, 2, 3} + // var l = len(s...) + _InvalidDotDotDot + + /* exprs > built-in */ + + // _UncalledBuiltin occurs when a built-in function is used as a + // function-valued expression, instead of being called. + // + // Per the spec: + // "The built-in functions do not have standard Go types, so they can only + // appear in call expressions; they cannot be used as function values." + // + // Example: + // var _ = copy + _UncalledBuiltin + + // _InvalidAppend occurs when append is called with a first argument that is + // not a slice. + // + // Example: + // var _ = append(1, 2) + _InvalidAppend + + // _InvalidCap occurs when an argument to the cap built-in function is not of + // supported type. + // + // See https://golang.org/ref/spec#Length_and_capacity for information on + // which underlying types are supported as arguments to cap and len. + // + // Example: + // var s = 2 + // var x = cap(s) + _InvalidCap + + // _InvalidClose occurs when close(...) is called with an argument that is + // not of channel type, or that is a receive-only channel. + // + // Example: + // func f() { + // var x int + // close(x) + // } + _InvalidClose + + // _InvalidCopy occurs when the arguments are not of slice type or do not + // have compatible type. + // + // See https://golang.org/ref/spec#Appending_and_copying_slices for more + // information on the type requirements for the copy built-in. + // + // Example: + // func f() { + // var x []int + // y := []int64{1,2,3} + // copy(x, y) + // } + _InvalidCopy + + // _InvalidComplex occurs when the complex built-in function is called with + // arguments with incompatible types. + // + // Example: + // var _ = complex(float32(1), float64(2)) + _InvalidComplex + + // _InvalidDelete occurs when the delete built-in function is called with a + // first argument that is not a map. + // + // Example: + // func f() { + // m := "hello" + // delete(m, "e") + // } + _InvalidDelete + + // _InvalidImag occurs when the imag built-in function is called with an + // argument that does not have complex type. + // + // Example: + // var _ = imag(int(1)) + _InvalidImag + + // _InvalidLen occurs when an argument to the len built-in function is not of + // supported type. + // + // See https://golang.org/ref/spec#Length_and_capacity for information on + // which underlying types are supported as arguments to cap and len. + // + // Example: + // var s = 2 + // var x = len(s) + _InvalidLen + + // _SwappedMakeArgs occurs when make is called with three arguments, and its + // length argument is larger than its capacity argument. + // + // Example: + // var x = make([]int, 3, 2) + _SwappedMakeArgs + + // _InvalidMake occurs when make is called with an unsupported type argument. + // + // See https://golang.org/ref/spec#Making_slices_maps_and_channels for + // information on the types that may be created using make. + // + // Example: + // var x = make(int) + _InvalidMake + + // _InvalidReal occurs when the real built-in function is called with an + // argument that does not have complex type. + // + // Example: + // var _ = real(int(1)) + _InvalidReal + + /* exprs > assertion */ + + // _InvalidAssert occurs when a type assertion is applied to a + // value that is not of interface type. + // + // Example: + // var x = 1 + // var _ = x.(float64) + _InvalidAssert + + // _ImpossibleAssert occurs for a type assertion x.(T) when the value x of + // interface cannot have dynamic type T, due to a missing or mismatching + // method on T. + // + // Example: + // type T int + // + // func (t *T) m() int { return int(*t) } + // + // type I interface { m() int } + // + // var x I + // var _ = x.(T) + _ImpossibleAssert + + /* exprs > conversion */ + + // _InvalidConversion occurs when the argument type cannot be converted to the + // target. + // + // See https://golang.org/ref/spec#Conversions for the rules of + // convertibility. + // + // Example: + // var x float64 + // var _ = string(x) + _InvalidConversion + + // _InvalidUntypedConversion occurs when an there is no valid implicit + // conversion from an untyped value satisfying the type constraints of the + // context in which it is used. + // + // Example: + // var _ = 1 + "" + _InvalidUntypedConversion + + /* offsetof */ + + // _BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument + // that is not a selector expression. + // + // Example: + // import "unsafe" + // + // var x int + // var _ = unsafe.Offsetof(x) + _BadOffsetofSyntax + + // _InvalidOffsetof occurs when unsafe.Offsetof is called with a method + // selector, rather than a field selector, or when the field is embedded via + // a pointer. + // + // Per the spec: + // + // "If f is an embedded field, it must be reachable without pointer + // indirections through fields of the struct. " + // + // Example: + // import "unsafe" + // + // type T struct { f int } + // type S struct { *T } + // var s S + // var _ = unsafe.Offsetof(s.f) + // + // Example: + // import "unsafe" + // + // type S struct{} + // + // func (S) m() {} + // + // var s S + // var _ = unsafe.Offsetof(s.m) + _InvalidOffsetof + + /* control flow > scope */ + + // _UnusedExpr occurs when a side-effect free expression is used as a + // statement. Such a statement has no effect. + // + // Example: + // func f(i int) { + // i*i + // } + _UnusedExpr + + // _UnusedVar occurs when a variable is declared but unused. + // + // Example: + // func f() { + // x := 1 + // } + _UnusedVar + + // _MissingReturn occurs when a function with results is missing a return + // statement. + // + // Example: + // func f() int {} + _MissingReturn + + // _WrongResultCount occurs when a return statement returns an incorrect + // number of values. + // + // Example: + // func ReturnOne() int { + // return 1, 2 + // } + _WrongResultCount + + // _OutOfScopeResult occurs when the name of a value implicitly returned by + // an empty return statement is shadowed in a nested scope. + // + // Example: + // func factor(n int) (i int) { + // for i := 2; i < n; i++ { + // if n%i == 0 { + // return + // } + // } + // return 0 + // } + _OutOfScopeResult + + /* control flow > if */ + + // _InvalidCond occurs when an if condition is not a boolean expression. + // + // Example: + // func checkReturn(i int) { + // if i { + // panic("non-zero return") + // } + // } + _InvalidCond + + /* control flow > for */ + + // _InvalidPostDecl occurs when there is a declaration in a for-loop post + // statement. + // + // Example: + // func f() { + // for i := 0; i < 10; j := 0 {} + // } + _InvalidPostDecl + + // _InvalidChanRange occurs when a send-only channel used in a range + // expression. + // + // Example: + // func sum(c chan<- int) { + // s := 0 + // for i := range c { + // s += i + // } + // } + _InvalidChanRange + + // _InvalidIterVar occurs when two iteration variables are used while ranging + // over a channel. + // + // Example: + // func f(c chan int) { + // for k, v := range c { + // println(k, v) + // } + // } + _InvalidIterVar + + // _InvalidRangeExpr occurs when the type of a range expression is not array, + // slice, string, map, or channel. + // + // Example: + // func f(i int) { + // for j := range i { + // println(j) + // } + // } + _InvalidRangeExpr + + /* control flow > switch */ + + // _MisplacedBreak occurs when a break statement is not within a for, switch, + // or select statement of the innermost function definition. + // + // Example: + // func f() { + // break + // } + _MisplacedBreak + + // _MisplacedContinue occurs when a continue statement is not within a for + // loop of the innermost function definition. + // + // Example: + // func sumeven(n int) int { + // proceed := func() { + // continue + // } + // sum := 0 + // for i := 1; i <= n; i++ { + // if i % 2 != 0 { + // proceed() + // } + // sum += i + // } + // return sum + // } + _MisplacedContinue + + // _MisplacedFallthrough occurs when a fallthrough statement is not within an + // expression switch. + // + // Example: + // func typename(i interface{}) string { + // switch i.(type) { + // case int64: + // fallthrough + // case int: + // return "int" + // } + // return "unsupported" + // } + _MisplacedFallthrough + + // _DuplicateCase occurs when a type or expression switch has duplicate + // cases. + // + // Example: + // func printInt(i int) { + // switch i { + // case 1: + // println("one") + // case 1: + // println("One") + // } + // } + _DuplicateCase + + // _DuplicateDefault occurs when a type or expression switch has multiple + // default clauses. + // + // Example: + // func printInt(i int) { + // switch i { + // case 1: + // println("one") + // default: + // println("One") + // default: + // println("1") + // } + // } + _DuplicateDefault + + // _BadTypeKeyword occurs when a .(type) expression is used anywhere other + // than a type switch. + // + // Example: + // type I interface { + // m() + // } + // var t I + // var _ = t.(type) + _BadTypeKeyword + + // _InvalidTypeSwitch occurs when .(type) is used on an expression that is + // not of interface type. + // + // Example: + // func f(i int) { + // switch x := i.(type) {} + // } + _InvalidTypeSwitch + + // _InvalidExprSwitch occurs when a switch expression is not comparable. + // + // Example: + // func _() { + // var a struct{ _ func() } + // switch a /* ERROR cannot switch on a */ { + // } + // } + _InvalidExprSwitch + + /* control flow > select */ + + // _InvalidSelectCase occurs when a select case is not a channel send or + // receive. + // + // Example: + // func checkChan(c <-chan int) bool { + // select { + // case c: + // return true + // default: + // return false + // } + // } + _InvalidSelectCase + + /* control flow > labels and jumps */ + + // _UndeclaredLabel occurs when an undeclared label is jumped to. + // + // Example: + // func f() { + // goto L + // } + _UndeclaredLabel + + // _DuplicateLabel occurs when a label is declared more than once. + // + // Example: + // func f() int { + // L: + // L: + // return 1 + // } + _DuplicateLabel + + // _MisplacedLabel occurs when a break or continue label is not on a for, + // switch, or select statement. + // + // Example: + // func f() { + // L: + // a := []int{1,2,3} + // for _, e := range a { + // if e > 10 { + // break L + // } + // println(a) + // } + // } + _MisplacedLabel + + // _UnusedLabel occurs when a label is declared but not used. + // + // Example: + // func f() { + // L: + // } + _UnusedLabel + + // _JumpOverDecl occurs when a label jumps over a variable declaration. + // + // Example: + // func f() int { + // goto L + // x := 2 + // L: + // x++ + // return x + // } + _JumpOverDecl + + // _JumpIntoBlock occurs when a forward jump goes to a label inside a nested + // block. + // + // Example: + // func f(x int) { + // goto L + // if x > 0 { + // L: + // print("inside block") + // } + // } + _JumpIntoBlock + + /* control flow > calls */ + + // _InvalidMethodExpr occurs when a pointer method is called but the argument + // is not addressable. + // + // Example: + // type T struct {} + // + // func (*T) m() int { return 1 } + // + // var _ = T.m(T{}) + _InvalidMethodExpr + + // _WrongArgCount occurs when too few or too many arguments are passed by a + // function call. + // + // Example: + // func f(i int) {} + // var x = f() + _WrongArgCount + + // _InvalidCall occurs when an expression is called that is not of function + // type. + // + // Example: + // var x = "x" + // var y = x() + _InvalidCall + + /* control flow > suspended */ + + // _UnusedResults occurs when a restricted expression-only built-in function + // is suspended via go or defer. Such a suspension discards the results of + // these side-effect free built-in functions, and therefore is ineffectual. + // + // Example: + // func f(a []int) int { + // defer len(a) + // return i + // } + _UnusedResults + + // _InvalidDefer occurs when a deferred expression is not a function call, + // for example if the expression is a type conversion. + // + // Example: + // func f(i int) int { + // defer int32(i) + // return i + // } + _InvalidDefer + + // _InvalidGo occurs when a go expression is not a function call, for example + // if the expression is a type conversion. + // + // Example: + // func f(i int) int { + // go int32(i) + // return i + // } + _InvalidGo +) diff --git a/libgo/go/go/types/errorcodes_test.go b/libgo/go/go/types/errorcodes_test.go new file mode 100644 index 00000000000..9652920042a --- /dev/null +++ b/libgo/go/go/types/errorcodes_test.go @@ -0,0 +1,199 @@ +// Copyright 2020 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 types_test + +import ( + "fmt" + "go/ast" + "go/constant" + "go/importer" + "go/parser" + "go/token" + "reflect" + "strings" + "testing" + + . "go/types" +) + +func TestErrorCodeExamples(t *testing.T) { + walkCodes(t, func(name string, value int, spec *ast.ValueSpec) { + t.Run(name, func(t *testing.T) { + doc := spec.Doc.Text() + examples := strings.Split(doc, "Example:") + for i := 1; i < len(examples); i++ { + example := examples[i] + err := checkExample(t, example) + if err == nil { + t.Fatalf("no error in example #%d", i) + } + typerr, ok := err.(Error) + if !ok { + t.Fatalf("not a types.Error: %v", err) + } + if got := readCode(typerr); got != value { + t.Errorf("%s: example #%d returned code %d (%s), want %d", name, i, got, err, value) + } + } + }) + }) +} + +func walkCodes(t *testing.T, f func(string, int, *ast.ValueSpec)) { + t.Skip("skipping for gccgo: importer does not work") + + t.Helper() + fset := token.NewFileSet() + files, err := pkgFiles(fset, ".", parser.ParseComments) // from self_test.go + if err != nil { + t.Fatal(err) + } + conf := Config{Importer: importer.Default()} + info := &Info{ + Types: make(map[ast.Expr]TypeAndValue), + Defs: make(map[*ast.Ident]Object), + Uses: make(map[*ast.Ident]Object), + } + _, err = conf.Check("types", fset, files, info) + if err != nil { + t.Fatal(err) + } + for _, file := range files { + for _, decl := range file.Decls { + decl, ok := decl.(*ast.GenDecl) + if !ok || decl.Tok != token.CONST { + continue + } + for _, spec := range decl.Specs { + spec, ok := spec.(*ast.ValueSpec) + if !ok || len(spec.Names) == 0 { + continue + } + obj := info.ObjectOf(spec.Names[0]) + if named, ok := obj.Type().(*Named); ok && named.Obj().Name() == "errorCode" { + if len(spec.Names) != 1 { + t.Fatalf("bad Code declaration for %q: got %d names, want exactly 1", spec.Names[0].Name, len(spec.Names)) + } + codename := spec.Names[0].Name + value := int(constant.Val(obj.(*Const).Val()).(int64)) + f(codename, value, spec) + } + } + } + } +} + +func readCode(err Error) int { + v := reflect.ValueOf(err) + return int(v.FieldByName("go116code").Int()) +} + +func checkExample(t *testing.T, example string) error { + t.Helper() + fset := token.NewFileSet() + src := fmt.Sprintf("package p\n\n%s", example) + file, err := parser.ParseFile(fset, "example.go", src, 0) + if err != nil { + t.Fatal(err) + } + conf := Config{ + FakeImportC: true, + Importer: importer.Default(), + } + _, err = conf.Check("example", fset, []*ast.File{file}, nil) + return err +} + +func TestErrorCodeStyle(t *testing.T) { + // The set of error codes is large and intended to be self-documenting, so + // this test enforces some style conventions. + forbiddenInIdent := []string{ + // use invalid instead + "illegal", + // words with a common short-form + "argument", + "assertion", + "assignment", + "boolean", + "channel", + "condition", + "declaration", + "expression", + "function", + "initial", // use init for initializer, initialization, etc. + "integer", + "interface", + "iterat", // use iter for iterator, iteration, etc. + "literal", + "operation", + "package", + "pointer", + "receiver", + "signature", + "statement", + "variable", + } + forbiddenInComment := []string{ + // lhs and rhs should be spelled-out. + "lhs", "rhs", + // builtin should be hyphenated. + "builtin", + // Use dot-dot-dot. + "ellipsis", + } + nameHist := make(map[int]int) + longestName := "" + maxValue := 0 + + walkCodes(t, func(name string, value int, spec *ast.ValueSpec) { + if name == "_" { + return + } + nameHist[len(name)]++ + if value > maxValue { + maxValue = value + } + if len(name) > len(longestName) { + longestName = name + } + if token.IsExported(name) { + // This is an experimental API, and errorCode values should not be + // exported. + t.Errorf("%q is exported", name) + } + if name[0] != '_' || !token.IsExported(name[1:]) { + t.Errorf("%q should start with _, followed by an exported identifier", name) + } + lower := strings.ToLower(name) + for _, bad := range forbiddenInIdent { + if strings.Contains(lower, bad) { + t.Errorf("%q contains forbidden word %q", name, bad) + } + } + doc := spec.Doc.Text() + if !strings.HasPrefix(doc, name) { + t.Errorf("doc for %q does not start with identifier", name) + } + lowerComment := strings.ToLower(strings.TrimPrefix(doc, name)) + for _, bad := range forbiddenInComment { + if strings.Contains(lowerComment, bad) { + t.Errorf("doc for %q contains forbidden word %q", name, bad) + } + } + }) + + if testing.Verbose() { + var totChars, totCount int + for chars, count := range nameHist { + totChars += chars * count + totCount += count + } + avg := float64(totChars) / float64(totCount) + fmt.Println() + fmt.Printf("%d error codes\n", totCount) + fmt.Printf("average length: %.2f chars\n", avg) + fmt.Printf("max length: %d (%s)\n", len(longestName), longestName) + } +} diff --git a/libgo/go/go/types/errors.go b/libgo/go/go/types/errors.go index 91b077163c4..a2195011f0e 100644 --- a/libgo/go/go/types/errors.go +++ b/libgo/go/go/types/errors.go @@ -7,6 +7,7 @@ package types import ( + "errors" "fmt" "go/ast" "go/token" @@ -72,22 +73,45 @@ func (check *Checker) dump(format string, args ...interface{}) { fmt.Println(check.sprintf(format, args...)) } -func (check *Checker) err(pos token.Pos, msg string, soft bool) { +func (check *Checker) err(err error) { + if err == nil { + return + } + var e Error + isInternal := errors.As(err, &e) // Cheap trick: Don't report errors with messages containing // "invalid operand" or "invalid type" as those tend to be // follow-on errors which don't add useful information. Only // exclude them if these strings are not at the beginning, // and only if we have at least one error already reported. - if check.firstErr != nil && (strings.Index(msg, "invalid operand") > 0 || strings.Index(msg, "invalid type") > 0) { + isInvalidErr := isInternal && (strings.Index(e.Msg, "invalid operand") > 0 || strings.Index(e.Msg, "invalid type") > 0) + if check.firstErr != nil && isInvalidErr { return } - err := Error{check.fset, pos, msg, soft} + if check.errpos != nil && isInternal { + // If we have an internal error and the errpos override is set, use it to + // augment our error positioning. + // TODO(rFindley) we may also want to augment the error message and refer + // to the position (pos) in the original expression. + span := spanOf(check.errpos) + e.Pos = span.pos + e.go116start = span.start + e.go116end = span.end + err = e + } + if check.firstErr == nil { check.firstErr = err } if trace { + pos := e.Pos + msg := e.Msg + if !isInternal { + msg = err.Error() + pos = token.NoPos + } check.trace(pos, "ERROR: %s", msg) } @@ -98,26 +122,106 @@ func (check *Checker) err(pos token.Pos, msg string, soft bool) { f(err) } -func (check *Checker) error(pos token.Pos, msg string) { - check.err(pos, msg, false) +func (check *Checker) newError(at positioner, code errorCode, soft bool, msg string) error { + span := spanOf(at) + return Error{ + Fset: check.fset, + Pos: span.pos, + Msg: msg, + Soft: soft, + go116code: code, + go116start: span.start, + go116end: span.end, + } +} + +// newErrorf creates a new Error, but does not handle it. +func (check *Checker) newErrorf(at positioner, code errorCode, soft bool, format string, args ...interface{}) error { + msg := check.sprintf(format, args...) + return check.newError(at, code, soft, msg) +} + +func (check *Checker) error(at positioner, code errorCode, msg string) { + check.err(check.newError(at, code, false, msg)) +} + +func (check *Checker) errorf(at positioner, code errorCode, format string, args ...interface{}) { + check.error(at, code, check.sprintf(format, args...)) +} + +func (check *Checker) softErrorf(at positioner, code errorCode, format string, args ...interface{}) { + check.err(check.newErrorf(at, code, true, format, args...)) +} + +func (check *Checker) invalidAST(at positioner, format string, args ...interface{}) { + check.errorf(at, 0, "invalid AST: "+format, args...) } -func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) { - check.err(pos, check.sprintf(format, args...), false) +func (check *Checker) invalidArg(at positioner, code errorCode, format string, args ...interface{}) { + check.errorf(at, code, "invalid argument: "+format, args...) } -func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) { - check.err(pos, check.sprintf(format, args...), true) +func (check *Checker) invalidOp(at positioner, code errorCode, format string, args ...interface{}) { + check.errorf(at, code, "invalid operation: "+format, args...) } -func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) { - check.errorf(pos, "invalid AST: "+format, args...) +// The positioner interface is used to extract the position of type-checker +// errors. +type positioner interface { + Pos() token.Pos } -func (check *Checker) invalidArg(pos token.Pos, format string, args ...interface{}) { - check.errorf(pos, "invalid argument: "+format, args...) +// posSpan holds a position range along with a highlighted position within that +// range. This is used for positioning errors, with pos by convention being the +// first position in the source where the error is known to exist, and start +// and end defining the full span of syntax being considered when the error was +// detected. Invariant: start <= pos < end || start == pos == end. +type posSpan struct { + start, pos, end token.Pos } -func (check *Checker) invalidOp(pos token.Pos, format string, args ...interface{}) { - check.errorf(pos, "invalid operation: "+format, args...) +func (e posSpan) Pos() token.Pos { + return e.pos +} + +// inNode creates a posSpan for the given node. +// Invariant: node.Pos() <= pos < node.End() (node.End() is the position of the +// first byte after node within the source). +func inNode(node ast.Node, pos token.Pos) posSpan { + start, end := node.Pos(), node.End() + if debug { + assert(start <= pos && pos < end) + } + return posSpan{start, pos, end} +} + +// atPos wraps a token.Pos to implement the positioner interface. +type atPos token.Pos + +func (s atPos) Pos() token.Pos { + return token.Pos(s) +} + +// spanOf extracts an error span from the given positioner. By default this is +// the trivial span starting and ending at pos, but this span is expanded when +// the argument naturally corresponds to a span of source code. +func spanOf(at positioner) posSpan { + switch x := at.(type) { + case nil: + panic("internal error: nil") + case posSpan: + return x + case ast.Node: + pos := x.Pos() + return posSpan{pos, pos, x.End()} + case *operand: + if x.expr != nil { + pos := x.Pos() + return posSpan{pos, pos, x.expr.End()} + } + return posSpan{token.NoPos, token.NoPos, token.NoPos} + default: + pos := at.Pos() + return posSpan{pos, pos, pos} + } } diff --git a/libgo/go/go/types/expr.go b/libgo/go/go/types/expr.go index d1e892a9b70..eb2056125a7 100644 --- a/libgo/go/go/types/expr.go +++ b/libgo/go/go/types/expr.go @@ -68,11 +68,11 @@ var unaryOpPredicates = opPredicates{ func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool { if pred := m[op]; pred != nil { if !pred(x.typ) { - check.invalidOp(x.pos(), "operator %s not defined for %s", op, x) + check.invalidOp(x, _UndefinedOp, "operator %s not defined for %s", op, x) return false } } else { - check.invalidAST(x.pos(), "unknown operator %s", op) + check.invalidAST(x, "unknown operator %s", op) return false } return true @@ -85,7 +85,7 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) { // spec: "As an exception to the addressability // requirement x may also be a composite literal." if _, ok := unparen(x.expr).(*ast.CompositeLit); !ok && x.mode != variable { - check.invalidOp(x.pos(), "cannot take address of %s", x) + check.invalidOp(x, _UnaddressableOperand, "cannot take address of %s", x) x.mode = invalid return } @@ -96,12 +96,12 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) { case token.ARROW: typ, ok := x.typ.Underlying().(*Chan) if !ok { - check.invalidOp(x.pos(), "cannot receive from non-channel %s", x) + check.invalidOp(x, _InvalidReceive, "cannot receive from non-channel %s", x) x.mode = invalid return } if typ.dir == SendOnly { - check.invalidOp(x.pos(), "cannot receive from send-only channel %s", x) + check.invalidOp(x, _InvalidReceive, "cannot receive from send-only channel %s", x) x.mode = invalid return } @@ -329,11 +329,20 @@ func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *c return false } -// representable checks that a constant operand is representable in the given basic type. +// representable checks that a constant operand is representable in the given +// basic type. func (check *Checker) representable(x *operand, typ *Basic) { + if err := check.isRepresentable(x, typ); err != nil { + x.mode = invalid + check.err(err) + } +} + +func (check *Checker) isRepresentable(x *operand, typ *Basic) error { assert(x.mode == constant_) if !representableConst(x.val, check, typ, &x.val) { var msg string + var code errorCode if isNumeric(x.typ) && isNumeric(typ) { // numeric conversion : error msg // @@ -344,15 +353,18 @@ func (check *Checker) representable(x *operand, typ *Basic) { // if !isInteger(x.typ) && isInteger(typ) { msg = "%s truncated to %s" + code = _TruncatedFloat } else { msg = "%s overflows %s" + code = _NumericOverflow } } else { msg = "cannot convert %s to %s" + code = _InvalidConstVal } - check.errorf(x.pos(), msg, x, typ) - x.mode = invalid + return check.newErrorf(x, code, false, msg, x, typ) } + return nil } // updateExprType updates the type of x to typ and invokes itself @@ -458,7 +470,7 @@ func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) { // We already know from the shift check that it is representable // as an integer if it is a constant. if !isInteger(typ) { - check.invalidOp(x.Pos(), "shifted operand %s (type %s) must be integer", x, typ) + check.invalidOp(x, _InvalidShiftOperand, "shifted operand %s (type %s) must be integer", x, typ) return } // Even if we have an integer, if the value is a constant we @@ -488,12 +500,16 @@ func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) { // convertUntyped attempts to set the type of an untyped value to the target type. func (check *Checker) convertUntyped(x *operand, target Type) { - if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] { - return + if err := check.canConvertUntyped(x, target); err != nil { + x.mode = invalid + check.err(err) } +} - // TODO(gri) Sloppy code - clean up. This function is central - // to assignment and expression checking. +func (check *Checker) canConvertUntyped(x *operand, target Type) error { + if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] { + return nil + } if isUntyped(target) { // both x and target are untyped @@ -505,89 +521,101 @@ func (check *Checker) convertUntyped(x *operand, target Type) { check.updateExprType(x.expr, target, false) } } else if xkind != tkind { - goto Error + return check.newErrorf(x, _InvalidUntypedConversion, false, "cannot convert %s to %s", x, target) } - return + return nil } - // typed target + if t, ok := target.Underlying().(*Basic); ok && x.mode == constant_ { + if err := check.isRepresentable(x, t); err != nil { + return err + } + // Expression value may have been rounded - update if needed. + check.updateExprVal(x.expr, x.val) + } else { + newTarget := check.implicitType(x, target) + if newTarget == nil { + return check.newErrorf(x, _InvalidUntypedConversion, false, "cannot convert %s to %s", x, target) + } + target = newTarget + } + x.typ = target + // Even though implicitType can return UntypedNil, this value is final: the + // predeclared identifier nil has no type. + check.updateExprType(x.expr, target, true) + return nil +} + +// implicitType returns the implicit type of x when used in a context where the +// target type is expected. If no such implicit conversion is possible, it +// returns nil. +func (check *Checker) implicitType(x *operand, target Type) Type { + assert(isUntyped(x.typ)) switch t := target.Underlying().(type) { case *Basic: - if x.mode == constant_ { - check.representable(x, t) - if x.mode == invalid { - return + assert(x.mode != constant_) + // Non-constant untyped values may appear as the + // result of comparisons (untyped bool), intermediate + // (delayed-checked) rhs operands of shifts, and as + // the value nil. + switch x.typ.(*Basic).kind { + case UntypedBool: + if !isBoolean(target) { + return nil } - // expression value may have been rounded - update if needed - check.updateExprVal(x.expr, x.val) - } else { - // Non-constant untyped values may appear as the - // result of comparisons (untyped bool), intermediate - // (delayed-checked) rhs operands of shifts, and as - // the value nil. - switch x.typ.(*Basic).kind { - case UntypedBool: - if !isBoolean(target) { - goto Error - } - case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex: - if !isNumeric(target) { - goto Error - } - case UntypedString: - // Non-constant untyped string values are not - // permitted by the spec and should not occur. - unreachable() - case UntypedNil: - // Unsafe.Pointer is a basic type that includes nil. - if !hasNil(target) { - goto Error - } - default: - goto Error + case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex: + if !isNumeric(target) { + return nil } + case UntypedString: + // Non-constant untyped string values are not permitted by the spec and + // should not occur during normal typechecking passes, but this path is + // reachable via the AssignableTo API. + if !isString(target) { + return nil + } + case UntypedNil: + // Unsafe.Pointer is a basic type that includes nil. + if !hasNil(target) { + return nil + } + default: + return nil } case *Interface: - // 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 - // (this is important for tools such as go vet which need - // the dynamic type for argument checking of say, print + // Values must have concrete dynamic types. If the value is nil, + // keep it untyped (this is important for tools such as go vet which + // need the dynamic type for argument checking of say, print // functions) if x.isNil() { - target = Typ[UntypedNil] - } else { - // cannot assign untyped values to non-empty interfaces - check.completeInterface(t) - if !t.Empty() { - goto Error - } - target = Default(x.typ) + return Typ[UntypedNil] } + // cannot assign untyped values to non-empty interfaces + check.completeInterface(t) + if !t.Empty() { + return nil + } + return Default(x.typ) case *Pointer, *Signature, *Slice, *Map, *Chan: if !x.isNil() { - goto Error + return nil } - // keep nil untyped - see comment for interfaces, above - target = Typ[UntypedNil] + // Keep nil untyped - see comment for interfaces, above. + return Typ[UntypedNil] default: - goto Error + return nil } - - x.typ = target - check.updateExprType(x.expr, target, true) // UntypedNils are final - return - -Error: - check.errorf(x.pos(), "cannot convert %s to %s", x, target) - x.mode = invalid + return target } func (check *Checker) comparison(x, y *operand, op token.Token) { // spec: "In any comparison, the first operand must be assignable // to the type of the second operand, or vice versa." err := "" - if x.assignableTo(check, y.typ, nil) || y.assignableTo(check, x.typ, nil) { + var code errorCode + xok, _ := x.assignableTo(check, y.typ, nil) + yok, _ := y.assignableTo(check, x.typ, nil) + if xok || yok { defined := false switch op { case token.EQL, token.NEQ: @@ -605,13 +633,15 @@ func (check *Checker) comparison(x, y *operand, op token.Token) { typ = y.typ } err = check.sprintf("operator %s not defined for %s", op, typ) + code = _UndefinedOp } } else { err = check.sprintf("mismatched types %s and %s", x.typ, y.typ) + code = _MismatchedTypes } if err != "" { - check.errorf(x.pos(), "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err) + check.errorf(x, code, "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err) x.mode = invalid return } @@ -648,7 +678,7 @@ func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) { // as an integer. Nothing to do. } else { // shift has no chance - check.invalidOp(x.pos(), "shifted operand %s must be integer", x) + check.invalidOp(x, _InvalidShiftOperand, "shifted operand %s must be integer", x) x.mode = invalid return } @@ -665,7 +695,7 @@ func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) { return } default: - check.invalidOp(y.pos(), "shift count %s must be integer", y) + check.invalidOp(y, _InvalidShiftCount, "shift count %s must be integer", y) x.mode = invalid return } @@ -678,7 +708,7 @@ func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) { yval = constant.ToInt(y.val) assert(yval.Kind() == constant.Int) if constant.Sign(yval) < 0 { - check.invalidOp(y.pos(), "negative shift count %s", y) + check.invalidOp(y, _InvalidShiftCount, "negative shift count %s", y) x.mode = invalid return } @@ -690,7 +720,7 @@ func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) { const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 s, ok := constant.Uint64Val(yval) if !ok || s > shiftBound { - check.invalidOp(y.pos(), "invalid shift count %s", y) + check.invalidOp(y, _InvalidShiftCount, "invalid shift count %s", y) x.mode = invalid return } @@ -747,7 +777,7 @@ func (check *Checker) shift(x, y *operand, e *ast.BinaryExpr, op token.Token) { // non-constant shift - lhs must be an integer if !isInteger(x.typ) { - check.invalidOp(x.pos(), "shifted operand %s must be integer", x) + check.invalidOp(x, _InvalidShiftOperand, "shifted operand %s must be integer", x) x.mode = invalid return } @@ -772,7 +802,7 @@ var binaryOpPredicates = opPredicates{ } // The binary expression e may be nil. It's passed in for better error messages only. -func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token) { +func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token, opPos token.Pos) { var y operand check.expr(x, lhs) @@ -811,7 +841,11 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o // 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] { - check.invalidOp(x.pos(), "mismatched types %s and %s", x.typ, y.typ) + var posn positioner = x + if e != nil { + posn = e + } + check.invalidOp(posn, _MismatchedTypes, "mismatched types %s and %s", x.typ, y.typ) } x.mode = invalid return @@ -825,7 +859,7 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o if op == token.QUO || op == token.REM { // check for zero divisor if (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 { - check.invalidOp(y.pos(), "division by zero") + check.invalidOp(&y, _DivByZero, "division by zero") x.mode = invalid return } @@ -835,7 +869,7 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o re, im := constant.Real(y.val), constant.Imag(y.val) re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im) if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 { - check.invalidOp(y.pos(), "division by zero") + check.invalidOp(&y, _DivByZero, "division by zero") x.mode = invalid return } @@ -851,6 +885,14 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o op = token.QUO_ASSIGN } x.val = constant.BinaryOp(xval, op, yval) + // report error if valid operands lead to an invalid result + if xval.Kind() != constant.Unknown && yval.Kind() != constant.Unknown && x.val.Kind() == constant.Unknown { + // TODO(gri) We should report exactly what went wrong. At the + // moment we don't have the (go/constant) API for that. + // See also TODO in go/constant/value.go. + check.errorf(atPos(opPos), _InvalidConstVal, "constant result is not representable") + // TODO(gri) Should we mark operands with unknown values as invalid? + } // Typed constants must be representable in // their type after each constant operation. if isTyped(typ) { @@ -888,7 +930,7 @@ func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) { // the index must be of integer type if !isInteger(x.typ) { - check.invalidArg(x.pos(), "index %s must be integer", &x) + check.invalidArg(&x, _InvalidIndex, "index %s must be integer", &x) return } @@ -898,13 +940,13 @@ func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) { // a constant index i must be in bounds if constant.Sign(x.val) < 0 { - check.invalidArg(x.pos(), "index %s must not be negative", &x) + check.invalidArg(&x, _InvalidIndex, "index %s must not be negative", &x) return } v, valid := constant.Int64Val(constant.ToInt(x.val)) if !valid || max >= 0 && v >= max { - check.errorf(x.pos(), "index %s is out of bounds", &x) + check.errorf(&x, _InvalidIndex, "index %s is out of bounds", &x) return } @@ -930,12 +972,12 @@ func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 index = i validIndex = true } else { - check.errorf(e.Pos(), "index %s must be integer constant", kv.Key) + check.errorf(e, _InvalidLitIndex, "index %s must be integer constant", kv.Key) } } eval = kv.Value } else if length >= 0 && index >= length { - check.errorf(e.Pos(), "index %d is out of bounds (>= %d)", index, length) + check.errorf(e, _OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length) } else { validIndex = true } @@ -943,7 +985,7 @@ func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 // if we have a valid index, check for duplicate entries if validIndex { if visited[index] { - check.errorf(e.Pos(), "duplicate index %d in array or slice literal", index) + check.errorf(e, _DuplicateLitKey, "duplicate index %d in array or slice literal", index) } visited[index] = true } @@ -1033,13 +1075,17 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { case *ast.Ellipsis: // ellipses are handled explicitly where they are legal // (array composite literals and parameter lists) - check.error(e.Pos(), "invalid use of '...'") + check.error(e, _BadDotDotDotSyntax, "invalid use of '...'") goto Error case *ast.BasicLit: x.setConst(e.Kind, e.Value) if x.mode == invalid { - check.invalidAST(e.Pos(), "invalid literal %v", e.Value) + // The parser already establishes syntactic correctness. + // If we reach here it's because of number under-/overflow. + // TODO(gri) setConst (and in turn the go/constant package) + // should return an error describing the issue. + check.errorf(e, _InvalidConstVal, "malformed constant: %s", e.Value) goto Error } @@ -1060,7 +1106,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { x.mode = value x.typ = sig } else { - check.invalidAST(e.Pos(), "invalid function literal %s", e) + check.invalidAST(e, "invalid function literal %s", e) goto Error } @@ -1092,7 +1138,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { default: // TODO(gri) provide better error messages depending on context - check.error(e.Pos(), "missing type in composite literal") + check.error(e, _UntypedLit, "missing type in composite literal") goto Error } @@ -1108,7 +1154,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { for _, e := range e.Elts { kv, _ := e.(*ast.KeyValueExpr) if kv == nil { - check.error(e.Pos(), "mixture of field:value and value elements in struct literal") + check.error(e, _MixedStructLit, "mixture of field:value and value elements in struct literal") continue } key, _ := kv.Key.(*ast.Ident) @@ -1116,12 +1162,12 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { // so we don't drop information on the floor check.expr(x, kv.Value) if key == nil { - check.errorf(kv.Pos(), "invalid field name %s in struct literal", kv.Key) + check.errorf(kv, _InvalidLitField, "invalid field name %s in struct literal", kv.Key) continue } i := fieldIndex(utyp.fields, check.pkg, key.Name) if i < 0 { - check.errorf(kv.Pos(), "unknown field %s in struct literal", key.Name) + check.errorf(kv, _MissingLitField, "unknown field %s in struct literal", key.Name) continue } fld := fields[i] @@ -1130,7 +1176,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { check.assignment(x, etyp, "struct literal") // 0 <= i < len(fields) if visited[i] { - check.errorf(kv.Pos(), "duplicate field name %s in struct literal", key.Name) + check.errorf(kv, _DuplicateLitField, "duplicate field name %s in struct literal", key.Name) continue } visited[i] = true @@ -1139,25 +1185,27 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { // no element must have a key for i, e := range e.Elts { if kv, _ := e.(*ast.KeyValueExpr); kv != nil { - check.error(kv.Pos(), "mixture of field:value and value elements in struct literal") + check.error(kv, _MixedStructLit, "mixture of field:value and value elements in struct literal") continue } check.expr(x, e) if i >= len(fields) { - check.error(x.pos(), "too many values in struct literal") + check.error(x, _InvalidStructLit, "too many values in struct literal") break // cannot continue } // i < len(fields) fld := fields[i] if !fld.Exported() && fld.pkg != check.pkg { - check.errorf(x.pos(), "implicit assignment to unexported field %s in %s literal", fld.name, typ) + check.errorf(x, + _UnexportedLitField, + "implicit assignment to unexported field %s in %s literal", fld.name, typ) continue } etyp := fld.typ check.assignment(x, etyp, "struct literal") } if len(e.Elts) < len(fields) { - check.error(e.Rbrace, "too few values in struct literal") + check.error(inNode(e, e.Rbrace), _InvalidStructLit, "too few values in struct literal") // ok to continue } } @@ -1167,7 +1215,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { // 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") + check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration") goto Error } n := check.indexedElts(e.Elts, utyp.elem, utyp.len) @@ -1194,7 +1242,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { // Prevent crash if the slice referred to is not yet set up. // See analogous comment for *Array. if utyp.elem == nil { - check.error(e.Pos(), "illegal cycle in type declaration") + check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration") goto Error } check.indexedElts(e.Elts, utyp.elem, -1) @@ -1203,14 +1251,14 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { // Prevent crash if the map referred to is not yet set up. // See analogous comment for *Array. if utyp.key == nil || utyp.elem == nil { - check.error(e.Pos(), "illegal cycle in type declaration") + check.error(e, _InvalidTypeCycle, "illegal cycle in type declaration") goto Error } visited := make(map[interface{}][]Type, len(e.Elts)) for _, e := range e.Elts { kv, _ := e.(*ast.KeyValueExpr) if kv == nil { - check.error(e.Pos(), "missing key in map literal") + check.error(e, _MissingLitKey, "missing key in map literal") continue } check.exprWithHint(x, kv.Key, utyp.key) @@ -1235,7 +1283,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { visited[xkey] = nil } if duplicate { - check.errorf(x.pos(), "duplicate key %s in map literal", x.val) + check.errorf(x, _DuplicateLitKey, "duplicate key %s in map literal", x.val) continue } } @@ -1257,7 +1305,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { } // if utyp is invalid, an error was reported before if utyp != Typ[Invalid] { - check.errorf(e.Pos(), "invalid composite literal type %s", typ) + check.errorf(e, _InvalidLit, "invalid composite literal type %s", typ) goto Error } } @@ -1321,9 +1369,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { var key operand check.expr(&key, e.Index) check.assignment(&key, typ.key, "map index") - if x.mode == invalid { - goto Error - } + // ok to continue even if indexing failed - map element type is known x.mode = mapindex x.typ = typ.elem x.expr = e @@ -1331,12 +1377,12 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { } if !valid { - check.invalidOp(x.pos(), "cannot index %s", x) + check.invalidOp(x, _NonIndexableOperand, "cannot index %s", x) goto Error } if e.Index == nil { - check.invalidAST(e.Pos(), "missing index for %s", x) + check.invalidAST(e, "missing index for %s", x) goto Error } @@ -1356,7 +1402,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { case *Basic: if isString(typ) { if e.Slice3 { - check.invalidOp(x.pos(), "3-index slice of string") + check.invalidOp(x, _InvalidSliceExpr, "3-index slice of string") goto Error } valid = true @@ -1374,7 +1420,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { valid = true length = typ.len if x.mode != variable { - check.invalidOp(x.pos(), "cannot slice %s (value not addressable)", x) + check.invalidOp(x, _NonSliceableOperand, "cannot slice %s (value not addressable)", x) goto Error } x.typ = &Slice{elem: typ.elem} @@ -1392,7 +1438,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { } if !valid { - check.invalidOp(x.pos(), "cannot slice %s", x) + check.invalidOp(x, _NonSliceableOperand, "cannot slice %s", x) goto Error } @@ -1400,7 +1446,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { // spec: "Only the first index may be omitted; it defaults to 0." if e.Slice3 && (e.High == nil || e.Max == nil) { - check.error(e.Rbrack, "2nd and 3rd index required in 3-index slice") + check.invalidAST(inNode(e, e.Rbrack), "2nd and 3rd index required in 3-index slice") goto Error } @@ -1437,7 +1483,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { if x > 0 { for _, y := range ind[i+1:] { if y >= 0 && x > y { - check.errorf(e.Rbrack, "invalid slice indices: %d > %d", x, y) + check.errorf(inNode(e, e.Rbrack), _SwappedSliceIndices, "swapped slice indices: %d > %d", x, y) break L // only report one error, ok to continue } } @@ -1451,19 +1497,21 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { } xtyp, _ := x.typ.Underlying().(*Interface) if xtyp == nil { - check.invalidOp(x.pos(), "%s is not an interface", x) + check.invalidOp(x, _InvalidAssert, "%s is not an interface", x) goto Error } // x.(type) expressions are handled explicitly in type switches if e.Type == nil { - check.invalidAST(e.Pos(), "use of .(type) outside type switch") + // Don't use invalidAST because this can occur in the AST produced by + // go/parser. + check.error(e, _BadTypeKeyword, "use of .(type) outside type switch") goto Error } T := check.typ(e.Type) if T == Typ[Invalid] { goto Error } - check.typeAssertion(x.pos(), x, xtyp, T) + check.typeAssertion(x, x, xtyp, T) x.mode = commaok x.typ = T @@ -1482,7 +1530,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { x.mode = variable x.typ = typ.base } else { - check.invalidOp(x.pos(), "cannot indirect %s", x) + check.invalidOp(x, _InvalidIndirection, "cannot indirect %s", x) goto Error } } @@ -1502,14 +1550,14 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { } case *ast.BinaryExpr: - check.binary(x, e, e.X, e.Y, e.Op) + check.binary(x, e, e.X, e.Y, e.Op, e.OpPos) if x.mode == invalid { goto Error } case *ast.KeyValueExpr: // key:value expressions are handled in composite literals - check.invalidAST(e.Pos(), "no key:value expected") + check.invalidAST(e, "no key:value expected") goto Error case *ast.ArrayType, *ast.StructType, *ast.FuncType, @@ -1561,7 +1609,7 @@ func keyVal(x constant.Value) interface{} { } // typeAssertion checks that x.(T) is legal; xtyp must be the type of x. -func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, T Type) { +func (check *Checker) typeAssertion(at positioner, x *operand, xtyp *Interface, T Type) { method, wrongType := check.assertableTo(xtyp, T) if method == nil { return @@ -1576,7 +1624,7 @@ func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, } else { msg = "missing method " + method.name } - check.errorf(pos, "%s cannot have dynamic type %s (%s)", x, T, msg) + check.errorf(at, _ImpossibleAssert, "%s cannot have dynamic type %s (%s)", x, T, msg) } func (check *Checker) singleValue(x *operand) { @@ -1584,7 +1632,7 @@ func (check *Checker) singleValue(x *operand) { // tuple types are never named - no need for underlying type below if t, ok := x.typ.(*Tuple); ok { assert(t.Len() != 1) - check.errorf(x.pos(), "%d-valued %s where single value is expected", t.Len(), x) + check.errorf(x, _TooManyValues, "%d-valued %s where single value is expected", t.Len(), x) x.mode = invalid } } @@ -1603,17 +1651,21 @@ func (check *Checker) expr(x *operand, e ast.Expr) { func (check *Checker) multiExpr(x *operand, e ast.Expr) { check.rawExpr(x, e, nil) var msg string + var code errorCode switch x.mode { default: return case novalue: msg = "%s used as value" + code = _TooManyValues case builtin: msg = "%s must be called" + code = _UncalledBuiltin case typexpr: msg = "%s is not an expression" + code = _NotAnExpr } - check.errorf(x.pos(), msg, x) + check.errorf(x, code, msg, x) x.mode = invalid } @@ -1626,17 +1678,21 @@ func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) { check.rawExpr(x, e, hint) check.singleValue(x) var msg string + var code errorCode switch x.mode { default: return case novalue: msg = "%s used as value" + code = _TooManyValues case builtin: msg = "%s must be called" + code = _UncalledBuiltin case typexpr: msg = "%s is not an expression" + code = _NotAnExpr } - check.errorf(x.pos(), msg, x) + check.errorf(x, code, msg, x) x.mode = invalid } @@ -1647,7 +1703,7 @@ func (check *Checker) exprOrType(x *operand, e ast.Expr) { check.rawExpr(x, e, nil) check.singleValue(x) if x.mode == novalue { - check.errorf(x.pos(), "%s used as value or type", x) + check.errorf(x, _NotAnExpr, "%s used as value or type", x) x.mode = invalid } } diff --git a/libgo/go/go/types/gotype.go b/libgo/go/go/types/gotype.go index 19dd702c451..52709df17bd 100644 --- a/libgo/go/go/types/gotype.go +++ b/libgo/go/go/types/gotype.go @@ -48,9 +48,9 @@ The flags are: Flags controlling additional output: -ast - print AST (forces -seq) + print AST -trace - print parse trace (forces -seq) + print parse trace -comments parse comments (ignored unless -ast or -trace is provided) -panic @@ -88,7 +88,7 @@ import ( "go/scanner" "go/token" "go/types" - "io/ioutil" + "io" "os" "path/filepath" "sync" @@ -104,8 +104,8 @@ var ( compiler = flag.String("c", "source", "compiler used for installed packages (gc, gccgo, or source)") // additional output control - printAST = flag.Bool("ast", false, "print AST (forces -seq)") - printTrace = flag.Bool("trace", false, "print parse trace (forces -seq)") + printAST = flag.Bool("ast", false, "print AST") + printTrace = flag.Bool("trace", false, "print parse trace") parseComments = flag.Bool("comments", false, "parse comments (ignored unless -ast or -trace is provided)") panicOnError = flag.Bool("panic", false, "panic on first error") ) @@ -191,7 +191,7 @@ func parse(filename string, src interface{}) (*ast.File, error) { } func parseStdin() (*ast.File, error) { - src, err := ioutil.ReadAll(os.Stdin) + src, err := io.ReadAll(os.Stdin) if err != nil { return nil, err } diff --git a/libgo/go/go/types/hilbert_test.go b/libgo/go/go/types/hilbert_test.go index 91c2ec97caa..791357a471c 100644 --- a/libgo/go/go/types/hilbert_test.go +++ b/libgo/go/go/types/hilbert_test.go @@ -12,7 +12,7 @@ import ( "go/importer" "go/parser" "go/token" - "io/ioutil" + "os" "testing" . "go/types" @@ -29,7 +29,7 @@ func TestHilbert(t *testing.T) { // generate source src := program(*H, *out) if *out != "" { - ioutil.WriteFile(*out, src, 0666) + os.WriteFile(*out, src, 0666) return } diff --git a/libgo/go/go/types/initorder.go b/libgo/go/go/types/initorder.go index 9d5e9165ad8..77a739c7c14 100644 --- a/libgo/go/go/types/initorder.go +++ b/libgo/go/go/types/initorder.go @@ -151,14 +151,14 @@ func findPath(objMap map[Object]*declInfo, from, to Object, seen map[Object]bool // reportCycle reports an error for the given cycle. func (check *Checker) reportCycle(cycle []Object) { obj := cycle[0] - check.errorf(obj.Pos(), "initialization cycle for %s", obj.Name()) + check.errorf(obj, _InvalidInitCycle, "initialization cycle for %s", obj.Name()) // subtle loop: print cycle[i] for i = 0, n-1, n-2, ... 1 for len(cycle) = n for i := len(cycle) - 1; i >= 0; i-- { - check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented + check.errorf(obj, _InvalidInitCycle, "\t%s refers to", obj.Name()) // secondary error, \t indented obj = cycle[i] } // print cycle[0] again to close the cycle - check.errorf(obj.Pos(), "\t%s", obj.Name()) + check.errorf(obj, _InvalidInitCycle, "\t%s", obj.Name()) } // ---------------------------------------------------------------------------- diff --git a/libgo/go/go/types/issues_test.go b/libgo/go/go/types/issues_test.go index f59f9053979..34850eb0348 100644 --- a/libgo/go/go/types/issues_test.go +++ b/libgo/go/go/types/issues_test.go @@ -12,6 +12,7 @@ import ( "go/ast" "go/importer" "go/parser" + "go/token" "internal/testenv" "sort" "strings" @@ -523,3 +524,28 @@ func TestIssue34921(t *testing.T) { pkg = res // res is imported by the next package in this test } } + +func TestIssue43088(t *testing.T) { + // type T1 struct { + // _ T2 + // } + // + // type T2 struct { + // _ struct { + // _ T2 + // } + // } + n1 := NewTypeName(token.NoPos, nil, "T1", nil) + T1 := NewNamed(n1, nil, nil) + n2 := NewTypeName(token.NoPos, nil, "T2", nil) + T2 := NewNamed(n2, nil, nil) + s1 := NewStruct([]*Var{NewField(token.NoPos, nil, "_", T2, false)}, nil) + T1.SetUnderlying(s1) + s2 := NewStruct([]*Var{NewField(token.NoPos, nil, "_", T2, false)}, nil) + s3 := NewStruct([]*Var{NewField(token.NoPos, nil, "_", s2, false)}, nil) + T2.SetUnderlying(s3) + + // These calls must terminate (no endless recursion). + Comparable(T1) + Comparable(T2) +} diff --git a/libgo/go/go/types/labels.go b/libgo/go/go/types/labels.go index 3b43b4ba05c..8cf6e63645e 100644 --- a/libgo/go/go/types/labels.go +++ b/libgo/go/go/types/labels.go @@ -22,20 +22,23 @@ func (check *Checker) labels(body *ast.BlockStmt) { // for the respective gotos. for _, jmp := range fwdJumps { var msg string + var code errorCode name := jmp.Label.Name if alt := all.Lookup(name); alt != nil { msg = "goto %s jumps into block" alt.(*Label).used = true // avoid another error + code = _JumpIntoBlock } else { msg = "label %s not declared" + code = _UndeclaredLabel } - check.errorf(jmp.Label.Pos(), msg, name) + check.errorf(jmp.Label, code, msg, name) } // spec: "It is illegal to define a label that is never used." for _, obj := range all.elems { if lbl := obj.(*Label); !lbl.used { - check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name) + check.softErrorf(lbl, _UnusedLabel, "label %s declared but not used", lbl.name) } } } @@ -133,7 +136,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele if name := s.Label.Name; name != "_" { lbl := NewLabel(s.Label.Pos(), check.pkg, name) if alt := all.Insert(lbl); alt != nil { - check.softErrorf(lbl.pos, "label %s already declared", name) + check.softErrorf(lbl, _DuplicateLabel, "label %s already declared", name) check.reportAltDecl(alt) // ok to continue } else { @@ -149,7 +152,8 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele check.recordUse(jmp.Label, lbl) if jumpsOverVarDecl(jmp) { check.softErrorf( - jmp.Label.Pos(), + jmp.Label, + _JumpOverDecl, "goto %s jumps over variable declaration at line %d", name, check.fset.Position(varDeclPos).Line, @@ -187,7 +191,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele } } if !valid { - check.errorf(s.Label.Pos(), "invalid break label %s", name) + check.errorf(s.Label, _MisplacedLabel, "invalid break label %s", name) return } @@ -202,7 +206,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele } } if !valid { - check.errorf(s.Label.Pos(), "invalid continue label %s", name) + check.errorf(s.Label, _MisplacedLabel, "invalid continue label %s", name) return } @@ -214,7 +218,7 @@ func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.Labele } default: - check.invalidAST(s.Pos(), "branch statement: %s %s", s.Tok, name) + check.invalidAST(s, "branch statement: %s %s", s.Tok, name) return } diff --git a/libgo/go/go/types/operand.go b/libgo/go/go/types/operand.go index 80d11e2f215..3e1ac312d9a 100644 --- a/libgo/go/go/types/operand.go +++ b/libgo/go/go/types/operand.go @@ -59,10 +59,10 @@ type operand struct { id builtinId } -// pos returns the position of the expression corresponding to x. +// Pos returns the position of the expression corresponding to x. // If x is invalid the position is token.NoPos. // -func (x *operand) pos() token.Pos { +func (x *operand) Pos() token.Pos { // x.expr may not be set if x is invalid if x.expr == nil { return token.NoPos @@ -195,9 +195,15 @@ func (x *operand) setConst(tok token.Token, lit string) { unreachable() } + val := constant.MakeFromLiteral(lit, tok, 0) + if val.Kind() == constant.Unknown { + x.mode = invalid + x.typ = Typ[Invalid] + return + } x.mode = constant_ x.typ = Typ[kind] - x.val = constant.MakeFromLiteral(lit, tok, 0) + x.val = val } // isNil reports whether x is the nil value. @@ -205,60 +211,39 @@ func (x *operand) isNil() bool { return x.mode == value && x.typ == Typ[UntypedNil] } -// TODO(gri) The functions operand.assignableTo, checker.convertUntyped, -// checker.representable, and checker.assignment are -// overlapping in functionality. Need to simplify and clean up. - -// assignableTo reports whether x is assignable to a variable of type T. -// If the result is false and a non-nil reason is provided, it may be set -// to a more detailed explanation of the failure (result != ""). -// The check parameter may be nil if assignableTo is invoked through -// an exported API call, i.e., when all methods have been type-checked. -func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool { +// assignableTo reports whether x is assignable to a variable of type T. If the +// result is false and a non-nil reason is provided, it may be set to a more +// detailed explanation of the failure (result != ""). The check parameter may +// be nil if assignableTo is invoked through an exported API call, i.e., when +// all methods have been type-checked. +func (x *operand) assignableTo(check *Checker, T Type, reason *string) (bool, errorCode) { if x.mode == invalid || T == Typ[Invalid] { - return true // avoid spurious errors + return true, 0 // avoid spurious errors } V := x.typ // x's type is identical to T if check.identical(V, T) { - return true + return true, 0 } Vu := V.Underlying() Tu := T.Underlying() - // x is an untyped value representable by a value of type T - // TODO(gri) This is borrowing from checker.convertUntyped and - // checker.representable. Need to clean up. + // x is an untyped value representable by a value of type T. if isUntyped(Vu) { - switch t := Tu.(type) { - case *Basic: - if x.isNil() && t.kind == UnsafePointer { - return true - } - if x.mode == constant_ { - return representableConst(x.val, check, t, nil) - } - // The result of a comparison is an untyped boolean, - // but may not be a constant. - if Vb, _ := Vu.(*Basic); Vb != nil { - 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() + if t, ok := Tu.(*Basic); ok && x.mode == constant_ { + return representableConst(x.val, check, t, nil), _IncompatibleAssign } + return check.implicitType(x, Tu) != nil, _IncompatibleAssign } // Vu is typed - // x's type V and T have identical underlying types - // and at least one of V or T is not a named type + // x's type V and T have identical underlying types and at least one of V or + // T is not a named type. if check.identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) { - return true + return true, 0 } // T is an interface type and x implements T @@ -276,9 +261,9 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool { *reason = "missing method " + m.Name() } } - return false + return false, _InvalidIfaceAssign } - return true + return true, 0 } // x is a bidirectional channel value, T is a channel @@ -286,9 +271,13 @@ func (x *operand) assignableTo(check *Checker, T Type, reason *string) bool { // 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 && check.identical(Vc.elem, Tc.elem) { - return !isNamed(V) || !isNamed(T) + if !isNamed(V) || !isNamed(T) { + return true, 0 + } else { + return false, _InvalidChanAssign + } } } - return false + return false, _IncompatibleAssign } diff --git a/libgo/go/go/types/predicates.go b/libgo/go/go/types/predicates.go index 057908eacd8..148edbfb767 100644 --- a/libgo/go/go/types/predicates.go +++ b/libgo/go/go/types/predicates.go @@ -79,6 +79,18 @@ func IsInterface(typ Type) bool { // Comparable reports whether values of type T are comparable. func Comparable(T Type) bool { + return comparable(T, nil) +} + +func comparable(T Type, seen map[Type]bool) bool { + if seen[T] { + return true + } + if seen == nil { + seen = make(map[Type]bool) + } + seen[T] = true + switch t := T.Underlying().(type) { case *Basic: // assume invalid types to be comparable @@ -88,13 +100,13 @@ func Comparable(T Type) bool { return true case *Struct: for _, f := range t.fields { - if !Comparable(f.typ) { + if !comparable(f.typ, seen) { return false } } return true case *Array: - return Comparable(t.elem) + return comparable(t.elem, seen) } return false } diff --git a/libgo/go/go/types/resolver.go b/libgo/go/go/types/resolver.go index 078adc5ec78..b637f8b8cac 100644 --- a/libgo/go/go/types/resolver.go +++ b/libgo/go/go/types/resolver.go @@ -17,12 +17,13 @@ import ( // A declInfo describes a package-level const, type, var, or func declaration. type declInfo struct { - file *Scope // scope of file containing this declaration - lhs []*Var // lhs of n:1 variable declarations, or nil - typ ast.Expr // type, or nil - init ast.Expr // init/orig expression, or nil - fdecl *ast.FuncDecl // func declaration, or nil - alias bool // type alias declaration + file *Scope // scope of file containing this declaration + lhs []*Var // lhs of n:1 variable declarations, or nil + typ ast.Expr // type, or nil + init ast.Expr // init/orig expression, or nil + inherited bool // if set, the init expression is inherited from a previous constant declaration + fdecl *ast.FuncDecl // func declaration, or nil + alias bool // type alias declaration // The deps field tracks initialization expression dependencies. deps map[Object]bool // lazily initialized @@ -55,26 +56,27 @@ func (check *Checker) arityMatch(s, init *ast.ValueSpec) { r = len(init.Values) } + const code = _WrongAssignCount switch { case init == nil && r == 0: // var decl w/o init expr if s.Type == nil { - check.errorf(s.Pos(), "missing type or init expr") + check.errorf(s, code, "missing type or init expr") } case l < r: if l < len(s.Values) { // init exprs from s n := s.Values[l] - check.errorf(n.Pos(), "extra init expr %s", n) + check.errorf(n, code, "extra init expr %s", n) // TODO(gri) avoid declared but not used error here } else { // init exprs "inherited" - check.errorf(s.Pos(), "extra init expr at %s", check.fset.Position(init.Pos())) + check.errorf(s, code, "extra init expr at %s", check.fset.Position(init.Pos())) // TODO(gri) avoid declared but not used error here } case l > r && (init != nil || r != 1): n := s.Names[r] - check.errorf(n.Pos(), "missing init expr for %s", n) + check.errorf(n, code, "missing init expr for %s", n) } } @@ -103,14 +105,14 @@ func (check *Checker) declarePkgObj(ident *ast.Ident, obj Object, d *declInfo) { // spec: "A package-scope or file-scope identifier with name init // may only be declared to be a function with this (func()) signature." if ident.Name == "init" { - check.errorf(ident.Pos(), "cannot declare init - must be func") + check.errorf(ident, _InvalidInitDecl, "cannot declare init - must be func") return } // spec: "The main package must have package name main and declare // a function main that takes no arguments and returns no value." if ident.Name == "main" && check.pkg.name == "main" { - check.errorf(ident.Pos(), "cannot declare main - must be func") + check.errorf(ident, _InvalidMainDecl, "cannot declare main - must be func") return } @@ -168,7 +170,7 @@ func (check *Checker) importPackage(pos token.Pos, path, dir string) *Package { imp = nil // create fake package below } if err != nil { - check.errorf(pos, "could not import %s (%s)", path, err) + check.errorf(atPos(pos), _BrokenImport, "could not import %s (%s)", path, err) if imp == nil { // create a new fake package // come up with a sensible package name (heuristic) @@ -235,179 +237,147 @@ func (check *Checker) collectObjects() { // we get "." as the directory which is what we would want. fileDir := dir(check.fset.Position(file.Name.Pos()).Filename) - for _, decl := range file.Decls { - switch d := decl.(type) { - case *ast.BadDecl: - // ignore - - case *ast.GenDecl: - var last *ast.ValueSpec // last ValueSpec with type or init exprs seen - for iota, spec := range d.Specs { - switch s := spec.(type) { - case *ast.ImportSpec: - // import package - path, err := validatedImportPath(s.Path.Value) - if err != nil { - check.errorf(s.Path.Pos(), "invalid import path (%s)", err) - continue - } + check.walkDecls(file.Decls, func(d decl) { + switch d := d.(type) { + case importDecl: + // import package + path, err := validatedImportPath(d.spec.Path.Value) + if err != nil { + check.errorf(d.spec.Path, _BadImportPath, "invalid import path (%s)", err) + return + } - imp := check.importPackage(s.Path.Pos(), path, fileDir) - if imp == nil { - continue - } + imp := check.importPackage(d.spec.Path.Pos(), path, fileDir) + if imp == nil { + return + } - // add package to list of explicit imports - // (this functionality is provided as a convenience - // for clients; it is not needed for type-checking) - if !pkgImports[imp] { - pkgImports[imp] = true - pkg.imports = append(pkg.imports, imp) - } + // add package to list of explicit imports + // (this functionality is provided as a convenience + // for clients; it is not needed for type-checking) + if !pkgImports[imp] { + pkgImports[imp] = true + pkg.imports = append(pkg.imports, imp) + } - // local name overrides imported package name - name := imp.name - if s.Name != nil { - name = s.Name.Name - if path == "C" { - // match cmd/compile (not prescribed by spec) - check.errorf(s.Name.Pos(), `cannot rename import "C"`) - continue - } - if name == "init" { - check.errorf(s.Name.Pos(), "cannot declare init - must be func") - continue - } - } + // local name overrides imported package name + name := imp.name + if d.spec.Name != nil { + name = d.spec.Name.Name + if path == "C" { + // match cmd/compile (not prescribed by spec) + check.errorf(d.spec.Name, _ImportCRenamed, `cannot rename import "C"`) + return + } + if name == "init" { + check.errorf(d.spec.Name, _InvalidInitDecl, "cannot declare init - must be func") + return + } + } - obj := NewPkgName(s.Pos(), pkg, name, imp) - if s.Name != nil { - // in a dot-import, the dot represents the package - check.recordDef(s.Name, obj) - } else { - check.recordImplicit(s, obj) - } + obj := NewPkgName(d.spec.Pos(), pkg, name, imp) + if d.spec.Name != nil { + // in a dot-import, the dot represents the package + check.recordDef(d.spec.Name, obj) + } else { + check.recordImplicit(d.spec, obj) + } - if path == "C" { - // match cmd/compile (not prescribed by spec) - obj.used = true - } + if path == "C" { + // match cmd/compile (not prescribed by spec) + obj.used = true + } - // add import to file scope - if name == "." { - // merge imported scope with file scope - for _, obj := range imp.scope.elems { - // A package scope may contain non-exported objects, - // do not import them! - if obj.Exported() { - // declare dot-imported object - // (Do not use check.declare because it modifies the object - // via Object.setScopePos, which leads to a race condition; - // the object may be imported into more than one file scope - // concurrently. See issue #32154.) - if alt := fileScope.Insert(obj); alt != nil { - check.errorf(s.Name.Pos(), "%s redeclared in this block", obj.Name()) - check.reportAltDecl(alt) - } - } + // add import to file scope + if name == "." { + // merge imported scope with file scope + for _, obj := range imp.scope.elems { + // A package scope may contain non-exported objects, + // do not import them! + if obj.Exported() { + // declare dot-imported object + // (Do not use check.declare because it modifies the object + // via Object.setScopePos, which leads to a race condition; + // the object may be imported into more than one file scope + // concurrently. See issue #32154.) + if alt := fileScope.Insert(obj); alt != nil { + check.errorf(d.spec.Name, _DuplicateDecl, "%s redeclared in this block", obj.Name()) + check.reportAltDecl(alt) } - // add position to set of dot-import positions for this file - // (this is only needed for "imported but not used" errors) - check.addUnusedDotImport(fileScope, imp, s.Pos()) - } else { - // declare imported package object in file scope - // (no need to provide s.Name since we called check.recordDef earlier) - check.declare(fileScope, nil, obj, token.NoPos) } + } + // add position to set of dot-import positions for this file + // (this is only needed for "imported but not used" errors) + check.addUnusedDotImport(fileScope, imp, d.spec) + } else { + // declare imported package object in file scope + // (no need to provide s.Name since we called check.recordDef earlier) + check.declare(fileScope, nil, obj, token.NoPos) + } + case constDecl: + // declare all constants + for i, name := range d.spec.Names { + obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota))) + + var init ast.Expr + if i < len(d.init) { + init = d.init[i] + } - case *ast.ValueSpec: - switch d.Tok { - case token.CONST: - // determine which initialization expressions to use - switch { - case s.Type != nil || len(s.Values) > 0: - last = s - case last == nil: - last = new(ast.ValueSpec) // make sure last exists - } - - // declare all constants - for i, name := range s.Names { - obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota))) - - var init ast.Expr - if i < len(last.Values) { - init = last.Values[i] - } - - d := &declInfo{file: fileScope, typ: last.Type, init: init} - check.declarePkgObj(name, obj, d) - } - - check.arityMatch(s, last) - - case token.VAR: - lhs := make([]*Var, len(s.Names)) - // If there's exactly one rhs initializer, use - // the same declInfo d1 for all lhs variables - // so that each lhs variable depends on the same - // rhs initializer (n:1 var declaration). - var d1 *declInfo - if len(s.Values) == 1 { - // The lhs elements are only set up after the for loop below, - // but that's ok because declareVar only collects the declInfo - // for a later phase. - d1 = &declInfo{file: fileScope, lhs: lhs, typ: s.Type, init: s.Values[0]} - } - - // declare all variables - for i, name := range s.Names { - obj := NewVar(name.Pos(), pkg, name.Name, nil) - lhs[i] = obj - - d := d1 - if d == nil { - // individual assignments - var init ast.Expr - if i < len(s.Values) { - init = s.Values[i] - } - d = &declInfo{file: fileScope, typ: s.Type, init: init} - } - - check.declarePkgObj(name, obj, d) - } + d := &declInfo{file: fileScope, typ: d.typ, init: init, inherited: d.inherited} + check.declarePkgObj(name, obj, d) + } - check.arityMatch(s, nil) + case varDecl: + lhs := make([]*Var, len(d.spec.Names)) + // If there's exactly one rhs initializer, use + // the same declInfo d1 for all lhs variables + // so that each lhs variable depends on the same + // rhs initializer (n:1 var declaration). + var d1 *declInfo + if len(d.spec.Values) == 1 { + // The lhs elements are only set up after the for loop below, + // but that's ok because declareVar only collects the declInfo + // for a later phase. + d1 = &declInfo{file: fileScope, lhs: lhs, typ: d.spec.Type, init: d.spec.Values[0]} + } - default: - check.invalidAST(s.Pos(), "invalid token %s", d.Tok) + // declare all variables + for i, name := range d.spec.Names { + obj := NewVar(name.Pos(), pkg, name.Name, nil) + lhs[i] = obj + + di := d1 + if di == nil { + // individual assignments + var init ast.Expr + if i < len(d.spec.Values) { + init = d.spec.Values[i] } - - case *ast.TypeSpec: - obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) - check.declarePkgObj(s.Name, obj, &declInfo{file: fileScope, typ: s.Type, alias: s.Assign.IsValid()}) - - default: - check.invalidAST(s.Pos(), "unknown ast.Spec node %T", s) + di = &declInfo{file: fileScope, typ: d.spec.Type, init: init} } - } - case *ast.FuncDecl: - name := d.Name.Name - obj := NewFunc(d.Name.Pos(), pkg, name, nil) - if d.Recv == nil { + check.declarePkgObj(name, obj, di) + } + case typeDecl: + obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil) + check.declarePkgObj(d.spec.Name, obj, &declInfo{file: fileScope, typ: d.spec.Type, alias: d.spec.Assign.IsValid()}) + case funcDecl: + info := &declInfo{file: fileScope, fdecl: d.decl} + name := d.decl.Name.Name + obj := NewFunc(d.decl.Name.Pos(), pkg, name, nil) + if d.decl.Recv == nil { // regular function if name == "init" { // don't declare init functions in the package scope - they are invisible obj.parent = pkg.scope - check.recordDef(d.Name, obj) + check.recordDef(d.decl.Name, obj) // init functions must have a body - if d.Body == nil { - check.softErrorf(obj.pos, "missing function body") + if d.decl.Body == nil { + check.softErrorf(obj, _MissingInitBody, "missing function body") } } else { - check.declare(pkg.scope, d.Name, obj, token.NoPos) + check.declare(pkg.scope, d.decl.Name, obj, token.NoPos) } } else { // method @@ -417,20 +387,16 @@ func (check *Checker) collectObjects() { if name != "_" { methods = append(methods, obj) } - check.recordDef(d.Name, obj) + check.recordDef(d.decl.Name, obj) } - info := &declInfo{file: fileScope, fdecl: d} // Methods are not package-level objects but we still track them in the // object map so that we can handle them like regular functions (if the // receiver is invalid); also we need their fdecl info when associating // them with their receiver base type, below. check.objMap[obj] = info obj.setOrder(uint32(len(check.objMap))) - - default: - check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d) } - } + }) } // verify that objects in package and file scopes have different names @@ -438,10 +404,10 @@ func (check *Checker) collectObjects() { for _, obj := range scope.elems { if alt := pkg.scope.Lookup(obj.Name()); alt != nil { if pkg, ok := obj.(*PkgName); ok { - check.errorf(alt.Pos(), "%s already declared through import of %s", alt.Name(), pkg.Imported()) + check.errorf(alt, _DuplicateDecl, "%s already declared through import of %s", alt.Name(), pkg.Imported()) check.reportAltDecl(pkg) } else { - check.errorf(alt.Pos(), "%s already declared through dot-import of %s", alt.Name(), obj.Pkg()) + check.errorf(alt, _DuplicateDecl, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg()) // TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything check.reportAltDecl(obj) } @@ -610,9 +576,9 @@ func (check *Checker) unusedImports() { path := obj.imported.path base := pkgName(path) if obj.name == base { - check.softErrorf(obj.pos, "%q imported but not used", path) + check.softErrorf(obj, _UnusedImport, "%q imported but not used", path) } else { - check.softErrorf(obj.pos, "%q imported but not used as %s", path, obj.name) + check.softErrorf(obj, _UnusedImport, "%q imported but not used as %s", path, obj.name) } } } @@ -622,7 +588,7 @@ func (check *Checker) unusedImports() { // check use of dot-imported packages for _, unusedDotImports := range check.unusedDotImports { for pkg, pos := range unusedDotImports { - check.softErrorf(pos, "%q imported but not used", pkg.path) + check.softErrorf(pos, _UnusedImport, "%q imported but not used", pkg.path) } } } diff --git a/libgo/go/go/types/self_test.go b/libgo/go/go/types/self_test.go index 528fc173f88..55a8312260e 100644 --- a/libgo/go/go/types/self_test.go +++ b/libgo/go/go/types/self_test.go @@ -5,12 +5,11 @@ package types_test import ( - "flag" - "fmt" "go/ast" "go/importer" "go/parser" "go/token" + "path" "path/filepath" "testing" "time" @@ -18,13 +17,11 @@ import ( . "go/types" ) -var benchmark = flag.Bool("b", false, "run benchmarks") - func TestSelf(t *testing.T) { t.Skip("skipping for gccgo--no importer") fset := token.NewFileSet() - files, err := pkgFiles(fset, ".") + files, err := pkgFiles(fset, ".", 0) if err != nil { t.Fatal(err) } @@ -41,36 +38,39 @@ func TestSelf(t *testing.T) { } } -func TestBenchmark(t *testing.T) { - if !*benchmark { - return - } - - // We're not using testing's benchmarking mechanism directly - // because we want custom output. - - for _, p := range []string{"types", "constant", filepath.Join("internal", "gcimporter")} { - path := filepath.Join("..", p) - runbench(t, path, false) - runbench(t, path, true) - fmt.Println() +func BenchmarkCheck(b *testing.B) { + for _, p := range []string{ + "net/http", + "go/parser", + "go/constant", + filepath.Join("go", "internal", "gcimporter"), + } { + b.Run(path.Base(p), func(b *testing.B) { + path := filepath.Join("..", "..", p) + for _, ignoreFuncBodies := range []bool{false, true} { + name := "funcbodies" + if ignoreFuncBodies { + name = "nofuncbodies" + } + b.Run(name, func(b *testing.B) { + b.Run("info", func(b *testing.B) { + runbench(b, path, ignoreFuncBodies, true) + }) + b.Run("noinfo", func(b *testing.B) { + runbench(b, path, ignoreFuncBodies, false) + }) + }) + } + }) } } -func runbench(t *testing.T, path string, ignoreFuncBodies bool) { +func runbench(b *testing.B, path string, ignoreFuncBodies, writeInfo bool) { fset := token.NewFileSet() - files, err := pkgFiles(fset, path) + files, err := pkgFiles(fset, path, 0) if err != nil { - t.Fatal(err) + b.Fatal(err) } - - b := testing.Benchmark(func(b *testing.B) { - for i := 0; i < b.N; i++ { - conf := Config{IgnoreFuncBodies: ignoreFuncBodies} - conf.Check(path, fset, files, nil) - } - }) - // determine line count lines := 0 fset.Iterate(func(f *token.File) bool { @@ -78,14 +78,33 @@ func runbench(t *testing.T, path string, ignoreFuncBodies bool) { return true }) - d := time.Duration(b.NsPerOp()) - fmt.Printf( - "%s: %s for %d lines (%d lines/s), ignoreFuncBodies = %v\n", - filepath.Base(path), d, lines, int64(float64(lines)/d.Seconds()), ignoreFuncBodies, - ) + b.ResetTimer() + start := time.Now() + for i := 0; i < b.N; i++ { + conf := Config{ + IgnoreFuncBodies: ignoreFuncBodies, + Importer: importer.Default(), + } + var info *Info + if writeInfo { + info = &Info{ + Types: make(map[ast.Expr]TypeAndValue), + Defs: make(map[*ast.Ident]Object), + Uses: make(map[*ast.Ident]Object), + Implicits: make(map[ast.Node]Object), + Selections: make(map[*ast.SelectorExpr]*Selection), + Scopes: make(map[ast.Node]*Scope), + } + } + if _, err := conf.Check(path, fset, files, info); err != nil { + b.Fatal(err) + } + } + b.StopTimer() + b.ReportMetric(float64(lines)*float64(b.N)/time.Since(start).Seconds(), "lines/s") } -func pkgFiles(fset *token.FileSet, path string) ([]*ast.File, error) { +func pkgFiles(fset *token.FileSet, path string, mode parser.Mode) ([]*ast.File, error) { filenames, err := pkgFilenames(path) // from stdlib_test.go if err != nil { return nil, err @@ -93,7 +112,7 @@ func pkgFiles(fset *token.FileSet, path string) ([]*ast.File, error) { var files []*ast.File for _, filename := range filenames { - file, err := parser.ParseFile(fset, filename, nil, 0) + file, err := parser.ParseFile(fset, filename, nil, mode) if err != nil { return nil, err } diff --git a/libgo/go/go/types/stdlib_test.go b/libgo/go/go/types/stdlib_test.go index 5c9fec7a633..29254027c2c 100644 --- a/libgo/go/go/types/stdlib_test.go +++ b/libgo/go/go/types/stdlib_test.go @@ -11,12 +11,11 @@ import ( "fmt" "go/ast" "go/build" - // "go/importer" + "go/importer" "go/parser" "go/scanner" "go/token" "internal/testenv" - "io/ioutil" "os" "path/filepath" "runtime" @@ -27,25 +26,21 @@ import ( . "go/types" ) -var ( - pkgCount int // number of packages processed - start time.Time - - // Use the same importer for all std lib tests to - // avoid repeated importing of the same packages. - - // importer.Default panics for gccgo - // stdLibImporter = importer.Default() - stdLibImporter Importer -) +// Use the same importer for all std lib tests to +// avoid repeated importing of the same packages. +var stdLibImporter = importer.Default() func TestStdlib(t *testing.T) { testenv.MustHaveGoBuild(t) - start = time.Now() - walkDirs(t, filepath.Join(runtime.GOROOT(), "src")) + pkgCount := 0 + duration := walkPkgDirs(filepath.Join(runtime.GOROOT(), "src"), func(dir string, filenames []string) { + typecheck(t, dir, filenames) + pkgCount++ + }, t.Error) + if testing.Verbose() { - fmt.Println(pkgCount, "packages typechecked in", time.Since(start)) + fmt.Println(pkgCount, "packages typechecked in", duration) } } @@ -93,7 +88,7 @@ func firstComment(filename string) string { func testTestDir(t *testing.T, path string, ignore ...string) { t.Skip("skipping for gccgo") - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { t.Fatal(err) } @@ -189,6 +184,8 @@ func TestStdFixed(t *testing.T) { "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 + "issue42058a.go", // go/types does not have constraints on channel element size + "issue42058b.go", // go/types does not have constraints on channel element size ) } @@ -242,7 +239,6 @@ func typecheck(t *testing.T, path string, filenames []string) { } info := Info{Uses: make(map[*ast.Ident]Object)} conf.Check(path, fset, files, &info) - pkgCount++ // Perform checks of API invariants. @@ -285,39 +281,48 @@ func pkgFilenames(dir string) ([]string, error) { return filenames, nil } -// Note: Could use filepath.Walk instead of walkDirs but that wouldn't -// necessarily be shorter or clearer after adding the code to -// terminate early for -short tests. +func walkPkgDirs(dir string, pkgh func(dir string, filenames []string), errh func(args ...interface{})) time.Duration { + w := walker{time.Now(), 10 * time.Millisecond, pkgh, errh} + w.walk(dir) + return time.Since(w.start) +} -func walkDirs(t *testing.T, dir string) { +type walker struct { + start time.Time + dmax time.Duration + pkgh func(dir string, filenames []string) + errh func(args ...interface{}) +} + +func (w *walker) walk(dir string) { // limit run time for short tests - if testing.Short() && time.Since(start) >= 10*time.Millisecond { + if testing.Short() && time.Since(w.start) >= w.dmax { return } - fis, err := ioutil.ReadDir(dir) + files, err := os.ReadDir(dir) if err != nil { - t.Error(err) + w.errh(err) return } - // typecheck package in directory + // apply pkgh to the files in directory dir // but ignore files directly under $GOROOT/src (might be temporary test files). if dir != filepath.Join(runtime.GOROOT(), "src") { files, err := pkgFilenames(dir) if err != nil { - t.Error(err) + w.errh(err) return } if files != nil { - typecheck(t, dir, files) + w.pkgh(dir, files) } } // traverse subdirectories, but don't walk into testdata - for _, fi := range fis { - if fi.IsDir() && fi.Name() != "testdata" { - walkDirs(t, filepath.Join(dir, fi.Name())) + for _, f := range files { + if f.IsDir() && f.Name() != "testdata" { + w.walk(filepath.Join(dir, f.Name())) } } } diff --git a/libgo/go/go/types/stmt.go b/libgo/go/go/types/stmt.go index c1593bbee9d..d88e47170c3 100644 --- a/libgo/go/go/types/stmt.go +++ b/libgo/go/go/types/stmt.go @@ -46,7 +46,7 @@ func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body } if sig.results.Len() > 0 && !check.isTerminating(body, "") { - check.error(body.Rbrace, "missing return") + check.error(atPos(body.Rbrace), _MissingReturn, "missing return") } // spec: "Implementation restriction: A compiler may make it illegal to @@ -65,7 +65,7 @@ func (check *Checker) usage(scope *Scope) { return unused[i].pos < unused[j].pos }) for _, v := range unused { - check.softErrorf(v.pos, "%s declared but not used", v.name) + check.softErrorf(v, _UnusedVar, "%s declared but not used", v.name) } for _, scope := range scope.children { @@ -135,11 +135,11 @@ func (check *Checker) multipleDefaults(list []ast.Stmt) { d = s } default: - check.invalidAST(s.Pos(), "case/communication clause expected") + check.invalidAST(s, "case/communication clause expected") } if d != nil { if first != nil { - check.errorf(d.Pos(), "multiple defaults (first at %s)", check.fset.Position(first.Pos())) + check.errorf(d, _DuplicateDefault, "multiple defaults (first at %s)", check.fset.Position(first.Pos())) } else { first = d } @@ -168,17 +168,23 @@ func assignOp(op token.Token) token.Token { func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) { var x operand var msg string + var code errorCode switch check.rawExpr(&x, call, nil) { case conversion: msg = "requires function call, not conversion" + code = _InvalidDefer + if keyword == "go" { + code = _InvalidGo + } case expression: msg = "discards result of" + code = _UnusedResults case statement: return default: unreachable() } - check.errorf(x.pos(), "%s %s %s", keyword, msg, &x) + check.errorf(&x, code, "%s %s %s", keyword, msg, &x) } // goVal returns the Go value for val, or nil. @@ -250,17 +256,17 @@ L: // (quadratic algorithm, but these lists tend to be very short) for _, vt := range seen[val] { 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 + check.errorf(&v, _DuplicateCase, "duplicate case %s in expression switch", &v) + check.error(atPos(vt.pos), _DuplicateCase, "\tprevious case") // secondary error, \t indented continue L } } - seen[val] = append(seen[val], valueType{v.pos(), v.typ}) + seen[val] = append(seen[val], valueType{v.Pos(), v.typ}) } } } -func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]token.Pos) (T Type) { +func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]ast.Expr) (T Type) { L: for _, e := range types { T = check.typOrNil(e) @@ -269,21 +275,21 @@ L: } // look for duplicate types // (quadratic algorithm, but type switches tend to be reasonably small) - for t, pos := range seen { + for t, other := range seen { 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 { Ts = T.String() } - check.errorf(e.Pos(), "duplicate case %s in type switch", Ts) - check.error(pos, "\tprevious case") // secondary error, \t indented + check.errorf(e, _DuplicateCase, "duplicate case %s in type switch", Ts) + check.error(other, _DuplicateCase, "\tprevious case") // secondary error, \t indented continue L } } - seen[T] = e.Pos() + seen[T] = e if T != nil { - check.typeAssertion(e.Pos(), x, xtyp, T) + check.typeAssertion(e, x, xtyp, T) } } return @@ -324,18 +330,22 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { var x operand kind := check.rawExpr(&x, s.X, nil) var msg string + var code errorCode switch x.mode { default: if kind == statement { return } msg = "is not used" + code = _UnusedExpr case builtin: msg = "must be called" + code = _UncalledBuiltin case typexpr: msg = "is not an expression" + code = _NotAnExpr } - check.errorf(x.pos(), "%s %s", &x, msg) + check.errorf(&x, code, "%s %s", &x, msg) case *ast.SendStmt: var ch, x operand @@ -347,12 +357,12 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { tch, ok := ch.typ.Underlying().(*Chan) if !ok { - check.invalidOp(s.Arrow, "cannot send to non-chan type %s", ch.typ) + check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "cannot send to non-chan type %s", ch.typ) return } if tch.dir == RecvOnly { - check.invalidOp(s.Arrow, "cannot send to receive-only type %s", tch) + check.invalidOp(inNode(s, s.Arrow), _InvalidSend, "cannot send to receive-only type %s", tch) return } @@ -366,7 +376,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { case token.DEC: op = token.SUB default: - check.invalidAST(s.TokPos, "unknown inc/dec operation %s", s.Tok) + check.invalidAST(inNode(s, s.TokPos), "unknown inc/dec operation %s", s.Tok) return } @@ -376,12 +386,12 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { return } if !isNumeric(x.typ) { - check.invalidOp(s.X.Pos(), "%s%s (non-numeric type %s)", s.X, s.Tok, x.typ) + check.invalidOp(s.X, _NonNumericIncDec, "%s%s (non-numeric type %s)", s.X, s.Tok, x.typ) return } Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position - check.binary(&x, nil, s.X, Y, op) + check.binary(&x, nil, s.X, Y, op, s.TokPos) if x.mode == invalid { return } @@ -391,11 +401,11 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { switch s.Tok { case token.ASSIGN, token.DEFINE: if len(s.Lhs) == 0 { - check.invalidAST(s.Pos(), "missing lhs in assignment") + check.invalidAST(s, "missing lhs in assignment") return } if s.Tok == token.DEFINE { - check.shortVarDecl(s.TokPos, s.Lhs, s.Rhs) + check.shortVarDecl(inNode(s, s.TokPos), s.Lhs, s.Rhs) } else { // regular assignment check.assignVars(s.Lhs, s.Rhs) @@ -404,16 +414,16 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { default: // assignment operations if len(s.Lhs) != 1 || len(s.Rhs) != 1 { - check.errorf(s.TokPos, "assignment operation %s requires single-valued expressions", s.Tok) + check.errorf(inNode(s, s.TokPos), _MultiValAssignOp, "assignment operation %s requires single-valued expressions", s.Tok) return } op := assignOp(s.Tok) if op == token.ILLEGAL { - check.invalidAST(s.TokPos, "unknown assignment operation %s", s.Tok) + check.invalidAST(atPos(s.TokPos), "unknown assignment operation %s", s.Tok) return } var x operand - check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op) + check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op, s.TokPos) if x.mode == invalid { return } @@ -437,8 +447,8 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { // with the same name as a result parameter is in scope at the place of the return." for _, obj := range res.vars { if alt := check.lookup(obj.name); alt != nil && alt != obj { - check.errorf(s.Pos(), "result parameter %s not in scope at return", obj.name) - check.errorf(alt.Pos(), "\tinner declaration of %s", obj) + check.errorf(s, _OutOfScopeResult, "result parameter %s not in scope at return", obj.name) + check.errorf(alt, _OutOfScopeResult, "\tinner declaration of %s", obj) // ok to continue } } @@ -447,7 +457,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { check.initVars(res.vars, s.Results, s.Return) } } else if len(s.Results) > 0 { - check.error(s.Results[0].Pos(), "no result values expected") + check.error(s.Results[0], _WrongResultCount, "no result values expected") check.use(s.Results...) } @@ -459,22 +469,23 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { switch s.Tok { case token.BREAK: if ctxt&breakOk == 0 { - check.error(s.Pos(), "break not in for, switch, or select statement") + check.error(s, _MisplacedBreak, "break not in for, switch, or select statement") } case token.CONTINUE: if ctxt&continueOk == 0 { - check.error(s.Pos(), "continue not in for statement") + check.error(s, _MisplacedContinue, "continue not in for statement") } case token.FALLTHROUGH: if ctxt&fallthroughOk == 0 { msg := "fallthrough statement out of place" + code := _MisplacedFallthrough if ctxt&finalSwitchCase != 0 { msg = "cannot fallthrough final case in switch" } - check.error(s.Pos(), msg) + check.error(s, code, msg) } default: - check.invalidAST(s.Pos(), "branch statement: %s", s.Tok) + check.invalidAST(s, "branch statement: %s", s.Tok) } case *ast.BlockStmt: @@ -491,7 +502,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { var x operand check.expr(&x, s.Cond) if x.mode != invalid && !isBoolean(x.typ) { - check.error(s.Cond.Pos(), "non-boolean condition in if statement") + check.error(s.Cond, _InvalidCond, "non-boolean condition in if statement") } check.stmt(inner, s.Body) // The parser produces a correct AST but if it was modified @@ -502,7 +513,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { case *ast.IfStmt, *ast.BlockStmt: check.stmt(inner, s.Else) default: - check.error(s.Else.Pos(), "invalid else branch in if statement") + check.invalidAST(s.Else, "invalid else branch in if statement") } case *ast.SwitchStmt: @@ -517,6 +528,10 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { // By checking assignment of x to an invisible temporary // (as a compiler would), we get all the relevant checks. check.assignment(&x, nil, "switch expression") + if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) { + check.errorf(&x, _InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ) + x.mode = invalid + } } else { // spec: "A missing switch expression is // equivalent to the boolean value true." @@ -532,7 +547,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { for i, c := range s.Body.List { clause, _ := c.(*ast.CaseClause) if clause == nil { - check.invalidAST(c.Pos(), "incorrect expression switch case") + check.invalidAST(c, "incorrect expression switch case") continue } check.caseValues(&x, clause.List, seen) @@ -569,19 +584,19 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { rhs = guard.X case *ast.AssignStmt: if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 { - check.invalidAST(s.Pos(), "incorrect form of type switch guard") + check.invalidAST(s, "incorrect form of type switch guard") return } lhs, _ = guard.Lhs[0].(*ast.Ident) if lhs == nil { - check.invalidAST(s.Pos(), "incorrect form of type switch guard") + check.invalidAST(s, "incorrect form of type switch guard") return } if lhs.Name == "_" { // _ := x.(type) is an invalid short variable declaration - check.softErrorf(lhs.Pos(), "no new variable on left side of :=") + check.softErrorf(lhs, _NoNewVar, "no new variable on left side of :=") lhs = nil // avoid declared but not used error below } else { check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause @@ -590,14 +605,14 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { rhs = guard.Rhs[0] default: - check.invalidAST(s.Pos(), "incorrect form of type switch guard") + check.invalidAST(s, "incorrect form of type switch guard") return } // rhs must be of the form: expr.(type) and expr must be an interface expr, _ := rhs.(*ast.TypeAssertExpr) if expr == nil || expr.Type != nil { - check.invalidAST(s.Pos(), "incorrect form of type switch guard") + check.invalidAST(s, "incorrect form of type switch guard") return } var x operand @@ -607,18 +622,18 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { } xtyp, _ := x.typ.Underlying().(*Interface) if xtyp == nil { - check.errorf(x.pos(), "%s is not an interface", &x) + check.errorf(&x, _InvalidTypeSwitch, "%s is not an interface", &x) return } check.multipleDefaults(s.Body.List) - var lhsVars []*Var // list of implicitly declared lhs variables - seen := make(map[Type]token.Pos) // map of seen types to positions + var lhsVars []*Var // list of implicitly declared lhs variables + seen := make(map[Type]ast.Expr) // map of seen types to positions for _, s := range s.Body.List { clause, _ := s.(*ast.CaseClause) if clause == nil { - check.invalidAST(s.Pos(), "incorrect type switch case") + check.invalidAST(s, "incorrect type switch case") continue } // Check each type in this type switch case. @@ -660,7 +675,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { v.used = true // avoid usage error when checking entire function } if !used { - check.softErrorf(lhs.Pos(), "%s declared but not used", lhs.Name) + check.softErrorf(lhs, _UnusedVar, "%s declared but not used", lhs.Name) } } @@ -697,7 +712,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { } if !valid { - check.error(clause.Comm.Pos(), "select case must be send or receive (possibly with assignment)") + check.error(clause.Comm, _InvalidSelectCase, "select case must be send or receive (possibly with assignment)") continue } @@ -719,14 +734,14 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { var x operand check.expr(&x, s.Cond) if x.mode != invalid && !isBoolean(x.typ) { - check.error(s.Cond.Pos(), "non-boolean condition in for statement") + check.error(s.Cond, _InvalidCond, "non-boolean condition in for statement") } } check.simpleStmt(s.Post) // spec: "The init statement may be a short variable // declaration, but the post statement must not." if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE { - check.softErrorf(s.Pos(), "cannot declare in post statement") + check.softErrorf(s, _InvalidPostDecl, "cannot declare in post statement") // Don't call useLHS here because we want to use the lhs in // this erroneous statement so that we don't get errors about // these lhs variables being declared but not used. @@ -770,18 +785,18 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { key = typ.elem val = Typ[Invalid] if typ.dir == SendOnly { - check.errorf(x.pos(), "cannot range over send-only channel %s", &x) + check.errorf(&x, _InvalidChanRange, "cannot range over send-only channel %s", &x) // ok to continue } if s.Value != nil { - check.errorf(s.Value.Pos(), "iteration over %s permits only one iteration variable", &x) + check.errorf(atPos(s.Value.Pos()), _InvalidIterVar, "iteration over %s permits only one iteration variable", &x) // ok to continue } } } if key == nil { - check.errorf(x.pos(), "cannot range over %s", &x) + check.errorf(&x, _InvalidRangeExpr, "cannot range over %s", &x) // ok to continue } @@ -814,7 +829,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { vars = append(vars, obj) } } else { - check.errorf(lhs.Pos(), "cannot declare %s", lhs) + check.invalidAST(lhs, "cannot declare %s", lhs) obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable } @@ -841,7 +856,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { check.declare(check.scope, nil /* recordDef already called */, obj, scopePos) } } else { - check.error(s.TokPos, "no new variables on left side of :=") + check.error(inNode(s, s.TokPos), _NoNewVar, "no new variables on left side of :=") } } else { // ordinary assignment @@ -861,6 +876,6 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) { check.stmt(inner, s.Body) default: - check.error(s.Pos(), "invalid statement") + check.invalidAST(s, "invalid statement") } } diff --git a/libgo/go/go/types/testdata/builtins.src b/libgo/go/go/types/testdata/builtins.src index ecdba51553e..98830eb08c6 100644 --- a/libgo/go/go/types/testdata/builtins.src +++ b/libgo/go/go/types/testdata/builtins.src @@ -35,9 +35,9 @@ func append1() { type S []byte type T string var t T - _ = append(s, "foo" /* ERROR cannot convert */ ) + _ = append(s, "foo" /* ERROR cannot use .* in argument to append */ ) _ = append(s, "foo"...) - _ = append(S(s), "foo" /* ERROR cannot convert */ ) + _ = append(S(s), "foo" /* ERROR cannot use .* in argument to append */ ) _ = append(S(s), "foo"...) _ = append(s, t /* ERROR cannot use t */ ) _ = append(s, t...) diff --git a/libgo/go/go/types/testdata/constdecl.src b/libgo/go/go/types/testdata/constdecl.src index c2f40ed6e67..680c85aff37 100644 --- a/libgo/go/go/types/testdata/constdecl.src +++ b/libgo/go/go/types/testdata/constdecl.src @@ -107,4 +107,35 @@ func _() { const x, y, z = 0, 1, unsafe.Sizeof(func() { _ = x /* ERROR "undeclared name" */ + y /* ERROR "undeclared name" */ + z /* ERROR "undeclared name" */ }) } +// Test cases for errors in inherited constant initialization expressions. +// Errors related to inherited initialization expressions must appear at +// the constant identifier being declared, not at the original expression +// (issues #42991, #42992). +const ( + _ byte = 255 + iota + /* some gap */ + _ // ERROR overflows + /* some gap */ + /* some gap */ _ /* ERROR overflows */; _ /* ERROR overflows */ + /* some gap */ + _ = 255 + iota + _ = byte /* ERROR overflows */ (255) + iota + _ /* ERROR overflows */ +) + +// Test cases from issue. +const ( + ok = byte(iota + 253) + bad + barn + bard // ERROR cannot convert +) + +const ( + c = len([1 - iota]int{}) + d + e // ERROR invalid array length + f // ERROR invalid array length +) + // TODO(gri) move extra tests from testdata/const0.src into here diff --git a/libgo/go/go/types/testdata/cycles.src b/libgo/go/go/types/testdata/cycles.src index b2ee8ecd5f6..218b4cad6ab 100644 --- a/libgo/go/go/types/testdata/cycles.src +++ b/libgo/go/go/types/testdata/cycles.src @@ -65,7 +65,7 @@ type ( I6 interface{ I5 } // maps - M0 map[M0 /* ERROR invalid map key */ ]M0 + M0 map[M0 /* ERROR incomparable map key */ ]M0 // channels C0 chan C0 @@ -114,7 +114,7 @@ func _() { i0 /* ERROR cycle */ interface{ i0 } // maps - m0 map[m0 /* ERROR invalid map key */ ]m0 + m0 map[m0 /* ERROR incomparable map key */ ]m0 // channels c0 chan c0 @@ -123,10 +123,10 @@ func _() { // test cases for issue 6667 -type A [10]map[A /* ERROR invalid map key */ ]bool +type A [10]map[A /* ERROR incomparable map key */ ]bool type S struct { - m map[S /* ERROR invalid map key */ ]bool + m map[S /* ERROR incomparable map key */ ]bool } // test cases for issue 7236 diff --git a/libgo/go/go/types/testdata/cycles2.src b/libgo/go/go/types/testdata/cycles2.src index 5fd9e838b60..1a7f40ae4b7 100644 --- a/libgo/go/go/types/testdata/cycles2.src +++ b/libgo/go/go/types/testdata/cycles2.src @@ -37,7 +37,7 @@ type A interface { } type B interface { - a() interface { + b() interface { AB } } @@ -59,8 +59,7 @@ var y interface { B } -// TODO(gri) This should be a valid compare. See #33656. -var _ = x /* ERROR cannot compare */ == y +var _ = x == y // Test case for issue 6638. diff --git a/libgo/go/go/types/testdata/decls1.src b/libgo/go/go/types/testdata/decls1.src index e6beb783589..f4d2eaba911 100644 --- a/libgo/go/go/types/testdata/decls1.src +++ b/libgo/go/go/types/testdata/decls1.src @@ -96,6 +96,8 @@ var ( v11 = xx/yy*yy - xx v12 = true && false v13 = nil /* ERROR "use of untyped nil" */ + v14 string = 257 // ERROR cannot use 257 .* as string value in variable declaration$ + v15 int8 = 257 // ERROR cannot use 257 .* as int8 value in variable declaration .*overflows ) // Multiple assignment expressions diff --git a/libgo/go/go/types/testdata/decls2b.src b/libgo/go/go/types/testdata/decls2b.src index 8e82c6dcde1..5c55750a103 100644 --- a/libgo/go/go/types/testdata/decls2b.src +++ b/libgo/go/go/types/testdata/decls2b.src @@ -40,17 +40,17 @@ func f_double /* ERROR "redeclared" */ () {} // Verify by checking that errors are reported. func (T /* ERROR "undeclared" */ ) _() {} func (T1) _(undeclared /* ERROR "undeclared" */ ) {} -func (T1) _() int { return "foo" /* ERROR "cannot convert" */ } +func (T1) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ } // Methods with undeclared receiver type can still be checked. // Verify by checking that errors are reported. func (Foo /* ERROR "undeclared" */ ) m() {} func (Foo /* ERROR "undeclared" */ ) m(undeclared /* ERROR "undeclared" */ ) {} -func (Foo /* ERROR "undeclared" */ ) m() int { return "foo" /* ERROR "cannot convert" */ } +func (Foo /* ERROR "undeclared" */ ) m() int { return "foo" /* ERROR "cannot use .* in return statement" */ } func (Foo /* ERROR "undeclared" */ ) _() {} func (Foo /* ERROR "undeclared" */ ) _(undeclared /* ERROR "undeclared" */ ) {} -func (Foo /* ERROR "undeclared" */ ) _() int { return "foo" /* ERROR "cannot convert" */ } +func (Foo /* ERROR "undeclared" */ ) _() int { return "foo" /* ERROR "cannot use .* in return statement" */ } // Receiver declarations are regular parameter lists; // receiver types may use parentheses, and the list @@ -72,4 +72,4 @@ var ( _ = (*T7).m4 _ = (*T7).m5 _ = (*T7).m6 -) \ No newline at end of file +) diff --git a/libgo/go/go/types/testdata/expr3.src b/libgo/go/go/types/testdata/expr3.src index 63af9fc867c..e6777aad2bb 100644 --- a/libgo/go/go/types/testdata/expr3.src +++ b/libgo/go/go/types/testdata/expr3.src @@ -43,9 +43,9 @@ func indexes() { _ = a[:10:10] _ = a[:11 /* ERROR "index .* out of bounds" */ :10] _ = a[:10:11 /* ERROR "index .* out of bounds" */ ] - _ = a[10:0:10] /* ERROR "invalid slice indices" */ - _ = a[0:10:0] /* ERROR "invalid slice indices" */ - _ = a[10:0:0] /* ERROR "invalid slice indices" */ + _ = a[10:0:10] /* ERROR swapped slice indices" */ + _ = a[0:10:0] /* ERROR "swapped slice indices" */ + _ = a[10:0:0] /* ERROR "swapped slice indices" */ _ = &a /* ERROR "cannot take address" */ [:10] pa := &a @@ -61,9 +61,9 @@ func indexes() { _ = pa[:10:10] _ = pa[:11 /* ERROR "index .* out of bounds" */ :10] _ = pa[:10:11 /* ERROR "index .* out of bounds" */ ] - _ = pa[10:0:10] /* ERROR "invalid slice indices" */ - _ = pa[0:10:0] /* ERROR "invalid slice indices" */ - _ = pa[10:0:0] /* ERROR "invalid slice indices" */ + _ = pa[10:0:10] /* ERROR "swapped slice indices" */ + _ = pa[0:10:0] /* ERROR "swapped slice indices" */ + _ = pa[10:0:0] /* ERROR "swapped slice indices" */ _ = &pa /* ERROR "cannot take address" */ [:10] var b [0]int @@ -81,20 +81,20 @@ func indexes() { _ = s[: - /* ERROR "negative" */ 1] _ = s[0] _ = s[1:2] - _ = s[2:1] /* ERROR "invalid slice indices" */ + _ = s[2:1] /* ERROR "swapped slice indices" */ _ = s[2:] _ = s[: 1 /* ERROR "overflows" */ <<100] _ = s[1 /* ERROR "overflows" */ <<100 :] _ = s[1 /* ERROR "overflows" */ <<100 : 1 /* ERROR "overflows" */ <<100] _ = s[: /* ERROR "2nd index required" */ : /* ERROR "3rd index required" */ ] _ = s[:10:10] - _ = s[10:0:10] /* ERROR "invalid slice indices" */ - _ = s[0:10:0] /* ERROR "invalid slice indices" */ - _ = s[10:0:0] /* ERROR "invalid slice indices" */ + _ = s[10:0:10] /* ERROR "swapped slice indices" */ + _ = s[0:10:0] /* ERROR "swapped slice indices" */ + _ = s[10:0:0] /* ERROR "swapped slice indices" */ _ = &s /* ERROR "cannot take address" */ [:10] var m map[string]int - _ = m[0 /* ERROR "cannot convert" */ ] + _ = m[0 /* ERROR "cannot use .* in map index" */ ] _ = m /* ERROR "cannot slice" */ ["foo" : "bar"] _ = m["foo"] // ok is of type bool @@ -102,6 +102,7 @@ func indexes() { var ok mybool _, ok = m["bar"] _ = ok + _ = m[0 /* ERROR "cannot use 0" */ ] + "foo" // ERROR "cannot convert" var t string _ = t[- /* ERROR "negative" */ 1] @@ -184,7 +185,7 @@ func struct_literals() { _ = T1{aa /* ERROR "unknown field" */ : 0} _ = T1{1 /* ERROR "invalid field name" */ : 0} _ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10} - _ = T1{a: "foo" /* ERROR "cannot convert" */ } + _ = T1{a: "foo" /* ERROR "cannot use .* in struct literal" */ } _ = T1{c /* ERROR "unknown field" */ : 0} _ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided _ = T1{T0: T0{}} @@ -195,7 +196,7 @@ func struct_literals() { _ = T0{1, b /* ERROR "mixture" */ : 2, 3} _ = T0{1, 2} /* ERROR "too few values" */ _ = T0{1, 2, 3, 4 /* ERROR "too many values" */ } - _ = T0{1, "foo" /* ERROR "cannot convert" */, 3.4 /* ERROR "truncated" */} + _ = T0{1, "foo" /* ERROR "cannot use .* in struct literal" */, 3.4 /* ERROR "cannot use .*\(truncated\)" */} // invalid type type P *struct{ @@ -235,7 +236,7 @@ func array_literals() { _ = A1{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4} _ = A1{2.0} _ = A1{2.1 /* ERROR "truncated" */ } - _ = A1{"foo" /* ERROR "cannot convert" */ } + _ = A1{"foo" /* ERROR "cannot use .* in array or slice literal" */ } // indices must be integer constants i := 1 @@ -301,7 +302,7 @@ func slice_literals() { _ = S0{5: 5, 6, 7, 4: 4, 1 /* ERROR "overflows" */ <<100: 4} _ = S0{2.0} _ = S0{2.1 /* ERROR "truncated" */ } - _ = S0{"foo" /* ERROR "cannot convert" */ } + _ = S0{"foo" /* ERROR "cannot use .* in array or slice literal" */ } // indices must be resolved correctly const index1 = 1 @@ -354,8 +355,8 @@ func map_literals() { _ = M0{} _ = M0{1 /* ERROR "missing key" */ } - _ = M0{1 /* ERROR "cannot convert" */ : 2} - _ = M0{"foo": "bar" /* ERROR "cannot convert" */ } + _ = M0{1 /* ERROR "cannot use .* in map literal" */ : 2} + _ = M0{"foo": "bar" /* ERROR "cannot use .* in map literal" */ } _ = M0{"foo": 1, "bar": 2, "foo" /* ERROR "duplicate key" */ : 3 } _ = map[interface{}]int{2: 1, 2 /* ERROR "duplicate key" */ : 1} diff --git a/libgo/go/go/types/testdata/issue23203a.src b/libgo/go/go/types/testdata/issue23203a.src deleted file mode 100644 index 48cb5889cd9..00000000000 --- a/libgo/go/go/types/testdata/issue23203a.src +++ /dev/null @@ -1,14 +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 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 deleted file mode 100644 index 638ec6c5ce3..00000000000 --- a/libgo/go/go/types/testdata/issue23203b.src +++ /dev/null @@ -1,14 +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 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/issue26390.src b/libgo/go/go/types/testdata/issue26390.src deleted file mode 100644 index b8e67e9bddb..00000000000 --- a/libgo/go/go/types/testdata/issue26390.src +++ /dev/null @@ -1,11 +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 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 deleted file mode 100644 index cd79e0e8b5d..00000000000 --- a/libgo/go/go/types/testdata/issue28251.src +++ /dev/null @@ -1,65 +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. - -// 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 "cannot call pointer method m4 on T" */ () } -func _() { (&T{}).m4() } - -type ( - T6 = (((T7))) - T7 = (*(T8)) - T8 = T -) - -func (T6) m6() {} -func _() { (T{}).m6 /* ERROR "cannot call pointer method m6 on 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 deleted file mode 100644 index 8f4e9ba2b21..00000000000 --- a/libgo/go/go/types/testdata/issue6977.src +++ /dev/null @@ -1,82 +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 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 4944f6f6187..e0c5d7a37cf 100644 --- a/libgo/go/go/types/testdata/issues.src +++ b/libgo/go/go/types/testdata/issues.src @@ -354,10 +354,10 @@ func issue26234c() { 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 + var _ T = 0 // ERROR cannot use 0 \(untyped int constant\) as 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 + var _ *syn.File = 0 // ERROR cannot use 0 \(untyped int constant\) as \*syntax.File // Because both t1 and t2 have the same global package name (template), // qualify packages with full path name in this case. diff --git a/libgo/go/go/types/testdata/shifts.src b/libgo/go/go/types/testdata/shifts.src index ebc95ba4d79..c9a38ae169e 100644 --- a/libgo/go/go/types/testdata/shifts.src +++ b/libgo/go/go/types/testdata/shifts.src @@ -193,14 +193,27 @@ func shifts6() { _ = float32(1.0 /* ERROR "must be integer" */ <= 0 { return n } - check.errorf(x.pos(), "invalid array length %s", &x) + check.errorf(&x, _InvalidArrayLen, "invalid array length %s", &x) return -1 } } } - check.errorf(x.pos(), "array length %s must be integer", &x) + check.errorf(&x, _InvalidArrayLen, "array length %s must be integer", &x) return -1 } @@ -407,7 +407,7 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 { variadic = true } else { - check.softErrorf(t.Pos(), "can only use ... with final parameter in list") + check.softErrorf(t, _MisplacedDotDotDot, "can only use ... with final parameter in list") // ignore ... and continue } } @@ -418,7 +418,7 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO // named parameter for _, name := range field.Names { if name.Name == "" { - check.invalidAST(name.Pos(), "anonymous parameter") + check.invalidAST(name, "anonymous parameter") // ok to continue } par := NewParam(name.Pos(), check.pkg, name.Name, typ) @@ -436,7 +436,7 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO } if named && anonymous { - check.invalidAST(list.Pos(), "list contains both named and anonymous parameters") + check.invalidAST(list, "list contains both named and anonymous parameters") // ok to continue } @@ -454,7 +454,7 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool { if alt := oset.insert(obj); alt != nil { - check.errorf(pos, "%s redeclared", obj.Name()) + check.errorf(atPos(pos), _DuplicateDecl, "%s redeclared", obj.Name()) check.reportAltDecl(alt) return false } @@ -469,7 +469,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d // 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 _") + check.errorf(name, _BlankIfaceMethod, "invalid method name _") continue // ignore } @@ -477,7 +477,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d sig, _ := typ.(*Signature) if sig == nil { if typ != Typ[Invalid] { - check.invalidAST(f.Type.Pos(), "%s is not a method signature", typ) + check.invalidAST(f.Type, "%s is not a method signature", typ) } continue // ignore } @@ -501,7 +501,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d utyp := check.underlying(typ) if _, ok := utyp.(*Interface); !ok { if utyp != Typ[Invalid] { - check.errorf(f.Type.Pos(), "%s is not an interface", typ) + check.errorf(f.Type, _InvalidIfaceEmbed, "%s is not an interface", typ) } continue } @@ -575,14 +575,14 @@ func (check *Checker) completeInterface(ityp *Interface) { 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 + check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name) + check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\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 + check.errorf(atPos(pos), _DuplicateDecl, "duplicate method %s", m.name) + check.errorf(atPos(mpos[other.(*Func)]), _DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented } }) } @@ -641,7 +641,7 @@ func (check *Checker) tag(t *ast.BasicLit) string { return val } } - check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value) + check.invalidAST(t, "incorrect tag syntax: %q", t.Value) } return "" } @@ -704,7 +704,7 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) { pos := f.Type.Pos() name := embeddedFieldIdent(f.Type) if name == nil { - check.invalidAST(pos, "embedded field type %s has no name", f.Type) + check.invalidAST(f.Type, "embedded field type %s has no name", f.Type) name = ast.NewIdent("_") name.NamePos = pos addInvalid(name, pos) @@ -723,19 +723,19 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) { // unsafe.Pointer is treated like a regular pointer if t.kind == UnsafePointer { - check.errorf(pos, "embedded field type cannot be unsafe.Pointer") + check.errorf(f.Type, _InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer") addInvalid(name, pos) continue } case *Pointer: - check.errorf(pos, "embedded field type cannot be a pointer") + check.errorf(f.Type, _InvalidPtrEmbed, "embedded field type cannot be a pointer") addInvalid(name, pos) continue case *Interface: if isPtr { - check.errorf(pos, "embedded field type cannot be a pointer to an interface") + check.errorf(f.Type, _InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface") addInvalid(name, pos) continue } diff --git a/libgo/go/golang.org/x/mod/modfile/read.go b/libgo/go/golang.org/x/mod/modfile/read.go index c1f2008ee4c..2a961ca81c2 100644 --- a/libgo/go/golang.org/x/mod/modfile/read.go +++ b/libgo/go/golang.org/x/mod/modfile/read.go @@ -477,9 +477,17 @@ func (in *input) startToken() { // endToken marks the end of an input token. // It records the actual token string in tok.text. +// A single trailing newline (LF or CRLF) will be removed from comment tokens. func (in *input) endToken(kind tokenKind) { in.token.kind = kind text := string(in.tokenStart[:len(in.tokenStart)-len(in.remaining)]) + if kind.isComment() { + if strings.HasSuffix(text, "\r\n") { + text = text[:len(text)-2] + } else { + text = strings.TrimSuffix(text, "\n") + } + } in.token.text = text in.token.endPos = in.pos } diff --git a/libgo/go/golang.org/x/mod/modfile/rule.go b/libgo/go/golang.org/x/mod/modfile/rule.go index 91ca6828df0..83398dda5d5 100644 --- a/libgo/go/golang.org/x/mod/modfile/rule.go +++ b/libgo/go/golang.org/x/mod/modfile/rule.go @@ -30,6 +30,7 @@ import ( "golang.org/x/mod/internal/lazyregexp" "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) // A File is the parsed, interpreted form of a go.mod file. @@ -39,6 +40,7 @@ type File struct { Require []*Require Exclude []*Exclude Replace []*Replace + Retract []*Retract Syntax *FileSyntax } @@ -75,6 +77,21 @@ type Replace struct { Syntax *Line } +// A Retract is a single retract statement. +type Retract struct { + VersionInterval + Rationale string + Syntax *Line +} + +// A VersionInterval represents a range of versions with upper and lower bounds. +// Intervals are closed: both bounds are included. When Low is equal to High, +// the interval may refer to a single version ('v1.2.3') or an interval +// ('[v1.2.3, v1.2.3]'); both have the same representation. +type VersionInterval struct { + Low, High string +} + func (f *File) AddModuleStmt(path string) error { if f.Syntax == nil { f.Syntax = new(FileSyntax) @@ -138,7 +155,7 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File for _, x := range fs.Stmt { switch x := x.(type) { case *Line: - f.add(&errs, x, x.Token[0], x.Token[1:], fix, strict) + f.add(&errs, nil, x, x.Token[0], x.Token[1:], fix, strict) case *LineBlock: if len(x.Token) > 1 { @@ -161,9 +178,9 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File }) } continue - case "module", "require", "exclude", "replace": + case "module", "require", "exclude", "replace", "retract": for _, l := range x.Line { - f.add(&errs, l, x.Token[0], l.Token, fix, strict) + f.add(&errs, x, l, x.Token[0], l.Token, fix, strict) } } } @@ -177,7 +194,7 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (*File var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) -func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix VersionFixer, strict bool) { +func (f *File) add(errs *ErrorList, block *LineBlock, 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 @@ -186,7 +203,7 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix // and simply ignore those statements. if !strict { switch verb { - case "module", "require", "go": + case "go", "module", "retract", "require": // want these even for dependency go.mods default: return @@ -232,6 +249,7 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix f.Go = &Go{Syntax: line} f.Go.Version = args[0] + case "module": if f.Module != nil { errorf("repeated module statement") @@ -248,6 +266,7 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix return } f.Module.Mod = module.Version{Path: s} + case "require", "exclude": if len(args) != 2 { errorf("usage: %s module/path v1.2.3", verb) @@ -284,6 +303,7 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix Syntax: line, }) } + case "replace": arrow := 2 if len(args) >= 2 && args[1] == "=>" { @@ -347,6 +367,33 @@ func (f *File) add(errs *ErrorList, line *Line, verb string, args []string, fix New: module.Version{Path: ns, Version: nv}, Syntax: line, }) + + case "retract": + rationale := parseRetractRationale(block, line) + vi, err := parseVersionInterval(verb, &args, fix) + if err != nil { + if strict { + wrapError(err) + return + } else { + // Only report errors parsing intervals in the main module. We may + // support additional syntax in the future, such as open and half-open + // intervals. Those can't be supported now, because they break the + // go.mod parser, even in lax mode. + return + } + } + if len(args) > 0 && strict { + // In the future, there may be additional information after the version. + errorf("unexpected token after version: %q", args[0]) + return + } + retract := &Retract{ + VersionInterval: vi, + Rationale: rationale, + Syntax: line, + } + f.Retract = append(f.Retract, retract) } } @@ -444,6 +491,53 @@ func AutoQuote(s string) string { return s } +func parseVersionInterval(verb string, args *[]string, fix VersionFixer) (VersionInterval, error) { + toks := *args + if len(toks) == 0 || toks[0] == "(" { + return VersionInterval{}, fmt.Errorf("expected '[' or version") + } + if toks[0] != "[" { + v, err := parseVersion(verb, "", &toks[0], fix) + if err != nil { + return VersionInterval{}, err + } + *args = toks[1:] + return VersionInterval{Low: v, High: v}, nil + } + toks = toks[1:] + + if len(toks) == 0 { + return VersionInterval{}, fmt.Errorf("expected version after '['") + } + low, err := parseVersion(verb, "", &toks[0], fix) + if err != nil { + return VersionInterval{}, err + } + toks = toks[1:] + + if len(toks) == 0 || toks[0] != "," { + return VersionInterval{}, fmt.Errorf("expected ',' after version") + } + toks = toks[1:] + + if len(toks) == 0 { + return VersionInterval{}, fmt.Errorf("expected version after ','") + } + high, err := parseVersion(verb, "", &toks[0], fix) + if err != nil { + return VersionInterval{}, err + } + toks = toks[1:] + + if len(toks) == 0 || toks[0] != "]" { + return VersionInterval{}, fmt.Errorf("expected ']' after version") + } + toks = toks[1:] + + *args = toks + return VersionInterval{Low: low, High: high}, nil +} + func parseString(s *string) (string, error) { t := *s if strings.HasPrefix(t, `"`) { @@ -461,6 +555,27 @@ func parseString(s *string) (string, error) { return t, nil } +// parseRetractRationale extracts the rationale for a retract directive from the +// surrounding comments. If the line does not have comments and is part of a +// block that does have comments, the block's comments are used. +func parseRetractRationale(block *LineBlock, line *Line) string { + comments := line.Comment() + if block != nil && len(comments.Before) == 0 && len(comments.Suffix) == 0 { + comments = block.Comment() + } + groups := [][]Comment{comments.Before, comments.Suffix} + var lines []string + for _, g := range groups { + for _, c := range g { + if !strings.HasPrefix(c.Token, "//") { + continue // blank line + } + lines = append(lines, strings.TrimSpace(strings.TrimPrefix(c.Token, "//"))) + } + } + return strings.Join(lines, "\n") +} + type ErrorList []Error func (e ErrorList) Error() string { @@ -494,6 +609,8 @@ func (e *Error) Error() string { var directive string if e.ModPath != "" { directive = fmt.Sprintf("%s %s: ", e.Verb, e.ModPath) + } else if e.Verb != "" { + directive = fmt.Sprintf("%s: ", e.Verb) } return pos + directive + e.Err.Error() @@ -585,6 +702,15 @@ func (f *File) Cleanup() { } f.Replace = f.Replace[:w] + w = 0 + for _, r := range f.Retract { + if r.Low != "" || r.High != "" { + f.Retract[w] = r + w++ + } + } + f.Retract = f.Retract[:w] + f.Syntax.Cleanup() } @@ -778,6 +904,34 @@ func (f *File) DropReplace(oldPath, oldVers string) error { return nil } +func (f *File) AddRetract(vi VersionInterval, rationale string) error { + r := &Retract{ + VersionInterval: vi, + } + if vi.Low == vi.High { + r.Syntax = f.Syntax.addLine(nil, "retract", AutoQuote(vi.Low)) + } else { + r.Syntax = f.Syntax.addLine(nil, "retract", "[", AutoQuote(vi.Low), ",", AutoQuote(vi.High), "]") + } + if rationale != "" { + for _, line := range strings.Split(rationale, "\n") { + com := Comment{Token: "// " + line} + r.Syntax.Comment().Before = append(r.Syntax.Comment().Before, com) + } + } + return nil +} + +func (f *File) DropRetract(vi VersionInterval) error { + for _, r := range f.Retract { + if r.VersionInterval == vi { + f.Syntax.removeLine(r.Syntax) + *r = Retract{} + } + } + return nil +} + func (f *File) SortBlocks() { f.removeDups() // otherwise sorting is unsafe @@ -786,28 +940,38 @@ func (f *File) SortBlocks() { 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) + less := lineLess + if block.Token[0] == "retract" { + less = lineRetractLess + } + sort.SliceStable(block.Line, func(i, j int) bool { + return less(block.Line[i], block.Line[j]) }) } } +// removeDups removes duplicate exclude and replace directives. +// +// Earlier exclude directives take priority. +// +// Later replace directives take priority. +// +// require directives are not de-duplicated. That's left up to higher-level +// logic (MVS). +// +// retract directives are not de-duplicated since comments are +// meaningful, and versions may be retracted multiple times. func (f *File) removeDups() { - have := make(map[module.Version]bool) kill := make(map[*Line]bool) + + // Remove duplicate excludes. + haveExclude := make(map[module.Version]bool) for _, x := range f.Exclude { - if have[x.Mod] { + if haveExclude[x.Mod] { kill[x.Syntax] = true continue } - have[x.Mod] = true + haveExclude[x.Mod] = true } var excl []*Exclude for _, x := range f.Exclude { @@ -817,15 +981,16 @@ func (f *File) removeDups() { } f.Exclude = excl - have = make(map[module.Version]bool) + // Remove duplicate replacements. // Later replacements take priority over earlier ones. + haveReplace := make(map[module.Version]bool) for i := len(f.Replace) - 1; i >= 0; i-- { x := f.Replace[i] - if have[x.Old] { + if haveReplace[x.Old] { kill[x.Syntax] = true continue } - have[x.Old] = true + haveReplace[x.Old] = true } var repl []*Replace for _, x := range f.Replace { @@ -835,6 +1000,9 @@ func (f *File) removeDups() { } f.Replace = repl + // Duplicate require and retract directives are not removed. + + // Drop killed statements from the syntax tree. var stmts []Expr for _, stmt := range f.Syntax.Stmt { switch stmt := stmt.(type) { @@ -858,3 +1026,38 @@ func (f *File) removeDups() { } f.Syntax.Stmt = stmts } + +// lineLess returns whether li should be sorted before lj. It sorts +// lexicographically without assigning any special meaning to tokens. +func lineLess(li, lj *Line) bool { + 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) +} + +// lineRetractLess returns whether li should be sorted before lj for lines in +// a "retract" block. It treats each line as a version interval. Single versions +// are compared as if they were intervals with the same low and high version. +// Intervals are sorted in descending order, first by low version, then by +// high version, using semver.Compare. +func lineRetractLess(li, lj *Line) bool { + interval := func(l *Line) VersionInterval { + if len(l.Token) == 1 { + return VersionInterval{Low: l.Token[0], High: l.Token[0]} + } else if len(l.Token) == 5 && l.Token[0] == "[" && l.Token[2] == "," && l.Token[4] == "]" { + return VersionInterval{Low: l.Token[1], High: l.Token[3]} + } else { + // Line in unknown format. Treat as an invalid version. + return VersionInterval{} + } + } + vii := interval(li) + vij := interval(lj) + if cmp := semver.Compare(vii.Low, vij.Low); cmp != 0 { + return cmp > 0 + } + return semver.Compare(vii.High, vij.High) > 0 +} diff --git a/libgo/go/golang.org/x/mod/module/module.go b/libgo/go/golang.org/x/mod/module/module.go index 6cd37280a85..c1c5263c427 100644 --- a/libgo/go/golang.org/x/mod/module/module.go +++ b/libgo/go/golang.org/x/mod/module/module.go @@ -97,6 +97,7 @@ package module import ( "fmt" + "path" "sort" "strings" "unicode" @@ -224,13 +225,13 @@ func firstPathOK(r rune) bool { } // pathOK reports whether r can appear in an import path element. -// Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: + - . _ and ~. +// 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 == '~' || + return r == '-' || r == '.' || r == '_' || r == '~' || '0' <= r && r <= '9' || 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' @@ -313,11 +314,13 @@ func CheckPath(path string) error { // 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 ~. +// 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). +// on Windows, regardless of case (CON, com1, NuL, and so on). The element +// must not have a suffix of a tilde followed by one or more ASCII digits +// (to exclude paths elements that look like Windows short-names). // // CheckImportPath may be less restrictive in the future, but see the // top-level package documentation for additional information about @@ -402,6 +405,29 @@ func checkElem(elem string, fileName bool) error { return fmt.Errorf("%q disallowed as path element component on Windows", short) } } + + if fileName { + // don't check for Windows short-names in file names. They're + // only an issue for import paths. + return nil + } + + // Reject path components that look like Windows short-names. + // Those usually end in a tilde followed by one or more ASCII digits. + if tilde := strings.LastIndexByte(short, '~'); tilde >= 0 && tilde < len(short)-1 { + suffix := short[tilde+1:] + suffixIsDigits := true + for _, r := range suffix { + if r < '0' || r > '9' { + suffixIsDigits = false + break + } + } + if suffixIsDigits { + return fmt.Errorf("trailing tilde and digits in path element") + } + } + return nil } @@ -716,3 +742,49 @@ func unescapeString(escaped string) (string, bool) { } return string(buf), true } + +// MatchPrefixPatterns reports whether any path prefix of target matches one of +// the glob patterns (as defined by path.Match) in the comma-separated globs +// list. This implements the algorithm used when matching a module path to the +// GOPRIVATE environment variable, as described by 'go help module-private'. +// +// It ignores any empty or malformed patterns in the list. +func MatchPrefixPatterns(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 +} diff --git a/libgo/go/golang.org/x/mod/semver/semver.go b/libgo/go/golang.org/x/mod/semver/semver.go index 2988e3cf9c5..4338f351774 100644 --- a/libgo/go/golang.org/x/mod/semver/semver.go +++ b/libgo/go/golang.org/x/mod/semver/semver.go @@ -138,6 +138,9 @@ func Compare(v, w string) int { // Max canonicalizes its arguments and then returns the version string // that compares greater. +// +// Deprecated: use Compare instead. In most cases, returning a canonicalized +// version is not expected or desired. func Max(v, w string) string { v = Canonical(v) w = Canonical(w) diff --git a/libgo/go/golang.org/x/mod/zip/zip.go b/libgo/go/golang.org/x/mod/zip/zip.go index 6865895b3d0..5b401ad4d8f 100644 --- a/libgo/go/golang.org/x/mod/zip/zip.go +++ b/libgo/go/golang.org/x/mod/zip/zip.go @@ -48,6 +48,7 @@ package zip import ( "archive/zip" "bytes" + "errors" "fmt" "io" "io/ioutil" @@ -92,40 +93,134 @@ type File interface { Open() (io.ReadCloser, error) } -// Create builds a zip archive for module m from an abstract list of files -// and writes it to w. +// CheckedFiles reports whether a set of files satisfy the name and size +// constraints required by module zip files. The constraints are listed in the +// package documentation. // -// 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} - } - }() +// Functions that produce this report may include slightly different sets of +// files. See documentation for CheckFiles, CheckDir, and CheckZip for details. +type CheckedFiles struct { + // Valid is a list of file paths that should be included in a zip file. + Valid []string + + // Omitted is a list of files that are ignored when creating a module zip + // file, along with the reason each file is ignored. + Omitted []FileError + + // Invalid is a list of files that should not be included in a module zip + // file, along with the reason each file is invalid. + Invalid []FileError + + // SizeError is non-nil if the total uncompressed size of the valid files + // exceeds the module zip size limit or if the zip file itself exceeds the + // limit. + SizeError error +} - // 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) +// Err returns an error if CheckedFiles does not describe a valid module zip +// file. SizeError is returned if that field is set. A FileErrorList is returned +// if there are one or more invalid files. Other errors may be returned in the +// future. +func (cf CheckedFiles) Err() error { + if cf.SizeError != nil { + return cf.SizeError } - if err := module.Check(m.Path, m.Version); err != nil { - return err + if len(cf.Invalid) > 0 { + return FileErrorList(cf.Invalid) + } + return nil +} + +type FileErrorList []FileError + +func (el FileErrorList) Error() string { + buf := &strings.Builder{} + sep := "" + for _, e := range el { + buf.WriteString(sep) + buf.WriteString(e.Error()) + sep = "\n" + } + return buf.String() +} + +type FileError struct { + Path string + Err error +} + +func (e FileError) Error() string { + return fmt.Sprintf("%s: %s", e.Path, e.Err) +} + +func (e FileError) Unwrap() error { + return e.Err +} + +var ( + // Predefined error messages for invalid files. Not exhaustive. + errPathNotClean = errors.New("file path is not clean") + errPathNotRelative = errors.New("file path is not relative") + errGoModCase = errors.New("go.mod files must have lowercase names") + errGoModSize = fmt.Errorf("go.mod file too large (max size is %d bytes)", MaxGoMod) + errLICENSESize = fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE) + + // Predefined error messages for omitted files. Not exhaustive. + errVCS = errors.New("directory is a version control repository") + errVendored = errors.New("file is in vendor directory") + errSubmoduleFile = errors.New("file is in another module") + errSubmoduleDir = errors.New("directory is in another module") + errHgArchivalTxt = errors.New("file is inserted by 'hg archive' and is always omitted") + errSymlink = errors.New("file is a symbolic link") + errNotRegular = errors.New("not a regular file") +) + +// CheckFiles reports whether a list of files satisfy the name and size +// constraints listed in the package documentation. The returned CheckedFiles +// record contains lists of valid, invalid, and omitted files. Every file in +// the given list will be included in exactly one of those lists. +// +// CheckFiles returns an error if the returned CheckedFiles does not describe +// a valid module zip file (according to CheckedFiles.Err). The returned +// CheckedFiles is still populated when an error is returned. +// +// Note that CheckFiles will not open any files, so Create may still fail when +// CheckFiles is successful due to I/O errors and reported size differences. +func CheckFiles(files []File) (CheckedFiles, error) { + cf, _, _ := checkFiles(files) + return cf, cf.Err() +} + +// checkFiles implements CheckFiles and also returns lists of valid files and +// their sizes, corresponding to cf.Valid. These lists are used in Crewate to +// avoid repeated calls to File.Lstat. +func checkFiles(files []File) (cf CheckedFiles, validFiles []File, validSizes []int64) { + errPaths := make(map[string]struct{}) + addError := func(path string, omitted bool, err error) { + if _, ok := errPaths[path]; ok { + return + } + errPaths[path] = struct{}{} + fe := FileError{Path: path, Err: err} + if omitted { + cf.Omitted = append(cf.Omitted, fe) + } else { + cf.Invalid = append(cf.Invalid, fe) + } } // Find directories containing go.mod files (other than the root). + // Files in these directories will be omitted. // 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()) + p := f.Path() + dir, base := path.Split(p) if strings.EqualFold(base, "go.mod") { info, err := f.Lstat() if err != nil { - return err + addError(p, false, err) + continue } if info.Mode().IsRegular() { haveGoMod[dir] = true @@ -146,77 +241,292 @@ func Create(w io.Writer, m module.Version, files []File) (err error) { } } - // 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) + addError(p, false, errPathNotClean) + continue } if path.IsAbs(p) { - return fmt.Errorf("file path %s is not relative", p) + addError(p, false, errPathNotRelative) + continue + } + if isVendoredPackage(p) { + addError(p, true, errVendored) + continue } - if isVendoredPackage(p) || inSubmodule(p) { + if inSubmodule(p) { + addError(p, true, errSubmoduleFile) continue } if p == ".hg_archival.txt" { // Inserted by hg archive. // The go command drops this regardless of the VCS being used. + addError(p, true, errHgArchivalTxt) continue } if err := module.CheckFilePath(p); err != nil { - return err + addError(p, false, err) + continue } if strings.ToLower(p) == "go.mod" && p != "go.mod" { - return fmt.Errorf("found file named %s, want all lower-case go.mod", p) + addError(p, false, errGoModCase) + continue } info, err := f.Lstat() if err != nil { - return err + addError(p, false, err) + continue } if err := collisions.check(p, info.IsDir()); err != nil { - return err + addError(p, false, err) + continue } - if !info.Mode().IsRegular() { + if info.Mode()&os.ModeType == os.ModeSymlink { // Skip symbolic links (golang.org/issue/27093). + addError(p, true, errSymlink) + continue + } + if !info.Mode().IsRegular() { + addError(p, true, errNotRegular) continue } size := info.Size() - if size < 0 || maxSize < size { - return fmt.Errorf("module source tree too large (max size is %d bytes)", MaxZipFile) + if size >= 0 && size <= maxSize { + maxSize -= size + } else if cf.SizeError == nil { + cf.SizeError = 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) + addError(p, false, errGoModSize) + continue } if p == "LICENSE" && size > MaxLICENSE { - return fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE) + addError(p, false, errLICENSESize) + continue + } + + cf.Valid = append(cf.Valid, p) + validFiles = append(validFiles, f) + validSizes = append(validSizes, info.Size()) + } + + return cf, validFiles, validSizes +} + +// CheckDir reports whether the files in dir satisfy the name and size +// constraints listed in the package documentation. The returned CheckedFiles +// record contains lists of valid, invalid, and omitted files. If a directory is +// omitted (for example, a nested module or vendor directory), it will appear in +// the omitted list, but its files won't be listed. +// +// CheckDir returns an error if it encounters an I/O error or if the returned +// CheckedFiles does not describe a valid module zip file (according to +// CheckedFiles.Err). The returned CheckedFiles is still populated when such +// an error is returned. +// +// Note that CheckDir will not open any files, so CreateFromDir may still fail +// when CheckDir is successful due to I/O errors. +func CheckDir(dir string) (CheckedFiles, error) { + // List files (as CreateFromDir would) and check which ones are omitted + // or invalid. + files, omitted, err := listFilesInDir(dir) + if err != nil { + return CheckedFiles{}, err + } + cf, cfErr := CheckFiles(files) + _ = cfErr // ignore this error; we'll generate our own after rewriting paths. + + // Replace all paths with file system paths. + // Paths returned by CheckFiles will be slash-separated paths relative to dir. + // That's probably not appropriate for error messages. + for i := range cf.Valid { + cf.Valid[i] = filepath.Join(dir, cf.Valid[i]) + } + cf.Omitted = append(cf.Omitted, omitted...) + for i := range cf.Omitted { + cf.Omitted[i].Path = filepath.Join(dir, cf.Omitted[i].Path) + } + for i := range cf.Invalid { + cf.Invalid[i].Path = filepath.Join(dir, cf.Invalid[i].Path) + } + return cf, cf.Err() +} + +// CheckZip reports whether the files contained in a zip file satisfy the name +// and size constraints listed in the package documentation. +// +// CheckZip returns an error if the returned CheckedFiles does not describe +// a valid module zip file (according to CheckedFiles.Err). The returned +// CheckedFiles is still populated when an error is returned. CheckZip will +// also return an error if the module path or version is malformed or if it +// encounters an error reading the zip file. +// +// Note that CheckZip does not read individual files, so Unzip may still fail +// when CheckZip is successful due to I/O errors. +func CheckZip(m module.Version, zipFile string) (CheckedFiles, error) { + f, err := os.Open(zipFile) + if err != nil { + return CheckedFiles{}, err + } + defer f.Close() + _, cf, err := checkZip(m, f) + return cf, err +} + +// checkZip implements checkZip and also returns the *zip.Reader. This is +// used in Unzip to avoid redundant I/O. +func checkZip(m module.Version, f *os.File) (*zip.Reader, CheckedFiles, error) { + // Make sure the module path and version are valid. + if vers := module.CanonicalVersion(m.Version); vers != m.Version { + return nil, CheckedFiles{}, fmt.Errorf("version %q is not canonical (should be %q)", m.Version, vers) + } + if err := module.Check(m.Path, m.Version); err != nil { + return nil, CheckedFiles{}, err + } + + // Check the total file size. + info, err := f.Stat() + if err != nil { + return nil, CheckedFiles{}, err + } + zipSize := info.Size() + if zipSize > MaxZipFile { + cf := CheckedFiles{SizeError: fmt.Errorf("module zip file is too large (%d bytes; limit is %d bytes)", zipSize, MaxZipFile)} + return nil, cf, cf.Err() + } + + // Check for valid file names, collisions. + var cf CheckedFiles + addError := func(zf *zip.File, err error) { + cf.Invalid = append(cf.Invalid, FileError{Path: zf.Name, Err: err}) + } + z, err := zip.NewReader(f, zipSize) + if err != nil { + return nil, CheckedFiles{}, err + } + prefix := fmt.Sprintf("%s@%s/", m.Path, m.Version) + collisions := make(collisionChecker) + var size int64 + for _, zf := range z.File { + if !strings.HasPrefix(zf.Name, prefix) { + addError(zf, fmt.Errorf("path does not have prefix %q", prefix)) + continue } + name := zf.Name[len(prefix):] + if name == "" { + continue + } + isDir := strings.HasSuffix(name, "/") + if isDir { + name = name[:len(name)-1] + } + if path.Clean(name) != name { + addError(zf, errPathNotClean) + continue + } + if err := module.CheckFilePath(name); err != nil { + addError(zf, err) + continue + } + if err := collisions.check(name, isDir); err != nil { + addError(zf, err) + continue + } + if isDir { + continue + } + if base := path.Base(name); strings.EqualFold(base, "go.mod") { + if base != name { + addError(zf, fmt.Errorf("go.mod file not in module root directory")) + continue + } + if name != "go.mod" { + addError(zf, errGoModCase) + continue + } + } + sz := int64(zf.UncompressedSize64) + if sz >= 0 && MaxZipFile-size >= sz { + size += sz + } else if cf.SizeError == nil { + cf.SizeError = fmt.Errorf("total uncompressed size of module contents too large (max size is %d bytes)", MaxZipFile) + } + if name == "go.mod" && sz > MaxGoMod { + addError(zf, fmt.Errorf("go.mod file too large (max size is %d bytes)", MaxGoMod)) + continue + } + if name == "LICENSE" && sz > MaxLICENSE { + addError(zf, fmt.Errorf("LICENSE file too large (max size is %d bytes)", MaxLICENSE)) + continue + } + cf.Valid = append(cf.Valid, zf.Name) + } + return z, cf, cf.Err() +} + +// 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 + } + + // Check whether files are valid, not valid, or should be omitted. + // Also check that the valid files don't exceed the maximum size. + cf, validFiles, validSizes := checkFiles(files) + if err := cf.Err(); err != nil { + return err + } + + // 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 + } + + for i, f := range validFiles { + p := f.Path() + size := validSizes[i] if err := addFile(f, p, size); err != nil { return err } @@ -245,61 +555,7 @@ func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) { } }() - var files []File - err = filepath.Walk(dir, func(filePath string, info os.FileInfo, err error) error { - if err != nil { - return err - } - 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 - }) + files, _, err := listFilesInDir(dir) if err != nil { return err } @@ -356,89 +612,28 @@ func Unzip(dir string, m module.Version, zipFile string) (err error) { } }() - 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 { + if files, _ := ioutil.ReadDir(dir); 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. + // Open the zip and check that it satisfies all restrictions. f, err := os.Open(zipFile) if err != nil { return err } defer f.Close() - info, err := f.Stat() + z, cf, err := checkZip(m, f) 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 { + if err := cf.Err(); err != nil { return err } - // Check total size, valid file names. - collisions := make(collisionChecker) + // Unzip, enforcing sizes declared in the zip file. 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 } @@ -515,6 +710,72 @@ func (cc collisionChecker) check(p string, isDir bool) error { return nil } +// listFilesInDir walks the directory tree rooted at dir and returns a list of +// files, as well as a list of directories and files that were skipped (for +// example, nested modules and symbolic links). +func listFilesInDir(dir string) (files []File, omitted []FileError, err error) { + err = filepath.Walk(dir, func(filePath string, info os.FileInfo, err error) error { + if err != nil { + return err + } + relPath, err := filepath.Rel(dir, filePath) + if err != nil { + return err + } + slashPath := filepath.ToSlash(relPath) + + // 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) { + omitted = append(omitted, FileError{Path: slashPath, Err: errVendored}) + return nil + } + + 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": + omitted = append(omitted, FileError{Path: slashPath, Err: errVCS}) + return filepath.SkipDir + } + + // Skip submodules (directories containing go.mod files). + if goModInfo, err := os.Lstat(filepath.Join(filePath, "go.mod")); err == nil && !goModInfo.IsDir() { + omitted = append(omitted, FileError{Path: slashPath, Err: errSubmoduleDir}) + return filepath.SkipDir + } + return nil + } + + // Skip irregular files and files in vendor directories. + // Irregular files are ignored. They're typically symbolic links. + if !info.Mode().IsRegular() { + omitted = append(omitted, FileError{Path: slashPath, Err: errNotRegular}) + return nil + } + + files = append(files, dirFile{ + filePath: filePath, + slashPath: slashPath, + info: info, + }) + return nil + }) + if err != nil { + return nil, nil, err + } + return files, omitted, nil +} + type zipError struct { verb, path string err error diff --git a/libgo/go/golang.org/x/net/http/httpproxy/proxy.go b/libgo/go/golang.org/x/net/http/httpproxy/proxy.go index 163645b86f3..1415b077912 100644 --- a/libgo/go/golang.org/x/net/http/httpproxy/proxy.go +++ b/libgo/go/golang.org/x/net/http/httpproxy/proxy.go @@ -27,8 +27,7 @@ import ( type Config struct { // HTTPProxy represents the value of the HTTP_PROXY or // http_proxy environment variable. It will be used as the proxy - // URL for HTTP requests and HTTPS requests unless overridden by - // HTTPSProxy or NoProxy. + // URL for HTTP requests unless overridden by NoProxy. HTTPProxy string // HTTPSProxy represents the HTTPS_PROXY or https_proxy @@ -129,8 +128,7 @@ func (cfg *config) proxyForURL(reqURL *url.URL) (*url.URL, error) { var proxy *url.URL if reqURL.Scheme == "https" { proxy = cfg.httpsProxy - } - if proxy == nil { + } else if reqURL.Scheme == "http" { proxy = cfg.httpProxy if proxy != nil && cfg.CGI { return nil, errors.New("refusing to use HTTP_PROXY value in CGI environment; see golang.org/s/cgihttpproxy") diff --git a/libgo/go/golang.org/x/net/idna/tables12.00.go b/libgo/go/golang.org/x/net/idna/tables12.0.0.go similarity index 99% rename from libgo/go/golang.org/x/net/idna/tables12.00.go rename to libgo/go/golang.org/x/net/idna/tables12.0.0.go index f4b8ea3638e..f39f0cb4cd8 100644 --- a/libgo/go/golang.org/x/net/idna/tables12.00.go +++ b/libgo/go/golang.org/x/net/idna/tables12.0.0.go @@ -1,6 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. -// +build go1.14 +// +build go1.14,!go1.16 package idna diff --git a/libgo/go/golang.org/x/net/idna/tables13.0.0.go b/libgo/go/golang.org/x/net/idna/tables13.0.0.go new file mode 100644 index 00000000000..e8c7a36d7a7 --- /dev/null +++ b/libgo/go/golang.org/x/net/idna/tables13.0.0.go @@ -0,0 +1,4839 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.16 + +package idna + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "13.0.0" + +var mappings string = "" + // Size: 8188 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\x06令和\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点\x04" + + "2点\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œ\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\x03p" + + "pv\x02wc\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: 30288 bytes (29.58 KiB). Checksum: c0cd84404a2f6f19. +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 < 126: + return uint16(idnaValues[n<<6+uint32(b)]) + default: + n -= 126 + return uint16(idnaSparse.lookup(n, b)) + } +} + +// idnaValues: 128 blocks, 8192 entries, 16384 bytes +// The third block is the zero block. +var idnaValues = [8192]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: 0x0c08, 0x557: 0x0c08, + 0x558: 0x0c08, 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: 0x3308, 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: 0x0008, + 0xf3c: 0x0008, 0xf3d: 0x0008, 0xf3e: 0x0008, 0xf3f: 0x0008, + // 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: 0x3cc9, + // Block 0x40, offset 0x1000 + 0x1000: 0x3d01, 0x1001: 0x3d69, 0x1002: 0x3dd1, 0x1003: 0x3e39, 0x1004: 0x3e89, 0x1005: 0x3ef1, + 0x1006: 0x3f41, 0x1007: 0x3f91, 0x1008: 0x4011, 0x1009: 0x4079, 0x100a: 0x40c9, 0x100b: 0x4119, + 0x100c: 0x4169, 0x100d: 0x41d1, 0x100e: 0x4239, 0x100f: 0x4289, 0x1010: 0x42d9, 0x1011: 0x4311, + 0x1012: 0x4361, 0x1013: 0x43c9, 0x1014: 0x4431, 0x1015: 0x4469, 0x1016: 0x44e9, 0x1017: 0x4581, + 0x1018: 0x4601, 0x1019: 0x4651, 0x101a: 0x46d1, 0x101b: 0x4751, 0x101c: 0x47b9, 0x101d: 0x4809, + 0x101e: 0x4859, 0x101f: 0x48a9, 0x1020: 0x4911, 0x1021: 0x4991, 0x1022: 0x49f9, 0x1023: 0x4a49, + 0x1024: 0x4a99, 0x1025: 0x4ae9, 0x1026: 0x4b21, 0x1027: 0x4b59, 0x1028: 0x4b91, 0x1029: 0x4bc9, + 0x102a: 0x4c19, 0x102b: 0x4c69, 0x102c: 0x4ce9, 0x102d: 0x4d39, 0x102e: 0x4da1, 0x102f: 0x4e21, + 0x1030: 0x4e71, 0x1031: 0x4ea9, 0x1032: 0x4ee1, 0x1033: 0x4f61, 0x1034: 0x4fc9, 0x1035: 0x5049, + 0x1036: 0x5099, 0x1037: 0x5119, 0x1038: 0x5151, 0x1039: 0x51a1, 0x103a: 0x51f1, 0x103b: 0x5241, + 0x103c: 0x5291, 0x103d: 0x52e1, 0x103e: 0x5349, 0x103f: 0x5399, + // Block 0x41, offset 0x1040 + 0x1040: 0x53d1, 0x1041: 0x5421, 0x1042: 0x5471, 0x1043: 0x54c1, 0x1044: 0x5529, 0x1045: 0x5579, + 0x1046: 0x55c9, 0x1047: 0x5619, 0x1048: 0x5699, 0x1049: 0x5701, 0x104a: 0x5739, 0x104b: 0x57b9, + 0x104c: 0x57f1, 0x104d: 0x5859, 0x104e: 0x58c1, 0x104f: 0x5911, 0x1050: 0x5961, 0x1051: 0x59b1, + 0x1052: 0x5a19, 0x1053: 0x5a51, 0x1054: 0x5aa1, 0x1055: 0x5b09, 0x1056: 0x5b41, 0x1057: 0x5bc1, + 0x1058: 0x5c11, 0x1059: 0x5c39, 0x105a: 0x5c61, 0x105b: 0x5c89, 0x105c: 0x5cb1, 0x105d: 0x5cd9, + 0x105e: 0x5d01, 0x105f: 0x5d29, 0x1060: 0x5d51, 0x1061: 0x5d79, 0x1062: 0x5da1, 0x1063: 0x5dd1, + 0x1064: 0x5e01, 0x1065: 0x5e31, 0x1066: 0x5e61, 0x1067: 0x5e91, 0x1068: 0x5ec1, 0x1069: 0x5ef1, + 0x106a: 0x5f21, 0x106b: 0x5f51, 0x106c: 0x5f81, 0x106d: 0x5fb1, 0x106e: 0x5fe1, 0x106f: 0x6011, + 0x1070: 0x6041, 0x1071: 0x4045, 0x1072: 0x6071, 0x1073: 0x6089, 0x1074: 0x4065, 0x1075: 0x60a1, + 0x1076: 0x60b9, 0x1077: 0x60d1, 0x1078: 0x4085, 0x1079: 0x4085, 0x107a: 0x60e9, 0x107b: 0x6101, + 0x107c: 0x6139, 0x107d: 0x6171, 0x107e: 0x61a9, 0x107f: 0x61e1, + // Block 0x42, offset 0x1080 + 0x1080: 0x6249, 0x1081: 0x6261, 0x1082: 0x40a5, 0x1083: 0x6279, 0x1084: 0x6291, 0x1085: 0x62a9, + 0x1086: 0x62c1, 0x1087: 0x62d9, 0x1088: 0x40c5, 0x1089: 0x62f1, 0x108a: 0x6319, 0x108b: 0x6331, + 0x108c: 0x40e5, 0x108d: 0x40e5, 0x108e: 0x6349, 0x108f: 0x6361, 0x1090: 0x6379, 0x1091: 0x4105, + 0x1092: 0x4125, 0x1093: 0x4145, 0x1094: 0x4165, 0x1095: 0x4185, 0x1096: 0x6391, 0x1097: 0x63a9, + 0x1098: 0x63c1, 0x1099: 0x63d9, 0x109a: 0x63f1, 0x109b: 0x41a5, 0x109c: 0x6409, 0x109d: 0x6421, + 0x109e: 0x6439, 0x109f: 0x41c5, 0x10a0: 0x41e5, 0x10a1: 0x6451, 0x10a2: 0x4205, 0x10a3: 0x4225, + 0x10a4: 0x4245, 0x10a5: 0x6469, 0x10a6: 0x4265, 0x10a7: 0x6481, 0x10a8: 0x64b1, 0x10a9: 0x6249, + 0x10aa: 0x4285, 0x10ab: 0x42a5, 0x10ac: 0x42c5, 0x10ad: 0x42e5, 0x10ae: 0x64e9, 0x10af: 0x6529, + 0x10b0: 0x6571, 0x10b1: 0x6589, 0x10b2: 0x4305, 0x10b3: 0x65a1, 0x10b4: 0x65b9, 0x10b5: 0x65d1, + 0x10b6: 0x4325, 0x10b7: 0x65e9, 0x10b8: 0x6601, 0x10b9: 0x65e9, 0x10ba: 0x6619, 0x10bb: 0x6631, + 0x10bc: 0x4345, 0x10bd: 0x6649, 0x10be: 0x6661, 0x10bf: 0x6649, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x4365, 0x10c1: 0x4385, 0x10c2: 0x0040, 0x10c3: 0x6679, 0x10c4: 0x6691, 0x10c5: 0x66a9, + 0x10c6: 0x66c1, 0x10c7: 0x0040, 0x10c8: 0x66f9, 0x10c9: 0x6711, 0x10ca: 0x6729, 0x10cb: 0x6741, + 0x10cc: 0x6759, 0x10cd: 0x6771, 0x10ce: 0x6439, 0x10cf: 0x6789, 0x10d0: 0x67a1, 0x10d1: 0x67b9, + 0x10d2: 0x43a5, 0x10d3: 0x67d1, 0x10d4: 0x62c1, 0x10d5: 0x43c5, 0x10d6: 0x43e5, 0x10d7: 0x67e9, + 0x10d8: 0x0040, 0x10d9: 0x4405, 0x10da: 0x6801, 0x10db: 0x6819, 0x10dc: 0x6831, 0x10dd: 0x6849, + 0x10de: 0x6861, 0x10df: 0x6891, 0x10e0: 0x68c1, 0x10e1: 0x68e9, 0x10e2: 0x6911, 0x10e3: 0x6939, + 0x10e4: 0x6961, 0x10e5: 0x6989, 0x10e6: 0x69b1, 0x10e7: 0x69d9, 0x10e8: 0x6a01, 0x10e9: 0x6a29, + 0x10ea: 0x6a59, 0x10eb: 0x6a89, 0x10ec: 0x6ab9, 0x10ed: 0x6ae9, 0x10ee: 0x6b19, 0x10ef: 0x6b49, + 0x10f0: 0x6b79, 0x10f1: 0x6ba9, 0x10f2: 0x6bd9, 0x10f3: 0x6c09, 0x10f4: 0x6c39, 0x10f5: 0x6c69, + 0x10f6: 0x6c99, 0x10f7: 0x6cc9, 0x10f8: 0x6cf9, 0x10f9: 0x6d29, 0x10fa: 0x6d59, 0x10fb: 0x6d89, + 0x10fc: 0x6db9, 0x10fd: 0x6de9, 0x10fe: 0x6e19, 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: 0x6e49, + 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: 0x6e61, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e79, 0x122e: 0x1221, 0x122f: 0x0008, + 0x1230: 0x6e91, 0x1231: 0x6ea9, 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: 0x6f19, 0x1290: 0x6f41, 0x1291: 0x6f69, + 0x1292: 0x7cad, 0x1293: 0x7ccd, 0x1294: 0x7ced, 0x1295: 0x6f91, 0x1296: 0x6fb9, 0x1297: 0x6fe1, + 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: 0x7009, 0x12c1: 0x7021, 0x12c2: 0x7039, 0x12c3: 0x7d4d, 0x12c4: 0x7d6d, 0x12c5: 0x7051, + 0x12c6: 0x7051, 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: 0x7069, 0x12d4: 0x7091, 0x12d5: 0x70b9, 0x12d6: 0x70e1, 0x12d7: 0x7109, + 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x7131, + 0x12de: 0x3308, 0x12df: 0x7159, 0x12e0: 0x7181, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7199, + 0x12e4: 0x71b1, 0x12e5: 0x71c9, 0x12e6: 0x71e1, 0x12e7: 0x71f9, 0x12e8: 0x7211, 0x12e9: 0x1fb2, + 0x12ea: 0x7229, 0x12eb: 0x7251, 0x12ec: 0x7279, 0x12ed: 0x72b1, 0x12ee: 0x72e9, 0x12ef: 0x7311, + 0x12f0: 0x7339, 0x12f1: 0x7361, 0x12f2: 0x7389, 0x12f3: 0x73b1, 0x12f4: 0x73d9, 0x12f5: 0x7401, + 0x12f6: 0x7429, 0x12f7: 0x0040, 0x12f8: 0x7451, 0x12f9: 0x7479, 0x12fa: 0x74a1, 0x12fb: 0x74c9, + 0x12fc: 0x74f1, 0x12fd: 0x0040, 0x12fe: 0x7519, 0x12ff: 0x0040, + // Block 0x4c, offset 0x1300 + 0x1300: 0x7541, 0x1301: 0x7569, 0x1302: 0x0040, 0x1303: 0x7591, 0x1304: 0x75b9, 0x1305: 0x0040, + 0x1306: 0x75e1, 0x1307: 0x7609, 0x1308: 0x7631, 0x1309: 0x7659, 0x130a: 0x7681, 0x130b: 0x76a9, + 0x130c: 0x76d1, 0x130d: 0x76f9, 0x130e: 0x7721, 0x130f: 0x7749, 0x1310: 0x7771, 0x1311: 0x7771, + 0x1312: 0x7789, 0x1313: 0x7789, 0x1314: 0x7789, 0x1315: 0x7789, 0x1316: 0x77a1, 0x1317: 0x77a1, + 0x1318: 0x77a1, 0x1319: 0x77a1, 0x131a: 0x77b9, 0x131b: 0x77b9, 0x131c: 0x77b9, 0x131d: 0x77b9, + 0x131e: 0x77d1, 0x131f: 0x77d1, 0x1320: 0x77d1, 0x1321: 0x77d1, 0x1322: 0x77e9, 0x1323: 0x77e9, + 0x1324: 0x77e9, 0x1325: 0x77e9, 0x1326: 0x7801, 0x1327: 0x7801, 0x1328: 0x7801, 0x1329: 0x7801, + 0x132a: 0x7819, 0x132b: 0x7819, 0x132c: 0x7819, 0x132d: 0x7819, 0x132e: 0x7831, 0x132f: 0x7831, + 0x1330: 0x7831, 0x1331: 0x7831, 0x1332: 0x7849, 0x1333: 0x7849, 0x1334: 0x7849, 0x1335: 0x7849, + 0x1336: 0x7861, 0x1337: 0x7861, 0x1338: 0x7861, 0x1339: 0x7861, 0x133a: 0x7879, 0x133b: 0x7879, + 0x133c: 0x7879, 0x133d: 0x7879, 0x133e: 0x7891, 0x133f: 0x7891, + // Block 0x4d, offset 0x1340 + 0x1340: 0x7891, 0x1341: 0x7891, 0x1342: 0x78a9, 0x1343: 0x78a9, 0x1344: 0x78c1, 0x1345: 0x78c1, + 0x1346: 0x78d9, 0x1347: 0x78d9, 0x1348: 0x78f1, 0x1349: 0x78f1, 0x134a: 0x7909, 0x134b: 0x7909, + 0x134c: 0x7921, 0x134d: 0x7921, 0x134e: 0x7939, 0x134f: 0x7939, 0x1350: 0x7939, 0x1351: 0x7939, + 0x1352: 0x7951, 0x1353: 0x7951, 0x1354: 0x7951, 0x1355: 0x7951, 0x1356: 0x7969, 0x1357: 0x7969, + 0x1358: 0x7969, 0x1359: 0x7969, 0x135a: 0x7981, 0x135b: 0x7981, 0x135c: 0x7981, 0x135d: 0x7981, + 0x135e: 0x7999, 0x135f: 0x7999, 0x1360: 0x79b1, 0x1361: 0x79b1, 0x1362: 0x79b1, 0x1363: 0x79b1, + 0x1364: 0x79c9, 0x1365: 0x79c9, 0x1366: 0x79e1, 0x1367: 0x79e1, 0x1368: 0x79e1, 0x1369: 0x79e1, + 0x136a: 0x79f9, 0x136b: 0x79f9, 0x136c: 0x79f9, 0x136d: 0x79f9, 0x136e: 0x7a11, 0x136f: 0x7a11, + 0x1370: 0x7a29, 0x1371: 0x7a29, 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: 0x7a41, 0x1394: 0x7a41, 0x1395: 0x7a41, 0x1396: 0x7a41, 0x1397: 0x7a59, + 0x1398: 0x7a59, 0x1399: 0x7a71, 0x139a: 0x7a71, 0x139b: 0x7a89, 0x139c: 0x7a89, 0x139d: 0x0479, + 0x139e: 0x7aa1, 0x139f: 0x7aa1, 0x13a0: 0x7ab9, 0x13a1: 0x7ab9, 0x13a2: 0x7ad1, 0x13a3: 0x7ad1, + 0x13a4: 0x7ae9, 0x13a5: 0x7ae9, 0x13a6: 0x7ae9, 0x13a7: 0x7ae9, 0x13a8: 0x7b01, 0x13a9: 0x7b01, + 0x13aa: 0x7b19, 0x13ab: 0x7b19, 0x13ac: 0x7b41, 0x13ad: 0x7b41, 0x13ae: 0x7b69, 0x13af: 0x7b69, + 0x13b0: 0x7b91, 0x13b1: 0x7b91, 0x13b2: 0x7bb9, 0x13b3: 0x7bb9, 0x13b4: 0x7be1, 0x13b5: 0x7be1, + 0x13b6: 0x7c09, 0x13b7: 0x7c09, 0x13b8: 0x7c09, 0x13b9: 0x7c31, 0x13ba: 0x7c31, 0x13bb: 0x7c31, + 0x13bc: 0x7c59, 0x13bd: 0x7c59, 0x13be: 0x7c59, 0x13bf: 0x7c59, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x8649, 0x13c1: 0x8671, 0x13c2: 0x8699, 0x13c3: 0x86c1, 0x13c4: 0x86e9, 0x13c5: 0x8711, + 0x13c6: 0x8739, 0x13c7: 0x8761, 0x13c8: 0x8789, 0x13c9: 0x87b1, 0x13ca: 0x87d9, 0x13cb: 0x8801, + 0x13cc: 0x8829, 0x13cd: 0x8851, 0x13ce: 0x8879, 0x13cf: 0x88a1, 0x13d0: 0x88c9, 0x13d1: 0x88f1, + 0x13d2: 0x8919, 0x13d3: 0x8941, 0x13d4: 0x8969, 0x13d5: 0x8991, 0x13d6: 0x89b9, 0x13d7: 0x89e1, + 0x13d8: 0x8a09, 0x13d9: 0x8a31, 0x13da: 0x8a59, 0x13db: 0x8a81, 0x13dc: 0x8aa9, 0x13dd: 0x8ad1, + 0x13de: 0x8afa, 0x13df: 0x8b2a, 0x13e0: 0x8b5a, 0x13e1: 0x8b8a, 0x13e2: 0x8bba, 0x13e3: 0x8bea, + 0x13e4: 0x8c19, 0x13e5: 0x8c41, 0x13e6: 0x7cc1, 0x13e7: 0x8c69, 0x13e8: 0x7c31, 0x13e9: 0x7ce9, + 0x13ea: 0x8c91, 0x13eb: 0x8cb9, 0x13ec: 0x7d89, 0x13ed: 0x8ce1, 0x13ee: 0x7db1, 0x13ef: 0x7dd9, + 0x13f0: 0x8d09, 0x13f1: 0x8d31, 0x13f2: 0x7e79, 0x13f3: 0x8d59, 0x13f4: 0x7ea1, 0x13f5: 0x7ec9, + 0x13f6: 0x8d81, 0x13f7: 0x8da9, 0x13f8: 0x7f19, 0x13f9: 0x8dd1, 0x13fa: 0x7f41, 0x13fb: 0x7f69, + 0x13fc: 0x83f1, 0x13fd: 0x8419, 0x13fe: 0x8491, 0x13ff: 0x84b9, + // Block 0x50, offset 0x1400 + 0x1400: 0x84e1, 0x1401: 0x8581, 0x1402: 0x85a9, 0x1403: 0x85d1, 0x1404: 0x85f9, 0x1405: 0x8699, + 0x1406: 0x86c1, 0x1407: 0x86e9, 0x1408: 0x8df9, 0x1409: 0x8789, 0x140a: 0x8e21, 0x140b: 0x8e49, + 0x140c: 0x8879, 0x140d: 0x8e71, 0x140e: 0x88a1, 0x140f: 0x88c9, 0x1410: 0x8ad1, 0x1411: 0x8e99, + 0x1412: 0x8ec1, 0x1413: 0x8a09, 0x1414: 0x8ee9, 0x1415: 0x8a31, 0x1416: 0x8a59, 0x1417: 0x7c71, + 0x1418: 0x7c99, 0x1419: 0x8f11, 0x141a: 0x7cc1, 0x141b: 0x8f39, 0x141c: 0x7d11, 0x141d: 0x7d39, + 0x141e: 0x7d61, 0x141f: 0x7d89, 0x1420: 0x8f61, 0x1421: 0x7e01, 0x1422: 0x7e29, 0x1423: 0x7e51, + 0x1424: 0x7e79, 0x1425: 0x8f89, 0x1426: 0x7f19, 0x1427: 0x7f91, 0x1428: 0x7fb9, 0x1429: 0x7fe1, + 0x142a: 0x8009, 0x142b: 0x8031, 0x142c: 0x8081, 0x142d: 0x80a9, 0x142e: 0x80d1, 0x142f: 0x80f9, + 0x1430: 0x8121, 0x1431: 0x8149, 0x1432: 0x8fb1, 0x1433: 0x8171, 0x1434: 0x8199, 0x1435: 0x81c1, + 0x1436: 0x81e9, 0x1437: 0x8211, 0x1438: 0x8239, 0x1439: 0x8289, 0x143a: 0x82b1, 0x143b: 0x82d9, + 0x143c: 0x8301, 0x143d: 0x8329, 0x143e: 0x8351, 0x143f: 0x8379, + // Block 0x51, offset 0x1440 + 0x1440: 0x83a1, 0x1441: 0x83c9, 0x1442: 0x8441, 0x1443: 0x8469, 0x1444: 0x8509, 0x1445: 0x8531, + 0x1446: 0x8559, 0x1447: 0x8581, 0x1448: 0x85a9, 0x1449: 0x8621, 0x144a: 0x8649, 0x144b: 0x8671, + 0x144c: 0x8699, 0x144d: 0x8fd9, 0x144e: 0x8711, 0x144f: 0x8739, 0x1450: 0x8761, 0x1451: 0x8789, + 0x1452: 0x8801, 0x1453: 0x8829, 0x1454: 0x8851, 0x1455: 0x8879, 0x1456: 0x9001, 0x1457: 0x88f1, + 0x1458: 0x8919, 0x1459: 0x9029, 0x145a: 0x8991, 0x145b: 0x89b9, 0x145c: 0x89e1, 0x145d: 0x8a09, + 0x145e: 0x9051, 0x145f: 0x7cc1, 0x1460: 0x8f39, 0x1461: 0x7d89, 0x1462: 0x8f61, 0x1463: 0x7e79, + 0x1464: 0x8f89, 0x1465: 0x7f19, 0x1466: 0x9079, 0x1467: 0x8121, 0x1468: 0x90a1, 0x1469: 0x90c9, + 0x146a: 0x90f1, 0x146b: 0x8581, 0x146c: 0x85a9, 0x146d: 0x8699, 0x146e: 0x8879, 0x146f: 0x9001, + 0x1470: 0x8a09, 0x1471: 0x9051, 0x1472: 0x9119, 0x1473: 0x9151, 0x1474: 0x9189, 0x1475: 0x91c1, + 0x1476: 0x91e9, 0x1477: 0x9211, 0x1478: 0x9239, 0x1479: 0x9261, 0x147a: 0x9289, 0x147b: 0x92b1, + 0x147c: 0x92d9, 0x147d: 0x9301, 0x147e: 0x9329, 0x147f: 0x9351, + // Block 0x52, offset 0x1480 + 0x1480: 0x9379, 0x1481: 0x93a1, 0x1482: 0x93c9, 0x1483: 0x93f1, 0x1484: 0x9419, 0x1485: 0x9441, + 0x1486: 0x9469, 0x1487: 0x9491, 0x1488: 0x94b9, 0x1489: 0x94e1, 0x148a: 0x9509, 0x148b: 0x9531, + 0x148c: 0x90c9, 0x148d: 0x9559, 0x148e: 0x9581, 0x148f: 0x95a9, 0x1490: 0x95d1, 0x1491: 0x91c1, + 0x1492: 0x91e9, 0x1493: 0x9211, 0x1494: 0x9239, 0x1495: 0x9261, 0x1496: 0x9289, 0x1497: 0x92b1, + 0x1498: 0x92d9, 0x1499: 0x9301, 0x149a: 0x9329, 0x149b: 0x9351, 0x149c: 0x9379, 0x149d: 0x93a1, + 0x149e: 0x93c9, 0x149f: 0x93f1, 0x14a0: 0x9419, 0x14a1: 0x9441, 0x14a2: 0x9469, 0x14a3: 0x9491, + 0x14a4: 0x94b9, 0x14a5: 0x94e1, 0x14a6: 0x9509, 0x14a7: 0x9531, 0x14a8: 0x90c9, 0x14a9: 0x9559, + 0x14aa: 0x9581, 0x14ab: 0x95a9, 0x14ac: 0x95d1, 0x14ad: 0x94e1, 0x14ae: 0x9509, 0x14af: 0x9531, + 0x14b0: 0x90c9, 0x14b1: 0x90a1, 0x14b2: 0x90f1, 0x14b3: 0x8261, 0x14b4: 0x80a9, 0x14b5: 0x80d1, + 0x14b6: 0x80f9, 0x14b7: 0x94e1, 0x14b8: 0x9509, 0x14b9: 0x9531, 0x14ba: 0x8261, 0x14bb: 0x8289, + 0x14bc: 0x95f9, 0x14bd: 0x95f9, 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: 0x9621, 0x14d1: 0x9659, + 0x14d2: 0x9659, 0x14d3: 0x9691, 0x14d4: 0x96c9, 0x14d5: 0x9701, 0x14d6: 0x9739, 0x14d7: 0x9771, + 0x14d8: 0x97a9, 0x14d9: 0x97a9, 0x14da: 0x97e1, 0x14db: 0x9819, 0x14dc: 0x9851, 0x14dd: 0x9889, + 0x14de: 0x98c1, 0x14df: 0x98f9, 0x14e0: 0x98f9, 0x14e1: 0x9931, 0x14e2: 0x9969, 0x14e3: 0x9969, + 0x14e4: 0x99a1, 0x14e5: 0x99a1, 0x14e6: 0x99d9, 0x14e7: 0x9a11, 0x14e8: 0x9a11, 0x14e9: 0x9a49, + 0x14ea: 0x9a81, 0x14eb: 0x9a81, 0x14ec: 0x9ab9, 0x14ed: 0x9ab9, 0x14ee: 0x9af1, 0x14ef: 0x9b29, + 0x14f0: 0x9b29, 0x14f1: 0x9b61, 0x14f2: 0x9b61, 0x14f3: 0x9b99, 0x14f4: 0x9bd1, 0x14f5: 0x9c09, + 0x14f6: 0x9c41, 0x14f7: 0x9c41, 0x14f8: 0x9c79, 0x14f9: 0x9cb1, 0x14fa: 0x9ce9, 0x14fb: 0x9d21, + 0x14fc: 0x9d59, 0x14fd: 0x9d59, 0x14fe: 0x9d91, 0x14ff: 0x9dc9, + // Block 0x54, offset 0x1500 + 0x1500: 0xa999, 0x1501: 0xa9d1, 0x1502: 0xaa09, 0x1503: 0xa8f1, 0x1504: 0x9c09, 0x1505: 0x99d9, + 0x1506: 0xaa41, 0x1507: 0xaa79, 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: 0xaab1, 0x1531: 0xaae9, 0x1532: 0xab21, 0x1533: 0xab69, 0x1534: 0xabb1, 0x1535: 0xabf9, + 0x1536: 0xac41, 0x1537: 0xac89, 0x1538: 0xacd1, 0x1539: 0xad19, 0x153a: 0xad52, 0x153b: 0xae62, + 0x153c: 0xaee1, 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: 0xaf2a, 0x1551: 0x7d8d, + 0x1552: 0x0040, 0x1553: 0xaf3a, 0x1554: 0x03c2, 0x1555: 0xaf4a, 0x1556: 0xaf5a, 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: 0xaf6a, 0x1574: 0xaf6a, 0x1575: 0x1fd2, + 0x1576: 0x1fe2, 0x1577: 0xaf7a, 0x1578: 0xaf8a, 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: 0xaf9a, 0x1588: 0xafaa, 0x1589: 0x7f4e, 0x158a: 0x7f6e, 0x158b: 0x7f8e, + 0x158c: 0x7fae, 0x158d: 0xaf6a, 0x158e: 0xaf6a, 0x158f: 0xaf6a, 0x1590: 0xaf2a, 0x1591: 0x7fcd, + 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaf3a, 0x1596: 0xaf5a, 0x1597: 0xaf4a, + 0x1598: 0x7fed, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf7a, 0x159c: 0xaf8a, 0x159d: 0x7ecd, + 0x159e: 0x7f2d, 0x159f: 0xafba, 0x15a0: 0xafca, 0x15a1: 0xafda, 0x15a2: 0x1fb2, 0x15a3: 0xafe9, + 0x15a4: 0xaffa, 0x15a5: 0xb00a, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xb01a, 0x15a9: 0xb02a, + 0x15aa: 0xb03a, 0x15ab: 0xb04a, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040, + 0x15b0: 0x800e, 0x15b1: 0xb059, 0x15b2: 0x802e, 0x15b3: 0x0808, 0x15b4: 0x804e, 0x15b5: 0x0040, + 0x15b6: 0x806e, 0x15b7: 0xb081, 0x15b8: 0x808e, 0x15b9: 0xb0a9, 0x15ba: 0x80ae, 0x15bb: 0xb0d1, + 0x15bc: 0x80ce, 0x15bd: 0xb0f9, 0x15be: 0x80ee, 0x15bf: 0xb121, + // Block 0x57, offset 0x15c0 + 0x15c0: 0xb149, 0x15c1: 0xb161, 0x15c2: 0xb161, 0x15c3: 0xb179, 0x15c4: 0xb179, 0x15c5: 0xb191, + 0x15c6: 0xb191, 0x15c7: 0xb1a9, 0x15c8: 0xb1a9, 0x15c9: 0xb1c1, 0x15ca: 0xb1c1, 0x15cb: 0xb1c1, + 0x15cc: 0xb1c1, 0x15cd: 0xb1d9, 0x15ce: 0xb1d9, 0x15cf: 0xb1f1, 0x15d0: 0xb1f1, 0x15d1: 0xb1f1, + 0x15d2: 0xb1f1, 0x15d3: 0xb209, 0x15d4: 0xb209, 0x15d5: 0xb221, 0x15d6: 0xb221, 0x15d7: 0xb221, + 0x15d8: 0xb221, 0x15d9: 0xb239, 0x15da: 0xb239, 0x15db: 0xb239, 0x15dc: 0xb239, 0x15dd: 0xb251, + 0x15de: 0xb251, 0x15df: 0xb251, 0x15e0: 0xb251, 0x15e1: 0xb269, 0x15e2: 0xb269, 0x15e3: 0xb269, + 0x15e4: 0xb269, 0x15e5: 0xb281, 0x15e6: 0xb281, 0x15e7: 0xb281, 0x15e8: 0xb281, 0x15e9: 0xb299, + 0x15ea: 0xb299, 0x15eb: 0xb2b1, 0x15ec: 0xb2b1, 0x15ed: 0xb2c9, 0x15ee: 0xb2c9, 0x15ef: 0xb2e1, + 0x15f0: 0xb2e1, 0x15f1: 0xb2f9, 0x15f2: 0xb2f9, 0x15f3: 0xb2f9, 0x15f4: 0xb2f9, 0x15f5: 0xb311, + 0x15f6: 0xb311, 0x15f7: 0xb311, 0x15f8: 0xb311, 0x15f9: 0xb329, 0x15fa: 0xb329, 0x15fb: 0xb329, + 0x15fc: 0xb329, 0x15fd: 0xb341, 0x15fe: 0xb341, 0x15ff: 0xb341, + // Block 0x58, offset 0x1600 + 0x1600: 0xb341, 0x1601: 0xb359, 0x1602: 0xb359, 0x1603: 0xb359, 0x1604: 0xb359, 0x1605: 0xb371, + 0x1606: 0xb371, 0x1607: 0xb371, 0x1608: 0xb371, 0x1609: 0xb389, 0x160a: 0xb389, 0x160b: 0xb389, + 0x160c: 0xb389, 0x160d: 0xb3a1, 0x160e: 0xb3a1, 0x160f: 0xb3a1, 0x1610: 0xb3a1, 0x1611: 0xb3b9, + 0x1612: 0xb3b9, 0x1613: 0xb3b9, 0x1614: 0xb3b9, 0x1615: 0xb3d1, 0x1616: 0xb3d1, 0x1617: 0xb3d1, + 0x1618: 0xb3d1, 0x1619: 0xb3e9, 0x161a: 0xb3e9, 0x161b: 0xb3e9, 0x161c: 0xb3e9, 0x161d: 0xb401, + 0x161e: 0xb401, 0x161f: 0xb401, 0x1620: 0xb401, 0x1621: 0xb419, 0x1622: 0xb419, 0x1623: 0xb419, + 0x1624: 0xb419, 0x1625: 0xb431, 0x1626: 0xb431, 0x1627: 0xb431, 0x1628: 0xb431, 0x1629: 0xb449, + 0x162a: 0xb449, 0x162b: 0xb449, 0x162c: 0xb449, 0x162d: 0xb461, 0x162e: 0xb461, 0x162f: 0x7b01, + 0x1630: 0x7b01, 0x1631: 0xb479, 0x1632: 0xb479, 0x1633: 0xb479, 0x1634: 0xb479, 0x1635: 0xb491, + 0x1636: 0xb491, 0x1637: 0xb4b9, 0x1638: 0xb4b9, 0x1639: 0xb4e1, 0x163a: 0xb4e1, 0x163b: 0xb509, + 0x163c: 0xb509, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x0040, 0x1641: 0xaf4a, 0x1642: 0xb532, 0x1643: 0xafba, 0x1644: 0xb02a, 0x1645: 0xb03a, + 0x1646: 0xafca, 0x1647: 0xb542, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xafda, 0x164b: 0x1fb2, + 0x164c: 0xaf2a, 0x164d: 0xafe9, 0x164e: 0x29d1, 0x164f: 0xb552, 0x1650: 0x1f41, 0x1651: 0x00c9, + 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81, + 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaf3a, 0x165b: 0x03c2, 0x165c: 0xaffa, 0x165d: 0x1fc2, + 0x165e: 0xb00a, 0x165f: 0xaf5a, 0x1660: 0xb04a, 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: 0xaf9a, + 0x167c: 0xb01a, 0x167d: 0xafaa, 0x167e: 0xb562, 0x167f: 0xaf6a, + // 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: 0xaf7a, 0x169c: 0xb572, 0x169d: 0xaf8a, + 0x169e: 0xb582, 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: 0xb591, 0x1721: 0xb5a9, 0x1722: 0xb5c1, 0x1723: 0x8a0e, + 0x1724: 0xb5d9, 0x1725: 0xb5f1, 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: 0x0008, 0x1841: 0x0008, 0x1842: 0x0008, 0x1843: 0x0008, 0x1844: 0x0008, 0x1845: 0x0008, + 0x1846: 0x0008, 0x1847: 0x0040, 0x1848: 0x0040, 0x1849: 0x0008, 0x184a: 0x0040, 0x184b: 0x0040, + 0x184c: 0x0008, 0x184d: 0x0008, 0x184e: 0x0008, 0x184f: 0x0008, 0x1850: 0x0008, 0x1851: 0x0008, + 0x1852: 0x0008, 0x1853: 0x0008, 0x1854: 0x0040, 0x1855: 0x0008, 0x1856: 0x0008, 0x1857: 0x0040, + 0x1858: 0x0008, 0x1859: 0x0008, 0x185a: 0x0008, 0x185b: 0x0008, 0x185c: 0x0008, 0x185d: 0x0008, + 0x185e: 0x0008, 0x185f: 0x0008, 0x1860: 0x0008, 0x1861: 0x0008, 0x1862: 0x0008, 0x1863: 0x0008, + 0x1864: 0x0008, 0x1865: 0x0008, 0x1866: 0x0008, 0x1867: 0x0008, 0x1868: 0x0008, 0x1869: 0x0008, + 0x186a: 0x0008, 0x186b: 0x0008, 0x186c: 0x0008, 0x186d: 0x0008, 0x186e: 0x0008, 0x186f: 0x0008, + 0x1870: 0x3008, 0x1871: 0x3008, 0x1872: 0x3008, 0x1873: 0x3008, 0x1874: 0x3008, 0x1875: 0x3008, + 0x1876: 0x0040, 0x1877: 0x3008, 0x1878: 0x3008, 0x1879: 0x0040, 0x187a: 0x0040, 0x187b: 0x3308, + 0x187c: 0x3308, 0x187d: 0x3808, 0x187e: 0x3b08, 0x187f: 0x0008, + // Block 0x62, offset 0x1880 + 0x1880: 0x0039, 0x1881: 0x0ee9, 0x1882: 0x1159, 0x1883: 0x0ef9, 0x1884: 0x0f09, 0x1885: 0x1199, + 0x1886: 0x0f31, 0x1887: 0x0249, 0x1888: 0x0f41, 0x1889: 0x0259, 0x188a: 0x0f51, 0x188b: 0x0359, + 0x188c: 0x0f61, 0x188d: 0x0f71, 0x188e: 0x00d9, 0x188f: 0x0f99, 0x1890: 0x2039, 0x1891: 0x0269, + 0x1892: 0x01d9, 0x1893: 0x0fa9, 0x1894: 0x0fb9, 0x1895: 0x1089, 0x1896: 0x0279, 0x1897: 0x0369, + 0x1898: 0x0289, 0x1899: 0x13d1, 0x189a: 0x0039, 0x189b: 0x0ee9, 0x189c: 0x1159, 0x189d: 0x0ef9, + 0x189e: 0x0f09, 0x189f: 0x1199, 0x18a0: 0x0f31, 0x18a1: 0x0249, 0x18a2: 0x0f41, 0x18a3: 0x0259, + 0x18a4: 0x0f51, 0x18a5: 0x0359, 0x18a6: 0x0f61, 0x18a7: 0x0f71, 0x18a8: 0x00d9, 0x18a9: 0x0f99, + 0x18aa: 0x2039, 0x18ab: 0x0269, 0x18ac: 0x01d9, 0x18ad: 0x0fa9, 0x18ae: 0x0fb9, 0x18af: 0x1089, + 0x18b0: 0x0279, 0x18b1: 0x0369, 0x18b2: 0x0289, 0x18b3: 0x13d1, 0x18b4: 0x0039, 0x18b5: 0x0ee9, + 0x18b6: 0x1159, 0x18b7: 0x0ef9, 0x18b8: 0x0f09, 0x18b9: 0x1199, 0x18ba: 0x0f31, 0x18bb: 0x0249, + 0x18bc: 0x0f41, 0x18bd: 0x0259, 0x18be: 0x0f51, 0x18bf: 0x0359, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0f61, 0x18c1: 0x0f71, 0x18c2: 0x00d9, 0x18c3: 0x0f99, 0x18c4: 0x2039, 0x18c5: 0x0269, + 0x18c6: 0x01d9, 0x18c7: 0x0fa9, 0x18c8: 0x0fb9, 0x18c9: 0x1089, 0x18ca: 0x0279, 0x18cb: 0x0369, + 0x18cc: 0x0289, 0x18cd: 0x13d1, 0x18ce: 0x0039, 0x18cf: 0x0ee9, 0x18d0: 0x1159, 0x18d1: 0x0ef9, + 0x18d2: 0x0f09, 0x18d3: 0x1199, 0x18d4: 0x0f31, 0x18d5: 0x0040, 0x18d6: 0x0f41, 0x18d7: 0x0259, + 0x18d8: 0x0f51, 0x18d9: 0x0359, 0x18da: 0x0f61, 0x18db: 0x0f71, 0x18dc: 0x00d9, 0x18dd: 0x0f99, + 0x18de: 0x2039, 0x18df: 0x0269, 0x18e0: 0x01d9, 0x18e1: 0x0fa9, 0x18e2: 0x0fb9, 0x18e3: 0x1089, + 0x18e4: 0x0279, 0x18e5: 0x0369, 0x18e6: 0x0289, 0x18e7: 0x13d1, 0x18e8: 0x0039, 0x18e9: 0x0ee9, + 0x18ea: 0x1159, 0x18eb: 0x0ef9, 0x18ec: 0x0f09, 0x18ed: 0x1199, 0x18ee: 0x0f31, 0x18ef: 0x0249, + 0x18f0: 0x0f41, 0x18f1: 0x0259, 0x18f2: 0x0f51, 0x18f3: 0x0359, 0x18f4: 0x0f61, 0x18f5: 0x0f71, + 0x18f6: 0x00d9, 0x18f7: 0x0f99, 0x18f8: 0x2039, 0x18f9: 0x0269, 0x18fa: 0x01d9, 0x18fb: 0x0fa9, + 0x18fc: 0x0fb9, 0x18fd: 0x1089, 0x18fe: 0x0279, 0x18ff: 0x0369, + // Block 0x64, offset 0x1900 + 0x1900: 0x0289, 0x1901: 0x13d1, 0x1902: 0x0039, 0x1903: 0x0ee9, 0x1904: 0x1159, 0x1905: 0x0ef9, + 0x1906: 0x0f09, 0x1907: 0x1199, 0x1908: 0x0f31, 0x1909: 0x0249, 0x190a: 0x0f41, 0x190b: 0x0259, + 0x190c: 0x0f51, 0x190d: 0x0359, 0x190e: 0x0f61, 0x190f: 0x0f71, 0x1910: 0x00d9, 0x1911: 0x0f99, + 0x1912: 0x2039, 0x1913: 0x0269, 0x1914: 0x01d9, 0x1915: 0x0fa9, 0x1916: 0x0fb9, 0x1917: 0x1089, + 0x1918: 0x0279, 0x1919: 0x0369, 0x191a: 0x0289, 0x191b: 0x13d1, 0x191c: 0x0039, 0x191d: 0x0040, + 0x191e: 0x1159, 0x191f: 0x0ef9, 0x1920: 0x0040, 0x1921: 0x0040, 0x1922: 0x0f31, 0x1923: 0x0040, + 0x1924: 0x0040, 0x1925: 0x0259, 0x1926: 0x0f51, 0x1927: 0x0040, 0x1928: 0x0040, 0x1929: 0x0f71, + 0x192a: 0x00d9, 0x192b: 0x0f99, 0x192c: 0x2039, 0x192d: 0x0040, 0x192e: 0x01d9, 0x192f: 0x0fa9, + 0x1930: 0x0fb9, 0x1931: 0x1089, 0x1932: 0x0279, 0x1933: 0x0369, 0x1934: 0x0289, 0x1935: 0x13d1, + 0x1936: 0x0039, 0x1937: 0x0ee9, 0x1938: 0x1159, 0x1939: 0x0ef9, 0x193a: 0x0040, 0x193b: 0x1199, + 0x193c: 0x0040, 0x193d: 0x0249, 0x193e: 0x0f41, 0x193f: 0x0259, + // Block 0x65, offset 0x1940 + 0x1940: 0x0f51, 0x1941: 0x0359, 0x1942: 0x0f61, 0x1943: 0x0f71, 0x1944: 0x0040, 0x1945: 0x0f99, + 0x1946: 0x2039, 0x1947: 0x0269, 0x1948: 0x01d9, 0x1949: 0x0fa9, 0x194a: 0x0fb9, 0x194b: 0x1089, + 0x194c: 0x0279, 0x194d: 0x0369, 0x194e: 0x0289, 0x194f: 0x13d1, 0x1950: 0x0039, 0x1951: 0x0ee9, + 0x1952: 0x1159, 0x1953: 0x0ef9, 0x1954: 0x0f09, 0x1955: 0x1199, 0x1956: 0x0f31, 0x1957: 0x0249, + 0x1958: 0x0f41, 0x1959: 0x0259, 0x195a: 0x0f51, 0x195b: 0x0359, 0x195c: 0x0f61, 0x195d: 0x0f71, + 0x195e: 0x00d9, 0x195f: 0x0f99, 0x1960: 0x2039, 0x1961: 0x0269, 0x1962: 0x01d9, 0x1963: 0x0fa9, + 0x1964: 0x0fb9, 0x1965: 0x1089, 0x1966: 0x0279, 0x1967: 0x0369, 0x1968: 0x0289, 0x1969: 0x13d1, + 0x196a: 0x0039, 0x196b: 0x0ee9, 0x196c: 0x1159, 0x196d: 0x0ef9, 0x196e: 0x0f09, 0x196f: 0x1199, + 0x1970: 0x0f31, 0x1971: 0x0249, 0x1972: 0x0f41, 0x1973: 0x0259, 0x1974: 0x0f51, 0x1975: 0x0359, + 0x1976: 0x0f61, 0x1977: 0x0f71, 0x1978: 0x00d9, 0x1979: 0x0f99, 0x197a: 0x2039, 0x197b: 0x0269, + 0x197c: 0x01d9, 0x197d: 0x0fa9, 0x197e: 0x0fb9, 0x197f: 0x1089, + // Block 0x66, offset 0x1980 + 0x1980: 0x0279, 0x1981: 0x0369, 0x1982: 0x0289, 0x1983: 0x13d1, 0x1984: 0x0039, 0x1985: 0x0ee9, + 0x1986: 0x0040, 0x1987: 0x0ef9, 0x1988: 0x0f09, 0x1989: 0x1199, 0x198a: 0x0f31, 0x198b: 0x0040, + 0x198c: 0x0040, 0x198d: 0x0259, 0x198e: 0x0f51, 0x198f: 0x0359, 0x1990: 0x0f61, 0x1991: 0x0f71, + 0x1992: 0x00d9, 0x1993: 0x0f99, 0x1994: 0x2039, 0x1995: 0x0040, 0x1996: 0x01d9, 0x1997: 0x0fa9, + 0x1998: 0x0fb9, 0x1999: 0x1089, 0x199a: 0x0279, 0x199b: 0x0369, 0x199c: 0x0289, 0x199d: 0x0040, + 0x199e: 0x0039, 0x199f: 0x0ee9, 0x19a0: 0x1159, 0x19a1: 0x0ef9, 0x19a2: 0x0f09, 0x19a3: 0x1199, + 0x19a4: 0x0f31, 0x19a5: 0x0249, 0x19a6: 0x0f41, 0x19a7: 0x0259, 0x19a8: 0x0f51, 0x19a9: 0x0359, + 0x19aa: 0x0f61, 0x19ab: 0x0f71, 0x19ac: 0x00d9, 0x19ad: 0x0f99, 0x19ae: 0x2039, 0x19af: 0x0269, + 0x19b0: 0x01d9, 0x19b1: 0x0fa9, 0x19b2: 0x0fb9, 0x19b3: 0x1089, 0x19b4: 0x0279, 0x19b5: 0x0369, + 0x19b6: 0x0289, 0x19b7: 0x13d1, 0x19b8: 0x0039, 0x19b9: 0x0ee9, 0x19ba: 0x0040, 0x19bb: 0x0ef9, + 0x19bc: 0x0f09, 0x19bd: 0x1199, 0x19be: 0x0f31, 0x19bf: 0x0040, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x0f41, 0x19c1: 0x0259, 0x19c2: 0x0f51, 0x19c3: 0x0359, 0x19c4: 0x0f61, 0x19c5: 0x0040, + 0x19c6: 0x00d9, 0x19c7: 0x0040, 0x19c8: 0x0040, 0x19c9: 0x0040, 0x19ca: 0x01d9, 0x19cb: 0x0fa9, + 0x19cc: 0x0fb9, 0x19cd: 0x1089, 0x19ce: 0x0279, 0x19cf: 0x0369, 0x19d0: 0x0289, 0x19d1: 0x0040, + 0x19d2: 0x0039, 0x19d3: 0x0ee9, 0x19d4: 0x1159, 0x19d5: 0x0ef9, 0x19d6: 0x0f09, 0x19d7: 0x1199, + 0x19d8: 0x0f31, 0x19d9: 0x0249, 0x19da: 0x0f41, 0x19db: 0x0259, 0x19dc: 0x0f51, 0x19dd: 0x0359, + 0x19de: 0x0f61, 0x19df: 0x0f71, 0x19e0: 0x00d9, 0x19e1: 0x0f99, 0x19e2: 0x2039, 0x19e3: 0x0269, + 0x19e4: 0x01d9, 0x19e5: 0x0fa9, 0x19e6: 0x0fb9, 0x19e7: 0x1089, 0x19e8: 0x0279, 0x19e9: 0x0369, + 0x19ea: 0x0289, 0x19eb: 0x13d1, 0x19ec: 0x0039, 0x19ed: 0x0ee9, 0x19ee: 0x1159, 0x19ef: 0x0ef9, + 0x19f0: 0x0f09, 0x19f1: 0x1199, 0x19f2: 0x0f31, 0x19f3: 0x0249, 0x19f4: 0x0f41, 0x19f5: 0x0259, + 0x19f6: 0x0f51, 0x19f7: 0x0359, 0x19f8: 0x0f61, 0x19f9: 0x0f71, 0x19fa: 0x00d9, 0x19fb: 0x0f99, + 0x19fc: 0x2039, 0x19fd: 0x0269, 0x19fe: 0x01d9, 0x19ff: 0x0fa9, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x0fb9, 0x1a01: 0x1089, 0x1a02: 0x0279, 0x1a03: 0x0369, 0x1a04: 0x0289, 0x1a05: 0x13d1, + 0x1a06: 0x0039, 0x1a07: 0x0ee9, 0x1a08: 0x1159, 0x1a09: 0x0ef9, 0x1a0a: 0x0f09, 0x1a0b: 0x1199, + 0x1a0c: 0x0f31, 0x1a0d: 0x0249, 0x1a0e: 0x0f41, 0x1a0f: 0x0259, 0x1a10: 0x0f51, 0x1a11: 0x0359, + 0x1a12: 0x0f61, 0x1a13: 0x0f71, 0x1a14: 0x00d9, 0x1a15: 0x0f99, 0x1a16: 0x2039, 0x1a17: 0x0269, + 0x1a18: 0x01d9, 0x1a19: 0x0fa9, 0x1a1a: 0x0fb9, 0x1a1b: 0x1089, 0x1a1c: 0x0279, 0x1a1d: 0x0369, + 0x1a1e: 0x0289, 0x1a1f: 0x13d1, 0x1a20: 0x0039, 0x1a21: 0x0ee9, 0x1a22: 0x1159, 0x1a23: 0x0ef9, + 0x1a24: 0x0f09, 0x1a25: 0x1199, 0x1a26: 0x0f31, 0x1a27: 0x0249, 0x1a28: 0x0f41, 0x1a29: 0x0259, + 0x1a2a: 0x0f51, 0x1a2b: 0x0359, 0x1a2c: 0x0f61, 0x1a2d: 0x0f71, 0x1a2e: 0x00d9, 0x1a2f: 0x0f99, + 0x1a30: 0x2039, 0x1a31: 0x0269, 0x1a32: 0x01d9, 0x1a33: 0x0fa9, 0x1a34: 0x0fb9, 0x1a35: 0x1089, + 0x1a36: 0x0279, 0x1a37: 0x0369, 0x1a38: 0x0289, 0x1a39: 0x13d1, 0x1a3a: 0x0039, 0x1a3b: 0x0ee9, + 0x1a3c: 0x1159, 0x1a3d: 0x0ef9, 0x1a3e: 0x0f09, 0x1a3f: 0x1199, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x0f31, 0x1a41: 0x0249, 0x1a42: 0x0f41, 0x1a43: 0x0259, 0x1a44: 0x0f51, 0x1a45: 0x0359, + 0x1a46: 0x0f61, 0x1a47: 0x0f71, 0x1a48: 0x00d9, 0x1a49: 0x0f99, 0x1a4a: 0x2039, 0x1a4b: 0x0269, + 0x1a4c: 0x01d9, 0x1a4d: 0x0fa9, 0x1a4e: 0x0fb9, 0x1a4f: 0x1089, 0x1a50: 0x0279, 0x1a51: 0x0369, + 0x1a52: 0x0289, 0x1a53: 0x13d1, 0x1a54: 0x0039, 0x1a55: 0x0ee9, 0x1a56: 0x1159, 0x1a57: 0x0ef9, + 0x1a58: 0x0f09, 0x1a59: 0x1199, 0x1a5a: 0x0f31, 0x1a5b: 0x0249, 0x1a5c: 0x0f41, 0x1a5d: 0x0259, + 0x1a5e: 0x0f51, 0x1a5f: 0x0359, 0x1a60: 0x0f61, 0x1a61: 0x0f71, 0x1a62: 0x00d9, 0x1a63: 0x0f99, + 0x1a64: 0x2039, 0x1a65: 0x0269, 0x1a66: 0x01d9, 0x1a67: 0x0fa9, 0x1a68: 0x0fb9, 0x1a69: 0x1089, + 0x1a6a: 0x0279, 0x1a6b: 0x0369, 0x1a6c: 0x0289, 0x1a6d: 0x13d1, 0x1a6e: 0x0039, 0x1a6f: 0x0ee9, + 0x1a70: 0x1159, 0x1a71: 0x0ef9, 0x1a72: 0x0f09, 0x1a73: 0x1199, 0x1a74: 0x0f31, 0x1a75: 0x0249, + 0x1a76: 0x0f41, 0x1a77: 0x0259, 0x1a78: 0x0f51, 0x1a79: 0x0359, 0x1a7a: 0x0f61, 0x1a7b: 0x0f71, + 0x1a7c: 0x00d9, 0x1a7d: 0x0f99, 0x1a7e: 0x2039, 0x1a7f: 0x0269, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x01d9, 0x1a81: 0x0fa9, 0x1a82: 0x0fb9, 0x1a83: 0x1089, 0x1a84: 0x0279, 0x1a85: 0x0369, + 0x1a86: 0x0289, 0x1a87: 0x13d1, 0x1a88: 0x0039, 0x1a89: 0x0ee9, 0x1a8a: 0x1159, 0x1a8b: 0x0ef9, + 0x1a8c: 0x0f09, 0x1a8d: 0x1199, 0x1a8e: 0x0f31, 0x1a8f: 0x0249, 0x1a90: 0x0f41, 0x1a91: 0x0259, + 0x1a92: 0x0f51, 0x1a93: 0x0359, 0x1a94: 0x0f61, 0x1a95: 0x0f71, 0x1a96: 0x00d9, 0x1a97: 0x0f99, + 0x1a98: 0x2039, 0x1a99: 0x0269, 0x1a9a: 0x01d9, 0x1a9b: 0x0fa9, 0x1a9c: 0x0fb9, 0x1a9d: 0x1089, + 0x1a9e: 0x0279, 0x1a9f: 0x0369, 0x1aa0: 0x0289, 0x1aa1: 0x13d1, 0x1aa2: 0x0039, 0x1aa3: 0x0ee9, + 0x1aa4: 0x1159, 0x1aa5: 0x0ef9, 0x1aa6: 0x0f09, 0x1aa7: 0x1199, 0x1aa8: 0x0f31, 0x1aa9: 0x0249, + 0x1aaa: 0x0f41, 0x1aab: 0x0259, 0x1aac: 0x0f51, 0x1aad: 0x0359, 0x1aae: 0x0f61, 0x1aaf: 0x0f71, + 0x1ab0: 0x00d9, 0x1ab1: 0x0f99, 0x1ab2: 0x2039, 0x1ab3: 0x0269, 0x1ab4: 0x01d9, 0x1ab5: 0x0fa9, + 0x1ab6: 0x0fb9, 0x1ab7: 0x1089, 0x1ab8: 0x0279, 0x1ab9: 0x0369, 0x1aba: 0x0289, 0x1abb: 0x13d1, + 0x1abc: 0x0039, 0x1abd: 0x0ee9, 0x1abe: 0x1159, 0x1abf: 0x0ef9, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x0f09, 0x1ac1: 0x1199, 0x1ac2: 0x0f31, 0x1ac3: 0x0249, 0x1ac4: 0x0f41, 0x1ac5: 0x0259, + 0x1ac6: 0x0f51, 0x1ac7: 0x0359, 0x1ac8: 0x0f61, 0x1ac9: 0x0f71, 0x1aca: 0x00d9, 0x1acb: 0x0f99, + 0x1acc: 0x2039, 0x1acd: 0x0269, 0x1ace: 0x01d9, 0x1acf: 0x0fa9, 0x1ad0: 0x0fb9, 0x1ad1: 0x1089, + 0x1ad2: 0x0279, 0x1ad3: 0x0369, 0x1ad4: 0x0289, 0x1ad5: 0x13d1, 0x1ad6: 0x0039, 0x1ad7: 0x0ee9, + 0x1ad8: 0x1159, 0x1ad9: 0x0ef9, 0x1ada: 0x0f09, 0x1adb: 0x1199, 0x1adc: 0x0f31, 0x1add: 0x0249, + 0x1ade: 0x0f41, 0x1adf: 0x0259, 0x1ae0: 0x0f51, 0x1ae1: 0x0359, 0x1ae2: 0x0f61, 0x1ae3: 0x0f71, + 0x1ae4: 0x00d9, 0x1ae5: 0x0f99, 0x1ae6: 0x2039, 0x1ae7: 0x0269, 0x1ae8: 0x01d9, 0x1ae9: 0x0fa9, + 0x1aea: 0x0fb9, 0x1aeb: 0x1089, 0x1aec: 0x0279, 0x1aed: 0x0369, 0x1aee: 0x0289, 0x1aef: 0x13d1, + 0x1af0: 0x0039, 0x1af1: 0x0ee9, 0x1af2: 0x1159, 0x1af3: 0x0ef9, 0x1af4: 0x0f09, 0x1af5: 0x1199, + 0x1af6: 0x0f31, 0x1af7: 0x0249, 0x1af8: 0x0f41, 0x1af9: 0x0259, 0x1afa: 0x0f51, 0x1afb: 0x0359, + 0x1afc: 0x0f61, 0x1afd: 0x0f71, 0x1afe: 0x00d9, 0x1aff: 0x0f99, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x2039, 0x1b01: 0x0269, 0x1b02: 0x01d9, 0x1b03: 0x0fa9, 0x1b04: 0x0fb9, 0x1b05: 0x1089, + 0x1b06: 0x0279, 0x1b07: 0x0369, 0x1b08: 0x0289, 0x1b09: 0x13d1, 0x1b0a: 0x0039, 0x1b0b: 0x0ee9, + 0x1b0c: 0x1159, 0x1b0d: 0x0ef9, 0x1b0e: 0x0f09, 0x1b0f: 0x1199, 0x1b10: 0x0f31, 0x1b11: 0x0249, + 0x1b12: 0x0f41, 0x1b13: 0x0259, 0x1b14: 0x0f51, 0x1b15: 0x0359, 0x1b16: 0x0f61, 0x1b17: 0x0f71, + 0x1b18: 0x00d9, 0x1b19: 0x0f99, 0x1b1a: 0x2039, 0x1b1b: 0x0269, 0x1b1c: 0x01d9, 0x1b1d: 0x0fa9, + 0x1b1e: 0x0fb9, 0x1b1f: 0x1089, 0x1b20: 0x0279, 0x1b21: 0x0369, 0x1b22: 0x0289, 0x1b23: 0x13d1, + 0x1b24: 0xbad1, 0x1b25: 0xbae9, 0x1b26: 0x0040, 0x1b27: 0x0040, 0x1b28: 0xbb01, 0x1b29: 0x1099, + 0x1b2a: 0x10b1, 0x1b2b: 0x10c9, 0x1b2c: 0xbb19, 0x1b2d: 0xbb31, 0x1b2e: 0xbb49, 0x1b2f: 0x1429, + 0x1b30: 0x1a31, 0x1b31: 0xbb61, 0x1b32: 0xbb79, 0x1b33: 0xbb91, 0x1b34: 0xbba9, 0x1b35: 0xbbc1, + 0x1b36: 0xbbd9, 0x1b37: 0x2109, 0x1b38: 0x1111, 0x1b39: 0x1429, 0x1b3a: 0xbbf1, 0x1b3b: 0xbc09, + 0x1b3c: 0xbc21, 0x1b3d: 0x10e1, 0x1b3e: 0x10f9, 0x1b3f: 0xbc39, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x2079, 0x1b41: 0xbc51, 0x1b42: 0xbb01, 0x1b43: 0x1099, 0x1b44: 0x10b1, 0x1b45: 0x10c9, + 0x1b46: 0xbb19, 0x1b47: 0xbb31, 0x1b48: 0xbb49, 0x1b49: 0x1429, 0x1b4a: 0x1a31, 0x1b4b: 0xbb61, + 0x1b4c: 0xbb79, 0x1b4d: 0xbb91, 0x1b4e: 0xbba9, 0x1b4f: 0xbbc1, 0x1b50: 0xbbd9, 0x1b51: 0x2109, + 0x1b52: 0x1111, 0x1b53: 0xbbf1, 0x1b54: 0xbbf1, 0x1b55: 0xbc09, 0x1b56: 0xbc21, 0x1b57: 0x10e1, + 0x1b58: 0x10f9, 0x1b59: 0xbc39, 0x1b5a: 0x2079, 0x1b5b: 0xbc71, 0x1b5c: 0xbb19, 0x1b5d: 0x1429, + 0x1b5e: 0xbb61, 0x1b5f: 0x10e1, 0x1b60: 0x1111, 0x1b61: 0x2109, 0x1b62: 0xbb01, 0x1b63: 0x1099, + 0x1b64: 0x10b1, 0x1b65: 0x10c9, 0x1b66: 0xbb19, 0x1b67: 0xbb31, 0x1b68: 0xbb49, 0x1b69: 0x1429, + 0x1b6a: 0x1a31, 0x1b6b: 0xbb61, 0x1b6c: 0xbb79, 0x1b6d: 0xbb91, 0x1b6e: 0xbba9, 0x1b6f: 0xbbc1, + 0x1b70: 0xbbd9, 0x1b71: 0x2109, 0x1b72: 0x1111, 0x1b73: 0x1429, 0x1b74: 0xbbf1, 0x1b75: 0xbc09, + 0x1b76: 0xbc21, 0x1b77: 0x10e1, 0x1b78: 0x10f9, 0x1b79: 0xbc39, 0x1b7a: 0x2079, 0x1b7b: 0xbc51, + 0x1b7c: 0xbb01, 0x1b7d: 0x1099, 0x1b7e: 0x10b1, 0x1b7f: 0x10c9, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0xbb19, 0x1b81: 0xbb31, 0x1b82: 0xbb49, 0x1b83: 0x1429, 0x1b84: 0x1a31, 0x1b85: 0xbb61, + 0x1b86: 0xbb79, 0x1b87: 0xbb91, 0x1b88: 0xbba9, 0x1b89: 0xbbc1, 0x1b8a: 0xbbd9, 0x1b8b: 0x2109, + 0x1b8c: 0x1111, 0x1b8d: 0xbbf1, 0x1b8e: 0xbbf1, 0x1b8f: 0xbc09, 0x1b90: 0xbc21, 0x1b91: 0x10e1, + 0x1b92: 0x10f9, 0x1b93: 0xbc39, 0x1b94: 0x2079, 0x1b95: 0xbc71, 0x1b96: 0xbb19, 0x1b97: 0x1429, + 0x1b98: 0xbb61, 0x1b99: 0x10e1, 0x1b9a: 0x1111, 0x1b9b: 0x2109, 0x1b9c: 0xbb01, 0x1b9d: 0x1099, + 0x1b9e: 0x10b1, 0x1b9f: 0x10c9, 0x1ba0: 0xbb19, 0x1ba1: 0xbb31, 0x1ba2: 0xbb49, 0x1ba3: 0x1429, + 0x1ba4: 0x1a31, 0x1ba5: 0xbb61, 0x1ba6: 0xbb79, 0x1ba7: 0xbb91, 0x1ba8: 0xbba9, 0x1ba9: 0xbbc1, + 0x1baa: 0xbbd9, 0x1bab: 0x2109, 0x1bac: 0x1111, 0x1bad: 0x1429, 0x1bae: 0xbbf1, 0x1baf: 0xbc09, + 0x1bb0: 0xbc21, 0x1bb1: 0x10e1, 0x1bb2: 0x10f9, 0x1bb3: 0xbc39, 0x1bb4: 0x2079, 0x1bb5: 0xbc51, + 0x1bb6: 0xbb01, 0x1bb7: 0x1099, 0x1bb8: 0x10b1, 0x1bb9: 0x10c9, 0x1bba: 0xbb19, 0x1bbb: 0xbb31, + 0x1bbc: 0xbb49, 0x1bbd: 0x1429, 0x1bbe: 0x1a31, 0x1bbf: 0xbb61, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0xbb79, 0x1bc1: 0xbb91, 0x1bc2: 0xbba9, 0x1bc3: 0xbbc1, 0x1bc4: 0xbbd9, 0x1bc5: 0x2109, + 0x1bc6: 0x1111, 0x1bc7: 0xbbf1, 0x1bc8: 0xbbf1, 0x1bc9: 0xbc09, 0x1bca: 0xbc21, 0x1bcb: 0x10e1, + 0x1bcc: 0x10f9, 0x1bcd: 0xbc39, 0x1bce: 0x2079, 0x1bcf: 0xbc71, 0x1bd0: 0xbb19, 0x1bd1: 0x1429, + 0x1bd2: 0xbb61, 0x1bd3: 0x10e1, 0x1bd4: 0x1111, 0x1bd5: 0x2109, 0x1bd6: 0xbb01, 0x1bd7: 0x1099, + 0x1bd8: 0x10b1, 0x1bd9: 0x10c9, 0x1bda: 0xbb19, 0x1bdb: 0xbb31, 0x1bdc: 0xbb49, 0x1bdd: 0x1429, + 0x1bde: 0x1a31, 0x1bdf: 0xbb61, 0x1be0: 0xbb79, 0x1be1: 0xbb91, 0x1be2: 0xbba9, 0x1be3: 0xbbc1, + 0x1be4: 0xbbd9, 0x1be5: 0x2109, 0x1be6: 0x1111, 0x1be7: 0x1429, 0x1be8: 0xbbf1, 0x1be9: 0xbc09, + 0x1bea: 0xbc21, 0x1beb: 0x10e1, 0x1bec: 0x10f9, 0x1bed: 0xbc39, 0x1bee: 0x2079, 0x1bef: 0xbc51, + 0x1bf0: 0xbb01, 0x1bf1: 0x1099, 0x1bf2: 0x10b1, 0x1bf3: 0x10c9, 0x1bf4: 0xbb19, 0x1bf5: 0xbb31, + 0x1bf6: 0xbb49, 0x1bf7: 0x1429, 0x1bf8: 0x1a31, 0x1bf9: 0xbb61, 0x1bfa: 0xbb79, 0x1bfb: 0xbb91, + 0x1bfc: 0xbba9, 0x1bfd: 0xbbc1, 0x1bfe: 0xbbd9, 0x1bff: 0x2109, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x1111, 0x1c01: 0xbbf1, 0x1c02: 0xbbf1, 0x1c03: 0xbc09, 0x1c04: 0xbc21, 0x1c05: 0x10e1, + 0x1c06: 0x10f9, 0x1c07: 0xbc39, 0x1c08: 0x2079, 0x1c09: 0xbc71, 0x1c0a: 0xbb19, 0x1c0b: 0x1429, + 0x1c0c: 0xbb61, 0x1c0d: 0x10e1, 0x1c0e: 0x1111, 0x1c0f: 0x2109, 0x1c10: 0xbb01, 0x1c11: 0x1099, + 0x1c12: 0x10b1, 0x1c13: 0x10c9, 0x1c14: 0xbb19, 0x1c15: 0xbb31, 0x1c16: 0xbb49, 0x1c17: 0x1429, + 0x1c18: 0x1a31, 0x1c19: 0xbb61, 0x1c1a: 0xbb79, 0x1c1b: 0xbb91, 0x1c1c: 0xbba9, 0x1c1d: 0xbbc1, + 0x1c1e: 0xbbd9, 0x1c1f: 0x2109, 0x1c20: 0x1111, 0x1c21: 0x1429, 0x1c22: 0xbbf1, 0x1c23: 0xbc09, + 0x1c24: 0xbc21, 0x1c25: 0x10e1, 0x1c26: 0x10f9, 0x1c27: 0xbc39, 0x1c28: 0x2079, 0x1c29: 0xbc51, + 0x1c2a: 0xbb01, 0x1c2b: 0x1099, 0x1c2c: 0x10b1, 0x1c2d: 0x10c9, 0x1c2e: 0xbb19, 0x1c2f: 0xbb31, + 0x1c30: 0xbb49, 0x1c31: 0x1429, 0x1c32: 0x1a31, 0x1c33: 0xbb61, 0x1c34: 0xbb79, 0x1c35: 0xbb91, + 0x1c36: 0xbba9, 0x1c37: 0xbbc1, 0x1c38: 0xbbd9, 0x1c39: 0x2109, 0x1c3a: 0x1111, 0x1c3b: 0xbbf1, + 0x1c3c: 0xbbf1, 0x1c3d: 0xbc09, 0x1c3e: 0xbc21, 0x1c3f: 0x10e1, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x10f9, 0x1c41: 0xbc39, 0x1c42: 0x2079, 0x1c43: 0xbc71, 0x1c44: 0xbb19, 0x1c45: 0x1429, + 0x1c46: 0xbb61, 0x1c47: 0x10e1, 0x1c48: 0x1111, 0x1c49: 0x2109, 0x1c4a: 0xbc91, 0x1c4b: 0xbc91, + 0x1c4c: 0x0040, 0x1c4d: 0x0040, 0x1c4e: 0x1f41, 0x1c4f: 0x00c9, 0x1c50: 0x0069, 0x1c51: 0x0079, + 0x1c52: 0x1f51, 0x1c53: 0x1f61, 0x1c54: 0x1f71, 0x1c55: 0x1f81, 0x1c56: 0x1f91, 0x1c57: 0x1fa1, + 0x1c58: 0x1f41, 0x1c59: 0x00c9, 0x1c5a: 0x0069, 0x1c5b: 0x0079, 0x1c5c: 0x1f51, 0x1c5d: 0x1f61, + 0x1c5e: 0x1f71, 0x1c5f: 0x1f81, 0x1c60: 0x1f91, 0x1c61: 0x1fa1, 0x1c62: 0x1f41, 0x1c63: 0x00c9, + 0x1c64: 0x0069, 0x1c65: 0x0079, 0x1c66: 0x1f51, 0x1c67: 0x1f61, 0x1c68: 0x1f71, 0x1c69: 0x1f81, + 0x1c6a: 0x1f91, 0x1c6b: 0x1fa1, 0x1c6c: 0x1f41, 0x1c6d: 0x00c9, 0x1c6e: 0x0069, 0x1c6f: 0x0079, + 0x1c70: 0x1f51, 0x1c71: 0x1f61, 0x1c72: 0x1f71, 0x1c73: 0x1f81, 0x1c74: 0x1f91, 0x1c75: 0x1fa1, + 0x1c76: 0x1f41, 0x1c77: 0x00c9, 0x1c78: 0x0069, 0x1c79: 0x0079, 0x1c7a: 0x1f51, 0x1c7b: 0x1f61, + 0x1c7c: 0x1f71, 0x1c7d: 0x1f81, 0x1c7e: 0x1f91, 0x1c7f: 0x1fa1, + // Block 0x72, offset 0x1c80 + 0x1c80: 0xe115, 0x1c81: 0xe115, 0x1c82: 0xe135, 0x1c83: 0xe135, 0x1c84: 0xe115, 0x1c85: 0xe115, + 0x1c86: 0xe175, 0x1c87: 0xe175, 0x1c88: 0xe115, 0x1c89: 0xe115, 0x1c8a: 0xe135, 0x1c8b: 0xe135, + 0x1c8c: 0xe115, 0x1c8d: 0xe115, 0x1c8e: 0xe1f5, 0x1c8f: 0xe1f5, 0x1c90: 0xe115, 0x1c91: 0xe115, + 0x1c92: 0xe135, 0x1c93: 0xe135, 0x1c94: 0xe115, 0x1c95: 0xe115, 0x1c96: 0xe175, 0x1c97: 0xe175, + 0x1c98: 0xe115, 0x1c99: 0xe115, 0x1c9a: 0xe135, 0x1c9b: 0xe135, 0x1c9c: 0xe115, 0x1c9d: 0xe115, + 0x1c9e: 0x8b3d, 0x1c9f: 0x8b3d, 0x1ca0: 0x04b5, 0x1ca1: 0x04b5, 0x1ca2: 0x0a08, 0x1ca3: 0x0a08, + 0x1ca4: 0x0a08, 0x1ca5: 0x0a08, 0x1ca6: 0x0a08, 0x1ca7: 0x0a08, 0x1ca8: 0x0a08, 0x1ca9: 0x0a08, + 0x1caa: 0x0a08, 0x1cab: 0x0a08, 0x1cac: 0x0a08, 0x1cad: 0x0a08, 0x1cae: 0x0a08, 0x1caf: 0x0a08, + 0x1cb0: 0x0a08, 0x1cb1: 0x0a08, 0x1cb2: 0x0a08, 0x1cb3: 0x0a08, 0x1cb4: 0x0a08, 0x1cb5: 0x0a08, + 0x1cb6: 0x0a08, 0x1cb7: 0x0a08, 0x1cb8: 0x0a08, 0x1cb9: 0x0a08, 0x1cba: 0x0a08, 0x1cbb: 0x0a08, + 0x1cbc: 0x0a08, 0x1cbd: 0x0a08, 0x1cbe: 0x0a08, 0x1cbf: 0x0a08, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0xb1d9, 0x1cc1: 0xb1f1, 0x1cc2: 0xb251, 0x1cc3: 0xb299, 0x1cc4: 0x0040, 0x1cc5: 0xb461, + 0x1cc6: 0xb2e1, 0x1cc7: 0xb269, 0x1cc8: 0xb359, 0x1cc9: 0xb479, 0x1cca: 0xb3e9, 0x1ccb: 0xb401, + 0x1ccc: 0xb419, 0x1ccd: 0xb431, 0x1cce: 0xb2f9, 0x1ccf: 0xb389, 0x1cd0: 0xb3b9, 0x1cd1: 0xb329, + 0x1cd2: 0xb3d1, 0x1cd3: 0xb2c9, 0x1cd4: 0xb311, 0x1cd5: 0xb221, 0x1cd6: 0xb239, 0x1cd7: 0xb281, + 0x1cd8: 0xb2b1, 0x1cd9: 0xb341, 0x1cda: 0xb371, 0x1cdb: 0xb3a1, 0x1cdc: 0xbca9, 0x1cdd: 0x7999, + 0x1cde: 0xbcc1, 0x1cdf: 0xbcd9, 0x1ce0: 0x0040, 0x1ce1: 0xb1f1, 0x1ce2: 0xb251, 0x1ce3: 0x0040, + 0x1ce4: 0xb449, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb269, 0x1ce8: 0x0040, 0x1ce9: 0xb479, + 0x1cea: 0xb3e9, 0x1ceb: 0xb401, 0x1cec: 0xb419, 0x1ced: 0xb431, 0x1cee: 0xb2f9, 0x1cef: 0xb389, + 0x1cf0: 0xb3b9, 0x1cf1: 0xb329, 0x1cf2: 0xb3d1, 0x1cf3: 0x0040, 0x1cf4: 0xb311, 0x1cf5: 0xb221, + 0x1cf6: 0xb239, 0x1cf7: 0xb281, 0x1cf8: 0x0040, 0x1cf9: 0xb341, 0x1cfa: 0x0040, 0x1cfb: 0xb3a1, + 0x1cfc: 0x0040, 0x1cfd: 0x0040, 0x1cfe: 0x0040, 0x1cff: 0x0040, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x0040, 0x1d01: 0x0040, 0x1d02: 0xb251, 0x1d03: 0x0040, 0x1d04: 0x0040, 0x1d05: 0x0040, + 0x1d06: 0x0040, 0x1d07: 0xb269, 0x1d08: 0x0040, 0x1d09: 0xb479, 0x1d0a: 0x0040, 0x1d0b: 0xb401, + 0x1d0c: 0x0040, 0x1d0d: 0xb431, 0x1d0e: 0xb2f9, 0x1d0f: 0xb389, 0x1d10: 0x0040, 0x1d11: 0xb329, + 0x1d12: 0xb3d1, 0x1d13: 0x0040, 0x1d14: 0xb311, 0x1d15: 0x0040, 0x1d16: 0x0040, 0x1d17: 0xb281, + 0x1d18: 0x0040, 0x1d19: 0xb341, 0x1d1a: 0x0040, 0x1d1b: 0xb3a1, 0x1d1c: 0x0040, 0x1d1d: 0x7999, + 0x1d1e: 0x0040, 0x1d1f: 0xbcd9, 0x1d20: 0x0040, 0x1d21: 0xb1f1, 0x1d22: 0xb251, 0x1d23: 0x0040, + 0x1d24: 0xb449, 0x1d25: 0x0040, 0x1d26: 0x0040, 0x1d27: 0xb269, 0x1d28: 0xb359, 0x1d29: 0xb479, + 0x1d2a: 0xb3e9, 0x1d2b: 0x0040, 0x1d2c: 0xb419, 0x1d2d: 0xb431, 0x1d2e: 0xb2f9, 0x1d2f: 0xb389, + 0x1d30: 0xb3b9, 0x1d31: 0xb329, 0x1d32: 0xb3d1, 0x1d33: 0x0040, 0x1d34: 0xb311, 0x1d35: 0xb221, + 0x1d36: 0xb239, 0x1d37: 0xb281, 0x1d38: 0x0040, 0x1d39: 0xb341, 0x1d3a: 0xb371, 0x1d3b: 0xb3a1, + 0x1d3c: 0xbca9, 0x1d3d: 0x0040, 0x1d3e: 0xbcc1, 0x1d3f: 0x0040, + // Block 0x75, offset 0x1d40 + 0x1d40: 0xb1d9, 0x1d41: 0xb1f1, 0x1d42: 0xb251, 0x1d43: 0xb299, 0x1d44: 0xb449, 0x1d45: 0xb461, + 0x1d46: 0xb2e1, 0x1d47: 0xb269, 0x1d48: 0xb359, 0x1d49: 0xb479, 0x1d4a: 0x0040, 0x1d4b: 0xb401, + 0x1d4c: 0xb419, 0x1d4d: 0xb431, 0x1d4e: 0xb2f9, 0x1d4f: 0xb389, 0x1d50: 0xb3b9, 0x1d51: 0xb329, + 0x1d52: 0xb3d1, 0x1d53: 0xb2c9, 0x1d54: 0xb311, 0x1d55: 0xb221, 0x1d56: 0xb239, 0x1d57: 0xb281, + 0x1d58: 0xb2b1, 0x1d59: 0xb341, 0x1d5a: 0xb371, 0x1d5b: 0xb3a1, 0x1d5c: 0x0040, 0x1d5d: 0x0040, + 0x1d5e: 0x0040, 0x1d5f: 0x0040, 0x1d60: 0x0040, 0x1d61: 0xb1f1, 0x1d62: 0xb251, 0x1d63: 0xb299, + 0x1d64: 0x0040, 0x1d65: 0xb461, 0x1d66: 0xb2e1, 0x1d67: 0xb269, 0x1d68: 0xb359, 0x1d69: 0xb479, + 0x1d6a: 0x0040, 0x1d6b: 0xb401, 0x1d6c: 0xb419, 0x1d6d: 0xb431, 0x1d6e: 0xb2f9, 0x1d6f: 0xb389, + 0x1d70: 0xb3b9, 0x1d71: 0xb329, 0x1d72: 0xb3d1, 0x1d73: 0xb2c9, 0x1d74: 0xb311, 0x1d75: 0xb221, + 0x1d76: 0xb239, 0x1d77: 0xb281, 0x1d78: 0xb2b1, 0x1d79: 0xb341, 0x1d7a: 0xb371, 0x1d7b: 0xb3a1, + 0x1d7c: 0x0040, 0x1d7d: 0x0040, 0x1d7e: 0x0040, 0x1d7f: 0x0040, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x0040, 0x1d81: 0xbcf2, 0x1d82: 0xbd0a, 0x1d83: 0xbd22, 0x1d84: 0xbd3a, 0x1d85: 0xbd52, + 0x1d86: 0xbd6a, 0x1d87: 0xbd82, 0x1d88: 0xbd9a, 0x1d89: 0xbdb2, 0x1d8a: 0xbdca, 0x1d8b: 0x0018, + 0x1d8c: 0x0018, 0x1d8d: 0x0018, 0x1d8e: 0x0018, 0x1d8f: 0x0018, 0x1d90: 0xbde2, 0x1d91: 0xbe02, + 0x1d92: 0xbe22, 0x1d93: 0xbe42, 0x1d94: 0xbe62, 0x1d95: 0xbe82, 0x1d96: 0xbea2, 0x1d97: 0xbec2, + 0x1d98: 0xbee2, 0x1d99: 0xbf02, 0x1d9a: 0xbf22, 0x1d9b: 0xbf42, 0x1d9c: 0xbf62, 0x1d9d: 0xbf82, + 0x1d9e: 0xbfa2, 0x1d9f: 0xbfc2, 0x1da0: 0xbfe2, 0x1da1: 0xc002, 0x1da2: 0xc022, 0x1da3: 0xc042, + 0x1da4: 0xc062, 0x1da5: 0xc082, 0x1da6: 0xc0a2, 0x1da7: 0xc0c2, 0x1da8: 0xc0e2, 0x1da9: 0xc102, + 0x1daa: 0xc121, 0x1dab: 0x1159, 0x1dac: 0x0269, 0x1dad: 0x66a9, 0x1dae: 0xc161, 0x1daf: 0x0018, + 0x1db0: 0x0039, 0x1db1: 0x0ee9, 0x1db2: 0x1159, 0x1db3: 0x0ef9, 0x1db4: 0x0f09, 0x1db5: 0x1199, + 0x1db6: 0x0f31, 0x1db7: 0x0249, 0x1db8: 0x0f41, 0x1db9: 0x0259, 0x1dba: 0x0f51, 0x1dbb: 0x0359, + 0x1dbc: 0x0f61, 0x1dbd: 0x0f71, 0x1dbe: 0x00d9, 0x1dbf: 0x0f99, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0x2039, 0x1dc1: 0x0269, 0x1dc2: 0x01d9, 0x1dc3: 0x0fa9, 0x1dc4: 0x0fb9, 0x1dc5: 0x1089, + 0x1dc6: 0x0279, 0x1dc7: 0x0369, 0x1dc8: 0x0289, 0x1dc9: 0x13d1, 0x1dca: 0xc179, 0x1dcb: 0x65e9, + 0x1dcc: 0xc191, 0x1dcd: 0x1441, 0x1dce: 0xc1a9, 0x1dcf: 0xc1c9, 0x1dd0: 0x0018, 0x1dd1: 0x0018, + 0x1dd2: 0x0018, 0x1dd3: 0x0018, 0x1dd4: 0x0018, 0x1dd5: 0x0018, 0x1dd6: 0x0018, 0x1dd7: 0x0018, + 0x1dd8: 0x0018, 0x1dd9: 0x0018, 0x1dda: 0x0018, 0x1ddb: 0x0018, 0x1ddc: 0x0018, 0x1ddd: 0x0018, + 0x1dde: 0x0018, 0x1ddf: 0x0018, 0x1de0: 0x0018, 0x1de1: 0x0018, 0x1de2: 0x0018, 0x1de3: 0x0018, + 0x1de4: 0x0018, 0x1de5: 0x0018, 0x1de6: 0x0018, 0x1de7: 0x0018, 0x1de8: 0x0018, 0x1de9: 0x0018, + 0x1dea: 0xc1e1, 0x1deb: 0xc1f9, 0x1dec: 0xc211, 0x1ded: 0x0018, 0x1dee: 0x0018, 0x1def: 0x0018, + 0x1df0: 0x0018, 0x1df1: 0x0018, 0x1df2: 0x0018, 0x1df3: 0x0018, 0x1df4: 0x0018, 0x1df5: 0x0018, + 0x1df6: 0x0018, 0x1df7: 0x0018, 0x1df8: 0x0018, 0x1df9: 0x0018, 0x1dfa: 0x0018, 0x1dfb: 0x0018, + 0x1dfc: 0x0018, 0x1dfd: 0x0018, 0x1dfe: 0x0018, 0x1dff: 0x0018, + // Block 0x78, offset 0x1e00 + 0x1e00: 0xc241, 0x1e01: 0xc279, 0x1e02: 0xc2b1, 0x1e03: 0x0040, 0x1e04: 0x0040, 0x1e05: 0x0040, + 0x1e06: 0x0040, 0x1e07: 0x0040, 0x1e08: 0x0040, 0x1e09: 0x0040, 0x1e0a: 0x0040, 0x1e0b: 0x0040, + 0x1e0c: 0x0040, 0x1e0d: 0x0040, 0x1e0e: 0x0040, 0x1e0f: 0x0040, 0x1e10: 0xc2d1, 0x1e11: 0xc2f1, + 0x1e12: 0xc311, 0x1e13: 0xc331, 0x1e14: 0xc351, 0x1e15: 0xc371, 0x1e16: 0xc391, 0x1e17: 0xc3b1, + 0x1e18: 0xc3d1, 0x1e19: 0xc3f1, 0x1e1a: 0xc411, 0x1e1b: 0xc431, 0x1e1c: 0xc451, 0x1e1d: 0xc471, + 0x1e1e: 0xc491, 0x1e1f: 0xc4b1, 0x1e20: 0xc4d1, 0x1e21: 0xc4f1, 0x1e22: 0xc511, 0x1e23: 0xc531, + 0x1e24: 0xc551, 0x1e25: 0xc571, 0x1e26: 0xc591, 0x1e27: 0xc5b1, 0x1e28: 0xc5d1, 0x1e29: 0xc5f1, + 0x1e2a: 0xc611, 0x1e2b: 0xc631, 0x1e2c: 0xc651, 0x1e2d: 0xc671, 0x1e2e: 0xc691, 0x1e2f: 0xc6b1, + 0x1e30: 0xc6d1, 0x1e31: 0xc6f1, 0x1e32: 0xc711, 0x1e33: 0xc731, 0x1e34: 0xc751, 0x1e35: 0xc771, + 0x1e36: 0xc791, 0x1e37: 0xc7b1, 0x1e38: 0xc7d1, 0x1e39: 0xc7f1, 0x1e3a: 0xc811, 0x1e3b: 0xc831, + 0x1e3c: 0x0040, 0x1e3d: 0x0040, 0x1e3e: 0x0040, 0x1e3f: 0x0040, + // Block 0x79, offset 0x1e40 + 0x1e40: 0xcb61, 0x1e41: 0xcb81, 0x1e42: 0xcba1, 0x1e43: 0x8b55, 0x1e44: 0xcbc1, 0x1e45: 0xcbe1, + 0x1e46: 0xcc01, 0x1e47: 0xcc21, 0x1e48: 0xcc41, 0x1e49: 0xcc61, 0x1e4a: 0xcc81, 0x1e4b: 0xcca1, + 0x1e4c: 0xccc1, 0x1e4d: 0x8b75, 0x1e4e: 0xcce1, 0x1e4f: 0xcd01, 0x1e50: 0xcd21, 0x1e51: 0xcd41, + 0x1e52: 0x8b95, 0x1e53: 0xcd61, 0x1e54: 0xcd81, 0x1e55: 0xc491, 0x1e56: 0x8bb5, 0x1e57: 0xcda1, + 0x1e58: 0xcdc1, 0x1e59: 0xcde1, 0x1e5a: 0xce01, 0x1e5b: 0xce21, 0x1e5c: 0x8bd5, 0x1e5d: 0xce41, + 0x1e5e: 0xce61, 0x1e5f: 0xce81, 0x1e60: 0xcea1, 0x1e61: 0xcec1, 0x1e62: 0xc7f1, 0x1e63: 0xcee1, + 0x1e64: 0xcf01, 0x1e65: 0xcf21, 0x1e66: 0xcf41, 0x1e67: 0xcf61, 0x1e68: 0xcf81, 0x1e69: 0xcfa1, + 0x1e6a: 0xcfc1, 0x1e6b: 0xcfe1, 0x1e6c: 0xd001, 0x1e6d: 0xd021, 0x1e6e: 0xd041, 0x1e6f: 0xd061, + 0x1e70: 0xd081, 0x1e71: 0xd0a1, 0x1e72: 0xd0a1, 0x1e73: 0xd0a1, 0x1e74: 0x8bf5, 0x1e75: 0xd0c1, + 0x1e76: 0xd0e1, 0x1e77: 0xd101, 0x1e78: 0x8c15, 0x1e79: 0xd121, 0x1e7a: 0xd141, 0x1e7b: 0xd161, + 0x1e7c: 0xd181, 0x1e7d: 0xd1a1, 0x1e7e: 0xd1c1, 0x1e7f: 0xd1e1, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0xd201, 0x1e81: 0xd221, 0x1e82: 0xd241, 0x1e83: 0xd261, 0x1e84: 0xd281, 0x1e85: 0xd2a1, + 0x1e86: 0xd2a1, 0x1e87: 0xd2c1, 0x1e88: 0xd2e1, 0x1e89: 0xd301, 0x1e8a: 0xd321, 0x1e8b: 0xd341, + 0x1e8c: 0xd361, 0x1e8d: 0xd381, 0x1e8e: 0xd3a1, 0x1e8f: 0xd3c1, 0x1e90: 0xd3e1, 0x1e91: 0xd401, + 0x1e92: 0xd421, 0x1e93: 0xd441, 0x1e94: 0xd461, 0x1e95: 0xd481, 0x1e96: 0xd4a1, 0x1e97: 0xd4c1, + 0x1e98: 0xd4e1, 0x1e99: 0x8c35, 0x1e9a: 0xd501, 0x1e9b: 0xd521, 0x1e9c: 0xd541, 0x1e9d: 0xc371, + 0x1e9e: 0xd561, 0x1e9f: 0xd581, 0x1ea0: 0x8c55, 0x1ea1: 0x8c75, 0x1ea2: 0xd5a1, 0x1ea3: 0xd5c1, + 0x1ea4: 0xd5e1, 0x1ea5: 0xd601, 0x1ea6: 0xd621, 0x1ea7: 0xd641, 0x1ea8: 0x2040, 0x1ea9: 0xd661, + 0x1eaa: 0xd681, 0x1eab: 0xd681, 0x1eac: 0x8c95, 0x1ead: 0xd6a1, 0x1eae: 0xd6c1, 0x1eaf: 0xd6e1, + 0x1eb0: 0xd701, 0x1eb1: 0x8cb5, 0x1eb2: 0xd721, 0x1eb3: 0xd741, 0x1eb4: 0x2040, 0x1eb5: 0xd761, + 0x1eb6: 0xd781, 0x1eb7: 0xd7a1, 0x1eb8: 0xd7c1, 0x1eb9: 0xd7e1, 0x1eba: 0xd801, 0x1ebb: 0x8cd5, + 0x1ebc: 0xd821, 0x1ebd: 0x8cf5, 0x1ebe: 0xd841, 0x1ebf: 0xd861, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0xd881, 0x1ec1: 0xd8a1, 0x1ec2: 0xd8c1, 0x1ec3: 0xd8e1, 0x1ec4: 0xd901, 0x1ec5: 0xd921, + 0x1ec6: 0xd941, 0x1ec7: 0xd961, 0x1ec8: 0xd981, 0x1ec9: 0x8d15, 0x1eca: 0xd9a1, 0x1ecb: 0xd9c1, + 0x1ecc: 0xd9e1, 0x1ecd: 0xda01, 0x1ece: 0xda21, 0x1ecf: 0x8d35, 0x1ed0: 0xda41, 0x1ed1: 0x8d55, + 0x1ed2: 0x8d75, 0x1ed3: 0xda61, 0x1ed4: 0xda81, 0x1ed5: 0xda81, 0x1ed6: 0xdaa1, 0x1ed7: 0x8d95, + 0x1ed8: 0x8db5, 0x1ed9: 0xdac1, 0x1eda: 0xdae1, 0x1edb: 0xdb01, 0x1edc: 0xdb21, 0x1edd: 0xdb41, + 0x1ede: 0xdb61, 0x1edf: 0xdb81, 0x1ee0: 0xdba1, 0x1ee1: 0xdbc1, 0x1ee2: 0xdbe1, 0x1ee3: 0xdc01, + 0x1ee4: 0x8dd5, 0x1ee5: 0xdc21, 0x1ee6: 0xdc41, 0x1ee7: 0xdc61, 0x1ee8: 0xdc81, 0x1ee9: 0xdc61, + 0x1eea: 0xdca1, 0x1eeb: 0xdcc1, 0x1eec: 0xdce1, 0x1eed: 0xdd01, 0x1eee: 0xdd21, 0x1eef: 0xdd41, + 0x1ef0: 0xdd61, 0x1ef1: 0xdd81, 0x1ef2: 0xdda1, 0x1ef3: 0xddc1, 0x1ef4: 0xdde1, 0x1ef5: 0xde01, + 0x1ef6: 0xde21, 0x1ef7: 0xde41, 0x1ef8: 0x8df5, 0x1ef9: 0xde61, 0x1efa: 0xde81, 0x1efb: 0xdea1, + 0x1efc: 0xdec1, 0x1efd: 0xdee1, 0x1efe: 0x8e15, 0x1eff: 0xdf01, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0xe601, 0x1f01: 0xe621, 0x1f02: 0xe641, 0x1f03: 0xe661, 0x1f04: 0xe681, 0x1f05: 0xe6a1, + 0x1f06: 0x8f35, 0x1f07: 0xe6c1, 0x1f08: 0xe6e1, 0x1f09: 0xe701, 0x1f0a: 0xe721, 0x1f0b: 0xe741, + 0x1f0c: 0xe761, 0x1f0d: 0x8f55, 0x1f0e: 0xe781, 0x1f0f: 0xe7a1, 0x1f10: 0x8f75, 0x1f11: 0x8f95, + 0x1f12: 0xe7c1, 0x1f13: 0xe7e1, 0x1f14: 0xe801, 0x1f15: 0xe821, 0x1f16: 0xe841, 0x1f17: 0xe861, + 0x1f18: 0xe881, 0x1f19: 0xe8a1, 0x1f1a: 0xe8c1, 0x1f1b: 0x8fb5, 0x1f1c: 0xe8e1, 0x1f1d: 0x8fd5, + 0x1f1e: 0xe901, 0x1f1f: 0x2040, 0x1f20: 0xe921, 0x1f21: 0xe941, 0x1f22: 0xe961, 0x1f23: 0x8ff5, + 0x1f24: 0xe981, 0x1f25: 0xe9a1, 0x1f26: 0x9015, 0x1f27: 0x9035, 0x1f28: 0xe9c1, 0x1f29: 0xe9e1, + 0x1f2a: 0xea01, 0x1f2b: 0xea21, 0x1f2c: 0xea41, 0x1f2d: 0xea41, 0x1f2e: 0xea61, 0x1f2f: 0xea81, + 0x1f30: 0xeaa1, 0x1f31: 0xeac1, 0x1f32: 0xeae1, 0x1f33: 0xeb01, 0x1f34: 0xeb21, 0x1f35: 0x9055, + 0x1f36: 0xeb41, 0x1f37: 0x9075, 0x1f38: 0xeb61, 0x1f39: 0x9095, 0x1f3a: 0xeb81, 0x1f3b: 0x90b5, + 0x1f3c: 0x90d5, 0x1f3d: 0x90f5, 0x1f3e: 0xeba1, 0x1f3f: 0xebc1, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0xebe1, 0x1f41: 0x9115, 0x1f42: 0x9135, 0x1f43: 0x9155, 0x1f44: 0x9175, 0x1f45: 0xec01, + 0x1f46: 0xec21, 0x1f47: 0xec21, 0x1f48: 0xec41, 0x1f49: 0xec61, 0x1f4a: 0xec81, 0x1f4b: 0xeca1, + 0x1f4c: 0xecc1, 0x1f4d: 0x9195, 0x1f4e: 0xece1, 0x1f4f: 0xed01, 0x1f50: 0xed21, 0x1f51: 0xed41, + 0x1f52: 0x91b5, 0x1f53: 0xed61, 0x1f54: 0x91d5, 0x1f55: 0x91f5, 0x1f56: 0xed81, 0x1f57: 0xeda1, + 0x1f58: 0xedc1, 0x1f59: 0xede1, 0x1f5a: 0xee01, 0x1f5b: 0xee21, 0x1f5c: 0x9215, 0x1f5d: 0x9235, + 0x1f5e: 0x9255, 0x1f5f: 0x2040, 0x1f60: 0xee41, 0x1f61: 0x9275, 0x1f62: 0xee61, 0x1f63: 0xee81, + 0x1f64: 0xeea1, 0x1f65: 0x9295, 0x1f66: 0xeec1, 0x1f67: 0xeee1, 0x1f68: 0xef01, 0x1f69: 0xef21, + 0x1f6a: 0xef41, 0x1f6b: 0x92b5, 0x1f6c: 0xef61, 0x1f6d: 0xef81, 0x1f6e: 0xefa1, 0x1f6f: 0xefc1, + 0x1f70: 0xefe1, 0x1f71: 0xf001, 0x1f72: 0x92d5, 0x1f73: 0x92f5, 0x1f74: 0xf021, 0x1f75: 0x9315, + 0x1f76: 0xf041, 0x1f77: 0x9335, 0x1f78: 0xf061, 0x1f79: 0xf081, 0x1f7a: 0xf0a1, 0x1f7b: 0x9355, + 0x1f7c: 0x9375, 0x1f7d: 0xf0c1, 0x1f7e: 0x9395, 0x1f7f: 0xf0e1, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0xf721, 0x1f81: 0xf741, 0x1f82: 0xf761, 0x1f83: 0xf781, 0x1f84: 0xf7a1, 0x1f85: 0x9555, + 0x1f86: 0xf7c1, 0x1f87: 0xf7e1, 0x1f88: 0xf801, 0x1f89: 0xf821, 0x1f8a: 0xf841, 0x1f8b: 0x9575, + 0x1f8c: 0x9595, 0x1f8d: 0xf861, 0x1f8e: 0xf881, 0x1f8f: 0xf8a1, 0x1f90: 0xf8c1, 0x1f91: 0xf8e1, + 0x1f92: 0xf901, 0x1f93: 0x95b5, 0x1f94: 0xf921, 0x1f95: 0xf941, 0x1f96: 0xf961, 0x1f97: 0xf981, + 0x1f98: 0x95d5, 0x1f99: 0x95f5, 0x1f9a: 0xf9a1, 0x1f9b: 0xf9c1, 0x1f9c: 0xf9e1, 0x1f9d: 0x9615, + 0x1f9e: 0xfa01, 0x1f9f: 0xfa21, 0x1fa0: 0x684d, 0x1fa1: 0x9635, 0x1fa2: 0xfa41, 0x1fa3: 0xfa61, + 0x1fa4: 0xfa81, 0x1fa5: 0x9655, 0x1fa6: 0xfaa1, 0x1fa7: 0xfac1, 0x1fa8: 0xfae1, 0x1fa9: 0xfb01, + 0x1faa: 0xfb21, 0x1fab: 0xfb41, 0x1fac: 0xfb61, 0x1fad: 0x9675, 0x1fae: 0xfb81, 0x1faf: 0xfba1, + 0x1fb0: 0xfbc1, 0x1fb1: 0x9695, 0x1fb2: 0xfbe1, 0x1fb3: 0xfc01, 0x1fb4: 0xfc21, 0x1fb5: 0xfc41, + 0x1fb6: 0x7b6d, 0x1fb7: 0x96b5, 0x1fb8: 0xfc61, 0x1fb9: 0xfc81, 0x1fba: 0xfca1, 0x1fbb: 0x96d5, + 0x1fbc: 0xfcc1, 0x1fbd: 0x96f5, 0x1fbe: 0xfce1, 0x1fbf: 0xfce1, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0xfd01, 0x1fc1: 0x9715, 0x1fc2: 0xfd21, 0x1fc3: 0xfd41, 0x1fc4: 0xfd61, 0x1fc5: 0xfd81, + 0x1fc6: 0xfda1, 0x1fc7: 0xfdc1, 0x1fc8: 0xfde1, 0x1fc9: 0x9735, 0x1fca: 0xfe01, 0x1fcb: 0xfe21, + 0x1fcc: 0xfe41, 0x1fcd: 0xfe61, 0x1fce: 0xfe81, 0x1fcf: 0xfea1, 0x1fd0: 0x9755, 0x1fd1: 0xfec1, + 0x1fd2: 0x9775, 0x1fd3: 0x9795, 0x1fd4: 0x97b5, 0x1fd5: 0xfee1, 0x1fd6: 0xff01, 0x1fd7: 0xff21, + 0x1fd8: 0xff41, 0x1fd9: 0xff61, 0x1fda: 0xff81, 0x1fdb: 0xffa1, 0x1fdc: 0xffc1, 0x1fdd: 0x97d5, + 0x1fde: 0x0040, 0x1fdf: 0x0040, 0x1fe0: 0x0040, 0x1fe1: 0x0040, 0x1fe2: 0x0040, 0x1fe3: 0x0040, + 0x1fe4: 0x0040, 0x1fe5: 0x0040, 0x1fe6: 0x0040, 0x1fe7: 0x0040, 0x1fe8: 0x0040, 0x1fe9: 0x0040, + 0x1fea: 0x0040, 0x1feb: 0x0040, 0x1fec: 0x0040, 0x1fed: 0x0040, 0x1fee: 0x0040, 0x1fef: 0x0040, + 0x1ff0: 0x0040, 0x1ff1: 0x0040, 0x1ff2: 0x0040, 0x1ff3: 0x0040, 0x1ff4: 0x0040, 0x1ff5: 0x0040, + 0x1ff6: 0x0040, 0x1ff7: 0x0040, 0x1ff8: 0x0040, 0x1ff9: 0x0040, 0x1ffa: 0x0040, 0x1ffb: 0x0040, + 0x1ffc: 0x0040, 0x1ffd: 0x0040, 0x1ffe: 0x0040, 0x1fff: 0x0040, +} + +// idnaIndex: 37 blocks, 2368 entries, 4736 bytes +// Block 0 is the zero block. +var idnaIndex = [2368]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x7e, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05, + 0xc8: 0x06, 0xc9: 0x7f, 0xca: 0x80, 0xcb: 0x07, 0xcc: 0x81, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a, + 0xd0: 0x82, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x83, 0xd6: 0x84, 0xd7: 0x85, + 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x86, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x87, 0xde: 0x88, 0xdf: 0x89, + 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: 0x1e, 0xf1: 0x1f, 0xf2: 0x1f, 0xf3: 0x21, 0xf4: 0x22, + // Block 0x4, offset 0x100 + 0x120: 0x8a, 0x121: 0x13, 0x122: 0x8b, 0x123: 0x8c, 0x124: 0x8d, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16, + 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8e, + 0x130: 0x8f, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x90, 0x135: 0x21, 0x136: 0x91, 0x137: 0x92, + 0x138: 0x93, 0x139: 0x94, 0x13a: 0x22, 0x13b: 0x95, 0x13c: 0x96, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x97, + // Block 0x5, offset 0x140 + 0x140: 0x98, 0x141: 0x99, 0x142: 0x9a, 0x143: 0x9b, 0x144: 0x9c, 0x145: 0x9d, 0x146: 0x9e, 0x147: 0x9f, + 0x148: 0xa0, 0x149: 0xa1, 0x14a: 0xa2, 0x14b: 0xa3, 0x14c: 0xa4, 0x14d: 0xa5, 0x14e: 0xa6, 0x14f: 0xa7, + 0x150: 0xa8, 0x151: 0xa0, 0x152: 0xa0, 0x153: 0xa0, 0x154: 0xa0, 0x155: 0xa0, 0x156: 0xa0, 0x157: 0xa0, + 0x158: 0xa0, 0x159: 0xa9, 0x15a: 0xaa, 0x15b: 0xab, 0x15c: 0xac, 0x15d: 0xad, 0x15e: 0xae, 0x15f: 0xaf, + 0x160: 0xb0, 0x161: 0xb1, 0x162: 0xb2, 0x163: 0xb3, 0x164: 0xb4, 0x165: 0xb5, 0x166: 0xb6, 0x167: 0xb7, + 0x168: 0xb8, 0x169: 0xb9, 0x16a: 0xba, 0x16b: 0xbb, 0x16c: 0xbc, 0x16d: 0xbd, 0x16e: 0xbe, 0x16f: 0xbf, + 0x170: 0xc0, 0x171: 0xc1, 0x172: 0xc2, 0x173: 0xc3, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc4, + 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc5, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c, + // Block 0x6, offset 0x180 + 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc6, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc7, 0x187: 0x9c, + 0x188: 0xc8, 0x189: 0xc9, 0x18a: 0x9c, 0x18b: 0x9c, 0x18c: 0xca, 0x18d: 0x9c, 0x18e: 0x9c, 0x18f: 0x9c, + 0x190: 0xcb, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9c, 0x195: 0x9c, 0x196: 0x9c, 0x197: 0x9c, + 0x198: 0x9c, 0x199: 0x9c, 0x19a: 0x9c, 0x19b: 0x9c, 0x19c: 0x9c, 0x19d: 0x9c, 0x19e: 0x9c, 0x19f: 0x9c, + 0x1a0: 0x9c, 0x1a1: 0x9c, 0x1a2: 0x9c, 0x1a3: 0x9c, 0x1a4: 0x9c, 0x1a5: 0x9c, 0x1a6: 0x9c, 0x1a7: 0x9c, + 0x1a8: 0xcc, 0x1a9: 0xcd, 0x1aa: 0x9c, 0x1ab: 0xce, 0x1ac: 0x9c, 0x1ad: 0xcf, 0x1ae: 0xd0, 0x1af: 0x9c, + 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5, + 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1, + 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41, + 0x1d0: 0xa0, 0x1d1: 0xa0, 0x1d2: 0xa0, 0x1d3: 0xa0, 0x1d4: 0xa0, 0x1d5: 0xa0, 0x1d6: 0xa0, 0x1d7: 0xa0, + 0x1d8: 0xa0, 0x1d9: 0xa0, 0x1da: 0xa0, 0x1db: 0xa0, 0x1dc: 0xa0, 0x1dd: 0xa0, 0x1de: 0xa0, 0x1df: 0xa0, + 0x1e0: 0xa0, 0x1e1: 0xa0, 0x1e2: 0xa0, 0x1e3: 0xa0, 0x1e4: 0xa0, 0x1e5: 0xa0, 0x1e6: 0xa0, 0x1e7: 0xa0, + 0x1e8: 0xa0, 0x1e9: 0xa0, 0x1ea: 0xa0, 0x1eb: 0xa0, 0x1ec: 0xa0, 0x1ed: 0xa0, 0x1ee: 0xa0, 0x1ef: 0xa0, + 0x1f0: 0xa0, 0x1f1: 0xa0, 0x1f2: 0xa0, 0x1f3: 0xa0, 0x1f4: 0xa0, 0x1f5: 0xa0, 0x1f6: 0xa0, 0x1f7: 0xa0, + 0x1f8: 0xa0, 0x1f9: 0xa0, 0x1fa: 0xa0, 0x1fb: 0xa0, 0x1fc: 0xa0, 0x1fd: 0xa0, 0x1fe: 0xa0, 0x1ff: 0xa0, + // Block 0x8, offset 0x200 + 0x200: 0xa0, 0x201: 0xa0, 0x202: 0xa0, 0x203: 0xa0, 0x204: 0xa0, 0x205: 0xa0, 0x206: 0xa0, 0x207: 0xa0, + 0x208: 0xa0, 0x209: 0xa0, 0x20a: 0xa0, 0x20b: 0xa0, 0x20c: 0xa0, 0x20d: 0xa0, 0x20e: 0xa0, 0x20f: 0xa0, + 0x210: 0xa0, 0x211: 0xa0, 0x212: 0xa0, 0x213: 0xa0, 0x214: 0xa0, 0x215: 0xa0, 0x216: 0xa0, 0x217: 0xa0, + 0x218: 0xa0, 0x219: 0xa0, 0x21a: 0xa0, 0x21b: 0xa0, 0x21c: 0xa0, 0x21d: 0xa0, 0x21e: 0xa0, 0x21f: 0xa0, + 0x220: 0xa0, 0x221: 0xa0, 0x222: 0xa0, 0x223: 0xa0, 0x224: 0xa0, 0x225: 0xa0, 0x226: 0xa0, 0x227: 0xa0, + 0x228: 0xa0, 0x229: 0xa0, 0x22a: 0xa0, 0x22b: 0xa0, 0x22c: 0xa0, 0x22d: 0xa0, 0x22e: 0xa0, 0x22f: 0xa0, + 0x230: 0xa0, 0x231: 0xa0, 0x232: 0xa0, 0x233: 0xa0, 0x234: 0xa0, 0x235: 0xa0, 0x236: 0xa0, 0x237: 0x9c, + 0x238: 0xa0, 0x239: 0xa0, 0x23a: 0xa0, 0x23b: 0xa0, 0x23c: 0xa0, 0x23d: 0xa0, 0x23e: 0xa0, 0x23f: 0xa0, + // Block 0x9, offset 0x240 + 0x240: 0xa0, 0x241: 0xa0, 0x242: 0xa0, 0x243: 0xa0, 0x244: 0xa0, 0x245: 0xa0, 0x246: 0xa0, 0x247: 0xa0, + 0x248: 0xa0, 0x249: 0xa0, 0x24a: 0xa0, 0x24b: 0xa0, 0x24c: 0xa0, 0x24d: 0xa0, 0x24e: 0xa0, 0x24f: 0xa0, + 0x250: 0xa0, 0x251: 0xa0, 0x252: 0xa0, 0x253: 0xa0, 0x254: 0xa0, 0x255: 0xa0, 0x256: 0xa0, 0x257: 0xa0, + 0x258: 0xa0, 0x259: 0xa0, 0x25a: 0xa0, 0x25b: 0xa0, 0x25c: 0xa0, 0x25d: 0xa0, 0x25e: 0xa0, 0x25f: 0xa0, + 0x260: 0xa0, 0x261: 0xa0, 0x262: 0xa0, 0x263: 0xa0, 0x264: 0xa0, 0x265: 0xa0, 0x266: 0xa0, 0x267: 0xa0, + 0x268: 0xa0, 0x269: 0xa0, 0x26a: 0xa0, 0x26b: 0xa0, 0x26c: 0xa0, 0x26d: 0xa0, 0x26e: 0xa0, 0x26f: 0xa0, + 0x270: 0xa0, 0x271: 0xa0, 0x272: 0xa0, 0x273: 0xa0, 0x274: 0xa0, 0x275: 0xa0, 0x276: 0xa0, 0x277: 0xa0, + 0x278: 0xa0, 0x279: 0xa0, 0x27a: 0xa0, 0x27b: 0xa0, 0x27c: 0xa0, 0x27d: 0xa0, 0x27e: 0xa0, 0x27f: 0xa0, + // Block 0xa, offset 0x280 + 0x280: 0xa0, 0x281: 0xa0, 0x282: 0xa0, 0x283: 0xa0, 0x284: 0xa0, 0x285: 0xa0, 0x286: 0xa0, 0x287: 0xa0, + 0x288: 0xa0, 0x289: 0xa0, 0x28a: 0xa0, 0x28b: 0xa0, 0x28c: 0xa0, 0x28d: 0xa0, 0x28e: 0xa0, 0x28f: 0xa0, + 0x290: 0xa0, 0x291: 0xa0, 0x292: 0xa0, 0x293: 0xa0, 0x294: 0xa0, 0x295: 0xa0, 0x296: 0xa0, 0x297: 0xa0, + 0x298: 0xa0, 0x299: 0xa0, 0x29a: 0xa0, 0x29b: 0xa0, 0x29c: 0xa0, 0x29d: 0xa0, 0x29e: 0xa0, 0x29f: 0xa0, + 0x2a0: 0xa0, 0x2a1: 0xa0, 0x2a2: 0xa0, 0x2a3: 0xa0, 0x2a4: 0xa0, 0x2a5: 0xa0, 0x2a6: 0xa0, 0x2a7: 0xa0, + 0x2a8: 0xa0, 0x2a9: 0xa0, 0x2aa: 0xa0, 0x2ab: 0xa0, 0x2ac: 0xa0, 0x2ad: 0xa0, 0x2ae: 0xa0, 0x2af: 0xa0, + 0x2b0: 0xa0, 0x2b1: 0xa0, 0x2b2: 0xa0, 0x2b3: 0xa0, 0x2b4: 0xa0, 0x2b5: 0xa0, 0x2b6: 0xa0, 0x2b7: 0xa0, + 0x2b8: 0xa0, 0x2b9: 0xa0, 0x2ba: 0xa0, 0x2bb: 0xa0, 0x2bc: 0xa0, 0x2bd: 0xa0, 0x2be: 0xa0, 0x2bf: 0xe3, + // Block 0xb, offset 0x2c0 + 0x2c0: 0xa0, 0x2c1: 0xa0, 0x2c2: 0xa0, 0x2c3: 0xa0, 0x2c4: 0xa0, 0x2c5: 0xa0, 0x2c6: 0xa0, 0x2c7: 0xa0, + 0x2c8: 0xa0, 0x2c9: 0xa0, 0x2ca: 0xa0, 0x2cb: 0xa0, 0x2cc: 0xa0, 0x2cd: 0xa0, 0x2ce: 0xa0, 0x2cf: 0xa0, + 0x2d0: 0xa0, 0x2d1: 0xa0, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0xa0, 0x2d5: 0xa0, 0x2d6: 0xa0, 0x2d7: 0xa0, + 0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8, + 0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0, + 0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8, + 0x2f0: 0xa0, 0x2f1: 0xa0, 0x2f2: 0xa0, 0x2f3: 0xa0, 0x2f4: 0xa0, 0x2f5: 0xa0, 0x2f6: 0xa0, 0x2f7: 0xa0, + 0x2f8: 0xa0, 0x2f9: 0xa0, 0x2fa: 0xa0, 0x2fb: 0xa0, 0x2fc: 0xa0, 0x2fd: 0xa0, 0x2fe: 0xa0, 0x2ff: 0xa0, + // Block 0xc, offset 0x300 + 0x300: 0xa0, 0x301: 0xa0, 0x302: 0xa0, 0x303: 0xa0, 0x304: 0xa0, 0x305: 0xa0, 0x306: 0xa0, 0x307: 0xa0, + 0x308: 0xa0, 0x309: 0xa0, 0x30a: 0xa0, 0x30b: 0xa0, 0x30c: 0xa0, 0x30d: 0xa0, 0x30e: 0xa0, 0x30f: 0xa0, + 0x310: 0xa0, 0x311: 0xa0, 0x312: 0xa0, 0x313: 0xa0, 0x314: 0xa0, 0x315: 0xa0, 0x316: 0xa0, 0x317: 0xa0, + 0x318: 0xa0, 0x319: 0xa0, 0x31a: 0xa0, 0x31b: 0xa0, 0x31c: 0xa0, 0x31d: 0xa0, 0x31e: 0xf9, 0x31f: 0xfa, + // Block 0xd, offset 0x340 + 0x340: 0xfb, 0x341: 0xfb, 0x342: 0xfb, 0x343: 0xfb, 0x344: 0xfb, 0x345: 0xfb, 0x346: 0xfb, 0x347: 0xfb, + 0x348: 0xfb, 0x349: 0xfb, 0x34a: 0xfb, 0x34b: 0xfb, 0x34c: 0xfb, 0x34d: 0xfb, 0x34e: 0xfb, 0x34f: 0xfb, + 0x350: 0xfb, 0x351: 0xfb, 0x352: 0xfb, 0x353: 0xfb, 0x354: 0xfb, 0x355: 0xfb, 0x356: 0xfb, 0x357: 0xfb, + 0x358: 0xfb, 0x359: 0xfb, 0x35a: 0xfb, 0x35b: 0xfb, 0x35c: 0xfb, 0x35d: 0xfb, 0x35e: 0xfb, 0x35f: 0xfb, + 0x360: 0xfb, 0x361: 0xfb, 0x362: 0xfb, 0x363: 0xfb, 0x364: 0xfb, 0x365: 0xfb, 0x366: 0xfb, 0x367: 0xfb, + 0x368: 0xfb, 0x369: 0xfb, 0x36a: 0xfb, 0x36b: 0xfb, 0x36c: 0xfb, 0x36d: 0xfb, 0x36e: 0xfb, 0x36f: 0xfb, + 0x370: 0xfb, 0x371: 0xfb, 0x372: 0xfb, 0x373: 0xfb, 0x374: 0xfb, 0x375: 0xfb, 0x376: 0xfb, 0x377: 0xfb, + 0x378: 0xfb, 0x379: 0xfb, 0x37a: 0xfb, 0x37b: 0xfb, 0x37c: 0xfb, 0x37d: 0xfb, 0x37e: 0xfb, 0x37f: 0xfb, + // Block 0xe, offset 0x380 + 0x380: 0xfb, 0x381: 0xfb, 0x382: 0xfb, 0x383: 0xfb, 0x384: 0xfb, 0x385: 0xfb, 0x386: 0xfb, 0x387: 0xfb, + 0x388: 0xfb, 0x389: 0xfb, 0x38a: 0xfb, 0x38b: 0xfb, 0x38c: 0xfb, 0x38d: 0xfb, 0x38e: 0xfb, 0x38f: 0xfb, + 0x390: 0xfb, 0x391: 0xfb, 0x392: 0xfb, 0x393: 0xfb, 0x394: 0xfb, 0x395: 0xfb, 0x396: 0xfb, 0x397: 0xfb, + 0x398: 0xfb, 0x399: 0xfb, 0x39a: 0xfb, 0x39b: 0xfb, 0x39c: 0xfb, 0x39d: 0xfb, 0x39e: 0xfb, 0x39f: 0xfb, + 0x3a0: 0xfb, 0x3a1: 0xfb, 0x3a2: 0xfb, 0x3a3: 0xfb, 0x3a4: 0xfc, 0x3a5: 0xfd, 0x3a6: 0xfe, 0x3a7: 0xff, + 0x3a8: 0x47, 0x3a9: 0x100, 0x3aa: 0x101, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c, + 0x3b0: 0x102, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x103, 0x3b7: 0x52, + 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x104, 0x3c1: 0x105, 0x3c2: 0xa0, 0x3c3: 0x106, 0x3c4: 0x107, 0x3c5: 0x9c, 0x3c6: 0x108, 0x3c7: 0x109, + 0x3c8: 0xfb, 0x3c9: 0xfb, 0x3ca: 0x10a, 0x3cb: 0x10b, 0x3cc: 0x10c, 0x3cd: 0x10d, 0x3ce: 0x10e, 0x3cf: 0x10f, + 0x3d0: 0x110, 0x3d1: 0xa0, 0x3d2: 0x111, 0x3d3: 0x112, 0x3d4: 0x113, 0x3d5: 0x114, 0x3d6: 0xfb, 0x3d7: 0xfb, + 0x3d8: 0xa0, 0x3d9: 0xa0, 0x3da: 0xa0, 0x3db: 0xa0, 0x3dc: 0x115, 0x3dd: 0x116, 0x3de: 0xfb, 0x3df: 0xfb, + 0x3e0: 0x117, 0x3e1: 0x118, 0x3e2: 0x119, 0x3e3: 0x11a, 0x3e4: 0x11b, 0x3e5: 0xfb, 0x3e6: 0x11c, 0x3e7: 0x11d, + 0x3e8: 0x11e, 0x3e9: 0x11f, 0x3ea: 0x120, 0x3eb: 0x5b, 0x3ec: 0x121, 0x3ed: 0x122, 0x3ee: 0x5c, 0x3ef: 0xfb, + 0x3f0: 0x123, 0x3f1: 0x124, 0x3f2: 0x125, 0x3f3: 0x126, 0x3f4: 0x127, 0x3f5: 0xfb, 0x3f6: 0xfb, 0x3f7: 0xfb, + 0x3f8: 0xfb, 0x3f9: 0x128, 0x3fa: 0x129, 0x3fb: 0xfb, 0x3fc: 0x12a, 0x3fd: 0x12b, 0x3fe: 0x12c, 0x3ff: 0x12d, + // Block 0x10, offset 0x400 + 0x400: 0x12e, 0x401: 0x12f, 0x402: 0x130, 0x403: 0x131, 0x404: 0x132, 0x405: 0x133, 0x406: 0x134, 0x407: 0x135, + 0x408: 0x136, 0x409: 0xfb, 0x40a: 0x137, 0x40b: 0x138, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xfb, 0x40f: 0xfb, + 0x410: 0x139, 0x411: 0x13a, 0x412: 0x13b, 0x413: 0x13c, 0x414: 0xfb, 0x415: 0xfb, 0x416: 0x13d, 0x417: 0x13e, + 0x418: 0x13f, 0x419: 0x140, 0x41a: 0x141, 0x41b: 0x142, 0x41c: 0x143, 0x41d: 0xfb, 0x41e: 0xfb, 0x41f: 0xfb, + 0x420: 0x144, 0x421: 0xfb, 0x422: 0x145, 0x423: 0x146, 0x424: 0x5f, 0x425: 0x147, 0x426: 0x148, 0x427: 0x149, + 0x428: 0x14a, 0x429: 0x14b, 0x42a: 0x14c, 0x42b: 0x14d, 0x42c: 0xfb, 0x42d: 0xfb, 0x42e: 0xfb, 0x42f: 0xfb, + 0x430: 0x14e, 0x431: 0x14f, 0x432: 0x150, 0x433: 0xfb, 0x434: 0x151, 0x435: 0x152, 0x436: 0x153, 0x437: 0xfb, + 0x438: 0xfb, 0x439: 0xfb, 0x43a: 0xfb, 0x43b: 0x154, 0x43c: 0xfb, 0x43d: 0xfb, 0x43e: 0x155, 0x43f: 0x156, + // Block 0x11, offset 0x440 + 0x440: 0xa0, 0x441: 0xa0, 0x442: 0xa0, 0x443: 0xa0, 0x444: 0xa0, 0x445: 0xa0, 0x446: 0xa0, 0x447: 0xa0, + 0x448: 0xa0, 0x449: 0xa0, 0x44a: 0xa0, 0x44b: 0xa0, 0x44c: 0xa0, 0x44d: 0xa0, 0x44e: 0x157, 0x44f: 0xfb, + 0x450: 0x9c, 0x451: 0x158, 0x452: 0xa0, 0x453: 0xa0, 0x454: 0xa0, 0x455: 0x159, 0x456: 0xfb, 0x457: 0xfb, + 0x458: 0xfb, 0x459: 0xfb, 0x45a: 0xfb, 0x45b: 0xfb, 0x45c: 0xfb, 0x45d: 0xfb, 0x45e: 0xfb, 0x45f: 0xfb, + 0x460: 0xfb, 0x461: 0xfb, 0x462: 0xfb, 0x463: 0xfb, 0x464: 0xfb, 0x465: 0xfb, 0x466: 0xfb, 0x467: 0xfb, + 0x468: 0xfb, 0x469: 0xfb, 0x46a: 0xfb, 0x46b: 0xfb, 0x46c: 0xfb, 0x46d: 0xfb, 0x46e: 0xfb, 0x46f: 0xfb, + 0x470: 0xfb, 0x471: 0xfb, 0x472: 0xfb, 0x473: 0xfb, 0x474: 0xfb, 0x475: 0xfb, 0x476: 0xfb, 0x477: 0xfb, + 0x478: 0xfb, 0x479: 0xfb, 0x47a: 0xfb, 0x47b: 0xfb, 0x47c: 0xfb, 0x47d: 0xfb, 0x47e: 0xfb, 0x47f: 0xfb, + // Block 0x12, offset 0x480 + 0x480: 0xa0, 0x481: 0xa0, 0x482: 0xa0, 0x483: 0xa0, 0x484: 0xa0, 0x485: 0xa0, 0x486: 0xa0, 0x487: 0xa0, + 0x488: 0xa0, 0x489: 0xa0, 0x48a: 0xa0, 0x48b: 0xa0, 0x48c: 0xa0, 0x48d: 0xa0, 0x48e: 0xa0, 0x48f: 0xa0, + 0x490: 0x15a, 0x491: 0xfb, 0x492: 0xfb, 0x493: 0xfb, 0x494: 0xfb, 0x495: 0xfb, 0x496: 0xfb, 0x497: 0xfb, + 0x498: 0xfb, 0x499: 0xfb, 0x49a: 0xfb, 0x49b: 0xfb, 0x49c: 0xfb, 0x49d: 0xfb, 0x49e: 0xfb, 0x49f: 0xfb, + 0x4a0: 0xfb, 0x4a1: 0xfb, 0x4a2: 0xfb, 0x4a3: 0xfb, 0x4a4: 0xfb, 0x4a5: 0xfb, 0x4a6: 0xfb, 0x4a7: 0xfb, + 0x4a8: 0xfb, 0x4a9: 0xfb, 0x4aa: 0xfb, 0x4ab: 0xfb, 0x4ac: 0xfb, 0x4ad: 0xfb, 0x4ae: 0xfb, 0x4af: 0xfb, + 0x4b0: 0xfb, 0x4b1: 0xfb, 0x4b2: 0xfb, 0x4b3: 0xfb, 0x4b4: 0xfb, 0x4b5: 0xfb, 0x4b6: 0xfb, 0x4b7: 0xfb, + 0x4b8: 0xfb, 0x4b9: 0xfb, 0x4ba: 0xfb, 0x4bb: 0xfb, 0x4bc: 0xfb, 0x4bd: 0xfb, 0x4be: 0xfb, 0x4bf: 0xfb, + // Block 0x13, offset 0x4c0 + 0x4c0: 0xfb, 0x4c1: 0xfb, 0x4c2: 0xfb, 0x4c3: 0xfb, 0x4c4: 0xfb, 0x4c5: 0xfb, 0x4c6: 0xfb, 0x4c7: 0xfb, + 0x4c8: 0xfb, 0x4c9: 0xfb, 0x4ca: 0xfb, 0x4cb: 0xfb, 0x4cc: 0xfb, 0x4cd: 0xfb, 0x4ce: 0xfb, 0x4cf: 0xfb, + 0x4d0: 0xa0, 0x4d1: 0xa0, 0x4d2: 0xa0, 0x4d3: 0xa0, 0x4d4: 0xa0, 0x4d5: 0xa0, 0x4d6: 0xa0, 0x4d7: 0xa0, + 0x4d8: 0xa0, 0x4d9: 0x15b, 0x4da: 0xfb, 0x4db: 0xfb, 0x4dc: 0xfb, 0x4dd: 0xfb, 0x4de: 0xfb, 0x4df: 0xfb, + 0x4e0: 0xfb, 0x4e1: 0xfb, 0x4e2: 0xfb, 0x4e3: 0xfb, 0x4e4: 0xfb, 0x4e5: 0xfb, 0x4e6: 0xfb, 0x4e7: 0xfb, + 0x4e8: 0xfb, 0x4e9: 0xfb, 0x4ea: 0xfb, 0x4eb: 0xfb, 0x4ec: 0xfb, 0x4ed: 0xfb, 0x4ee: 0xfb, 0x4ef: 0xfb, + 0x4f0: 0xfb, 0x4f1: 0xfb, 0x4f2: 0xfb, 0x4f3: 0xfb, 0x4f4: 0xfb, 0x4f5: 0xfb, 0x4f6: 0xfb, 0x4f7: 0xfb, + 0x4f8: 0xfb, 0x4f9: 0xfb, 0x4fa: 0xfb, 0x4fb: 0xfb, 0x4fc: 0xfb, 0x4fd: 0xfb, 0x4fe: 0xfb, 0x4ff: 0xfb, + // Block 0x14, offset 0x500 + 0x500: 0xfb, 0x501: 0xfb, 0x502: 0xfb, 0x503: 0xfb, 0x504: 0xfb, 0x505: 0xfb, 0x506: 0xfb, 0x507: 0xfb, + 0x508: 0xfb, 0x509: 0xfb, 0x50a: 0xfb, 0x50b: 0xfb, 0x50c: 0xfb, 0x50d: 0xfb, 0x50e: 0xfb, 0x50f: 0xfb, + 0x510: 0xfb, 0x511: 0xfb, 0x512: 0xfb, 0x513: 0xfb, 0x514: 0xfb, 0x515: 0xfb, 0x516: 0xfb, 0x517: 0xfb, + 0x518: 0xfb, 0x519: 0xfb, 0x51a: 0xfb, 0x51b: 0xfb, 0x51c: 0xfb, 0x51d: 0xfb, 0x51e: 0xfb, 0x51f: 0xfb, + 0x520: 0xa0, 0x521: 0xa0, 0x522: 0xa0, 0x523: 0xa0, 0x524: 0xa0, 0x525: 0xa0, 0x526: 0xa0, 0x527: 0xa0, + 0x528: 0x14d, 0x529: 0x15c, 0x52a: 0xfb, 0x52b: 0x15d, 0x52c: 0x15e, 0x52d: 0x15f, 0x52e: 0x160, 0x52f: 0xfb, + 0x530: 0xfb, 0x531: 0xfb, 0x532: 0xfb, 0x533: 0xfb, 0x534: 0xfb, 0x535: 0xfb, 0x536: 0xfb, 0x537: 0xfb, + 0x538: 0xfb, 0x539: 0x161, 0x53a: 0x162, 0x53b: 0xfb, 0x53c: 0xa0, 0x53d: 0x163, 0x53e: 0x164, 0x53f: 0x165, + // Block 0x15, offset 0x540 + 0x540: 0xa0, 0x541: 0xa0, 0x542: 0xa0, 0x543: 0xa0, 0x544: 0xa0, 0x545: 0xa0, 0x546: 0xa0, 0x547: 0xa0, + 0x548: 0xa0, 0x549: 0xa0, 0x54a: 0xa0, 0x54b: 0xa0, 0x54c: 0xa0, 0x54d: 0xa0, 0x54e: 0xa0, 0x54f: 0xa0, + 0x550: 0xa0, 0x551: 0xa0, 0x552: 0xa0, 0x553: 0xa0, 0x554: 0xa0, 0x555: 0xa0, 0x556: 0xa0, 0x557: 0xa0, + 0x558: 0xa0, 0x559: 0xa0, 0x55a: 0xa0, 0x55b: 0xa0, 0x55c: 0xa0, 0x55d: 0xa0, 0x55e: 0xa0, 0x55f: 0x166, + 0x560: 0xa0, 0x561: 0xa0, 0x562: 0xa0, 0x563: 0xa0, 0x564: 0xa0, 0x565: 0xa0, 0x566: 0xa0, 0x567: 0xa0, + 0x568: 0xa0, 0x569: 0xa0, 0x56a: 0xa0, 0x56b: 0xa0, 0x56c: 0xa0, 0x56d: 0xa0, 0x56e: 0xa0, 0x56f: 0xa0, + 0x570: 0xa0, 0x571: 0xa0, 0x572: 0xa0, 0x573: 0x167, 0x574: 0x168, 0x575: 0xfb, 0x576: 0xfb, 0x577: 0xfb, + 0x578: 0xfb, 0x579: 0xfb, 0x57a: 0xfb, 0x57b: 0xfb, 0x57c: 0xfb, 0x57d: 0xfb, 0x57e: 0xfb, 0x57f: 0xfb, + // Block 0x16, offset 0x580 + 0x580: 0xa0, 0x581: 0xa0, 0x582: 0xa0, 0x583: 0xa0, 0x584: 0x169, 0x585: 0x16a, 0x586: 0xa0, 0x587: 0xa0, + 0x588: 0xa0, 0x589: 0xa0, 0x58a: 0xa0, 0x58b: 0x16b, 0x58c: 0xfb, 0x58d: 0xfb, 0x58e: 0xfb, 0x58f: 0xfb, + 0x590: 0xfb, 0x591: 0xfb, 0x592: 0xfb, 0x593: 0xfb, 0x594: 0xfb, 0x595: 0xfb, 0x596: 0xfb, 0x597: 0xfb, + 0x598: 0xfb, 0x599: 0xfb, 0x59a: 0xfb, 0x59b: 0xfb, 0x59c: 0xfb, 0x59d: 0xfb, 0x59e: 0xfb, 0x59f: 0xfb, + 0x5a0: 0xfb, 0x5a1: 0xfb, 0x5a2: 0xfb, 0x5a3: 0xfb, 0x5a4: 0xfb, 0x5a5: 0xfb, 0x5a6: 0xfb, 0x5a7: 0xfb, + 0x5a8: 0xfb, 0x5a9: 0xfb, 0x5aa: 0xfb, 0x5ab: 0xfb, 0x5ac: 0xfb, 0x5ad: 0xfb, 0x5ae: 0xfb, 0x5af: 0xfb, + 0x5b0: 0xa0, 0x5b1: 0x16c, 0x5b2: 0x16d, 0x5b3: 0xfb, 0x5b4: 0xfb, 0x5b5: 0xfb, 0x5b6: 0xfb, 0x5b7: 0xfb, + 0x5b8: 0xfb, 0x5b9: 0xfb, 0x5ba: 0xfb, 0x5bb: 0xfb, 0x5bc: 0xfb, 0x5bd: 0xfb, 0x5be: 0xfb, 0x5bf: 0xfb, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x9c, 0x5c1: 0x9c, 0x5c2: 0x9c, 0x5c3: 0x16e, 0x5c4: 0x16f, 0x5c5: 0x170, 0x5c6: 0x171, 0x5c7: 0x172, + 0x5c8: 0x9c, 0x5c9: 0x173, 0x5ca: 0xfb, 0x5cb: 0x174, 0x5cc: 0x9c, 0x5cd: 0x175, 0x5ce: 0xfb, 0x5cf: 0xfb, + 0x5d0: 0x60, 0x5d1: 0x61, 0x5d2: 0x62, 0x5d3: 0x63, 0x5d4: 0x64, 0x5d5: 0x65, 0x5d6: 0x66, 0x5d7: 0x67, + 0x5d8: 0x68, 0x5d9: 0x69, 0x5da: 0x6a, 0x5db: 0x6b, 0x5dc: 0x6c, 0x5dd: 0x6d, 0x5de: 0x6e, 0x5df: 0x6f, + 0x5e0: 0x9c, 0x5e1: 0x9c, 0x5e2: 0x9c, 0x5e3: 0x9c, 0x5e4: 0x9c, 0x5e5: 0x9c, 0x5e6: 0x9c, 0x5e7: 0x9c, + 0x5e8: 0x176, 0x5e9: 0x177, 0x5ea: 0x178, 0x5eb: 0xfb, 0x5ec: 0xfb, 0x5ed: 0xfb, 0x5ee: 0xfb, 0x5ef: 0xfb, + 0x5f0: 0xfb, 0x5f1: 0xfb, 0x5f2: 0xfb, 0x5f3: 0xfb, 0x5f4: 0xfb, 0x5f5: 0xfb, 0x5f6: 0xfb, 0x5f7: 0xfb, + 0x5f8: 0xfb, 0x5f9: 0xfb, 0x5fa: 0xfb, 0x5fb: 0xfb, 0x5fc: 0xfb, 0x5fd: 0xfb, 0x5fe: 0xfb, 0x5ff: 0xfb, + // Block 0x18, offset 0x600 + 0x600: 0x179, 0x601: 0xfb, 0x602: 0xfb, 0x603: 0xfb, 0x604: 0x17a, 0x605: 0x17b, 0x606: 0xfb, 0x607: 0xfb, + 0x608: 0xfb, 0x609: 0xfb, 0x60a: 0xfb, 0x60b: 0x17c, 0x60c: 0xfb, 0x60d: 0xfb, 0x60e: 0xfb, 0x60f: 0xfb, + 0x610: 0xfb, 0x611: 0xfb, 0x612: 0xfb, 0x613: 0xfb, 0x614: 0xfb, 0x615: 0xfb, 0x616: 0xfb, 0x617: 0xfb, + 0x618: 0xfb, 0x619: 0xfb, 0x61a: 0xfb, 0x61b: 0xfb, 0x61c: 0xfb, 0x61d: 0xfb, 0x61e: 0xfb, 0x61f: 0xfb, + 0x620: 0x123, 0x621: 0x123, 0x622: 0x123, 0x623: 0x17d, 0x624: 0x70, 0x625: 0x17e, 0x626: 0xfb, 0x627: 0xfb, + 0x628: 0xfb, 0x629: 0xfb, 0x62a: 0xfb, 0x62b: 0xfb, 0x62c: 0xfb, 0x62d: 0xfb, 0x62e: 0xfb, 0x62f: 0xfb, + 0x630: 0xfb, 0x631: 0x17f, 0x632: 0x180, 0x633: 0xfb, 0x634: 0x181, 0x635: 0xfb, 0x636: 0xfb, 0x637: 0xfb, + 0x638: 0x71, 0x639: 0x72, 0x63a: 0x73, 0x63b: 0x182, 0x63c: 0xfb, 0x63d: 0xfb, 0x63e: 0xfb, 0x63f: 0xfb, + // Block 0x19, offset 0x640 + 0x640: 0x183, 0x641: 0x9c, 0x642: 0x184, 0x643: 0x185, 0x644: 0x74, 0x645: 0x75, 0x646: 0x186, 0x647: 0x187, + 0x648: 0x76, 0x649: 0x188, 0x64a: 0xfb, 0x64b: 0xfb, 0x64c: 0x9c, 0x64d: 0x9c, 0x64e: 0x9c, 0x64f: 0x9c, + 0x650: 0x9c, 0x651: 0x9c, 0x652: 0x9c, 0x653: 0x9c, 0x654: 0x9c, 0x655: 0x9c, 0x656: 0x9c, 0x657: 0x9c, + 0x658: 0x9c, 0x659: 0x9c, 0x65a: 0x9c, 0x65b: 0x189, 0x65c: 0x9c, 0x65d: 0x18a, 0x65e: 0x9c, 0x65f: 0x18b, + 0x660: 0x18c, 0x661: 0x18d, 0x662: 0x18e, 0x663: 0xfb, 0x664: 0x9c, 0x665: 0x18f, 0x666: 0x9c, 0x667: 0x190, + 0x668: 0x9c, 0x669: 0x191, 0x66a: 0x192, 0x66b: 0x193, 0x66c: 0x9c, 0x66d: 0x9c, 0x66e: 0x194, 0x66f: 0x195, + 0x670: 0xfb, 0x671: 0xfb, 0x672: 0xfb, 0x673: 0xfb, 0x674: 0xfb, 0x675: 0xfb, 0x676: 0xfb, 0x677: 0xfb, + 0x678: 0xfb, 0x679: 0xfb, 0x67a: 0xfb, 0x67b: 0xfb, 0x67c: 0xfb, 0x67d: 0xfb, 0x67e: 0xfb, 0x67f: 0xfb, + // Block 0x1a, offset 0x680 + 0x680: 0xa0, 0x681: 0xa0, 0x682: 0xa0, 0x683: 0xa0, 0x684: 0xa0, 0x685: 0xa0, 0x686: 0xa0, 0x687: 0xa0, + 0x688: 0xa0, 0x689: 0xa0, 0x68a: 0xa0, 0x68b: 0xa0, 0x68c: 0xa0, 0x68d: 0xa0, 0x68e: 0xa0, 0x68f: 0xa0, + 0x690: 0xa0, 0x691: 0xa0, 0x692: 0xa0, 0x693: 0xa0, 0x694: 0xa0, 0x695: 0xa0, 0x696: 0xa0, 0x697: 0xa0, + 0x698: 0xa0, 0x699: 0xa0, 0x69a: 0xa0, 0x69b: 0x196, 0x69c: 0xa0, 0x69d: 0xa0, 0x69e: 0xa0, 0x69f: 0xa0, + 0x6a0: 0xa0, 0x6a1: 0xa0, 0x6a2: 0xa0, 0x6a3: 0xa0, 0x6a4: 0xa0, 0x6a5: 0xa0, 0x6a6: 0xa0, 0x6a7: 0xa0, + 0x6a8: 0xa0, 0x6a9: 0xa0, 0x6aa: 0xa0, 0x6ab: 0xa0, 0x6ac: 0xa0, 0x6ad: 0xa0, 0x6ae: 0xa0, 0x6af: 0xa0, + 0x6b0: 0xa0, 0x6b1: 0xa0, 0x6b2: 0xa0, 0x6b3: 0xa0, 0x6b4: 0xa0, 0x6b5: 0xa0, 0x6b6: 0xa0, 0x6b7: 0xa0, + 0x6b8: 0xa0, 0x6b9: 0xa0, 0x6ba: 0xa0, 0x6bb: 0xa0, 0x6bc: 0xa0, 0x6bd: 0xa0, 0x6be: 0xa0, 0x6bf: 0xa0, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0xa0, 0x6c1: 0xa0, 0x6c2: 0xa0, 0x6c3: 0xa0, 0x6c4: 0xa0, 0x6c5: 0xa0, 0x6c6: 0xa0, 0x6c7: 0xa0, + 0x6c8: 0xa0, 0x6c9: 0xa0, 0x6ca: 0xa0, 0x6cb: 0xa0, 0x6cc: 0xa0, 0x6cd: 0xa0, 0x6ce: 0xa0, 0x6cf: 0xa0, + 0x6d0: 0xa0, 0x6d1: 0xa0, 0x6d2: 0xa0, 0x6d3: 0xa0, 0x6d4: 0xa0, 0x6d5: 0xa0, 0x6d6: 0xa0, 0x6d7: 0xa0, + 0x6d8: 0xa0, 0x6d9: 0xa0, 0x6da: 0xa0, 0x6db: 0xa0, 0x6dc: 0x197, 0x6dd: 0xa0, 0x6de: 0xa0, 0x6df: 0xa0, + 0x6e0: 0x198, 0x6e1: 0xa0, 0x6e2: 0xa0, 0x6e3: 0xa0, 0x6e4: 0xa0, 0x6e5: 0xa0, 0x6e6: 0xa0, 0x6e7: 0xa0, + 0x6e8: 0xa0, 0x6e9: 0xa0, 0x6ea: 0xa0, 0x6eb: 0xa0, 0x6ec: 0xa0, 0x6ed: 0xa0, 0x6ee: 0xa0, 0x6ef: 0xa0, + 0x6f0: 0xa0, 0x6f1: 0xa0, 0x6f2: 0xa0, 0x6f3: 0xa0, 0x6f4: 0xa0, 0x6f5: 0xa0, 0x6f6: 0xa0, 0x6f7: 0xa0, + 0x6f8: 0xa0, 0x6f9: 0xa0, 0x6fa: 0xa0, 0x6fb: 0xa0, 0x6fc: 0xa0, 0x6fd: 0xa0, 0x6fe: 0xa0, 0x6ff: 0xa0, + // Block 0x1c, offset 0x700 + 0x700: 0xa0, 0x701: 0xa0, 0x702: 0xa0, 0x703: 0xa0, 0x704: 0xa0, 0x705: 0xa0, 0x706: 0xa0, 0x707: 0xa0, + 0x708: 0xa0, 0x709: 0xa0, 0x70a: 0xa0, 0x70b: 0xa0, 0x70c: 0xa0, 0x70d: 0xa0, 0x70e: 0xa0, 0x70f: 0xa0, + 0x710: 0xa0, 0x711: 0xa0, 0x712: 0xa0, 0x713: 0xa0, 0x714: 0xa0, 0x715: 0xa0, 0x716: 0xa0, 0x717: 0xa0, + 0x718: 0xa0, 0x719: 0xa0, 0x71a: 0xa0, 0x71b: 0xa0, 0x71c: 0xa0, 0x71d: 0xa0, 0x71e: 0xa0, 0x71f: 0xa0, + 0x720: 0xa0, 0x721: 0xa0, 0x722: 0xa0, 0x723: 0xa0, 0x724: 0xa0, 0x725: 0xa0, 0x726: 0xa0, 0x727: 0xa0, + 0x728: 0xa0, 0x729: 0xa0, 0x72a: 0xa0, 0x72b: 0xa0, 0x72c: 0xa0, 0x72d: 0xa0, 0x72e: 0xa0, 0x72f: 0xa0, + 0x730: 0xa0, 0x731: 0xa0, 0x732: 0xa0, 0x733: 0xa0, 0x734: 0xa0, 0x735: 0xa0, 0x736: 0xa0, 0x737: 0xa0, + 0x738: 0xa0, 0x739: 0xa0, 0x73a: 0x199, 0x73b: 0xa0, 0x73c: 0xa0, 0x73d: 0xa0, 0x73e: 0xa0, 0x73f: 0xa0, + // Block 0x1d, offset 0x740 + 0x740: 0xa0, 0x741: 0xa0, 0x742: 0xa0, 0x743: 0xa0, 0x744: 0xa0, 0x745: 0xa0, 0x746: 0xa0, 0x747: 0xa0, + 0x748: 0xa0, 0x749: 0xa0, 0x74a: 0xa0, 0x74b: 0xa0, 0x74c: 0xa0, 0x74d: 0xa0, 0x74e: 0xa0, 0x74f: 0xa0, + 0x750: 0xa0, 0x751: 0xa0, 0x752: 0xa0, 0x753: 0xa0, 0x754: 0xa0, 0x755: 0xa0, 0x756: 0xa0, 0x757: 0xa0, + 0x758: 0xa0, 0x759: 0xa0, 0x75a: 0xa0, 0x75b: 0xa0, 0x75c: 0xa0, 0x75d: 0xa0, 0x75e: 0xa0, 0x75f: 0xa0, + 0x760: 0xa0, 0x761: 0xa0, 0x762: 0xa0, 0x763: 0xa0, 0x764: 0xa0, 0x765: 0xa0, 0x766: 0xa0, 0x767: 0xa0, + 0x768: 0xa0, 0x769: 0xa0, 0x76a: 0xa0, 0x76b: 0xa0, 0x76c: 0xa0, 0x76d: 0xa0, 0x76e: 0xa0, 0x76f: 0x19a, + 0x770: 0xfb, 0x771: 0xfb, 0x772: 0xfb, 0x773: 0xfb, 0x774: 0xfb, 0x775: 0xfb, 0x776: 0xfb, 0x777: 0xfb, + 0x778: 0xfb, 0x779: 0xfb, 0x77a: 0xfb, 0x77b: 0xfb, 0x77c: 0xfb, 0x77d: 0xfb, 0x77e: 0xfb, 0x77f: 0xfb, + // Block 0x1e, offset 0x780 + 0x780: 0xfb, 0x781: 0xfb, 0x782: 0xfb, 0x783: 0xfb, 0x784: 0xfb, 0x785: 0xfb, 0x786: 0xfb, 0x787: 0xfb, + 0x788: 0xfb, 0x789: 0xfb, 0x78a: 0xfb, 0x78b: 0xfb, 0x78c: 0xfb, 0x78d: 0xfb, 0x78e: 0xfb, 0x78f: 0xfb, + 0x790: 0xfb, 0x791: 0xfb, 0x792: 0xfb, 0x793: 0xfb, 0x794: 0xfb, 0x795: 0xfb, 0x796: 0xfb, 0x797: 0xfb, + 0x798: 0xfb, 0x799: 0xfb, 0x79a: 0xfb, 0x79b: 0xfb, 0x79c: 0xfb, 0x79d: 0xfb, 0x79e: 0xfb, 0x79f: 0xfb, + 0x7a0: 0x77, 0x7a1: 0x78, 0x7a2: 0x79, 0x7a3: 0x19b, 0x7a4: 0x7a, 0x7a5: 0x7b, 0x7a6: 0x19c, 0x7a7: 0x7c, + 0x7a8: 0x7d, 0x7a9: 0xfb, 0x7aa: 0xfb, 0x7ab: 0xfb, 0x7ac: 0xfb, 0x7ad: 0xfb, 0x7ae: 0xfb, 0x7af: 0xfb, + 0x7b0: 0xfb, 0x7b1: 0xfb, 0x7b2: 0xfb, 0x7b3: 0xfb, 0x7b4: 0xfb, 0x7b5: 0xfb, 0x7b6: 0xfb, 0x7b7: 0xfb, + 0x7b8: 0xfb, 0x7b9: 0xfb, 0x7ba: 0xfb, 0x7bb: 0xfb, 0x7bc: 0xfb, 0x7bd: 0xfb, 0x7be: 0xfb, 0x7bf: 0xfb, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0xa0, 0x7c1: 0xa0, 0x7c2: 0xa0, 0x7c3: 0xa0, 0x7c4: 0xa0, 0x7c5: 0xa0, 0x7c6: 0xa0, 0x7c7: 0xa0, + 0x7c8: 0xa0, 0x7c9: 0xa0, 0x7ca: 0xa0, 0x7cb: 0xa0, 0x7cc: 0xa0, 0x7cd: 0x19d, 0x7ce: 0xfb, 0x7cf: 0xfb, + 0x7d0: 0xfb, 0x7d1: 0xfb, 0x7d2: 0xfb, 0x7d3: 0xfb, 0x7d4: 0xfb, 0x7d5: 0xfb, 0x7d6: 0xfb, 0x7d7: 0xfb, + 0x7d8: 0xfb, 0x7d9: 0xfb, 0x7da: 0xfb, 0x7db: 0xfb, 0x7dc: 0xfb, 0x7dd: 0xfb, 0x7de: 0xfb, 0x7df: 0xfb, + 0x7e0: 0xfb, 0x7e1: 0xfb, 0x7e2: 0xfb, 0x7e3: 0xfb, 0x7e4: 0xfb, 0x7e5: 0xfb, 0x7e6: 0xfb, 0x7e7: 0xfb, + 0x7e8: 0xfb, 0x7e9: 0xfb, 0x7ea: 0xfb, 0x7eb: 0xfb, 0x7ec: 0xfb, 0x7ed: 0xfb, 0x7ee: 0xfb, 0x7ef: 0xfb, + 0x7f0: 0xfb, 0x7f1: 0xfb, 0x7f2: 0xfb, 0x7f3: 0xfb, 0x7f4: 0xfb, 0x7f5: 0xfb, 0x7f6: 0xfb, 0x7f7: 0xfb, + 0x7f8: 0xfb, 0x7f9: 0xfb, 0x7fa: 0xfb, 0x7fb: 0xfb, 0x7fc: 0xfb, 0x7fd: 0xfb, 0x7fe: 0xfb, 0x7ff: 0xfb, + // Block 0x20, offset 0x800 + 0x810: 0x0d, 0x811: 0x0e, 0x812: 0x0f, 0x813: 0x10, 0x814: 0x11, 0x815: 0x0b, 0x816: 0x12, 0x817: 0x07, + 0x818: 0x13, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x14, 0x81c: 0x0b, 0x81d: 0x15, 0x81e: 0x16, 0x81f: 0x17, + 0x820: 0x07, 0x821: 0x07, 0x822: 0x07, 0x823: 0x07, 0x824: 0x07, 0x825: 0x07, 0x826: 0x07, 0x827: 0x07, + 0x828: 0x07, 0x829: 0x07, 0x82a: 0x18, 0x82b: 0x19, 0x82c: 0x1a, 0x82d: 0x07, 0x82e: 0x1b, 0x82f: 0x1c, + 0x830: 0x07, 0x831: 0x1d, 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: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b, + 0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b, + 0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b, + 0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b, + 0x860: 0x0b, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b, + 0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b, + 0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b, + 0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b, + // Block 0x22, offset 0x880 + 0x880: 0x19e, 0x881: 0x19f, 0x882: 0xfb, 0x883: 0xfb, 0x884: 0x1a0, 0x885: 0x1a0, 0x886: 0x1a0, 0x887: 0x1a1, + 0x888: 0xfb, 0x889: 0xfb, 0x88a: 0xfb, 0x88b: 0xfb, 0x88c: 0xfb, 0x88d: 0xfb, 0x88e: 0xfb, 0x88f: 0xfb, + 0x890: 0xfb, 0x891: 0xfb, 0x892: 0xfb, 0x893: 0xfb, 0x894: 0xfb, 0x895: 0xfb, 0x896: 0xfb, 0x897: 0xfb, + 0x898: 0xfb, 0x899: 0xfb, 0x89a: 0xfb, 0x89b: 0xfb, 0x89c: 0xfb, 0x89d: 0xfb, 0x89e: 0xfb, 0x89f: 0xfb, + 0x8a0: 0xfb, 0x8a1: 0xfb, 0x8a2: 0xfb, 0x8a3: 0xfb, 0x8a4: 0xfb, 0x8a5: 0xfb, 0x8a6: 0xfb, 0x8a7: 0xfb, + 0x8a8: 0xfb, 0x8a9: 0xfb, 0x8aa: 0xfb, 0x8ab: 0xfb, 0x8ac: 0xfb, 0x8ad: 0xfb, 0x8ae: 0xfb, 0x8af: 0xfb, + 0x8b0: 0xfb, 0x8b1: 0xfb, 0x8b2: 0xfb, 0x8b3: 0xfb, 0x8b4: 0xfb, 0x8b5: 0xfb, 0x8b6: 0xfb, 0x8b7: 0xfb, + 0x8b8: 0xfb, 0x8b9: 0xfb, 0x8ba: 0xfb, 0x8bb: 0xfb, 0x8bc: 0xfb, 0x8bd: 0xfb, 0x8be: 0xfb, 0x8bf: 0xfb, + // 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, + 0x8d0: 0x0b, 0x8d1: 0x0b, 0x8d2: 0x0b, 0x8d3: 0x0b, 0x8d4: 0x0b, 0x8d5: 0x0b, 0x8d6: 0x0b, 0x8d7: 0x0b, + 0x8d8: 0x0b, 0x8d9: 0x0b, 0x8da: 0x0b, 0x8db: 0x0b, 0x8dc: 0x0b, 0x8dd: 0x0b, 0x8de: 0x0b, 0x8df: 0x0b, + 0x8e0: 0x20, 0x8e1: 0x0b, 0x8e2: 0x0b, 0x8e3: 0x0b, 0x8e4: 0x0b, 0x8e5: 0x0b, 0x8e6: 0x0b, 0x8e7: 0x0b, + 0x8e8: 0x0b, 0x8e9: 0x0b, 0x8ea: 0x0b, 0x8eb: 0x0b, 0x8ec: 0x0b, 0x8ed: 0x0b, 0x8ee: 0x0b, 0x8ef: 0x0b, + 0x8f0: 0x0b, 0x8f1: 0x0b, 0x8f2: 0x0b, 0x8f3: 0x0b, 0x8f4: 0x0b, 0x8f5: 0x0b, 0x8f6: 0x0b, 0x8f7: 0x0b, + 0x8f8: 0x0b, 0x8f9: 0x0b, 0x8fa: 0x0b, 0x8fb: 0x0b, 0x8fc: 0x0b, 0x8fd: 0x0b, 0x8fe: 0x0b, 0x8ff: 0x0b, + // Block 0x24, offset 0x900 + 0x900: 0x0b, 0x901: 0x0b, 0x902: 0x0b, 0x903: 0x0b, 0x904: 0x0b, 0x905: 0x0b, 0x906: 0x0b, 0x907: 0x0b, + 0x908: 0x0b, 0x909: 0x0b, 0x90a: 0x0b, 0x90b: 0x0b, 0x90c: 0x0b, 0x90d: 0x0b, 0x90e: 0x0b, 0x90f: 0x0b, +} + +// idnaSparseOffset: 292 entries, 584 bytes +var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x85, 0x8b, 0x94, 0xa4, 0xb2, 0xbd, 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, 0x225, 0x22f, 0x23b, 0x247, 0x253, 0x25b, 0x260, 0x26d, 0x27e, 0x282, 0x28d, 0x291, 0x29a, 0x2a2, 0x2a8, 0x2ad, 0x2b0, 0x2b4, 0x2ba, 0x2be, 0x2c2, 0x2c6, 0x2cc, 0x2d4, 0x2db, 0x2e6, 0x2f0, 0x2f4, 0x2f7, 0x2fd, 0x301, 0x303, 0x306, 0x308, 0x30b, 0x315, 0x318, 0x327, 0x32b, 0x330, 0x333, 0x337, 0x33c, 0x341, 0x347, 0x358, 0x368, 0x36e, 0x372, 0x381, 0x386, 0x38e, 0x398, 0x3a3, 0x3ab, 0x3bc, 0x3c5, 0x3d5, 0x3e2, 0x3ee, 0x3f3, 0x400, 0x404, 0x409, 0x40b, 0x40d, 0x411, 0x413, 0x417, 0x420, 0x426, 0x42a, 0x43a, 0x444, 0x449, 0x44c, 0x452, 0x459, 0x45e, 0x462, 0x468, 0x46d, 0x476, 0x47b, 0x481, 0x488, 0x48f, 0x496, 0x49a, 0x49f, 0x4a2, 0x4a7, 0x4b3, 0x4b9, 0x4be, 0x4c5, 0x4cd, 0x4d2, 0x4d6, 0x4e6, 0x4ed, 0x4f1, 0x4f5, 0x4fc, 0x4fe, 0x501, 0x504, 0x508, 0x511, 0x515, 0x51d, 0x525, 0x52d, 0x539, 0x545, 0x54b, 0x554, 0x560, 0x567, 0x570, 0x57b, 0x582, 0x591, 0x59e, 0x5ab, 0x5b4, 0x5b8, 0x5c7, 0x5cf, 0x5da, 0x5e3, 0x5e9, 0x5f1, 0x5fa, 0x605, 0x608, 0x614, 0x61d, 0x620, 0x625, 0x62e, 0x633, 0x640, 0x64b, 0x654, 0x65e, 0x661, 0x66b, 0x674, 0x680, 0x68d, 0x69a, 0x6a8, 0x6af, 0x6b3, 0x6b7, 0x6ba, 0x6bf, 0x6c2, 0x6c7, 0x6ca, 0x6d1, 0x6d8, 0x6dc, 0x6e7, 0x6ea, 0x6ed, 0x6f0, 0x6f6, 0x6fc, 0x705, 0x708, 0x70b, 0x70e, 0x711, 0x718, 0x71b, 0x720, 0x72a, 0x72d, 0x731, 0x740, 0x74c, 0x750, 0x755, 0x759, 0x75e, 0x762, 0x767, 0x770, 0x77b, 0x781, 0x787, 0x78d, 0x793, 0x79c, 0x79f, 0x7a2, 0x7a6, 0x7aa, 0x7ae, 0x7b4, 0x7ba, 0x7bf, 0x7c2, 0x7d2, 0x7d9, 0x7dc, 0x7e1, 0x7e5, 0x7eb, 0x7f2, 0x7f6, 0x7fa, 0x803, 0x80a, 0x80f, 0x813, 0x821, 0x824, 0x827, 0x82b, 0x82f, 0x832, 0x842, 0x853, 0x856, 0x85b, 0x85d, 0x85f} + +// idnaSparseValues: 2146 entries, 8584 bytes +var idnaSparseValues = [2146]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: 0x0c}, + {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: 0xbf}, + // Block 0xe, offset 0x85 + {value: 0x0000, lo: 0x05}, + {value: 0x0a08, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, 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: 0x0a}, + {value: 0x3308, lo: 0x80, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x83}, + {value: 0x0008, lo: 0x84, 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 0xbd + {value: 0x0000, lo: 0x0c}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x3308, lo: 0x81, 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: 0x3308, lo: 0xbf, hi: 0xbf}, + // Block 0x3d, offset 0x222 + {value: 0x0000, lo: 0x02}, + {value: 0x3308, lo: 0x80, hi: 0x80}, + {value: 0x0040, lo: 0x81, hi: 0xbf}, + // Block 0x3e, offset 0x225 + {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 0x22f + {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 0x23b + {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 0x247 + {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 0x253 + {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 0x25b + {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 0x260 + {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 0x26d + {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 0x27e + {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 0x282 + {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 0x28d + {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 0x291 + {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 0x29a + {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 0x2a2 + {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 0x2a8 + {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 0x2ad + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xbf}, + // Block 0x4e, offset 0x2b0 + {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 0x2b4 + {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 0x2ba + {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 0x2be + {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 0x2c2 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0x96}, + {value: 0x0018, lo: 0x97, hi: 0xbf}, + // Block 0x53, offset 0x2c6 + {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 0x2cc + {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 0x2d4 + {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 0x2db + {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 0x2e6 + {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 0x2f0 + {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 0x2f4 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x92}, + {value: 0x0040, lo: 0x93, hi: 0xbf}, + // Block 0x5a, offset 0x2f7 + {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 0x2fd + {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 0x301 + {value: 0x0020, lo: 0x01}, + {value: 0x0f35, lo: 0x80, hi: 0xbf}, + // Block 0x5d, offset 0x303 + {value: 0x0020, lo: 0x02}, + {value: 0x1735, lo: 0x80, hi: 0x8f}, + {value: 0x1915, lo: 0x90, hi: 0xbf}, + // Block 0x5e, offset 0x306 + {value: 0x0020, lo: 0x01}, + {value: 0x1f15, lo: 0x80, hi: 0xbf}, + // Block 0x5f, offset 0x308 + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0xbf}, + // Block 0x60, offset 0x30b + {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 0x315 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbe}, + {value: 0x2a69, lo: 0xbf, hi: 0xbf}, + // Block 0x62, offset 0x318 + {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 0x327 + {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 0x32b + {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 0x330 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x66, offset 0x333 + {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 0x337 + {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 0x33c + {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 0x341 + {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 0x347 + {value: 0x0000, lo: 0x10}, + {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: 0xe07d, lo: 0x87, hi: 0x87}, + {value: 0x0008, lo: 0x88, hi: 0x88}, + {value: 0xe01d, lo: 0x89, hi: 0x89}, + {value: 0x0008, lo: 0x8a, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0xb4}, + {value: 0xe01d, lo: 0xb5, hi: 0xb5}, + {value: 0x0008, lo: 0xb6, hi: 0xb7}, + {value: 0x2009, lo: 0xb8, hi: 0xb8}, + {value: 0x6ec1, lo: 0xb9, hi: 0xb9}, + {value: 0x0008, lo: 0xba, hi: 0xbf}, + // Block 0x6b, offset 0x358 + {value: 0x0000, lo: 0x0f}, + {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: 0x3b08, lo: 0xac, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x6c, offset 0x368 + {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 0x36e + {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 0x372 + {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 0x381 + {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 0x386 + {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 0x38e + {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 0x398 + {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 0x3a3 + {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 0x3ab + {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 0x3bc + {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 0x3c5 + {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 0x3d5 + {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 0x3e2 + {value: 0x0000, lo: 0x0b}, + {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: 0xa8}, + {value: 0x6ed9, lo: 0xa9, hi: 0xa9}, + {value: 0x0018, lo: 0xaa, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x44cd, lo: 0xb0, hi: 0xbf}, + // Block 0x79, offset 0x3ee + {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 0x3f3 + {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 0x400 + {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 0x404 + {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 0x409 + {value: 0x0000, lo: 0x01}, + {value: 0x0040, lo: 0x80, hi: 0xbf}, + // Block 0x7e, offset 0x40b + {value: 0x0020, lo: 0x01}, + {value: 0x454d, lo: 0x80, hi: 0xbf}, + // Block 0x7f, offset 0x40d + {value: 0x0020, lo: 0x03}, + {value: 0x4d4d, lo: 0x80, hi: 0x94}, + {value: 0x4b0d, lo: 0x95, hi: 0x95}, + {value: 0x4fed, lo: 0x96, hi: 0xbf}, + // Block 0x80, offset 0x411 + {value: 0x0020, lo: 0x01}, + {value: 0x552d, lo: 0x80, hi: 0xbf}, + // Block 0x81, offset 0x413 + {value: 0x0020, lo: 0x03}, + {value: 0x5d2d, lo: 0x80, hi: 0x84}, + {value: 0x568d, lo: 0x85, hi: 0x85}, + {value: 0x5dcd, lo: 0x86, hi: 0xbf}, + // Block 0x82, offset 0x417 + {value: 0x0020, lo: 0x08}, + {value: 0x6b8d, lo: 0x80, hi: 0x8f}, + {value: 0x6d4d, lo: 0x90, hi: 0x90}, + {value: 0x6d8d, lo: 0x91, hi: 0xab}, + {value: 0x6ef1, 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 0x83, offset 0x420 + {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 0x84, offset 0x426 + {value: 0x0028, lo: 0x03}, + {value: 0x7c71, lo: 0x80, hi: 0x82}, + {value: 0x7c31, lo: 0x83, hi: 0x83}, + {value: 0x7ce9, lo: 0x84, hi: 0xbf}, + // Block 0x85, offset 0x42a + {value: 0x0038, lo: 0x0f}, + {value: 0x9e01, lo: 0x80, hi: 0x83}, + {value: 0x9ea9, lo: 0x84, hi: 0x85}, + {value: 0x9ee1, lo: 0x86, hi: 0x87}, + {value: 0x9f19, lo: 0x88, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x90}, + {value: 0x0040, lo: 0x91, hi: 0x91}, + {value: 0xa0d9, lo: 0x92, hi: 0x97}, + {value: 0xa1f1, lo: 0x98, hi: 0x9c}, + {value: 0xa2d1, lo: 0x9d, hi: 0xb3}, + {value: 0x9d91, lo: 0xb4, hi: 0xb4}, + {value: 0x9e01, lo: 0xb5, hi: 0xb5}, + {value: 0xa7d9, lo: 0xb6, hi: 0xbb}, + {value: 0xa8b9, lo: 0xbc, hi: 0xbc}, + {value: 0xa849, lo: 0xbd, hi: 0xbd}, + {value: 0xa929, lo: 0xbe, hi: 0xbf}, + // Block 0x86, offset 0x43a + {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 0x87, offset 0x444 + {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 0x88, offset 0x449 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x89, offset 0x44c + {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 0x8a, offset 0x452 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x8e}, + {value: 0x0040, lo: 0x8f, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x8b, offset 0x459 + {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 0x8c, offset 0x45e + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9c}, + {value: 0x0040, lo: 0x9d, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x8d, offset 0x462 + {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 0x8e, offset 0x468 + {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 0x8f, offset 0x46d + {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 0x90, offset 0x476 + {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 0x91, offset 0x47b + {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 0x92, offset 0x481 + {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 0x93, offset 0x488 + {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 0x94, offset 0x48f + {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 0x95, offset 0x496 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa7}, + {value: 0x0040, lo: 0xa8, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x96, offset 0x49a + {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 0x97, offset 0x49f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x98, offset 0x4a2 + {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 0x99, offset 0x4a7 + {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 0x9a, offset 0x4b3 + {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 0x9b, offset 0x4b9 + {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 0x9c, offset 0x4be + {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 0x9d, offset 0x4c5 + {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 0x9e, offset 0x4cd + {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 0x9f, offset 0x4d2 + {value: 0x0000, lo: 0x03}, + {value: 0x0818, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0x91}, + {value: 0x0818, lo: 0x92, hi: 0xbf}, + // Block 0xa0, offset 0x4d6 + {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 0xa1, offset 0x4e6 + {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 0xa2, offset 0x4ed + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0x9c}, + {value: 0x0818, lo: 0x9d, hi: 0x9f}, + {value: 0x0040, lo: 0xa0, hi: 0xbf}, + // Block 0xa3, offset 0x4f1 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xb8}, + {value: 0x0018, lo: 0xb9, hi: 0xbf}, + // Block 0xa4, offset 0x4f5 + {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 0xa5, offset 0x4fc + {value: 0x0000, lo: 0x01}, + {value: 0x0808, lo: 0x80, hi: 0xbf}, + // Block 0xa6, offset 0x4fe + {value: 0x0000, lo: 0x02}, + {value: 0x0808, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xa7, offset 0x501 + {value: 0x0000, lo: 0x02}, + {value: 0x03dd, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xbf}, + // Block 0xa8, offset 0x504 + {value: 0x0000, lo: 0x03}, + {value: 0x0808, lo: 0x80, hi: 0xb2}, + {value: 0x0040, lo: 0xb3, hi: 0xb9}, + {value: 0x0818, lo: 0xba, hi: 0xbf}, + // Block 0xa9, offset 0x508 + {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 0xaa, offset 0x511 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0818, lo: 0xa0, hi: 0xbe}, + {value: 0x0040, lo: 0xbf, hi: 0xbf}, + // Block 0xab, offset 0x515 + {value: 0x0000, lo: 0x07}, + {value: 0x0808, lo: 0x80, hi: 0xa9}, + {value: 0x0040, lo: 0xaa, hi: 0xaa}, + {value: 0x3308, lo: 0xab, hi: 0xac}, + {value: 0x0818, lo: 0xad, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0808, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xac, offset 0x51d + {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 0xad, offset 0x525 + {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 0xae, offset 0x52d + {value: 0x0000, lo: 0x0b}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0a08, lo: 0xb0, hi: 0xb0}, + {value: 0x0808, lo: 0xb1, hi: 0xb1}, + {value: 0x0a08, lo: 0xb2, hi: 0xb3}, + {value: 0x0c08, lo: 0xb4, hi: 0xb6}, + {value: 0x0808, lo: 0xb7, hi: 0xb7}, + {value: 0x0a08, lo: 0xb8, hi: 0xb8}, + {value: 0x0c08, lo: 0xb9, hi: 0xba}, + {value: 0x0a08, lo: 0xbb, hi: 0xbc}, + {value: 0x0c08, lo: 0xbd, hi: 0xbd}, + {value: 0x0a08, lo: 0xbe, hi: 0xbf}, + // Block 0xaf, offset 0x539 + {value: 0x0000, lo: 0x0b}, + {value: 0x0808, lo: 0x80, hi: 0x80}, + {value: 0x0a08, lo: 0x81, hi: 0x81}, + {value: 0x0c08, lo: 0x82, hi: 0x83}, + {value: 0x0a08, lo: 0x84, hi: 0x84}, + {value: 0x0818, lo: 0x85, hi: 0x88}, + {value: 0x0c18, lo: 0x89, hi: 0x89}, + {value: 0x0a18, lo: 0x8a, hi: 0x8a}, + {value: 0x0918, lo: 0x8b, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x9f}, + {value: 0x0808, lo: 0xa0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0xb0, offset 0x545 + {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 0xb1, offset 0x54b + {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 0xb2, offset 0x554 + {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 0xb3, offset 0x560 + {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 0xb4, offset 0x567 + {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 0xb5, offset 0x570 + {value: 0x0000, lo: 0x0a}, + {value: 0x0018, lo: 0x80, hi: 0x83}, + {value: 0x0008, lo: 0x84, hi: 0x84}, + {value: 0x3008, lo: 0x85, hi: 0x86}, + {value: 0x0008, lo: 0x87, hi: 0x87}, + {value: 0x0040, lo: 0x88, 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 0xb6, offset 0x57b + {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 0xb7, offset 0x582 + {value: 0x0000, lo: 0x0e}, + {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: 0x3008, lo: 0x8e, hi: 0x8e}, + {value: 0x3308, lo: 0x8f, 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 0xb8, offset 0x591 + {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 0xb9, offset 0x59e + {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 0xba, offset 0x5ab + {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 0xbb, offset 0x5b4 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x3008, lo: 0xb5, hi: 0xb7}, + {value: 0x3308, lo: 0xb8, hi: 0xbf}, + // Block 0xbc, offset 0x5b8 + {value: 0x0000, lo: 0x0e}, + {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: 0x0018, lo: 0x9a, 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: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xbf}, + // Block 0xbd, offset 0x5c7 + {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 0xbe, offset 0x5cf + {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 0xbf, offset 0x5da + {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 0xc0, offset 0x5e3 + {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 0xc1, offset 0x5e9 + {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 0xc2, offset 0x5f1 + {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 0xc3, offset 0x5fa + {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 0xc4, offset 0x605 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x89}, + {value: 0x0040, lo: 0x8a, hi: 0xbf}, + // Block 0xc5, offset 0x608 + {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 0xc6, offset 0x614 + {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 0xc7, offset 0x61d + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x049d, lo: 0xa0, hi: 0xbf}, + // Block 0xc8, offset 0x620 + {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 0xc9, offset 0x625 + {value: 0x0000, lo: 0x08}, + {value: 0x3008, lo: 0x80, hi: 0x80}, + {value: 0x0008, lo: 0x81, hi: 0x81}, + {value: 0x3008, lo: 0x82, hi: 0x82}, + {value: 0x3308, lo: 0x83, hi: 0x83}, + {value: 0x0018, lo: 0x84, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0008, lo: 0x90, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xca, offset 0x62e + {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 0xcb, offset 0x633 + {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 0xcc, offset 0x640 + {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 0xcd, offset 0x64b + {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 0xce, offset 0x654 + {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 0xcf, offset 0x65e + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xbf}, + // Block 0xd0, offset 0x661 + {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 0xd1, offset 0x66b + {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 0xd2, offset 0x674 + {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 0xd3, offset 0x680 + {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 0xd4, offset 0x68d + {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 0xd5, offset 0x69a + {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 0xd6, offset 0x6a8 + {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 0xd7, offset 0x6af + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xb0}, + {value: 0x0040, lo: 0xb1, hi: 0xbf}, + // Block 0xd8, offset 0x6b3 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbe}, + {value: 0x0018, lo: 0xbf, hi: 0xbf}, + // Block 0xd9, offset 0x6b7 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x99}, + {value: 0x0040, lo: 0x9a, hi: 0xbf}, + // Block 0xda, offset 0x6ba + {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 0xdb, offset 0x6bf + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x83}, + {value: 0x0040, lo: 0x84, hi: 0xbf}, + // Block 0xdc, offset 0x6c2 + {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 0xdd, offset 0x6c7 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0xbf}, + // Block 0xde, offset 0x6ca + {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 0xdf, offset 0x6d1 + {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 0xe0, offset 0x6d8 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xaf}, + {value: 0x3308, lo: 0xb0, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xbf}, + // Block 0xe1, offset 0x6dc + {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 0xe2, offset 0x6e7 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8f}, + {value: 0x0040, lo: 0x90, hi: 0xbf}, + // Block 0xe3, offset 0x6ea + {value: 0x0000, lo: 0x02}, + {value: 0xe105, lo: 0x80, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0xe4, offset 0x6ed + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0x9a}, + {value: 0x0040, lo: 0x9b, hi: 0xbf}, + // Block 0xe5, offset 0x6f0 + {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 0xe6, offset 0x6f6 + {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 0xe7, offset 0x6fc + {value: 0x0000, lo: 0x08}, + {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: 0x3308, lo: 0xa4, hi: 0xa4}, + {value: 0x0040, lo: 0xa5, hi: 0xaf}, + {value: 0x3008, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0xe8, offset 0x705 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb7}, + {value: 0x0040, lo: 0xb8, hi: 0xbf}, + // Block 0xe9, offset 0x708 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x95}, + {value: 0x0040, lo: 0x96, hi: 0xbf}, + // Block 0xea, offset 0x70b + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0xbf}, + // Block 0xeb, offset 0x70e + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x9e}, + {value: 0x0040, lo: 0x9f, hi: 0xbf}, + // Block 0xec, offset 0x711 + {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 0xed, offset 0x718 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xbb}, + {value: 0x0040, lo: 0xbc, hi: 0xbf}, + // Block 0xee, offset 0x71b + {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 0xef, offset 0x720 + {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 0xf0, offset 0x72a + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb5}, + {value: 0x0040, lo: 0xb6, hi: 0xbf}, + // Block 0xf1, offset 0x72d + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xa6}, + {value: 0x0040, lo: 0xa7, hi: 0xa8}, + {value: 0x0018, lo: 0xa9, hi: 0xbf}, + // Block 0xf2, offset 0x731 + {value: 0x0000, lo: 0x0e}, + {value: 0x0018, lo: 0x80, hi: 0x9d}, + {value: 0xb609, lo: 0x9e, hi: 0x9e}, + {value: 0xb651, lo: 0x9f, hi: 0x9f}, + {value: 0xb699, lo: 0xa0, hi: 0xa0}, + {value: 0xb701, lo: 0xa1, hi: 0xa1}, + {value: 0xb769, lo: 0xa2, hi: 0xa2}, + {value: 0xb7d1, lo: 0xa3, hi: 0xa3}, + {value: 0xb839, 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 0xf3, offset 0x740 + {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: 0xb8a1, lo: 0xbb, hi: 0xbb}, + {value: 0xb8e9, lo: 0xbc, hi: 0xbc}, + {value: 0xb931, lo: 0xbd, hi: 0xbd}, + {value: 0xb999, lo: 0xbe, hi: 0xbe}, + {value: 0xba01, lo: 0xbf, hi: 0xbf}, + // Block 0xf4, offset 0x74c + {value: 0x0000, lo: 0x03}, + {value: 0xba69, lo: 0x80, hi: 0x80}, + {value: 0x0018, lo: 0x81, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xbf}, + // Block 0xf5, offset 0x750 + {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 0xf6, offset 0x755 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0xf7, offset 0x759 + {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 0xf8, offset 0x75e + {value: 0x0000, lo: 0x03}, + {value: 0x3308, lo: 0x80, hi: 0xb6}, + {value: 0x0018, lo: 0xb7, hi: 0xba}, + {value: 0x3308, lo: 0xbb, hi: 0xbf}, + // Block 0xf9, offset 0x762 + {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 0xfa, offset 0x767 + {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 0xfb, offset 0x770 + {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 0xfc, offset 0x77b + {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 0xfd, offset 0x781 + {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 0xfe, offset 0x787 + {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 0xff, offset 0x78d + {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 0x100, offset 0x793 + {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 0x101, offset 0x79c + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xb0}, + {value: 0x0818, lo: 0xb1, hi: 0xbf}, + // Block 0x102, offset 0x79f + {value: 0x0000, lo: 0x02}, + {value: 0x0818, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x103, offset 0x7a2 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0x80}, + {value: 0x0818, lo: 0x81, hi: 0xbd}, + {value: 0x0040, lo: 0xbe, hi: 0xbf}, + // Block 0x104, offset 0x7a6 + {value: 0x0000, lo: 0x03}, + {value: 0x0040, lo: 0x80, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0x105, offset 0x7aa + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xab}, + {value: 0x0040, lo: 0xac, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbf}, + // Block 0x106, offset 0x7ae + {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 0x107, offset 0x7b4 + {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 0x108, offset 0x7ba + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x8f}, + {value: 0xc229, lo: 0x90, hi: 0x90}, + {value: 0x0018, lo: 0x91, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xbf}, + // Block 0x109, offset 0x7bf + {value: 0x0000, lo: 0x02}, + {value: 0x0040, lo: 0x80, hi: 0xa5}, + {value: 0x0018, lo: 0xa6, hi: 0xbf}, + // Block 0x10a, offset 0x7c2 + {value: 0x0000, lo: 0x0f}, + {value: 0xc851, lo: 0x80, hi: 0x80}, + {value: 0xc8a1, lo: 0x81, hi: 0x81}, + {value: 0xc8f1, lo: 0x82, hi: 0x82}, + {value: 0xc941, lo: 0x83, hi: 0x83}, + {value: 0xc991, lo: 0x84, hi: 0x84}, + {value: 0xc9e1, lo: 0x85, hi: 0x85}, + {value: 0xca31, lo: 0x86, hi: 0x86}, + {value: 0xca81, lo: 0x87, hi: 0x87}, + {value: 0xcad1, lo: 0x88, hi: 0x88}, + {value: 0x0040, lo: 0x89, hi: 0x8f}, + {value: 0xcb21, lo: 0x90, hi: 0x90}, + {value: 0xcb41, lo: 0x91, hi: 0x91}, + {value: 0x0040, lo: 0x92, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xa5}, + {value: 0x0040, lo: 0xa6, hi: 0xbf}, + // Block 0x10b, offset 0x7d2 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x97}, + {value: 0x0040, lo: 0x98, hi: 0x9f}, + {value: 0x0018, lo: 0xa0, hi: 0xac}, + {value: 0x0040, lo: 0xad, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xbc}, + {value: 0x0040, lo: 0xbd, hi: 0xbf}, + // Block 0x10c, offset 0x7d9 + {value: 0x0000, lo: 0x02}, + {value: 0x0018, lo: 0x80, hi: 0xb3}, + {value: 0x0040, lo: 0xb4, hi: 0xbf}, + // Block 0x10d, offset 0x7dc + {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 0x10e, offset 0x7e1 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xbf}, + // Block 0x10f, offset 0x7e5 + {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 0x110, offset 0x7eb + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x87}, + {value: 0x0040, lo: 0x88, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xad}, + {value: 0x0040, lo: 0xae, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb1}, + {value: 0x0040, lo: 0xb2, hi: 0xbf}, + // Block 0x111, offset 0x7f2 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0xb8}, + {value: 0x0040, lo: 0xb9, hi: 0xb9}, + {value: 0x0018, lo: 0xba, hi: 0xbf}, + // Block 0x112, offset 0x7f6 + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x8b}, + {value: 0x0040, lo: 0x8c, hi: 0x8c}, + {value: 0x0018, lo: 0x8d, hi: 0xbf}, + // Block 0x113, offset 0x7fa + {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: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xb7}, + {value: 0x0018, lo: 0xb8, hi: 0xba}, + {value: 0x0040, lo: 0xbb, hi: 0xbf}, + // Block 0x114, offset 0x803 + {value: 0x0000, lo: 0x06}, + {value: 0x0018, lo: 0x80, hi: 0x86}, + {value: 0x0040, lo: 0x87, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0xa8}, + {value: 0x0040, lo: 0xa9, hi: 0xaf}, + {value: 0x0018, lo: 0xb0, hi: 0xb6}, + {value: 0x0040, lo: 0xb7, hi: 0xbf}, + // Block 0x115, offset 0x80a + {value: 0x0000, lo: 0x04}, + {value: 0x0018, lo: 0x80, hi: 0x82}, + {value: 0x0040, lo: 0x83, hi: 0x8f}, + {value: 0x0018, lo: 0x90, hi: 0x96}, + {value: 0x0040, lo: 0x97, hi: 0xbf}, + // Block 0x116, offset 0x80f + {value: 0x0000, lo: 0x03}, + {value: 0x0018, lo: 0x80, hi: 0x92}, + {value: 0x0040, lo: 0x93, hi: 0x93}, + {value: 0x0018, lo: 0x94, hi: 0xbf}, + // Block 0x117, offset 0x813 + {value: 0x0000, lo: 0x0d}, + {value: 0x0018, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0xaf}, + {value: 0x1f41, lo: 0xb0, hi: 0xb0}, + {value: 0x00c9, lo: 0xb1, hi: 0xb1}, + {value: 0x0069, lo: 0xb2, hi: 0xb2}, + {value: 0x0079, lo: 0xb3, hi: 0xb3}, + {value: 0x1f51, lo: 0xb4, hi: 0xb4}, + {value: 0x1f61, lo: 0xb5, hi: 0xb5}, + {value: 0x1f71, lo: 0xb6, hi: 0xb6}, + {value: 0x1f81, lo: 0xb7, hi: 0xb7}, + {value: 0x1f91, lo: 0xb8, hi: 0xb8}, + {value: 0x1fa1, lo: 0xb9, hi: 0xb9}, + {value: 0x0040, lo: 0xba, hi: 0xbf}, + // Block 0x118, offset 0x821 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0xbf}, + // Block 0x119, offset 0x824 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xb4}, + {value: 0x0040, lo: 0xb5, hi: 0xbf}, + // Block 0x11a, offset 0x827 + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0x9d}, + {value: 0x0040, lo: 0x9e, hi: 0x9f}, + {value: 0x0008, lo: 0xa0, hi: 0xbf}, + // Block 0x11b, offset 0x82b + {value: 0x0000, lo: 0x03}, + {value: 0x0008, lo: 0x80, hi: 0xa1}, + {value: 0x0040, lo: 0xa2, hi: 0xaf}, + {value: 0x0008, lo: 0xb0, hi: 0xbf}, + // Block 0x11c, offset 0x82f + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0xa0}, + {value: 0x0040, lo: 0xa1, hi: 0xbf}, + // Block 0x11d, offset 0x832 + {value: 0x0020, lo: 0x0f}, + {value: 0xdf21, lo: 0x80, hi: 0x89}, + {value: 0x8e35, lo: 0x8a, hi: 0x8a}, + {value: 0xe061, lo: 0x8b, hi: 0x9c}, + {value: 0x8e55, lo: 0x9d, hi: 0x9d}, + {value: 0xe2a1, lo: 0x9e, hi: 0xa2}, + {value: 0x8e75, lo: 0xa3, hi: 0xa3}, + {value: 0xe341, lo: 0xa4, hi: 0xab}, + {value: 0x7f0d, lo: 0xac, hi: 0xac}, + {value: 0xe441, lo: 0xad, hi: 0xaf}, + {value: 0x8e95, lo: 0xb0, hi: 0xb0}, + {value: 0xe4a1, lo: 0xb1, hi: 0xb6}, + {value: 0x8eb5, lo: 0xb7, hi: 0xb9}, + {value: 0xe561, lo: 0xba, hi: 0xba}, + {value: 0x8f15, lo: 0xbb, hi: 0xbb}, + {value: 0xe581, lo: 0xbc, hi: 0xbf}, + // Block 0x11e, offset 0x842 + {value: 0x0020, lo: 0x10}, + {value: 0x93b5, lo: 0x80, hi: 0x80}, + {value: 0xf101, lo: 0x81, hi: 0x86}, + {value: 0x93d5, lo: 0x87, hi: 0x8a}, + {value: 0xda61, lo: 0x8b, hi: 0x8b}, + {value: 0xf1c1, lo: 0x8c, hi: 0x96}, + {value: 0x9455, lo: 0x97, hi: 0x97}, + {value: 0xf321, lo: 0x98, hi: 0xa3}, + {value: 0x9475, lo: 0xa4, hi: 0xa6}, + {value: 0xf4a1, lo: 0xa7, hi: 0xaa}, + {value: 0x94d5, lo: 0xab, hi: 0xab}, + {value: 0xf521, lo: 0xac, hi: 0xac}, + {value: 0x94f5, lo: 0xad, hi: 0xad}, + {value: 0xf541, lo: 0xae, hi: 0xaf}, + {value: 0x9515, lo: 0xb0, hi: 0xb1}, + {value: 0xf581, lo: 0xb2, hi: 0xbe}, + {value: 0x2040, lo: 0xbf, hi: 0xbf}, + // Block 0x11f, offset 0x853 + {value: 0x0000, lo: 0x02}, + {value: 0x0008, lo: 0x80, hi: 0x8a}, + {value: 0x0040, lo: 0x8b, hi: 0xbf}, + // Block 0x120, offset 0x856 + {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 0x121, offset 0x85b + {value: 0x0000, lo: 0x01}, + {value: 0x0340, lo: 0x80, hi: 0xbf}, + // Block 0x122, offset 0x85d + {value: 0x0000, lo: 0x01}, + {value: 0x33c0, lo: 0x80, hi: 0xbf}, + // Block 0x123, offset 0x85f + {value: 0x0000, lo: 0x02}, + {value: 0x33c0, lo: 0x80, hi: 0xaf}, + {value: 0x0040, lo: 0xb0, hi: 0xbf}, +} + +// Total table size 43370 bytes (42KiB); checksum: EBD909C0 diff --git a/libgo/go/golang.org/x/net/nettest/nettest.go b/libgo/go/golang.org/x/net/nettest/nettest.go index a402a46bb33..83ba858e249 100644 --- a/libgo/go/golang.org/x/net/nettest/nettest.go +++ b/libgo/go/golang.org/x/net/nettest/nettest.go @@ -97,7 +97,7 @@ func TestableNetwork(network string) bool { switch runtime.GOOS { case "android", "fuchsia", "hurd", "js", "nacl", "plan9", "windows": return false - case "darwin": + case "darwin", "ios": // iOS doesn't support it. if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { return false @@ -118,7 +118,7 @@ func TestableNetwork(network string) bool { return false case "aix": return unixStrmDgramEnabled() - case "darwin": + case "darwin", "ios": // iOS does not support unix, unixgram. if runtime.GOARCH == "arm" || runtime.GOARCH == "arm64" { return false @@ -126,7 +126,7 @@ func TestableNetwork(network string) bool { } case "unixpacket": switch runtime.GOOS { - case "aix", "android", "fuchsia", "hurd", "darwin", "js", "nacl", "plan9", "windows": + case "aix", "android", "fuchsia", "hurd", "darwin", "ios", "js", "nacl", "plan9", "windows", "zos": return false case "netbsd": // It passes on amd64 at least. 386 fails diff --git a/libgo/go/golang.org/x/net/nettest/nettest_stub.go b/libgo/go/golang.org/x/net/nettest/nettest_stub.go index 2bb8c05762c..22c2461c1c0 100644 --- a/libgo/go/golang.org/x/net/nettest/nettest_stub.go +++ b/libgo/go/golang.org/x/net/nettest/nettest_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,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows +// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows,!zos package nettest diff --git a/libgo/go/golang.org/x/net/nettest/nettest_unix.go b/libgo/go/golang.org/x/net/nettest/nettest_unix.go index afff744e8fd..c1b13593fe7 100644 --- a/libgo/go/golang.org/x/net/nettest/nettest_unix.go +++ b/libgo/go/golang.org/x/net/nettest/nettest_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 linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos package nettest diff --git a/libgo/go/golang.org/x/net/route/address.go b/libgo/go/golang.org/x/net/route/address.go index e3125a473bc..3c2fe15a970 100644 --- a/libgo/go/golang.org/x/net/route/address.go +++ b/libgo/go/golang.org/x/net/route/address.go @@ -221,7 +221,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) { // to make the tuple to be conformed with // the routing message boundary l := int(b[0]) - if runtime.GOOS == "darwin" { + if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { // On Darwin, an address in the kernel form is also // used as a message filler. if l == 0 || len(b) > roundup(l) { 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 a7d3864646b..b83add668e7 100644 --- a/libgo/go/golang.org/x/net/route/route_classic.go +++ b/libgo/go/golang.org/x/net/route/route_classic.go @@ -17,7 +17,7 @@ func (m *RouteMessage) marshal() ([]byte, error) { return nil, errUnsupportedMessage } l := w.bodyOff + addrsSpace(m.Addrs) - if runtime.GOOS == "darwin" { + if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { // Fix stray pointer writes on macOS. // See golang.org/issue/22456. l += 1024 diff --git a/libgo/go/golang.org/x/sys/cpu/byteorder.go b/libgo/go/golang.org/x/sys/cpu/byteorder.go index ff3eb5b4481..dcbb14ef35a 100644 --- a/libgo/go/golang.org/x/sys/cpu/byteorder.go +++ b/libgo/go/golang.org/x/sys/cpu/byteorder.go @@ -39,8 +39,8 @@ func (bigEndian) Uint64(b []byte) uint64 { uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 } -// hostByteOrder returns binary.LittleEndian on little-endian machines and -// binary.BigEndian on big-endian machines. +// hostByteOrder returns littleEndian on little-endian machines and +// bigEndian on big-endian machines. func hostByteOrder() byteOrder { switch runtime.GOARCH { case "386", "amd64", "amd64p32", diff --git a/libgo/go/golang.org/x/sys/cpu/cpu.go b/libgo/go/golang.org/x/sys/cpu/cpu.go index e44deb75746..f77701fe868 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu.go @@ -6,6 +6,11 @@ // various CPU architectures. package cpu +import ( + "os" + "strings" +) + // Initialized reports whether the CPU features were initialized. // // For some GOOS/GOARCH combinations initialization of the CPU features depends @@ -24,26 +29,46 @@ type CacheLinePad struct{ _ [cacheLineSize]byte } // and HasAVX2 are only set if the OS supports XMM and YMM // registers in addition to the CPUID feature bit being set. var X86 struct { - _ CacheLinePad - HasAES bool // AES hardware implementation (AES NI) - HasADX bool // Multi-precision add-carry instruction extensions - HasAVX bool // Advanced vector extension - HasAVX2 bool // Advanced vector extension 2 - HasBMI1 bool // Bit manipulation instruction set 1 - HasBMI2 bool // Bit manipulation instruction set 2 - HasERMS bool // Enhanced REP for MOVSB and STOSB - HasFMA bool // Fused-multiply-add instructions - HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers. - HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM - HasPOPCNT bool // Hamming weight instruction POPCNT. - HasRDRAND bool // RDRAND instruction (on-chip random number generator) - HasRDSEED bool // RDSEED instruction (on-chip random number generator) - HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64) - HasSSE3 bool // Streaming SIMD extension 3 - HasSSSE3 bool // Supplemental streaming SIMD extension 3 - HasSSE41 bool // Streaming SIMD extension 4 and 4.1 - HasSSE42 bool // Streaming SIMD extension 4 and 4.2 - _ CacheLinePad + _ CacheLinePad + HasAES bool // AES hardware implementation (AES NI) + HasADX bool // Multi-precision add-carry instruction extensions + HasAVX bool // Advanced vector extension + HasAVX2 bool // Advanced vector extension 2 + HasAVX512 bool // Advanced vector extension 512 + HasAVX512F bool // Advanced vector extension 512 Foundation Instructions + HasAVX512CD bool // Advanced vector extension 512 Conflict Detection Instructions + HasAVX512ER bool // Advanced vector extension 512 Exponential and Reciprocal Instructions + HasAVX512PF bool // Advanced vector extension 512 Prefetch Instructions Instructions + HasAVX512VL bool // Advanced vector extension 512 Vector Length Extensions + HasAVX512BW bool // Advanced vector extension 512 Byte and Word Instructions + HasAVX512DQ bool // Advanced vector extension 512 Doubleword and Quadword Instructions + HasAVX512IFMA bool // Advanced vector extension 512 Integer Fused Multiply Add + HasAVX512VBMI bool // Advanced vector extension 512 Vector Byte Manipulation Instructions + HasAVX5124VNNIW bool // Advanced vector extension 512 Vector Neural Network Instructions Word variable precision + HasAVX5124FMAPS bool // Advanced vector extension 512 Fused Multiply Accumulation Packed Single precision + HasAVX512VPOPCNTDQ bool // Advanced vector extension 512 Double and quad word population count instructions + HasAVX512VPCLMULQDQ bool // Advanced vector extension 512 Vector carry-less multiply operations + HasAVX512VNNI bool // Advanced vector extension 512 Vector Neural Network Instructions + HasAVX512GFNI bool // Advanced vector extension 512 Galois field New Instructions + HasAVX512VAES bool // Advanced vector extension 512 Vector AES instructions + HasAVX512VBMI2 bool // Advanced vector extension 512 Vector Byte Manipulation Instructions 2 + HasAVX512BITALG bool // Advanced vector extension 512 Bit Algorithms + HasAVX512BF16 bool // Advanced vector extension 512 BFloat16 Instructions + HasBMI1 bool // Bit manipulation instruction set 1 + HasBMI2 bool // Bit manipulation instruction set 2 + HasERMS bool // Enhanced REP for MOVSB and STOSB + HasFMA bool // Fused-multiply-add instructions + HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers. + HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM + HasPOPCNT bool // Hamming weight instruction POPCNT. + HasRDRAND bool // RDRAND instruction (on-chip random number generator) + HasRDSEED bool // RDSEED instruction (on-chip random number generator) + HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64) + HasSSE3 bool // Streaming SIMD extension 3 + HasSSSE3 bool // Supplemental streaming SIMD extension 3 + HasSSE41 bool // Streaming SIMD extension 4 and 4.1 + HasSSE42 bool // Streaming SIMD extension 4 and 4.2 + _ CacheLinePad } // ARM64 contains the supported CPU features of the @@ -169,3 +194,94 @@ var S390X struct { HasVXE bool // vector-enhancements facility 1 _ CacheLinePad } + +func init() { + archInit() + initOptions() + processOptions() +} + +// options contains the cpu debug options that can be used in GODEBUG. +// Options are arch dependent and are added by the arch specific initOptions functions. +// Features that are mandatory for the specific GOARCH should have the Required field set +// (e.g. SSE2 on amd64). +var options []option + +// Option names should be lower case. e.g. avx instead of AVX. +type option struct { + Name string + Feature *bool + Specified bool // whether feature value was specified in GODEBUG + Enable bool // whether feature should be enabled + Required bool // whether feature is mandatory and can not be disabled +} + +func processOptions() { + env := os.Getenv("GODEBUG") +field: + for env != "" { + field := "" + i := strings.IndexByte(env, ',') + if i < 0 { + field, env = env, "" + } else { + field, env = env[:i], env[i+1:] + } + if len(field) < 4 || field[:4] != "cpu." { + continue + } + i = strings.IndexByte(field, '=') + if i < 0 { + print("GODEBUG sys/cpu: no value specified for \"", field, "\"\n") + continue + } + key, value := field[4:i], field[i+1:] // e.g. "SSE2", "on" + + var enable bool + switch value { + case "on": + enable = true + case "off": + enable = false + default: + print("GODEBUG sys/cpu: value \"", value, "\" not supported for cpu option \"", key, "\"\n") + continue field + } + + if key == "all" { + for i := range options { + options[i].Specified = true + options[i].Enable = enable || options[i].Required + } + continue field + } + + for i := range options { + if options[i].Name == key { + options[i].Specified = true + options[i].Enable = enable + continue field + } + } + + print("GODEBUG sys/cpu: unknown cpu feature \"", key, "\"\n") + } + + for _, o := range options { + if !o.Specified { + continue + } + + if o.Enable && !*o.Feature { + print("GODEBUG sys/cpu: can not enable \"", o.Name, "\", missing CPU support\n") + continue + } + + if !o.Enable && o.Required { + print("GODEBUG sys/cpu: can not disable \"", o.Name, "\", required CPU feature\n") + continue + } + + *o.Feature = o.Enable + } +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_aix.go b/libgo/go/golang.org/x/sys/cpu/cpu_aix.go index 02d03129e50..464a209cf59 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_aix.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_aix.go @@ -13,7 +13,7 @@ const ( _IMPL_POWER9 = 0x20000 ) -func init() { +func archInit() { impl := getsystemcfg(_SC_IMPL) if impl&_IMPL_POWER8 != 0 { PPC64.IsPOWER8 = true diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_arm.go b/libgo/go/golang.org/x/sys/cpu/cpu_arm.go index bb0b91577cf..64668c9f574 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_arm.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_arm.go @@ -38,3 +38,36 @@ const ( hwcap2_SHA2 = 1 << 3 hwcap2_CRC32 = 1 << 4 ) + +func initOptions() { + options = []option{ + {Name: "pmull", Feature: &ARM.HasPMULL}, + {Name: "sha1", Feature: &ARM.HasSHA1}, + {Name: "sha2", Feature: &ARM.HasSHA2}, + {Name: "swp", Feature: &ARM.HasSWP}, + {Name: "thumb", Feature: &ARM.HasTHUMB}, + {Name: "thumbee", Feature: &ARM.HasTHUMBEE}, + {Name: "tls", Feature: &ARM.HasTLS}, + {Name: "vfp", Feature: &ARM.HasVFP}, + {Name: "vfpd32", Feature: &ARM.HasVFPD32}, + {Name: "vfpv3", Feature: &ARM.HasVFPv3}, + {Name: "vfpv3d16", Feature: &ARM.HasVFPv3D16}, + {Name: "vfpv4", Feature: &ARM.HasVFPv4}, + {Name: "half", Feature: &ARM.HasHALF}, + {Name: "26bit", Feature: &ARM.Has26BIT}, + {Name: "fastmul", Feature: &ARM.HasFASTMUL}, + {Name: "fpa", Feature: &ARM.HasFPA}, + {Name: "edsp", Feature: &ARM.HasEDSP}, + {Name: "java", Feature: &ARM.HasJAVA}, + {Name: "iwmmxt", Feature: &ARM.HasIWMMXT}, + {Name: "crunch", Feature: &ARM.HasCRUNCH}, + {Name: "neon", Feature: &ARM.HasNEON}, + {Name: "idivt", Feature: &ARM.HasIDIVT}, + {Name: "idiva", Feature: &ARM.HasIDIVA}, + {Name: "lpae", Feature: &ARM.HasLPAE}, + {Name: "evtstrm", Feature: &ARM.HasEVTSTRM}, + {Name: "aes", Feature: &ARM.HasAES}, + {Name: "crc32", Feature: &ARM.HasCRC32}, + } + +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_arm64.go index 74df5c6ff83..af6d03994e8 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_arm64.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_arm64.go @@ -8,27 +8,65 @@ import "runtime" // const cacheLineSize = 64 -func init() { +func initOptions() { + options = []option{ + {Name: "fp", Feature: &ARM64.HasFP}, + {Name: "asimd", Feature: &ARM64.HasASIMD}, + {Name: "evstrm", Feature: &ARM64.HasEVTSTRM}, + {Name: "aes", Feature: &ARM64.HasAES}, + {Name: "fphp", Feature: &ARM64.HasFPHP}, + {Name: "jscvt", Feature: &ARM64.HasJSCVT}, + {Name: "lrcpc", Feature: &ARM64.HasLRCPC}, + {Name: "pmull", Feature: &ARM64.HasPMULL}, + {Name: "sha1", Feature: &ARM64.HasSHA1}, + {Name: "sha2", Feature: &ARM64.HasSHA2}, + {Name: "sha3", Feature: &ARM64.HasSHA3}, + {Name: "sha512", Feature: &ARM64.HasSHA512}, + {Name: "sm3", Feature: &ARM64.HasSM3}, + {Name: "sm4", Feature: &ARM64.HasSM4}, + {Name: "sve", Feature: &ARM64.HasSVE}, + {Name: "crc32", Feature: &ARM64.HasCRC32}, + {Name: "atomics", Feature: &ARM64.HasATOMICS}, + {Name: "asimdhp", Feature: &ARM64.HasASIMDHP}, + {Name: "cpuid", Feature: &ARM64.HasCPUID}, + {Name: "asimrdm", Feature: &ARM64.HasASIMDRDM}, + {Name: "fcma", Feature: &ARM64.HasFCMA}, + {Name: "dcpop", Feature: &ARM64.HasDCPOP}, + {Name: "asimddp", Feature: &ARM64.HasASIMDDP}, + {Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM}, + } +} + +func archInit() { switch runtime.GOOS { - case "android", "darwin": - // Android and iOS don't seem to allow reading these registers. - // Fake the minimal features expected by - // TestARM64minimalFeatures. - ARM64.HasASIMD = true - ARM64.HasFP = true - case "linux": + case "freebsd": + readARM64Registers() + case "linux", "netbsd": doinit() default: - readARM64Registers() + // Most platforms don't seem to allow reading these registers. + // + // OpenBSD: + // See https://golang.org/issue/31746 + setMinimalFeatures() } } +// setMinimalFeatures fakes the minimal ARM64 features expected by +// TestARM64minimalFeatures. +func setMinimalFeatures() { + ARM64.HasASIMD = true + ARM64.HasFP = true +} + func readARM64Registers() { Initialized = true - // ID_AA64ISAR0_EL1 - isar0 := getisar0() + parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0()) +} +func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { + // ID_AA64ISAR0_EL1 switch extractBits(isar0, 4, 7) { case 1: ARM64.HasAES = true @@ -86,8 +124,6 @@ func readARM64Registers() { } // ID_AA64ISAR1_EL1 - isar1 := getisar1() - switch extractBits(isar1, 0, 3) { case 1: ARM64.HasDCPOP = true @@ -109,8 +145,6 @@ func readARM64Registers() { } // ID_AA64PFR0_EL1 - pfr0 := getpfr0() - switch extractBits(pfr0, 16, 19) { case 0: ARM64.HasFP = true diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gc_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_gc_arm64.go index 7b88e865a42..7f7f272a014 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_gc_arm64.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_gc_arm64.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 !gccgo +// +build gc package cpu diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gc_s390x.go b/libgo/go/golang.org/x/sys/cpu/cpu_gc_s390x.go index 568bcd031aa..75a95566161 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_gc_s390x.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_gc_s390x.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 !gccgo +// +build gc package cpu diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_gc_x86.go b/libgo/go/golang.org/x/sys/cpu/cpu_gc_x86.go index f7cb46971cb..4adb89cf9cc 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_gc_x86.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_gc_x86.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build 386 amd64 amd64p32 -// +build !gccgo +// +build gc package cpu diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux.go index fe139182c8d..6fc874f7fef 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux.go @@ -6,7 +6,7 @@ package cpu -func init() { +func archInit() { if err := readHWCAP(); err != nil { return } diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_mips64x.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_mips64x.go index eb24e5073e7..5a418900538 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux_mips64x.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_mips64x.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build linux // +build mips64 mips64le package cpu diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_ppc64x.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_ppc64x.go index 6b1b8932f16..99f8a6399ef 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux_ppc64x.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_ppc64x.go @@ -7,8 +7,6 @@ package cpu -// const cacheLineSize = 128 - // HWCAP/HWCAP2 bits. These are exposed by the kernel. const ( // ISA Level diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_linux_s390x.go b/libgo/go/golang.org/x/sys/cpu/cpu_linux_s390x.go index 92f2896ffa0..1517ac61d31 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_linux_s390x.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_linux_s390x.go @@ -4,8 +4,6 @@ package cpu -// const cacheLineSize = 256 - const ( // bit mask values from /usr/include/bits/hwcap.h hwcap_ZARCH = 2 @@ -19,86 +17,7 @@ const ( hwcap_VXE = 8192 ) -// bitIsSet reports whether the bit at index is set. The bit index -// is in big endian order, so bit index 0 is the leftmost bit. -func bitIsSet(bits []uint64, index uint) bool { - return bits[index/64]&((1<<63)>>(index%64)) != 0 -} - -// function is the code for the named cryptographic function. -type function uint8 - -const ( - // KM{,A,C,CTR} function codes - aes128 function = 18 // AES-128 - aes192 function = 19 // AES-192 - aes256 function = 20 // AES-256 - - // K{I,L}MD function codes - sha1 function = 1 // SHA-1 - sha256 function = 2 // SHA-256 - sha512 function = 3 // SHA-512 - sha3_224 function = 32 // SHA3-224 - sha3_256 function = 33 // SHA3-256 - sha3_384 function = 34 // SHA3-384 - sha3_512 function = 35 // SHA3-512 - shake128 function = 36 // SHAKE-128 - shake256 function = 37 // SHAKE-256 - - // KLMD function codes - ghash function = 65 // GHASH -) - -// queryResult contains the result of a Query function -// call. Bits are numbered in big endian order so the -// leftmost bit (the MSB) is at index 0. -type queryResult struct { - bits [2]uint64 -} - -// Has reports whether the given functions are present. -func (q *queryResult) Has(fns ...function) bool { - if len(fns) == 0 { - panic("no function codes provided") - } - for _, f := range fns { - if !bitIsSet(q.bits[:], uint(f)) { - return false - } - } - return true -} - -// facility is a bit index for the named facility. -type facility uint8 - -const ( - // cryptography facilities - msa4 facility = 77 // message-security-assist extension 4 - msa8 facility = 146 // message-security-assist extension 8 -) - -// facilityList contains the result of an STFLE call. -// Bits are numbered in big endian order so the -// leftmost bit (the MSB) is at index 0. -type facilityList struct { - bits [4]uint64 -} - -// Has reports whether the given facilities are present. -func (s *facilityList) Has(fs ...facility) bool { - if len(fs) == 0 { - panic("no facility bits provided") - } - for _, f := range fs { - if !bitIsSet(s.bits[:], uint(f)) { - return false - } - } - return true -} - -func doinit() { +func initS390Xbase() { // test HWCAP bit vector has := func(featureMask uint) bool { return hwCap&featureMask == featureMask @@ -118,44 +37,4 @@ func doinit() { if S390X.HasVX { S390X.HasVXE = has(hwcap_VXE) } - - // We need implementations of stfle, km and so on - // to detect cryptographic features. - if !haveAsmFunctions() { - return - } - - // optional cryptographic functions - if S390X.HasMSA { - aes := []function{aes128, aes192, aes256} - - // cipher message - km, kmc := kmQuery(), kmcQuery() - S390X.HasAES = km.Has(aes...) - S390X.HasAESCBC = kmc.Has(aes...) - if S390X.HasSTFLE { - facilities := stfle() - if facilities.Has(msa4) { - kmctr := kmctrQuery() - S390X.HasAESCTR = kmctr.Has(aes...) - } - if facilities.Has(msa8) { - kma := kmaQuery() - S390X.HasAESGCM = kma.Has(aes...) - } - } - - // compute message digest - kimd := kimdQuery() // intermediate (no padding) - klmd := klmdQuery() // last (padding) - S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) - S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) - S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) - S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist - sha3 := []function{ - sha3_224, sha3_256, sha3_384, sha3_512, - shake128, shake256, - } - S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) - } } diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_mips64x.go b/libgo/go/golang.org/x/sys/cpu/cpu_mips64x.go index 35675579033..eb4e0104936 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_mips64x.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_mips64x.go @@ -7,3 +7,9 @@ package cpu // const cacheLineSize = 32 + +func initOptions() { + options = []option{ + {Name: "msa", Feature: &MIPS64X.HasMSA}, + } +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_mipsx.go b/libgo/go/golang.org/x/sys/cpu/cpu_mipsx.go index 2af7fa5b0a4..f6767b70028 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_mipsx.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_mipsx.go @@ -7,3 +7,5 @@ package cpu // const cacheLineSize = 32 + +func initOptions() {} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_netbsd_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_netbsd_arm64.go new file mode 100644 index 00000000000..ebfb3fc8e76 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_netbsd_arm64.go @@ -0,0 +1,173 @@ +// Copyright 2020 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 cpu + +import ( + "syscall" + "unsafe" +) + +// Minimal copy of functionality from x/sys/unix so the cpu package can call +// sysctl without depending on x/sys/unix. + +const ( + _CTL_QUERY = -2 + + _SYSCTL_VERS_1 = 0x1000000 +) + +var _zero uintptr + +func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { + var _p0 unsafe.Pointer + if len(mib) > 0 { + _p0 = unsafe.Pointer(&mib[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + _, _, errno := syscall.Syscall6( + syscall.SYS___SYSCTL, + uintptr(_p0), + uintptr(len(mib)), + uintptr(unsafe.Pointer(old)), + uintptr(unsafe.Pointer(oldlen)), + uintptr(unsafe.Pointer(new)), + uintptr(newlen)) + if errno != 0 { + return errno + } + return nil +} + +type sysctlNode struct { + Flags uint32 + Num int32 + Name [32]int8 + Ver uint32 + __rsvd uint32 + Un [16]byte + _sysctl_size [8]byte + _sysctl_func [8]byte + _sysctl_parent [8]byte + _sysctl_desc [8]byte +} + +func sysctlNodes(mib []int32) ([]sysctlNode, error) { + var olen uintptr + + // Get a list of all sysctl nodes below the given MIB by performing + // a sysctl for the given MIB with CTL_QUERY appended. + mib = append(mib, _CTL_QUERY) + qnode := sysctlNode{Flags: _SYSCTL_VERS_1} + qp := (*byte)(unsafe.Pointer(&qnode)) + sz := unsafe.Sizeof(qnode) + if err := sysctl(mib, nil, &olen, qp, sz); err != nil { + return nil, err + } + + // Now that we know the size, get the actual nodes. + nodes := make([]sysctlNode, olen/sz) + np := (*byte)(unsafe.Pointer(&nodes[0])) + if err := sysctl(mib, np, &olen, qp, sz); err != nil { + return nil, err + } + + return nodes, nil +} + +func nametomib(name string) ([]int32, error) { + // Split name into components. + var parts []string + last := 0 + for i := 0; i < len(name); i++ { + if name[i] == '.' { + parts = append(parts, name[last:i]) + last = i + 1 + } + } + parts = append(parts, name[last:]) + + mib := []int32{} + // Discover the nodes and construct the MIB OID. + for partno, part := range parts { + nodes, err := sysctlNodes(mib) + if err != nil { + return nil, err + } + for _, node := range nodes { + n := make([]byte, 0) + for i := range node.Name { + if node.Name[i] != 0 { + n = append(n, byte(node.Name[i])) + } + } + if string(n) == part { + mib = append(mib, int32(node.Num)) + break + } + } + if len(mib) != partno+1 { + return nil, err + } + } + + return mib, nil +} + +// aarch64SysctlCPUID is struct aarch64_sysctl_cpu_id from NetBSD's +type aarch64SysctlCPUID struct { + midr uint64 /* Main ID Register */ + revidr uint64 /* Revision ID Register */ + mpidr uint64 /* Multiprocessor Affinity Register */ + aa64dfr0 uint64 /* A64 Debug Feature Register 0 */ + aa64dfr1 uint64 /* A64 Debug Feature Register 1 */ + aa64isar0 uint64 /* A64 Instruction Set Attribute Register 0 */ + aa64isar1 uint64 /* A64 Instruction Set Attribute Register 1 */ + aa64mmfr0 uint64 /* A64 Memory Model Feature Register 0 */ + aa64mmfr1 uint64 /* A64 Memory Model Feature Register 1 */ + aa64mmfr2 uint64 /* A64 Memory Model Feature Register 2 */ + aa64pfr0 uint64 /* A64 Processor Feature Register 0 */ + aa64pfr1 uint64 /* A64 Processor Feature Register 1 */ + aa64zfr0 uint64 /* A64 SVE Feature ID Register 0 */ + mvfr0 uint32 /* Media and VFP Feature Register 0 */ + mvfr1 uint32 /* Media and VFP Feature Register 1 */ + mvfr2 uint32 /* Media and VFP Feature Register 2 */ + pad uint32 + clidr uint64 /* Cache Level ID Register */ + ctr uint64 /* Cache Type Register */ +} + +func sysctlCPUID(name string) (*aarch64SysctlCPUID, error) { + mib, err := nametomib(name) + if err != nil { + return nil, err + } + + out := aarch64SysctlCPUID{} + n := unsafe.Sizeof(out) + _, _, errno := syscall.Syscall6( + syscall.SYS___SYSCTL, + uintptr(unsafe.Pointer(&mib[0])), + uintptr(len(mib)), + uintptr(unsafe.Pointer(&out)), + uintptr(unsafe.Pointer(&n)), + uintptr(0), + uintptr(0)) + if errno != 0 { + return nil, errno + } + return &out, nil +} + +func doinit() { + cpuid, err := sysctlCPUID("machdep.cpu0.cpu_id") + if err != nil { + setMinimalFeatures() + return + } + parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0) + + Initialized = true +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_other_arm.go b/libgo/go/golang.org/x/sys/cpu/cpu_other_arm.go new file mode 100644 index 00000000000..b412efc1bd1 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_other_arm.go @@ -0,0 +1,9 @@ +// Copyright 2020 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 !linux,arm + +package cpu + +func archInit() {} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_other_arm64.go b/libgo/go/golang.org/x/sys/cpu/cpu_other_arm64.go index 3ffc4afa03c..16c1c4090ee 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_other_arm64.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_other_arm64.go @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build !linux,arm64 +// +build !linux,!netbsd +// +build arm64 package cpu diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_other_mips64x.go b/libgo/go/golang.org/x/sys/cpu/cpu_other_mips64x.go new file mode 100644 index 00000000000..f49fad67783 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_other_mips64x.go @@ -0,0 +1,12 @@ +// Copyright 2020 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 !linux +// +build mips64 mips64le + +package cpu + +func archInit() { + Initialized = true +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_ppc64x.go b/libgo/go/golang.org/x/sys/cpu/cpu_ppc64x.go new file mode 100644 index 00000000000..aedfb17e3f9 --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_ppc64x.go @@ -0,0 +1,16 @@ +// Copyright 2020 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 ppc64 ppc64le + +package cpu + +// const cacheLineSize = 128 + +func initOptions() { + options = []option{ + {Name: "darn", Feature: &PPC64.HasDARN}, + {Name: "scv", Feature: &PPC64.HasSCV}, + } +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go b/libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go index bc41bbb3b3b..2001b99893b 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_riscv64.go @@ -7,3 +7,5 @@ package cpu // const cacheLineSize = 32 + +func initOptions() {} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_s390x.go b/libgo/go/golang.org/x/sys/cpu/cpu_s390x.go new file mode 100644 index 00000000000..14816c004fe --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_s390x.go @@ -0,0 +1,172 @@ +// Copyright 2020 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 cpu + +// const cacheLineSize = 256 + +func initOptions() { + options = []option{ + {Name: "zarch", Feature: &S390X.HasZARCH, Required: true}, + {Name: "stfle", Feature: &S390X.HasSTFLE, Required: true}, + {Name: "ldisp", Feature: &S390X.HasLDISP, Required: true}, + {Name: "eimm", Feature: &S390X.HasEIMM, Required: true}, + {Name: "dfp", Feature: &S390X.HasDFP}, + {Name: "etf3eh", Feature: &S390X.HasETF3EH}, + {Name: "msa", Feature: &S390X.HasMSA}, + {Name: "aes", Feature: &S390X.HasAES}, + {Name: "aescbc", Feature: &S390X.HasAESCBC}, + {Name: "aesctr", Feature: &S390X.HasAESCTR}, + {Name: "aesgcm", Feature: &S390X.HasAESGCM}, + {Name: "ghash", Feature: &S390X.HasGHASH}, + {Name: "sha1", Feature: &S390X.HasSHA1}, + {Name: "sha256", Feature: &S390X.HasSHA256}, + {Name: "sha3", Feature: &S390X.HasSHA3}, + {Name: "sha512", Feature: &S390X.HasSHA512}, + {Name: "vx", Feature: &S390X.HasVX}, + {Name: "vxe", Feature: &S390X.HasVXE}, + } +} + +// bitIsSet reports whether the bit at index is set. The bit index +// is in big endian order, so bit index 0 is the leftmost bit. +func bitIsSet(bits []uint64, index uint) bool { + return bits[index/64]&((1<<63)>>(index%64)) != 0 +} + +// facility is a bit index for the named facility. +type facility uint8 + +const ( + // mandatory facilities + zarch facility = 1 // z architecture mode is active + stflef facility = 7 // store-facility-list-extended + ldisp facility = 18 // long-displacement + eimm facility = 21 // extended-immediate + + // miscellaneous facilities + dfp facility = 42 // decimal-floating-point + etf3eh facility = 30 // extended-translation 3 enhancement + + // cryptography facilities + msa facility = 17 // message-security-assist + msa3 facility = 76 // message-security-assist extension 3 + msa4 facility = 77 // message-security-assist extension 4 + msa5 facility = 57 // message-security-assist extension 5 + msa8 facility = 146 // message-security-assist extension 8 + msa9 facility = 155 // message-security-assist extension 9 + + // vector facilities + vx facility = 129 // vector facility + vxe facility = 135 // vector-enhancements 1 + vxe2 facility = 148 // vector-enhancements 2 +) + +// facilityList contains the result of an STFLE call. +// Bits are numbered in big endian order so the +// leftmost bit (the MSB) is at index 0. +type facilityList struct { + bits [4]uint64 +} + +// Has reports whether the given facilities are present. +func (s *facilityList) Has(fs ...facility) bool { + if len(fs) == 0 { + panic("no facility bits provided") + } + for _, f := range fs { + if !bitIsSet(s.bits[:], uint(f)) { + return false + } + } + return true +} + +// function is the code for the named cryptographic function. +type function uint8 + +const ( + // KM{,A,C,CTR} function codes + aes128 function = 18 // AES-128 + aes192 function = 19 // AES-192 + aes256 function = 20 // AES-256 + + // K{I,L}MD function codes + sha1 function = 1 // SHA-1 + sha256 function = 2 // SHA-256 + sha512 function = 3 // SHA-512 + sha3_224 function = 32 // SHA3-224 + sha3_256 function = 33 // SHA3-256 + sha3_384 function = 34 // SHA3-384 + sha3_512 function = 35 // SHA3-512 + shake128 function = 36 // SHAKE-128 + shake256 function = 37 // SHAKE-256 + + // KLMD function codes + ghash function = 65 // GHASH +) + +// queryResult contains the result of a Query function +// call. Bits are numbered in big endian order so the +// leftmost bit (the MSB) is at index 0. +type queryResult struct { + bits [2]uint64 +} + +// Has reports whether the given functions are present. +func (q *queryResult) Has(fns ...function) bool { + if len(fns) == 0 { + panic("no function codes provided") + } + for _, f := range fns { + if !bitIsSet(q.bits[:], uint(f)) { + return false + } + } + return true +} + +func doinit() { + initS390Xbase() + + // We need implementations of stfle, km and so on + // to detect cryptographic features. + if !haveAsmFunctions() { + return + } + + // optional cryptographic functions + if S390X.HasMSA { + aes := []function{aes128, aes192, aes256} + + // cipher message + km, kmc := kmQuery(), kmcQuery() + S390X.HasAES = km.Has(aes...) + S390X.HasAESCBC = kmc.Has(aes...) + if S390X.HasSTFLE { + facilities := stfle() + if facilities.Has(msa4) { + kmctr := kmctrQuery() + S390X.HasAESCTR = kmctr.Has(aes...) + } + if facilities.Has(msa8) { + kma := kmaQuery() + S390X.HasAESGCM = kma.Has(aes...) + } + } + + // compute message digest + kimd := kimdQuery() // intermediate (no padding) + klmd := klmdQuery() // last (padding) + S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) + S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) + S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) + S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist + sha3 := []function{ + sha3_224, sha3_256, sha3_384, sha3_512, + shake128, shake256, + } + S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) + } +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_wasm.go b/libgo/go/golang.org/x/sys/cpu/cpu_wasm.go index c890010e308..60017a6fae3 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_wasm.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_wasm.go @@ -11,3 +11,7 @@ package cpu // rules are good enough. // const cacheLineSize = 0 + +func initOptions() {} + +func archInit() {} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_x86.go b/libgo/go/golang.org/x/sys/cpu/cpu_x86.go index d6afec9f97a..8cc67e68fdf 100644 --- a/libgo/go/golang.org/x/sys/cpu/cpu_x86.go +++ b/libgo/go/golang.org/x/sys/cpu/cpu_x86.go @@ -6,9 +6,57 @@ package cpu +import "runtime" + // const cacheLineSize = 64 -func init() { +func initOptions() { + options = []option{ + {Name: "adx", Feature: &X86.HasADX}, + {Name: "aes", Feature: &X86.HasAES}, + {Name: "avx", Feature: &X86.HasAVX}, + {Name: "avx2", Feature: &X86.HasAVX2}, + {Name: "avx512", Feature: &X86.HasAVX512}, + {Name: "avx512f", Feature: &X86.HasAVX512F}, + {Name: "avx512cd", Feature: &X86.HasAVX512CD}, + {Name: "avx512er", Feature: &X86.HasAVX512ER}, + {Name: "avx512pf", Feature: &X86.HasAVX512PF}, + {Name: "avx512vl", Feature: &X86.HasAVX512VL}, + {Name: "avx512bw", Feature: &X86.HasAVX512BW}, + {Name: "avx512dq", Feature: &X86.HasAVX512DQ}, + {Name: "avx512ifma", Feature: &X86.HasAVX512IFMA}, + {Name: "avx512vbmi", Feature: &X86.HasAVX512VBMI}, + {Name: "avx512vnniw", Feature: &X86.HasAVX5124VNNIW}, + {Name: "avx5124fmaps", Feature: &X86.HasAVX5124FMAPS}, + {Name: "avx512vpopcntdq", Feature: &X86.HasAVX512VPOPCNTDQ}, + {Name: "avx512vpclmulqdq", Feature: &X86.HasAVX512VPCLMULQDQ}, + {Name: "avx512vnni", Feature: &X86.HasAVX512VNNI}, + {Name: "avx512gfni", Feature: &X86.HasAVX512GFNI}, + {Name: "avx512vaes", Feature: &X86.HasAVX512VAES}, + {Name: "avx512vbmi2", Feature: &X86.HasAVX512VBMI2}, + {Name: "avx512bitalg", Feature: &X86.HasAVX512BITALG}, + {Name: "avx512bf16", Feature: &X86.HasAVX512BF16}, + {Name: "bmi1", Feature: &X86.HasBMI1}, + {Name: "bmi2", Feature: &X86.HasBMI2}, + {Name: "erms", Feature: &X86.HasERMS}, + {Name: "fma", Feature: &X86.HasFMA}, + {Name: "osxsave", Feature: &X86.HasOSXSAVE}, + {Name: "pclmulqdq", Feature: &X86.HasPCLMULQDQ}, + {Name: "popcnt", Feature: &X86.HasPOPCNT}, + {Name: "rdrand", Feature: &X86.HasRDRAND}, + {Name: "rdseed", Feature: &X86.HasRDSEED}, + {Name: "sse3", Feature: &X86.HasSSE3}, + {Name: "sse41", Feature: &X86.HasSSE41}, + {Name: "sse42", Feature: &X86.HasSSE42}, + {Name: "ssse3", Feature: &X86.HasSSSE3}, + + // These capabilities should always be enabled on amd64: + {Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"}, + } +} + +func archInit() { + Initialized = true maxID, _, _, _ := cpuid(0, 0) @@ -31,12 +79,15 @@ func init() { X86.HasOSXSAVE = isSet(27, ecx1) X86.HasRDRAND = isSet(30, ecx1) - osSupportsAVX := false + var osSupportsAVX, osSupportsAVX512 bool // For XGETBV, OSXSAVE bit is required and sufficient. if X86.HasOSXSAVE { eax, _ := xgetbv() // Check if XMM and YMM registers have OS support. osSupportsAVX = isSet(1, eax) && isSet(2, eax) + + // Check if OPMASK and ZMM registers have OS support. + osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax) } X86.HasAVX = isSet(28, ecx1) && osSupportsAVX @@ -45,13 +96,38 @@ func init() { return } - _, ebx7, _, _ := cpuid(7, 0) + _, ebx7, ecx7, edx7 := cpuid(7, 0) X86.HasBMI1 = isSet(3, ebx7) X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX X86.HasBMI2 = isSet(8, ebx7) X86.HasERMS = isSet(9, ebx7) X86.HasRDSEED = isSet(18, ebx7) X86.HasADX = isSet(19, ebx7) + + X86.HasAVX512 = isSet(16, ebx7) && osSupportsAVX512 // Because avx-512 foundation is the core required extension + if X86.HasAVX512 { + X86.HasAVX512F = true + X86.HasAVX512CD = isSet(28, ebx7) + X86.HasAVX512ER = isSet(27, ebx7) + X86.HasAVX512PF = isSet(26, ebx7) + X86.HasAVX512VL = isSet(31, ebx7) + X86.HasAVX512BW = isSet(30, ebx7) + X86.HasAVX512DQ = isSet(17, ebx7) + X86.HasAVX512IFMA = isSet(21, ebx7) + X86.HasAVX512VBMI = isSet(1, ecx7) + X86.HasAVX5124VNNIW = isSet(2, edx7) + X86.HasAVX5124FMAPS = isSet(3, edx7) + X86.HasAVX512VPOPCNTDQ = isSet(14, ecx7) + X86.HasAVX512VPCLMULQDQ = isSet(10, ecx7) + X86.HasAVX512VNNI = isSet(11, ecx7) + X86.HasAVX512GFNI = isSet(8, ecx7) + X86.HasAVX512VAES = isSet(9, ecx7) + X86.HasAVX512VBMI2 = isSet(6, ecx7) + X86.HasAVX512BITALG = isSet(12, ecx7) + + eax71, _, _, _ := cpuid(7, 1) + X86.HasAVX512BF16 = isSet(5, eax71) + } } func isSet(bitpos uint, value uint32) bool { diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_zos.go b/libgo/go/golang.org/x/sys/cpu/cpu_zos.go new file mode 100644 index 00000000000..5f54683a22e --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_zos.go @@ -0,0 +1,10 @@ +// Copyright 2020 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 cpu + +func archInit() { + doinit() + Initialized = true +} diff --git a/libgo/go/golang.org/x/sys/cpu/cpu_zos_s390x.go b/libgo/go/golang.org/x/sys/cpu/cpu_zos_s390x.go new file mode 100644 index 00000000000..ccb1b708aba --- /dev/null +++ b/libgo/go/golang.org/x/sys/cpu/cpu_zos_s390x.go @@ -0,0 +1,25 @@ +// Copyright 2020 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 cpu + +func initS390Xbase() { + // get the facilities list + facilities := stfle() + + // mandatory + S390X.HasZARCH = facilities.Has(zarch) + S390X.HasSTFLE = facilities.Has(stflef) + S390X.HasLDISP = facilities.Has(ldisp) + S390X.HasEIMM = facilities.Has(eimm) + + // optional + S390X.HasETF3EH = facilities.Has(etf3eh) + S390X.HasDFP = facilities.Has(dfp) + S390X.HasMSA = facilities.Has(msa) + S390X.HasVX = facilities.Has(vx) + if S390X.HasVX { + S390X.HasVXE = facilities.Has(vxe) + } +} diff --git a/libgo/go/golang.org/x/sys/cpu/syscall_aix_gccgo.go b/libgo/go/golang.org/x/sys/cpu/syscall_aix_gccgo.go index 2609cc49ae7..76fbe40b762 100644 --- a/libgo/go/golang.org/x/sys/cpu/syscall_aix_gccgo.go +++ b/libgo/go/golang.org/x/sys/cpu/syscall_aix_gccgo.go @@ -5,8 +5,8 @@ // Recreate a getsystemcfg syscall handler instead of // using the one provided by x/sys/unix to avoid having // the dependency between them. (See golang.org/issue/32102) -// Morover, this file will be used during the building of -// gccgo's libgo and thus must not use a CGo method. +// Morever, this file will be used during the building of +// gccgo's libgo and thus must not used a CGo method. // +build aix // +build gccgo diff --git a/libgo/go/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go b/libgo/go/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go index 78fe25e86fb..5b427d67e2f 100644 --- a/libgo/go/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go +++ b/libgo/go/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go @@ -7,7 +7,7 @@ // (See golang.org/issue/32102) // +build aix,ppc64 -// +build !gccgo +// +build gc package cpu diff --git a/libgo/go/golang.org/x/text/transform/transform.go b/libgo/go/golang.org/x/text/transform/transform.go index 520b9ada0e2..48ec64b40ca 100644 --- a/libgo/go/golang.org/x/text/transform/transform.go +++ b/libgo/go/golang.org/x/text/transform/transform.go @@ -648,7 +648,8 @@ func String(t Transformer, s string) (result string, n int, err error) { // Transform the remaining input, growing dst and src buffers as necessary. for { n := copy(src, s[pSrc:]) - nDst, nSrc, err := t.Transform(dst[pDst:], src[:n], pSrc+n == len(s)) + atEOF := pSrc+n == len(s) + nDst, nSrc, err := t.Transform(dst[pDst:], src[:n], atEOF) pDst += nDst pSrc += nSrc @@ -659,6 +660,9 @@ func String(t Transformer, s string) (result string, n int, err error) { dst = grow(dst, pDst) } } else if err == ErrShortSrc { + if atEOF { + return string(dst[:pDst]), pSrc, err + } if nSrc == 0 { src = grow(src, 0) } 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 index 7ffa365121c..647f2d4279e 100644 --- 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 @@ -1,6 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. -// +build go1.14 +// +build go1.14,!go1.16 package bidi diff --git a/libgo/go/golang.org/x/text/unicode/bidi/tables13.0.0.go b/libgo/go/golang.org/x/text/unicode/bidi/tables13.0.0.go new file mode 100644 index 00000000000..c937d0976fe --- /dev/null +++ b/libgo/go/golang.org/x/text/unicode/bidi/tables13.0.0.go @@ -0,0 +1,1955 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.16 + +package bidi + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "13.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: 17408 bytes (17.00 KiB). Checksum: df85fcbfe9b8377f. +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: 248 blocks, 15872 entries, 15872 bytes +// The third block is the zero block. +var bidiValues = [15872]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, + 0x895: 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 + 0xa81: 0x000c, + // Block 0x2b, offset 0xac0 + 0xaca: 0x000c, + 0xad2: 0x000c, 0xad3: 0x000c, 0xad4: 0x000c, 0xad6: 0x000c, + // Block 0x2c, offset 0xb00 + 0xb31: 0x000c, 0xb34: 0x000c, 0xb35: 0x000c, + 0xb36: 0x000c, 0xb37: 0x000c, 0xb38: 0x000c, 0xb39: 0x000c, 0xb3a: 0x000c, + 0xb3f: 0x0004, + // Block 0x2d, offset 0xb40 + 0xb47: 0x000c, 0xb48: 0x000c, 0xb49: 0x000c, 0xb4a: 0x000c, 0xb4b: 0x000c, + 0xb4c: 0x000c, 0xb4d: 0x000c, 0xb4e: 0x000c, + // Block 0x2e, offset 0xb80 + 0xbb1: 0x000c, 0xbb4: 0x000c, 0xbb5: 0x000c, + 0xbb6: 0x000c, 0xbb7: 0x000c, 0xbb8: 0x000c, 0xbb9: 0x000c, 0xbba: 0x000c, 0xbbb: 0x000c, + 0xbbc: 0x000c, + // Block 0x2f, offset 0xbc0 + 0xbc8: 0x000c, 0xbc9: 0x000c, 0xbca: 0x000c, 0xbcb: 0x000c, + 0xbcc: 0x000c, 0xbcd: 0x000c, + // Block 0x30, offset 0xc00 + 0xc18: 0x000c, 0xc19: 0x000c, + 0xc35: 0x000c, + 0xc37: 0x000c, 0xc39: 0x000c, 0xc3a: 0x003a, 0xc3b: 0x002a, + 0xc3c: 0x003a, 0xc3d: 0x002a, + // Block 0x31, offset 0xc40 + 0xc71: 0x000c, 0xc72: 0x000c, 0xc73: 0x000c, 0xc74: 0x000c, 0xc75: 0x000c, + 0xc76: 0x000c, 0xc77: 0x000c, 0xc78: 0x000c, 0xc79: 0x000c, 0xc7a: 0x000c, 0xc7b: 0x000c, + 0xc7c: 0x000c, 0xc7d: 0x000c, 0xc7e: 0x000c, + // Block 0x32, offset 0xc80 + 0xc80: 0x000c, 0xc81: 0x000c, 0xc82: 0x000c, 0xc83: 0x000c, 0xc84: 0x000c, + 0xc86: 0x000c, 0xc87: 0x000c, + 0xc8d: 0x000c, 0xc8e: 0x000c, 0xc8f: 0x000c, 0xc90: 0x000c, 0xc91: 0x000c, + 0xc92: 0x000c, 0xc93: 0x000c, 0xc94: 0x000c, 0xc95: 0x000c, 0xc96: 0x000c, 0xc97: 0x000c, + 0xc99: 0x000c, 0xc9a: 0x000c, 0xc9b: 0x000c, 0xc9c: 0x000c, 0xc9d: 0x000c, + 0xc9e: 0x000c, 0xc9f: 0x000c, 0xca0: 0x000c, 0xca1: 0x000c, 0xca2: 0x000c, 0xca3: 0x000c, + 0xca4: 0x000c, 0xca5: 0x000c, 0xca6: 0x000c, 0xca7: 0x000c, 0xca8: 0x000c, 0xca9: 0x000c, + 0xcaa: 0x000c, 0xcab: 0x000c, 0xcac: 0x000c, 0xcad: 0x000c, 0xcae: 0x000c, 0xcaf: 0x000c, + 0xcb0: 0x000c, 0xcb1: 0x000c, 0xcb2: 0x000c, 0xcb3: 0x000c, 0xcb4: 0x000c, 0xcb5: 0x000c, + 0xcb6: 0x000c, 0xcb7: 0x000c, 0xcb8: 0x000c, 0xcb9: 0x000c, 0xcba: 0x000c, 0xcbb: 0x000c, + 0xcbc: 0x000c, + // Block 0x33, offset 0xcc0 + 0xcc6: 0x000c, + // Block 0x34, offset 0xd00 + 0xd2d: 0x000c, 0xd2e: 0x000c, 0xd2f: 0x000c, + 0xd30: 0x000c, 0xd32: 0x000c, 0xd33: 0x000c, 0xd34: 0x000c, 0xd35: 0x000c, + 0xd36: 0x000c, 0xd37: 0x000c, 0xd39: 0x000c, 0xd3a: 0x000c, + 0xd3d: 0x000c, 0xd3e: 0x000c, + // Block 0x35, offset 0xd40 + 0xd58: 0x000c, 0xd59: 0x000c, + 0xd5e: 0x000c, 0xd5f: 0x000c, 0xd60: 0x000c, + 0xd71: 0x000c, 0xd72: 0x000c, 0xd73: 0x000c, 0xd74: 0x000c, + // Block 0x36, offset 0xd80 + 0xd82: 0x000c, 0xd85: 0x000c, + 0xd86: 0x000c, + 0xd8d: 0x000c, + 0xd9d: 0x000c, + // Block 0x37, offset 0xdc0 + 0xddd: 0x000c, + 0xdde: 0x000c, 0xddf: 0x000c, + // Block 0x38, offset 0xe00 + 0xe10: 0x000a, 0xe11: 0x000a, + 0xe12: 0x000a, 0xe13: 0x000a, 0xe14: 0x000a, 0xe15: 0x000a, 0xe16: 0x000a, 0xe17: 0x000a, + 0xe18: 0x000a, 0xe19: 0x000a, + // Block 0x39, offset 0xe40 + 0xe40: 0x000a, + // Block 0x3a, offset 0xe80 + 0xe80: 0x0009, + 0xe9b: 0x007a, 0xe9c: 0x006a, + // Block 0x3b, offset 0xec0 + 0xed2: 0x000c, 0xed3: 0x000c, 0xed4: 0x000c, + 0xef2: 0x000c, 0xef3: 0x000c, 0xef4: 0x000c, + // Block 0x3c, offset 0xf00 + 0xf12: 0x000c, 0xf13: 0x000c, + 0xf32: 0x000c, 0xf33: 0x000c, + // Block 0x3d, offset 0xf40 + 0xf74: 0x000c, 0xf75: 0x000c, + 0xf77: 0x000c, 0xf78: 0x000c, 0xf79: 0x000c, 0xf7a: 0x000c, 0xf7b: 0x000c, + 0xf7c: 0x000c, 0xf7d: 0x000c, + // Block 0x3e, offset 0xf80 + 0xf86: 0x000c, 0xf89: 0x000c, 0xf8a: 0x000c, 0xf8b: 0x000c, + 0xf8c: 0x000c, 0xf8d: 0x000c, 0xf8e: 0x000c, 0xf8f: 0x000c, 0xf90: 0x000c, 0xf91: 0x000c, + 0xf92: 0x000c, 0xf93: 0x000c, + 0xf9b: 0x0004, 0xf9d: 0x000c, + 0xfb0: 0x000a, 0xfb1: 0x000a, 0xfb2: 0x000a, 0xfb3: 0x000a, 0xfb4: 0x000a, 0xfb5: 0x000a, + 0xfb6: 0x000a, 0xfb7: 0x000a, 0xfb8: 0x000a, 0xfb9: 0x000a, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x000a, 0xfc1: 0x000a, 0xfc2: 0x000a, 0xfc3: 0x000a, 0xfc4: 0x000a, 0xfc5: 0x000a, + 0xfc6: 0x000a, 0xfc7: 0x000a, 0xfc8: 0x000a, 0xfc9: 0x000a, 0xfca: 0x000a, 0xfcb: 0x000c, + 0xfcc: 0x000c, 0xfcd: 0x000c, 0xfce: 0x000b, + // Block 0x40, offset 0x1000 + 0x1005: 0x000c, + 0x1006: 0x000c, + 0x1029: 0x000c, + // Block 0x41, offset 0x1040 + 0x1060: 0x000c, 0x1061: 0x000c, 0x1062: 0x000c, + 0x1067: 0x000c, 0x1068: 0x000c, + 0x1072: 0x000c, + 0x1079: 0x000c, 0x107a: 0x000c, 0x107b: 0x000c, + // Block 0x42, offset 0x1080 + 0x1080: 0x000a, 0x1084: 0x000a, 0x1085: 0x000a, + // Block 0x43, offset 0x10c0 + 0x10de: 0x000a, 0x10df: 0x000a, 0x10e0: 0x000a, 0x10e1: 0x000a, 0x10e2: 0x000a, 0x10e3: 0x000a, + 0x10e4: 0x000a, 0x10e5: 0x000a, 0x10e6: 0x000a, 0x10e7: 0x000a, 0x10e8: 0x000a, 0x10e9: 0x000a, + 0x10ea: 0x000a, 0x10eb: 0x000a, 0x10ec: 0x000a, 0x10ed: 0x000a, 0x10ee: 0x000a, 0x10ef: 0x000a, + 0x10f0: 0x000a, 0x10f1: 0x000a, 0x10f2: 0x000a, 0x10f3: 0x000a, 0x10f4: 0x000a, 0x10f5: 0x000a, + 0x10f6: 0x000a, 0x10f7: 0x000a, 0x10f8: 0x000a, 0x10f9: 0x000a, 0x10fa: 0x000a, 0x10fb: 0x000a, + 0x10fc: 0x000a, 0x10fd: 0x000a, 0x10fe: 0x000a, 0x10ff: 0x000a, + // Block 0x44, offset 0x1100 + 0x1117: 0x000c, + 0x1118: 0x000c, 0x111b: 0x000c, + // Block 0x45, offset 0x1140 + 0x1156: 0x000c, + 0x1158: 0x000c, 0x1159: 0x000c, 0x115a: 0x000c, 0x115b: 0x000c, 0x115c: 0x000c, 0x115d: 0x000c, + 0x115e: 0x000c, 0x1160: 0x000c, 0x1162: 0x000c, + 0x1165: 0x000c, 0x1166: 0x000c, 0x1167: 0x000c, 0x1168: 0x000c, 0x1169: 0x000c, + 0x116a: 0x000c, 0x116b: 0x000c, 0x116c: 0x000c, + 0x1173: 0x000c, 0x1174: 0x000c, 0x1175: 0x000c, + 0x1176: 0x000c, 0x1177: 0x000c, 0x1178: 0x000c, 0x1179: 0x000c, 0x117a: 0x000c, 0x117b: 0x000c, + 0x117c: 0x000c, 0x117f: 0x000c, + // Block 0x46, offset 0x1180 + 0x11b0: 0x000c, 0x11b1: 0x000c, 0x11b2: 0x000c, 0x11b3: 0x000c, 0x11b4: 0x000c, 0x11b5: 0x000c, + 0x11b6: 0x000c, 0x11b7: 0x000c, 0x11b8: 0x000c, 0x11b9: 0x000c, 0x11ba: 0x000c, 0x11bb: 0x000c, + 0x11bc: 0x000c, 0x11bd: 0x000c, 0x11be: 0x000c, 0x11bf: 0x000c, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x000c, + // Block 0x48, offset 0x1200 + 0x1200: 0x000c, 0x1201: 0x000c, 0x1202: 0x000c, 0x1203: 0x000c, + 0x1234: 0x000c, + 0x1236: 0x000c, 0x1237: 0x000c, 0x1238: 0x000c, 0x1239: 0x000c, 0x123a: 0x000c, + 0x123c: 0x000c, + // Block 0x49, offset 0x1240 + 0x1242: 0x000c, + 0x126b: 0x000c, 0x126c: 0x000c, 0x126d: 0x000c, 0x126e: 0x000c, 0x126f: 0x000c, + 0x1270: 0x000c, 0x1271: 0x000c, 0x1272: 0x000c, 0x1273: 0x000c, + // Block 0x4a, offset 0x1280 + 0x1280: 0x000c, 0x1281: 0x000c, + 0x12a2: 0x000c, 0x12a3: 0x000c, + 0x12a4: 0x000c, 0x12a5: 0x000c, 0x12a8: 0x000c, 0x12a9: 0x000c, + 0x12ab: 0x000c, 0x12ac: 0x000c, 0x12ad: 0x000c, + // Block 0x4b, offset 0x12c0 + 0x12e6: 0x000c, 0x12e8: 0x000c, 0x12e9: 0x000c, + 0x12ed: 0x000c, 0x12ef: 0x000c, + 0x12f0: 0x000c, 0x12f1: 0x000c, + // Block 0x4c, offset 0x1300 + 0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c, + 0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c, + 0x1336: 0x000c, 0x1337: 0x000c, + // Block 0x4d, offset 0x1340 + 0x1350: 0x000c, 0x1351: 0x000c, + 0x1352: 0x000c, 0x1354: 0x000c, 0x1355: 0x000c, 0x1356: 0x000c, 0x1357: 0x000c, + 0x1358: 0x000c, 0x1359: 0x000c, 0x135a: 0x000c, 0x135b: 0x000c, 0x135c: 0x000c, 0x135d: 0x000c, + 0x135e: 0x000c, 0x135f: 0x000c, 0x1360: 0x000c, 0x1362: 0x000c, 0x1363: 0x000c, + 0x1364: 0x000c, 0x1365: 0x000c, 0x1366: 0x000c, 0x1367: 0x000c, 0x1368: 0x000c, + 0x136d: 0x000c, + 0x1374: 0x000c, + 0x1378: 0x000c, 0x1379: 0x000c, + // Block 0x4e, offset 0x1380 + 0x1380: 0x000c, 0x1381: 0x000c, 0x1382: 0x000c, 0x1383: 0x000c, 0x1384: 0x000c, 0x1385: 0x000c, + 0x1386: 0x000c, 0x1387: 0x000c, 0x1388: 0x000c, 0x1389: 0x000c, 0x138a: 0x000c, 0x138b: 0x000c, + 0x138c: 0x000c, 0x138d: 0x000c, 0x138e: 0x000c, 0x138f: 0x000c, 0x1390: 0x000c, 0x1391: 0x000c, + 0x1392: 0x000c, 0x1393: 0x000c, 0x1394: 0x000c, 0x1395: 0x000c, 0x1396: 0x000c, 0x1397: 0x000c, + 0x1398: 0x000c, 0x1399: 0x000c, 0x139a: 0x000c, 0x139b: 0x000c, 0x139c: 0x000c, 0x139d: 0x000c, + 0x139e: 0x000c, 0x139f: 0x000c, 0x13a0: 0x000c, 0x13a1: 0x000c, 0x13a2: 0x000c, 0x13a3: 0x000c, + 0x13a4: 0x000c, 0x13a5: 0x000c, 0x13a6: 0x000c, 0x13a7: 0x000c, 0x13a8: 0x000c, 0x13a9: 0x000c, + 0x13aa: 0x000c, 0x13ab: 0x000c, 0x13ac: 0x000c, 0x13ad: 0x000c, 0x13ae: 0x000c, 0x13af: 0x000c, + 0x13b0: 0x000c, 0x13b1: 0x000c, 0x13b2: 0x000c, 0x13b3: 0x000c, 0x13b4: 0x000c, 0x13b5: 0x000c, + 0x13b6: 0x000c, 0x13b7: 0x000c, 0x13b8: 0x000c, 0x13b9: 0x000c, 0x13bb: 0x000c, + 0x13bc: 0x000c, 0x13bd: 0x000c, 0x13be: 0x000c, 0x13bf: 0x000c, + // Block 0x4f, offset 0x13c0 + 0x13fd: 0x000a, 0x13ff: 0x000a, + // Block 0x50, offset 0x1400 + 0x1400: 0x000a, 0x1401: 0x000a, + 0x140d: 0x000a, 0x140e: 0x000a, 0x140f: 0x000a, + 0x141d: 0x000a, + 0x141e: 0x000a, 0x141f: 0x000a, + 0x142d: 0x000a, 0x142e: 0x000a, 0x142f: 0x000a, + 0x143d: 0x000a, 0x143e: 0x000a, + // Block 0x51, offset 0x1440 + 0x1440: 0x0009, 0x1441: 0x0009, 0x1442: 0x0009, 0x1443: 0x0009, 0x1444: 0x0009, 0x1445: 0x0009, + 0x1446: 0x0009, 0x1447: 0x0009, 0x1448: 0x0009, 0x1449: 0x0009, 0x144a: 0x0009, 0x144b: 0x000b, + 0x144c: 0x000b, 0x144d: 0x000b, 0x144f: 0x0001, 0x1450: 0x000a, 0x1451: 0x000a, + 0x1452: 0x000a, 0x1453: 0x000a, 0x1454: 0x000a, 0x1455: 0x000a, 0x1456: 0x000a, 0x1457: 0x000a, + 0x1458: 0x000a, 0x1459: 0x000a, 0x145a: 0x000a, 0x145b: 0x000a, 0x145c: 0x000a, 0x145d: 0x000a, + 0x145e: 0x000a, 0x145f: 0x000a, 0x1460: 0x000a, 0x1461: 0x000a, 0x1462: 0x000a, 0x1463: 0x000a, + 0x1464: 0x000a, 0x1465: 0x000a, 0x1466: 0x000a, 0x1467: 0x000a, 0x1468: 0x0009, 0x1469: 0x0007, + 0x146a: 0x000e, 0x146b: 0x000e, 0x146c: 0x000e, 0x146d: 0x000e, 0x146e: 0x000e, 0x146f: 0x0006, + 0x1470: 0x0004, 0x1471: 0x0004, 0x1472: 0x0004, 0x1473: 0x0004, 0x1474: 0x0004, 0x1475: 0x000a, + 0x1476: 0x000a, 0x1477: 0x000a, 0x1478: 0x000a, 0x1479: 0x000a, 0x147a: 0x000a, 0x147b: 0x000a, + 0x147c: 0x000a, 0x147d: 0x000a, 0x147e: 0x000a, 0x147f: 0x000a, + // Block 0x52, offset 0x1480 + 0x1480: 0x000a, 0x1481: 0x000a, 0x1482: 0x000a, 0x1483: 0x000a, 0x1484: 0x0006, 0x1485: 0x009a, + 0x1486: 0x008a, 0x1487: 0x000a, 0x1488: 0x000a, 0x1489: 0x000a, 0x148a: 0x000a, 0x148b: 0x000a, + 0x148c: 0x000a, 0x148d: 0x000a, 0x148e: 0x000a, 0x148f: 0x000a, 0x1490: 0x000a, 0x1491: 0x000a, + 0x1492: 0x000a, 0x1493: 0x000a, 0x1494: 0x000a, 0x1495: 0x000a, 0x1496: 0x000a, 0x1497: 0x000a, + 0x1498: 0x000a, 0x1499: 0x000a, 0x149a: 0x000a, 0x149b: 0x000a, 0x149c: 0x000a, 0x149d: 0x000a, + 0x149e: 0x000a, 0x149f: 0x0009, 0x14a0: 0x000b, 0x14a1: 0x000b, 0x14a2: 0x000b, 0x14a3: 0x000b, + 0x14a4: 0x000b, 0x14a5: 0x000b, 0x14a6: 0x000e, 0x14a7: 0x000e, 0x14a8: 0x000e, 0x14a9: 0x000e, + 0x14aa: 0x000b, 0x14ab: 0x000b, 0x14ac: 0x000b, 0x14ad: 0x000b, 0x14ae: 0x000b, 0x14af: 0x000b, + 0x14b0: 0x0002, 0x14b4: 0x0002, 0x14b5: 0x0002, + 0x14b6: 0x0002, 0x14b7: 0x0002, 0x14b8: 0x0002, 0x14b9: 0x0002, 0x14ba: 0x0003, 0x14bb: 0x0003, + 0x14bc: 0x000a, 0x14bd: 0x009a, 0x14be: 0x008a, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x0002, 0x14c1: 0x0002, 0x14c2: 0x0002, 0x14c3: 0x0002, 0x14c4: 0x0002, 0x14c5: 0x0002, + 0x14c6: 0x0002, 0x14c7: 0x0002, 0x14c8: 0x0002, 0x14c9: 0x0002, 0x14ca: 0x0003, 0x14cb: 0x0003, + 0x14cc: 0x000a, 0x14cd: 0x009a, 0x14ce: 0x008a, + 0x14e0: 0x0004, 0x14e1: 0x0004, 0x14e2: 0x0004, 0x14e3: 0x0004, + 0x14e4: 0x0004, 0x14e5: 0x0004, 0x14e6: 0x0004, 0x14e7: 0x0004, 0x14e8: 0x0004, 0x14e9: 0x0004, + 0x14ea: 0x0004, 0x14eb: 0x0004, 0x14ec: 0x0004, 0x14ed: 0x0004, 0x14ee: 0x0004, 0x14ef: 0x0004, + 0x14f0: 0x0004, 0x14f1: 0x0004, 0x14f2: 0x0004, 0x14f3: 0x0004, 0x14f4: 0x0004, 0x14f5: 0x0004, + 0x14f6: 0x0004, 0x14f7: 0x0004, 0x14f8: 0x0004, 0x14f9: 0x0004, 0x14fa: 0x0004, 0x14fb: 0x0004, + 0x14fc: 0x0004, 0x14fd: 0x0004, 0x14fe: 0x0004, 0x14ff: 0x0004, + // Block 0x54, offset 0x1500 + 0x1500: 0x0004, 0x1501: 0x0004, 0x1502: 0x0004, 0x1503: 0x0004, 0x1504: 0x0004, 0x1505: 0x0004, + 0x1506: 0x0004, 0x1507: 0x0004, 0x1508: 0x0004, 0x1509: 0x0004, 0x150a: 0x0004, 0x150b: 0x0004, + 0x150c: 0x0004, 0x150d: 0x0004, 0x150e: 0x0004, 0x150f: 0x0004, 0x1510: 0x000c, 0x1511: 0x000c, + 0x1512: 0x000c, 0x1513: 0x000c, 0x1514: 0x000c, 0x1515: 0x000c, 0x1516: 0x000c, 0x1517: 0x000c, + 0x1518: 0x000c, 0x1519: 0x000c, 0x151a: 0x000c, 0x151b: 0x000c, 0x151c: 0x000c, 0x151d: 0x000c, + 0x151e: 0x000c, 0x151f: 0x000c, 0x1520: 0x000c, 0x1521: 0x000c, 0x1522: 0x000c, 0x1523: 0x000c, + 0x1524: 0x000c, 0x1525: 0x000c, 0x1526: 0x000c, 0x1527: 0x000c, 0x1528: 0x000c, 0x1529: 0x000c, + 0x152a: 0x000c, 0x152b: 0x000c, 0x152c: 0x000c, 0x152d: 0x000c, 0x152e: 0x000c, 0x152f: 0x000c, + 0x1530: 0x000c, + // Block 0x55, offset 0x1540 + 0x1540: 0x000a, 0x1541: 0x000a, 0x1543: 0x000a, 0x1544: 0x000a, 0x1545: 0x000a, + 0x1546: 0x000a, 0x1548: 0x000a, 0x1549: 0x000a, + 0x1554: 0x000a, 0x1556: 0x000a, 0x1557: 0x000a, + 0x1558: 0x000a, + 0x155e: 0x000a, 0x155f: 0x000a, 0x1560: 0x000a, 0x1561: 0x000a, 0x1562: 0x000a, 0x1563: 0x000a, + 0x1565: 0x000a, 0x1567: 0x000a, 0x1569: 0x000a, + 0x156e: 0x0004, + 0x157a: 0x000a, 0x157b: 0x000a, + // Block 0x56, offset 0x1580 + 0x1580: 0x000a, 0x1581: 0x000a, 0x1582: 0x000a, 0x1583: 0x000a, 0x1584: 0x000a, + 0x158a: 0x000a, 0x158b: 0x000a, + 0x158c: 0x000a, 0x158d: 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, + // Block 0x57, offset 0x15c0 + 0x15c9: 0x000a, 0x15ca: 0x000a, 0x15cb: 0x000a, + 0x15d0: 0x000a, 0x15d1: 0x000a, + 0x15d2: 0x000a, 0x15d3: 0x000a, 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: 0x000a, 0x1609: 0x000a, 0x160a: 0x000a, 0x160b: 0x000a, + 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: 0x000a, + 0x162a: 0x000a, 0x162b: 0x000a, 0x162c: 0x000a, 0x162d: 0x000a, 0x162e: 0x000a, 0x162f: 0x000a, + 0x1630: 0x000a, 0x1631: 0x000a, 0x1632: 0x000a, 0x1633: 0x000a, 0x1634: 0x000a, 0x1635: 0x000a, + 0x1636: 0x000a, 0x1637: 0x000a, 0x1638: 0x000a, 0x1639: 0x000a, 0x163a: 0x000a, 0x163b: 0x000a, + 0x163c: 0x000a, 0x163d: 0x000a, 0x163e: 0x000a, 0x163f: 0x000a, + // Block 0x59, offset 0x1640 + 0x1640: 0x000a, 0x1641: 0x000a, 0x1642: 0x000a, 0x1643: 0x000a, 0x1644: 0x000a, 0x1645: 0x000a, + 0x1646: 0x000a, 0x1647: 0x000a, 0x1648: 0x000a, 0x1649: 0x000a, 0x164a: 0x000a, 0x164b: 0x000a, + 0x164c: 0x000a, 0x164d: 0x000a, 0x164e: 0x000a, 0x164f: 0x000a, 0x1650: 0x000a, 0x1651: 0x000a, + 0x1652: 0x0003, 0x1653: 0x0004, 0x1654: 0x000a, 0x1655: 0x000a, 0x1656: 0x000a, 0x1657: 0x000a, + 0x1658: 0x000a, 0x1659: 0x000a, 0x165a: 0x000a, 0x165b: 0x000a, 0x165c: 0x000a, 0x165d: 0x000a, + 0x165e: 0x000a, 0x165f: 0x000a, 0x1660: 0x000a, 0x1661: 0x000a, 0x1662: 0x000a, 0x1663: 0x000a, + 0x1664: 0x000a, 0x1665: 0x000a, 0x1666: 0x000a, 0x1667: 0x000a, 0x1668: 0x000a, 0x1669: 0x000a, + 0x166a: 0x000a, 0x166b: 0x000a, 0x166c: 0x000a, 0x166d: 0x000a, 0x166e: 0x000a, 0x166f: 0x000a, + 0x1670: 0x000a, 0x1671: 0x000a, 0x1672: 0x000a, 0x1673: 0x000a, 0x1674: 0x000a, 0x1675: 0x000a, + 0x1676: 0x000a, 0x1677: 0x000a, 0x1678: 0x000a, 0x1679: 0x000a, 0x167a: 0x000a, 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: 0x003a, 0x1689: 0x002a, 0x168a: 0x003a, 0x168b: 0x002a, + 0x168c: 0x000a, 0x168d: 0x000a, 0x168e: 0x000a, 0x168f: 0x000a, 0x1690: 0x000a, 0x1691: 0x000a, + 0x1692: 0x000a, 0x1693: 0x000a, 0x1694: 0x000a, 0x1695: 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: 0x009a, + 0x16aa: 0x008a, 0x16ab: 0x000a, 0x16ac: 0x000a, 0x16ad: 0x000a, 0x16ae: 0x000a, 0x16af: 0x000a, + 0x16b0: 0x000a, 0x16b1: 0x000a, 0x16b2: 0x000a, 0x16b3: 0x000a, 0x16b4: 0x000a, 0x16b5: 0x000a, + // Block 0x5b, offset 0x16c0 + 0x16fb: 0x000a, + 0x16fc: 0x000a, 0x16fd: 0x000a, 0x16fe: 0x000a, 0x16ff: 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, 0x170b: 0x000a, + 0x170c: 0x000a, 0x170d: 0x000a, 0x170e: 0x000a, 0x170f: 0x000a, 0x1710: 0x000a, 0x1711: 0x000a, + 0x1712: 0x000a, 0x1713: 0x000a, 0x1714: 0x000a, 0x1716: 0x000a, 0x1717: 0x000a, + 0x1718: 0x000a, 0x1719: 0x000a, 0x171a: 0x000a, 0x171b: 0x000a, 0x171c: 0x000a, 0x171d: 0x000a, + 0x171e: 0x000a, 0x171f: 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: 0x000a, 0x1749: 0x000a, 0x174a: 0x000a, 0x174b: 0x000a, + 0x174c: 0x000a, 0x174d: 0x000a, 0x174e: 0x000a, 0x174f: 0x000a, 0x1750: 0x000a, 0x1751: 0x000a, + 0x1752: 0x000a, 0x1753: 0x000a, 0x1754: 0x000a, 0x1755: 0x000a, 0x1756: 0x000a, 0x1757: 0x000a, + 0x1758: 0x000a, 0x1759: 0x000a, 0x175a: 0x000a, 0x175b: 0x000a, 0x175c: 0x000a, 0x175d: 0x000a, + 0x175e: 0x000a, 0x175f: 0x000a, 0x1760: 0x000a, 0x1761: 0x000a, 0x1762: 0x000a, 0x1763: 0x000a, + 0x1764: 0x000a, 0x1765: 0x000a, 0x1766: 0x000a, + // Block 0x5e, offset 0x1780 + 0x1780: 0x000a, 0x1781: 0x000a, 0x1782: 0x000a, 0x1783: 0x000a, 0x1784: 0x000a, 0x1785: 0x000a, + 0x1786: 0x000a, 0x1787: 0x000a, 0x1788: 0x000a, 0x1789: 0x000a, 0x178a: 0x000a, + 0x17a0: 0x000a, 0x17a1: 0x000a, 0x17a2: 0x000a, 0x17a3: 0x000a, + 0x17a4: 0x000a, 0x17a5: 0x000a, 0x17a6: 0x000a, 0x17a7: 0x000a, 0x17a8: 0x000a, 0x17a9: 0x000a, + 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: 0x0002, 0x17c9: 0x0002, 0x17ca: 0x0002, 0x17cb: 0x0002, + 0x17cc: 0x0002, 0x17cd: 0x0002, 0x17ce: 0x0002, 0x17cf: 0x0002, 0x17d0: 0x0002, 0x17d1: 0x0002, + 0x17d2: 0x0002, 0x17d3: 0x0002, 0x17d4: 0x0002, 0x17d5: 0x0002, 0x17d6: 0x0002, 0x17d7: 0x0002, + 0x17d8: 0x0002, 0x17d9: 0x0002, 0x17da: 0x0002, 0x17db: 0x0002, + // Block 0x60, offset 0x1800 + 0x182a: 0x000a, 0x182b: 0x000a, 0x182c: 0x000a, 0x182d: 0x000a, 0x182e: 0x000a, 0x182f: 0x000a, + 0x1830: 0x000a, 0x1831: 0x000a, 0x1832: 0x000a, 0x1833: 0x000a, 0x1834: 0x000a, 0x1835: 0x000a, + 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: 0x000a, + 0x1846: 0x000a, 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: 0x000a, 0x1867: 0x000a, 0x1868: 0x000a, 0x1869: 0x000a, + 0x186a: 0x000a, 0x186b: 0x000a, 0x186d: 0x000a, 0x186e: 0x000a, 0x186f: 0x000a, + 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: 0x000a, 0x1884: 0x000a, 0x1885: 0x000a, + 0x1886: 0x000a, 0x1887: 0x000a, 0x1888: 0x000a, 0x1889: 0x000a, 0x188a: 0x000a, 0x188b: 0x000a, + 0x188c: 0x000a, 0x188d: 0x000a, 0x188e: 0x000a, 0x188f: 0x000a, 0x1890: 0x000a, 0x1891: 0x000a, + 0x1892: 0x000a, 0x1893: 0x000a, 0x1894: 0x000a, 0x1895: 0x000a, 0x1896: 0x000a, 0x1897: 0x000a, + 0x1898: 0x000a, 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: 0x003a, 0x18a9: 0x002a, + 0x18aa: 0x003a, 0x18ab: 0x002a, 0x18ac: 0x003a, 0x18ad: 0x002a, 0x18ae: 0x003a, 0x18af: 0x002a, + 0x18b0: 0x003a, 0x18b1: 0x002a, 0x18b2: 0x003a, 0x18b3: 0x002a, 0x18b4: 0x003a, 0x18b5: 0x002a, + 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: 0x009a, + 0x18c6: 0x008a, 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: 0x000a, 0x18d9: 0x000a, 0x18da: 0x000a, 0x18db: 0x000a, 0x18dc: 0x000a, 0x18dd: 0x000a, + 0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a, + 0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x003a, 0x18e7: 0x002a, 0x18e8: 0x003a, 0x18e9: 0x002a, + 0x18ea: 0x003a, 0x18eb: 0x002a, 0x18ec: 0x003a, 0x18ed: 0x002a, 0x18ee: 0x003a, 0x18ef: 0x002a, + 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: 0x000a, 0x18fd: 0x000a, 0x18fe: 0x000a, 0x18ff: 0x000a, + // Block 0x64, offset 0x1900 + 0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x007a, 0x1904: 0x006a, 0x1905: 0x009a, + 0x1906: 0x008a, 0x1907: 0x00ba, 0x1908: 0x00aa, 0x1909: 0x009a, 0x190a: 0x008a, 0x190b: 0x007a, + 0x190c: 0x006a, 0x190d: 0x00da, 0x190e: 0x002a, 0x190f: 0x003a, 0x1910: 0x00ca, 0x1911: 0x009a, + 0x1912: 0x008a, 0x1913: 0x007a, 0x1914: 0x006a, 0x1915: 0x009a, 0x1916: 0x008a, 0x1917: 0x00ba, + 0x1918: 0x00aa, 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, 0x1934: 0x000a, 0x1935: 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, 0x1956: 0x000a, 0x1957: 0x000a, + 0x1958: 0x003a, 0x1959: 0x002a, 0x195a: 0x003a, 0x195b: 0x002a, 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: 0x003a, 0x197d: 0x002a, 0x197e: 0x000a, 0x197f: 0x000a, + // Block 0x66, offset 0x1980 + 0x1980: 0x000a, 0x1981: 0x000a, 0x1982: 0x000a, 0x1983: 0x000a, 0x1984: 0x000a, 0x1985: 0x000a, + 0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x1989: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a, + 0x198c: 0x000a, 0x198d: 0x000a, 0x198e: 0x000a, 0x198f: 0x000a, 0x1990: 0x000a, 0x1991: 0x000a, + 0x1992: 0x000a, 0x1993: 0x000a, 0x1994: 0x000a, 0x1995: 0x000a, 0x1996: 0x000a, 0x1997: 0x000a, + 0x1998: 0x000a, 0x1999: 0x000a, 0x199a: 0x000a, 0x199b: 0x000a, 0x199c: 0x000a, 0x199d: 0x000a, + 0x199e: 0x000a, 0x199f: 0x000a, 0x19a0: 0x000a, 0x19a1: 0x000a, 0x19a2: 0x000a, 0x19a3: 0x000a, + 0x19a4: 0x000a, 0x19a5: 0x000a, 0x19a6: 0x000a, 0x19a7: 0x000a, 0x19a8: 0x000a, 0x19a9: 0x000a, + 0x19aa: 0x000a, 0x19ab: 0x000a, 0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a, + 0x19b0: 0x000a, 0x19b1: 0x000a, 0x19b2: 0x000a, 0x19b3: 0x000a, + 0x19b6: 0x000a, 0x19b7: 0x000a, 0x19b8: 0x000a, 0x19b9: 0x000a, 0x19ba: 0x000a, 0x19bb: 0x000a, + 0x19bc: 0x000a, 0x19bd: 0x000a, 0x19be: 0x000a, 0x19bf: 0x000a, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x000a, 0x19c1: 0x000a, 0x19c2: 0x000a, 0x19c3: 0x000a, 0x19c4: 0x000a, 0x19c5: 0x000a, + 0x19c6: 0x000a, 0x19c7: 0x000a, 0x19c8: 0x000a, 0x19c9: 0x000a, 0x19ca: 0x000a, 0x19cb: 0x000a, + 0x19cc: 0x000a, 0x19cd: 0x000a, 0x19ce: 0x000a, 0x19cf: 0x000a, 0x19d0: 0x000a, 0x19d1: 0x000a, + 0x19d2: 0x000a, 0x19d3: 0x000a, 0x19d4: 0x000a, 0x19d5: 0x000a, 0x19d7: 0x000a, + 0x19d8: 0x000a, 0x19d9: 0x000a, 0x19da: 0x000a, 0x19db: 0x000a, 0x19dc: 0x000a, 0x19dd: 0x000a, + 0x19de: 0x000a, 0x19df: 0x000a, 0x19e0: 0x000a, 0x19e1: 0x000a, 0x19e2: 0x000a, 0x19e3: 0x000a, + 0x19e4: 0x000a, 0x19e5: 0x000a, 0x19e6: 0x000a, 0x19e7: 0x000a, 0x19e8: 0x000a, 0x19e9: 0x000a, + 0x19ea: 0x000a, 0x19eb: 0x000a, 0x19ec: 0x000a, 0x19ed: 0x000a, 0x19ee: 0x000a, 0x19ef: 0x000a, + 0x19f0: 0x000a, 0x19f1: 0x000a, 0x19f2: 0x000a, 0x19f3: 0x000a, 0x19f4: 0x000a, 0x19f5: 0x000a, + 0x19f6: 0x000a, 0x19f7: 0x000a, 0x19f8: 0x000a, 0x19f9: 0x000a, 0x19fa: 0x000a, 0x19fb: 0x000a, + 0x19fc: 0x000a, 0x19fd: 0x000a, 0x19fe: 0x000a, 0x19ff: 0x000a, + // Block 0x68, offset 0x1a00 + 0x1a25: 0x000a, 0x1a26: 0x000a, 0x1a27: 0x000a, 0x1a28: 0x000a, 0x1a29: 0x000a, + 0x1a2a: 0x000a, 0x1a2f: 0x000c, + 0x1a30: 0x000c, 0x1a31: 0x000c, + 0x1a39: 0x000a, 0x1a3a: 0x000a, 0x1a3b: 0x000a, + 0x1a3c: 0x000a, 0x1a3d: 0x000a, 0x1a3e: 0x000a, 0x1a3f: 0x000a, + // Block 0x69, offset 0x1a40 + 0x1a7f: 0x000c, + // Block 0x6a, offset 0x1a80 + 0x1aa0: 0x000c, 0x1aa1: 0x000c, 0x1aa2: 0x000c, 0x1aa3: 0x000c, + 0x1aa4: 0x000c, 0x1aa5: 0x000c, 0x1aa6: 0x000c, 0x1aa7: 0x000c, 0x1aa8: 0x000c, 0x1aa9: 0x000c, + 0x1aaa: 0x000c, 0x1aab: 0x000c, 0x1aac: 0x000c, 0x1aad: 0x000c, 0x1aae: 0x000c, 0x1aaf: 0x000c, + 0x1ab0: 0x000c, 0x1ab1: 0x000c, 0x1ab2: 0x000c, 0x1ab3: 0x000c, 0x1ab4: 0x000c, 0x1ab5: 0x000c, + 0x1ab6: 0x000c, 0x1ab7: 0x000c, 0x1ab8: 0x000c, 0x1ab9: 0x000c, 0x1aba: 0x000c, 0x1abb: 0x000c, + 0x1abc: 0x000c, 0x1abd: 0x000c, 0x1abe: 0x000c, 0x1abf: 0x000c, + // 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, 0x1ada: 0x000a, 0x1adb: 0x000a, 0x1adc: 0x000a, 0x1add: 0x000a, + 0x1ade: 0x000a, 0x1adf: 0x000a, 0x1ae0: 0x000a, 0x1ae1: 0x000a, 0x1ae2: 0x003a, 0x1ae3: 0x002a, + 0x1ae4: 0x003a, 0x1ae5: 0x002a, 0x1ae6: 0x003a, 0x1ae7: 0x002a, 0x1ae8: 0x003a, 0x1ae9: 0x002a, + 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, + // 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, 0x1b56: 0x000a, 0x1b57: 0x000a, + 0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a, + 0x1b5e: 0x000a, 0x1b5f: 0x000a, 0x1b60: 0x000a, 0x1b61: 0x000a, 0x1b62: 0x000a, 0x1b63: 0x000a, + 0x1b64: 0x000a, 0x1b65: 0x000a, 0x1b66: 0x000a, 0x1b67: 0x000a, 0x1b68: 0x000a, 0x1b69: 0x000a, + 0x1b6a: 0x000a, 0x1b6b: 0x000a, 0x1b6c: 0x000a, 0x1b6d: 0x000a, 0x1b6e: 0x000a, 0x1b6f: 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, + 0x1b7c: 0x000a, 0x1b7d: 0x000a, 0x1b7e: 0x000a, 0x1b7f: 0x000a, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x000a, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, 0x1b85: 0x000a, + 0x1b86: 0x000a, 0x1b87: 0x000a, 0x1b88: 0x000a, 0x1b89: 0x000a, 0x1b8a: 0x000a, 0x1b8b: 0x000a, + 0x1b8c: 0x000a, 0x1b8d: 0x000a, 0x1b8e: 0x000a, 0x1b8f: 0x000a, 0x1b90: 0x000a, 0x1b91: 0x000a, + 0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a, 0x1b96: 0x000a, 0x1b97: 0x000a, + 0x1b98: 0x000a, 0x1b99: 0x000a, 0x1b9a: 0x000a, 0x1b9b: 0x000a, 0x1b9c: 0x000a, 0x1b9d: 0x000a, + 0x1b9e: 0x000a, 0x1b9f: 0x000a, 0x1ba0: 0x000a, 0x1ba1: 0x000a, 0x1ba2: 0x000a, 0x1ba3: 0x000a, + 0x1ba4: 0x000a, 0x1ba5: 0x000a, 0x1ba6: 0x000a, 0x1ba7: 0x000a, 0x1ba8: 0x000a, 0x1ba9: 0x000a, + 0x1baa: 0x000a, 0x1bab: 0x000a, 0x1bac: 0x000a, 0x1bad: 0x000a, 0x1bae: 0x000a, 0x1baf: 0x000a, + 0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x000a, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a, 0x1bc5: 0x000a, + 0x1bc6: 0x000a, 0x1bc7: 0x000a, 0x1bc8: 0x000a, 0x1bc9: 0x000a, 0x1bca: 0x000a, 0x1bcb: 0x000a, + 0x1bcc: 0x000a, 0x1bcd: 0x000a, 0x1bce: 0x000a, 0x1bcf: 0x000a, 0x1bd0: 0x000a, 0x1bd1: 0x000a, + 0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x000a, 0x1bd5: 0x000a, + 0x1bf0: 0x000a, 0x1bf1: 0x000a, 0x1bf2: 0x000a, 0x1bf3: 0x000a, 0x1bf4: 0x000a, 0x1bf5: 0x000a, + 0x1bf6: 0x000a, 0x1bf7: 0x000a, 0x1bf8: 0x000a, 0x1bf9: 0x000a, 0x1bfa: 0x000a, 0x1bfb: 0x000a, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x0009, 0x1c01: 0x000a, 0x1c02: 0x000a, 0x1c03: 0x000a, 0x1c04: 0x000a, + 0x1c08: 0x003a, 0x1c09: 0x002a, 0x1c0a: 0x003a, 0x1c0b: 0x002a, + 0x1c0c: 0x003a, 0x1c0d: 0x002a, 0x1c0e: 0x003a, 0x1c0f: 0x002a, 0x1c10: 0x003a, 0x1c11: 0x002a, + 0x1c12: 0x000a, 0x1c13: 0x000a, 0x1c14: 0x003a, 0x1c15: 0x002a, 0x1c16: 0x003a, 0x1c17: 0x002a, + 0x1c18: 0x003a, 0x1c19: 0x002a, 0x1c1a: 0x003a, 0x1c1b: 0x002a, 0x1c1c: 0x000a, 0x1c1d: 0x000a, + 0x1c1e: 0x000a, 0x1c1f: 0x000a, 0x1c20: 0x000a, + 0x1c2a: 0x000c, 0x1c2b: 0x000c, 0x1c2c: 0x000c, 0x1c2d: 0x000c, + 0x1c30: 0x000a, + 0x1c36: 0x000a, 0x1c37: 0x000a, + 0x1c3d: 0x000a, 0x1c3e: 0x000a, 0x1c3f: 0x000a, + // Block 0x71, offset 0x1c40 + 0x1c59: 0x000c, 0x1c5a: 0x000c, 0x1c5b: 0x000a, 0x1c5c: 0x000a, + 0x1c60: 0x000a, + // Block 0x72, offset 0x1c80 + 0x1cbb: 0x000a, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x000a, 0x1cc1: 0x000a, 0x1cc2: 0x000a, 0x1cc3: 0x000a, 0x1cc4: 0x000a, 0x1cc5: 0x000a, + 0x1cc6: 0x000a, 0x1cc7: 0x000a, 0x1cc8: 0x000a, 0x1cc9: 0x000a, 0x1cca: 0x000a, 0x1ccb: 0x000a, + 0x1ccc: 0x000a, 0x1ccd: 0x000a, 0x1cce: 0x000a, 0x1ccf: 0x000a, 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, 0x1ce0: 0x000a, 0x1ce1: 0x000a, 0x1ce2: 0x000a, 0x1ce3: 0x000a, + // Block 0x74, offset 0x1d00 + 0x1d1d: 0x000a, + 0x1d1e: 0x000a, + // Block 0x75, offset 0x1d40 + 0x1d50: 0x000a, 0x1d51: 0x000a, + 0x1d52: 0x000a, 0x1d53: 0x000a, 0x1d54: 0x000a, 0x1d55: 0x000a, 0x1d56: 0x000a, 0x1d57: 0x000a, + 0x1d58: 0x000a, 0x1d59: 0x000a, 0x1d5a: 0x000a, 0x1d5b: 0x000a, 0x1d5c: 0x000a, 0x1d5d: 0x000a, + 0x1d5e: 0x000a, 0x1d5f: 0x000a, + 0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a, + // Block 0x76, offset 0x1d80 + 0x1db1: 0x000a, 0x1db2: 0x000a, 0x1db3: 0x000a, 0x1db4: 0x000a, 0x1db5: 0x000a, + 0x1db6: 0x000a, 0x1db7: 0x000a, 0x1db8: 0x000a, 0x1db9: 0x000a, 0x1dba: 0x000a, 0x1dbb: 0x000a, + 0x1dbc: 0x000a, 0x1dbd: 0x000a, 0x1dbe: 0x000a, 0x1dbf: 0x000a, + // Block 0x77, offset 0x1dc0 + 0x1dcc: 0x000a, 0x1dcd: 0x000a, 0x1dce: 0x000a, 0x1dcf: 0x000a, + // Block 0x78, offset 0x1e00 + 0x1e37: 0x000a, 0x1e38: 0x000a, 0x1e39: 0x000a, 0x1e3a: 0x000a, + // Block 0x79, offset 0x1e40 + 0x1e5e: 0x000a, 0x1e5f: 0x000a, + 0x1e7f: 0x000a, + // Block 0x7a, offset 0x1e80 + 0x1e90: 0x000a, 0x1e91: 0x000a, + 0x1e92: 0x000a, 0x1e93: 0x000a, 0x1e94: 0x000a, 0x1e95: 0x000a, 0x1e96: 0x000a, 0x1e97: 0x000a, + 0x1e98: 0x000a, 0x1e99: 0x000a, 0x1e9a: 0x000a, 0x1e9b: 0x000a, 0x1e9c: 0x000a, 0x1e9d: 0x000a, + 0x1e9e: 0x000a, 0x1e9f: 0x000a, 0x1ea0: 0x000a, 0x1ea1: 0x000a, 0x1ea2: 0x000a, 0x1ea3: 0x000a, + 0x1ea4: 0x000a, 0x1ea5: 0x000a, 0x1ea6: 0x000a, 0x1ea7: 0x000a, 0x1ea8: 0x000a, 0x1ea9: 0x000a, + 0x1eaa: 0x000a, 0x1eab: 0x000a, 0x1eac: 0x000a, 0x1ead: 0x000a, 0x1eae: 0x000a, 0x1eaf: 0x000a, + 0x1eb0: 0x000a, 0x1eb1: 0x000a, 0x1eb2: 0x000a, 0x1eb3: 0x000a, 0x1eb4: 0x000a, 0x1eb5: 0x000a, + 0x1eb6: 0x000a, 0x1eb7: 0x000a, 0x1eb8: 0x000a, 0x1eb9: 0x000a, 0x1eba: 0x000a, 0x1ebb: 0x000a, + 0x1ebc: 0x000a, 0x1ebd: 0x000a, 0x1ebe: 0x000a, 0x1ebf: 0x000a, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0x000a, 0x1ec1: 0x000a, 0x1ec2: 0x000a, 0x1ec3: 0x000a, 0x1ec4: 0x000a, 0x1ec5: 0x000a, + 0x1ec6: 0x000a, + // Block 0x7c, offset 0x1f00 + 0x1f0d: 0x000a, 0x1f0e: 0x000a, 0x1f0f: 0x000a, + // Block 0x7d, offset 0x1f40 + 0x1f6f: 0x000c, + 0x1f70: 0x000c, 0x1f71: 0x000c, 0x1f72: 0x000c, 0x1f73: 0x000a, 0x1f74: 0x000c, 0x1f75: 0x000c, + 0x1f76: 0x000c, 0x1f77: 0x000c, 0x1f78: 0x000c, 0x1f79: 0x000c, 0x1f7a: 0x000c, 0x1f7b: 0x000c, + 0x1f7c: 0x000c, 0x1f7d: 0x000c, 0x1f7e: 0x000a, 0x1f7f: 0x000a, + // Block 0x7e, offset 0x1f80 + 0x1f9e: 0x000c, 0x1f9f: 0x000c, + // Block 0x7f, offset 0x1fc0 + 0x1ff0: 0x000c, 0x1ff1: 0x000c, + // Block 0x80, offset 0x2000 + 0x2000: 0x000a, 0x2001: 0x000a, 0x2002: 0x000a, 0x2003: 0x000a, 0x2004: 0x000a, 0x2005: 0x000a, + 0x2006: 0x000a, 0x2007: 0x000a, 0x2008: 0x000a, 0x2009: 0x000a, 0x200a: 0x000a, 0x200b: 0x000a, + 0x200c: 0x000a, 0x200d: 0x000a, 0x200e: 0x000a, 0x200f: 0x000a, 0x2010: 0x000a, 0x2011: 0x000a, + 0x2012: 0x000a, 0x2013: 0x000a, 0x2014: 0x000a, 0x2015: 0x000a, 0x2016: 0x000a, 0x2017: 0x000a, + 0x2018: 0x000a, 0x2019: 0x000a, 0x201a: 0x000a, 0x201b: 0x000a, 0x201c: 0x000a, 0x201d: 0x000a, + 0x201e: 0x000a, 0x201f: 0x000a, 0x2020: 0x000a, 0x2021: 0x000a, + // Block 0x81, offset 0x2040 + 0x2048: 0x000a, + // Block 0x82, offset 0x2080 + 0x2082: 0x000c, + 0x2086: 0x000c, 0x208b: 0x000c, + 0x20a5: 0x000c, 0x20a6: 0x000c, 0x20a8: 0x000a, 0x20a9: 0x000a, + 0x20aa: 0x000a, 0x20ab: 0x000a, 0x20ac: 0x000c, + 0x20b8: 0x0004, 0x20b9: 0x0004, + // Block 0x83, offset 0x20c0 + 0x20f4: 0x000a, 0x20f5: 0x000a, + 0x20f6: 0x000a, 0x20f7: 0x000a, + // Block 0x84, offset 0x2100 + 0x2104: 0x000c, 0x2105: 0x000c, + 0x2120: 0x000c, 0x2121: 0x000c, 0x2122: 0x000c, 0x2123: 0x000c, + 0x2124: 0x000c, 0x2125: 0x000c, 0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c, + 0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c, 0x212e: 0x000c, 0x212f: 0x000c, + 0x2130: 0x000c, 0x2131: 0x000c, + 0x213f: 0x000c, + // Block 0x85, offset 0x2140 + 0x2166: 0x000c, 0x2167: 0x000c, 0x2168: 0x000c, 0x2169: 0x000c, + 0x216a: 0x000c, 0x216b: 0x000c, 0x216c: 0x000c, 0x216d: 0x000c, + // Block 0x86, offset 0x2180 + 0x2187: 0x000c, 0x2188: 0x000c, 0x2189: 0x000c, 0x218a: 0x000c, 0x218b: 0x000c, + 0x218c: 0x000c, 0x218d: 0x000c, 0x218e: 0x000c, 0x218f: 0x000c, 0x2190: 0x000c, 0x2191: 0x000c, + // Block 0x87, offset 0x21c0 + 0x21c0: 0x000c, 0x21c1: 0x000c, 0x21c2: 0x000c, + 0x21f3: 0x000c, + 0x21f6: 0x000c, 0x21f7: 0x000c, 0x21f8: 0x000c, 0x21f9: 0x000c, + 0x21fc: 0x000c, 0x21fd: 0x000c, + // Block 0x88, offset 0x2200 + 0x2225: 0x000c, + // Block 0x89, offset 0x2240 + 0x2269: 0x000c, + 0x226a: 0x000c, 0x226b: 0x000c, 0x226c: 0x000c, 0x226d: 0x000c, 0x226e: 0x000c, + 0x2271: 0x000c, 0x2272: 0x000c, 0x2275: 0x000c, + 0x2276: 0x000c, + // Block 0x8a, offset 0x2280 + 0x2283: 0x000c, + 0x228c: 0x000c, + 0x22bc: 0x000c, + // Block 0x8b, offset 0x22c0 + 0x22f0: 0x000c, 0x22f2: 0x000c, 0x22f3: 0x000c, 0x22f4: 0x000c, + 0x22f7: 0x000c, 0x22f8: 0x000c, + 0x22fe: 0x000c, 0x22ff: 0x000c, + // Block 0x8c, offset 0x2300 + 0x2301: 0x000c, + 0x232c: 0x000c, 0x232d: 0x000c, + 0x2336: 0x000c, + // Block 0x8d, offset 0x2340 + 0x236a: 0x000a, 0x236b: 0x000a, + // Block 0x8e, offset 0x2380 + 0x23a5: 0x000c, 0x23a8: 0x000c, + 0x23ad: 0x000c, + // Block 0x8f, offset 0x23c0 + 0x23dd: 0x0001, + 0x23de: 0x000c, 0x23df: 0x0001, 0x23e0: 0x0001, 0x23e1: 0x0001, 0x23e2: 0x0001, 0x23e3: 0x0001, + 0x23e4: 0x0001, 0x23e5: 0x0001, 0x23e6: 0x0001, 0x23e7: 0x0001, 0x23e8: 0x0001, 0x23e9: 0x0003, + 0x23ea: 0x0001, 0x23eb: 0x0001, 0x23ec: 0x0001, 0x23ed: 0x0001, 0x23ee: 0x0001, 0x23ef: 0x0001, + 0x23f0: 0x0001, 0x23f1: 0x0001, 0x23f2: 0x0001, 0x23f3: 0x0001, 0x23f4: 0x0001, 0x23f5: 0x0001, + 0x23f6: 0x0001, 0x23f7: 0x0001, 0x23f8: 0x0001, 0x23f9: 0x0001, 0x23fa: 0x0001, 0x23fb: 0x0001, + 0x23fc: 0x0001, 0x23fd: 0x0001, 0x23fe: 0x0001, 0x23ff: 0x0001, + // Block 0x90, offset 0x2400 + 0x2400: 0x0001, 0x2401: 0x0001, 0x2402: 0x0001, 0x2403: 0x0001, 0x2404: 0x0001, 0x2405: 0x0001, + 0x2406: 0x0001, 0x2407: 0x0001, 0x2408: 0x0001, 0x2409: 0x0001, 0x240a: 0x0001, 0x240b: 0x0001, + 0x240c: 0x0001, 0x240d: 0x0001, 0x240e: 0x0001, 0x240f: 0x0001, 0x2410: 0x000d, 0x2411: 0x000d, + 0x2412: 0x000d, 0x2413: 0x000d, 0x2414: 0x000d, 0x2415: 0x000d, 0x2416: 0x000d, 0x2417: 0x000d, + 0x2418: 0x000d, 0x2419: 0x000d, 0x241a: 0x000d, 0x241b: 0x000d, 0x241c: 0x000d, 0x241d: 0x000d, + 0x241e: 0x000d, 0x241f: 0x000d, 0x2420: 0x000d, 0x2421: 0x000d, 0x2422: 0x000d, 0x2423: 0x000d, + 0x2424: 0x000d, 0x2425: 0x000d, 0x2426: 0x000d, 0x2427: 0x000d, 0x2428: 0x000d, 0x2429: 0x000d, + 0x242a: 0x000d, 0x242b: 0x000d, 0x242c: 0x000d, 0x242d: 0x000d, 0x242e: 0x000d, 0x242f: 0x000d, + 0x2430: 0x000d, 0x2431: 0x000d, 0x2432: 0x000d, 0x2433: 0x000d, 0x2434: 0x000d, 0x2435: 0x000d, + 0x2436: 0x000d, 0x2437: 0x000d, 0x2438: 0x000d, 0x2439: 0x000d, 0x243a: 0x000d, 0x243b: 0x000d, + 0x243c: 0x000d, 0x243d: 0x000d, 0x243e: 0x000d, 0x243f: 0x000d, + // Block 0x91, offset 0x2440 + 0x2440: 0x000d, 0x2441: 0x000d, 0x2442: 0x000d, 0x2443: 0x000d, 0x2444: 0x000d, 0x2445: 0x000d, + 0x2446: 0x000d, 0x2447: 0x000d, 0x2448: 0x000d, 0x2449: 0x000d, 0x244a: 0x000d, 0x244b: 0x000d, + 0x244c: 0x000d, 0x244d: 0x000d, 0x244e: 0x000d, 0x244f: 0x000d, 0x2450: 0x000d, 0x2451: 0x000d, + 0x2452: 0x000d, 0x2453: 0x000d, 0x2454: 0x000d, 0x2455: 0x000d, 0x2456: 0x000d, 0x2457: 0x000d, + 0x2458: 0x000d, 0x2459: 0x000d, 0x245a: 0x000d, 0x245b: 0x000d, 0x245c: 0x000d, 0x245d: 0x000d, + 0x245e: 0x000d, 0x245f: 0x000d, 0x2460: 0x000d, 0x2461: 0x000d, 0x2462: 0x000d, 0x2463: 0x000d, + 0x2464: 0x000d, 0x2465: 0x000d, 0x2466: 0x000d, 0x2467: 0x000d, 0x2468: 0x000d, 0x2469: 0x000d, + 0x246a: 0x000d, 0x246b: 0x000d, 0x246c: 0x000d, 0x246d: 0x000d, 0x246e: 0x000d, 0x246f: 0x000d, + 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: 0x000a, 0x247f: 0x000a, + // 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: 0x000b, 0x2491: 0x000b, + 0x2492: 0x000b, 0x2493: 0x000b, 0x2494: 0x000b, 0x2495: 0x000b, 0x2496: 0x000b, 0x2497: 0x000b, + 0x2498: 0x000b, 0x2499: 0x000b, 0x249a: 0x000b, 0x249b: 0x000b, 0x249c: 0x000b, 0x249d: 0x000b, + 0x249e: 0x000b, 0x249f: 0x000b, 0x24a0: 0x000b, 0x24a1: 0x000b, 0x24a2: 0x000b, 0x24a3: 0x000b, + 0x24a4: 0x000b, 0x24a5: 0x000b, 0x24a6: 0x000b, 0x24a7: 0x000b, 0x24a8: 0x000b, 0x24a9: 0x000b, + 0x24aa: 0x000b, 0x24ab: 0x000b, 0x24ac: 0x000b, 0x24ad: 0x000b, 0x24ae: 0x000b, 0x24af: 0x000b, + 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: 0x000a, 0x24be: 0x000d, 0x24bf: 0x000d, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x000c, 0x24c1: 0x000c, 0x24c2: 0x000c, 0x24c3: 0x000c, 0x24c4: 0x000c, 0x24c5: 0x000c, + 0x24c6: 0x000c, 0x24c7: 0x000c, 0x24c8: 0x000c, 0x24c9: 0x000c, 0x24ca: 0x000c, 0x24cb: 0x000c, + 0x24cc: 0x000c, 0x24cd: 0x000c, 0x24ce: 0x000c, 0x24cf: 0x000c, 0x24d0: 0x000a, 0x24d1: 0x000a, + 0x24d2: 0x000a, 0x24d3: 0x000a, 0x24d4: 0x000a, 0x24d5: 0x000a, 0x24d6: 0x000a, 0x24d7: 0x000a, + 0x24d8: 0x000a, 0x24d9: 0x000a, + 0x24e0: 0x000c, 0x24e1: 0x000c, 0x24e2: 0x000c, 0x24e3: 0x000c, + 0x24e4: 0x000c, 0x24e5: 0x000c, 0x24e6: 0x000c, 0x24e7: 0x000c, 0x24e8: 0x000c, 0x24e9: 0x000c, + 0x24ea: 0x000c, 0x24eb: 0x000c, 0x24ec: 0x000c, 0x24ed: 0x000c, 0x24ee: 0x000c, 0x24ef: 0x000c, + 0x24f0: 0x000a, 0x24f1: 0x000a, 0x24f2: 0x000a, 0x24f3: 0x000a, 0x24f4: 0x000a, 0x24f5: 0x000a, + 0x24f6: 0x000a, 0x24f7: 0x000a, 0x24f8: 0x000a, 0x24f9: 0x000a, 0x24fa: 0x000a, 0x24fb: 0x000a, + 0x24fc: 0x000a, 0x24fd: 0x000a, 0x24fe: 0x000a, 0x24ff: 0x000a, + // Block 0x94, offset 0x2500 + 0x2500: 0x000a, 0x2501: 0x000a, 0x2502: 0x000a, 0x2503: 0x000a, 0x2504: 0x000a, 0x2505: 0x000a, + 0x2506: 0x000a, 0x2507: 0x000a, 0x2508: 0x000a, 0x2509: 0x000a, 0x250a: 0x000a, 0x250b: 0x000a, + 0x250c: 0x000a, 0x250d: 0x000a, 0x250e: 0x000a, 0x250f: 0x000a, 0x2510: 0x0006, 0x2511: 0x000a, + 0x2512: 0x0006, 0x2514: 0x000a, 0x2515: 0x0006, 0x2516: 0x000a, 0x2517: 0x000a, + 0x2518: 0x000a, 0x2519: 0x009a, 0x251a: 0x008a, 0x251b: 0x007a, 0x251c: 0x006a, 0x251d: 0x009a, + 0x251e: 0x008a, 0x251f: 0x0004, 0x2520: 0x000a, 0x2521: 0x000a, 0x2522: 0x0003, 0x2523: 0x0003, + 0x2524: 0x000a, 0x2525: 0x000a, 0x2526: 0x000a, 0x2528: 0x000a, 0x2529: 0x0004, + 0x252a: 0x0004, 0x252b: 0x000a, + 0x2530: 0x000d, 0x2531: 0x000d, 0x2532: 0x000d, 0x2533: 0x000d, 0x2534: 0x000d, 0x2535: 0x000d, + 0x2536: 0x000d, 0x2537: 0x000d, 0x2538: 0x000d, 0x2539: 0x000d, 0x253a: 0x000d, 0x253b: 0x000d, + 0x253c: 0x000d, 0x253d: 0x000d, 0x253e: 0x000d, 0x253f: 0x000d, + // Block 0x95, offset 0x2540 + 0x2540: 0x000d, 0x2541: 0x000d, 0x2542: 0x000d, 0x2543: 0x000d, 0x2544: 0x000d, 0x2545: 0x000d, + 0x2546: 0x000d, 0x2547: 0x000d, 0x2548: 0x000d, 0x2549: 0x000d, 0x254a: 0x000d, 0x254b: 0x000d, + 0x254c: 0x000d, 0x254d: 0x000d, 0x254e: 0x000d, 0x254f: 0x000d, 0x2550: 0x000d, 0x2551: 0x000d, + 0x2552: 0x000d, 0x2553: 0x000d, 0x2554: 0x000d, 0x2555: 0x000d, 0x2556: 0x000d, 0x2557: 0x000d, + 0x2558: 0x000d, 0x2559: 0x000d, 0x255a: 0x000d, 0x255b: 0x000d, 0x255c: 0x000d, 0x255d: 0x000d, + 0x255e: 0x000d, 0x255f: 0x000d, 0x2560: 0x000d, 0x2561: 0x000d, 0x2562: 0x000d, 0x2563: 0x000d, + 0x2564: 0x000d, 0x2565: 0x000d, 0x2566: 0x000d, 0x2567: 0x000d, 0x2568: 0x000d, 0x2569: 0x000d, + 0x256a: 0x000d, 0x256b: 0x000d, 0x256c: 0x000d, 0x256d: 0x000d, 0x256e: 0x000d, 0x256f: 0x000d, + 0x2570: 0x000d, 0x2571: 0x000d, 0x2572: 0x000d, 0x2573: 0x000d, 0x2574: 0x000d, 0x2575: 0x000d, + 0x2576: 0x000d, 0x2577: 0x000d, 0x2578: 0x000d, 0x2579: 0x000d, 0x257a: 0x000d, 0x257b: 0x000d, + 0x257c: 0x000d, 0x257d: 0x000d, 0x257e: 0x000d, 0x257f: 0x000b, + // Block 0x96, offset 0x2580 + 0x2581: 0x000a, 0x2582: 0x000a, 0x2583: 0x0004, 0x2584: 0x0004, 0x2585: 0x0004, + 0x2586: 0x000a, 0x2587: 0x000a, 0x2588: 0x003a, 0x2589: 0x002a, 0x258a: 0x000a, 0x258b: 0x0003, + 0x258c: 0x0006, 0x258d: 0x0003, 0x258e: 0x0006, 0x258f: 0x0006, 0x2590: 0x0002, 0x2591: 0x0002, + 0x2592: 0x0002, 0x2593: 0x0002, 0x2594: 0x0002, 0x2595: 0x0002, 0x2596: 0x0002, 0x2597: 0x0002, + 0x2598: 0x0002, 0x2599: 0x0002, 0x259a: 0x0006, 0x259b: 0x000a, 0x259c: 0x000a, 0x259d: 0x000a, + 0x259e: 0x000a, 0x259f: 0x000a, 0x25a0: 0x000a, + 0x25bb: 0x005a, + 0x25bc: 0x000a, 0x25bd: 0x004a, 0x25be: 0x000a, 0x25bf: 0x000a, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x000a, + 0x25db: 0x005a, 0x25dc: 0x000a, 0x25dd: 0x004a, + 0x25de: 0x000a, 0x25df: 0x00fa, 0x25e0: 0x00ea, 0x25e1: 0x000a, 0x25e2: 0x003a, 0x25e3: 0x002a, + 0x25e4: 0x000a, 0x25e5: 0x000a, + // Block 0x98, offset 0x2600 + 0x2620: 0x0004, 0x2621: 0x0004, 0x2622: 0x000a, 0x2623: 0x000a, + 0x2624: 0x000a, 0x2625: 0x0004, 0x2626: 0x0004, 0x2628: 0x000a, 0x2629: 0x000a, + 0x262a: 0x000a, 0x262b: 0x000a, 0x262c: 0x000a, 0x262d: 0x000a, 0x262e: 0x000a, + 0x2630: 0x000b, 0x2631: 0x000b, 0x2632: 0x000b, 0x2633: 0x000b, 0x2634: 0x000b, 0x2635: 0x000b, + 0x2636: 0x000b, 0x2637: 0x000b, 0x2638: 0x000b, 0x2639: 0x000a, 0x263a: 0x000a, 0x263b: 0x000a, + 0x263c: 0x000a, 0x263d: 0x000a, 0x263e: 0x000b, 0x263f: 0x000b, + // Block 0x99, offset 0x2640 + 0x2641: 0x000a, + // Block 0x9a, offset 0x2680 + 0x2680: 0x000a, 0x2681: 0x000a, 0x2682: 0x000a, 0x2683: 0x000a, 0x2684: 0x000a, 0x2685: 0x000a, + 0x2686: 0x000a, 0x2687: 0x000a, 0x2688: 0x000a, 0x2689: 0x000a, 0x268a: 0x000a, 0x268b: 0x000a, + 0x268c: 0x000a, 0x2690: 0x000a, 0x2691: 0x000a, + 0x2692: 0x000a, 0x2693: 0x000a, 0x2694: 0x000a, 0x2695: 0x000a, 0x2696: 0x000a, 0x2697: 0x000a, + 0x2698: 0x000a, 0x2699: 0x000a, 0x269a: 0x000a, 0x269b: 0x000a, 0x269c: 0x000a, + 0x26a0: 0x000a, + // Block 0x9b, offset 0x26c0 + 0x26fd: 0x000c, + // Block 0x9c, offset 0x2700 + 0x2720: 0x000c, 0x2721: 0x0002, 0x2722: 0x0002, 0x2723: 0x0002, + 0x2724: 0x0002, 0x2725: 0x0002, 0x2726: 0x0002, 0x2727: 0x0002, 0x2728: 0x0002, 0x2729: 0x0002, + 0x272a: 0x0002, 0x272b: 0x0002, 0x272c: 0x0002, 0x272d: 0x0002, 0x272e: 0x0002, 0x272f: 0x0002, + 0x2730: 0x0002, 0x2731: 0x0002, 0x2732: 0x0002, 0x2733: 0x0002, 0x2734: 0x0002, 0x2735: 0x0002, + 0x2736: 0x0002, 0x2737: 0x0002, 0x2738: 0x0002, 0x2739: 0x0002, 0x273a: 0x0002, 0x273b: 0x0002, + // Block 0x9d, offset 0x2740 + 0x2776: 0x000c, 0x2777: 0x000c, 0x2778: 0x000c, 0x2779: 0x000c, 0x277a: 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: 0x0001, 0x27a6: 0x0001, 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: 0x000a, 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: 0x0001, 0x27fa: 0x0001, 0x27fb: 0x0001, + 0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x0001, + // Block 0xa0, offset 0x2800 + 0x2800: 0x0001, 0x2801: 0x000c, 0x2802: 0x000c, 0x2803: 0x000c, 0x2804: 0x0001, 0x2805: 0x000c, + 0x2806: 0x000c, 0x2807: 0x0001, 0x2808: 0x0001, 0x2809: 0x0001, 0x280a: 0x0001, 0x280b: 0x0001, + 0x280c: 0x000c, 0x280d: 0x000c, 0x280e: 0x000c, 0x280f: 0x000c, 0x2810: 0x0001, 0x2811: 0x0001, + 0x2812: 0x0001, 0x2813: 0x0001, 0x2814: 0x0001, 0x2815: 0x0001, 0x2816: 0x0001, 0x2817: 0x0001, + 0x2818: 0x0001, 0x2819: 0x0001, 0x281a: 0x0001, 0x281b: 0x0001, 0x281c: 0x0001, 0x281d: 0x0001, + 0x281e: 0x0001, 0x281f: 0x0001, 0x2820: 0x0001, 0x2821: 0x0001, 0x2822: 0x0001, 0x2823: 0x0001, + 0x2824: 0x0001, 0x2825: 0x0001, 0x2826: 0x0001, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001, + 0x282a: 0x0001, 0x282b: 0x0001, 0x282c: 0x0001, 0x282d: 0x0001, 0x282e: 0x0001, 0x282f: 0x0001, + 0x2830: 0x0001, 0x2831: 0x0001, 0x2832: 0x0001, 0x2833: 0x0001, 0x2834: 0x0001, 0x2835: 0x0001, + 0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x000c, 0x2839: 0x000c, 0x283a: 0x000c, 0x283b: 0x0001, + 0x283c: 0x0001, 0x283d: 0x0001, 0x283e: 0x0001, 0x283f: 0x000c, + // 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: 0x0001, 0x2861: 0x0001, 0x2862: 0x0001, 0x2863: 0x0001, + 0x2864: 0x0001, 0x2865: 0x000c, 0x2866: 0x000c, 0x2867: 0x0001, 0x2868: 0x0001, 0x2869: 0x0001, + 0x286a: 0x0001, 0x286b: 0x0001, 0x286c: 0x0001, 0x286d: 0x0001, 0x286e: 0x0001, 0x286f: 0x0001, + 0x2870: 0x0001, 0x2871: 0x0001, 0x2872: 0x0001, 0x2873: 0x0001, 0x2874: 0x0001, 0x2875: 0x0001, + 0x2876: 0x0001, 0x2877: 0x0001, 0x2878: 0x0001, 0x2879: 0x0001, 0x287a: 0x0001, 0x287b: 0x0001, + 0x287c: 0x0001, 0x287d: 0x0001, 0x287e: 0x0001, 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: 0x0001, 0x28b1: 0x0001, 0x28b2: 0x0001, 0x28b3: 0x0001, 0x28b4: 0x0001, 0x28b5: 0x0001, + 0x28b6: 0x0001, 0x28b7: 0x0001, 0x28b8: 0x0001, 0x28b9: 0x000a, 0x28ba: 0x000a, 0x28bb: 0x000a, + 0x28bc: 0x000a, 0x28bd: 0x000a, 0x28be: 0x000a, 0x28bf: 0x000a, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x000d, 0x28c1: 0x000d, 0x28c2: 0x000d, 0x28c3: 0x000d, 0x28c4: 0x000d, 0x28c5: 0x000d, + 0x28c6: 0x000d, 0x28c7: 0x000d, 0x28c8: 0x000d, 0x28c9: 0x000d, 0x28ca: 0x000d, 0x28cb: 0x000d, + 0x28cc: 0x000d, 0x28cd: 0x000d, 0x28ce: 0x000d, 0x28cf: 0x000d, 0x28d0: 0x000d, 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: 0x000c, 0x28e5: 0x000c, 0x28e6: 0x000c, 0x28e7: 0x000c, 0x28e8: 0x000d, 0x28e9: 0x000d, + 0x28ea: 0x000d, 0x28eb: 0x000d, 0x28ec: 0x000d, 0x28ed: 0x000d, 0x28ee: 0x000d, 0x28ef: 0x000d, + 0x28f0: 0x0005, 0x28f1: 0x0005, 0x28f2: 0x0005, 0x28f3: 0x0005, 0x28f4: 0x0005, 0x28f5: 0x0005, + 0x28f6: 0x0005, 0x28f7: 0x0005, 0x28f8: 0x0005, 0x28f9: 0x0005, 0x28fa: 0x000d, 0x28fb: 0x000d, + 0x28fc: 0x000d, 0x28fd: 0x000d, 0x28fe: 0x000d, 0x28ff: 0x000d, + // Block 0xa4, offset 0x2900 + 0x2900: 0x0001, 0x2901: 0x0001, 0x2902: 0x0001, 0x2903: 0x0001, 0x2904: 0x0001, 0x2905: 0x0001, + 0x2906: 0x0001, 0x2907: 0x0001, 0x2908: 0x0001, 0x2909: 0x0001, 0x290a: 0x0001, 0x290b: 0x0001, + 0x290c: 0x0001, 0x290d: 0x0001, 0x290e: 0x0001, 0x290f: 0x0001, 0x2910: 0x0001, 0x2911: 0x0001, + 0x2912: 0x0001, 0x2913: 0x0001, 0x2914: 0x0001, 0x2915: 0x0001, 0x2916: 0x0001, 0x2917: 0x0001, + 0x2918: 0x0001, 0x2919: 0x0001, 0x291a: 0x0001, 0x291b: 0x0001, 0x291c: 0x0001, 0x291d: 0x0001, + 0x291e: 0x0001, 0x291f: 0x0001, 0x2920: 0x0005, 0x2921: 0x0005, 0x2922: 0x0005, 0x2923: 0x0005, + 0x2924: 0x0005, 0x2925: 0x0005, 0x2926: 0x0005, 0x2927: 0x0005, 0x2928: 0x0005, 0x2929: 0x0005, + 0x292a: 0x0005, 0x292b: 0x0005, 0x292c: 0x0005, 0x292d: 0x0005, 0x292e: 0x0005, 0x292f: 0x0005, + 0x2930: 0x0005, 0x2931: 0x0005, 0x2932: 0x0005, 0x2933: 0x0005, 0x2934: 0x0005, 0x2935: 0x0005, + 0x2936: 0x0005, 0x2937: 0x0005, 0x2938: 0x0005, 0x2939: 0x0005, 0x293a: 0x0005, 0x293b: 0x0005, + 0x293c: 0x0005, 0x293d: 0x0005, 0x293e: 0x0005, 0x293f: 0x0001, + // Block 0xa5, offset 0x2940 + 0x2940: 0x0001, 0x2941: 0x0001, 0x2942: 0x0001, 0x2943: 0x0001, 0x2944: 0x0001, 0x2945: 0x0001, + 0x2946: 0x0001, 0x2947: 0x0001, 0x2948: 0x0001, 0x2949: 0x0001, 0x294a: 0x0001, 0x294b: 0x0001, + 0x294c: 0x0001, 0x294d: 0x0001, 0x294e: 0x0001, 0x294f: 0x0001, 0x2950: 0x0001, 0x2951: 0x0001, + 0x2952: 0x0001, 0x2953: 0x0001, 0x2954: 0x0001, 0x2955: 0x0001, 0x2956: 0x0001, 0x2957: 0x0001, + 0x2958: 0x0001, 0x2959: 0x0001, 0x295a: 0x0001, 0x295b: 0x0001, 0x295c: 0x0001, 0x295d: 0x0001, + 0x295e: 0x0001, 0x295f: 0x0001, 0x2960: 0x0001, 0x2961: 0x0001, 0x2962: 0x0001, 0x2963: 0x0001, + 0x2964: 0x0001, 0x2965: 0x0001, 0x2966: 0x0001, 0x2967: 0x0001, 0x2968: 0x0001, 0x2969: 0x0001, + 0x296a: 0x0001, 0x296b: 0x000c, 0x296c: 0x000c, 0x296d: 0x0001, 0x296e: 0x0001, 0x296f: 0x0001, + 0x2970: 0x0001, 0x2971: 0x0001, 0x2972: 0x0001, 0x2973: 0x0001, 0x2974: 0x0001, 0x2975: 0x0001, + 0x2976: 0x0001, 0x2977: 0x0001, 0x2978: 0x0001, 0x2979: 0x0001, 0x297a: 0x0001, 0x297b: 0x0001, + 0x297c: 0x0001, 0x297d: 0x0001, 0x297e: 0x0001, 0x297f: 0x0001, + // Block 0xa6, offset 0x2980 + 0x2980: 0x0001, 0x2981: 0x0001, 0x2982: 0x0001, 0x2983: 0x0001, 0x2984: 0x0001, 0x2985: 0x0001, + 0x2986: 0x0001, 0x2987: 0x0001, 0x2988: 0x0001, 0x2989: 0x0001, 0x298a: 0x0001, 0x298b: 0x0001, + 0x298c: 0x0001, 0x298d: 0x0001, 0x298e: 0x0001, 0x298f: 0x0001, 0x2990: 0x0001, 0x2991: 0x0001, + 0x2992: 0x0001, 0x2993: 0x0001, 0x2994: 0x0001, 0x2995: 0x0001, 0x2996: 0x0001, 0x2997: 0x0001, + 0x2998: 0x0001, 0x2999: 0x0001, 0x299a: 0x0001, 0x299b: 0x0001, 0x299c: 0x0001, 0x299d: 0x0001, + 0x299e: 0x0001, 0x299f: 0x0001, 0x29a0: 0x0001, 0x29a1: 0x0001, 0x29a2: 0x0001, 0x29a3: 0x0001, + 0x29a4: 0x0001, 0x29a5: 0x0001, 0x29a6: 0x0001, 0x29a7: 0x0001, 0x29a8: 0x0001, 0x29a9: 0x0001, + 0x29aa: 0x0001, 0x29ab: 0x0001, 0x29ac: 0x0001, 0x29ad: 0x0001, 0x29ae: 0x0001, 0x29af: 0x0001, + 0x29b0: 0x000d, 0x29b1: 0x000d, 0x29b2: 0x000d, 0x29b3: 0x000d, 0x29b4: 0x000d, 0x29b5: 0x000d, + 0x29b6: 0x000d, 0x29b7: 0x000d, 0x29b8: 0x000d, 0x29b9: 0x000d, 0x29ba: 0x000d, 0x29bb: 0x000d, + 0x29bc: 0x000d, 0x29bd: 0x000d, 0x29be: 0x000d, 0x29bf: 0x000d, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x000d, 0x29c1: 0x000d, 0x29c2: 0x000d, 0x29c3: 0x000d, 0x29c4: 0x000d, 0x29c5: 0x000d, + 0x29c6: 0x000c, 0x29c7: 0x000c, 0x29c8: 0x000c, 0x29c9: 0x000c, 0x29ca: 0x000c, 0x29cb: 0x000c, + 0x29cc: 0x000c, 0x29cd: 0x000c, 0x29ce: 0x000c, 0x29cf: 0x000c, 0x29d0: 0x000c, 0x29d1: 0x000d, + 0x29d2: 0x000d, 0x29d3: 0x000d, 0x29d4: 0x000d, 0x29d5: 0x000d, 0x29d6: 0x000d, 0x29d7: 0x000d, + 0x29d8: 0x000d, 0x29d9: 0x000d, 0x29da: 0x000d, 0x29db: 0x000d, 0x29dc: 0x000d, 0x29dd: 0x000d, + 0x29de: 0x000d, 0x29df: 0x000d, 0x29e0: 0x000d, 0x29e1: 0x000d, 0x29e2: 0x000d, 0x29e3: 0x000d, + 0x29e4: 0x000d, 0x29e5: 0x000d, 0x29e6: 0x000d, 0x29e7: 0x000d, 0x29e8: 0x000d, 0x29e9: 0x000d, + 0x29ea: 0x000d, 0x29eb: 0x000d, 0x29ec: 0x000d, 0x29ed: 0x000d, 0x29ee: 0x000d, 0x29ef: 0x000d, + 0x29f0: 0x0001, 0x29f1: 0x0001, 0x29f2: 0x0001, 0x29f3: 0x0001, 0x29f4: 0x0001, 0x29f5: 0x0001, + 0x29f6: 0x0001, 0x29f7: 0x0001, 0x29f8: 0x0001, 0x29f9: 0x0001, 0x29fa: 0x0001, 0x29fb: 0x0001, + 0x29fc: 0x0001, 0x29fd: 0x0001, 0x29fe: 0x0001, 0x29ff: 0x0001, + // Block 0xa8, offset 0x2a00 + 0x2a01: 0x000c, + 0x2a38: 0x000c, 0x2a39: 0x000c, 0x2a3a: 0x000c, 0x2a3b: 0x000c, + 0x2a3c: 0x000c, 0x2a3d: 0x000c, 0x2a3e: 0x000c, 0x2a3f: 0x000c, + // Block 0xa9, offset 0x2a40 + 0x2a40: 0x000c, 0x2a41: 0x000c, 0x2a42: 0x000c, 0x2a43: 0x000c, 0x2a44: 0x000c, 0x2a45: 0x000c, + 0x2a46: 0x000c, + 0x2a52: 0x000a, 0x2a53: 0x000a, 0x2a54: 0x000a, 0x2a55: 0x000a, 0x2a56: 0x000a, 0x2a57: 0x000a, + 0x2a58: 0x000a, 0x2a59: 0x000a, 0x2a5a: 0x000a, 0x2a5b: 0x000a, 0x2a5c: 0x000a, 0x2a5d: 0x000a, + 0x2a5e: 0x000a, 0x2a5f: 0x000a, 0x2a60: 0x000a, 0x2a61: 0x000a, 0x2a62: 0x000a, 0x2a63: 0x000a, + 0x2a64: 0x000a, 0x2a65: 0x000a, + 0x2a7f: 0x000c, + // Block 0xaa, offset 0x2a80 + 0x2a80: 0x000c, 0x2a81: 0x000c, + 0x2ab3: 0x000c, 0x2ab4: 0x000c, 0x2ab5: 0x000c, + 0x2ab6: 0x000c, 0x2ab9: 0x000c, 0x2aba: 0x000c, + // Block 0xab, offset 0x2ac0 + 0x2ac0: 0x000c, 0x2ac1: 0x000c, 0x2ac2: 0x000c, + 0x2ae7: 0x000c, 0x2ae8: 0x000c, 0x2ae9: 0x000c, + 0x2aea: 0x000c, 0x2aeb: 0x000c, 0x2aed: 0x000c, 0x2aee: 0x000c, 0x2aef: 0x000c, + 0x2af0: 0x000c, 0x2af1: 0x000c, 0x2af2: 0x000c, 0x2af3: 0x000c, 0x2af4: 0x000c, + // Block 0xac, offset 0x2b00 + 0x2b33: 0x000c, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x000c, 0x2b41: 0x000c, + 0x2b76: 0x000c, 0x2b77: 0x000c, 0x2b78: 0x000c, 0x2b79: 0x000c, 0x2b7a: 0x000c, 0x2b7b: 0x000c, + 0x2b7c: 0x000c, 0x2b7d: 0x000c, 0x2b7e: 0x000c, + // Block 0xae, offset 0x2b80 + 0x2b89: 0x000c, 0x2b8a: 0x000c, 0x2b8b: 0x000c, + 0x2b8c: 0x000c, 0x2b8f: 0x000c, + // Block 0xaf, offset 0x2bc0 + 0x2bef: 0x000c, + 0x2bf0: 0x000c, 0x2bf1: 0x000c, 0x2bf4: 0x000c, + 0x2bf6: 0x000c, 0x2bf7: 0x000c, + 0x2bfe: 0x000c, + // Block 0xb0, offset 0x2c00 + 0x2c1f: 0x000c, 0x2c23: 0x000c, + 0x2c24: 0x000c, 0x2c25: 0x000c, 0x2c26: 0x000c, 0x2c27: 0x000c, 0x2c28: 0x000c, 0x2c29: 0x000c, + 0x2c2a: 0x000c, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0x000c, + 0x2c66: 0x000c, 0x2c67: 0x000c, 0x2c68: 0x000c, 0x2c69: 0x000c, + 0x2c6a: 0x000c, 0x2c6b: 0x000c, 0x2c6c: 0x000c, + 0x2c70: 0x000c, 0x2c71: 0x000c, 0x2c72: 0x000c, 0x2c73: 0x000c, 0x2c74: 0x000c, + // Block 0xb2, offset 0x2c80 + 0x2cb8: 0x000c, 0x2cb9: 0x000c, 0x2cba: 0x000c, 0x2cbb: 0x000c, + 0x2cbc: 0x000c, 0x2cbd: 0x000c, 0x2cbe: 0x000c, 0x2cbf: 0x000c, + // Block 0xb3, offset 0x2cc0 + 0x2cc2: 0x000c, 0x2cc3: 0x000c, 0x2cc4: 0x000c, + 0x2cc6: 0x000c, + 0x2cde: 0x000c, + // Block 0xb4, offset 0x2d00 + 0x2d33: 0x000c, 0x2d34: 0x000c, 0x2d35: 0x000c, + 0x2d36: 0x000c, 0x2d37: 0x000c, 0x2d38: 0x000c, 0x2d3a: 0x000c, + 0x2d3f: 0x000c, + // Block 0xb5, offset 0x2d40 + 0x2d40: 0x000c, 0x2d42: 0x000c, 0x2d43: 0x000c, + // Block 0xb6, offset 0x2d80 + 0x2db2: 0x000c, 0x2db3: 0x000c, 0x2db4: 0x000c, 0x2db5: 0x000c, + 0x2dbc: 0x000c, 0x2dbd: 0x000c, 0x2dbf: 0x000c, + // Block 0xb7, offset 0x2dc0 + 0x2dc0: 0x000c, + 0x2ddc: 0x000c, 0x2ddd: 0x000c, + // Block 0xb8, offset 0x2e00 + 0x2e33: 0x000c, 0x2e34: 0x000c, 0x2e35: 0x000c, + 0x2e36: 0x000c, 0x2e37: 0x000c, 0x2e38: 0x000c, 0x2e39: 0x000c, 0x2e3a: 0x000c, + 0x2e3d: 0x000c, 0x2e3f: 0x000c, + // Block 0xb9, offset 0x2e40 + 0x2e40: 0x000c, + 0x2e60: 0x000a, 0x2e61: 0x000a, 0x2e62: 0x000a, 0x2e63: 0x000a, + 0x2e64: 0x000a, 0x2e65: 0x000a, 0x2e66: 0x000a, 0x2e67: 0x000a, 0x2e68: 0x000a, 0x2e69: 0x000a, + 0x2e6a: 0x000a, 0x2e6b: 0x000a, 0x2e6c: 0x000a, + // Block 0xba, offset 0x2e80 + 0x2eab: 0x000c, 0x2ead: 0x000c, + 0x2eb0: 0x000c, 0x2eb1: 0x000c, 0x2eb2: 0x000c, 0x2eb3: 0x000c, 0x2eb4: 0x000c, 0x2eb5: 0x000c, + 0x2eb7: 0x000c, + // Block 0xbb, offset 0x2ec0 + 0x2edd: 0x000c, + 0x2ede: 0x000c, 0x2edf: 0x000c, 0x2ee2: 0x000c, 0x2ee3: 0x000c, + 0x2ee4: 0x000c, 0x2ee5: 0x000c, 0x2ee7: 0x000c, 0x2ee8: 0x000c, 0x2ee9: 0x000c, + 0x2eea: 0x000c, 0x2eeb: 0x000c, + // Block 0xbc, offset 0x2f00 + 0x2f2f: 0x000c, + 0x2f30: 0x000c, 0x2f31: 0x000c, 0x2f32: 0x000c, 0x2f33: 0x000c, 0x2f34: 0x000c, 0x2f35: 0x000c, + 0x2f36: 0x000c, 0x2f37: 0x000c, 0x2f39: 0x000c, 0x2f3a: 0x000c, + // Block 0xbd, offset 0x2f40 + 0x2f7b: 0x000c, + 0x2f7c: 0x000c, 0x2f7e: 0x000c, + // Block 0xbe, offset 0x2f80 + 0x2f83: 0x000c, + // Block 0xbf, offset 0x2fc0 + 0x2fd4: 0x000c, 0x2fd5: 0x000c, 0x2fd6: 0x000c, 0x2fd7: 0x000c, + 0x2fda: 0x000c, 0x2fdb: 0x000c, + 0x2fe0: 0x000c, + // Block 0xc0, offset 0x3000 + 0x3001: 0x000c, 0x3002: 0x000c, 0x3003: 0x000c, 0x3004: 0x000c, 0x3005: 0x000c, + 0x3006: 0x000c, 0x3009: 0x000c, 0x300a: 0x000c, + 0x3033: 0x000c, 0x3034: 0x000c, 0x3035: 0x000c, + 0x3036: 0x000c, 0x3037: 0x000c, 0x3038: 0x000c, 0x303b: 0x000c, + 0x303c: 0x000c, 0x303d: 0x000c, 0x303e: 0x000c, + // Block 0xc1, offset 0x3040 + 0x3047: 0x000c, + 0x3051: 0x000c, + 0x3052: 0x000c, 0x3053: 0x000c, 0x3054: 0x000c, 0x3055: 0x000c, 0x3056: 0x000c, + 0x3059: 0x000c, 0x305a: 0x000c, 0x305b: 0x000c, + // Block 0xc2, offset 0x3080 + 0x308a: 0x000c, 0x308b: 0x000c, + 0x308c: 0x000c, 0x308d: 0x000c, 0x308e: 0x000c, 0x308f: 0x000c, 0x3090: 0x000c, 0x3091: 0x000c, + 0x3092: 0x000c, 0x3093: 0x000c, 0x3094: 0x000c, 0x3095: 0x000c, 0x3096: 0x000c, + 0x3098: 0x000c, 0x3099: 0x000c, + // Block 0xc3, offset 0x30c0 + 0x30f0: 0x000c, 0x30f1: 0x000c, 0x30f2: 0x000c, 0x30f3: 0x000c, 0x30f4: 0x000c, 0x30f5: 0x000c, + 0x30f6: 0x000c, 0x30f8: 0x000c, 0x30f9: 0x000c, 0x30fa: 0x000c, 0x30fb: 0x000c, + 0x30fc: 0x000c, 0x30fd: 0x000c, + // Block 0xc4, offset 0x3100 + 0x3112: 0x000c, 0x3113: 0x000c, 0x3114: 0x000c, 0x3115: 0x000c, 0x3116: 0x000c, 0x3117: 0x000c, + 0x3118: 0x000c, 0x3119: 0x000c, 0x311a: 0x000c, 0x311b: 0x000c, 0x311c: 0x000c, 0x311d: 0x000c, + 0x311e: 0x000c, 0x311f: 0x000c, 0x3120: 0x000c, 0x3121: 0x000c, 0x3122: 0x000c, 0x3123: 0x000c, + 0x3124: 0x000c, 0x3125: 0x000c, 0x3126: 0x000c, 0x3127: 0x000c, + 0x312a: 0x000c, 0x312b: 0x000c, 0x312c: 0x000c, 0x312d: 0x000c, 0x312e: 0x000c, 0x312f: 0x000c, + 0x3130: 0x000c, 0x3132: 0x000c, 0x3133: 0x000c, 0x3135: 0x000c, + 0x3136: 0x000c, + // Block 0xc5, offset 0x3140 + 0x3171: 0x000c, 0x3172: 0x000c, 0x3173: 0x000c, 0x3174: 0x000c, 0x3175: 0x000c, + 0x3176: 0x000c, 0x317a: 0x000c, + 0x317c: 0x000c, 0x317d: 0x000c, 0x317f: 0x000c, + // Block 0xc6, offset 0x3180 + 0x3180: 0x000c, 0x3181: 0x000c, 0x3182: 0x000c, 0x3183: 0x000c, 0x3184: 0x000c, 0x3185: 0x000c, + 0x3187: 0x000c, + // Block 0xc7, offset 0x31c0 + 0x31d0: 0x000c, 0x31d1: 0x000c, + 0x31d5: 0x000c, 0x31d7: 0x000c, + // Block 0xc8, offset 0x3200 + 0x3233: 0x000c, 0x3234: 0x000c, + // Block 0xc9, offset 0x3240 + 0x3255: 0x000a, 0x3256: 0x000a, 0x3257: 0x000a, + 0x3258: 0x000a, 0x3259: 0x000a, 0x325a: 0x000a, 0x325b: 0x000a, 0x325c: 0x000a, 0x325d: 0x0004, + 0x325e: 0x0004, 0x325f: 0x0004, 0x3260: 0x0004, 0x3261: 0x000a, 0x3262: 0x000a, 0x3263: 0x000a, + 0x3264: 0x000a, 0x3265: 0x000a, 0x3266: 0x000a, 0x3267: 0x000a, 0x3268: 0x000a, 0x3269: 0x000a, + 0x326a: 0x000a, 0x326b: 0x000a, 0x326c: 0x000a, 0x326d: 0x000a, 0x326e: 0x000a, 0x326f: 0x000a, + 0x3270: 0x000a, 0x3271: 0x000a, + // Block 0xca, offset 0x3280 + 0x32b0: 0x000c, 0x32b1: 0x000c, 0x32b2: 0x000c, 0x32b3: 0x000c, 0x32b4: 0x000c, + // Block 0xcb, offset 0x32c0 + 0x32f0: 0x000c, 0x32f1: 0x000c, 0x32f2: 0x000c, 0x32f3: 0x000c, 0x32f4: 0x000c, 0x32f5: 0x000c, + 0x32f6: 0x000c, + // Block 0xcc, offset 0x3300 + 0x330f: 0x000c, + // Block 0xcd, offset 0x3340 + 0x334f: 0x000c, 0x3350: 0x000c, 0x3351: 0x000c, + 0x3352: 0x000c, + // Block 0xce, offset 0x3380 + 0x33a2: 0x000a, + 0x33a4: 0x000c, + // Block 0xcf, offset 0x33c0 + 0x33dd: 0x000c, + 0x33de: 0x000c, 0x33e0: 0x000b, 0x33e1: 0x000b, 0x33e2: 0x000b, 0x33e3: 0x000b, + // Block 0xd0, offset 0x3400 + 0x3427: 0x000c, 0x3428: 0x000c, 0x3429: 0x000c, + 0x3433: 0x000b, 0x3434: 0x000b, 0x3435: 0x000b, + 0x3436: 0x000b, 0x3437: 0x000b, 0x3438: 0x000b, 0x3439: 0x000b, 0x343a: 0x000b, 0x343b: 0x000c, + 0x343c: 0x000c, 0x343d: 0x000c, 0x343e: 0x000c, 0x343f: 0x000c, + // Block 0xd1, offset 0x3440 + 0x3440: 0x000c, 0x3441: 0x000c, 0x3442: 0x000c, 0x3445: 0x000c, + 0x3446: 0x000c, 0x3447: 0x000c, 0x3448: 0x000c, 0x3449: 0x000c, 0x344a: 0x000c, 0x344b: 0x000c, + 0x346a: 0x000c, 0x346b: 0x000c, 0x346c: 0x000c, 0x346d: 0x000c, + // Block 0xd2, offset 0x3480 + 0x3480: 0x000a, 0x3481: 0x000a, 0x3482: 0x000c, 0x3483: 0x000c, 0x3484: 0x000c, 0x3485: 0x000a, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x000a, 0x34c1: 0x000a, 0x34c2: 0x000a, 0x34c3: 0x000a, 0x34c4: 0x000a, 0x34c5: 0x000a, + 0x34c6: 0x000a, 0x34c7: 0x000a, 0x34c8: 0x000a, 0x34c9: 0x000a, 0x34ca: 0x000a, 0x34cb: 0x000a, + 0x34cc: 0x000a, 0x34cd: 0x000a, 0x34ce: 0x000a, 0x34cf: 0x000a, 0x34d0: 0x000a, 0x34d1: 0x000a, + 0x34d2: 0x000a, 0x34d3: 0x000a, 0x34d4: 0x000a, 0x34d5: 0x000a, 0x34d6: 0x000a, + // Block 0xd4, offset 0x3500 + 0x351b: 0x000a, + // Block 0xd5, offset 0x3540 + 0x3555: 0x000a, + // Block 0xd6, offset 0x3580 + 0x358f: 0x000a, + // Block 0xd7, offset 0x35c0 + 0x35c9: 0x000a, + // Block 0xd8, offset 0x3600 + 0x3603: 0x000a, + 0x360e: 0x0002, 0x360f: 0x0002, 0x3610: 0x0002, 0x3611: 0x0002, + 0x3612: 0x0002, 0x3613: 0x0002, 0x3614: 0x0002, 0x3615: 0x0002, 0x3616: 0x0002, 0x3617: 0x0002, + 0x3618: 0x0002, 0x3619: 0x0002, 0x361a: 0x0002, 0x361b: 0x0002, 0x361c: 0x0002, 0x361d: 0x0002, + 0x361e: 0x0002, 0x361f: 0x0002, 0x3620: 0x0002, 0x3621: 0x0002, 0x3622: 0x0002, 0x3623: 0x0002, + 0x3624: 0x0002, 0x3625: 0x0002, 0x3626: 0x0002, 0x3627: 0x0002, 0x3628: 0x0002, 0x3629: 0x0002, + 0x362a: 0x0002, 0x362b: 0x0002, 0x362c: 0x0002, 0x362d: 0x0002, 0x362e: 0x0002, 0x362f: 0x0002, + 0x3630: 0x0002, 0x3631: 0x0002, 0x3632: 0x0002, 0x3633: 0x0002, 0x3634: 0x0002, 0x3635: 0x0002, + 0x3636: 0x0002, 0x3637: 0x0002, 0x3638: 0x0002, 0x3639: 0x0002, 0x363a: 0x0002, 0x363b: 0x0002, + 0x363c: 0x0002, 0x363d: 0x0002, 0x363e: 0x0002, 0x363f: 0x0002, + // Block 0xd9, offset 0x3640 + 0x3640: 0x000c, 0x3641: 0x000c, 0x3642: 0x000c, 0x3643: 0x000c, 0x3644: 0x000c, 0x3645: 0x000c, + 0x3646: 0x000c, 0x3647: 0x000c, 0x3648: 0x000c, 0x3649: 0x000c, 0x364a: 0x000c, 0x364b: 0x000c, + 0x364c: 0x000c, 0x364d: 0x000c, 0x364e: 0x000c, 0x364f: 0x000c, 0x3650: 0x000c, 0x3651: 0x000c, + 0x3652: 0x000c, 0x3653: 0x000c, 0x3654: 0x000c, 0x3655: 0x000c, 0x3656: 0x000c, 0x3657: 0x000c, + 0x3658: 0x000c, 0x3659: 0x000c, 0x365a: 0x000c, 0x365b: 0x000c, 0x365c: 0x000c, 0x365d: 0x000c, + 0x365e: 0x000c, 0x365f: 0x000c, 0x3660: 0x000c, 0x3661: 0x000c, 0x3662: 0x000c, 0x3663: 0x000c, + 0x3664: 0x000c, 0x3665: 0x000c, 0x3666: 0x000c, 0x3667: 0x000c, 0x3668: 0x000c, 0x3669: 0x000c, + 0x366a: 0x000c, 0x366b: 0x000c, 0x366c: 0x000c, 0x366d: 0x000c, 0x366e: 0x000c, 0x366f: 0x000c, + 0x3670: 0x000c, 0x3671: 0x000c, 0x3672: 0x000c, 0x3673: 0x000c, 0x3674: 0x000c, 0x3675: 0x000c, + 0x3676: 0x000c, 0x367b: 0x000c, + 0x367c: 0x000c, 0x367d: 0x000c, 0x367e: 0x000c, 0x367f: 0x000c, + // Block 0xda, offset 0x3680 + 0x3680: 0x000c, 0x3681: 0x000c, 0x3682: 0x000c, 0x3683: 0x000c, 0x3684: 0x000c, 0x3685: 0x000c, + 0x3686: 0x000c, 0x3687: 0x000c, 0x3688: 0x000c, 0x3689: 0x000c, 0x368a: 0x000c, 0x368b: 0x000c, + 0x368c: 0x000c, 0x368d: 0x000c, 0x368e: 0x000c, 0x368f: 0x000c, 0x3690: 0x000c, 0x3691: 0x000c, + 0x3692: 0x000c, 0x3693: 0x000c, 0x3694: 0x000c, 0x3695: 0x000c, 0x3696: 0x000c, 0x3697: 0x000c, + 0x3698: 0x000c, 0x3699: 0x000c, 0x369a: 0x000c, 0x369b: 0x000c, 0x369c: 0x000c, 0x369d: 0x000c, + 0x369e: 0x000c, 0x369f: 0x000c, 0x36a0: 0x000c, 0x36a1: 0x000c, 0x36a2: 0x000c, 0x36a3: 0x000c, + 0x36a4: 0x000c, 0x36a5: 0x000c, 0x36a6: 0x000c, 0x36a7: 0x000c, 0x36a8: 0x000c, 0x36a9: 0x000c, + 0x36aa: 0x000c, 0x36ab: 0x000c, 0x36ac: 0x000c, + 0x36b5: 0x000c, + // Block 0xdb, offset 0x36c0 + 0x36c4: 0x000c, + 0x36db: 0x000c, 0x36dc: 0x000c, 0x36dd: 0x000c, + 0x36de: 0x000c, 0x36df: 0x000c, 0x36e1: 0x000c, 0x36e2: 0x000c, 0x36e3: 0x000c, + 0x36e4: 0x000c, 0x36e5: 0x000c, 0x36e6: 0x000c, 0x36e7: 0x000c, 0x36e8: 0x000c, 0x36e9: 0x000c, + 0x36ea: 0x000c, 0x36eb: 0x000c, 0x36ec: 0x000c, 0x36ed: 0x000c, 0x36ee: 0x000c, 0x36ef: 0x000c, + // Block 0xdc, offset 0x3700 + 0x3700: 0x000c, 0x3701: 0x000c, 0x3702: 0x000c, 0x3703: 0x000c, 0x3704: 0x000c, 0x3705: 0x000c, + 0x3706: 0x000c, 0x3708: 0x000c, 0x3709: 0x000c, 0x370a: 0x000c, 0x370b: 0x000c, + 0x370c: 0x000c, 0x370d: 0x000c, 0x370e: 0x000c, 0x370f: 0x000c, 0x3710: 0x000c, 0x3711: 0x000c, + 0x3712: 0x000c, 0x3713: 0x000c, 0x3714: 0x000c, 0x3715: 0x000c, 0x3716: 0x000c, 0x3717: 0x000c, + 0x3718: 0x000c, 0x371b: 0x000c, 0x371c: 0x000c, 0x371d: 0x000c, + 0x371e: 0x000c, 0x371f: 0x000c, 0x3720: 0x000c, 0x3721: 0x000c, 0x3723: 0x000c, + 0x3724: 0x000c, 0x3726: 0x000c, 0x3727: 0x000c, 0x3728: 0x000c, 0x3729: 0x000c, + 0x372a: 0x000c, + // Block 0xdd, offset 0x3740 + 0x376c: 0x000c, 0x376d: 0x000c, 0x376e: 0x000c, 0x376f: 0x000c, + 0x377f: 0x0004, + // Block 0xde, offset 0x3780 + 0x3780: 0x0001, 0x3781: 0x0001, 0x3782: 0x0001, 0x3783: 0x0001, 0x3784: 0x0001, 0x3785: 0x0001, + 0x3786: 0x0001, 0x3787: 0x0001, 0x3788: 0x0001, 0x3789: 0x0001, 0x378a: 0x0001, 0x378b: 0x0001, + 0x378c: 0x0001, 0x378d: 0x0001, 0x378e: 0x0001, 0x378f: 0x0001, 0x3790: 0x000c, 0x3791: 0x000c, + 0x3792: 0x000c, 0x3793: 0x000c, 0x3794: 0x000c, 0x3795: 0x000c, 0x3796: 0x000c, 0x3797: 0x0001, + 0x3798: 0x0001, 0x3799: 0x0001, 0x379a: 0x0001, 0x379b: 0x0001, 0x379c: 0x0001, 0x379d: 0x0001, + 0x379e: 0x0001, 0x379f: 0x0001, 0x37a0: 0x0001, 0x37a1: 0x0001, 0x37a2: 0x0001, 0x37a3: 0x0001, + 0x37a4: 0x0001, 0x37a5: 0x0001, 0x37a6: 0x0001, 0x37a7: 0x0001, 0x37a8: 0x0001, 0x37a9: 0x0001, + 0x37aa: 0x0001, 0x37ab: 0x0001, 0x37ac: 0x0001, 0x37ad: 0x0001, 0x37ae: 0x0001, 0x37af: 0x0001, + 0x37b0: 0x0001, 0x37b1: 0x0001, 0x37b2: 0x0001, 0x37b3: 0x0001, 0x37b4: 0x0001, 0x37b5: 0x0001, + 0x37b6: 0x0001, 0x37b7: 0x0001, 0x37b8: 0x0001, 0x37b9: 0x0001, 0x37ba: 0x0001, 0x37bb: 0x0001, + 0x37bc: 0x0001, 0x37bd: 0x0001, 0x37be: 0x0001, 0x37bf: 0x0001, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x0001, 0x37c1: 0x0001, 0x37c2: 0x0001, 0x37c3: 0x0001, 0x37c4: 0x000c, 0x37c5: 0x000c, + 0x37c6: 0x000c, 0x37c7: 0x000c, 0x37c8: 0x000c, 0x37c9: 0x000c, 0x37ca: 0x000c, 0x37cb: 0x0001, + 0x37cc: 0x0001, 0x37cd: 0x0001, 0x37ce: 0x0001, 0x37cf: 0x0001, 0x37d0: 0x0001, 0x37d1: 0x0001, + 0x37d2: 0x0001, 0x37d3: 0x0001, 0x37d4: 0x0001, 0x37d5: 0x0001, 0x37d6: 0x0001, 0x37d7: 0x0001, + 0x37d8: 0x0001, 0x37d9: 0x0001, 0x37da: 0x0001, 0x37db: 0x0001, 0x37dc: 0x0001, 0x37dd: 0x0001, + 0x37de: 0x0001, 0x37df: 0x0001, 0x37e0: 0x0001, 0x37e1: 0x0001, 0x37e2: 0x0001, 0x37e3: 0x0001, + 0x37e4: 0x0001, 0x37e5: 0x0001, 0x37e6: 0x0001, 0x37e7: 0x0001, 0x37e8: 0x0001, 0x37e9: 0x0001, + 0x37ea: 0x0001, 0x37eb: 0x0001, 0x37ec: 0x0001, 0x37ed: 0x0001, 0x37ee: 0x0001, 0x37ef: 0x0001, + 0x37f0: 0x0001, 0x37f1: 0x0001, 0x37f2: 0x0001, 0x37f3: 0x0001, 0x37f4: 0x0001, 0x37f5: 0x0001, + 0x37f6: 0x0001, 0x37f7: 0x0001, 0x37f8: 0x0001, 0x37f9: 0x0001, 0x37fa: 0x0001, 0x37fb: 0x0001, + 0x37fc: 0x0001, 0x37fd: 0x0001, 0x37fe: 0x0001, 0x37ff: 0x0001, + // Block 0xe0, offset 0x3800 + 0x3800: 0x000d, 0x3801: 0x000d, 0x3802: 0x000d, 0x3803: 0x000d, 0x3804: 0x000d, 0x3805: 0x000d, + 0x3806: 0x000d, 0x3807: 0x000d, 0x3808: 0x000d, 0x3809: 0x000d, 0x380a: 0x000d, 0x380b: 0x000d, + 0x380c: 0x000d, 0x380d: 0x000d, 0x380e: 0x000d, 0x380f: 0x000d, 0x3810: 0x0001, 0x3811: 0x0001, + 0x3812: 0x0001, 0x3813: 0x0001, 0x3814: 0x0001, 0x3815: 0x0001, 0x3816: 0x0001, 0x3817: 0x0001, + 0x3818: 0x0001, 0x3819: 0x0001, 0x381a: 0x0001, 0x381b: 0x0001, 0x381c: 0x0001, 0x381d: 0x0001, + 0x381e: 0x0001, 0x381f: 0x0001, 0x3820: 0x0001, 0x3821: 0x0001, 0x3822: 0x0001, 0x3823: 0x0001, + 0x3824: 0x0001, 0x3825: 0x0001, 0x3826: 0x0001, 0x3827: 0x0001, 0x3828: 0x0001, 0x3829: 0x0001, + 0x382a: 0x0001, 0x382b: 0x0001, 0x382c: 0x0001, 0x382d: 0x0001, 0x382e: 0x0001, 0x382f: 0x0001, + 0x3830: 0x0001, 0x3831: 0x0001, 0x3832: 0x0001, 0x3833: 0x0001, 0x3834: 0x0001, 0x3835: 0x0001, + 0x3836: 0x0001, 0x3837: 0x0001, 0x3838: 0x0001, 0x3839: 0x0001, 0x383a: 0x0001, 0x383b: 0x0001, + 0x383c: 0x0001, 0x383d: 0x0001, 0x383e: 0x0001, 0x383f: 0x0001, + // Block 0xe1, offset 0x3840 + 0x3840: 0x000d, 0x3841: 0x000d, 0x3842: 0x000d, 0x3843: 0x000d, 0x3844: 0x000d, 0x3845: 0x000d, + 0x3846: 0x000d, 0x3847: 0x000d, 0x3848: 0x000d, 0x3849: 0x000d, 0x384a: 0x000d, 0x384b: 0x000d, + 0x384c: 0x000d, 0x384d: 0x000d, 0x384e: 0x000d, 0x384f: 0x000d, 0x3850: 0x000d, 0x3851: 0x000d, + 0x3852: 0x000d, 0x3853: 0x000d, 0x3854: 0x000d, 0x3855: 0x000d, 0x3856: 0x000d, 0x3857: 0x000d, + 0x3858: 0x000d, 0x3859: 0x000d, 0x385a: 0x000d, 0x385b: 0x000d, 0x385c: 0x000d, 0x385d: 0x000d, + 0x385e: 0x000d, 0x385f: 0x000d, 0x3860: 0x000d, 0x3861: 0x000d, 0x3862: 0x000d, 0x3863: 0x000d, + 0x3864: 0x000d, 0x3865: 0x000d, 0x3866: 0x000d, 0x3867: 0x000d, 0x3868: 0x000d, 0x3869: 0x000d, + 0x386a: 0x000d, 0x386b: 0x000d, 0x386c: 0x000d, 0x386d: 0x000d, 0x386e: 0x000d, 0x386f: 0x000d, + 0x3870: 0x000a, 0x3871: 0x000a, 0x3872: 0x000d, 0x3873: 0x000d, 0x3874: 0x000d, 0x3875: 0x000d, + 0x3876: 0x000d, 0x3877: 0x000d, 0x3878: 0x000d, 0x3879: 0x000d, 0x387a: 0x000d, 0x387b: 0x000d, + 0x387c: 0x000d, 0x387d: 0x000d, 0x387e: 0x000d, 0x387f: 0x000d, + // 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, 0x3896: 0x000a, 0x3897: 0x000a, + 0x3898: 0x000a, 0x3899: 0x000a, 0x389a: 0x000a, 0x389b: 0x000a, 0x389c: 0x000a, 0x389d: 0x000a, + 0x389e: 0x000a, 0x389f: 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, + 0x38b0: 0x000a, 0x38b1: 0x000a, 0x38b2: 0x000a, 0x38b3: 0x000a, 0x38b4: 0x000a, 0x38b5: 0x000a, + 0x38b6: 0x000a, 0x38b7: 0x000a, 0x38b8: 0x000a, 0x38b9: 0x000a, 0x38ba: 0x000a, 0x38bb: 0x000a, + 0x38bc: 0x000a, 0x38bd: 0x000a, 0x38be: 0x000a, 0x38bf: 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, + 0x38e0: 0x000a, 0x38e1: 0x000a, 0x38e2: 0x000a, 0x38e3: 0x000a, + 0x38e4: 0x000a, 0x38e5: 0x000a, 0x38e6: 0x000a, 0x38e7: 0x000a, 0x38e8: 0x000a, 0x38e9: 0x000a, + 0x38ea: 0x000a, 0x38eb: 0x000a, 0x38ec: 0x000a, 0x38ed: 0x000a, 0x38ee: 0x000a, + 0x38f1: 0x000a, 0x38f2: 0x000a, 0x38f3: 0x000a, 0x38f4: 0x000a, 0x38f5: 0x000a, + 0x38f6: 0x000a, 0x38f7: 0x000a, 0x38f8: 0x000a, 0x38f9: 0x000a, 0x38fa: 0x000a, 0x38fb: 0x000a, + 0x38fc: 0x000a, 0x38fd: 0x000a, 0x38fe: 0x000a, 0x38ff: 0x000a, + // Block 0xe4, offset 0x3900 + 0x3901: 0x000a, 0x3902: 0x000a, 0x3903: 0x000a, 0x3904: 0x000a, 0x3905: 0x000a, + 0x3906: 0x000a, 0x3907: 0x000a, 0x3908: 0x000a, 0x3909: 0x000a, 0x390a: 0x000a, 0x390b: 0x000a, + 0x390c: 0x000a, 0x390d: 0x000a, 0x390e: 0x000a, 0x390f: 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, + // Block 0xe5, offset 0x3940 + 0x3940: 0x0002, 0x3941: 0x0002, 0x3942: 0x0002, 0x3943: 0x0002, 0x3944: 0x0002, 0x3945: 0x0002, + 0x3946: 0x0002, 0x3947: 0x0002, 0x3948: 0x0002, 0x3949: 0x0002, 0x394a: 0x0002, 0x394b: 0x000a, + 0x394c: 0x000a, 0x394d: 0x000a, 0x394e: 0x000a, 0x394f: 0x000a, + 0x396f: 0x000a, + // Block 0xe6, offset 0x3980 + 0x39aa: 0x000a, 0x39ab: 0x000a, 0x39ac: 0x000a, 0x39ad: 0x000a, 0x39ae: 0x000a, 0x39af: 0x000a, + // Block 0xe7, offset 0x39c0 + 0x39ed: 0x000a, + // Block 0xe8, offset 0x3a00 + 0x3a20: 0x000a, 0x3a21: 0x000a, 0x3a22: 0x000a, 0x3a23: 0x000a, + 0x3a24: 0x000a, 0x3a25: 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, + 0x3a60: 0x000a, 0x3a61: 0x000a, 0x3a62: 0x000a, 0x3a63: 0x000a, + 0x3a64: 0x000a, 0x3a65: 0x000a, 0x3a66: 0x000a, 0x3a67: 0x000a, 0x3a68: 0x000a, 0x3a69: 0x000a, + 0x3a6a: 0x000a, 0x3a6b: 0x000a, 0x3a6c: 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, + // 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, 0x3a8b: 0x000a, + 0x3a8c: 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, + 0x3aa0: 0x000a, 0x3aa1: 0x000a, 0x3aa2: 0x000a, 0x3aa3: 0x000a, + 0x3aa4: 0x000a, 0x3aa5: 0x000a, 0x3aa6: 0x000a, 0x3aa7: 0x000a, 0x3aa8: 0x000a, 0x3aa9: 0x000a, + 0x3aaa: 0x000a, 0x3aab: 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, + 0x3ad0: 0x000a, 0x3ad1: 0x000a, + 0x3ad2: 0x000a, 0x3ad3: 0x000a, 0x3ad4: 0x000a, 0x3ad5: 0x000a, 0x3ad6: 0x000a, 0x3ad7: 0x000a, + 0x3ad8: 0x000a, 0x3ad9: 0x000a, 0x3ada: 0x000a, 0x3adb: 0x000a, 0x3adc: 0x000a, 0x3add: 0x000a, + 0x3ade: 0x000a, 0x3adf: 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, 0x3aee: 0x000a, 0x3aef: 0x000a, + 0x3af0: 0x000a, 0x3af1: 0x000a, 0x3af2: 0x000a, 0x3af3: 0x000a, 0x3af4: 0x000a, 0x3af5: 0x000a, + 0x3af6: 0x000a, 0x3af7: 0x000a, 0x3af8: 0x000a, 0x3af9: 0x000a, 0x3afa: 0x000a, 0x3afb: 0x000a, + 0x3afc: 0x000a, 0x3afd: 0x000a, 0x3afe: 0x000a, 0x3aff: 0x000a, + // Block 0xec, offset 0x3b00 + 0x3b00: 0x000a, 0x3b01: 0x000a, 0x3b02: 0x000a, 0x3b03: 0x000a, 0x3b04: 0x000a, 0x3b05: 0x000a, + 0x3b06: 0x000a, 0x3b07: 0x000a, + 0x3b10: 0x000a, 0x3b11: 0x000a, + 0x3b12: 0x000a, 0x3b13: 0x000a, 0x3b14: 0x000a, 0x3b15: 0x000a, 0x3b16: 0x000a, 0x3b17: 0x000a, + 0x3b18: 0x000a, 0x3b19: 0x000a, + 0x3b20: 0x000a, 0x3b21: 0x000a, 0x3b22: 0x000a, 0x3b23: 0x000a, + 0x3b24: 0x000a, 0x3b25: 0x000a, 0x3b26: 0x000a, 0x3b27: 0x000a, 0x3b28: 0x000a, 0x3b29: 0x000a, + 0x3b2a: 0x000a, 0x3b2b: 0x000a, 0x3b2c: 0x000a, 0x3b2d: 0x000a, 0x3b2e: 0x000a, 0x3b2f: 0x000a, + 0x3b30: 0x000a, 0x3b31: 0x000a, 0x3b32: 0x000a, 0x3b33: 0x000a, 0x3b34: 0x000a, 0x3b35: 0x000a, + 0x3b36: 0x000a, 0x3b37: 0x000a, 0x3b38: 0x000a, 0x3b39: 0x000a, 0x3b3a: 0x000a, 0x3b3b: 0x000a, + 0x3b3c: 0x000a, 0x3b3d: 0x000a, 0x3b3e: 0x000a, 0x3b3f: 0x000a, + // Block 0xed, offset 0x3b40 + 0x3b40: 0x000a, 0x3b41: 0x000a, 0x3b42: 0x000a, 0x3b43: 0x000a, 0x3b44: 0x000a, 0x3b45: 0x000a, + 0x3b46: 0x000a, 0x3b47: 0x000a, + 0x3b50: 0x000a, 0x3b51: 0x000a, + 0x3b52: 0x000a, 0x3b53: 0x000a, 0x3b54: 0x000a, 0x3b55: 0x000a, 0x3b56: 0x000a, 0x3b57: 0x000a, + 0x3b58: 0x000a, 0x3b59: 0x000a, 0x3b5a: 0x000a, 0x3b5b: 0x000a, 0x3b5c: 0x000a, 0x3b5d: 0x000a, + 0x3b5e: 0x000a, 0x3b5f: 0x000a, 0x3b60: 0x000a, 0x3b61: 0x000a, 0x3b62: 0x000a, 0x3b63: 0x000a, + 0x3b64: 0x000a, 0x3b65: 0x000a, 0x3b66: 0x000a, 0x3b67: 0x000a, 0x3b68: 0x000a, 0x3b69: 0x000a, + 0x3b6a: 0x000a, 0x3b6b: 0x000a, 0x3b6c: 0x000a, 0x3b6d: 0x000a, + 0x3b70: 0x000a, 0x3b71: 0x000a, + // Block 0xee, offset 0x3b80 + 0x3b80: 0x000a, 0x3b81: 0x000a, 0x3b82: 0x000a, 0x3b83: 0x000a, 0x3b84: 0x000a, 0x3b85: 0x000a, + 0x3b86: 0x000a, 0x3b87: 0x000a, 0x3b88: 0x000a, 0x3b89: 0x000a, 0x3b8a: 0x000a, 0x3b8b: 0x000a, + 0x3b8c: 0x000a, 0x3b8d: 0x000a, 0x3b8e: 0x000a, 0x3b8f: 0x000a, 0x3b90: 0x000a, 0x3b91: 0x000a, + 0x3b92: 0x000a, 0x3b93: 0x000a, 0x3b94: 0x000a, 0x3b95: 0x000a, 0x3b96: 0x000a, 0x3b97: 0x000a, + 0x3b98: 0x000a, 0x3b99: 0x000a, 0x3b9a: 0x000a, 0x3b9b: 0x000a, 0x3b9c: 0x000a, 0x3b9d: 0x000a, + 0x3b9e: 0x000a, 0x3b9f: 0x000a, 0x3ba0: 0x000a, 0x3ba1: 0x000a, 0x3ba2: 0x000a, 0x3ba3: 0x000a, + 0x3ba4: 0x000a, 0x3ba5: 0x000a, 0x3ba6: 0x000a, 0x3ba7: 0x000a, 0x3ba8: 0x000a, 0x3ba9: 0x000a, + 0x3baa: 0x000a, 0x3bab: 0x000a, 0x3bac: 0x000a, 0x3bad: 0x000a, 0x3bae: 0x000a, 0x3baf: 0x000a, + 0x3bb0: 0x000a, 0x3bb1: 0x000a, 0x3bb2: 0x000a, 0x3bb3: 0x000a, 0x3bb4: 0x000a, 0x3bb5: 0x000a, + 0x3bb6: 0x000a, 0x3bb7: 0x000a, 0x3bb8: 0x000a, 0x3bba: 0x000a, 0x3bbb: 0x000a, + 0x3bbc: 0x000a, 0x3bbd: 0x000a, 0x3bbe: 0x000a, 0x3bbf: 0x000a, + // Block 0xef, offset 0x3bc0 + 0x3bc0: 0x000a, 0x3bc1: 0x000a, 0x3bc2: 0x000a, 0x3bc3: 0x000a, 0x3bc4: 0x000a, 0x3bc5: 0x000a, + 0x3bc6: 0x000a, 0x3bc7: 0x000a, 0x3bc8: 0x000a, 0x3bc9: 0x000a, 0x3bca: 0x000a, 0x3bcb: 0x000a, + 0x3bcd: 0x000a, 0x3bce: 0x000a, 0x3bcf: 0x000a, 0x3bd0: 0x000a, 0x3bd1: 0x000a, + 0x3bd2: 0x000a, 0x3bd3: 0x000a, 0x3bd4: 0x000a, 0x3bd5: 0x000a, 0x3bd6: 0x000a, 0x3bd7: 0x000a, + 0x3bd8: 0x000a, 0x3bd9: 0x000a, 0x3bda: 0x000a, 0x3bdb: 0x000a, 0x3bdc: 0x000a, 0x3bdd: 0x000a, + 0x3bde: 0x000a, 0x3bdf: 0x000a, 0x3be0: 0x000a, 0x3be1: 0x000a, 0x3be2: 0x000a, 0x3be3: 0x000a, + 0x3be4: 0x000a, 0x3be5: 0x000a, 0x3be6: 0x000a, 0x3be7: 0x000a, 0x3be8: 0x000a, 0x3be9: 0x000a, + 0x3bea: 0x000a, 0x3beb: 0x000a, 0x3bec: 0x000a, 0x3bed: 0x000a, 0x3bee: 0x000a, 0x3bef: 0x000a, + 0x3bf0: 0x000a, 0x3bf1: 0x000a, 0x3bf2: 0x000a, 0x3bf3: 0x000a, 0x3bf4: 0x000a, 0x3bf5: 0x000a, + 0x3bf6: 0x000a, 0x3bf7: 0x000a, 0x3bf8: 0x000a, 0x3bf9: 0x000a, 0x3bfa: 0x000a, 0x3bfb: 0x000a, + 0x3bfc: 0x000a, 0x3bfd: 0x000a, 0x3bfe: 0x000a, 0x3bff: 0x000a, + // Block 0xf0, offset 0x3c00 + 0x3c00: 0x000a, 0x3c01: 0x000a, 0x3c02: 0x000a, 0x3c03: 0x000a, 0x3c04: 0x000a, 0x3c05: 0x000a, + 0x3c06: 0x000a, 0x3c07: 0x000a, 0x3c08: 0x000a, 0x3c09: 0x000a, 0x3c0a: 0x000a, 0x3c0b: 0x000a, + 0x3c0c: 0x000a, 0x3c0d: 0x000a, 0x3c0e: 0x000a, 0x3c0f: 0x000a, 0x3c10: 0x000a, 0x3c11: 0x000a, + 0x3c12: 0x000a, 0x3c13: 0x000a, + 0x3c20: 0x000a, 0x3c21: 0x000a, 0x3c22: 0x000a, 0x3c23: 0x000a, + 0x3c24: 0x000a, 0x3c25: 0x000a, 0x3c26: 0x000a, 0x3c27: 0x000a, 0x3c28: 0x000a, 0x3c29: 0x000a, + 0x3c2a: 0x000a, 0x3c2b: 0x000a, 0x3c2c: 0x000a, 0x3c2d: 0x000a, + 0x3c30: 0x000a, 0x3c31: 0x000a, 0x3c32: 0x000a, 0x3c33: 0x000a, 0x3c34: 0x000a, + 0x3c38: 0x000a, 0x3c39: 0x000a, 0x3c3a: 0x000a, + // Block 0xf1, offset 0x3c40 + 0x3c40: 0x000a, 0x3c41: 0x000a, 0x3c42: 0x000a, 0x3c43: 0x000a, 0x3c44: 0x000a, 0x3c45: 0x000a, + 0x3c46: 0x000a, + 0x3c50: 0x000a, 0x3c51: 0x000a, + 0x3c52: 0x000a, 0x3c53: 0x000a, 0x3c54: 0x000a, 0x3c55: 0x000a, 0x3c56: 0x000a, 0x3c57: 0x000a, + 0x3c58: 0x000a, 0x3c59: 0x000a, 0x3c5a: 0x000a, 0x3c5b: 0x000a, 0x3c5c: 0x000a, 0x3c5d: 0x000a, + 0x3c5e: 0x000a, 0x3c5f: 0x000a, 0x3c60: 0x000a, 0x3c61: 0x000a, 0x3c62: 0x000a, 0x3c63: 0x000a, + 0x3c64: 0x000a, 0x3c65: 0x000a, 0x3c66: 0x000a, 0x3c67: 0x000a, 0x3c68: 0x000a, + 0x3c70: 0x000a, 0x3c71: 0x000a, 0x3c72: 0x000a, 0x3c73: 0x000a, 0x3c74: 0x000a, 0x3c75: 0x000a, + 0x3c76: 0x000a, + // Block 0xf2, offset 0x3c80 + 0x3c80: 0x000a, 0x3c81: 0x000a, 0x3c82: 0x000a, + 0x3c90: 0x000a, 0x3c91: 0x000a, + 0x3c92: 0x000a, 0x3c93: 0x000a, 0x3c94: 0x000a, 0x3c95: 0x000a, 0x3c96: 0x000a, + // Block 0xf3, offset 0x3cc0 + 0x3cc0: 0x000a, 0x3cc1: 0x000a, 0x3cc2: 0x000a, 0x3cc3: 0x000a, 0x3cc4: 0x000a, 0x3cc5: 0x000a, + 0x3cc6: 0x000a, 0x3cc7: 0x000a, 0x3cc8: 0x000a, 0x3cc9: 0x000a, 0x3cca: 0x000a, 0x3ccb: 0x000a, + 0x3ccc: 0x000a, 0x3ccd: 0x000a, 0x3cce: 0x000a, 0x3ccf: 0x000a, 0x3cd0: 0x000a, 0x3cd1: 0x000a, + 0x3cd2: 0x000a, 0x3cd4: 0x000a, 0x3cd5: 0x000a, 0x3cd6: 0x000a, 0x3cd7: 0x000a, + 0x3cd8: 0x000a, 0x3cd9: 0x000a, 0x3cda: 0x000a, 0x3cdb: 0x000a, 0x3cdc: 0x000a, 0x3cdd: 0x000a, + 0x3cde: 0x000a, 0x3cdf: 0x000a, 0x3ce0: 0x000a, 0x3ce1: 0x000a, 0x3ce2: 0x000a, 0x3ce3: 0x000a, + 0x3ce4: 0x000a, 0x3ce5: 0x000a, 0x3ce6: 0x000a, 0x3ce7: 0x000a, 0x3ce8: 0x000a, 0x3ce9: 0x000a, + 0x3cea: 0x000a, 0x3ceb: 0x000a, 0x3cec: 0x000a, 0x3ced: 0x000a, 0x3cee: 0x000a, 0x3cef: 0x000a, + 0x3cf0: 0x000a, 0x3cf1: 0x000a, 0x3cf2: 0x000a, 0x3cf3: 0x000a, 0x3cf4: 0x000a, 0x3cf5: 0x000a, + 0x3cf6: 0x000a, 0x3cf7: 0x000a, 0x3cf8: 0x000a, 0x3cf9: 0x000a, 0x3cfa: 0x000a, 0x3cfb: 0x000a, + 0x3cfc: 0x000a, 0x3cfd: 0x000a, 0x3cfe: 0x000a, 0x3cff: 0x000a, + // Block 0xf4, offset 0x3d00 + 0x3d00: 0x000a, 0x3d01: 0x000a, 0x3d02: 0x000a, 0x3d03: 0x000a, 0x3d04: 0x000a, 0x3d05: 0x000a, + 0x3d06: 0x000a, 0x3d07: 0x000a, 0x3d08: 0x000a, 0x3d09: 0x000a, 0x3d0a: 0x000a, + 0x3d30: 0x0002, 0x3d31: 0x0002, 0x3d32: 0x0002, 0x3d33: 0x0002, 0x3d34: 0x0002, 0x3d35: 0x0002, + 0x3d36: 0x0002, 0x3d37: 0x0002, 0x3d38: 0x0002, 0x3d39: 0x0002, + // Block 0xf5, offset 0x3d40 + 0x3d7e: 0x000b, 0x3d7f: 0x000b, + // Block 0xf6, offset 0x3d80 + 0x3d80: 0x000b, 0x3d81: 0x000b, 0x3d82: 0x000b, 0x3d83: 0x000b, 0x3d84: 0x000b, 0x3d85: 0x000b, + 0x3d86: 0x000b, 0x3d87: 0x000b, 0x3d88: 0x000b, 0x3d89: 0x000b, 0x3d8a: 0x000b, 0x3d8b: 0x000b, + 0x3d8c: 0x000b, 0x3d8d: 0x000b, 0x3d8e: 0x000b, 0x3d8f: 0x000b, 0x3d90: 0x000b, 0x3d91: 0x000b, + 0x3d92: 0x000b, 0x3d93: 0x000b, 0x3d94: 0x000b, 0x3d95: 0x000b, 0x3d96: 0x000b, 0x3d97: 0x000b, + 0x3d98: 0x000b, 0x3d99: 0x000b, 0x3d9a: 0x000b, 0x3d9b: 0x000b, 0x3d9c: 0x000b, 0x3d9d: 0x000b, + 0x3d9e: 0x000b, 0x3d9f: 0x000b, 0x3da0: 0x000b, 0x3da1: 0x000b, 0x3da2: 0x000b, 0x3da3: 0x000b, + 0x3da4: 0x000b, 0x3da5: 0x000b, 0x3da6: 0x000b, 0x3da7: 0x000b, 0x3da8: 0x000b, 0x3da9: 0x000b, + 0x3daa: 0x000b, 0x3dab: 0x000b, 0x3dac: 0x000b, 0x3dad: 0x000b, 0x3dae: 0x000b, 0x3daf: 0x000b, + 0x3db0: 0x000b, 0x3db1: 0x000b, 0x3db2: 0x000b, 0x3db3: 0x000b, 0x3db4: 0x000b, 0x3db5: 0x000b, + 0x3db6: 0x000b, 0x3db7: 0x000b, 0x3db8: 0x000b, 0x3db9: 0x000b, 0x3dba: 0x000b, 0x3dbb: 0x000b, + 0x3dbc: 0x000b, 0x3dbd: 0x000b, 0x3dbe: 0x000b, 0x3dbf: 0x000b, + // Block 0xf7, offset 0x3dc0 + 0x3dc0: 0x000c, 0x3dc1: 0x000c, 0x3dc2: 0x000c, 0x3dc3: 0x000c, 0x3dc4: 0x000c, 0x3dc5: 0x000c, + 0x3dc6: 0x000c, 0x3dc7: 0x000c, 0x3dc8: 0x000c, 0x3dc9: 0x000c, 0x3dca: 0x000c, 0x3dcb: 0x000c, + 0x3dcc: 0x000c, 0x3dcd: 0x000c, 0x3dce: 0x000c, 0x3dcf: 0x000c, 0x3dd0: 0x000c, 0x3dd1: 0x000c, + 0x3dd2: 0x000c, 0x3dd3: 0x000c, 0x3dd4: 0x000c, 0x3dd5: 0x000c, 0x3dd6: 0x000c, 0x3dd7: 0x000c, + 0x3dd8: 0x000c, 0x3dd9: 0x000c, 0x3dda: 0x000c, 0x3ddb: 0x000c, 0x3ddc: 0x000c, 0x3ddd: 0x000c, + 0x3dde: 0x000c, 0x3ddf: 0x000c, 0x3de0: 0x000c, 0x3de1: 0x000c, 0x3de2: 0x000c, 0x3de3: 0x000c, + 0x3de4: 0x000c, 0x3de5: 0x000c, 0x3de6: 0x000c, 0x3de7: 0x000c, 0x3de8: 0x000c, 0x3de9: 0x000c, + 0x3dea: 0x000c, 0x3deb: 0x000c, 0x3dec: 0x000c, 0x3ded: 0x000c, 0x3dee: 0x000c, 0x3def: 0x000c, + 0x3df0: 0x000b, 0x3df1: 0x000b, 0x3df2: 0x000b, 0x3df3: 0x000b, 0x3df4: 0x000b, 0x3df5: 0x000b, + 0x3df6: 0x000b, 0x3df7: 0x000b, 0x3df8: 0x000b, 0x3df9: 0x000b, 0x3dfa: 0x000b, 0x3dfb: 0x000b, + 0x3dfc: 0x000b, 0x3dfd: 0x000b, 0x3dfe: 0x000b, 0x3dff: 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, 0x136: 0x28, 0x137: 0x29, + 0x138: 0x2a, 0x139: 0x2b, 0x13a: 0x2c, 0x13b: 0x2d, 0x13c: 0x2e, 0x13d: 0x2f, 0x13e: 0x30, 0x13f: 0x31, + // Block 0x5, offset 0x140 + 0x140: 0x32, 0x141: 0x33, 0x142: 0x34, + 0x14d: 0x35, 0x14e: 0x36, + 0x150: 0x37, + 0x15a: 0x38, 0x15c: 0x39, 0x15d: 0x3a, 0x15e: 0x3b, 0x15f: 0x3c, + 0x160: 0x3d, 0x162: 0x3e, 0x164: 0x3f, 0x165: 0x40, 0x167: 0x41, + 0x168: 0x42, 0x169: 0x43, 0x16a: 0x44, 0x16b: 0x45, 0x16c: 0x46, 0x16d: 0x47, 0x16e: 0x48, 0x16f: 0x49, + 0x170: 0x4a, 0x173: 0x4b, 0x177: 0x4c, + 0x17e: 0x4d, 0x17f: 0x4e, + // Block 0x6, offset 0x180 + 0x180: 0x4f, 0x181: 0x50, 0x182: 0x51, 0x183: 0x52, 0x184: 0x53, 0x185: 0x54, 0x186: 0x55, 0x187: 0x56, + 0x188: 0x57, 0x189: 0x56, 0x18a: 0x56, 0x18b: 0x56, 0x18c: 0x58, 0x18d: 0x59, 0x18e: 0x5a, 0x18f: 0x56, + 0x190: 0x5b, 0x191: 0x5c, 0x192: 0x5d, 0x193: 0x5e, 0x194: 0x56, 0x195: 0x56, 0x196: 0x56, 0x197: 0x56, + 0x198: 0x56, 0x199: 0x56, 0x19a: 0x5f, 0x19b: 0x56, 0x19c: 0x56, 0x19d: 0x60, 0x19e: 0x56, 0x19f: 0x61, + 0x1a4: 0x56, 0x1a5: 0x56, 0x1a6: 0x62, 0x1a7: 0x63, + 0x1a8: 0x56, 0x1a9: 0x56, 0x1aa: 0x56, 0x1ab: 0x56, 0x1ac: 0x56, 0x1ad: 0x64, 0x1ae: 0x65, 0x1af: 0x56, + 0x1b3: 0x66, 0x1b5: 0x67, 0x1b7: 0x68, + 0x1b8: 0x69, 0x1b9: 0x6a, 0x1ba: 0x6b, 0x1bb: 0x6c, 0x1bc: 0x56, 0x1bd: 0x56, 0x1be: 0x56, 0x1bf: 0x6d, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x6e, 0x1c2: 0x6f, 0x1c3: 0x70, 0x1c7: 0x71, + 0x1c8: 0x72, 0x1c9: 0x73, 0x1ca: 0x74, 0x1cb: 0x75, 0x1cd: 0x76, 0x1cf: 0x77, + // Block 0x8, offset 0x200 + 0x237: 0x56, + // Block 0x9, offset 0x240 + 0x252: 0x78, 0x253: 0x79, + 0x258: 0x7a, 0x259: 0x7b, 0x25a: 0x7c, 0x25b: 0x7d, 0x25c: 0x7e, 0x25e: 0x7f, + 0x260: 0x80, 0x261: 0x81, 0x263: 0x82, 0x264: 0x83, 0x265: 0x84, 0x266: 0x85, 0x267: 0x86, + 0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26d: 0x8b, 0x26f: 0x8c, + // Block 0xa, offset 0x280 + 0x2ac: 0x8d, 0x2ad: 0x8e, 0x2ae: 0x0e, 0x2af: 0x0e, + 0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8f, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x90, + 0x2b8: 0x91, 0x2b9: 0x92, 0x2ba: 0x0e, 0x2bb: 0x93, 0x2bc: 0x94, 0x2bd: 0x95, 0x2bf: 0x96, + // Block 0xb, offset 0x2c0 + 0x2c4: 0x97, 0x2c5: 0x56, 0x2c6: 0x98, 0x2c7: 0x99, + 0x2cb: 0x9a, 0x2cd: 0x9b, + 0x2e0: 0x9c, 0x2e1: 0x9c, 0x2e2: 0x9c, 0x2e3: 0x9c, 0x2e4: 0x9d, 0x2e5: 0x9c, 0x2e6: 0x9c, 0x2e7: 0x9c, + 0x2e8: 0x9e, 0x2e9: 0x9c, 0x2ea: 0x9c, 0x2eb: 0x9f, 0x2ec: 0xa0, 0x2ed: 0x9c, 0x2ee: 0x9c, 0x2ef: 0x9c, + 0x2f0: 0x9c, 0x2f1: 0x9c, 0x2f2: 0x9c, 0x2f3: 0x9c, 0x2f4: 0xa1, 0x2f5: 0x9c, 0x2f6: 0x9c, 0x2f7: 0x9c, + 0x2f8: 0x9c, 0x2f9: 0xa2, 0x2fa: 0xa3, 0x2fb: 0x9c, 0x2fc: 0xa4, 0x2fd: 0xa5, 0x2fe: 0x9c, 0x2ff: 0x9c, + // Block 0xc, offset 0x300 + 0x300: 0xa6, 0x301: 0xa7, 0x302: 0xa8, 0x304: 0xa9, 0x305: 0xaa, 0x306: 0xab, 0x307: 0xac, + 0x308: 0xad, 0x30b: 0xae, 0x30c: 0x26, 0x30d: 0xaf, + 0x310: 0xb0, 0x311: 0xb1, 0x312: 0xb2, 0x313: 0xb3, 0x316: 0xb4, 0x317: 0xb5, + 0x318: 0xb6, 0x319: 0xb7, 0x31a: 0xb8, 0x31c: 0xb9, + 0x320: 0xba, 0x324: 0xbb, 0x325: 0xbc, 0x327: 0xbd, + 0x328: 0xbe, 0x329: 0xbf, 0x32a: 0xc0, + 0x330: 0xc1, 0x332: 0xc2, 0x334: 0xc3, 0x335: 0xc4, 0x336: 0xc5, + 0x33b: 0xc6, 0x33f: 0xc7, + // Block 0xd, offset 0x340 + 0x36b: 0xc8, 0x36c: 0xc9, + 0x37d: 0xca, 0x37e: 0xcb, 0x37f: 0xcc, + // Block 0xe, offset 0x380 + 0x3b2: 0xcd, + // Block 0xf, offset 0x3c0 + 0x3c5: 0xce, 0x3c6: 0xcf, + 0x3c8: 0x56, 0x3c9: 0xd0, 0x3cc: 0x56, 0x3cd: 0xd1, + 0x3db: 0xd2, 0x3dc: 0xd3, 0x3dd: 0xd4, 0x3de: 0xd5, 0x3df: 0xd6, + 0x3e8: 0xd7, 0x3e9: 0xd8, 0x3ea: 0xd9, + // Block 0x10, offset 0x400 + 0x400: 0xda, 0x404: 0xc9, + 0x40b: 0xdb, + 0x420: 0x9c, 0x421: 0x9c, 0x422: 0x9c, 0x423: 0xdc, 0x424: 0x9c, 0x425: 0xdd, 0x426: 0x9c, 0x427: 0x9c, + 0x428: 0x9c, 0x429: 0x9c, 0x42a: 0x9c, 0x42b: 0x9c, 0x42c: 0x9c, 0x42d: 0x9c, 0x42e: 0x9c, 0x42f: 0x9c, + 0x430: 0x9c, 0x431: 0xa4, 0x432: 0x0e, 0x433: 0x9c, 0x434: 0x0e, 0x435: 0xde, 0x436: 0x9c, 0x437: 0x9c, + 0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xdf, 0x43c: 0x9c, 0x43d: 0x9c, 0x43e: 0x9c, 0x43f: 0x9c, + // Block 0x11, offset 0x440 + 0x440: 0xe0, 0x441: 0x56, 0x442: 0xe1, 0x443: 0xe2, 0x444: 0xe3, 0x445: 0xe4, 0x446: 0xe5, + 0x449: 0xe6, 0x44c: 0x56, 0x44d: 0x56, 0x44e: 0x56, 0x44f: 0x56, + 0x450: 0x56, 0x451: 0x56, 0x452: 0x56, 0x453: 0x56, 0x454: 0x56, 0x455: 0x56, 0x456: 0x56, 0x457: 0x56, + 0x458: 0x56, 0x459: 0x56, 0x45a: 0x56, 0x45b: 0xe7, 0x45c: 0x56, 0x45d: 0x6c, 0x45e: 0x56, 0x45f: 0xe8, + 0x460: 0xe9, 0x461: 0xea, 0x462: 0xeb, 0x464: 0x56, 0x465: 0xec, 0x466: 0x56, 0x467: 0xed, + 0x468: 0x56, 0x469: 0xee, 0x46a: 0xef, 0x46b: 0xf0, 0x46c: 0x56, 0x46d: 0x56, 0x46e: 0xf1, 0x46f: 0xf2, + 0x47f: 0xf3, + // Block 0x12, offset 0x480 + 0x4bf: 0xf3, + // 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: 0xf4, 0x541: 0xf4, 0x542: 0xf4, 0x543: 0xf4, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xf5, + 0x548: 0xf4, 0x549: 0xf4, 0x54a: 0xf4, 0x54b: 0xf4, 0x54c: 0xf4, 0x54d: 0xf4, 0x54e: 0xf4, 0x54f: 0xf4, + 0x550: 0xf4, 0x551: 0xf4, 0x552: 0xf4, 0x553: 0xf4, 0x554: 0xf4, 0x555: 0xf4, 0x556: 0xf4, 0x557: 0xf4, + 0x558: 0xf4, 0x559: 0xf4, 0x55a: 0xf4, 0x55b: 0xf4, 0x55c: 0xf4, 0x55d: 0xf4, 0x55e: 0xf4, 0x55f: 0xf4, + 0x560: 0xf4, 0x561: 0xf4, 0x562: 0xf4, 0x563: 0xf4, 0x564: 0xf4, 0x565: 0xf4, 0x566: 0xf4, 0x567: 0xf4, + 0x568: 0xf4, 0x569: 0xf4, 0x56a: 0xf4, 0x56b: 0xf4, 0x56c: 0xf4, 0x56d: 0xf4, 0x56e: 0xf4, 0x56f: 0xf4, + 0x570: 0xf4, 0x571: 0xf4, 0x572: 0xf4, 0x573: 0xf4, 0x574: 0xf4, 0x575: 0xf4, 0x576: 0xf4, 0x577: 0xf4, + 0x578: 0xf4, 0x579: 0xf4, 0x57a: 0xf4, 0x57b: 0xf4, 0x57c: 0xf4, 0x57d: 0xf4, 0x57e: 0xf4, 0x57f: 0xf4, + // Block 0x16, offset 0x580 + 0x58f: 0x10, + 0x59f: 0x10, + 0x5a0: 0x13, + 0x5af: 0x10, + 0x5bf: 0x10, + // Block 0x17, offset 0x5c0 + 0x5cf: 0x10, +} + +// Total table size 17464 bytes (17KiB); checksum: F50EF68C 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 index 10f5202c693..7e1ae096e5c 100644 --- 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 @@ -1,6 +1,6 @@ // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. -// +build go1.14 +// +build go1.14,!go1.16 package norm diff --git a/libgo/go/golang.org/x/text/unicode/norm/tables13.0.0.go b/libgo/go/golang.org/x/text/unicode/norm/tables13.0.0.go new file mode 100644 index 00000000000..9ea1b421407 --- /dev/null +++ b/libgo/go/golang.org/x/text/unicode/norm/tables13.0.0.go @@ -0,0 +1,7760 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +// +build go1.16 + +package norm + +import "sync" + +const ( + // Version is the Unicode edition from which the tables are derived. + Version = "13.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 = [56]uint8{ + 0, 1, 6, 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 = 0x1870 + firstCCC = 0x2CAB + endMulti = 0x2F77 + firstLeadingCCC = 0x49C5 + firstCCCZeroExcept = 0x4A8F + firstStarterWithNLead = 0x4AB6 + lastDecomp = 0x4AB8 + maxDecomp = 0x8000 +) + +// decomps: 19128 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, + 0x8D, 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, + // Bytes 180 - 1bf + 0xCE, 0x94, 0x42, 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, + // Bytes 1c0 - 1ff + 0xB1, 0x42, 0xCE, 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, + // Bytes 200 - 23f + 0x42, 0xCF, 0x87, 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, + // Bytes 240 - 27f + 0xD8, 0xA8, 0x42, 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, + // Bytes 280 - 2bf + 0x83, 0x42, 0xD9, 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, + // Bytes 2c0 - 2ff + 0x42, 0xDA, 0x8C, 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, + // Bytes 300 - 33f + 0xDB, 0x89, 0x42, 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, + // Bytes 340 - 37f + 0x84, 0x8A, 0x43, 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, + // Bytes 380 - 3bf + 0x84, 0xA1, 0x43, 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, + // Bytes 3c0 - 3ff + 0x85, 0x98, 0x43, 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, + // Bytes 400 - 43f + 0x87, 0x97, 0x43, 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, + // Bytes 440 - 47f + 0x80, 0x90, 0x43, 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, + // Bytes 480 - 4bf + 0xA6, 0x86, 0x43, 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, + // Bytes 4c0 - 4ff + 0x80, 0x95, 0x43, 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, + // Bytes 500 - 53f + 0x82, 0xB1, 0x43, 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, + // Bytes 540 - 57f + 0x83, 0x8D, 0x43, 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, + // Bytes 580 - 5bf + 0x83, 0xA7, 0x43, 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, + // Bytes 5c0 - 5ff + 0x92, 0xBB, 0x43, 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, + // Bytes 600 - 63f + 0xAC, 0x88, 0x43, 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, + // Bytes 640 - 67f + 0x82, 0x96, 0x43, 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, + // Bytes 680 - 6bf + 0x95, 0xAB, 0x43, 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, + // Bytes 6c0 - 6ff + 0xB5, 0x96, 0x43, 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, + // Bytes 700 - 73f + 0xB8, 0xBD, 0x43, 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, + // Bytes 740 - 77f + 0xBB, 0xA4, 0x43, 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, + // Bytes 780 - 7bf + 0x83, 0xA7, 0x43, 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, + // Bytes 7c0 - 7ff + 0x86, 0x82, 0x43, 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, + // Bytes 800 - 83f + 0x87, 0xA0, 0x43, 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, + // Bytes 840 - 87f + 0x8A, 0xA3, 0x43, 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, + // Bytes 880 - 8bf + 0x8C, 0xB8, 0x43, 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, + // Bytes 8c0 - 8ff + 0x8D, 0xBF, 0x43, 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, + // Bytes 900 - 93f + 0x90, 0x8D, 0x43, 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, + // Bytes 940 - 97f + 0x95, 0xA3, 0x43, 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, + // Bytes 980 - 9bf + 0x9B, 0x9B, 0x43, 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, + // Bytes 9c0 - 9ff + 0xA2, 0xAC, 0x43, 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, + // Bytes a00 - a3f + 0xA4, 0xA7, 0x43, 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, + // Bytes a40 - a7f + 0xAC, 0xA8, 0x43, 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, + // Bytes a80 - abf + 0xB0, 0x8F, 0x43, 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, + // Bytes ac0 - aff + 0xB5, 0xAE, 0x43, 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, + // Bytes b00 - b3f + 0xB9, 0xB4, 0x43, 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, + // Bytes b40 - b7f + 0xBC, 0x84, 0x43, 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, + // Bytes b80 - bbf + 0xBE, 0xAD, 0x43, 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, + // Bytes bc0 - bff + 0x85, 0x88, 0x43, 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, + // Bytes c00 - c3f + 0x88, 0x90, 0x43, 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, + // Bytes c40 - c7f + 0x8C, 0x87, 0x43, 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, + // Bytes c80 - cbf + 0x91, 0xB7, 0x43, 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, + // Bytes cc0 - cff + 0x96, 0xB9, 0x43, 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, + // Bytes d00 - d3f + 0x9B, 0xB4, 0x43, 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, + // Bytes d40 - d7f + 0x9F, 0xB3, 0x43, 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, + // Bytes d80 - dbf + 0xAA, 0xA8, 0x43, 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, + // Bytes dc0 - dff + 0xAE, 0xBB, 0x43, 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, + // Bytes e00 - e3f + 0xB4, 0x96, 0x43, 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, + // Bytes e40 - e7f + 0xB8, 0xAF, 0x43, 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, + // Bytes e80 - ebf + 0xBF, 0xBE, 0x43, 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, + // Bytes ec0 - eff + 0x85, 0xAE, 0x43, 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, + // Bytes f00 - f3f + 0x89, 0x9B, 0x43, 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, + // Bytes f40 - f7f + 0x8E, 0xA5, 0x43, 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, + // Bytes f80 - fbf + 0x94, 0x86, 0x43, 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, + // Bytes fc0 - fff + 0x97, 0xA2, 0x43, 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, + // Bytes 1000 - 103f + 0x9C, 0x81, 0x43, 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, + // Bytes 1040 - 107f + 0xA3, 0xBB, 0x43, 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, + // Bytes 1080 - 10bf + 0xA6, 0x8F, 0x43, 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, + // Bytes 10c0 - 10ff + 0xAB, 0xAE, 0x43, 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, + // Bytes 1100 - 113f + 0xB3, 0xA7, 0x43, 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, + // Bytes 1140 - 117f + 0xB8, 0xB7, 0x43, 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, + // Bytes 1180 - 11bf + 0x80, 0x85, 0x43, 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, + // Bytes 11c0 - 11ff + 0x87, 0x98, 0x43, 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, + // Bytes 1200 - 123f + 0x89, 0xB8, 0x43, 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, + // Bytes 1240 - 127f + 0x8E, 0xAD, 0x43, 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, + // Bytes 1280 - 12bf + 0x94, 0x96, 0x43, 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, + // Bytes 12c0 - 12ff + 0x9B, 0xA2, 0x43, 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, + // Bytes 1300 - 133f + 0xA3, 0x97, 0x43, 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, + // Bytes 1340 - 137f + 0xAA, 0xAA, 0x43, 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, + // Bytes 1380 - 13bf + 0xB1, 0x95, 0x43, 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, + // Bytes 13c0 - 13ff + 0xB6, 0xB3, 0x43, 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, + // Bytes 1400 - 143f + 0xBE, 0xB5, 0x43, 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, + // Bytes 1440 - 147f + 0x84, 0x9B, 0x43, 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, + // Bytes 1480 - 14bf + 0x8C, 0x84, 0x43, 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, + // Bytes 14c0 - 14ff + 0x9A, 0x86, 0x43, 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, + // Bytes 1500 - 153f + 0x9D, 0x96, 0x43, 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, + // Bytes 1540 - 157f + 0xA1, 0x9E, 0x43, 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, + // Bytes 1580 - 15bf + 0xA9, 0xAA, 0x43, 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, + // Bytes 15c0 - 15ff + 0xB6, 0xB4, 0x43, 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, + // Bytes 1600 - 163f + 0xBC, 0x85, 0x43, 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, + // Bytes 1640 - 167f + 0x9D, 0xAF, 0x43, 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, + // Bytes 1680 - 16bf + 0xA8, 0x44, 0xF0, 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, + // Bytes 16c0 - 16ff + 0xAC, 0x8C, 0x44, 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, + // Bytes 1700 - 173f + 0xA3, 0xAB, 0xBA, 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, + // Bytes 1740 - 177f + 0xF0, 0xA4, 0xB2, 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, + // Bytes 1780 - 17bf + 0x44, 0xF0, 0xA5, 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, + // Bytes 17c0 - 17ff + 0xA3, 0x44, 0xF0, 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, + // Bytes 1800 - 183f + 0xA2, 0xAE, 0x44, 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, + // Bytes 1840 - 187f + 0xA9, 0x90, 0x8A, 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, + // Bytes 1880 - 18bf + 0x31, 0x2C, 0x42, 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, + // Bytes 18c0 - 18ff + 0x37, 0x42, 0x32, 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, + // Bytes 1900 - 193f + 0x42, 0x34, 0x35, 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, + // Bytes 1940 - 197f + 0x43, 0x44, 0x42, 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, + // Bytes 1980 - 19bf + 0x43, 0x42, 0x4D, 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, + // Bytes 19c0 - 19ff + 0x42, 0x63, 0x63, 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, + // Bytes 1a00 - 1a3f + 0x6B, 0x57, 0x42, 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, + // Bytes 1a40 - 1a7f + 0x56, 0x42, 0x6E, 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, + // Bytes 1a80 - 1abf + 0x35, 0x29, 0x43, 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, + // Bytes 1ac0 - 1aff + 0x4C, 0x29, 0x43, 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, + // Bytes 1b00 - 1b3f + 0x62, 0x29, 0x43, 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, + // Bytes 1b40 - 1b7f + 0x72, 0x29, 0x43, 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, + // Bytes 1b80 - 1bbf + 0x36, 0x2E, 0x43, 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, + // Bytes 1bc0 - 1bff + 0xCE, 0xA9, 0x43, 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, + // Bytes 1c00 - 1c3f + 0x6D, 0x33, 0x43, 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, + // Bytes 1c40 - 1c7f + 0x69, 0x6C, 0x43, 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, + // Bytes 1c80 - 1cbf + 0xBC, 0x6D, 0x43, 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, + // Bytes 1cc0 - 1cff + 0x82, 0xB9, 0x44, 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, + // Bytes 1d00 - 1d3f + 0xE7, 0x82, 0xB9, 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, + // Bytes 1d40 - 1d7f + 0x39, 0xE6, 0x97, 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, + // Bytes 1d80 - 1dbf + 0x44, 0xD5, 0xBE, 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, + // Bytes 1dc0 - 1dff + 0x8A, 0x44, 0xD8, 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, + // Bytes 1e00 - 1e3f + 0xD8, 0xB2, 0x44, 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, + // Bytes 1e40 - 1e7f + 0xAD, 0xD9, 0x8A, 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, + // Bytes 1e80 - 1ebf + 0xD8, 0xB3, 0xD9, 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, + // Bytes 1ec0 - 1eff + 0x44, 0xD8, 0xB5, 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, + // Bytes 1f00 - 1f3f + 0x8A, 0x44, 0xD8, 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, + // Bytes 1f40 - 1f7f + 0xD9, 0x85, 0x44, 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, + // Bytes 1f80 - 1fbf + 0x83, 0xD9, 0x89, 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, + // Bytes 1fc0 - 1fff + 0xD9, 0x85, 0xD8, 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, + // Bytes 2000 - 203f + 0x44, 0xD9, 0x86, 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, + // Bytes 2040 - 207f + 0x86, 0x44, 0xD9, 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, + // Bytes 2080 - 20bf + 0xE1, 0x84, 0x89, 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, + // Bytes 20c0 - 20ff + 0x45, 0x28, 0xE4, 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, + // Bytes 2100 - 213f + 0x94, 0x29, 0x45, 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, + // Bytes 2140 - 217f + 0xE6, 0xB0, 0xB4, 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, + // Bytes 2180 - 21bf + 0x45, 0x28, 0xE9, 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, + // Bytes 21c0 - 21ff + 0x82, 0xB9, 0x45, 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, + // Bytes 2200 - 223f + 0x38, 0xE6, 0x97, 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, + // Bytes 2240 - 227f + 0x45, 0x31, 0xE2, 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, + // Bytes 2280 - 22bf + 0x82, 0xB9, 0x45, 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, + // Bytes 22c0 - 22ff + 0xE2, 0x81, 0x84, 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, + // Bytes 2300 - 233f + 0x6B, 0x67, 0x46, 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, + // Bytes 2340 - 237f + 0x85, 0x46, 0xD8, 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, + // Bytes 2380 - 23bf + 0x46, 0xD8, 0xAC, 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, + // Bytes 23c0 - 23ff + 0xD8, 0xB3, 0xD8, 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, + // Bytes 2400 - 243f + 0xB4, 0xD9, 0x85, 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, + // Bytes 2440 - 247f + 0xD9, 0x85, 0xD8, 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, + // Bytes 2480 - 24bf + 0x85, 0xD9, 0x8A, 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, + // Bytes 24c0 - 24ff + 0xD8, 0xAC, 0x46, 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, + // Bytes 2500 - 253f + 0xAD, 0x46, 0xD9, 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, + // Bytes 2540 - 257f + 0x46, 0xD9, 0x85, 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, + // Bytes 2580 - 25bf + 0xD9, 0x86, 0xD9, 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, + // Bytes 25c0 - 25ff + 0x8A, 0xD9, 0x94, 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, + // Bytes 2600 - 263f + 0xD9, 0x94, 0xD9, 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, + // Bytes 2640 - 267f + 0xE0, 0xBA, 0xB2, 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, + // Bytes 2680 - 26bf + 0xBE, 0xB7, 0x46, 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, + // Bytes 26c0 - 26ff + 0x8A, 0x46, 0xE3, 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, + // Bytes 2700 - 273f + 0x46, 0xE4, 0xBB, 0xA4, 0xE5, 0x92, 0x8C, 0x46, + 0xE5, 0xA4, 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, + // Bytes 2740 - 277f + 0x82, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, + 0x84, 0x83, 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, + // Bytes 2780 - 27bf + 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, + 0x8C, 0xE1, 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, + // Bytes 27c0 - 27ff + 0x95, 0x73, 0x32, 0x48, 0xD8, 0xA7, 0xD9, 0x83, + 0xD8, 0xA8, 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, + // Bytes 2800 - 283f + 0xD8, 0xAF, 0x48, 0xD9, 0x88, 0xD8, 0xB3, 0xD9, + 0x84, 0xD9, 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, + // Bytes 2840 - 287f + 0x94, 0xE4, 0xBA, 0x8C, 0xE3, 0x80, 0x95, 0x49, + 0xE3, 0x80, 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, + // Bytes 2880 - 28bf + 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7, + 0x9B, 0x97, 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, + // Bytes 28c0 - 28ff + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83, + 0xAA, 0x49, 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, + // Bytes 2900 - 293f + 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, + 0x8E, 0xE3, 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, + // Bytes 2940 - 297f + 0xBD, 0x49, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB, + 0xE3, 0x83, 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, + // Bytes 2980 - 29bf + 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49, + 0xE3, 0x83, 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, + // Bytes 29c0 - 29ff + 0x82, 0xA1, 0x4C, 0xE3, 0x82, 0xA8, 0xE3, 0x83, + 0xBC, 0xE3, 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, + // Bytes 2a00 - 2a3f + 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAD, 0xE3, + 0x82, 0x99, 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, + // Bytes 2a40 - 2a7f + 0xAF, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x82, 0xBF, + 0xE3, 0x82, 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, + // Bytes 2a80 - 2abf + 0x83, 0xBC, 0xE3, 0x82, 0xBF, 0x4C, 0xE3, 0x83, + 0x98, 0xE3, 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, + // Bytes 2ac0 - 2aff + 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x4C, 0xE3, + 0x83, 0xA1, 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, + // Bytes 2b00 - 2b3f + 0x85, 0xA9, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xAE, + 0x29, 0x4F, 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, + // Bytes 2b40 - 2b7f + 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83, + 0x88, 0x4F, 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, + // Bytes 2b80 - 2bbf + 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83, + 0x88, 0x4F, 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, + // Bytes 2bc0 - 2bff + 0xA9, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA5, 0xE1, + 0x86, 0xAB, 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, + // Bytes 2c00 - 2c3f + 0x88, 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x82, 0xAF, + 0xE3, 0x82, 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, + // Bytes 2c40 - 2c7f + 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0xE3, + 0x82, 0xB9, 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, + // Bytes 2c80 - 2cbf + 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83, + 0xB3, 0x61, 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, + // Bytes 2cc0 - 2cff + 0xAC, 0xBE, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0, + 0xAD, 0x96, 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, + // Bytes 2d00 - 2d3f + 0xB3, 0x95, 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0, + 0xB3, 0x96, 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, + // Bytes 2d40 - 2d7f + 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x89, 0xE1, + 0xAC, 0xB5, 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, + // Bytes 2d80 - 2dbf + 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAD, 0x82, 0xE1, + 0xAC, 0xB5, 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, + // Bytes 2dc0 - 2dff + 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xBA, 0x01, 0x08, + 0xF0, 0x91, 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, 0x08, 0xF0, 0x91, + 0xA4, 0xB5, 0xF0, 0x91, 0xA4, 0xB0, 0x01, 0x09, + 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3, + 0x95, 0x02, 0x09, 0xE0, 0xB7, 0x99, 0xE0, 0xB7, + // Bytes 2e00 - 2e3f + 0x8F, 0xE0, 0xB7, 0x8A, 0x16, 0x44, 0x44, 0x5A, + 0xCC, 0x8C, 0xCD, 0x44, 0x44, 0x7A, 0xCC, 0x8C, + 0xCD, 0x44, 0x64, 0x7A, 0xCC, 0x8C, 0xCD, 0x46, + 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xCD, 0x46, + 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xCD, 0x46, + 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xB9, 0x46, + 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x01, 0x46, + 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x01, 0x46, + // Bytes 2e40 - 2e7f + 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x01, 0x46, + 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x01, 0x46, + 0xE1, 0x84, 0x86, 0xE1, 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, + // Bytes 2e80 - 2ebf + 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x01, 0x46, + 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x01, 0x46, + 0xE1, 0x84, 0x90, 0xE1, 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, 0x11, 0x4C, 0xE1, 0x84, 0x8C, 0xE1, 0x85, + 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, 0x01, + // Bytes 2ec0 - 2eff + 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3, + 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x11, 0x4C, 0xE3, + 0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x9B, + 0xE3, 0x82, 0x9A, 0x11, 0x4C, 0xE3, 0x83, 0xA4, + 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82, + 0x99, 0x11, 0x4F, 0xE1, 0x84, 0x8E, 0xE1, 0x85, + 0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, 0xE1, + 0x85, 0xA9, 0x01, 0x4F, 0xE3, 0x82, 0xA4, 0xE3, + // Bytes 2f00 - 2f3f + 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF, + 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, 0x82, 0xB7, + 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82, + 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, 0x83, + 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, + 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, + 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x52, + // Bytes 2f40 - 2f7f + 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, 0x82, + 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, + 0x82, 0x99, 0x11, 0x52, 0xE3, 0x83, 0x95, 0xE3, + 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 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, + // Bytes 2f80 - 2fbf + 0x05, 0x03, 0x3E, 0xCC, 0xB8, 0x05, 0x03, 0x41, + 0xCC, 0x80, 0xCD, 0x03, 0x41, 0xCC, 0x81, 0xCD, + 0x03, 0x41, 0xCC, 0x83, 0xCD, 0x03, 0x41, 0xCC, + 0x84, 0xCD, 0x03, 0x41, 0xCC, 0x89, 0xCD, 0x03, + 0x41, 0xCC, 0x8C, 0xCD, 0x03, 0x41, 0xCC, 0x8F, + 0xCD, 0x03, 0x41, 0xCC, 0x91, 0xCD, 0x03, 0x41, + 0xCC, 0xA5, 0xB9, 0x03, 0x41, 0xCC, 0xA8, 0xA9, + 0x03, 0x42, 0xCC, 0x87, 0xCD, 0x03, 0x42, 0xCC, + // Bytes 2fc0 - 2fff + 0xA3, 0xB9, 0x03, 0x42, 0xCC, 0xB1, 0xB9, 0x03, + 0x43, 0xCC, 0x81, 0xCD, 0x03, 0x43, 0xCC, 0x82, + 0xCD, 0x03, 0x43, 0xCC, 0x87, 0xCD, 0x03, 0x43, + 0xCC, 0x8C, 0xCD, 0x03, 0x44, 0xCC, 0x87, 0xCD, + 0x03, 0x44, 0xCC, 0x8C, 0xCD, 0x03, 0x44, 0xCC, + 0xA3, 0xB9, 0x03, 0x44, 0xCC, 0xA7, 0xA9, 0x03, + 0x44, 0xCC, 0xAD, 0xB9, 0x03, 0x44, 0xCC, 0xB1, + 0xB9, 0x03, 0x45, 0xCC, 0x80, 0xCD, 0x03, 0x45, + // Bytes 3000 - 303f + 0xCC, 0x81, 0xCD, 0x03, 0x45, 0xCC, 0x83, 0xCD, + 0x03, 0x45, 0xCC, 0x86, 0xCD, 0x03, 0x45, 0xCC, + 0x87, 0xCD, 0x03, 0x45, 0xCC, 0x88, 0xCD, 0x03, + 0x45, 0xCC, 0x89, 0xCD, 0x03, 0x45, 0xCC, 0x8C, + 0xCD, 0x03, 0x45, 0xCC, 0x8F, 0xCD, 0x03, 0x45, + 0xCC, 0x91, 0xCD, 0x03, 0x45, 0xCC, 0xA8, 0xA9, + 0x03, 0x45, 0xCC, 0xAD, 0xB9, 0x03, 0x45, 0xCC, + 0xB0, 0xB9, 0x03, 0x46, 0xCC, 0x87, 0xCD, 0x03, + // Bytes 3040 - 307f + 0x47, 0xCC, 0x81, 0xCD, 0x03, 0x47, 0xCC, 0x82, + 0xCD, 0x03, 0x47, 0xCC, 0x84, 0xCD, 0x03, 0x47, + 0xCC, 0x86, 0xCD, 0x03, 0x47, 0xCC, 0x87, 0xCD, + 0x03, 0x47, 0xCC, 0x8C, 0xCD, 0x03, 0x47, 0xCC, + 0xA7, 0xA9, 0x03, 0x48, 0xCC, 0x82, 0xCD, 0x03, + 0x48, 0xCC, 0x87, 0xCD, 0x03, 0x48, 0xCC, 0x88, + 0xCD, 0x03, 0x48, 0xCC, 0x8C, 0xCD, 0x03, 0x48, + 0xCC, 0xA3, 0xB9, 0x03, 0x48, 0xCC, 0xA7, 0xA9, + // Bytes 3080 - 30bf + 0x03, 0x48, 0xCC, 0xAE, 0xB9, 0x03, 0x49, 0xCC, + 0x80, 0xCD, 0x03, 0x49, 0xCC, 0x81, 0xCD, 0x03, + 0x49, 0xCC, 0x82, 0xCD, 0x03, 0x49, 0xCC, 0x83, + 0xCD, 0x03, 0x49, 0xCC, 0x84, 0xCD, 0x03, 0x49, + 0xCC, 0x86, 0xCD, 0x03, 0x49, 0xCC, 0x87, 0xCD, + 0x03, 0x49, 0xCC, 0x89, 0xCD, 0x03, 0x49, 0xCC, + 0x8C, 0xCD, 0x03, 0x49, 0xCC, 0x8F, 0xCD, 0x03, + 0x49, 0xCC, 0x91, 0xCD, 0x03, 0x49, 0xCC, 0xA3, + // Bytes 30c0 - 30ff + 0xB9, 0x03, 0x49, 0xCC, 0xA8, 0xA9, 0x03, 0x49, + 0xCC, 0xB0, 0xB9, 0x03, 0x4A, 0xCC, 0x82, 0xCD, + 0x03, 0x4B, 0xCC, 0x81, 0xCD, 0x03, 0x4B, 0xCC, + 0x8C, 0xCD, 0x03, 0x4B, 0xCC, 0xA3, 0xB9, 0x03, + 0x4B, 0xCC, 0xA7, 0xA9, 0x03, 0x4B, 0xCC, 0xB1, + 0xB9, 0x03, 0x4C, 0xCC, 0x81, 0xCD, 0x03, 0x4C, + 0xCC, 0x8C, 0xCD, 0x03, 0x4C, 0xCC, 0xA7, 0xA9, + 0x03, 0x4C, 0xCC, 0xAD, 0xB9, 0x03, 0x4C, 0xCC, + // Bytes 3100 - 313f + 0xB1, 0xB9, 0x03, 0x4D, 0xCC, 0x81, 0xCD, 0x03, + 0x4D, 0xCC, 0x87, 0xCD, 0x03, 0x4D, 0xCC, 0xA3, + 0xB9, 0x03, 0x4E, 0xCC, 0x80, 0xCD, 0x03, 0x4E, + 0xCC, 0x81, 0xCD, 0x03, 0x4E, 0xCC, 0x83, 0xCD, + 0x03, 0x4E, 0xCC, 0x87, 0xCD, 0x03, 0x4E, 0xCC, + 0x8C, 0xCD, 0x03, 0x4E, 0xCC, 0xA3, 0xB9, 0x03, + 0x4E, 0xCC, 0xA7, 0xA9, 0x03, 0x4E, 0xCC, 0xAD, + 0xB9, 0x03, 0x4E, 0xCC, 0xB1, 0xB9, 0x03, 0x4F, + // Bytes 3140 - 317f + 0xCC, 0x80, 0xCD, 0x03, 0x4F, 0xCC, 0x81, 0xCD, + 0x03, 0x4F, 0xCC, 0x86, 0xCD, 0x03, 0x4F, 0xCC, + 0x89, 0xCD, 0x03, 0x4F, 0xCC, 0x8B, 0xCD, 0x03, + 0x4F, 0xCC, 0x8C, 0xCD, 0x03, 0x4F, 0xCC, 0x8F, + 0xCD, 0x03, 0x4F, 0xCC, 0x91, 0xCD, 0x03, 0x50, + 0xCC, 0x81, 0xCD, 0x03, 0x50, 0xCC, 0x87, 0xCD, + 0x03, 0x52, 0xCC, 0x81, 0xCD, 0x03, 0x52, 0xCC, + 0x87, 0xCD, 0x03, 0x52, 0xCC, 0x8C, 0xCD, 0x03, + // Bytes 3180 - 31bf + 0x52, 0xCC, 0x8F, 0xCD, 0x03, 0x52, 0xCC, 0x91, + 0xCD, 0x03, 0x52, 0xCC, 0xA7, 0xA9, 0x03, 0x52, + 0xCC, 0xB1, 0xB9, 0x03, 0x53, 0xCC, 0x82, 0xCD, + 0x03, 0x53, 0xCC, 0x87, 0xCD, 0x03, 0x53, 0xCC, + 0xA6, 0xB9, 0x03, 0x53, 0xCC, 0xA7, 0xA9, 0x03, + 0x54, 0xCC, 0x87, 0xCD, 0x03, 0x54, 0xCC, 0x8C, + 0xCD, 0x03, 0x54, 0xCC, 0xA3, 0xB9, 0x03, 0x54, + 0xCC, 0xA6, 0xB9, 0x03, 0x54, 0xCC, 0xA7, 0xA9, + // Bytes 31c0 - 31ff + 0x03, 0x54, 0xCC, 0xAD, 0xB9, 0x03, 0x54, 0xCC, + 0xB1, 0xB9, 0x03, 0x55, 0xCC, 0x80, 0xCD, 0x03, + 0x55, 0xCC, 0x81, 0xCD, 0x03, 0x55, 0xCC, 0x82, + 0xCD, 0x03, 0x55, 0xCC, 0x86, 0xCD, 0x03, 0x55, + 0xCC, 0x89, 0xCD, 0x03, 0x55, 0xCC, 0x8A, 0xCD, + 0x03, 0x55, 0xCC, 0x8B, 0xCD, 0x03, 0x55, 0xCC, + 0x8C, 0xCD, 0x03, 0x55, 0xCC, 0x8F, 0xCD, 0x03, + 0x55, 0xCC, 0x91, 0xCD, 0x03, 0x55, 0xCC, 0xA3, + // Bytes 3200 - 323f + 0xB9, 0x03, 0x55, 0xCC, 0xA4, 0xB9, 0x03, 0x55, + 0xCC, 0xA8, 0xA9, 0x03, 0x55, 0xCC, 0xAD, 0xB9, + 0x03, 0x55, 0xCC, 0xB0, 0xB9, 0x03, 0x56, 0xCC, + 0x83, 0xCD, 0x03, 0x56, 0xCC, 0xA3, 0xB9, 0x03, + 0x57, 0xCC, 0x80, 0xCD, 0x03, 0x57, 0xCC, 0x81, + 0xCD, 0x03, 0x57, 0xCC, 0x82, 0xCD, 0x03, 0x57, + 0xCC, 0x87, 0xCD, 0x03, 0x57, 0xCC, 0x88, 0xCD, + 0x03, 0x57, 0xCC, 0xA3, 0xB9, 0x03, 0x58, 0xCC, + // Bytes 3240 - 327f + 0x87, 0xCD, 0x03, 0x58, 0xCC, 0x88, 0xCD, 0x03, + 0x59, 0xCC, 0x80, 0xCD, 0x03, 0x59, 0xCC, 0x81, + 0xCD, 0x03, 0x59, 0xCC, 0x82, 0xCD, 0x03, 0x59, + 0xCC, 0x83, 0xCD, 0x03, 0x59, 0xCC, 0x84, 0xCD, + 0x03, 0x59, 0xCC, 0x87, 0xCD, 0x03, 0x59, 0xCC, + 0x88, 0xCD, 0x03, 0x59, 0xCC, 0x89, 0xCD, 0x03, + 0x59, 0xCC, 0xA3, 0xB9, 0x03, 0x5A, 0xCC, 0x81, + 0xCD, 0x03, 0x5A, 0xCC, 0x82, 0xCD, 0x03, 0x5A, + // Bytes 3280 - 32bf + 0xCC, 0x87, 0xCD, 0x03, 0x5A, 0xCC, 0x8C, 0xCD, + 0x03, 0x5A, 0xCC, 0xA3, 0xB9, 0x03, 0x5A, 0xCC, + 0xB1, 0xB9, 0x03, 0x61, 0xCC, 0x80, 0xCD, 0x03, + 0x61, 0xCC, 0x81, 0xCD, 0x03, 0x61, 0xCC, 0x83, + 0xCD, 0x03, 0x61, 0xCC, 0x84, 0xCD, 0x03, 0x61, + 0xCC, 0x89, 0xCD, 0x03, 0x61, 0xCC, 0x8C, 0xCD, + 0x03, 0x61, 0xCC, 0x8F, 0xCD, 0x03, 0x61, 0xCC, + 0x91, 0xCD, 0x03, 0x61, 0xCC, 0xA5, 0xB9, 0x03, + // Bytes 32c0 - 32ff + 0x61, 0xCC, 0xA8, 0xA9, 0x03, 0x62, 0xCC, 0x87, + 0xCD, 0x03, 0x62, 0xCC, 0xA3, 0xB9, 0x03, 0x62, + 0xCC, 0xB1, 0xB9, 0x03, 0x63, 0xCC, 0x81, 0xCD, + 0x03, 0x63, 0xCC, 0x82, 0xCD, 0x03, 0x63, 0xCC, + 0x87, 0xCD, 0x03, 0x63, 0xCC, 0x8C, 0xCD, 0x03, + 0x64, 0xCC, 0x87, 0xCD, 0x03, 0x64, 0xCC, 0x8C, + 0xCD, 0x03, 0x64, 0xCC, 0xA3, 0xB9, 0x03, 0x64, + 0xCC, 0xA7, 0xA9, 0x03, 0x64, 0xCC, 0xAD, 0xB9, + // Bytes 3300 - 333f + 0x03, 0x64, 0xCC, 0xB1, 0xB9, 0x03, 0x65, 0xCC, + 0x80, 0xCD, 0x03, 0x65, 0xCC, 0x81, 0xCD, 0x03, + 0x65, 0xCC, 0x83, 0xCD, 0x03, 0x65, 0xCC, 0x86, + 0xCD, 0x03, 0x65, 0xCC, 0x87, 0xCD, 0x03, 0x65, + 0xCC, 0x88, 0xCD, 0x03, 0x65, 0xCC, 0x89, 0xCD, + 0x03, 0x65, 0xCC, 0x8C, 0xCD, 0x03, 0x65, 0xCC, + 0x8F, 0xCD, 0x03, 0x65, 0xCC, 0x91, 0xCD, 0x03, + 0x65, 0xCC, 0xA8, 0xA9, 0x03, 0x65, 0xCC, 0xAD, + // Bytes 3340 - 337f + 0xB9, 0x03, 0x65, 0xCC, 0xB0, 0xB9, 0x03, 0x66, + 0xCC, 0x87, 0xCD, 0x03, 0x67, 0xCC, 0x81, 0xCD, + 0x03, 0x67, 0xCC, 0x82, 0xCD, 0x03, 0x67, 0xCC, + 0x84, 0xCD, 0x03, 0x67, 0xCC, 0x86, 0xCD, 0x03, + 0x67, 0xCC, 0x87, 0xCD, 0x03, 0x67, 0xCC, 0x8C, + 0xCD, 0x03, 0x67, 0xCC, 0xA7, 0xA9, 0x03, 0x68, + 0xCC, 0x82, 0xCD, 0x03, 0x68, 0xCC, 0x87, 0xCD, + 0x03, 0x68, 0xCC, 0x88, 0xCD, 0x03, 0x68, 0xCC, + // Bytes 3380 - 33bf + 0x8C, 0xCD, 0x03, 0x68, 0xCC, 0xA3, 0xB9, 0x03, + 0x68, 0xCC, 0xA7, 0xA9, 0x03, 0x68, 0xCC, 0xAE, + 0xB9, 0x03, 0x68, 0xCC, 0xB1, 0xB9, 0x03, 0x69, + 0xCC, 0x80, 0xCD, 0x03, 0x69, 0xCC, 0x81, 0xCD, + 0x03, 0x69, 0xCC, 0x82, 0xCD, 0x03, 0x69, 0xCC, + 0x83, 0xCD, 0x03, 0x69, 0xCC, 0x84, 0xCD, 0x03, + 0x69, 0xCC, 0x86, 0xCD, 0x03, 0x69, 0xCC, 0x89, + 0xCD, 0x03, 0x69, 0xCC, 0x8C, 0xCD, 0x03, 0x69, + // Bytes 33c0 - 33ff + 0xCC, 0x8F, 0xCD, 0x03, 0x69, 0xCC, 0x91, 0xCD, + 0x03, 0x69, 0xCC, 0xA3, 0xB9, 0x03, 0x69, 0xCC, + 0xA8, 0xA9, 0x03, 0x69, 0xCC, 0xB0, 0xB9, 0x03, + 0x6A, 0xCC, 0x82, 0xCD, 0x03, 0x6A, 0xCC, 0x8C, + 0xCD, 0x03, 0x6B, 0xCC, 0x81, 0xCD, 0x03, 0x6B, + 0xCC, 0x8C, 0xCD, 0x03, 0x6B, 0xCC, 0xA3, 0xB9, + 0x03, 0x6B, 0xCC, 0xA7, 0xA9, 0x03, 0x6B, 0xCC, + 0xB1, 0xB9, 0x03, 0x6C, 0xCC, 0x81, 0xCD, 0x03, + // Bytes 3400 - 343f + 0x6C, 0xCC, 0x8C, 0xCD, 0x03, 0x6C, 0xCC, 0xA7, + 0xA9, 0x03, 0x6C, 0xCC, 0xAD, 0xB9, 0x03, 0x6C, + 0xCC, 0xB1, 0xB9, 0x03, 0x6D, 0xCC, 0x81, 0xCD, + 0x03, 0x6D, 0xCC, 0x87, 0xCD, 0x03, 0x6D, 0xCC, + 0xA3, 0xB9, 0x03, 0x6E, 0xCC, 0x80, 0xCD, 0x03, + 0x6E, 0xCC, 0x81, 0xCD, 0x03, 0x6E, 0xCC, 0x83, + 0xCD, 0x03, 0x6E, 0xCC, 0x87, 0xCD, 0x03, 0x6E, + 0xCC, 0x8C, 0xCD, 0x03, 0x6E, 0xCC, 0xA3, 0xB9, + // Bytes 3440 - 347f + 0x03, 0x6E, 0xCC, 0xA7, 0xA9, 0x03, 0x6E, 0xCC, + 0xAD, 0xB9, 0x03, 0x6E, 0xCC, 0xB1, 0xB9, 0x03, + 0x6F, 0xCC, 0x80, 0xCD, 0x03, 0x6F, 0xCC, 0x81, + 0xCD, 0x03, 0x6F, 0xCC, 0x86, 0xCD, 0x03, 0x6F, + 0xCC, 0x89, 0xCD, 0x03, 0x6F, 0xCC, 0x8B, 0xCD, + 0x03, 0x6F, 0xCC, 0x8C, 0xCD, 0x03, 0x6F, 0xCC, + 0x8F, 0xCD, 0x03, 0x6F, 0xCC, 0x91, 0xCD, 0x03, + 0x70, 0xCC, 0x81, 0xCD, 0x03, 0x70, 0xCC, 0x87, + // Bytes 3480 - 34bf + 0xCD, 0x03, 0x72, 0xCC, 0x81, 0xCD, 0x03, 0x72, + 0xCC, 0x87, 0xCD, 0x03, 0x72, 0xCC, 0x8C, 0xCD, + 0x03, 0x72, 0xCC, 0x8F, 0xCD, 0x03, 0x72, 0xCC, + 0x91, 0xCD, 0x03, 0x72, 0xCC, 0xA7, 0xA9, 0x03, + 0x72, 0xCC, 0xB1, 0xB9, 0x03, 0x73, 0xCC, 0x82, + 0xCD, 0x03, 0x73, 0xCC, 0x87, 0xCD, 0x03, 0x73, + 0xCC, 0xA6, 0xB9, 0x03, 0x73, 0xCC, 0xA7, 0xA9, + 0x03, 0x74, 0xCC, 0x87, 0xCD, 0x03, 0x74, 0xCC, + // Bytes 34c0 - 34ff + 0x88, 0xCD, 0x03, 0x74, 0xCC, 0x8C, 0xCD, 0x03, + 0x74, 0xCC, 0xA3, 0xB9, 0x03, 0x74, 0xCC, 0xA6, + 0xB9, 0x03, 0x74, 0xCC, 0xA7, 0xA9, 0x03, 0x74, + 0xCC, 0xAD, 0xB9, 0x03, 0x74, 0xCC, 0xB1, 0xB9, + 0x03, 0x75, 0xCC, 0x80, 0xCD, 0x03, 0x75, 0xCC, + 0x81, 0xCD, 0x03, 0x75, 0xCC, 0x82, 0xCD, 0x03, + 0x75, 0xCC, 0x86, 0xCD, 0x03, 0x75, 0xCC, 0x89, + 0xCD, 0x03, 0x75, 0xCC, 0x8A, 0xCD, 0x03, 0x75, + // Bytes 3500 - 353f + 0xCC, 0x8B, 0xCD, 0x03, 0x75, 0xCC, 0x8C, 0xCD, + 0x03, 0x75, 0xCC, 0x8F, 0xCD, 0x03, 0x75, 0xCC, + 0x91, 0xCD, 0x03, 0x75, 0xCC, 0xA3, 0xB9, 0x03, + 0x75, 0xCC, 0xA4, 0xB9, 0x03, 0x75, 0xCC, 0xA8, + 0xA9, 0x03, 0x75, 0xCC, 0xAD, 0xB9, 0x03, 0x75, + 0xCC, 0xB0, 0xB9, 0x03, 0x76, 0xCC, 0x83, 0xCD, + 0x03, 0x76, 0xCC, 0xA3, 0xB9, 0x03, 0x77, 0xCC, + 0x80, 0xCD, 0x03, 0x77, 0xCC, 0x81, 0xCD, 0x03, + // Bytes 3540 - 357f + 0x77, 0xCC, 0x82, 0xCD, 0x03, 0x77, 0xCC, 0x87, + 0xCD, 0x03, 0x77, 0xCC, 0x88, 0xCD, 0x03, 0x77, + 0xCC, 0x8A, 0xCD, 0x03, 0x77, 0xCC, 0xA3, 0xB9, + 0x03, 0x78, 0xCC, 0x87, 0xCD, 0x03, 0x78, 0xCC, + 0x88, 0xCD, 0x03, 0x79, 0xCC, 0x80, 0xCD, 0x03, + 0x79, 0xCC, 0x81, 0xCD, 0x03, 0x79, 0xCC, 0x82, + 0xCD, 0x03, 0x79, 0xCC, 0x83, 0xCD, 0x03, 0x79, + 0xCC, 0x84, 0xCD, 0x03, 0x79, 0xCC, 0x87, 0xCD, + // Bytes 3580 - 35bf + 0x03, 0x79, 0xCC, 0x88, 0xCD, 0x03, 0x79, 0xCC, + 0x89, 0xCD, 0x03, 0x79, 0xCC, 0x8A, 0xCD, 0x03, + 0x79, 0xCC, 0xA3, 0xB9, 0x03, 0x7A, 0xCC, 0x81, + 0xCD, 0x03, 0x7A, 0xCC, 0x82, 0xCD, 0x03, 0x7A, + 0xCC, 0x87, 0xCD, 0x03, 0x7A, 0xCC, 0x8C, 0xCD, + 0x03, 0x7A, 0xCC, 0xA3, 0xB9, 0x03, 0x7A, 0xCC, + 0xB1, 0xB9, 0x04, 0xC2, 0xA8, 0xCC, 0x80, 0xCE, + 0x04, 0xC2, 0xA8, 0xCC, 0x81, 0xCE, 0x04, 0xC2, + // Bytes 35c0 - 35ff + 0xA8, 0xCD, 0x82, 0xCE, 0x04, 0xC3, 0x86, 0xCC, + 0x81, 0xCD, 0x04, 0xC3, 0x86, 0xCC, 0x84, 0xCD, + 0x04, 0xC3, 0x98, 0xCC, 0x81, 0xCD, 0x04, 0xC3, + 0xA6, 0xCC, 0x81, 0xCD, 0x04, 0xC3, 0xA6, 0xCC, + 0x84, 0xCD, 0x04, 0xC3, 0xB8, 0xCC, 0x81, 0xCD, + 0x04, 0xC5, 0xBF, 0xCC, 0x87, 0xCD, 0x04, 0xC6, + 0xB7, 0xCC, 0x8C, 0xCD, 0x04, 0xCA, 0x92, 0xCC, + 0x8C, 0xCD, 0x04, 0xCE, 0x91, 0xCC, 0x80, 0xCD, + // Bytes 3600 - 363f + 0x04, 0xCE, 0x91, 0xCC, 0x81, 0xCD, 0x04, 0xCE, + 0x91, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0x91, 0xCC, + 0x86, 0xCD, 0x04, 0xCE, 0x91, 0xCD, 0x85, 0xDD, + 0x04, 0xCE, 0x95, 0xCC, 0x80, 0xCD, 0x04, 0xCE, + 0x95, 0xCC, 0x81, 0xCD, 0x04, 0xCE, 0x97, 0xCC, + 0x80, 0xCD, 0x04, 0xCE, 0x97, 0xCC, 0x81, 0xCD, + 0x04, 0xCE, 0x97, 0xCD, 0x85, 0xDD, 0x04, 0xCE, + 0x99, 0xCC, 0x80, 0xCD, 0x04, 0xCE, 0x99, 0xCC, + // Bytes 3640 - 367f + 0x81, 0xCD, 0x04, 0xCE, 0x99, 0xCC, 0x84, 0xCD, + 0x04, 0xCE, 0x99, 0xCC, 0x86, 0xCD, 0x04, 0xCE, + 0x99, 0xCC, 0x88, 0xCD, 0x04, 0xCE, 0x9F, 0xCC, + 0x80, 0xCD, 0x04, 0xCE, 0x9F, 0xCC, 0x81, 0xCD, + 0x04, 0xCE, 0xA1, 0xCC, 0x94, 0xCD, 0x04, 0xCE, + 0xA5, 0xCC, 0x80, 0xCD, 0x04, 0xCE, 0xA5, 0xCC, + 0x81, 0xCD, 0x04, 0xCE, 0xA5, 0xCC, 0x84, 0xCD, + 0x04, 0xCE, 0xA5, 0xCC, 0x86, 0xCD, 0x04, 0xCE, + // Bytes 3680 - 36bf + 0xA5, 0xCC, 0x88, 0xCD, 0x04, 0xCE, 0xA9, 0xCC, + 0x80, 0xCD, 0x04, 0xCE, 0xA9, 0xCC, 0x81, 0xCD, + 0x04, 0xCE, 0xA9, 0xCD, 0x85, 0xDD, 0x04, 0xCE, + 0xB1, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0xB1, 0xCC, + 0x86, 0xCD, 0x04, 0xCE, 0xB1, 0xCD, 0x85, 0xDD, + 0x04, 0xCE, 0xB5, 0xCC, 0x80, 0xCD, 0x04, 0xCE, + 0xB5, 0xCC, 0x81, 0xCD, 0x04, 0xCE, 0xB7, 0xCD, + 0x85, 0xDD, 0x04, 0xCE, 0xB9, 0xCC, 0x80, 0xCD, + // Bytes 36c0 - 36ff + 0x04, 0xCE, 0xB9, 0xCC, 0x81, 0xCD, 0x04, 0xCE, + 0xB9, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0xB9, 0xCC, + 0x86, 0xCD, 0x04, 0xCE, 0xB9, 0xCD, 0x82, 0xCD, + 0x04, 0xCE, 0xBF, 0xCC, 0x80, 0xCD, 0x04, 0xCE, + 0xBF, 0xCC, 0x81, 0xCD, 0x04, 0xCF, 0x81, 0xCC, + 0x93, 0xCD, 0x04, 0xCF, 0x81, 0xCC, 0x94, 0xCD, + 0x04, 0xCF, 0x85, 0xCC, 0x80, 0xCD, 0x04, 0xCF, + 0x85, 0xCC, 0x81, 0xCD, 0x04, 0xCF, 0x85, 0xCC, + // Bytes 3700 - 373f + 0x84, 0xCD, 0x04, 0xCF, 0x85, 0xCC, 0x86, 0xCD, + 0x04, 0xCF, 0x85, 0xCD, 0x82, 0xCD, 0x04, 0xCF, + 0x89, 0xCD, 0x85, 0xDD, 0x04, 0xCF, 0x92, 0xCC, + 0x81, 0xCD, 0x04, 0xCF, 0x92, 0xCC, 0x88, 0xCD, + 0x04, 0xD0, 0x86, 0xCC, 0x88, 0xCD, 0x04, 0xD0, + 0x90, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0x90, 0xCC, + 0x88, 0xCD, 0x04, 0xD0, 0x93, 0xCC, 0x81, 0xCD, + 0x04, 0xD0, 0x95, 0xCC, 0x80, 0xCD, 0x04, 0xD0, + // Bytes 3740 - 377f + 0x95, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0x95, 0xCC, + 0x88, 0xCD, 0x04, 0xD0, 0x96, 0xCC, 0x86, 0xCD, + 0x04, 0xD0, 0x96, 0xCC, 0x88, 0xCD, 0x04, 0xD0, + 0x97, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0x98, 0xCC, + 0x80, 0xCD, 0x04, 0xD0, 0x98, 0xCC, 0x84, 0xCD, + 0x04, 0xD0, 0x98, 0xCC, 0x86, 0xCD, 0x04, 0xD0, + 0x98, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0x9A, 0xCC, + 0x81, 0xCD, 0x04, 0xD0, 0x9E, 0xCC, 0x88, 0xCD, + // Bytes 3780 - 37bf + 0x04, 0xD0, 0xA3, 0xCC, 0x84, 0xCD, 0x04, 0xD0, + 0xA3, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0xA3, 0xCC, + 0x88, 0xCD, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, 0xCD, + 0x04, 0xD0, 0xA7, 0xCC, 0x88, 0xCD, 0x04, 0xD0, + 0xAB, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0xAD, 0xCC, + 0x88, 0xCD, 0x04, 0xD0, 0xB0, 0xCC, 0x86, 0xCD, + 0x04, 0xD0, 0xB0, 0xCC, 0x88, 0xCD, 0x04, 0xD0, + 0xB3, 0xCC, 0x81, 0xCD, 0x04, 0xD0, 0xB5, 0xCC, + // Bytes 37c0 - 37ff + 0x80, 0xCD, 0x04, 0xD0, 0xB5, 0xCC, 0x86, 0xCD, + 0x04, 0xD0, 0xB5, 0xCC, 0x88, 0xCD, 0x04, 0xD0, + 0xB6, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0xB6, 0xCC, + 0x88, 0xCD, 0x04, 0xD0, 0xB7, 0xCC, 0x88, 0xCD, + 0x04, 0xD0, 0xB8, 0xCC, 0x80, 0xCD, 0x04, 0xD0, + 0xB8, 0xCC, 0x84, 0xCD, 0x04, 0xD0, 0xB8, 0xCC, + 0x86, 0xCD, 0x04, 0xD0, 0xB8, 0xCC, 0x88, 0xCD, + 0x04, 0xD0, 0xBA, 0xCC, 0x81, 0xCD, 0x04, 0xD0, + // Bytes 3800 - 383f + 0xBE, 0xCC, 0x88, 0xCD, 0x04, 0xD1, 0x83, 0xCC, + 0x84, 0xCD, 0x04, 0xD1, 0x83, 0xCC, 0x86, 0xCD, + 0x04, 0xD1, 0x83, 0xCC, 0x88, 0xCD, 0x04, 0xD1, + 0x83, 0xCC, 0x8B, 0xCD, 0x04, 0xD1, 0x87, 0xCC, + 0x88, 0xCD, 0x04, 0xD1, 0x8B, 0xCC, 0x88, 0xCD, + 0x04, 0xD1, 0x8D, 0xCC, 0x88, 0xCD, 0x04, 0xD1, + 0x96, 0xCC, 0x88, 0xCD, 0x04, 0xD1, 0xB4, 0xCC, + 0x8F, 0xCD, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, 0xCD, + // Bytes 3840 - 387f + 0x04, 0xD3, 0x98, 0xCC, 0x88, 0xCD, 0x04, 0xD3, + 0x99, 0xCC, 0x88, 0xCD, 0x04, 0xD3, 0xA8, 0xCC, + 0x88, 0xCD, 0x04, 0xD3, 0xA9, 0xCC, 0x88, 0xCD, + 0x04, 0xD8, 0xA7, 0xD9, 0x93, 0xCD, 0x04, 0xD8, + 0xA7, 0xD9, 0x94, 0xCD, 0x04, 0xD8, 0xA7, 0xD9, + 0x95, 0xB9, 0x04, 0xD9, 0x88, 0xD9, 0x94, 0xCD, + 0x04, 0xD9, 0x8A, 0xD9, 0x94, 0xCD, 0x04, 0xDB, + 0x81, 0xD9, 0x94, 0xCD, 0x04, 0xDB, 0x92, 0xD9, + // Bytes 3880 - 38bf + 0x94, 0xCD, 0x04, 0xDB, 0x95, 0xD9, 0x94, 0xCD, + 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, + 0x41, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x41, + 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x41, 0xCC, + 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x41, 0xCC, 0x86, + 0xCC, 0x80, 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, + 0x81, 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x83, + 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x89, 0xCE, + // Bytes 38c0 - 38ff + 0x05, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, + 0x41, 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x41, + 0xCC, 0x8A, 0xCC, 0x81, 0xCE, 0x05, 0x41, 0xCC, + 0xA3, 0xCC, 0x82, 0xCE, 0x05, 0x41, 0xCC, 0xA3, + 0xCC, 0x86, 0xCE, 0x05, 0x43, 0xCC, 0xA7, 0xCC, + 0x81, 0xCE, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x80, + 0xCE, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x81, 0xCE, + 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, + // Bytes 3900 - 393f + 0x45, 0xCC, 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x45, + 0xCC, 0x84, 0xCC, 0x80, 0xCE, 0x05, 0x45, 0xCC, + 0x84, 0xCC, 0x81, 0xCE, 0x05, 0x45, 0xCC, 0xA3, + 0xCC, 0x82, 0xCE, 0x05, 0x45, 0xCC, 0xA7, 0xCC, + 0x86, 0xCE, 0x05, 0x49, 0xCC, 0x88, 0xCC, 0x81, + 0xCE, 0x05, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, 0xCE, + 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, + 0x4F, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x4F, + // Bytes 3940 - 397f + 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x4F, 0xCC, + 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x4F, 0xCC, 0x83, + 0xCC, 0x81, 0xCE, 0x05, 0x4F, 0xCC, 0x83, 0xCC, + 0x84, 0xCE, 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x88, + 0xCE, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, 0xCE, + 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xCE, 0x05, + 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x4F, + 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x4F, 0xCC, + // Bytes 3980 - 39bf + 0x9B, 0xCC, 0x80, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, + 0xCC, 0x81, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, + 0x83, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x89, + 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, + 0x05, 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0xCE, 0x05, + 0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xCE, 0x05, 0x52, + 0xCC, 0xA3, 0xCC, 0x84, 0xCE, 0x05, 0x53, 0xCC, + 0x81, 0xCC, 0x87, 0xCE, 0x05, 0x53, 0xCC, 0x8C, + // Bytes 39c0 - 39ff + 0xCC, 0x87, 0xCE, 0x05, 0x53, 0xCC, 0xA3, 0xCC, + 0x87, 0xCE, 0x05, 0x55, 0xCC, 0x83, 0xCC, 0x81, + 0xCE, 0x05, 0x55, 0xCC, 0x84, 0xCC, 0x88, 0xCE, + 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x05, + 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x05, 0x55, + 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x55, 0xCC, + 0x88, 0xCC, 0x8C, 0xCE, 0x05, 0x55, 0xCC, 0x9B, + 0xCC, 0x80, 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, + // Bytes 3a00 - 3a3f + 0x81, 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x83, + 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x89, 0xCE, + 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05, + 0x61, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, 0x61, + 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x61, 0xCC, + 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x61, 0xCC, 0x82, + 0xCC, 0x89, 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, + 0x80, 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x81, + // Bytes 3a40 - 3a7f + 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, 0xCE, + 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x89, 0xCE, 0x05, + 0x61, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x61, + 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x61, 0xCC, + 0x8A, 0xCC, 0x81, 0xCE, 0x05, 0x61, 0xCC, 0xA3, + 0xCC, 0x82, 0xCE, 0x05, 0x61, 0xCC, 0xA3, 0xCC, + 0x86, 0xCE, 0x05, 0x63, 0xCC, 0xA7, 0xCC, 0x81, + 0xCE, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x80, 0xCE, + // Bytes 3a80 - 3abf + 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, + 0x65, 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x65, + 0xCC, 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x65, 0xCC, + 0x84, 0xCC, 0x80, 0xCE, 0x05, 0x65, 0xCC, 0x84, + 0xCC, 0x81, 0xCE, 0x05, 0x65, 0xCC, 0xA3, 0xCC, + 0x82, 0xCE, 0x05, 0x65, 0xCC, 0xA7, 0xCC, 0x86, + 0xCE, 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, 0xCE, + 0x05, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xCE, 0x05, + // Bytes 3ac0 - 3aff + 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, 0x6F, + 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x6F, 0xCC, + 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x6F, 0xCC, 0x82, + 0xCC, 0x89, 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, + 0x81, 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x84, + 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xCE, + 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0xCE, 0x05, + 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xCE, 0x05, 0x6F, + // Bytes 3b00 - 3b3f + 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x6F, 0xCC, + 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, + 0xCC, 0x80, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, + 0x81, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x83, + 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xCE, + 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05, + 0x6F, 0xCC, 0xA3, 0xCC, 0x82, 0xCE, 0x05, 0x6F, + 0xCC, 0xA8, 0xCC, 0x84, 0xCE, 0x05, 0x72, 0xCC, + // Bytes 3b40 - 3b7f + 0xA3, 0xCC, 0x84, 0xCE, 0x05, 0x73, 0xCC, 0x81, + 0xCC, 0x87, 0xCE, 0x05, 0x73, 0xCC, 0x8C, 0xCC, + 0x87, 0xCE, 0x05, 0x73, 0xCC, 0xA3, 0xCC, 0x87, + 0xCE, 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, 0xCE, + 0x05, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xCE, 0x05, + 0x75, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x05, 0x75, + 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x05, 0x75, 0xCC, + 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x75, 0xCC, 0x88, + // Bytes 3b80 - 3bbf + 0xCC, 0x8C, 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, + 0x80, 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x81, + 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xCE, + 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x89, 0xCE, 0x05, + 0x75, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05, 0xE1, + 0xBE, 0xBF, 0xCC, 0x80, 0xCE, 0x05, 0xE1, 0xBE, + 0xBF, 0xCC, 0x81, 0xCE, 0x05, 0xE1, 0xBE, 0xBF, + 0xCD, 0x82, 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, + // Bytes 3bc0 - 3bff + 0x80, 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, 0x81, + 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCD, 0x82, 0xCE, + 0x05, 0xE2, 0x86, 0x90, 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, + // Bytes 3c00 - 3c3f + 0x05, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0x05, + 0x05, 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x88, 0xA3, 0xCC, 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, + // Bytes 3c40 - 3c7f + 0x05, 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, 0x05, + 0xE2, 0x89, 0xA4, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x89, 0xA5, 0xCC, 0xB8, 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, + // Bytes 3c80 - 3cbf + 0xE2, 0x89, 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2, + 0x89, 0xBD, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + 0x82, 0xCC, 0xB8, 0x05, 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, + // Bytes 3cc0 - 3cff + 0x8A, 0xA8, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, + 0xA9, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xAB, + 0xCC, 0xB8, 0x05, 0x05, 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, 0xDE, 0x06, + 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06, + // Bytes 3d00 - 3d3f + 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06, + // Bytes 3d40 - 3d7f + 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06, + 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06, + 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06, + // Bytes 3d80 - 3dbf + 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06, + 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB1, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06, + // Bytes 3dc0 - 3dff + 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06, + // Bytes 3e00 - 3e3f + 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06, + 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xCE, 0x06, + 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06, + // Bytes 3e40 - 3e7f + 0xCE, 0xB9, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06, + 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0xB9, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06, + 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06, + 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06, + 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06, + // Bytes 3e80 - 3ebf + 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x06, + 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x06, + 0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, 0xCE, 0x06, + 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06, + 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06, + 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06, + 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06, + 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06, + // Bytes 3ec0 - 3eff + 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06, + 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06, + 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06, + 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06, + 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06, + 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06, + 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0x0D, 0x06, + 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x0D, 0x06, + // Bytes 3f00 - 3f3f + 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x0D, 0x06, + 0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96, 0x89, 0x06, + 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8A, 0x15, 0x06, + 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x11, 0x06, + // Bytes 3f40 - 3f7f + 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x97, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x11, 0x06, + // Bytes 3f80 - 3fbf + 0xE3, 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0xA6, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0xA8, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0x11, 0x06, + 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x11, 0x06, + 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x11, 0x06, + // Bytes 3fc0 - 3fff + 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x11, 0x06, + 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x9A, 0x11, 0x06, + 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0x11, 0x06, + 0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x11, 0x06, + // Bytes 4000 - 403f + 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x11, 0x06, + // Bytes 4040 - 407f + 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x11, 0x06, + // Bytes 4080 - 40bf + 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x11, 0x06, + 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0x11, 0x06, + 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0x11, 0x06, + 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x11, 0x06, + // Bytes 40c0 - 40ff + 0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0x11, 0x06, + 0xE3, 0x83, 0xBD, 0xE3, 0x82, 0x99, 0x11, 0x08, + 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, + 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81, + 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x93, + // Bytes 4100 - 413f + 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x91, + 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, + 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, + 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x82, + 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x93, + 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, + 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, + 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, + // Bytes 4140 - 417f + 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80, + 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x94, + 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, + 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, + 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, + 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81, + 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x93, + 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xA9, + // Bytes 4180 - 41bf + 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, + 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, + 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82, + 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x93, + 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, + 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, + 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, + 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x80, + // Bytes 41c0 - 41ff + 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x94, + 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, + 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, + 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85, + 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x81, + 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x93, + 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB7, + 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, + // Bytes 4200 - 423f + 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85, + 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82, + 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x93, + 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, + 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, + 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85, + 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80, + 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x94, + // Bytes 4240 - 427f + 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, + 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, + 0xF0, 0x91, 0x82, 0x99, 0xF0, 0x91, 0x82, 0xBA, + 0x0D, 0x08, 0xF0, 0x91, 0x82, 0x9B, 0xF0, 0x91, + 0x82, 0xBA, 0x0D, 0x08, 0xF0, 0x91, 0x82, 0xA5, + 0xF0, 0x91, 0x82, 0xBA, 0x0D, 0x42, 0xC2, 0xB4, + 0x01, 0x43, 0x20, 0xCC, 0x81, 0xCD, 0x43, 0x20, + 0xCC, 0x83, 0xCD, 0x43, 0x20, 0xCC, 0x84, 0xCD, + // Bytes 4280 - 42bf + 0x43, 0x20, 0xCC, 0x85, 0xCD, 0x43, 0x20, 0xCC, + 0x86, 0xCD, 0x43, 0x20, 0xCC, 0x87, 0xCD, 0x43, + 0x20, 0xCC, 0x88, 0xCD, 0x43, 0x20, 0xCC, 0x8A, + 0xCD, 0x43, 0x20, 0xCC, 0x8B, 0xCD, 0x43, 0x20, + 0xCC, 0x93, 0xCD, 0x43, 0x20, 0xCC, 0x94, 0xCD, + 0x43, 0x20, 0xCC, 0xA7, 0xA9, 0x43, 0x20, 0xCC, + 0xA8, 0xA9, 0x43, 0x20, 0xCC, 0xB3, 0xB9, 0x43, + 0x20, 0xCD, 0x82, 0xCD, 0x43, 0x20, 0xCD, 0x85, + // Bytes 42c0 - 42ff + 0xDD, 0x43, 0x20, 0xD9, 0x8B, 0x5D, 0x43, 0x20, + 0xD9, 0x8C, 0x61, 0x43, 0x20, 0xD9, 0x8D, 0x65, + 0x43, 0x20, 0xD9, 0x8E, 0x69, 0x43, 0x20, 0xD9, + 0x8F, 0x6D, 0x43, 0x20, 0xD9, 0x90, 0x71, 0x43, + 0x20, 0xD9, 0x91, 0x75, 0x43, 0x20, 0xD9, 0x92, + 0x79, 0x43, 0x41, 0xCC, 0x8A, 0xCD, 0x43, 0x73, + 0xCC, 0x87, 0xCD, 0x44, 0x20, 0xE3, 0x82, 0x99, + 0x11, 0x44, 0x20, 0xE3, 0x82, 0x9A, 0x11, 0x44, + // Bytes 4300 - 433f + 0xC2, 0xA8, 0xCC, 0x81, 0xCE, 0x44, 0xCE, 0x91, + 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0x95, 0xCC, 0x81, + 0xCD, 0x44, 0xCE, 0x97, 0xCC, 0x81, 0xCD, 0x44, + 0xCE, 0x99, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0x9F, + 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xA5, 0xCC, 0x81, + 0xCD, 0x44, 0xCE, 0xA5, 0xCC, 0x88, 0xCD, 0x44, + 0xCE, 0xA9, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xB1, + 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xB5, 0xCC, 0x81, + // Bytes 4340 - 437f + 0xCD, 0x44, 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x44, + 0xCE, 0xB9, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xBF, + 0xCC, 0x81, 0xCD, 0x44, 0xCF, 0x85, 0xCC, 0x81, + 0xCD, 0x44, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x44, + 0xD7, 0x90, 0xD6, 0xB7, 0x35, 0x44, 0xD7, 0x90, + 0xD6, 0xB8, 0x39, 0x44, 0xD7, 0x90, 0xD6, 0xBC, + 0x45, 0x44, 0xD7, 0x91, 0xD6, 0xBC, 0x45, 0x44, + 0xD7, 0x91, 0xD6, 0xBF, 0x4D, 0x44, 0xD7, 0x92, + // Bytes 4380 - 43bf + 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x93, 0xD6, 0xBC, + 0x45, 0x44, 0xD7, 0x94, 0xD6, 0xBC, 0x45, 0x44, + 0xD7, 0x95, 0xD6, 0xB9, 0x3D, 0x44, 0xD7, 0x95, + 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x96, 0xD6, 0xBC, + 0x45, 0x44, 0xD7, 0x98, 0xD6, 0xBC, 0x45, 0x44, + 0xD7, 0x99, 0xD6, 0xB4, 0x29, 0x44, 0xD7, 0x99, + 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x9A, 0xD6, 0xBC, + 0x45, 0x44, 0xD7, 0x9B, 0xD6, 0xBC, 0x45, 0x44, + // Bytes 43c0 - 43ff + 0xD7, 0x9B, 0xD6, 0xBF, 0x4D, 0x44, 0xD7, 0x9C, + 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x9E, 0xD6, 0xBC, + 0x45, 0x44, 0xD7, 0xA0, 0xD6, 0xBC, 0x45, 0x44, + 0xD7, 0xA1, 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA3, + 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA4, 0xD6, 0xBC, + 0x45, 0x44, 0xD7, 0xA4, 0xD6, 0xBF, 0x4D, 0x44, + 0xD7, 0xA6, 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA7, + 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA8, 0xD6, 0xBC, + // Bytes 4400 - 443f + 0x45, 0x44, 0xD7, 0xA9, 0xD6, 0xBC, 0x45, 0x44, + 0xD7, 0xA9, 0xD7, 0x81, 0x51, 0x44, 0xD7, 0xA9, + 0xD7, 0x82, 0x55, 0x44, 0xD7, 0xAA, 0xD6, 0xBC, + 0x45, 0x44, 0xD7, 0xB2, 0xD6, 0xB7, 0x35, 0x44, + 0xD8, 0xA7, 0xD9, 0x8B, 0x5D, 0x44, 0xD8, 0xA7, + 0xD9, 0x93, 0xCD, 0x44, 0xD8, 0xA7, 0xD9, 0x94, + 0xCD, 0x44, 0xD8, 0xA7, 0xD9, 0x95, 0xB9, 0x44, + 0xD8, 0xB0, 0xD9, 0xB0, 0x7D, 0x44, 0xD8, 0xB1, + // Bytes 4440 - 447f + 0xD9, 0xB0, 0x7D, 0x44, 0xD9, 0x80, 0xD9, 0x8B, + 0x5D, 0x44, 0xD9, 0x80, 0xD9, 0x8E, 0x69, 0x44, + 0xD9, 0x80, 0xD9, 0x8F, 0x6D, 0x44, 0xD9, 0x80, + 0xD9, 0x90, 0x71, 0x44, 0xD9, 0x80, 0xD9, 0x91, + 0x75, 0x44, 0xD9, 0x80, 0xD9, 0x92, 0x79, 0x44, + 0xD9, 0x87, 0xD9, 0xB0, 0x7D, 0x44, 0xD9, 0x88, + 0xD9, 0x94, 0xCD, 0x44, 0xD9, 0x89, 0xD9, 0xB0, + 0x7D, 0x44, 0xD9, 0x8A, 0xD9, 0x94, 0xCD, 0x44, + // Bytes 4480 - 44bf + 0xDB, 0x92, 0xD9, 0x94, 0xCD, 0x44, 0xDB, 0x95, + 0xD9, 0x94, 0xCD, 0x45, 0x20, 0xCC, 0x88, 0xCC, + 0x80, 0xCE, 0x45, 0x20, 0xCC, 0x88, 0xCC, 0x81, + 0xCE, 0x45, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xCE, + 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x45, + 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x45, 0x20, + 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x45, 0x20, 0xCC, + 0x94, 0xCC, 0x80, 0xCE, 0x45, 0x20, 0xCC, 0x94, + // Bytes 44c0 - 44ff + 0xCC, 0x81, 0xCE, 0x45, 0x20, 0xCC, 0x94, 0xCD, + 0x82, 0xCE, 0x45, 0x20, 0xD9, 0x8C, 0xD9, 0x91, + 0x76, 0x45, 0x20, 0xD9, 0x8D, 0xD9, 0x91, 0x76, + 0x45, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x76, 0x45, + 0x20, 0xD9, 0x8F, 0xD9, 0x91, 0x76, 0x45, 0x20, + 0xD9, 0x90, 0xD9, 0x91, 0x76, 0x45, 0x20, 0xD9, + 0x91, 0xD9, 0xB0, 0x7E, 0x45, 0xE2, 0xAB, 0x9D, + 0xCC, 0xB8, 0x05, 0x46, 0xCE, 0xB9, 0xCC, 0x88, + // Bytes 4500 - 453f + 0xCC, 0x81, 0xCE, 0x46, 0xCF, 0x85, 0xCC, 0x88, + 0xCC, 0x81, 0xCE, 0x46, 0xD7, 0xA9, 0xD6, 0xBC, + 0xD7, 0x81, 0x52, 0x46, 0xD7, 0xA9, 0xD6, 0xBC, + 0xD7, 0x82, 0x56, 0x46, 0xD9, 0x80, 0xD9, 0x8E, + 0xD9, 0x91, 0x76, 0x46, 0xD9, 0x80, 0xD9, 0x8F, + 0xD9, 0x91, 0x76, 0x46, 0xD9, 0x80, 0xD9, 0x90, + 0xD9, 0x91, 0x76, 0x46, 0xE0, 0xA4, 0x95, 0xE0, + 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x96, 0xE0, + // Bytes 4540 - 457f + 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x97, 0xE0, + 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x9C, 0xE0, + 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xA1, 0xE0, + 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xA2, 0xE0, + 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xAB, 0xE0, + 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xAF, 0xE0, + 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xA1, 0xE0, + 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xA2, 0xE0, + // Bytes 4580 - 45bf + 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xAF, 0xE0, + 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x96, 0xE0, + 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x97, 0xE0, + 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x9C, 0xE0, + 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xAB, 0xE0, + 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xB2, 0xE0, + 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xB8, 0xE0, + 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xAC, 0xA1, 0xE0, + // Bytes 45c0 - 45ff + 0xAC, 0xBC, 0x0D, 0x46, 0xE0, 0xAC, 0xA2, 0xE0, + 0xAC, 0xBC, 0x0D, 0x46, 0xE0, 0xBE, 0xB2, 0xE0, + 0xBE, 0x80, 0xA1, 0x46, 0xE0, 0xBE, 0xB3, 0xE0, + 0xBE, 0x80, 0xA1, 0x46, 0xE3, 0x83, 0x86, 0xE3, + 0x82, 0x99, 0x11, 0x48, 0xF0, 0x9D, 0x85, 0x97, + 0xF0, 0x9D, 0x85, 0xA5, 0xB1, 0x48, 0xF0, 0x9D, + 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xB1, 0x48, + 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, + // Bytes 4600 - 463f + 0xB1, 0x48, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, + 0x85, 0xA5, 0xB1, 0x49, 0xE0, 0xBE, 0xB2, 0xE0, + 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xA2, 0x49, 0xE0, + 0xBE, 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80, + 0xA2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, + 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xB2, 0x4C, + 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, + 0xF0, 0x9D, 0x85, 0xAF, 0xB2, 0x4C, 0xF0, 0x9D, + // Bytes 4640 - 467f + 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + 0x85, 0xB0, 0xB2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, + 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB1, + 0xB2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, + 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xB2, 0x4C, + 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, + 0xF0, 0x9D, 0x85, 0xAE, 0xB2, 0x4C, 0xF0, 0x9D, + 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, + // Bytes 4680 - 46bf + 0x85, 0xAF, 0xB2, 0x4C, 0xF0, 0x9D, 0x86, 0xBA, + 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, + 0xB2, 0x4C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D, + 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xB2, 0x83, + 0x41, 0xCC, 0x82, 0xCD, 0x83, 0x41, 0xCC, 0x86, + 0xCD, 0x83, 0x41, 0xCC, 0x87, 0xCD, 0x83, 0x41, + 0xCC, 0x88, 0xCD, 0x83, 0x41, 0xCC, 0x8A, 0xCD, + 0x83, 0x41, 0xCC, 0xA3, 0xB9, 0x83, 0x43, 0xCC, + // Bytes 46c0 - 46ff + 0xA7, 0xA9, 0x83, 0x45, 0xCC, 0x82, 0xCD, 0x83, + 0x45, 0xCC, 0x84, 0xCD, 0x83, 0x45, 0xCC, 0xA3, + 0xB9, 0x83, 0x45, 0xCC, 0xA7, 0xA9, 0x83, 0x49, + 0xCC, 0x88, 0xCD, 0x83, 0x4C, 0xCC, 0xA3, 0xB9, + 0x83, 0x4F, 0xCC, 0x82, 0xCD, 0x83, 0x4F, 0xCC, + 0x83, 0xCD, 0x83, 0x4F, 0xCC, 0x84, 0xCD, 0x83, + 0x4F, 0xCC, 0x87, 0xCD, 0x83, 0x4F, 0xCC, 0x88, + 0xCD, 0x83, 0x4F, 0xCC, 0x9B, 0xB1, 0x83, 0x4F, + // Bytes 4700 - 473f + 0xCC, 0xA3, 0xB9, 0x83, 0x4F, 0xCC, 0xA8, 0xA9, + 0x83, 0x52, 0xCC, 0xA3, 0xB9, 0x83, 0x53, 0xCC, + 0x81, 0xCD, 0x83, 0x53, 0xCC, 0x8C, 0xCD, 0x83, + 0x53, 0xCC, 0xA3, 0xB9, 0x83, 0x55, 0xCC, 0x83, + 0xCD, 0x83, 0x55, 0xCC, 0x84, 0xCD, 0x83, 0x55, + 0xCC, 0x88, 0xCD, 0x83, 0x55, 0xCC, 0x9B, 0xB1, + 0x83, 0x61, 0xCC, 0x82, 0xCD, 0x83, 0x61, 0xCC, + 0x86, 0xCD, 0x83, 0x61, 0xCC, 0x87, 0xCD, 0x83, + // Bytes 4740 - 477f + 0x61, 0xCC, 0x88, 0xCD, 0x83, 0x61, 0xCC, 0x8A, + 0xCD, 0x83, 0x61, 0xCC, 0xA3, 0xB9, 0x83, 0x63, + 0xCC, 0xA7, 0xA9, 0x83, 0x65, 0xCC, 0x82, 0xCD, + 0x83, 0x65, 0xCC, 0x84, 0xCD, 0x83, 0x65, 0xCC, + 0xA3, 0xB9, 0x83, 0x65, 0xCC, 0xA7, 0xA9, 0x83, + 0x69, 0xCC, 0x88, 0xCD, 0x83, 0x6C, 0xCC, 0xA3, + 0xB9, 0x83, 0x6F, 0xCC, 0x82, 0xCD, 0x83, 0x6F, + 0xCC, 0x83, 0xCD, 0x83, 0x6F, 0xCC, 0x84, 0xCD, + // Bytes 4780 - 47bf + 0x83, 0x6F, 0xCC, 0x87, 0xCD, 0x83, 0x6F, 0xCC, + 0x88, 0xCD, 0x83, 0x6F, 0xCC, 0x9B, 0xB1, 0x83, + 0x6F, 0xCC, 0xA3, 0xB9, 0x83, 0x6F, 0xCC, 0xA8, + 0xA9, 0x83, 0x72, 0xCC, 0xA3, 0xB9, 0x83, 0x73, + 0xCC, 0x81, 0xCD, 0x83, 0x73, 0xCC, 0x8C, 0xCD, + 0x83, 0x73, 0xCC, 0xA3, 0xB9, 0x83, 0x75, 0xCC, + 0x83, 0xCD, 0x83, 0x75, 0xCC, 0x84, 0xCD, 0x83, + 0x75, 0xCC, 0x88, 0xCD, 0x83, 0x75, 0xCC, 0x9B, + // Bytes 47c0 - 47ff + 0xB1, 0x84, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x84, + 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0x95, + 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0x95, 0xCC, 0x94, + 0xCD, 0x84, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x84, + 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0x99, + 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0x99, 0xCC, 0x94, + 0xCD, 0x84, 0xCE, 0x9F, 0xCC, 0x93, 0xCD, 0x84, + 0xCE, 0x9F, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0xA5, + // Bytes 4800 - 483f + 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0xA9, 0xCC, 0x93, + 0xCD, 0x84, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x84, + 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x84, 0xCE, 0xB1, + 0xCC, 0x81, 0xCD, 0x84, 0xCE, 0xB1, 0xCC, 0x93, + 0xCD, 0x84, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x84, + 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x84, 0xCE, 0xB5, + 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB5, 0xCC, 0x94, + 0xCD, 0x84, 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x84, + // Bytes 4840 - 487f + 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x84, 0xCE, 0xB7, + 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB7, 0xCC, 0x94, + 0xCD, 0x84, 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x84, + 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x84, 0xCE, 0xB9, + 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB9, 0xCC, 0x94, + 0xCD, 0x84, 0xCE, 0xBF, 0xCC, 0x93, 0xCD, 0x84, + 0xCE, 0xBF, 0xCC, 0x94, 0xCD, 0x84, 0xCF, 0x85, + 0xCC, 0x88, 0xCD, 0x84, 0xCF, 0x85, 0xCC, 0x93, + // Bytes 4880 - 48bf + 0xCD, 0x84, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x84, + 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x84, 0xCF, 0x89, + 0xCC, 0x81, 0xCD, 0x84, 0xCF, 0x89, 0xCC, 0x93, + 0xCD, 0x84, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x84, + 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x86, 0xCE, 0x91, + 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x91, + 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x91, + 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x91, + // Bytes 48c0 - 48ff + 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x91, + 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x91, + 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x97, + 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x97, + 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x97, + 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x97, + 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x97, + 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x97, + // Bytes 4900 - 493f + 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xA9, + 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xA9, + 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xA9, + 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xA9, + 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xA9, + 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xA9, + 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB1, + 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB1, + // Bytes 4940 - 497f + 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB1, + 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB1, + 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB1, + 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB1, + 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB7, + 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB7, + 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB7, + 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB7, + // Bytes 4980 - 49bf + 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB7, + 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB7, + 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCF, 0x89, + 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCF, 0x89, + 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCF, 0x89, + 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCF, 0x89, + 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCF, 0x89, + 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCF, 0x89, + // Bytes 49c0 - 49ff + 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x42, 0xCC, 0x80, + 0xCD, 0x33, 0x42, 0xCC, 0x81, 0xCD, 0x33, 0x42, + 0xCC, 0x93, 0xCD, 0x33, 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, + // Bytes 4a00 - 4a3f + 0x85, 0xA8, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA9, + 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAA, 0x01, 0x00, + 0x43, 0xE1, 0x85, 0xAB, 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, + // Bytes 4a40 - 4a7f + 0x43, 0xE1, 0x85, 0xB3, 0x01, 0x00, 0x43, 0xE1, + 0x85, 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB5, + 0x01, 0x00, 0x43, 0xE1, 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, + // Bytes 4a80 - 4abf + 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB5, 0x01, 0x00, + 0x44, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x33, 0x43, + 0xE3, 0x82, 0x99, 0x11, 0x04, 0x43, 0xE3, 0x82, + 0x9A, 0x11, 0x04, 0x46, 0xE0, 0xBD, 0xB1, 0xE0, + 0xBD, 0xB2, 0xA2, 0x27, 0x46, 0xE0, 0xBD, 0xB1, + 0xE0, 0xBD, 0xB4, 0xA6, 0x27, 0x46, 0xE0, 0xBD, + 0xB1, 0xE0, 0xBE, 0x80, 0xA2, 0x27, 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: 10680 bytes (10.43 KiB). Checksum: a555db76d4becdd2. +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: 0x2f86, 0xc1: 0x2f8b, 0xc2: 0x469f, 0xc3: 0x2f90, 0xc4: 0x46ae, 0xc5: 0x46b3, + 0xc6: 0xa000, 0xc7: 0x46bd, 0xc8: 0x2ff9, 0xc9: 0x2ffe, 0xca: 0x46c2, 0xcb: 0x3012, + 0xcc: 0x3085, 0xcd: 0x308a, 0xce: 0x308f, 0xcf: 0x46d6, 0xd1: 0x311b, + 0xd2: 0x313e, 0xd3: 0x3143, 0xd4: 0x46e0, 0xd5: 0x46e5, 0xd6: 0x46f4, + 0xd8: 0xa000, 0xd9: 0x31ca, 0xda: 0x31cf, 0xdb: 0x31d4, 0xdc: 0x4726, 0xdd: 0x324c, + 0xe0: 0x3292, 0xe1: 0x3297, 0xe2: 0x4730, 0xe3: 0x329c, + 0xe4: 0x473f, 0xe5: 0x4744, 0xe6: 0xa000, 0xe7: 0x474e, 0xe8: 0x3305, 0xe9: 0x330a, + 0xea: 0x4753, 0xeb: 0x331e, 0xec: 0x3396, 0xed: 0x339b, 0xee: 0x33a0, 0xef: 0x4767, + 0xf1: 0x342c, 0xf2: 0x344f, 0xf3: 0x3454, 0xf4: 0x4771, 0xf5: 0x4776, + 0xf6: 0x4785, 0xf8: 0xa000, 0xf9: 0x34e0, 0xfa: 0x34e5, 0xfb: 0x34ea, + 0xfc: 0x47b7, 0xfd: 0x3567, 0xff: 0x3580, + // Block 0x4, offset 0x100 + 0x100: 0x2f95, 0x101: 0x32a1, 0x102: 0x46a4, 0x103: 0x4735, 0x104: 0x2fb3, 0x105: 0x32bf, + 0x106: 0x2fc7, 0x107: 0x32d3, 0x108: 0x2fcc, 0x109: 0x32d8, 0x10a: 0x2fd1, 0x10b: 0x32dd, + 0x10c: 0x2fd6, 0x10d: 0x32e2, 0x10e: 0x2fe0, 0x10f: 0x32ec, + 0x112: 0x46c7, 0x113: 0x4758, 0x114: 0x3008, 0x115: 0x3314, 0x116: 0x300d, 0x117: 0x3319, + 0x118: 0x302b, 0x119: 0x3337, 0x11a: 0x301c, 0x11b: 0x3328, 0x11c: 0x3044, 0x11d: 0x3350, + 0x11e: 0x304e, 0x11f: 0x335a, 0x120: 0x3053, 0x121: 0x335f, 0x122: 0x305d, 0x123: 0x3369, + 0x124: 0x3062, 0x125: 0x336e, 0x128: 0x3094, 0x129: 0x33a5, + 0x12a: 0x3099, 0x12b: 0x33aa, 0x12c: 0x309e, 0x12d: 0x33af, 0x12e: 0x30c1, 0x12f: 0x33cd, + 0x130: 0x30a3, 0x134: 0x30cb, 0x135: 0x33d7, + 0x136: 0x30df, 0x137: 0x33f0, 0x139: 0x30e9, 0x13a: 0x33fa, 0x13b: 0x30f3, + 0x13c: 0x3404, 0x13d: 0x30ee, 0x13e: 0x33ff, + // Block 0x5, offset 0x140 + 0x143: 0x3116, 0x144: 0x3427, 0x145: 0x312f, + 0x146: 0x3440, 0x147: 0x3125, 0x148: 0x3436, + 0x14c: 0x46ea, 0x14d: 0x477b, 0x14e: 0x3148, 0x14f: 0x3459, 0x150: 0x3152, 0x151: 0x3463, + 0x154: 0x3170, 0x155: 0x3481, 0x156: 0x3189, 0x157: 0x349a, + 0x158: 0x317a, 0x159: 0x348b, 0x15a: 0x470d, 0x15b: 0x479e, 0x15c: 0x3193, 0x15d: 0x34a4, + 0x15e: 0x31a2, 0x15f: 0x34b3, 0x160: 0x4712, 0x161: 0x47a3, 0x162: 0x31bb, 0x163: 0x34d1, + 0x164: 0x31ac, 0x165: 0x34c2, 0x168: 0x471c, 0x169: 0x47ad, + 0x16a: 0x4721, 0x16b: 0x47b2, 0x16c: 0x31d9, 0x16d: 0x34ef, 0x16e: 0x31e3, 0x16f: 0x34f9, + 0x170: 0x31e8, 0x171: 0x34fe, 0x172: 0x3206, 0x173: 0x351c, 0x174: 0x3229, 0x175: 0x353f, + 0x176: 0x3251, 0x177: 0x356c, 0x178: 0x3265, 0x179: 0x3274, 0x17a: 0x3594, 0x17b: 0x327e, + 0x17c: 0x359e, 0x17d: 0x3283, 0x17e: 0x35a3, 0x17f: 0xa000, + // Block 0x6, offset 0x180 + 0x184: 0x8100, 0x185: 0x8100, + 0x186: 0x8100, + 0x18d: 0x2f9f, 0x18e: 0x32ab, 0x18f: 0x30ad, 0x190: 0x33b9, 0x191: 0x3157, + 0x192: 0x3468, 0x193: 0x31ed, 0x194: 0x3503, 0x195: 0x39e6, 0x196: 0x3b75, 0x197: 0x39df, + 0x198: 0x3b6e, 0x199: 0x39ed, 0x19a: 0x3b7c, 0x19b: 0x39d8, 0x19c: 0x3b67, + 0x19e: 0x38c7, 0x19f: 0x3a56, 0x1a0: 0x38c0, 0x1a1: 0x3a4f, 0x1a2: 0x35ca, 0x1a3: 0x35dc, + 0x1a6: 0x3058, 0x1a7: 0x3364, 0x1a8: 0x30d5, 0x1a9: 0x33e6, + 0x1aa: 0x4703, 0x1ab: 0x4794, 0x1ac: 0x39a7, 0x1ad: 0x3b36, 0x1ae: 0x35ee, 0x1af: 0x35f4, + 0x1b0: 0x33dc, 0x1b4: 0x303f, 0x1b5: 0x334b, + 0x1b8: 0x3111, 0x1b9: 0x3422, 0x1ba: 0x38ce, 0x1bb: 0x3a5d, + 0x1bc: 0x35c4, 0x1bd: 0x35d6, 0x1be: 0x35d0, 0x1bf: 0x35e2, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2fa4, 0x1c1: 0x32b0, 0x1c2: 0x2fa9, 0x1c3: 0x32b5, 0x1c4: 0x3021, 0x1c5: 0x332d, + 0x1c6: 0x3026, 0x1c7: 0x3332, 0x1c8: 0x30b2, 0x1c9: 0x33be, 0x1ca: 0x30b7, 0x1cb: 0x33c3, + 0x1cc: 0x315c, 0x1cd: 0x346d, 0x1ce: 0x3161, 0x1cf: 0x3472, 0x1d0: 0x317f, 0x1d1: 0x3490, + 0x1d2: 0x3184, 0x1d3: 0x3495, 0x1d4: 0x31f2, 0x1d5: 0x3508, 0x1d6: 0x31f7, 0x1d7: 0x350d, + 0x1d8: 0x319d, 0x1d9: 0x34ae, 0x1da: 0x31b6, 0x1db: 0x34cc, + 0x1de: 0x3071, 0x1df: 0x337d, + 0x1e6: 0x46a9, 0x1e7: 0x473a, 0x1e8: 0x46d1, 0x1e9: 0x4762, + 0x1ea: 0x3976, 0x1eb: 0x3b05, 0x1ec: 0x3953, 0x1ed: 0x3ae2, 0x1ee: 0x46ef, 0x1ef: 0x4780, + 0x1f0: 0x396f, 0x1f1: 0x3afe, 0x1f2: 0x325b, 0x1f3: 0x3576, + // Block 0x8, offset 0x200 + 0x200: 0x9933, 0x201: 0x9933, 0x202: 0x9933, 0x203: 0x9933, 0x204: 0x9933, 0x205: 0x8133, + 0x206: 0x9933, 0x207: 0x9933, 0x208: 0x9933, 0x209: 0x9933, 0x20a: 0x9933, 0x20b: 0x9933, + 0x20c: 0x9933, 0x20d: 0x8133, 0x20e: 0x8133, 0x20f: 0x9933, 0x210: 0x8133, 0x211: 0x9933, + 0x212: 0x8133, 0x213: 0x9933, 0x214: 0x9933, 0x215: 0x8134, 0x216: 0x812e, 0x217: 0x812e, + 0x218: 0x812e, 0x219: 0x812e, 0x21a: 0x8134, 0x21b: 0x992c, 0x21c: 0x812e, 0x21d: 0x812e, + 0x21e: 0x812e, 0x21f: 0x812e, 0x220: 0x812e, 0x221: 0x812a, 0x222: 0x812a, 0x223: 0x992e, + 0x224: 0x992e, 0x225: 0x992e, 0x226: 0x992e, 0x227: 0x992a, 0x228: 0x992a, 0x229: 0x812e, + 0x22a: 0x812e, 0x22b: 0x812e, 0x22c: 0x812e, 0x22d: 0x992e, 0x22e: 0x992e, 0x22f: 0x812e, + 0x230: 0x992e, 0x231: 0x992e, 0x232: 0x812e, 0x233: 0x812e, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812e, 0x23a: 0x812e, 0x23b: 0x812e, + 0x23c: 0x812e, 0x23d: 0x8133, 0x23e: 0x8133, 0x23f: 0x8133, + // Block 0x9, offset 0x240 + 0x240: 0x49c5, 0x241: 0x49ca, 0x242: 0x9933, 0x243: 0x49cf, 0x244: 0x4a88, 0x245: 0x9937, + 0x246: 0x8133, 0x247: 0x812e, 0x248: 0x812e, 0x249: 0x812e, 0x24a: 0x8133, 0x24b: 0x8133, + 0x24c: 0x8133, 0x24d: 0x812e, 0x24e: 0x812e, 0x250: 0x8133, 0x251: 0x8133, + 0x252: 0x8133, 0x253: 0x812e, 0x254: 0x812e, 0x255: 0x812e, 0x256: 0x812e, 0x257: 0x8133, + 0x258: 0x8134, 0x259: 0x812e, 0x25a: 0x812e, 0x25b: 0x8133, 0x25c: 0x8135, 0x25d: 0x8136, + 0x25e: 0x8136, 0x25f: 0x8135, 0x260: 0x8136, 0x261: 0x8136, 0x262: 0x8135, 0x263: 0x8133, + 0x264: 0x8133, 0x265: 0x8133, 0x266: 0x8133, 0x267: 0x8133, 0x268: 0x8133, 0x269: 0x8133, + 0x26a: 0x8133, 0x26b: 0x8133, 0x26c: 0x8133, 0x26d: 0x8133, 0x26e: 0x8133, 0x26f: 0x8133, + 0x274: 0x0173, + 0x27a: 0x8100, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x8100, 0x285: 0x35b8, + 0x286: 0x3600, 0x287: 0x00ce, 0x288: 0x361e, 0x289: 0x362a, 0x28a: 0x363c, + 0x28c: 0x365a, 0x28e: 0x366c, 0x28f: 0x368a, 0x290: 0x3e1f, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x364e, 0x2ab: 0x367e, 0x2ac: 0x4815, 0x2ad: 0x36ae, 0x2ae: 0x483f, 0x2af: 0x36c0, + 0x2b0: 0x3e87, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x3738, 0x2c1: 0x3744, 0x2c3: 0x3732, + 0x2c6: 0xa000, 0x2c7: 0x3720, + 0x2cc: 0x3774, 0x2cd: 0x375c, 0x2ce: 0x3786, 0x2d0: 0xa000, + 0x2d3: 0xa000, 0x2d5: 0xa000, 0x2d6: 0xa000, 0x2d7: 0xa000, + 0x2d8: 0xa000, 0x2d9: 0x3768, 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: 0x37ec, 0x2fa: 0xa000, + 0x2fe: 0xa000, + // Block 0xc, offset 0x300 + 0x301: 0x374a, 0x302: 0x37ce, + 0x310: 0x3726, 0x311: 0x37aa, + 0x312: 0x372c, 0x313: 0x37b0, 0x316: 0x373e, 0x317: 0x37c2, + 0x318: 0xa000, 0x319: 0xa000, 0x31a: 0x3840, 0x31b: 0x3846, 0x31c: 0x3750, 0x31d: 0x37d4, + 0x31e: 0x3756, 0x31f: 0x37da, 0x322: 0x3762, 0x323: 0x37e6, + 0x324: 0x376e, 0x325: 0x37f2, 0x326: 0x377a, 0x327: 0x37fe, 0x328: 0xa000, 0x329: 0xa000, + 0x32a: 0x384c, 0x32b: 0x3852, 0x32c: 0x37a4, 0x32d: 0x3828, 0x32e: 0x3780, 0x32f: 0x3804, + 0x330: 0x378c, 0x331: 0x3810, 0x332: 0x3792, 0x333: 0x3816, 0x334: 0x3798, 0x335: 0x381c, + 0x338: 0x379e, 0x339: 0x3822, + // Block 0xd, offset 0x340 + 0x351: 0x812e, + 0x352: 0x8133, 0x353: 0x8133, 0x354: 0x8133, 0x355: 0x8133, 0x356: 0x812e, 0x357: 0x8133, + 0x358: 0x8133, 0x359: 0x8133, 0x35a: 0x812f, 0x35b: 0x812e, 0x35c: 0x8133, 0x35d: 0x8133, + 0x35e: 0x8133, 0x35f: 0x8133, 0x360: 0x8133, 0x361: 0x8133, 0x362: 0x812e, 0x363: 0x812e, + 0x364: 0x812e, 0x365: 0x812e, 0x366: 0x812e, 0x367: 0x812e, 0x368: 0x8133, 0x369: 0x8133, + 0x36a: 0x812e, 0x36b: 0x8133, 0x36c: 0x8133, 0x36d: 0x812f, 0x36e: 0x8132, 0x36f: 0x8133, + 0x370: 0x8106, 0x371: 0x8107, 0x372: 0x8108, 0x373: 0x8109, 0x374: 0x810a, 0x375: 0x810b, + 0x376: 0x810c, 0x377: 0x810d, 0x378: 0x810e, 0x379: 0x810f, 0x37a: 0x810f, 0x37b: 0x8110, + 0x37c: 0x8111, 0x37d: 0x8112, 0x37f: 0x8113, + // Block 0xe, offset 0x380 + 0x388: 0xa000, 0x38a: 0xa000, 0x38b: 0x8117, + 0x38c: 0x8118, 0x38d: 0x8119, 0x38e: 0x811a, 0x38f: 0x811b, 0x390: 0x811c, 0x391: 0x811d, + 0x392: 0x811e, 0x393: 0x9933, 0x394: 0x9933, 0x395: 0x992e, 0x396: 0x812e, 0x397: 0x8133, + 0x398: 0x8133, 0x399: 0x8133, 0x39a: 0x8133, 0x39b: 0x8133, 0x39c: 0x812e, 0x39d: 0x8133, + 0x39e: 0x8133, 0x39f: 0x812e, + 0x3b0: 0x811f, + // Block 0xf, offset 0x3c0 + 0x3d3: 0x812e, 0x3d4: 0x8133, 0x3d5: 0x8133, 0x3d6: 0x8133, 0x3d7: 0x8133, + 0x3d8: 0x8133, 0x3d9: 0x8133, 0x3da: 0x8133, 0x3db: 0x8133, 0x3dc: 0x8133, 0x3dd: 0x8133, + 0x3de: 0x8133, 0x3df: 0x8133, 0x3e0: 0x8133, 0x3e1: 0x8133, 0x3e3: 0x812e, + 0x3e4: 0x8133, 0x3e5: 0x8133, 0x3e6: 0x812e, 0x3e7: 0x8133, 0x3e8: 0x8133, 0x3e9: 0x812e, + 0x3ea: 0x8133, 0x3eb: 0x8133, 0x3ec: 0x8133, 0x3ed: 0x812e, 0x3ee: 0x812e, 0x3ef: 0x812e, + 0x3f0: 0x8117, 0x3f1: 0x8118, 0x3f2: 0x8119, 0x3f3: 0x8133, 0x3f4: 0x8133, 0x3f5: 0x8133, + 0x3f6: 0x812e, 0x3f7: 0x8133, 0x3f8: 0x8133, 0x3f9: 0x812e, 0x3fa: 0x812e, 0x3fb: 0x8133, + 0x3fc: 0x8133, 0x3fd: 0x8133, 0x3fe: 0x8133, 0x3ff: 0x8133, + // Block 0x10, offset 0x400 + 0x405: 0xa000, + 0x406: 0x2d33, 0x407: 0xa000, 0x408: 0x2d3b, 0x409: 0xa000, 0x40a: 0x2d43, 0x40b: 0xa000, + 0x40c: 0x2d4b, 0x40d: 0xa000, 0x40e: 0x2d53, 0x411: 0xa000, + 0x412: 0x2d5b, + 0x434: 0x8103, 0x435: 0x9900, + 0x43a: 0xa000, 0x43b: 0x2d63, + 0x43c: 0xa000, 0x43d: 0x2d6b, 0x43e: 0xa000, 0x43f: 0xa000, + // Block 0x11, offset 0x440 + 0x440: 0x8133, 0x441: 0x8133, 0x442: 0x812e, 0x443: 0x8133, 0x444: 0x8133, 0x445: 0x8133, + 0x446: 0x8133, 0x447: 0x8133, 0x448: 0x8133, 0x449: 0x8133, 0x44a: 0x812e, 0x44b: 0x8133, + 0x44c: 0x8133, 0x44d: 0x8136, 0x44e: 0x812b, 0x44f: 0x812e, 0x450: 0x812a, 0x451: 0x8133, + 0x452: 0x8133, 0x453: 0x8133, 0x454: 0x8133, 0x455: 0x8133, 0x456: 0x8133, 0x457: 0x8133, + 0x458: 0x8133, 0x459: 0x8133, 0x45a: 0x8133, 0x45b: 0x8133, 0x45c: 0x8133, 0x45d: 0x8133, + 0x45e: 0x8133, 0x45f: 0x8133, 0x460: 0x8133, 0x461: 0x8133, 0x462: 0x8133, 0x463: 0x8133, + 0x464: 0x8133, 0x465: 0x8133, 0x466: 0x8133, 0x467: 0x8133, 0x468: 0x8133, 0x469: 0x8133, + 0x46a: 0x8133, 0x46b: 0x8133, 0x46c: 0x8133, 0x46d: 0x8133, 0x46e: 0x8133, 0x46f: 0x8133, + 0x470: 0x8133, 0x471: 0x8133, 0x472: 0x8133, 0x473: 0x8133, 0x474: 0x8133, 0x475: 0x8133, + 0x476: 0x8134, 0x477: 0x8132, 0x478: 0x8132, 0x479: 0x812e, 0x47b: 0x8133, + 0x47c: 0x8135, 0x47d: 0x812e, 0x47e: 0x8133, 0x47f: 0x812e, + // Block 0x12, offset 0x480 + 0x480: 0x2fae, 0x481: 0x32ba, 0x482: 0x2fb8, 0x483: 0x32c4, 0x484: 0x2fbd, 0x485: 0x32c9, + 0x486: 0x2fc2, 0x487: 0x32ce, 0x488: 0x38e3, 0x489: 0x3a72, 0x48a: 0x2fdb, 0x48b: 0x32e7, + 0x48c: 0x2fe5, 0x48d: 0x32f1, 0x48e: 0x2ff4, 0x48f: 0x3300, 0x490: 0x2fea, 0x491: 0x32f6, + 0x492: 0x2fef, 0x493: 0x32fb, 0x494: 0x3906, 0x495: 0x3a95, 0x496: 0x390d, 0x497: 0x3a9c, + 0x498: 0x3030, 0x499: 0x333c, 0x49a: 0x3035, 0x49b: 0x3341, 0x49c: 0x391b, 0x49d: 0x3aaa, + 0x49e: 0x303a, 0x49f: 0x3346, 0x4a0: 0x3049, 0x4a1: 0x3355, 0x4a2: 0x3067, 0x4a3: 0x3373, + 0x4a4: 0x3076, 0x4a5: 0x3382, 0x4a6: 0x306c, 0x4a7: 0x3378, 0x4a8: 0x307b, 0x4a9: 0x3387, + 0x4aa: 0x3080, 0x4ab: 0x338c, 0x4ac: 0x30c6, 0x4ad: 0x33d2, 0x4ae: 0x3922, 0x4af: 0x3ab1, + 0x4b0: 0x30d0, 0x4b1: 0x33e1, 0x4b2: 0x30da, 0x4b3: 0x33eb, 0x4b4: 0x30e4, 0x4b5: 0x33f5, + 0x4b6: 0x46db, 0x4b7: 0x476c, 0x4b8: 0x3929, 0x4b9: 0x3ab8, 0x4ba: 0x30fd, 0x4bb: 0x340e, + 0x4bc: 0x30f8, 0x4bd: 0x3409, 0x4be: 0x3102, 0x4bf: 0x3413, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x3107, 0x4c1: 0x3418, 0x4c2: 0x310c, 0x4c3: 0x341d, 0x4c4: 0x3120, 0x4c5: 0x3431, + 0x4c6: 0x312a, 0x4c7: 0x343b, 0x4c8: 0x3139, 0x4c9: 0x344a, 0x4ca: 0x3134, 0x4cb: 0x3445, + 0x4cc: 0x394c, 0x4cd: 0x3adb, 0x4ce: 0x395a, 0x4cf: 0x3ae9, 0x4d0: 0x3961, 0x4d1: 0x3af0, + 0x4d2: 0x3968, 0x4d3: 0x3af7, 0x4d4: 0x3166, 0x4d5: 0x3477, 0x4d6: 0x316b, 0x4d7: 0x347c, + 0x4d8: 0x3175, 0x4d9: 0x3486, 0x4da: 0x4708, 0x4db: 0x4799, 0x4dc: 0x39ae, 0x4dd: 0x3b3d, + 0x4de: 0x318e, 0x4df: 0x349f, 0x4e0: 0x3198, 0x4e1: 0x34a9, 0x4e2: 0x4717, 0x4e3: 0x47a8, + 0x4e4: 0x39b5, 0x4e5: 0x3b44, 0x4e6: 0x39bc, 0x4e7: 0x3b4b, 0x4e8: 0x39c3, 0x4e9: 0x3b52, + 0x4ea: 0x31a7, 0x4eb: 0x34b8, 0x4ec: 0x31b1, 0x4ed: 0x34c7, 0x4ee: 0x31c5, 0x4ef: 0x34db, + 0x4f0: 0x31c0, 0x4f1: 0x34d6, 0x4f2: 0x3201, 0x4f3: 0x3517, 0x4f4: 0x3210, 0x4f5: 0x3526, + 0x4f6: 0x320b, 0x4f7: 0x3521, 0x4f8: 0x39ca, 0x4f9: 0x3b59, 0x4fa: 0x39d1, 0x4fb: 0x3b60, + 0x4fc: 0x3215, 0x4fd: 0x352b, 0x4fe: 0x321a, 0x4ff: 0x3530, + // Block 0x14, offset 0x500 + 0x500: 0x321f, 0x501: 0x3535, 0x502: 0x3224, 0x503: 0x353a, 0x504: 0x3233, 0x505: 0x3549, + 0x506: 0x322e, 0x507: 0x3544, 0x508: 0x3238, 0x509: 0x3553, 0x50a: 0x323d, 0x50b: 0x3558, + 0x50c: 0x3242, 0x50d: 0x355d, 0x50e: 0x3260, 0x50f: 0x357b, 0x510: 0x3279, 0x511: 0x3599, + 0x512: 0x3288, 0x513: 0x35a8, 0x514: 0x328d, 0x515: 0x35ad, 0x516: 0x3391, 0x517: 0x34bd, + 0x518: 0x354e, 0x519: 0x358a, 0x51b: 0x35e8, + 0x520: 0x46b8, 0x521: 0x4749, 0x522: 0x2f9a, 0x523: 0x32a6, + 0x524: 0x388f, 0x525: 0x3a1e, 0x526: 0x3888, 0x527: 0x3a17, 0x528: 0x389d, 0x529: 0x3a2c, + 0x52a: 0x3896, 0x52b: 0x3a25, 0x52c: 0x38d5, 0x52d: 0x3a64, 0x52e: 0x38ab, 0x52f: 0x3a3a, + 0x530: 0x38a4, 0x531: 0x3a33, 0x532: 0x38b9, 0x533: 0x3a48, 0x534: 0x38b2, 0x535: 0x3a41, + 0x536: 0x38dc, 0x537: 0x3a6b, 0x538: 0x46cc, 0x539: 0x475d, 0x53a: 0x3017, 0x53b: 0x3323, + 0x53c: 0x3003, 0x53d: 0x330f, 0x53e: 0x38f1, 0x53f: 0x3a80, + // Block 0x15, offset 0x540 + 0x540: 0x38ea, 0x541: 0x3a79, 0x542: 0x38ff, 0x543: 0x3a8e, 0x544: 0x38f8, 0x545: 0x3a87, + 0x546: 0x3914, 0x547: 0x3aa3, 0x548: 0x30a8, 0x549: 0x33b4, 0x54a: 0x30bc, 0x54b: 0x33c8, + 0x54c: 0x46fe, 0x54d: 0x478f, 0x54e: 0x314d, 0x54f: 0x345e, 0x550: 0x3937, 0x551: 0x3ac6, + 0x552: 0x3930, 0x553: 0x3abf, 0x554: 0x3945, 0x555: 0x3ad4, 0x556: 0x393e, 0x557: 0x3acd, + 0x558: 0x39a0, 0x559: 0x3b2f, 0x55a: 0x3984, 0x55b: 0x3b13, 0x55c: 0x397d, 0x55d: 0x3b0c, + 0x55e: 0x3992, 0x55f: 0x3b21, 0x560: 0x398b, 0x561: 0x3b1a, 0x562: 0x3999, 0x563: 0x3b28, + 0x564: 0x31fc, 0x565: 0x3512, 0x566: 0x31de, 0x567: 0x34f4, 0x568: 0x39fb, 0x569: 0x3b8a, + 0x56a: 0x39f4, 0x56b: 0x3b83, 0x56c: 0x3a09, 0x56d: 0x3b98, 0x56e: 0x3a02, 0x56f: 0x3b91, + 0x570: 0x3a10, 0x571: 0x3b9f, 0x572: 0x3247, 0x573: 0x3562, 0x574: 0x326f, 0x575: 0x358f, + 0x576: 0x326a, 0x577: 0x3585, 0x578: 0x3256, 0x579: 0x3571, + // Block 0x16, offset 0x580 + 0x580: 0x481b, 0x581: 0x4821, 0x582: 0x4935, 0x583: 0x494d, 0x584: 0x493d, 0x585: 0x4955, + 0x586: 0x4945, 0x587: 0x495d, 0x588: 0x47c1, 0x589: 0x47c7, 0x58a: 0x48a5, 0x58b: 0x48bd, + 0x58c: 0x48ad, 0x58d: 0x48c5, 0x58e: 0x48b5, 0x58f: 0x48cd, 0x590: 0x482d, 0x591: 0x4833, + 0x592: 0x3dcf, 0x593: 0x3ddf, 0x594: 0x3dd7, 0x595: 0x3de7, + 0x598: 0x47cd, 0x599: 0x47d3, 0x59a: 0x3cff, 0x59b: 0x3d0f, 0x59c: 0x3d07, 0x59d: 0x3d17, + 0x5a0: 0x4845, 0x5a1: 0x484b, 0x5a2: 0x4965, 0x5a3: 0x497d, + 0x5a4: 0x496d, 0x5a5: 0x4985, 0x5a6: 0x4975, 0x5a7: 0x498d, 0x5a8: 0x47d9, 0x5a9: 0x47df, + 0x5aa: 0x48d5, 0x5ab: 0x48ed, 0x5ac: 0x48dd, 0x5ad: 0x48f5, 0x5ae: 0x48e5, 0x5af: 0x48fd, + 0x5b0: 0x485d, 0x5b1: 0x4863, 0x5b2: 0x3e2f, 0x5b3: 0x3e47, 0x5b4: 0x3e37, 0x5b5: 0x3e4f, + 0x5b6: 0x3e3f, 0x5b7: 0x3e57, 0x5b8: 0x47e5, 0x5b9: 0x47eb, 0x5ba: 0x3d2f, 0x5bb: 0x3d47, + 0x5bc: 0x3d37, 0x5bd: 0x3d4f, 0x5be: 0x3d3f, 0x5bf: 0x3d57, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x4869, 0x5c1: 0x486f, 0x5c2: 0x3e5f, 0x5c3: 0x3e6f, 0x5c4: 0x3e67, 0x5c5: 0x3e77, + 0x5c8: 0x47f1, 0x5c9: 0x47f7, 0x5ca: 0x3d5f, 0x5cb: 0x3d6f, + 0x5cc: 0x3d67, 0x5cd: 0x3d77, 0x5d0: 0x487b, 0x5d1: 0x4881, + 0x5d2: 0x3e97, 0x5d3: 0x3eaf, 0x5d4: 0x3e9f, 0x5d5: 0x3eb7, 0x5d6: 0x3ea7, 0x5d7: 0x3ebf, + 0x5d9: 0x47fd, 0x5db: 0x3d7f, 0x5dd: 0x3d87, + 0x5df: 0x3d8f, 0x5e0: 0x4893, 0x5e1: 0x4899, 0x5e2: 0x4995, 0x5e3: 0x49ad, + 0x5e4: 0x499d, 0x5e5: 0x49b5, 0x5e6: 0x49a5, 0x5e7: 0x49bd, 0x5e8: 0x4803, 0x5e9: 0x4809, + 0x5ea: 0x4905, 0x5eb: 0x491d, 0x5ec: 0x490d, 0x5ed: 0x4925, 0x5ee: 0x4915, 0x5ef: 0x492d, + 0x5f0: 0x480f, 0x5f1: 0x4335, 0x5f2: 0x36a8, 0x5f3: 0x433b, 0x5f4: 0x4839, 0x5f5: 0x4341, + 0x5f6: 0x36ba, 0x5f7: 0x4347, 0x5f8: 0x36d8, 0x5f9: 0x434d, 0x5fa: 0x36f0, 0x5fb: 0x4353, + 0x5fc: 0x4887, 0x5fd: 0x4359, + // Block 0x18, offset 0x600 + 0x600: 0x3db7, 0x601: 0x3dbf, 0x602: 0x419b, 0x603: 0x41b9, 0x604: 0x41a5, 0x605: 0x41c3, + 0x606: 0x41af, 0x607: 0x41cd, 0x608: 0x3cef, 0x609: 0x3cf7, 0x60a: 0x40e7, 0x60b: 0x4105, + 0x60c: 0x40f1, 0x60d: 0x410f, 0x60e: 0x40fb, 0x60f: 0x4119, 0x610: 0x3dff, 0x611: 0x3e07, + 0x612: 0x41d7, 0x613: 0x41f5, 0x614: 0x41e1, 0x615: 0x41ff, 0x616: 0x41eb, 0x617: 0x4209, + 0x618: 0x3d1f, 0x619: 0x3d27, 0x61a: 0x4123, 0x61b: 0x4141, 0x61c: 0x412d, 0x61d: 0x414b, + 0x61e: 0x4137, 0x61f: 0x4155, 0x620: 0x3ed7, 0x621: 0x3edf, 0x622: 0x4213, 0x623: 0x4231, + 0x624: 0x421d, 0x625: 0x423b, 0x626: 0x4227, 0x627: 0x4245, 0x628: 0x3d97, 0x629: 0x3d9f, + 0x62a: 0x415f, 0x62b: 0x417d, 0x62c: 0x4169, 0x62d: 0x4187, 0x62e: 0x4173, 0x62f: 0x4191, + 0x630: 0x369c, 0x631: 0x3696, 0x632: 0x3da7, 0x633: 0x36a2, 0x634: 0x3daf, + 0x636: 0x4827, 0x637: 0x3dc7, 0x638: 0x360c, 0x639: 0x3606, 0x63a: 0x35fa, 0x63b: 0x4305, + 0x63c: 0x3612, 0x63d: 0x8100, 0x63e: 0x01d6, 0x63f: 0xa100, + // Block 0x19, offset 0x640 + 0x640: 0x8100, 0x641: 0x35be, 0x642: 0x3def, 0x643: 0x36b4, 0x644: 0x3df7, + 0x646: 0x4851, 0x647: 0x3e0f, 0x648: 0x3618, 0x649: 0x430b, 0x64a: 0x3624, 0x64b: 0x4311, + 0x64c: 0x3630, 0x64d: 0x3ba6, 0x64e: 0x3bad, 0x64f: 0x3bb4, 0x650: 0x36cc, 0x651: 0x36c6, + 0x652: 0x3e17, 0x653: 0x44fb, 0x656: 0x36d2, 0x657: 0x3e27, + 0x658: 0x3648, 0x659: 0x3642, 0x65a: 0x3636, 0x65b: 0x4317, 0x65d: 0x3bbb, + 0x65e: 0x3bc2, 0x65f: 0x3bc9, 0x660: 0x3702, 0x661: 0x36fc, 0x662: 0x3e7f, 0x663: 0x4503, + 0x664: 0x36e4, 0x665: 0x36ea, 0x666: 0x3708, 0x667: 0x3e8f, 0x668: 0x3678, 0x669: 0x3672, + 0x66a: 0x3666, 0x66b: 0x4323, 0x66c: 0x3660, 0x66d: 0x35b2, 0x66e: 0x42ff, 0x66f: 0x0081, + 0x672: 0x3ec7, 0x673: 0x370e, 0x674: 0x3ecf, + 0x676: 0x489f, 0x677: 0x3ee7, 0x678: 0x3654, 0x679: 0x431d, 0x67a: 0x3684, 0x67b: 0x432f, + 0x67c: 0x3690, 0x67d: 0x426d, 0x67e: 0xa100, + // Block 0x1a, offset 0x680 + 0x681: 0x3c1d, 0x683: 0xa000, 0x684: 0x3c24, 0x685: 0xa000, + 0x687: 0x3c2b, 0x688: 0xa000, 0x689: 0x3c32, + 0x68d: 0xa000, + 0x6a0: 0x2f7c, 0x6a1: 0xa000, 0x6a2: 0x3c40, + 0x6a4: 0xa000, 0x6a5: 0xa000, + 0x6ad: 0x3c39, 0x6ae: 0x2f77, 0x6af: 0x2f81, + 0x6b0: 0x3c47, 0x6b1: 0x3c4e, 0x6b2: 0xa000, 0x6b3: 0xa000, 0x6b4: 0x3c55, 0x6b5: 0x3c5c, + 0x6b6: 0xa000, 0x6b7: 0xa000, 0x6b8: 0x3c63, 0x6b9: 0x3c6a, 0x6ba: 0xa000, 0x6bb: 0xa000, + 0x6bc: 0xa000, 0x6bd: 0xa000, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x3c71, 0x6c1: 0x3c78, 0x6c2: 0xa000, 0x6c3: 0xa000, 0x6c4: 0x3c8d, 0x6c5: 0x3c94, + 0x6c6: 0xa000, 0x6c7: 0xa000, 0x6c8: 0x3c9b, 0x6c9: 0x3ca2, + 0x6d1: 0xa000, + 0x6d2: 0xa000, + 0x6e2: 0xa000, + 0x6e8: 0xa000, 0x6e9: 0xa000, + 0x6eb: 0xa000, 0x6ec: 0x3cb7, 0x6ed: 0x3cbe, 0x6ee: 0x3cc5, 0x6ef: 0x3ccc, + 0x6f2: 0xa000, 0x6f3: 0xa000, 0x6f4: 0xa000, 0x6f5: 0xa000, + // Block 0x1c, offset 0x700 + 0x706: 0xa000, 0x70b: 0xa000, + 0x70c: 0x3f1f, 0x70d: 0xa000, 0x70e: 0x3f27, 0x70f: 0xa000, 0x710: 0x3f2f, 0x711: 0xa000, + 0x712: 0x3f37, 0x713: 0xa000, 0x714: 0x3f3f, 0x715: 0xa000, 0x716: 0x3f47, 0x717: 0xa000, + 0x718: 0x3f4f, 0x719: 0xa000, 0x71a: 0x3f57, 0x71b: 0xa000, 0x71c: 0x3f5f, 0x71d: 0xa000, + 0x71e: 0x3f67, 0x71f: 0xa000, 0x720: 0x3f6f, 0x721: 0xa000, 0x722: 0x3f77, + 0x724: 0xa000, 0x725: 0x3f7f, 0x726: 0xa000, 0x727: 0x3f87, 0x728: 0xa000, 0x729: 0x3f8f, + 0x72f: 0xa000, + 0x730: 0x3f97, 0x731: 0x3f9f, 0x732: 0xa000, 0x733: 0x3fa7, 0x734: 0x3faf, 0x735: 0xa000, + 0x736: 0x3fb7, 0x737: 0x3fbf, 0x738: 0xa000, 0x739: 0x3fc7, 0x73a: 0x3fcf, 0x73b: 0xa000, + 0x73c: 0x3fd7, 0x73d: 0x3fdf, + // Block 0x1d, offset 0x740 + 0x754: 0x3f17, + 0x759: 0x9904, 0x75a: 0x9904, 0x75b: 0x8100, 0x75c: 0x8100, 0x75d: 0xa000, + 0x75e: 0x3fe7, + 0x766: 0xa000, + 0x76b: 0xa000, 0x76c: 0x3ff7, 0x76d: 0xa000, 0x76e: 0x3fff, 0x76f: 0xa000, + 0x770: 0x4007, 0x771: 0xa000, 0x772: 0x400f, 0x773: 0xa000, 0x774: 0x4017, 0x775: 0xa000, + 0x776: 0x401f, 0x777: 0xa000, 0x778: 0x4027, 0x779: 0xa000, 0x77a: 0x402f, 0x77b: 0xa000, + 0x77c: 0x4037, 0x77d: 0xa000, 0x77e: 0x403f, 0x77f: 0xa000, + // Block 0x1e, offset 0x780 + 0x780: 0x4047, 0x781: 0xa000, 0x782: 0x404f, 0x784: 0xa000, 0x785: 0x4057, + 0x786: 0xa000, 0x787: 0x405f, 0x788: 0xa000, 0x789: 0x4067, + 0x78f: 0xa000, 0x790: 0x406f, 0x791: 0x4077, + 0x792: 0xa000, 0x793: 0x407f, 0x794: 0x4087, 0x795: 0xa000, 0x796: 0x408f, 0x797: 0x4097, + 0x798: 0xa000, 0x799: 0x409f, 0x79a: 0x40a7, 0x79b: 0xa000, 0x79c: 0x40af, 0x79d: 0x40b7, + 0x7af: 0xa000, + 0x7b0: 0xa000, 0x7b1: 0xa000, 0x7b2: 0xa000, 0x7b4: 0x3fef, + 0x7b7: 0x40bf, 0x7b8: 0x40c7, 0x7b9: 0x40cf, 0x7ba: 0x40d7, + 0x7bd: 0xa000, 0x7be: 0x40df, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x137a, 0x7c1: 0x0cfe, 0x7c2: 0x13d6, 0x7c3: 0x13a2, 0x7c4: 0x0e5a, 0x7c5: 0x06ee, + 0x7c6: 0x08e2, 0x7c7: 0x162e, 0x7c8: 0x162e, 0x7c9: 0x0a0e, 0x7ca: 0x1462, 0x7cb: 0x0946, + 0x7cc: 0x0a0a, 0x7cd: 0x0bf2, 0x7ce: 0x0fd2, 0x7cf: 0x1162, 0x7d0: 0x129a, 0x7d1: 0x12d6, + 0x7d2: 0x130a, 0x7d3: 0x141e, 0x7d4: 0x0d76, 0x7d5: 0x0e02, 0x7d6: 0x0eae, 0x7d7: 0x0f46, + 0x7d8: 0x1262, 0x7d9: 0x144a, 0x7da: 0x1576, 0x7db: 0x0712, 0x7dc: 0x08b6, 0x7dd: 0x0d8a, + 0x7de: 0x0ed2, 0x7df: 0x1296, 0x7e0: 0x15c6, 0x7e1: 0x0ab6, 0x7e2: 0x0e7a, 0x7e3: 0x1286, + 0x7e4: 0x131a, 0x7e5: 0x0c26, 0x7e6: 0x11be, 0x7e7: 0x12e2, 0x7e8: 0x0b22, 0x7e9: 0x0d12, + 0x7ea: 0x0e1a, 0x7eb: 0x0f1e, 0x7ec: 0x142a, 0x7ed: 0x0752, 0x7ee: 0x07ea, 0x7ef: 0x0856, + 0x7f0: 0x0c8e, 0x7f1: 0x0d82, 0x7f2: 0x0ece, 0x7f3: 0x0ff2, 0x7f4: 0x117a, 0x7f5: 0x128e, + 0x7f6: 0x12a6, 0x7f7: 0x13ca, 0x7f8: 0x14f2, 0x7f9: 0x15a6, 0x7fa: 0x15c2, 0x7fb: 0x102e, + 0x7fc: 0x106e, 0x7fd: 0x1126, 0x7fe: 0x1246, 0x7ff: 0x147e, + // Block 0x20, offset 0x800 + 0x800: 0x15ce, 0x801: 0x134e, 0x802: 0x09ca, 0x803: 0x0b3e, 0x804: 0x10de, 0x805: 0x119e, + 0x806: 0x0f02, 0x807: 0x1036, 0x808: 0x139a, 0x809: 0x14ea, 0x80a: 0x09c6, 0x80b: 0x0a92, + 0x80c: 0x0d7a, 0x80d: 0x0e2e, 0x80e: 0x0e62, 0x80f: 0x1116, 0x810: 0x113e, 0x811: 0x14aa, + 0x812: 0x0852, 0x813: 0x11aa, 0x814: 0x07f6, 0x815: 0x07f2, 0x816: 0x109a, 0x817: 0x112a, + 0x818: 0x125e, 0x819: 0x14b2, 0x81a: 0x136a, 0x81b: 0x0c2a, 0x81c: 0x0d76, 0x81d: 0x135a, + 0x81e: 0x06fa, 0x81f: 0x0a66, 0x820: 0x0b96, 0x821: 0x0f32, 0x822: 0x0fb2, 0x823: 0x0876, + 0x824: 0x103e, 0x825: 0x0762, 0x826: 0x0b7a, 0x827: 0x06da, 0x828: 0x0dee, 0x829: 0x0ca6, + 0x82a: 0x1112, 0x82b: 0x08ca, 0x82c: 0x09b6, 0x82d: 0x0ffe, 0x82e: 0x1266, 0x82f: 0x133e, + 0x830: 0x0dba, 0x831: 0x13fa, 0x832: 0x0de6, 0x833: 0x0c3a, 0x834: 0x121e, 0x835: 0x0c5a, + 0x836: 0x0fae, 0x837: 0x072e, 0x838: 0x07aa, 0x839: 0x07ee, 0x83a: 0x0d56, 0x83b: 0x10fe, + 0x83c: 0x11f6, 0x83d: 0x134a, 0x83e: 0x145e, 0x83f: 0x085e, + // Block 0x21, offset 0x840 + 0x840: 0x0912, 0x841: 0x0a1a, 0x842: 0x0b32, 0x843: 0x0cc2, 0x844: 0x0e7e, 0x845: 0x1042, + 0x846: 0x149a, 0x847: 0x157e, 0x848: 0x15d2, 0x849: 0x15ea, 0x84a: 0x083a, 0x84b: 0x0cf6, + 0x84c: 0x0da6, 0x84d: 0x13ee, 0x84e: 0x0afe, 0x84f: 0x0bda, 0x850: 0x0bf6, 0x851: 0x0c86, + 0x852: 0x0e6e, 0x853: 0x0eba, 0x854: 0x0f6a, 0x855: 0x108e, 0x856: 0x1132, 0x857: 0x1196, + 0x858: 0x13de, 0x859: 0x126e, 0x85a: 0x1406, 0x85b: 0x1482, 0x85c: 0x0812, 0x85d: 0x083e, + 0x85e: 0x0926, 0x85f: 0x0eaa, 0x860: 0x12f6, 0x861: 0x133e, 0x862: 0x0b1e, 0x863: 0x0b8e, + 0x864: 0x0c52, 0x865: 0x0db2, 0x866: 0x10da, 0x867: 0x0f26, 0x868: 0x073e, 0x869: 0x0982, + 0x86a: 0x0a66, 0x86b: 0x0aca, 0x86c: 0x0b9a, 0x86d: 0x0f42, 0x86e: 0x0f5e, 0x86f: 0x116e, + 0x870: 0x118e, 0x871: 0x1466, 0x872: 0x14e6, 0x873: 0x14f6, 0x874: 0x1532, 0x875: 0x0756, + 0x876: 0x1082, 0x877: 0x1452, 0x878: 0x14ce, 0x879: 0x0bb2, 0x87a: 0x071a, 0x87b: 0x077a, + 0x87c: 0x0a6a, 0x87d: 0x0a8a, 0x87e: 0x0cb2, 0x87f: 0x0d76, + // Block 0x22, offset 0x880 + 0x880: 0x0ec6, 0x881: 0x0fce, 0x882: 0x127a, 0x883: 0x141a, 0x884: 0x1626, 0x885: 0x0ce6, + 0x886: 0x14a6, 0x887: 0x0836, 0x888: 0x0d32, 0x889: 0x0d3e, 0x88a: 0x0e12, 0x88b: 0x0e4a, + 0x88c: 0x0f4e, 0x88d: 0x0faa, 0x88e: 0x102a, 0x88f: 0x110e, 0x890: 0x153e, 0x891: 0x07b2, + 0x892: 0x0c06, 0x893: 0x14b6, 0x894: 0x076a, 0x895: 0x0aae, 0x896: 0x0e32, 0x897: 0x13e2, + 0x898: 0x0b6a, 0x899: 0x0bba, 0x89a: 0x0d46, 0x89b: 0x0f32, 0x89c: 0x14be, 0x89d: 0x081a, + 0x89e: 0x0902, 0x89f: 0x0a9a, 0x8a0: 0x0cd6, 0x8a1: 0x0d22, 0x8a2: 0x0d62, 0x8a3: 0x0df6, + 0x8a4: 0x0f4a, 0x8a5: 0x0fbe, 0x8a6: 0x115a, 0x8a7: 0x12fa, 0x8a8: 0x1306, 0x8a9: 0x145a, + 0x8aa: 0x14da, 0x8ab: 0x0886, 0x8ac: 0x0e4e, 0x8ad: 0x0906, 0x8ae: 0x0eca, 0x8af: 0x0f6e, + 0x8b0: 0x128a, 0x8b1: 0x14c2, 0x8b2: 0x15ae, 0x8b3: 0x15d6, 0x8b4: 0x0d3a, 0x8b5: 0x0e2a, + 0x8b6: 0x11c6, 0x8b7: 0x10ba, 0x8b8: 0x10c6, 0x8b9: 0x10ea, 0x8ba: 0x0f1a, 0x8bb: 0x0ea2, + 0x8bc: 0x1366, 0x8bd: 0x0736, 0x8be: 0x122e, 0x8bf: 0x081e, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x080e, 0x8c1: 0x0b0e, 0x8c2: 0x0c2e, 0x8c3: 0x10f6, 0x8c4: 0x0a56, 0x8c5: 0x0e06, + 0x8c6: 0x0cf2, 0x8c7: 0x13ea, 0x8c8: 0x12ea, 0x8c9: 0x14ae, 0x8ca: 0x1326, 0x8cb: 0x0b2a, + 0x8cc: 0x078a, 0x8cd: 0x095e, 0x8d0: 0x09b2, + 0x8d2: 0x0ce2, 0x8d5: 0x07fa, 0x8d6: 0x0f22, 0x8d7: 0x0fe6, + 0x8d8: 0x104a, 0x8d9: 0x1066, 0x8da: 0x106a, 0x8db: 0x107e, 0x8dc: 0x14fe, 0x8dd: 0x10ee, + 0x8de: 0x1172, 0x8e0: 0x1292, 0x8e2: 0x1356, + 0x8e5: 0x140a, 0x8e6: 0x1436, + 0x8ea: 0x1552, 0x8eb: 0x1556, 0x8ec: 0x155a, 0x8ed: 0x15be, 0x8ee: 0x142e, 0x8ef: 0x14ca, + 0x8f0: 0x075a, 0x8f1: 0x077e, 0x8f2: 0x0792, 0x8f3: 0x084e, 0x8f4: 0x085a, 0x8f5: 0x089a, + 0x8f6: 0x094e, 0x8f7: 0x096a, 0x8f8: 0x0972, 0x8f9: 0x09ae, 0x8fa: 0x09ba, 0x8fb: 0x0a96, + 0x8fc: 0x0a9e, 0x8fd: 0x0ba6, 0x8fe: 0x0bce, 0x8ff: 0x0bd6, + // Block 0x24, offset 0x900 + 0x900: 0x0bee, 0x901: 0x0c9a, 0x902: 0x0cca, 0x903: 0x0cea, 0x904: 0x0d5a, 0x905: 0x0e1e, + 0x906: 0x0e3a, 0x907: 0x0e6a, 0x908: 0x0ebe, 0x909: 0x0ede, 0x90a: 0x0f52, 0x90b: 0x1032, + 0x90c: 0x104e, 0x90d: 0x1056, 0x90e: 0x1052, 0x90f: 0x105a, 0x910: 0x105e, 0x911: 0x1062, + 0x912: 0x1076, 0x913: 0x107a, 0x914: 0x109e, 0x915: 0x10b2, 0x916: 0x10ce, 0x917: 0x1132, + 0x918: 0x113a, 0x919: 0x1142, 0x91a: 0x1156, 0x91b: 0x117e, 0x91c: 0x11ce, 0x91d: 0x1202, + 0x91e: 0x1202, 0x91f: 0x126a, 0x920: 0x1312, 0x921: 0x132a, 0x922: 0x135e, 0x923: 0x1362, + 0x924: 0x13a6, 0x925: 0x13aa, 0x926: 0x1402, 0x927: 0x140a, 0x928: 0x14de, 0x929: 0x1522, + 0x92a: 0x153a, 0x92b: 0x0b9e, 0x92c: 0x1721, 0x92d: 0x11e6, + 0x930: 0x06e2, 0x931: 0x07e6, 0x932: 0x07a6, 0x933: 0x074e, 0x934: 0x078e, 0x935: 0x07ba, + 0x936: 0x084a, 0x937: 0x0866, 0x938: 0x094e, 0x939: 0x093a, 0x93a: 0x094a, 0x93b: 0x0966, + 0x93c: 0x09b2, 0x93d: 0x09c2, 0x93e: 0x0a06, 0x93f: 0x0a12, + // Block 0x25, offset 0x940 + 0x940: 0x0a2e, 0x941: 0x0a3e, 0x942: 0x0b26, 0x943: 0x0b2e, 0x944: 0x0b5e, 0x945: 0x0b7e, + 0x946: 0x0bae, 0x947: 0x0bc6, 0x948: 0x0bb6, 0x949: 0x0bd6, 0x94a: 0x0bca, 0x94b: 0x0bee, + 0x94c: 0x0c0a, 0x94d: 0x0c62, 0x94e: 0x0c6e, 0x94f: 0x0c76, 0x950: 0x0c9e, 0x951: 0x0ce2, + 0x952: 0x0d12, 0x953: 0x0d16, 0x954: 0x0d2a, 0x955: 0x0daa, 0x956: 0x0dba, 0x957: 0x0e12, + 0x958: 0x0e5e, 0x959: 0x0e56, 0x95a: 0x0e6a, 0x95b: 0x0e86, 0x95c: 0x0ebe, 0x95d: 0x1016, + 0x95e: 0x0ee2, 0x95f: 0x0f16, 0x960: 0x0f22, 0x961: 0x0f62, 0x962: 0x0f7e, 0x963: 0x0fa2, + 0x964: 0x0fc6, 0x965: 0x0fca, 0x966: 0x0fe6, 0x967: 0x0fea, 0x968: 0x0ffa, 0x969: 0x100e, + 0x96a: 0x100a, 0x96b: 0x103a, 0x96c: 0x10b6, 0x96d: 0x10ce, 0x96e: 0x10e6, 0x96f: 0x111e, + 0x970: 0x1132, 0x971: 0x114e, 0x972: 0x117e, 0x973: 0x1232, 0x974: 0x125a, 0x975: 0x12ce, + 0x976: 0x1316, 0x977: 0x1322, 0x978: 0x132a, 0x979: 0x1342, 0x97a: 0x1356, 0x97b: 0x1346, + 0x97c: 0x135e, 0x97d: 0x135a, 0x97e: 0x1352, 0x97f: 0x1362, + // Block 0x26, offset 0x980 + 0x980: 0x136e, 0x981: 0x13aa, 0x982: 0x13e6, 0x983: 0x1416, 0x984: 0x144e, 0x985: 0x146e, + 0x986: 0x14ba, 0x987: 0x14de, 0x988: 0x14fe, 0x989: 0x1512, 0x98a: 0x1522, 0x98b: 0x152e, + 0x98c: 0x153a, 0x98d: 0x158e, 0x98e: 0x162e, 0x98f: 0x16b8, 0x990: 0x16b3, 0x991: 0x16e5, + 0x992: 0x060a, 0x993: 0x0632, 0x994: 0x0636, 0x995: 0x1767, 0x996: 0x1794, 0x997: 0x180c, + 0x998: 0x161a, 0x999: 0x162a, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x06fe, 0x9c1: 0x06f6, 0x9c2: 0x0706, 0x9c3: 0x164a, 0x9c4: 0x074a, 0x9c5: 0x075a, + 0x9c6: 0x075e, 0x9c7: 0x0766, 0x9c8: 0x076e, 0x9c9: 0x0772, 0x9ca: 0x077e, 0x9cb: 0x0776, + 0x9cc: 0x05b6, 0x9cd: 0x165e, 0x9ce: 0x0792, 0x9cf: 0x0796, 0x9d0: 0x079a, 0x9d1: 0x07b6, + 0x9d2: 0x164f, 0x9d3: 0x05ba, 0x9d4: 0x07a2, 0x9d5: 0x07c2, 0x9d6: 0x1659, 0x9d7: 0x07d2, + 0x9d8: 0x07da, 0x9d9: 0x073a, 0x9da: 0x07e2, 0x9db: 0x07e6, 0x9dc: 0x1834, 0x9dd: 0x0802, + 0x9de: 0x080a, 0x9df: 0x05c2, 0x9e0: 0x0822, 0x9e1: 0x0826, 0x9e2: 0x082e, 0x9e3: 0x0832, + 0x9e4: 0x05c6, 0x9e5: 0x084a, 0x9e6: 0x084e, 0x9e7: 0x085a, 0x9e8: 0x0866, 0x9e9: 0x086a, + 0x9ea: 0x086e, 0x9eb: 0x0876, 0x9ec: 0x0896, 0x9ed: 0x089a, 0x9ee: 0x08a2, 0x9ef: 0x08b2, + 0x9f0: 0x08ba, 0x9f1: 0x08be, 0x9f2: 0x08be, 0x9f3: 0x08be, 0x9f4: 0x166d, 0x9f5: 0x0e96, + 0x9f6: 0x08d2, 0x9f7: 0x08da, 0x9f8: 0x1672, 0x9f9: 0x08e6, 0x9fa: 0x08ee, 0x9fb: 0x08f6, + 0x9fc: 0x091e, 0x9fd: 0x090a, 0x9fe: 0x0916, 0x9ff: 0x091a, + // Block 0x28, offset 0xa00 + 0xa00: 0x0922, 0xa01: 0x092a, 0xa02: 0x092e, 0xa03: 0x0936, 0xa04: 0x093e, 0xa05: 0x0942, + 0xa06: 0x0942, 0xa07: 0x094a, 0xa08: 0x0952, 0xa09: 0x0956, 0xa0a: 0x0962, 0xa0b: 0x0986, + 0xa0c: 0x096a, 0xa0d: 0x098a, 0xa0e: 0x096e, 0xa0f: 0x0976, 0xa10: 0x080e, 0xa11: 0x09d2, + 0xa12: 0x099a, 0xa13: 0x099e, 0xa14: 0x09a2, 0xa15: 0x0996, 0xa16: 0x09aa, 0xa17: 0x09a6, + 0xa18: 0x09be, 0xa19: 0x1677, 0xa1a: 0x09da, 0xa1b: 0x09de, 0xa1c: 0x09e6, 0xa1d: 0x09f2, + 0xa1e: 0x09fa, 0xa1f: 0x0a16, 0xa20: 0x167c, 0xa21: 0x1681, 0xa22: 0x0a22, 0xa23: 0x0a26, + 0xa24: 0x0a2a, 0xa25: 0x0a1e, 0xa26: 0x0a32, 0xa27: 0x05ca, 0xa28: 0x05ce, 0xa29: 0x0a3a, + 0xa2a: 0x0a42, 0xa2b: 0x0a42, 0xa2c: 0x1686, 0xa2d: 0x0a5e, 0xa2e: 0x0a62, 0xa2f: 0x0a66, + 0xa30: 0x0a6e, 0xa31: 0x168b, 0xa32: 0x0a76, 0xa33: 0x0a7a, 0xa34: 0x0b52, 0xa35: 0x0a82, + 0xa36: 0x05d2, 0xa37: 0x0a8e, 0xa38: 0x0a9e, 0xa39: 0x0aaa, 0xa3a: 0x0aa6, 0xa3b: 0x1695, + 0xa3c: 0x0ab2, 0xa3d: 0x169a, 0xa3e: 0x0abe, 0xa3f: 0x0aba, + // Block 0x29, offset 0xa40 + 0xa40: 0x0ac2, 0xa41: 0x0ad2, 0xa42: 0x0ad6, 0xa43: 0x05d6, 0xa44: 0x0ae6, 0xa45: 0x0aee, + 0xa46: 0x0af2, 0xa47: 0x0af6, 0xa48: 0x05da, 0xa49: 0x169f, 0xa4a: 0x05de, 0xa4b: 0x0b12, + 0xa4c: 0x0b16, 0xa4d: 0x0b1a, 0xa4e: 0x0b22, 0xa4f: 0x1866, 0xa50: 0x0b3a, 0xa51: 0x16a9, + 0xa52: 0x16a9, 0xa53: 0x11da, 0xa54: 0x0b4a, 0xa55: 0x0b4a, 0xa56: 0x05e2, 0xa57: 0x16cc, + 0xa58: 0x179e, 0xa59: 0x0b5a, 0xa5a: 0x0b62, 0xa5b: 0x05e6, 0xa5c: 0x0b76, 0xa5d: 0x0b86, + 0xa5e: 0x0b8a, 0xa5f: 0x0b92, 0xa60: 0x0ba2, 0xa61: 0x05ee, 0xa62: 0x05ea, 0xa63: 0x0ba6, + 0xa64: 0x16ae, 0xa65: 0x0baa, 0xa66: 0x0bbe, 0xa67: 0x0bc2, 0xa68: 0x0bc6, 0xa69: 0x0bc2, + 0xa6a: 0x0bd2, 0xa6b: 0x0bd6, 0xa6c: 0x0be6, 0xa6d: 0x0bde, 0xa6e: 0x0be2, 0xa6f: 0x0bea, + 0xa70: 0x0bee, 0xa71: 0x0bf2, 0xa72: 0x0bfe, 0xa73: 0x0c02, 0xa74: 0x0c1a, 0xa75: 0x0c22, + 0xa76: 0x0c32, 0xa77: 0x0c46, 0xa78: 0x16bd, 0xa79: 0x0c42, 0xa7a: 0x0c36, 0xa7b: 0x0c4e, + 0xa7c: 0x0c56, 0xa7d: 0x0c6a, 0xa7e: 0x16c2, 0xa7f: 0x0c72, + // Block 0x2a, offset 0xa80 + 0xa80: 0x0c66, 0xa81: 0x0c5e, 0xa82: 0x05f2, 0xa83: 0x0c7a, 0xa84: 0x0c82, 0xa85: 0x0c8a, + 0xa86: 0x0c7e, 0xa87: 0x05f6, 0xa88: 0x0c9a, 0xa89: 0x0ca2, 0xa8a: 0x16c7, 0xa8b: 0x0cce, + 0xa8c: 0x0d02, 0xa8d: 0x0cde, 0xa8e: 0x0602, 0xa8f: 0x0cea, 0xa90: 0x05fe, 0xa91: 0x05fa, + 0xa92: 0x07c6, 0xa93: 0x07ca, 0xa94: 0x0d06, 0xa95: 0x0cee, 0xa96: 0x11ae, 0xa97: 0x0666, + 0xa98: 0x0d12, 0xa99: 0x0d16, 0xa9a: 0x0d1a, 0xa9b: 0x0d2e, 0xa9c: 0x0d26, 0xa9d: 0x16e0, + 0xa9e: 0x0606, 0xa9f: 0x0d42, 0xaa0: 0x0d36, 0xaa1: 0x0d52, 0xaa2: 0x0d5a, 0xaa3: 0x16ea, + 0xaa4: 0x0d5e, 0xaa5: 0x0d4a, 0xaa6: 0x0d66, 0xaa7: 0x060a, 0xaa8: 0x0d6a, 0xaa9: 0x0d6e, + 0xaaa: 0x0d72, 0xaab: 0x0d7e, 0xaac: 0x16ef, 0xaad: 0x0d86, 0xaae: 0x060e, 0xaaf: 0x0d92, + 0xab0: 0x16f4, 0xab1: 0x0d96, 0xab2: 0x0612, 0xab3: 0x0da2, 0xab4: 0x0dae, 0xab5: 0x0dba, + 0xab6: 0x0dbe, 0xab7: 0x16f9, 0xab8: 0x1690, 0xab9: 0x16fe, 0xaba: 0x0dde, 0xabb: 0x1703, + 0xabc: 0x0dea, 0xabd: 0x0df2, 0xabe: 0x0de2, 0xabf: 0x0dfe, + // Block 0x2b, offset 0xac0 + 0xac0: 0x0e0e, 0xac1: 0x0e1e, 0xac2: 0x0e12, 0xac3: 0x0e16, 0xac4: 0x0e22, 0xac5: 0x0e26, + 0xac6: 0x1708, 0xac7: 0x0e0a, 0xac8: 0x0e3e, 0xac9: 0x0e42, 0xaca: 0x0616, 0xacb: 0x0e56, + 0xacc: 0x0e52, 0xacd: 0x170d, 0xace: 0x0e36, 0xacf: 0x0e72, 0xad0: 0x1712, 0xad1: 0x1717, + 0xad2: 0x0e76, 0xad3: 0x0e8a, 0xad4: 0x0e86, 0xad5: 0x0e82, 0xad6: 0x061a, 0xad7: 0x0e8e, + 0xad8: 0x0e9e, 0xad9: 0x0e9a, 0xada: 0x0ea6, 0xadb: 0x1654, 0xadc: 0x0eb6, 0xadd: 0x171c, + 0xade: 0x0ec2, 0xadf: 0x1726, 0xae0: 0x0ed6, 0xae1: 0x0ee2, 0xae2: 0x0ef6, 0xae3: 0x172b, + 0xae4: 0x0f0a, 0xae5: 0x0f0e, 0xae6: 0x1730, 0xae7: 0x1735, 0xae8: 0x0f2a, 0xae9: 0x0f3a, + 0xaea: 0x061e, 0xaeb: 0x0f3e, 0xaec: 0x0622, 0xaed: 0x0622, 0xaee: 0x0f56, 0xaef: 0x0f5a, + 0xaf0: 0x0f62, 0xaf1: 0x0f66, 0xaf2: 0x0f72, 0xaf3: 0x0626, 0xaf4: 0x0f8a, 0xaf5: 0x173a, + 0xaf6: 0x0fa6, 0xaf7: 0x173f, 0xaf8: 0x0fb2, 0xaf9: 0x16a4, 0xafa: 0x0fc2, 0xafb: 0x1744, + 0xafc: 0x1749, 0xafd: 0x174e, 0xafe: 0x062a, 0xaff: 0x062e, + // Block 0x2c, offset 0xb00 + 0xb00: 0x0ffa, 0xb01: 0x1758, 0xb02: 0x1753, 0xb03: 0x175d, 0xb04: 0x1762, 0xb05: 0x1002, + 0xb06: 0x1006, 0xb07: 0x1006, 0xb08: 0x100e, 0xb09: 0x0636, 0xb0a: 0x1012, 0xb0b: 0x063a, + 0xb0c: 0x063e, 0xb0d: 0x176c, 0xb0e: 0x1026, 0xb0f: 0x102e, 0xb10: 0x103a, 0xb11: 0x0642, + 0xb12: 0x1771, 0xb13: 0x105e, 0xb14: 0x1776, 0xb15: 0x177b, 0xb16: 0x107e, 0xb17: 0x1096, + 0xb18: 0x0646, 0xb19: 0x109e, 0xb1a: 0x10a2, 0xb1b: 0x10a6, 0xb1c: 0x1780, 0xb1d: 0x1785, + 0xb1e: 0x1785, 0xb1f: 0x10be, 0xb20: 0x064a, 0xb21: 0x178a, 0xb22: 0x10d2, 0xb23: 0x10d6, + 0xb24: 0x064e, 0xb25: 0x178f, 0xb26: 0x10f2, 0xb27: 0x0652, 0xb28: 0x1102, 0xb29: 0x10fa, + 0xb2a: 0x110a, 0xb2b: 0x1799, 0xb2c: 0x1122, 0xb2d: 0x0656, 0xb2e: 0x112e, 0xb2f: 0x1136, + 0xb30: 0x1146, 0xb31: 0x065a, 0xb32: 0x17a3, 0xb33: 0x17a8, 0xb34: 0x065e, 0xb35: 0x17ad, + 0xb36: 0x115e, 0xb37: 0x17b2, 0xb38: 0x116a, 0xb39: 0x1176, 0xb3a: 0x117e, 0xb3b: 0x17b7, + 0xb3c: 0x17bc, 0xb3d: 0x1192, 0xb3e: 0x17c1, 0xb3f: 0x119a, + // Block 0x2d, offset 0xb40 + 0xb40: 0x16d1, 0xb41: 0x0662, 0xb42: 0x11b2, 0xb43: 0x11b6, 0xb44: 0x066a, 0xb45: 0x11ba, + 0xb46: 0x0a36, 0xb47: 0x17c6, 0xb48: 0x17cb, 0xb49: 0x16d6, 0xb4a: 0x16db, 0xb4b: 0x11da, + 0xb4c: 0x11de, 0xb4d: 0x13f6, 0xb4e: 0x066e, 0xb4f: 0x120a, 0xb50: 0x1206, 0xb51: 0x120e, + 0xb52: 0x0842, 0xb53: 0x1212, 0xb54: 0x1216, 0xb55: 0x121a, 0xb56: 0x1222, 0xb57: 0x17d0, + 0xb58: 0x121e, 0xb59: 0x1226, 0xb5a: 0x123a, 0xb5b: 0x123e, 0xb5c: 0x122a, 0xb5d: 0x1242, + 0xb5e: 0x1256, 0xb5f: 0x126a, 0xb60: 0x1236, 0xb61: 0x124a, 0xb62: 0x124e, 0xb63: 0x1252, + 0xb64: 0x17d5, 0xb65: 0x17df, 0xb66: 0x17da, 0xb67: 0x0672, 0xb68: 0x1272, 0xb69: 0x1276, + 0xb6a: 0x127e, 0xb6b: 0x17f3, 0xb6c: 0x1282, 0xb6d: 0x17e4, 0xb6e: 0x0676, 0xb6f: 0x067a, + 0xb70: 0x17e9, 0xb71: 0x17ee, 0xb72: 0x067e, 0xb73: 0x12a2, 0xb74: 0x12a6, 0xb75: 0x12aa, + 0xb76: 0x12ae, 0xb77: 0x12ba, 0xb78: 0x12b6, 0xb79: 0x12c2, 0xb7a: 0x12be, 0xb7b: 0x12ce, + 0xb7c: 0x12c6, 0xb7d: 0x12ca, 0xb7e: 0x12d2, 0xb7f: 0x0682, + // Block 0x2e, offset 0xb80 + 0xb80: 0x12da, 0xb81: 0x12de, 0xb82: 0x0686, 0xb83: 0x12ee, 0xb84: 0x12f2, 0xb85: 0x17f8, + 0xb86: 0x12fe, 0xb87: 0x1302, 0xb88: 0x068a, 0xb89: 0x130e, 0xb8a: 0x05be, 0xb8b: 0x17fd, + 0xb8c: 0x1802, 0xb8d: 0x068e, 0xb8e: 0x0692, 0xb8f: 0x133a, 0xb90: 0x1352, 0xb91: 0x136e, + 0xb92: 0x137e, 0xb93: 0x1807, 0xb94: 0x1392, 0xb95: 0x1396, 0xb96: 0x13ae, 0xb97: 0x13ba, + 0xb98: 0x1811, 0xb99: 0x1663, 0xb9a: 0x13c6, 0xb9b: 0x13c2, 0xb9c: 0x13ce, 0xb9d: 0x1668, + 0xb9e: 0x13da, 0xb9f: 0x13e6, 0xba0: 0x1816, 0xba1: 0x181b, 0xba2: 0x1426, 0xba3: 0x1432, + 0xba4: 0x143a, 0xba5: 0x1820, 0xba6: 0x143e, 0xba7: 0x146a, 0xba8: 0x1476, 0xba9: 0x147a, + 0xbaa: 0x1472, 0xbab: 0x1486, 0xbac: 0x148a, 0xbad: 0x1825, 0xbae: 0x1496, 0xbaf: 0x0696, + 0xbb0: 0x149e, 0xbb1: 0x182a, 0xbb2: 0x069a, 0xbb3: 0x14d6, 0xbb4: 0x0ac6, 0xbb5: 0x14ee, + 0xbb6: 0x182f, 0xbb7: 0x1839, 0xbb8: 0x069e, 0xbb9: 0x06a2, 0xbba: 0x1516, 0xbbb: 0x183e, + 0xbbc: 0x06a6, 0xbbd: 0x1843, 0xbbe: 0x152e, 0xbbf: 0x152e, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x1536, 0xbc1: 0x1848, 0xbc2: 0x154e, 0xbc3: 0x06aa, 0xbc4: 0x155e, 0xbc5: 0x156a, + 0xbc6: 0x1572, 0xbc7: 0x157a, 0xbc8: 0x06ae, 0xbc9: 0x184d, 0xbca: 0x158e, 0xbcb: 0x15aa, + 0xbcc: 0x15b6, 0xbcd: 0x06b2, 0xbce: 0x06b6, 0xbcf: 0x15ba, 0xbd0: 0x1852, 0xbd1: 0x06ba, + 0xbd2: 0x1857, 0xbd3: 0x185c, 0xbd4: 0x1861, 0xbd5: 0x15de, 0xbd6: 0x06be, 0xbd7: 0x15f2, + 0xbd8: 0x15fa, 0xbd9: 0x15fe, 0xbda: 0x1606, 0xbdb: 0x160e, 0xbdc: 0x1616, 0xbdd: 0x186b, +} + +// 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, 0x16b: 0x64, 0x16c: 0x0e, 0x16d: 0x65, 0x16e: 0x66, 0x16f: 0x67, + 0x170: 0x68, 0x173: 0x69, 0x177: 0x0f, + 0x178: 0x10, 0x179: 0x11, 0x17a: 0x12, 0x17b: 0x13, 0x17c: 0x14, 0x17d: 0x15, 0x17e: 0x16, 0x17f: 0x17, + // Block 0x6, offset 0x180 + 0x180: 0x6a, 0x183: 0x6b, 0x184: 0x6c, 0x186: 0x6d, 0x187: 0x6e, + 0x188: 0x6f, 0x189: 0x18, 0x18a: 0x19, 0x18b: 0x70, 0x18c: 0x71, + 0x1ab: 0x72, + 0x1b3: 0x73, 0x1b5: 0x74, 0x1b7: 0x75, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x76, 0x1c1: 0x1a, 0x1c2: 0x1b, 0x1c3: 0x1c, 0x1c4: 0x77, 0x1c5: 0x78, + 0x1c9: 0x79, 0x1cc: 0x7a, 0x1cd: 0x7b, + // Block 0x8, offset 0x200 + 0x219: 0x7c, 0x21a: 0x7d, 0x21b: 0x7e, + 0x220: 0x7f, 0x223: 0x80, 0x224: 0x81, 0x225: 0x82, 0x226: 0x83, 0x227: 0x84, + 0x22a: 0x85, 0x22b: 0x86, 0x22f: 0x87, + 0x230: 0x88, 0x231: 0x89, 0x232: 0x8a, 0x233: 0x8b, 0x234: 0x8c, 0x235: 0x8d, 0x236: 0x8e, 0x237: 0x88, + 0x238: 0x89, 0x239: 0x8a, 0x23a: 0x8b, 0x23b: 0x8c, 0x23c: 0x8d, 0x23d: 0x8e, 0x23e: 0x88, 0x23f: 0x89, + // Block 0x9, offset 0x240 + 0x240: 0x8a, 0x241: 0x8b, 0x242: 0x8c, 0x243: 0x8d, 0x244: 0x8e, 0x245: 0x88, 0x246: 0x89, 0x247: 0x8a, + 0x248: 0x8b, 0x249: 0x8c, 0x24a: 0x8d, 0x24b: 0x8e, 0x24c: 0x88, 0x24d: 0x89, 0x24e: 0x8a, 0x24f: 0x8b, + 0x250: 0x8c, 0x251: 0x8d, 0x252: 0x8e, 0x253: 0x88, 0x254: 0x89, 0x255: 0x8a, 0x256: 0x8b, 0x257: 0x8c, + 0x258: 0x8d, 0x259: 0x8e, 0x25a: 0x88, 0x25b: 0x89, 0x25c: 0x8a, 0x25d: 0x8b, 0x25e: 0x8c, 0x25f: 0x8d, + 0x260: 0x8e, 0x261: 0x88, 0x262: 0x89, 0x263: 0x8a, 0x264: 0x8b, 0x265: 0x8c, 0x266: 0x8d, 0x267: 0x8e, + 0x268: 0x88, 0x269: 0x89, 0x26a: 0x8a, 0x26b: 0x8b, 0x26c: 0x8c, 0x26d: 0x8d, 0x26e: 0x8e, 0x26f: 0x88, + 0x270: 0x89, 0x271: 0x8a, 0x272: 0x8b, 0x273: 0x8c, 0x274: 0x8d, 0x275: 0x8e, 0x276: 0x88, 0x277: 0x89, + 0x278: 0x8a, 0x279: 0x8b, 0x27a: 0x8c, 0x27b: 0x8d, 0x27c: 0x8e, 0x27d: 0x88, 0x27e: 0x89, 0x27f: 0x8a, + // Block 0xa, offset 0x280 + 0x280: 0x8b, 0x281: 0x8c, 0x282: 0x8d, 0x283: 0x8e, 0x284: 0x88, 0x285: 0x89, 0x286: 0x8a, 0x287: 0x8b, + 0x288: 0x8c, 0x289: 0x8d, 0x28a: 0x8e, 0x28b: 0x88, 0x28c: 0x89, 0x28d: 0x8a, 0x28e: 0x8b, 0x28f: 0x8c, + 0x290: 0x8d, 0x291: 0x8e, 0x292: 0x88, 0x293: 0x89, 0x294: 0x8a, 0x295: 0x8b, 0x296: 0x8c, 0x297: 0x8d, + 0x298: 0x8e, 0x299: 0x88, 0x29a: 0x89, 0x29b: 0x8a, 0x29c: 0x8b, 0x29d: 0x8c, 0x29e: 0x8d, 0x29f: 0x8e, + 0x2a0: 0x88, 0x2a1: 0x89, 0x2a2: 0x8a, 0x2a3: 0x8b, 0x2a4: 0x8c, 0x2a5: 0x8d, 0x2a6: 0x8e, 0x2a7: 0x88, + 0x2a8: 0x89, 0x2a9: 0x8a, 0x2aa: 0x8b, 0x2ab: 0x8c, 0x2ac: 0x8d, 0x2ad: 0x8e, 0x2ae: 0x88, 0x2af: 0x89, + 0x2b0: 0x8a, 0x2b1: 0x8b, 0x2b2: 0x8c, 0x2b3: 0x8d, 0x2b4: 0x8e, 0x2b5: 0x88, 0x2b6: 0x89, 0x2b7: 0x8a, + 0x2b8: 0x8b, 0x2b9: 0x8c, 0x2ba: 0x8d, 0x2bb: 0x8e, 0x2bc: 0x88, 0x2bd: 0x89, 0x2be: 0x8a, 0x2bf: 0x8b, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x8c, 0x2c1: 0x8d, 0x2c2: 0x8e, 0x2c3: 0x88, 0x2c4: 0x89, 0x2c5: 0x8a, 0x2c6: 0x8b, 0x2c7: 0x8c, + 0x2c8: 0x8d, 0x2c9: 0x8e, 0x2ca: 0x88, 0x2cb: 0x89, 0x2cc: 0x8a, 0x2cd: 0x8b, 0x2ce: 0x8c, 0x2cf: 0x8d, + 0x2d0: 0x8e, 0x2d1: 0x88, 0x2d2: 0x89, 0x2d3: 0x8a, 0x2d4: 0x8b, 0x2d5: 0x8c, 0x2d6: 0x8d, 0x2d7: 0x8e, + 0x2d8: 0x88, 0x2d9: 0x89, 0x2da: 0x8a, 0x2db: 0x8b, 0x2dc: 0x8c, 0x2dd: 0x8d, 0x2de: 0x8f, + // Block 0xc, offset 0x300 + 0x324: 0x1d, 0x325: 0x1e, 0x326: 0x1f, 0x327: 0x20, + 0x328: 0x21, 0x329: 0x22, 0x32a: 0x23, 0x32b: 0x24, 0x32c: 0x90, 0x32d: 0x91, 0x32e: 0x92, + 0x331: 0x93, 0x332: 0x94, 0x333: 0x95, 0x334: 0x96, + 0x338: 0x97, 0x339: 0x98, 0x33a: 0x99, 0x33b: 0x9a, 0x33e: 0x9b, 0x33f: 0x9c, + // Block 0xd, offset 0x340 + 0x347: 0x9d, + 0x34b: 0x9e, 0x34d: 0x9f, + 0x368: 0xa0, 0x36b: 0xa1, + 0x374: 0xa2, + 0x37a: 0xa3, 0x37d: 0xa4, + // Block 0xe, offset 0x380 + 0x381: 0xa5, 0x382: 0xa6, 0x384: 0xa7, 0x385: 0x83, 0x387: 0xa8, + 0x388: 0xa9, 0x38b: 0xaa, 0x38c: 0xab, 0x38d: 0xac, + 0x391: 0xad, 0x392: 0xae, 0x393: 0xaf, 0x396: 0xb0, 0x397: 0xb1, + 0x398: 0x74, 0x39a: 0xb2, 0x39c: 0xb3, + 0x3a0: 0xb4, 0x3a4: 0xb5, 0x3a5: 0xb6, 0x3a7: 0xb7, + 0x3a8: 0xb8, 0x3a9: 0xb9, 0x3aa: 0xba, + 0x3b0: 0x74, 0x3b5: 0xbb, 0x3b6: 0xbc, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xbd, 0x3ec: 0xbe, + 0x3ff: 0xbf, + // Block 0x10, offset 0x400 + 0x432: 0xc0, + // Block 0x11, offset 0x440 + 0x445: 0xc1, 0x446: 0xc2, 0x447: 0xc3, + 0x449: 0xc4, + // Block 0x12, offset 0x480 + 0x480: 0xc5, 0x484: 0xbe, + 0x48b: 0xc6, + 0x4a3: 0xc7, 0x4a5: 0xc8, + // Block 0x13, offset 0x4c0 + 0x4c8: 0xc9, + // 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: 156 entries, 312 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, 0x120, 0x122, 0x12b, 0x12d, 0x130, 0x132, 0x13d, 0x141, 0x14f, 0x152, 0x158, 0x15e, 0x169, 0x16d, 0x16f, 0x171, 0x173, 0x175, 0x177, 0x17d, 0x181, 0x183, 0x185, 0x18d, 0x191, 0x194, 0x196, 0x198, 0x19b, 0x19e, 0x1a0, 0x1a2, 0x1a4, 0x1a6, 0x1ac, 0x1af, 0x1b1, 0x1b8, 0x1be, 0x1c4, 0x1cc, 0x1d2, 0x1d8, 0x1de, 0x1e2, 0x1f0, 0x1f9, 0x1fc, 0x1ff, 0x201, 0x204, 0x206, 0x20a, 0x20f, 0x211, 0x213, 0x218, 0x21e, 0x220, 0x222, 0x224, 0x22a, 0x22d, 0x22f, 0x231, 0x237, 0x23a, 0x242, 0x249, 0x24c, 0x24f, 0x251, 0x254, 0x25c, 0x260, 0x267, 0x26a, 0x270, 0x272, 0x275, 0x277, 0x27a, 0x27f, 0x281, 0x283, 0x285, 0x287, 0x289, 0x28c, 0x28e, 0x290, 0x292, 0x294, 0x296, 0x2a3, 0x2ad, 0x2af, 0x2b1, 0x2b7, 0x2b9, 0x2bb, 0x2be} + +// nfcSparseValues: 704 entries, 2816 bytes +var nfcSparseValues = [704]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: 0x46f9, lo: 0xa0, hi: 0xa1}, + {value: 0x472b, 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: 0x4857, lo: 0x8a, hi: 0x8a}, + {value: 0x4875, lo: 0x8b, hi: 0x8b}, + {value: 0x36de, lo: 0x8c, hi: 0x8c}, + {value: 0x36f6, lo: 0x8d, hi: 0x8d}, + {value: 0x488d, lo: 0x8e, hi: 0x8e}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x3714, 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: 0x37bc, lo: 0x90, hi: 0x90}, + {value: 0x37c8, lo: 0x91, hi: 0x91}, + {value: 0x37b6, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x382e, lo: 0x97, hi: 0x97}, + {value: 0x37f8, lo: 0x9c, hi: 0x9c}, + {value: 0x37e0, lo: 0x9d, hi: 0x9d}, + {value: 0x380a, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x3834, lo: 0xb6, hi: 0xb6}, + {value: 0x383a, lo: 0xb7, hi: 0xb7}, + // Block 0x6, offset 0x28 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0x83, hi: 0x87}, + // Block 0x7, offset 0x2a + {value: 0x0001, lo: 0x04}, + {value: 0x8114, lo: 0x81, hi: 0x82}, + {value: 0x8133, lo: 0x84, hi: 0x84}, + {value: 0x812e, lo: 0x85, hi: 0x85}, + {value: 0x810e, lo: 0x87, hi: 0x87}, + // Block 0x8, offset 0x2f + {value: 0x0000, lo: 0x0a}, + {value: 0x8133, lo: 0x90, hi: 0x97}, + {value: 0x811a, lo: 0x98, hi: 0x98}, + {value: 0x811b, lo: 0x99, hi: 0x99}, + {value: 0x811c, lo: 0x9a, hi: 0x9a}, + {value: 0x3858, lo: 0xa2, hi: 0xa2}, + {value: 0x385e, lo: 0xa3, hi: 0xa3}, + {value: 0x386a, lo: 0xa4, hi: 0xa4}, + {value: 0x3864, lo: 0xa5, hi: 0xa5}, + {value: 0x3870, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x9, offset 0x3a + {value: 0x0000, lo: 0x0e}, + {value: 0x3882, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x3876, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x387c, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8133, lo: 0x96, hi: 0x9c}, + {value: 0x8133, lo: 0x9f, hi: 0xa2}, + {value: 0x812e, lo: 0xa3, hi: 0xa3}, + {value: 0x8133, lo: 0xa4, hi: 0xa4}, + {value: 0x8133, lo: 0xa7, hi: 0xa8}, + {value: 0x812e, lo: 0xaa, hi: 0xaa}, + {value: 0x8133, lo: 0xab, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + // Block 0xa, offset 0x49 + {value: 0x0000, lo: 0x0c}, + {value: 0x8120, lo: 0x91, hi: 0x91}, + {value: 0x8133, lo: 0xb0, hi: 0xb0}, + {value: 0x812e, lo: 0xb1, hi: 0xb1}, + {value: 0x8133, lo: 0xb2, hi: 0xb3}, + {value: 0x812e, lo: 0xb4, hi: 0xb4}, + {value: 0x8133, lo: 0xb5, hi: 0xb6}, + {value: 0x812e, lo: 0xb7, hi: 0xb9}, + {value: 0x8133, lo: 0xba, hi: 0xba}, + {value: 0x812e, lo: 0xbb, hi: 0xbc}, + {value: 0x8133, lo: 0xbd, hi: 0xbd}, + {value: 0x812e, lo: 0xbe, hi: 0xbe}, + {value: 0x8133, lo: 0xbf, hi: 0xbf}, + // Block 0xb, offset 0x56 + {value: 0x0005, lo: 0x07}, + {value: 0x8133, lo: 0x80, hi: 0x80}, + {value: 0x8133, lo: 0x81, hi: 0x81}, + {value: 0x812e, lo: 0x82, hi: 0x83}, + {value: 0x812e, lo: 0x84, hi: 0x85}, + {value: 0x812e, lo: 0x86, hi: 0x87}, + {value: 0x812e, lo: 0x88, hi: 0x89}, + {value: 0x8133, lo: 0x8a, hi: 0x8a}, + // Block 0xc, offset 0x5e + {value: 0x0000, lo: 0x04}, + {value: 0x8133, lo: 0xab, hi: 0xb1}, + {value: 0x812e, lo: 0xb2, hi: 0xb2}, + {value: 0x8133, lo: 0xb3, hi: 0xb3}, + {value: 0x812e, lo: 0xbd, hi: 0xbd}, + // Block 0xd, offset 0x63 + {value: 0x0000, lo: 0x04}, + {value: 0x8133, lo: 0x96, hi: 0x99}, + {value: 0x8133, lo: 0x9b, hi: 0xa3}, + {value: 0x8133, lo: 0xa5, hi: 0xa7}, + {value: 0x8133, lo: 0xa9, hi: 0xad}, + // Block 0xe, offset 0x68 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x99, hi: 0x9b}, + // Block 0xf, offset 0x6a + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3eef, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ef7, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3eff, lo: 0xb4, hi: 0xb4}, + {value: 0x9903, lo: 0xbc, hi: 0xbc}, + // Block 0x10, offset 0x72 + {value: 0x0008, lo: 0x06}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x8133, lo: 0x91, hi: 0x91}, + {value: 0x812e, lo: 0x92, hi: 0x92}, + {value: 0x8133, lo: 0x93, hi: 0x93}, + {value: 0x8133, lo: 0x94, hi: 0x94}, + {value: 0x4533, lo: 0x98, hi: 0x9f}, + // Block 0x11, offset 0x79 + {value: 0x0000, lo: 0x02}, + {value: 0x8103, 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: 0x2cab, lo: 0x8b, hi: 0x8c}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x4573, lo: 0x9c, hi: 0x9d}, + {value: 0x4583, lo: 0x9f, hi: 0x9f}, + {value: 0x8133, lo: 0xbe, hi: 0xbe}, + // Block 0x13, offset 0x84 + {value: 0x0000, lo: 0x03}, + {value: 0x45ab, lo: 0xb3, hi: 0xb3}, + {value: 0x45b3, lo: 0xb6, hi: 0xb6}, + {value: 0x8103, lo: 0xbc, hi: 0xbc}, + // Block 0x14, offset 0x88 + {value: 0x0008, lo: 0x03}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x458b, lo: 0x99, hi: 0x9b}, + {value: 0x45a3, lo: 0x9e, hi: 0x9e}, + // Block 0x15, offset 0x8c + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0xbc, hi: 0xbc}, + // Block 0x16, offset 0x8e + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + // Block 0x17, offset 0x90 + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cc3, lo: 0x88, hi: 0x88}, + {value: 0x2cbb, lo: 0x8b, hi: 0x8b}, + {value: 0x2ccb, lo: 0x8c, hi: 0x8c}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45bb, lo: 0x9c, hi: 0x9c}, + {value: 0x45c3, lo: 0x9d, hi: 0x9d}, + // Block 0x18, offset 0x99 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cd3, 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: 0x2cdb, lo: 0x8a, hi: 0x8a}, + {value: 0x2ceb, lo: 0x8b, hi: 0x8b}, + {value: 0x2ce3, lo: 0x8c, hi: 0x8c}, + {value: 0x8105, 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: 0x3f07, lo: 0x88, hi: 0x88}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x8121, lo: 0x95, hi: 0x96}, + // Block 0x1b, offset 0xa9 + {value: 0x0000, lo: 0x02}, + {value: 0x8103, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1c, offset 0xac + {value: 0x0000, lo: 0x09}, + {value: 0x2cf3, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cfb, lo: 0x87, hi: 0x87}, + {value: 0x2d03, lo: 0x88, hi: 0x88}, + {value: 0x2f67, lo: 0x8a, hi: 0x8a}, + {value: 0x2def, lo: 0x8b, hi: 0x8b}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1d, offset 0xb6 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, 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: 0x2d0b, lo: 0x8a, hi: 0x8a}, + {value: 0x2d1b, lo: 0x8b, hi: 0x8b}, + {value: 0x2d13, lo: 0x8c, hi: 0x8c}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1f, offset 0xc0 + {value: 0x6bdd, lo: 0x07}, + {value: 0x9905, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3f0f, lo: 0x9a, hi: 0x9a}, + {value: 0x2f6f, lo: 0x9c, hi: 0x9c}, + {value: 0x2dfa, lo: 0x9d, hi: 0x9d}, + {value: 0x2d23, lo: 0x9e, hi: 0x9f}, + // Block 0x20, offset 0xc8 + {value: 0x0000, lo: 0x02}, + {value: 0x8123, lo: 0xb8, hi: 0xb9}, + {value: 0x8105, lo: 0xba, hi: 0xba}, + // Block 0x21, offset 0xcb + {value: 0x0000, lo: 0x01}, + {value: 0x8124, lo: 0x88, hi: 0x8b}, + // Block 0x22, offset 0xcd + {value: 0x0000, lo: 0x02}, + {value: 0x8125, lo: 0xb8, hi: 0xb9}, + {value: 0x8105, lo: 0xba, hi: 0xba}, + // Block 0x23, offset 0xd0 + {value: 0x0000, lo: 0x01}, + {value: 0x8126, lo: 0x88, hi: 0x8b}, + // Block 0x24, offset 0xd2 + {value: 0x0000, lo: 0x04}, + {value: 0x812e, lo: 0x98, hi: 0x99}, + {value: 0x812e, lo: 0xb5, hi: 0xb5}, + {value: 0x812e, lo: 0xb7, hi: 0xb7}, + {value: 0x812c, lo: 0xb9, hi: 0xb9}, + // Block 0x25, offset 0xd7 + {value: 0x0000, lo: 0x10}, + {value: 0x264a, lo: 0x83, hi: 0x83}, + {value: 0x2651, lo: 0x8d, hi: 0x8d}, + {value: 0x2658, lo: 0x92, hi: 0x92}, + {value: 0x265f, lo: 0x97, hi: 0x97}, + {value: 0x2666, lo: 0x9c, hi: 0x9c}, + {value: 0x2643, lo: 0xa9, hi: 0xa9}, + {value: 0x8127, lo: 0xb1, hi: 0xb1}, + {value: 0x8128, lo: 0xb2, hi: 0xb2}, + {value: 0x4a9b, lo: 0xb3, hi: 0xb3}, + {value: 0x8129, lo: 0xb4, hi: 0xb4}, + {value: 0x4aa4, lo: 0xb5, hi: 0xb5}, + {value: 0x45cb, lo: 0xb6, hi: 0xb6}, + {value: 0x8200, lo: 0xb7, hi: 0xb7}, + {value: 0x45d3, lo: 0xb8, hi: 0xb8}, + {value: 0x8200, lo: 0xb9, hi: 0xb9}, + {value: 0x8128, lo: 0xba, hi: 0xbd}, + // Block 0x26, offset 0xe8 + {value: 0x0000, lo: 0x0b}, + {value: 0x8128, lo: 0x80, hi: 0x80}, + {value: 0x4aad, lo: 0x81, hi: 0x81}, + {value: 0x8133, lo: 0x82, hi: 0x83}, + {value: 0x8105, lo: 0x84, hi: 0x84}, + {value: 0x8133, lo: 0x86, hi: 0x87}, + {value: 0x2674, lo: 0x93, hi: 0x93}, + {value: 0x267b, lo: 0x9d, hi: 0x9d}, + {value: 0x2682, lo: 0xa2, hi: 0xa2}, + {value: 0x2689, lo: 0xa7, hi: 0xa7}, + {value: 0x2690, lo: 0xac, hi: 0xac}, + {value: 0x266d, lo: 0xb9, hi: 0xb9}, + // Block 0x27, offset 0xf4 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x86, hi: 0x86}, + // Block 0x28, offset 0xf6 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d2b, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8103, lo: 0xb7, hi: 0xb7}, + {value: 0x8105, lo: 0xb9, hi: 0xba}, + // Block 0x29, offset 0xfc + {value: 0x0000, lo: 0x01}, + {value: 0x812e, 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: 0x8133, lo: 0x9d, hi: 0x9f}, + // Block 0x2f, offset 0x108 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x94, hi: 0x94}, + {value: 0x8105, lo: 0xb4, hi: 0xb4}, + // Block 0x30, offset 0x10b + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x92, hi: 0x92}, + {value: 0x8133, lo: 0x9d, hi: 0x9d}, + // Block 0x31, offset 0x10e + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + // Block 0x32, offset 0x110 + {value: 0x0004, lo: 0x02}, + {value: 0x812f, lo: 0xb9, hi: 0xba}, + {value: 0x812e, lo: 0xbb, hi: 0xbb}, + // Block 0x33, offset 0x113 + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0x97, hi: 0x97}, + {value: 0x812e, lo: 0x98, hi: 0x98}, + // Block 0x34, offset 0x116 + {value: 0x0000, lo: 0x03}, + {value: 0x8105, lo: 0xa0, hi: 0xa0}, + {value: 0x8133, lo: 0xb5, hi: 0xbc}, + {value: 0x812e, lo: 0xbf, hi: 0xbf}, + // Block 0x35, offset 0x11a + {value: 0x0000, lo: 0x05}, + {value: 0x8133, lo: 0xb0, hi: 0xb4}, + {value: 0x812e, lo: 0xb5, hi: 0xba}, + {value: 0x8133, lo: 0xbb, hi: 0xbc}, + {value: 0x812e, lo: 0xbd, hi: 0xbd}, + {value: 0x812e, lo: 0xbf, hi: 0xbf}, + // Block 0x36, offset 0x120 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x80, hi: 0x80}, + // Block 0x37, offset 0x122 + {value: 0x0000, lo: 0x08}, + {value: 0x2d73, lo: 0x80, hi: 0x80}, + {value: 0x2d7b, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d83, lo: 0x83, hi: 0x83}, + {value: 0x8105, lo: 0x84, hi: 0x84}, + {value: 0x8133, lo: 0xab, hi: 0xab}, + {value: 0x812e, lo: 0xac, hi: 0xac}, + {value: 0x8133, lo: 0xad, hi: 0xb3}, + // Block 0x38, offset 0x12b + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xaa, hi: 0xab}, + // Block 0x39, offset 0x12d + {value: 0x0000, lo: 0x02}, + {value: 0x8103, lo: 0xa6, hi: 0xa6}, + {value: 0x8105, lo: 0xb2, hi: 0xb3}, + // Block 0x3a, offset 0x130 + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0xb7, hi: 0xb7}, + // Block 0x3b, offset 0x132 + {value: 0x0000, lo: 0x0a}, + {value: 0x8133, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812e, lo: 0x95, hi: 0x99}, + {value: 0x8133, lo: 0x9a, hi: 0x9b}, + {value: 0x812e, lo: 0x9c, hi: 0x9f}, + {value: 0x8133, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x8133, lo: 0xb4, hi: 0xb4}, + {value: 0x8133, lo: 0xb8, hi: 0xb9}, + // Block 0x3c, offset 0x13d + {value: 0x0004, lo: 0x03}, + {value: 0x0436, lo: 0x80, hi: 0x81}, + {value: 0x8100, lo: 0x97, hi: 0x97}, + {value: 0x8100, lo: 0xbe, hi: 0xbe}, + // Block 0x3d, offset 0x141 + {value: 0x0000, lo: 0x0d}, + {value: 0x8133, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8133, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8133, lo: 0x9b, hi: 0x9c}, + {value: 0x8133, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8133, lo: 0xa7, hi: 0xa7}, + {value: 0x812e, lo: 0xa8, hi: 0xa8}, + {value: 0x8133, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812e, lo: 0xac, hi: 0xaf}, + {value: 0x8133, lo: 0xb0, hi: 0xb0}, + // Block 0x3e, offset 0x14f + {value: 0x4292, lo: 0x02}, + {value: 0x01bb, lo: 0xa6, hi: 0xa6}, + {value: 0x0057, lo: 0xaa, hi: 0xab}, + // Block 0x3f, offset 0x152 + {value: 0x0007, lo: 0x05}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bd0, lo: 0x9a, hi: 0x9b}, + {value: 0x3bde, lo: 0xae, hi: 0xae}, + // Block 0x40, offset 0x158 + {value: 0x000e, lo: 0x05}, + {value: 0x3be5, lo: 0x8d, hi: 0x8e}, + {value: 0x3bec, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x41, offset 0x15e + {value: 0x63f1, lo: 0x0a}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3bfa, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3c01, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3c08, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3c0f, lo: 0xa4, hi: 0xa5}, + {value: 0x3c16, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x42, offset 0x169 + {value: 0x0007, lo: 0x03}, + {value: 0x3c7f, lo: 0xa0, hi: 0xa1}, + {value: 0x3ca9, lo: 0xa2, hi: 0xa3}, + {value: 0x3cd3, lo: 0xaa, hi: 0xad}, + // Block 0x43, offset 0x16d + {value: 0x0004, lo: 0x01}, + {value: 0x048e, lo: 0xa9, hi: 0xaa}, + // Block 0x44, offset 0x16f + {value: 0x0000, lo: 0x01}, + {value: 0x44f4, lo: 0x9c, hi: 0x9c}, + // Block 0x45, offset 0x171 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xaf, hi: 0xb1}, + // Block 0x46, offset 0x173 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x47, offset 0x175 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xa0, hi: 0xbf}, + // Block 0x48, offset 0x177 + {value: 0x0000, lo: 0x05}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x8134, lo: 0xac, hi: 0xac}, + {value: 0x812f, lo: 0xad, hi: 0xad}, + {value: 0x8130, lo: 0xae, hi: 0xaf}, + // Block 0x49, offset 0x17d + {value: 0x0000, lo: 0x03}, + {value: 0x4ab6, lo: 0xb3, hi: 0xb3}, + {value: 0x4ab6, lo: 0xb5, hi: 0xb6}, + {value: 0x4ab6, lo: 0xba, hi: 0xbf}, + // Block 0x4a, offset 0x181 + {value: 0x0000, lo: 0x01}, + {value: 0x4ab6, lo: 0x8f, hi: 0xa3}, + // Block 0x4b, offset 0x183 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xae, hi: 0xbe}, + // Block 0x4c, offset 0x185 + {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 0x4d, offset 0x18d + {value: 0x0000, lo: 0x03}, + {value: 0x8100, lo: 0x80, hi: 0x80}, + {value: 0x8100, lo: 0x8b, hi: 0x8b}, + {value: 0x8100, lo: 0x8e, hi: 0x8e}, + // Block 0x4e, offset 0x191 + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0xaf, hi: 0xaf}, + {value: 0x8133, lo: 0xb4, hi: 0xbd}, + // Block 0x4f, offset 0x194 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0x9e, hi: 0x9f}, + // Block 0x50, offset 0x196 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xb0, hi: 0xb1}, + // Block 0x51, offset 0x198 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x86, hi: 0x86}, + {value: 0x8105, lo: 0xac, hi: 0xac}, + // Block 0x52, offset 0x19b + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x84, hi: 0x84}, + {value: 0x8133, lo: 0xa0, hi: 0xb1}, + // Block 0x53, offset 0x19e + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0xab, hi: 0xad}, + // Block 0x54, offset 0x1a0 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x93, hi: 0x93}, + // Block 0x55, offset 0x1a2 + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0xb3, hi: 0xb3}, + // Block 0x56, offset 0x1a4 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x80, hi: 0x80}, + // Block 0x57, offset 0x1a6 + {value: 0x0000, lo: 0x05}, + {value: 0x8133, lo: 0xb0, hi: 0xb0}, + {value: 0x8133, lo: 0xb2, hi: 0xb3}, + {value: 0x812e, lo: 0xb4, hi: 0xb4}, + {value: 0x8133, lo: 0xb7, hi: 0xb8}, + {value: 0x8133, lo: 0xbe, hi: 0xbf}, + // Block 0x58, offset 0x1ac + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0x81, hi: 0x81}, + {value: 0x8105, lo: 0xb6, hi: 0xb6}, + // Block 0x59, offset 0x1af + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xad, hi: 0xad}, + // Block 0x5a, offset 0x1b1 + {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 0x5b, offset 0x1b8 + {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 0x5c, offset 0x1be + {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 0x5d, offset 0x1c4 + {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 0x5e, offset 0x1cc + {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 0x5f, offset 0x1d2 + {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 0x60, offset 0x1d8 + {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 0x61, offset 0x1de + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x62, offset 0x1e2 + {value: 0x0006, lo: 0x0d}, + {value: 0x43a7, lo: 0x9d, hi: 0x9d}, + {value: 0x8116, lo: 0x9e, hi: 0x9e}, + {value: 0x4419, lo: 0x9f, hi: 0x9f}, + {value: 0x4407, lo: 0xaa, hi: 0xab}, + {value: 0x450b, lo: 0xac, hi: 0xac}, + {value: 0x4513, lo: 0xad, hi: 0xad}, + {value: 0x435f, lo: 0xae, hi: 0xb1}, + {value: 0x437d, lo: 0xb2, hi: 0xb4}, + {value: 0x4395, lo: 0xb5, hi: 0xb6}, + {value: 0x43a1, lo: 0xb8, hi: 0xb8}, + {value: 0x43ad, lo: 0xb9, hi: 0xbb}, + {value: 0x43c5, lo: 0xbc, hi: 0xbc}, + {value: 0x43cb, lo: 0xbe, hi: 0xbe}, + // Block 0x63, offset 0x1f0 + {value: 0x0006, lo: 0x08}, + {value: 0x43d1, lo: 0x80, hi: 0x81}, + {value: 0x43dd, lo: 0x83, hi: 0x84}, + {value: 0x43ef, lo: 0x86, hi: 0x89}, + {value: 0x4413, lo: 0x8a, hi: 0x8a}, + {value: 0x438f, lo: 0x8b, hi: 0x8b}, + {value: 0x4377, lo: 0x8c, hi: 0x8c}, + {value: 0x43bf, lo: 0x8d, hi: 0x8d}, + {value: 0x43e9, lo: 0x8e, hi: 0x8e}, + // Block 0x64, offset 0x1f9 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0xa4, hi: 0xa5}, + {value: 0x8100, lo: 0xb0, hi: 0xb1}, + // Block 0x65, offset 0x1fc + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x9b, hi: 0x9d}, + {value: 0x8200, lo: 0x9e, hi: 0xa3}, + // Block 0x66, offset 0x1ff + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x90, hi: 0x90}, + // Block 0x67, offset 0x201 + {value: 0x0000, lo: 0x02}, + {value: 0x8100, lo: 0x99, hi: 0x99}, + {value: 0x8200, lo: 0xb2, hi: 0xb4}, + // Block 0x68, offset 0x204 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xbc, hi: 0xbd}, + // Block 0x69, offset 0x206 + {value: 0x0000, lo: 0x03}, + {value: 0x8133, lo: 0xa0, hi: 0xa6}, + {value: 0x812e, lo: 0xa7, hi: 0xad}, + {value: 0x8133, lo: 0xae, hi: 0xaf}, + // Block 0x6a, offset 0x20a + {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 0x6b, offset 0x20f + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0x81, hi: 0x8c}, + // Block 0x6c, offset 0x211 + {value: 0x0000, lo: 0x01}, + {value: 0x8100, lo: 0xb5, hi: 0xba}, + // Block 0x6d, offset 0x213 + {value: 0x0000, lo: 0x04}, + {value: 0x4ab6, lo: 0x9e, hi: 0x9f}, + {value: 0x4ab6, lo: 0xa3, hi: 0xa3}, + {value: 0x4ab6, lo: 0xa5, hi: 0xa6}, + {value: 0x4ab6, lo: 0xaa, hi: 0xaf}, + // Block 0x6e, offset 0x218 + {value: 0x0000, lo: 0x05}, + {value: 0x4ab6, lo: 0x82, hi: 0x87}, + {value: 0x4ab6, lo: 0x8a, hi: 0x8f}, + {value: 0x4ab6, lo: 0x92, hi: 0x97}, + {value: 0x4ab6, lo: 0x9a, hi: 0x9c}, + {value: 0x8100, lo: 0xa3, hi: 0xa3}, + // Block 0x6f, offset 0x21e + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0xbd, hi: 0xbd}, + // Block 0x70, offset 0x220 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0xa0, hi: 0xa0}, + // Block 0x71, offset 0x222 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xb6, hi: 0xba}, + // Block 0x72, offset 0x224 + {value: 0x002d, lo: 0x05}, + {value: 0x812e, lo: 0x8d, hi: 0x8d}, + {value: 0x8133, lo: 0x8f, hi: 0x8f}, + {value: 0x8133, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x73, offset 0x22a + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0xa5, hi: 0xa5}, + {value: 0x812e, lo: 0xa6, hi: 0xa6}, + // Block 0x74, offset 0x22d + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xa4, hi: 0xa7}, + // Block 0x75, offset 0x22f + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xab, hi: 0xac}, + // Block 0x76, offset 0x231 + {value: 0x0000, lo: 0x05}, + {value: 0x812e, lo: 0x86, hi: 0x87}, + {value: 0x8133, lo: 0x88, hi: 0x8a}, + {value: 0x812e, lo: 0x8b, hi: 0x8b}, + {value: 0x8133, lo: 0x8c, hi: 0x8c}, + {value: 0x812e, lo: 0x8d, hi: 0x90}, + // Block 0x77, offset 0x237 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x86, hi: 0x86}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x78, offset 0x23a + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x424f, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4259, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x4263, lo: 0xab, hi: 0xab}, + {value: 0x8105, lo: 0xb9, hi: 0xba}, + // Block 0x79, offset 0x242 + {value: 0x0000, lo: 0x06}, + {value: 0x8133, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d8b, lo: 0xae, hi: 0xae}, + {value: 0x2d95, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8105, lo: 0xb3, hi: 0xb4}, + // Block 0x7a, offset 0x249 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x80, hi: 0x80}, + {value: 0x8103, lo: 0x8a, hi: 0x8a}, + // Block 0x7b, offset 0x24c + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0xb5, hi: 0xb5}, + {value: 0x8103, lo: 0xb6, hi: 0xb6}, + // Block 0x7c, offset 0x24f + {value: 0x0002, lo: 0x01}, + {value: 0x8103, lo: 0xa9, hi: 0xaa}, + // Block 0x7d, offset 0x251 + {value: 0x0000, lo: 0x02}, + {value: 0x8103, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x7e, offset 0x254 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d9f, lo: 0x8b, hi: 0x8b}, + {value: 0x2da9, lo: 0x8c, hi: 0x8c}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8133, lo: 0xa6, hi: 0xac}, + {value: 0x8133, lo: 0xb0, hi: 0xb4}, + // Block 0x7f, offset 0x25c + {value: 0x0000, lo: 0x03}, + {value: 0x8105, lo: 0x82, hi: 0x82}, + {value: 0x8103, lo: 0x86, hi: 0x86}, + {value: 0x8133, lo: 0x9e, hi: 0x9e}, + // Block 0x80, offset 0x260 + {value: 0x6b4d, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2dbd, lo: 0xbb, hi: 0xbb}, + {value: 0x2db3, lo: 0xbc, hi: 0xbd}, + {value: 0x2dc7, lo: 0xbe, hi: 0xbe}, + // Block 0x81, offset 0x267 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x82, hi: 0x82}, + {value: 0x8103, lo: 0x83, hi: 0x83}, + // Block 0x82, offset 0x26a + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dd1, lo: 0xba, hi: 0xba}, + {value: 0x2ddb, lo: 0xbb, hi: 0xbb}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x83, offset 0x270 + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0x80, hi: 0x80}, + // Block 0x84, offset 0x272 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0xb6, hi: 0xb6}, + {value: 0x8103, lo: 0xb7, hi: 0xb7}, + // Block 0x85, offset 0x275 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xab, hi: 0xab}, + // Block 0x86, offset 0x277 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0xb9, hi: 0xb9}, + {value: 0x8103, lo: 0xba, hi: 0xba}, + // Block 0x87, offset 0x27a + {value: 0x0000, lo: 0x04}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb5, hi: 0xb5}, + {value: 0x2de5, lo: 0xb8, hi: 0xb8}, + {value: 0x8105, lo: 0xbd, hi: 0xbe}, + // Block 0x88, offset 0x27f + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0x83, hi: 0x83}, + // Block 0x89, offset 0x281 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xa0, hi: 0xa0}, + // Block 0x8a, offset 0x283 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xb4, hi: 0xb4}, + // Block 0x8b, offset 0x285 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x87, hi: 0x87}, + // Block 0x8c, offset 0x287 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x99, hi: 0x99}, + // Block 0x8d, offset 0x289 + {value: 0x0000, lo: 0x02}, + {value: 0x8103, lo: 0x82, hi: 0x82}, + {value: 0x8105, lo: 0x84, hi: 0x85}, + // Block 0x8e, offset 0x28c + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x97, hi: 0x97}, + // Block 0x8f, offset 0x28e + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x90, offset 0x290 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xb0, hi: 0xb6}, + // Block 0x91, offset 0x292 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb0, hi: 0xb1}, + // Block 0x92, offset 0x294 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x93, offset 0x296 + {value: 0x0000, lo: 0x0c}, + {value: 0x45e3, lo: 0x9e, hi: 0x9e}, + {value: 0x45ed, lo: 0x9f, hi: 0x9f}, + {value: 0x4621, lo: 0xa0, hi: 0xa0}, + {value: 0x462f, lo: 0xa1, hi: 0xa1}, + {value: 0x463d, lo: 0xa2, hi: 0xa2}, + {value: 0x464b, lo: 0xa3, hi: 0xa3}, + {value: 0x4659, lo: 0xa4, hi: 0xa4}, + {value: 0x812c, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8131, lo: 0xad, hi: 0xad}, + {value: 0x812c, lo: 0xae, hi: 0xb2}, + {value: 0x812e, lo: 0xbb, hi: 0xbf}, + // Block 0x94, offset 0x2a3 + {value: 0x0000, lo: 0x09}, + {value: 0x812e, lo: 0x80, hi: 0x82}, + {value: 0x8133, lo: 0x85, hi: 0x89}, + {value: 0x812e, lo: 0x8a, hi: 0x8b}, + {value: 0x8133, lo: 0xaa, hi: 0xad}, + {value: 0x45f7, lo: 0xbb, hi: 0xbb}, + {value: 0x4601, lo: 0xbc, hi: 0xbc}, + {value: 0x4667, lo: 0xbd, hi: 0xbd}, + {value: 0x4683, lo: 0xbe, hi: 0xbe}, + {value: 0x4675, lo: 0xbf, hi: 0xbf}, + // Block 0x95, offset 0x2ad + {value: 0x0000, lo: 0x01}, + {value: 0x4691, lo: 0x80, hi: 0x80}, + // Block 0x96, offset 0x2af + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0x82, hi: 0x84}, + // Block 0x97, offset 0x2b1 + {value: 0x0000, lo: 0x05}, + {value: 0x8133, lo: 0x80, hi: 0x86}, + {value: 0x8133, lo: 0x88, hi: 0x98}, + {value: 0x8133, lo: 0x9b, hi: 0xa1}, + {value: 0x8133, lo: 0xa3, hi: 0xa4}, + {value: 0x8133, lo: 0xa6, hi: 0xaa}, + // Block 0x98, offset 0x2b7 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xac, hi: 0xaf}, + // Block 0x99, offset 0x2b9 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x90, hi: 0x96}, + // Block 0x9a, offset 0x2bb + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0x84, hi: 0x89}, + {value: 0x8103, lo: 0x8a, hi: 0x8a}, + // Block 0x9b, offset 0x2be + {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: 18768 bytes (18.33 KiB). Checksum: c51186dd2412943d. +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: 0x2f86, 0xc1: 0x2f8b, 0xc2: 0x469f, 0xc3: 0x2f90, 0xc4: 0x46ae, 0xc5: 0x46b3, + 0xc6: 0xa000, 0xc7: 0x46bd, 0xc8: 0x2ff9, 0xc9: 0x2ffe, 0xca: 0x46c2, 0xcb: 0x3012, + 0xcc: 0x3085, 0xcd: 0x308a, 0xce: 0x308f, 0xcf: 0x46d6, 0xd1: 0x311b, + 0xd2: 0x313e, 0xd3: 0x3143, 0xd4: 0x46e0, 0xd5: 0x46e5, 0xd6: 0x46f4, + 0xd8: 0xa000, 0xd9: 0x31ca, 0xda: 0x31cf, 0xdb: 0x31d4, 0xdc: 0x4726, 0xdd: 0x324c, + 0xe0: 0x3292, 0xe1: 0x3297, 0xe2: 0x4730, 0xe3: 0x329c, + 0xe4: 0x473f, 0xe5: 0x4744, 0xe6: 0xa000, 0xe7: 0x474e, 0xe8: 0x3305, 0xe9: 0x330a, + 0xea: 0x4753, 0xeb: 0x331e, 0xec: 0x3396, 0xed: 0x339b, 0xee: 0x33a0, 0xef: 0x4767, + 0xf1: 0x342c, 0xf2: 0x344f, 0xf3: 0x3454, 0xf4: 0x4771, 0xf5: 0x4776, + 0xf6: 0x4785, 0xf8: 0xa000, 0xf9: 0x34e0, 0xfa: 0x34e5, 0xfb: 0x34ea, + 0xfc: 0x47b7, 0xfd: 0x3567, 0xff: 0x3580, + // Block 0x4, offset 0x100 + 0x100: 0x2f95, 0x101: 0x32a1, 0x102: 0x46a4, 0x103: 0x4735, 0x104: 0x2fb3, 0x105: 0x32bf, + 0x106: 0x2fc7, 0x107: 0x32d3, 0x108: 0x2fcc, 0x109: 0x32d8, 0x10a: 0x2fd1, 0x10b: 0x32dd, + 0x10c: 0x2fd6, 0x10d: 0x32e2, 0x10e: 0x2fe0, 0x10f: 0x32ec, + 0x112: 0x46c7, 0x113: 0x4758, 0x114: 0x3008, 0x115: 0x3314, 0x116: 0x300d, 0x117: 0x3319, + 0x118: 0x302b, 0x119: 0x3337, 0x11a: 0x301c, 0x11b: 0x3328, 0x11c: 0x3044, 0x11d: 0x3350, + 0x11e: 0x304e, 0x11f: 0x335a, 0x120: 0x3053, 0x121: 0x335f, 0x122: 0x305d, 0x123: 0x3369, + 0x124: 0x3062, 0x125: 0x336e, 0x128: 0x3094, 0x129: 0x33a5, + 0x12a: 0x3099, 0x12b: 0x33aa, 0x12c: 0x309e, 0x12d: 0x33af, 0x12e: 0x30c1, 0x12f: 0x33cd, + 0x130: 0x30a3, 0x132: 0x1960, 0x133: 0x19ed, 0x134: 0x30cb, 0x135: 0x33d7, + 0x136: 0x30df, 0x137: 0x33f0, 0x139: 0x30e9, 0x13a: 0x33fa, 0x13b: 0x30f3, + 0x13c: 0x3404, 0x13d: 0x30ee, 0x13e: 0x33ff, 0x13f: 0x1bb2, + // Block 0x5, offset 0x140 + 0x140: 0x1c3a, 0x143: 0x3116, 0x144: 0x3427, 0x145: 0x312f, + 0x146: 0x3440, 0x147: 0x3125, 0x148: 0x3436, 0x149: 0x1c62, + 0x14c: 0x46ea, 0x14d: 0x477b, 0x14e: 0x3148, 0x14f: 0x3459, 0x150: 0x3152, 0x151: 0x3463, + 0x154: 0x3170, 0x155: 0x3481, 0x156: 0x3189, 0x157: 0x349a, + 0x158: 0x317a, 0x159: 0x348b, 0x15a: 0x470d, 0x15b: 0x479e, 0x15c: 0x3193, 0x15d: 0x34a4, + 0x15e: 0x31a2, 0x15f: 0x34b3, 0x160: 0x4712, 0x161: 0x47a3, 0x162: 0x31bb, 0x163: 0x34d1, + 0x164: 0x31ac, 0x165: 0x34c2, 0x168: 0x471c, 0x169: 0x47ad, + 0x16a: 0x4721, 0x16b: 0x47b2, 0x16c: 0x31d9, 0x16d: 0x34ef, 0x16e: 0x31e3, 0x16f: 0x34f9, + 0x170: 0x31e8, 0x171: 0x34fe, 0x172: 0x3206, 0x173: 0x351c, 0x174: 0x3229, 0x175: 0x353f, + 0x176: 0x3251, 0x177: 0x356c, 0x178: 0x3265, 0x179: 0x3274, 0x17a: 0x3594, 0x17b: 0x327e, + 0x17c: 0x359e, 0x17d: 0x3283, 0x17e: 0x35a3, 0x17f: 0x00a7, + // Block 0x6, offset 0x180 + 0x184: 0x2e05, 0x185: 0x2e0b, + 0x186: 0x2e11, 0x187: 0x1975, 0x188: 0x1978, 0x189: 0x1a0e, 0x18a: 0x198d, 0x18b: 0x1990, + 0x18c: 0x1a44, 0x18d: 0x2f9f, 0x18e: 0x32ab, 0x18f: 0x30ad, 0x190: 0x33b9, 0x191: 0x3157, + 0x192: 0x3468, 0x193: 0x31ed, 0x194: 0x3503, 0x195: 0x39e6, 0x196: 0x3b75, 0x197: 0x39df, + 0x198: 0x3b6e, 0x199: 0x39ed, 0x19a: 0x3b7c, 0x19b: 0x39d8, 0x19c: 0x3b67, + 0x19e: 0x38c7, 0x19f: 0x3a56, 0x1a0: 0x38c0, 0x1a1: 0x3a4f, 0x1a2: 0x35ca, 0x1a3: 0x35dc, + 0x1a6: 0x3058, 0x1a7: 0x3364, 0x1a8: 0x30d5, 0x1a9: 0x33e6, + 0x1aa: 0x4703, 0x1ab: 0x4794, 0x1ac: 0x39a7, 0x1ad: 0x3b36, 0x1ae: 0x35ee, 0x1af: 0x35f4, + 0x1b0: 0x33dc, 0x1b1: 0x1945, 0x1b2: 0x1948, 0x1b3: 0x19d5, 0x1b4: 0x303f, 0x1b5: 0x334b, + 0x1b8: 0x3111, 0x1b9: 0x3422, 0x1ba: 0x38ce, 0x1bb: 0x3a5d, + 0x1bc: 0x35c4, 0x1bd: 0x35d6, 0x1be: 0x35d0, 0x1bf: 0x35e2, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x2fa4, 0x1c1: 0x32b0, 0x1c2: 0x2fa9, 0x1c3: 0x32b5, 0x1c4: 0x3021, 0x1c5: 0x332d, + 0x1c6: 0x3026, 0x1c7: 0x3332, 0x1c8: 0x30b2, 0x1c9: 0x33be, 0x1ca: 0x30b7, 0x1cb: 0x33c3, + 0x1cc: 0x315c, 0x1cd: 0x346d, 0x1ce: 0x3161, 0x1cf: 0x3472, 0x1d0: 0x317f, 0x1d1: 0x3490, + 0x1d2: 0x3184, 0x1d3: 0x3495, 0x1d4: 0x31f2, 0x1d5: 0x3508, 0x1d6: 0x31f7, 0x1d7: 0x350d, + 0x1d8: 0x319d, 0x1d9: 0x34ae, 0x1da: 0x31b6, 0x1db: 0x34cc, + 0x1de: 0x3071, 0x1df: 0x337d, + 0x1e6: 0x46a9, 0x1e7: 0x473a, 0x1e8: 0x46d1, 0x1e9: 0x4762, + 0x1ea: 0x3976, 0x1eb: 0x3b05, 0x1ec: 0x3953, 0x1ed: 0x3ae2, 0x1ee: 0x46ef, 0x1ef: 0x4780, + 0x1f0: 0x396f, 0x1f1: 0x3afe, 0x1f2: 0x325b, 0x1f3: 0x3576, + // Block 0x8, offset 0x200 + 0x200: 0x9933, 0x201: 0x9933, 0x202: 0x9933, 0x203: 0x9933, 0x204: 0x9933, 0x205: 0x8133, + 0x206: 0x9933, 0x207: 0x9933, 0x208: 0x9933, 0x209: 0x9933, 0x20a: 0x9933, 0x20b: 0x9933, + 0x20c: 0x9933, 0x20d: 0x8133, 0x20e: 0x8133, 0x20f: 0x9933, 0x210: 0x8133, 0x211: 0x9933, + 0x212: 0x8133, 0x213: 0x9933, 0x214: 0x9933, 0x215: 0x8134, 0x216: 0x812e, 0x217: 0x812e, + 0x218: 0x812e, 0x219: 0x812e, 0x21a: 0x8134, 0x21b: 0x992c, 0x21c: 0x812e, 0x21d: 0x812e, + 0x21e: 0x812e, 0x21f: 0x812e, 0x220: 0x812e, 0x221: 0x812a, 0x222: 0x812a, 0x223: 0x992e, + 0x224: 0x992e, 0x225: 0x992e, 0x226: 0x992e, 0x227: 0x992a, 0x228: 0x992a, 0x229: 0x812e, + 0x22a: 0x812e, 0x22b: 0x812e, 0x22c: 0x812e, 0x22d: 0x992e, 0x22e: 0x992e, 0x22f: 0x812e, + 0x230: 0x992e, 0x231: 0x992e, 0x232: 0x812e, 0x233: 0x812e, 0x234: 0x8101, 0x235: 0x8101, + 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812e, 0x23a: 0x812e, 0x23b: 0x812e, + 0x23c: 0x812e, 0x23d: 0x8133, 0x23e: 0x8133, 0x23f: 0x8133, + // Block 0x9, offset 0x240 + 0x240: 0x49c5, 0x241: 0x49ca, 0x242: 0x9933, 0x243: 0x49cf, 0x244: 0x4a88, 0x245: 0x9937, + 0x246: 0x8133, 0x247: 0x812e, 0x248: 0x812e, 0x249: 0x812e, 0x24a: 0x8133, 0x24b: 0x8133, + 0x24c: 0x8133, 0x24d: 0x812e, 0x24e: 0x812e, 0x250: 0x8133, 0x251: 0x8133, + 0x252: 0x8133, 0x253: 0x812e, 0x254: 0x812e, 0x255: 0x812e, 0x256: 0x812e, 0x257: 0x8133, + 0x258: 0x8134, 0x259: 0x812e, 0x25a: 0x812e, 0x25b: 0x8133, 0x25c: 0x8135, 0x25d: 0x8136, + 0x25e: 0x8136, 0x25f: 0x8135, 0x260: 0x8136, 0x261: 0x8136, 0x262: 0x8135, 0x263: 0x8133, + 0x264: 0x8133, 0x265: 0x8133, 0x266: 0x8133, 0x267: 0x8133, 0x268: 0x8133, 0x269: 0x8133, + 0x26a: 0x8133, 0x26b: 0x8133, 0x26c: 0x8133, 0x26d: 0x8133, 0x26e: 0x8133, 0x26f: 0x8133, + 0x274: 0x0173, + 0x27a: 0x42bc, + 0x27e: 0x0037, + // Block 0xa, offset 0x280 + 0x284: 0x4271, 0x285: 0x4492, + 0x286: 0x3600, 0x287: 0x00ce, 0x288: 0x361e, 0x289: 0x362a, 0x28a: 0x363c, + 0x28c: 0x365a, 0x28e: 0x366c, 0x28f: 0x368a, 0x290: 0x3e1f, 0x291: 0xa000, + 0x295: 0xa000, 0x297: 0xa000, + 0x299: 0xa000, + 0x29f: 0xa000, 0x2a1: 0xa000, + 0x2a5: 0xa000, 0x2a9: 0xa000, + 0x2aa: 0x364e, 0x2ab: 0x367e, 0x2ac: 0x4815, 0x2ad: 0x36ae, 0x2ae: 0x483f, 0x2af: 0x36c0, + 0x2b0: 0x3e87, 0x2b1: 0xa000, 0x2b5: 0xa000, + 0x2b7: 0xa000, 0x2b9: 0xa000, + 0x2bf: 0xa000, + // Block 0xb, offset 0x2c0 + 0x2c1: 0xa000, 0x2c5: 0xa000, + 0x2c9: 0xa000, 0x2ca: 0x4857, 0x2cb: 0x4875, + 0x2cc: 0x36de, 0x2cd: 0x36f6, 0x2ce: 0x488d, 0x2d0: 0x01c1, 0x2d1: 0x01d3, + 0x2d2: 0x01af, 0x2d3: 0x4323, 0x2d4: 0x4329, 0x2d5: 0x01fd, 0x2d6: 0x01eb, + 0x2f0: 0x01d9, 0x2f1: 0x01ee, 0x2f2: 0x01f1, 0x2f4: 0x018b, 0x2f5: 0x01ca, + 0x2f9: 0x01a9, + // Block 0xc, offset 0x300 + 0x300: 0x3738, 0x301: 0x3744, 0x303: 0x3732, + 0x306: 0xa000, 0x307: 0x3720, + 0x30c: 0x3774, 0x30d: 0x375c, 0x30e: 0x3786, 0x310: 0xa000, + 0x313: 0xa000, 0x315: 0xa000, 0x316: 0xa000, 0x317: 0xa000, + 0x318: 0xa000, 0x319: 0x3768, 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: 0x37ec, 0x33a: 0xa000, + 0x33e: 0xa000, + // Block 0xd, offset 0x340 + 0x341: 0x374a, 0x342: 0x37ce, + 0x350: 0x3726, 0x351: 0x37aa, + 0x352: 0x372c, 0x353: 0x37b0, 0x356: 0x373e, 0x357: 0x37c2, + 0x358: 0xa000, 0x359: 0xa000, 0x35a: 0x3840, 0x35b: 0x3846, 0x35c: 0x3750, 0x35d: 0x37d4, + 0x35e: 0x3756, 0x35f: 0x37da, 0x362: 0x3762, 0x363: 0x37e6, + 0x364: 0x376e, 0x365: 0x37f2, 0x366: 0x377a, 0x367: 0x37fe, 0x368: 0xa000, 0x369: 0xa000, + 0x36a: 0x384c, 0x36b: 0x3852, 0x36c: 0x37a4, 0x36d: 0x3828, 0x36e: 0x3780, 0x36f: 0x3804, + 0x370: 0x378c, 0x371: 0x3810, 0x372: 0x3792, 0x373: 0x3816, 0x374: 0x3798, 0x375: 0x381c, + 0x378: 0x379e, 0x379: 0x3822, + // Block 0xe, offset 0x380 + 0x387: 0x1d67, + 0x391: 0x812e, + 0x392: 0x8133, 0x393: 0x8133, 0x394: 0x8133, 0x395: 0x8133, 0x396: 0x812e, 0x397: 0x8133, + 0x398: 0x8133, 0x399: 0x8133, 0x39a: 0x812f, 0x39b: 0x812e, 0x39c: 0x8133, 0x39d: 0x8133, + 0x39e: 0x8133, 0x39f: 0x8133, 0x3a0: 0x8133, 0x3a1: 0x8133, 0x3a2: 0x812e, 0x3a3: 0x812e, + 0x3a4: 0x812e, 0x3a5: 0x812e, 0x3a6: 0x812e, 0x3a7: 0x812e, 0x3a8: 0x8133, 0x3a9: 0x8133, + 0x3aa: 0x812e, 0x3ab: 0x8133, 0x3ac: 0x8133, 0x3ad: 0x812f, 0x3ae: 0x8132, 0x3af: 0x8133, + 0x3b0: 0x8106, 0x3b1: 0x8107, 0x3b2: 0x8108, 0x3b3: 0x8109, 0x3b4: 0x810a, 0x3b5: 0x810b, + 0x3b6: 0x810c, 0x3b7: 0x810d, 0x3b8: 0x810e, 0x3b9: 0x810f, 0x3ba: 0x810f, 0x3bb: 0x8110, + 0x3bc: 0x8111, 0x3bd: 0x8112, 0x3bf: 0x8113, + // Block 0xf, offset 0x3c0 + 0x3c8: 0xa000, 0x3ca: 0xa000, 0x3cb: 0x8117, + 0x3cc: 0x8118, 0x3cd: 0x8119, 0x3ce: 0x811a, 0x3cf: 0x811b, 0x3d0: 0x811c, 0x3d1: 0x811d, + 0x3d2: 0x811e, 0x3d3: 0x9933, 0x3d4: 0x9933, 0x3d5: 0x992e, 0x3d6: 0x812e, 0x3d7: 0x8133, + 0x3d8: 0x8133, 0x3d9: 0x8133, 0x3da: 0x8133, 0x3db: 0x8133, 0x3dc: 0x812e, 0x3dd: 0x8133, + 0x3de: 0x8133, 0x3df: 0x812e, + 0x3f0: 0x811f, 0x3f5: 0x1d8a, + 0x3f6: 0x2019, 0x3f7: 0x2055, 0x3f8: 0x2050, + // Block 0x10, offset 0x400 + 0x413: 0x812e, 0x414: 0x8133, 0x415: 0x8133, 0x416: 0x8133, 0x417: 0x8133, + 0x418: 0x8133, 0x419: 0x8133, 0x41a: 0x8133, 0x41b: 0x8133, 0x41c: 0x8133, 0x41d: 0x8133, + 0x41e: 0x8133, 0x41f: 0x8133, 0x420: 0x8133, 0x421: 0x8133, 0x423: 0x812e, + 0x424: 0x8133, 0x425: 0x8133, 0x426: 0x812e, 0x427: 0x8133, 0x428: 0x8133, 0x429: 0x812e, + 0x42a: 0x8133, 0x42b: 0x8133, 0x42c: 0x8133, 0x42d: 0x812e, 0x42e: 0x812e, 0x42f: 0x812e, + 0x430: 0x8117, 0x431: 0x8118, 0x432: 0x8119, 0x433: 0x8133, 0x434: 0x8133, 0x435: 0x8133, + 0x436: 0x812e, 0x437: 0x8133, 0x438: 0x8133, 0x439: 0x812e, 0x43a: 0x812e, 0x43b: 0x8133, + 0x43c: 0x8133, 0x43d: 0x8133, 0x43e: 0x8133, 0x43f: 0x8133, + // Block 0x11, offset 0x440 + 0x445: 0xa000, + 0x446: 0x2d33, 0x447: 0xa000, 0x448: 0x2d3b, 0x449: 0xa000, 0x44a: 0x2d43, 0x44b: 0xa000, + 0x44c: 0x2d4b, 0x44d: 0xa000, 0x44e: 0x2d53, 0x451: 0xa000, + 0x452: 0x2d5b, + 0x474: 0x8103, 0x475: 0x9900, + 0x47a: 0xa000, 0x47b: 0x2d63, + 0x47c: 0xa000, 0x47d: 0x2d6b, 0x47e: 0xa000, 0x47f: 0xa000, + // Block 0x12, offset 0x480 + 0x480: 0x0069, 0x481: 0x006b, 0x482: 0x006f, 0x483: 0x0083, 0x484: 0x00f5, 0x485: 0x00f8, + 0x486: 0x0416, 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: 0x041a, 0x495: 0x041e, 0x496: 0x00a1, 0x497: 0x00a9, + 0x498: 0x00ab, 0x499: 0x0426, 0x49a: 0x012b, 0x49b: 0x00ad, 0x49c: 0x042a, 0x49d: 0x01c1, + 0x49e: 0x01c4, 0x49f: 0x01c7, 0x4a0: 0x01fd, 0x4a1: 0x0200, 0x4a2: 0x0093, 0x4a3: 0x00a5, + 0x4a4: 0x00ab, 0x4a5: 0x00ad, 0x4a6: 0x01c1, 0x4a7: 0x01c4, 0x4a8: 0x01ee, 0x4a9: 0x01fd, + 0x4aa: 0x0200, + 0x4b8: 0x020f, + // 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: 0x042e, 0x4e8: 0x016d, 0x4e9: 0x0128, + 0x4ea: 0x0432, 0x4eb: 0x0170, 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: 0x0422, 0x4f9: 0x0158, 0x4fa: 0x015b, 0x4fb: 0x00b5, + 0x4fc: 0x0161, 0x4fd: 0x0164, 0x4fe: 0x0167, 0x4ff: 0x01d3, + // Block 0x14, offset 0x500 + 0x500: 0x8133, 0x501: 0x8133, 0x502: 0x812e, 0x503: 0x8133, 0x504: 0x8133, 0x505: 0x8133, + 0x506: 0x8133, 0x507: 0x8133, 0x508: 0x8133, 0x509: 0x8133, 0x50a: 0x812e, 0x50b: 0x8133, + 0x50c: 0x8133, 0x50d: 0x8136, 0x50e: 0x812b, 0x50f: 0x812e, 0x510: 0x812a, 0x511: 0x8133, + 0x512: 0x8133, 0x513: 0x8133, 0x514: 0x8133, 0x515: 0x8133, 0x516: 0x8133, 0x517: 0x8133, + 0x518: 0x8133, 0x519: 0x8133, 0x51a: 0x8133, 0x51b: 0x8133, 0x51c: 0x8133, 0x51d: 0x8133, + 0x51e: 0x8133, 0x51f: 0x8133, 0x520: 0x8133, 0x521: 0x8133, 0x522: 0x8133, 0x523: 0x8133, + 0x524: 0x8133, 0x525: 0x8133, 0x526: 0x8133, 0x527: 0x8133, 0x528: 0x8133, 0x529: 0x8133, + 0x52a: 0x8133, 0x52b: 0x8133, 0x52c: 0x8133, 0x52d: 0x8133, 0x52e: 0x8133, 0x52f: 0x8133, + 0x530: 0x8133, 0x531: 0x8133, 0x532: 0x8133, 0x533: 0x8133, 0x534: 0x8133, 0x535: 0x8133, + 0x536: 0x8134, 0x537: 0x8132, 0x538: 0x8132, 0x539: 0x812e, 0x53b: 0x8133, + 0x53c: 0x8135, 0x53d: 0x812e, 0x53e: 0x8133, 0x53f: 0x812e, + // Block 0x15, offset 0x540 + 0x540: 0x2fae, 0x541: 0x32ba, 0x542: 0x2fb8, 0x543: 0x32c4, 0x544: 0x2fbd, 0x545: 0x32c9, + 0x546: 0x2fc2, 0x547: 0x32ce, 0x548: 0x38e3, 0x549: 0x3a72, 0x54a: 0x2fdb, 0x54b: 0x32e7, + 0x54c: 0x2fe5, 0x54d: 0x32f1, 0x54e: 0x2ff4, 0x54f: 0x3300, 0x550: 0x2fea, 0x551: 0x32f6, + 0x552: 0x2fef, 0x553: 0x32fb, 0x554: 0x3906, 0x555: 0x3a95, 0x556: 0x390d, 0x557: 0x3a9c, + 0x558: 0x3030, 0x559: 0x333c, 0x55a: 0x3035, 0x55b: 0x3341, 0x55c: 0x391b, 0x55d: 0x3aaa, + 0x55e: 0x303a, 0x55f: 0x3346, 0x560: 0x3049, 0x561: 0x3355, 0x562: 0x3067, 0x563: 0x3373, + 0x564: 0x3076, 0x565: 0x3382, 0x566: 0x306c, 0x567: 0x3378, 0x568: 0x307b, 0x569: 0x3387, + 0x56a: 0x3080, 0x56b: 0x338c, 0x56c: 0x30c6, 0x56d: 0x33d2, 0x56e: 0x3922, 0x56f: 0x3ab1, + 0x570: 0x30d0, 0x571: 0x33e1, 0x572: 0x30da, 0x573: 0x33eb, 0x574: 0x30e4, 0x575: 0x33f5, + 0x576: 0x46db, 0x577: 0x476c, 0x578: 0x3929, 0x579: 0x3ab8, 0x57a: 0x30fd, 0x57b: 0x340e, + 0x57c: 0x30f8, 0x57d: 0x3409, 0x57e: 0x3102, 0x57f: 0x3413, + // Block 0x16, offset 0x580 + 0x580: 0x3107, 0x581: 0x3418, 0x582: 0x310c, 0x583: 0x341d, 0x584: 0x3120, 0x585: 0x3431, + 0x586: 0x312a, 0x587: 0x343b, 0x588: 0x3139, 0x589: 0x344a, 0x58a: 0x3134, 0x58b: 0x3445, + 0x58c: 0x394c, 0x58d: 0x3adb, 0x58e: 0x395a, 0x58f: 0x3ae9, 0x590: 0x3961, 0x591: 0x3af0, + 0x592: 0x3968, 0x593: 0x3af7, 0x594: 0x3166, 0x595: 0x3477, 0x596: 0x316b, 0x597: 0x347c, + 0x598: 0x3175, 0x599: 0x3486, 0x59a: 0x4708, 0x59b: 0x4799, 0x59c: 0x39ae, 0x59d: 0x3b3d, + 0x59e: 0x318e, 0x59f: 0x349f, 0x5a0: 0x3198, 0x5a1: 0x34a9, 0x5a2: 0x4717, 0x5a3: 0x47a8, + 0x5a4: 0x39b5, 0x5a5: 0x3b44, 0x5a6: 0x39bc, 0x5a7: 0x3b4b, 0x5a8: 0x39c3, 0x5a9: 0x3b52, + 0x5aa: 0x31a7, 0x5ab: 0x34b8, 0x5ac: 0x31b1, 0x5ad: 0x34c7, 0x5ae: 0x31c5, 0x5af: 0x34db, + 0x5b0: 0x31c0, 0x5b1: 0x34d6, 0x5b2: 0x3201, 0x5b3: 0x3517, 0x5b4: 0x3210, 0x5b5: 0x3526, + 0x5b6: 0x320b, 0x5b7: 0x3521, 0x5b8: 0x39ca, 0x5b9: 0x3b59, 0x5ba: 0x39d1, 0x5bb: 0x3b60, + 0x5bc: 0x3215, 0x5bd: 0x352b, 0x5be: 0x321a, 0x5bf: 0x3530, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x321f, 0x5c1: 0x3535, 0x5c2: 0x3224, 0x5c3: 0x353a, 0x5c4: 0x3233, 0x5c5: 0x3549, + 0x5c6: 0x322e, 0x5c7: 0x3544, 0x5c8: 0x3238, 0x5c9: 0x3553, 0x5ca: 0x323d, 0x5cb: 0x3558, + 0x5cc: 0x3242, 0x5cd: 0x355d, 0x5ce: 0x3260, 0x5cf: 0x357b, 0x5d0: 0x3279, 0x5d1: 0x3599, + 0x5d2: 0x3288, 0x5d3: 0x35a8, 0x5d4: 0x328d, 0x5d5: 0x35ad, 0x5d6: 0x3391, 0x5d7: 0x34bd, + 0x5d8: 0x354e, 0x5d9: 0x358a, 0x5da: 0x1be6, 0x5db: 0x42ee, + 0x5e0: 0x46b8, 0x5e1: 0x4749, 0x5e2: 0x2f9a, 0x5e3: 0x32a6, + 0x5e4: 0x388f, 0x5e5: 0x3a1e, 0x5e6: 0x3888, 0x5e7: 0x3a17, 0x5e8: 0x389d, 0x5e9: 0x3a2c, + 0x5ea: 0x3896, 0x5eb: 0x3a25, 0x5ec: 0x38d5, 0x5ed: 0x3a64, 0x5ee: 0x38ab, 0x5ef: 0x3a3a, + 0x5f0: 0x38a4, 0x5f1: 0x3a33, 0x5f2: 0x38b9, 0x5f3: 0x3a48, 0x5f4: 0x38b2, 0x5f5: 0x3a41, + 0x5f6: 0x38dc, 0x5f7: 0x3a6b, 0x5f8: 0x46cc, 0x5f9: 0x475d, 0x5fa: 0x3017, 0x5fb: 0x3323, + 0x5fc: 0x3003, 0x5fd: 0x330f, 0x5fe: 0x38f1, 0x5ff: 0x3a80, + // Block 0x18, offset 0x600 + 0x600: 0x38ea, 0x601: 0x3a79, 0x602: 0x38ff, 0x603: 0x3a8e, 0x604: 0x38f8, 0x605: 0x3a87, + 0x606: 0x3914, 0x607: 0x3aa3, 0x608: 0x30a8, 0x609: 0x33b4, 0x60a: 0x30bc, 0x60b: 0x33c8, + 0x60c: 0x46fe, 0x60d: 0x478f, 0x60e: 0x314d, 0x60f: 0x345e, 0x610: 0x3937, 0x611: 0x3ac6, + 0x612: 0x3930, 0x613: 0x3abf, 0x614: 0x3945, 0x615: 0x3ad4, 0x616: 0x393e, 0x617: 0x3acd, + 0x618: 0x39a0, 0x619: 0x3b2f, 0x61a: 0x3984, 0x61b: 0x3b13, 0x61c: 0x397d, 0x61d: 0x3b0c, + 0x61e: 0x3992, 0x61f: 0x3b21, 0x620: 0x398b, 0x621: 0x3b1a, 0x622: 0x3999, 0x623: 0x3b28, + 0x624: 0x31fc, 0x625: 0x3512, 0x626: 0x31de, 0x627: 0x34f4, 0x628: 0x39fb, 0x629: 0x3b8a, + 0x62a: 0x39f4, 0x62b: 0x3b83, 0x62c: 0x3a09, 0x62d: 0x3b98, 0x62e: 0x3a02, 0x62f: 0x3b91, + 0x630: 0x3a10, 0x631: 0x3b9f, 0x632: 0x3247, 0x633: 0x3562, 0x634: 0x326f, 0x635: 0x358f, + 0x636: 0x326a, 0x637: 0x3585, 0x638: 0x3256, 0x639: 0x3571, + // Block 0x19, offset 0x640 + 0x640: 0x481b, 0x641: 0x4821, 0x642: 0x4935, 0x643: 0x494d, 0x644: 0x493d, 0x645: 0x4955, + 0x646: 0x4945, 0x647: 0x495d, 0x648: 0x47c1, 0x649: 0x47c7, 0x64a: 0x48a5, 0x64b: 0x48bd, + 0x64c: 0x48ad, 0x64d: 0x48c5, 0x64e: 0x48b5, 0x64f: 0x48cd, 0x650: 0x482d, 0x651: 0x4833, + 0x652: 0x3dcf, 0x653: 0x3ddf, 0x654: 0x3dd7, 0x655: 0x3de7, + 0x658: 0x47cd, 0x659: 0x47d3, 0x65a: 0x3cff, 0x65b: 0x3d0f, 0x65c: 0x3d07, 0x65d: 0x3d17, + 0x660: 0x4845, 0x661: 0x484b, 0x662: 0x4965, 0x663: 0x497d, + 0x664: 0x496d, 0x665: 0x4985, 0x666: 0x4975, 0x667: 0x498d, 0x668: 0x47d9, 0x669: 0x47df, + 0x66a: 0x48d5, 0x66b: 0x48ed, 0x66c: 0x48dd, 0x66d: 0x48f5, 0x66e: 0x48e5, 0x66f: 0x48fd, + 0x670: 0x485d, 0x671: 0x4863, 0x672: 0x3e2f, 0x673: 0x3e47, 0x674: 0x3e37, 0x675: 0x3e4f, + 0x676: 0x3e3f, 0x677: 0x3e57, 0x678: 0x47e5, 0x679: 0x47eb, 0x67a: 0x3d2f, 0x67b: 0x3d47, + 0x67c: 0x3d37, 0x67d: 0x3d4f, 0x67e: 0x3d3f, 0x67f: 0x3d57, + // Block 0x1a, offset 0x680 + 0x680: 0x4869, 0x681: 0x486f, 0x682: 0x3e5f, 0x683: 0x3e6f, 0x684: 0x3e67, 0x685: 0x3e77, + 0x688: 0x47f1, 0x689: 0x47f7, 0x68a: 0x3d5f, 0x68b: 0x3d6f, + 0x68c: 0x3d67, 0x68d: 0x3d77, 0x690: 0x487b, 0x691: 0x4881, + 0x692: 0x3e97, 0x693: 0x3eaf, 0x694: 0x3e9f, 0x695: 0x3eb7, 0x696: 0x3ea7, 0x697: 0x3ebf, + 0x699: 0x47fd, 0x69b: 0x3d7f, 0x69d: 0x3d87, + 0x69f: 0x3d8f, 0x6a0: 0x4893, 0x6a1: 0x4899, 0x6a2: 0x4995, 0x6a3: 0x49ad, + 0x6a4: 0x499d, 0x6a5: 0x49b5, 0x6a6: 0x49a5, 0x6a7: 0x49bd, 0x6a8: 0x4803, 0x6a9: 0x4809, + 0x6aa: 0x4905, 0x6ab: 0x491d, 0x6ac: 0x490d, 0x6ad: 0x4925, 0x6ae: 0x4915, 0x6af: 0x492d, + 0x6b0: 0x480f, 0x6b1: 0x4335, 0x6b2: 0x36a8, 0x6b3: 0x433b, 0x6b4: 0x4839, 0x6b5: 0x4341, + 0x6b6: 0x36ba, 0x6b7: 0x4347, 0x6b8: 0x36d8, 0x6b9: 0x434d, 0x6ba: 0x36f0, 0x6bb: 0x4353, + 0x6bc: 0x4887, 0x6bd: 0x4359, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x3db7, 0x6c1: 0x3dbf, 0x6c2: 0x419b, 0x6c3: 0x41b9, 0x6c4: 0x41a5, 0x6c5: 0x41c3, + 0x6c6: 0x41af, 0x6c7: 0x41cd, 0x6c8: 0x3cef, 0x6c9: 0x3cf7, 0x6ca: 0x40e7, 0x6cb: 0x4105, + 0x6cc: 0x40f1, 0x6cd: 0x410f, 0x6ce: 0x40fb, 0x6cf: 0x4119, 0x6d0: 0x3dff, 0x6d1: 0x3e07, + 0x6d2: 0x41d7, 0x6d3: 0x41f5, 0x6d4: 0x41e1, 0x6d5: 0x41ff, 0x6d6: 0x41eb, 0x6d7: 0x4209, + 0x6d8: 0x3d1f, 0x6d9: 0x3d27, 0x6da: 0x4123, 0x6db: 0x4141, 0x6dc: 0x412d, 0x6dd: 0x414b, + 0x6de: 0x4137, 0x6df: 0x4155, 0x6e0: 0x3ed7, 0x6e1: 0x3edf, 0x6e2: 0x4213, 0x6e3: 0x4231, + 0x6e4: 0x421d, 0x6e5: 0x423b, 0x6e6: 0x4227, 0x6e7: 0x4245, 0x6e8: 0x3d97, 0x6e9: 0x3d9f, + 0x6ea: 0x415f, 0x6eb: 0x417d, 0x6ec: 0x4169, 0x6ed: 0x4187, 0x6ee: 0x4173, 0x6ef: 0x4191, + 0x6f0: 0x369c, 0x6f1: 0x3696, 0x6f2: 0x3da7, 0x6f3: 0x36a2, 0x6f4: 0x3daf, + 0x6f6: 0x4827, 0x6f7: 0x3dc7, 0x6f8: 0x360c, 0x6f9: 0x3606, 0x6fa: 0x35fa, 0x6fb: 0x4305, + 0x6fc: 0x3612, 0x6fd: 0x429e, 0x6fe: 0x01d6, 0x6ff: 0x429e, + // Block 0x1c, offset 0x700 + 0x700: 0x42b7, 0x701: 0x4499, 0x702: 0x3def, 0x703: 0x36b4, 0x704: 0x3df7, + 0x706: 0x4851, 0x707: 0x3e0f, 0x708: 0x3618, 0x709: 0x430b, 0x70a: 0x3624, 0x70b: 0x4311, + 0x70c: 0x3630, 0x70d: 0x44a0, 0x70e: 0x44a7, 0x70f: 0x44ae, 0x710: 0x36cc, 0x711: 0x36c6, + 0x712: 0x3e17, 0x713: 0x44fb, 0x716: 0x36d2, 0x717: 0x3e27, + 0x718: 0x3648, 0x719: 0x3642, 0x71a: 0x3636, 0x71b: 0x4317, 0x71d: 0x44b5, + 0x71e: 0x44bc, 0x71f: 0x44c3, 0x720: 0x3702, 0x721: 0x36fc, 0x722: 0x3e7f, 0x723: 0x4503, + 0x724: 0x36e4, 0x725: 0x36ea, 0x726: 0x3708, 0x727: 0x3e8f, 0x728: 0x3678, 0x729: 0x3672, + 0x72a: 0x3666, 0x72b: 0x4323, 0x72c: 0x3660, 0x72d: 0x448b, 0x72e: 0x4492, 0x72f: 0x0081, + 0x732: 0x3ec7, 0x733: 0x370e, 0x734: 0x3ecf, + 0x736: 0x489f, 0x737: 0x3ee7, 0x738: 0x3654, 0x739: 0x431d, 0x73a: 0x3684, 0x73b: 0x432f, + 0x73c: 0x3690, 0x73d: 0x4271, 0x73e: 0x42a3, + // Block 0x1d, offset 0x740 + 0x740: 0x1bde, 0x741: 0x1be2, 0x742: 0x0047, 0x743: 0x1c5a, 0x745: 0x1bee, + 0x746: 0x1bf2, 0x747: 0x00e9, 0x749: 0x1c5e, 0x74a: 0x008f, 0x74b: 0x0051, + 0x74c: 0x0051, 0x74d: 0x0051, 0x74e: 0x0091, 0x74f: 0x00da, 0x750: 0x0053, 0x751: 0x0053, + 0x752: 0x0059, 0x753: 0x0099, 0x755: 0x005d, 0x756: 0x1993, + 0x759: 0x0061, 0x75a: 0x0063, 0x75b: 0x0065, 0x75c: 0x0065, 0x75d: 0x0065, + 0x760: 0x19a5, 0x761: 0x1bce, 0x762: 0x19ae, + 0x764: 0x0075, 0x766: 0x01bb, 0x768: 0x0075, + 0x76a: 0x0057, 0x76b: 0x42e9, 0x76c: 0x0045, 0x76d: 0x0047, 0x76f: 0x008b, + 0x770: 0x004b, 0x771: 0x004d, 0x773: 0x005b, 0x774: 0x009f, 0x775: 0x0218, + 0x776: 0x021b, 0x777: 0x021e, 0x778: 0x0221, 0x779: 0x0093, 0x77b: 0x1b9e, + 0x77c: 0x01eb, 0x77d: 0x01c4, 0x77e: 0x017c, 0x77f: 0x01a3, + // Block 0x1e, offset 0x780 + 0x780: 0x0466, 0x785: 0x0049, + 0x786: 0x0089, 0x787: 0x008b, 0x788: 0x0093, 0x789: 0x0095, + 0x790: 0x2234, 0x791: 0x2240, + 0x792: 0x22f4, 0x793: 0x221c, 0x794: 0x22a0, 0x795: 0x2228, 0x796: 0x22a6, 0x797: 0x22be, + 0x798: 0x22ca, 0x799: 0x222e, 0x79a: 0x22d0, 0x79b: 0x223a, 0x79c: 0x22c4, 0x79d: 0x22d6, + 0x79e: 0x22dc, 0x79f: 0x1cc2, 0x7a0: 0x0053, 0x7a1: 0x195d, 0x7a2: 0x1baa, 0x7a3: 0x1966, + 0x7a4: 0x006d, 0x7a5: 0x19b1, 0x7a6: 0x1bd6, 0x7a7: 0x1d4e, 0x7a8: 0x1969, 0x7a9: 0x0071, + 0x7aa: 0x19bd, 0x7ab: 0x1bda, 0x7ac: 0x0059, 0x7ad: 0x0047, 0x7ae: 0x0049, 0x7af: 0x005b, + 0x7b0: 0x0093, 0x7b1: 0x19ea, 0x7b2: 0x1c1e, 0x7b3: 0x19f3, 0x7b4: 0x00ad, 0x7b5: 0x1a68, + 0x7b6: 0x1c52, 0x7b7: 0x1d62, 0x7b8: 0x19f6, 0x7b9: 0x00b1, 0x7ba: 0x1a6b, 0x7bb: 0x1c56, + 0x7bc: 0x0099, 0x7bd: 0x0087, 0x7be: 0x0089, 0x7bf: 0x009b, + // Block 0x1f, offset 0x7c0 + 0x7c1: 0x3c1d, 0x7c3: 0xa000, 0x7c4: 0x3c24, 0x7c5: 0xa000, + 0x7c7: 0x3c2b, 0x7c8: 0xa000, 0x7c9: 0x3c32, + 0x7cd: 0xa000, + 0x7e0: 0x2f7c, 0x7e1: 0xa000, 0x7e2: 0x3c40, + 0x7e4: 0xa000, 0x7e5: 0xa000, + 0x7ed: 0x3c39, 0x7ee: 0x2f77, 0x7ef: 0x2f81, + 0x7f0: 0x3c47, 0x7f1: 0x3c4e, 0x7f2: 0xa000, 0x7f3: 0xa000, 0x7f4: 0x3c55, 0x7f5: 0x3c5c, + 0x7f6: 0xa000, 0x7f7: 0xa000, 0x7f8: 0x3c63, 0x7f9: 0x3c6a, 0x7fa: 0xa000, 0x7fb: 0xa000, + 0x7fc: 0xa000, 0x7fd: 0xa000, + // Block 0x20, offset 0x800 + 0x800: 0x3c71, 0x801: 0x3c78, 0x802: 0xa000, 0x803: 0xa000, 0x804: 0x3c8d, 0x805: 0x3c94, + 0x806: 0xa000, 0x807: 0xa000, 0x808: 0x3c9b, 0x809: 0x3ca2, + 0x811: 0xa000, + 0x812: 0xa000, + 0x822: 0xa000, + 0x828: 0xa000, 0x829: 0xa000, + 0x82b: 0xa000, 0x82c: 0x3cb7, 0x82d: 0x3cbe, 0x82e: 0x3cc5, 0x82f: 0x3ccc, + 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: 0x1885, + 0x86a: 0x1888, 0x86b: 0x188b, 0x86c: 0x188e, 0x86d: 0x1891, 0x86e: 0x1894, 0x86f: 0x1897, + 0x870: 0x189a, 0x871: 0x189d, 0x872: 0x18a0, 0x873: 0x18a9, 0x874: 0x1a6e, 0x875: 0x1a72, + 0x876: 0x1a76, 0x877: 0x1a7a, 0x878: 0x1a7e, 0x879: 0x1a82, 0x87a: 0x1a86, 0x87b: 0x1a8a, + 0x87c: 0x1a8e, 0x87d: 0x1c86, 0x87e: 0x1c8b, 0x87f: 0x1c90, + // Block 0x22, offset 0x880 + 0x880: 0x1c95, 0x881: 0x1c9a, 0x882: 0x1c9f, 0x883: 0x1ca4, 0x884: 0x1ca9, 0x885: 0x1cae, + 0x886: 0x1cb3, 0x887: 0x1cb8, 0x888: 0x1882, 0x889: 0x18a6, 0x88a: 0x18ca, 0x88b: 0x18ee, + 0x88c: 0x1912, 0x88d: 0x191b, 0x88e: 0x1921, 0x88f: 0x1927, 0x890: 0x192d, 0x891: 0x1b66, + 0x892: 0x1b6a, 0x893: 0x1b6e, 0x894: 0x1b72, 0x895: 0x1b76, 0x896: 0x1b7a, 0x897: 0x1b7e, + 0x898: 0x1b82, 0x899: 0x1b86, 0x89a: 0x1b8a, 0x89b: 0x1b8e, 0x89c: 0x1afa, 0x89d: 0x1afe, + 0x89e: 0x1b02, 0x89f: 0x1b06, 0x8a0: 0x1b0a, 0x8a1: 0x1b0e, 0x8a2: 0x1b12, 0x8a3: 0x1b16, + 0x8a4: 0x1b1a, 0x8a5: 0x1b1e, 0x8a6: 0x1b22, 0x8a7: 0x1b26, 0x8a8: 0x1b2a, 0x8a9: 0x1b2e, + 0x8aa: 0x1b32, 0x8ab: 0x1b36, 0x8ac: 0x1b3a, 0x8ad: 0x1b3e, 0x8ae: 0x1b42, 0x8af: 0x1b46, + 0x8b0: 0x1b4a, 0x8b1: 0x1b4e, 0x8b2: 0x1b52, 0x8b3: 0x1b56, 0x8b4: 0x1b5a, 0x8b5: 0x1b5e, + 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: 0x06c2, 0x8c1: 0x06e6, 0x8c2: 0x06f2, 0x8c3: 0x0702, 0x8c4: 0x070a, 0x8c5: 0x0716, + 0x8c6: 0x071e, 0x8c7: 0x0726, 0x8c8: 0x0732, 0x8c9: 0x0786, 0x8ca: 0x079e, 0x8cb: 0x07ae, + 0x8cc: 0x07be, 0x8cd: 0x07ce, 0x8ce: 0x07de, 0x8cf: 0x07fe, 0x8d0: 0x0802, 0x8d1: 0x0806, + 0x8d2: 0x083a, 0x8d3: 0x0862, 0x8d4: 0x0872, 0x8d5: 0x087a, 0x8d6: 0x087e, 0x8d7: 0x088a, + 0x8d8: 0x08a6, 0x8d9: 0x08aa, 0x8da: 0x08c2, 0x8db: 0x08c6, 0x8dc: 0x08ce, 0x8dd: 0x08de, + 0x8de: 0x097a, 0x8df: 0x098e, 0x8e0: 0x09ce, 0x8e1: 0x09e2, 0x8e2: 0x09ea, 0x8e3: 0x09ee, + 0x8e4: 0x09fe, 0x8e5: 0x0a1a, 0x8e6: 0x0a46, 0x8e7: 0x0a52, 0x8e8: 0x0a72, 0x8e9: 0x0a7e, + 0x8ea: 0x0a82, 0x8eb: 0x0a86, 0x8ec: 0x0a9e, 0x8ed: 0x0aa2, 0x8ee: 0x0ace, 0x8ef: 0x0ada, + 0x8f0: 0x0ae2, 0x8f1: 0x0aea, 0x8f2: 0x0afa, 0x8f3: 0x0b02, 0x8f4: 0x0b0a, 0x8f5: 0x0b36, + 0x8f6: 0x0b3a, 0x8f7: 0x0b42, 0x8f8: 0x0b46, 0x8f9: 0x0b4e, 0x8fa: 0x0b56, 0x8fb: 0x0b66, + 0x8fc: 0x0b82, 0x8fd: 0x0bfa, 0x8fe: 0x0c0e, 0x8ff: 0x0c12, + // Block 0x24, offset 0x900 + 0x900: 0x0c92, 0x901: 0x0c96, 0x902: 0x0caa, 0x903: 0x0cae, 0x904: 0x0cb6, 0x905: 0x0cbe, + 0x906: 0x0cc6, 0x907: 0x0cd2, 0x908: 0x0cfa, 0x909: 0x0d0a, 0x90a: 0x0d1e, 0x90b: 0x0d8e, + 0x90c: 0x0d9a, 0x90d: 0x0daa, 0x90e: 0x0db6, 0x90f: 0x0dc2, 0x910: 0x0dca, 0x911: 0x0dce, + 0x912: 0x0dd2, 0x913: 0x0dd6, 0x914: 0x0dda, 0x915: 0x0e92, 0x916: 0x0eda, 0x917: 0x0ee6, + 0x918: 0x0eea, 0x919: 0x0eee, 0x91a: 0x0ef2, 0x91b: 0x0efa, 0x91c: 0x0efe, 0x91d: 0x0f12, + 0x91e: 0x0f2e, 0x91f: 0x0f36, 0x920: 0x0f76, 0x921: 0x0f7a, 0x922: 0x0f82, 0x923: 0x0f86, + 0x924: 0x0f8e, 0x925: 0x0f92, 0x926: 0x0fb6, 0x927: 0x0fba, 0x928: 0x0fd6, 0x929: 0x0fda, + 0x92a: 0x0fde, 0x92b: 0x0fe2, 0x92c: 0x0ff6, 0x92d: 0x101a, 0x92e: 0x101e, 0x92f: 0x1022, + 0x930: 0x1046, 0x931: 0x1086, 0x932: 0x108a, 0x933: 0x10aa, 0x934: 0x10ba, 0x935: 0x10c2, + 0x936: 0x10e2, 0x937: 0x1106, 0x938: 0x114a, 0x939: 0x1152, 0x93a: 0x1166, 0x93b: 0x1172, + 0x93c: 0x117a, 0x93d: 0x1182, 0x93e: 0x1186, 0x93f: 0x118a, + // Block 0x25, offset 0x940 + 0x940: 0x11a2, 0x941: 0x11a6, 0x942: 0x11c2, 0x943: 0x11ca, 0x944: 0x11d2, 0x945: 0x11d6, + 0x946: 0x11e2, 0x947: 0x11ea, 0x948: 0x11ee, 0x949: 0x11f2, 0x94a: 0x11fa, 0x94b: 0x11fe, + 0x94c: 0x129e, 0x94d: 0x12b2, 0x94e: 0x12e6, 0x94f: 0x12ea, 0x950: 0x12f2, 0x951: 0x131e, + 0x952: 0x1326, 0x953: 0x132e, 0x954: 0x1336, 0x955: 0x1372, 0x956: 0x1376, 0x957: 0x137e, + 0x958: 0x1382, 0x959: 0x1386, 0x95a: 0x13b2, 0x95b: 0x13b6, 0x95c: 0x13be, 0x95d: 0x13d2, + 0x95e: 0x13d6, 0x95f: 0x13f2, 0x960: 0x13fa, 0x961: 0x13fe, 0x962: 0x1422, 0x963: 0x1442, + 0x964: 0x1456, 0x965: 0x145a, 0x966: 0x1462, 0x967: 0x148e, 0x968: 0x1492, 0x969: 0x14a2, + 0x96a: 0x14c6, 0x96b: 0x14d2, 0x96c: 0x14e2, 0x96d: 0x14fa, 0x96e: 0x1502, 0x96f: 0x1506, + 0x970: 0x150a, 0x971: 0x150e, 0x972: 0x151a, 0x973: 0x151e, 0x974: 0x1526, 0x975: 0x1542, + 0x976: 0x1546, 0x977: 0x154a, 0x978: 0x1562, 0x979: 0x1566, 0x97a: 0x156e, 0x97b: 0x1582, + 0x97c: 0x1586, 0x97d: 0x158a, 0x97e: 0x1592, 0x97f: 0x1596, + // Block 0x26, offset 0x980 + 0x986: 0xa000, 0x98b: 0xa000, + 0x98c: 0x3f1f, 0x98d: 0xa000, 0x98e: 0x3f27, 0x98f: 0xa000, 0x990: 0x3f2f, 0x991: 0xa000, + 0x992: 0x3f37, 0x993: 0xa000, 0x994: 0x3f3f, 0x995: 0xa000, 0x996: 0x3f47, 0x997: 0xa000, + 0x998: 0x3f4f, 0x999: 0xa000, 0x99a: 0x3f57, 0x99b: 0xa000, 0x99c: 0x3f5f, 0x99d: 0xa000, + 0x99e: 0x3f67, 0x99f: 0xa000, 0x9a0: 0x3f6f, 0x9a1: 0xa000, 0x9a2: 0x3f77, + 0x9a4: 0xa000, 0x9a5: 0x3f7f, 0x9a6: 0xa000, 0x9a7: 0x3f87, 0x9a8: 0xa000, 0x9a9: 0x3f8f, + 0x9af: 0xa000, + 0x9b0: 0x3f97, 0x9b1: 0x3f9f, 0x9b2: 0xa000, 0x9b3: 0x3fa7, 0x9b4: 0x3faf, 0x9b5: 0xa000, + 0x9b6: 0x3fb7, 0x9b7: 0x3fbf, 0x9b8: 0xa000, 0x9b9: 0x3fc7, 0x9ba: 0x3fcf, 0x9bb: 0xa000, + 0x9bc: 0x3fd7, 0x9bd: 0x3fdf, + // Block 0x27, offset 0x9c0 + 0x9d4: 0x3f17, + 0x9d9: 0x9904, 0x9da: 0x9904, 0x9db: 0x42f3, 0x9dc: 0x42f9, 0x9dd: 0xa000, + 0x9de: 0x3fe7, 0x9df: 0x26ba, + 0x9e6: 0xa000, + 0x9eb: 0xa000, 0x9ec: 0x3ff7, 0x9ed: 0xa000, 0x9ee: 0x3fff, 0x9ef: 0xa000, + 0x9f0: 0x4007, 0x9f1: 0xa000, 0x9f2: 0x400f, 0x9f3: 0xa000, 0x9f4: 0x4017, 0x9f5: 0xa000, + 0x9f6: 0x401f, 0x9f7: 0xa000, 0x9f8: 0x4027, 0x9f9: 0xa000, 0x9fa: 0x402f, 0x9fb: 0xa000, + 0x9fc: 0x4037, 0x9fd: 0xa000, 0x9fe: 0x403f, 0x9ff: 0xa000, + // Block 0x28, offset 0xa00 + 0xa00: 0x4047, 0xa01: 0xa000, 0xa02: 0x404f, 0xa04: 0xa000, 0xa05: 0x4057, + 0xa06: 0xa000, 0xa07: 0x405f, 0xa08: 0xa000, 0xa09: 0x4067, + 0xa0f: 0xa000, 0xa10: 0x406f, 0xa11: 0x4077, + 0xa12: 0xa000, 0xa13: 0x407f, 0xa14: 0x4087, 0xa15: 0xa000, 0xa16: 0x408f, 0xa17: 0x4097, + 0xa18: 0xa000, 0xa19: 0x409f, 0xa1a: 0x40a7, 0xa1b: 0xa000, 0xa1c: 0x40af, 0xa1d: 0x40b7, + 0xa2f: 0xa000, + 0xa30: 0xa000, 0xa31: 0xa000, 0xa32: 0xa000, 0xa34: 0x3fef, + 0xa37: 0x40bf, 0xa38: 0x40c7, 0xa39: 0x40cf, 0xa3a: 0x40d7, + 0xa3d: 0xa000, 0xa3e: 0x40df, 0xa3f: 0x26cf, + // Block 0x29, offset 0xa40 + 0xa40: 0x036a, 0xa41: 0x032e, 0xa42: 0x0332, 0xa43: 0x0336, 0xa44: 0x037e, 0xa45: 0x033a, + 0xa46: 0x033e, 0xa47: 0x0342, 0xa48: 0x0346, 0xa49: 0x034a, 0xa4a: 0x034e, 0xa4b: 0x0352, + 0xa4c: 0x0356, 0xa4d: 0x035a, 0xa4e: 0x035e, 0xa4f: 0x49d4, 0xa50: 0x49da, 0xa51: 0x49e0, + 0xa52: 0x49e6, 0xa53: 0x49ec, 0xa54: 0x49f2, 0xa55: 0x49f8, 0xa56: 0x49fe, 0xa57: 0x4a04, + 0xa58: 0x4a0a, 0xa59: 0x4a10, 0xa5a: 0x4a16, 0xa5b: 0x4a1c, 0xa5c: 0x4a22, 0xa5d: 0x4a28, + 0xa5e: 0x4a2e, 0xa5f: 0x4a34, 0xa60: 0x4a3a, 0xa61: 0x4a40, 0xa62: 0x4a46, 0xa63: 0x4a4c, + 0xa64: 0x03c6, 0xa65: 0x0362, 0xa66: 0x0366, 0xa67: 0x03ea, 0xa68: 0x03ee, 0xa69: 0x03f2, + 0xa6a: 0x03f6, 0xa6b: 0x03fa, 0xa6c: 0x03fe, 0xa6d: 0x0402, 0xa6e: 0x036e, 0xa6f: 0x0406, + 0xa70: 0x040a, 0xa71: 0x0372, 0xa72: 0x0376, 0xa73: 0x037a, 0xa74: 0x0382, 0xa75: 0x0386, + 0xa76: 0x038a, 0xa77: 0x038e, 0xa78: 0x0392, 0xa79: 0x0396, 0xa7a: 0x039a, 0xa7b: 0x039e, + 0xa7c: 0x03a2, 0xa7d: 0x03a6, 0xa7e: 0x03aa, 0xa7f: 0x03ae, + // Block 0x2a, offset 0xa80 + 0xa80: 0x03b2, 0xa81: 0x03b6, 0xa82: 0x040e, 0xa83: 0x0412, 0xa84: 0x03ba, 0xa85: 0x03be, + 0xa86: 0x03c2, 0xa87: 0x03ca, 0xa88: 0x03ce, 0xa89: 0x03d2, 0xa8a: 0x03d6, 0xa8b: 0x03da, + 0xa8c: 0x03de, 0xa8d: 0x03e2, 0xa8e: 0x03e6, + 0xa92: 0x06c2, 0xa93: 0x071e, 0xa94: 0x06ce, 0xa95: 0x097e, 0xa96: 0x06d2, 0xa97: 0x06ea, + 0xa98: 0x06d6, 0xa99: 0x0f96, 0xa9a: 0x070a, 0xa9b: 0x06de, 0xa9c: 0x06c6, 0xa9d: 0x0a02, + 0xa9e: 0x0992, 0xa9f: 0x0732, + // Block 0x2b, offset 0xac0 + 0xac0: 0x205a, 0xac1: 0x2060, 0xac2: 0x2066, 0xac3: 0x206c, 0xac4: 0x2072, 0xac5: 0x2078, + 0xac6: 0x207e, 0xac7: 0x2084, 0xac8: 0x208a, 0xac9: 0x2090, 0xaca: 0x2096, 0xacb: 0x209c, + 0xacc: 0x20a2, 0xacd: 0x20a8, 0xace: 0x2733, 0xacf: 0x273c, 0xad0: 0x2745, 0xad1: 0x274e, + 0xad2: 0x2757, 0xad3: 0x2760, 0xad4: 0x2769, 0xad5: 0x2772, 0xad6: 0x277b, 0xad7: 0x278d, + 0xad8: 0x2796, 0xad9: 0x279f, 0xada: 0x27a8, 0xadb: 0x27b1, 0xadc: 0x2784, 0xadd: 0x2bb9, + 0xade: 0x2afa, 0xae0: 0x20ae, 0xae1: 0x20c6, 0xae2: 0x20ba, 0xae3: 0x210e, + 0xae4: 0x20cc, 0xae5: 0x20ea, 0xae6: 0x20b4, 0xae7: 0x20e4, 0xae8: 0x20c0, 0xae9: 0x20f6, + 0xaea: 0x2126, 0xaeb: 0x2144, 0xaec: 0x213e, 0xaed: 0x2132, 0xaee: 0x2180, 0xaef: 0x2114, + 0xaf0: 0x2120, 0xaf1: 0x2138, 0xaf2: 0x212c, 0xaf3: 0x2156, 0xaf4: 0x2102, 0xaf5: 0x214a, + 0xaf6: 0x2174, 0xaf7: 0x215c, 0xaf8: 0x20f0, 0xaf9: 0x20d2, 0xafa: 0x2108, 0xafb: 0x211a, + 0xafc: 0x2150, 0xafd: 0x20d8, 0xafe: 0x217a, 0xaff: 0x20fc, + // Block 0x2c, offset 0xb00 + 0xb00: 0x2162, 0xb01: 0x20de, 0xb02: 0x2168, 0xb03: 0x216e, 0xb04: 0x0932, 0xb05: 0x0b06, + 0xb06: 0x0caa, 0xb07: 0x10ca, + 0xb10: 0x1bca, 0xb11: 0x18ac, + 0xb12: 0x18af, 0xb13: 0x18b2, 0xb14: 0x18b5, 0xb15: 0x18b8, 0xb16: 0x18bb, 0xb17: 0x18be, + 0xb18: 0x18c1, 0xb19: 0x18c4, 0xb1a: 0x18cd, 0xb1b: 0x18d0, 0xb1c: 0x18d3, 0xb1d: 0x18d6, + 0xb1e: 0x18d9, 0xb1f: 0x18dc, 0xb20: 0x0316, 0xb21: 0x031e, 0xb22: 0x0322, 0xb23: 0x032a, + 0xb24: 0x032e, 0xb25: 0x0332, 0xb26: 0x033a, 0xb27: 0x0342, 0xb28: 0x0346, 0xb29: 0x034e, + 0xb2a: 0x0352, 0xb2b: 0x0356, 0xb2c: 0x035a, 0xb2d: 0x035e, 0xb2e: 0x2e2f, 0xb2f: 0x2e37, + 0xb30: 0x2e3f, 0xb31: 0x2e47, 0xb32: 0x2e4f, 0xb33: 0x2e57, 0xb34: 0x2e5f, 0xb35: 0x2e67, + 0xb36: 0x2e77, 0xb37: 0x2e7f, 0xb38: 0x2e87, 0xb39: 0x2e8f, 0xb3a: 0x2e97, 0xb3b: 0x2e9f, + 0xb3c: 0x2eea, 0xb3d: 0x2eb2, 0xb3e: 0x2e6f, + // Block 0x2d, offset 0xb40 + 0xb40: 0x06c2, 0xb41: 0x071e, 0xb42: 0x06ce, 0xb43: 0x097e, 0xb44: 0x0722, 0xb45: 0x07b2, + 0xb46: 0x06ca, 0xb47: 0x07ae, 0xb48: 0x070e, 0xb49: 0x088a, 0xb4a: 0x0d0a, 0xb4b: 0x0e92, + 0xb4c: 0x0dda, 0xb4d: 0x0d1e, 0xb4e: 0x1462, 0xb4f: 0x098e, 0xb50: 0x0cd2, 0xb51: 0x0d4e, + 0xb52: 0x0d0e, 0xb53: 0x104e, 0xb54: 0x08fe, 0xb55: 0x0f06, 0xb56: 0x138a, 0xb57: 0x1062, + 0xb58: 0x0846, 0xb59: 0x1092, 0xb5a: 0x0f9e, 0xb5b: 0x0a1a, 0xb5c: 0x1412, 0xb5d: 0x0782, + 0xb5e: 0x08ae, 0xb5f: 0x0dfa, 0xb60: 0x152a, 0xb61: 0x0746, 0xb62: 0x07d6, 0xb63: 0x0d9e, + 0xb64: 0x06d2, 0xb65: 0x06ea, 0xb66: 0x06d6, 0xb67: 0x0ade, 0xb68: 0x08f2, 0xb69: 0x0882, + 0xb6a: 0x0a5a, 0xb6b: 0x0a4e, 0xb6c: 0x0fee, 0xb6d: 0x0742, 0xb6e: 0x139e, 0xb6f: 0x089e, + 0xb70: 0x09f6, 0xb71: 0x18df, 0xb72: 0x18e2, 0xb73: 0x18e5, 0xb74: 0x18e8, 0xb75: 0x18f1, + 0xb76: 0x18f4, 0xb77: 0x18f7, 0xb78: 0x18fa, 0xb79: 0x18fd, 0xb7a: 0x1900, 0xb7b: 0x1903, + 0xb7c: 0x1906, 0xb7d: 0x1909, 0xb7e: 0x190c, 0xb7f: 0x1915, + // Block 0x2e, offset 0xb80 + 0xb80: 0x1ccc, 0xb81: 0x1cdb, 0xb82: 0x1cea, 0xb83: 0x1cf9, 0xb84: 0x1d08, 0xb85: 0x1d17, + 0xb86: 0x1d26, 0xb87: 0x1d35, 0xb88: 0x1d44, 0xb89: 0x2192, 0xb8a: 0x21a4, 0xb8b: 0x21b6, + 0xb8c: 0x1957, 0xb8d: 0x1c0a, 0xb8e: 0x19d8, 0xb8f: 0x1bae, 0xb90: 0x04ce, 0xb91: 0x04d6, + 0xb92: 0x04de, 0xb93: 0x04e6, 0xb94: 0x04ee, 0xb95: 0x04f2, 0xb96: 0x04f6, 0xb97: 0x04fa, + 0xb98: 0x04fe, 0xb99: 0x0502, 0xb9a: 0x0506, 0xb9b: 0x050a, 0xb9c: 0x050e, 0xb9d: 0x0512, + 0xb9e: 0x0516, 0xb9f: 0x051a, 0xba0: 0x051e, 0xba1: 0x0526, 0xba2: 0x052a, 0xba3: 0x052e, + 0xba4: 0x0532, 0xba5: 0x0536, 0xba6: 0x053a, 0xba7: 0x053e, 0xba8: 0x0542, 0xba9: 0x0546, + 0xbaa: 0x054a, 0xbab: 0x054e, 0xbac: 0x0552, 0xbad: 0x0556, 0xbae: 0x055a, 0xbaf: 0x055e, + 0xbb0: 0x0562, 0xbb1: 0x0566, 0xbb2: 0x056a, 0xbb3: 0x0572, 0xbb4: 0x057a, 0xbb5: 0x0582, + 0xbb6: 0x0586, 0xbb7: 0x058a, 0xbb8: 0x058e, 0xbb9: 0x0592, 0xbba: 0x0596, 0xbbb: 0x059a, + 0xbbc: 0x059e, 0xbbd: 0x05a2, 0xbbe: 0x05a6, 0xbbf: 0x2700, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x2b19, 0xbc1: 0x29b5, 0xbc2: 0x2b29, 0xbc3: 0x288d, 0xbc4: 0x2efb, 0xbc5: 0x2897, + 0xbc6: 0x28a1, 0xbc7: 0x2f3f, 0xbc8: 0x29c2, 0xbc9: 0x28ab, 0xbca: 0x28b5, 0xbcb: 0x28bf, + 0xbcc: 0x29e9, 0xbcd: 0x29f6, 0xbce: 0x29cf, 0xbcf: 0x29dc, 0xbd0: 0x2ec0, 0xbd1: 0x2a03, + 0xbd2: 0x2a10, 0xbd3: 0x2bcb, 0xbd4: 0x26c1, 0xbd5: 0x2bde, 0xbd6: 0x2bf1, 0xbd7: 0x2b39, + 0xbd8: 0x2a1d, 0xbd9: 0x2c04, 0xbda: 0x2c17, 0xbdb: 0x2a2a, 0xbdc: 0x28c9, 0xbdd: 0x28d3, + 0xbde: 0x2ece, 0xbdf: 0x2a37, 0xbe0: 0x2b49, 0xbe1: 0x2f0c, 0xbe2: 0x28dd, 0xbe3: 0x28e7, + 0xbe4: 0x2a44, 0xbe5: 0x28f1, 0xbe6: 0x28fb, 0xbe7: 0x26d6, 0xbe8: 0x26dd, 0xbe9: 0x2905, + 0xbea: 0x290f, 0xbeb: 0x2c2a, 0xbec: 0x2a51, 0xbed: 0x2b59, 0xbee: 0x2c3d, 0xbef: 0x2a5e, + 0xbf0: 0x2923, 0xbf1: 0x2919, 0xbf2: 0x2f53, 0xbf3: 0x2a6b, 0xbf4: 0x2c50, 0xbf5: 0x292d, + 0xbf6: 0x2b69, 0xbf7: 0x2937, 0xbf8: 0x2a85, 0xbf9: 0x2941, 0xbfa: 0x2a92, 0xbfb: 0x2f1d, + 0xbfc: 0x2a78, 0xbfd: 0x2b79, 0xbfe: 0x2a9f, 0xbff: 0x26e4, + // Block 0x30, offset 0xc00 + 0xc00: 0x2f2e, 0xc01: 0x294b, 0xc02: 0x2955, 0xc03: 0x2aac, 0xc04: 0x295f, 0xc05: 0x2969, + 0xc06: 0x2973, 0xc07: 0x2b89, 0xc08: 0x2ab9, 0xc09: 0x26eb, 0xc0a: 0x2c63, 0xc0b: 0x2ea7, + 0xc0c: 0x2b99, 0xc0d: 0x2ac6, 0xc0e: 0x2edc, 0xc0f: 0x297d, 0xc10: 0x2987, 0xc11: 0x2ad3, + 0xc12: 0x26f2, 0xc13: 0x2ae0, 0xc14: 0x2ba9, 0xc15: 0x26f9, 0xc16: 0x2c76, 0xc17: 0x2991, + 0xc18: 0x1cbd, 0xc19: 0x1cd1, 0xc1a: 0x1ce0, 0xc1b: 0x1cef, 0xc1c: 0x1cfe, 0xc1d: 0x1d0d, + 0xc1e: 0x1d1c, 0xc1f: 0x1d2b, 0xc20: 0x1d3a, 0xc21: 0x1d49, 0xc22: 0x2198, 0xc23: 0x21aa, + 0xc24: 0x21bc, 0xc25: 0x21c8, 0xc26: 0x21d4, 0xc27: 0x21e0, 0xc28: 0x21ec, 0xc29: 0x21f8, + 0xc2a: 0x2204, 0xc2b: 0x2210, 0xc2c: 0x224c, 0xc2d: 0x2258, 0xc2e: 0x2264, 0xc2f: 0x2270, + 0xc30: 0x227c, 0xc31: 0x1c1a, 0xc32: 0x19cc, 0xc33: 0x1939, 0xc34: 0x1bea, 0xc35: 0x1a4d, + 0xc36: 0x1a5c, 0xc37: 0x19d2, 0xc38: 0x1c02, 0xc39: 0x1c06, 0xc3a: 0x1963, 0xc3b: 0x270e, + 0xc3c: 0x271c, 0xc3d: 0x2707, 0xc3e: 0x2715, 0xc3f: 0x2aed, + // Block 0x31, offset 0xc40 + 0xc40: 0x1a50, 0xc41: 0x1a38, 0xc42: 0x1c66, 0xc43: 0x1a20, 0xc44: 0x19f9, 0xc45: 0x196c, + 0xc46: 0x197b, 0xc47: 0x194b, 0xc48: 0x1bf6, 0xc49: 0x1d58, 0xc4a: 0x1a53, 0xc4b: 0x1a3b, + 0xc4c: 0x1c6a, 0xc4d: 0x1c76, 0xc4e: 0x1a2c, 0xc4f: 0x1a02, 0xc50: 0x195a, 0xc51: 0x1c22, + 0xc52: 0x1bb6, 0xc53: 0x1ba2, 0xc54: 0x1bd2, 0xc55: 0x1c7a, 0xc56: 0x1a2f, 0xc57: 0x19cf, + 0xc58: 0x1a05, 0xc59: 0x19e4, 0xc5a: 0x1a47, 0xc5b: 0x1c7e, 0xc5c: 0x1a32, 0xc5d: 0x19c6, + 0xc5e: 0x1a08, 0xc5f: 0x1c42, 0xc60: 0x1bfa, 0xc61: 0x1a1a, 0xc62: 0x1c2a, 0xc63: 0x1c46, + 0xc64: 0x1bfe, 0xc65: 0x1a1d, 0xc66: 0x1c2e, 0xc67: 0x22ee, 0xc68: 0x2302, 0xc69: 0x199c, + 0xc6a: 0x1c26, 0xc6b: 0x1bba, 0xc6c: 0x1ba6, 0xc6d: 0x1c4e, 0xc6e: 0x2723, 0xc6f: 0x27ba, + 0xc70: 0x1a5f, 0xc71: 0x1a4a, 0xc72: 0x1c82, 0xc73: 0x1a35, 0xc74: 0x1a56, 0xc75: 0x1a3e, + 0xc76: 0x1c6e, 0xc77: 0x1a23, 0xc78: 0x19fc, 0xc79: 0x1987, 0xc7a: 0x1a59, 0xc7b: 0x1a41, + 0xc7c: 0x1c72, 0xc7d: 0x1a26, 0xc7e: 0x19ff, 0xc7f: 0x198a, + // Block 0x32, offset 0xc80 + 0xc80: 0x1c32, 0xc81: 0x1bbe, 0xc82: 0x1d53, 0xc83: 0x193c, 0xc84: 0x19c0, 0xc85: 0x19c3, + 0xc86: 0x22fb, 0xc87: 0x1b9a, 0xc88: 0x19c9, 0xc89: 0x194e, 0xc8a: 0x19e7, 0xc8b: 0x1951, + 0xc8c: 0x19f0, 0xc8d: 0x196f, 0xc8e: 0x1972, 0xc8f: 0x1a0b, 0xc90: 0x1a11, 0xc91: 0x1a14, + 0xc92: 0x1c36, 0xc93: 0x1a17, 0xc94: 0x1a29, 0xc95: 0x1c3e, 0xc96: 0x1c4a, 0xc97: 0x1996, + 0xc98: 0x1d5d, 0xc99: 0x1bc2, 0xc9a: 0x1999, 0xc9b: 0x1a62, 0xc9c: 0x19ab, 0xc9d: 0x19ba, + 0xc9e: 0x22e8, 0xc9f: 0x22e2, 0xca0: 0x1cc7, 0xca1: 0x1cd6, 0xca2: 0x1ce5, 0xca3: 0x1cf4, + 0xca4: 0x1d03, 0xca5: 0x1d12, 0xca6: 0x1d21, 0xca7: 0x1d30, 0xca8: 0x1d3f, 0xca9: 0x218c, + 0xcaa: 0x219e, 0xcab: 0x21b0, 0xcac: 0x21c2, 0xcad: 0x21ce, 0xcae: 0x21da, 0xcaf: 0x21e6, + 0xcb0: 0x21f2, 0xcb1: 0x21fe, 0xcb2: 0x220a, 0xcb3: 0x2246, 0xcb4: 0x2252, 0xcb5: 0x225e, + 0xcb6: 0x226a, 0xcb7: 0x2276, 0xcb8: 0x2282, 0xcb9: 0x2288, 0xcba: 0x228e, 0xcbb: 0x2294, + 0xcbc: 0x229a, 0xcbd: 0x22ac, 0xcbe: 0x22b2, 0xcbf: 0x1c16, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x137a, 0xcc1: 0x0cfe, 0xcc2: 0x13d6, 0xcc3: 0x13a2, 0xcc4: 0x0e5a, 0xcc5: 0x06ee, + 0xcc6: 0x08e2, 0xcc7: 0x162e, 0xcc8: 0x162e, 0xcc9: 0x0a0e, 0xcca: 0x1462, 0xccb: 0x0946, + 0xccc: 0x0a0a, 0xccd: 0x0bf2, 0xcce: 0x0fd2, 0xccf: 0x1162, 0xcd0: 0x129a, 0xcd1: 0x12d6, + 0xcd2: 0x130a, 0xcd3: 0x141e, 0xcd4: 0x0d76, 0xcd5: 0x0e02, 0xcd6: 0x0eae, 0xcd7: 0x0f46, + 0xcd8: 0x1262, 0xcd9: 0x144a, 0xcda: 0x1576, 0xcdb: 0x0712, 0xcdc: 0x08b6, 0xcdd: 0x0d8a, + 0xcde: 0x0ed2, 0xcdf: 0x1296, 0xce0: 0x15c6, 0xce1: 0x0ab6, 0xce2: 0x0e7a, 0xce3: 0x1286, + 0xce4: 0x131a, 0xce5: 0x0c26, 0xce6: 0x11be, 0xce7: 0x12e2, 0xce8: 0x0b22, 0xce9: 0x0d12, + 0xcea: 0x0e1a, 0xceb: 0x0f1e, 0xcec: 0x142a, 0xced: 0x0752, 0xcee: 0x07ea, 0xcef: 0x0856, + 0xcf0: 0x0c8e, 0xcf1: 0x0d82, 0xcf2: 0x0ece, 0xcf3: 0x0ff2, 0xcf4: 0x117a, 0xcf5: 0x128e, + 0xcf6: 0x12a6, 0xcf7: 0x13ca, 0xcf8: 0x14f2, 0xcf9: 0x15a6, 0xcfa: 0x15c2, 0xcfb: 0x102e, + 0xcfc: 0x106e, 0xcfd: 0x1126, 0xcfe: 0x1246, 0xcff: 0x147e, + // Block 0x34, offset 0xd00 + 0xd00: 0x15ce, 0xd01: 0x134e, 0xd02: 0x09ca, 0xd03: 0x0b3e, 0xd04: 0x10de, 0xd05: 0x119e, + 0xd06: 0x0f02, 0xd07: 0x1036, 0xd08: 0x139a, 0xd09: 0x14ea, 0xd0a: 0x09c6, 0xd0b: 0x0a92, + 0xd0c: 0x0d7a, 0xd0d: 0x0e2e, 0xd0e: 0x0e62, 0xd0f: 0x1116, 0xd10: 0x113e, 0xd11: 0x14aa, + 0xd12: 0x0852, 0xd13: 0x11aa, 0xd14: 0x07f6, 0xd15: 0x07f2, 0xd16: 0x109a, 0xd17: 0x112a, + 0xd18: 0x125e, 0xd19: 0x14b2, 0xd1a: 0x136a, 0xd1b: 0x0c2a, 0xd1c: 0x0d76, 0xd1d: 0x135a, + 0xd1e: 0x06fa, 0xd1f: 0x0a66, 0xd20: 0x0b96, 0xd21: 0x0f32, 0xd22: 0x0fb2, 0xd23: 0x0876, + 0xd24: 0x103e, 0xd25: 0x0762, 0xd26: 0x0b7a, 0xd27: 0x06da, 0xd28: 0x0dee, 0xd29: 0x0ca6, + 0xd2a: 0x1112, 0xd2b: 0x08ca, 0xd2c: 0x09b6, 0xd2d: 0x0ffe, 0xd2e: 0x1266, 0xd2f: 0x133e, + 0xd30: 0x0dba, 0xd31: 0x13fa, 0xd32: 0x0de6, 0xd33: 0x0c3a, 0xd34: 0x121e, 0xd35: 0x0c5a, + 0xd36: 0x0fae, 0xd37: 0x072e, 0xd38: 0x07aa, 0xd39: 0x07ee, 0xd3a: 0x0d56, 0xd3b: 0x10fe, + 0xd3c: 0x11f6, 0xd3d: 0x134a, 0xd3e: 0x145e, 0xd3f: 0x085e, + // Block 0x35, offset 0xd40 + 0xd40: 0x0912, 0xd41: 0x0a1a, 0xd42: 0x0b32, 0xd43: 0x0cc2, 0xd44: 0x0e7e, 0xd45: 0x1042, + 0xd46: 0x149a, 0xd47: 0x157e, 0xd48: 0x15d2, 0xd49: 0x15ea, 0xd4a: 0x083a, 0xd4b: 0x0cf6, + 0xd4c: 0x0da6, 0xd4d: 0x13ee, 0xd4e: 0x0afe, 0xd4f: 0x0bda, 0xd50: 0x0bf6, 0xd51: 0x0c86, + 0xd52: 0x0e6e, 0xd53: 0x0eba, 0xd54: 0x0f6a, 0xd55: 0x108e, 0xd56: 0x1132, 0xd57: 0x1196, + 0xd58: 0x13de, 0xd59: 0x126e, 0xd5a: 0x1406, 0xd5b: 0x1482, 0xd5c: 0x0812, 0xd5d: 0x083e, + 0xd5e: 0x0926, 0xd5f: 0x0eaa, 0xd60: 0x12f6, 0xd61: 0x133e, 0xd62: 0x0b1e, 0xd63: 0x0b8e, + 0xd64: 0x0c52, 0xd65: 0x0db2, 0xd66: 0x10da, 0xd67: 0x0f26, 0xd68: 0x073e, 0xd69: 0x0982, + 0xd6a: 0x0a66, 0xd6b: 0x0aca, 0xd6c: 0x0b9a, 0xd6d: 0x0f42, 0xd6e: 0x0f5e, 0xd6f: 0x116e, + 0xd70: 0x118e, 0xd71: 0x1466, 0xd72: 0x14e6, 0xd73: 0x14f6, 0xd74: 0x1532, 0xd75: 0x0756, + 0xd76: 0x1082, 0xd77: 0x1452, 0xd78: 0x14ce, 0xd79: 0x0bb2, 0xd7a: 0x071a, 0xd7b: 0x077a, + 0xd7c: 0x0a6a, 0xd7d: 0x0a8a, 0xd7e: 0x0cb2, 0xd7f: 0x0d76, + // Block 0x36, offset 0xd80 + 0xd80: 0x0ec6, 0xd81: 0x0fce, 0xd82: 0x127a, 0xd83: 0x141a, 0xd84: 0x1626, 0xd85: 0x0ce6, + 0xd86: 0x14a6, 0xd87: 0x0836, 0xd88: 0x0d32, 0xd89: 0x0d3e, 0xd8a: 0x0e12, 0xd8b: 0x0e4a, + 0xd8c: 0x0f4e, 0xd8d: 0x0faa, 0xd8e: 0x102a, 0xd8f: 0x110e, 0xd90: 0x153e, 0xd91: 0x07b2, + 0xd92: 0x0c06, 0xd93: 0x14b6, 0xd94: 0x076a, 0xd95: 0x0aae, 0xd96: 0x0e32, 0xd97: 0x13e2, + 0xd98: 0x0b6a, 0xd99: 0x0bba, 0xd9a: 0x0d46, 0xd9b: 0x0f32, 0xd9c: 0x14be, 0xd9d: 0x081a, + 0xd9e: 0x0902, 0xd9f: 0x0a9a, 0xda0: 0x0cd6, 0xda1: 0x0d22, 0xda2: 0x0d62, 0xda3: 0x0df6, + 0xda4: 0x0f4a, 0xda5: 0x0fbe, 0xda6: 0x115a, 0xda7: 0x12fa, 0xda8: 0x1306, 0xda9: 0x145a, + 0xdaa: 0x14da, 0xdab: 0x0886, 0xdac: 0x0e4e, 0xdad: 0x0906, 0xdae: 0x0eca, 0xdaf: 0x0f6e, + 0xdb0: 0x128a, 0xdb1: 0x14c2, 0xdb2: 0x15ae, 0xdb3: 0x15d6, 0xdb4: 0x0d3a, 0xdb5: 0x0e2a, + 0xdb6: 0x11c6, 0xdb7: 0x10ba, 0xdb8: 0x10c6, 0xdb9: 0x10ea, 0xdba: 0x0f1a, 0xdbb: 0x0ea2, + 0xdbc: 0x1366, 0xdbd: 0x0736, 0xdbe: 0x122e, 0xdbf: 0x081e, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x080e, 0xdc1: 0x0b0e, 0xdc2: 0x0c2e, 0xdc3: 0x10f6, 0xdc4: 0x0a56, 0xdc5: 0x0e06, + 0xdc6: 0x0cf2, 0xdc7: 0x13ea, 0xdc8: 0x12ea, 0xdc9: 0x14ae, 0xdca: 0x1326, 0xdcb: 0x0b2a, + 0xdcc: 0x078a, 0xdcd: 0x095e, 0xdd0: 0x09b2, + 0xdd2: 0x0ce2, 0xdd5: 0x07fa, 0xdd6: 0x0f22, 0xdd7: 0x0fe6, + 0xdd8: 0x104a, 0xdd9: 0x1066, 0xdda: 0x106a, 0xddb: 0x107e, 0xddc: 0x14fe, 0xddd: 0x10ee, + 0xdde: 0x1172, 0xde0: 0x1292, 0xde2: 0x1356, + 0xde5: 0x140a, 0xde6: 0x1436, + 0xdea: 0x1552, 0xdeb: 0x1556, 0xdec: 0x155a, 0xded: 0x15be, 0xdee: 0x142e, 0xdef: 0x14ca, + 0xdf0: 0x075a, 0xdf1: 0x077e, 0xdf2: 0x0792, 0xdf3: 0x084e, 0xdf4: 0x085a, 0xdf5: 0x089a, + 0xdf6: 0x094e, 0xdf7: 0x096a, 0xdf8: 0x0972, 0xdf9: 0x09ae, 0xdfa: 0x09ba, 0xdfb: 0x0a96, + 0xdfc: 0x0a9e, 0xdfd: 0x0ba6, 0xdfe: 0x0bce, 0xdff: 0x0bd6, + // Block 0x38, offset 0xe00 + 0xe00: 0x0bee, 0xe01: 0x0c9a, 0xe02: 0x0cca, 0xe03: 0x0cea, 0xe04: 0x0d5a, 0xe05: 0x0e1e, + 0xe06: 0x0e3a, 0xe07: 0x0e6a, 0xe08: 0x0ebe, 0xe09: 0x0ede, 0xe0a: 0x0f52, 0xe0b: 0x1032, + 0xe0c: 0x104e, 0xe0d: 0x1056, 0xe0e: 0x1052, 0xe0f: 0x105a, 0xe10: 0x105e, 0xe11: 0x1062, + 0xe12: 0x1076, 0xe13: 0x107a, 0xe14: 0x109e, 0xe15: 0x10b2, 0xe16: 0x10ce, 0xe17: 0x1132, + 0xe18: 0x113a, 0xe19: 0x1142, 0xe1a: 0x1156, 0xe1b: 0x117e, 0xe1c: 0x11ce, 0xe1d: 0x1202, + 0xe1e: 0x1202, 0xe1f: 0x126a, 0xe20: 0x1312, 0xe21: 0x132a, 0xe22: 0x135e, 0xe23: 0x1362, + 0xe24: 0x13a6, 0xe25: 0x13aa, 0xe26: 0x1402, 0xe27: 0x140a, 0xe28: 0x14de, 0xe29: 0x1522, + 0xe2a: 0x153a, 0xe2b: 0x0b9e, 0xe2c: 0x1721, 0xe2d: 0x11e6, + 0xe30: 0x06e2, 0xe31: 0x07e6, 0xe32: 0x07a6, 0xe33: 0x074e, 0xe34: 0x078e, 0xe35: 0x07ba, + 0xe36: 0x084a, 0xe37: 0x0866, 0xe38: 0x094e, 0xe39: 0x093a, 0xe3a: 0x094a, 0xe3b: 0x0966, + 0xe3c: 0x09b2, 0xe3d: 0x09c2, 0xe3e: 0x0a06, 0xe3f: 0x0a12, + // Block 0x39, offset 0xe40 + 0xe40: 0x0a2e, 0xe41: 0x0a3e, 0xe42: 0x0b26, 0xe43: 0x0b2e, 0xe44: 0x0b5e, 0xe45: 0x0b7e, + 0xe46: 0x0bae, 0xe47: 0x0bc6, 0xe48: 0x0bb6, 0xe49: 0x0bd6, 0xe4a: 0x0bca, 0xe4b: 0x0bee, + 0xe4c: 0x0c0a, 0xe4d: 0x0c62, 0xe4e: 0x0c6e, 0xe4f: 0x0c76, 0xe50: 0x0c9e, 0xe51: 0x0ce2, + 0xe52: 0x0d12, 0xe53: 0x0d16, 0xe54: 0x0d2a, 0xe55: 0x0daa, 0xe56: 0x0dba, 0xe57: 0x0e12, + 0xe58: 0x0e5e, 0xe59: 0x0e56, 0xe5a: 0x0e6a, 0xe5b: 0x0e86, 0xe5c: 0x0ebe, 0xe5d: 0x1016, + 0xe5e: 0x0ee2, 0xe5f: 0x0f16, 0xe60: 0x0f22, 0xe61: 0x0f62, 0xe62: 0x0f7e, 0xe63: 0x0fa2, + 0xe64: 0x0fc6, 0xe65: 0x0fca, 0xe66: 0x0fe6, 0xe67: 0x0fea, 0xe68: 0x0ffa, 0xe69: 0x100e, + 0xe6a: 0x100a, 0xe6b: 0x103a, 0xe6c: 0x10b6, 0xe6d: 0x10ce, 0xe6e: 0x10e6, 0xe6f: 0x111e, + 0xe70: 0x1132, 0xe71: 0x114e, 0xe72: 0x117e, 0xe73: 0x1232, 0xe74: 0x125a, 0xe75: 0x12ce, + 0xe76: 0x1316, 0xe77: 0x1322, 0xe78: 0x132a, 0xe79: 0x1342, 0xe7a: 0x1356, 0xe7b: 0x1346, + 0xe7c: 0x135e, 0xe7d: 0x135a, 0xe7e: 0x1352, 0xe7f: 0x1362, + // Block 0x3a, offset 0xe80 + 0xe80: 0x136e, 0xe81: 0x13aa, 0xe82: 0x13e6, 0xe83: 0x1416, 0xe84: 0x144e, 0xe85: 0x146e, + 0xe86: 0x14ba, 0xe87: 0x14de, 0xe88: 0x14fe, 0xe89: 0x1512, 0xe8a: 0x1522, 0xe8b: 0x152e, + 0xe8c: 0x153a, 0xe8d: 0x158e, 0xe8e: 0x162e, 0xe8f: 0x16b8, 0xe90: 0x16b3, 0xe91: 0x16e5, + 0xe92: 0x060a, 0xe93: 0x0632, 0xe94: 0x0636, 0xe95: 0x1767, 0xe96: 0x1794, 0xe97: 0x180c, + 0xe98: 0x161a, 0xe99: 0x162a, + // Block 0x3b, offset 0xec0 + 0xec0: 0x19db, 0xec1: 0x19de, 0xec2: 0x19e1, 0xec3: 0x1c0e, 0xec4: 0x1c12, 0xec5: 0x1a65, + 0xec6: 0x1a65, + 0xed3: 0x1d7b, 0xed4: 0x1d6c, 0xed5: 0x1d71, 0xed6: 0x1d80, 0xed7: 0x1d76, + 0xedd: 0x43a7, + 0xede: 0x8116, 0xedf: 0x4419, 0xee0: 0x0230, 0xee1: 0x0218, 0xee2: 0x0221, 0xee3: 0x0224, + 0xee4: 0x0227, 0xee5: 0x022a, 0xee6: 0x022d, 0xee7: 0x0233, 0xee8: 0x0236, 0xee9: 0x0017, + 0xeea: 0x4407, 0xeeb: 0x440d, 0xeec: 0x450b, 0xeed: 0x4513, 0xeee: 0x435f, 0xeef: 0x4365, + 0xef0: 0x436b, 0xef1: 0x4371, 0xef2: 0x437d, 0xef3: 0x4383, 0xef4: 0x4389, 0xef5: 0x4395, + 0xef6: 0x439b, 0xef8: 0x43a1, 0xef9: 0x43ad, 0xefa: 0x43b3, 0xefb: 0x43b9, + 0xefc: 0x43c5, 0xefe: 0x43cb, + // Block 0x3c, offset 0xf00 + 0xf00: 0x43d1, 0xf01: 0x43d7, 0xf03: 0x43dd, 0xf04: 0x43e3, + 0xf06: 0x43ef, 0xf07: 0x43f5, 0xf08: 0x43fb, 0xf09: 0x4401, 0xf0a: 0x4413, 0xf0b: 0x438f, + 0xf0c: 0x4377, 0xf0d: 0x43bf, 0xf0e: 0x43e9, 0xf0f: 0x1d85, 0xf10: 0x029c, 0xf11: 0x029c, + 0xf12: 0x02a5, 0xf13: 0x02a5, 0xf14: 0x02a5, 0xf15: 0x02a5, 0xf16: 0x02a8, 0xf17: 0x02a8, + 0xf18: 0x02a8, 0xf19: 0x02a8, 0xf1a: 0x02ae, 0xf1b: 0x02ae, 0xf1c: 0x02ae, 0xf1d: 0x02ae, + 0xf1e: 0x02a2, 0xf1f: 0x02a2, 0xf20: 0x02a2, 0xf21: 0x02a2, 0xf22: 0x02ab, 0xf23: 0x02ab, + 0xf24: 0x02ab, 0xf25: 0x02ab, 0xf26: 0x029f, 0xf27: 0x029f, 0xf28: 0x029f, 0xf29: 0x029f, + 0xf2a: 0x02d2, 0xf2b: 0x02d2, 0xf2c: 0x02d2, 0xf2d: 0x02d2, 0xf2e: 0x02d5, 0xf2f: 0x02d5, + 0xf30: 0x02d5, 0xf31: 0x02d5, 0xf32: 0x02b4, 0xf33: 0x02b4, 0xf34: 0x02b4, 0xf35: 0x02b4, + 0xf36: 0x02b1, 0xf37: 0x02b1, 0xf38: 0x02b1, 0xf39: 0x02b1, 0xf3a: 0x02b7, 0xf3b: 0x02b7, + 0xf3c: 0x02b7, 0xf3d: 0x02b7, 0xf3e: 0x02ba, 0xf3f: 0x02ba, + // Block 0x3d, offset 0xf40 + 0xf40: 0x02ba, 0xf41: 0x02ba, 0xf42: 0x02c3, 0xf43: 0x02c3, 0xf44: 0x02c0, 0xf45: 0x02c0, + 0xf46: 0x02c6, 0xf47: 0x02c6, 0xf48: 0x02bd, 0xf49: 0x02bd, 0xf4a: 0x02cc, 0xf4b: 0x02cc, + 0xf4c: 0x02c9, 0xf4d: 0x02c9, 0xf4e: 0x02d8, 0xf4f: 0x02d8, 0xf50: 0x02d8, 0xf51: 0x02d8, + 0xf52: 0x02de, 0xf53: 0x02de, 0xf54: 0x02de, 0xf55: 0x02de, 0xf56: 0x02e4, 0xf57: 0x02e4, + 0xf58: 0x02e4, 0xf59: 0x02e4, 0xf5a: 0x02e1, 0xf5b: 0x02e1, 0xf5c: 0x02e1, 0xf5d: 0x02e1, + 0xf5e: 0x02e7, 0xf5f: 0x02e7, 0xf60: 0x02ea, 0xf61: 0x02ea, 0xf62: 0x02ea, 0xf63: 0x02ea, + 0xf64: 0x4485, 0xf65: 0x4485, 0xf66: 0x02f0, 0xf67: 0x02f0, 0xf68: 0x02f0, 0xf69: 0x02f0, + 0xf6a: 0x02ed, 0xf6b: 0x02ed, 0xf6c: 0x02ed, 0xf6d: 0x02ed, 0xf6e: 0x030b, 0xf6f: 0x030b, + 0xf70: 0x447f, 0xf71: 0x447f, + // Block 0x3e, offset 0xf80 + 0xf93: 0x02db, 0xf94: 0x02db, 0xf95: 0x02db, 0xf96: 0x02db, 0xf97: 0x02f9, + 0xf98: 0x02f9, 0xf99: 0x02f6, 0xf9a: 0x02f6, 0xf9b: 0x02fc, 0xf9c: 0x02fc, 0xf9d: 0x2055, + 0xf9e: 0x0302, 0xf9f: 0x0302, 0xfa0: 0x02f3, 0xfa1: 0x02f3, 0xfa2: 0x02ff, 0xfa3: 0x02ff, + 0xfa4: 0x0308, 0xfa5: 0x0308, 0xfa6: 0x0308, 0xfa7: 0x0308, 0xfa8: 0x0290, 0xfa9: 0x0290, + 0xfaa: 0x25b0, 0xfab: 0x25b0, 0xfac: 0x2620, 0xfad: 0x2620, 0xfae: 0x25ef, 0xfaf: 0x25ef, + 0xfb0: 0x260b, 0xfb1: 0x260b, 0xfb2: 0x2604, 0xfb3: 0x2604, 0xfb4: 0x2612, 0xfb5: 0x2612, + 0xfb6: 0x2619, 0xfb7: 0x2619, 0xfb8: 0x2619, 0xfb9: 0x25f6, 0xfba: 0x25f6, 0xfbb: 0x25f6, + 0xfbc: 0x0305, 0xfbd: 0x0305, 0xfbe: 0x0305, 0xfbf: 0x0305, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x25b7, 0xfc1: 0x25be, 0xfc2: 0x25da, 0xfc3: 0x25f6, 0xfc4: 0x25fd, 0xfc5: 0x1d8f, + 0xfc6: 0x1d94, 0xfc7: 0x1d99, 0xfc8: 0x1da8, 0xfc9: 0x1db7, 0xfca: 0x1dbc, 0xfcb: 0x1dc1, + 0xfcc: 0x1dc6, 0xfcd: 0x1dcb, 0xfce: 0x1dda, 0xfcf: 0x1de9, 0xfd0: 0x1dee, 0xfd1: 0x1df3, + 0xfd2: 0x1e02, 0xfd3: 0x1e11, 0xfd4: 0x1e16, 0xfd5: 0x1e1b, 0xfd6: 0x1e20, 0xfd7: 0x1e2f, + 0xfd8: 0x1e34, 0xfd9: 0x1e43, 0xfda: 0x1e48, 0xfdb: 0x1e4d, 0xfdc: 0x1e5c, 0xfdd: 0x1e61, + 0xfde: 0x1e66, 0xfdf: 0x1e70, 0xfe0: 0x1eac, 0xfe1: 0x1ebb, 0xfe2: 0x1eca, 0xfe3: 0x1ecf, + 0xfe4: 0x1ed4, 0xfe5: 0x1ede, 0xfe6: 0x1eed, 0xfe7: 0x1ef2, 0xfe8: 0x1f01, 0xfe9: 0x1f06, + 0xfea: 0x1f0b, 0xfeb: 0x1f1a, 0xfec: 0x1f1f, 0xfed: 0x1f2e, 0xfee: 0x1f33, 0xfef: 0x1f38, + 0xff0: 0x1f3d, 0xff1: 0x1f42, 0xff2: 0x1f47, 0xff3: 0x1f4c, 0xff4: 0x1f51, 0xff5: 0x1f56, + 0xff6: 0x1f5b, 0xff7: 0x1f60, 0xff8: 0x1f65, 0xff9: 0x1f6a, 0xffa: 0x1f6f, 0xffb: 0x1f74, + 0xffc: 0x1f79, 0xffd: 0x1f7e, 0xffe: 0x1f83, 0xfff: 0x1f8d, + // Block 0x40, offset 0x1000 + 0x1000: 0x1f92, 0x1001: 0x1f97, 0x1002: 0x1f9c, 0x1003: 0x1fa6, 0x1004: 0x1fab, 0x1005: 0x1fb5, + 0x1006: 0x1fba, 0x1007: 0x1fbf, 0x1008: 0x1fc4, 0x1009: 0x1fc9, 0x100a: 0x1fce, 0x100b: 0x1fd3, + 0x100c: 0x1fd8, 0x100d: 0x1fdd, 0x100e: 0x1fec, 0x100f: 0x1ffb, 0x1010: 0x2000, 0x1011: 0x2005, + 0x1012: 0x200a, 0x1013: 0x200f, 0x1014: 0x2014, 0x1015: 0x201e, 0x1016: 0x2023, 0x1017: 0x2028, + 0x1018: 0x2037, 0x1019: 0x2046, 0x101a: 0x204b, 0x101b: 0x4437, 0x101c: 0x443d, 0x101d: 0x4473, + 0x101e: 0x44ca, 0x101f: 0x44d1, 0x1020: 0x44d8, 0x1021: 0x44df, 0x1022: 0x44e6, 0x1023: 0x44ed, + 0x1024: 0x25cc, 0x1025: 0x25d3, 0x1026: 0x25da, 0x1027: 0x25e1, 0x1028: 0x25f6, 0x1029: 0x25fd, + 0x102a: 0x1d9e, 0x102b: 0x1da3, 0x102c: 0x1da8, 0x102d: 0x1dad, 0x102e: 0x1db7, 0x102f: 0x1dbc, + 0x1030: 0x1dd0, 0x1031: 0x1dd5, 0x1032: 0x1dda, 0x1033: 0x1ddf, 0x1034: 0x1de9, 0x1035: 0x1dee, + 0x1036: 0x1df8, 0x1037: 0x1dfd, 0x1038: 0x1e02, 0x1039: 0x1e07, 0x103a: 0x1e11, 0x103b: 0x1e16, + 0x103c: 0x1f42, 0x103d: 0x1f47, 0x103e: 0x1f56, 0x103f: 0x1f5b, + // Block 0x41, offset 0x1040 + 0x1040: 0x1f60, 0x1041: 0x1f74, 0x1042: 0x1f79, 0x1043: 0x1f7e, 0x1044: 0x1f83, 0x1045: 0x1f9c, + 0x1046: 0x1fa6, 0x1047: 0x1fab, 0x1048: 0x1fb0, 0x1049: 0x1fc4, 0x104a: 0x1fe2, 0x104b: 0x1fe7, + 0x104c: 0x1fec, 0x104d: 0x1ff1, 0x104e: 0x1ffb, 0x104f: 0x2000, 0x1050: 0x4473, 0x1051: 0x202d, + 0x1052: 0x2032, 0x1053: 0x2037, 0x1054: 0x203c, 0x1055: 0x2046, 0x1056: 0x204b, 0x1057: 0x25b7, + 0x1058: 0x25be, 0x1059: 0x25c5, 0x105a: 0x25da, 0x105b: 0x25e8, 0x105c: 0x1d8f, 0x105d: 0x1d94, + 0x105e: 0x1d99, 0x105f: 0x1da8, 0x1060: 0x1db2, 0x1061: 0x1dc1, 0x1062: 0x1dc6, 0x1063: 0x1dcb, + 0x1064: 0x1dda, 0x1065: 0x1de4, 0x1066: 0x1e02, 0x1067: 0x1e1b, 0x1068: 0x1e20, 0x1069: 0x1e2f, + 0x106a: 0x1e34, 0x106b: 0x1e43, 0x106c: 0x1e4d, 0x106d: 0x1e5c, 0x106e: 0x1e61, 0x106f: 0x1e66, + 0x1070: 0x1e70, 0x1071: 0x1eac, 0x1072: 0x1eb1, 0x1073: 0x1ebb, 0x1074: 0x1eca, 0x1075: 0x1ecf, + 0x1076: 0x1ed4, 0x1077: 0x1ede, 0x1078: 0x1eed, 0x1079: 0x1f01, 0x107a: 0x1f06, 0x107b: 0x1f0b, + 0x107c: 0x1f1a, 0x107d: 0x1f1f, 0x107e: 0x1f2e, 0x107f: 0x1f33, + // Block 0x42, offset 0x1080 + 0x1080: 0x1f38, 0x1081: 0x1f3d, 0x1082: 0x1f4c, 0x1083: 0x1f51, 0x1084: 0x1f65, 0x1085: 0x1f6a, + 0x1086: 0x1f6f, 0x1087: 0x1f74, 0x1088: 0x1f79, 0x1089: 0x1f8d, 0x108a: 0x1f92, 0x108b: 0x1f97, + 0x108c: 0x1f9c, 0x108d: 0x1fa1, 0x108e: 0x1fb5, 0x108f: 0x1fba, 0x1090: 0x1fbf, 0x1091: 0x1fc4, + 0x1092: 0x1fd3, 0x1093: 0x1fd8, 0x1094: 0x1fdd, 0x1095: 0x1fec, 0x1096: 0x1ff6, 0x1097: 0x2005, + 0x1098: 0x200a, 0x1099: 0x4467, 0x109a: 0x201e, 0x109b: 0x2023, 0x109c: 0x2028, 0x109d: 0x2037, + 0x109e: 0x2041, 0x109f: 0x25da, 0x10a0: 0x25e8, 0x10a1: 0x1da8, 0x10a2: 0x1db2, 0x10a3: 0x1dda, + 0x10a4: 0x1de4, 0x10a5: 0x1e02, 0x10a6: 0x1e0c, 0x10a7: 0x1e70, 0x10a8: 0x1e75, 0x10a9: 0x1e98, + 0x10aa: 0x1e9d, 0x10ab: 0x1f74, 0x10ac: 0x1f79, 0x10ad: 0x1f9c, 0x10ae: 0x1fec, 0x10af: 0x1ff6, + 0x10b0: 0x2037, 0x10b1: 0x2041, 0x10b2: 0x451b, 0x10b3: 0x4523, 0x10b4: 0x452b, 0x10b5: 0x1ef7, + 0x10b6: 0x1efc, 0x10b7: 0x1f10, 0x10b8: 0x1f15, 0x10b9: 0x1f24, 0x10ba: 0x1f29, 0x10bb: 0x1e7a, + 0x10bc: 0x1e7f, 0x10bd: 0x1ea2, 0x10be: 0x1ea7, 0x10bf: 0x1e39, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x1e3e, 0x10c1: 0x1e25, 0x10c2: 0x1e2a, 0x10c3: 0x1e52, 0x10c4: 0x1e57, 0x10c5: 0x1ec0, + 0x10c6: 0x1ec5, 0x10c7: 0x1ee3, 0x10c8: 0x1ee8, 0x10c9: 0x1e84, 0x10ca: 0x1e89, 0x10cb: 0x1e8e, + 0x10cc: 0x1e98, 0x10cd: 0x1e93, 0x10ce: 0x1e6b, 0x10cf: 0x1eb6, 0x10d0: 0x1ed9, 0x10d1: 0x1ef7, + 0x10d2: 0x1efc, 0x10d3: 0x1f10, 0x10d4: 0x1f15, 0x10d5: 0x1f24, 0x10d6: 0x1f29, 0x10d7: 0x1e7a, + 0x10d8: 0x1e7f, 0x10d9: 0x1ea2, 0x10da: 0x1ea7, 0x10db: 0x1e39, 0x10dc: 0x1e3e, 0x10dd: 0x1e25, + 0x10de: 0x1e2a, 0x10df: 0x1e52, 0x10e0: 0x1e57, 0x10e1: 0x1ec0, 0x10e2: 0x1ec5, 0x10e3: 0x1ee3, + 0x10e4: 0x1ee8, 0x10e5: 0x1e84, 0x10e6: 0x1e89, 0x10e7: 0x1e8e, 0x10e8: 0x1e98, 0x10e9: 0x1e93, + 0x10ea: 0x1e6b, 0x10eb: 0x1eb6, 0x10ec: 0x1ed9, 0x10ed: 0x1e84, 0x10ee: 0x1e89, 0x10ef: 0x1e8e, + 0x10f0: 0x1e98, 0x10f1: 0x1e75, 0x10f2: 0x1e9d, 0x10f3: 0x1ef2, 0x10f4: 0x1e5c, 0x10f5: 0x1e61, + 0x10f6: 0x1e66, 0x10f7: 0x1e84, 0x10f8: 0x1e89, 0x10f9: 0x1e8e, 0x10fa: 0x1ef2, 0x10fb: 0x1f01, + 0x10fc: 0x441f, 0x10fd: 0x441f, + // Block 0x44, offset 0x1100 + 0x1110: 0x2317, 0x1111: 0x232c, + 0x1112: 0x232c, 0x1113: 0x2333, 0x1114: 0x233a, 0x1115: 0x234f, 0x1116: 0x2356, 0x1117: 0x235d, + 0x1118: 0x2380, 0x1119: 0x2380, 0x111a: 0x23a3, 0x111b: 0x239c, 0x111c: 0x23b8, 0x111d: 0x23aa, + 0x111e: 0x23b1, 0x111f: 0x23d4, 0x1120: 0x23d4, 0x1121: 0x23cd, 0x1122: 0x23db, 0x1123: 0x23db, + 0x1124: 0x2405, 0x1125: 0x2405, 0x1126: 0x2421, 0x1127: 0x23e9, 0x1128: 0x23e9, 0x1129: 0x23e2, + 0x112a: 0x23f7, 0x112b: 0x23f7, 0x112c: 0x23fe, 0x112d: 0x23fe, 0x112e: 0x2428, 0x112f: 0x2436, + 0x1130: 0x2436, 0x1131: 0x243d, 0x1132: 0x243d, 0x1133: 0x2444, 0x1134: 0x244b, 0x1135: 0x2452, + 0x1136: 0x2459, 0x1137: 0x2459, 0x1138: 0x2460, 0x1139: 0x246e, 0x113a: 0x247c, 0x113b: 0x2475, + 0x113c: 0x2483, 0x113d: 0x2483, 0x113e: 0x2498, 0x113f: 0x249f, + // Block 0x45, offset 0x1140 + 0x1140: 0x24d0, 0x1141: 0x24de, 0x1142: 0x24d7, 0x1143: 0x24bb, 0x1144: 0x24bb, 0x1145: 0x24e5, + 0x1146: 0x24e5, 0x1147: 0x24ec, 0x1148: 0x24ec, 0x1149: 0x2516, 0x114a: 0x251d, 0x114b: 0x2524, + 0x114c: 0x24fa, 0x114d: 0x2508, 0x114e: 0x252b, 0x114f: 0x2532, + 0x1152: 0x2501, 0x1153: 0x2586, 0x1154: 0x258d, 0x1155: 0x2563, 0x1156: 0x256a, 0x1157: 0x254e, + 0x1158: 0x254e, 0x1159: 0x2555, 0x115a: 0x257f, 0x115b: 0x2578, 0x115c: 0x25a2, 0x115d: 0x25a2, + 0x115e: 0x2310, 0x115f: 0x2325, 0x1160: 0x231e, 0x1161: 0x2348, 0x1162: 0x2341, 0x1163: 0x236b, + 0x1164: 0x2364, 0x1165: 0x238e, 0x1166: 0x2372, 0x1167: 0x2387, 0x1168: 0x23bf, 0x1169: 0x240c, + 0x116a: 0x23f0, 0x116b: 0x242f, 0x116c: 0x24c9, 0x116d: 0x24f3, 0x116e: 0x259b, 0x116f: 0x2594, + 0x1170: 0x25a9, 0x1171: 0x2540, 0x1172: 0x24a6, 0x1173: 0x2571, 0x1174: 0x2498, 0x1175: 0x24d0, + 0x1176: 0x2467, 0x1177: 0x24b4, 0x1178: 0x2547, 0x1179: 0x2539, 0x117a: 0x24c2, 0x117b: 0x24ad, + 0x117c: 0x24c2, 0x117d: 0x2547, 0x117e: 0x2379, 0x117f: 0x2395, + // Block 0x46, offset 0x1180 + 0x1180: 0x250f, 0x1181: 0x248a, 0x1182: 0x2309, 0x1183: 0x24ad, 0x1184: 0x2452, 0x1185: 0x2421, + 0x1186: 0x23c6, 0x1187: 0x255c, + 0x11b0: 0x241a, 0x11b1: 0x2491, 0x11b2: 0x27cc, 0x11b3: 0x27c3, 0x11b4: 0x27f9, 0x11b5: 0x27e7, + 0x11b6: 0x27d5, 0x11b7: 0x27f0, 0x11b8: 0x2802, 0x11b9: 0x2413, 0x11ba: 0x2c89, 0x11bb: 0x2b09, + 0x11bc: 0x27de, + // Block 0x47, offset 0x11c0 + 0x11d0: 0x0019, 0x11d1: 0x0486, + 0x11d2: 0x048a, 0x11d3: 0x0035, 0x11d4: 0x0037, 0x11d5: 0x0003, 0x11d6: 0x003f, 0x11d7: 0x04c2, + 0x11d8: 0x04c6, 0x11d9: 0x1b62, + 0x11e0: 0x8133, 0x11e1: 0x8133, 0x11e2: 0x8133, 0x11e3: 0x8133, + 0x11e4: 0x8133, 0x11e5: 0x8133, 0x11e6: 0x8133, 0x11e7: 0x812e, 0x11e8: 0x812e, 0x11e9: 0x812e, + 0x11ea: 0x812e, 0x11eb: 0x812e, 0x11ec: 0x812e, 0x11ed: 0x812e, 0x11ee: 0x8133, 0x11ef: 0x8133, + 0x11f0: 0x1876, 0x11f1: 0x0446, 0x11f2: 0x0442, 0x11f3: 0x007f, 0x11f4: 0x007f, 0x11f5: 0x0011, + 0x11f6: 0x0013, 0x11f7: 0x00b7, 0x11f8: 0x00bb, 0x11f9: 0x04ba, 0x11fa: 0x04be, 0x11fb: 0x04ae, + 0x11fc: 0x04b2, 0x11fd: 0x0496, 0x11fe: 0x049a, 0x11ff: 0x048e, + // Block 0x48, offset 0x1200 + 0x1200: 0x0492, 0x1201: 0x049e, 0x1202: 0x04a2, 0x1203: 0x04a6, 0x1204: 0x04aa, + 0x1207: 0x0077, 0x1208: 0x007b, 0x1209: 0x4280, 0x120a: 0x4280, 0x120b: 0x4280, + 0x120c: 0x4280, 0x120d: 0x007f, 0x120e: 0x007f, 0x120f: 0x007f, 0x1210: 0x0019, 0x1211: 0x0486, + 0x1212: 0x001d, 0x1214: 0x0037, 0x1215: 0x0035, 0x1216: 0x003f, 0x1217: 0x0003, + 0x1218: 0x0446, 0x1219: 0x0011, 0x121a: 0x0013, 0x121b: 0x00b7, 0x121c: 0x00bb, 0x121d: 0x04ba, + 0x121e: 0x04be, 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: 0x42c1, 0x1231: 0x4443, 0x1232: 0x42c6, 0x1234: 0x42cb, + 0x1236: 0x42d0, 0x1237: 0x4449, 0x1238: 0x42d5, 0x1239: 0x444f, 0x123a: 0x42da, 0x123b: 0x4455, + 0x123c: 0x42df, 0x123d: 0x445b, 0x123e: 0x42e4, 0x123f: 0x4461, + // Block 0x49, offset 0x1240 + 0x1240: 0x0239, 0x1241: 0x4425, 0x1242: 0x4425, 0x1243: 0x442b, 0x1244: 0x442b, 0x1245: 0x446d, + 0x1246: 0x446d, 0x1247: 0x4431, 0x1248: 0x4431, 0x1249: 0x4479, 0x124a: 0x4479, 0x124b: 0x4479, + 0x124c: 0x4479, 0x124d: 0x023c, 0x124e: 0x023c, 0x124f: 0x023f, 0x1250: 0x023f, 0x1251: 0x023f, + 0x1252: 0x023f, 0x1253: 0x0242, 0x1254: 0x0242, 0x1255: 0x0245, 0x1256: 0x0245, 0x1257: 0x0245, + 0x1258: 0x0245, 0x1259: 0x0248, 0x125a: 0x0248, 0x125b: 0x0248, 0x125c: 0x0248, 0x125d: 0x024b, + 0x125e: 0x024b, 0x125f: 0x024b, 0x1260: 0x024b, 0x1261: 0x024e, 0x1262: 0x024e, 0x1263: 0x024e, + 0x1264: 0x024e, 0x1265: 0x0251, 0x1266: 0x0251, 0x1267: 0x0251, 0x1268: 0x0251, 0x1269: 0x0254, + 0x126a: 0x0254, 0x126b: 0x0257, 0x126c: 0x0257, 0x126d: 0x025a, 0x126e: 0x025a, 0x126f: 0x025d, + 0x1270: 0x025d, 0x1271: 0x0260, 0x1272: 0x0260, 0x1273: 0x0260, 0x1274: 0x0260, 0x1275: 0x0263, + 0x1276: 0x0263, 0x1277: 0x0263, 0x1278: 0x0263, 0x1279: 0x0266, 0x127a: 0x0266, 0x127b: 0x0266, + 0x127c: 0x0266, 0x127d: 0x0269, 0x127e: 0x0269, 0x127f: 0x0269, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0269, 0x1281: 0x026c, 0x1282: 0x026c, 0x1283: 0x026c, 0x1284: 0x026c, 0x1285: 0x026f, + 0x1286: 0x026f, 0x1287: 0x026f, 0x1288: 0x026f, 0x1289: 0x0272, 0x128a: 0x0272, 0x128b: 0x0272, + 0x128c: 0x0272, 0x128d: 0x0275, 0x128e: 0x0275, 0x128f: 0x0275, 0x1290: 0x0275, 0x1291: 0x0278, + 0x1292: 0x0278, 0x1293: 0x0278, 0x1294: 0x0278, 0x1295: 0x027b, 0x1296: 0x027b, 0x1297: 0x027b, + 0x1298: 0x027b, 0x1299: 0x027e, 0x129a: 0x027e, 0x129b: 0x027e, 0x129c: 0x027e, 0x129d: 0x0281, + 0x129e: 0x0281, 0x129f: 0x0281, 0x12a0: 0x0281, 0x12a1: 0x0284, 0x12a2: 0x0284, 0x12a3: 0x0284, + 0x12a4: 0x0284, 0x12a5: 0x0287, 0x12a6: 0x0287, 0x12a7: 0x0287, 0x12a8: 0x0287, 0x12a9: 0x028a, + 0x12aa: 0x028a, 0x12ab: 0x028a, 0x12ac: 0x028a, 0x12ad: 0x028d, 0x12ae: 0x028d, 0x12af: 0x0290, + 0x12b0: 0x0290, 0x12b1: 0x0293, 0x12b2: 0x0293, 0x12b3: 0x0293, 0x12b4: 0x0293, 0x12b5: 0x2e17, + 0x12b6: 0x2e17, 0x12b7: 0x2e1f, 0x12b8: 0x2e1f, 0x12b9: 0x2e27, 0x12ba: 0x2e27, 0x12bb: 0x1f88, + 0x12bc: 0x1f88, + // 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: 0x047a, 0x12e0: 0x047e, 0x12e1: 0x048a, 0x12e2: 0x049e, 0x12e3: 0x04a2, + 0x12e4: 0x0486, 0x12e5: 0x05ae, 0x12e6: 0x05a6, 0x12e7: 0x04ca, 0x12e8: 0x04d2, 0x12e9: 0x04da, + 0x12ea: 0x04e2, 0x12eb: 0x04ea, 0x12ec: 0x056e, 0x12ed: 0x0576, 0x12ee: 0x057e, 0x12ef: 0x0522, + 0x12f0: 0x05b2, 0x12f1: 0x04ce, 0x12f2: 0x04d6, 0x12f3: 0x04de, 0x12f4: 0x04e6, 0x12f5: 0x04ee, + 0x12f6: 0x04f2, 0x12f7: 0x04f6, 0x12f8: 0x04fa, 0x12f9: 0x04fe, 0x12fa: 0x0502, 0x12fb: 0x0506, + 0x12fc: 0x050a, 0x12fd: 0x050e, 0x12fe: 0x0512, 0x12ff: 0x0516, + // Block 0x4c, offset 0x1300 + 0x1300: 0x051a, 0x1301: 0x051e, 0x1302: 0x0526, 0x1303: 0x052a, 0x1304: 0x052e, 0x1305: 0x0532, + 0x1306: 0x0536, 0x1307: 0x053a, 0x1308: 0x053e, 0x1309: 0x0542, 0x130a: 0x0546, 0x130b: 0x054a, + 0x130c: 0x054e, 0x130d: 0x0552, 0x130e: 0x0556, 0x130f: 0x055a, 0x1310: 0x055e, 0x1311: 0x0562, + 0x1312: 0x0566, 0x1313: 0x056a, 0x1314: 0x0572, 0x1315: 0x057a, 0x1316: 0x0582, 0x1317: 0x0586, + 0x1318: 0x058a, 0x1319: 0x058e, 0x131a: 0x0592, 0x131b: 0x0596, 0x131c: 0x059a, 0x131d: 0x05aa, + 0x131e: 0x4a8f, 0x131f: 0x4a95, 0x1320: 0x03c6, 0x1321: 0x0316, 0x1322: 0x031a, 0x1323: 0x4a52, + 0x1324: 0x031e, 0x1325: 0x4a58, 0x1326: 0x4a5e, 0x1327: 0x0322, 0x1328: 0x0326, 0x1329: 0x032a, + 0x132a: 0x4a64, 0x132b: 0x4a6a, 0x132c: 0x4a70, 0x132d: 0x4a76, 0x132e: 0x4a7c, 0x132f: 0x4a82, + 0x1330: 0x036a, 0x1331: 0x032e, 0x1332: 0x0332, 0x1333: 0x0336, 0x1334: 0x037e, 0x1335: 0x033a, + 0x1336: 0x033e, 0x1337: 0x0342, 0x1338: 0x0346, 0x1339: 0x034a, 0x133a: 0x034e, 0x133b: 0x0352, + 0x133c: 0x0356, 0x133d: 0x035a, 0x133e: 0x035e, + // Block 0x4d, offset 0x1340 + 0x1342: 0x49d4, 0x1343: 0x49da, 0x1344: 0x49e0, 0x1345: 0x49e6, + 0x1346: 0x49ec, 0x1347: 0x49f2, 0x134a: 0x49f8, 0x134b: 0x49fe, + 0x134c: 0x4a04, 0x134d: 0x4a0a, 0x134e: 0x4a10, 0x134f: 0x4a16, + 0x1352: 0x4a1c, 0x1353: 0x4a22, 0x1354: 0x4a28, 0x1355: 0x4a2e, 0x1356: 0x4a34, 0x1357: 0x4a3a, + 0x135a: 0x4a40, 0x135b: 0x4a46, 0x135c: 0x4a4c, + 0x1360: 0x00bf, 0x1361: 0x00c2, 0x1362: 0x00cb, 0x1363: 0x427b, + 0x1364: 0x00c8, 0x1365: 0x00c5, 0x1366: 0x044a, 0x1368: 0x046e, 0x1369: 0x044e, + 0x136a: 0x0452, 0x136b: 0x0456, 0x136c: 0x045a, 0x136d: 0x0472, 0x136e: 0x0476, + // 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: 0x0176, 0x13a9: 0x0179, + 0x13aa: 0x017c, 0x13ab: 0x017f, 0x13ac: 0x0182, 0x13ad: 0x0185, 0x13ae: 0x0188, 0x13af: 0x018b, + 0x13b0: 0x018e, 0x13b1: 0x0191, 0x13b2: 0x0194, 0x13b3: 0x0197, 0x13b4: 0x019a, 0x13b5: 0x019d, + 0x13b6: 0x01a0, 0x13b7: 0x01a3, 0x13b8: 0x01a6, 0x13b9: 0x018b, 0x13ba: 0x01a9, 0x13bb: 0x01ac, + 0x13bc: 0x01af, 0x13bd: 0x01b2, 0x13be: 0x01b5, 0x13bf: 0x01b8, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x0200, 0x13c1: 0x0203, 0x13c2: 0x0206, 0x13c3: 0x045e, 0x13c4: 0x01ca, 0x13c5: 0x01d3, + 0x13c6: 0x01d9, 0x13c7: 0x01fd, 0x13c8: 0x01ee, 0x13c9: 0x01eb, 0x13ca: 0x0209, 0x13cb: 0x020c, + 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: 0x023c, 0x1401: 0x023f, 0x1402: 0x024b, 0x1403: 0x0254, 0x1405: 0x028d, + 0x1406: 0x025d, 0x1407: 0x024e, 0x1408: 0x026c, 0x1409: 0x0293, 0x140a: 0x027e, 0x140b: 0x0281, + 0x140c: 0x0284, 0x140d: 0x0287, 0x140e: 0x0260, 0x140f: 0x0272, 0x1410: 0x0278, 0x1411: 0x0266, + 0x1412: 0x027b, 0x1413: 0x025a, 0x1414: 0x0263, 0x1415: 0x0245, 0x1416: 0x0248, 0x1417: 0x0251, + 0x1418: 0x0257, 0x1419: 0x0269, 0x141a: 0x026f, 0x141b: 0x0275, 0x141c: 0x0296, 0x141d: 0x02e7, + 0x141e: 0x02cf, 0x141f: 0x0299, 0x1421: 0x023f, 0x1422: 0x024b, + 0x1424: 0x028a, 0x1427: 0x024e, 0x1429: 0x0293, + 0x142a: 0x027e, 0x142b: 0x0281, 0x142c: 0x0284, 0x142d: 0x0287, 0x142e: 0x0260, 0x142f: 0x0272, + 0x1430: 0x0278, 0x1431: 0x0266, 0x1432: 0x027b, 0x1434: 0x0263, 0x1435: 0x0245, + 0x1436: 0x0248, 0x1437: 0x0251, 0x1439: 0x0269, 0x143b: 0x0275, + // Block 0x51, offset 0x1440 + 0x1442: 0x024b, + 0x1447: 0x024e, 0x1449: 0x0293, 0x144b: 0x0281, + 0x144d: 0x0287, 0x144e: 0x0260, 0x144f: 0x0272, 0x1451: 0x0266, + 0x1452: 0x027b, 0x1454: 0x0263, 0x1457: 0x0251, + 0x1459: 0x0269, 0x145b: 0x0275, 0x145d: 0x02e7, + 0x145f: 0x0299, 0x1461: 0x023f, 0x1462: 0x024b, + 0x1464: 0x028a, 0x1467: 0x024e, 0x1468: 0x026c, 0x1469: 0x0293, + 0x146a: 0x027e, 0x146c: 0x0284, 0x146d: 0x0287, 0x146e: 0x0260, 0x146f: 0x0272, + 0x1470: 0x0278, 0x1471: 0x0266, 0x1472: 0x027b, 0x1474: 0x0263, 0x1475: 0x0245, + 0x1476: 0x0248, 0x1477: 0x0251, 0x1479: 0x0269, 0x147a: 0x026f, 0x147b: 0x0275, + 0x147c: 0x0296, 0x147e: 0x02cf, + // Block 0x52, offset 0x1480 + 0x1480: 0x023c, 0x1481: 0x023f, 0x1482: 0x024b, 0x1483: 0x0254, 0x1484: 0x028a, 0x1485: 0x028d, + 0x1486: 0x025d, 0x1487: 0x024e, 0x1488: 0x026c, 0x1489: 0x0293, 0x148b: 0x0281, + 0x148c: 0x0284, 0x148d: 0x0287, 0x148e: 0x0260, 0x148f: 0x0272, 0x1490: 0x0278, 0x1491: 0x0266, + 0x1492: 0x027b, 0x1493: 0x025a, 0x1494: 0x0263, 0x1495: 0x0245, 0x1496: 0x0248, 0x1497: 0x0251, + 0x1498: 0x0257, 0x1499: 0x0269, 0x149a: 0x026f, 0x149b: 0x0275, + 0x14a1: 0x023f, 0x14a2: 0x024b, 0x14a3: 0x0254, + 0x14a5: 0x028d, 0x14a6: 0x025d, 0x14a7: 0x024e, 0x14a8: 0x026c, 0x14a9: 0x0293, + 0x14ab: 0x0281, 0x14ac: 0x0284, 0x14ad: 0x0287, 0x14ae: 0x0260, 0x14af: 0x0272, + 0x14b0: 0x0278, 0x14b1: 0x0266, 0x14b2: 0x027b, 0x14b3: 0x025a, 0x14b4: 0x0263, 0x14b5: 0x0245, + 0x14b6: 0x0248, 0x14b7: 0x0251, 0x14b8: 0x0257, 0x14b9: 0x0269, 0x14ba: 0x026f, 0x14bb: 0x0275, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x187c, 0x14c1: 0x1879, 0x14c2: 0x187f, 0x14c3: 0x18a3, 0x14c4: 0x18c7, 0x14c5: 0x18eb, + 0x14c6: 0x190f, 0x14c7: 0x1918, 0x14c8: 0x191e, 0x14c9: 0x1924, 0x14ca: 0x192a, + 0x14d0: 0x1a92, 0x14d1: 0x1a96, + 0x14d2: 0x1a9a, 0x14d3: 0x1a9e, 0x14d4: 0x1aa2, 0x14d5: 0x1aa6, 0x14d6: 0x1aaa, 0x14d7: 0x1aae, + 0x14d8: 0x1ab2, 0x14d9: 0x1ab6, 0x14da: 0x1aba, 0x14db: 0x1abe, 0x14dc: 0x1ac2, 0x14dd: 0x1ac6, + 0x14de: 0x1aca, 0x14df: 0x1ace, 0x14e0: 0x1ad2, 0x14e1: 0x1ad6, 0x14e2: 0x1ada, 0x14e3: 0x1ade, + 0x14e4: 0x1ae2, 0x14e5: 0x1ae6, 0x14e6: 0x1aea, 0x14e7: 0x1aee, 0x14e8: 0x1af2, 0x14e9: 0x1af6, + 0x14ea: 0x272b, 0x14eb: 0x0047, 0x14ec: 0x0065, 0x14ed: 0x193f, 0x14ee: 0x19b7, + 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: 0x26b3, 0x1501: 0x26c8, 0x1502: 0x0506, + 0x1510: 0x0c12, 0x1511: 0x0a4a, + 0x1512: 0x08d6, 0x1513: 0x45db, 0x1514: 0x071e, 0x1515: 0x09f2, 0x1516: 0x1332, 0x1517: 0x0a02, + 0x1518: 0x072a, 0x1519: 0x0cda, 0x151a: 0x0eb2, 0x151b: 0x0cb2, 0x151c: 0x082a, 0x151d: 0x0b6e, + 0x151e: 0x07c2, 0x151f: 0x0cba, 0x1520: 0x0816, 0x1521: 0x111a, 0x1522: 0x0f86, 0x1523: 0x138e, + 0x1524: 0x09d6, 0x1525: 0x090e, 0x1526: 0x0e66, 0x1527: 0x0c1e, 0x1528: 0x0c4a, 0x1529: 0x06c2, + 0x152a: 0x06ce, 0x152b: 0x140e, 0x152c: 0x0ade, 0x152d: 0x06ea, 0x152e: 0x08f2, 0x152f: 0x0c3e, + 0x1530: 0x13b6, 0x1531: 0x0c16, 0x1532: 0x1072, 0x1533: 0x10ae, 0x1534: 0x08fa, 0x1535: 0x0e46, + 0x1536: 0x0d0e, 0x1537: 0x0d0a, 0x1538: 0x0f9a, 0x1539: 0x082e, 0x153a: 0x095a, 0x153b: 0x1446, + // Block 0x55, offset 0x1540 + 0x1540: 0x06fe, 0x1541: 0x06f6, 0x1542: 0x0706, 0x1543: 0x164a, 0x1544: 0x074a, 0x1545: 0x075a, + 0x1546: 0x075e, 0x1547: 0x0766, 0x1548: 0x076e, 0x1549: 0x0772, 0x154a: 0x077e, 0x154b: 0x0776, + 0x154c: 0x05b6, 0x154d: 0x165e, 0x154e: 0x0792, 0x154f: 0x0796, 0x1550: 0x079a, 0x1551: 0x07b6, + 0x1552: 0x164f, 0x1553: 0x05ba, 0x1554: 0x07a2, 0x1555: 0x07c2, 0x1556: 0x1659, 0x1557: 0x07d2, + 0x1558: 0x07da, 0x1559: 0x073a, 0x155a: 0x07e2, 0x155b: 0x07e6, 0x155c: 0x1834, 0x155d: 0x0802, + 0x155e: 0x080a, 0x155f: 0x05c2, 0x1560: 0x0822, 0x1561: 0x0826, 0x1562: 0x082e, 0x1563: 0x0832, + 0x1564: 0x05c6, 0x1565: 0x084a, 0x1566: 0x084e, 0x1567: 0x085a, 0x1568: 0x0866, 0x1569: 0x086a, + 0x156a: 0x086e, 0x156b: 0x0876, 0x156c: 0x0896, 0x156d: 0x089a, 0x156e: 0x08a2, 0x156f: 0x08b2, + 0x1570: 0x08ba, 0x1571: 0x08be, 0x1572: 0x08be, 0x1573: 0x08be, 0x1574: 0x166d, 0x1575: 0x0e96, + 0x1576: 0x08d2, 0x1577: 0x08da, 0x1578: 0x1672, 0x1579: 0x08e6, 0x157a: 0x08ee, 0x157b: 0x08f6, + 0x157c: 0x091e, 0x157d: 0x090a, 0x157e: 0x0916, 0x157f: 0x091a, + // Block 0x56, offset 0x1580 + 0x1580: 0x0922, 0x1581: 0x092a, 0x1582: 0x092e, 0x1583: 0x0936, 0x1584: 0x093e, 0x1585: 0x0942, + 0x1586: 0x0942, 0x1587: 0x094a, 0x1588: 0x0952, 0x1589: 0x0956, 0x158a: 0x0962, 0x158b: 0x0986, + 0x158c: 0x096a, 0x158d: 0x098a, 0x158e: 0x096e, 0x158f: 0x0976, 0x1590: 0x080e, 0x1591: 0x09d2, + 0x1592: 0x099a, 0x1593: 0x099e, 0x1594: 0x09a2, 0x1595: 0x0996, 0x1596: 0x09aa, 0x1597: 0x09a6, + 0x1598: 0x09be, 0x1599: 0x1677, 0x159a: 0x09da, 0x159b: 0x09de, 0x159c: 0x09e6, 0x159d: 0x09f2, + 0x159e: 0x09fa, 0x159f: 0x0a16, 0x15a0: 0x167c, 0x15a1: 0x1681, 0x15a2: 0x0a22, 0x15a3: 0x0a26, + 0x15a4: 0x0a2a, 0x15a5: 0x0a1e, 0x15a6: 0x0a32, 0x15a7: 0x05ca, 0x15a8: 0x05ce, 0x15a9: 0x0a3a, + 0x15aa: 0x0a42, 0x15ab: 0x0a42, 0x15ac: 0x1686, 0x15ad: 0x0a5e, 0x15ae: 0x0a62, 0x15af: 0x0a66, + 0x15b0: 0x0a6e, 0x15b1: 0x168b, 0x15b2: 0x0a76, 0x15b3: 0x0a7a, 0x15b4: 0x0b52, 0x15b5: 0x0a82, + 0x15b6: 0x05d2, 0x15b7: 0x0a8e, 0x15b8: 0x0a9e, 0x15b9: 0x0aaa, 0x15ba: 0x0aa6, 0x15bb: 0x1695, + 0x15bc: 0x0ab2, 0x15bd: 0x169a, 0x15be: 0x0abe, 0x15bf: 0x0aba, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x0ac2, 0x15c1: 0x0ad2, 0x15c2: 0x0ad6, 0x15c3: 0x05d6, 0x15c4: 0x0ae6, 0x15c5: 0x0aee, + 0x15c6: 0x0af2, 0x15c7: 0x0af6, 0x15c8: 0x05da, 0x15c9: 0x169f, 0x15ca: 0x05de, 0x15cb: 0x0b12, + 0x15cc: 0x0b16, 0x15cd: 0x0b1a, 0x15ce: 0x0b22, 0x15cf: 0x1866, 0x15d0: 0x0b3a, 0x15d1: 0x16a9, + 0x15d2: 0x16a9, 0x15d3: 0x11da, 0x15d4: 0x0b4a, 0x15d5: 0x0b4a, 0x15d6: 0x05e2, 0x15d7: 0x16cc, + 0x15d8: 0x179e, 0x15d9: 0x0b5a, 0x15da: 0x0b62, 0x15db: 0x05e6, 0x15dc: 0x0b76, 0x15dd: 0x0b86, + 0x15de: 0x0b8a, 0x15df: 0x0b92, 0x15e0: 0x0ba2, 0x15e1: 0x05ee, 0x15e2: 0x05ea, 0x15e3: 0x0ba6, + 0x15e4: 0x16ae, 0x15e5: 0x0baa, 0x15e6: 0x0bbe, 0x15e7: 0x0bc2, 0x15e8: 0x0bc6, 0x15e9: 0x0bc2, + 0x15ea: 0x0bd2, 0x15eb: 0x0bd6, 0x15ec: 0x0be6, 0x15ed: 0x0bde, 0x15ee: 0x0be2, 0x15ef: 0x0bea, + 0x15f0: 0x0bee, 0x15f1: 0x0bf2, 0x15f2: 0x0bfe, 0x15f3: 0x0c02, 0x15f4: 0x0c1a, 0x15f5: 0x0c22, + 0x15f6: 0x0c32, 0x15f7: 0x0c46, 0x15f8: 0x16bd, 0x15f9: 0x0c42, 0x15fa: 0x0c36, 0x15fb: 0x0c4e, + 0x15fc: 0x0c56, 0x15fd: 0x0c6a, 0x15fe: 0x16c2, 0x15ff: 0x0c72, + // Block 0x58, offset 0x1600 + 0x1600: 0x0c66, 0x1601: 0x0c5e, 0x1602: 0x05f2, 0x1603: 0x0c7a, 0x1604: 0x0c82, 0x1605: 0x0c8a, + 0x1606: 0x0c7e, 0x1607: 0x05f6, 0x1608: 0x0c9a, 0x1609: 0x0ca2, 0x160a: 0x16c7, 0x160b: 0x0cce, + 0x160c: 0x0d02, 0x160d: 0x0cde, 0x160e: 0x0602, 0x160f: 0x0cea, 0x1610: 0x05fe, 0x1611: 0x05fa, + 0x1612: 0x07c6, 0x1613: 0x07ca, 0x1614: 0x0d06, 0x1615: 0x0cee, 0x1616: 0x11ae, 0x1617: 0x0666, + 0x1618: 0x0d12, 0x1619: 0x0d16, 0x161a: 0x0d1a, 0x161b: 0x0d2e, 0x161c: 0x0d26, 0x161d: 0x16e0, + 0x161e: 0x0606, 0x161f: 0x0d42, 0x1620: 0x0d36, 0x1621: 0x0d52, 0x1622: 0x0d5a, 0x1623: 0x16ea, + 0x1624: 0x0d5e, 0x1625: 0x0d4a, 0x1626: 0x0d66, 0x1627: 0x060a, 0x1628: 0x0d6a, 0x1629: 0x0d6e, + 0x162a: 0x0d72, 0x162b: 0x0d7e, 0x162c: 0x16ef, 0x162d: 0x0d86, 0x162e: 0x060e, 0x162f: 0x0d92, + 0x1630: 0x16f4, 0x1631: 0x0d96, 0x1632: 0x0612, 0x1633: 0x0da2, 0x1634: 0x0dae, 0x1635: 0x0dba, + 0x1636: 0x0dbe, 0x1637: 0x16f9, 0x1638: 0x1690, 0x1639: 0x16fe, 0x163a: 0x0dde, 0x163b: 0x1703, + 0x163c: 0x0dea, 0x163d: 0x0df2, 0x163e: 0x0de2, 0x163f: 0x0dfe, + // Block 0x59, offset 0x1640 + 0x1640: 0x0e0e, 0x1641: 0x0e1e, 0x1642: 0x0e12, 0x1643: 0x0e16, 0x1644: 0x0e22, 0x1645: 0x0e26, + 0x1646: 0x1708, 0x1647: 0x0e0a, 0x1648: 0x0e3e, 0x1649: 0x0e42, 0x164a: 0x0616, 0x164b: 0x0e56, + 0x164c: 0x0e52, 0x164d: 0x170d, 0x164e: 0x0e36, 0x164f: 0x0e72, 0x1650: 0x1712, 0x1651: 0x1717, + 0x1652: 0x0e76, 0x1653: 0x0e8a, 0x1654: 0x0e86, 0x1655: 0x0e82, 0x1656: 0x061a, 0x1657: 0x0e8e, + 0x1658: 0x0e9e, 0x1659: 0x0e9a, 0x165a: 0x0ea6, 0x165b: 0x1654, 0x165c: 0x0eb6, 0x165d: 0x171c, + 0x165e: 0x0ec2, 0x165f: 0x1726, 0x1660: 0x0ed6, 0x1661: 0x0ee2, 0x1662: 0x0ef6, 0x1663: 0x172b, + 0x1664: 0x0f0a, 0x1665: 0x0f0e, 0x1666: 0x1730, 0x1667: 0x1735, 0x1668: 0x0f2a, 0x1669: 0x0f3a, + 0x166a: 0x061e, 0x166b: 0x0f3e, 0x166c: 0x0622, 0x166d: 0x0622, 0x166e: 0x0f56, 0x166f: 0x0f5a, + 0x1670: 0x0f62, 0x1671: 0x0f66, 0x1672: 0x0f72, 0x1673: 0x0626, 0x1674: 0x0f8a, 0x1675: 0x173a, + 0x1676: 0x0fa6, 0x1677: 0x173f, 0x1678: 0x0fb2, 0x1679: 0x16a4, 0x167a: 0x0fc2, 0x167b: 0x1744, + 0x167c: 0x1749, 0x167d: 0x174e, 0x167e: 0x062a, 0x167f: 0x062e, + // Block 0x5a, offset 0x1680 + 0x1680: 0x0ffa, 0x1681: 0x1758, 0x1682: 0x1753, 0x1683: 0x175d, 0x1684: 0x1762, 0x1685: 0x1002, + 0x1686: 0x1006, 0x1687: 0x1006, 0x1688: 0x100e, 0x1689: 0x0636, 0x168a: 0x1012, 0x168b: 0x063a, + 0x168c: 0x063e, 0x168d: 0x176c, 0x168e: 0x1026, 0x168f: 0x102e, 0x1690: 0x103a, 0x1691: 0x0642, + 0x1692: 0x1771, 0x1693: 0x105e, 0x1694: 0x1776, 0x1695: 0x177b, 0x1696: 0x107e, 0x1697: 0x1096, + 0x1698: 0x0646, 0x1699: 0x109e, 0x169a: 0x10a2, 0x169b: 0x10a6, 0x169c: 0x1780, 0x169d: 0x1785, + 0x169e: 0x1785, 0x169f: 0x10be, 0x16a0: 0x064a, 0x16a1: 0x178a, 0x16a2: 0x10d2, 0x16a3: 0x10d6, + 0x16a4: 0x064e, 0x16a5: 0x178f, 0x16a6: 0x10f2, 0x16a7: 0x0652, 0x16a8: 0x1102, 0x16a9: 0x10fa, + 0x16aa: 0x110a, 0x16ab: 0x1799, 0x16ac: 0x1122, 0x16ad: 0x0656, 0x16ae: 0x112e, 0x16af: 0x1136, + 0x16b0: 0x1146, 0x16b1: 0x065a, 0x16b2: 0x17a3, 0x16b3: 0x17a8, 0x16b4: 0x065e, 0x16b5: 0x17ad, + 0x16b6: 0x115e, 0x16b7: 0x17b2, 0x16b8: 0x116a, 0x16b9: 0x1176, 0x16ba: 0x117e, 0x16bb: 0x17b7, + 0x16bc: 0x17bc, 0x16bd: 0x1192, 0x16be: 0x17c1, 0x16bf: 0x119a, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x16d1, 0x16c1: 0x0662, 0x16c2: 0x11b2, 0x16c3: 0x11b6, 0x16c4: 0x066a, 0x16c5: 0x11ba, + 0x16c6: 0x0a36, 0x16c7: 0x17c6, 0x16c8: 0x17cb, 0x16c9: 0x16d6, 0x16ca: 0x16db, 0x16cb: 0x11da, + 0x16cc: 0x11de, 0x16cd: 0x13f6, 0x16ce: 0x066e, 0x16cf: 0x120a, 0x16d0: 0x1206, 0x16d1: 0x120e, + 0x16d2: 0x0842, 0x16d3: 0x1212, 0x16d4: 0x1216, 0x16d5: 0x121a, 0x16d6: 0x1222, 0x16d7: 0x17d0, + 0x16d8: 0x121e, 0x16d9: 0x1226, 0x16da: 0x123a, 0x16db: 0x123e, 0x16dc: 0x122a, 0x16dd: 0x1242, + 0x16de: 0x1256, 0x16df: 0x126a, 0x16e0: 0x1236, 0x16e1: 0x124a, 0x16e2: 0x124e, 0x16e3: 0x1252, + 0x16e4: 0x17d5, 0x16e5: 0x17df, 0x16e6: 0x17da, 0x16e7: 0x0672, 0x16e8: 0x1272, 0x16e9: 0x1276, + 0x16ea: 0x127e, 0x16eb: 0x17f3, 0x16ec: 0x1282, 0x16ed: 0x17e4, 0x16ee: 0x0676, 0x16ef: 0x067a, + 0x16f0: 0x17e9, 0x16f1: 0x17ee, 0x16f2: 0x067e, 0x16f3: 0x12a2, 0x16f4: 0x12a6, 0x16f5: 0x12aa, + 0x16f6: 0x12ae, 0x16f7: 0x12ba, 0x16f8: 0x12b6, 0x16f9: 0x12c2, 0x16fa: 0x12be, 0x16fb: 0x12ce, + 0x16fc: 0x12c6, 0x16fd: 0x12ca, 0x16fe: 0x12d2, 0x16ff: 0x0682, + // Block 0x5c, offset 0x1700 + 0x1700: 0x12da, 0x1701: 0x12de, 0x1702: 0x0686, 0x1703: 0x12ee, 0x1704: 0x12f2, 0x1705: 0x17f8, + 0x1706: 0x12fe, 0x1707: 0x1302, 0x1708: 0x068a, 0x1709: 0x130e, 0x170a: 0x05be, 0x170b: 0x17fd, + 0x170c: 0x1802, 0x170d: 0x068e, 0x170e: 0x0692, 0x170f: 0x133a, 0x1710: 0x1352, 0x1711: 0x136e, + 0x1712: 0x137e, 0x1713: 0x1807, 0x1714: 0x1392, 0x1715: 0x1396, 0x1716: 0x13ae, 0x1717: 0x13ba, + 0x1718: 0x1811, 0x1719: 0x1663, 0x171a: 0x13c6, 0x171b: 0x13c2, 0x171c: 0x13ce, 0x171d: 0x1668, + 0x171e: 0x13da, 0x171f: 0x13e6, 0x1720: 0x1816, 0x1721: 0x181b, 0x1722: 0x1426, 0x1723: 0x1432, + 0x1724: 0x143a, 0x1725: 0x1820, 0x1726: 0x143e, 0x1727: 0x146a, 0x1728: 0x1476, 0x1729: 0x147a, + 0x172a: 0x1472, 0x172b: 0x1486, 0x172c: 0x148a, 0x172d: 0x1825, 0x172e: 0x1496, 0x172f: 0x0696, + 0x1730: 0x149e, 0x1731: 0x182a, 0x1732: 0x069a, 0x1733: 0x14d6, 0x1734: 0x0ac6, 0x1735: 0x14ee, + 0x1736: 0x182f, 0x1737: 0x1839, 0x1738: 0x069e, 0x1739: 0x06a2, 0x173a: 0x1516, 0x173b: 0x183e, + 0x173c: 0x06a6, 0x173d: 0x1843, 0x173e: 0x152e, 0x173f: 0x152e, + // Block 0x5d, offset 0x1740 + 0x1740: 0x1536, 0x1741: 0x1848, 0x1742: 0x154e, 0x1743: 0x06aa, 0x1744: 0x155e, 0x1745: 0x156a, + 0x1746: 0x1572, 0x1747: 0x157a, 0x1748: 0x06ae, 0x1749: 0x184d, 0x174a: 0x158e, 0x174b: 0x15aa, + 0x174c: 0x15b6, 0x174d: 0x06b2, 0x174e: 0x06b6, 0x174f: 0x15ba, 0x1750: 0x1852, 0x1751: 0x06ba, + 0x1752: 0x1857, 0x1753: 0x185c, 0x1754: 0x1861, 0x1755: 0x15de, 0x1756: 0x06be, 0x1757: 0x15f2, + 0x1758: 0x15fa, 0x1759: 0x15fe, 0x175a: 0x1606, 0x175b: 0x160e, 0x175c: 0x1616, 0x175d: 0x186b, +} + +// 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, 0x16b: 0x92, 0x16c: 0x0f, 0x16d: 0x93, 0x16e: 0x94, 0x16f: 0x95, + 0x170: 0x96, 0x173: 0x97, 0x174: 0x98, 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: 0x99, 0x181: 0x9a, 0x182: 0x9b, 0x183: 0x9c, 0x184: 0x1b, 0x185: 0x1c, 0x186: 0x9d, 0x187: 0x9e, + 0x188: 0x9f, 0x189: 0x1d, 0x18a: 0x1e, 0x18b: 0xa0, 0x18c: 0xa1, + 0x191: 0x1f, 0x192: 0x20, 0x193: 0xa2, + 0x1a8: 0xa3, 0x1a9: 0xa4, 0x1ab: 0xa5, + 0x1b1: 0xa6, 0x1b3: 0xa7, 0x1b5: 0xa8, 0x1b7: 0xa9, + 0x1ba: 0xaa, 0x1bb: 0xab, 0x1bc: 0x21, 0x1bd: 0x22, 0x1be: 0x23, 0x1bf: 0xac, + // Block 0x7, offset 0x1c0 + 0x1c0: 0xad, 0x1c1: 0x24, 0x1c2: 0x25, 0x1c3: 0x26, 0x1c4: 0xae, 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: 0xaf, 0x21a: 0xb0, 0x21b: 0xb1, 0x21d: 0xb2, 0x21f: 0xb3, + 0x220: 0xb4, 0x223: 0xb5, 0x224: 0xb6, 0x225: 0xb7, 0x226: 0xb8, 0x227: 0xb9, + 0x22a: 0xba, 0x22b: 0xbb, 0x22d: 0xbc, 0x22f: 0xbd, + 0x230: 0xbe, 0x231: 0xbf, 0x232: 0xc0, 0x233: 0xc1, 0x234: 0xc2, 0x235: 0xc3, 0x236: 0xc4, 0x237: 0xbe, + 0x238: 0xbf, 0x239: 0xc0, 0x23a: 0xc1, 0x23b: 0xc2, 0x23c: 0xc3, 0x23d: 0xc4, 0x23e: 0xbe, 0x23f: 0xbf, + // Block 0x9, offset 0x240 + 0x240: 0xc0, 0x241: 0xc1, 0x242: 0xc2, 0x243: 0xc3, 0x244: 0xc4, 0x245: 0xbe, 0x246: 0xbf, 0x247: 0xc0, + 0x248: 0xc1, 0x249: 0xc2, 0x24a: 0xc3, 0x24b: 0xc4, 0x24c: 0xbe, 0x24d: 0xbf, 0x24e: 0xc0, 0x24f: 0xc1, + 0x250: 0xc2, 0x251: 0xc3, 0x252: 0xc4, 0x253: 0xbe, 0x254: 0xbf, 0x255: 0xc0, 0x256: 0xc1, 0x257: 0xc2, + 0x258: 0xc3, 0x259: 0xc4, 0x25a: 0xbe, 0x25b: 0xbf, 0x25c: 0xc0, 0x25d: 0xc1, 0x25e: 0xc2, 0x25f: 0xc3, + 0x260: 0xc4, 0x261: 0xbe, 0x262: 0xbf, 0x263: 0xc0, 0x264: 0xc1, 0x265: 0xc2, 0x266: 0xc3, 0x267: 0xc4, + 0x268: 0xbe, 0x269: 0xbf, 0x26a: 0xc0, 0x26b: 0xc1, 0x26c: 0xc2, 0x26d: 0xc3, 0x26e: 0xc4, 0x26f: 0xbe, + 0x270: 0xbf, 0x271: 0xc0, 0x272: 0xc1, 0x273: 0xc2, 0x274: 0xc3, 0x275: 0xc4, 0x276: 0xbe, 0x277: 0xbf, + 0x278: 0xc0, 0x279: 0xc1, 0x27a: 0xc2, 0x27b: 0xc3, 0x27c: 0xc4, 0x27d: 0xbe, 0x27e: 0xbf, 0x27f: 0xc0, + // Block 0xa, offset 0x280 + 0x280: 0xc1, 0x281: 0xc2, 0x282: 0xc3, 0x283: 0xc4, 0x284: 0xbe, 0x285: 0xbf, 0x286: 0xc0, 0x287: 0xc1, + 0x288: 0xc2, 0x289: 0xc3, 0x28a: 0xc4, 0x28b: 0xbe, 0x28c: 0xbf, 0x28d: 0xc0, 0x28e: 0xc1, 0x28f: 0xc2, + 0x290: 0xc3, 0x291: 0xc4, 0x292: 0xbe, 0x293: 0xbf, 0x294: 0xc0, 0x295: 0xc1, 0x296: 0xc2, 0x297: 0xc3, + 0x298: 0xc4, 0x299: 0xbe, 0x29a: 0xbf, 0x29b: 0xc0, 0x29c: 0xc1, 0x29d: 0xc2, 0x29e: 0xc3, 0x29f: 0xc4, + 0x2a0: 0xbe, 0x2a1: 0xbf, 0x2a2: 0xc0, 0x2a3: 0xc1, 0x2a4: 0xc2, 0x2a5: 0xc3, 0x2a6: 0xc4, 0x2a7: 0xbe, + 0x2a8: 0xbf, 0x2a9: 0xc0, 0x2aa: 0xc1, 0x2ab: 0xc2, 0x2ac: 0xc3, 0x2ad: 0xc4, 0x2ae: 0xbe, 0x2af: 0xbf, + 0x2b0: 0xc0, 0x2b1: 0xc1, 0x2b2: 0xc2, 0x2b3: 0xc3, 0x2b4: 0xc4, 0x2b5: 0xbe, 0x2b6: 0xbf, 0x2b7: 0xc0, + 0x2b8: 0xc1, 0x2b9: 0xc2, 0x2ba: 0xc3, 0x2bb: 0xc4, 0x2bc: 0xbe, 0x2bd: 0xbf, 0x2be: 0xc0, 0x2bf: 0xc1, + // Block 0xb, offset 0x2c0 + 0x2c0: 0xc2, 0x2c1: 0xc3, 0x2c2: 0xc4, 0x2c3: 0xbe, 0x2c4: 0xbf, 0x2c5: 0xc0, 0x2c6: 0xc1, 0x2c7: 0xc2, + 0x2c8: 0xc3, 0x2c9: 0xc4, 0x2ca: 0xbe, 0x2cb: 0xbf, 0x2cc: 0xc0, 0x2cd: 0xc1, 0x2ce: 0xc2, 0x2cf: 0xc3, + 0x2d0: 0xc4, 0x2d1: 0xbe, 0x2d2: 0xbf, 0x2d3: 0xc0, 0x2d4: 0xc1, 0x2d5: 0xc2, 0x2d6: 0xc3, 0x2d7: 0xc4, + 0x2d8: 0xbe, 0x2d9: 0xbf, 0x2da: 0xc0, 0x2db: 0xc1, 0x2dc: 0xc2, 0x2dd: 0xc3, 0x2de: 0xc5, + // 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: 0xc6, 0x33d: 0x49, 0x33e: 0x4a, 0x33f: 0x4b, + // Block 0xd, offset 0x340 + 0x347: 0xc7, + 0x34b: 0xc8, 0x34d: 0xc9, + 0x368: 0xca, 0x36b: 0xcb, + 0x374: 0xcc, + 0x37a: 0xcd, 0x37d: 0xce, + // Block 0xe, offset 0x380 + 0x381: 0xcf, 0x382: 0xd0, 0x384: 0xd1, 0x385: 0xb8, 0x387: 0xd2, + 0x388: 0xd3, 0x38b: 0xd4, 0x38c: 0xd5, 0x38d: 0xd6, + 0x391: 0xd7, 0x392: 0xd8, 0x393: 0xd9, 0x396: 0xda, 0x397: 0xdb, + 0x398: 0xdc, 0x39a: 0xdd, 0x39c: 0xde, + 0x3a0: 0xdf, 0x3a4: 0xe0, 0x3a5: 0xe1, 0x3a7: 0xe2, + 0x3a8: 0xe3, 0x3a9: 0xe4, 0x3aa: 0xe5, + 0x3b0: 0xdc, 0x3b5: 0xe6, 0x3b6: 0xe7, + // Block 0xf, offset 0x3c0 + 0x3eb: 0xe8, 0x3ec: 0xe9, + 0x3ff: 0xea, + // Block 0x10, offset 0x400 + 0x432: 0xeb, + // Block 0x11, offset 0x440 + 0x445: 0xec, 0x446: 0xed, 0x447: 0xee, + 0x449: 0xef, + 0x450: 0xf0, 0x451: 0xf1, 0x452: 0xf2, 0x453: 0xf3, 0x454: 0xf4, 0x455: 0xf5, 0x456: 0xf6, 0x457: 0xf7, + 0x458: 0xf8, 0x459: 0xf9, 0x45a: 0x4c, 0x45b: 0xfa, 0x45c: 0xfb, 0x45d: 0xfc, 0x45e: 0xfd, 0x45f: 0x4d, + // Block 0x12, offset 0x480 + 0x480: 0xfe, 0x484: 0xe9, + 0x48b: 0xff, + 0x4a3: 0x100, 0x4a5: 0x101, + 0x4b8: 0x4e, 0x4b9: 0x4f, 0x4ba: 0x50, + // Block 0x13, offset 0x4c0 + 0x4c4: 0x51, 0x4c5: 0x102, 0x4c6: 0x103, + 0x4c8: 0x52, 0x4c9: 0x104, + 0x4ef: 0x105, + // 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: 170 entries, 340 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, 0x134, 0x136, 0x13f, 0x141, 0x144, 0x146, 0x151, 0x15c, 0x16a, 0x178, 0x188, 0x196, 0x19d, 0x1a3, 0x1b2, 0x1b6, 0x1b8, 0x1bc, 0x1be, 0x1c1, 0x1c3, 0x1c6, 0x1c8, 0x1cb, 0x1cd, 0x1cf, 0x1d1, 0x1dd, 0x1e7, 0x1f1, 0x1f4, 0x1f8, 0x1fa, 0x1fc, 0x1fe, 0x201, 0x204, 0x206, 0x208, 0x20a, 0x20c, 0x212, 0x215, 0x21a, 0x21c, 0x223, 0x229, 0x22f, 0x237, 0x23d, 0x243, 0x249, 0x24d, 0x24f, 0x251, 0x253, 0x255, 0x25b, 0x25e, 0x260, 0x262, 0x268, 0x26b, 0x273, 0x27a, 0x27d, 0x280, 0x282, 0x285, 0x28d, 0x291, 0x298, 0x29b, 0x2a1, 0x2a3, 0x2a5, 0x2a8, 0x2aa, 0x2ad, 0x2b2, 0x2b4, 0x2b6, 0x2b8, 0x2ba, 0x2bc, 0x2bf, 0x2c1, 0x2c3, 0x2c5, 0x2c7, 0x2c9, 0x2d6, 0x2e0, 0x2e2, 0x2e4, 0x2e8, 0x2ed, 0x2f9, 0x2fe, 0x307, 0x30d, 0x312, 0x316, 0x31b, 0x31f, 0x32f, 0x33d, 0x34b, 0x359, 0x35f, 0x361, 0x363, 0x366, 0x371, 0x373, 0x37d} + +// nfkcSparseValues: 895 entries, 3580 bytes +var nfkcSparseValues = [895]valueRange{ + // Block 0x0, offset 0x0 + {value: 0x0002, lo: 0x0d}, + {value: 0x0001, lo: 0xa0, hi: 0xa0}, + {value: 0x428f, lo: 0xa8, hi: 0xa8}, + {value: 0x0083, lo: 0xaa, hi: 0xaa}, + {value: 0x427b, lo: 0xaf, hi: 0xaf}, + {value: 0x0025, lo: 0xb2, hi: 0xb3}, + {value: 0x4271, lo: 0xb4, hi: 0xb4}, + {value: 0x01df, lo: 0xb5, hi: 0xb5}, + {value: 0x42a8, lo: 0xb8, hi: 0xb8}, + {value: 0x0023, lo: 0xb9, hi: 0xb9}, + {value: 0x009f, lo: 0xba, hi: 0xba}, + {value: 0x2222, lo: 0xbc, hi: 0xbc}, + {value: 0x2216, lo: 0xbd, hi: 0xbd}, + {value: 0x22b8, lo: 0xbe, hi: 0xbe}, + // Block 0x1, offset 0xe + {value: 0x0091, lo: 0x03}, + {value: 0x46f9, lo: 0xa0, hi: 0xa1}, + {value: 0x472b, 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: 0x4285, lo: 0x98, hi: 0x98}, + {value: 0x428a, lo: 0x99, hi: 0x9a}, + {value: 0x42ad, lo: 0x9b, hi: 0x9b}, + {value: 0x4276, lo: 0x9c, hi: 0x9c}, + {value: 0x4299, lo: 0x9d, hi: 0x9d}, + {value: 0x0113, lo: 0xa0, hi: 0xa0}, + {value: 0x0099, lo: 0xa1, hi: 0xa1}, + {value: 0x00a7, lo: 0xa2, hi: 0xa3}, + {value: 0x016a, 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: 0x37bc, lo: 0x90, hi: 0x90}, + {value: 0x37c8, lo: 0x91, hi: 0x91}, + {value: 0x37b6, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x96, hi: 0x96}, + {value: 0x382e, lo: 0x97, hi: 0x97}, + {value: 0x37f8, lo: 0x9c, hi: 0x9c}, + {value: 0x37e0, lo: 0x9d, hi: 0x9d}, + {value: 0x380a, lo: 0x9e, hi: 0x9e}, + {value: 0xa000, lo: 0xb4, hi: 0xb5}, + {value: 0x3834, lo: 0xb6, hi: 0xb6}, + {value: 0x383a, lo: 0xb7, hi: 0xb7}, + // Block 0x5, offset 0x35 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0x83, hi: 0x87}, + // Block 0x6, offset 0x37 + {value: 0x0001, lo: 0x04}, + {value: 0x8114, lo: 0x81, hi: 0x82}, + {value: 0x8133, lo: 0x84, hi: 0x84}, + {value: 0x812e, lo: 0x85, hi: 0x85}, + {value: 0x810e, lo: 0x87, hi: 0x87}, + // Block 0x7, offset 0x3c + {value: 0x0000, lo: 0x0a}, + {value: 0x8133, lo: 0x90, hi: 0x97}, + {value: 0x811a, lo: 0x98, hi: 0x98}, + {value: 0x811b, lo: 0x99, hi: 0x99}, + {value: 0x811c, lo: 0x9a, hi: 0x9a}, + {value: 0x3858, lo: 0xa2, hi: 0xa2}, + {value: 0x385e, lo: 0xa3, hi: 0xa3}, + {value: 0x386a, lo: 0xa4, hi: 0xa4}, + {value: 0x3864, lo: 0xa5, hi: 0xa5}, + {value: 0x3870, lo: 0xa6, hi: 0xa6}, + {value: 0xa000, lo: 0xa7, hi: 0xa7}, + // Block 0x8, offset 0x47 + {value: 0x0000, lo: 0x0e}, + {value: 0x3882, lo: 0x80, hi: 0x80}, + {value: 0xa000, lo: 0x81, hi: 0x81}, + {value: 0x3876, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x387c, lo: 0x93, hi: 0x93}, + {value: 0xa000, lo: 0x95, hi: 0x95}, + {value: 0x8133, lo: 0x96, hi: 0x9c}, + {value: 0x8133, lo: 0x9f, hi: 0xa2}, + {value: 0x812e, lo: 0xa3, hi: 0xa3}, + {value: 0x8133, lo: 0xa4, hi: 0xa4}, + {value: 0x8133, lo: 0xa7, hi: 0xa8}, + {value: 0x812e, lo: 0xaa, hi: 0xaa}, + {value: 0x8133, lo: 0xab, hi: 0xac}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + // Block 0x9, offset 0x56 + {value: 0x0000, lo: 0x0c}, + {value: 0x8120, lo: 0x91, hi: 0x91}, + {value: 0x8133, lo: 0xb0, hi: 0xb0}, + {value: 0x812e, lo: 0xb1, hi: 0xb1}, + {value: 0x8133, lo: 0xb2, hi: 0xb3}, + {value: 0x812e, lo: 0xb4, hi: 0xb4}, + {value: 0x8133, lo: 0xb5, hi: 0xb6}, + {value: 0x812e, lo: 0xb7, hi: 0xb9}, + {value: 0x8133, lo: 0xba, hi: 0xba}, + {value: 0x812e, lo: 0xbb, hi: 0xbc}, + {value: 0x8133, lo: 0xbd, hi: 0xbd}, + {value: 0x812e, lo: 0xbe, hi: 0xbe}, + {value: 0x8133, lo: 0xbf, hi: 0xbf}, + // Block 0xa, offset 0x63 + {value: 0x0005, lo: 0x07}, + {value: 0x8133, lo: 0x80, hi: 0x80}, + {value: 0x8133, lo: 0x81, hi: 0x81}, + {value: 0x812e, lo: 0x82, hi: 0x83}, + {value: 0x812e, lo: 0x84, hi: 0x85}, + {value: 0x812e, lo: 0x86, hi: 0x87}, + {value: 0x812e, lo: 0x88, hi: 0x89}, + {value: 0x8133, lo: 0x8a, hi: 0x8a}, + // Block 0xb, offset 0x6b + {value: 0x0000, lo: 0x04}, + {value: 0x8133, lo: 0xab, hi: 0xb1}, + {value: 0x812e, lo: 0xb2, hi: 0xb2}, + {value: 0x8133, lo: 0xb3, hi: 0xb3}, + {value: 0x812e, lo: 0xbd, hi: 0xbd}, + // Block 0xc, offset 0x70 + {value: 0x0000, lo: 0x04}, + {value: 0x8133, lo: 0x96, hi: 0x99}, + {value: 0x8133, lo: 0x9b, hi: 0xa3}, + {value: 0x8133, lo: 0xa5, hi: 0xa7}, + {value: 0x8133, lo: 0xa9, hi: 0xad}, + // Block 0xd, offset 0x75 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x99, hi: 0x9b}, + // Block 0xe, offset 0x77 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0xa8, hi: 0xa8}, + {value: 0x3eef, lo: 0xa9, hi: 0xa9}, + {value: 0xa000, lo: 0xb0, hi: 0xb0}, + {value: 0x3ef7, lo: 0xb1, hi: 0xb1}, + {value: 0xa000, lo: 0xb3, hi: 0xb3}, + {value: 0x3eff, lo: 0xb4, hi: 0xb4}, + {value: 0x9903, lo: 0xbc, hi: 0xbc}, + // Block 0xf, offset 0x7f + {value: 0x0008, lo: 0x06}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x8133, lo: 0x91, hi: 0x91}, + {value: 0x812e, lo: 0x92, hi: 0x92}, + {value: 0x8133, lo: 0x93, hi: 0x93}, + {value: 0x8133, lo: 0x94, hi: 0x94}, + {value: 0x4533, lo: 0x98, hi: 0x9f}, + // Block 0x10, offset 0x86 + {value: 0x0000, lo: 0x02}, + {value: 0x8103, 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: 0x2cab, lo: 0x8b, hi: 0x8c}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x4573, lo: 0x9c, hi: 0x9d}, + {value: 0x4583, lo: 0x9f, hi: 0x9f}, + {value: 0x8133, lo: 0xbe, hi: 0xbe}, + // Block 0x12, offset 0x91 + {value: 0x0000, lo: 0x03}, + {value: 0x45ab, lo: 0xb3, hi: 0xb3}, + {value: 0x45b3, lo: 0xb6, hi: 0xb6}, + {value: 0x8103, lo: 0xbc, hi: 0xbc}, + // Block 0x13, offset 0x95 + {value: 0x0008, lo: 0x03}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x458b, lo: 0x99, hi: 0x9b}, + {value: 0x45a3, lo: 0x9e, hi: 0x9e}, + // Block 0x14, offset 0x99 + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0xbc, hi: 0xbc}, + // Block 0x15, offset 0x9b + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + // Block 0x16, offset 0x9d + {value: 0x0000, lo: 0x08}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2cc3, lo: 0x88, hi: 0x88}, + {value: 0x2cbb, lo: 0x8b, hi: 0x8b}, + {value: 0x2ccb, lo: 0x8c, hi: 0x8c}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x96, hi: 0x97}, + {value: 0x45bb, lo: 0x9c, hi: 0x9c}, + {value: 0x45c3, lo: 0x9d, hi: 0x9d}, + // Block 0x17, offset 0xa6 + {value: 0x0000, lo: 0x03}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0x2cd3, 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: 0x2cdb, lo: 0x8a, hi: 0x8a}, + {value: 0x2ceb, lo: 0x8b, hi: 0x8b}, + {value: 0x2ce3, lo: 0x8c, hi: 0x8c}, + {value: 0x8105, 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: 0x3f07, lo: 0x88, hi: 0x88}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x8121, lo: 0x95, hi: 0x96}, + // Block 0x1a, offset 0xb6 + {value: 0x0000, lo: 0x02}, + {value: 0x8103, lo: 0xbc, hi: 0xbc}, + {value: 0xa000, lo: 0xbf, hi: 0xbf}, + // Block 0x1b, offset 0xb9 + {value: 0x0000, lo: 0x09}, + {value: 0x2cf3, lo: 0x80, hi: 0x80}, + {value: 0x9900, lo: 0x82, hi: 0x82}, + {value: 0xa000, lo: 0x86, hi: 0x86}, + {value: 0x2cfb, lo: 0x87, hi: 0x87}, + {value: 0x2d03, lo: 0x88, hi: 0x88}, + {value: 0x2f67, lo: 0x8a, hi: 0x8a}, + {value: 0x2def, lo: 0x8b, hi: 0x8b}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x95, hi: 0x96}, + // Block 0x1c, offset 0xc3 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, 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: 0x2d0b, lo: 0x8a, hi: 0x8a}, + {value: 0x2d1b, lo: 0x8b, hi: 0x8b}, + {value: 0x2d13, lo: 0x8c, hi: 0x8c}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + // Block 0x1e, offset 0xcd + {value: 0x6bdd, lo: 0x07}, + {value: 0x9905, lo: 0x8a, hi: 0x8a}, + {value: 0x9900, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x3f0f, lo: 0x9a, hi: 0x9a}, + {value: 0x2f6f, lo: 0x9c, hi: 0x9c}, + {value: 0x2dfa, lo: 0x9d, hi: 0x9d}, + {value: 0x2d23, lo: 0x9e, hi: 0x9f}, + // Block 0x1f, offset 0xd5 + {value: 0x0000, lo: 0x03}, + {value: 0x2627, lo: 0xb3, hi: 0xb3}, + {value: 0x8123, lo: 0xb8, hi: 0xb9}, + {value: 0x8105, lo: 0xba, hi: 0xba}, + // Block 0x20, offset 0xd9 + {value: 0x0000, lo: 0x01}, + {value: 0x8124, lo: 0x88, hi: 0x8b}, + // Block 0x21, offset 0xdb + {value: 0x0000, lo: 0x03}, + {value: 0x263c, lo: 0xb3, hi: 0xb3}, + {value: 0x8125, lo: 0xb8, hi: 0xb9}, + {value: 0x8105, lo: 0xba, hi: 0xba}, + // Block 0x22, offset 0xdf + {value: 0x0000, lo: 0x03}, + {value: 0x8126, lo: 0x88, hi: 0x8b}, + {value: 0x262e, lo: 0x9c, hi: 0x9c}, + {value: 0x2635, lo: 0x9d, hi: 0x9d}, + // Block 0x23, offset 0xe3 + {value: 0x0000, lo: 0x05}, + {value: 0x030e, lo: 0x8c, hi: 0x8c}, + {value: 0x812e, lo: 0x98, hi: 0x99}, + {value: 0x812e, lo: 0xb5, hi: 0xb5}, + {value: 0x812e, lo: 0xb7, hi: 0xb7}, + {value: 0x812c, lo: 0xb9, hi: 0xb9}, + // Block 0x24, offset 0xe9 + {value: 0x0000, lo: 0x10}, + {value: 0x264a, lo: 0x83, hi: 0x83}, + {value: 0x2651, lo: 0x8d, hi: 0x8d}, + {value: 0x2658, lo: 0x92, hi: 0x92}, + {value: 0x265f, lo: 0x97, hi: 0x97}, + {value: 0x2666, lo: 0x9c, hi: 0x9c}, + {value: 0x2643, lo: 0xa9, hi: 0xa9}, + {value: 0x8127, lo: 0xb1, hi: 0xb1}, + {value: 0x8128, lo: 0xb2, hi: 0xb2}, + {value: 0x4a9b, lo: 0xb3, hi: 0xb3}, + {value: 0x8129, lo: 0xb4, hi: 0xb4}, + {value: 0x4aa4, lo: 0xb5, hi: 0xb5}, + {value: 0x45cb, lo: 0xb6, hi: 0xb6}, + {value: 0x460b, lo: 0xb7, hi: 0xb7}, + {value: 0x45d3, lo: 0xb8, hi: 0xb8}, + {value: 0x4616, lo: 0xb9, hi: 0xb9}, + {value: 0x8128, lo: 0xba, hi: 0xbd}, + // Block 0x25, offset 0xfa + {value: 0x0000, lo: 0x0b}, + {value: 0x8128, lo: 0x80, hi: 0x80}, + {value: 0x4aad, lo: 0x81, hi: 0x81}, + {value: 0x8133, lo: 0x82, hi: 0x83}, + {value: 0x8105, lo: 0x84, hi: 0x84}, + {value: 0x8133, lo: 0x86, hi: 0x87}, + {value: 0x2674, lo: 0x93, hi: 0x93}, + {value: 0x267b, lo: 0x9d, hi: 0x9d}, + {value: 0x2682, lo: 0xa2, hi: 0xa2}, + {value: 0x2689, lo: 0xa7, hi: 0xa7}, + {value: 0x2690, lo: 0xac, hi: 0xac}, + {value: 0x266d, lo: 0xb9, hi: 0xb9}, + // Block 0x26, offset 0x106 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x86, hi: 0x86}, + // Block 0x27, offset 0x108 + {value: 0x0000, lo: 0x05}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x2d2b, lo: 0xa6, hi: 0xa6}, + {value: 0x9900, lo: 0xae, hi: 0xae}, + {value: 0x8103, lo: 0xb7, hi: 0xb7}, + {value: 0x8105, lo: 0xb9, hi: 0xba}, + // Block 0x28, offset 0x10e + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x8d, hi: 0x8d}, + // Block 0x29, offset 0x110 + {value: 0x0000, lo: 0x01}, + {value: 0x0312, 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: 0x8133, lo: 0x9d, hi: 0x9f}, + // Block 0x2f, offset 0x11c + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x94, hi: 0x94}, + {value: 0x8105, lo: 0xb4, hi: 0xb4}, + // Block 0x30, offset 0x11f + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x92, hi: 0x92}, + {value: 0x8133, lo: 0x9d, hi: 0x9d}, + // Block 0x31, offset 0x122 + {value: 0x0000, lo: 0x01}, + {value: 0x8132, lo: 0xa9, hi: 0xa9}, + // Block 0x32, offset 0x124 + {value: 0x0004, lo: 0x02}, + {value: 0x812f, lo: 0xb9, hi: 0xba}, + {value: 0x812e, lo: 0xbb, hi: 0xbb}, + // Block 0x33, offset 0x127 + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0x97, hi: 0x97}, + {value: 0x812e, lo: 0x98, hi: 0x98}, + // Block 0x34, offset 0x12a + {value: 0x0000, lo: 0x03}, + {value: 0x8105, lo: 0xa0, hi: 0xa0}, + {value: 0x8133, lo: 0xb5, hi: 0xbc}, + {value: 0x812e, lo: 0xbf, hi: 0xbf}, + // Block 0x35, offset 0x12e + {value: 0x0000, lo: 0x05}, + {value: 0x8133, lo: 0xb0, hi: 0xb4}, + {value: 0x812e, lo: 0xb5, hi: 0xba}, + {value: 0x8133, lo: 0xbb, hi: 0xbc}, + {value: 0x812e, lo: 0xbd, hi: 0xbd}, + {value: 0x812e, lo: 0xbf, hi: 0xbf}, + // Block 0x36, offset 0x134 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x80, hi: 0x80}, + // Block 0x37, offset 0x136 + {value: 0x0000, lo: 0x08}, + {value: 0x2d73, lo: 0x80, hi: 0x80}, + {value: 0x2d7b, lo: 0x81, hi: 0x81}, + {value: 0xa000, lo: 0x82, hi: 0x82}, + {value: 0x2d83, lo: 0x83, hi: 0x83}, + {value: 0x8105, lo: 0x84, hi: 0x84}, + {value: 0x8133, lo: 0xab, hi: 0xab}, + {value: 0x812e, lo: 0xac, hi: 0xac}, + {value: 0x8133, lo: 0xad, hi: 0xb3}, + // Block 0x38, offset 0x13f + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xaa, hi: 0xab}, + // Block 0x39, offset 0x141 + {value: 0x0000, lo: 0x02}, + {value: 0x8103, lo: 0xa6, hi: 0xa6}, + {value: 0x8105, lo: 0xb2, hi: 0xb3}, + // Block 0x3a, offset 0x144 + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0xb7, hi: 0xb7}, + // Block 0x3b, offset 0x146 + {value: 0x0000, lo: 0x0a}, + {value: 0x8133, lo: 0x90, hi: 0x92}, + {value: 0x8101, lo: 0x94, hi: 0x94}, + {value: 0x812e, lo: 0x95, hi: 0x99}, + {value: 0x8133, lo: 0x9a, hi: 0x9b}, + {value: 0x812e, lo: 0x9c, hi: 0x9f}, + {value: 0x8133, lo: 0xa0, hi: 0xa0}, + {value: 0x8101, lo: 0xa2, hi: 0xa8}, + {value: 0x812e, lo: 0xad, hi: 0xad}, + {value: 0x8133, lo: 0xb4, hi: 0xb4}, + {value: 0x8133, lo: 0xb8, hi: 0xb9}, + // Block 0x3c, offset 0x151 + {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 0x3d, offset 0x15c + {value: 0x0000, lo: 0x0d}, + {value: 0x0001, lo: 0x80, hi: 0x8a}, + {value: 0x043e, lo: 0x91, hi: 0x91}, + {value: 0x42b2, lo: 0x97, hi: 0x97}, + {value: 0x001d, lo: 0xa4, hi: 0xa4}, + {value: 0x1876, lo: 0xa5, hi: 0xa5}, + {value: 0x1b62, lo: 0xa6, hi: 0xa6}, + {value: 0x0001, lo: 0xaf, hi: 0xaf}, + {value: 0x2697, lo: 0xb3, hi: 0xb3}, + {value: 0x280b, lo: 0xb4, hi: 0xb4}, + {value: 0x269e, lo: 0xb6, hi: 0xb6}, + {value: 0x2815, lo: 0xb7, hi: 0xb7}, + {value: 0x1870, lo: 0xbc, hi: 0xbc}, + {value: 0x4280, lo: 0xbe, hi: 0xbe}, + // Block 0x3e, offset 0x16a + {value: 0x0002, lo: 0x0d}, + {value: 0x1936, lo: 0x87, hi: 0x87}, + {value: 0x1933, lo: 0x88, hi: 0x88}, + {value: 0x1873, lo: 0x89, hi: 0x89}, + {value: 0x299b, 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: 0x046a, lo: 0xbb, hi: 0xbb}, + {value: 0x003b, lo: 0xbc, hi: 0xbc}, + {value: 0x0011, lo: 0xbd, hi: 0xbe}, + {value: 0x009d, lo: 0xbf, hi: 0xbf}, + // Block 0x3f, offset 0x178 + {value: 0x0002, lo: 0x0f}, + {value: 0x0021, lo: 0x80, hi: 0x89}, + {value: 0x0017, lo: 0x8a, hi: 0x8a}, + {value: 0x046a, 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: 0x199f, lo: 0xa8, hi: 0xa8}, + // Block 0x40, offset 0x188 + {value: 0x0000, lo: 0x0d}, + {value: 0x8133, lo: 0x90, hi: 0x91}, + {value: 0x8101, lo: 0x92, hi: 0x93}, + {value: 0x8133, lo: 0x94, hi: 0x97}, + {value: 0x8101, lo: 0x98, hi: 0x9a}, + {value: 0x8133, lo: 0x9b, hi: 0x9c}, + {value: 0x8133, lo: 0xa1, hi: 0xa1}, + {value: 0x8101, lo: 0xa5, hi: 0xa6}, + {value: 0x8133, lo: 0xa7, hi: 0xa7}, + {value: 0x812e, lo: 0xa8, hi: 0xa8}, + {value: 0x8133, lo: 0xa9, hi: 0xa9}, + {value: 0x8101, lo: 0xaa, hi: 0xab}, + {value: 0x812e, lo: 0xac, hi: 0xaf}, + {value: 0x8133, lo: 0xb0, hi: 0xb0}, + // Block 0x41, offset 0x196 + {value: 0x0007, lo: 0x06}, + {value: 0x2186, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + {value: 0x3bd0, lo: 0x9a, hi: 0x9b}, + {value: 0x3bde, lo: 0xae, hi: 0xae}, + // Block 0x42, offset 0x19d + {value: 0x000e, lo: 0x05}, + {value: 0x3be5, lo: 0x8d, hi: 0x8e}, + {value: 0x3bec, lo: 0x8f, hi: 0x8f}, + {value: 0xa000, lo: 0x90, hi: 0x90}, + {value: 0xa000, lo: 0x92, hi: 0x92}, + {value: 0xa000, lo: 0x94, hi: 0x94}, + // Block 0x43, offset 0x1a3 + {value: 0x017a, lo: 0x0e}, + {value: 0xa000, lo: 0x83, hi: 0x83}, + {value: 0x3bfa, lo: 0x84, hi: 0x84}, + {value: 0xa000, lo: 0x88, hi: 0x88}, + {value: 0x3c01, lo: 0x89, hi: 0x89}, + {value: 0xa000, lo: 0x8b, hi: 0x8b}, + {value: 0x3c08, lo: 0x8c, hi: 0x8c}, + {value: 0xa000, lo: 0xa3, hi: 0xa3}, + {value: 0x3c0f, lo: 0xa4, hi: 0xa4}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x3c16, lo: 0xa6, hi: 0xa6}, + {value: 0x26a5, lo: 0xac, hi: 0xad}, + {value: 0x26ac, lo: 0xaf, hi: 0xaf}, + {value: 0x2829, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xbc, hi: 0xbc}, + // Block 0x44, offset 0x1b2 + {value: 0x0007, lo: 0x03}, + {value: 0x3c7f, lo: 0xa0, hi: 0xa1}, + {value: 0x3ca9, lo: 0xa2, hi: 0xa3}, + {value: 0x3cd3, lo: 0xaa, hi: 0xad}, + // Block 0x45, offset 0x1b6 + {value: 0x0004, lo: 0x01}, + {value: 0x048e, lo: 0xa9, hi: 0xaa}, + // Block 0x46, offset 0x1b8 + {value: 0x0002, lo: 0x03}, + {value: 0x0057, lo: 0x80, hi: 0x8f}, + {value: 0x0083, lo: 0x90, hi: 0xa9}, + {value: 0x0021, lo: 0xaa, hi: 0xaa}, + // Block 0x47, offset 0x1bc + {value: 0x0000, lo: 0x01}, + {value: 0x29a8, lo: 0x8c, hi: 0x8c}, + // Block 0x48, offset 0x1be + {value: 0x0266, lo: 0x02}, + {value: 0x1b92, lo: 0xb4, hi: 0xb4}, + {value: 0x1930, lo: 0xb5, hi: 0xb6}, + // Block 0x49, offset 0x1c1 + {value: 0x0000, lo: 0x01}, + {value: 0x44f4, lo: 0x9c, hi: 0x9c}, + // Block 0x4a, offset 0x1c3 + {value: 0x0000, lo: 0x02}, + {value: 0x0095, lo: 0xbc, hi: 0xbc}, + {value: 0x006d, lo: 0xbd, hi: 0xbd}, + // Block 0x4b, offset 0x1c6 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xaf, hi: 0xb1}, + // Block 0x4c, offset 0x1c8 + {value: 0x0000, lo: 0x02}, + {value: 0x0482, lo: 0xaf, hi: 0xaf}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x4d, offset 0x1cb + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xa0, hi: 0xbf}, + // Block 0x4e, offset 0x1cd + {value: 0x0000, lo: 0x01}, + {value: 0x0dc6, lo: 0x9f, hi: 0x9f}, + // Block 0x4f, offset 0x1cf + {value: 0x0000, lo: 0x01}, + {value: 0x1632, lo: 0xb3, hi: 0xb3}, + // Block 0x50, offset 0x1d1 + {value: 0x0004, lo: 0x0b}, + {value: 0x159a, lo: 0x80, hi: 0x82}, + {value: 0x15b2, lo: 0x83, hi: 0x83}, + {value: 0x15ca, lo: 0x84, hi: 0x85}, + {value: 0x15da, lo: 0x86, hi: 0x89}, + {value: 0x15ee, lo: 0x8a, hi: 0x8c}, + {value: 0x1602, lo: 0x8d, hi: 0x8d}, + {value: 0x160a, lo: 0x8e, hi: 0x8e}, + {value: 0x1612, lo: 0x8f, hi: 0x90}, + {value: 0x161e, lo: 0x91, hi: 0x93}, + {value: 0x162e, lo: 0x94, hi: 0x94}, + {value: 0x1636, lo: 0x95, hi: 0x95}, + // Block 0x51, offset 0x1dd + {value: 0x0004, lo: 0x09}, + {value: 0x0001, lo: 0x80, hi: 0x80}, + {value: 0x812d, lo: 0xaa, hi: 0xaa}, + {value: 0x8132, lo: 0xab, hi: 0xab}, + {value: 0x8134, lo: 0xac, hi: 0xac}, + {value: 0x812f, lo: 0xad, hi: 0xad}, + {value: 0x8130, lo: 0xae, hi: 0xae}, + {value: 0x8130, lo: 0xaf, hi: 0xaf}, + {value: 0x04b6, lo: 0xb6, hi: 0xb6}, + {value: 0x088a, lo: 0xb8, hi: 0xba}, + // Block 0x52, offset 0x1e7 + {value: 0x0006, lo: 0x09}, + {value: 0x0316, lo: 0xb1, hi: 0xb1}, + {value: 0x031a, lo: 0xb2, hi: 0xb2}, + {value: 0x4a52, lo: 0xb3, hi: 0xb3}, + {value: 0x031e, lo: 0xb4, hi: 0xb4}, + {value: 0x4a58, lo: 0xb5, hi: 0xb6}, + {value: 0x0322, lo: 0xb7, hi: 0xb7}, + {value: 0x0326, lo: 0xb8, hi: 0xb8}, + {value: 0x032a, lo: 0xb9, hi: 0xb9}, + {value: 0x4a64, lo: 0xba, hi: 0xbf}, + // Block 0x53, offset 0x1f1 + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0xaf, hi: 0xaf}, + {value: 0x8133, lo: 0xb4, hi: 0xbd}, + // Block 0x54, offset 0x1f4 + {value: 0x0000, lo: 0x03}, + {value: 0x0212, lo: 0x9c, hi: 0x9c}, + {value: 0x0215, lo: 0x9d, hi: 0x9d}, + {value: 0x8133, lo: 0x9e, hi: 0x9f}, + // Block 0x55, offset 0x1f8 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xb0, hi: 0xb1}, + // Block 0x56, offset 0x1fa + {value: 0x0000, lo: 0x01}, + {value: 0x163e, lo: 0xb0, hi: 0xb0}, + // Block 0x57, offset 0x1fc + {value: 0x000c, lo: 0x01}, + {value: 0x00d7, lo: 0xb8, hi: 0xb9}, + // Block 0x58, offset 0x1fe + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x86, hi: 0x86}, + {value: 0x8105, lo: 0xac, hi: 0xac}, + // Block 0x59, offset 0x201 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x84, hi: 0x84}, + {value: 0x8133, lo: 0xa0, hi: 0xb1}, + // Block 0x5a, offset 0x204 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0xab, hi: 0xad}, + // Block 0x5b, offset 0x206 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x93, hi: 0x93}, + // Block 0x5c, offset 0x208 + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0xb3, hi: 0xb3}, + // Block 0x5d, offset 0x20a + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x80, hi: 0x80}, + // Block 0x5e, offset 0x20c + {value: 0x0000, lo: 0x05}, + {value: 0x8133, lo: 0xb0, hi: 0xb0}, + {value: 0x8133, lo: 0xb2, hi: 0xb3}, + {value: 0x812e, lo: 0xb4, hi: 0xb4}, + {value: 0x8133, lo: 0xb7, hi: 0xb8}, + {value: 0x8133, lo: 0xbe, hi: 0xbf}, + // Block 0x5f, offset 0x212 + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0x81, hi: 0x81}, + {value: 0x8105, lo: 0xb6, hi: 0xb6}, + // Block 0x60, offset 0x215 + {value: 0x0008, lo: 0x04}, + {value: 0x163a, lo: 0x9c, hi: 0x9d}, + {value: 0x0125, lo: 0x9e, hi: 0x9e}, + {value: 0x1646, lo: 0x9f, hi: 0x9f}, + {value: 0x015e, lo: 0xa9, hi: 0xa9}, + // Block 0x61, offset 0x21a + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xad, hi: 0xad}, + // Block 0x62, offset 0x21c + {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 0x63, offset 0x223 + {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 0x64, offset 0x229 + {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 0x65, offset 0x22f + {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 0x66, offset 0x237 + {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 0x67, offset 0x23d + {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 0x68, offset 0x243 + {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 0x69, offset 0x249 + {value: 0x0000, lo: 0x03}, + {value: 0xc600, lo: 0x80, hi: 0x87}, + {value: 0xe500, lo: 0x88, hi: 0x88}, + {value: 0xc600, lo: 0x89, hi: 0xa3}, + // Block 0x6a, offset 0x24d + {value: 0x0002, lo: 0x01}, + {value: 0x0003, lo: 0x81, hi: 0xbf}, + // Block 0x6b, offset 0x24f + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0xbd, hi: 0xbd}, + // Block 0x6c, offset 0x251 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0xa0, hi: 0xa0}, + // Block 0x6d, offset 0x253 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xb6, hi: 0xba}, + // Block 0x6e, offset 0x255 + {value: 0x002d, lo: 0x05}, + {value: 0x812e, lo: 0x8d, hi: 0x8d}, + {value: 0x8133, lo: 0x8f, hi: 0x8f}, + {value: 0x8133, lo: 0xb8, hi: 0xb8}, + {value: 0x8101, lo: 0xb9, hi: 0xba}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x6f, offset 0x25b + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0xa5, hi: 0xa5}, + {value: 0x812e, lo: 0xa6, hi: 0xa6}, + // Block 0x70, offset 0x25e + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xa4, hi: 0xa7}, + // Block 0x71, offset 0x260 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xab, hi: 0xac}, + // Block 0x72, offset 0x262 + {value: 0x0000, lo: 0x05}, + {value: 0x812e, lo: 0x86, hi: 0x87}, + {value: 0x8133, lo: 0x88, hi: 0x8a}, + {value: 0x812e, lo: 0x8b, hi: 0x8b}, + {value: 0x8133, lo: 0x8c, hi: 0x8c}, + {value: 0x812e, lo: 0x8d, hi: 0x90}, + // Block 0x73, offset 0x268 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x86, hi: 0x86}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x74, offset 0x26b + {value: 0x17fe, lo: 0x07}, + {value: 0xa000, lo: 0x99, hi: 0x99}, + {value: 0x424f, lo: 0x9a, hi: 0x9a}, + {value: 0xa000, lo: 0x9b, hi: 0x9b}, + {value: 0x4259, lo: 0x9c, hi: 0x9c}, + {value: 0xa000, lo: 0xa5, hi: 0xa5}, + {value: 0x4263, lo: 0xab, hi: 0xab}, + {value: 0x8105, lo: 0xb9, hi: 0xba}, + // Block 0x75, offset 0x273 + {value: 0x0000, lo: 0x06}, + {value: 0x8133, lo: 0x80, hi: 0x82}, + {value: 0x9900, lo: 0xa7, hi: 0xa7}, + {value: 0x2d8b, lo: 0xae, hi: 0xae}, + {value: 0x2d95, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb1, hi: 0xb2}, + {value: 0x8105, lo: 0xb3, hi: 0xb4}, + // Block 0x76, offset 0x27a + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x80, hi: 0x80}, + {value: 0x8103, lo: 0x8a, hi: 0x8a}, + // Block 0x77, offset 0x27d + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0xb5, hi: 0xb5}, + {value: 0x8103, lo: 0xb6, hi: 0xb6}, + // Block 0x78, offset 0x280 + {value: 0x0002, lo: 0x01}, + {value: 0x8103, lo: 0xa9, hi: 0xaa}, + // Block 0x79, offset 0x282 + {value: 0x0000, lo: 0x02}, + {value: 0x8103, lo: 0xbb, hi: 0xbc}, + {value: 0x9900, lo: 0xbe, hi: 0xbe}, + // Block 0x7a, offset 0x285 + {value: 0x0000, lo: 0x07}, + {value: 0xa000, lo: 0x87, hi: 0x87}, + {value: 0x2d9f, lo: 0x8b, hi: 0x8b}, + {value: 0x2da9, lo: 0x8c, hi: 0x8c}, + {value: 0x8105, lo: 0x8d, hi: 0x8d}, + {value: 0x9900, lo: 0x97, hi: 0x97}, + {value: 0x8133, lo: 0xa6, hi: 0xac}, + {value: 0x8133, lo: 0xb0, hi: 0xb4}, + // Block 0x7b, offset 0x28d + {value: 0x0000, lo: 0x03}, + {value: 0x8105, lo: 0x82, hi: 0x82}, + {value: 0x8103, lo: 0x86, hi: 0x86}, + {value: 0x8133, lo: 0x9e, hi: 0x9e}, + // Block 0x7c, offset 0x291 + {value: 0x6b4d, lo: 0x06}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb9, hi: 0xb9}, + {value: 0x9900, lo: 0xba, hi: 0xba}, + {value: 0x2dbd, lo: 0xbb, hi: 0xbb}, + {value: 0x2db3, lo: 0xbc, hi: 0xbd}, + {value: 0x2dc7, lo: 0xbe, hi: 0xbe}, + // Block 0x7d, offset 0x298 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0x82, hi: 0x82}, + {value: 0x8103, lo: 0x83, hi: 0x83}, + // Block 0x7e, offset 0x29b + {value: 0x0000, lo: 0x05}, + {value: 0x9900, lo: 0xaf, hi: 0xaf}, + {value: 0xa000, lo: 0xb8, hi: 0xb9}, + {value: 0x2dd1, lo: 0xba, hi: 0xba}, + {value: 0x2ddb, lo: 0xbb, hi: 0xbb}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x7f, offset 0x2a1 + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0x80, hi: 0x80}, + // Block 0x80, offset 0x2a3 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xbf, hi: 0xbf}, + // Block 0x81, offset 0x2a5 + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0xb6, hi: 0xb6}, + {value: 0x8103, lo: 0xb7, hi: 0xb7}, + // Block 0x82, offset 0x2a8 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xab, hi: 0xab}, + // Block 0x83, offset 0x2aa + {value: 0x0000, lo: 0x02}, + {value: 0x8105, lo: 0xb9, hi: 0xb9}, + {value: 0x8103, lo: 0xba, hi: 0xba}, + // Block 0x84, offset 0x2ad + {value: 0x0000, lo: 0x04}, + {value: 0x9900, lo: 0xb0, hi: 0xb0}, + {value: 0xa000, lo: 0xb5, hi: 0xb5}, + {value: 0x2de5, lo: 0xb8, hi: 0xb8}, + {value: 0x8105, lo: 0xbd, hi: 0xbe}, + // Block 0x85, offset 0x2b2 + {value: 0x0000, lo: 0x01}, + {value: 0x8103, lo: 0x83, hi: 0x83}, + // Block 0x86, offset 0x2b4 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xa0, hi: 0xa0}, + // Block 0x87, offset 0x2b6 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0xb4, hi: 0xb4}, + // Block 0x88, offset 0x2b8 + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x87, hi: 0x87}, + // Block 0x89, offset 0x2ba + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x99, hi: 0x99}, + // Block 0x8a, offset 0x2bc + {value: 0x0000, lo: 0x02}, + {value: 0x8103, lo: 0x82, hi: 0x82}, + {value: 0x8105, lo: 0x84, hi: 0x85}, + // Block 0x8b, offset 0x2bf + {value: 0x0000, lo: 0x01}, + {value: 0x8105, lo: 0x97, hi: 0x97}, + // Block 0x8c, offset 0x2c1 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0xb0, hi: 0xb4}, + // Block 0x8d, offset 0x2c3 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xb0, hi: 0xb6}, + // Block 0x8e, offset 0x2c5 + {value: 0x0000, lo: 0x01}, + {value: 0x8102, lo: 0xb0, hi: 0xb1}, + // Block 0x8f, offset 0x2c7 + {value: 0x0000, lo: 0x01}, + {value: 0x8101, lo: 0x9e, hi: 0x9e}, + // Block 0x90, offset 0x2c9 + {value: 0x0000, lo: 0x0c}, + {value: 0x45e3, lo: 0x9e, hi: 0x9e}, + {value: 0x45ed, lo: 0x9f, hi: 0x9f}, + {value: 0x4621, lo: 0xa0, hi: 0xa0}, + {value: 0x462f, lo: 0xa1, hi: 0xa1}, + {value: 0x463d, lo: 0xa2, hi: 0xa2}, + {value: 0x464b, lo: 0xa3, hi: 0xa3}, + {value: 0x4659, lo: 0xa4, hi: 0xa4}, + {value: 0x812c, lo: 0xa5, hi: 0xa6}, + {value: 0x8101, lo: 0xa7, hi: 0xa9}, + {value: 0x8131, lo: 0xad, hi: 0xad}, + {value: 0x812c, lo: 0xae, hi: 0xb2}, + {value: 0x812e, lo: 0xbb, hi: 0xbf}, + // Block 0x91, offset 0x2d6 + {value: 0x0000, lo: 0x09}, + {value: 0x812e, lo: 0x80, hi: 0x82}, + {value: 0x8133, lo: 0x85, hi: 0x89}, + {value: 0x812e, lo: 0x8a, hi: 0x8b}, + {value: 0x8133, lo: 0xaa, hi: 0xad}, + {value: 0x45f7, lo: 0xbb, hi: 0xbb}, + {value: 0x4601, lo: 0xbc, hi: 0xbc}, + {value: 0x4667, lo: 0xbd, hi: 0xbd}, + {value: 0x4683, lo: 0xbe, hi: 0xbe}, + {value: 0x4675, lo: 0xbf, hi: 0xbf}, + // Block 0x92, offset 0x2e0 + {value: 0x0000, lo: 0x01}, + {value: 0x4691, lo: 0x80, hi: 0x80}, + // Block 0x93, offset 0x2e2 + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0x82, hi: 0x84}, + // Block 0x94, offset 0x2e4 + {value: 0x0002, lo: 0x03}, + {value: 0x0043, lo: 0x80, hi: 0x99}, + {value: 0x0083, lo: 0x9a, hi: 0xb3}, + {value: 0x0043, lo: 0xb4, hi: 0xbf}, + // Block 0x95, offset 0x2e8 + {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 0x96, offset 0x2ed + {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 0x97, offset 0x2f9 + {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 0x98, offset 0x2fe + {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 0x99, offset 0x307 + {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 0x9a, offset 0x30d + {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 0x9b, offset 0x312 + {value: 0x0002, lo: 0x03}, + {value: 0x008f, lo: 0x80, hi: 0x93}, + {value: 0x0043, lo: 0x94, hi: 0xad}, + {value: 0x0083, lo: 0xae, hi: 0xbf}, + // Block 0x9c, offset 0x316 + {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 0x9d, offset 0x31b + {value: 0x0002, lo: 0x03}, + {value: 0x004b, lo: 0x80, hi: 0x95}, + {value: 0x0083, lo: 0x96, hi: 0xaf}, + {value: 0x0043, lo: 0xb0, hi: 0xbf}, + // Block 0x9e, offset 0x31f + {value: 0x0003, lo: 0x0f}, + {value: 0x01bb, lo: 0x80, hi: 0x80}, + {value: 0x0462, lo: 0x81, hi: 0x81}, + {value: 0x01be, lo: 0x82, hi: 0x9a}, + {value: 0x045e, lo: 0x9b, hi: 0x9b}, + {value: 0x01ca, lo: 0x9c, hi: 0x9c}, + {value: 0x01d3, lo: 0x9d, hi: 0x9d}, + {value: 0x01d9, lo: 0x9e, hi: 0x9e}, + {value: 0x01fd, lo: 0x9f, hi: 0x9f}, + {value: 0x01ee, lo: 0xa0, hi: 0xa0}, + {value: 0x01eb, lo: 0xa1, hi: 0xa1}, + {value: 0x0176, lo: 0xa2, hi: 0xb2}, + {value: 0x018b, lo: 0xb3, hi: 0xb3}, + {value: 0x01a9, lo: 0xb4, hi: 0xba}, + {value: 0x0462, lo: 0xbb, hi: 0xbb}, + {value: 0x01be, lo: 0xbc, hi: 0xbf}, + // Block 0x9f, offset 0x32f + {value: 0x0003, lo: 0x0d}, + {value: 0x01ca, lo: 0x80, hi: 0x94}, + {value: 0x045e, lo: 0x95, hi: 0x95}, + {value: 0x01ca, lo: 0x96, hi: 0x96}, + {value: 0x01d3, lo: 0x97, hi: 0x97}, + {value: 0x01d9, lo: 0x98, hi: 0x98}, + {value: 0x01fd, lo: 0x99, hi: 0x99}, + {value: 0x01ee, lo: 0x9a, hi: 0x9a}, + {value: 0x01eb, lo: 0x9b, hi: 0x9b}, + {value: 0x0176, lo: 0x9c, hi: 0xac}, + {value: 0x018b, lo: 0xad, hi: 0xad}, + {value: 0x01a9, lo: 0xae, hi: 0xb4}, + {value: 0x0462, lo: 0xb5, hi: 0xb5}, + {value: 0x01be, lo: 0xb6, hi: 0xbf}, + // Block 0xa0, offset 0x33d + {value: 0x0003, lo: 0x0d}, + {value: 0x01dc, lo: 0x80, hi: 0x8e}, + {value: 0x045e, lo: 0x8f, hi: 0x8f}, + {value: 0x01ca, lo: 0x90, hi: 0x90}, + {value: 0x01d3, lo: 0x91, hi: 0x91}, + {value: 0x01d9, lo: 0x92, hi: 0x92}, + {value: 0x01fd, lo: 0x93, hi: 0x93}, + {value: 0x01ee, lo: 0x94, hi: 0x94}, + {value: 0x01eb, lo: 0x95, hi: 0x95}, + {value: 0x0176, lo: 0x96, hi: 0xa6}, + {value: 0x018b, lo: 0xa7, hi: 0xa7}, + {value: 0x01a9, lo: 0xa8, hi: 0xae}, + {value: 0x0462, lo: 0xaf, hi: 0xaf}, + {value: 0x01be, lo: 0xb0, hi: 0xbf}, + // Block 0xa1, offset 0x34b + {value: 0x0003, lo: 0x0d}, + {value: 0x01ee, lo: 0x80, hi: 0x88}, + {value: 0x045e, lo: 0x89, hi: 0x89}, + {value: 0x01ca, lo: 0x8a, hi: 0x8a}, + {value: 0x01d3, lo: 0x8b, hi: 0x8b}, + {value: 0x01d9, lo: 0x8c, hi: 0x8c}, + {value: 0x01fd, lo: 0x8d, hi: 0x8d}, + {value: 0x01ee, lo: 0x8e, hi: 0x8e}, + {value: 0x01eb, lo: 0x8f, hi: 0x8f}, + {value: 0x0176, lo: 0x90, hi: 0xa0}, + {value: 0x018b, lo: 0xa1, hi: 0xa1}, + {value: 0x01a9, lo: 0xa2, hi: 0xa8}, + {value: 0x0462, lo: 0xa9, hi: 0xa9}, + {value: 0x01be, lo: 0xaa, hi: 0xbf}, + // Block 0xa2, offset 0x359 + {value: 0x0000, lo: 0x05}, + {value: 0x8133, lo: 0x80, hi: 0x86}, + {value: 0x8133, lo: 0x88, hi: 0x98}, + {value: 0x8133, lo: 0x9b, hi: 0xa1}, + {value: 0x8133, lo: 0xa3, hi: 0xa4}, + {value: 0x8133, lo: 0xa6, hi: 0xaa}, + // Block 0xa3, offset 0x35f + {value: 0x0000, lo: 0x01}, + {value: 0x8133, lo: 0xac, hi: 0xaf}, + // Block 0xa4, offset 0x361 + {value: 0x0000, lo: 0x01}, + {value: 0x812e, lo: 0x90, hi: 0x96}, + // Block 0xa5, offset 0x363 + {value: 0x0000, lo: 0x02}, + {value: 0x8133, lo: 0x84, hi: 0x89}, + {value: 0x8103, lo: 0x8a, hi: 0x8a}, + // Block 0xa6, offset 0x366 + {value: 0x0002, lo: 0x0a}, + {value: 0x0063, lo: 0x80, hi: 0x89}, + {value: 0x1954, lo: 0x8a, hi: 0x8a}, + {value: 0x1987, lo: 0x8b, hi: 0x8b}, + {value: 0x19a2, lo: 0x8c, hi: 0x8c}, + {value: 0x19a8, lo: 0x8d, hi: 0x8d}, + {value: 0x1bc6, lo: 0x8e, hi: 0x8e}, + {value: 0x19b4, lo: 0x8f, hi: 0x8f}, + {value: 0x197e, lo: 0xaa, hi: 0xaa}, + {value: 0x1981, lo: 0xab, hi: 0xab}, + {value: 0x1984, lo: 0xac, hi: 0xac}, + // Block 0xa7, offset 0x371 + {value: 0x0000, lo: 0x01}, + {value: 0x1942, lo: 0x90, hi: 0x90}, + // Block 0xa8, offset 0x373 + {value: 0x0028, lo: 0x09}, + {value: 0x286f, lo: 0x80, hi: 0x80}, + {value: 0x2833, lo: 0x81, hi: 0x81}, + {value: 0x283d, lo: 0x82, hi: 0x82}, + {value: 0x2851, lo: 0x83, hi: 0x84}, + {value: 0x285b, lo: 0x85, hi: 0x86}, + {value: 0x2847, lo: 0x87, hi: 0x87}, + {value: 0x2865, lo: 0x88, hi: 0x88}, + {value: 0x0b72, lo: 0x90, hi: 0x90}, + {value: 0x08ea, lo: 0x91, hi: 0x91}, + // Block 0xa9, offset 0x37d + {value: 0x0002, lo: 0x01}, + {value: 0x0021, lo: 0xb0, hi: 0xb9}, +} + +// recompMap: 7528 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 + "\x195\x190\x00\x01\x198" + // 0x19351930: 0x00011938 + "" + // Total size of tables: 55KB (56160 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 8c9977355c9..8c3c2e7ab95 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/analysis.go +++ b/libgo/go/golang.org/x/tools/go/analysis/analysis.go @@ -95,12 +95,13 @@ type Pass struct { Analyzer *Analyzer // the identity of the current analyzer // syntax and type information - Fset *token.FileSet // file position information - Files []*ast.File // the abstract syntax tree of each file - OtherFiles []string // names of non-Go files of this package - Pkg *types.Package // type information about the package - TypesInfo *types.Info // type information about the syntax trees - TypesSizes types.Sizes // function for computing sizes of types + Fset *token.FileSet // file position information + Files []*ast.File // the abstract syntax tree of each file + OtherFiles []string // names of non-Go files of this package + IgnoredFiles []string // names of ignored source files in this package + Pkg *types.Package // type information about the package + TypesInfo *types.Info // type information about the syntax trees + TypesSizes types.Sizes // function for computing sizes of types // Report reports a Diagnostic, a finding about a specific location // in the analyzed source code such as a potential mistake. 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 fb17a0e4154..9fa3302dfbe 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/doc.go +++ b/libgo/go/golang.org/x/tools/go/analysis/doc.go @@ -121,13 +121,14 @@ package being analyzed, and provides operations to the Run function for reporting diagnostics and other information back to the driver. type Pass struct { - Fset *token.FileSet - Files []*ast.File - OtherFiles []string - Pkg *types.Package - TypesInfo *types.Info - ResultOf map[*Analyzer]interface{} - Report func(Diagnostic) + Fset *token.FileSet + Files []*ast.File + OtherFiles []string + IgnoredFiles []string + Pkg *types.Package + TypesInfo *types.Info + ResultOf map[*Analyzer]interface{} + Report func(Diagnostic) ... } @@ -139,6 +140,12 @@ files such as assembly that are part of this package. See the "asmdecl" or "buildtags" analyzers for examples of loading non-Go files and reporting diagnostics against them. +The IgnoredFiles field provides the names, but not the contents, +of ignored Go and non-Go source files that are not part of this package +with the current build configuration but may be part of other build +configurations. See the "buildtags" analyzer for an example of loading +and checking IgnoredFiles. + The ResultOf field provides the results computed by the analyzers required by this one, as expressed in its Analyzer.Requires field. The driver runs the required analyzers first and makes their results 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 0f521503ac6..34c7a36234d 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 @@ -139,6 +139,7 @@ var ( asmSP = re(`[^+\-0-9](([0-9]+)\(([A-Z0-9]+)\))`) asmOpcode = re(`^\s*(?:[A-Z0-9a-z_]+:)?\s*([A-Z]+)\s*([^,]*)(?:,\s*(.*))?`) ppc64Suff = re(`([BHWD])(ZU|Z|U|BR)?$`) + abiSuff = re(`^(.+)$`) ) func run(pass *analysis.Pass) (interface{}, error) { @@ -202,6 +203,13 @@ Files: } retLine = nil } + trimABI := func(fnName string) string { + m := abiSuff.FindStringSubmatch(fnName) + if m != nil { + return m[1] + } + return fnName + } for lineno, line := range lines { lineno++ @@ -270,6 +278,8 @@ Files: continue } } + // Trim off optional ABI selector. + fnName := trimABI(fnName) flag := m[3] fn = knownFunc[fnName][arch] if fn != nil { @@ -300,7 +310,8 @@ Files: continue } - if strings.Contains(line, "RET") { + if strings.Contains(line, "RET") && !strings.Contains(line, "(SB)") { + // RET f(SB) is a tail call. It is okay to not write the results. retLine = append(retLine, lineno) } 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 78176f10114..841b9285784 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 @@ -9,6 +9,7 @@ import ( "bytes" "fmt" "go/ast" + "go/parser" "strings" "unicode" @@ -33,6 +34,20 @@ func runBuildTag(pass *analysis.Pass) (interface{}, error) { return nil, err } } + for _, name := range pass.IgnoredFiles { + if strings.HasSuffix(name, ".go") { + f, err := parser.ParseFile(pass.Fset, name, nil, parser.ParseComments) + if err != nil { + // Not valid Go source code - not our job to diagnose, so ignore. + return nil, nil + } + checkGoFile(pass, f) + } else { + if err := checkOtherFile(pass, name); err != nil { + return nil, err + } + } + } return nil, nil } @@ -132,13 +147,6 @@ func checkLine(line string, pastCutoff bool) error { } func checkArguments(fields []string) error { - // The original version of this checker in vet could examine - // files with malformed build tags that would cause the file to - // be always ignored by "go build". However, drivers for the new - // analysis API will analyze only the files selected to form a - // package, so these checks will never fire. - // TODO(adonovan): rethink this. - for _, arg := range fields[1:] { for _, elem := range strings.Split(arg, ",") { if strings.HasPrefix(elem, "!!") { diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go b/libgo/go/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go new file mode 100644 index 00000000000..741492e4779 --- /dev/null +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/framepointer/framepointer.go @@ -0,0 +1,91 @@ +// Copyright 2020 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 framepointer defines an Analyzer that reports assembly code +// that clobbers the frame pointer before saving it. +package framepointer + +import ( + "go/build" + "regexp" + "strings" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" +) + +const Doc = "report assembly that clobbers the frame pointer before saving it" + +var Analyzer = &analysis.Analyzer{ + Name: "framepointer", + Doc: Doc, + Run: run, +} + +var ( + re = regexp.MustCompile + asmWriteBP = re(`,\s*BP$`) // TODO: can have false positive, e.g. for TESTQ BP,BP. Seems unlikely. + asmMentionBP = re(`\bBP\b`) + asmControlFlow = re(`^(J|RET)`) +) + +func run(pass *analysis.Pass) (interface{}, error) { + if build.Default.GOARCH != "amd64" { // TODO: arm64 also? + return nil, nil + } + if build.Default.GOOS != "linux" && build.Default.GOOS != "darwin" { + return nil, nil + } + + // Find assembly files to work on. + var sfiles []string + for _, fname := range pass.OtherFiles { + if strings.HasSuffix(fname, ".s") && pass.Pkg.Path() != "runtime" { + sfiles = append(sfiles, fname) + } + } + + for _, fname := range sfiles { + content, tf, err := analysisutil.ReadFile(pass.Fset, fname) + if err != nil { + return nil, err + } + + lines := strings.SplitAfter(string(content), "\n") + active := false + for lineno, line := range lines { + lineno++ + + // Ignore comments and commented-out code. + if i := strings.Index(line, "//"); i >= 0 { + line = line[:i] + } + line = strings.TrimSpace(line) + + // We start checking code at a TEXT line for a frameless function. + if strings.HasPrefix(line, "TEXT") && strings.Contains(line, "(SB)") && strings.Contains(line, "$0") { + active = true + continue + } + if !active { + continue + } + + if asmWriteBP.MatchString(line) { // clobber of BP, function is not OK + pass.Reportf(analysisutil.LineStart(tf, lineno), "frame pointer is clobbered before saving") + active = false + continue + } + if asmMentionBP.MatchString(line) { // any other use of BP might be a read, so function is OK + active = false + continue + } + if asmControlFlow.MatchString(line) { // give up after any branch instruction + active = false + continue + } + } + } + return nil, nil +} diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go b/libgo/go/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go index c5a71a7c570..fd2285332cc 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/ifaceassert/ifaceassert.go @@ -41,6 +41,10 @@ var Analyzer = &analysis.Analyzer{ // assertableTo checks whether interface v can be asserted into t. It returns // nil on success, or the first conflicting method on failure. func assertableTo(v, t types.Type) *types.Func { + if t == nil || v == nil { + // not assertable to, but there is no missing method + return nil + } // ensure that v and t are interfaces V, _ := v.Underlying().(*types.Interface) T, _ := t.Underlying().(*types.Interface) 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 e09160379f6..02555648a0b 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 @@ -116,7 +116,11 @@ func checkCanonicalFieldTag(pass *analysis.Pass, field *types.Var, tag string, s } for _, enc := range [...]string{"json", "xml"} { - if reflect.StructTag(tag).Get(enc) != "" { + switch reflect.StructTag(tag).Get(enc) { + // Ignore warning if the field not exported and the tag is marked as + // ignored. + case "", "-": + default: pass.Reportf(field.Pos(), "struct field %s has %s tag but is not exported", field.Name(), enc) return } @@ -203,12 +207,12 @@ var ( ) // validateStructTag parses the struct tag and returns an error if it is not -// in the canonical format, which is a space-separated list of key:"value" -// settings. The value may contain spaces. +// in the canonical format, as defined by reflect.StructTag. func validateStructTag(tag string) error { // This code is based on the StructTag.Get code in package reflect. n := 0 + var keys []string for ; tag != ""; n++ { if n > 0 && tag != "" && tag[0] != ' ' { // More restrictive than reflect, but catches likely mistakes @@ -236,14 +240,27 @@ func validateStructTag(tag string) error { if i == 0 { return errTagKeySyntax } - if i+1 >= len(tag) || tag[i] != ':' { + if i+1 >= len(tag) || tag[i] < ' ' || tag[i] == 0x7f { return errTagSyntax } - if tag[i+1] != '"' { + key := tag[:i] + keys = append(keys, key) + tag = tag[i:] + + // If we found a space char here - assume that we have a tag with + // multiple keys. + if tag[0] == ' ' { + continue + } + + // Spaces were filtered above so we assume that here we have + // only valid tag value started with `:"`. + if tag[0] != ':' || tag[1] != '"' { return errTagValueSyntax } - key := tag[:i] - tag = tag[i+1:] + + // Remove the colon leaving tag at the start of the quoted string. + tag = tag[1:] // Scan quoted string to find value. i = 1 @@ -259,51 +276,56 @@ func validateStructTag(tag string) error { qvalue := tag[:i+1] tag = tag[i+1:] - value, err := strconv.Unquote(qvalue) + wholeValue, err := strconv.Unquote(qvalue) if err != nil { return errTagValueSyntax } - if !checkTagSpaces[key] { - continue - } - - switch key { - case "xml": - // If the first or last character in the XML tag is a space, it is - // suspicious. - if strings.Trim(value, " ") != value { - return errTagValueSpace + for _, key := range keys { + if !checkTagSpaces[key] { + continue } - // If there are multiple spaces, they are suspicious. - if strings.Count(value, " ") > 1 { - return errTagValueSpace - } + value := wholeValue + switch key { + case "xml": + // If the first or last character in the XML tag is a space, it is + // suspicious. + if strings.Trim(value, " ") != value { + return errTagValueSpace + } - // If there is no comma, skip the rest of the checks. - comma := strings.IndexRune(value, ',') - if comma < 0 { - continue + // If there are multiple spaces, they are suspicious. + if strings.Count(value, " ") > 1 { + return errTagValueSpace + } + + // If there is no comma, skip the rest of the checks. + comma := strings.IndexRune(value, ',') + if comma < 0 { + continue + } + + // If the character before a comma is a space, this is suspicious. + if comma > 0 && value[comma-1] == ' ' { + return errTagValueSpace + } + value = value[comma+1:] + case "json": + // JSON allows using spaces in the name, so skip it. + comma := strings.IndexRune(value, ',') + if comma < 0 { + continue + } + value = value[comma+1:] } - // If the character before a comma is a space, this is suspicious. - if comma > 0 && value[comma-1] == ' ' { + if strings.IndexByte(value, ' ') >= 0 { return errTagValueSpace } - value = value[comma+1:] - case "json": - // JSON allows using spaces in the name, so skip it. - comma := strings.IndexRune(value, ',') - if comma < 0 { - continue - } - value = value[comma+1:] } - if strings.IndexByte(value, ' ') >= 0 { - return errTagValueSpace - } + keys = keys[:0] } return nil } diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go b/libgo/go/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go new file mode 100644 index 00000000000..d2b9a5640d9 --- /dev/null +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/testinggoroutine/testinggoroutine.go @@ -0,0 +1,154 @@ +// Copyright 2020 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 testinggoroutine + +import ( + "go/ast" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" + "golang.org/x/tools/go/ast/inspector" +) + +const Doc = `report calls to (*testing.T).Fatal from goroutines started by a test. + +Functions that abruptly terminate a test, such as the Fatal, Fatalf, FailNow, and +Skip{,f,Now} methods of *testing.T, must be called from the test goroutine itself. +This checker detects calls to these functions that occur within a goroutine +started by the test. For example: + +func TestFoo(t *testing.T) { + go func() { + t.Fatal("oops") // error: (*T).Fatal called from non-test goroutine + }() +} +` + +var Analyzer = &analysis.Analyzer{ + Name: "testinggoroutine", + Doc: Doc, + Requires: []*analysis.Analyzer{inspect.Analyzer}, + Run: run, +} + +var forbidden = map[string]bool{ + "FailNow": true, + "Fatal": true, + "Fatalf": true, + "Skip": true, + "Skipf": true, + "SkipNow": true, +} + +func run(pass *analysis.Pass) (interface{}, error) { + inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) + + if !analysisutil.Imports(pass.Pkg, "testing") { + return nil, nil + } + + // Filter out anything that isn't a function declaration. + onlyFuncs := []ast.Node{ + (*ast.FuncDecl)(nil), + } + + inspect.Nodes(onlyFuncs, func(node ast.Node, push bool) bool { + fnDecl, ok := node.(*ast.FuncDecl) + if !ok { + return false + } + + if !hasBenchmarkOrTestParams(fnDecl) { + return false + } + + // Now traverse the benchmark/test's body and check that none of the + // forbidden methods are invoked in the goroutines within the body. + ast.Inspect(fnDecl, func(n ast.Node) bool { + goStmt, ok := n.(*ast.GoStmt) + if !ok { + return true + } + + checkGoStmt(pass, goStmt) + + // No need to further traverse the GoStmt since right + // above we manually traversed it in the ast.Inspect(goStmt, ...) + return false + }) + + return false + }) + + return nil, nil +} + +func hasBenchmarkOrTestParams(fnDecl *ast.FuncDecl) bool { + // Check that the function's arguments include "*testing.T" or "*testing.B". + params := fnDecl.Type.Params.List + + for _, param := range params { + if _, ok := typeIsTestingDotTOrB(param.Type); ok { + return true + } + } + + return false +} + +func typeIsTestingDotTOrB(expr ast.Expr) (string, bool) { + starExpr, ok := expr.(*ast.StarExpr) + if !ok { + return "", false + } + selExpr, ok := starExpr.X.(*ast.SelectorExpr) + if !ok { + return "", false + } + + varPkg := selExpr.X.(*ast.Ident) + if varPkg.Name != "testing" { + return "", false + } + + varTypeName := selExpr.Sel.Name + ok = varTypeName == "B" || varTypeName == "T" + return varTypeName, ok +} + +// checkGoStmt traverses the goroutine and checks for the +// use of the forbidden *testing.(B, T) methods. +func checkGoStmt(pass *analysis.Pass, goStmt *ast.GoStmt) { + // Otherwise examine the goroutine to check for the forbidden methods. + ast.Inspect(goStmt, func(n ast.Node) bool { + selExpr, ok := n.(*ast.SelectorExpr) + if !ok { + return true + } + + _, bad := forbidden[selExpr.Sel.Name] + if !bad { + return true + } + + // Now filter out false positives by the import-path/type. + ident, ok := selExpr.X.(*ast.Ident) + if !ok { + return true + } + if ident.Obj == nil || ident.Obj.Decl == nil { + return true + } + field, ok := ident.Obj.Decl.(*ast.Field) + if !ok { + return true + } + if typeName, ok := typeIsTestingDotTOrB(field.Type); ok { + pass.ReportRangef(selExpr, "call to (*%s).%s from a non-test goroutine", typeName, selExpr.Sel) + } + return true + }) +} 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 f9cc993cbb4..92b37caff9f 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 @@ -30,7 +30,7 @@ var Analyzer = &analysis.Analyzer{ func run(pass *analysis.Pass) (interface{}, error) { switch pass.Pkg.Path() { - case "encoding/gob", "encoding/json", "encoding/xml": + case "encoding/gob", "encoding/json", "encoding/xml", "encoding/asn1": // These packages know how to use their own APIs. // Sometimes they are testing what happens to incorrect programs. return nil, nil @@ -53,9 +53,10 @@ func run(pass *analysis.Pass) (interface{}, error) { recv := fn.Type().(*types.Signature).Recv() if fn.Name() == "Unmarshal" && recv == nil { // "encoding/json".Unmarshal - // "encoding/xml".Unmarshal + // "encoding/xml".Unmarshal + // "encoding/asn1".Unmarshal switch fn.Pkg().Path() { - case "encoding/json", "encoding/xml": + case "encoding/json", "encoding/xml", "encoding/asn1": argidx = 1 // func([]byte, interface{}) } } else if fn.Name() == "Decode" && recv != nil { 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 d5bafb859d2..ed86e5ebf00 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 @@ -13,6 +13,7 @@ import ( "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis/passes/inspect" + "golang.org/x/tools/go/analysis/passes/internal/analysisutil" "golang.org/x/tools/go/ast/inspector" ) @@ -36,32 +37,44 @@ func run(pass *analysis.Pass) (interface{}, error) { nodeFilter := []ast.Node{ (*ast.CallExpr)(nil), + (*ast.StarExpr)(nil), + (*ast.UnaryExpr)(nil), } inspect.Preorder(nodeFilter, func(n ast.Node) { - x := n.(*ast.CallExpr) - if len(x.Args) != 1 { - return - } - if hasBasicType(pass.TypesInfo, x.Fun, types.UnsafePointer) && - hasBasicType(pass.TypesInfo, x.Args[0], types.Uintptr) && - !isSafeUintptr(pass.TypesInfo, x.Args[0]) { - pass.ReportRangef(x, "possible misuse of unsafe.Pointer") + switch x := n.(type) { + case *ast.CallExpr: + if len(x.Args) == 1 && + hasBasicType(pass.TypesInfo, x.Fun, types.UnsafePointer) && + hasBasicType(pass.TypesInfo, x.Args[0], types.Uintptr) && + !isSafeUintptr(pass.TypesInfo, x.Args[0]) { + pass.ReportRangef(x, "possible misuse of unsafe.Pointer") + } + case *ast.StarExpr: + if t := pass.TypesInfo.Types[x].Type; isReflectHeader(t) { + pass.ReportRangef(x, "possible misuse of %s", t) + } + case *ast.UnaryExpr: + if x.Op != token.AND { + return + } + if t := pass.TypesInfo.Types[x.X].Type; isReflectHeader(t) { + pass.ReportRangef(x, "possible misuse of %s", t) + } } }) return nil, nil } // isSafeUintptr reports whether x - already known to be a uintptr - -// is safe to convert to unsafe.Pointer. It is safe if x is itself derived -// directly from an unsafe.Pointer via conversion and pointer arithmetic -// or if x is the result of reflect.Value.Pointer or reflect.Value.UnsafeAddr -// or obtained from the Data field of a *reflect.SliceHeader or *reflect.StringHeader. +// is safe to convert to unsafe.Pointer. func isSafeUintptr(info *types.Info, x ast.Expr) bool { - switch x := x.(type) { - case *ast.ParenExpr: - return isSafeUintptr(info, x.X) + // Check unsafe.Pointer safety rules according to + // https://golang.org/pkg/unsafe/#Pointer. + switch x := analysisutil.Unparen(x).(type) { case *ast.SelectorExpr: + // "(6) Conversion of a reflect.SliceHeader or + // reflect.StringHeader Data field to or from Pointer." if x.Sel.Name != "Data" { break } @@ -78,44 +91,56 @@ func isSafeUintptr(info *types.Info, x ast.Expr) bool { // For now approximate by saying that *Header is okay // but Header is not. pt, ok := info.Types[x.X].Type.(*types.Pointer) - if ok { - t, ok := pt.Elem().(*types.Named) - if ok && t.Obj().Pkg().Path() == "reflect" { - switch t.Obj().Name() { - case "StringHeader", "SliceHeader": - return true - } - } + if ok && isReflectHeader(pt.Elem()) { + return true } case *ast.CallExpr: - switch len(x.Args) { - case 0: - // maybe call to reflect.Value.Pointer or reflect.Value.UnsafeAddr. - sel, ok := x.Fun.(*ast.SelectorExpr) - if !ok { - break - } - switch sel.Sel.Name { - case "Pointer", "UnsafeAddr": - t, ok := info.Types[sel.X].Type.(*types.Named) - if ok && t.Obj().Pkg().Path() == "reflect" && t.Obj().Name() == "Value" { - return true - } + // "(5) Conversion of the result of reflect.Value.Pointer or + // reflect.Value.UnsafeAddr from uintptr to Pointer." + if len(x.Args) != 0 { + break + } + sel, ok := x.Fun.(*ast.SelectorExpr) + if !ok { + break + } + switch sel.Sel.Name { + case "Pointer", "UnsafeAddr": + t, ok := info.Types[sel.X].Type.(*types.Named) + if ok && t.Obj().Pkg().Path() == "reflect" && t.Obj().Name() == "Value" { + return true } - - case 1: - // maybe conversion of uintptr to unsafe.Pointer - return hasBasicType(info, x.Fun, types.Uintptr) && - hasBasicType(info, x.Args[0], types.UnsafePointer) } + } + + // "(3) Conversion of a Pointer to a uintptr and back, with arithmetic." + return isSafeArith(info, x) +} + +// isSafeArith reports whether x is a pointer arithmetic expression that is safe +// to convert to unsafe.Pointer. +func isSafeArith(info *types.Info, x ast.Expr) bool { + switch x := analysisutil.Unparen(x).(type) { + case *ast.CallExpr: + // Base case: initial conversion from unsafe.Pointer to uintptr. + return len(x.Args) == 1 && + hasBasicType(info, x.Fun, types.Uintptr) && + hasBasicType(info, x.Args[0], types.UnsafePointer) case *ast.BinaryExpr: + // "It is valid both to add and to subtract offsets from a + // pointer in this way. It is also valid to use &^ to round + // pointers, usually for alignment." switch x.Op { case token.ADD, token.SUB, token.AND_NOT: - return isSafeUintptr(info, x.X) && !isSafeUintptr(info, x.Y) + // TODO(mdempsky): Match compiler + // semantics. ADD allows a pointer on either + // side; SUB and AND_NOT don't care about RHS. + return isSafeArith(info, x.X) && !isSafeArith(info, x.Y) } } + return false } @@ -128,3 +153,16 @@ func hasBasicType(info *types.Info, x ast.Expr, kind types.BasicKind) bool { b, ok := t.(*types.Basic) return ok && b.Kind() == kind } + +// isReflectHeader reports whether t is reflect.SliceHeader or reflect.StringHeader. +func isReflectHeader(t types.Type) bool { + if named, ok := t.(*types.Named); ok { + if obj := named.Obj(); obj.Pkg() != nil && obj.Pkg().Path() == "reflect" { + switch obj.Name() { + case "SliceHeader", "StringHeader": + return true + } + } + } + return false +} diff --git a/libgo/go/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go b/libgo/go/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go index 76d4ab23827..bececee7e93 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go +++ b/libgo/go/golang.org/x/tools/go/analysis/passes/unusedresult/unusedresult.go @@ -44,7 +44,7 @@ var funcs, stringMethods stringSetFlag func init() { // TODO(adonovan): provide a comment syntax to allow users to // add their functions to this set using facts. - funcs.Set("errors.New,fmt.Errorf,fmt.Sprintf,fmt.Sprint,sort.Reverse") + funcs.Set("errors.New,fmt.Errorf,fmt.Sprintf,fmt.Sprint,sort.Reverse,context.WithValue,context.WithCancel,context.WithDeadline,context.WithTimeout") Analyzer.Flags.Var(&funcs, "funcs", "comma-separated list of functions whose results must be used") 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 ed5f43c2601..02ec2fa3f21 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 @@ -63,6 +63,7 @@ type Config struct { ImportPath string GoFiles []string NonGoFiles []string + IgnoredFiles []string ImportMap map[string]string PackageFile map[string]string Standard map[string]bool @@ -333,6 +334,7 @@ func run(fset *token.FileSet, cfg *Config, analyzers []*analysis.Analyzer) ([]re Fset: fset, Files: files, OtherFiles: cfg.NonGoFiles, + IgnoredFiles: cfg.IgnoredFiles, Pkg: pkg, TypesInfo: info, TypesSizes: tc.Sizes, 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 be98143461e..ad0e7276c91 100644 --- a/libgo/go/golang.org/x/tools/go/analysis/validate.go +++ b/libgo/go/golang.org/x/tools/go/analysis/validate.go @@ -3,6 +3,7 @@ package analysis import ( "fmt" "reflect" + "strings" "unicode" ) @@ -58,14 +59,28 @@ func Validate(analyzers []*Analyzer) error { } // recursion - for i, req := range a.Requires { + for _, req := range a.Requires { if err := visit(req); err != nil { - return fmt.Errorf("%s.Requires[%d]: %v", a.Name, i, err) + return err } } color[a] = black } + if color[a] == grey { + stack := []*Analyzer{a} + inCycle := map[string]bool{} + for len(stack) > 0 { + current := stack[len(stack)-1] + stack = stack[:len(stack)-1] + if color[current] == grey && !inCycle[current.Name] { + inCycle[current.Name] = true + stack = append(stack, current.Requires...) + } + } + return &CycleInRequiresGraphError{AnalyzerNames: inCycle} + } + return nil } for _, a := range analyzers { @@ -95,3 +110,17 @@ func validIdent(name string) bool { } return name != "" } + +type CycleInRequiresGraphError struct { + AnalyzerNames map[string]bool +} + +func (e *CycleInRequiresGraphError) Error() string { + var b strings.Builder + b.WriteString("cycle detected involving the following analyzers:") + for n := range e.AnalyzerNames { + b.WriteByte(' ') + b.WriteString(n) + } + return b.String() +} diff --git a/libgo/go/golang.org/x/tools/internal/analysisinternal/analysis.go b/libgo/go/golang.org/x/tools/internal/analysisinternal/analysis.go index 26586810c7f..01f6e829f75 100644 --- a/libgo/go/golang.org/x/tools/internal/analysisinternal/analysis.go +++ b/libgo/go/golang.org/x/tools/internal/analysisinternal/analysis.go @@ -14,6 +14,12 @@ import ( "strings" "golang.org/x/tools/go/ast/astutil" + "golang.org/x/tools/internal/lsp/fuzzy" +) + +var ( + GetTypeErrors func(p interface{}) []types.Error + SetTypeErrors func(p interface{}, errors []types.Error) ) func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos { @@ -45,32 +51,34 @@ func ZeroValue(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.T default: panic("unknown basic type") } - case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice: + case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice, *types.Array: return ast.NewIdent("nil") case *types.Struct: - texpr := typeExpr(fset, f, pkg, typ) // typ because we want the name here. + texpr := TypeExpr(fset, f, pkg, typ) // typ because we want the name here. if texpr == nil { return nil } return &ast.CompositeLit{ Type: texpr, } - case *types.Array: - texpr := typeExpr(fset, f, pkg, u.Elem()) - if texpr == nil { - return nil - } - return &ast.CompositeLit{ - Type: &ast.ArrayType{ - Elt: texpr, - Len: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprintf("%v", u.Len())}, - }, - } } return nil } -func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { +// IsZeroValue checks whether the given expression is a 'zero value' (as determined by output of +// analysisinternal.ZeroValue) +func IsZeroValue(expr ast.Expr) bool { + switch e := expr.(type) { + case *ast.BasicLit: + return e.Value == "0" || e.Value == `""` + case *ast.Ident: + return e.Name == "nil" || e.Name == "false" + default: + return false + } +} + +func TypeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { switch t := typ.(type) { case *types.Basic: switch t.Kind() { @@ -79,7 +87,96 @@ func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Ty default: return ast.NewIdent(t.Name()) } + case *types.Pointer: + x := TypeExpr(fset, f, pkg, t.Elem()) + if x == nil { + return nil + } + return &ast.UnaryExpr{ + Op: token.MUL, + X: x, + } + case *types.Array: + elt := TypeExpr(fset, f, pkg, t.Elem()) + if elt == nil { + return nil + } + return &ast.ArrayType{ + Len: &ast.BasicLit{ + Kind: token.INT, + Value: fmt.Sprintf("%d", t.Len()), + }, + Elt: elt, + } + case *types.Slice: + elt := TypeExpr(fset, f, pkg, t.Elem()) + if elt == nil { + return nil + } + return &ast.ArrayType{ + Elt: elt, + } + case *types.Map: + key := TypeExpr(fset, f, pkg, t.Key()) + value := TypeExpr(fset, f, pkg, t.Elem()) + if key == nil || value == nil { + return nil + } + return &ast.MapType{ + Key: key, + Value: value, + } + case *types.Chan: + dir := ast.ChanDir(t.Dir()) + if t.Dir() == types.SendRecv { + dir = ast.SEND | ast.RECV + } + value := TypeExpr(fset, f, pkg, t.Elem()) + if value == nil { + return nil + } + return &ast.ChanType{ + Dir: dir, + Value: value, + } + case *types.Signature: + var params []*ast.Field + for i := 0; i < t.Params().Len(); i++ { + p := TypeExpr(fset, f, pkg, t.Params().At(i).Type()) + if p == nil { + return nil + } + params = append(params, &ast.Field{ + Type: p, + Names: []*ast.Ident{ + { + Name: t.Params().At(i).Name(), + }, + }, + }) + } + var returns []*ast.Field + for i := 0; i < t.Results().Len(); i++ { + r := TypeExpr(fset, f, pkg, t.Results().At(i).Type()) + if r == nil { + return nil + } + returns = append(returns, &ast.Field{ + Type: r, + }) + } + return &ast.FuncType{ + Params: &ast.FieldList{ + List: params, + }, + Results: &ast.FieldList{ + List: returns, + }, + } case *types.Named: + if t.Obj().Pkg() == nil { + return ast.NewIdent(t.Obj().Name()) + } if t.Obj().Pkg() == pkg { return ast.NewIdent(t.Obj().Name()) } @@ -101,14 +198,15 @@ func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Ty X: ast.NewIdent(pkgName), Sel: ast.NewIdent(t.Obj().Name()), } + case *types.Struct: + return ast.NewIdent(t.String()) + case *types.Interface: + return ast.NewIdent(t.String()) default: - return nil // TODO: anonymous structs, but who does that + return nil } } -var GetTypeErrors = func(p interface{}) []types.Error { return nil } -var SetTypeErrors = func(p interface{}, errors []types.Error) {} - type TypeErrorPass string const ( @@ -116,3 +214,212 @@ const ( NoResultValues TypeErrorPass = "noresultvalues" UndeclaredName TypeErrorPass = "undeclaredname" ) + +// StmtToInsertVarBefore returns the ast.Stmt before which we can safely insert a new variable. +// Some examples: +// +// Basic Example: +// z := 1 +// y := z + x +// If x is undeclared, then this function would return `y := z + x`, so that we +// can insert `x := ` on the line before `y := z + x`. +// +// If stmt example: +// if z == 1 { +// } else if z == y {} +// If y is undeclared, then this function would return `if z == 1 {`, because we cannot +// insert a statement between an if and an else if statement. As a result, we need to find +// the top of the if chain to insert `y := ` before. +func StmtToInsertVarBefore(path []ast.Node) ast.Stmt { + enclosingIndex := -1 + for i, p := range path { + if _, ok := p.(ast.Stmt); ok { + enclosingIndex = i + break + } + } + if enclosingIndex == -1 { + return nil + } + enclosingStmt := path[enclosingIndex] + switch enclosingStmt.(type) { + case *ast.IfStmt: + // The enclosingStmt is inside of the if declaration, + // We need to check if we are in an else-if stmt and + // get the base if statement. + return baseIfStmt(path, enclosingIndex) + case *ast.CaseClause: + // Get the enclosing switch stmt if the enclosingStmt is + // inside of the case statement. + for i := enclosingIndex + 1; i < len(path); i++ { + if node, ok := path[i].(*ast.SwitchStmt); ok { + return node + } else if node, ok := path[i].(*ast.TypeSwitchStmt); ok { + return node + } + } + } + if len(path) <= enclosingIndex+1 { + return enclosingStmt.(ast.Stmt) + } + // Check if the enclosing statement is inside another node. + switch expr := path[enclosingIndex+1].(type) { + case *ast.IfStmt: + // Get the base if statement. + return baseIfStmt(path, enclosingIndex+1) + case *ast.ForStmt: + if expr.Init == enclosingStmt || expr.Post == enclosingStmt { + return expr + } + } + return enclosingStmt.(ast.Stmt) +} + +// baseIfStmt walks up the if/else-if chain until we get to +// the top of the current if chain. +func baseIfStmt(path []ast.Node, index int) ast.Stmt { + stmt := path[index] + for i := index + 1; i < len(path); i++ { + if node, ok := path[i].(*ast.IfStmt); ok && node.Else == stmt { + stmt = node + continue + } + break + } + return stmt.(ast.Stmt) +} + +// WalkASTWithParent walks the AST rooted at n. The semantics are +// similar to ast.Inspect except it does not call f(nil). +func WalkASTWithParent(n ast.Node, f func(n ast.Node, parent ast.Node) bool) { + var ancestors []ast.Node + ast.Inspect(n, func(n ast.Node) (recurse bool) { + if n == nil { + ancestors = ancestors[:len(ancestors)-1] + return false + } + + var parent ast.Node + if len(ancestors) > 0 { + parent = ancestors[len(ancestors)-1] + } + ancestors = append(ancestors, n) + return f(n, parent) + }) +} + +// FindMatchingIdents finds all identifiers in 'node' that match any of the given types. +// 'pos' represents the position at which the identifiers may be inserted. 'pos' must be within +// the scope of each of identifier we select. Otherwise, we will insert a variable at 'pos' that +// is unrecognized. +func FindMatchingIdents(typs []types.Type, node ast.Node, pos token.Pos, info *types.Info, pkg *types.Package) map[types.Type][]*ast.Ident { + matches := map[types.Type][]*ast.Ident{} + // Initialize matches to contain the variable types we are searching for. + for _, typ := range typs { + if typ == nil { + continue + } + matches[typ] = []*ast.Ident{} + } + seen := map[types.Object]struct{}{} + ast.Inspect(node, func(n ast.Node) bool { + if n == nil { + return false + } + // Prevent circular definitions. If 'pos' is within an assignment statement, do not + // allow any identifiers in that assignment statement to be selected. Otherwise, + // we could do the following, where 'x' satisfies the type of 'f0': + // + // x := fakeStruct{f0: x} + // + assignment, ok := n.(*ast.AssignStmt) + if ok && pos > assignment.Pos() && pos <= assignment.End() { + return false + } + if n.End() > pos { + return n.Pos() <= pos + } + ident, ok := n.(*ast.Ident) + if !ok || ident.Name == "_" { + return true + } + obj := info.Defs[ident] + if obj == nil || obj.Type() == nil { + return true + } + if _, ok := obj.(*types.TypeName); ok { + return true + } + // Prevent duplicates in matches' values. + if _, ok = seen[obj]; ok { + return true + } + seen[obj] = struct{}{} + // Find the scope for the given position. Then, check whether the object + // exists within the scope. + innerScope := pkg.Scope().Innermost(pos) + if innerScope == nil { + return true + } + _, foundObj := innerScope.LookupParent(ident.Name, pos) + if foundObj != obj { + return true + } + // The object must match one of the types that we are searching for. + if idents, ok := matches[obj.Type()]; ok { + matches[obj.Type()] = append(idents, ast.NewIdent(ident.Name)) + } + // If the object type does not exactly match any of the target types, greedily + // find the first target type that the object type can satisfy. + for typ := range matches { + if obj.Type() == typ { + continue + } + if equivalentTypes(obj.Type(), typ) { + matches[typ] = append(matches[typ], ast.NewIdent(ident.Name)) + } + } + return true + }) + return matches +} + +func equivalentTypes(want, got types.Type) bool { + if want == got || types.Identical(want, got) { + return true + } + // Code segment to help check for untyped equality from (golang/go#32146). + if rhs, ok := want.(*types.Basic); ok && rhs.Info()&types.IsUntyped > 0 { + if lhs, ok := got.Underlying().(*types.Basic); ok { + return rhs.Info()&types.IsConstType == lhs.Info()&types.IsConstType + } + } + return types.AssignableTo(want, got) +} + +// FindBestMatch employs fuzzy matching to evaluate the similarity of each given identifier to the +// given pattern. We return the identifier whose name is most similar to the pattern. +func FindBestMatch(pattern string, idents []*ast.Ident) ast.Expr { + fuzz := fuzzy.NewMatcher(pattern) + var bestFuzz ast.Expr + highScore := float32(0) // minimum score is 0 (no match) + for _, ident := range idents { + // TODO: Improve scoring algorithm. + score := fuzz.Score(ident.Name) + if score > highScore { + highScore = score + bestFuzz = ident + } else if score == 0 { + // Order matters in the fuzzy matching algorithm. If we find no match + // when matching the target to the identifier, try matching the identifier + // to the target. + revFuzz := fuzzy.NewMatcher(ident.Name) + revScore := revFuzz.Score(pattern) + if revScore > highScore { + highScore = revScore + bestFuzz = ident + } + } + } + return bestFuzz +} diff --git a/libgo/go/golang.org/x/tools/internal/lsp/fuzzy/input.go b/libgo/go/golang.org/x/tools/internal/lsp/fuzzy/input.go new file mode 100644 index 00000000000..ac377035ec6 --- /dev/null +++ b/libgo/go/golang.org/x/tools/internal/lsp/fuzzy/input.go @@ -0,0 +1,168 @@ +// 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 fuzzy + +import ( + "unicode" +) + +// RuneRole specifies the role of a rune in the context of an input. +type RuneRole byte + +const ( + // RNone specifies a rune without any role in the input (i.e., whitespace/non-ASCII). + RNone RuneRole = iota + // RSep specifies a rune with the role of segment separator. + RSep + // RTail specifies a rune which is a lower-case tail in a word in the input. + RTail + // RUCTail specifies a rune which is an upper-case tail in a word in the input. + RUCTail + // RHead specifies a rune which is the first character in a word in the input. + RHead +) + +// RuneRoles detects the roles of each byte rune in an input string and stores it in the output +// slice. The rune role depends on the input type. Stops when it parsed all the runes in the string +// or when it filled the output. If output is nil, then it gets created. +func RuneRoles(str string, reuse []RuneRole) []RuneRole { + var output []RuneRole + if cap(reuse) < len(str) { + output = make([]RuneRole, 0, len(str)) + } else { + output = reuse[:0] + } + + prev, prev2 := rtNone, rtNone + for i := 0; i < len(str); i++ { + r := rune(str[i]) + + role := RNone + + curr := rtLower + if str[i] <= unicode.MaxASCII { + curr = runeType(rt[str[i]] - '0') + } + + if curr == rtLower { + if prev == rtNone || prev == rtPunct { + role = RHead + } else { + role = RTail + } + } else if curr == rtUpper { + role = RHead + + if prev == rtUpper { + // This and previous characters are both upper case. + + if i+1 == len(str) { + // This is last character, previous was also uppercase -> this is UCTail + // i.e., (current char is C): aBC / BC / ABC + role = RUCTail + } + } + } else if curr == rtPunct { + switch r { + case '.', ':': + role = RSep + } + } + if curr != rtLower { + if i > 1 && output[i-1] == RHead && prev2 == rtUpper && (output[i-2] == RHead || output[i-2] == RUCTail) { + // The previous two characters were uppercase. The current one is not a lower case, so the + // previous one can't be a HEAD. Make it a UCTail. + // i.e., (last char is current char - B must be a UCTail): ABC / ZABC / AB. + output[i-1] = RUCTail + } + } + + output = append(output, role) + prev2 = prev + prev = curr + } + return output +} + +type runeType byte + +const ( + rtNone runeType = iota + rtPunct + rtLower + rtUpper +) + +const rt = "00000000000000000000000000000000000000000000001122222222221000000333333333333333333333333330000002222222222222222222222222200000" + +// LastSegment returns the substring representing the last segment from the input, where each +// byte has an associated RuneRole in the roles slice. This makes sense only for inputs of Symbol +// or Filename type. +func LastSegment(input string, roles []RuneRole) string { + // Exclude ending separators. + end := len(input) - 1 + for end >= 0 && roles[end] == RSep { + end-- + } + if end < 0 { + return "" + } + + start := end - 1 + for start >= 0 && roles[start] != RSep { + start-- + } + + return input[start+1 : end+1] +} + +// ToLower transforms the input string to lower case, which is stored in the output byte slice. +// The lower casing considers only ASCII values - non ASCII values are left unmodified. +// Stops when parsed all input or when it filled the output slice. If output is nil, then it gets +// created. +func ToLower(input string, reuse []byte) []byte { + output := reuse + if cap(reuse) < len(input) { + output = make([]byte, len(input)) + } + + for i := 0; i < len(input); i++ { + r := rune(input[i]) + if r <= unicode.MaxASCII { + if 'A' <= r && r <= 'Z' { + r += 'a' - 'A' + } + } + output[i] = byte(r) + } + return output[:len(input)] +} + +// WordConsumer defines a consumer for a word delimited by the [start,end) byte offsets in an input +// (start is inclusive, end is exclusive). +type WordConsumer func(start, end int) + +// Words find word delimiters in an input based on its bytes' mappings to rune roles. The offset +// delimiters for each word are fed to the provided consumer function. +func Words(roles []RuneRole, consume WordConsumer) { + var wordStart int + for i, r := range roles { + switch r { + case RUCTail, RTail: + case RHead, RNone, RSep: + if i != wordStart { + consume(wordStart, i) + } + wordStart = i + if r != RHead { + // Skip this character. + wordStart = i + 1 + } + } + } + if wordStart != len(roles) { + consume(wordStart, len(roles)) + } +} diff --git a/libgo/go/golang.org/x/tools/internal/lsp/fuzzy/matcher.go b/libgo/go/golang.org/x/tools/internal/lsp/fuzzy/matcher.go new file mode 100644 index 00000000000..16a643097de --- /dev/null +++ b/libgo/go/golang.org/x/tools/internal/lsp/fuzzy/matcher.go @@ -0,0 +1,398 @@ +// 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 fuzzy implements a fuzzy matching algorithm. +package fuzzy + +import ( + "bytes" + "fmt" +) + +const ( + // MaxInputSize is the maximum size of the input scored against the fuzzy matcher. Longer inputs + // will be truncated to this size. + MaxInputSize = 127 + // MaxPatternSize is the maximum size of the pattern used to construct the fuzzy matcher. Longer + // inputs are truncated to this size. + MaxPatternSize = 63 +) + +type scoreVal int + +func (s scoreVal) val() int { + return int(s) >> 1 +} + +func (s scoreVal) prevK() int { + return int(s) & 1 +} + +func score(val int, prevK int /*0 or 1*/) scoreVal { + return scoreVal(val<<1 + prevK) +} + +// Matcher implements a fuzzy matching algorithm for scoring candidates against a pattern. +// The matcher does not support parallel usage. +type Matcher struct { + pattern string + patternLower []byte // lower-case version of the pattern + patternShort []byte // first characters of the pattern + caseSensitive bool // set if the pattern is mix-cased + + patternRoles []RuneRole // the role of each character in the pattern + roles []RuneRole // the role of each character in the tested string + + scores [MaxInputSize + 1][MaxPatternSize + 1][2]scoreVal + + scoreScale float32 + + lastCandidateLen int // in bytes + lastCandidateMatched bool + + // Here we save the last candidate in lower-case. This is basically a byte slice we reuse for + // performance reasons, so the slice is not reallocated for every candidate. + lowerBuf [MaxInputSize]byte + rolesBuf [MaxInputSize]RuneRole +} + +func (m *Matcher) bestK(i, j int) int { + if m.scores[i][j][0].val() < m.scores[i][j][1].val() { + return 1 + } + return 0 +} + +// NewMatcher returns a new fuzzy matcher for scoring candidates against the provided pattern. +func NewMatcher(pattern string) *Matcher { + if len(pattern) > MaxPatternSize { + pattern = pattern[:MaxPatternSize] + } + + m := &Matcher{ + pattern: pattern, + patternLower: ToLower(pattern, nil), + } + + for i, c := range m.patternLower { + if pattern[i] != c { + m.caseSensitive = true + break + } + } + + if len(pattern) > 3 { + m.patternShort = m.patternLower[:3] + } else { + m.patternShort = m.patternLower + } + + m.patternRoles = RuneRoles(pattern, nil) + + if len(pattern) > 0 { + maxCharScore := 4 + m.scoreScale = 1 / float32(maxCharScore*len(pattern)) + } + + return m +} + +// Score returns the score returned by matching the candidate to the pattern. +// This is not designed for parallel use. Multiple candidates must be scored sequentially. +// Returns a score between 0 and 1 (0 - no match, 1 - perfect match). +func (m *Matcher) Score(candidate string) float32 { + if len(candidate) > MaxInputSize { + candidate = candidate[:MaxInputSize] + } + lower := ToLower(candidate, m.lowerBuf[:]) + m.lastCandidateLen = len(candidate) + + if len(m.pattern) == 0 { + // Empty patterns perfectly match candidates. + return 1 + } + + if m.match(candidate, lower) { + sc := m.computeScore(candidate, lower) + if sc > minScore/2 && !m.poorMatch() { + m.lastCandidateMatched = true + if len(m.pattern) == len(candidate) { + // Perfect match. + return 1 + } + + if sc < 0 { + sc = 0 + } + normalizedScore := float32(sc) * m.scoreScale + if normalizedScore > 1 { + normalizedScore = 1 + } + + return normalizedScore + } + } + + m.lastCandidateMatched = false + return 0 +} + +const minScore = -10000 + +// MatchedRanges returns matches ranges for the last scored string as a flattened array of +// [begin, end) byte offset pairs. +func (m *Matcher) MatchedRanges() []int { + if len(m.pattern) == 0 || !m.lastCandidateMatched { + return nil + } + i, j := m.lastCandidateLen, len(m.pattern) + if m.scores[i][j][0].val() < minScore/2 && m.scores[i][j][1].val() < minScore/2 { + return nil + } + + var ret []int + k := m.bestK(i, j) + for i > 0 { + take := (k == 1) + k = m.scores[i][j][k].prevK() + if take { + if len(ret) == 0 || ret[len(ret)-1] != i { + ret = append(ret, i) + ret = append(ret, i-1) + } else { + ret[len(ret)-1] = i - 1 + } + j-- + } + i-- + } + // Reverse slice. + for i := 0; i < len(ret)/2; i++ { + ret[i], ret[len(ret)-1-i] = ret[len(ret)-1-i], ret[i] + } + return ret +} + +func (m *Matcher) match(candidate string, candidateLower []byte) bool { + i, j := 0, 0 + for ; i < len(candidateLower) && j < len(m.patternLower); i++ { + if candidateLower[i] == m.patternLower[j] { + j++ + } + } + if j != len(m.patternLower) { + return false + } + + // The input passes the simple test against pattern, so it is time to classify its characters. + // Character roles are used below to find the last segment. + m.roles = RuneRoles(candidate, m.rolesBuf[:]) + + return true +} + +func (m *Matcher) computeScore(candidate string, candidateLower []byte) int { + pattLen, candLen := len(m.pattern), len(candidate) + + for j := 0; j <= len(m.pattern); j++ { + m.scores[0][j][0] = minScore << 1 + m.scores[0][j][1] = minScore << 1 + } + m.scores[0][0][0] = score(0, 0) // Start with 0. + + segmentsLeft, lastSegStart := 1, 0 + for i := 0; i < candLen; i++ { + if m.roles[i] == RSep { + segmentsLeft++ + lastSegStart = i + 1 + } + } + + // A per-character bonus for a consecutive match. + consecutiveBonus := 2 + wordIdx := 0 // Word count within segment. + for i := 1; i <= candLen; i++ { + + role := m.roles[i-1] + isHead := role == RHead + + if isHead { + wordIdx++ + } else if role == RSep && segmentsLeft > 1 { + wordIdx = 0 + segmentsLeft-- + } + + var skipPenalty int + if i == 1 || (i-1) == lastSegStart { + // Skipping the start of first or last segment. + skipPenalty++ + } + + for j := 0; j <= pattLen; j++ { + // By default, we don't have a match. Fill in the skip data. + m.scores[i][j][1] = minScore << 1 + + // Compute the skip score. + k := 0 + if m.scores[i-1][j][0].val() < m.scores[i-1][j][1].val() { + k = 1 + } + + skipScore := m.scores[i-1][j][k].val() + // Do not penalize missing characters after the last matched segment. + if j != pattLen { + skipScore -= skipPenalty + } + m.scores[i][j][0] = score(skipScore, k) + + if j == 0 || candidateLower[i-1] != m.patternLower[j-1] { + // Not a match. + continue + } + pRole := m.patternRoles[j-1] + + if role == RTail && pRole == RHead { + if j > 1 { + // Not a match: a head in the pattern matches a tail character in the candidate. + continue + } + // Special treatment for the first character of the pattern. We allow + // matches in the middle of a word if they are long enough, at least + // min(3, pattern.length) characters. + if !bytes.HasPrefix(candidateLower[i-1:], m.patternShort) { + continue + } + } + + // Compute the char score. + var charScore int + // Bonus 1: the char is in the candidate's last segment. + if segmentsLeft <= 1 { + charScore++ + } + // Bonus 2: Case match or a Head in the pattern aligns with one in the word. + // Single-case patterns lack segmentation signals and we assume any character + // can be a head of a segment. + if candidate[i-1] == m.pattern[j-1] || role == RHead && (!m.caseSensitive || pRole == RHead) { + charScore++ + } + + // Penalty 1: pattern char is Head, candidate char is Tail. + if role == RTail && pRole == RHead { + charScore-- + } + // Penalty 2: first pattern character matched in the middle of a word. + if j == 1 && role == RTail { + charScore -= 4 + } + + // Third dimension encodes whether there is a gap between the previous match and the current + // one. + for k := 0; k < 2; k++ { + sc := m.scores[i-1][j-1][k].val() + charScore + + isConsecutive := k == 1 || i-1 == 0 || i-1 == lastSegStart + if isConsecutive { + // Bonus 3: a consecutive match. First character match also gets a bonus to + // ensure prefix final match score normalizes to 1.0. + // Logically, this is a part of charScore, but we have to compute it here because it + // only applies for consecutive matches (k == 1). + sc += consecutiveBonus + } + if k == 0 { + // Penalty 3: Matching inside a segment (and previous char wasn't matched). Penalize for the lack + // of alignment. + if role == RTail || role == RUCTail { + sc -= 3 + } + } + + if sc > m.scores[i][j][1].val() { + m.scores[i][j][1] = score(sc, k) + } + } + } + } + + result := m.scores[len(candidate)][len(m.pattern)][m.bestK(len(candidate), len(m.pattern))].val() + + return result +} + +// ScoreTable returns the score table computed for the provided candidate. Used only for debugging. +func (m *Matcher) ScoreTable(candidate string) string { + var buf bytes.Buffer + + var line1, line2, separator bytes.Buffer + line1.WriteString("\t") + line2.WriteString("\t") + for j := 0; j < len(m.pattern); j++ { + line1.WriteString(fmt.Sprintf("%c\t\t", m.pattern[j])) + separator.WriteString("----------------") + } + + buf.WriteString(line1.String()) + buf.WriteString("\n") + buf.WriteString(separator.String()) + buf.WriteString("\n") + + for i := 1; i <= len(candidate); i++ { + line1.Reset() + line2.Reset() + + line1.WriteString(fmt.Sprintf("%c\t", candidate[i-1])) + line2.WriteString("\t") + + for j := 1; j <= len(m.pattern); j++ { + line1.WriteString(fmt.Sprintf("M%6d(%c)\t", m.scores[i][j][0].val(), dir(m.scores[i][j][0].prevK()))) + line2.WriteString(fmt.Sprintf("H%6d(%c)\t", m.scores[i][j][1].val(), dir(m.scores[i][j][1].prevK()))) + } + buf.WriteString(line1.String()) + buf.WriteString("\n") + buf.WriteString(line2.String()) + buf.WriteString("\n") + buf.WriteString(separator.String()) + buf.WriteString("\n") + } + + return buf.String() +} + +func dir(prevK int) rune { + if prevK == 0 { + return 'M' + } + return 'H' +} + +func (m *Matcher) poorMatch() bool { + if len(m.pattern) < 2 { + return false + } + + i, j := m.lastCandidateLen, len(m.pattern) + k := m.bestK(i, j) + + var counter, len int + for i > 0 { + take := (k == 1) + k = m.scores[i][j][k].prevK() + if take { + len++ + if k == 0 && len < 3 && m.roles[i-1] == RTail { + // Short match in the middle of a word + counter++ + if counter > 1 { + return true + } + } + j-- + } else { + len = 0 + } + i-- + } + return false +} diff --git a/libgo/go/hash/crc32/crc32.go b/libgo/go/hash/crc32/crc32.go index 908b84adcb2..f330fdb77a5 100644 --- a/libgo/go/hash/crc32/crc32.go +++ b/libgo/go/hash/crc32/crc32.go @@ -16,6 +16,7 @@ import ( "errors" "hash" "sync" + "sync/atomic" ) // The size of a CRC-32 checksum in bytes. @@ -78,6 +79,7 @@ var castagnoliTable8 *slicing8Table var castagnoliArchImpl bool var updateCastagnoli func(crc uint32, p []byte) uint32 var castagnoliOnce sync.Once +var haveCastagnoli uint32 func castagnoliInit() { castagnoliTable = simpleMakeTable(Castagnoli) @@ -93,6 +95,8 @@ func castagnoliInit() { return slicingUpdate(crc, castagnoliTable8, p) } } + + atomic.StoreUint32(&haveCastagnoli, 1) } // IEEETable is the table for the IEEE polynomial. @@ -208,10 +212,10 @@ func readUint32(b []byte) uint32 { // Update returns the result of adding the bytes in p to the crc. func Update(crc uint32, tab *Table, p []byte) uint32 { - switch tab { - case castagnoliTable: + switch { + case atomic.LoadUint32(&haveCastagnoli) != 0 && tab == castagnoliTable: return updateCastagnoli(crc, p) - case IEEETable: + case tab == IEEETable: // Unfortunately, because IEEETable is exported, IEEE may be used without a // call to MakeTable. We have to make sure it gets initialized in that case. ieeeOnce.Do(ieeeInit) @@ -222,10 +226,10 @@ func Update(crc uint32, tab *Table, p []byte) uint32 { } func (d *digest) Write(p []byte) (n int, err error) { - switch d.tab { - case castagnoliTable: + switch { + case atomic.LoadUint32(&haveCastagnoli) != 0 && d.tab == castagnoliTable: d.crc = updateCastagnoli(d.crc, p) - case IEEETable: + case d.tab == IEEETable: // We only create digest objects through New() which takes care of // initialization in this case. d.crc = updateIEEE(d.crc, p) diff --git a/libgo/go/hash/crc32/crc32_test.go b/libgo/go/hash/crc32/crc32_test.go index 4bdafaf8f52..cbb869dfd64 100644 --- a/libgo/go/hash/crc32/crc32_test.go +++ b/libgo/go/hash/crc32/crc32_test.go @@ -13,6 +13,16 @@ import ( "testing" ) +// First test, so that it can be the one to initialize castagnoliTable. +func TestCastagnoliRace(t *testing.T) { + // The MakeTable(Castagnoli) lazily initializes castagnoliTable, + // which races with the switch on tab during Write to check + // whether tab == castagnoliTable. + ieee := NewIEEE() + go MakeTable(Castagnoli) + ieee.Write([]byte("hello")) +} + type test struct { ieee, castagnoli uint32 in string diff --git a/libgo/go/hash/crc32/gen_const_ppc64le.go b/libgo/go/hash/crc32/gen_const_ppc64le.go index bfb3b3a2278..d7af018af48 100644 --- a/libgo/go/hash/crc32/gen_const_ppc64le.go +++ b/libgo/go/hash/crc32/gen_const_ppc64le.go @@ -27,7 +27,7 @@ package main import ( "bytes" "fmt" - "io/ioutil" + "os" ) var blocking = 32 * 1024 @@ -103,7 +103,7 @@ func main() { genCrc32ConstTable(w, 0xeb31d82e, "Koop") b := w.Bytes() - err := ioutil.WriteFile("crc32_table_ppc64le.s", b, 0666) + err := os.WriteFile("crc32_table_ppc64le.s", b, 0666) if err != nil { fmt.Printf("can't write output: %s\n", err) } diff --git a/libgo/go/hash/maphash/maphash.go b/libgo/go/hash/maphash/maphash.go index 071dc04b548..ecc147d5997 100644 --- a/libgo/go/hash/maphash/maphash.go +++ b/libgo/go/hash/maphash/maphash.go @@ -6,12 +6,11 @@ // 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 on unsigned 64-bit integers. +// Each different instance of a hash table or data structure should use its own Seed. // -// The hash functions are collision-resistant but not cryptographically secure. +// The hash functions are not cryptographically secure. // (See crypto/sha256 and crypto/sha512 for cryptographic use.) // -// The hash value of a given byte sequence is consistent within a -// single process, but will be different in different processes. package maphash import "unsafe" diff --git a/libgo/go/hash/maphash/maphash_test.go b/libgo/go/hash/maphash/maphash_test.go index caea43a8c83..daf6eb47866 100644 --- a/libgo/go/hash/maphash/maphash_test.go +++ b/libgo/go/hash/maphash/maphash_test.go @@ -165,3 +165,32 @@ func TestSeedFromReset(t *testing.T) { // Make sure a Hash implements the hash.Hash and hash.Hash64 interfaces. var _ hash.Hash = &Hash{} var _ hash.Hash64 = &Hash{} + +func benchmarkSize(b *testing.B, size int) { + h := &Hash{} + buf := make([]byte, size) + b.SetBytes(int64(size)) + b.ResetTimer() + + for i := 0; i < b.N; i++ { + h.Reset() + h.Write(buf) + h.Sum64() + } +} + +func BenchmarkHash8Bytes(b *testing.B) { + benchmarkSize(b, 8) +} + +func BenchmarkHash320Bytes(b *testing.B) { + benchmarkSize(b, 320) +} + +func BenchmarkHash1K(b *testing.B) { + benchmarkSize(b, 1024) +} + +func BenchmarkHash8K(b *testing.B) { + benchmarkSize(b, 8192) +} diff --git a/libgo/go/html/template/clone_test.go b/libgo/go/html/template/clone_test.go index c9c619f0d45..7cb1b9ca062 100644 --- a/libgo/go/html/template/clone_test.go +++ b/libgo/go/html/template/clone_test.go @@ -8,7 +8,7 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" + "io" "strings" "sync" "testing" @@ -171,7 +171,7 @@ func TestCloneThenParse(t *testing.T) { t.Error("adding a template to a clone added it to the original") } // double check that the embedded template isn't available in the original - err := t0.ExecuteTemplate(ioutil.Discard, "a", nil) + err := t0.ExecuteTemplate(io.Discard, "a", nil) if err == nil { t.Error("expected 'no such template' error") } @@ -185,13 +185,13 @@ func TestFuncMapWorksAfterClone(t *testing.T) { // get the expected error output (no clone) uncloned := Must(New("").Funcs(funcs).Parse("{{customFunc}}")) - wantErr := uncloned.Execute(ioutil.Discard, nil) + wantErr := uncloned.Execute(io.Discard, nil) // toClone must be the same as uncloned. It has to be recreated from scratch, // since cloning cannot occur after execution. toClone := Must(New("").Funcs(funcs).Parse("{{customFunc}}")) cloned := Must(toClone.Clone()) - gotErr := cloned.Execute(ioutil.Discard, nil) + gotErr := cloned.Execute(io.Discard, nil) if wantErr.Error() != gotErr.Error() { t.Errorf("clone error message mismatch want %q got %q", wantErr, gotErr) @@ -213,7 +213,7 @@ func TestTemplateCloneExecuteRace(t *testing.T) { go func() { defer wg.Done() for i := 0; i < 100; i++ { - if err := tmpl.Execute(ioutil.Discard, "data"); err != nil { + if err := tmpl.Execute(io.Discard, "data"); err != nil { panic(err) } } @@ -237,7 +237,7 @@ func TestCloneGrowth(t *testing.T) { tmpl = Must(tmpl.Clone()) Must(tmpl.Parse(`{{define "B"}}Text{{end}}`)) for i := 0; i < 10; i++ { - tmpl.Execute(ioutil.Discard, nil) + tmpl.Execute(io.Discard, nil) } if len(tmpl.DefinedTemplates()) > 200 { t.Fatalf("too many templates: %v", len(tmpl.DefinedTemplates())) @@ -257,7 +257,7 @@ func TestCloneRedefinedName(t *testing.T) { for i := 0; i < 2; i++ { t2 := Must(t1.Clone()) t2 = Must(t2.New(fmt.Sprintf("%d", i)).Parse(page)) - err := t2.Execute(ioutil.Discard, nil) + err := t2.Execute(io.Discard, nil) if err != nil { t.Fatal(err) } diff --git a/libgo/go/html/template/escape.go b/libgo/go/html/template/escape.go index f12dafa8702..8739735cb7b 100644 --- a/libgo/go/html/template/escape.go +++ b/libgo/go/html/template/escape.go @@ -124,6 +124,8 @@ func (e *escaper) escape(c context, n parse.Node) context { switch n := n.(type) { case *parse.ActionNode: return e.escapeAction(c, n) + case *parse.CommentNode: + return c case *parse.IfNode: return e.escapeBranch(c, &n.BranchNode, "if") case *parse.ListNode: diff --git a/libgo/go/html/template/examplefiles_test.go b/libgo/go/html/template/examplefiles_test.go index 60518aee9ec..5eb25974641 100644 --- a/libgo/go/html/template/examplefiles_test.go +++ b/libgo/go/html/template/examplefiles_test.go @@ -6,7 +6,6 @@ package template_test import ( "io" - "io/ioutil" "log" "os" "path/filepath" @@ -20,7 +19,7 @@ type templateFile struct { } func createTestDir(files []templateFile) string { - dir, err := ioutil.TempDir("", "template") + dir, err := os.MkdirTemp("", "template") if err != nil { log.Fatal(err) } diff --git a/libgo/go/html/template/exec_test.go b/libgo/go/html/template/exec_test.go index ec2bfcccab5..eb008242603 100644 --- a/libgo/go/html/template/exec_test.go +++ b/libgo/go/html/template/exec_test.go @@ -11,9 +11,10 @@ import ( "errors" "flag" "fmt" - "io/ioutil" + "io" "reflect" "strings" + "sync" "testing" "text/template" ) @@ -1302,7 +1303,7 @@ func TestUnterminatedStringError(t *testing.T) { t.Fatal("expected error") } str := err.Error() - if !strings.Contains(str, "X:3: unexpected unterminated raw quoted string") { + if !strings.Contains(str, "X:3: unterminated raw quoted string") { t.Fatalf("unexpected error: %s", str) } } @@ -1335,7 +1336,7 @@ func TestExecuteGivesExecError(t *testing.T) { if err != nil { t.Fatal(err) } - err = tmpl.Execute(ioutil.Discard, 0) + err = tmpl.Execute(io.Discard, 0) if err == nil { t.Fatal("expected error; got none") } @@ -1481,7 +1482,7 @@ func TestEvalFieldErrors(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { tmpl := Must(New("tmpl").Parse(tc.src)) - err := tmpl.Execute(ioutil.Discard, tc.value) + err := tmpl.Execute(io.Discard, tc.value) got := "" if err != nil { got = err.Error() @@ -1498,7 +1499,7 @@ func TestMaxExecDepth(t *testing.T) { t.Skip("skipping in -short mode") } tmpl := Must(New("tmpl").Parse(`{{template "tmpl" .}}`)) - err := tmpl.Execute(ioutil.Discard, nil) + err := tmpl.Execute(io.Discard, nil) got := "" if err != nil { got = err.Error() @@ -1706,3 +1707,72 @@ func TestIssue31810(t *testing.T) { t.Errorf("%s got %q, expected %q", textCall, b.String(), "result") } } + +// Issue 39807. There was a race applying escapeTemplate. + +const raceText = ` +{{- define "jstempl" -}} +var v = "v"; +{{- end -}} + +` + +func TestEscapeRace(t *testing.T) { + tmpl := New("") + _, err := tmpl.New("templ.html").Parse(raceText) + if err != nil { + t.Fatal(err) + } + const count = 20 + for i := 0; i < count; i++ { + _, err := tmpl.New(fmt.Sprintf("x%d.html", i)).Parse(`{{ template "templ.html" .}}`) + if err != nil { + t.Fatal(err) + } + } + + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + for j := 0; j < count; j++ { + sub := tmpl.Lookup(fmt.Sprintf("x%d.html", j)) + if err := sub.Execute(io.Discard, nil); err != nil { + t.Error(err) + } + } + }() + } + wg.Wait() +} + +func TestRecursiveExecute(t *testing.T) { + tmpl := New("") + + recur := func() (HTML, error) { + var sb strings.Builder + if err := tmpl.ExecuteTemplate(&sb, "subroutine", nil); err != nil { + t.Fatal(err) + } + return HTML(sb.String()), nil + } + + m := FuncMap{ + "recur": recur, + } + + top, err := tmpl.New("x.html").Funcs(m).Parse(`{{recur}}`) + if err != nil { + t.Fatal(err) + } + _, err = tmpl.New("subroutine").Parse(``) + if err != nil { + t.Fatal(err) + } + if err := top.Execute(io.Discard, nil); err != nil { + t.Fatal(err) + } +} diff --git a/libgo/go/html/template/multi_test.go b/libgo/go/html/template/multi_test.go index 50526c5b65f..6535ab6c043 100644 --- a/libgo/go/html/template/multi_test.go +++ b/libgo/go/html/template/multi_test.go @@ -7,7 +7,9 @@ package template import ( + "archive/zip" "bytes" + "os" "testing" "text/template/parse" ) @@ -82,6 +84,35 @@ func TestParseGlob(t *testing.T) { testExecute(multiExecTests, template, t) } +func TestParseFS(t *testing.T) { + fs := os.DirFS("testdata") + + { + _, err := ParseFS(fs, "DOES NOT EXIST") + if err == nil { + t.Error("expected error for non-existent file; got none") + } + } + + { + template := New("root") + _, err := template.ParseFS(fs, "file1.tmpl", "file2.tmpl") + if err != nil { + t.Fatalf("error parsing files: %v", err) + } + testExecute(multiExecTests, template, t) + } + + { + template := New("root") + _, err := template.ParseFS(fs, "file*.tmpl") + if err != nil { + t.Fatalf("error parsing files: %v", err) + } + testExecute(multiExecTests, template, t) + } +} + // In these tests, actual content (not just template definitions) comes from the parsed files. var templateFileExecTests = []execTest{ @@ -104,6 +135,18 @@ func TestParseGlobWithData(t *testing.T) { testExecute(templateFileExecTests, template, t) } +func TestParseZipFS(t *testing.T) { + z, err := zip.OpenReader("testdata/fs.zip") + if err != nil { + t.Fatalf("error parsing zip: %v", err) + } + template, err := New("root").ParseFS(z, "tmpl*.tmpl") + if err != nil { + t.Fatalf("error parsing files: %v", err) + } + testExecute(templateFileExecTests, template, t) +} + const ( cloneText1 = `{{define "a"}}{{template "b"}}{{template "c"}}{{end}}` cloneText2 = `{{define "b"}}b{{end}}` diff --git a/libgo/go/html/template/template.go b/libgo/go/html/template/template.go index 75437879e2e..09d71d43e2f 100644 --- a/libgo/go/html/template/template.go +++ b/libgo/go/html/template/template.go @@ -7,8 +7,11 @@ package template import ( "fmt" "io" - "io/ioutil" + "io/fs" + "os" + "path" "path/filepath" + "reflect" "sync" "text/template" "text/template/parse" @@ -24,7 +27,9 @@ type Template struct { // template's in sync. text *template.Template // The underlying template's parse tree, updated to be HTML-safe. - Tree *parse.Tree + Tree *parse.Tree + // The original functions, before wrapping. + funcMap FuncMap *nameSpace // common to all associated templates } @@ -33,7 +38,7 @@ var escapeOK = fmt.Errorf("template escaped correctly") // nameSpace is the data structure shared by all templates in an association. type nameSpace struct { - mu sync.Mutex + mu sync.RWMutex set map[string]*Template escaped bool esc escaper @@ -43,8 +48,8 @@ type nameSpace struct { // itself. func (t *Template) Templates() []*Template { ns := t.nameSpace - ns.mu.Lock() - defer ns.mu.Unlock() + ns.mu.RLock() + defer ns.mu.RUnlock() // Return a slice so we don't expose the map. m := make([]*Template, 0, len(ns.set)) for _, v := range ns.set { @@ -82,8 +87,8 @@ func (t *Template) checkCanParse() error { if t == nil { return nil } - t.nameSpace.mu.Lock() - defer t.nameSpace.mu.Unlock() + t.nameSpace.mu.RLock() + defer t.nameSpace.mu.RUnlock() if t.nameSpace.escaped { return fmt.Errorf("html/template: cannot Parse after Execute") } @@ -92,6 +97,16 @@ func (t *Template) checkCanParse() error { // escape escapes all associated templates. func (t *Template) escape() error { + t.nameSpace.mu.RLock() + escapeErr := t.escapeErr + t.nameSpace.mu.RUnlock() + if escapeErr != nil { + if escapeErr == escapeOK { + return nil + } + return escapeErr + } + t.nameSpace.mu.Lock() defer t.nameSpace.mu.Unlock() t.nameSpace.escaped = true @@ -119,6 +134,8 @@ func (t *Template) Execute(wr io.Writer, data interface{}) error { if err := t.escape(); err != nil { return err } + t.nameSpace.mu.RLock() + defer t.nameSpace.mu.RUnlock() return t.text.Execute(wr, data) } @@ -134,6 +151,8 @@ func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) if err != nil { return err } + t.nameSpace.mu.RLock() + defer t.nameSpace.mu.RUnlock() return tmpl.text.Execute(wr, data) } @@ -141,13 +160,27 @@ func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) // is escaped, or returns an error if it cannot be. It returns the named // template. func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err error) { - t.nameSpace.mu.Lock() - defer t.nameSpace.mu.Unlock() - t.nameSpace.escaped = true + t.nameSpace.mu.RLock() tmpl = t.set[name] + var escapeErr error + if tmpl != nil { + escapeErr = tmpl.escapeErr + } + t.nameSpace.mu.RUnlock() + if tmpl == nil { return nil, fmt.Errorf("html/template: %q is undefined", name) } + if escapeErr != nil { + if escapeErr != escapeOK { + return nil, escapeErr + } + return tmpl, nil + } + + t.nameSpace.mu.Lock() + defer t.nameSpace.mu.Unlock() + t.nameSpace.escaped = true if tmpl.escapeErr != nil && tmpl.escapeErr != escapeOK { return nil, tmpl.escapeErr } @@ -227,6 +260,7 @@ func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error nil, text, text.Tree, + nil, t.nameSpace, } t.set[name] = ret @@ -257,8 +291,10 @@ func (t *Template) Clone() (*Template, error) { nil, textClone, textClone.Tree, + t.funcMap, ns, } + ret.wrapFuncs() ret.set[ret.Name()] = ret for _, x := range textClone.Templates() { name := x.Name() @@ -267,12 +303,15 @@ func (t *Template) Clone() (*Template, error) { return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name()) } x.Tree = x.Tree.Copy() - ret.set[name] = &Template{ + tc := &Template{ nil, x, x.Tree, + src.funcMap, ret.nameSpace, } + tc.wrapFuncs() + ret.set[name] = tc } // Return the template associated with the name of this template. return ret.set[ret.Name()], nil @@ -286,6 +325,7 @@ func New(name string) *Template { nil, template.New(name), nil, + nil, ns, } tmpl.set[name] = tmpl @@ -311,6 +351,7 @@ func (t *Template) new(name string) *Template { nil, t.text.New(name), nil, + nil, t.nameSpace, } if existing, ok := tmpl.set[name]; ok { @@ -341,10 +382,35 @@ type FuncMap map[string]interface{} // type. However, it is legal to overwrite elements of the map. The return // value is the template, so calls can be chained. func (t *Template) Funcs(funcMap FuncMap) *Template { - t.text.Funcs(template.FuncMap(funcMap)) + t.funcMap = funcMap + t.wrapFuncs() return t } +// wrapFuncs records the functions with text/template. We wrap them to +// unlock the nameSpace. See TestRecursiveExecute for a test case. +func (t *Template) wrapFuncs() { + if len(t.funcMap) == 0 { + return + } + tfuncs := make(template.FuncMap, len(t.funcMap)) + for name, fn := range t.funcMap { + fnv := reflect.ValueOf(fn) + wrapper := func(args []reflect.Value) []reflect.Value { + t.nameSpace.mu.RUnlock() + defer t.nameSpace.mu.RLock() + if fnv.Type().IsVariadic() { + return fnv.CallSlice(args) + } else { + return fnv.Call(args) + } + } + wrapped := reflect.MakeFunc(fnv.Type(), wrapper) + tfuncs[name] = wrapped.Interface() + } + t.text.Funcs(tfuncs) +} + // Delims sets the action delimiters to the specified strings, to be used in // subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template // definitions will inherit the settings. An empty delimiter stands for the @@ -358,8 +424,8 @@ func (t *Template) Delims(left, right string) *Template { // Lookup returns the template with the given name that is associated with t, // or nil if there is no such template. func (t *Template) Lookup(name string) *Template { - t.nameSpace.mu.Lock() - defer t.nameSpace.mu.Unlock() + t.nameSpace.mu.RLock() + defer t.nameSpace.mu.RUnlock() return t.set[name] } @@ -384,7 +450,7 @@ func Must(t *Template, err error) *Template { // For instance, ParseFiles("a/foo", "b/foo") stores "b/foo" as the template // named "foo", while "a/foo" is unavailable. func ParseFiles(filenames ...string) (*Template, error) { - return parseFiles(nil, filenames...) + return parseFiles(nil, readFileOS, filenames...) } // ParseFiles parses the named files and associates the resulting templates with @@ -396,12 +462,12 @@ func ParseFiles(filenames ...string) (*Template, error) { // // ParseFiles returns an error if t or any associated template has already been executed. func (t *Template) ParseFiles(filenames ...string) (*Template, error) { - return parseFiles(t, filenames...) + return parseFiles(t, readFileOS, filenames...) } // parseFiles is the helper for the method and function. If the argument // template is nil, it is created from the first file. -func parseFiles(t *Template, filenames ...string) (*Template, error) { +func parseFiles(t *Template, readFile func(string) (string, []byte, error), filenames ...string) (*Template, error) { if err := t.checkCanParse(); err != nil { return nil, err } @@ -411,12 +477,11 @@ func parseFiles(t *Template, filenames ...string) (*Template, error) { return nil, fmt.Errorf("html/template: no files named in call to ParseFiles") } for _, filename := range filenames { - b, err := ioutil.ReadFile(filename) + name, b, err := readFile(filename) if err != nil { return nil, err } s := string(b) - name := filepath.Base(filename) // First template becomes return value if not already defined, // and we use that one for subsequent New calls to associate // all the templates together. Also, if this file has the same name @@ -479,7 +544,7 @@ func parseGlob(t *Template, pattern string) (*Template, error) { if len(filenames) == 0 { return nil, fmt.Errorf("html/template: pattern matches no files: %#q", pattern) } - return parseFiles(t, filenames...) + return parseFiles(t, readFileOS, filenames...) } // IsTrue reports whether the value is 'true', in the sense of not the zero of its type, @@ -488,3 +553,48 @@ func parseGlob(t *Template, pattern string) (*Template, error) { func IsTrue(val interface{}) (truth, ok bool) { return template.IsTrue(val) } + +// ParseFS is like ParseFiles or ParseGlob but reads from the file system fs +// instead of the host operating system's file system. +// It accepts a list of glob patterns. +// (Note that most file names serve as glob patterns matching only themselves.) +func ParseFS(fs fs.FS, patterns ...string) (*Template, error) { + return parseFS(nil, fs, patterns) +} + +// ParseFS is like ParseFiles or ParseGlob but reads from the file system fs +// instead of the host operating system's file system. +// It accepts a list of glob patterns. +// (Note that most file names serve as glob patterns matching only themselves.) +func (t *Template) ParseFS(fs fs.FS, patterns ...string) (*Template, error) { + return parseFS(t, fs, patterns) +} + +func parseFS(t *Template, fsys fs.FS, patterns []string) (*Template, error) { + var filenames []string + for _, pattern := range patterns { + list, err := fs.Glob(fsys, pattern) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, fmt.Errorf("template: pattern matches no files: %#q", pattern) + } + filenames = append(filenames, list...) + } + return parseFiles(t, readFileFS(fsys), filenames...) +} + +func readFileOS(file string) (name string, b []byte, err error) { + name = filepath.Base(file) + b, err = os.ReadFile(file) + return +} + +func readFileFS(fsys fs.FS) func(string) (string, []byte, error) { + return func(file string) (name string, b []byte, err error) { + name = path.Base(file) + b, err = fs.ReadFile(fsys, file) + return + } +} diff --git a/libgo/go/html/template/template_test.go b/libgo/go/html/template/template_test.go index 86bd4db444d..1f2c888bbea 100644 --- a/libgo/go/html/template/template_test.go +++ b/libgo/go/html/template/template_test.go @@ -10,6 +10,7 @@ import ( . "html/template" "strings" "testing" + "text/template/parse" ) func TestTemplateClone(t *testing.T) { @@ -160,6 +161,21 @@ func TestStringsInScriptsWithJsonContentTypeAreCorrectlyEscaped(t *testing.T) { } } +func TestSkipEscapeComments(t *testing.T) { + c := newTestCase(t) + tr := parse.New("root") + tr.Mode = parse.ParseComments + newT, err := tr.Parse("{{/* A comment */}}{{ 1 }}{{/* Another comment */}}", "", "", make(map[string]*parse.Tree)) + if err != nil { + t.Fatalf("Cannot parse template text: %v", err) + } + c.root, err = c.root.AddParseTree("root", newT) + if err != nil { + t.Fatalf("Cannot add parse tree to template: %v", err) + } + c.mustExecute(c.root, nil, "1") +} + type testCase struct { t *testing.T root *Template diff --git a/libgo/go/html/template/testdata/fs.zip b/libgo/go/html/template/testdata/fs.zip new file mode 100644 index 0000000000000000000000000000000000000000..8581313ae36f2b3980e320f3a8f747db9727386a GIT binary patch literal 406 zcmWIWW@Zs#U|`^2;3#<;P@%SDw+@hJ1jJknG7KfT1v!R#ATl(BlYx2t3ZD4q!ou;T z72FJrEV`i#3@pL%j11bIXLV0_>Uf$yS+&m3)A#fl@6do%0jt)oU9ryZtoO>btX$I_ zrfO(}GO6xh2tct<= 8 { if err != nil { t.Errorf("upperBound=%d: %v", upperBound, err) @@ -429,7 +430,7 @@ func TestEncodeImplicitConfigSize(t *testing.T) { Image: images, Delay: make([]int, len(images)), } - err := EncodeAll(ioutil.Discard, g) + err := EncodeAll(io.Discard, g) if lowerBound >= 0 { if err != nil { t.Errorf("lowerBound=%d: %v", lowerBound, err) @@ -508,7 +509,7 @@ func TestEncodeBadPalettes(t *testing.T) { } } - err := EncodeAll(ioutil.Discard, &GIF{ + err := EncodeAll(io.Discard, &GIF{ Image: []*image.Paletted{ image.NewPaletted(image.Rect(0, 0, w, h), pal), }, @@ -656,39 +657,28 @@ func TestEncodeWrappedImage(t *testing.T) { } } -func BenchmarkEncode(b *testing.B) { +func BenchmarkEncodeRandomPaletted(b *testing.B) { + paletted := image.NewPaletted(image.Rect(0, 0, 640, 480), palette.Plan9) rnd := rand.New(rand.NewSource(123)) - - // Restrict to a 256-color paletted image to avoid quantization path. - palette := make(color.Palette, 256) - for i := range palette { - palette[i] = color.RGBA{ - uint8(rnd.Intn(256)), - uint8(rnd.Intn(256)), - uint8(rnd.Intn(256)), - 255, - } - } - img := image.NewPaletted(image.Rect(0, 0, 640, 480), palette) - for i := range img.Pix { - img.Pix[i] = uint8(rnd.Intn(256)) + for i := range paletted.Pix { + paletted.Pix[i] = uint8(rnd.Intn(256)) } - b.SetBytes(640 * 480 * 4) + b.SetBytes(640 * 480 * 1) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img, nil) + Encode(io.Discard, paletted, nil) } } -func BenchmarkQuantizedEncode(b *testing.B) { - img := image.NewRGBA(image.Rect(0, 0, 640, 480)) - bo := img.Bounds() +func BenchmarkEncodeRandomRGBA(b *testing.B) { + rgba := image.NewRGBA(image.Rect(0, 0, 640, 480)) + bo := rgba.Bounds() rnd := rand.New(rand.NewSource(123)) for y := bo.Min.Y; y < bo.Max.Y; y++ { for x := bo.Min.X; x < bo.Max.X; x++ { - img.SetRGBA(x, y, color.RGBA{ + rgba.SetRGBA(x, y, color.RGBA{ uint8(rnd.Intn(256)), uint8(rnd.Intn(256)), uint8(rnd.Intn(256)), @@ -696,10 +686,49 @@ func BenchmarkQuantizedEncode(b *testing.B) { }) } } + b.SetBytes(640 * 480 * 4) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img, nil) + Encode(io.Discard, rgba, nil) + } +} + +func BenchmarkEncodeRealisticPaletted(b *testing.B) { + img, err := readImg("../testdata/video-001.png") + if err != nil { + b.Fatalf("readImg: %v", err) + } + bo := img.Bounds() + paletted := image.NewPaletted(bo, palette.Plan9) + draw.Draw(paletted, bo, img, bo.Min, draw.Src) + + b.SetBytes(int64(bo.Dx() * bo.Dy() * 1)) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + Encode(io.Discard, paletted, nil) + } +} + +func BenchmarkEncodeRealisticRGBA(b *testing.B) { + img, err := readImg("../testdata/video-001.png") + if err != nil { + b.Fatalf("readImg: %v", err) + } + bo := img.Bounds() + // Converting img to rgba is redundant for video-001.png, which is already + // in the RGBA format, but for those copy/pasting this benchmark (but + // changing the source image), the conversion ensures that we're still + // benchmarking encoding an RGBA image. + rgba := image.NewRGBA(bo) + draw.Draw(rgba, bo, img, bo.Min, draw.Src) + + b.SetBytes(int64(bo.Dx() * bo.Dy() * 4)) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + Encode(io.Discard, rgba, nil) } } diff --git a/libgo/go/image/internal/imageutil/gen.go b/libgo/go/image/internal/imageutil/gen.go index bc85c512f9c..36de5dc9cc6 100644 --- a/libgo/go/image/internal/imageutil/gen.go +++ b/libgo/go/image/internal/imageutil/gen.go @@ -11,7 +11,6 @@ import ( "flag" "fmt" "go/format" - "io/ioutil" "log" "os" ) @@ -36,7 +35,7 @@ func main() { if err != nil { log.Fatal(err) } - if err := ioutil.WriteFile("impl.go", out, 0660); err != nil { + if err := os.WriteFile("impl.go", out, 0660); err != nil { log.Fatal(err) } } diff --git a/libgo/go/image/jpeg/reader_test.go b/libgo/go/image/jpeg/reader_test.go index 1e2798c9457..bf07fadede5 100644 --- a/libgo/go/image/jpeg/reader_test.go +++ b/libgo/go/image/jpeg/reader_test.go @@ -11,7 +11,6 @@ import ( "image" "image/color" "io" - "io/ioutil" "math/rand" "os" "strings" @@ -118,7 +117,7 @@ func (r *eofReader) Read(b []byte) (n int, err error) { func TestDecodeEOF(t *testing.T) { // Check that if reader returns final data and EOF at same time, jpeg handles it. - data, err := ioutil.ReadFile("../testdata/video-001.jpeg") + data, err := os.ReadFile("../testdata/video-001.jpeg") if err != nil { t.Fatal(err) } @@ -189,7 +188,7 @@ func pixString(pix []byte, stride, x, y int) string { } func TestTruncatedSOSDataDoesntPanic(t *testing.T) { - b, err := ioutil.ReadFile("../testdata/video-005.gray.q50.jpeg") + b, err := os.ReadFile("../testdata/video-005.gray.q50.jpeg") if err != nil { t.Fatal(err) } @@ -493,7 +492,7 @@ func TestExtraneousData(t *testing.T) { } func benchmarkDecode(b *testing.B, filename string) { - data, err := ioutil.ReadFile(filename) + data, err := os.ReadFile(filename) if err != nil { b.Fatal(err) } diff --git a/libgo/go/image/jpeg/writer_test.go b/libgo/go/image/jpeg/writer_test.go index 3aff7426325..abd5e323339 100644 --- a/libgo/go/image/jpeg/writer_test.go +++ b/libgo/go/image/jpeg/writer_test.go @@ -10,7 +10,7 @@ import ( "image" "image/color" "image/png" - "io/ioutil" + "io" "math/rand" "os" "testing" @@ -261,7 +261,7 @@ func BenchmarkEncodeRGBA(b *testing.B) { b.ResetTimer() options := &Options{Quality: 90} for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img, options) + Encode(io.Discard, img, options) } } @@ -283,6 +283,6 @@ func BenchmarkEncodeYCbCr(b *testing.B) { b.ResetTimer() options := &Options{Quality: 90} for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img, options) + Encode(io.Discard, img, options) } } diff --git a/libgo/go/image/png/reader_test.go b/libgo/go/image/png/reader_test.go index 22c704e5cba..39376852941 100644 --- a/libgo/go/image/png/reader_test.go +++ b/libgo/go/image/png/reader_test.go @@ -11,7 +11,6 @@ import ( "image" "image/color" "io" - "io/ioutil" "os" "reflect" "strings" @@ -785,7 +784,7 @@ func TestDimensionOverflow(t *testing.T) { } func benchmarkDecode(b *testing.B, filename string, bytesPerPixel int) { - data, err := ioutil.ReadFile(filename) + data, err := os.ReadFile(filename) if err != nil { b.Fatal(err) } diff --git a/libgo/go/image/png/writer_test.go b/libgo/go/image/png/writer_test.go index 5d131ff823a..47aa8613398 100644 --- a/libgo/go/image/png/writer_test.go +++ b/libgo/go/image/png/writer_test.go @@ -12,7 +12,6 @@ import ( "image" "image/color" "io" - "io/ioutil" "testing" ) @@ -169,7 +168,7 @@ func TestWriterPaletted(t *testing.T) { t.Error(err) return } - n, err := io.Copy(ioutil.Discard, r) + n, err := io.Copy(io.Discard, r) if err != nil { t.Errorf("got error while reading image data: %v", err) } @@ -234,7 +233,7 @@ func BenchmarkEncodeGray(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) + Encode(io.Discard, img) } } @@ -259,7 +258,7 @@ func BenchmarkEncodeGrayWithBufferPool(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - e.Encode(ioutil.Discard, img) + e.Encode(io.Discard, img) } } @@ -279,7 +278,7 @@ func BenchmarkEncodeNRGBOpaque(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) + Encode(io.Discard, img) } } @@ -292,7 +291,7 @@ func BenchmarkEncodeNRGBA(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) + Encode(io.Discard, img) } } @@ -305,7 +304,7 @@ func BenchmarkEncodePaletted(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) + Encode(io.Discard, img) } } @@ -325,7 +324,7 @@ func BenchmarkEncodeRGBOpaque(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) + Encode(io.Discard, img) } } @@ -338,6 +337,6 @@ func BenchmarkEncodeRGBA(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - Encode(ioutil.Discard, img) + Encode(io.Discard, img) } } diff --git a/libgo/go/index/suffixarray/gen.go b/libgo/go/index/suffixarray/gen.go index 8c3de553c9f..94184d71b68 100644 --- a/libgo/go/index/suffixarray/gen.go +++ b/libgo/go/index/suffixarray/gen.go @@ -11,8 +11,8 @@ package main import ( "bytes" - "io/ioutil" "log" + "os" "strings" ) @@ -20,7 +20,7 @@ func main() { log.SetPrefix("gen: ") log.SetFlags(0) - data, err := ioutil.ReadFile("sais.go") + data, err := os.ReadFile("sais.go") if err != nil { log.Fatal(err) } @@ -64,7 +64,7 @@ func main() { } } - if err := ioutil.WriteFile("sais2.go", buf.Bytes(), 0666); err != nil { + if err := os.WriteFile("sais2.go", buf.Bytes(), 0666); err != nil { log.Fatal(err) } } diff --git a/libgo/go/index/suffixarray/suffixarray_test.go b/libgo/go/index/suffixarray/suffixarray_test.go index 28090de9aa2..44c50415355 100644 --- a/libgo/go/index/suffixarray/suffixarray_test.go +++ b/libgo/go/index/suffixarray/suffixarray_test.go @@ -7,7 +7,7 @@ package suffixarray import ( "bytes" "fmt" - "io/ioutil" + "io/fs" "math/rand" "os" "path/filepath" @@ -498,14 +498,14 @@ func makeText(name string) ([]byte, error) { switch name { case "opticks": var err error - data, err = ioutil.ReadFile("../../testdata/Isaac.Newton-Opticks.txt") + data, err = os.ReadFile("../../testdata/Isaac.Newton-Opticks.txt") if err != nil { return nil, err } case "go": - err := filepath.Walk("../..", func(path string, info os.FileInfo, err error) error { + err := filepath.WalkDir("../..", func(path string, info fs.DirEntry, err error) error { if err == nil && strings.HasSuffix(path, ".go") && !info.IsDir() { - file, err := ioutil.ReadFile(path) + file, err := os.ReadFile(path) if err != nil { return err } diff --git a/libgo/go/internal/bytealg/bytealg.go b/libgo/go/internal/bytealg/bytealg.go index abdba5fb580..58efb95c328 100644 --- a/libgo/go/internal/bytealg/bytealg.go +++ b/libgo/go/internal/bytealg/bytealg.go @@ -99,7 +99,7 @@ func HashStrRev(sep string) (uint32, uint32) { } // IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the -// first occurence of substr in s, or -1 if not present. +// first occurrence of substr in s, or -1 if not present. func IndexRabinKarpBytes(s, sep []byte) int { // Rabin-Karp search hashsep, pow := HashStrBytes(sep) @@ -124,7 +124,7 @@ func IndexRabinKarpBytes(s, sep []byte) int { } // IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the -// first occurence of substr in s, or -1 if not present. +// first occurrence of substr in s, or -1 if not present. func IndexRabinKarp(s, substr string) int { // Rabin-Karp search hashss, pow := HashStr(substr) diff --git a/libgo/go/internal/bytealg/count_generic.go b/libgo/go/internal/bytealg/count_generic.go index e95cd1ccbb6..7e4510c0b13 100644 --- a/libgo/go/internal/bytealg/count_generic.go +++ b/libgo/go/internal/bytealg/count_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,!arm,!arm64,!ppc64le,!ppc64,!s390x +// -build !amd64,!arm,!arm64,!ppc64le,!ppc64,!riscv64,!s390x package bytealg diff --git a/libgo/go/internal/bytealg/count_native.go b/libgo/go/internal/bytealg/count_native.go index 16ff34821f1..a0151a09350 100644 --- a/libgo/go/internal/bytealg/count_native.go +++ b/libgo/go/internal/bytealg/count_native.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build ignore_for_gccgo -// +build amd64 arm arm64 ppc64le ppc64 s390x +// +build amd64 arm arm64 ppc64le ppc64 riscv64 s390x package bytealg diff --git a/libgo/go/internal/cfg/cfg.go b/libgo/go/internal/cfg/cfg.go index bdbe9df3e75..553021374d5 100644 --- a/libgo/go/internal/cfg/cfg.go +++ b/libgo/go/internal/cfg/cfg.go @@ -58,6 +58,7 @@ const KnownEnv = ` GOSUMDB GOTMPDIR GOTOOLDIR + GOVCS GOWASM GO_EXTLINK_ENABLED PKG_CONFIG diff --git a/libgo/go/internal/cpu/cpu.go b/libgo/go/internal/cpu/cpu.go index 2829945af0b..dab5d068ef3 100644 --- a/libgo/go/internal/cpu/cpu.go +++ b/libgo/go/internal/cpu/cpu.go @@ -56,32 +56,17 @@ var ARM struct { // The booleans in ARM64 contain the correspondingly named cpu feature bit. // The struct is padded to avoid false sharing. var ARM64 struct { - _ CacheLinePad - HasFP bool - HasASIMD bool - HasEVTSTRM bool - HasAES bool - HasPMULL bool - HasSHA1 bool - HasSHA2 bool - HasCRC32 bool - HasATOMICS bool - HasFPHP bool - HasASIMDHP bool - HasCPUID bool - HasASIMDRDM bool - HasJSCVT bool - HasFCMA bool - HasLRCPC bool - HasDCPOP bool - HasSHA3 bool - HasSM3 bool - HasSM4 bool - HasASIMDDP bool - HasSHA512 bool - HasSVE bool - HasASIMDFHM bool - _ CacheLinePad + _ CacheLinePad + HasAES bool + HasPMULL bool + HasSHA1 bool + HasSHA2 bool + HasCRC32 bool + HasATOMICS bool + HasCPUID bool + IsNeoverseN1 bool + IsZeus bool + _ CacheLinePad } var MIPS64X struct { diff --git a/libgo/go/internal/cpu/cpu_arm64.go b/libgo/go/internal/cpu/cpu_arm64.go index c1f0b01e648..c5003b5d8a7 100644 --- a/libgo/go/internal/cpu/cpu_arm64.go +++ b/libgo/go/internal/cpu/cpu_arm64.go @@ -4,97 +4,25 @@ package cpu -// arm64 doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. -// These are initialized by archauxv and should not be changed after they are -// initialized. -var HWCap uint -var HWCap2 uint - -// HWCAP/HWCAP2 bits. These are exposed by Linux. -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 -) +// const CacheLinePadSize = 64 func doinit() { options = []option{ - {Name: "evtstrm", Feature: &ARM64.HasEVTSTRM}, {Name: "aes", Feature: &ARM64.HasAES}, {Name: "pmull", Feature: &ARM64.HasPMULL}, {Name: "sha1", Feature: &ARM64.HasSHA1}, {Name: "sha2", Feature: &ARM64.HasSHA2}, {Name: "crc32", Feature: &ARM64.HasCRC32}, {Name: "atomics", Feature: &ARM64.HasATOMICS}, - {Name: "fphp", Feature: &ARM64.HasFPHP}, - {Name: "asimdhp", Feature: &ARM64.HasASIMDHP}, {Name: "cpuid", Feature: &ARM64.HasCPUID}, - {Name: "asimdrdm", Feature: &ARM64.HasASIMDRDM}, - {Name: "jscvt", Feature: &ARM64.HasJSCVT}, - {Name: "fcma", Feature: &ARM64.HasFCMA}, - {Name: "lrcpc", Feature: &ARM64.HasLRCPC}, - {Name: "dcpop", Feature: &ARM64.HasDCPOP}, - {Name: "sha3", Feature: &ARM64.HasSHA3}, - {Name: "sm3", Feature: &ARM64.HasSM3}, - {Name: "sm4", Feature: &ARM64.HasSM4}, - {Name: "asimddp", Feature: &ARM64.HasASIMDDP}, - {Name: "sha512", Feature: &ARM64.HasSHA512}, - {Name: "sve", Feature: &ARM64.HasSVE}, - {Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM}, - - // These capabilities should always be enabled on arm64: - {Name: "fp", Feature: &ARM64.HasFP, Required: true}, - {Name: "asimd", Feature: &ARM64.HasASIMD, Required: true}, + {Name: "isNeoverseN1", Feature: &ARM64.IsNeoverseN1}, + {Name: "isZeus", Feature: &ARM64.IsZeus}, } - // HWCAP feature bits - ARM64.HasFP = isSet(HWCap, hwcap_FP) - ARM64.HasASIMD = isSet(HWCap, hwcap_ASIMD) - ARM64.HasEVTSTRM = isSet(HWCap, hwcap_EVTSTRM) - ARM64.HasAES = isSet(HWCap, hwcap_AES) - ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL) - ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1) - ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2) - ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32) - ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) - ARM64.HasFPHP = isSet(HWCap, hwcap_FPHP) - ARM64.HasASIMDHP = isSet(HWCap, hwcap_ASIMDHP) - ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID) - ARM64.HasASIMDRDM = isSet(HWCap, hwcap_ASIMDRDM) - ARM64.HasJSCVT = isSet(HWCap, hwcap_JSCVT) - ARM64.HasFCMA = isSet(HWCap, hwcap_FCMA) - ARM64.HasLRCPC = isSet(HWCap, hwcap_LRCPC) - ARM64.HasDCPOP = isSet(HWCap, hwcap_DCPOP) - ARM64.HasSHA3 = isSet(HWCap, hwcap_SHA3) - ARM64.HasSM3 = isSet(HWCap, hwcap_SM3) - ARM64.HasSM4 = isSet(HWCap, hwcap_SM4) - ARM64.HasASIMDDP = isSet(HWCap, hwcap_ASIMDDP) - ARM64.HasSHA512 = isSet(HWCap, hwcap_SHA512) - ARM64.HasSVE = isSet(HWCap, hwcap_SVE) - ARM64.HasASIMDFHM = isSet(HWCap, hwcap_ASIMDFHM) + // arm64 uses different ways to detect CPU features at runtime depending on the operating system. + osInit() } -func isSet(hwc uint, value uint) bool { - return hwc&value != 0 -} +func getisar0() uint64 + +func getMIDR() uint64 diff --git a/libgo/go/internal/cpu/cpu_arm64_android.go b/libgo/go/internal/cpu/cpu_arm64_android.go new file mode 100644 index 00000000000..3c9e57c52aa --- /dev/null +++ b/libgo/go/internal/cpu/cpu_arm64_android.go @@ -0,0 +1,11 @@ +// Copyright 2020 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 + +package cpu + +func osInit() { + hwcapInit("android") +} diff --git a/libgo/go/internal/cpu/cpu_arm64_darwin.go b/libgo/go/internal/cpu/cpu_arm64_darwin.go new file mode 100644 index 00000000000..e094b97f973 --- /dev/null +++ b/libgo/go/internal/cpu/cpu_arm64_darwin.go @@ -0,0 +1,34 @@ +// Copyright 2020 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 +// +build darwin +// +build !ios + +package cpu + +func osInit() { + ARM64.HasATOMICS = sysctlEnabled([]byte("hw.optional.armv8_1_atomics\x00")) + ARM64.HasCRC32 = sysctlEnabled([]byte("hw.optional.armv8_crc32\x00")) + + // There are no hw.optional sysctl values for the below features on Mac OS 11.0 + // to detect their supported state dynamically. Assume the CPU features that + // Apple Silicon M1 supports to be available as a minimal set of features + // to all Go programs running on darwin/arm64. + ARM64.HasAES = true + ARM64.HasPMULL = true + ARM64.HasSHA1 = true + ARM64.HasSHA2 = true +} + +//go:noescape +func getsysctlbyname(name []byte) (int32, int32) + +func sysctlEnabled(name []byte) bool { + ret, value := getsysctlbyname(name) + if ret < 0 { + return false + } + return value > 0 +} diff --git a/libgo/go/internal/cpu/cpu_arm64_freebsd.go b/libgo/go/internal/cpu/cpu_arm64_freebsd.go new file mode 100644 index 00000000000..9de2005c2e3 --- /dev/null +++ b/libgo/go/internal/cpu/cpu_arm64_freebsd.go @@ -0,0 +1,45 @@ +// Copyright 2020 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 + +package cpu + +func osInit() { + // Retrieve info from system register ID_AA64ISAR0_EL1. + isar0 := getisar0() + + // ID_AA64ISAR0_EL1 + switch extractBits(isar0, 4, 7) { + case 1: + ARM64.HasAES = true + case 2: + ARM64.HasAES = true + ARM64.HasPMULL = true + } + + switch extractBits(isar0, 8, 11) { + case 1: + ARM64.HasSHA1 = true + } + + switch extractBits(isar0, 12, 15) { + case 1, 2: + ARM64.HasSHA2 = true + } + + switch extractBits(isar0, 16, 19) { + case 1: + ARM64.HasCRC32 = true + } + + switch extractBits(isar0, 20, 23) { + case 2: + ARM64.HasATOMICS = true + } +} + +func extractBits(data uint64, start, end uint) uint { + return (uint)(data>>start) & ((1 << (end - start + 1)) - 1) +} diff --git a/libgo/go/internal/cpu/cpu_arm64_hwcap.go b/libgo/go/internal/cpu/cpu_arm64_hwcap.go new file mode 100644 index 00000000000..fdaf43e1a25 --- /dev/null +++ b/libgo/go/internal/cpu/cpu_arm64_hwcap.go @@ -0,0 +1,63 @@ +// Copyright 2020 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 +// +build linux + +package cpu + +// HWCap may be initialized by archauxv and +// should not be changed after it was initialized. +var HWCap uint + +// HWCAP bits. These are exposed by Linux. +const ( + 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_CPUID = 1 << 11 +) + +func hwcapInit(os string) { + // HWCap was populated by the runtime from the auxiliary vector. + // Use HWCap information since reading aarch64 system registers + // is not supported in user space on older linux kernels. + ARM64.HasAES = isSet(HWCap, hwcap_AES) + ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL) + ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1) + ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2) + ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32) + ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID) + + // The Samsung S9+ kernel reports support for atomics, but not all cores + // actually support them, resulting in SIGILL. See issue #28431. + // TODO(elias.naur): Only disable the optimization on bad chipsets on android. + ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) && os != "android" + + // Check to see if executing on a NeoverseN1 and in order to do that, + // check the AUXV for the CPUID bit. The getMIDR function executes an + // instruction which would normally be an illegal instruction, but it's + // trapped by the kernel, the value sanitized and then returned. Without + // the CPUID bit the kernel will not trap the instruction and the process + // will be terminated with SIGILL. + if ARM64.HasCPUID { + midr := getMIDR() + part_num := uint16((midr >> 4) & 0xfff) + implementor := byte((midr >> 24) & 0xff) + + if implementor == 'A' && part_num == 0xd0c { + ARM64.IsNeoverseN1 = true + } + if implementor == 'A' && part_num == 0xd40 { + ARM64.IsZeus = true + } + } +} + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/libgo/go/internal/cpu/cpu_arm64_linux.go b/libgo/go/internal/cpu/cpu_arm64_linux.go new file mode 100644 index 00000000000..2f7411ff1e1 --- /dev/null +++ b/libgo/go/internal/cpu/cpu_arm64_linux.go @@ -0,0 +1,13 @@ +// Copyright 2020 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 +// +build linux +// +build !android + +package cpu + +func osInit() { + hwcapInit("linux") +} diff --git a/libgo/go/internal/cpu/cpu_arm64_other.go b/libgo/go/internal/cpu/cpu_arm64_other.go new file mode 100644 index 00000000000..f191db28d2a --- /dev/null +++ b/libgo/go/internal/cpu/cpu_arm64_other.go @@ -0,0 +1,17 @@ +// Copyright 2020 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 +// +build !linux +// +build !freebsd +// +build !android +// +build !darwin ios + +package cpu + +func osInit() { + // Other operating systems do not support reading HWCap from auxiliary vector, + // reading privileged aarch64 system registers or sysctl in user space to detect + // CPU features at runtime. +} diff --git a/libgo/go/internal/cpu/cpu_no_init.go b/libgo/go/internal/cpu/cpu_no_init.go deleted file mode 100644 index e7ff87383c3..00000000000 --- a/libgo/go/internal/cpu/cpu_no_init.go +++ /dev/null @@ -1,19 +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 !386 -// +build !amd64 -// +build !arm -// +build !arm64 -// +build !ppc -// +build !ppc64 -// +build !ppc64le -// +build !s390x -// +build !mips64 -// +build !mips64le - -package cpu - -func doinit() { -} diff --git a/libgo/go/internal/cpu/cpu_no_name.go b/libgo/go/internal/cpu/cpu_no_name.go new file mode 100644 index 00000000000..ce1c37a3c7c --- /dev/null +++ b/libgo/go/internal/cpu/cpu_no_name.go @@ -0,0 +1,19 @@ +// Copyright 2020 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 !386 +// +build !amd64 + +package cpu + +// Name returns the CPU name given by the vendor +// if it can be read directly from memory or by CPU instructions. +// If the CPU name can not be determined an empty string is returned. +// +// Implementations that use the Operating System (e.g. sysctl or /sys/) +// to gather CPU information for display should be placed in internal/sysinfo. +func Name() string { + // "A CPU has no name". + return "" +} diff --git a/libgo/go/internal/cpu/cpu_ppc64x_aix.go b/libgo/go/internal/cpu/cpu_ppc64x_aix.go new file mode 100644 index 00000000000..b840b823bae --- /dev/null +++ b/libgo/go/internal/cpu/cpu_ppc64x_aix.go @@ -0,0 +1,21 @@ +// Copyright 2020 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 ppc64 ppc64le + +package cpu + +const ( + // getsystemcfg constants + _SC_IMPL = 2 + _IMPL_POWER9 = 0x20000 +) + +func osinit() { + impl := getsystemcfg(_SC_IMPL) + PPC64.IsPOWER9 = isSet(impl, _IMPL_POWER9) +} + +// getsystemcfg is defined in runtime/os2_aix.go +func getsystemcfg(label uint) uint diff --git a/libgo/go/internal/cpu/cpu_ppc64x_linux.go b/libgo/go/internal/cpu/cpu_ppc64x_linux.go new file mode 100644 index 00000000000..73b191436df --- /dev/null +++ b/libgo/go/internal/cpu/cpu_ppc64x_linux.go @@ -0,0 +1,29 @@ +// Copyright 2020 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 ppc64 ppc64le + +package cpu + +// ppc64 doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. +// These are initialized by archauxv and should not be changed after they are +// initialized. +var HWCap uint +var HWCap2 uint + +// HWCAP bits. These are exposed by Linux. +const ( + // ISA Level + hwcap2_ARCH_3_00 = 0x00800000 + + // CPU features + hwcap2_DARN = 0x00200000 + hwcap2_SCV = 0x00100000 +) + +func osinit() { + PPC64.IsPOWER9 = isSet(HWCap2, hwcap2_ARCH_3_00) + PPC64.HasDARN = isSet(HWCap2, hwcap2_DARN) + PPC64.HasSCV = isSet(HWCap2, hwcap2_SCV) +} diff --git a/libgo/go/internal/cpu/cpu_riscv64.go b/libgo/go/internal/cpu/cpu_riscv64.go index d920fcf7a6d..e74aa7d8945 100644 --- a/libgo/go/internal/cpu/cpu_riscv64.go +++ b/libgo/go/internal/cpu/cpu_riscv64.go @@ -3,3 +3,8 @@ // license that can be found in the LICENSE file. package cpu + +// const CacheLinePadSize = 32 + +func doinit() { +} diff --git a/libgo/go/internal/cpu/cpu_s390x.go b/libgo/go/internal/cpu/cpu_s390x.go index a7c5572010b..694510c6ceb 100644 --- a/libgo/go/internal/cpu/cpu_s390x.go +++ b/libgo/go/internal/cpu/cpu_s390x.go @@ -4,6 +4,10 @@ package cpu +// const CacheLinePadSize = 256 + +var HWCap uint + // bitIsSet reports whether the bit at index is set. The bit index // is in big endian order, so bit index 0 is the leftmost bit. func bitIsSet(bits []uint64, index uint) bool { @@ -93,8 +97,10 @@ const ( // vector facilities vxe facility = 135 // vector-enhancements 1 - // Note: vx and highgprs are excluded because they require - // kernel support and so must be fetched from HWCAP. + // Note: vx requires kernel support + // and so must be fetched from HWCAP. + + hwcap_VX = 1 << 11 // vector facility ) // facilityList contains the result of an STFLE call. @@ -178,7 +184,14 @@ func doinit() { S390X.HasEDDSA = kdsa.Has(eddsaVerifyEd25519, eddsaSignEd25519, eddsaVerifyEd448, eddsaSignEd448) } } + + S390X.HasVX = isSet(HWCap, hwcap_VX) + if S390X.HasVX { S390X.HasVXE = facilities.Has(vxe) } } + +func isSet(hwc uint, value uint) bool { + return hwc&value != 0 +} diff --git a/libgo/go/internal/cpu/cpu_s390x_test.go b/libgo/go/internal/cpu/cpu_s390x_test.go index d910bbe6952..ad86858db01 100644 --- a/libgo/go/internal/cpu/cpu_s390x_test.go +++ b/libgo/go/internal/cpu/cpu_s390x_test.go @@ -7,13 +7,13 @@ package cpu_test import ( "errors" . "internal/cpu" - "io/ioutil" + "os" "regexp" "testing" ) func getFeatureList() ([]string, error) { - cpuinfo, err := ioutil.ReadFile("/proc/cpuinfo") + cpuinfo, err := os.ReadFile("/proc/cpuinfo") if err != nil { return nil, err } diff --git a/libgo/go/internal/cpu/cpu_test.go b/libgo/go/internal/cpu/cpu_test.go index d9be38eb3e2..5a4c89701a7 100644 --- a/libgo/go/internal/cpu/cpu_test.go +++ b/libgo/go/internal/cpu/cpu_test.go @@ -15,9 +15,10 @@ import ( ) func TestMinimalFeatures(t *testing.T) { + // TODO: maybe do MustSupportFeatureDectection(t) ? if runtime.GOARCH == "arm64" { switch runtime.GOOS { - case "linux", "android": + case "linux", "android", "darwin": default: t.Skipf("%s/%s is not supported", runtime.GOOS, runtime.GOARCH) } @@ -36,6 +37,10 @@ func MustHaveDebugOptionsSupport(t *testing.T) { } } +func MustSupportFeatureDectection(t *testing.T) { + // TODO: add platforms that do not have CPU feature detection support. +} + func runDebugOptionsTest(t *testing.T, test string, options string) { MustHaveDebugOptionsSupport(t) @@ -58,6 +63,7 @@ func runDebugOptionsTest(t *testing.T, test string, options string) { } func TestDisableAllCapabilities(t *testing.T) { + MustSupportFeatureDectection(t) runDebugOptionsTest(t, "TestAllCapabilitiesDisabled", "cpu.all=off") } diff --git a/libgo/go/internal/cpu/cpu_x86.go b/libgo/go/internal/cpu/cpu_x86.go index eceeb441e51..62853a1aebd 100644 --- a/libgo/go/internal/cpu/cpu_x86.go +++ b/libgo/go/internal/cpu/cpu_x86.go @@ -36,6 +36,8 @@ const ( cpuid_ADX = 1 << 19 ) +var maxExtendedFunctionInformation uint32 + func doinit() { options = []option{ {Name: "adx", Feature: &X86.HasADX}, @@ -63,19 +65,30 @@ func doinit() { return } + maxExtendedFunctionInformation, _, _, _ = cpuid(0x80000000, 0) + _, _, ecx1, edx1 := cpuid(1, 0) X86.HasSSE2 = isSet(edx1, cpuid_SSE2) X86.HasSSE3 = isSet(ecx1, cpuid_SSE3) X86.HasPCLMULQDQ = isSet(ecx1, cpuid_PCLMULQDQ) X86.HasSSSE3 = isSet(ecx1, cpuid_SSSE3) - X86.HasFMA = isSet(ecx1, cpuid_FMA) X86.HasSSE41 = isSet(ecx1, cpuid_SSE41) X86.HasSSE42 = isSet(ecx1, cpuid_SSE42) X86.HasPOPCNT = isSet(ecx1, cpuid_POPCNT) X86.HasAES = isSet(ecx1, cpuid_AES) + + // OSXSAVE can be false when using older Operating Systems + // or when explicitly disabled on newer Operating Systems by + // e.g. setting the xsavedisable boot option on Windows 10. X86.HasOSXSAVE = isSet(ecx1, cpuid_OSXSAVE) + // The FMA instruction set extension only has VEX prefixed instructions. + // VEX prefixed instructions require OSXSAVE to be enabled. + // See Intel 64 and IA-32 Architecture Software Developer’s Manual Volume 2 + // Section 2.4 "AVX and SSE Instruction Exception Specification" + X86.HasFMA = isSet(ecx1, cpuid_FMA) && X86.HasOSXSAVE + osSupportsAVX := false // For XGETBV, OSXSAVE bit is required and sufficient. if X86.HasOSXSAVE { @@ -101,3 +114,48 @@ func doinit() { func isSet(hwc uint32, value uint32) bool { return hwc&value != 0 } + +// Name returns the CPU name given by the vendor. +// If the CPU name can not be determined an +// empty string is returned. +func Name() string { + if maxExtendedFunctionInformation < 0x80000004 { + return "" + } + + data := make([]byte, 0, 3*4*4) + + var eax, ebx, ecx, edx uint32 + eax, ebx, ecx, edx = cpuid(0x80000002, 0) + data = appendBytes(data, eax, ebx, ecx, edx) + eax, ebx, ecx, edx = cpuid(0x80000003, 0) + data = appendBytes(data, eax, ebx, ecx, edx) + eax, ebx, ecx, edx = cpuid(0x80000004, 0) + data = appendBytes(data, eax, ebx, ecx, edx) + + // Trim leading spaces. + for len(data) > 0 && data[0] == ' ' { + data = data[1:] + } + + // Trim tail after and including the first null byte. + for i, c := range data { + if c == '\x00' { + data = data[:i] + break + } + } + + return string(data) +} + +func appendBytes(b []byte, args ...uint32) []byte { + for _, arg := range args { + b = append(b, + byte((arg >> 0)), + byte((arg >> 8)), + byte((arg >> 16)), + byte((arg >> 24))) + } + return b +} diff --git a/libgo/go/internal/fmtsort/sort.go b/libgo/go/internal/fmtsort/sort.go index b01229bd06a..7127ba6ac3d 100644 --- a/libgo/go/internal/fmtsort/sort.go +++ b/libgo/go/internal/fmtsort/sort.go @@ -130,7 +130,7 @@ func compare(aVal, bVal reflect.Value) int { default: return -1 } - case reflect.Ptr: + case reflect.Ptr, reflect.UnsafePointer: a, b := aVal.Pointer(), bVal.Pointer() switch { case a < b: diff --git a/libgo/go/internal/fmtsort/sort_test.go b/libgo/go/internal/fmtsort/sort_test.go index aaa0004666d..5c4db1c5faa 100644 --- a/libgo/go/internal/fmtsort/sort_test.go +++ b/libgo/go/internal/fmtsort/sort_test.go @@ -11,6 +11,7 @@ import ( "reflect" "strings" "testing" + "unsafe" ) var compareTests = [][]reflect.Value{ @@ -32,6 +33,7 @@ var compareTests = [][]reflect.Value{ ct(reflect.TypeOf(complex128(0+1i)), -1-1i, -1+0i, -1+1i, 0-1i, 0+0i, 0+1i, 1-1i, 1+0i, 1+1i), ct(reflect.TypeOf(false), false, true), ct(reflect.TypeOf(&ints[0]), &ints[0], &ints[1], &ints[2]), + ct(reflect.TypeOf(unsafe.Pointer(&ints[0])), unsafe.Pointer(&ints[0]), unsafe.Pointer(&ints[1]), unsafe.Pointer(&ints[2])), ct(reflect.TypeOf(chans[0]), chans[0], chans[1], chans[2]), ct(reflect.TypeOf(toy{}), toy{0, 1}, toy{0, 2}, toy{1, -1}, toy{1, 1}), ct(reflect.TypeOf([2]int{}), [2]int{1, 1}, [2]int{1, 2}, [2]int{2, 0}), @@ -118,6 +120,10 @@ var sortTests = []sortTest{ pointerMap(), "PTR0:0 PTR1:1 PTR2:2", }, + { + unsafePointerMap(), + "UNSAFEPTR0:0 UNSAFEPTR1:1 UNSAFEPTR2:2", + }, { map[toy]string{{7, 2}: "72", {7, 1}: "71", {3, 4}: "34"}, "{3 4}:34 {7 1}:71 {7 2}:72", @@ -159,6 +165,14 @@ func sprintKey(key reflect.Value) string { } } return "PTR???" + case "unsafe.Pointer": + ptr := key.Interface().(unsafe.Pointer) + for i := range ints { + if ptr == unsafe.Pointer(&ints[i]) { + return fmt.Sprintf("UNSAFEPTR%d", i) + } + } + return "UNSAFEPTR???" case "chan int": c := key.Interface().(chan int) for i := range chans { @@ -185,6 +199,14 @@ func pointerMap() map[*int]string { return m } +func unsafePointerMap() map[unsafe.Pointer]string { + m := make(map[unsafe.Pointer]string) + for i := 2; i >= 0; i-- { + m[unsafe.Pointer(&ints[i])] = fmt.Sprint(i) + } + return m +} + func chanMap() map[chan int]string { m := make(map[chan int]string) for i := 2; i >= 0; i-- { diff --git a/libgo/go/internal/goversion/goversion.go b/libgo/go/internal/goversion/goversion.go index 4ffd34c1a28..513be456bda 100644 --- a/libgo/go/internal/goversion/goversion.go +++ b/libgo/go/internal/goversion/goversion.go @@ -4,10 +4,9 @@ package goversion -// Version is the current Go 1.x version. During development cycles on -// the master branch it changes to be the version of the next Go 1.x -// release. +// Version is the Go 1.x version which is currently +// in development and will eventually get released. // -// When incrementing this, also add to the list at src/go/build/doc.go -// (search for "onward"). -const Version = 15 +// It should be updated at the start of each development cycle to be +// the version of the next Go 1.x release. See golang.org/issue/40705. +const Version = 16 diff --git a/libgo/go/internal/obscuretestdata/obscuretestdata.go b/libgo/go/internal/obscuretestdata/obscuretestdata.go index 512f3759b4c..5ea2cdf5d14 100644 --- a/libgo/go/internal/obscuretestdata/obscuretestdata.go +++ b/libgo/go/internal/obscuretestdata/obscuretestdata.go @@ -10,7 +10,6 @@ package obscuretestdata import ( "encoding/base64" "io" - "io/ioutil" "os" ) @@ -24,7 +23,7 @@ func DecodeToTempFile(name string) (path string, err error) { } defer f.Close() - tmp, err := ioutil.TempFile("", "obscuretestdata-decoded-") + tmp, err := os.CreateTemp("", "obscuretestdata-decoded-") if err != nil { return "", err } @@ -47,5 +46,5 @@ func ReadFile(name string) ([]byte, error) { return nil, err } defer f.Close() - return ioutil.ReadAll(base64.NewDecoder(base64.StdEncoding, f)) + return io.ReadAll(base64.NewDecoder(base64.StdEncoding, f)) } diff --git a/libgo/go/internal/poll/error_test.go b/libgo/go/internal/poll/error_test.go index 06b96f635a5..abc8b1684f5 100644 --- a/libgo/go/internal/poll/error_test.go +++ b/libgo/go/internal/poll/error_test.go @@ -6,6 +6,7 @@ package poll_test import ( "fmt" + "io/fs" "net" "os" "testing" @@ -37,7 +38,7 @@ func parseReadError(nestedErr error, verify func(error) (string, bool)) error { if nerr, ok := err.(*net.OpError); ok { err = nerr.Err } - if nerr, ok := err.(*os.PathError); ok { + if nerr, ok := err.(*fs.PathError); ok { err = nerr.Err } if nerr, ok := err.(*os.SyscallError); ok { diff --git a/libgo/go/internal/poll/fd_fsync_darwin.go b/libgo/go/internal/poll/fd_fsync_darwin.go index 91751496a41..48e7596922b 100644 --- a/libgo/go/internal/poll/fd_fsync_darwin.go +++ b/libgo/go/internal/poll/fd_fsync_darwin.go @@ -14,7 +14,8 @@ func (fd *FD) Fsync() error { return err } defer fd.decref() - - _, e1 := fcntl(fd.Sysfd, syscall.F_FULLFSYNC, 0) - return e1 + return ignoringEINTR(func() error { + _, err := fcntl(fd.Sysfd, syscall.F_FULLFSYNC, 0) + return err + }) } diff --git a/libgo/go/internal/poll/fd_fsync_posix.go b/libgo/go/internal/poll/fd_fsync_posix.go index dfc8b77e910..9be0f5462ea 100644 --- a/libgo/go/internal/poll/fd_fsync_posix.go +++ b/libgo/go/internal/poll/fd_fsync_posix.go @@ -14,5 +14,7 @@ func (fd *FD) Fsync() error { return err } defer fd.decref() - return syscall.Fsync(fd.Sysfd) + return ignoringEINTR(func() error { + return syscall.Fsync(fd.Sysfd) + }) } diff --git a/libgo/go/internal/poll/fd_opendir_darwin.go b/libgo/go/internal/poll/fd_opendir_darwin.go index c7d3318c72e..8eb770c3581 100644 --- a/libgo/go/internal/poll/fd_opendir_darwin.go +++ b/libgo/go/internal/poll/fd_opendir_darwin.go @@ -19,7 +19,13 @@ func (fd *FD) OpenDir() (uintptr, string, error) { if err != nil { return 0, call, err } - dir, err := fdopendir(fd2) + var dir uintptr + for { + dir, err = fdopendir(fd2) + if err != syscall.EINTR { + break + } + } if err != nil { syscall.Close(fd2) return 0, "fdopendir", err diff --git a/libgo/go/internal/poll/fd_posix.go b/libgo/go/internal/poll/fd_posix.go index 986cd331854..16c2e50057d 100644 --- a/libgo/go/internal/poll/fd_posix.go +++ b/libgo/go/internal/poll/fd_posix.go @@ -29,22 +29,15 @@ func (fd *FD) Shutdown(how int) error { return syscall.Shutdown(fd.Sysfd, how) } -// Fchmod wraps syscall.Fchmod. -func (fd *FD) Fchmod(mode uint32) error { - if err := fd.incref(); err != nil { - return err - } - defer fd.decref() - return syscall.Fchmod(fd.Sysfd, mode) -} - // Fchown wraps syscall.Fchown. func (fd *FD) Fchown(uid, gid int) error { if err := fd.incref(); err != nil { return err } defer fd.decref() - return syscall.Fchown(fd.Sysfd, uid, gid) + return ignoringEINTR(func() error { + return syscall.Fchown(fd.Sysfd, uid, gid) + }) } // Ftruncate wraps syscall.Ftruncate. @@ -53,7 +46,9 @@ func (fd *FD) Ftruncate(size int64) error { return err } defer fd.decref() - return syscall.Ftruncate(fd.Sysfd, size) + return ignoringEINTR(func() error { + return syscall.Ftruncate(fd.Sysfd, size) + }) } // RawControl invokes the user-defined function f for a non-IO @@ -66,3 +61,19 @@ func (fd *FD) RawControl(f func(uintptr)) error { f(uintptr(fd.Sysfd)) return nil } + +// ignoringEINTR makes a function call and repeats it if it returns +// an EINTR error. This appears to be required even though we install all +// signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846. +// Also #20400 and #36644 are issues in which a signal handler is +// installed without setting SA_RESTART. None of these are the common case, +// but there are enough of them that it seems that we can't avoid +// an EINTR loop. +func ignoringEINTR(fn func() error) error { + for { + err := fn() + if err != syscall.EINTR { + return err + } + } +} diff --git a/libgo/go/internal/poll/fd_unix.go b/libgo/go/internal/poll/fd_unix.go index 10cf1735d6a..013b7e54574 100644 --- a/libgo/go/internal/poll/fd_unix.go +++ b/libgo/go/internal/poll/fd_unix.go @@ -74,7 +74,14 @@ func (fd *FD) destroy() error { // Poller may want to unregister fd in readiness notification mechanism, // so this must be executed before CloseFunc. fd.pd.close() + + // We don't use ignoringEINTR here because POSIX does not define + // whether the descriptor is closed if close returns EINTR. + // If the descriptor is indeed closed, using a loop would race + // with some other goroutine opening a new descriptor. + // (The Linux kernel guarantees that it is closed on an EINTR error.) err := CloseFunc(fd.Sysfd) + fd.Sysfd = -1 runtime_Semrelease(&fd.csema) return err @@ -152,7 +159,7 @@ func (fd *FD) Read(p []byte) (int, error) { p = p[:maxRW] } for { - n, err := ignoringEINTR(func() (int, error) { return syscall.Read(fd.Sysfd, p) }) + n, err := ignoringEINTRIO(syscall.Read, fd.Sysfd, p) if err != nil { n = 0 if err == syscall.EAGAIN && fd.pd.pollable() { @@ -264,7 +271,7 @@ func (fd *FD) Write(p []byte) (int, error) { if fd.IsStream && max-nn > maxRW { max = nn + maxRW } - n, err := ignoringEINTR(func() (int, error) { return syscall.Write(fd.Sysfd, p[nn:max]) }) + n, err := ignoringEINTRIO(syscall.Write, fd.Sysfd, p[nn:max]) if n > 0 { nn += n } @@ -423,7 +430,7 @@ func (fd *FD) ReadDirent(buf []byte) (int, error) { } defer fd.decref() for { - n, err := ignoringEINTR(func() (int, error) { return syscall.ReadDirent(fd.Sysfd, buf) }) + n, err := ignoringEINTRIO(syscall.ReadDirent, fd.Sysfd, buf) if err != nil { n = 0 if err == syscall.EAGAIN && fd.pd.pollable() { @@ -437,6 +444,17 @@ func (fd *FD) ReadDirent(buf []byte) (int, error) { } } +// Fchmod wraps syscall.Fchmod. +func (fd *FD) Fchmod(mode uint32) error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + return ignoringEINTR(func() error { + return syscall.Fchmod(fd.Sysfd, mode) + }) +} + // Fchdir wraps syscall.Fchdir. func (fd *FD) Fchdir() error { if err := fd.incref(); err != nil { @@ -452,7 +470,9 @@ func (fd *FD) Fstat(s *syscall.Stat_t) error { return err } defer fd.decref() - return syscall.Fstat(fd.Sysfd, s) + return ignoringEINTR(func() error { + return syscall.Fstat(fd.Sysfd, s) + }) } // tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used. @@ -514,7 +534,7 @@ func (fd *FD) WriteOnce(p []byte) (int, error) { return 0, err } defer fd.writeUnlock() - return ignoringEINTR(func() (int, error) { return syscall.Write(fd.Sysfd, p) }) + return ignoringEINTRIO(syscall.Write, fd.Sysfd, p) } // RawRead invokes the user-defined function f for a read operation. @@ -555,16 +575,10 @@ func (fd *FD) RawWrite(f func(uintptr) bool) error { } } -// ignoringEINTR makes a function call and repeats it if it returns -// an EINTR error. This appears to be required even though we install -// all signal handlers with SA_RESTART: see #22838, #38033, #38836. -// Also #20400 and #36644 are issues in which a signal handler is -// installed without setting SA_RESTART. None of these are the common case, -// but there are enough of them that it seems that we can't avoid -// an EINTR loop. -func ignoringEINTR(fn func() (int, error)) (int, error) { +// ignoringEINTRIO is like ignoringEINTR, but just for IO calls. +func ignoringEINTRIO(fn func(fd int, p []byte) (int, error), fd int, p []byte) (int, error) { for { - n, err := fn() + n, err := fn(fd, p) if err != syscall.EINTR { return n, err } diff --git a/libgo/go/internal/poll/fd_windows.go b/libgo/go/internal/poll/fd_windows.go index e1ef6199b37..d8c834f9299 100644 --- a/libgo/go/internal/poll/fd_windows.go +++ b/libgo/go/internal/poll/fd_windows.go @@ -886,6 +886,33 @@ func (fd *FD) FindNextFile(data *syscall.Win32finddata) error { return syscall.FindNextFile(fd.Sysfd, data) } +// Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed. +func (fd *FD) Fchmod(mode uint32) error { + if err := fd.incref(); err != nil { + return err + } + defer fd.decref() + + var d syscall.ByHandleFileInformation + if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil { + return err + } + attrs := d.FileAttributes + if mode&syscall.S_IWRITE != 0 { + attrs &^= syscall.FILE_ATTRIBUTE_READONLY + } else { + attrs |= syscall.FILE_ATTRIBUTE_READONLY + } + if attrs == d.FileAttributes { + return nil + } + + var du windows.FILE_BASIC_INFO + du.FileAttributes = attrs + l := uint32(unsafe.Sizeof(d)) + return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, uintptr(unsafe.Pointer(&du)), l) +} + // Fchdir wraps syscall.Fchdir. func (fd *FD) Fchdir() error { if err := fd.incref(); err != nil { diff --git a/libgo/go/internal/poll/fd_writev_illumos.go b/libgo/go/internal/poll/fd_writev_illumos.go new file mode 100644 index 00000000000..1fa47ab1a32 --- /dev/null +++ b/libgo/go/internal/poll/fd_writev_illumos.go @@ -0,0 +1,16 @@ +// Copyright 2020 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 illumos + +package poll + +import ( + "internal/syscall/unix" + "syscall" +) + +func writev(fd int, iovecs []syscall.Iovec) (uintptr, error) { + return unix.Writev(fd, iovecs) +} diff --git a/libgo/go/internal/poll/hook_cloexec.go b/libgo/go/internal/poll/hook_cloexec.go index 7fc874bfaf7..b8ce58d6ec5 100644 --- a/libgo/go/internal/poll/hook_cloexec.go +++ b/libgo/go/internal/poll/hook_cloexec.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 dragonfly freebsd hurd linux netbsd openbsd +// +build dragonfly freebsd hurd illumos linux netbsd openbsd package poll diff --git a/libgo/go/internal/poll/iovec_illumos.go b/libgo/go/internal/poll/iovec_illumos.go new file mode 100644 index 00000000000..057067465bf --- /dev/null +++ b/libgo/go/internal/poll/iovec_illumos.go @@ -0,0 +1,16 @@ +// Copyright 2020 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 illumos + +package poll + +import ( + "syscall" + "unsafe" +) + +func newIovecWithBase(base *byte) syscall.Iovec { + return syscall.Iovec{Base: (*int8)(unsafe.Pointer(base))} +} diff --git a/libgo/go/internal/poll/iovec_unix.go b/libgo/go/internal/poll/iovec_unix.go new file mode 100644 index 00000000000..6f98947866a --- /dev/null +++ b/libgo/go/internal/poll/iovec_unix.go @@ -0,0 +1,13 @@ +// Copyright 2020 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 poll + +import "syscall" + +func newIovecWithBase(base *byte) syscall.Iovec { + return syscall.Iovec{Base: base} +} diff --git a/libgo/go/internal/poll/read_test.go b/libgo/go/internal/poll/read_test.go index b4f5236d3ea..598a52ee44c 100644 --- a/libgo/go/internal/poll/read_test.go +++ b/libgo/go/internal/poll/read_test.go @@ -5,7 +5,6 @@ package poll_test import ( - "io/ioutil" "os" "runtime" "sync" @@ -22,7 +21,7 @@ func TestRead(t *testing.T) { go func(p string) { defer wg.Done() for i := 0; i < 100; i++ { - if _, err := ioutil.ReadFile(p); err != nil { + if _, err := os.ReadFile(p); err != nil { t.Error(err) return } @@ -38,7 +37,7 @@ func TestRead(t *testing.T) { func specialFiles() []string { var ps []string switch runtime.GOOS { - case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd": + case "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd": ps = []string{ "/dev/null", } diff --git a/libgo/go/internal/poll/sock_cloexec.go b/libgo/go/internal/poll/sock_cloexec.go index 2f2f9fc3939..09bc4b6fd87 100644 --- a/libgo/go/internal/poll/sock_cloexec.go +++ b/libgo/go/internal/poll/sock_cloexec.go @@ -5,7 +5,7 @@ // This file implements sysSocket and accept for platforms that // provide a fast path for setting SetNonblock and CloseOnExec. -// +build dragonfly freebsd hurd linux netbsd openbsd +// +build dragonfly freebsd hurd illumos linux netbsd openbsd package poll diff --git a/libgo/go/internal/poll/sys_cloexec.go b/libgo/go/internal/poll/sys_cloexec.go index 7b87f136dfe..4b3c6421731 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 solaris +// +build aix darwin js,wasm solaris,!illumos package poll diff --git a/libgo/go/internal/poll/writev.go b/libgo/go/internal/poll/writev.go index 305e2fd2094..0123fc33de7 100644 --- a/libgo/go/internal/poll/writev.go +++ b/libgo/go/internal/poll/writev.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 linux netbsd openbsd +// +build darwin dragonfly freebsd illumos linux netbsd openbsd package poll @@ -38,7 +38,7 @@ func (fd *FD) Writev(v *[][]byte) (int64, error) { if len(chunk) == 0 { continue } - iovecs = append(iovecs, syscall.Iovec{Base: &chunk[0]}) + iovecs = append(iovecs, newIovecWithBase(&chunk[0])) if fd.IsStream && len(chunk) > 1<<30 { iovecs[len(iovecs)-1].SetLen(1 << 30) break // continue chunk on next writev diff --git a/libgo/go/internal/profile/profile.go b/libgo/go/internal/profile/profile.go index a6275bc6de4..29568aa4b5f 100644 --- a/libgo/go/internal/profile/profile.go +++ b/libgo/go/internal/profile/profile.go @@ -12,7 +12,6 @@ import ( "compress/gzip" "fmt" "io" - "io/ioutil" "regexp" "strings" "time" @@ -125,7 +124,7 @@ type Function struct { // may be a gzip-compressed encoded protobuf or one of many legacy // profile formats which may be unsupported in the future. func Parse(r io.Reader) (*Profile, error) { - orig, err := ioutil.ReadAll(r) + orig, err := io.ReadAll(r) if err != nil { return nil, err } @@ -136,7 +135,7 @@ func Parse(r io.Reader) (*Profile, error) { if err != nil { return nil, fmt.Errorf("decompressing profile: %v", err) } - data, err := ioutil.ReadAll(gz) + data, err := io.ReadAll(gz) if err != nil { return nil, fmt.Errorf("decompressing profile: %v", err) } diff --git a/libgo/go/internal/reflectlite/reflect_mirror_test.go b/libgo/go/internal/reflectlite/reflect_mirror_test.go index fbb6fb397ef..9b28b13550e 100644 --- a/libgo/go/internal/reflectlite/reflect_mirror_test.go +++ b/libgo/go/internal/reflectlite/reflect_mirror_test.go @@ -9,6 +9,7 @@ import ( "go/ast" "go/parser" "go/token" + "io/fs" "os" "path/filepath" "runtime" @@ -71,7 +72,7 @@ func (v visitor) Visit(n ast.Node) ast.Visitor { func loadTypes(path, pkgName string, v visitor) { fset := token.NewFileSet() - filter := func(fi os.FileInfo) bool { + filter := func(fi fs.FileInfo) bool { return strings.HasSuffix(fi.Name(), ".go") } pkgs, err := parser.ParseDir(fset, path, filter, 0) diff --git a/libgo/go/internal/reflectlite/type.go b/libgo/go/internal/reflectlite/type.go index 1609a06a53e..0c1b9944b7e 100644 --- a/libgo/go/internal/reflectlite/type.go +++ b/libgo/go/internal/reflectlite/type.go @@ -263,6 +263,44 @@ const ( kindMask = (1 << 5) - 1 ) +// String returns the name of k. +func (k Kind) String() string { + if int(k) < len(kindNames) { + return kindNames[k] + } + return kindNames[0] +} + +var kindNames = []string{ + Invalid: "invalid", + Bool: "bool", + Int: "int", + Int8: "int8", + Int16: "int16", + Int32: "int32", + Int64: "int64", + Uint: "uint", + Uint8: "uint8", + Uint16: "uint16", + Uint32: "uint32", + Uint64: "uint64", + Uintptr: "uintptr", + Float32: "float32", + Float64: "float64", + Complex64: "complex64", + Complex128: "complex128", + Array: "array", + Chan: "chan", + Func: "func", + Interface: "interface", + Map: "map", + Ptr: "ptr", + Slice: "slice", + String: "string", + Struct: "struct", + UnsafePointer: "unsafe.Pointer", +} + func (t *uncommonType) exportedMethods() []method { allm := t.methods allExported := true diff --git a/libgo/go/internal/reflectlite/value.go b/libgo/go/internal/reflectlite/value.go index b78efaea4be..d3576dd64b2 100644 --- a/libgo/go/internal/reflectlite/value.go +++ b/libgo/go/internal/reflectlite/value.go @@ -161,7 +161,10 @@ type ValueError struct { } func (e *ValueError) Error() string { - return "reflect: call of " + e.Method + " on zero Value" + if e.Kind == 0 { + return "reflect: call of " + e.Method + " on zero Value" + } + return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value" } // methodName returns the name of the calling method, diff --git a/libgo/go/internal/syscall/windows/mksyscall.go b/libgo/go/internal/syscall/windows/mksyscall.go index 95e36f7aa3c..599f07601bd 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 golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall_windows.go security_windows.go psapi_windows.go symlink_windows.go +//go:generate go run ../../../syscall/mksyscall_windows.go -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/key.go b/libgo/go/internal/syscall/windows/registry/key.go index cc3d0c774bd..612c48f0840 100644 --- a/libgo/go/internal/syscall/windows/registry/key.go +++ b/libgo/go/internal/syscall/windows/registry/key.go @@ -25,10 +25,7 @@ // package registry -import ( - "io" - "syscall" -) +import "syscall" const ( // Registry key security and access rights. @@ -90,20 +87,13 @@ func OpenKey(k Key, path string, access uint32) (Key, error) { } // ReadSubKeyNames returns the names of subkeys of key k. -// The parameter n controls the number of returned names, -// analogous to the way os.File.Readdirnames works. -func (k Key) ReadSubKeyNames(n int) ([]string, error) { +func (k Key) ReadSubKeyNames() ([]string, error) { names := make([]string, 0) // Registry key size limit is 255 bytes and described there: // https://msdn.microsoft.com/library/windows/desktop/ms724872.aspx buf := make([]uint16, 256) //plus extra room for terminating zero byte loopItems: for i := uint32(0); ; i++ { - if n > 0 { - if len(names) == n { - return names, nil - } - } l := uint32(len(buf)) for { err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil) @@ -123,9 +113,6 @@ loopItems: } names = append(names, syscall.UTF16ToString(buf[:l])) } - if n > len(names) { - return names, io.EOF - } return names, nil } diff --git a/libgo/go/internal/syscall/windows/registry/mksyscall.go b/libgo/go/internal/syscall/windows/registry/mksyscall.go index cb4906a7b26..320abf7fc69 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 golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall.go +//go:generate go run ../../../../syscall/mksyscall_windows.go -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 8227232c703..57971629006 100644 --- a/libgo/go/internal/syscall/windows/registry/registry_test.go +++ b/libgo/go/internal/syscall/windows/registry/registry_test.go @@ -34,7 +34,7 @@ func TestReadSubKeyNames(t *testing.T) { } defer k.Close() - names, err := k.ReadSubKeyNames(-1) + names, err := k.ReadSubKeyNames() if err != nil { t.Fatal(err) } @@ -190,7 +190,7 @@ func setValues(t *testing.T, k registry.Key) { } func enumerateValues(t *testing.T, k registry.Key) { - names, err := k.ReadValueNames(-1) + names, err := k.ReadValueNames() if err != nil { t.Error(err) return @@ -480,7 +480,7 @@ func deleteValues(t *testing.T, k registry.Key) { continue } } - names, err := k.ReadValueNames(-1) + names, err := k.ReadValueNames() if err != nil { t.Error(err) return diff --git a/libgo/go/internal/syscall/windows/registry/value.go b/libgo/go/internal/syscall/windows/registry/value.go index bf8ab007590..dc3930a6bc2 100644 --- a/libgo/go/internal/syscall/windows/registry/value.go +++ b/libgo/go/internal/syscall/windows/registry/value.go @@ -8,7 +8,6 @@ package registry import ( "errors" - "io" "syscall" "unicode/utf16" "unsafe" @@ -341,9 +340,7 @@ func (k Key) DeleteValue(name string) error { } // ReadValueNames returns the value names of key k. -// The parameter n controls the number of returned names, -// analogous to the way os.File.Readdirnames works. -func (k Key) ReadValueNames(n int) ([]string, error) { +func (k Key) ReadValueNames() ([]string, error) { ki, err := k.Stat() if err != nil { return nil, err @@ -352,11 +349,6 @@ func (k Key) ReadValueNames(n int) ([]string, error) { buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character loopItems: for i := uint32(0); ; i++ { - if n > 0 { - if len(names) == n { - return names, nil - } - } l := uint32(len(buf)) for { err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil) @@ -376,8 +368,5 @@ loopItems: } names = append(names, syscall.UTF16ToString(buf[:l])) } - if n > len(names) { - return names, io.EOF - } return names, nil } diff --git a/libgo/go/internal/syscall/windows/registry/zsyscall_windows.go b/libgo/go/internal/syscall/windows/registry/zsyscall_windows.go index c3f3a8a2154..cab13193749 100644 --- a/libgo/go/internal/syscall/windows/registry/zsyscall_windows.go +++ b/libgo/go/internal/syscall/windows/registry/zsyscall_windows.go @@ -18,6 +18,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -25,7 +26,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -41,10 +42,10 @@ var ( procRegCreateKeyExW = modadvapi32.NewProc("RegCreateKeyExW") procRegDeleteKeyW = modadvapi32.NewProc("RegDeleteKeyW") - procRegSetValueExW = modadvapi32.NewProc("RegSetValueExW") - procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW") procRegDeleteValueW = modadvapi32.NewProc("RegDeleteValueW") + procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW") procRegLoadMUIStringW = modadvapi32.NewProc("RegLoadMUIStringW") + procRegSetValueExW = modadvapi32.NewProc("RegSetValueExW") procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW") ) @@ -64,8 +65,8 @@ func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) { return } -func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) { - r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize)) +func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) { + r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -80,16 +81,16 @@ func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint3 return } -func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) { - r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0) +func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) { + r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0) if r0 != 0 { regerrno = syscall.Errno(r0) } return } -func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) { - r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0) +func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) { + r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize)) if r0 != 0 { regerrno = syscall.Errno(r0) } @@ -100,11 +101,7 @@ func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size)) n = uint32(r0) if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } diff --git a/libgo/go/internal/syscall/windows/syscall_windows.go b/libgo/go/internal/syscall/windows/syscall_windows.go index edf0b5a40b8..1f40c118205 100644 --- a/libgo/go/internal/syscall/windows/syscall_windows.go +++ b/libgo/go/internal/syscall/windows/syscall_windows.go @@ -131,6 +131,14 @@ type IpAdapterAddresses struct { /* more fields might be present here. */ } +type FILE_BASIC_INFO struct { + CreationTime syscall.Filetime + LastAccessTime syscall.Filetime + LastWriteTime syscall.Filetime + ChangedTime syscall.Filetime + FileAttributes uint32 +} + const ( IfOperStatusUp = 1 IfOperStatusDown = 2 @@ -145,6 +153,7 @@ const ( //sys GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW //sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW //sys GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW +//sys SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle const ( WSA_FLAG_OVERLAPPED = 0x01 diff --git a/libgo/go/internal/syscall/windows/zsyscall_windows.go b/libgo/go/internal/syscall/windows/zsyscall_windows.go index ca5b4e6f16d..170b239486d 100644 --- a/libgo/go/internal/syscall/windows/zsyscall_windows.go +++ b/libgo/go/internal/syscall/windows/zsyscall_windows.go @@ -18,6 +18,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -25,7 +26,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -36,121 +37,113 @@ func errnoErr(e syscall.Errno) error { } var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) - modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) - modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) - moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) + moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) + modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") + procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") + procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") + procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procGetACP = modkernel32.NewProc("GetACP") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") - procMoveFileExW = modkernel32.NewProc("MoveFileExW") + procGetConsoleCP = modkernel32.NewProc("GetConsoleCP") + procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") + procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") + procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW") procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW") - procWSASocketW = modws2_32.NewProc("WSASocketW") procLockFileEx = modkernel32.NewProc("LockFileEx") - procUnlockFileEx = modkernel32.NewProc("UnlockFileEx") - procGetACP = modkernel32.NewProc("GetACP") - procGetConsoleCP = modkernel32.NewProc("GetConsoleCP") + procMoveFileExW = modkernel32.NewProc("MoveFileExW") procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar") - procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") + procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle") + procUnlockFileEx = modkernel32.NewProc("UnlockFileEx") procNetShareAdd = modnetapi32.NewProc("NetShareAdd") procNetShareDel = modnetapi32.NewProc("NetShareDel") - procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW") + procNetUserGetLocalGroups = modnetapi32.NewProc("NetUserGetLocalGroups") + procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock") procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock") - procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") - procRevertToSelf = modadvapi32.NewProc("RevertToSelf") - procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") - procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") - procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") - procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") procGetProfilesDirectoryW = moduserenv.NewProc("GetProfilesDirectoryW") - procNetUserGetLocalGroups = modnetapi32.NewProc("NetUserGetLocalGroups") - procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") - procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx") + procWSASocketW = modws2_32.NewProc("WSASocketW") ) -func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { - r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) - if r0 != 0 { - errcode = syscall.Errno(r0) +func adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (ret uint32, err error) { + var _p0 uint32 + if disableAllPrivileges { + _p0 = 1 + } + r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) + ret = uint32(r0) + if true { + err = errnoErr(e1) } return } -func GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nameformat), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) +func DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) { + r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), uintptr(unsafe.Pointer(lpTokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(phNewToken))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) +func ImpersonateSelf(impersonationlevel uint32) (err error) { + r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(fn)), uintptr(len)) - n = uint32(r0) - if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) { + r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) + if r1 == 0 { + err = errnoErr(e1) } return } -func WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protinfo)), uintptr(group), uintptr(flags)) - handle = syscall.Handle(r0) - if handle == syscall.InvalidHandle { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func OpenThreadToken(h syscall.Handle, access uint32, openasself bool, token *syscall.Token) (err error) { + var _p0 uint32 + if openasself { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(h), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) +func RevertToSelf() (err error) { + r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0) +func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(tokenHandle), uintptr(tokenInformationClass), uintptr(tokenInformation), uintptr(tokenInformationLength), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) + } + return +} + +func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) { + r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0) + if r0 != 0 { + errcode = syscall.Errno(r0) } return } @@ -161,22 +154,17 @@ func GetACP() (acp uint32) { return } -func GetConsoleCP() (ccp uint32) { - r0, _, _ := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0) - ccp = uint32(r0) +func GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nameformat), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n))) + if r1 == 0 { + err = errnoErr(e1) + } return } -func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { - r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) - nwrite = int32(r0) - if nwrite == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } +func GetConsoleCP() (ccp uint32) { + r0, _, _ := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0) + ccp = uint32(r0) return } @@ -184,211 +172,143 @@ func GetCurrentThread() (pseudoHandle syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) pseudoHandle = syscall.Handle(r0) if pseudoHandle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) { - r0, _, _ := syscall.Syscall6(procNetShareAdd.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(parmErr)), 0, 0) - if r0 != 0 { - neterr = syscall.Errno(r0) +func GetFileInformationByHandleEx(handle syscall.Handle, class uint32, info *byte, bufsize uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(info)), uintptr(bufsize), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) { - r0, _, _ := syscall.Syscall(procNetShareDel.Addr(), 3, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(netName)), uintptr(reserved)) - if r0 != 0 { - neterr = syscall.Errno(r0) +func GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0) + n = uint32(r0) + if n == 0 { + err = errnoErr(e1) } return } -func GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) { - r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0) +func GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) { + r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(fn)), uintptr(len)) n = uint32(r0) if n == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) { - var _p0 uint32 - if inheritExisting { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) +func LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped))) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func DestroyEnvironmentBlock(block *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0) +func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) { + r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func ImpersonateSelf(impersonationlevel uint32) (err error) { - r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) { + r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar)) + nwrite = int32(r0) + if nwrite == 0 { + err = errnoErr(e1) } return } -func RevertToSelf() (err error) { - r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) +func SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(handle), uintptr(fileInformationClass), uintptr(buf), uintptr(bufsize), 0, 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func OpenThreadToken(h syscall.Handle, access uint32, openasself bool, token *syscall.Token) (err error) { - var _p0 uint32 - if openasself { - _p0 = 1 - } else { - _p0 = 0 - } - r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(h), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) +func UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) { + r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) { - r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) { + r0, _, _ := syscall.Syscall6(procNetShareAdd.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(parmErr)), 0, 0) + if r0 != 0 { + neterr = syscall.Errno(r0) } return } -func adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (ret uint32, err error) { - var _p0 uint32 - if disableAllPrivileges { - _p0 = 1 - } else { - _p0 = 0 - } - r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen))) - ret = uint32(r0) - if true { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) { + r0, _, _ := syscall.Syscall(procNetShareDel.Addr(), 3, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(netName)), uintptr(reserved)) + if r0 != 0 { + neterr = syscall.Errno(r0) } return } -func DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) { - r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), uintptr(unsafe.Pointer(lpTokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(phNewToken))) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func NetUserGetLocalGroups(serverName *uint16, userName *uint16, level uint32, flags uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32) (neterr error) { + r0, _, _ := syscall.Syscall9(procNetUserGetLocalGroups.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(flags), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), 0) + if r0 != 0 { + neterr = syscall.Errno(r0) } return } -func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(tokenHandle), uintptr(tokenInformationClass), uintptr(tokenInformation), uintptr(tokenInformationLength), 0, 0) +func GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(memCounters)), uintptr(cb)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetProfilesDirectory(dir *uint16, dirLen *uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetProfilesDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)), 0) +func CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) { + var _p0 uint32 + if inheritExisting { + _p0 = 1 + } + r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0)) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func NetUserGetLocalGroups(serverName *uint16, userName *uint16, level uint32, flags uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32) (neterr error) { - r0, _, _ := syscall.Syscall9(procNetUserGetLocalGroups.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(flags), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), 0) - if r0 != 0 { - neterr = syscall.Errno(r0) +func DestroyEnvironmentBlock(block *uint16) (err error) { + r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0) + if r1 == 0 { + err = errnoErr(e1) } return } -func GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) { - r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(memCounters)), uintptr(cb)) +func GetProfilesDirectory(dir *uint16, dirLen *uint32) (err error) { + r1, _, e1 := syscall.Syscall(procGetProfilesDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)), 0) if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func GetFileInformationByHandleEx(handle syscall.Handle, class uint32, info *byte, bufsize uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(info)), uintptr(bufsize), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protinfo)), uintptr(group), uintptr(flags)) + handle = syscall.Handle(r0) + if handle == syscall.InvalidHandle { + err = errnoErr(e1) } return } diff --git a/libgo/go/internal/sysinfo/sysinfo.go b/libgo/go/internal/sysinfo/sysinfo.go new file mode 100644 index 00000000000..961be7abaee --- /dev/null +++ b/libgo/go/internal/sysinfo/sysinfo.go @@ -0,0 +1,31 @@ +// Copyright 2020 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 sysinfo implements high level hardware information gathering +// that can be used for debugging or information purposes. +package sysinfo + +import ( + internalcpu "internal/cpu" + "sync" +) + +type cpuInfo struct { + once sync.Once + name string +} + +var CPU cpuInfo + +func (cpu *cpuInfo) Name() string { + cpu.once.Do(func() { + // Try to get the information from internal/cpu. + if name := internalcpu.Name(); name != "" { + cpu.name = name + return + } + // TODO(martisch): use /proc/cpuinfo and /sys/devices/system/cpu/ on Linux as fallback. + }) + return cpu.name +} diff --git a/libgo/go/internal/testenv/testenv.go b/libgo/go/internal/testenv/testenv.go index 5de56d99ece..dfb44e8013a 100644 --- a/libgo/go/internal/testenv/testenv.go +++ b/libgo/go/internal/testenv/testenv.go @@ -50,12 +50,8 @@ func HasGoBuild() bool { return false } switch runtime.GOOS { - case "android", "js": + case "android", "js", "ios": return false - case "darwin": - if runtime.GOARCH == "arm64" { - return false - } } // gccgo tests can not run "go build". return testingGotools() @@ -136,12 +132,8 @@ func GoTool() (string, error) { // using os.StartProcess or (more commonly) exec.Command. func HasExec() bool { switch runtime.GOOS { - case "js": + case "js", "ios": return false - case "darwin": - if runtime.GOARCH == "arm64" { - return false - } } return true } @@ -149,10 +141,8 @@ func HasExec() bool { // HasSrc reports whether the entire source tree is available under GOROOT. func HasSrc() bool { switch runtime.GOOS { - case "darwin": - if runtime.GOARCH == "arm64" { - return false - } + case "ios": + return false } if runtime.Compiler == "gccgo" { return false @@ -219,6 +209,32 @@ func MustHaveCGO(t testing.TB) { } } +// CanInternalLink reports whether the current system can link programs with +// internal linking. +// (This is the opposite of cmd/internal/sys.MustLinkExternal. Keep them in sync.) +func CanInternalLink() bool { + switch runtime.GOOS { + case "android": + if runtime.GOARCH != "arm64" { + return false + } + case "ios": + if runtime.GOARCH == "arm64" { + return false + } + } + return true +} + +// MustInternalLink checks that the current system can link programs with internal +// linking. +// If not, MustInternalLink calls t.Skip with an explanation. +func MustInternalLink(t testing.TB) { + if !CanInternalLink() { + t.Skipf("skipping test: internal linking on %s/%s is not supported", runtime.GOOS, runtime.GOARCH) + } +} + // HasSymlink reports whether the current system can use os.Symlink. func HasSymlink() bool { ok, _ := hasSymlink() @@ -287,3 +303,23 @@ func CleanCmdEnv(cmd *exec.Cmd) *exec.Cmd { } return cmd } + +// CPUIsSlow reports whether the CPU running the test is suspected to be slow. +func CPUIsSlow() bool { + switch runtime.GOARCH { + case "arm", "mips", "mipsle", "mips64", "mips64le": + return true + } + return false +} + +// SkipIfShortAndSlow skips t if -short is set and the CPU running the test is +// suspected to be slow. +// +// (This is useful for CPU-intensive tests that otherwise complete quickly.) +func SkipIfShortAndSlow(t testing.TB) { + if testing.Short() && CPUIsSlow() { + t.Helper() + t.Skipf("skipping test in -short mode on %s", runtime.GOARCH) + } +} diff --git a/libgo/go/internal/testenv/testenv_windows.go b/libgo/go/internal/testenv/testenv_windows.go index eb8d6ac1650..4802b139518 100644 --- a/libgo/go/internal/testenv/testenv_windows.go +++ b/libgo/go/internal/testenv/testenv_windows.go @@ -5,7 +5,6 @@ package testenv import ( - "io/ioutil" "os" "path/filepath" "sync" @@ -16,7 +15,7 @@ var symlinkOnce sync.Once var winSymlinkErr error func initWinHasSymlink() { - tmpdir, err := ioutil.TempDir("", "symtest") + tmpdir, err := os.MkdirTemp("", "symtest") if err != nil { panic("failed to create temp directory: " + err.Error()) } diff --git a/libgo/go/internal/testlog/exit.go b/libgo/go/internal/testlog/exit.go new file mode 100644 index 00000000000..e15defdb5b0 --- /dev/null +++ b/libgo/go/internal/testlog/exit.go @@ -0,0 +1,33 @@ +// Copyright 2020 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 testlog + +import "sync" + +// PanicOnExit0 reports whether to panic on a call to os.Exit(0). +// This is in the testlog package because, like other definitions in +// package testlog, it is a hook between the testing package and the +// os package. This is used to ensure that an early call to os.Exit(0) +// does not cause a test to pass. +func PanicOnExit0() bool { + panicOnExit0.mu.Lock() + defer panicOnExit0.mu.Unlock() + return panicOnExit0.val +} + +// panicOnExit0 is the flag used for PanicOnExit0. This uses a lock +// because the value can be cleared via a timer call that may race +// with calls to os.Exit +var panicOnExit0 struct { + mu sync.Mutex + val bool +} + +// SetPanicOnExit0 sets panicOnExit0 to v. +func SetPanicOnExit0(v bool) { + panicOnExit0.mu.Lock() + defer panicOnExit0.mu.Unlock() + panicOnExit0.val = v +} diff --git a/libgo/go/internal/trace/gc_test.go b/libgo/go/internal/trace/gc_test.go index 4f9c77041a9..9b9771e7b0c 100644 --- a/libgo/go/internal/trace/gc_test.go +++ b/libgo/go/internal/trace/gc_test.go @@ -6,8 +6,8 @@ package trace import ( "bytes" - "io/ioutil" "math" + "os" "testing" "time" ) @@ -84,7 +84,7 @@ func TestMMUTrace(t *testing.T) { t.Skip("skipping in -short mode") } - data, err := ioutil.ReadFile("testdata/stress_1_10_good") + data, err := os.ReadFile("testdata/stress_1_10_good") if err != nil { t.Fatalf("failed to read input file: %v", err) } @@ -126,7 +126,7 @@ func TestMMUTrace(t *testing.T) { } func BenchmarkMMU(b *testing.B) { - data, err := ioutil.ReadFile("testdata/stress_1_10_good") + data, err := os.ReadFile("testdata/stress_1_10_good") if err != nil { b.Fatalf("failed to read input file: %v", err) } diff --git a/libgo/go/internal/trace/parser_test.go b/libgo/go/internal/trace/parser_test.go index 6d879701577..cdab95a59ec 100644 --- a/libgo/go/internal/trace/parser_test.go +++ b/libgo/go/internal/trace/parser_test.go @@ -6,7 +6,6 @@ package trace import ( "bytes" - "io/ioutil" "os" "path/filepath" "strings" @@ -34,20 +33,20 @@ func TestCorruptedInputs(t *testing.T) { } func TestParseCanned(t *testing.T) { - files, err := ioutil.ReadDir("./testdata") + files, err := os.ReadDir("./testdata") if err != nil { t.Fatalf("failed to read ./testdata: %v", err) } for _, f := range files { - name := filepath.Join("./testdata", f.Name()) - info, err := os.Stat(name) + info, err := f.Info() if err != nil { t.Fatal(err) } if testing.Short() && info.Size() > 10000 { continue } - data, err := ioutil.ReadFile(name) + name := filepath.Join("./testdata", f.Name()) + data, err := os.ReadFile(name) if err != nil { t.Fatal(err) } diff --git a/libgo/go/io/example_test.go b/libgo/go/io/example_test.go index 465eed4d5e4..6d338acd140 100644 --- a/libgo/go/io/example_test.go +++ b/libgo/go/io/example_test.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "log" "os" "strings" @@ -141,7 +140,7 @@ func ExampleTeeReader() { r = io.TeeReader(r, os.Stdout) // Everything read from r will be copied to stdout. - ioutil.ReadAll(r) + io.ReadAll(r) // Output: // some io.Reader stream to be read @@ -241,3 +240,17 @@ func ExamplePipe() { // Output: // some io.Reader stream to be read } + +func ExampleReadAll() { + r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.") + + b, err := io.ReadAll(r) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("%s", b) + + // Output: + // Go is a general-purpose language designed with systems programming in mind. +} diff --git a/libgo/go/io/export_test.go b/libgo/go/io/export_test.go new file mode 100644 index 00000000000..fa3e8e76f61 --- /dev/null +++ b/libgo/go/io/export_test.go @@ -0,0 +1,8 @@ +// Copyright 2020 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 io + +// exported for test +var ErrInvalidWrite = errInvalidWrite diff --git a/libgo/go/io/fs/fs.go b/libgo/go/io/fs/fs.go new file mode 100644 index 00000000000..b691a860498 --- /dev/null +++ b/libgo/go/io/fs/fs.go @@ -0,0 +1,251 @@ +// Copyright 2020 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 fs defines basic interfaces to a file system. +// A file system can be provided by the host operating system +// but also by other packages. +package fs + +import ( + "internal/oserror" + "time" +) + +// An FS provides access to a hierarchical file system. +// +// The FS interface is the minimum implementation required of the file system. +// A file system may implement additional interfaces, +// such as ReadFileFS, to provide additional or optimized functionality. +type FS interface { + // Open opens the named file. + // + // When Open returns an error, it should be of type *PathError + // with the Op field set to "open", the Path field set to name, + // and the Err field describing the problem. + // + // Open should reject attempts to open names that do not satisfy + // ValidPath(name), returning a *PathError with Err set to + // ErrInvalid or ErrNotExist. + Open(name string) (File, error) +} + +// ValidPath reports whether the given path name +// is valid for use in a call to Open. +// Path names passed to open are unrooted, slash-separated +// sequences of path elements, like “x/y/z”. +// Path names must not contain a “.” or “..” or empty element, +// except for the special case that the root directory is named “.”. +// +// Paths are slash-separated on all systems, even Windows. +// Backslashes must not appear in path names. +func ValidPath(name string) bool { + if name == "." { + // special case + return true + } + + // Iterate over elements in name, checking each. + for { + i := 0 + for i < len(name) && name[i] != '/' { + if name[i] == '\\' { + return false + } + i++ + } + elem := name[:i] + if elem == "" || elem == "." || elem == ".." { + return false + } + if i == len(name) { + return true // reached clean ending + } + name = name[i+1:] + } +} + +// A File provides access to a single file. +// The File interface is the minimum implementation required of the file. +// A file may implement additional interfaces, such as +// ReadDirFile, ReaderAt, or Seeker, to provide additional or optimized functionality. +type File interface { + Stat() (FileInfo, error) + Read([]byte) (int, error) + Close() error +} + +// A DirEntry is an entry read from a directory +// (using the ReadDir function or a ReadDirFile's ReadDir method). +type DirEntry interface { + // Name returns the name of the file (or subdirectory) described by the entry. + // This name is only the final element of the path (the base name), not the entire path. + // For example, Name would return "hello.go" not "/home/gopher/hello.go". + Name() string + + // IsDir reports whether the entry describes a directory. + IsDir() bool + + // Type returns the type bits for the entry. + // The type bits are a subset of the usual FileMode bits, those returned by the FileMode.Type method. + Type() FileMode + + // Info returns the FileInfo for the file or subdirectory described by the entry. + // The returned FileInfo may be from the time of the original directory read + // or from the time of the call to Info. If the file has been removed or renamed + // since the directory read, Info may return an error satisfying errors.Is(err, ErrNotExist). + // If the entry denotes a symbolic link, Info reports the information about the link itself, + // not the link's target. + Info() (FileInfo, error) +} + +// A ReadDirFile is a directory file whose entries can be read with the ReadDir method. +// Every directory file should implement this interface. +// (It is permissible for any file to implement this interface, +// but if so ReadDir should return an error for non-directories.) +type ReadDirFile interface { + File + + // ReadDir reads the contents of the directory and returns + // a slice of up to n DirEntry values in directory order. + // Subsequent calls on the same file will yield further DirEntry values. + // + // If n > 0, ReadDir returns at most n DirEntry structures. + // In this case, if ReadDir returns an empty slice, it will return + // a non-nil error explaining why. + // At the end of a directory, the error is io.EOF. + // + // If n <= 0, ReadDir returns all the DirEntry values from the directory + // in a single slice. In this case, if ReadDir succeeds (reads all the way + // to the end of the directory), it returns the slice and a nil error. + // If it encounters an error before the end of the directory, + // ReadDir returns the DirEntry list read until that point and a non-nil error. + ReadDir(n int) ([]DirEntry, error) +} + +// Generic file system errors. +// Errors returned by file systems can be tested against these errors +// using errors.Is. +var ( + ErrInvalid = errInvalid() // "invalid argument" + ErrPermission = errPermission() // "permission denied" + ErrExist = errExist() // "file already exists" + ErrNotExist = errNotExist() // "file does not exist" + ErrClosed = errClosed() // "file already closed" +) + +func errInvalid() error { return oserror.ErrInvalid } +func errPermission() error { return oserror.ErrPermission } +func errExist() error { return oserror.ErrExist } +func errNotExist() error { return oserror.ErrNotExist } +func errClosed() error { return oserror.ErrClosed } + +// A FileInfo describes a file and is returned by Stat. +type FileInfo interface { + Name() string // base name of the file + Size() int64 // length in bytes for regular files; system-dependent for others + Mode() FileMode // file mode bits + ModTime() time.Time // modification time + IsDir() bool // abbreviation for Mode().IsDir() + Sys() interface{} // underlying data source (can return nil) +} + +// A FileMode represents a file's mode and permission bits. +// The bits have the same definition on all systems, so that +// information about files can be moved from one system +// to another portably. Not all bits apply to all systems. +// The only required bit is ModeDir for directories. +type FileMode uint32 + +// The defined file mode bits are the most significant bits of the FileMode. +// The nine least-significant bits are the standard Unix rwxrwxrwx permissions. +// The values of these bits should be considered part of the public API and +// may be used in wire protocols or disk representations: they must not be +// changed, although new bits might be added. +const ( + // The single letters are the abbreviations + // used by the String method's formatting. + ModeDir FileMode = 1 << (32 - 1 - iota) // d: is a directory + ModeAppend // a: append-only + ModeExclusive // l: exclusive use + ModeTemporary // T: temporary file; Plan 9 only + ModeSymlink // L: symbolic link + ModeDevice // D: device file + ModeNamedPipe // p: named pipe (FIFO) + ModeSocket // S: Unix domain socket + ModeSetuid // u: setuid + ModeSetgid // g: setgid + ModeCharDevice // c: Unix character device, when ModeDevice is set + ModeSticky // t: sticky + ModeIrregular // ?: non-regular file; nothing else is known about this file + + // Mask for the type bits. For regular files, none will be set. + ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregular + + ModePerm FileMode = 0777 // Unix permission bits +) + +func (m FileMode) String() string { + const str = "dalTLDpSugct?" + var buf [32]byte // Mode is uint32. + w := 0 + for i, c := range str { + if m&(1<= cap(data) { + d := append(data[:cap(data)], 0) + data = d[:len(data)] + } + n, err := file.Read(data[len(data):cap(data)]) + data = data[:len(data)+n] + if err != nil { + if err == io.EOF { + err = nil + } + return data, err + } + } +} diff --git a/libgo/go/io/fs/readfile_test.go b/libgo/go/io/fs/readfile_test.go new file mode 100644 index 00000000000..07219c14458 --- /dev/null +++ b/libgo/go/io/fs/readfile_test.go @@ -0,0 +1,59 @@ +// Copyright 2020 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 fs_test + +import ( + . "io/fs" + "testing" + "testing/fstest" + "time" +) + +var testFsys = fstest.MapFS{ + "hello.txt": { + Data: []byte("hello, world"), + Mode: 0456, + ModTime: time.Now(), + Sys: &sysValue, + }, + "sub/goodbye.txt": { + Data: []byte("goodbye, world"), + Mode: 0456, + ModTime: time.Now(), + Sys: &sysValue, + }, +} + +var sysValue int + +type readFileOnly struct{ ReadFileFS } + +func (readFileOnly) Open(name string) (File, error) { return nil, ErrNotExist } + +type openOnly struct{ FS } + +func TestReadFile(t *testing.T) { + // Test that ReadFile uses the method when present. + data, err := ReadFile(readFileOnly{testFsys}, "hello.txt") + if string(data) != "hello, world" || err != nil { + t.Fatalf(`ReadFile(readFileOnly, "hello.txt") = %q, %v, want %q, nil`, data, err, "hello, world") + } + + // Test that ReadFile uses Open when the method is not present. + data, err = ReadFile(openOnly{testFsys}, "hello.txt") + if string(data) != "hello, world" || err != nil { + t.Fatalf(`ReadFile(openOnly, "hello.txt") = %q, %v, want %q, nil`, data, err, "hello, world") + } + + // Test that ReadFile on Sub of . works (sub_test checks non-trivial subs). + sub, err := Sub(testFsys, ".") + if err != nil { + t.Fatal(err) + } + data, err = ReadFile(sub, "hello.txt") + if string(data) != "hello, world" || err != nil { + t.Fatalf(`ReadFile(sub(.), "hello.txt") = %q, %v, want %q, nil`, data, err, "hello, world") + } +} diff --git a/libgo/go/io/fs/stat.go b/libgo/go/io/fs/stat.go new file mode 100644 index 00000000000..735a6e3281c --- /dev/null +++ b/libgo/go/io/fs/stat.go @@ -0,0 +1,31 @@ +// Copyright 2020 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 fs + +// A StatFS is a file system with a Stat method. +type StatFS interface { + FS + + // Stat returns a FileInfo describing the file. + // If there is an error, it should be of type *PathError. + Stat(name string) (FileInfo, error) +} + +// Stat returns a FileInfo describing the named file from the file system. +// +// If fs implements StatFS, Stat calls fs.Stat. +// Otherwise, Stat opens the file to stat it. +func Stat(fsys FS, name string) (FileInfo, error) { + if fsys, ok := fsys.(StatFS); ok { + return fsys.Stat(name) + } + + file, err := fsys.Open(name) + if err != nil { + return nil, err + } + defer file.Close() + return file.Stat() +} diff --git a/libgo/go/io/fs/stat_test.go b/libgo/go/io/fs/stat_test.go new file mode 100644 index 00000000000..e312b6fbd91 --- /dev/null +++ b/libgo/go/io/fs/stat_test.go @@ -0,0 +1,36 @@ +// Copyright 2020 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 fs_test + +import ( + "fmt" + . "io/fs" + "testing" +) + +type statOnly struct{ StatFS } + +func (statOnly) Open(name string) (File, error) { return nil, ErrNotExist } + +func TestStat(t *testing.T) { + check := func(desc string, info FileInfo, err error) { + t.Helper() + if err != nil || info == nil || info.Mode() != 0456 { + infoStr := "" + if info != nil { + infoStr = fmt.Sprintf("FileInfo(Mode: %#o)", info.Mode()) + } + t.Fatalf("Stat(%s) = %v, %v, want Mode:0456, nil", desc, infoStr, err) + } + } + + // Test that Stat uses the method when present. + info, err := Stat(statOnly{testFsys}, "hello.txt") + check("statOnly", info, err) + + // Test that Stat uses Open when the method is not present. + info, err = Stat(openOnly{testFsys}, "hello.txt") + check("openOnly", info, err) +} diff --git a/libgo/go/io/fs/sub.go b/libgo/go/io/fs/sub.go new file mode 100644 index 00000000000..64cdffe6dec --- /dev/null +++ b/libgo/go/io/fs/sub.go @@ -0,0 +1,127 @@ +// Copyright 2020 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 fs + +import ( + "errors" + "path" +) + +// A SubFS is a file system with a Sub method. +type SubFS interface { + FS + + // Sub returns an FS corresponding to the subtree rooted at dir. + Sub(dir string) (FS, error) +} + +// Sub returns an FS corresponding to the subtree rooted at fsys's dir. +// +// If fs implements SubFS, Sub calls returns fsys.Sub(dir). +// Otherwise, if dir is ".", Sub returns fsys unchanged. +// Otherwise, Sub returns a new FS implementation sub that, +// in effect, implements sub.Open(dir) as fsys.Open(path.Join(dir, name)). +// The implementation also translates calls to ReadDir, ReadFile, and Glob appropriately. +// +// Note that Sub(os.DirFS("/"), "prefix") is equivalent to os.DirFS("/prefix") +// and that neither of them guarantees to avoid operating system +// accesses outside "/prefix", because the implementation of os.DirFS +// does not check for symbolic links inside "/prefix" that point to +// other directories. That is, os.DirFS is not a general substitute for a +// chroot-style security mechanism, and Sub does not change that fact. +func Sub(fsys FS, dir string) (FS, error) { + if !ValidPath(dir) { + return nil, &PathError{Op: "sub", Path: dir, Err: errors.New("invalid name")} + } + if dir == "." { + return fsys, nil + } + if fsys, ok := fsys.(SubFS); ok { + return fsys.Sub(dir) + } + return &subFS{fsys, dir}, nil +} + +type subFS struct { + fsys FS + dir string +} + +// fullName maps name to the fully-qualified name dir/name. +func (f *subFS) fullName(op string, name string) (string, error) { + if !ValidPath(name) { + return "", &PathError{Op: op, Path: name, Err: errors.New("invalid name")} + } + return path.Join(f.dir, name), nil +} + +// shorten maps name, which should start with f.dir, back to the suffix after f.dir. +func (f *subFS) shorten(name string) (rel string, ok bool) { + if name == f.dir { + return ".", true + } + if len(name) >= len(f.dir)+2 && name[len(f.dir)] == '/' && name[:len(f.dir)] == f.dir { + return name[len(f.dir)+1:], true + } + return "", false +} + +// fixErr shortens any reported names in PathErrors by stripping dir. +func (f *subFS) fixErr(err error) error { + if e, ok := err.(*PathError); ok { + if short, ok := f.shorten(e.Path); ok { + e.Path = short + } + } + return err +} + +func (f *subFS) Open(name string) (File, error) { + full, err := f.fullName("open", name) + if err != nil { + return nil, err + } + file, err := f.fsys.Open(full) + return file, f.fixErr(err) +} + +func (f *subFS) ReadDir(name string) ([]DirEntry, error) { + full, err := f.fullName("read", name) + if err != nil { + return nil, err + } + dir, err := ReadDir(f.fsys, full) + return dir, f.fixErr(err) +} + +func (f *subFS) ReadFile(name string) ([]byte, error) { + full, err := f.fullName("read", name) + if err != nil { + return nil, err + } + data, err := ReadFile(f.fsys, full) + return data, f.fixErr(err) +} + +func (f *subFS) Glob(pattern string) ([]string, error) { + // Check pattern is well-formed. + if _, err := path.Match(pattern, ""); err != nil { + return nil, err + } + if pattern == "." { + return []string{"."}, nil + } + + full := f.dir + "/" + pattern + list, err := Glob(f.fsys, full) + for i, name := range list { + name, ok := f.shorten(name) + if !ok { + return nil, errors.New("invalid result from inner fsys Glob: " + name + " not in " + f.dir) // can't use fmt in this package + } + list[i] = name + } + return list, f.fixErr(err) +} diff --git a/libgo/go/io/fs/sub_test.go b/libgo/go/io/fs/sub_test.go new file mode 100644 index 00000000000..451b0efb02f --- /dev/null +++ b/libgo/go/io/fs/sub_test.go @@ -0,0 +1,57 @@ +// Copyright 2020 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 fs_test + +import ( + . "io/fs" + "testing" +) + +type subOnly struct{ SubFS } + +func (subOnly) Open(name string) (File, error) { return nil, ErrNotExist } + +func TestSub(t *testing.T) { + check := func(desc string, sub FS, err error) { + t.Helper() + if err != nil { + t.Errorf("Sub(sub): %v", err) + return + } + data, err := ReadFile(sub, "goodbye.txt") + if string(data) != "goodbye, world" || err != nil { + t.Errorf(`ReadFile(%s, "goodbye.txt" = %q, %v, want %q, nil`, desc, string(data), err, "goodbye, world") + } + + dirs, err := ReadDir(sub, ".") + if err != nil || len(dirs) != 1 || dirs[0].Name() != "goodbye.txt" { + var names []string + for _, d := range dirs { + names = append(names, d.Name()) + } + t.Errorf(`ReadDir(%s, ".") = %v, %v, want %v, nil`, desc, names, err, []string{"goodbye.txt"}) + } + } + + // Test that Sub uses the method when present. + sub, err := Sub(subOnly{testFsys}, "sub") + check("subOnly", sub, err) + + // Test that Sub uses Open when the method is not present. + sub, err = Sub(openOnly{testFsys}, "sub") + check("openOnly", sub, err) + + _, err = sub.Open("nonexist") + if err == nil { + t.Fatal("Open(nonexist): succeeded") + } + pe, ok := err.(*PathError) + if !ok { + t.Fatalf("Open(nonexist): error is %T, want *PathError", err) + } + if pe.Path != "nonexist" { + t.Fatalf("Open(nonexist): err.Path = %q, want %q", pe.Path, "nonexist") + } +} diff --git a/libgo/go/io/fs/walk.go b/libgo/go/io/fs/walk.go new file mode 100644 index 00000000000..06d0b1769c5 --- /dev/null +++ b/libgo/go/io/fs/walk.go @@ -0,0 +1,132 @@ +// Copyright 2020 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 fs + +import ( + "errors" + "path" +) + +// SkipDir is used as a return value from WalkDirFuncs to indicate that +// the directory named in the call is to be skipped. It is not returned +// as an error by any function. +var SkipDir = errors.New("skip this directory") + +// WalkDirFunc is the type of the function called by WalkDir to visit +// each each file or directory. +// +// The path argument contains the argument to Walk as a prefix. +// That is, if Walk is called with root argument "dir" and finds a file +// named "a" in that directory, the walk function will be called with +// argument "dir/a". +// +// The directory and file are joined with Join, which may clean the +// directory name: if Walk is called with the root argument "x/../dir" +// and finds a file named "a" in that directory, the walk function will +// be called with argument "dir/a", not "x/../dir/a". +// +// The d argument is the fs.DirEntry for the named path. +// +// The error result returned by the function controls how WalkDir +// continues. If the function returns the special value SkipDir, WalkDir +// skips the current directory (path if d.IsDir() is true, otherwise +// path's parent directory). Otherwise, if the function returns a non-nil +// error, WalkDir stops entirely and returns that error. +// +// The err argument reports an error related to path, signaling that +// WalkDir will not walk into that directory. The function can decide how +// to handle that error; as described earlier, returning the error will +// cause WalkDir to stop walking the entire tree. +// +// WalkDir calls the function with a non-nil err argument in two cases. +// +// First, if the initial os.Lstat on the root directory fails, WalkDir +// calls the function with path set to root, d set to nil, and err set to +// the error from os.Lstat. +// +// Second, if a directory's ReadDir method fails, WalkDir calls the +// function with path set to the directory's path, d set to an +// fs.DirEntry describing the directory, and err set to the error from +// ReadDir. In this second case, the function is called twice with the +// path of the directory: the first call is before the directory read is +// attempted and has err set to nil, giving the function a chance to +// return SkipDir and avoid the ReadDir entirely. The second call is +// after a failed ReadDir and reports the error from ReadDir. +// (If ReadDir succeeds, there is no second call.) +// +// The differences between WalkDirFunc compared to filepath.WalkFunc are: +// +// - The second argument has type fs.DirEntry instead of fs.FileInfo. +// - The function is called before reading a directory, to allow SkipDir +// to bypass the directory read entirely. +// - If a directory read fails, the function is called a second time +// for that directory to report the error. +// +type WalkDirFunc func(path string, d DirEntry, err error) error + +// walkDir recursively descends path, calling walkDirFn. +func walkDir(fsys FS, name string, d DirEntry, walkDirFn WalkDirFunc) error { + if err := walkDirFn(name, d, nil); err != nil || !d.IsDir() { + if err == SkipDir && d.IsDir() { + // Successfully skipped directory. + err = nil + } + return err + } + + dirs, err := ReadDir(fsys, name) + if err != nil { + // Second call, to report ReadDir error. + err = walkDirFn(name, d, err) + if err != nil { + return err + } + } + + for _, d1 := range dirs { + name1 := path.Join(name, d1.Name()) + if err := walkDir(fsys, name1, d1, walkDirFn); err != nil { + if err == SkipDir { + break + } + return err + } + } + return nil +} + +// WalkDir walks the file tree rooted at root, calling fn for each file or +// directory in the tree, including root. +// +// All errors that arise visiting files and directories are filtered by fn: +// see the fs.WalkDirFunc documentation for details. +// +// The files are walked in lexical order, which makes the output deterministic +// but requires WalkDir to read an entire directory into memory before proceeding +// to walk that directory. +// +// WalkDir does not follow symbolic links found in directories, +// but if root itself is a symbolic link, its target will be walked. +func WalkDir(fsys FS, root string, fn WalkDirFunc) error { + info, err := Stat(fsys, root) + if err != nil { + err = fn(root, nil, err) + } else { + err = walkDir(fsys, root, &statDirEntry{info}, fn) + } + if err == SkipDir { + return nil + } + return err +} + +type statDirEntry struct { + info FileInfo +} + +func (d *statDirEntry) Name() string { return d.info.Name() } +func (d *statDirEntry) IsDir() bool { return d.info.IsDir() } +func (d *statDirEntry) Type() FileMode { return d.info.Mode().Type() } +func (d *statDirEntry) Info() (FileInfo, error) { return d.info, nil } diff --git a/libgo/go/io/fs/walk_test.go b/libgo/go/io/fs/walk_test.go new file mode 100644 index 00000000000..395471e2e8a --- /dev/null +++ b/libgo/go/io/fs/walk_test.go @@ -0,0 +1,155 @@ +// Copyright 2020 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 fs_test + +import ( + . "io/fs" + "io/ioutil" + "os" + pathpkg "path" + "runtime" + "testing" + "testing/fstest" +) + +type Node struct { + name string + entries []*Node // nil if the entry is a file + mark int +} + +var tree = &Node{ + "testdata", + []*Node{ + {"a", nil, 0}, + {"b", []*Node{}, 0}, + {"c", nil, 0}, + { + "d", + []*Node{ + {"x", nil, 0}, + {"y", []*Node{}, 0}, + { + "z", + []*Node{ + {"u", nil, 0}, + {"v", nil, 0}, + }, + 0, + }, + }, + 0, + }, + }, + 0, +} + +func walkTree(n *Node, path string, f func(path string, n *Node)) { + f(path, n) + for _, e := range n.entries { + walkTree(e, pathpkg.Join(path, e.name), f) + } +} + +func makeTree(t *testing.T) FS { + fsys := fstest.MapFS{} + walkTree(tree, tree.name, func(path string, n *Node) { + if n.entries == nil { + fsys[path] = &fstest.MapFile{} + } else { + fsys[path] = &fstest.MapFile{Mode: ModeDir} + } + }) + return fsys +} + +func markTree(n *Node) { walkTree(n, "", func(path string, n *Node) { n.mark++ }) } + +func checkMarks(t *testing.T, report bool) { + walkTree(tree, tree.name, func(path string, n *Node) { + if n.mark != 1 && report { + t.Errorf("node %s mark = %d; expected 1", path, n.mark) + } + n.mark = 0 + }) +} + +// Assumes that each node name is unique. Good enough for a test. +// If clear is true, any incoming error is cleared before return. The errors +// are always accumulated, though. +func mark(entry DirEntry, err error, errors *[]error, clear bool) error { + name := entry.Name() + walkTree(tree, tree.name, func(path string, n *Node) { + if n.name == name { + n.mark++ + } + }) + if err != nil { + *errors = append(*errors, err) + if clear { + return nil + } + return err + } + return nil +} + +func chtmpdir(t *testing.T) (restore func()) { + oldwd, err := os.Getwd() + if err != nil { + t.Fatalf("chtmpdir: %v", err) + } + d, err := ioutil.TempDir("", "test") + if err != nil { + t.Fatalf("chtmpdir: %v", err) + } + if err := os.Chdir(d); err != nil { + t.Fatalf("chtmpdir: %v", err) + } + return func() { + if err := os.Chdir(oldwd); err != nil { + t.Fatalf("chtmpdir: %v", err) + } + os.RemoveAll(d) + } +} + +func TestWalkDir(t *testing.T) { + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { + restore := chtmpdir(t) + defer restore() + } + + tmpDir, err := ioutil.TempDir("", "TestWalk") + if err != nil { + t.Fatal("creating temp dir:", err) + } + defer os.RemoveAll(tmpDir) + + origDir, err := os.Getwd() + if err != nil { + t.Fatal("finding working dir:", err) + } + if err = os.Chdir(tmpDir); err != nil { + t.Fatal("entering temp dir:", err) + } + defer os.Chdir(origDir) + + fsys := makeTree(t) + errors := make([]error, 0, 10) + clear := true + markFn := func(path string, entry DirEntry, err error) error { + return mark(entry, err, &errors, clear) + } + // Expect no errors. + err = WalkDir(fsys, ".", markFn) + if err != nil { + t.Fatalf("no error expected, found: %s", err) + } + if len(errors) != 0 { + t.Fatalf("unexpected errors: %s", errors) + } + checkMarks(t, true) +} diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go index 3dea70b947b..ffd3cedc254 100644 --- a/libgo/go/io/io.go +++ b/libgo/go/io/io.go @@ -14,6 +14,7 @@ package io import ( "errors" + "sync" ) // Seek whence values. @@ -27,10 +28,15 @@ const ( // but failed to return an explicit error. var ErrShortWrite = errors.New("short write") +// errInvalidWrite means that a write returned an impossible count. +var errInvalidWrite = errors.New("invalid write result") + // ErrShortBuffer means that a read required a longer buffer than was provided. var ErrShortBuffer = errors.New("short buffer") // EOF is the error returned by Read when no more input is available. +// (Read must return EOF itself, not an error wrapping EOF, +// because callers will test for EOF using ==.) // Functions should return EOF only to signal a graceful end of input. // If the EOF occurs unexpectedly in a structured data stream, // the appropriate error is either ErrUnexpectedEOF or some other error @@ -41,9 +47,9 @@ var EOF = errors.New("EOF") // middle of reading a fixed-size block or data structure. var ErrUnexpectedEOF = errors.New("unexpected EOF") -// ErrNoProgress is returned by some clients of an io.Reader when +// ErrNoProgress is returned by some clients of an Reader when // many calls to Read have failed to return any data or error, -// usually the sign of a broken io.Reader implementation. +// usually the sign of a broken Reader implementation. var ErrNoProgress = errors.New("multiple Read calls return no data or error") // Reader is the interface that wraps the basic Read method. @@ -147,6 +153,14 @@ type ReadSeeker interface { Seeker } +// ReadSeekCloser is the interface that groups the basic Read, Seek and Close +// methods. +type ReadSeekCloser interface { + Reader + Seeker + Closer +} + // WriteSeeker is the interface that groups the basic Write and Seek methods. type WriteSeeker interface { Writer @@ -164,7 +178,7 @@ type ReadWriteSeeker interface { // // ReadFrom reads data from r until EOF or error. // The return value n is the number of bytes read. -// Any error except io.EOF encountered during the read is also returned. +// Any error except EOF encountered during the read is also returned. // // The Copy function uses ReaderFrom if available. type ReaderFrom interface { @@ -377,7 +391,7 @@ func Copy(dst Writer, src Reader) (written int64, err error) { // 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") + panic("empty buffer in CopyBuffer") } return copyBuffer(dst, src, buf) } @@ -409,9 +423,13 @@ func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) { nr, er := src.Read(buf) if nr > 0 { nw, ew := dst.Write(buf[0:nr]) - if nw > 0 { - written += int64(nw) + if nw < 0 || nr < nw { + nw = 0 + if ew == nil { + ew = errInvalidWrite + } } + written += int64(nw) if ew != nil { err = ew break @@ -547,3 +565,78 @@ func (t *teeReader) Read(p []byte) (n int, err error) { } return } + +// Discard is an Writer on which all Write calls succeed +// without doing anything. +var Discard Writer = discard{} + +type discard struct{} + +// discard implements ReaderFrom as an optimization so Copy to +// io.Discard can avoid doing unnecessary work. +var _ ReaderFrom = discard{} + +func (discard) Write(p []byte) (int, error) { + return len(p), nil +} + +func (discard) WriteString(s string) (int, error) { + return len(s), nil +} + +var blackHolePool = sync.Pool{ + New: func() interface{} { + b := make([]byte, 8192) + return &b + }, +} + +func (discard) ReadFrom(r Reader) (n int64, err error) { + bufp := blackHolePool.Get().(*[]byte) + readSize := 0 + for { + readSize, err = r.Read(*bufp) + n += int64(readSize) + if err != nil { + blackHolePool.Put(bufp) + if err == EOF { + return n, nil + } + return + } + } +} + +// NopCloser returns a ReadCloser with a no-op Close method wrapping +// the provided Reader r. +func NopCloser(r Reader) ReadCloser { + return nopCloser{r} +} + +type nopCloser struct { + Reader +} + +func (nopCloser) Close() error { return nil } + +// ReadAll reads from r until an error or EOF and returns the data it read. +// A successful call returns err == nil, not err == EOF. Because ReadAll is +// defined to read from src until EOF, it does not treat an EOF from Read +// as an error to be reported. +func ReadAll(r Reader) ([]byte, error) { + b := make([]byte, 0, 512) + for { + if len(b) == cap(b) { + // Add more capacity (let append pick how much). + b = append(b, 0)[:len(b)] + } + n, err := r.Read(b[len(b):cap(b)]) + b = b[:len(b)+n] + if err != nil { + if err == EOF { + err = nil + } + return b, err + } + } +} diff --git a/libgo/go/io/io_test.go b/libgo/go/io/io_test.go index 170513dcc0d..5b355e8c55b 100644 --- a/libgo/go/io/io_test.go +++ b/libgo/go/io/io_test.go @@ -429,3 +429,31 @@ func TestSectionReader_Size(t *testing.T) { } } } + +// largeWriter returns an invalid count that is larger than the number +// of bytes provided (issue 39978). +type largeWriter struct { + err error +} + +func (w largeWriter) Write(p []byte) (int, error) { + return len(p) + 1, w.err +} + +func TestCopyLargeWriter(t *testing.T) { + want := ErrInvalidWrite + rb := new(Buffer) + wb := largeWriter{} + rb.WriteString("hello, world.") + if _, err := Copy(wb, rb); err != want { + t.Errorf("Copy error: got %v, want %v", err, want) + } + + want = errors.New("largeWriterError") + rb = new(Buffer) + wb = largeWriter{err: want} + rb.WriteString("hello, world.") + if _, err := Copy(wb, rb); err != want { + t.Errorf("Copy error: got %v, want %v", err, want) + } +} diff --git a/libgo/go/io/ioutil/ioutil.go b/libgo/go/io/ioutil/ioutil.go index acc6ec3a40a..45682b89c99 100644 --- a/libgo/go/io/ioutil/ioutil.go +++ b/libgo/go/io/ioutil/ioutil.go @@ -3,94 +3,59 @@ // license that can be found in the LICENSE file. // Package ioutil implements some I/O utility functions. +// +// As of Go 1.16, the same functionality is now provided +// by package io or package os, and those implementations +// should be preferred in new code. +// See the specific function documentation for details. package ioutil import ( - "bytes" "io" + "io/fs" "os" "sort" - "sync" ) -// readAll reads from r until an error or EOF and returns the data it read -// from the internal buffer allocated with a specified capacity. -func readAll(r io.Reader, capacity int64) (b []byte, err error) { - var buf bytes.Buffer - // If the buffer overflows, we will get bytes.ErrTooLarge. - // Return that as an error. Any other panic remains. - defer func() { - e := recover() - if e == nil { - return - } - if panicErr, ok := e.(error); ok && panicErr == bytes.ErrTooLarge { - err = panicErr - } else { - panic(e) - } - }() - if int64(int(capacity)) == capacity { - buf.Grow(int(capacity)) - } - _, err = buf.ReadFrom(r) - return buf.Bytes(), err -} - // ReadAll reads from r until an error or EOF and returns the data it read. // A successful call returns err == nil, not err == EOF. Because ReadAll is // defined to read from src until EOF, it does not treat an EOF from Read // as an error to be reported. +// +// As of Go 1.16, this function simply calls io.ReadAll. func ReadAll(r io.Reader) ([]byte, error) { - return readAll(r, bytes.MinRead) + return io.ReadAll(r) } // ReadFile reads the file named by filename and returns the contents. // A successful call returns err == nil, not err == EOF. Because ReadFile // reads the whole file, it does not treat an EOF from Read as an error // to be reported. +// +// As of Go 1.16, this function simply calls os.ReadFile. func ReadFile(filename string) ([]byte, error) { - f, err := os.Open(filename) - if err != nil { - return nil, err - } - defer f.Close() - // It's a good but not certain bet that FileInfo will tell us exactly how much to - // read, so let's try it but be prepared for the answer to be wrong. - var n int64 = bytes.MinRead - - if fi, err := f.Stat(); err == nil { - // As initial capacity for readAll, use Size + a little extra in case Size - // is zero, and to avoid another allocation after Read has filled the - // buffer. The readAll call will read into its allocated internal buffer - // cheaply. If the size was wrong, we'll either waste some space off the end - // or reallocate as needed, but in the overwhelmingly common case we'll get - // it just right. - if size := fi.Size() + bytes.MinRead; size > n { - n = size - } - } - return readAll(f, n) + return os.ReadFile(filename) } // WriteFile writes data to a file named by filename. // If the file does not exist, WriteFile creates it with permissions perm // (before umask); otherwise WriteFile truncates it before writing, without changing permissions. -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 - } - _, err = f.Write(data) - if err1 := f.Close(); err == nil { - err = err1 - } - return err +// +// As of Go 1.16, this function simply calls os.WriteFile. +func WriteFile(filename string, data []byte, perm fs.FileMode) error { + return os.WriteFile(filename, data, perm) } // ReadDir reads the directory named by dirname and returns -// a list of directory entries sorted by filename. -func ReadDir(dirname string) ([]os.FileInfo, error) { +// a list of fs.FileInfo for the directory's contents, +// sorted by filename. If an error occurs reading the directory, +// ReadDir returns no directory entries along with the error. +// +// As of Go 1.16, os.ReadDir is a more efficient and correct choice: +// it returns a list of fs.DirEntry instead of fs.FileInfo, +// and it returns partial results in the case of an error +// midway through reading a directory. +func ReadDir(dirname string) ([]fs.FileInfo, error) { f, err := os.Open(dirname) if err != nil { return nil, err @@ -104,55 +69,16 @@ func ReadDir(dirname string) ([]os.FileInfo, error) { return list, nil } -type nopCloser struct { - io.Reader -} - -func (nopCloser) Close() error { return nil } - // NopCloser returns a ReadCloser with a no-op Close method wrapping // the provided Reader r. +// +// As of Go 1.16, this function simply calls io.NopCloser. func NopCloser(r io.Reader) io.ReadCloser { - return nopCloser{r} -} - -type devNull int - -// devNull implements ReaderFrom as an optimization so io.Copy to -// ioutil.Discard can avoid doing unnecessary work. -var _ io.ReaderFrom = devNull(0) - -func (devNull) Write(p []byte) (int, error) { - return len(p), nil -} - -func (devNull) WriteString(s string) (int, error) { - return len(s), nil -} - -var blackHolePool = sync.Pool{ - New: func() interface{} { - b := make([]byte, 8192) - return &b - }, -} - -func (devNull) ReadFrom(r io.Reader) (n int64, err error) { - bufp := blackHolePool.Get().(*[]byte) - readSize := 0 - for { - readSize, err = r.Read(*bufp) - n += int64(readSize) - if err != nil { - blackHolePool.Put(bufp) - if err == io.EOF { - return n, nil - } - return - } - } + return io.NopCloser(r) } // Discard is an io.Writer on which all Write calls succeed // without doing anything. -var Discard io.Writer = devNull(0) +// +// As of Go 1.16, this value is simply io.Discard. +var Discard io.Writer = io.Discard diff --git a/libgo/go/io/ioutil/tempfile_test.go b/libgo/go/io/ioutil/tempfile_test.go index fcc5101fcc8..440c7cffc67 100644 --- a/libgo/go/io/ioutil/tempfile_test.go +++ b/libgo/go/io/ioutil/tempfile_test.go @@ -5,6 +5,7 @@ package ioutil_test import ( + "io/fs" . "io/ioutil" "os" "path/filepath" @@ -151,7 +152,7 @@ func TestTempDir_BadDir(t *testing.T) { badDir := filepath.Join(dir, "not-exist") _, err = TempDir(badDir, "foo") - if pe, ok := err.(*os.PathError); !ok || !os.IsNotExist(err) || pe.Path != badDir { + if pe, ok := err.(*fs.PathError); !ok || !os.IsNotExist(err) || pe.Path != badDir { t.Errorf("TempDir error = %#v; want PathError for path %q satisifying os.IsNotExist", err, badDir) } } diff --git a/libgo/go/io/multi_test.go b/libgo/go/io/multi_test.go index bc6b0ab7546..c059fa67dc6 100644 --- a/libgo/go/io/multi_test.go +++ b/libgo/go/io/multi_test.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" . "io" - "io/ioutil" "runtime" "strings" "testing" @@ -143,7 +142,7 @@ func testMultiWriter(t *testing.T, sink interface { } } -// writerFunc is an io.Writer implemented by the underlying func. +// writerFunc is an Writer implemented by the underlying func. type writerFunc func(p []byte) (int, error) func (f writerFunc) Write(p []byte) (int, error) { @@ -197,7 +196,7 @@ func TestMultiReaderCopy(t *testing.T) { slice := []Reader{strings.NewReader("hello world")} r := MultiReader(slice...) slice[0] = nil - data, err := ioutil.ReadAll(r) + data, err := ReadAll(r) if err != nil || string(data) != "hello world" { t.Errorf("ReadAll() = %q, %v, want %q, nil", data, err, "hello world") } @@ -218,7 +217,7 @@ func TestMultiWriterCopy(t *testing.T) { } } -// readerFunc is an io.Reader implemented by the underlying func. +// readerFunc is an Reader implemented by the underlying func. type readerFunc func(p []byte) (int, error) func (f readerFunc) Read(p []byte) (int, error) { @@ -262,7 +261,7 @@ func TestMultiReaderFlatten(t *testing.T) { } // byteAndEOFReader is a Reader which reads one byte (the underlying -// byte) and io.EOF at once in its Read call. +// byte) and EOF at once in its Read call. type byteAndEOFReader byte func (b byteAndEOFReader) Read(p []byte) (n int, err error) { @@ -277,7 +276,7 @@ func (b byteAndEOFReader) Read(p []byte) (n int, err error) { // This used to yield bytes forever; issue 16795. func TestMultiReaderSingleByteWithEOF(t *testing.T) { - got, err := ioutil.ReadAll(LimitReader(MultiReader(byteAndEOFReader('a'), byteAndEOFReader('b')), 10)) + got, err := ReadAll(LimitReader(MultiReader(byteAndEOFReader('a'), byteAndEOFReader('b')), 10)) if err != nil { t.Fatal(err) } diff --git a/libgo/go/log/log.go b/libgo/go/log/log.go index 216cfe03222..b77af290329 100644 --- a/libgo/go/log/log.go +++ b/libgo/go/log/log.go @@ -75,6 +75,9 @@ func (l *Logger) SetOutput(w io.Writer) { var std = New(os.Stderr, "", LstdFlags) +// Default returns the standard logger used by the package-level output functions. +func Default() *Logger { return std } + // Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. func itoa(buf *[]byte, i int, wid int) { // Assemble decimal in reverse order. diff --git a/libgo/go/log/log_test.go b/libgo/go/log/log_test.go index cdccbc554d8..5be8e822586 100644 --- a/libgo/go/log/log_test.go +++ b/libgo/go/log/log_test.go @@ -74,6 +74,12 @@ func testPrint(t *testing.T, flag int, prefix string, pattern string, useFormat SetOutput(os.Stderr) } +func TestDefault(t *testing.T) { + if got := Default(); got != std { + t.Errorf("Default [%p] should be std [%p]", got, std) + } +} + func TestAll(t *testing.T) { for _, testcase := range tests { testPrint(t, testcase.flag, testcase.prefix, testcase.pattern, false) diff --git a/libgo/go/log/syslog/syslog.go b/libgo/go/log/syslog/syslog.go index 82dd4e7dd6d..97c10f31df3 100644 --- a/libgo/go/log/syslog/syslog.go +++ b/libgo/go/log/syslog/syslog.go @@ -161,7 +161,10 @@ func (w *Writer) connect() (err error) { var c net.Conn c, err = net.Dial(w.network, w.raddr) if err == nil { - w.conn = &netConn{conn: c} + w.conn = &netConn{ + conn: c, + local: w.network == "unixgram" || w.network == "unix", + } if w.hostname == "" { w.hostname = c.LocalAddr().String() } diff --git a/libgo/go/log/syslog/syslog_test.go b/libgo/go/log/syslog/syslog_test.go index f778e965f3b..207bcf57c17 100644 --- a/libgo/go/log/syslog/syslog_test.go +++ b/libgo/go/log/syslog/syslog_test.go @@ -10,7 +10,6 @@ import ( "bufio" "fmt" "io" - "io/ioutil" "log" "net" "os" @@ -51,12 +50,7 @@ func testableNetwork(network string) bool { switch network { case "unix", "unixgram": switch runtime.GOOS { - case "darwin": - switch runtime.GOARCH { - case "arm64": - return false - } - case "android": + case "ios", "android": return false } } @@ -93,8 +87,8 @@ func startServer(n, la string, done chan<- string) (addr string, sock io.Closer, } else { // unix and unixgram: choose an address if none given if la == "" { - // use ioutil.TempFile to get a name that is unique - f, err := ioutil.TempFile("", "syslogtest") + // use os.CreateTemp to get a name that is unique + f, err := os.CreateTemp("", "syslogtest") if err != nil { log.Fatal("TempFile: ", err) } @@ -159,7 +153,7 @@ func TestWithSimulated(t *testing.T) { if err != nil { t.Fatalf("log failed: %v", err) } - check(t, msg, <-done) + check(t, msg, <-done, tr) s.Close() } } @@ -185,7 +179,7 @@ func TestFlap(t *testing.T) { if err != nil { t.Fatalf("log failed: %v", err) } - check(t, msg, <-done) + check(t, msg, <-done, net) // restart the server _, sock2, srvWG2 := startServer(net, addr, done) @@ -198,7 +192,7 @@ func TestFlap(t *testing.T) { if err != nil { t.Fatalf("log failed: %v", err) } - check(t, msg, <-done) + check(t, msg, <-done, net) s.Close() } @@ -258,16 +252,31 @@ func TestDial(t *testing.T) { l.Close() } -func check(t *testing.T, in, out string) { - tmpl := fmt.Sprintf("<%d>%%s %%s syslog_test[%%d]: %s\n", LOG_USER+LOG_INFO, in) - if hostname, err := os.Hostname(); err != nil { +func check(t *testing.T, in, out, transport string) { + hostname, err := os.Hostname() + if err != nil { t.Error("Error retrieving hostname") - } else { - var parsedHostname, timestamp string + return + } + + if transport == "unixgram" || transport == "unix" { + var month, date, ts string var pid int - if n, err := fmt.Sscanf(out, tmpl, ×tamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname { + tmpl := fmt.Sprintf("<%d>%%s %%s %%s syslog_test[%%d]: %s\n", LOG_USER+LOG_INFO, in) + n, err := fmt.Sscanf(out, tmpl, &month, &date, &ts, &pid) + if n != 4 || err != nil { t.Errorf("Got %q, does not match template %q (%d %s)", out, tmpl, n, err) } + return + } + + // Non-UNIX domain transports. + var parsedHostname, timestamp string + var pid int + tmpl := fmt.Sprintf("<%d>%%s %%s syslog_test[%%d]: %s\n", LOG_USER+LOG_INFO, in) + n, err := fmt.Sscanf(out, tmpl, ×tamp, &parsedHostname, &pid) + if n != 3 || err != nil || hostname != parsedHostname { + t.Errorf("Got %q, does not match template %q (%d %s)", out, tmpl, n, err) } } diff --git a/libgo/go/math/acosh.go b/libgo/go/math/acosh.go index 97e84d01777..4b3ebf574dc 100644 --- a/libgo/go/math/acosh.go +++ b/libgo/go/math/acosh.go @@ -47,10 +47,7 @@ func Acosh(x float64) float64 { func libc_acosh(float64) float64 func acosh(x float64) float64 { - const ( - Ln2 = 6.93147180559945286227e-01 // 0x3FE62E42FEFA39EF - Large = 1 << 28 // 2**28 - ) + const Large = 1 << 28 // 2**28 // first case is special case switch { case x < 1 || IsNaN(x): diff --git a/libgo/go/math/big/arith.go b/libgo/go/math/big/arith.go index b0885f261fe..750ce8aa398 100644 --- a/libgo/go/math/big/arith.go +++ b/libgo/go/math/big/arith.go @@ -60,12 +60,6 @@ func nlz(x Word) uint { return uint(bits.LeadingZeros(uint(x))) } -// q = (u1<<_W + u0 - r)/v -func divWW_g(u1, u0, v Word) (q, r Word) { - qq, rr := bits.Div(uint(u1), uint(u0), uint(v)) - return Word(qq), Word(rr) -} - // The resulting carry c is either 0 or 1. func addVV_g(z, x, y []Word) (c Word) { // The comment near the top of this file discusses this for loop condition. @@ -207,10 +201,87 @@ func addMulVVW_g(z, x []Word, y Word) (c Word) { return } -func divWVW_g(z []Word, xn Word, x []Word, y Word) (r Word) { +// q = ( x1 << _W + x0 - r)/y. m = floor(( _B^2 - 1 ) / d - _B). Requiring x1>(_W-s) + x0 <<= s + y <<= s + } + d := uint(y) + // We know that + // m = ⎣(B^2-1)/d⎦-B + // ⎣(B^2-1)/d⎦ = m+B + // (B^2-1)/d = m+B+delta1 0 <= delta1 <= (d-1)/d + // B^2/d = m+B+delta2 0 <= delta2 <= 1 + // The quotient we're trying to compute is + // quotient = ⎣(x1*B+x0)/d⎦ + // = ⎣(x1*B*(B^2/d)+x0*(B^2/d))/B^2⎦ + // = ⎣(x1*B*(m+B+delta2)+x0*(m+B+delta2))/B^2⎦ + // = ⎣(x1*m+x1*B+x0)/B + x0*m/B^2 + delta2*(x1*B+x0)/B^2⎦ + // The latter two terms of this three-term sum are between 0 and 1. + // So we can compute just the first term, and we will be low by at most 2. + t1, t0 := bits.Mul(uint(m), uint(x1)) + _, c := bits.Add(t0, uint(x0), 0) + t1, _ = bits.Add(t1, uint(x1), c) + // The quotient is either t1, t1+1, or t1+2. + // We'll try t1 and adjust if needed. + qq := t1 + // compute remainder r=x-d*q. + dq1, dq0 := bits.Mul(d, qq) + r0, b := bits.Sub(uint(x0), dq0, 0) + r1, _ := bits.Sub(uint(x1), dq1, b) + // The remainder we just computed is bounded above by B+d: + // r = x1*B + x0 - d*q. + // = x1*B + x0 - d*⎣(x1*m+x1*B+x0)/B⎦ + // = x1*B + x0 - d*((x1*m+x1*B+x0)/B-alpha) 0 <= alpha < 1 + // = x1*B + x0 - x1*d/B*m - x1*d - x0*d/B + d*alpha + // = x1*B + x0 - x1*d/B*⎣(B^2-1)/d-B⎦ - x1*d - x0*d/B + d*alpha + // = x1*B + x0 - x1*d/B*⎣(B^2-1)/d-B⎦ - x1*d - x0*d/B + d*alpha + // = x1*B + x0 - x1*d/B*((B^2-1)/d-B-beta) - x1*d - x0*d/B + d*alpha 0 <= beta < 1 + // = x1*B + x0 - x1*B + x1/B + x1*d + x1*d/B*beta - x1*d - x0*d/B + d*alpha + // = x0 + x1/B + x1*d/B*beta - x0*d/B + d*alpha + // = x0*(1-d/B) + x1*(1+d*beta)/B + d*alpha + // < B*(1-d/B) + d*B/B + d because x00), x1= d { + qq++ + r0 -= d + } + return Word(qq), Word(r0 >> s) +} + +func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) { r = xn + if len(x) == 1 { + qq, rr := bits.Div(uint(r), uint(x[0]), uint(y)) + z[0] = Word(qq) + return Word(rr) + } + rec := reciprocalWord(y) for i := len(z) - 1; i >= 0; i-- { - z[i], r = divWW_g(r, x[i], y) + z[i], r = divWW(r, x[i], y, rec) } - return + return r +} + +// reciprocalWord return the reciprocal of the divisor. rec = floor(( _B^2 - 1 ) / u - _B). u = d1 << nlz(d1). +func reciprocalWord(d1 Word) Word { + u := uint(d1 << nlz(d1)) + x1 := ^u + x0 := uint(_M) + rec, _ := bits.Div(x1, x0, u) // (_B^2-1)/U-_B = (_B*(_M-C)+_M)/U + return Word(rec) } diff --git a/libgo/go/math/big/arith_decl.go b/libgo/go/math/big/arith_decl.go index 61df0df9f24..a14fda3087a 100644 --- a/libgo/go/math/big/arith_decl.go +++ b/libgo/go/math/big/arith_decl.go @@ -9,7 +9,6 @@ package big // implemented in arith_$GOARCH.s func mulWW(x, y Word) (z1, z0 Word) -func divWW(x1, x0, y Word) (q, r Word) func addVV(z, x, y []Word) (c Word) func subVV(z, x, y []Word) (c Word) func addVW(z, x []Word, y Word) (c Word) @@ -18,4 +17,3 @@ func shlVU(z, x []Word, s uint) (c Word) func shrVU(z, x []Word, s uint) (c Word) func mulAddVWW(z, x []Word, y, r Word) (c Word) func addMulVVW(z, x []Word, y Word) (c Word) -func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) diff --git a/libgo/go/math/big/arith_decl_pure.go b/libgo/go/math/big/arith_decl_pure.go index ee8f92211e8..ac789850389 100644 --- a/libgo/go/math/big/arith_decl_pure.go +++ b/libgo/go/math/big/arith_decl_pure.go @@ -10,10 +10,6 @@ func mulWW(x, y Word) (z1, z0 Word) { return mulWW_g(x, y) } -func divWW(x1, x0, y Word) (q, r Word) { - return divWW_g(x1, x0, y) -} - func addVV(z, x, y []Word) (c Word) { return addVV_g(z, x, y) } @@ -55,7 +51,3 @@ func mulAddVWW(z, x []Word, y, r Word) (c Word) { func addMulVVW(z, x []Word, y Word) (c Word) { return addMulVVW_g(z, x, y) } - -func divWVW(z []Word, xn Word, x []Word, y Word) (r Word) { - return divWVW_g(z, xn, x, y) -} diff --git a/libgo/go/math/big/arith_test.go b/libgo/go/math/big/arith_test.go index 05136f1895f..2aca0effde2 100644 --- a/libgo/go/math/big/arith_test.go +++ b/libgo/go/math/big/arith_test.go @@ -7,6 +7,7 @@ package big import ( "fmt" "internal/testenv" + "math/bits" "math/rand" "strings" "testing" @@ -179,6 +180,23 @@ func testFunVW(t *testing.T, msg string, f funVW, a argVW) { } } +func testFunVWext(t *testing.T, msg string, f funVW, f_g funVW, a argVW) { + // using the result of addVW_g/subVW_g as golden + z_g := make(nat, len(a.z)) + c_g := f_g(z_g, a.x, a.y) + c := f(a.z, a.x, a.y) + + for i, zi := range a.z { + if zi != z_g[i] { + t.Errorf("%s\n\tgot z[%d] = %#x; want %#x", msg, i, zi, z_g[i]) + break + } + } + if c != c_g { + t.Errorf("%s\n\tgot c = %#x; want %#x", msg, c, c_g) + } +} + func makeFunVW(f func(z, x []Word, s uint) (c Word)) funVW { return func(z, x []Word, s Word) (c Word) { return f(z, x, uint(s)) @@ -213,6 +231,49 @@ func TestFunVW(t *testing.T) { } } +// Construct a vector comprising the same word, usually '0' or 'maximum uint' +func makeWordVec(e Word, n int) []Word { + v := make([]Word, n) + for i := range v { + v[i] = e + } + return v +} + +// Extended testing to addVW and subVW using various kinds of input data. +// We utilize the results of addVW_g and subVW_g as golden reference to check +// correctness. +func TestFunVWExt(t *testing.T) { + // 32 is the current threshold that triggers an optimized version of + // calculation for large-sized vector, ensure we have sizes around it tested. + var vwSizes = []int{0, 1, 3, 4, 5, 8, 9, 23, 31, 32, 33, 34, 35, 36, 50, 120} + for _, n := range vwSizes { + // vector of random numbers, using the result of addVW_g/subVW_g as golden + x := rndV(n) + y := rndW() + z := make(nat, n) + arg := argVW{z, x, y, 0} + testFunVWext(t, "addVW, random inputs", addVW, addVW_g, arg) + testFunVWext(t, "subVW, random inputs", subVW, subVW_g, arg) + + // vector of random numbers, but make 'x' and 'z' share storage + arg = argVW{x, x, y, 0} + testFunVWext(t, "addVW, random inputs, sharing storage", addVW, addVW_g, arg) + testFunVWext(t, "subVW, random inputs, sharing storage", subVW, subVW_g, arg) + + // vector of maximum uint, to force carry flag set in each 'add' + y = ^Word(0) + x = makeWordVec(y, n) + arg = argVW{z, x, y, 0} + testFunVWext(t, "addVW, vector of max uint", addVW, addVW_g, arg) + + // vector of '0', to force carry flag set in each 'sub' + x = makeWordVec(0, n) + arg = argVW{z, x, 1, 0} + testFunVWext(t, "subVW, vector of zero", subVW, subVW_g, arg) + } +} + type argVU struct { d []Word // d is a Word slice, the input parameters x and z come from this array. l uint // l is the length of the input parameters x and z. @@ -224,13 +285,36 @@ type argVU struct { m string // message. } +var argshlVUIn = []Word{1, 2, 4, 8, 16, 32, 64, 0, 0, 0} +var argshlVUr0 = []Word{1, 2, 4, 8, 16, 32, 64} +var argshlVUr1 = []Word{2, 4, 8, 16, 32, 64, 128} +var argshlVUrWm1 = []Word{1 << (_W - 1), 0, 1, 2, 4, 8, 16} + var argshlVU = []argVU{ // test cases for shlVU {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0}, 7, 0, 0, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "complete overlap of shlVU"}, {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0}, 7, 0, 3, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by half of shlVU"}, {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0}, 7, 0, 6, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "partial overlap by 1 Word of shlVU"}, {[]Word{1, _M, _M, _M, _M, _M, 3 << (_W - 2), 0, 0, 0, 0, 0, 0, 0, 0}, 7, 0, 7, 1, []Word{2, _M - 1, _M, _M, _M, _M, 1<<(_W-1) + 1}, 1, "no overlap of shlVU"}, -} + // additional test cases with shift values of 0, 1 and (_W-1) + {argshlVUIn, 7, 0, 0, 0, argshlVUr0, 0, "complete overlap of shlVU and shift of 0"}, + {argshlVUIn, 7, 0, 0, 1, argshlVUr1, 0, "complete overlap of shlVU and shift of 1"}, + {argshlVUIn, 7, 0, 0, _W - 1, argshlVUrWm1, 32, "complete overlap of shlVU and shift of _W - 1"}, + {argshlVUIn, 7, 0, 1, 0, argshlVUr0, 0, "partial overlap by 6 Words of shlVU and shift of 0"}, + {argshlVUIn, 7, 0, 1, 1, argshlVUr1, 0, "partial overlap by 6 Words of shlVU and shift of 1"}, + {argshlVUIn, 7, 0, 1, _W - 1, argshlVUrWm1, 32, "partial overlap by 6 Words of shlVU and shift of _W - 1"}, + {argshlVUIn, 7, 0, 2, 0, argshlVUr0, 0, "partial overlap by 5 Words of shlVU and shift of 0"}, + {argshlVUIn, 7, 0, 2, 1, argshlVUr1, 0, "partial overlap by 5 Words of shlVU and shift of 1"}, + {argshlVUIn, 7, 0, 2, _W - 1, argshlVUrWm1, 32, "partial overlap by 5 Words of shlVU abd shift of _W - 1"}, + {argshlVUIn, 7, 0, 3, 0, argshlVUr0, 0, "partial overlap by 4 Words of shlVU and shift of 0"}, + {argshlVUIn, 7, 0, 3, 1, argshlVUr1, 0, "partial overlap by 4 Words of shlVU and shift of 1"}, + {argshlVUIn, 7, 0, 3, _W - 1, argshlVUrWm1, 32, "partial overlap by 4 Words of shlVU and shift of _W - 1"}, +} + +var argshrVUIn = []Word{0, 0, 0, 1, 2, 4, 8, 16, 32, 64} +var argshrVUr0 = []Word{1, 2, 4, 8, 16, 32, 64} +var argshrVUr1 = []Word{0, 1, 2, 4, 8, 16, 32} +var argshrVUrWm1 = []Word{4, 8, 16, 32, 64, 128, 0} var argshrVU = []argVU{ // test cases for shrVU @@ -238,23 +322,36 @@ var argshrVU = []argVU{ {[]Word{0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 4, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by half of shrVU"}, {[]Word{0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 7, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "partial overlap by 1 Word of shrVU"}, {[]Word{0, 0, 0, 0, 0, 0, 0, 0, 3, _M, _M, _M, _M, _M, 1 << (_W - 1)}, 7, 8, 1, 1, []Word{1<<(_W-1) + 1, _M, _M, _M, _M, _M >> 1, 1 << (_W - 2)}, 1 << (_W - 1), "no overlap of shrVU"}, + // additional test cases with shift values of 0, 1 and (_W-1) + {argshrVUIn, 7, 3, 3, 0, argshrVUr0, 0, "complete overlap of shrVU and shift of 0"}, + {argshrVUIn, 7, 3, 3, 1, argshrVUr1, 1 << (_W - 1), "complete overlap of shrVU and shift of 1"}, + {argshrVUIn, 7, 3, 3, _W - 1, argshrVUrWm1, 2, "complete overlap of shrVU and shift of _W - 1"}, + {argshrVUIn, 7, 3, 2, 0, argshrVUr0, 0, "partial overlap by 6 Words of shrVU and shift of 0"}, + {argshrVUIn, 7, 3, 2, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 6 Words of shrVU and shift of 1"}, + {argshrVUIn, 7, 3, 2, _W - 1, argshrVUrWm1, 2, "partial overlap by 6 Words of shrVU and shift of _W - 1"}, + {argshrVUIn, 7, 3, 1, 0, argshrVUr0, 0, "partial overlap by 5 Words of shrVU and shift of 0"}, + {argshrVUIn, 7, 3, 1, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 5 Words of shrVU and shift of 1"}, + {argshrVUIn, 7, 3, 1, _W - 1, argshrVUrWm1, 2, "partial overlap by 5 Words of shrVU and shift of _W - 1"}, + {argshrVUIn, 7, 3, 0, 0, argshrVUr0, 0, "partial overlap by 4 Words of shrVU and shift of 0"}, + {argshrVUIn, 7, 3, 0, 1, argshrVUr1, 1 << (_W - 1), "partial overlap by 4 Words of shrVU and shift of 1"}, + {argshrVUIn, 7, 3, 0, _W - 1, argshrVUrWm1, 2, "partial overlap by 4 Words of shrVU and shift of _W - 1"}, } func testShiftFunc(t *testing.T, f func(z, x []Word, s uint) Word, a argVU) { - // save a.d for error message, or it will be overwritten. + // work on copy of a.d to preserve the original data. b := make([]Word, len(a.d)) copy(b, a.d) - z := a.d[a.zp : a.zp+a.l] - x := a.d[a.xp : a.xp+a.l] + z := b[a.zp : a.zp+a.l] + x := b[a.xp : a.xp+a.l] c := f(z, x, a.s) for i, zi := range z { if zi != a.r[i] { - t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i]) + t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot z[%d] = %#x; want %#x", a.d, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, i, zi, a.r[i]) break } } if c != a.c { - t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", b, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c) + t.Errorf("d := %v, %s(d[%d:%d], d[%d:%d], %d)\n\tgot c = %#x; want %#x", a.d, a.m, a.zp, a.zp+a.l, a.xp, a.xp+a.l, a.s, c, a.c) } } @@ -274,11 +371,24 @@ func TestIssue31084(t *testing.T) { // compute 10^n via 5^n << n. const n = 165 p := nat(nil).expNN(nat{5}, nat{n}, nil) - p = p.shl(p, uint(n)) + p = p.shl(p, n) got := string(p.utoa(10)) want := "1" + strings.Repeat("0", n) if got != want { - t.Errorf("shl(%v, %v)\n\tgot %s; want %s\n", p, uint(n), got, want) + t.Errorf("shl(%v, %v)\n\tgot %s\n\twant %s", p, n, got, want) + } +} + +const issue42838Value = "159309191113245227702888039776771180559110455519261878607388585338616290151305816094308987472018268594098344692611135542392730712890625" + +func TestIssue42838(t *testing.T) { + const s = 192 + z, _, _, _ := nat(nil).scan(strings.NewReader(issue42838Value), 0, false) + z = z.shl(z, s) + got := string(z.utoa(10)) + want := "1" + strings.Repeat("0", s) + if got != want { + t.Errorf("shl(%v, %v)\n\tgot %s\n\twant %s", z, s, got, want) } } @@ -299,6 +409,24 @@ func BenchmarkAddVW(b *testing.B) { } } +// Benchmarking addVW using vector of maximum uint to force carry flag set +func BenchmarkAddVWext(b *testing.B) { + for _, n := range benchSizes { + if isRaceBuilder && n > 1e3 { + continue + } + y := ^Word(0) + x := makeWordVec(y, n) + z := make([]Word, n) + b.Run(fmt.Sprint(n), func(b *testing.B) { + b.SetBytes(int64(n * _S)) + for i := 0; i < b.N; i++ { + addVW(z, x, y) + } + }) + } +} + func BenchmarkSubVW(b *testing.B) { for _, n := range benchSizes { if isRaceBuilder && n > 1e3 { @@ -316,6 +444,24 @@ func BenchmarkSubVW(b *testing.B) { } } +// Benchmarking subVW using vector of zero to force carry flag set +func BenchmarkSubVWext(b *testing.B) { + for _, n := range benchSizes { + if isRaceBuilder && n > 1e3 { + continue + } + x := makeWordVec(0, n) + y := Word(1) + z := make([]Word, n) + b.Run(fmt.Sprint(n), func(b *testing.B) { + b.SetBytes(int64(n * _S)) + for i := 0; i < b.N; i++ { + subVW(z, x, y) + } + }) + } +} + type funVWW func(z, x []Word, y, r Word) (c Word) type argVWW struct { z, x nat @@ -397,7 +543,6 @@ func TestFunVWW(t *testing.T) { if a.y != 0 && a.r < a.y { arg := argWVW{a.x, a.c, a.z, a.y, a.r} - testFunWVW(t, "divWVW_g", divWVW_g, arg) testFunWVW(t, "divWVW", divWVW, arg) } } @@ -440,6 +585,42 @@ func TestMulAddWWW(t *testing.T) { } } +var divWWTests = []struct { + x1, x0, y Word + q, r Word +}{ + {_M >> 1, 0, _M, _M >> 1, _M >> 1}, + {_M - (1 << (_W - 2)), _M, 3 << (_W - 2), _M, _M - (1 << (_W - 2))}, +} + +const testsNumber = 1 << 16 + +func TestDivWW(t *testing.T) { + i := 0 + for i, test := range divWWTests { + rec := reciprocalWord(test.y) + q, r := divWW(test.x1, test.x0, test.y, rec) + if q != test.q || r != test.r { + t.Errorf("#%d got (%x, %x) want (%x, %x)", i, q, r, test.q, test.r) + } + } + //random tests + for ; i < testsNumber; i++ { + x1 := rndW() + x0 := rndW() + y := rndW() + if x1 >= y { + continue + } + rec := reciprocalWord(y) + qGot, rGot := divWW(x1, x0, y, rec) + qWant, rWant := bits.Div(uint(x1), uint(x0), uint(y)) + if uint(qGot) != qWant || uint(rGot) != rWant { + t.Errorf("#%d got (%x, %x) want (%x, %x)", i, qGot, rGot, qWant, rWant) + } + } +} + func BenchmarkMulAddVWW(b *testing.B) { for _, n := range benchSizes { if isRaceBuilder && n > 1e3 { @@ -474,3 +655,19 @@ func BenchmarkAddMulVVW(b *testing.B) { }) } } +func BenchmarkDivWVW(b *testing.B) { + for _, n := range benchSizes { + if isRaceBuilder && n > 1e3 { + continue + } + x := rndV(n) + y := rndW() + z := make([]Word, n) + b.Run(fmt.Sprint(n), func(b *testing.B) { + b.SetBytes(int64(n * _W)) + for i := 0; i < b.N; i++ { + divWVW(z, 0, x, y) + } + }) + } +} diff --git a/libgo/go/math/big/decimal.go b/libgo/go/math/big/decimal.go index ae9ffb5db6a..716f03bfa43 100644 --- a/libgo/go/math/big/decimal.go +++ b/libgo/go/math/big/decimal.go @@ -166,18 +166,21 @@ func (x *decimal) String() string { switch { case x.exp <= 0: // 0.00ddd + buf = make([]byte, 0, 2+(-x.exp)+len(x.mant)) buf = append(buf, "0."...) buf = appendZeros(buf, -x.exp) buf = append(buf, x.mant...) case /* 0 < */ x.exp < len(x.mant): // dd.ddd + buf = make([]byte, 0, 1+len(x.mant)) buf = append(buf, x.mant[:x.exp]...) buf = append(buf, '.') buf = append(buf, x.mant[x.exp:]...) default: // len(x.mant) <= x.exp // ddd00 + buf = make([]byte, 0, x.exp) buf = append(buf, x.mant...) buf = appendZeros(buf, x.exp-len(x.mant)) } diff --git a/libgo/go/math/big/float.go b/libgo/go/math/big/float.go index da964eef3e8..42050e2c39d 100644 --- a/libgo/go/math/big/float.go +++ b/libgo/go/math/big/float.go @@ -322,10 +322,11 @@ func (z *Float) SetMantExp(mant *Float, exp int) *Float { mant.validate() } z.Copy(mant) - if z.form != finite { - return z + + if z.form == finite { + // 0 < |mant| < +Inf + z.setExpAndRound(int64(z.exp)+int64(exp), 0) } - z.setExpAndRound(int64(z.exp)+int64(exp), 0) return z } diff --git a/libgo/go/math/big/link_test.go b/libgo/go/math/big/link_test.go index 2212bd444ff..42f9cefca07 100644 --- a/libgo/go/math/big/link_test.go +++ b/libgo/go/math/big/link_test.go @@ -7,7 +7,7 @@ package big import ( "bytes" "internal/testenv" - "io/ioutil" + "os" "os/exec" "path/filepath" "testing" @@ -27,7 +27,7 @@ func TestLinkerGC(t *testing.T) { import _ "math/big" func main() {} `) - if err := ioutil.WriteFile(goFile, file, 0644); err != nil { + if err := os.WriteFile(goFile, file, 0644); err != nil { t.Fatal(err) } cmd := exec.Command(goBin, "build", "-o", "x.exe", "x.go") diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go index 8c43de69d33..068176e1c1a 100644 --- a/libgo/go/math/big/nat.go +++ b/libgo/go/math/big/nat.go @@ -751,6 +751,7 @@ func (q nat) divBasic(u, v nat) { // D2. vn1 := v[n-1] + rec := reciprocalWord(vn1) for j := m; j >= 0; j-- { // D3. qhat := Word(_M) @@ -760,7 +761,7 @@ func (q nat) divBasic(u, v nat) { } if ujn != vn1 { var rhat Word - qhat, rhat = divWW(ujn, u[j+n-1], vn1) + qhat, rhat = divWW(ujn, u[j+n-1], vn1, rec) // x1 | x2 = q̂v_{n-2} vn2 := v[n-2] diff --git a/libgo/go/math/big/nat_test.go b/libgo/go/math/big/nat_test.go index 89e913fc16e..08508189321 100644 --- a/libgo/go/math/big/nat_test.go +++ b/libgo/go/math/big/nat_test.go @@ -804,3 +804,13 @@ func TestIssue37499(t *testing.T) { t.Fatalf("incorrect quotient: %s", s) } } + +// TestIssue42552 triggers an edge case of recursive division +// where the first division loop is never entered, and correcting +// the remainder takes exactly two iterations in the final loop. +func TestIssue42552(t *testing.T) { + u := natFromString("0xc23b166884c3869092a520eceedeced2b00847bd256c9cf3b2c5e2227c15bd5e6ee7ef8a2f49236ad0eedf2c8a3b453cf6e0706f64285c526b372c4b1321245519d430540804a50b7ca8b6f1b34a2ec05cdbc24de7599af112d3e3c8db347e8799fe70f16e43c6566ba3aeb169463a3ecc486172deb2d9b80a3699c776e44fef20036bd946f1b4d054dd88a2c1aeb986199b0b2b7e58c42288824b74934d112fe1fc06e06b4d99fe1c5e725946b23210521e209cd507cce90b5f39a523f27e861f9e232aee50c3f585208b4573dcc0b897b6177f2ba20254fd5c50a033e849dee1b3a93bd2dc44ba8ca836cab2c2ae50e50b126284524fa0187af28628ff0face68d87709200329db1392852c8b8963fbe3d05fb1efe19f0ed5ca9fadc2f96f82187c24bb2512b2e85a66333a7e176605695211e1c8e0b9b9e82813e50654964945b1e1e66a90840396c7d10e23e47f364d2d3f660fa54598e18d1ca2ea4fe4f35a40a11f69f201c80b48eaee3e2e9b0eda63decf92bec08a70f731587d4ed0f218d5929285c8b2ccbc497e20db42de73885191fa453350335990184d8df805072f958d5354debda38f5421effaaafd6cb9b721ace74be0892d77679f62a4a126697cd35797f6858193da4ba1770c06aea2e5c59ec04b8ea26749e61b72ecdde403f3bc7e5e546cd799578cc939fa676dfd5e648576d4a06cbadb028adc2c0b461f145b2321f42e5e0f3b4fb898ecd461df07a6f5154067787bf74b5cc5c03704a1ce47494961931f0263b0aac32505102595957531a2de69dd71aac51f8a49902f81f21283dbe8e21e01e5d82517868826f86acf338d935aa6b4d5a25c8d540389b277dd9d64569d68baf0f71bd03dba45b92a7fc052601d1bd011a2fc6790a23f97c6fa5caeea040ab86841f268d39ce4f7caf01069df78bba098e04366492f0c2ac24f1bf16828752765fa523c9a4d42b71109d123e6be8c7b1ab3ccf8ea03404075fe1a9596f1bba1d267f9a7879ceece514818316c9c0583469d2367831fc42b517ea028a28df7c18d783d16ea2436cee2b15d52db68b5dfdee6b4d26f0905f9b030c911a04d078923a4136afea96eed6874462a482917353264cc9bee298f167ac65a6db4e4eda88044b39cc0b33183843eaa946564a00c3a0ab661f2c915e70bf0bb65bfbb6fa2eea20aed16bf2c1a1d00ec55fb4ff2f76b8e462ea70c19efa579c9ee78194b86708fdae66a9ce6e2cf3d366037798cfb50277ba6d2fd4866361022fd788ab7735b40b8b61d55e32243e06719e53992e9ac16c9c4b6e6933635c3c47c8f7e73e17dd54d0dd8aeba5d76de46894e7b3f9d3ec25ad78ee82297ba69905ea0fa094b8667faa2b8885e2187b3da80268aa1164761d7b0d6de206b676777348152b8ae1d4afed753bc63c739a5ca8ce7afb2b241a226bd9e502baba391b5b13f5054f070b65a9cf3a67063bfaa803ba390732cd03888f664023f888741d04d564e0b5674b0a183ace81452001b3fbb4214c77d42ca75376742c471e58f67307726d56a1032bd236610cbcbcd03d0d7a452900136897dc55bb3ce959d10d4e6a10fb635006bd8c41cd9ded2d3dfdd8f2e229590324a7370cb2124210b2330f4c56155caa09a2564932ceded8d92c79664dcdeb87faad7d3da006cc2ea267ee3df41e9677789cc5a8cc3b83add6491561b3047919e0648b1b2e97d7ad6f6c2aa80cab8e9ae10e1f75b1fdd0246151af709d259a6a0ed0b26bd711024965ecad7c41387de45443defce53f66612948694a6032279131c257119ed876a8e805dfb49576ef5c563574115ee87050d92d191bc761ef51d966918e2ef925639400069e3959d8fe19f36136e947ff430bf74e71da0aa5923b00000000") + v := natFromString("0x838332321d443a3d30373d47301d47073847473a383d3030f25b3d3d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e00000000000000000041603038331c3d32f5303441e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e01c0a5459bfc7b9be9fcbb9d2383840464319434707303030f43a32f53034411c0a5459413820878787878787878787878787878787878787878787878787878787878787878787870630303a3a30334036605b923a6101f83638413943413960204337602043323801526040523241846038414143015238604060328452413841413638523c0240384141364036605b923a6101f83638413943413960204334602043323801526040523241846038414143015238604060328452413841413638523c02403841413638433030f25a8b83838383838383838383838383838383837d838383ffffffffffffffff838383838383838383000000000000000000030000007d26e27c7c8b83838383838383838383838383838383837d838383ffffffffffffffff83838383838383838383838383838383838383838383435960f535073030f3343200000000000000011881301938343030fa398383300000002300000000000000000000f11af4600c845252904141364138383c60406032414443095238010241414303364443434132305b595a15434160b042385341ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff47476043410536613603593a6005411c437405fcfcfcfcfcfcfc0000000000005a3b075815054359000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + q := nat(nil).make(16) + q.div(q, u, v) +} diff --git a/libgo/go/math/bits/make_examples.go b/libgo/go/math/bits/make_examples.go index cd81cd6c4db..1d3ad53fe67 100644 --- a/libgo/go/math/bits/make_examples.go +++ b/libgo/go/math/bits/make_examples.go @@ -11,9 +11,9 @@ package main import ( "bytes" "fmt" - "io/ioutil" "log" "math/bits" + "os" ) const header = `// Copyright 2017 The Go Authors. All rights reserved. @@ -106,7 +106,7 @@ func main() { } } - if err := ioutil.WriteFile("example_test.go", w.Bytes(), 0666); err != nil { + if err := os.WriteFile("example_test.go", w.Bytes(), 0666); err != nil { log.Fatal(err) } } diff --git a/libgo/go/math/bits/make_tables.go b/libgo/go/math/bits/make_tables.go index ff2fe2e385e..b068d5e0e39 100644 --- a/libgo/go/math/bits/make_tables.go +++ b/libgo/go/math/bits/make_tables.go @@ -13,8 +13,8 @@ import ( "fmt" "go/format" "io" - "io/ioutil" "log" + "os" ) var header = []byte(`// Copyright 2017 The Go Authors. All rights reserved. @@ -40,7 +40,7 @@ func main() { log.Fatal(err) } - err = ioutil.WriteFile("bits_tables.go", out, 0666) + err = os.WriteFile("bits_tables.go", out, 0666) if err != nil { log.Fatal(err) } diff --git a/libgo/go/math/log1p.go b/libgo/go/math/log1p.go index c155730aecc..2c68ca96ed7 100644 --- a/libgo/go/math/log1p.go +++ b/libgo/go/math/log1p.go @@ -131,10 +131,7 @@ func log1p(x float64) float64 { return Inf(1) } - absx := x - if absx < 0 { - absx = -absx - } + absx := Abs(x) var f float64 var iu uint64 diff --git a/libgo/go/mime/encodedword_test.go b/libgo/go/mime/encodedword_test.go index 6c54e502adb..2a98794380f 100644 --- a/libgo/go/mime/encodedword_test.go +++ b/libgo/go/mime/encodedword_test.go @@ -7,7 +7,6 @@ package mime import ( "errors" "io" - "io/ioutil" "strings" "testing" ) @@ -182,7 +181,7 @@ func TestCharsetDecoder(t *testing.T) { if charset != test.charsets[i] { t.Errorf("DecodeHeader(%q), got charset %q, want %q", test.src, charset, test.charsets[i]) } - content, err := ioutil.ReadAll(input) + content, err := io.ReadAll(input) if err != nil { t.Errorf("DecodeHeader(%q), error in reader: %v", test.src, err) } diff --git a/libgo/go/mime/example_test.go b/libgo/go/mime/example_test.go index c7d13cdcdb5..8a96873e5dc 100644 --- a/libgo/go/mime/example_test.go +++ b/libgo/go/mime/example_test.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "mime" ) @@ -38,7 +37,7 @@ func ExampleWordDecoder_Decode() { // Fake character set for example. // Real use would integrate with packages such // as code.google.com/p/go-charset - content, err := ioutil.ReadAll(input) + content, err := io.ReadAll(input) if err != nil { return nil, err } @@ -77,7 +76,7 @@ func ExampleWordDecoder_DecodeHeader() { // Fake character set for example. // Real use would integrate with packages such // as code.google.com/p/go-charset - content, err := ioutil.ReadAll(input) + content, err := io.ReadAll(input) if err != nil { return nil, err } @@ -96,3 +95,29 @@ func ExampleWordDecoder_DecodeHeader() { // ¡Hola, señor! // HELLO WORLD! } + +func ExampleFormatMediaType() { + mediatype := "text/html" + params := map[string]string{ + "charset": "utf-8", + } + + result := mime.FormatMediaType(mediatype, params) + + fmt.Println("result:", result) + // Output: + // result: text/html; charset=utf-8 +} + +func ExampleParseMediaType() { + mediatype, params, err := mime.ParseMediaType("text/html; charset=utf-8") + if err != nil { + panic(err) + } + + fmt.Println("type:", mediatype) + fmt.Println("charset:", params["charset"]) + // Output: + // type: text/html + // charset: utf-8 +} diff --git a/libgo/go/mime/multipart/formdata.go b/libgo/go/mime/multipart/formdata.go index 832d0ad6936..fca5f9e15fb 100644 --- a/libgo/go/mime/multipart/formdata.go +++ b/libgo/go/mime/multipart/formdata.go @@ -8,7 +8,7 @@ import ( "bytes" "errors" "io" - "io/ioutil" + "math" "net/textproto" "os" ) @@ -41,6 +41,13 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) { // Reserve an additional 10 MB for non-file parts. maxValueBytes := maxMemory + int64(10<<20) + if maxValueBytes <= 0 { + if maxMemory < 0 { + maxValueBytes = 0 + } else { + maxValueBytes = math.MaxInt64 + } + } for { p, err := r.NextPart() if err == io.EOF { @@ -83,7 +90,7 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) { } if n > maxMemory { // too big, write to disk and flush buffer - file, err := ioutil.TempFile("", "multipart-") + file, err := os.CreateTemp("", "multipart-") if err != nil { return nil, err } diff --git a/libgo/go/mime/multipart/formdata_test.go b/libgo/go/mime/multipart/formdata_test.go index 7d756c8c244..e3a3a3eae8e 100644 --- a/libgo/go/mime/multipart/formdata_test.go +++ b/libgo/go/mime/multipart/formdata_test.go @@ -7,6 +7,7 @@ package multipart import ( "bytes" "io" + "math" "os" "strings" "testing" @@ -52,6 +53,19 @@ func TestReadFormWithNamelessFile(t *testing.T) { } } +// Issue 40430: Handle ReadForm(math.MaxInt64) +func TestReadFormMaxMemoryOverflow(t *testing.T) { + b := strings.NewReader(strings.ReplaceAll(messageWithTextContentType, "\n", "\r\n")) + r := NewReader(b, boundary) + f, err := r.ReadForm(math.MaxInt64) + if err != nil { + t.Fatalf("ReadForm(MaxInt64): %v", err) + } + if f == nil { + t.Fatal("ReadForm(MaxInt64): missing form") + } +} + func TestReadFormWithTextContentType(t *testing.T) { // From https://github.com/golang/go/issues/24041 b := strings.NewReader(strings.ReplaceAll(messageWithTextContentType, "\n", "\r\n")) diff --git a/libgo/go/mime/multipart/multipart.go b/libgo/go/mime/multipart/multipart.go index 1750300fb53..cb8bf393383 100644 --- a/libgo/go/mime/multipart/multipart.go +++ b/libgo/go/mime/multipart/multipart.go @@ -17,7 +17,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" "mime" "mime/quotedprintable" "net/textproto" @@ -278,7 +277,7 @@ func matchAfterPrefix(buf, prefix []byte, readErr error) int { } func (p *Part) Close() error { - io.Copy(ioutil.Discard, p) + io.Copy(io.Discard, p) return nil } diff --git a/libgo/go/mime/multipart/multipart_test.go b/libgo/go/mime/multipart/multipart_test.go index b60c54a2042..741d2304ed4 100644 --- a/libgo/go/mime/multipart/multipart_test.go +++ b/libgo/go/mime/multipart/multipart_test.go @@ -9,7 +9,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "net/textproto" "os" "reflect" @@ -307,7 +306,7 @@ Oh no, premature EOF! if err != nil { t.Fatalf("didn't get a part") } - _, err = io.Copy(ioutil.Discard, part) + _, err = io.Copy(io.Discard, part) if err != io.ErrUnexpectedEOF { t.Fatalf("expected error io.ErrUnexpectedEOF; got %v", err) } @@ -372,7 +371,7 @@ Body 2 if !reflect.DeepEqual(part.Header, hdr) { t.Errorf("Part %d: part.Header = %v, want %v", i, part.Header, hdr) } - data, err := ioutil.ReadAll(part) + data, err := io.ReadAll(part) expectEq(t, body, string(data), fmt.Sprintf("Part %d body", i)) if err != nil { t.Fatalf("Part %d: ReadAll failed: %v", i, err) @@ -530,14 +529,14 @@ func TestNested(t *testing.T) { if err != nil { t.Fatalf("reading text/plain part: %v", err) } - if b, err := ioutil.ReadAll(p); string(b) != "*body*\r\n" || err != nil { + if b, err := io.ReadAll(p); string(b) != "*body*\r\n" || err != nil { t.Fatalf("reading text/plain part: got %q, %v", b, err) } p, err = mr2.NextPart() if err != nil { t.Fatalf("reading text/html part: %v", err) } - if b, err := ioutil.ReadAll(p); string(b) != "body\r\n" || err != nil { + if b, err := io.ReadAll(p); string(b) != "body\r\n" || err != nil { t.Fatalf("reading text/html part: got %q, %v", b, err) } @@ -850,7 +849,7 @@ Cases: t.Errorf("in test %q, NextPart: %v", tt.name, err) continue Cases } - pbody, err := ioutil.ReadAll(p) + pbody, err := io.ReadAll(p) if err != nil { t.Errorf("in test %q, error reading part: %v", tt.name, err) continue Cases @@ -882,7 +881,7 @@ func partsFromReader(r *Reader) ([]headerBody, error) { if err != nil { return nil, fmt.Errorf("NextPart: %v", err) } - pbody, err := ioutil.ReadAll(p) + pbody, err := io.ReadAll(p) if err != nil { return nil, fmt.Errorf("error reading part: %v", err) } diff --git a/libgo/go/mime/multipart/writer_test.go b/libgo/go/mime/multipart/writer_test.go index b89b093fff6..cfc0f09f37f 100644 --- a/libgo/go/mime/multipart/writer_test.go +++ b/libgo/go/mime/multipart/writer_test.go @@ -6,7 +6,7 @@ package multipart import ( "bytes" - "io/ioutil" + "io" "mime" "net/textproto" "strings" @@ -51,7 +51,7 @@ func TestWriter(t *testing.T) { if g, e := part.FormName(), "myfile"; g != e { t.Errorf("part 1: want form name %q, got %q", e, g) } - slurp, err := ioutil.ReadAll(part) + slurp, err := io.ReadAll(part) if err != nil { t.Fatalf("part 1: ReadAll: %v", err) } @@ -66,7 +66,7 @@ func TestWriter(t *testing.T) { if g, e := part.FormName(), "key"; g != e { t.Errorf("part 2: want form name %q, got %q", e, g) } - slurp, err = ioutil.ReadAll(part) + slurp, err = io.ReadAll(part) if err != nil { t.Fatalf("part 2: ReadAll: %v", err) } @@ -134,7 +134,7 @@ func TestWriterBoundaryGoroutines(t *testing.T) { // different goroutines. This was previously broken by // https://codereview.appspot.com/95760043/ and reverted in // https://codereview.appspot.com/117600043/ - w := NewWriter(ioutil.Discard) + w := NewWriter(io.Discard) done := make(chan int) go func() { w.CreateFormField("foo") diff --git a/libgo/go/mime/quotedprintable/example_test.go b/libgo/go/mime/quotedprintable/example_test.go index 5a9ab450a3c..e5a479a3a7f 100644 --- a/libgo/go/mime/quotedprintable/example_test.go +++ b/libgo/go/mime/quotedprintable/example_test.go @@ -6,7 +6,7 @@ package quotedprintable_test import ( "fmt" - "io/ioutil" + "io" "mime/quotedprintable" "os" "strings" @@ -18,7 +18,7 @@ func ExampleNewReader() { `invalid escape: hello`, "Hello, Gophers! This symbol will be unescaped: =3D and this will be written in =\r\none line.", } { - b, err := ioutil.ReadAll(quotedprintable.NewReader(strings.NewReader(s))) + b, err := io.ReadAll(quotedprintable.NewReader(strings.NewReader(s))) fmt.Printf("%s %v\n", b, err) } // Output: diff --git a/libgo/go/mime/quotedprintable/writer_test.go b/libgo/go/mime/quotedprintable/writer_test.go index d494c1e3dc3..42de0f3d6e8 100644 --- a/libgo/go/mime/quotedprintable/writer_test.go +++ b/libgo/go/mime/quotedprintable/writer_test.go @@ -6,7 +6,7 @@ package quotedprintable import ( "bytes" - "io/ioutil" + "io" "strings" "testing" ) @@ -128,7 +128,7 @@ func TestRoundTrip(t *testing.T) { } r := NewReader(buf) - gotBytes, err := ioutil.ReadAll(r) + gotBytes, err := io.ReadAll(r) if err != nil { t.Fatalf("Error while reading from Reader: %v", err) } @@ -151,7 +151,7 @@ var testMsg = []byte("Quoted-Printable (QP) est un format d'encodage de données func BenchmarkWriter(b *testing.B) { for i := 0; i < b.N; i++ { - w := NewWriter(ioutil.Discard) + w := NewWriter(io.Discard) w.Write(testMsg) w.Close() } diff --git a/libgo/go/mime/type_unix.go b/libgo/go/mime/type_unix.go index 5db1b68ee53..6ac056c7e2b 100644 --- a/libgo/go/mime/type_unix.go +++ b/libgo/go/mime/type_unix.go @@ -20,6 +20,7 @@ var typeFiles = []string{ "/etc/mime.types", "/etc/apache2/mime.types", "/etc/apache/mime.types", + "/etc/httpd/conf/mime.types", } func loadMimeFile(filename string) { diff --git a/libgo/go/mime/type_windows.go b/libgo/go/mime/type_windows.go index 97b9aeba7a3..cee9c9db041 100644 --- a/libgo/go/mime/type_windows.go +++ b/libgo/go/mime/type_windows.go @@ -13,7 +13,7 @@ func init() { } func initMimeWindows() { - names, err := registry.CLASSES_ROOT.ReadSubKeyNames(-1) + names, err := registry.CLASSES_ROOT.ReadSubKeyNames() if err != nil { return } diff --git a/libgo/go/net/conf.go b/libgo/go/net/conf.go index d064d9eb991..b0f1b7968ad 100644 --- a/libgo/go/net/conf.go +++ b/libgo/go/net/conf.go @@ -69,7 +69,7 @@ func initConfVal() { // Darwin pops up annoying dialog boxes if programs try to do // their own DNS requests. So always use cgo instead, which // avoids that. - if runtime.GOOS == "darwin" { + if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { confVal.forceCgoLookupHost = true return } @@ -202,11 +202,6 @@ func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrde // illumos defaults to "nis [NOTFOUND=return] files" return fallbackOrder } - if c.goos == "linux" { - // glibc says the default is "dns [!UNAVAIL=return] files" - // https://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html. - return hostLookupDNSFiles - } return hostLookupFilesDNS } if nss.err != nil { diff --git a/libgo/go/net/conf_test.go b/libgo/go/net/conf_test.go index 081a274ccbb..a8e18070f4a 100644 --- a/libgo/go/net/conf_test.go +++ b/libgo/go/net/conf_test.go @@ -7,7 +7,7 @@ package net import ( - "os" + "io/fs" "strings" "testing" ) @@ -26,7 +26,7 @@ var defaultResolvConf = &dnsConfig{ ndots: 1, timeout: 5, attempts: 2, - err: os.ErrNotExist, + err: fs.ErrNotExist, } func TestConfHostLookupOrder(t *testing.T) { @@ -106,7 +106,7 @@ func TestConfHostLookupOrder(t *testing.T) { name: "solaris_no_nsswitch", c: &conf{ goos: "solaris", - nss: &nssConf{err: os.ErrNotExist}, + nss: &nssConf{err: fs.ErrNotExist}, resolv: defaultResolvConf, }, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupCgo}}, @@ -170,16 +170,23 @@ func TestConfHostLookupOrder(t *testing.T) { }, hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}}, }, - // glibc lacking an nsswitch.conf, per - // https://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html { name: "linux_no_nsswitch.conf", c: &conf{ goos: "linux", - nss: &nssConf{err: os.ErrNotExist}, + nss: &nssConf{err: fs.ErrNotExist}, resolv: defaultResolvConf, }, - hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupDNSFiles}}, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}}, + }, + { + name: "linux_empty_nsswitch.conf", + c: &conf{ + goos: "linux", + nss: nssStr(""), + resolv: defaultResolvConf, + }, + hostTests: []nssHostTest{{"google.com", "myhostname", hostLookupFilesDNS}}, }, { name: "files_mdns_dns", diff --git a/libgo/go/net/conn_test.go b/libgo/go/net/conn_test.go index 6854898da2a..771cabcd3cd 100644 --- a/libgo/go/net/conn_test.go +++ b/libgo/go/net/conn_test.go @@ -32,7 +32,7 @@ func TestConnAndListener(t *testing.T) { } defer ls.teardown() ch := make(chan error, 1) - handler := func(ls *localServer, ln Listener) { transponder(ln, ch) } + handler := func(ls *localServer, ln Listener) { ls.transponder(ln, ch) } if err := ls.buildup(handler); err != nil { t.Fatal(err) } diff --git a/libgo/go/net/dial_test.go b/libgo/go/net/dial_test.go index 01582489de1..57cf5554ad2 100644 --- a/libgo/go/net/dial_test.go +++ b/libgo/go/net/dial_test.go @@ -160,7 +160,7 @@ func dialClosedPort(t *testing.T) (actual, expected time.Duration) { // but other platforms should be instantaneous. if runtime.GOOS == "windows" { expected = 1500 * time.Millisecond - } else if runtime.GOOS == "darwin" { + } else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" { expected = 150 * time.Millisecond } else { expected = 95 * time.Millisecond @@ -990,7 +990,7 @@ func TestDialerControl(t *testing.T) { // except that it won't skip testing on non-mobile builders. func mustHaveExternalNetwork(t *testing.T) { t.Helper() - mobile := runtime.GOOS == "android" || runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" + mobile := runtime.GOOS == "android" || runtime.GOOS == "ios" if testenv.Builder() == "" || mobile { testenv.MustHaveExternalNetwork(t) } diff --git a/libgo/go/net/dnsclient.go b/libgo/go/net/dnsclient.go index b5bb3a4d11d..e9c73845d78 100644 --- a/libgo/go/net/dnsclient.go +++ b/libgo/go/net/dnsclient.go @@ -5,12 +5,25 @@ package net import ( - "math/rand" "sort" "golang.org/x/net/dns/dnsmessage" ) +// provided by runtime +func fastrand() uint32 + +func randInt() int { + x, y := fastrand(), fastrand() // 32-bit halves + u := uint(x)<<31 ^ uint(int32(y)) // full uint, even on 64-bit systems; avoid 32-bit shift on 32-bit systems + i := int(u >> 1) // clear sign bit, even on 32-bit systems + return i +} + +func randIntn(n int) int { + return randInt() % n +} + // reverseaddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP // address addr suitable for rDNS (PTR) record lookup or an error if it fails // to parse the IP address. @@ -162,7 +175,7 @@ func (addrs byPriorityWeight) shuffleByWeight() { } for sum > 0 && len(addrs) > 1 { s := 0 - n := rand.Intn(sum) + n := randIntn(sum) for i := range addrs { s += int(addrs[i].Weight) if s > n { @@ -206,7 +219,7 @@ func (s byPref) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // sort reorders MX records as specified in RFC 5321. func (s byPref) sort() { for i := range s { - j := rand.Intn(i + 1) + j := randIntn(i + 1) s[i], s[j] = s[j], s[i] } sort.Sort(s) diff --git a/libgo/go/net/dnsclient_test.go b/libgo/go/net/dnsclient_test.go index f3ed62db36a..24cd69e13be 100644 --- a/libgo/go/net/dnsclient_test.go +++ b/libgo/go/net/dnsclient_test.go @@ -5,7 +5,6 @@ package net import ( - "math/rand" "testing" ) @@ -17,7 +16,7 @@ func checkDistribution(t *testing.T, data []*SRV, margin float64) { results := make(map[string]int) - count := 1000 + count := 10000 for j := 0; j < count; j++ { d := make([]*SRV, len(data)) copy(d, data) @@ -39,7 +38,6 @@ func checkDistribution(t *testing.T, data []*SRV, margin float64) { } func testUniformity(t *testing.T, size int, margin float64) { - rand.Seed(1) data := make([]*SRV, size) for i := 0; i < size; i++ { data[i] = &SRV{Target: string('a' + rune(i)), Weight: 1} @@ -55,7 +53,6 @@ func TestDNSSRVUniformity(t *testing.T) { } func testWeighting(t *testing.T, margin float64) { - rand.Seed(1) data := []*SRV{ {Target: "a", Weight: 60}, {Target: "b", Weight: 30}, diff --git a/libgo/go/net/dnsclient_unix.go b/libgo/go/net/dnsclient_unix.go index 5f6c8706be8..c5bfab92a0f 100644 --- a/libgo/go/net/dnsclient_unix.go +++ b/libgo/go/net/dnsclient_unix.go @@ -18,7 +18,6 @@ import ( "context" "errors" "io" - "math/rand" "os" "sync" "time" @@ -47,7 +46,7 @@ var ( ) func newRequest(q dnsmessage.Question) (id uint16, udpReq, tcpReq []byte, err error) { - id = uint16(rand.Int()) ^ uint16(time.Now().UnixNano()) + id = uint16(randInt()) b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true}) b.EnableCompression() if err := b.StartQuestions(); err != nil { diff --git a/libgo/go/net/dnsclient_unix_test.go b/libgo/go/net/dnsclient_unix_test.go index a89dcccbc58..f57f231d699 100644 --- a/libgo/go/net/dnsclient_unix_test.go +++ b/libgo/go/net/dnsclient_unix_test.go @@ -10,7 +10,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "path" "reflect" @@ -235,7 +234,7 @@ type resolvConfTest struct { } func newResolvConfTest() (*resolvConfTest, error) { - dir, err := ioutil.TempDir("", "go-resolvconftest") + dir, err := os.MkdirTemp("", "go-resolvconftest") if err != nil { return nil, err } diff --git a/libgo/go/net/dnsconfig_unix_test.go b/libgo/go/net/dnsconfig_unix_test.go index 2fca3293501..f6edffcd791 100644 --- a/libgo/go/net/dnsconfig_unix_test.go +++ b/libgo/go/net/dnsconfig_unix_test.go @@ -8,6 +8,7 @@ package net import ( "errors" + "io/fs" "os" "reflect" "strings" @@ -183,7 +184,7 @@ func TestDNSReadMissingFile(t *testing.T) { conf := dnsReadConfig("a-nonexistent-file") if !os.IsNotExist(conf.err) { - t.Errorf("missing resolv.conf:\ngot: %v\nwant: %v", conf.err, os.ErrNotExist) + t.Errorf("missing resolv.conf:\ngot: %v\nwant: %v", conf.err, fs.ErrNotExist) } conf.err = nil want := &dnsConfig{ diff --git a/libgo/go/net/error_test.go b/libgo/go/net/error_test.go index 8d4a7ffb3d0..556eb8c8d47 100644 --- a/libgo/go/net/error_test.go +++ b/libgo/go/net/error_test.go @@ -8,10 +8,11 @@ package net import ( "context" + "errors" "fmt" "internal/poll" "io" - "io/ioutil" + "io/fs" "net/internal/socktest" "os" "runtime" @@ -96,12 +97,12 @@ second: case *os.SyscallError: nestedErr = err.Err goto third - case *os.PathError: // for Plan 9 + case *fs.PathError: // for Plan 9 nestedErr = err.Err goto third } switch nestedErr { - case errCanceled, poll.ErrNetClosing, errMissingAddress, errNoSuitableAddress, + case errCanceled, ErrClosed, errMissingAddress, errNoSuitableAddress, context.DeadlineExceeded, context.Canceled: return nil } @@ -436,7 +437,7 @@ second: goto third } switch nestedErr { - case poll.ErrNetClosing, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded: + case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded: return nil } return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) @@ -478,7 +479,7 @@ second: goto third } switch nestedErr { - case errCanceled, poll.ErrNetClosing, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF: + case errCanceled, ErrClosed, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF: return nil } return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) @@ -508,6 +509,10 @@ func parseCloseError(nestedErr error, isShutdown bool) error { return fmt.Errorf("error string %q does not contain expected string %q", nestedErr, want) } + if !isShutdown && !errors.Is(nestedErr, ErrClosed) { + return fmt.Errorf("errors.Is(%v, errClosed) returns false, want true", nestedErr) + } + switch err := nestedErr.(type) { case *OpError: if err := err.isValid(); err != nil { @@ -526,12 +531,12 @@ second: case *os.SyscallError: nestedErr = err.Err goto third - case *os.PathError: // for Plan 9 + case *fs.PathError: // for Plan 9 nestedErr = err.Err goto third } switch nestedErr { - case poll.ErrNetClosing: + case ErrClosed: return nil } return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) @@ -541,7 +546,7 @@ third: return nil } switch nestedErr { - case os.ErrClosed: // for Plan 9 + case fs.ErrClosed: // for Plan 9 return nil } return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr) @@ -622,12 +627,12 @@ second: case *os.SyscallError: nestedErr = err.Err goto third - case *os.PathError: // for Plan 9 + case *fs.PathError: // for Plan 9 nestedErr = err.Err goto third } switch nestedErr { - case poll.ErrNetClosing, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded: + case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded: return nil } return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) @@ -701,12 +706,12 @@ second: case *os.LinkError: nestedErr = err.Err goto third - case *os.PathError: + case *fs.PathError: nestedErr = err.Err goto third } switch nestedErr { - case poll.ErrNetClosing: + case ErrClosed: return nil } return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr) @@ -724,7 +729,7 @@ func TestFileError(t *testing.T) { t.Skipf("not supported on %s", runtime.GOOS) } - f, err := ioutil.TempFile("", "go-nettest") + f, err := os.CreateTemp("", "go-nettest") if err != nil { t.Fatal(err) } @@ -794,7 +799,7 @@ func parseLookupPortError(nestedErr error) error { switch nestedErr.(type) { case *AddrError, *DNSError: return nil - case *os.PathError: // for Plan 9 + case *fs.PathError: // for Plan 9 return nil } return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr) diff --git a/libgo/go/net/example_test.go b/libgo/go/net/example_test.go index ef8c38f9f4a..72c7183c134 100644 --- a/libgo/go/net/example_test.go +++ b/libgo/go/net/example_test.go @@ -55,6 +55,27 @@ func ExampleDialer() { } } +func ExampleDialer_unix() { + // DialUnix does not take a context.Context parameter. This example shows + // how to dial a Unix socket with a Context. Note that the Context only + // applies to the dial operation; it does not apply to the connection once + // it has been established. + var d net.Dialer + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + d.LocalAddr = nil // if you have a local addr, add it here + raddr := net.UnixAddr{Name: "/path/to/unix.sock", Net: "unix"} + conn, err := d.DialContext(ctx, "unix", raddr.String()) + if err != nil { + log.Fatalf("Failed to dial: %v", err) + } + defer conn.Close() + if _, err := conn.Write([]byte("Hello, socket!")); err != nil { + log.Fatal(err) + } +} + func ExampleIPv4() { fmt.Println(net.IPv4(8, 8, 8, 8)) diff --git a/libgo/go/net/http/alpn_test.go b/libgo/go/net/http/alpn_test.go index 618bdbe54a6..a51038c355a 100644 --- a/libgo/go/net/http/alpn_test.go +++ b/libgo/go/net/http/alpn_test.go @@ -11,7 +11,6 @@ import ( "crypto/x509" "fmt" "io" - "io/ioutil" . "net/http" "net/http/httptest" "strings" @@ -49,7 +48,7 @@ func TestNextProtoUpgrade(t *testing.T) { if err != nil { t.Fatal(err) } - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { t.Fatal(err) } @@ -93,7 +92,7 @@ func TestNextProtoUpgrade(t *testing.T) { t.Fatal(err) } conn.Write([]byte("GET /foo\n")) - body, err := ioutil.ReadAll(conn) + body, err := io.ReadAll(conn) if err != nil { t.Fatal(err) } diff --git a/libgo/go/net/http/cgi/child.go b/libgo/go/net/http/cgi/child.go index 61de6165f61..0114da377b5 100644 --- a/libgo/go/net/http/cgi/child.go +++ b/libgo/go/net/http/cgi/child.go @@ -13,7 +13,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "net/url" @@ -32,7 +31,7 @@ func Request() (*http.Request, error) { return nil, err } if r.ContentLength > 0 { - r.Body = ioutil.NopCloser(io.LimitReader(os.Stdin, r.ContentLength)) + r.Body = io.NopCloser(io.LimitReader(os.Stdin, r.ContentLength)) } return r, nil } @@ -146,6 +145,9 @@ func Serve(handler http.Handler) error { if err != nil { return err } + if req.Body == nil { + req.Body = http.NoBody + } if handler == nil { handler = http.DefaultServeMux } diff --git a/libgo/go/net/http/cgi/child_test.go b/libgo/go/net/http/cgi/child_test.go index f6ecb6eb80f..18cf789bd59 100644 --- a/libgo/go/net/http/cgi/child_test.go +++ b/libgo/go/net/http/cgi/child_test.go @@ -154,17 +154,6 @@ func TestRequestWithoutRemotePort(t *testing.T) { } } -type countingWriter int - -func (c *countingWriter) Write(p []byte) (int, error) { - *c += countingWriter(len(p)) - return len(p), nil -} -func (c *countingWriter) WriteString(p string) (int, error) { - *c += countingWriter(len(p)) - return len(p), nil -} - func TestResponse(t *testing.T) { var tests = []struct { name string diff --git a/libgo/go/net/http/cgi/integration_test.go b/libgo/go/net/http/cgi/integration_test.go index 295c3b82d40..76cbca8e603 100644 --- a/libgo/go/net/http/cgi/integration_test.go +++ b/libgo/go/net/http/cgi/integration_test.go @@ -154,6 +154,23 @@ func TestChildOnlyHeaders(t *testing.T) { } } +// Test that a child handler does not receive a nil Request Body. +// golang.org/issue/39190 +func TestNilRequestBody(t *testing.T) { + testenv.MustHaveExec(t) + + h := &Handler{ + Path: os.Args[0], + Root: "/test.go", + Args: []string{"-test.run=TestBeChildCGIProcess"}, + } + expectedMap := map[string]string{ + "nil-request-body": "false", + } + _ = runCgiTest(t, h, "POST /test.go?nil-request-body=1 HTTP/1.0\nHost: example.com\n\n", expectedMap) + _ = runCgiTest(t, h, "POST /test.go?nil-request-body=1 HTTP/1.0\nHost: example.com\nContent-Length: 0\n\n", expectedMap) +} + func TestChildContentType(t *testing.T) { testenv.MustHaveExec(t) @@ -245,6 +262,10 @@ func TestBeChildCGIProcess(t *testing.T) { os.Exit(0) } Serve(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + if req.FormValue("nil-request-body") == "1" { + fmt.Fprintf(rw, "nil-request-body=%v\n", req.Body == nil) + return + } rw.Header().Set("X-Test-Header", "X-Test-Value") req.ParseForm() if req.FormValue("no-body") == "1" { diff --git a/libgo/go/net/http/client.go b/libgo/go/net/http/client.go index 3860d97d8f4..88e2028bc34 100644 --- a/libgo/go/net/http/client.go +++ b/libgo/go/net/http/client.go @@ -16,7 +16,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "log" "net/url" "reflect" @@ -282,7 +281,7 @@ func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, d if resp.ContentLength > 0 && req.Method != "HEAD" { return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a *Response with content length %d but a nil Body", rt, resp.ContentLength) } - resp.Body = ioutil.NopCloser(strings.NewReader("")) + resp.Body = io.NopCloser(strings.NewReader("")) } if !deadline.IsZero() { resp.Body = &cancelTimerBody{ @@ -321,7 +320,7 @@ func knownRoundTripperImpl(rt RoundTripper, req *Request) bool { return true } // There's a very minor chance of a false positive with this. - // Insted of detecting our golang.org/x/net/http2.Transport, + // Instead 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 @@ -697,7 +696,7 @@ func (c *Client) do(req *Request) (retres *Response, reterr error) { // fails, the Transport won't reuse it anyway. const maxBodySlurpSize = 2 << 10 if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize { - io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize) + io.CopyN(io.Discard, resp.Body, maxBodySlurpSize) } resp.Body.Close() diff --git a/libgo/go/net/http/client_test.go b/libgo/go/net/http/client_test.go index 80807fae7a4..d90b4841c66 100644 --- a/libgo/go/net/http/client_test.go +++ b/libgo/go/net/http/client_test.go @@ -14,7 +14,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "log" "net" . "net/http" @@ -35,7 +34,7 @@ var robotsTxtHandler = HandlerFunc(func(w ResponseWriter, r *Request) { fmt.Fprintf(w, "User-agent: go\nDisallow: /something/") }) -// pedanticReadAll works like ioutil.ReadAll but additionally +// pedanticReadAll works like io.ReadAll but additionally // verifies that r obeys the documented io.Reader contract. func pedanticReadAll(r io.Reader) (b []byte, err error) { var bufa [64]byte @@ -190,7 +189,7 @@ func TestPostFormRequestFormat(t *testing.T) { if g, e := tr.req.ContentLength, int64(len(expectedBody)); g != e { t.Errorf("got ContentLength %d, want %d", g, e) } - bodyb, err := ioutil.ReadAll(tr.req.Body) + bodyb, err := io.ReadAll(tr.req.Body) if err != nil { t.Fatalf("ReadAll on req.Body: %v", err) } @@ -421,7 +420,7 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa var ts *httptest.Server ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { log.Lock() - slurp, _ := ioutil.ReadAll(r.Body) + slurp, _ := io.ReadAll(r.Body) fmt.Fprintf(&log.Buffer, "%s %s %q", r.Method, r.RequestURI, slurp) if cl := r.Header.Get("Content-Length"); r.Method == "GET" && len(slurp) == 0 && (r.ContentLength != 0 || cl != "") { fmt.Fprintf(&log.Buffer, " (but with body=%T, content-length = %v, %q)", r.Body, r.ContentLength, cl) @@ -452,7 +451,7 @@ func testRedirectsByMethod(t *testing.T, method string, table []redirectTest, wa for _, tt := range table { content := tt.redirectBody req, _ := NewRequest(method, ts.URL+tt.suffix, strings.NewReader(content)) - req.GetBody = func() (io.ReadCloser, error) { return ioutil.NopCloser(strings.NewReader(content)), nil } + req.GetBody = func() (io.ReadCloser, error) { return io.NopCloser(strings.NewReader(content)), nil } res, err := c.Do(req) if err != nil { @@ -522,7 +521,7 @@ func TestClientRedirectUseResponse(t *testing.T) { t.Errorf("status = %d; want %d", res.StatusCode, StatusFound) } defer res.Body.Close() - slurp, err := ioutil.ReadAll(res.Body) + slurp, err := io.ReadAll(res.Body) if err != nil { t.Fatal(err) } @@ -1042,7 +1041,7 @@ func testClientHeadContentLength(t *testing.T, h2 bool) { if res.ContentLength != tt.want { t.Errorf("Content-Length = %d; want %d", res.ContentLength, tt.want) } - bs, err := ioutil.ReadAll(res.Body) + bs, err := io.ReadAll(res.Body) if err != nil { t.Fatal(err) } @@ -1257,7 +1256,7 @@ func testClientTimeout(t *testing.T, h2 bool) { errc := make(chan error, 1) go func() { - _, err := ioutil.ReadAll(res.Body) + _, err := io.ReadAll(res.Body) errc <- err res.Body.Close() }() @@ -1348,7 +1347,7 @@ func TestClientTimeoutCancel(t *testing.T) { t.Fatal(err) } cancel() - _, err = io.Copy(ioutil.Discard, res.Body) + _, err = io.Copy(io.Discard, res.Body) if err != ExportErrRequestCanceled { t.Fatalf("error = %v; want errRequestCanceled", err) } @@ -1372,7 +1371,7 @@ func testClientRedirectEatsBody(t *testing.T, h2 bool) { if err != nil { t.Fatal(err) } - _, err = ioutil.ReadAll(res.Body) + _, err = io.ReadAll(res.Body) res.Body.Close() if err != nil { t.Fatal(err) @@ -1450,7 +1449,7 @@ func (issue15577Tripper) RoundTrip(*Request) (*Response, error) { resp := &Response{ StatusCode: 303, Header: map[string][]string{"Location": {"http://www.example.com/"}}, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), } return resp, nil } @@ -1591,7 +1590,7 @@ func TestClientCopyHostOnRedirect(t *testing.T) { if resp.StatusCode != 200 { t.Fatal(resp.Status) } - if got, err := ioutil.ReadAll(resp.Body); err != nil || string(got) != wantBody { + if got, err := io.ReadAll(resp.Body); err != nil || string(got) != wantBody { t.Errorf("body = %q; want %q", got, wantBody) } } @@ -2020,9 +2019,66 @@ func TestClientPopulatesNilResponseBody(t *testing.T) { } }() - if b, err := ioutil.ReadAll(resp.Body); err != nil { + if b, err := io.ReadAll(resp.Body); err != nil { t.Errorf("read error from substitute Response.Body: %v", err) } else if len(b) != 0 { t.Errorf("substitute Response.Body was unexpectedly non-empty: %q", b) } } + +// Issue 40382: Client calls Close multiple times on Request.Body. +func TestClientCallsCloseOnlyOnce(t *testing.T) { + setParallel(t) + defer afterTest(t) + cst := newClientServerTest(t, h1Mode, HandlerFunc(func(w ResponseWriter, r *Request) { + w.WriteHeader(StatusNoContent) + })) + defer cst.close() + + // Issue occurred non-deterministically: needed to occur after a successful + // write (into TCP buffer) but before end of body. + for i := 0; i < 50 && !t.Failed(); i++ { + body := &issue40382Body{t: t, n: 300000} + req, err := NewRequest(MethodPost, cst.ts.URL, body) + if err != nil { + t.Fatal(err) + } + resp, err := cst.tr.RoundTrip(req) + if err != nil { + t.Fatal(err) + } + resp.Body.Close() + } +} + +// issue40382Body is an io.ReadCloser for TestClientCallsCloseOnlyOnce. +// Its Read reads n bytes before returning io.EOF. +// Its Close returns nil but fails the test if called more than once. +type issue40382Body struct { + t *testing.T + n int + closeCallsAtomic int32 +} + +func (b *issue40382Body) Read(p []byte) (int, error) { + switch { + case b.n == 0: + return 0, io.EOF + case b.n < len(p): + p = p[:b.n] + fallthrough + default: + for i := range p { + p[i] = 'x' + } + b.n -= len(p) + return len(p), nil + } +} + +func (b *issue40382Body) Close() error { + if atomic.AddInt32(&b.closeCallsAtomic, 1) == 2 { + b.t.Error("Body closed more than once") + } + return nil +} diff --git a/libgo/go/net/http/clientserver_test.go b/libgo/go/net/http/clientserver_test.go index 70bcd0ec387..42207acc2f5 100644 --- a/libgo/go/net/http/clientserver_test.go +++ b/libgo/go/net/http/clientserver_test.go @@ -15,7 +15,6 @@ import ( "fmt" "hash" "io" - "io/ioutil" "log" "net" . "net/http" @@ -53,7 +52,7 @@ func (t *clientServerTest) getURL(u string) string { t.t.Fatal(err) } defer res.Body.Close() - slurp, err := ioutil.ReadAll(res.Body) + slurp, err := io.ReadAll(res.Body) if err != nil { t.t.Fatal(err) } @@ -152,7 +151,7 @@ func TestChunkedResponseHeaders_h2(t *testing.T) { testChunkedResponseHeaders(t, func testChunkedResponseHeaders(t *testing.T, h2 bool) { defer afterTest(t) - log.SetOutput(ioutil.Discard) // is noisy otherwise + log.SetOutput(io.Discard) // is noisy otherwise defer log.SetOutput(os.Stderr) cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted @@ -266,11 +265,11 @@ func (tt h12Compare) normalizeRes(t *testing.T, res *Response, wantProto string) } else { t.Errorf("got %q response; want %q", res.Proto, wantProto) } - slurp, err := ioutil.ReadAll(res.Body) + slurp, err := io.ReadAll(res.Body) res.Body.Close() res.Body = slurpResult{ - ReadCloser: ioutil.NopCloser(bytes.NewReader(slurp)), + ReadCloser: io.NopCloser(bytes.NewReader(slurp)), body: slurp, err: err, } @@ -477,7 +476,7 @@ func test304Responses(t *testing.T, h2 bool) { if len(res.TransferEncoding) > 0 { t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding) } - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { t.Error(err) } @@ -564,7 +563,7 @@ func testCancelRequestMidBody(t *testing.T, h2 bool) { close(cancel) - rest, err := ioutil.ReadAll(res.Body) + rest, err := io.ReadAll(res.Body) all := string(firstRead) + string(rest) if all != "Hello" { t.Errorf("Read %q (%q + %q); want Hello", all, firstRead, rest) @@ -587,7 +586,7 @@ func testTrailersClientToServer(t *testing.T, h2 bool) { } sort.Strings(decl) - slurp, err := ioutil.ReadAll(r.Body) + slurp, err := io.ReadAll(r.Body) if err != nil { t.Errorf("Server reading request body: %v", err) } @@ -721,7 +720,7 @@ func testResponseBodyReadAfterClose(t *testing.T, h2 bool) { t.Fatal(err) } res.Body.Close() - data, err := ioutil.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) if len(data) != 0 || err == nil { t.Fatalf("ReadAll returned %q, %v; want error", data, err) } @@ -740,7 +739,7 @@ func testConcurrentReadWriteReqBody(t *testing.T, h2 bool) { // Read in one goroutine. go func() { defer wg.Done() - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) if string(data) != reqBody { t.Errorf("Handler read %q; want %q", data, reqBody) } @@ -770,7 +769,7 @@ func testConcurrentReadWriteReqBody(t *testing.T, h2 bool) { if err != nil { t.Fatal(err) } - data, err := ioutil.ReadAll(res.Body) + data, err := io.ReadAll(res.Body) defer res.Body.Close() if err != nil { t.Fatal(err) @@ -887,7 +886,7 @@ func testTransportUserAgent(t *testing.T, h2 bool) { t.Errorf("%d. RoundTrip = %v", i, err) continue } - slurp, err := ioutil.ReadAll(res.Body) + slurp, err := io.ReadAll(res.Body) res.Body.Close() if err != nil { t.Errorf("%d. read body = %v", i, err) @@ -1009,11 +1008,17 @@ func TestTransportDiscardsUnneededConns(t *testing.T) { defer wg.Done() resp, err := c.Get(cst.ts.URL) if err != nil { - t.Errorf("Get: %v", err) - return + // Try to work around spurious connection reset on loaded system. + // See golang.org/issue/33585 and golang.org/issue/36797. + time.Sleep(10 * time.Millisecond) + resp, err = c.Get(cst.ts.URL) + if err != nil { + t.Errorf("Get: %v", err) + return + } } defer resp.Body.Close() - slurp, err := ioutil.ReadAll(resp.Body) + slurp, err := io.ReadAll(resp.Body) if err != nil { t.Error(err) } @@ -1062,7 +1067,7 @@ func testTransportGCRequest(t *testing.T, h2, body bool) { setParallel(t) defer afterTest(t) cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { - ioutil.ReadAll(r.Body) + io.ReadAll(r.Body) if body { io.WriteString(w, "Hello.") } @@ -1078,7 +1083,7 @@ func testTransportGCRequest(t *testing.T, h2, body bool) { if err != nil { t.Fatal(err) } - if _, err := ioutil.ReadAll(res.Body); err != nil { + if _, err := io.ReadAll(res.Body); err != nil { t.Fatal(err) } if err := res.Body.Close(); err != nil { @@ -1139,7 +1144,7 @@ func testTransportRejectsInvalidHeaders(t *testing.T, h2 bool) { res, err := cst.c.Do(req) var body []byte if err == nil { - body, _ = ioutil.ReadAll(res.Body) + body, _ = io.ReadAll(res.Body) res.Body.Close() } var dialed bool @@ -1196,7 +1201,7 @@ func testInterruptWithPanic(t *testing.T, h2 bool, panicValue interface{}) { } gotHeaders <- true defer res.Body.Close() - slurp, err := ioutil.ReadAll(res.Body) + slurp, err := io.ReadAll(res.Body) if string(slurp) != msg { t.Errorf("client read %q; want %q", slurp, msg) } @@ -1361,7 +1366,7 @@ func testServerUndeclaredTrailers(t *testing.T, h2 bool) { if err != nil { t.Fatal(err) } - if _, err := io.Copy(ioutil.Discard, res.Body); err != nil { + if _, err := io.Copy(io.Discard, res.Body); err != nil { t.Fatal(err) } res.Body.Close() @@ -1379,7 +1384,7 @@ func testServerUndeclaredTrailers(t *testing.T, h2 bool) { func TestBadResponseAfterReadingBody(t *testing.T) { defer afterTest(t) cst := newClientServerTest(t, false, HandlerFunc(func(w ResponseWriter, r *Request) { - _, err := io.Copy(ioutil.Discard, r.Body) + _, err := io.Copy(io.Discard, r.Body) if err != nil { t.Fatal(err) } @@ -1472,7 +1477,7 @@ func testWriteHeaderAfterWrite(t *testing.T, h2, hijack bool) { t.Fatal(err) } defer res.Body.Close() - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { t.Fatal(err) } diff --git a/libgo/go/net/http/cookie.go b/libgo/go/net/http/cookie.go index d7a8f5e94e5..141bc947f6e 100644 --- a/libgo/go/net/http/cookie.go +++ b/libgo/go/net/http/cookie.go @@ -220,7 +220,7 @@ func (c *Cookie) String() string { } switch c.SameSite { case SameSiteDefaultMode: - b.WriteString("; SameSite") + // Skip, default mode is obtained by not emitting the attribute. case SameSiteNoneMode: b.WriteString("; SameSite=None") case SameSiteLaxMode: diff --git a/libgo/go/net/http/cookie_test.go b/libgo/go/net/http/cookie_test.go index 9e8196ebce0..959713a0dcf 100644 --- a/libgo/go/net/http/cookie_test.go +++ b/libgo/go/net/http/cookie_test.go @@ -67,7 +67,7 @@ var writeSetCookiesTests = []struct { }, { &Cookie{Name: "cookie-12", Value: "samesite-default", SameSite: SameSiteDefaultMode}, - "cookie-12=samesite-default; SameSite", + "cookie-12=samesite-default", }, { &Cookie{Name: "cookie-13", Value: "samesite-lax", SameSite: SameSiteLaxMode}, @@ -282,6 +282,15 @@ var readSetCookiesTests = []struct { Raw: "samesitedefault=foo; SameSite", }}, }, + { + Header{"Set-Cookie": {"samesiteinvalidisdefault=foo; SameSite=invalid"}}, + []*Cookie{{ + Name: "samesiteinvalidisdefault", + Value: "foo", + SameSite: SameSiteDefaultMode, + Raw: "samesiteinvalidisdefault=foo; SameSite=invalid", + }}, + }, { Header{"Set-Cookie": {"samesitelax=foo; SameSite=Lax"}}, []*Cookie{{ diff --git a/libgo/go/net/http/doc.go b/libgo/go/net/http/doc.go index 7855feaaa99..ae9b708c695 100644 --- a/libgo/go/net/http/doc.go +++ b/libgo/go/net/http/doc.go @@ -21,7 +21,7 @@ The client must close the response body when finished with it: // handle error } defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) // ... For control over HTTP client headers, redirect policy, and other diff --git a/libgo/go/net/http/example_filesystem_test.go b/libgo/go/net/http/example_filesystem_test.go index e1fd42d0494..0e81458a071 100644 --- a/libgo/go/net/http/example_filesystem_test.go +++ b/libgo/go/net/http/example_filesystem_test.go @@ -5,9 +5,9 @@ package http_test import ( + "io/fs" "log" "net/http" - "os" "strings" ) @@ -33,7 +33,7 @@ type dotFileHidingFile struct { // Readdir is a wrapper around the Readdir method of the embedded File // that filters out all files that start with a period in their name. -func (f dotFileHidingFile) Readdir(n int) (fis []os.FileInfo, err error) { +func (f dotFileHidingFile) Readdir(n int) (fis []fs.FileInfo, err error) { files, err := f.File.Readdir(n) for _, file := range files { // Filters out the dot files if !strings.HasPrefix(file.Name(), ".") { @@ -52,12 +52,12 @@ type dotFileHidingFileSystem struct { // Open is a wrapper around the Open method of the embedded FileSystem // that serves a 403 permission error when name has a file or directory // with whose name starts with a period in its path. -func (fs dotFileHidingFileSystem) Open(name string) (http.File, error) { +func (fsys dotFileHidingFileSystem) Open(name string) (http.File, error) { if containsDotFile(name) { // If dot file, return 403 response - return nil, os.ErrPermission + return nil, fs.ErrPermission } - file, err := fs.FileSystem.Open(name) + file, err := fsys.FileSystem.Open(name) if err != nil { return nil, err } @@ -65,7 +65,7 @@ func (fs dotFileHidingFileSystem) Open(name string) (http.File, error) { } func ExampleFileServer_dotFileHiding() { - fs := dotFileHidingFileSystem{http.Dir(".")} - http.Handle("/", http.FileServer(fs)) + fsys := dotFileHidingFileSystem{http.Dir(".")} + http.Handle("/", http.FileServer(fsys)) log.Fatal(http.ListenAndServe(":8080", nil)) } diff --git a/libgo/go/net/http/example_test.go b/libgo/go/net/http/example_test.go index a783b466185..c677d522385 100644 --- a/libgo/go/net/http/example_test.go +++ b/libgo/go/net/http/example_test.go @@ -8,7 +8,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "log" "net/http" "os" @@ -46,7 +45,7 @@ func ExampleGet() { if err != nil { log.Fatal(err) } - robots, err := ioutil.ReadAll(res.Body) + robots, err := io.ReadAll(res.Body) res.Body.Close() if err != nil { log.Fatal(err) diff --git a/libgo/go/net/http/export_test.go b/libgo/go/net/http/export_test.go index 657ff9dba49..096a6d382a8 100644 --- a/libgo/go/net/http/export_test.go +++ b/libgo/go/net/http/export_test.go @@ -254,7 +254,7 @@ func hookSetter(dst *func()) func(func()) { } func ExportHttp2ConfigureTransport(t *Transport) error { - t2, err := http2configureTransport(t) + t2, err := http2configureTransports(t) if err != nil { return err } @@ -274,6 +274,17 @@ func (s *Server) ExportAllConnsIdle() bool { return true } +func (s *Server) ExportAllConnsByState() map[ConnState]int { + states := map[ConnState]int{} + s.mu.Lock() + defer s.mu.Unlock() + for c := range s.activeConn { + st, _ := c.getState() + states[st] += 1 + } + return states +} + func (r *Request) WithT(t *testing.T) *Request { return r.WithContext(context.WithValue(r.Context(), tLogKey{}, t.Logf)) } diff --git a/libgo/go/net/http/fcgi/child.go b/libgo/go/net/http/fcgi/child.go index a31273b3eca..e97b8440e1d 100644 --- a/libgo/go/net/http/fcgi/child.go +++ b/libgo/go/net/http/fcgi/child.go @@ -11,7 +11,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "net/http/cgi" @@ -172,9 +171,12 @@ func (c *child) serve() { defer c.cleanUp() var rec record for { + c.conn.mutex.Lock() if err := rec.read(c.conn.rwc); err != nil { + c.conn.mutex.Unlock() return } + c.conn.mutex.Unlock() if err := c.handleRecord(&rec); err != nil { return } @@ -183,7 +185,7 @@ func (c *child) serve() { var errCloseConn = errors.New("fcgi: connection should be closed") -var emptyBody = ioutil.NopCloser(strings.NewReader("")) +var emptyBody = io.NopCloser(strings.NewReader("")) // ErrRequestAborted is returned by Read when a handler attempts to read the // body of a request that has been aborted by the web server. @@ -322,7 +324,7 @@ func (c *child) serveRequest(req *request, body io.ReadCloser) { // some sort of abort request to the host, so the host // can properly cut off the client sending all the data. // For now just bound it a little and - io.CopyN(ioutil.Discard, body, 100<<20) + io.CopyN(io.Discard, body, 100<<20) body.Close() if !req.keepConn { diff --git a/libgo/go/net/http/fcgi/fcgi_test.go b/libgo/go/net/http/fcgi/fcgi_test.go index 59246c26cc8..d3b704f8219 100644 --- a/libgo/go/net/http/fcgi/fcgi_test.go +++ b/libgo/go/net/http/fcgi/fcgi_test.go @@ -8,7 +8,6 @@ import ( "bytes" "errors" "io" - "io/ioutil" "net/http" "strings" "testing" @@ -243,7 +242,7 @@ func TestChildServeCleansUp(t *testing.T) { r *http.Request, ) { // block on reading body of request - _, err := io.Copy(ioutil.Discard, r.Body) + _, err := io.Copy(io.Discard, r.Body) if err != tt.err { t.Errorf("Expected %#v, got %#v", tt.err, err) } @@ -275,7 +274,7 @@ func TestMalformedParams(t *testing.T) { // end of params 1, 4, 0, 1, 0, 0, 0, 0, } - rw := rwNopCloser{bytes.NewReader(input), ioutil.Discard} + rw := rwNopCloser{bytes.NewReader(input), io.Discard} c := newChild(rw, http.DefaultServeMux) c.serve() } @@ -347,7 +346,6 @@ func TestChildServeReadsEnvVars(t *testing.T) { } func TestResponseWriterSniffsContentType(t *testing.T) { - t.Skip("this test is flaky, see Issue 41167") var tests = []struct { name string body string diff --git a/libgo/go/net/http/filetransport_test.go b/libgo/go/net/http/filetransport_test.go index 2a2f32c7694..b58888dcb14 100644 --- a/libgo/go/net/http/filetransport_test.go +++ b/libgo/go/net/http/filetransport_test.go @@ -5,7 +5,7 @@ package http import ( - "io/ioutil" + "io" "os" "path/filepath" "testing" @@ -23,10 +23,10 @@ func checker(t *testing.T) func(string, error) { func TestFileTransport(t *testing.T) { check := checker(t) - dname, err := ioutil.TempDir("", "") + dname, err := os.MkdirTemp("", "") check("TempDir", err) fname := filepath.Join(dname, "foo.txt") - err = ioutil.WriteFile(fname, []byte("Bar"), 0644) + err = os.WriteFile(fname, []byte("Bar"), 0644) check("WriteFile", err) defer os.Remove(dname) defer os.Remove(fname) @@ -48,7 +48,7 @@ func TestFileTransport(t *testing.T) { if res.Body == nil { t.Fatalf("for %s, nil Body", urlstr) } - slurp, err := ioutil.ReadAll(res.Body) + slurp, err := io.ReadAll(res.Body) res.Body.Close() check("ReadAll "+urlstr, err) if string(slurp) != "Bar" { diff --git a/libgo/go/net/http/fs.go b/libgo/go/net/http/fs.go index 922706ada14..a28ae85958f 100644 --- a/libgo/go/net/http/fs.go +++ b/libgo/go/net/http/fs.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "io" + "io/fs" "mime" "mime/multipart" "net/textproto" @@ -43,7 +44,7 @@ type Dir string // mapDirOpenError maps the provided non-nil error from opening name // to a possibly better non-nil error. In particular, it turns OS-specific errors -// about opening files in non-directories into os.ErrNotExist. See Issue 18984. +// about opening files in non-directories into fs.ErrNotExist. See Issue 18984. func mapDirOpenError(originalErr error, name string) error { if os.IsNotExist(originalErr) || os.IsPermission(originalErr) { return originalErr @@ -59,7 +60,7 @@ func mapDirOpenError(originalErr error, name string) error { return originalErr } if !fi.IsDir() { - return os.ErrNotExist + return fs.ErrNotExist } } return originalErr @@ -86,6 +87,10 @@ func (d Dir) Open(name string) (File, error) { // A FileSystem implements access to a collection of named files. // The elements in a file path are separated by slash ('/', U+002F) // characters, regardless of host operating system convention. +// See the FileServer function to convert a FileSystem to a Handler. +// +// This interface predates the fs.FS interface, which can be used instead: +// the FS adapter function converts an fs.FS to a FileSystem. type FileSystem interface { Open(name string) (File, error) } @@ -98,24 +103,56 @@ type File interface { io.Closer io.Reader io.Seeker - Readdir(count int) ([]os.FileInfo, error) - Stat() (os.FileInfo, error) + Readdir(count int) ([]fs.FileInfo, error) + Stat() (fs.FileInfo, error) +} + +type anyDirs interface { + len() int + name(i int) string + isDir(i int) bool } +type fileInfoDirs []fs.FileInfo + +func (d fileInfoDirs) len() int { return len(d) } +func (d fileInfoDirs) isDir(i int) bool { return d[i].IsDir() } +func (d fileInfoDirs) name(i int) string { return d[i].Name() } + +type dirEntryDirs []fs.DirEntry + +func (d dirEntryDirs) len() int { return len(d) } +func (d dirEntryDirs) isDir(i int) bool { return d[i].IsDir() } +func (d dirEntryDirs) name(i int) string { return d[i].Name() } + func dirList(w ResponseWriter, r *Request, f File) { - dirs, err := f.Readdir(-1) + // Prefer to use ReadDir instead of Readdir, + // because the former doesn't require calling + // Stat on every entry of a directory on Unix. + var dirs anyDirs + var err error + if d, ok := f.(fs.ReadDirFile); ok { + var list dirEntryDirs + list, err = d.ReadDir(-1) + dirs = list + } else { + var list fileInfoDirs + list, err = f.Readdir(-1) + dirs = list + } + if err != nil { logf(r, "http: error reading directory: %v", err) Error(w, "Error reading directory", StatusInternalServerError) return } - sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() }) + sort.Slice(dirs, func(i, j int) bool { return dirs.name(i) < dirs.name(j) }) w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprintf(w, "
\n")
-	for _, d := range dirs {
-		name := d.Name()
-		if d.IsDir() {
+	for i, n := 0, dirs.len(); i < n; i++ {
+		name := dirs.name(i)
+		if dirs.isDir(i) {
 			name += "/"
 		}
 		// name may contain '?' or '#', which must be escaped to remain
@@ -706,17 +743,98 @@ type fileHandler struct {
 	root FileSystem
 }
 
+type ioFS struct {
+	fsys fs.FS
+}
+
+type ioFile struct {
+	file fs.File
+}
+
+func (f ioFS) Open(name string) (File, error) {
+	if name == "/" {
+		name = "."
+	} else {
+		name = strings.TrimPrefix(name, "/")
+	}
+	file, err := f.fsys.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	return ioFile{file}, nil
+}
+
+func (f ioFile) Close() error               { return f.file.Close() }
+func (f ioFile) Read(b []byte) (int, error) { return f.file.Read(b) }
+func (f ioFile) Stat() (fs.FileInfo, error) { return f.file.Stat() }
+
+var errMissingSeek = errors.New("io.File missing Seek method")
+var errMissingReadDir = errors.New("io.File directory missing ReadDir method")
+
+func (f ioFile) Seek(offset int64, whence int) (int64, error) {
+	s, ok := f.file.(io.Seeker)
+	if !ok {
+		return 0, errMissingSeek
+	}
+	return s.Seek(offset, whence)
+}
+
+func (f ioFile) ReadDir(count int) ([]fs.DirEntry, error) {
+	d, ok := f.file.(fs.ReadDirFile)
+	if !ok {
+		return nil, errMissingReadDir
+	}
+	return d.ReadDir(count)
+}
+
+func (f ioFile) Readdir(count int) ([]fs.FileInfo, error) {
+	d, ok := f.file.(fs.ReadDirFile)
+	if !ok {
+		return nil, errMissingReadDir
+	}
+	var list []fs.FileInfo
+	for {
+		dirs, err := d.ReadDir(count - len(list))
+		for _, dir := range dirs {
+			info, err := dir.Info()
+			if err != nil {
+				// Pretend it doesn't exist, like (*os.File).Readdir does.
+				continue
+			}
+			list = append(list, info)
+		}
+		if err != nil {
+			return list, err
+		}
+		if count < 0 || len(list) >= count {
+			break
+		}
+	}
+	return list, nil
+}
+
+// FS converts fsys to a FileSystem implementation,
+// for use with FileServer and NewFileTransport.
+func FS(fsys fs.FS) FileSystem {
+	return ioFS{fsys}
+}
+
 // FileServer returns a handler that serves HTTP requests
 // with the contents of the file system rooted at root.
 //
+// As a special case, the returned file server redirects any request
+// ending in "/index.html" to the same path, without the final
+// "index.html".
+//
 // To use the operating system's file system implementation,
 // use http.Dir:
 //
 //     http.Handle("/", http.FileServer(http.Dir("/tmp")))
 //
-// As a special case, the returned file server redirects any request
-// ending in "/index.html" to the same path, without the final
-// "index.html".
+// To use an fs.FS implementation, use http.FS to convert it:
+//
+//	http.Handle("/", http.FileServer(http.FS(fsys)))
+//
 func FileServer(root FileSystem) Handler {
 	return &fileHandler{root}
 }
@@ -771,9 +889,15 @@ func parseRange(s string, size int64) ([]httpRange, error) {
 		var r httpRange
 		if start == "" {
 			// If no start is specified, end specifies the
-			// range start relative to the end of the file.
+			// range start relative to the end of the file,
+			// and we are dealing with 
+			// which has to be a non-negative integer as per
+			// RFC 7233 Section 2.1 "Byte-Ranges".
+			if end == "" || end[0] == '-' {
+				return nil, errors.New("invalid range")
+			}
 			i, err := strconv.ParseInt(end, 10, 64)
-			if err != nil {
+			if i < 0 || err != nil {
 				return nil, errors.New("invalid range")
 			}
 			if i > size {
diff --git a/libgo/go/net/http/fs_test.go b/libgo/go/net/http/fs_test.go
index c082ceee71b..24990516250 100644
--- a/libgo/go/net/http/fs_test.go
+++ b/libgo/go/net/http/fs_test.go
@@ -10,6 +10,7 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"io/fs"
 	"io/ioutil"
 	"mime"
 	"mime/multipart"
@@ -78,7 +79,7 @@ func TestServeFile(t *testing.T) {
 
 	var err error
 
-	file, err := ioutil.ReadFile(testFile)
+	file, err := os.ReadFile(testFile)
 	if err != nil {
 		t.Fatal("reading file:", err)
 	}
@@ -159,7 +160,7 @@ Cases:
 				if g, w := part.Header.Get("Content-Range"), wantContentRange; g != w {
 					t.Errorf("range=%q: part Content-Range = %q; want %q", rt.r, g, w)
 				}
-				body, err := ioutil.ReadAll(part)
+				body, err := io.ReadAll(part)
 				if err != nil {
 					t.Errorf("range=%q, reading part index %d body: %v", rt.r, ri, err)
 					continue Cases
@@ -311,7 +312,7 @@ func TestFileServerEscapesNames(t *testing.T) {
 		if err != nil {
 			t.Fatalf("test %q: Get: %v", test.name, err)
 		}
-		b, err := ioutil.ReadAll(res.Body)
+		b, err := io.ReadAll(res.Body)
 		if err != nil {
 			t.Fatalf("test %q: read Body: %v", test.name, err)
 		}
@@ -359,7 +360,7 @@ func TestFileServerSortsNames(t *testing.T) {
 	}
 	defer res.Body.Close()
 
-	b, err := ioutil.ReadAll(res.Body)
+	b, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatalf("read Body: %v", err)
 	}
@@ -378,12 +379,12 @@ func mustRemoveAll(dir string) {
 
 func TestFileServerImplicitLeadingSlash(t *testing.T) {
 	defer afterTest(t)
-	tempDir, err := ioutil.TempDir("", "")
+	tempDir, err := os.MkdirTemp("", "")
 	if err != nil {
 		t.Fatalf("TempDir: %v", err)
 	}
 	defer mustRemoveAll(tempDir)
-	if err := ioutil.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil {
+	if err := os.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil {
 		t.Fatalf("WriteFile: %v", err)
 	}
 	ts := httptest.NewServer(StripPrefix("/bar/", FileServer(Dir(tempDir))))
@@ -393,7 +394,7 @@ func TestFileServerImplicitLeadingSlash(t *testing.T) {
 		if err != nil {
 			t.Fatalf("Get %s: %v", suffix, err)
 		}
-		b, err := ioutil.ReadAll(res.Body)
+		b, err := io.ReadAll(res.Body)
 		if err != nil {
 			t.Fatalf("ReadAll %s: %v", suffix, err)
 		}
@@ -570,6 +571,43 @@ func testServeFileWithContentEncoding(t *testing.T, h2 bool) {
 
 func TestServeIndexHtml(t *testing.T) {
 	defer afterTest(t)
+
+	for i := 0; i < 2; i++ {
+		var h Handler
+		var name string
+		switch i {
+		case 0:
+			h = FileServer(Dir("."))
+			name = "Dir"
+		case 1:
+			h = FileServer(FS(os.DirFS(".")))
+			name = "DirFS"
+		}
+		t.Run(name, func(t *testing.T) {
+			const want = "index.html says hello\n"
+			ts := httptest.NewServer(h)
+			defer ts.Close()
+
+			for _, path := range []string{"/testdata/", "/testdata/index.html"} {
+				res, err := Get(ts.URL + path)
+				if err != nil {
+					t.Fatal(err)
+				}
+				b, err := ioutil.ReadAll(res.Body)
+				if err != nil {
+					t.Fatal("reading Body:", err)
+				}
+				if s := string(b); s != want {
+					t.Errorf("for path %q got %q, want %q", path, s, want)
+				}
+				res.Body.Close()
+			}
+		})
+	}
+}
+
+func TestServeIndexHtmlFS(t *testing.T) {
+	defer afterTest(t)
 	const want = "index.html says hello\n"
 	ts := httptest.NewServer(FileServer(Dir(".")))
 	defer ts.Close()
@@ -579,7 +617,7 @@ func TestServeIndexHtml(t *testing.T) {
 		if err != nil {
 			t.Fatal(err)
 		}
-		b, err := ioutil.ReadAll(res.Body)
+		b, err := io.ReadAll(res.Body)
 		if err != nil {
 			t.Fatal("reading Body:", err)
 		}
@@ -629,9 +667,9 @@ func (f *fakeFileInfo) Sys() interface{}   { return nil }
 func (f *fakeFileInfo) ModTime() time.Time { return f.modtime }
 func (f *fakeFileInfo) IsDir() bool        { return f.dir }
 func (f *fakeFileInfo) Size() int64        { return int64(len(f.contents)) }
-func (f *fakeFileInfo) Mode() os.FileMode {
+func (f *fakeFileInfo) Mode() fs.FileMode {
 	if f.dir {
-		return 0755 | os.ModeDir
+		return 0755 | fs.ModeDir
 	}
 	return 0644
 }
@@ -644,12 +682,12 @@ type fakeFile struct {
 }
 
 func (f *fakeFile) Close() error               { return nil }
-func (f *fakeFile) Stat() (os.FileInfo, error) { return f.fi, nil }
-func (f *fakeFile) Readdir(count int) ([]os.FileInfo, error) {
+func (f *fakeFile) Stat() (fs.FileInfo, error) { return f.fi, nil }
+func (f *fakeFile) Readdir(count int) ([]fs.FileInfo, error) {
 	if !f.fi.dir {
-		return nil, os.ErrInvalid
+		return nil, fs.ErrInvalid
 	}
-	var fis []os.FileInfo
+	var fis []fs.FileInfo
 
 	limit := f.entpos + count
 	if count <= 0 || limit > len(f.fi.ents) {
@@ -668,11 +706,11 @@ func (f *fakeFile) Readdir(count int) ([]os.FileInfo, error) {
 
 type fakeFS map[string]*fakeFileInfo
 
-func (fs fakeFS) Open(name string) (File, error) {
+func (fsys fakeFS) Open(name string) (File, error) {
 	name = path.Clean(name)
-	f, ok := fs[name]
+	f, ok := fsys[name]
 	if !ok {
-		return nil, os.ErrNotExist
+		return nil, fs.ErrNotExist
 	}
 	if f.err != nil {
 		return nil, f.err
@@ -707,7 +745,7 @@ func TestDirectoryIfNotModified(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	b, err := ioutil.ReadAll(res.Body)
+	b, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -747,7 +785,7 @@ func TestDirectoryIfNotModified(t *testing.T) {
 	res.Body.Close()
 }
 
-func mustStat(t *testing.T, fileName string) os.FileInfo {
+func mustStat(t *testing.T, fileName string) fs.FileInfo {
 	fi, err := os.Stat(fileName)
 	if err != nil {
 		t.Fatal(err)
@@ -1044,7 +1082,7 @@ func TestServeContent(t *testing.T) {
 			if err != nil {
 				t.Fatal(err)
 			}
-			io.Copy(ioutil.Discard, res.Body)
+			io.Copy(io.Discard, res.Body)
 			res.Body.Close()
 			if res.StatusCode != tt.wantStatus {
 				t.Errorf("test %q using %q: got status = %d; want %d", testName, method, res.StatusCode, tt.wantStatus)
@@ -1081,7 +1119,7 @@ func (issue12991FS) Open(string) (File, error) { return issue12991File{}, nil }
 
 type issue12991File struct{ File }
 
-func (issue12991File) Stat() (os.FileInfo, error) { return nil, os.ErrPermission }
+func (issue12991File) Stat() (fs.FileInfo, error) { return nil, fs.ErrPermission }
 func (issue12991File) Close() error               { return nil }
 
 func TestServeContentErrorMessages(t *testing.T) {
@@ -1091,7 +1129,7 @@ func TestServeContentErrorMessages(t *testing.T) {
 			err: errors.New("random error"),
 		},
 		"/403": &fakeFileInfo{
-			err: &os.PathError{Err: os.ErrPermission},
+			err: &fs.PathError{Err: fs.ErrPermission},
 		},
 	}
 	ts := httptest.NewServer(FileServer(fs))
@@ -1136,6 +1174,14 @@ func TestLinuxSendfile(t *testing.T) {
 		t.Skipf("skipping; failed to run strace: %v", err)
 	}
 
+	filename := fmt.Sprintf("1kb-%d", os.Getpid())
+	filepath := path.Join(os.TempDir(), filename)
+
+	if err := os.WriteFile(filepath, bytes.Repeat([]byte{'a'}, 1<<10), 0755); err != nil {
+		t.Fatal(err)
+	}
+	defer os.Remove(filepath)
+
 	var buf bytes.Buffer
 	child := exec.Command("strace", "-f", "-q", os.Args[0], "-test.run=TestLinuxSendfileChild")
 	child.ExtraFiles = append(child.ExtraFiles, lnf)
@@ -1146,11 +1192,11 @@ func TestLinuxSendfile(t *testing.T) {
 		t.Skipf("skipping; failed to start straced child: %v", err)
 	}
 
-	res, err := Get(fmt.Sprintf("http://%s/", ln.Addr()))
+	res, err := Get(fmt.Sprintf("http://%s/%s", ln.Addr(), filename))
 	if err != nil {
 		t.Fatalf("http client error: %v", err)
 	}
-	_, err = io.Copy(ioutil.Discard, res.Body)
+	_, err = io.Copy(io.Discard, res.Body)
 	if err != nil {
 		t.Fatalf("client body read error: %v", err)
 	}
@@ -1172,7 +1218,7 @@ func getBody(t *testing.T, testName string, req Request, client *Client) (*Respo
 	if err != nil {
 		t.Fatalf("%s: for URL %q, send error: %v", testName, req.URL.String(), err)
 	}
-	b, err := ioutil.ReadAll(r.Body)
+	b, err := io.ReadAll(r.Body)
 	if err != nil {
 		t.Fatalf("%s: for URL %q, reading body: %v", testName, req.URL.String(), err)
 	}
@@ -1192,7 +1238,7 @@ func TestLinuxSendfileChild(*testing.T) {
 		panic(err)
 	}
 	mux := NewServeMux()
-	mux.Handle("/", FileServer(Dir("testdata")))
+	mux.Handle("/", FileServer(Dir(os.TempDir())))
 	mux.HandleFunc("/quit", func(ResponseWriter, *Request) {
 		os.Exit(0)
 	})
@@ -1281,7 +1327,7 @@ func (d fileServerCleanPathDir) Open(path string) (File, error) {
 		// Just return back something that's a directory.
 		return Dir(".").Open(".")
 	}
-	return nil, os.ErrNotExist
+	return nil, fs.ErrNotExist
 }
 
 type panicOnSeek struct{ io.ReadSeeker }
@@ -1308,3 +1354,61 @@ func Test_scanETag(t *testing.T) {
 		}
 	}
 }
+
+// Issue 40940: Ensure that we only accept non-negative suffix-lengths
+// in "Range": "bytes=-N", and should reject "bytes=--2".
+func TestServeFileRejectsInvalidSuffixLengths_h1(t *testing.T) {
+	testServeFileRejectsInvalidSuffixLengths(t, h1Mode)
+}
+func TestServeFileRejectsInvalidSuffixLengths_h2(t *testing.T) {
+	testServeFileRejectsInvalidSuffixLengths(t, h2Mode)
+}
+
+func testServeFileRejectsInvalidSuffixLengths(t *testing.T, h2 bool) {
+	defer afterTest(t)
+	cst := httptest.NewUnstartedServer(FileServer(Dir("testdata")))
+	cst.EnableHTTP2 = h2
+	cst.StartTLS()
+	defer cst.Close()
+
+	tests := []struct {
+		r        string
+		wantCode int
+		wantBody string
+	}{
+		{"bytes=--6", 416, "invalid range\n"},
+		{"bytes=--0", 416, "invalid range\n"},
+		{"bytes=---0", 416, "invalid range\n"},
+		{"bytes=-6", 206, "hello\n"},
+		{"bytes=6-", 206, "html says hello\n"},
+		{"bytes=-6-", 416, "invalid range\n"},
+		{"bytes=-0", 206, ""},
+		{"bytes=", 200, "index.html says hello\n"},
+	}
+
+	for _, tt := range tests {
+		tt := tt
+		t.Run(tt.r, func(t *testing.T) {
+			req, err := NewRequest("GET", cst.URL+"/index.html", nil)
+			if err != nil {
+				t.Fatal(err)
+			}
+			req.Header.Set("Range", tt.r)
+			res, err := cst.Client().Do(req)
+			if err != nil {
+				t.Fatal(err)
+			}
+			if g, w := res.StatusCode, tt.wantCode; g != w {
+				t.Errorf("StatusCode mismatch: got %d want %d", g, w)
+			}
+			slurp, err := io.ReadAll(res.Body)
+			res.Body.Close()
+			if err != nil {
+				t.Fatal(err)
+			}
+			if g, w := string(slurp), tt.wantBody; g != w {
+				t.Fatalf("Content mismatch:\nGot:  %q\nWant: %q", g, w)
+			}
+		})
+	}
+}
diff --git a/libgo/go/net/http/h2_bundle.go b/libgo/go/net/http/h2_bundle.go
index 71592e97675..e13c6619db7 100644
--- a/libgo/go/net/http/h2_bundle.go
+++ b/libgo/go/net/http/h2_bundle.go
@@ -5592,7 +5592,11 @@ func (sc *http2serverConn) newWriterAndRequest(st *http2stream, f *http2MetaHead
 	}
 	if bodyOpen {
 		if vv, ok := rp.header["Content-Length"]; ok {
-			req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64)
+			if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
+				req.ContentLength = int64(cl)
+			} else {
+				req.ContentLength = 0
+			}
 		} else {
 			req.ContentLength = -1
 		}
@@ -5630,7 +5634,7 @@ func (sc *http2serverConn) newWriterAndRequestNoBody(st *http2stream, rp http2re
 	var trailer Header
 	for _, v := range rp.header["Trailer"] {
 		for _, key := range strings.Split(v, ",") {
-			key = CanonicalHeaderKey(strings.TrimSpace(key))
+			key = CanonicalHeaderKey(textproto.TrimString(key))
 			switch key {
 			case "Transfer-Encoding", "Trailer", "Content-Length":
 				// Bogus. (copy of http1 rules)
@@ -5975,9 +5979,8 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
 		var ctype, clen string
 		if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
 			rws.snapHeader.Del("Content-Length")
-			clen64, err := strconv.ParseInt(clen, 10, 64)
-			if err == nil && clen64 >= 0 {
-				rws.sentContentLen = clen64
+			if cl, err := strconv.ParseUint(clen, 10, 63); err == nil {
+				rws.sentContentLen = int64(cl)
 			} else {
 				clen = ""
 			}
@@ -6607,6 +6610,19 @@ type http2Transport struct {
 	// waiting for their turn.
 	StrictMaxConcurrentStreams bool
 
+	// ReadIdleTimeout is the timeout after which a health check using ping
+	// frame will be carried out if no frame is received on the connection.
+	// Note that a ping response will is considered a received frame, so if
+	// there is no other traffic on the connection, the health check will
+	// be performed every ReadIdleTimeout interval.
+	// If zero, no health check is performed.
+	ReadIdleTimeout time.Duration
+
+	// PingTimeout is the timeout after which the connection will be closed
+	// if a response to Ping is not received.
+	// Defaults to 15s.
+	PingTimeout time.Duration
+
 	// t1, if non-nil, is the standard library Transport using
 	// this transport. Its settings are used (but not its
 	// RoundTrip method, etc).
@@ -6630,14 +6646,31 @@ func (t *http2Transport) disableCompression() bool {
 	return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
 }
 
+func (t *http2Transport) pingTimeout() time.Duration {
+	if t.PingTimeout == 0 {
+		return 15 * time.Second
+	}
+	return t.PingTimeout
+
+}
+
 // ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
 // It returns an error if t1 has already been HTTP/2-enabled.
+//
+// Use ConfigureTransports instead to configure the HTTP/2 Transport.
 func http2ConfigureTransport(t1 *Transport) error {
-	_, err := http2configureTransport(t1)
+	_, err := http2ConfigureTransports(t1)
 	return err
 }
 
-func http2configureTransport(t1 *Transport) (*http2Transport, error) {
+// ConfigureTransports configures a net/http HTTP/1 Transport to use HTTP/2.
+// It returns a new HTTP/2 Transport for further configuration.
+// It returns an error if t1 has already been HTTP/2-enabled.
+func http2ConfigureTransports(t1 *Transport) (*http2Transport, error) {
+	return http2configureTransports(t1)
+}
+
+func http2configureTransports(t1 *Transport) (*http2Transport, error) {
 	connPool := new(http2clientConnPool)
 	t2 := &http2Transport{
 		ConnPool: http2noDialClientConnPool{connPool},
@@ -7176,6 +7209,20 @@ func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2Client
 	return cc, nil
 }
 
+func (cc *http2ClientConn) healthCheck() {
+	pingTimeout := cc.t.pingTimeout()
+	// We don't need to periodically ping in the health check, because the readLoop of ClientConn will
+	// trigger the healthCheck again if there is no frame received.
+	ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
+	defer cancel()
+	err := cc.Ping(ctx)
+	if err != nil {
+		cc.closeForLostPing()
+		cc.t.connPool().MarkDead(cc)
+		return
+	}
+}
+
 func (cc *http2ClientConn) setGoAway(f *http2GoAwayFrame) {
 	cc.mu.Lock()
 	defer cc.mu.Unlock()
@@ -7347,14 +7394,12 @@ func (cc *http2ClientConn) sendGoAway() error {
 	return nil
 }
 
-// Close closes the client connection immediately.
-//
-// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
-func (cc *http2ClientConn) Close() error {
+// closes the client connection immediately. In-flight requests are interrupted.
+// err is sent to streams.
+func (cc *http2ClientConn) closeForError(err error) error {
 	cc.mu.Lock()
 	defer cc.cond.Broadcast()
 	defer cc.mu.Unlock()
-	err := errors.New("http2: client connection force closed via ClientConn.Close")
 	for id, cs := range cc.streams {
 		select {
 		case cs.resc <- http2resAndError{err: err}:
@@ -7367,6 +7412,20 @@ func (cc *http2ClientConn) Close() error {
 	return cc.tconn.Close()
 }
 
+// Close closes the client connection immediately.
+//
+// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
+func (cc *http2ClientConn) Close() error {
+	err := errors.New("http2: client connection force closed via ClientConn.Close")
+	return cc.closeForError(err)
+}
+
+// closes the client connection immediately. In-flight requests are interrupted.
+func (cc *http2ClientConn) closeForLostPing() error {
+	err := errors.New("http2: client connection lost")
+	return cc.closeForError(err)
+}
+
 const http2maxAllocFrameSize = 512 << 10
 
 // frameBuffer returns a scratch buffer suitable for writing DATA frames.
@@ -7592,6 +7651,9 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
 			// we can keep it.
 			bodyWriter.cancel()
 			cs.abortRequestBodyWrite(http2errStopReqBodyWrite)
+			if hasBody && !bodyWritten {
+				<-bodyWriter.resc
+			}
 		}
 		if re.err != nil {
 			cc.forgetStreamID(cs.ID)
@@ -7612,6 +7674,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
 			} else {
 				bodyWriter.cancel()
 				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
+				<-bodyWriter.resc
 			}
 			cc.forgetStreamID(cs.ID)
 			return nil, cs.getStartedWrite(), http2errTimeout
@@ -7626,6 +7689,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
 			} else {
 				bodyWriter.cancel()
 				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
+				<-bodyWriter.resc
 			}
 			cc.forgetStreamID(cs.ID)
 			return nil, cs.getStartedWrite(), ctx.Err()
@@ -7640,6 +7704,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
 			} else {
 				bodyWriter.cancel()
 				cs.abortRequestBodyWrite(http2errStopReqBodyWriteAndCancel)
+				<-bodyWriter.resc
 			}
 			cc.forgetStreamID(cs.ID)
 			return nil, cs.getStartedWrite(), http2errRequestCanceled
@@ -7654,6 +7719,7 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
 			// forgetStreamID.
 			return nil, cs.getStartedWrite(), cs.resetErr
 		case err := <-bodyWriter.resc:
+			bodyWritten = true
 			// Prefer the read loop's response, if available. Issue 16102.
 			select {
 			case re := <-readLoopResCh:
@@ -7664,7 +7730,6 @@ func (cc *http2ClientConn) roundTrip(req *Request) (res *Response, gotErrAfterRe
 				cc.forgetStreamID(cs.ID)
 				return nil, cs.getStartedWrite(), err
 			}
-			bodyWritten = true
 			if d := cc.responseHeaderTimeout(); d != 0 {
 				timer := time.NewTimer(d)
 				defer timer.Stop()
@@ -8262,8 +8327,17 @@ func (rl *http2clientConnReadLoop) run() error {
 	rl.closeWhenIdle = cc.t.disableKeepAlives() || cc.singleUse
 	gotReply := false // ever saw a HEADERS reply
 	gotSettings := false
+	readIdleTimeout := cc.t.ReadIdleTimeout
+	var t *time.Timer
+	if readIdleTimeout != 0 {
+		t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
+		defer t.Stop()
+	}
 	for {
 		f, err := cc.fr.ReadFrame()
+		if t != nil {
+			t.Reset(readIdleTimeout)
+		}
 		if err != nil {
 			cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
 		}
@@ -8475,8 +8549,8 @@ func (rl *http2clientConnReadLoop) handleResponse(cs *http2clientStream, f *http
 	if !streamEnded || isHead {
 		res.ContentLength = -1
 		if clens := res.Header["Content-Length"]; len(clens) == 1 {
-			if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil {
-				res.ContentLength = clen64
+			if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {
+				res.ContentLength = int64(cl)
 			} else {
 				// TODO: care? unlike http/1, it won't mess up our framing, so it's
 				// more safe smuggling-wise to ignore.
@@ -8994,6 +9068,8 @@ func http2strSliceContains(ss []string, s string) bool {
 
 type http2erringRoundTripper struct{ err error }
 
+func (rt http2erringRoundTripper) RoundTripErr() error { return rt.err }
+
 func (rt http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { return nil, rt.err }
 
 // gzipReader wraps a response body so it can lazily
@@ -9075,7 +9151,9 @@ func (t *http2Transport) getBodyWriterState(cs *http2clientStream, body io.Reade
 
 func (s http2bodyWriterState) cancel() {
 	if s.timer != nil {
-		s.timer.Stop()
+		if s.timer.Stop() {
+			s.resc <- nil
+		}
 	}
 }
 
diff --git a/libgo/go/net/http/http_test.go b/libgo/go/net/http/http_test.go
index f4ea52db3bc..3f1d7cee710 100644
--- a/libgo/go/net/http/http_test.go
+++ b/libgo/go/net/http/http_test.go
@@ -13,13 +13,8 @@ import (
 	"os/exec"
 	"reflect"
 	"testing"
-	"time"
 )
 
-func init() {
-	shutdownPollInterval = 5 * time.Millisecond
-}
-
 func TestForeachHeaderElement(t *testing.T) {
 	tests := []struct {
 		in   string
@@ -91,7 +86,7 @@ func TestCmdGoNoHTTPServer(t *testing.T) {
 	}
 	wantSym := map[string]bool{
 		// Verify these exist: (sanity checking this test)
-		"net/http.(*Client).Get":          true,
+		"net/http.(*Client).do":           true,
 		"net/http.(*Transport).RoundTrip": true,
 
 		// Verify these don't exist:
diff --git a/libgo/go/net/http/httptest/example_test.go b/libgo/go/net/http/httptest/example_test.go
index 54e77dbb84c..a6738432ebf 100644
--- a/libgo/go/net/http/httptest/example_test.go
+++ b/libgo/go/net/http/httptest/example_test.go
@@ -7,7 +7,6 @@ package httptest_test
 import (
 	"fmt"
 	"io"
-	"io/ioutil"
 	"log"
 	"net/http"
 	"net/http/httptest"
@@ -23,7 +22,7 @@ func ExampleResponseRecorder() {
 	handler(w, req)
 
 	resp := w.Result()
-	body, _ := ioutil.ReadAll(resp.Body)
+	body, _ := io.ReadAll(resp.Body)
 
 	fmt.Println(resp.StatusCode)
 	fmt.Println(resp.Header.Get("Content-Type"))
@@ -45,7 +44,7 @@ func ExampleServer() {
 	if err != nil {
 		log.Fatal(err)
 	}
-	greeting, err := ioutil.ReadAll(res.Body)
+	greeting, err := io.ReadAll(res.Body)
 	res.Body.Close()
 	if err != nil {
 		log.Fatal(err)
@@ -67,7 +66,7 @@ func ExampleServer_hTTP2() {
 	if err != nil {
 		log.Fatal(err)
 	}
-	greeting, err := ioutil.ReadAll(res.Body)
+	greeting, err := io.ReadAll(res.Body)
 	res.Body.Close()
 	if err != nil {
 		log.Fatal(err)
@@ -89,7 +88,7 @@ func ExampleNewTLSServer() {
 		log.Fatal(err)
 	}
 
-	greeting, err := ioutil.ReadAll(res.Body)
+	greeting, err := io.ReadAll(res.Body)
 	res.Body.Close()
 	if err != nil {
 		log.Fatal(err)
diff --git a/libgo/go/net/http/httptest/httptest.go b/libgo/go/net/http/httptest/httptest.go
index f7202da92ff..9bedefd2bc0 100644
--- a/libgo/go/net/http/httptest/httptest.go
+++ b/libgo/go/net/http/httptest/httptest.go
@@ -10,7 +10,6 @@ import (
 	"bytes"
 	"crypto/tls"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"strings"
 )
@@ -66,7 +65,7 @@ func NewRequest(method, target string, body io.Reader) *http.Request {
 		if rc, ok := body.(io.ReadCloser); ok {
 			req.Body = rc
 		} else {
-			req.Body = ioutil.NopCloser(body)
+			req.Body = io.NopCloser(body)
 		}
 	}
 
diff --git a/libgo/go/net/http/httptest/httptest_test.go b/libgo/go/net/http/httptest/httptest_test.go
index ef7d9438377..071add67ea6 100644
--- a/libgo/go/net/http/httptest/httptest_test.go
+++ b/libgo/go/net/http/httptest/httptest_test.go
@@ -7,7 +7,6 @@ package httptest
 import (
 	"crypto/tls"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/url"
 	"reflect"
@@ -155,7 +154,7 @@ func TestNewRequest(t *testing.T) {
 	} {
 		t.Run(tt.name, func(t *testing.T) {
 			got := NewRequest(tt.method, tt.uri, tt.body)
-			slurp, err := ioutil.ReadAll(got.Body)
+			slurp, err := io.ReadAll(got.Body)
 			if err != nil {
 				t.Errorf("ReadAll: %v", err)
 			}
diff --git a/libgo/go/net/http/httptest/recorder.go b/libgo/go/net/http/httptest/recorder.go
index 66e67e78b30..24284826122 100644
--- a/libgo/go/net/http/httptest/recorder.go
+++ b/libgo/go/net/http/httptest/recorder.go
@@ -7,7 +7,7 @@ package httptest
 import (
 	"bytes"
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/textproto"
 	"strconv"
@@ -179,7 +179,7 @@ func (rw *ResponseRecorder) Result() *http.Response {
 	}
 	res.Status = fmt.Sprintf("%03d %s", res.StatusCode, http.StatusText(res.StatusCode))
 	if rw.Body != nil {
-		res.Body = ioutil.NopCloser(bytes.NewReader(rw.Body.Bytes()))
+		res.Body = io.NopCloser(bytes.NewReader(rw.Body.Bytes()))
 	} else {
 		res.Body = http.NoBody
 	}
diff --git a/libgo/go/net/http/httptest/recorder_test.go b/libgo/go/net/http/httptest/recorder_test.go
index e9534894b6c..a865e878b9b 100644
--- a/libgo/go/net/http/httptest/recorder_test.go
+++ b/libgo/go/net/http/httptest/recorder_test.go
@@ -7,7 +7,6 @@ package httptest
 import (
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"testing"
 )
@@ -42,7 +41,7 @@ func TestRecorder(t *testing.T) {
 	}
 	hasResultContents := func(want string) checkFunc {
 		return func(rec *ResponseRecorder) error {
-			contentBytes, err := ioutil.ReadAll(rec.Result().Body)
+			contentBytes, err := io.ReadAll(rec.Result().Body)
 			if err != nil {
 				return err
 			}
diff --git a/libgo/go/net/http/httptest/server_test.go b/libgo/go/net/http/httptest/server_test.go
index 0aad15c5ed2..39568b358c2 100644
--- a/libgo/go/net/http/httptest/server_test.go
+++ b/libgo/go/net/http/httptest/server_test.go
@@ -6,7 +6,7 @@ package httptest
 
 import (
 	"bufio"
-	"io/ioutil"
+	"io"
 	"net"
 	"net/http"
 	"testing"
@@ -61,7 +61,7 @@ func testServer(t *testing.T, newServer newServerFunc) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	got, err := ioutil.ReadAll(res.Body)
+	got, err := io.ReadAll(res.Body)
 	res.Body.Close()
 	if err != nil {
 		t.Fatal(err)
@@ -81,7 +81,7 @@ func testGetAfterClose(t *testing.T, newServer newServerFunc) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	got, err := ioutil.ReadAll(res.Body)
+	got, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -93,7 +93,7 @@ func testGetAfterClose(t *testing.T, newServer newServerFunc) {
 
 	res, err = http.Get(ts.URL)
 	if err == nil {
-		body, _ := ioutil.ReadAll(res.Body)
+		body, _ := io.ReadAll(res.Body)
 		t.Fatalf("Unexpected response after close: %v, %v, %s", res.Status, res.Header, body)
 	}
 }
@@ -152,7 +152,7 @@ func testServerClient(t *testing.T, newTLSServer newServerFunc) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	got, err := ioutil.ReadAll(res.Body)
+	got, err := io.ReadAll(res.Body)
 	res.Body.Close()
 	if err != nil {
 		t.Fatal(err)
diff --git a/libgo/go/net/http/httputil/dump.go b/libgo/go/net/http/httputil/dump.go
index c97be066d7d..4c9d28bed8f 100644
--- a/libgo/go/net/http/httputil/dump.go
+++ b/libgo/go/net/http/httputil/dump.go
@@ -10,7 +10,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net"
 	"net/http"
 	"net/url"
@@ -35,7 +34,7 @@ func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) {
 	if err = b.Close(); err != nil {
 		return nil, b, err
 	}
-	return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil
+	return io.NopCloser(&buf), io.NopCloser(bytes.NewReader(buf.Bytes())), nil
 }
 
 // dumpConn is a net.Conn which writes to Writer and reads from Reader
@@ -81,7 +80,7 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
 	if !body {
 		contentLength := outgoingLength(req)
 		if contentLength != 0 {
-			req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), contentLength))
+			req.Body = io.NopCloser(io.LimitReader(neverEnding('x'), contentLength))
 			dummyBody = true
 		}
 	} else {
@@ -133,7 +132,7 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
 		if err == nil {
 			// Ensure all the body is read; otherwise
 			// we'll get a partial dump.
-			io.Copy(ioutil.Discard, req.Body)
+			io.Copy(io.Discard, req.Body)
 			req.Body.Close()
 		}
 		select {
@@ -296,7 +295,7 @@ func (failureToReadBody) Read([]byte) (int, error) { return 0, errNoBody }
 func (failureToReadBody) Close() error             { return nil }
 
 // emptyBody is an instance of empty reader.
-var emptyBody = ioutil.NopCloser(strings.NewReader(""))
+var emptyBody = io.NopCloser(strings.NewReader(""))
 
 // DumpResponse is like DumpRequest but dumps a response.
 func DumpResponse(resp *http.Response, body bool) ([]byte, error) {
diff --git a/libgo/go/net/http/httputil/dump_test.go b/libgo/go/net/http/httputil/dump_test.go
index ead56bc172b..7571eb0820d 100644
--- a/libgo/go/net/http/httputil/dump_test.go
+++ b/libgo/go/net/http/httputil/dump_test.go
@@ -9,7 +9,6 @@ import (
 	"bytes"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net/http"
 	"net/url"
 	"runtime"
@@ -268,7 +267,7 @@ func TestDumpRequest(t *testing.T) {
 			}
 			switch b := ti.Body.(type) {
 			case []byte:
-				req.Body = ioutil.NopCloser(bytes.NewReader(b))
+				req.Body = io.NopCloser(bytes.NewReader(b))
 			case func() io.ReadCloser:
 				req.Body = b()
 			default:
@@ -363,7 +362,7 @@ var dumpResTests = []struct {
 			Header: http.Header{
 				"Foo": []string{"Bar"},
 			},
-			Body: ioutil.NopCloser(strings.NewReader("foo")), // shouldn't be used
+			Body: io.NopCloser(strings.NewReader("foo")), // shouldn't be used
 		},
 		body: false, // to verify we see 50, not empty or 3.
 		want: `HTTP/1.1 200 OK
@@ -379,7 +378,7 @@ Foo: Bar`,
 			ProtoMajor:    1,
 			ProtoMinor:    1,
 			ContentLength: 3,
-			Body:          ioutil.NopCloser(strings.NewReader("foo")),
+			Body:          io.NopCloser(strings.NewReader("foo")),
 		},
 		body: true,
 		want: `HTTP/1.1 200 OK
@@ -396,7 +395,7 @@ foo`,
 			ProtoMajor:       1,
 			ProtoMinor:       1,
 			ContentLength:    -1,
-			Body:             ioutil.NopCloser(strings.NewReader("foo")),
+			Body:             io.NopCloser(strings.NewReader("foo")),
 			TransferEncoding: []string{"chunked"},
 		},
 		body: true,
diff --git a/libgo/go/net/http/httputil/example_test.go b/libgo/go/net/http/httputil/example_test.go
index 61916036745..b77a243ca3a 100644
--- a/libgo/go/net/http/httputil/example_test.go
+++ b/libgo/go/net/http/httputil/example_test.go
@@ -6,7 +6,7 @@ package httputil_test
 
 import (
 	"fmt"
-	"io/ioutil"
+	"io"
 	"log"
 	"net/http"
 	"net/http/httptest"
@@ -39,7 +39,7 @@ func ExampleDumpRequest() {
 	}
 	defer resp.Body.Close()
 
-	b, err := ioutil.ReadAll(resp.Body)
+	b, err := io.ReadAll(resp.Body)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -111,7 +111,7 @@ func ExampleReverseProxy() {
 		log.Fatal(err)
 	}
 
-	b, err := ioutil.ReadAll(resp.Body)
+	b, err := io.ReadAll(resp.Body)
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/libgo/go/net/http/httputil/reverseproxy.go b/libgo/go/net/http/httputil/reverseproxy.go
index 3f48fab544e..4e369580ea8 100644
--- a/libgo/go/net/http/httputil/reverseproxy.go
+++ b/libgo/go/net/http/httputil/reverseproxy.go
@@ -58,9 +58,9 @@ type ReverseProxy struct {
 	// A negative value means to flush immediately
 	// after each write to the client.
 	// The FlushInterval is ignored when ReverseProxy
-	// recognizes a response as a streaming response;
-	// for such responses, writes are flushed to the client
-	// immediately.
+	// recognizes a response as a streaming response, or
+	// if its ContentLength is -1; for such responses, writes
+	// are flushed to the client immediately.
 	FlushInterval time.Duration
 
 	// ErrorLog specifies an optional logger for errors
@@ -325,7 +325,7 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 
 	rw.WriteHeader(res.StatusCode)
 
-	err = p.copyResponse(rw, res.Body, p.flushInterval(req, res))
+	err = p.copyResponse(rw, res.Body, p.flushInterval(res))
 	if err != nil {
 		defer res.Body.Close()
 		// Since we're streaming the response, if we run into an error all we can do
@@ -397,7 +397,7 @@ func removeConnectionHeaders(h http.Header) {
 
 // flushInterval returns the p.FlushInterval value, conditionally
 // overriding its value for a specific request/response.
-func (p *ReverseProxy) flushInterval(req *http.Request, res *http.Response) time.Duration {
+func (p *ReverseProxy) flushInterval(res *http.Response) time.Duration {
 	resCT := res.Header.Get("Content-Type")
 
 	// For Server-Sent Events responses, flush immediately.
@@ -406,7 +406,11 @@ func (p *ReverseProxy) flushInterval(req *http.Request, res *http.Response) time
 		return -1 // negative means immediately
 	}
 
-	// TODO: more specific cases? e.g. res.ContentLength == -1?
+	// We might have the case of streaming for which Content-Length might be unset.
+	if res.ContentLength == -1 {
+		return -1
+	}
+
 	return p.FlushInterval
 }
 
@@ -545,8 +549,6 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R
 		return
 	}
 
-	copyHeader(res.Header, rw.Header())
-
 	hj, ok := rw.(http.Hijacker)
 	if !ok {
 		p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw))
@@ -577,6 +579,10 @@ func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.R
 		return
 	}
 	defer conn.Close()
+
+	copyHeader(rw.Header(), res.Header)
+
+	res.Header = rw.Header()
 	res.Body = nil // so res.Write only writes the headers; we have res.Body in backConn above
 	if err := res.Write(brw); err != nil {
 		p.getErrorHandler()(rw, req, fmt.Errorf("response write: %v", err))
diff --git a/libgo/go/net/http/httputil/reverseproxy_test.go b/libgo/go/net/http/httputil/reverseproxy_test.go
index 764939fb0f0..3acbd940e4b 100644
--- a/libgo/go/net/http/httputil/reverseproxy_test.go
+++ b/libgo/go/net/http/httputil/reverseproxy_test.go
@@ -13,7 +13,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"log"
 	"net/http"
 	"net/http/httptest"
@@ -84,7 +83,7 @@ func TestReverseProxy(t *testing.T) {
 		t.Fatal(err)
 	}
 	proxyHandler := NewSingleHostReverseProxy(backendURL)
-	proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
 	frontend := httptest.NewServer(proxyHandler)
 	defer frontend.Close()
 	frontendClient := frontend.Client()
@@ -124,7 +123,7 @@ func TestReverseProxy(t *testing.T) {
 	if cookie := res.Cookies()[0]; cookie.Name != "flavor" {
 		t.Errorf("unexpected cookie %q", cookie.Name)
 	}
-	bodyBytes, _ := ioutil.ReadAll(res.Body)
+	bodyBytes, _ := io.ReadAll(res.Body)
 	if g, e := string(bodyBytes), backendResponse; g != e {
 		t.Errorf("got body %q; expected %q", g, e)
 	}
@@ -218,7 +217,7 @@ func TestReverseProxyStripHeadersPresentInConnection(t *testing.T) {
 		t.Fatalf("Get: %v", err)
 	}
 	defer res.Body.Close()
-	bodyBytes, err := ioutil.ReadAll(res.Body)
+	bodyBytes, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatalf("reading body: %v", err)
 	}
@@ -271,7 +270,7 @@ func TestXForwardedFor(t *testing.T) {
 	if g, e := res.StatusCode, backendStatus; g != e {
 		t.Errorf("got res.StatusCode %d; expected %d", g, e)
 	}
-	bodyBytes, _ := ioutil.ReadAll(res.Body)
+	bodyBytes, _ := io.ReadAll(res.Body)
 	if g, e := string(bodyBytes), backendResponse; g != e {
 		t.Errorf("got body %q; expected %q", g, e)
 	}
@@ -373,7 +372,7 @@ func TestReverseProxyFlushInterval(t *testing.T) {
 		t.Fatalf("Get: %v", err)
 	}
 	defer res.Body.Close()
-	if bodyBytes, _ := ioutil.ReadAll(res.Body); string(bodyBytes) != expected {
+	if bodyBytes, _ := io.ReadAll(res.Body); string(bodyBytes) != expected {
 		t.Errorf("got body %q; expected %q", bodyBytes, expected)
 	}
 }
@@ -441,7 +440,7 @@ func TestReverseProxyCancellation(t *testing.T) {
 
 	defer backend.Close()
 
-	backend.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
+	backend.Config.ErrorLog = log.New(io.Discard, "", 0)
 
 	backendURL, err := url.Parse(backend.URL)
 	if err != nil {
@@ -452,7 +451,7 @@ func TestReverseProxyCancellation(t *testing.T) {
 
 	// Discards errors of the form:
 	// http: proxy error: read tcp 127.0.0.1:44643: use of closed network connection
-	proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0)
+	proxyHandler.ErrorLog = log.New(io.Discard, "", 0)
 
 	frontend := httptest.NewServer(proxyHandler)
 	defer frontend.Close()
@@ -504,7 +503,7 @@ func TestNilBody(t *testing.T) {
 		t.Fatal(err)
 	}
 	defer res.Body.Close()
-	slurp, err := ioutil.ReadAll(res.Body)
+	slurp, err := io.ReadAll(res.Body)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -533,7 +532,7 @@ func TestUserAgentHeader(t *testing.T) {
 		t.Fatal(err)
 	}
 	proxyHandler := NewSingleHostReverseProxy(backendURL)
-	proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
 	frontend := httptest.NewServer(proxyHandler)
 	defer frontend.Close()
 	frontendClient := frontend.Client()
@@ -606,7 +605,7 @@ func TestReverseProxyGetPutBuffer(t *testing.T) {
 	if err != nil {
 		t.Fatalf("Get: %v", err)
 	}
-	slurp, err := ioutil.ReadAll(res.Body)
+	slurp, err := io.ReadAll(res.Body)
 	res.Body.Close()
 	if err != nil {
 		t.Fatalf("reading body: %v", err)
@@ -627,7 +626,7 @@ func TestReverseProxy_Post(t *testing.T) {
 	const backendStatus = 200
 	var requestBody = bytes.Repeat([]byte("a"), 1<<20)
 	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		slurp, err := ioutil.ReadAll(r.Body)
+		slurp, err := io.ReadAll(r.Body)
 		if err != nil {
 			t.Errorf("Backend body read = %v", err)
 		}
@@ -656,7 +655,7 @@ func TestReverseProxy_Post(t *testing.T) {
 	if g, e := res.StatusCode, backendStatus; g != e {
 		t.Errorf("got res.StatusCode %d; expected %d", g, e)
 	}
-	bodyBytes, _ := ioutil.ReadAll(res.Body)
+	bodyBytes, _ := io.ReadAll(res.Body)
 	if g, e := string(bodyBytes), backendResponse; g != e {
 		t.Errorf("got body %q; expected %q", g, e)
 	}
@@ -672,7 +671,7 @@ func (fn RoundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error)
 func TestReverseProxy_NilBody(t *testing.T) {
 	backendURL, _ := url.Parse("http://fake.tld/")
 	proxyHandler := NewSingleHostReverseProxy(backendURL)
-	proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
 	proxyHandler.Transport = RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
 		if req.Body != nil {
 			t.Error("Body != nil; want a nil Body")
@@ -695,8 +694,8 @@ func TestReverseProxy_NilBody(t *testing.T) {
 // Issue 33142: always allocate the request headers
 func TestReverseProxy_AllocatedHeader(t *testing.T) {
 	proxyHandler := new(ReverseProxy)
-	proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
-	proxyHandler.Director = func(*http.Request) {}         // noop
+	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
+	proxyHandler.Director = func(*http.Request) {}     // noop
 	proxyHandler.Transport = RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
 		if req.Header == nil {
 			t.Error("Header == nil; want a non-nil Header")
@@ -722,7 +721,7 @@ func TestReverseProxyModifyResponse(t *testing.T) {
 
 	rpURL, _ := url.Parse(backendServer.URL)
 	rproxy := NewSingleHostReverseProxy(rpURL)
-	rproxy.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+	rproxy.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
 	rproxy.ModifyResponse = func(resp *http.Response) error {
 		if resp.Header.Get("X-Hit-Mod") != "true" {
 			return fmt.Errorf("tried to by-pass proxy")
@@ -821,7 +820,7 @@ func TestReverseProxyErrorHandler(t *testing.T) {
 			if rproxy.Transport == nil {
 				rproxy.Transport = failingRoundTripper{}
 			}
-			rproxy.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+			rproxy.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
 			if tt.errorHandler != nil {
 				rproxy.ErrorHandler = tt.errorHandler
 			}
@@ -896,7 +895,7 @@ func (t *staticTransport) RoundTrip(r *http.Request) (*http.Response, error) {
 func BenchmarkServeHTTP(b *testing.B) {
 	res := &http.Response{
 		StatusCode: 200,
-		Body:       ioutil.NopCloser(strings.NewReader("")),
+		Body:       io.NopCloser(strings.NewReader("")),
 	}
 	proxy := &ReverseProxy{
 		Director:  func(*http.Request) {},
@@ -953,7 +952,7 @@ func TestServeHTTPDeepCopy(t *testing.T) {
 // Issue 18327: verify we always do a deep copy of the Request.Header map
 // before any mutations.
 func TestClonesRequestHeaders(t *testing.T) {
-	log.SetOutput(ioutil.Discard)
+	log.SetOutput(io.Discard)
 	defer log.SetOutput(os.Stderr)
 	req, _ := http.NewRequest("GET", "http://foo.tld/", nil)
 	req.RemoteAddr = "1.2.3.4:56789"
@@ -1031,7 +1030,7 @@ func (cc *checkCloser) Read(b []byte) (int, error) {
 
 // Issue 23643: panic on body copy error
 func TestReverseProxy_PanicBodyError(t *testing.T) {
-	log.SetOutput(ioutil.Discard)
+	log.SetOutput(io.Discard)
 	defer log.SetOutput(os.Stderr)
 	backendServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		out := "this call was relayed by the reverse proxy"
@@ -1067,7 +1066,6 @@ func TestSelectFlushInterval(t *testing.T) {
 	tests := []struct {
 		name string
 		p    *ReverseProxy
-		req  *http.Request
 		res  *http.Response
 		want time.Duration
 	}{
@@ -1097,10 +1095,26 @@ func TestSelectFlushInterval(t *testing.T) {
 			p:    &ReverseProxy{FlushInterval: 0},
 			want: -1,
 		},
+		{
+			name: "Content-Length: -1, overrides non-zero",
+			res: &http.Response{
+				ContentLength: -1,
+			},
+			p:    &ReverseProxy{FlushInterval: 123},
+			want: -1,
+		},
+		{
+			name: "Content-Length: -1, overrides zero",
+			res: &http.Response{
+				ContentLength: -1,
+			},
+			p:    &ReverseProxy{FlushInterval: 0},
+			want: -1,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got := tt.p.flushInterval(tt.req, tt.res)
+			got := tt.p.flushInterval(tt.res)
 			if got != tt.want {
 				t.Errorf("flushLatency = %v; want %v", got, tt.want)
 			}
@@ -1133,7 +1147,7 @@ func TestReverseProxyWebSocket(t *testing.T) {
 
 	backURL, _ := url.Parse(backendServer.URL)
 	rproxy := NewSingleHostReverseProxy(backURL)
-	rproxy.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+	rproxy.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
 	rproxy.ModifyResponse = func(res *http.Response) error {
 		res.Header.Add("X-Modified", "true")
 		return nil
@@ -1142,6 +1156,9 @@ func TestReverseProxyWebSocket(t *testing.T) {
 	handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
 		rw.Header().Set("X-Header", "X-Value")
 		rproxy.ServeHTTP(rw, req)
+		if got, want := rw.Header().Get("X-Modified"), "true"; got != want {
+			t.Errorf("response writer X-Modified header = %q; want %q", got, want)
+		}
 	})
 
 	frontendProxy := httptest.NewServer(handler)
@@ -1247,7 +1264,7 @@ func TestReverseProxyWebSocketCancelation(t *testing.T) {
 
 	backendURL, _ := url.Parse(cst.URL)
 	rproxy := NewSingleHostReverseProxy(backendURL)
-	rproxy.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+	rproxy.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
 	rproxy.ModifyResponse = func(res *http.Response) error {
 		res.Header.Add("X-Modified", "true")
 		return nil
@@ -1334,7 +1351,7 @@ func TestUnannouncedTrailer(t *testing.T) {
 		t.Fatal(err)
 	}
 	proxyHandler := NewSingleHostReverseProxy(backendURL)
-	proxyHandler.ErrorLog = log.New(ioutil.Discard, "", 0) // quiet for tests
+	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
 	frontend := httptest.NewServer(proxyHandler)
 	defer frontend.Close()
 	frontendClient := frontend.Client()
@@ -1344,7 +1361,7 @@ func TestUnannouncedTrailer(t *testing.T) {
 		t.Fatalf("Get: %v", err)
 	}
 
-	ioutil.ReadAll(res.Body)
+	io.ReadAll(res.Body)
 
 	if g, w := res.Trailer.Get("X-Unannounced-Trailer"), "unannounced_trailer_value"; g != w {
 		t.Errorf("Trailer(X-Unannounced-Trailer) = %q; want %q", g, w)
diff --git a/libgo/go/net/http/internal/chunked_test.go b/libgo/go/net/http/internal/chunked_test.go
index d06716591ab..08152ed1e24 100644
--- a/libgo/go/net/http/internal/chunked_test.go
+++ b/libgo/go/net/http/internal/chunked_test.go
@@ -9,7 +9,6 @@ import (
 	"bytes"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"strings"
 	"testing"
 )
@@ -29,7 +28,7 @@ func TestChunk(t *testing.T) {
 	}
 
 	r := NewChunkedReader(&b)
-	data, err := ioutil.ReadAll(r)
+	data, err := io.ReadAll(r)
 	if err != nil {
 		t.Logf(`data: "%s"`, data)
 		t.Fatalf("ReadAll from reader: %v", err)
@@ -177,7 +176,7 @@ func TestChunkReadingIgnoresExtensions(t *testing.T) {
 		"17;someext\r\n" + // token without value
 		"world! 0123456789abcdef\r\n" +
 		"0;someextension=sometoken\r\n" // token=token
-	data, err := ioutil.ReadAll(NewChunkedReader(strings.NewReader(in)))
+	data, err := io.ReadAll(NewChunkedReader(strings.NewReader(in)))
 	if err != nil {
 		t.Fatalf("ReadAll = %q, %v", data, err)
 	}
diff --git a/libgo/go/net/http/main_test.go b/libgo/go/net/http/main_test.go
index 35cc80977c4..6564627998f 100644
--- a/libgo/go/net/http/main_test.go
+++ b/libgo/go/net/http/main_test.go
@@ -6,7 +6,7 @@ package http_test
 
 import (
 	"fmt"
-	"io/ioutil"
+	"io"
 	"log"
 	"net/http"
 	"os"
@@ -17,7 +17,7 @@ import (
 	"time"
 )
 
-var quietLog = log.New(ioutil.Discard, "", 0)
+var quietLog = log.New(io.Discard, "", 0)
 
 func TestMain(m *testing.M) {
 	v := m.Run()
diff --git a/libgo/go/net/http/omithttp2.go b/libgo/go/net/http/omithttp2.go
index 7e2f4925798..30c6e48cfcb 100644
--- a/libgo/go/net/http/omithttp2.go
+++ b/libgo/go/net/http/omithttp2.go
@@ -32,10 +32,6 @@ type http2Transport struct {
 func (*http2Transport) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
 func (*http2Transport) CloseIdleConnections()                 {}
 
-type http2erringRoundTripper struct{ err error }
-
-func (http2erringRoundTripper) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
-
 type http2noDialH2RoundTripper struct{}
 
 func (http2noDialH2RoundTripper) RoundTrip(*Request) (*Response, error) { panic(noHTTP2) }
@@ -49,7 +45,7 @@ type http2clientConnPool struct {
 	conns map[string][]struct{}
 }
 
-func http2configureTransport(*Transport) (*http2Transport, error) { panic(noHTTP2) }
+func http2configureTransports(*Transport) (*http2Transport, error) { panic(noHTTP2) }
 
 func http2isNoCachedConnError(err error) bool {
 	_, ok := err.(interface{ IsHTTP2NoCachedConnError() })
diff --git a/libgo/go/net/http/pprof/pprof.go b/libgo/go/net/http/pprof/pprof.go
index 81df0448e94..5389a388c17 100644
--- a/libgo/go/net/http/pprof/pprof.go
+++ b/libgo/go/net/http/pprof/pprof.go
@@ -61,11 +61,12 @@ import (
 	"bytes"
 	"context"
 	"fmt"
-	"html/template"
+	"html"
 	"internal/profile"
 	"io"
 	"log"
 	"net/http"
+	"net/url"
 	"os"
 	"runtime"
 	"runtime/pprof"
@@ -90,17 +91,13 @@ func init() {
 func Cmdline(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("X-Content-Type-Options", "nosniff")
 	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
+	fmt.Fprint(w, strings.Join(os.Args, "\x00"))
 }
 
-func sleep(w http.ResponseWriter, d time.Duration) {
-	var clientGone <-chan bool
-	if cn, ok := w.(http.CloseNotifier); ok {
-		clientGone = cn.CloseNotify()
-	}
+func sleep(r *http.Request, d time.Duration) {
 	select {
 	case <-time.After(d):
-	case <-clientGone:
+	case <-r.Context().Done():
 	}
 }
 
@@ -142,7 +139,7 @@ func Profile(w http.ResponseWriter, r *http.Request) {
 			fmt.Sprintf("Could not enable CPU profiling: %s", err))
 		return
 	}
-	sleep(w, time.Duration(sec)*time.Second)
+	sleep(r, time.Duration(sec)*time.Second)
 	pprof.StopCPUProfile()
 }
 
@@ -171,7 +168,7 @@ func Trace(w http.ResponseWriter, r *http.Request) {
 			fmt.Sprintf("Could not enable tracing: %s", err))
 		return
 	}
-	sleep(w, time.Duration(sec*float64(time.Second)))
+	sleep(r, time.Duration(sec*float64(time.Second)))
 	trace.Stop()
 }
 
@@ -356,6 +353,13 @@ var profileDescriptions = map[string]string{
 	"trace":        "A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace.",
 }
 
+type profileEntry struct {
+	Name  string
+	Href  string
+	Desc  string
+	Count int
+}
+
 // Index responds with the pprof-formatted profile named by the request.
 // For example, "/debug/pprof/heap" serves the "heap" profile.
 // Index responds to a request for "/debug/pprof/" with an HTML page
@@ -372,17 +376,11 @@ func Index(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("X-Content-Type-Options", "nosniff")
 	w.Header().Set("Content-Type", "text/html; charset=utf-8")
 
-	type profile struct {
-		Name  string
-		Href  string
-		Desc  string
-		Count int
-	}
-	var profiles []profile
+	var profiles []profileEntry
 	for _, p := range pprof.Profiles() {
-		profiles = append(profiles, profile{
+		profiles = append(profiles, profileEntry{
 			Name:  p.Name(),
-			Href:  p.Name() + "?debug=1",
+			Href:  p.Name(),
 			Desc:  profileDescriptions[p.Name()],
 			Count: p.Count(),
 		})
@@ -390,7 +388,7 @@ func Index(w http.ResponseWriter, r *http.Request) {
 
 	// Adding other profiles exposed from within this package
 	for _, p := range []string{"cmdline", "profile", "trace"} {
-		profiles = append(profiles, profile{
+		profiles = append(profiles, profileEntry{
 			Name: p,
 			Href: p,
 			Desc: profileDescriptions[p],
@@ -401,12 +399,14 @@ func Index(w http.ResponseWriter, r *http.Request) {
 		return profiles[i].Name < profiles[j].Name
 	})
 
-	if err := indexTmpl.Execute(w, profiles); err != nil {
+	if err := indexTmplExecute(w, profiles); err != nil {
 		log.Print(err)
 	}
 }
 
-var indexTmpl = template.Must(template.New("index").Parse(`
+func indexTmplExecute(w io.Writer, profiles []profileEntry) error {
+	var b bytes.Buffer
+	b.WriteString(`
 
 /debug/pprof/