├── README.md ├── aes ├── aes.go └── aes_test.go ├── client ├── client_msgsub_test.go ├── client_test.go └── cmd_test.go ├── client_main.go ├── dns ├── .gitignore ├── LICENSE ├── README.markdown ├── TODO.markdown ├── client.go ├── client_test.go ├── clientconfig.go ├── contrib │ └── check-soa │ │ └── check-soa.go ├── debian │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── docs │ ├── patches │ │ ├── series │ │ └── zscan-typo │ ├── rules │ └── source │ │ └── format ├── defaults.go ├── dns.go ├── dns_test.go ├── dnssec.go ├── dnssec_test.go ├── dyn_test.go ├── edns.go ├── ex │ ├── as112 │ │ └── as112.go │ ├── chaos │ │ └── chaos.go │ ├── q │ │ └── q.go │ └── reflect │ │ └── reflect.go ├── example_test.go ├── keygen.go ├── kscan.go ├── labels.go ├── labels_test.go ├── msg.go ├── nsecx.go ├── nsecx_test.go ├── parse_test.go ├── rawmsg.go ├── scanner.go ├── server.go ├── server_test.go ├── singleinflight.go ├── tlsa.go ├── tsig.go ├── types.go ├── update.go ├── xfr.go ├── zgenerate.go ├── zscan.go └── zscan_rr.go ├── dns_server_mx.json ├── dns_server_text.json ├── dnstunnel_client.linux64 ├── dnstunnel_client.win64 ├── dnstunnel_server.linux64 ├── dnstunnel_server.win64 ├── generator ├── generator.bak └── generator.e ├── http_test.go ├── logger ├── logger.go └── logw.go ├── server_main.go.b └── vendor ├── golang.org └── x │ └── text │ ├── LICENSE │ ├── PATENTS │ ├── cases │ ├── cases.go │ ├── context.go │ ├── context_test.go │ ├── example_test.go │ ├── fold.go │ ├── fold_test.go │ ├── gen.go │ ├── gen_trieval.go │ ├── icu.go │ ├── icu_test.go │ ├── info.go │ ├── map.go │ ├── map_test.go │ ├── tables10.0.0.go │ ├── tables10.0.0_test.go │ ├── tables9.0.0.go │ ├── tables9.0.0_test.go │ └── trieval.go │ ├── encoding │ ├── charmap │ │ ├── charmap.go │ │ ├── charmap_test.go │ │ ├── maketables.go │ │ └── tables.go │ ├── encoding.go │ ├── encoding_test.go │ ├── example_test.go │ ├── internal │ │ ├── enctest │ │ │ └── enctest.go │ │ ├── identifier │ │ │ ├── gen.go │ │ │ ├── identifier.go │ │ │ └── mib.go │ │ └── internal.go │ ├── simplifiedchinese │ │ ├── all.go │ │ ├── all_test.go │ │ ├── gbk.go │ │ ├── hzgb2312.go │ │ ├── maketables.go │ │ └── tables.go │ ├── testdata │ │ ├── candide-gb18030.txt │ │ ├── candide-utf-16le.txt │ │ ├── candide-utf-32be.txt │ │ ├── candide-utf-8.txt │ │ ├── candide-windows-1252.txt │ │ ├── rashomon-euc-jp.txt │ │ ├── rashomon-iso-2022-jp.txt │ │ ├── rashomon-shift-jis.txt │ │ ├── rashomon-utf-8.txt │ │ ├── sunzi-bingfa-gb-levels-1-and-2-hz-gb2312.txt │ │ ├── sunzi-bingfa-gb-levels-1-and-2-utf-8.txt │ │ ├── sunzi-bingfa-simplified-gbk.txt │ │ ├── sunzi-bingfa-simplified-utf-8.txt │ │ ├── sunzi-bingfa-traditional-big5.txt │ │ ├── sunzi-bingfa-traditional-utf-8.txt │ │ ├── unsu-joh-eun-nal-euc-kr.txt │ │ └── unsu-joh-eun-nal-utf-8.txt │ └── unicode │ │ ├── override.go │ │ ├── unicode.go │ │ └── unicode_test.go │ ├── internal │ ├── gen │ │ ├── code.go │ │ └── gen.go │ ├── internal.go │ ├── internal_test.go │ ├── language │ │ ├── common.go │ │ ├── compact.go │ │ ├── compact │ │ │ ├── compact.go │ │ │ ├── gen.go │ │ │ ├── gen_index.go │ │ │ ├── gen_parents.go │ │ │ ├── gen_test.go │ │ │ ├── language.go │ │ │ ├── language_test.go │ │ │ ├── parents.go │ │ │ ├── parse_test.go │ │ │ ├── tables.go │ │ │ └── tags.go │ │ ├── compose.go │ │ ├── compose_test.go │ │ ├── coverage.go │ │ ├── gen.go │ │ ├── gen_common.go │ │ ├── language.go │ │ ├── language_test.go │ │ ├── lookup.go │ │ ├── lookup_test.go │ │ ├── match.go │ │ ├── match_test.go │ │ ├── parse.go │ │ ├── parse_test.go │ │ ├── tables.go │ │ └── tags.go │ ├── match.go │ ├── match_test.go │ ├── tag │ │ ├── tag.go │ │ └── tag_test.go │ ├── testtext │ │ ├── codesize.go │ │ ├── flag.go │ │ ├── gc.go │ │ ├── gccgo.go │ │ ├── go1_6.go │ │ ├── go1_7.go │ │ └── text.go │ ├── ucd │ │ ├── example_test.go │ │ ├── ucd.go │ │ └── ucd_test.go │ └── utf8internal │ │ └── utf8internal.go │ ├── language │ ├── coverage.go │ ├── coverage_test.go │ ├── doc.go │ ├── examples_test.go │ ├── gen.go │ ├── go1_1.go │ ├── go1_2.go │ ├── httpexample_test.go │ ├── language.go │ ├── language_test.go │ ├── lookup_test.go │ ├── match.go │ ├── match_test.go │ ├── parse.go │ ├── parse_test.go │ ├── tables.go │ ├── tags.go │ └── testdata │ │ ├── CLDRLocaleMatcherTest.txt │ │ └── GoLocaleMatcherTest.txt │ ├── runes │ ├── cond.go │ ├── cond_test.go │ ├── example_test.go │ ├── runes.go │ └── runes_test.go │ ├── transform │ ├── examples_test.go │ ├── transform.go │ └── transform_test.go │ ├── unicode │ ├── cldr │ │ ├── base.go │ │ ├── cldr.go │ │ ├── cldr_test.go │ │ ├── collate.go │ │ ├── collate_test.go │ │ ├── data_test.go │ │ ├── decode.go │ │ ├── examples_test.go │ │ ├── makexml.go │ │ ├── resolve.go │ │ ├── resolve_test.go │ │ ├── slice.go │ │ ├── slice_test.go │ │ └── xml.go │ ├── norm │ │ ├── composition.go │ │ ├── composition_test.go │ │ ├── data10.0.0_test.go │ │ ├── data9.0.0_test.go │ │ ├── example_iter_test.go │ │ ├── example_test.go │ │ ├── forminfo.go │ │ ├── forminfo_test.go │ │ ├── input.go │ │ ├── iter.go │ │ ├── iter_test.go │ │ ├── maketables.go │ │ ├── normalize.go │ │ ├── normalize_test.go │ │ ├── readwriter.go │ │ ├── readwriter_test.go │ │ ├── tables10.0.0.go │ │ ├── tables9.0.0.go │ │ ├── transform.go │ │ ├── transform_test.go │ │ ├── trie.go │ │ ├── triegen.go │ │ └── ucd_test.go │ └── rangetable │ │ ├── gen.go │ │ ├── merge.go │ │ ├── merge_test.go │ │ ├── rangetable.go │ │ ├── rangetable_test.go │ │ ├── tables10.0.0.go │ │ └── tables9.0.0.go │ └── width │ ├── common_test.go │ ├── example_test.go │ ├── gen.go │ ├── gen_common.go │ ├── gen_trieval.go │ ├── kind_string.go │ ├── runes_test.go │ ├── tables10.0.0.go │ ├── tables9.0.0.go │ ├── tables_test.go │ ├── transform.go │ ├── transform_test.go │ ├── trieval.go │ └── width.go └── vendor.json /README.md: -------------------------------------------------------------------------------- 1 | # Ice Dns Tunnel Backdoor (DNS 隧道 渗透&后门) 2 | 本作品使用了DNS隧道技术,且是跨平台的(go语言),生成器使用了易语言,做界面简单粗暴。目前编译成了 windows 64位 和 linux64位的两个版本。功能和操作相同
3 | 4 | 本作品是我花费了2天半的时间写的,遵循了标准的DNS MX协议,在极端网络屏蔽情况下,内网渗透变得复杂,我们只能把通信包装成dns协议才能继续内网渗透。本作品利用了超长域名分段传输数据

5 | 6 | **优势:**
7 | 1】使用了aes对称加密算法,传输过程即使人工手动检测到DNS异常传输也难以解码
8 | 2】传输协议稳定,客户端&服务端严格遵循DNS MX协议,且传输过程分段打包传输
9 | 3】使用了http扩展协议,可以通过http post的方式优雅关停服务。避免手动hook隐藏以后 找不到进程无法结束(例如linux上使用 curl 即可优雅关停,下文有使用说明)
10 | 4】跨平台,多平台
11 | 12 | 13 | **劣势:**
14 | 1】没有做相关的rookit hook 进程可见。在此推荐1个linux效果不错 兼容性很强的hook。可以自己手动hook。已经测试了可用。
15 | 另一方面考虑是系统兼容性问题所以没有整合到代码中,还是自己make自己手动hook稳定性比较好。
16 | https://github.com/gianlucaborello/libprocesshider (使用了 ld preloader 技术)

17 | 18 | 2】体积略大,因为是使用golang写的,在没压缩的情况下已经比较大了,可以自行加壳压缩。目前渗透工作,文件体积大小不是瓶颈
19 | 3】只使用了dns隧道,其他隧道没有做,因为目前做工具只想做专精,不想整合太多隧道,恶意行为太多容易被一些极端防火墙告警。 20 | 后续其他隧道预计独立项目开发。尽量不做整合
21 | 4】传输略慢,因为dns隧道对数据包的大小有严格要求,所以只能分段传输,最后还要合包。效率不及普通TCP。
22 | 命令回显需要等待一些时间。命令发送禁止超长命令。
23 | 24 | **使用场景:**
25 | 内网极端环境下的渗透(防火墙只允许dns协议),以及拿到root权限后,配合hook隐藏技术,下后门。
26 | 27 | **用途:**
28 | 可以使用此工具 远程执行shell命令
29 | 30 | 31 | ## 目录结构 32 | client 目录 -> 目录里的_test文件是一些很重要的测试
33 | server_main.go.b -> 是服务端的main文件
34 | client.main.go -> 是客户端的main文件
35 | generator 目录 -> 是使用易语言写的生成器,只是生成方便一些,给菜鸟使用。大牛可以自行改代码编译

36 | generator.exe -> 是易语言编译好的生成器
37 | 38 | 39 | ## 使用说明 40 | 1、使用生成器generator.exe 配置服务端端口 和 客户端连接的地址 设置aes密钥(16位)
41 | 2、服务端启动、客户端启动。在服务端控制台上发送shell命令。稍作等待即可回显
42 | 3、优雅关停: 配置http服务端口,, 向指定地址 /off 发送http post请求,即可关闭程序
43 | 例如linux : curl "http://127.0.0.1:8080/off" -X POST -d "aes密钥"
44 | 密钥必须记好 否则不能优雅关停。
45 | 优雅关停场景:在hook进程或者内核hook的情况下,很难找到这个进程,销毁变得麻烦。使用优雅关停 http请求后自动销毁关闭,省心省力。
46 | 4、在服务端使用过程中, /e 可以直接退出程序 /up 可以返回上层菜单
47 | 5、该工具灵活运用,做好hook的情况下,可以在内网畅通无阻。
48 | 49 | ## 更新计划 50 | 1、添加win平台的自动 hook(感谢提建议),linux平台依然建议使用上面的工具手动hook。
51 | 2、添加端口复用
52 | 53 | ## 回答疑问 54 | 1、服务器只有web对外,无法通过转发等手段连接桌面3389,regeorg又被阻断(疑似检测到来了socket代理的缘故吧),这样的网络结构还有什么办法把3389转发出来么。
55 | 56 | 答:可以通过端口复用拦截,走web服务,思路和隧道一样,也可以叫https http隧道,将3389的数据包转发出来。等上面2个功能更新好后,后续我这边会研究一下。类似于国外软件 reduh
57 | 58 | 59 | ## 写给使用者 60 | 【免责声明:无恶意代码,仅作隧道技术研究,用于非法用途自负】

61 | 62 | 写的比较仓促,基础测试已经做过,基本命令可以执行,在windows环境上测试成功,linux还没来得及测试。有BUG可以提出。另外重申,不考虑整合入太多功能,而尽量是分散开。
63 | 64 | 如果有急迫需要什么工具的可以提issues 或者 联系我 。可以给我提供一些新思路。谢谢
65 | 66 | 67 | ## 写给golang爱好者 68 | 69 | 该程序大量使用了chan管道,编程难点在利用dns协议,数据大小有限,格式固定的情况下进行分包,组包。
70 | 71 | ### End 72 | -------------------------------------------------------------------------------- /aes/aes.go: -------------------------------------------------------------------------------- 1 | package aes 2 | 3 | import ( 4 | "bytes" 5 | "crypto/aes" 6 | "crypto/cipher" 7 | "encoding/base64" 8 | ) 9 | 10 | // 明文加密aes编码base64 11 | func AesEncrypt(origData, key []byte) (string, error) { 12 | block, err := aes.NewCipher(key) 13 | if err != nil { 14 | return "", err 15 | } 16 | 17 | blockSize := block.BlockSize() 18 | origData = PKCS5Padding(origData, blockSize) 19 | blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) 20 | crypted := make([]byte, len(origData)) 21 | blockMode.CryptBlocks(crypted, origData) 22 | pass64 := base64.StdEncoding.EncodeToString(crypted) 23 | return pass64, nil 24 | } 25 | 26 | //base64 + aes解密 27 | func AesDecrypt(crypted string, key []byte) ([]byte, error) { 28 | bytesPass, err := base64.StdEncoding.DecodeString(crypted) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | block, err := aes.NewCipher(key) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | blockSize := block.BlockSize() 39 | blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) 40 | origData := make([]byte, len(bytesPass)) 41 | blockMode.CryptBlocks(origData, bytesPass) 42 | origData = PKCS5UnPadding(origData) 43 | return origData, nil 44 | } 45 | 46 | func PKCS5Padding(ciphertext []byte, blockSize int) []byte { 47 | padding := blockSize - len(ciphertext)%blockSize 48 | padtext := bytes.Repeat([]byte{byte(padding)}, padding) 49 | return append(ciphertext, padtext...) 50 | } 51 | 52 | func PKCS5UnPadding(origData []byte) []byte { 53 | length := len(origData) 54 | unpadding := int(origData[length-1]) 55 | return origData[:(length - unpadding)] 56 | } 57 | -------------------------------------------------------------------------------- /aes/aes_test.go: -------------------------------------------------------------------------------- 1 | package aes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestAes(t *testing.T) { 9 | //务必16位 10 | AesKey = "321423u9y8d2fwfl" 11 | enStr, err := AesEncrypt([]byte("guigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9k"), []byte(AesKey)) 12 | fmt.Println(err) 13 | fmt.Println(enStr) 14 | 15 | deStr, err := AesDecrypt(enStr, []byte(AesKey)) 16 | fmt.Println(err) 17 | fmt.Println(string(deStr)) 18 | } 19 | -------------------------------------------------------------------------------- /client/client_msgsub_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math" 7 | "strconv" 8 | "testing" 9 | ) 10 | 11 | //测试分割回传消息 是否完整 12 | func TestSubMsg(t *testing.T) { 13 | rootHost := "baidu.com" 14 | body := "guigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9kguigjdfsjkl;ewlrejltejggfklldldlfkjksjskadsjtjgjvgldlkaskjdkiksdkjgju2u3i39g9gijkekeklfjbhsjiqi9193o9k" 15 | shengyuLen := 63 - len(rootHost) - 1 - 1 //减去两个点的长度 和 根域名的长度 16 | bodyLen := len(body) 17 | //消息分段回传 18 | msgArray := make([]string, 0) 19 | if bodyLen > shengyuLen { 20 | f := float64(bodyLen) / float64(shengyuLen) 21 | //需要分多少段 向上取整 22 | duanCeilInt := int(math.Ceil(f)) 23 | rs := []rune(body) 24 | for i := 0; i < duanCeilInt; i++ { 25 | var meiduan string 26 | if (i + 1) == duanCeilInt { 27 | //最后一段了 28 | //最后一段直接不用分割 直接放入 29 | meiduan = string(rs[(shengyuLen-1)*i:]) 30 | } else { 31 | //每段分割长度为dns name的剩余长度 shengyuLen 32 | //分割好后存入切片 33 | meiduan = string(rs[(shengyuLen-1)*i : (shengyuLen-1)*(i+1)]) 34 | } 35 | msgArray = append(msgArray, meiduan) 36 | } 37 | 38 | } else { 39 | //无需分段 40 | msgArray = append(msgArray, body) 41 | } 42 | b, _ := json.Marshal(msgArray) 43 | fmt.Println("msgArray len=" + strconv.Itoa(len(msgArray))) 44 | fmt.Println(string(b)) 45 | } 46 | -------------------------------------------------------------------------------- /client/cmd_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "golang.org/x/text/encoding/simplifiedchinese" 5 | "io/ioutil" 6 | "log" 7 | "os/exec" 8 | "strconv" 9 | "testing" 10 | ) 11 | 12 | func TestCmd(t *testing.T) { 13 | str := "abcd" 14 | log.Println(str[1:]) 15 | 16 | msgIdStr := "1" + strconv.Itoa(int(123)) 17 | msgId, _ := strconv.Atoi(msgIdStr) 18 | uint := uint16(msgId) 19 | log.Println(uint) 20 | log.Println(exe("whoami")) 21 | } 22 | 23 | func exe(commond string) string { 24 | cmd := exec.Command(commond) 25 | //创建获取命令输出管道 26 | stdout, err := cmd.StdoutPipe() 27 | if err != nil { 28 | return "Error:can not obtain stdout pipe for command:" + err.Error() 29 | } 30 | //执行命令 31 | if err := cmd.Start(); err != nil { 32 | return "Error:The command is err," + err.Error() 33 | } 34 | //读取所有输出 35 | bytes, err := ioutil.ReadAll(stdout) 36 | if err != nil { 37 | return "ReadAll Stdout:" + err.Error() 38 | } 39 | if err := cmd.Wait(); err != nil { 40 | return "wait:" + err.Error() 41 | } 42 | var decodeBytes, _ = simplifiedchinese.GB18030.NewDecoder().Bytes(bytes) 43 | return string(decodeBytes) 44 | } 45 | -------------------------------------------------------------------------------- /dns/.gitignore: -------------------------------------------------------------------------------- 1 | *.6 2 | test.out 3 | a.out 4 | -------------------------------------------------------------------------------- /dns/LICENSE: -------------------------------------------------------------------------------- 1 | Extensions of the original work are copyright (c) 2011 Miek Gieben 2 | 3 | As this is fork of the official Go code the same license applies: 4 | 5 | Copyright (c) 2009 The Go Authors. All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | * Neither the name of Google Inc. nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | 33 | -------------------------------------------------------------------------------- /dns/README.markdown: -------------------------------------------------------------------------------- 1 | # Alternative (more granular) approach to a DNS library. 2 | 3 | > Less is more. 4 | 5 | Complete and usable DNS library. All widely used Resource Records are 6 | supported, including the DNSSEC types. It follows a lean and mean philosophy. 7 | If there is stuff you should know as a DNS programmer there isn't a convenience 8 | function for it. Server side and client side programming is supported, i.e. you 9 | can build servers and resolvers with it. 10 | 11 | If you like this, you may also be interested in: 12 | 13 | * https://github.com/miekg/fks -- a (in)complete nameserver written in Go; 14 | * https://github.com/miekg/unbound -- Go wrapper for the Unbound resolver. 15 | 16 | # Goals 17 | 18 | * KISS; 19 | * Fast 20 | * Small API, if its easy to code in Go, don't make a function for it. 21 | 22 | # Users 23 | 24 | A not-so-up-to-date-list-that-may-be-actually-current: 25 | 26 | * https://github.com/abh/geodns 27 | * http://www.statdns.com/ 28 | * http://www.dnsinspect.com/ 29 | * https://github.com/chuangbo/jianbing-dictionary-dns 30 | * http://www.dns-lg.com/ 31 | * https://github.com/fcambus/rrda 32 | * https://github.com/kenshinx/godns 33 | * more? (send pull request if you want to be listed here) 34 | 35 | # Features 36 | 37 | * UDP/TCP queries, IPv4 and IPv6; 38 | * RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE (for all record types) are supported; 39 | * Fast: 40 | * Reply speed around ~ 80K qps (faster hardware results in more qps); 41 | * Parsing RRs with ~ 100K RR/s, that's 5M records in about 50 seconds; 42 | * Server side programming (mimicking the net/http package); 43 | * Client side programming; 44 | * DNSSEC: signing, validating and key generation for DSA, RSA and ECDSA; 45 | * EDNS0, NSID; 46 | * AXFR/IXFR; 47 | * TSIG; 48 | * DNS name compression. 49 | 50 | Have fun! 51 | 52 | Miek Gieben - 2010-2012 - miek@miek.nl 53 | 54 | # Building 55 | 56 | Building is done with the `go` tool. If you have setup your GOPATH 57 | correctly, the following should work: 58 | 59 | go get github.com/miekg/dns 60 | go build github/com/miekg/dns 61 | 62 | A short "how to use the API" is at the beginning of dns.go (this also will show 63 | when you call `go doc github.com/miekg/dns`. Sample 64 | programs can be found in the `ex` directory. They can also be build 65 | with: `go build`. 66 | 67 | ## Supported RFCs 68 | 69 | *all of them* 70 | 71 | * 103{4,5} - DNS standard 72 | * 1982 - Serial Arithmetic 73 | * 1876 - LOC record 74 | * 1995 - IXFR 75 | * 1996 - DNS notify 76 | * 2136 - DNS Update (dynamic updates) 77 | * 2181 - RRset definition 78 | * 2537 - RSAMD5 DNS keys 79 | * 2065 - DNSSEC (updated in later RFCs) 80 | * 2671 - EDNS record 81 | * 2782 - SRV record 82 | * 2845 - TSIG record 83 | * 2915 - NAPTR record 84 | * 2929 - DNS IANA Considerations 85 | * 3110 - RSASHA1 DNS keys 86 | * 3225 - DO bit (DNSSEC OK) 87 | * 340{1,2,3} - NAPTR record 88 | * 3445 - Limiting the scope of (DNS)KEY 89 | * 3597 - Unkown RRs 90 | * 403{3,4,5} - DNSSEC + validation functions 91 | * 4255 - SSHFP record 92 | * 4343 - Case insensitivity 93 | * 4408 - SPF record 94 | * 4509 - SHA256 Hash in DS 95 | * 4592 - Wildcards in the DNS 96 | * 4635 - HMAC SHA TSIG 97 | * 4701 - DHCID 98 | * 4892 - id.server 99 | * 5001 - NSID 100 | * 5155 - NSEC3 record 101 | * 5205 - HIP record 102 | * 5702 - SHA2 in the DNS 103 | * 5936 - AXFR 104 | * 6605 - ECDSA 105 | * 6742 - ILNP DNS 106 | * 6891 - EDNS0 update 107 | * xxxx - URI record (draft) 108 | * xxxx - EDNS0 DNS Update Lease (draft) 109 | * xxxx - IEU48/IEU64 records (draft) 110 | * xxxx - Algorithm-Signal (draft) 111 | 112 | ## Loosely based upon 113 | 114 | * `ldns` 115 | * `NSD` 116 | * `Net::DNS` 117 | * `GRONG` 118 | -------------------------------------------------------------------------------- /dns/TODO.markdown: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | * Support for on-the-fly-signing or check how to do it 4 | * Ratelimiting? server side (rrl) 5 | * Ratelimiting? client side 6 | 7 | ## Nice to have 8 | 9 | * Speed, we can always go faster. A simple reflect server now hits 75/80K qps on 10 | moderate hardware 11 | * go test; only works correct on my machine 12 | * privatekey.Precompute() when signing? 13 | 14 | ## RRs not implemented 15 | 16 | These are deprecated, or rarely used (or just a bitch to implement). 17 | 18 | NSAP 19 | NSAP-PTR 20 | PX 21 | GPOS 22 | NIMLOC 23 | ATMA 24 | A6 25 | KEY 26 | SIG 27 | NXT 28 | -------------------------------------------------------------------------------- /dns/client_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | import ( 8 | "testing" 9 | "time" 10 | ) 11 | 12 | func TestClientSync(t *testing.T) { 13 | m := new(Msg) 14 | m.SetQuestion("miek.nl.", TypeSOA) 15 | 16 | c := new(Client) 17 | r, _, _ := c.Exchange(m, "37.251.95.53:53") 18 | 19 | if r != nil && r.Rcode != RcodeSuccess { 20 | t.Log("Failed to get an valid answer") 21 | t.Fail() 22 | t.Logf("%v\n", r) 23 | } 24 | } 25 | 26 | func TestClientEDNS0(t *testing.T) { 27 | m := new(Msg) 28 | m.SetQuestion("miek.nl.", TypeDNSKEY) 29 | 30 | m.SetEdns0(2048, true) 31 | //edns.Option = make([]Option, 1) 32 | //edns.SetNsid("") // Empty to request it 33 | 34 | c := new(Client) 35 | r, _, _ := c.Exchange(m, "37.251.95.53:53") 36 | 37 | if r != nil && r.Rcode != RcodeSuccess { 38 | t.Log("Failed to get an valid answer") 39 | t.Fail() 40 | t.Logf("%v\n", r) 41 | } 42 | } 43 | 44 | func TestSingleSingleInflight(t *testing.T) { 45 | m := new(Msg) 46 | m.SetQuestion("miek.nl.", TypeDNSKEY) 47 | 48 | c := new(Client) 49 | c.SingleInflight = true 50 | nr := 10 51 | ch := make(chan time.Duration) 52 | for i := 0; i < nr; i++ { 53 | go func() { 54 | _, rtt, _ := c.Exchange(m, "37.251.95.53:53") 55 | ch <- rtt 56 | }() 57 | } 58 | i := 0 59 | var first time.Duration 60 | // With inflight *all* rtt are identical, and by doing actual lookups 61 | // the changes that this is a coincidence is small. 62 | Loop: 63 | for { 64 | select { 65 | case rtt := <-ch: 66 | if i == 0 { 67 | first = rtt 68 | } else { 69 | if first != rtt { 70 | t.Log("All rtt should be equal") 71 | t.Fail() 72 | } 73 | } 74 | i++ 75 | if i == 10 { 76 | break Loop 77 | } 78 | } 79 | } 80 | } 81 | 82 | func TestClientTsigAXFR(t *testing.T) { 83 | m := new(Msg) 84 | m.SetAxfr("miek.nl.") 85 | m.SetTsig("axfr.", HmacMD5, 300, time.Now().Unix()) 86 | 87 | c := new(Client) 88 | c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} 89 | c.Net = "tcp" 90 | 91 | if a, err := c.TransferIn(m, "37.251.95.53:53"); err != nil { 92 | t.Log("Failed to setup axfr: " + err.Error()) 93 | t.Fatal() 94 | } else { 95 | for ex := range a { 96 | if ex.Error != nil { 97 | t.Logf("Error %s\n", ex.Error.Error()) 98 | t.Fail() 99 | break 100 | } 101 | for _, rr := range ex.RR { 102 | t.Logf("%s\n", rr.String()) 103 | } 104 | } 105 | } 106 | } 107 | 108 | func TestClientAXFRMultipleMessages(t *testing.T) { 109 | m := new(Msg) 110 | m.SetAxfr("dnsex.nl.") 111 | 112 | c := new(Client) 113 | c.Net = "tcp" 114 | 115 | if a, err := c.TransferIn(m, "37.251.95.53:53"); err != nil { 116 | t.Log("Failed to setup axfr" + err.Error()) 117 | t.Fail() 118 | return 119 | } else { 120 | for ex := range a { 121 | if ex.Error != nil { 122 | t.Logf("Error %s\n", ex.Error.Error()) 123 | t.Fail() 124 | break 125 | } 126 | } 127 | } 128 | } 129 | 130 | // not really a test, but shows how to use update leases 131 | func TestUpdateLeaseTSIG(t *testing.T) { 132 | m := new(Msg) 133 | m.SetUpdate("t.local.ip6.io.") 134 | rr, _ := NewRR("t.local.ip6.io. 30 A 127.0.0.1") 135 | rrs := make([]RR, 1) 136 | rrs[0] = rr 137 | m.Insert(rrs) 138 | 139 | lease_rr := new(OPT) 140 | lease_rr.Hdr.Name = "." 141 | lease_rr.Hdr.Rrtype = TypeOPT 142 | e := new(EDNS0_UL) 143 | e.Code = EDNS0UL 144 | e.Lease = 120 145 | lease_rr.Option = append(lease_rr.Option, e) 146 | m.Extra = append(m.Extra, lease_rr) 147 | 148 | c := new(Client) 149 | m.SetTsig("polvi.", HmacMD5, 300, time.Now().Unix()) 150 | c.TsigSecret = map[string]string{"polvi.": "pRZgBrBvI4NAHZYhxmhs/Q=="} 151 | 152 | w := new(reply) 153 | w.client = c 154 | w.addr = "127.0.0.1:53" 155 | w.req = m 156 | 157 | if err := w.dial(); err != nil { 158 | t.Fail() 159 | } 160 | if err := w.send(m); err != nil { 161 | t.Fail() 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /dns/clientconfig.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | // Extensions of the original work are copyright (c) 2011 Miek Gieben 5 | 6 | package dns 7 | 8 | import ( 9 | "bufio" 10 | "os" 11 | "strconv" 12 | "strings" 13 | ) 14 | 15 | // Wraps the contents of the /etc/resolv.conf. 16 | type ClientConfig struct { 17 | Servers []string // servers to use 18 | Search []string // suffixes to append to local name 19 | Port string // what port to use 20 | Ndots int // number of dots in name to trigger absolute lookup 21 | Timeout int // seconds before giving up on packet 22 | Attempts int // lost packets before giving up on server, not used in the package dns 23 | } 24 | 25 | // ClientConfigFromFile parses a resolv.conf(5) like file and returns 26 | // a *ClientConfig. 27 | func ClientConfigFromFile(conf string) (*ClientConfig, error) { 28 | file, err := os.Open(conf) 29 | if err != nil { 30 | return nil, err 31 | } 32 | defer file.Close() 33 | c := new(ClientConfig) 34 | b := bufio.NewReader(file) 35 | c.Servers = make([]string, 0) 36 | c.Search = make([]string, 0) 37 | c.Port = "53" 38 | c.Ndots = 1 39 | c.Timeout = 5 40 | c.Attempts = 2 41 | for line, ok := b.ReadString('\n'); ok == nil; line, ok = b.ReadString('\n') { 42 | f := strings.Fields(line) 43 | if len(f) < 1 { 44 | continue 45 | } 46 | switch f[0] { 47 | case "nameserver": // add one name server 48 | if len(f) > 1 { 49 | // One more check: make sure server name is 50 | // just an IP address. Otherwise we need DNS 51 | // to look it up. 52 | name := f[1] 53 | // Don't use this. net.JoinHostPort will fix this for you 54 | // switch x := net.ParseIP(name); true { 55 | // case x.To4() != nil: 56 | // c.Servers = append(c.Servers, name) 57 | // case x.To16() != nil: 58 | // name = "[" + name + "]" 59 | c.Servers = append(c.Servers, name) 60 | // } 61 | } 62 | 63 | case "domain": // set search path to just this domain 64 | if len(f) > 1 { 65 | c.Search = make([]string, 1) 66 | c.Search[0] = f[1] 67 | } else { 68 | c.Search = make([]string, 0) 69 | } 70 | 71 | case "search": // set search path to given servers 72 | c.Search = make([]string, len(f)-1) 73 | for i := 0; i < len(c.Search); i++ { 74 | c.Search[i] = f[i+1] 75 | } 76 | 77 | case "options": // magic options 78 | for i := 1; i < len(f); i++ { 79 | s := f[i] 80 | switch { 81 | case len(s) >= 6 && s[:6] == "ndots:": 82 | n, _ := strconv.Atoi(s[6:]) 83 | if n < 1 { 84 | n = 1 85 | } 86 | c.Ndots = n 87 | case len(s) >= 8 && s[:8] == "timeout:": 88 | n, _ := strconv.Atoi(s[8:]) 89 | if n < 1 { 90 | n = 1 91 | } 92 | c.Timeout = n 93 | case len(s) >= 8 && s[:9] == "attempts:": 94 | n, _ := strconv.Atoi(s[9:]) 95 | if n < 1 { 96 | n = 1 97 | } 98 | c.Attempts = n 99 | case s == "rotate": 100 | /* not imp */ 101 | } 102 | } 103 | } 104 | } 105 | return c, nil 106 | } 107 | -------------------------------------------------------------------------------- /dns/debian/changelog: -------------------------------------------------------------------------------- 1 | golang-dns (0.0~git20130912-1) unstable; urgency=low 2 | 3 | * Initial release. Closes: 722973 4 | 5 | -- Tonnerre LOMBARD Sun, 15 Sep 2013 01:08:44 +0200 6 | -------------------------------------------------------------------------------- /dns/debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /dns/debian/control: -------------------------------------------------------------------------------- 1 | Source: golang-dns 2 | Section: devel 3 | Priority: extra 4 | Maintainer: Tonnerre LOMBARD 5 | Build-Depends: debhelper (>= 9), dh-golang, golang-go 6 | Standards-Version: 3.9.4 7 | Homepage: http://miek.nl/projects/godns/ 8 | Vcs-Git: git://anonscm.debian.org/pkg-go/packages/golang-dns.git 9 | Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-go/packages/golang-dns.git;a=summary 10 | 11 | Package: golang-dns-dev 12 | Architecture: all 13 | Depends: ${shlibs:Depends}, ${misc:Depends}, golang-go 14 | Description: DNS protocol library for Go 15 | Complete and usable DNS library. All widely used Resource Records 16 | are supported, including the DNSSEC types. It follows a lean and 17 | mean philosophy. If there is stuff you should know as a DNS 18 | programmer there isn't a convenience function for it. Server side 19 | and client side programming is supported, i.e. you can build 20 | servers and resolvers with it. 21 | -------------------------------------------------------------------------------- /dns/debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: golang-dns 3 | Source: https://github.com/miekg/dns/ 4 | 5 | Files: * 6 | Copyright: 2009-2013 Miek Gieben 7 | License: BSD-3-Clause 8 | 9 | Files: debian/* 10 | Copyright: 2013 Tonnerre Lombard 11 | License: BSD-3-Clause 12 | 13 | License: BSD-3-Clause 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions 16 | are met: 17 | . 18 | 1. Redistributions of source code must retain the above copyright 19 | notice, this list of conditions and the following disclaimer. 20 | 2. Redistributions in binary form must reproduce the above copyright 21 | notice, this list of conditions and the following disclaimer in the 22 | documentation and/or other materials provided with the distribution. 23 | 3. Neither the name of the University nor the names of its contributors 24 | may be used to endorse or promote products derived from this software 25 | without specific prior written permission. 26 | . 27 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 | SUCH DAMAGE. 38 | -------------------------------------------------------------------------------- /dns/debian/docs: -------------------------------------------------------------------------------- 1 | README.markdown 2 | TODO.markdown 3 | -------------------------------------------------------------------------------- /dns/debian/patches/series: -------------------------------------------------------------------------------- 1 | zscan-typo 2 | -------------------------------------------------------------------------------- /dns/debian/patches/zscan-typo: -------------------------------------------------------------------------------- 1 | Description: Fix for typo in message in zscan_rr. 2 | Adress is spelled with an insufficient number of ds. 3 | Author: Tonnerre LOMBARD 4 | Forwarded: yes, https://github.com/miekg/dns/pull/54 5 | Last-Update: 2013-09-15 6 | 7 | --- golang-dns-0.0~git20130912.orig/zscan_rr.go 8 | +++ golang-dns-0.0~git20130912/zscan_rr.go 9 | @@ -1360,7 +1360,7 @@ func setWKS(h RR_Header, c chan lex, f s 10 | l := <-c 11 | rr.Address = net.ParseIP(l.token) 12 | if rr.Address == nil { 13 | - return nil, &ParseError{f, "bad WKS Adress", l}, "" 14 | + return nil, &ParseError{f, "bad WKS Address", l}, "" 15 | } 16 | 17 | <-c // _BLANK 18 | -------------------------------------------------------------------------------- /dns/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | # Uncomment this to turn on verbose mode. 4 | export DH_VERBOSE=1 5 | 6 | # DH_GOPKG is the upstream path which you would normally “go get”. 7 | # Using it allows us to build applications without patching locations. 8 | export DH_GOPKG := github.com/miekg/dns 9 | 10 | # Currently, tests can't win. 11 | override_dh_auto_test: 12 | 13 | %: 14 | dh $@ --buildsystem=golang --with=golang 15 | 16 | override_dh_auto_install: 17 | dh_auto_install -O--buildsystem=golang 18 | rm -rf ${CURDIR}/debian/golang-dns-dev/usr/bin 19 | -------------------------------------------------------------------------------- /dns/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /dns/dyn_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | // Find better solution 8 | -------------------------------------------------------------------------------- /dns/ex/as112/as112.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // An AS112 blackhole DNS server. Similar to the one found in evldns. 6 | // Also see https://www.as112.net/ 7 | 8 | package main 9 | 10 | import ( 11 | "github.com/miekg/dns" 12 | "log" 13 | "os" 14 | "os/signal" 15 | "runtime" 16 | "syscall" 17 | ) 18 | 19 | const SOA string = "@ SOA prisoner.iana.org. hostmaster.root-servers.org. 2002040800 1800 900 0604800 604800" 20 | 21 | func NewRR(s string) dns.RR { r, _ := dns.NewRR(s); return r } 22 | 23 | var zones = map[string]dns.RR{ 24 | "10.in-addr.arpa.": NewRR("$ORIGIN 10.in-addr.arpa.\n" + SOA), 25 | "254.169.in-addr.arpa.": NewRR("$ORIGIN 254.169.in-addr.arpa.\n" + SOA), 26 | "168.192.in-addr.arpa.": NewRR("$ORIGIN 168.192.in-addr.arpa.\n" + SOA), 27 | "16.172.in-addr.arpa.": NewRR("$ORIGIN 16.172.in-addr.arpa.\n" + SOA), 28 | "17.172.in-addr.arpa.": NewRR("$ORIGIN 17.172.in-addr.arpa.\n" + SOA), 29 | "18.172.in-addr.arpa.": NewRR("$ORIGIN 18.172.in-addr.arpa.\n" + SOA), 30 | "19.172.in-addr.arpa.": NewRR("$ORIGIN 19.172.in-addr.arpa.\n" + SOA), 31 | "20.172.in-addr.arpa.": NewRR("$ORIGIN 20.172.in-addr.arpa.\n" + SOA), 32 | "21.172.in-addr.arpa.": NewRR("$ORIGIN 21.172.in-addr.arpa.\n" + SOA), 33 | "22.172.in-addr.arpa.": NewRR("$ORIGIN 22.172.in-addr.arpa.\n" + SOA), 34 | "23.172.in-addr.arpa.": NewRR("$ORIGIN 23.172.in-addr.arpa.\n" + SOA), 35 | "24.172.in-addr.arpa.": NewRR("$ORIGIN 24.172.in-addr.arpa.\n" + SOA), 36 | "25.172.in-addr.arpa.": NewRR("$ORIGIN 25.172.in-addr.arpa.\n" + SOA), 37 | "26.172.in-addr.arpa.": NewRR("$ORIGIN 26.172.in-addr.arpa.\n" + SOA), 38 | "27.172.in-addr.arpa.": NewRR("$ORIGIN 27.172.in-addr.arpa.\n" + SOA), 39 | "28.172.in-addr.arpa.": NewRR("$ORIGIN 28.172.in-addr.arpa.\n" + SOA), 40 | "29.172.in-addr.arpa.": NewRR("$ORIGIN 29.172.in-addr.arpa.\n" + SOA), 41 | "30.172.in-addr.arpa.": NewRR("$ORIGIN 30.172.in-addr.arpa.\n" + SOA), 42 | "31.172.in-addr.arpa.": NewRR("$ORIGIN 31.172.in-addr.arpa.\n" + SOA), 43 | } 44 | 45 | func main() { 46 | runtime.GOMAXPROCS(runtime.NumCPU() * 4) 47 | for z, rr := range zones { 48 | rrx := rr.(*dns.SOA) // Needed to create the actual RR, and not an reference. 49 | dns.HandleFunc(z, func(w dns.ResponseWriter, r *dns.Msg) { 50 | m := new(dns.Msg) 51 | m.SetReply(r) 52 | m.Authoritative = true 53 | m.Ns = []dns.RR{rrx} 54 | w.WriteMsg(m) 55 | }) 56 | } 57 | go func() { 58 | err := dns.ListenAndServe(":8053", "tcp", nil) 59 | if err != nil { 60 | log.Fatal("Failed to set tcp listener %s\n", err.Error()) 61 | } 62 | }() 63 | go func() { 64 | err := dns.ListenAndServe(":8053", "udp", nil) 65 | if err != nil { 66 | log.Fatal("Failed to set udp listener %s\n", err.Error()) 67 | } 68 | }() 69 | sig := make(chan os.Signal) 70 | signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) 71 | for { 72 | select { 73 | case s := <-sig: 74 | log.Fatalf("Signal (%d) received, stopping\n", s) 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /dns/ex/chaos/chaos.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Chaos is a small program that prints the version.bind and hostname.bind 6 | // for each address of the nameserver given as argument. 7 | package main 8 | 9 | import ( 10 | "fmt" 11 | "github.com/miekg/dns" 12 | "net" 13 | "os" 14 | ) 15 | 16 | func main() { 17 | if len(os.Args) != 2 { 18 | fmt.Printf("%s NAMESERVER\n", os.Args[0]) 19 | os.Exit(1) 20 | } 21 | conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf") 22 | 23 | m := new(dns.Msg) 24 | m.Question = make([]dns.Question, 1) 25 | c := new(dns.Client) 26 | 27 | addr := addresses(conf, c, os.Args[1]) 28 | if len(addr) == 0 { 29 | fmt.Printf("No address found for %s\n", os.Args[1]) 30 | os.Exit(1) 31 | } 32 | for _, a := range addr { 33 | m.Question[0] = dns.Question{"version.bind.", dns.TypeTXT, dns.ClassCHAOS} 34 | in, rtt, _ := c.Exchange(m, a) 35 | if in != nil && len(in.Answer) > 0 { 36 | fmt.Printf("(time %.3d µs) %v\n", rtt/1e3, in.Answer[0]) 37 | } 38 | m.Question[0] = dns.Question{"hostname.bind.", dns.TypeTXT, dns.ClassCHAOS} 39 | in, rtt, _ = c.Exchange(m, a) 40 | if in != nil && len(in.Answer) > 0 { 41 | fmt.Printf("(time %.3d µs) %v\n", rtt/1e3, in.Answer[0]) 42 | } 43 | } 44 | } 45 | 46 | func do(t chan *dns.Msg, c *dns.Client, m *dns.Msg, addr string) { 47 | go func() { 48 | r, _, err := c.Exchange(m, addr) 49 | if err != nil { 50 | //print error stuff 51 | t <- nil 52 | } 53 | t <- r 54 | }() 55 | } 56 | 57 | func addresses(conf *dns.ClientConfig, c *dns.Client, name string) (ips []string) { 58 | m4 := new(dns.Msg) 59 | m4.SetQuestion(dns.Fqdn(os.Args[1]), dns.TypeA) 60 | m6 := new(dns.Msg) 61 | m6.SetQuestion(dns.Fqdn(os.Args[1]), dns.TypeAAAA) 62 | t := make(chan *dns.Msg) 63 | defer close(t) 64 | do(t, c, m4, net.JoinHostPort(conf.Servers[0], conf.Port)) 65 | do(t, c, m6, net.JoinHostPort(conf.Servers[0], conf.Port)) 66 | 67 | i := 2 // two outstanding queries 68 | forever: 69 | for { 70 | select { 71 | case d := <-t: 72 | i-- 73 | if d == nil { 74 | continue 75 | } 76 | if i == 0 { 77 | break forever 78 | } 79 | if d.Rcode == dns.RcodeSuccess { 80 | for _, a := range d.Answer { 81 | switch a.(type) { 82 | case *dns.A: 83 | ips = append(ips, 84 | net.JoinHostPort(a.(*dns.A).A.String(), "53")) 85 | case *dns.AAAA: 86 | ips = append(ips, 87 | net.JoinHostPort(a.(*dns.AAAA).AAAA.String(), "53")) 88 | 89 | } 90 | } 91 | } 92 | } 93 | } 94 | return ips 95 | } 96 | -------------------------------------------------------------------------------- /dns/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | import ( 8 | "fmt" 9 | ) 10 | 11 | // Retrieve the MX records for miek.nl. 12 | func ExampleMX() { 13 | config, _ := ClientConfigFromFile("/etc/resolv.conf") 14 | c := new(Client) 15 | m := new(Msg) 16 | m.SetQuestion("miek.nl.", TypeMX) 17 | m.RecursionDesired = true 18 | r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port) 19 | if err != nil { 20 | return 21 | } 22 | if r.Rcode != RcodeSuccess { 23 | return 24 | } 25 | for _, a := range r.Answer { 26 | if mx, ok := a.(*MX); ok { 27 | fmt.Printf("%s\n", mx.String()) 28 | } 29 | } 30 | } 31 | 32 | // Retrieve the DNSKEY records of a zone and convert them 33 | // to DS records for SHA1, SHA256 and SHA384. 34 | func ExampleDS(zone string) { 35 | config, _ := ClientConfigFromFile("/etc/resolv.conf") 36 | c := new(Client) 37 | m := new(Msg) 38 | if zone == "" { 39 | zone = "miek.nl" 40 | } 41 | m.SetQuestion(Fqdn(zone), TypeDNSKEY) 42 | m.SetEdns0(4096, true) 43 | r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port) 44 | if err != nil { 45 | return 46 | } 47 | if r.Rcode != RcodeSuccess { 48 | return 49 | } 50 | for _, k := range r.Answer { 51 | if key, ok := k.(*DNSKEY); ok { 52 | for _, alg := range []int{SHA1, SHA256, SHA384} { 53 | fmt.Printf("%s; %d\n", key.ToDS(alg).String(), key.Flags) 54 | } 55 | } 56 | } 57 | } 58 | 59 | // Show how to setup the authors for 'authors.bind. CH TXT' or 'authors.server. CH TXT' 60 | // queries. 61 | func ExampleAuthors() { 62 | // ... server setup is out of scope ... 63 | 64 | // Register the handle funcs. 65 | HandleFunc("authors.bind.", HandleAuthors) 66 | HandleFunc("authors.server.", HandleAuthors) 67 | 68 | // To extend the authors list, just append to dns.Authors (a []string) 69 | Authors = append(Authors, "G. I. Joe") 70 | 71 | // Or ... 72 | Authors = []string{"Just Me"} 73 | } 74 | -------------------------------------------------------------------------------- /dns/labels.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | // Holds a bunch of helper functions for dealing with labels. 8 | 9 | // SplitDomainName splits a name string into it's labels. 10 | // www.miek.nl. returns []string{"www", "miek", "nl"} 11 | // The root label (.) returns nil. 12 | func SplitDomainName(s string) (labels []string) { 13 | fqdnEnd := 0 // offset of the final '.' or the length of the name 14 | idx := Split(s) 15 | begin := 0 16 | 17 | if s[len(s)-1] == '.' { 18 | fqdnEnd = len(s) - 1 19 | } else { 20 | fqdnEnd = len(s) 21 | } 22 | 23 | switch len(idx) { 24 | case 0: 25 | return nil 26 | case 1: 27 | // no-op 28 | default: 29 | end := 0 30 | for i := 1; i < len(idx); i++ { 31 | end = idx[i] 32 | labels = append(labels, s[begin:end-1]) 33 | begin = end 34 | } 35 | } 36 | 37 | labels = append(labels, s[begin:fqdnEnd]) 38 | return labels 39 | } 40 | 41 | // CompareDomainName compares the names s1 and s2 and 42 | // returns how many labels they have in common starting from the *right*. 43 | // The comparison stops at the first inequality. The names are not downcased 44 | // before the comparison. 45 | // 46 | // www.miek.nl. and miek.nl. have two labels in common: miek and nl 47 | // www.miek.nl. and www.bla.nl. have one label in common: nl 48 | func CompareDomainName(s1, s2 string) (n int) { 49 | s1 = Fqdn(s1) 50 | s2 = Fqdn(s2) 51 | l1 := Split(s1) 52 | l2 := Split(s2) 53 | 54 | // the first check: root label 55 | if l1 == nil || l2 == nil { 56 | return 57 | } 58 | 59 | j1 := len(l1) - 1 // end 60 | i1 := len(l1) - 2 // start 61 | j2 := len(l2) - 1 62 | i2 := len(l2) - 2 63 | // the second check can be done here: last/only label 64 | // before we fall through into the for-loop below 65 | if s1[l1[j1]:] == s2[l2[j2]:] { 66 | n++ 67 | } else { 68 | return 69 | } 70 | for { 71 | if i1 < 0 || i2 < 0 { 72 | break 73 | } 74 | if s1[l1[i1]:l1[j1]] == s2[l2[i2]:l2[j2]] { 75 | n++ 76 | } else { 77 | break 78 | } 79 | j1-- 80 | i1-- 81 | j2-- 82 | i2-- 83 | } 84 | return 85 | } 86 | 87 | // CountLabel counts the the number of labels in the string s. 88 | func CountLabel(s string) (labels int) { 89 | if s == "." { 90 | return 91 | } 92 | off := 0 93 | end := false 94 | for { 95 | off, end = NextLabel(s, off) 96 | labels++ 97 | if end { 98 | return 99 | } 100 | } 101 | panic("dns: not reached") 102 | } 103 | 104 | // Split splits a name s into its label indexes. 105 | // www.miek.nl. returns []int{0, 4, 9}, www.miek.nl also returns []int{0, 4, 9}. 106 | // The root name (.) returns nil. 107 | func Split(s string) []int { 108 | if s == "." { 109 | return nil 110 | } 111 | idx := []int{0} 112 | off := 0 113 | end := false 114 | 115 | for { 116 | off, end = NextLabel(s, off) 117 | if end { 118 | return idx 119 | } 120 | idx = append(idx, off) 121 | } 122 | panic("dns: not reached") 123 | } 124 | 125 | // NextLabel returns the index of the start of the next label in the 126 | // string s starting at offset. 127 | // The bool end is true when the end of the string has been reached. 128 | func NextLabel(s string, offset int) (i int, end bool) { 129 | quote := false 130 | for i = offset; i < len(s)-1; i++ { 131 | switch s[i] { 132 | case '\\': 133 | quote = !quote 134 | default: 135 | quote = false 136 | case '.': 137 | if quote { 138 | quote = !quote 139 | continue 140 | } 141 | return i + 1, false 142 | } 143 | } 144 | return i + 1, true 145 | } 146 | 147 | // PrevLabel returns the index of the label when starting from the right and 148 | // jumping n labels to the left. 149 | // The bool start is true when the start of the string has been overshot. 150 | func PrevLabel(s string, n int) (i int, start bool) { 151 | if n == 0 { 152 | return len(s), false 153 | } 154 | lab := Split(s) 155 | if lab == nil { 156 | return 0, true 157 | } 158 | if n > len(lab) { 159 | return 0, true 160 | } 161 | return lab[len(lab)-n], false 162 | } 163 | 164 | func LenLabels(s string) int { 165 | println("LenLabels is to be removed in future versions, for the better named CountLabel") 166 | return CountLabel(s) 167 | } 168 | func SplitLabels(s string) []string { 169 | println("SplitLabels is to be removed in future versions, for the better named SplitDomainName") 170 | return SplitDomainName(s) 171 | } 172 | 173 | func CompareLabels(s1, s2 string) (n int) { 174 | println("CompareLabels is to be removed in future versions, for better named CompareDomainName") 175 | return CompareDomainName(s1, s2) 176 | } 177 | -------------------------------------------------------------------------------- /dns/nsecx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | import ( 8 | "crypto/sha1" 9 | "hash" 10 | "io" 11 | "strings" 12 | ) 13 | 14 | type saltWireFmt struct { 15 | Salt string `dns:"size-hex"` 16 | } 17 | 18 | // HashName hashes a string (label) according to RFC 5155. It returns the hashed string. 19 | func HashName(label string, ha uint8, iter uint16, salt string) string { 20 | saltwire := new(saltWireFmt) 21 | saltwire.Salt = salt 22 | wire := make([]byte, DefaultMsgSize) 23 | n, err := PackStruct(saltwire, wire, 0) 24 | if err != nil { 25 | return "" 26 | } 27 | wire = wire[:n] 28 | name := make([]byte, 255) 29 | off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false) 30 | if err != nil { 31 | return "" 32 | } 33 | name = name[:off] 34 | var s hash.Hash 35 | switch ha { 36 | case SHA1: 37 | s = sha1.New() 38 | default: 39 | return "" 40 | } 41 | 42 | // k = 0 43 | name = append(name, wire...) 44 | io.WriteString(s, string(name)) 45 | nsec3 := s.Sum(nil) 46 | // k > 0 47 | for k := uint16(0); k < iter; k++ { 48 | s.Reset() 49 | nsec3 = append(nsec3, wire...) 50 | io.WriteString(s, string(nsec3)) 51 | nsec3 = s.Sum(nil) 52 | } 53 | return unpackBase32(nsec3) 54 | } 55 | -------------------------------------------------------------------------------- /dns/nsecx_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | import ( 8 | "testing" 9 | ) 10 | 11 | func TestPackNsec3(t *testing.T) { 12 | nsec3 := HashName("dnsex.nl.", SHA1, 0, "DEAD") 13 | if nsec3 != "ROCCJAE8BJJU7HN6T7NG3TNM8ACRS87J" { 14 | t.Logf("%v\n", nsec3) 15 | t.Fail() 16 | } 17 | 18 | nsec3 = HashName("a.b.c.example.org.", SHA1, 2, "DEAD") 19 | if nsec3 != "6LQ07OAHBTOOEU2R9ANI2AT70K5O0RCG" { 20 | t.Logf("%v\n", nsec3) 21 | t.Fail() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dns/rawmsg.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | // These raw* functions do not use reflection, they directly set the values 8 | // in the buffer. There are faster than their reflection counterparts. 9 | 10 | // RawSetId sets the message id in buf. 11 | func rawSetId(msg []byte, i uint16) bool { 12 | if len(msg) < 2 { 13 | return false 14 | } 15 | msg[0], msg[1] = packUint16(i) 16 | return true 17 | } 18 | 19 | // rawSetQuestionLen sets the length of the question section. 20 | func rawSetQuestionLen(msg []byte, i uint16) bool { 21 | if len(msg) < 6 { 22 | return false 23 | } 24 | msg[4], msg[5] = packUint16(i) 25 | return true 26 | } 27 | 28 | // rawSetAnswerLen sets the lenght of the answer section. 29 | func rawSetAnswerLen(msg []byte, i uint16) bool { 30 | if len(msg) < 8 { 31 | return false 32 | } 33 | msg[6], msg[7] = packUint16(i) 34 | return true 35 | } 36 | 37 | // rawSetsNsLen sets the lenght of the authority section. 38 | func rawSetNsLen(msg []byte, i uint16) bool { 39 | if len(msg) < 10 { 40 | return false 41 | } 42 | msg[8], msg[9] = packUint16(i) 43 | return true 44 | } 45 | 46 | // rawSetExtraLen sets the lenght of the additional section. 47 | func rawSetExtraLen(msg []byte, i uint16) bool { 48 | if len(msg) < 12 { 49 | return false 50 | } 51 | msg[10], msg[11] = packUint16(i) 52 | return true 53 | } 54 | 55 | // rawSetRdlength sets the rdlength in the header of 56 | // the RR. The offset 'off' must be positioned at the 57 | // start of the header of the RR, 'end' must be the 58 | // end of the RR. 59 | func rawSetRdlength(msg []byte, off, end int) bool { 60 | l := len(msg) 61 | Loop: 62 | for { 63 | if off+1 > l { 64 | return false 65 | } 66 | c := int(msg[off]) 67 | off++ 68 | switch c & 0xC0 { 69 | case 0x00: 70 | if c == 0x00 { 71 | // End of the domainname 72 | break Loop 73 | } 74 | if off+c > l { 75 | return false 76 | } 77 | off += c 78 | 79 | case 0xC0: 80 | // pointer, next byte included, ends domainname 81 | off++ 82 | break Loop 83 | } 84 | } 85 | // The domainname has been seen, we at the start of the fixed part in the header. 86 | // Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length. 87 | off += 2 + 2 + 4 88 | if off+2 > l { 89 | return false 90 | } 91 | //off+1 is the end of the header, 'end' is the end of the rr 92 | //so 'end' - 'off+2' is the lenght of the rdata 93 | msg[off], msg[off+1] = packUint16(uint16(end - (off + 2))) 94 | return true 95 | } 96 | -------------------------------------------------------------------------------- /dns/scanner.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | // Implement a simple scanner, return a byte stream from an io reader. 8 | 9 | import ( 10 | "bufio" 11 | "io" 12 | "text/scanner" 13 | ) 14 | 15 | type scan struct { 16 | src *bufio.Reader 17 | position scanner.Position 18 | eof bool // Have we just seen a eof 19 | } 20 | 21 | func scanInit(r io.Reader) *scan { 22 | s := new(scan) 23 | s.src = bufio.NewReader(r) 24 | s.position.Line = 1 25 | return s 26 | } 27 | 28 | // tokenText returns the next byte from the input 29 | func (s *scan) tokenText() (byte, error) { 30 | c, err := s.src.ReadByte() 31 | if err != nil { 32 | return c, err 33 | } 34 | // delay the newline handling until the next token is delivered, 35 | // fixes off-by-one errors when reporting a parse error. 36 | if s.eof == true { 37 | s.position.Line++ 38 | s.position.Column = 0 39 | s.eof = false 40 | } 41 | if c == '\n' { 42 | s.eof = true 43 | return c, nil 44 | } 45 | s.position.Column++ 46 | return c, nil 47 | } 48 | -------------------------------------------------------------------------------- /dns/server_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | import ( 8 | "runtime" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func HelloServer(w ResponseWriter, req *Msg) { 14 | m := new(Msg) 15 | m.SetReply(req) 16 | 17 | m.Extra = make([]RR, 1) 18 | m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} 19 | w.WriteMsg(m) 20 | } 21 | 22 | func AnotherHelloServer(w ResponseWriter, req *Msg) { 23 | m := new(Msg) 24 | m.SetReply(req) 25 | 26 | m.Extra = make([]RR, 1) 27 | m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello example"}} 28 | w.WriteMsg(m) 29 | } 30 | 31 | func TestServing(t *testing.T) { 32 | HandleFunc("miek.nl.", HelloServer) 33 | HandleFunc("example.com.", AnotherHelloServer) 34 | go func() { 35 | err := ListenAndServe(":8053", "udp", nil) 36 | if err != nil { 37 | t.Log("ListenAndServe: ", err.Error()) 38 | t.Fail() 39 | } 40 | }() 41 | time.Sleep(4e8) 42 | c := new(Client) 43 | m := new(Msg) 44 | m.SetQuestion("miek.nl.", TypeTXT) 45 | r, _, _ := c.Exchange(m, "127.0.0.1:8053") 46 | txt := r.Extra[0].(*TXT).Txt[0] 47 | if txt != "Hello world" { 48 | t.Log("Unexpected result for miek.nl", txt, "!= Hello world") 49 | t.Fail() 50 | } 51 | m.SetQuestion("example.com.", TypeTXT) 52 | r, _, _ = c.Exchange(m, "127.0.0.1:8053") 53 | txt = r.Extra[0].(*TXT).Txt[0] 54 | if txt != "Hello example" { 55 | t.Log("Unexpected result for example.com", txt, "!= Hello example") 56 | t.Fail() 57 | } 58 | // Test Mixes cased as notices by Ask. 59 | m.SetQuestion("eXaMplE.cOm.", TypeTXT) 60 | r, _, _ = c.Exchange(m, "127.0.0.1:8053") 61 | txt = r.Extra[0].(*TXT).Txt[0] 62 | if txt != "Hello example" { 63 | t.Log("Unexpected result for example.com", txt, "!= Hello example") 64 | t.Fail() 65 | } 66 | } 67 | 68 | func BenchmarkServing(b *testing.B) { 69 | b.StopTimer() 70 | HandleFunc("miek.nl.", HelloServer) 71 | a := runtime.GOMAXPROCS(4) 72 | go func() { 73 | ListenAndServe("127.0.0.1:8053", "udp", nil) 74 | }() 75 | c := new(Client) 76 | m := new(Msg) 77 | m.SetQuestion("miek.nl", TypeSOA) 78 | 79 | b.StartTimer() 80 | for i := 0; i < b.N; i++ { 81 | c.Exchange(m, "127.0.0.1:8053") 82 | } 83 | runtime.GOMAXPROCS(a) 84 | } 85 | 86 | func HelloServerCompress(w ResponseWriter, req *Msg) { 87 | m := new(Msg) 88 | m.SetReply(req) 89 | m.Extra = make([]RR, 1) 90 | m.Extra[0] = &TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} 91 | m.Compress = true 92 | w.WriteMsg(m) 93 | } 94 | 95 | func BenchmarkServingCompress(b *testing.B) { 96 | b.StopTimer() 97 | HandleFunc("miek.nl.", HelloServerCompress) 98 | a := runtime.GOMAXPROCS(4) 99 | go func() { 100 | ListenAndServe("127.0.0.1:8053", "udp", nil) 101 | }() 102 | 103 | c := new(Client) 104 | m := new(Msg) 105 | m.SetQuestion("miek.nl", TypeSOA) 106 | b.StartTimer() 107 | for i := 0; i < b.N; i++ { 108 | c.Exchange(m, "127.0.0.1:8053") 109 | } 110 | runtime.GOMAXPROCS(a) 111 | } 112 | 113 | func TestDotAsCatchAllWildcard(t *testing.T) { 114 | mux := NewServeMux() 115 | mux.Handle(".", HandlerFunc(HelloServer)) 116 | mux.Handle("example.com.", HandlerFunc(AnotherHelloServer)) 117 | 118 | handler := mux.match("www.miek.nl.", TypeTXT) 119 | if handler == nil { 120 | t.Error("wildcard match failed") 121 | } 122 | 123 | handler = mux.match("www.example.com.", TypeTXT) 124 | if handler == nil { 125 | t.Error("example.com match failed") 126 | } 127 | 128 | handler = mux.match("a.www.example.com.", TypeTXT) 129 | if handler == nil { 130 | t.Error("a.www.example.com match failed") 131 | } 132 | 133 | handler = mux.match("boe.", TypeTXT) 134 | if handler == nil { 135 | t.Error("boe. match failed") 136 | } 137 | } 138 | 139 | func TestRootServer(t *testing.T) { 140 | mux := NewServeMux() 141 | mux.Handle(".", HandlerFunc(HelloServer)) 142 | 143 | handler := mux.match(".", TypeNS) 144 | if handler == nil { 145 | t.Error("root match failed") 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /dns/singleinflight.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Adapted for dns package usage by Miek Gieben. 6 | 7 | package dns 8 | 9 | import "sync" 10 | import "time" 11 | 12 | // call is an in-flight or completed singleflight.Do call 13 | type call struct { 14 | wg sync.WaitGroup 15 | val *Msg 16 | rtt time.Duration 17 | err error 18 | dups int 19 | } 20 | 21 | // singleflight represents a class of work and forms a namespace in 22 | // which units of work can be executed with duplicate suppression. 23 | type singleflight struct { 24 | sync.Mutex // protects m 25 | m map[string]*call // lazily initialized 26 | } 27 | 28 | // Do executes and returns the results of the given function, making 29 | // sure that only one execution is in-flight for a given key at a 30 | // time. If a duplicate comes in, the duplicate caller waits for the 31 | // original to complete and receives the same results. 32 | // The return value shared indicates whether v was given to multiple callers. 33 | func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v *Msg, rtt time.Duration, err error, shared bool) { 34 | g.Lock() 35 | if g.m == nil { 36 | g.m = make(map[string]*call) 37 | } 38 | if c, ok := g.m[key]; ok { 39 | c.dups++ 40 | g.Unlock() 41 | c.wg.Wait() 42 | return c.val, c.rtt, c.err, true 43 | } 44 | c := new(call) 45 | c.wg.Add(1) 46 | g.m[key] = c 47 | g.Unlock() 48 | 49 | c.val, c.rtt, c.err = fn() 50 | c.wg.Done() 51 | 52 | g.Lock() 53 | delete(g.m, key) 54 | g.Unlock() 55 | 56 | return c.val, c.rtt, c.err, c.dups > 0 57 | } 58 | -------------------------------------------------------------------------------- /dns/tlsa.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | import ( 8 | "crypto/sha256" 9 | "crypto/sha512" 10 | "crypto/x509" 11 | "encoding/hex" 12 | "errors" 13 | "io" 14 | "net" 15 | "strconv" 16 | ) 17 | 18 | // CertificateToDANE converts a certificate to a hex string as used in the TLSA record. 19 | func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) { 20 | switch matchingType { 21 | case 0: 22 | switch selector { 23 | case 0: 24 | return hex.EncodeToString(cert.Raw), nil 25 | case 1: 26 | return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil 27 | } 28 | case 1: 29 | h := sha256.New() 30 | switch selector { 31 | case 0: 32 | return hex.EncodeToString(cert.Raw), nil 33 | case 1: 34 | io.WriteString(h, string(cert.RawSubjectPublicKeyInfo)) 35 | return hex.EncodeToString(h.Sum(nil)), nil 36 | } 37 | case 2: 38 | h := sha512.New() 39 | switch selector { 40 | case 0: 41 | return hex.EncodeToString(cert.Raw), nil 42 | case 1: 43 | io.WriteString(h, string(cert.RawSubjectPublicKeyInfo)) 44 | return hex.EncodeToString(h.Sum(nil)), nil 45 | } 46 | } 47 | return "", errors.New("dns: bad TLSA MatchingType or TLSA Selector") 48 | } 49 | 50 | // Sign creates a TLSA record from an SSL certificate. 51 | func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { 52 | r.Hdr.Rrtype = TypeTLSA 53 | r.Usage = uint8(usage) 54 | r.Selector = uint8(selector) 55 | r.MatchingType = uint8(matchingType) 56 | 57 | r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert) 58 | if err != nil { 59 | return err 60 | } 61 | return nil 62 | } 63 | 64 | // Verify verifies a TLSA record against an SSL certificate. If it is OK 65 | // a nil error is returned. 66 | func (r *TLSA) Verify(cert *x509.Certificate) error { 67 | c, err := CertificateToDANE(r.Selector, r.MatchingType, cert) 68 | if err != nil { 69 | return err // Not also ErrSig? 70 | } 71 | if r.Certificate == c { 72 | return nil 73 | } 74 | return ErrSig // ErrSig, really? 75 | } 76 | 77 | // TLSAName returns the ownername of a TLSA resource record as per the 78 | // rules specified in RFC 6698, Section 3. 79 | func TLSAName(name, service, network string) (string, error) { 80 | if !IsFqdn(name) { 81 | return "", ErrFqdn 82 | } 83 | p, e := net.LookupPort(network, service) 84 | if e != nil { 85 | return "", e 86 | } 87 | return "_" + strconv.Itoa(p) + "_" + network + "." + name, nil 88 | } 89 | -------------------------------------------------------------------------------- /dns/zgenerate.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Miek Gieben. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package dns 6 | 7 | import ( 8 | "fmt" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | // Parse the $GENERATE statement as used in BIND9 zones. 14 | // See http://www.zytrax.com/books/dns/ch8/generate.html for instance. 15 | // We are called after '$GENERATE '. After which we expect: 16 | // * the range (12-24/2) 17 | // * lhs (ownername) 18 | // * [[ttl][class]] 19 | // * type 20 | // * rhs (rdata) 21 | // But we are lazy here, only the range is parsed *all* occurences 22 | // of $ after that are interpreted. 23 | // Any error are returned as a string value, the empty string signals 24 | // "no error". 25 | func generate(l lex, c chan lex, t chan Token, o string) string { 26 | step := 1 27 | if i := strings.IndexAny(l.token, "/"); i != -1 { 28 | if i+1 == len(l.token) { 29 | return "bad step in $GENERATE range" 30 | } 31 | if s, e := strconv.Atoi(l.token[i+1:]); e != nil { 32 | return "bad step in $GENERATE range" 33 | } else { 34 | if s < 0 { 35 | return "bad step in $GENERATE range" 36 | } 37 | step = s 38 | } 39 | l.token = l.token[:i] 40 | } 41 | sx := strings.SplitN(l.token, "-", 2) 42 | if len(sx) != 2 { 43 | return "bad start-stop in $GENERATE range" 44 | } 45 | start, err := strconv.Atoi(sx[0]) 46 | if err != nil { 47 | return "bad start in $GENERATE range" 48 | } 49 | end, err := strconv.Atoi(sx[1]) 50 | if err != nil { 51 | return "bad stop in $GENERATE range" 52 | } 53 | if end < 0 || start < 0 || end <= start { 54 | return "bad range in $GENERATE range" 55 | } 56 | 57 | <-c // _BLANK 58 | // Create a complete new string, which we then parse again. 59 | s := "" 60 | BuildRR: 61 | l = <-c 62 | if l.value != _NEWLINE && l.value != _EOF { 63 | s += l.token 64 | goto BuildRR 65 | } 66 | for i := start; i <= end; i += step { 67 | var ( 68 | escape bool 69 | dom string 70 | mod string 71 | err string 72 | offset int 73 | ) 74 | 75 | for j := 0; j < len(s); j++ { // No 'range' because we need to jump around 76 | switch s[j] { 77 | case '\\': 78 | if escape { 79 | dom += "\\" 80 | escape = false 81 | continue 82 | } 83 | escape = true 84 | case '$': 85 | mod = "%d" 86 | offset = 0 87 | if escape { 88 | dom += "$" 89 | escape = false 90 | continue 91 | } 92 | escape = false 93 | if j+1 >= len(s) { // End of the string 94 | dom += fmt.Sprintf(mod, i+offset) 95 | continue 96 | } else { 97 | if s[j+1] == '$' { 98 | dom += "$" 99 | j++ 100 | continue 101 | } 102 | } 103 | // Search for { and } 104 | if s[j+1] == '{' { // Modifier block 105 | sep := strings.Index(s[j+2:], "}") 106 | if sep == -1 { 107 | return "bad modifier in $GENERATE" 108 | } 109 | mod, offset, err = modToPrintf(s[j+2 : j+2+sep]) 110 | if err != "" { 111 | return err 112 | } 113 | j += 2 + sep // Jump to it 114 | } 115 | dom += fmt.Sprintf(mod, i+offset) 116 | default: 117 | if escape { // Pretty useless here 118 | escape = false 119 | continue 120 | } 121 | dom += string(s[j]) 122 | } 123 | } 124 | // Re-parse the RR and send it on the current channel t 125 | rx, e := NewRR("$ORIGIN " + o + "\n" + dom) 126 | if e != nil { 127 | return e.(*ParseError).err 128 | } 129 | t <- Token{RR: rx} 130 | // Its more efficient to first built the rrlist and then parse it in 131 | // one go! But is this a problem? 132 | } 133 | return "" 134 | } 135 | 136 | // Convert a $GENERATE modifier 0,0,d to something Printf can deal with. 137 | func modToPrintf(s string) (string, int, string) { 138 | xs := strings.SplitN(s, ",", 3) 139 | if len(xs) != 3 { 140 | return "", 0, "bad modifier in $GENERATE" 141 | } 142 | // xs[0] is offset, xs[1] is width, xs[2] is base 143 | if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" { 144 | return "", 0, "bad base in $GENERATE" 145 | } 146 | offset, err := strconv.Atoi(xs[0]) 147 | if err != nil { 148 | return "", 0, "bad offset in $GENERATE" 149 | } 150 | width, err := strconv.Atoi(xs[1]) 151 | if err != nil { 152 | return "", offset, "bad width in $GENERATE" 153 | } 154 | switch { 155 | case width < 0: 156 | return "", offset, "bad width in $GENERATE" 157 | case width == 0: 158 | return "%" + xs[1] + xs[2], offset, "" 159 | default: 160 | return "%0" + xs[1] + xs[2], offset, "" 161 | } 162 | panic("dns: not reached") 163 | } 164 | -------------------------------------------------------------------------------- /dns_server_mx.json: -------------------------------------------------------------------------------- 1 | { 2 | "Id": 5102, 3 | "Response": true, 4 | "Opcode": 0, 5 | "Authoritative": false, 6 | "Truncated": false, 7 | "RecursionDesired": true, 8 | "RecursionAvailable": true, 9 | "Zero": false, 10 | "AuthenticatedData": false, 11 | "CheckingDisabled": false, 12 | "Rcode": 0, 13 | "Question": [ 14 | { 15 | "Name": "baidu.com.", 16 | "Qtype": 15, 17 | "Qclass": 1 18 | } 19 | ], 20 | "Answer": [ 21 | { 22 | "Hdr": { 23 | "Name": "baidu.com.", 24 | "Rrtype": 15, 25 | "Class": 1, 26 | "Ttl": 5019, 27 | "Rdlength": 8 28 | }, 29 | "Preference": 20, 30 | "Mx": "mx1.baidu.com." 31 | }, 32 | { 33 | "Hdr": { 34 | "Name": "baidu.com.", 35 | "Rrtype": 15, 36 | "Class": 1, 37 | "Ttl": 5019, 38 | "Rdlength": 9 39 | }, 40 | "Preference": 20, 41 | "Mx": "jpmx.baidu.com." 42 | }, 43 | { 44 | "Hdr": { 45 | "Name": "baidu.com.", 46 | "Rrtype": 15, 47 | "Class": 1, 48 | "Ttl": 5019, 49 | "Rdlength": 16 50 | }, 51 | "Preference": 15, 52 | "Mx": "mx.n.shifen.com." 53 | }, 54 | { 55 | "Hdr": { 56 | "Name": "baidu.com.", 57 | "Rrtype": 15, 58 | "Class": 1, 59 | "Ttl": 5019, 60 | "Rdlength": 14 61 | }, 62 | "Preference": 10, 63 | "Mx": "mx.maillb.baidu.com." 64 | }, 65 | { 66 | "Hdr": { 67 | "Name": "baidu.com.", 68 | "Rrtype": 15, 69 | "Class": 1, 70 | "Ttl": 5019, 71 | "Rdlength": 9 72 | }, 73 | "Preference": 20, 74 | "Mx": "mx50.baidu.com." 75 | } 76 | ], 77 | "Ns": [], 78 | "Extra": [] 79 | } -------------------------------------------------------------------------------- /dns_server_text.json: -------------------------------------------------------------------------------- 1 | { 2 | "Id": 50334, 3 | "Response": true, 4 | "Opcode": 0, 5 | "Authoritative": false, 6 | "Truncated": false, 7 | "RecursionDesired": true, 8 | "RecursionAvailable": false, 9 | "Zero": false, 10 | "AuthenticatedData": false, 11 | "CheckingDisabled": false, 12 | "Rcode": 0, 13 | "Question": [ 14 | { 15 | "Name": "baidu.com.", 16 | "Qtype": 16, 17 | "Qclass": 1 18 | } 19 | ], 20 | "Answer": [], 21 | "Ns": [], 22 | "Extra": [ 23 | { 24 | "Hdr": { 25 | "Name": "baidu.com.", 26 | "Rrtype": 16, 27 | "Class": 1, 28 | "Ttl": 0, 29 | "Rdlength": 12 30 | }, 31 | "Txt": [ 32 | "Hello world" 33 | ] 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /dnstunnel_client.linux64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/dnstunnel_client.linux64 -------------------------------------------------------------------------------- /dnstunnel_client.win64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/dnstunnel_client.win64 -------------------------------------------------------------------------------- /dnstunnel_server.linux64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/dnstunnel_server.linux64 -------------------------------------------------------------------------------- /dnstunnel_server.win64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/dnstunnel_server.win64 -------------------------------------------------------------------------------- /generator/generator.bak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/generator/generator.bak -------------------------------------------------------------------------------- /generator/generator.e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/generator/generator.e -------------------------------------------------------------------------------- /http_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net/http" 7 | "strings" 8 | "testing" 9 | ) 10 | 11 | func TestHttpOff(t *testing.T) { 12 | fmt.Println(strings.Trim(" abc ", " ")) 13 | resp, err := http.Post("http://127.0.0.1:8081/off", 14 | "text/plain", 15 | strings.NewReader("1111111111111111")) 16 | if err != nil { 17 | fmt.Println(err) 18 | return 19 | } 20 | 21 | defer resp.Body.Close() 22 | body, err := ioutil.ReadAll(resp.Body) 23 | if err != nil { 24 | fmt.Println(err) 25 | return 26 | } 27 | 28 | fmt.Println(string(body)) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/cases/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cases_test 6 | 7 | import ( 8 | "fmt" 9 | 10 | "golang.org/x/text/cases" 11 | "golang.org/x/text/language" 12 | ) 13 | 14 | func Example() { 15 | src := []string{ 16 | "hello world!", 17 | "i with dot", 18 | "'n ijsberg", 19 | "here comes O'Brian", 20 | } 21 | for _, c := range []cases.Caser{ 22 | cases.Lower(language.Und), 23 | cases.Upper(language.Turkish), 24 | cases.Title(language.Dutch), 25 | cases.Title(language.Und, cases.NoLower), 26 | } { 27 | fmt.Println() 28 | for _, s := range src { 29 | fmt.Println(c.String(s)) 30 | } 31 | } 32 | 33 | // Output: 34 | // hello world! 35 | // i with dot 36 | // 'n ijsberg 37 | // here comes o'brian 38 | // 39 | // HELLO WORLD! 40 | // İ WİTH DOT 41 | // 'N İJSBERG 42 | // HERE COMES O'BRİAN 43 | // 44 | // Hello World! 45 | // I With Dot 46 | // 'n IJsberg 47 | // Here Comes O'brian 48 | // 49 | // Hello World! 50 | // I With Dot 51 | // 'N Ijsberg 52 | // Here Comes O'Brian 53 | } 54 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/cases/fold.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cases 6 | 7 | import "golang.org/x/text/transform" 8 | 9 | type caseFolder struct{ transform.NopResetter } 10 | 11 | // caseFolder implements the Transformer interface for doing case folding. 12 | func (t *caseFolder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 13 | c := context{dst: dst, src: src, atEOF: atEOF} 14 | for c.next() { 15 | foldFull(&c) 16 | c.checkpoint() 17 | } 18 | return c.ret() 19 | } 20 | 21 | func (t *caseFolder) Span(src []byte, atEOF bool) (n int, err error) { 22 | c := context{src: src, atEOF: atEOF} 23 | for c.next() && isFoldFull(&c) { 24 | c.checkpoint() 25 | } 26 | return c.retSpan() 27 | } 28 | 29 | func makeFold(o options) transform.SpanningTransformer { 30 | // TODO: Special case folding, through option Language, Special/Turkic, or 31 | // both. 32 | // TODO: Implement Compact options. 33 | return &caseFolder{} 34 | } 35 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/cases/fold_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cases 6 | 7 | import ( 8 | "testing" 9 | 10 | "golang.org/x/text/internal/testtext" 11 | ) 12 | 13 | var foldTestCases = []string{ 14 | "βß\u13f8", // "βssᏰ" 15 | "ab\u13fc\uab7aꭰ", // abᏴᎪᎠ 16 | "affifflast", // affifflast 17 | "Iİiı\u0345", // ii̇iıι 18 | "µµΜΜςσΣΣ", // μμμμσσσσ 19 | } 20 | 21 | func TestFold(t *testing.T) { 22 | for _, tc := range foldTestCases { 23 | testEntry := func(name string, c Caser, m func(r rune) string) { 24 | want := "" 25 | for _, r := range tc { 26 | want += m(r) 27 | } 28 | if got := c.String(tc); got != want { 29 | t.Errorf("%s(%s) = %+q; want %+q", name, tc, got, want) 30 | } 31 | dst := make([]byte, 256) // big enough to hold any result 32 | src := []byte(tc) 33 | v := testtext.AllocsPerRun(20, func() { 34 | c.Transform(dst, src, true) 35 | }) 36 | if v > 0 { 37 | t.Errorf("%s(%s): number of allocs was %f; want 0", name, tc, v) 38 | } 39 | } 40 | testEntry("FullFold", Fold(), func(r rune) string { 41 | return runeFoldData(r).full 42 | }) 43 | // TODO: 44 | // testEntry("SimpleFold", Fold(Compact), func(r rune) string { 45 | // return runeFoldData(r).simple 46 | // }) 47 | // testEntry("SpecialFold", Fold(Turkic), func(r rune) string { 48 | // return runeFoldData(r).special 49 | // }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/cases/icu.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build icu 6 | 7 | package cases 8 | 9 | // Ideally these functions would be defined in a test file, but go test doesn't 10 | // allow CGO in tests. The build tag should ensure either way that these 11 | // functions will not end up in the package. 12 | 13 | // TODO: Ensure that the correct ICU version is set. 14 | 15 | /* 16 | #cgo LDFLAGS: -licui18n.57 -licuuc.57 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | */ 23 | import "C" 24 | 25 | import "unsafe" 26 | 27 | func doICU(tag, caser, input string) string { 28 | err := C.UErrorCode(0) 29 | loc := C.CString(tag) 30 | cm := C.ucasemap_open(loc, C.uint32_t(0), &err) 31 | 32 | buf := make([]byte, len(input)*4) 33 | dst := (*C.char)(unsafe.Pointer(&buf[0])) 34 | src := C.CString(input) 35 | 36 | cn := C.int32_t(0) 37 | 38 | switch caser { 39 | case "fold": 40 | cn = C.ucasemap_utf8FoldCase(cm, 41 | dst, C.int32_t(len(buf)), 42 | src, C.int32_t(len(input)), 43 | &err) 44 | case "lower": 45 | cn = C.ucasemap_utf8ToLower(cm, 46 | dst, C.int32_t(len(buf)), 47 | src, C.int32_t(len(input)), 48 | &err) 49 | case "upper": 50 | cn = C.ucasemap_utf8ToUpper(cm, 51 | dst, C.int32_t(len(buf)), 52 | src, C.int32_t(len(input)), 53 | &err) 54 | case "title": 55 | cn = C.ucasemap_utf8ToTitle(cm, 56 | dst, C.int32_t(len(buf)), 57 | src, C.int32_t(len(input)), 58 | &err) 59 | } 60 | return string(buf[:cn]) 61 | } 62 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/cases/info.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cases 6 | 7 | func (c info) cccVal() info { 8 | if c&exceptionBit != 0 { 9 | return info(exceptions[c>>exceptionShift]) & cccMask 10 | } 11 | return c & cccMask 12 | } 13 | 14 | func (c info) cccType() info { 15 | ccc := c.cccVal() 16 | if ccc <= cccZero { 17 | return cccZero 18 | } 19 | return ccc 20 | } 21 | 22 | // TODO: Implement full Unicode breaking algorithm: 23 | // 1) Implement breaking in separate package. 24 | // 2) Use the breaker here. 25 | // 3) Compare table size and performance of using the more generic breaker. 26 | // 27 | // Note that we can extend the current algorithm to be much more accurate. This 28 | // only makes sense, though, if the performance and/or space penalty of using 29 | // the generic breaker is big. Extra data will only be needed for non-cased 30 | // runes, which means there are sufficient bits left in the caseType. 31 | // ICU prohibits breaking in such cases as well. 32 | 33 | // For the purpose of title casing we use an approximation of the Unicode Word 34 | // Breaking algorithm defined in Annex #29: 35 | // https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table. 36 | // 37 | // For our approximation, we group the Word Break types into the following 38 | // categories, with associated rules: 39 | // 40 | // 1) Letter: 41 | // ALetter, Hebrew_Letter, Numeric, ExtendNumLet, Extend, Format_FE, ZWJ. 42 | // Rule: Never break between consecutive runes of this category. 43 | // 44 | // 2) Mid: 45 | // MidLetter, MidNumLet, Single_Quote. 46 | // (Cf. case-ignorable: MidLetter, MidNumLet, Single_Quote or cat is Mn, 47 | // Me, Cf, Lm or Sk). 48 | // Rule: Don't break between Letter and Mid, but break between two Mids. 49 | // 50 | // 3) Break: 51 | // Any other category: NewLine, MidNum, CR, LF, Double_Quote, Katakana, and 52 | // Other. 53 | // These categories should always result in a break between two cased letters. 54 | // Rule: Always break. 55 | // 56 | // Note 1: the Katakana and MidNum categories can, in esoteric cases, result in 57 | // preventing a break between two cased letters. For now we will ignore this 58 | // (e.g. [ALetter] [ExtendNumLet] [Katakana] [ExtendNumLet] [ALetter] and 59 | // [ALetter] [Numeric] [MidNum] [Numeric] [ALetter].) 60 | // 61 | // Note 2: the rule for Mid is very approximate, but works in most cases. To 62 | // improve, we could store the categories in the trie value and use a FA to 63 | // manage breaks. See TODO comment above. 64 | // 65 | // Note 3: according to the spec, it is possible for the Extend category to 66 | // introduce breaks between other categories grouped in Letter. However, this 67 | // is undesirable for our purposes. ICU prevents breaks in such cases as well. 68 | 69 | // isBreak returns whether this rune should introduce a break. 70 | func (c info) isBreak() bool { 71 | return c.cccVal() == cccBreak 72 | } 73 | 74 | // isLetter returns whether the rune is of break type ALetter, Hebrew_Letter, 75 | // Numeric, ExtendNumLet, or Extend. 76 | func (c info) isLetter() bool { 77 | ccc := c.cccVal() 78 | if ccc == cccZero { 79 | return !c.isCaseIgnorable() 80 | } 81 | return ccc != cccBreak 82 | } 83 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package encoding_test 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | "os" 11 | "strings" 12 | 13 | "golang.org/x/text/encoding" 14 | "golang.org/x/text/encoding/charmap" 15 | "golang.org/x/text/encoding/unicode" 16 | "golang.org/x/text/transform" 17 | ) 18 | 19 | func ExampleDecodeWindows1252() { 20 | sr := strings.NewReader("Gar\xe7on !") 21 | tr := charmap.Windows1252.NewDecoder().Reader(sr) 22 | io.Copy(os.Stdout, tr) 23 | // Output: Garçon ! 24 | } 25 | 26 | func ExampleUTF8Validator() { 27 | for i := 0; i < 2; i++ { 28 | var transformer transform.Transformer 29 | transformer = unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM).NewEncoder() 30 | if i == 1 { 31 | transformer = transform.Chain(encoding.UTF8Validator, transformer) 32 | } 33 | dst := make([]byte, 256) 34 | src := []byte("abc\xffxyz") // src is invalid UTF-8. 35 | nDst, nSrc, err := transformer.Transform(dst, src, true) 36 | fmt.Printf("i=%d: produced %q, consumed %q, error %v\n", 37 | i, dst[:nDst], src[:nSrc], err) 38 | } 39 | // Output: 40 | // i=0: produced "\x00a\x00b\x00c\xff\xfd\x00x\x00y\x00z", consumed "abc\xffxyz", error 41 | // i=1: produced "\x00a\x00b\x00c", consumed "abc", error encoding: invalid UTF-8 42 | } 43 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/internal/identifier/gen.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package identifier 8 | 9 | import ( 10 | "bytes" 11 | "encoding/xml" 12 | "fmt" 13 | "io" 14 | "log" 15 | "strings" 16 | 17 | "golang.org/x/text/internal/gen" 18 | ) 19 | 20 | type registry struct { 21 | XMLName xml.Name `xml:"registry"` 22 | Updated string `xml:"updated"` 23 | Registry []struct { 24 | ID string `xml:"id,attr"` 25 | Record []struct { 26 | Name string `xml:"name"` 27 | Xref []struct { 28 | Type string `xml:"type,attr"` 29 | Data string `xml:"data,attr"` 30 | } `xml:"xref"` 31 | Desc struct { 32 | Data string `xml:",innerxml"` 33 | // Any []struct { 34 | // Data string `xml:",chardata"` 35 | // } `xml:",any"` 36 | // Data string `xml:",chardata"` 37 | } `xml:"description,"` 38 | MIB string `xml:"value"` 39 | Alias []string `xml:"alias"` 40 | MIME string `xml:"preferred_alias"` 41 | } `xml:"record"` 42 | } `xml:"registry"` 43 | } 44 | 45 | func main() { 46 | r := gen.OpenIANAFile("assignments/character-sets/character-sets.xml") 47 | reg := ®istry{} 48 | if err := xml.NewDecoder(r).Decode(®); err != nil && err != io.EOF { 49 | log.Fatalf("Error decoding charset registry: %v", err) 50 | } 51 | if len(reg.Registry) == 0 || reg.Registry[0].ID != "character-sets-1" { 52 | log.Fatalf("Unexpected ID %s", reg.Registry[0].ID) 53 | } 54 | 55 | w := &bytes.Buffer{} 56 | fmt.Fprintf(w, "const (\n") 57 | for _, rec := range reg.Registry[0].Record { 58 | constName := "" 59 | for _, a := range rec.Alias { 60 | if strings.HasPrefix(a, "cs") && strings.IndexByte(a, '-') == -1 { 61 | // Some of the constant definitions have comments in them. Strip those. 62 | constName = strings.Title(strings.SplitN(a[2:], "\n", 2)[0]) 63 | } 64 | } 65 | if constName == "" { 66 | switch rec.MIB { 67 | case "2085": 68 | constName = "HZGB2312" // Not listed as alias for some reason. 69 | default: 70 | log.Fatalf("No cs alias defined for %s.", rec.MIB) 71 | } 72 | } 73 | if rec.MIME != "" { 74 | rec.MIME = fmt.Sprintf(" (MIME: %s)", rec.MIME) 75 | } 76 | fmt.Fprintf(w, "// %s is the MIB identifier with IANA name %s%s.\n//\n", constName, rec.Name, rec.MIME) 77 | if len(rec.Desc.Data) > 0 { 78 | fmt.Fprint(w, "// ") 79 | d := xml.NewDecoder(strings.NewReader(rec.Desc.Data)) 80 | inElem := true 81 | attr := "" 82 | for { 83 | t, err := d.Token() 84 | if err != nil { 85 | if err != io.EOF { 86 | log.Fatal(err) 87 | } 88 | break 89 | } 90 | switch x := t.(type) { 91 | case xml.CharData: 92 | attr = "" // Don't need attribute info. 93 | a := bytes.Split([]byte(x), []byte("\n")) 94 | for i, b := range a { 95 | if b = bytes.TrimSpace(b); len(b) != 0 { 96 | if !inElem && i > 0 { 97 | fmt.Fprint(w, "\n// ") 98 | } 99 | inElem = false 100 | fmt.Fprintf(w, "%s ", string(b)) 101 | } 102 | } 103 | case xml.StartElement: 104 | if x.Name.Local == "xref" { 105 | inElem = true 106 | use := false 107 | for _, a := range x.Attr { 108 | if a.Name.Local == "type" { 109 | use = use || a.Value != "person" 110 | } 111 | if a.Name.Local == "data" && use { 112 | attr = a.Value + " " 113 | } 114 | } 115 | } 116 | case xml.EndElement: 117 | inElem = false 118 | fmt.Fprint(w, attr) 119 | } 120 | } 121 | fmt.Fprint(w, "\n") 122 | } 123 | for _, x := range rec.Xref { 124 | switch x.Type { 125 | case "rfc": 126 | fmt.Fprintf(w, "// Reference: %s\n", strings.ToUpper(x.Data)) 127 | case "uri": 128 | fmt.Fprintf(w, "// Reference: %s\n", x.Data) 129 | } 130 | } 131 | fmt.Fprintf(w, "%s MIB = %s\n", constName, rec.MIB) 132 | fmt.Fprintln(w) 133 | } 134 | fmt.Fprintln(w, ")") 135 | 136 | gen.WriteGoFile("mib.go", "identifier", w.Bytes()) 137 | } 138 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/internal/identifier/identifier.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:generate go run gen.go 6 | 7 | // Package identifier defines the contract between implementations of Encoding 8 | // and Index by defining identifiers that uniquely identify standardized coded 9 | // character sets (CCS) and character encoding schemes (CES), which we will 10 | // together refer to as encodings, for which Encoding implementations provide 11 | // converters to and from UTF-8. This package is typically only of concern to 12 | // implementers of Indexes and Encodings. 13 | // 14 | // One part of the identifier is the MIB code, which is defined by IANA and 15 | // uniquely identifies a CCS or CES. Each code is associated with data that 16 | // references authorities, official documentation as well as aliases and MIME 17 | // names. 18 | // 19 | // Not all CESs are covered by the IANA registry. The "other" string that is 20 | // returned by ID can be used to identify other character sets or versions of 21 | // existing ones. 22 | // 23 | // It is recommended that each package that provides a set of Encodings provide 24 | // the All and Common variables to reference all supported encodings and 25 | // commonly used subset. This allows Index implementations to include all 26 | // available encodings without explicitly referencing or knowing about them. 27 | package identifier 28 | 29 | // Note: this package is internal, but could be made public if there is a need 30 | // for writing third-party Indexes and Encodings. 31 | 32 | // References: 33 | // - http://source.icu-project.org/repos/icu/icu/trunk/source/data/mappings/convrtrs.txt 34 | // - http://www.iana.org/assignments/character-sets/character-sets.xhtml 35 | // - http://www.iana.org/assignments/ianacharset-mib/ianacharset-mib 36 | // - http://www.ietf.org/rfc/rfc2978.txt 37 | // - https://www.unicode.org/reports/tr22/ 38 | // - http://www.w3.org/TR/encoding/ 39 | // - https://encoding.spec.whatwg.org/ 40 | // - https://encoding.spec.whatwg.org/encodings.json 41 | // - https://tools.ietf.org/html/rfc6657#section-5 42 | 43 | // Interface can be implemented by Encodings to define the CCS or CES for which 44 | // it implements conversions. 45 | type Interface interface { 46 | // ID returns an encoding identifier. Exactly one of the mib and other 47 | // values should be non-zero. 48 | // 49 | // In the usual case it is only necessary to indicate the MIB code. The 50 | // other string can be used to specify encodings for which there is no MIB, 51 | // such as "x-mac-dingbat". 52 | // 53 | // The other string may only contain the characters a-z, A-Z, 0-9, - and _. 54 | ID() (mib MIB, other string) 55 | 56 | // NOTE: the restrictions on the encoding are to allow extending the syntax 57 | // with additional information such as versions, vendors and other variants. 58 | } 59 | 60 | // A MIB identifies an encoding. It is derived from the IANA MIB codes and adds 61 | // some identifiers for some encodings that are not covered by the IANA 62 | // standard. 63 | // 64 | // See http://www.iana.org/assignments/ianacharset-mib. 65 | type MIB uint16 66 | 67 | // These additional MIB types are not defined in IANA. They are added because 68 | // they are common and defined within the text repo. 69 | const ( 70 | // Unofficial marks the start of encodings not registered by IANA. 71 | Unofficial MIB = 10000 + iota 72 | 73 | // Replacement is the WhatWG replacement encoding. 74 | Replacement 75 | 76 | // XUserDefined is the code for x-user-defined. 77 | XUserDefined 78 | 79 | // MacintoshCyrillic is the code for x-mac-cyrillic. 80 | MacintoshCyrillic 81 | ) 82 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/internal/internal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains code that is shared among encoding implementations. 6 | package internal 7 | 8 | import ( 9 | "golang.org/x/text/encoding" 10 | "golang.org/x/text/encoding/internal/identifier" 11 | "golang.org/x/text/transform" 12 | ) 13 | 14 | // Encoding is an implementation of the Encoding interface that adds the String 15 | // and ID methods to an existing encoding. 16 | type Encoding struct { 17 | encoding.Encoding 18 | Name string 19 | MIB identifier.MIB 20 | } 21 | 22 | // _ verifies that Encoding implements identifier.Interface. 23 | var _ identifier.Interface = (*Encoding)(nil) 24 | 25 | func (e *Encoding) String() string { 26 | return e.Name 27 | } 28 | 29 | func (e *Encoding) ID() (mib identifier.MIB, other string) { 30 | return e.MIB, "" 31 | } 32 | 33 | // SimpleEncoding is an Encoding that combines two Transformers. 34 | type SimpleEncoding struct { 35 | Decoder transform.Transformer 36 | Encoder transform.Transformer 37 | } 38 | 39 | func (e *SimpleEncoding) NewDecoder() *encoding.Decoder { 40 | return &encoding.Decoder{Transformer: e.Decoder} 41 | } 42 | 43 | func (e *SimpleEncoding) NewEncoder() *encoding.Encoder { 44 | return &encoding.Encoder{Transformer: e.Encoder} 45 | } 46 | 47 | // FuncEncoding is an Encoding that combines two functions returning a new 48 | // Transformer. 49 | type FuncEncoding struct { 50 | Decoder func() transform.Transformer 51 | Encoder func() transform.Transformer 52 | } 53 | 54 | func (e FuncEncoding) NewDecoder() *encoding.Decoder { 55 | return &encoding.Decoder{Transformer: e.Decoder()} 56 | } 57 | 58 | func (e FuncEncoding) NewEncoder() *encoding.Encoder { 59 | return &encoding.Encoder{Transformer: e.Encoder()} 60 | } 61 | 62 | // A RepertoireError indicates a rune is not in the repertoire of a destination 63 | // encoding. It is associated with an encoding-specific suggested replacement 64 | // byte. 65 | type RepertoireError byte 66 | 67 | // Error implements the error interrface. 68 | func (r RepertoireError) Error() string { 69 | return "encoding: rune not supported by encoding." 70 | } 71 | 72 | // Replacement returns the replacement string associated with this error. 73 | func (r RepertoireError) Replacement() byte { return byte(r) } 74 | 75 | var ErrASCIIReplacement = RepertoireError(encoding.ASCIISub) 76 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/simplifiedchinese/all.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package simplifiedchinese 6 | 7 | import ( 8 | "golang.org/x/text/encoding" 9 | ) 10 | 11 | // All is a list of all defined encodings in this package. 12 | var All = []encoding.Encoding{GB18030, GBK, HZGB2312} 13 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/candide-gb18030.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/candide-gb18030.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/candide-utf-16le.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/candide-utf-16le.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/candide-utf-32be.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/candide-utf-32be.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/candide-windows-1252.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/candide-windows-1252.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/rashomon-euc-jp.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/rashomon-euc-jp.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/rashomon-shift-jis.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/rashomon-shift-jis.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/sunzi-bingfa-simplified-gbk.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/sunzi-bingfa-simplified-gbk.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/sunzi-bingfa-traditional-big5.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/sunzi-bingfa-traditional-big5.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/testdata/unsu-joh-eun-nal-euc-kr.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ice-ice/dnstunnel/b2d617046a1be94d54f50e5d0fc946e871e0ad81/vendor/golang.org/x/text/encoding/testdata/unsu-joh-eun-nal-euc-kr.txt -------------------------------------------------------------------------------- /vendor/golang.org/x/text/encoding/unicode/override.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package unicode 6 | 7 | import ( 8 | "golang.org/x/text/transform" 9 | ) 10 | 11 | // BOMOverride returns a new decoder transformer that is identical to fallback, 12 | // except that the presence of a Byte Order Mark at the start of the input 13 | // causes it to switch to the corresponding Unicode decoding. It will only 14 | // consider BOMs for UTF-8, UTF-16BE, and UTF-16LE. 15 | // 16 | // This differs from using ExpectBOM by allowing a BOM to switch to UTF-8, not 17 | // just UTF-16 variants, and allowing falling back to any encoding scheme. 18 | // 19 | // This technique is recommended by the W3C for use in HTML 5: "For 20 | // compatibility with deployed content, the byte order mark (also known as BOM) 21 | // is considered more authoritative than anything else." 22 | // http://www.w3.org/TR/encoding/#specification-hooks 23 | // 24 | // Using BOMOverride is mostly intended for use cases where the first characters 25 | // of a fallback encoding are known to not be a BOM, for example, for valid HTML 26 | // and most encodings. 27 | func BOMOverride(fallback transform.Transformer) transform.Transformer { 28 | // TODO: possibly allow a variadic argument of unicode encodings to allow 29 | // specifying details of which fallbacks are supported as well as 30 | // specifying the details of the implementations. This would also allow for 31 | // support for UTF-32, which should not be supported by default. 32 | return &bomOverride{fallback: fallback} 33 | } 34 | 35 | type bomOverride struct { 36 | fallback transform.Transformer 37 | current transform.Transformer 38 | } 39 | 40 | func (d *bomOverride) Reset() { 41 | d.current = nil 42 | d.fallback.Reset() 43 | } 44 | 45 | var ( 46 | // TODO: we could use decode functions here, instead of allocating a new 47 | // decoder on every NewDecoder as IgnoreBOM decoders can be stateless. 48 | utf16le = UTF16(LittleEndian, IgnoreBOM) 49 | utf16be = UTF16(BigEndian, IgnoreBOM) 50 | ) 51 | 52 | const utf8BOM = "\ufeff" 53 | 54 | func (d *bomOverride) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 55 | if d.current != nil { 56 | return d.current.Transform(dst, src, atEOF) 57 | } 58 | if len(src) < 3 && !atEOF { 59 | return 0, 0, transform.ErrShortSrc 60 | } 61 | d.current = d.fallback 62 | bomSize := 0 63 | if len(src) >= 2 { 64 | if src[0] == 0xFF && src[1] == 0xFE { 65 | d.current = utf16le.NewDecoder() 66 | bomSize = 2 67 | } else if src[0] == 0xFE && src[1] == 0xFF { 68 | d.current = utf16be.NewDecoder() 69 | bomSize = 2 70 | } else if len(src) >= 3 && 71 | src[0] == utf8BOM[0] && 72 | src[1] == utf8BOM[1] && 73 | src[2] == utf8BOM[2] { 74 | d.current = transform.Nop 75 | bomSize = 3 76 | } 77 | } 78 | if bomSize < len(src) { 79 | nDst, nSrc, err = d.current.Transform(dst, src[bomSize:], atEOF) 80 | } 81 | return nDst, nSrc + bomSize, err 82 | } 83 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/internal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains non-exported functionality that are used by 6 | // packages in the text repository. 7 | package internal // import "golang.org/x/text/internal" 8 | 9 | import ( 10 | "sort" 11 | 12 | "golang.org/x/text/language" 13 | ) 14 | 15 | // SortTags sorts tags in place. 16 | func SortTags(tags []language.Tag) { 17 | sort.Sort(sorter(tags)) 18 | } 19 | 20 | type sorter []language.Tag 21 | 22 | func (s sorter) Len() int { 23 | return len(s) 24 | } 25 | 26 | func (s sorter) Swap(i, j int) { 27 | s[i], s[j] = s[j], s[i] 28 | } 29 | 30 | func (s sorter) Less(i, j int) bool { 31 | return s[i].String() < s[j].String() 32 | } 33 | 34 | // UniqueTags sorts and filters duplicate tags in place and returns a slice with 35 | // only unique tags. 36 | func UniqueTags(tags []language.Tag) []language.Tag { 37 | if len(tags) <= 1 { 38 | return tags 39 | } 40 | SortTags(tags) 41 | k := 0 42 | for i := 1; i < len(tags); i++ { 43 | if tags[k].String() < tags[i].String() { 44 | k++ 45 | tags[k] = tags[i] 46 | } 47 | } 48 | return tags[:k+1] 49 | } 50 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/internal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package internal 6 | 7 | import ( 8 | "fmt" 9 | "strings" 10 | "testing" 11 | 12 | "golang.org/x/text/language" 13 | ) 14 | 15 | func TestUnique(t *testing.T) { 16 | testCases := []struct { 17 | in, want string 18 | }{ 19 | {"", "[]"}, 20 | {"en", "[en]"}, 21 | {"en en", "[en]"}, 22 | {"en en en", "[en]"}, 23 | {"en-u-cu-eur en", "[en en-u-cu-eur]"}, 24 | {"nl en", "[en nl]"}, 25 | {"pt-Pt pt", "[pt pt-PT]"}, 26 | } 27 | for _, tc := range testCases { 28 | tags := []language.Tag{} 29 | for _, s := range strings.Split(tc.in, " ") { 30 | if s != "" { 31 | tags = append(tags, language.MustParse(s)) 32 | } 33 | } 34 | if got := fmt.Sprint(UniqueTags(tags)); got != tc.want { 35 | t.Errorf("Unique(%s) = %s; want %s", tc.in, got, tc.want) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/common.go: -------------------------------------------------------------------------------- 1 | // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. 2 | 3 | package language 4 | 5 | // This file contains code common to the maketables.go and the package code. 6 | 7 | // AliasType is the type of an alias in AliasMap. 8 | type AliasType int8 9 | 10 | const ( 11 | Deprecated AliasType = iota 12 | Macro 13 | Legacy 14 | 15 | AliasTypeUnknown AliasType = -1 16 | ) 17 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/compact.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package language 6 | 7 | // CompactCoreInfo is a compact integer with the three core tags encoded. 8 | type CompactCoreInfo uint32 9 | 10 | // GetCompactCore generates a uint32 value that is guaranteed to be unique for 11 | // different language, region, and script values. 12 | func GetCompactCore(t Tag) (cci CompactCoreInfo, ok bool) { 13 | if t.LangID > langNoIndexOffset { 14 | return 0, false 15 | } 16 | cci |= CompactCoreInfo(t.LangID) << (8 + 12) 17 | cci |= CompactCoreInfo(t.ScriptID) << 12 18 | cci |= CompactCoreInfo(t.RegionID) 19 | return cci, true 20 | } 21 | 22 | // Tag generates a tag from c. 23 | func (c CompactCoreInfo) Tag() Tag { 24 | return Tag{ 25 | LangID: Language(c >> 20), 26 | RegionID: Region(c & 0x3ff), 27 | ScriptID: Script(c>>12) & 0xff, 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/compact/compact.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package compact defines a compact representation of language tags. 6 | // 7 | // Common language tags (at least all for which locale information is defined 8 | // in CLDR) are assigned a unique index. Each Tag is associated with such an 9 | // ID for selecting language-related resources (such as translations) as well 10 | // as one for selecting regional defaults (currency, number formatting, etc.) 11 | // 12 | // It may want to export this functionality at some point, but at this point 13 | // this is only available for use within x/text. 14 | package compact // import "golang.org/x/text/internal/language/compact" 15 | 16 | import ( 17 | "sort" 18 | "strings" 19 | 20 | "golang.org/x/text/internal/language" 21 | ) 22 | 23 | // ID is an integer identifying a single tag. 24 | type ID uint16 25 | 26 | func getCoreIndex(t language.Tag) (id ID, ok bool) { 27 | cci, ok := language.GetCompactCore(t) 28 | if !ok { 29 | return 0, false 30 | } 31 | i := sort.Search(len(coreTags), func(i int) bool { 32 | return cci <= coreTags[i] 33 | }) 34 | if i == len(coreTags) || coreTags[i] != cci { 35 | return 0, false 36 | } 37 | return ID(i), true 38 | } 39 | 40 | // Parent returns the ID of the parent or the root ID if id is already the root. 41 | func (id ID) Parent() ID { 42 | return parents[id] 43 | } 44 | 45 | // Tag converts id to an internal language Tag. 46 | func (id ID) Tag() language.Tag { 47 | if int(id) >= len(coreTags) { 48 | return specialTags[int(id)-len(coreTags)] 49 | } 50 | return coreTags[id].Tag() 51 | } 52 | 53 | var specialTags []language.Tag 54 | 55 | func init() { 56 | tags := strings.Split(specialTagsStr, " ") 57 | specialTags = make([]language.Tag, len(tags)) 58 | for i, t := range tags { 59 | specialTags[i] = language.MustParse(t) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/compact/gen.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | // Language tag table generator. 8 | // Data read from the web. 9 | 10 | package compact 11 | 12 | import ( 13 | "flag" 14 | "fmt" 15 | "log" 16 | 17 | "golang.org/x/text/internal/gen" 18 | "golang.org/x/text/unicode/cldr" 19 | ) 20 | 21 | var ( 22 | test = flag.Bool("test", 23 | false, 24 | "test existing tables; can be used to compare web data with package data.") 25 | outputFile = flag.String("output", 26 | "tables.go", 27 | "output file for generated tables") 28 | ) 29 | 30 | func main() { 31 | gen.Init() 32 | 33 | w := gen.NewCodeWriter() 34 | defer w.WriteGoFile("tables.go", "compact") 35 | 36 | fmt.Fprintln(w, `import "golang.org/x/text/internal/language"`) 37 | 38 | b := newBuilder(w) 39 | gen.WriteCLDRVersion(w) 40 | 41 | b.writeCompactIndex() 42 | } 43 | 44 | type builder struct { 45 | w *gen.CodeWriter 46 | data *cldr.CLDR 47 | supp *cldr.SupplementalData 48 | } 49 | 50 | func newBuilder(w *gen.CodeWriter) *builder { 51 | r := gen.OpenCLDRCoreZip() 52 | defer r.Close() 53 | d := &cldr.Decoder{} 54 | data, err := d.DecodeZip(r) 55 | if err != nil { 56 | log.Fatal(err) 57 | } 58 | b := builder{ 59 | w: w, 60 | data: data, 61 | supp: data.Supplemental(), 62 | } 63 | return &b 64 | } 65 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/compact/gen_index.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package compact 8 | 9 | // This file generates derivative tables based on the language package itself. 10 | 11 | import ( 12 | "fmt" 13 | "log" 14 | "sort" 15 | "strings" 16 | 17 | "golang.org/x/text/internal/language" 18 | ) 19 | 20 | // Compact indices: 21 | // Note -va-X variants only apply to localization variants. 22 | // BCP variants only ever apply to language. 23 | // The only ambiguity between tags is with regions. 24 | 25 | func (b *builder) writeCompactIndex() { 26 | // Collect all language tags for which we have any data in CLDR. 27 | m := map[language.Tag]bool{} 28 | for _, lang := range b.data.Locales() { 29 | // We include all locales unconditionally to be consistent with en_US. 30 | // We want en_US, even though it has no data associated with it. 31 | 32 | // TODO: put any of the languages for which no data exists at the end 33 | // of the index. This allows all components based on ICU to use that 34 | // as the cutoff point. 35 | // if x := data.RawLDML(lang); false || 36 | // x.LocaleDisplayNames != nil || 37 | // x.Characters != nil || 38 | // x.Delimiters != nil || 39 | // x.Measurement != nil || 40 | // x.Dates != nil || 41 | // x.Numbers != nil || 42 | // x.Units != nil || 43 | // x.ListPatterns != nil || 44 | // x.Collations != nil || 45 | // x.Segmentations != nil || 46 | // x.Rbnf != nil || 47 | // x.Annotations != nil || 48 | // x.Metadata != nil { 49 | 50 | // TODO: support POSIX natively, albeit non-standard. 51 | tag := language.Make(strings.Replace(lang, "_POSIX", "-u-va-posix", 1)) 52 | m[tag] = true 53 | // } 54 | } 55 | 56 | // TODO: plural rules are also defined for the deprecated tags: 57 | // iw mo sh tl 58 | // Consider removing these as compact tags. 59 | 60 | // Include locales for plural rules, which uses a different structure. 61 | for _, plurals := range b.supp.Plurals { 62 | for _, rules := range plurals.PluralRules { 63 | for _, lang := range strings.Split(rules.Locales, " ") { 64 | m[language.Make(lang)] = true 65 | } 66 | } 67 | } 68 | 69 | var coreTags []language.CompactCoreInfo 70 | var special []string 71 | 72 | for t := range m { 73 | if x := t.Extensions(); len(x) != 0 && fmt.Sprint(x) != "[u-va-posix]" { 74 | log.Fatalf("Unexpected extension %v in %v", x, t) 75 | } 76 | if len(t.Variants()) == 0 && len(t.Extensions()) == 0 { 77 | cci, ok := language.GetCompactCore(t) 78 | if !ok { 79 | log.Fatalf("Locale for non-basic language %q", t) 80 | } 81 | coreTags = append(coreTags, cci) 82 | } else { 83 | special = append(special, t.String()) 84 | } 85 | } 86 | 87 | w := b.w 88 | 89 | sort.Slice(coreTags, func(i, j int) bool { return coreTags[i] < coreTags[j] }) 90 | sort.Strings(special) 91 | 92 | w.WriteComment(` 93 | NumCompactTags is the number of common tags. The maximum tag is 94 | NumCompactTags-1.`) 95 | w.WriteConst("NumCompactTags", len(m)) 96 | 97 | fmt.Fprintln(w, "const (") 98 | for i, t := range coreTags { 99 | fmt.Fprintf(w, "%s ID = %d\n", ident(t.Tag().String()), i) 100 | } 101 | for i, t := range special { 102 | fmt.Fprintf(w, "%s ID = %d\n", ident(t), i+len(coreTags)) 103 | } 104 | fmt.Fprintln(w, ")") 105 | 106 | w.WriteVar("coreTags", coreTags) 107 | 108 | w.WriteConst("specialTagsStr", strings.Join(special, " ")) 109 | } 110 | 111 | func ident(s string) string { 112 | return strings.Replace(s, "-", "", -1) + "Index" 113 | } 114 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/compact/gen_parents.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package compact 8 | 9 | import ( 10 | "log" 11 | 12 | "golang.org/x/text/internal/gen" 13 | "golang.org/x/text/internal/language" 14 | "golang.org/x/text/internal/language/compact" 15 | "golang.org/x/text/unicode/cldr" 16 | ) 17 | 18 | func main() { 19 | r := gen.OpenCLDRCoreZip() 20 | defer r.Close() 21 | 22 | d := &cldr.Decoder{} 23 | data, err := d.DecodeZip(r) 24 | if err != nil { 25 | log.Fatalf("DecodeZip: %v", err) 26 | } 27 | 28 | w := gen.NewCodeWriter() 29 | defer w.WriteGoFile("parents.go", "compact") 30 | 31 | // Create parents table. 32 | type ID uint16 33 | parents := make([]ID, compact.NumCompactTags) 34 | for _, loc := range data.Locales() { 35 | tag := language.MustParse(loc) 36 | index, ok := compact.FromTag(tag) 37 | if !ok { 38 | continue 39 | } 40 | parentIndex := compact.ID(0) // und 41 | for p := tag.Parent(); p != language.Und; p = p.Parent() { 42 | if x, ok := compact.FromTag(p); ok { 43 | parentIndex = x 44 | break 45 | } 46 | } 47 | parents[index] = ID(parentIndex) 48 | } 49 | 50 | w.WriteComment(` 51 | parents maps a compact index of a tag to the compact index of the parent of 52 | this tag.`) 53 | w.WriteVar("parents", parents) 54 | } 55 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/compact/gen_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package compact 6 | 7 | import ( 8 | "testing" 9 | 10 | "golang.org/x/text/internal/language" 11 | ) 12 | 13 | func TestParents(t *testing.T) { 14 | testCases := []struct { 15 | tag, parent string 16 | }{ 17 | {"af", "und"}, 18 | {"en", "und"}, 19 | {"en-001", "en"}, 20 | {"en-AU", "en-001"}, 21 | {"en-US", "en"}, 22 | {"en-US-u-va-posix", "en-US"}, 23 | {"ca-ES-valencia", "ca-ES"}, 24 | } 25 | for _, tc := range testCases { 26 | tag, ok := LanguageID(Make(language.MustParse(tc.tag))) 27 | if !ok { 28 | t.Fatalf("Could not get index of flag %s", tc.tag) 29 | } 30 | want, ok := LanguageID(Make(language.MustParse(tc.parent))) 31 | if !ok { 32 | t.Fatalf("Could not get index of parent %s of tag %s", tc.parent, tc.tag) 33 | } 34 | if got := parents[tag]; got != want { 35 | t.Errorf("Parent[%s] = %d; want %d (%s)", tc.tag, got, want, tc.parent) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/compose.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package language 6 | 7 | import ( 8 | "sort" 9 | "strings" 10 | ) 11 | 12 | // A Builder allows constructing a Tag from individual components. 13 | // Its main user is Compose in the top-level language package. 14 | type Builder struct { 15 | Tag Tag 16 | 17 | private string // the x extension 18 | variants []string 19 | extensions []string 20 | } 21 | 22 | // Make returns a new Tag from the current settings. 23 | func (b *Builder) Make() Tag { 24 | t := b.Tag 25 | 26 | if len(b.extensions) > 0 || len(b.variants) > 0 { 27 | sort.Sort(sortVariants(b.variants)) 28 | sort.Strings(b.extensions) 29 | 30 | if b.private != "" { 31 | b.extensions = append(b.extensions, b.private) 32 | } 33 | n := maxCoreSize + tokenLen(b.variants...) + tokenLen(b.extensions...) 34 | buf := make([]byte, n) 35 | p := t.genCoreBytes(buf) 36 | t.pVariant = byte(p) 37 | p += appendTokens(buf[p:], b.variants...) 38 | t.pExt = uint16(p) 39 | p += appendTokens(buf[p:], b.extensions...) 40 | t.str = string(buf[:p]) 41 | // We may not always need to remake the string, but when or when not 42 | // to do so is rather tricky. 43 | scan := makeScanner(buf[:p]) 44 | t, _ = parse(&scan, "") 45 | return t 46 | 47 | } else if b.private != "" { 48 | t.str = b.private 49 | t.RemakeString() 50 | } 51 | return t 52 | } 53 | 54 | // SetTag copies all the settings from a given Tag. Any previously set values 55 | // are discarded. 56 | func (b *Builder) SetTag(t Tag) { 57 | b.Tag.LangID = t.LangID 58 | b.Tag.RegionID = t.RegionID 59 | b.Tag.ScriptID = t.ScriptID 60 | // TODO: optimize 61 | b.variants = b.variants[:0] 62 | if variants := t.Variants(); variants != "" { 63 | for _, vr := range strings.Split(variants[1:], "-") { 64 | b.variants = append(b.variants, vr) 65 | } 66 | } 67 | b.extensions, b.private = b.extensions[:0], "" 68 | for _, e := range t.Extensions() { 69 | b.AddExt(e) 70 | } 71 | } 72 | 73 | // AddExt adds extension e to the tag. e must be a valid extension as returned 74 | // by Tag.Extension. If the extension already exists, it will be discarded, 75 | // except for a -u extension, where non-existing key-type pairs will added. 76 | func (b *Builder) AddExt(e string) { 77 | if e[0] == 'x' { 78 | if b.private == "" { 79 | b.private = e 80 | } 81 | return 82 | } 83 | for i, s := range b.extensions { 84 | if s[0] == e[0] { 85 | if e[0] == 'u' { 86 | b.extensions[i] += e[1:] 87 | } 88 | return 89 | } 90 | } 91 | b.extensions = append(b.extensions, e) 92 | } 93 | 94 | // SetExt sets the extension e to the tag. e must be a valid extension as 95 | // returned by Tag.Extension. If the extension already exists, it will be 96 | // overwritten, except for a -u extension, where the individual key-type pairs 97 | // will be set. 98 | func (b *Builder) SetExt(e string) { 99 | if e[0] == 'x' { 100 | b.private = e 101 | return 102 | } 103 | for i, s := range b.extensions { 104 | if s[0] == e[0] { 105 | if e[0] == 'u' { 106 | b.extensions[i] = e + s[1:] 107 | } else { 108 | b.extensions[i] = e 109 | } 110 | return 111 | } 112 | } 113 | b.extensions = append(b.extensions, e) 114 | } 115 | 116 | // AddVariant adds any number of variants. 117 | func (b *Builder) AddVariant(v ...string) { 118 | for _, v := range v { 119 | if v != "" { 120 | b.variants = append(b.variants, v) 121 | } 122 | } 123 | } 124 | 125 | // ClearVariants removes any variants previously added, including those 126 | // copied from a Tag in SetTag. 127 | func (b *Builder) ClearVariants() { 128 | b.variants = b.variants[:0] 129 | } 130 | 131 | // ClearExtensions removes any extensions previously added, including those 132 | // copied from a Tag in SetTag. 133 | func (b *Builder) ClearExtensions() { 134 | b.private = "" 135 | b.extensions = b.extensions[:0] 136 | } 137 | 138 | func tokenLen(token ...string) (n int) { 139 | for _, t := range token { 140 | n += len(t) + 1 141 | } 142 | return 143 | } 144 | 145 | func appendTokens(b []byte, token ...string) int { 146 | p := 0 147 | for _, t := range token { 148 | b[p] = '-' 149 | copy(b[p+1:], t) 150 | p += 1 + len(t) 151 | } 152 | return p 153 | } 154 | 155 | type sortVariants []string 156 | 157 | func (s sortVariants) Len() int { 158 | return len(s) 159 | } 160 | 161 | func (s sortVariants) Swap(i, j int) { 162 | s[j], s[i] = s[i], s[j] 163 | } 164 | 165 | func (s sortVariants) Less(i, j int) bool { 166 | return variantIndex[s[i]] < variantIndex[s[j]] 167 | } 168 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/compose_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package language 6 | 7 | import ( 8 | "strings" 9 | "testing" 10 | ) 11 | 12 | func parseBase(s string) Language { 13 | if s == "" { 14 | return 0 15 | } 16 | return MustParseBase(s) 17 | } 18 | 19 | func parseScript(s string) Script { 20 | if s == "" { 21 | return 0 22 | } 23 | return MustParseScript(s) 24 | } 25 | 26 | func parseRegion(s string) Region { 27 | if s == "" { 28 | return 0 29 | } 30 | return MustParseRegion(s) 31 | } 32 | 33 | func TestBuilder(t *testing.T) { 34 | partChecks(t, func(t *testing.T, tt *parseTest) (id Tag, skip bool) { 35 | tag := Make(tt.in) 36 | b := Builder{} 37 | b.SetTag(Tag{ 38 | LangID: parseBase(tt.lang), 39 | ScriptID: parseScript(tt.script), 40 | RegionID: parseRegion(tt.region), 41 | }) 42 | if tt.variants != "" { 43 | b.AddVariant(strings.Split(tt.variants, "-")...) 44 | } 45 | for _, e := range tag.Extensions() { 46 | b.AddExt(e) 47 | } 48 | got := b.Make() 49 | if got != tag { 50 | t.Errorf("%s: got %v; want %v", tt.in, got, tag) 51 | } 52 | return got, false 53 | }) 54 | } 55 | 56 | func TestSetTag(t *testing.T) { 57 | partChecks(t, func(t *testing.T, tt *parseTest) (id Tag, skip bool) { 58 | tag := Make(tt.in) 59 | b := Builder{} 60 | b.SetTag(tag) 61 | got := b.Make() 62 | if got != tag { 63 | t.Errorf("%s: got %v; want %v", tt.in, got, tag) 64 | } 65 | return got, false 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/coverage.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package language 6 | 7 | // BaseLanguages returns the list of all supported base languages. It generates 8 | // the list by traversing the internal structures. 9 | func BaseLanguages() []Language { 10 | base := make([]Language, 0, NumLanguages) 11 | for i := 0; i < langNoIndexOffset; i++ { 12 | // We included "und" already for the value 0. 13 | if i != nonCanonicalUnd { 14 | base = append(base, Language(i)) 15 | } 16 | } 17 | i := langNoIndexOffset 18 | for _, v := range langNoIndex { 19 | for k := 0; k < 8; k++ { 20 | if v&1 == 1 { 21 | base = append(base, Language(i)) 22 | } 23 | v >>= 1 24 | i++ 25 | } 26 | } 27 | return base 28 | } 29 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/gen_common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package language 8 | 9 | // This file contains code common to the maketables.go and the package code. 10 | 11 | // AliasType is the type of an alias in AliasMap. 12 | type AliasType int8 13 | 14 | const ( 15 | Deprecated AliasType = iota 16 | Macro 17 | Legacy 18 | 19 | AliasTypeUnknown AliasType = -1 20 | ) 21 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/language/tags.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package language 6 | 7 | // MustParse is like Parse, but panics if the given BCP 47 tag cannot be parsed. 8 | // It simplifies safe initialization of Tag values. 9 | func MustParse(s string) Tag { 10 | t, err := Parse(s) 11 | if err != nil { 12 | panic(err) 13 | } 14 | return t 15 | } 16 | 17 | // MustParseBase is like ParseBase, but panics if the given base cannot be parsed. 18 | // It simplifies safe initialization of Base values. 19 | func MustParseBase(s string) Language { 20 | b, err := ParseBase(s) 21 | if err != nil { 22 | panic(err) 23 | } 24 | return b 25 | } 26 | 27 | // MustParseScript is like ParseScript, but panics if the given script cannot be 28 | // parsed. It simplifies safe initialization of Script values. 29 | func MustParseScript(s string) Script { 30 | scr, err := ParseScript(s) 31 | if err != nil { 32 | panic(err) 33 | } 34 | return scr 35 | } 36 | 37 | // MustParseRegion is like ParseRegion, but panics if the given region cannot be 38 | // parsed. It simplifies safe initialization of Region values. 39 | func MustParseRegion(s string) Region { 40 | r, err := ParseRegion(s) 41 | if err != nil { 42 | panic(err) 43 | } 44 | return r 45 | } 46 | 47 | // Und is the root language. 48 | var Und Tag 49 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/match.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package internal 6 | 7 | // This file contains matchers that implement CLDR inheritance. 8 | // 9 | // See https://unicode.org/reports/tr35/#Locale_Inheritance. 10 | // 11 | // Some of the inheritance described in this document is already handled by 12 | // the cldr package. 13 | 14 | import ( 15 | "golang.org/x/text/language" 16 | ) 17 | 18 | // TODO: consider if (some of the) matching algorithm needs to be public after 19 | // getting some feel about what is generic and what is specific. 20 | 21 | // NewInheritanceMatcher returns a matcher that matches based on the inheritance 22 | // chain. 23 | // 24 | // The matcher uses canonicalization and the parent relationship to find a 25 | // match. The resulting match will always be either Und or a language with the 26 | // same language and script as the requested language. It will not match 27 | // languages for which there is understood to be mutual or one-directional 28 | // intelligibility. 29 | // 30 | // A Match will indicate an Exact match if the language matches after 31 | // canonicalization and High if the matched tag is a parent. 32 | func NewInheritanceMatcher(t []language.Tag) *InheritanceMatcher { 33 | tags := &InheritanceMatcher{make(map[language.Tag]int)} 34 | for i, tag := range t { 35 | ct, err := language.All.Canonicalize(tag) 36 | if err != nil { 37 | ct = tag 38 | } 39 | tags.index[ct] = i 40 | } 41 | return tags 42 | } 43 | 44 | type InheritanceMatcher struct { 45 | index map[language.Tag]int 46 | } 47 | 48 | func (m InheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) { 49 | for _, t := range want { 50 | ct, err := language.All.Canonicalize(t) 51 | if err != nil { 52 | ct = t 53 | } 54 | conf := language.Exact 55 | for { 56 | if index, ok := m.index[ct]; ok { 57 | return ct, index, conf 58 | } 59 | if ct == language.Und { 60 | break 61 | } 62 | ct = ct.Parent() 63 | conf = language.High 64 | } 65 | } 66 | return language.Und, 0, language.No 67 | } 68 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/match_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package internal 6 | 7 | import ( 8 | "strings" 9 | "testing" 10 | 11 | "golang.org/x/text/language" 12 | ) 13 | 14 | func TestInheritanceMatcher(t *testing.T) { 15 | for i, tt := range []struct { 16 | haveTags string 17 | wantTags string 18 | match string 19 | conf language.Confidence 20 | }{ 21 | {"und,en,en-US", "en-US", "en-US", language.Exact}, // most specific match 22 | {"zh-Hant,zh", "zh-TW", "zh-Hant", language.High}, // zh-TW implies Hant. 23 | {"und,zh", "zh-TW", "und", language.High}, // zh-TW does not match zh. 24 | {"zh", "zh-TW", "und", language.No}, // zh-TW does not match zh. 25 | {"iw,en,nl", "he", "he", language.Exact}, // matches after canonicalization 26 | {"he,en,nl", "iw", "he", language.Exact}, // matches after canonicalization 27 | // Prefer first match over more specific match for various reasons: 28 | // a) consistency of user interface is more important than an exact match, 29 | // b) _if_ und is specified, it should be considered a correct and useful match, 30 | // Note that a call to this Match will almost always be with a single tag. 31 | {"und,en,en-US", "he,en-US", "und", language.High}, 32 | } { 33 | have := parseTags(tt.haveTags) 34 | m := NewInheritanceMatcher(have) 35 | tag, index, conf := m.Match(parseTags(tt.wantTags)...) 36 | want := language.Raw.Make(tt.match) 37 | if tag != want { 38 | t.Errorf("%d:tag: got %q; want %q", i, tag, want) 39 | } 40 | if conf != language.No { 41 | if got, _ := language.All.Canonicalize(have[index]); got != want { 42 | t.Errorf("%d:index: got %q; want %q ", i, got, want) 43 | } 44 | } 45 | if conf != tt.conf { 46 | t.Errorf("%d:conf: got %v; want %v", i, conf, tt.conf) 47 | } 48 | } 49 | } 50 | 51 | func parseTags(list string) (out []language.Tag) { 52 | for _, s := range strings.Split(list, ",") { 53 | out = append(out, language.Raw.Make(strings.TrimSpace(s))) 54 | } 55 | return out 56 | } 57 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/tag/tag.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package tag contains functionality handling tags and related data. 6 | package tag // import "golang.org/x/text/internal/tag" 7 | 8 | import "sort" 9 | 10 | // An Index converts tags to a compact numeric value. 11 | // 12 | // All elements are of size 4. Tags may be up to 4 bytes long. Excess bytes can 13 | // be used to store additional information about the tag. 14 | type Index string 15 | 16 | // Elem returns the element data at the given index. 17 | func (s Index) Elem(x int) string { 18 | return string(s[x*4 : x*4+4]) 19 | } 20 | 21 | // Index reports the index of the given key or -1 if it could not be found. 22 | // Only the first len(key) bytes from the start of the 4-byte entries will be 23 | // considered for the search and the first match in Index will be returned. 24 | func (s Index) Index(key []byte) int { 25 | n := len(key) 26 | // search the index of the first entry with an equal or higher value than 27 | // key in s. 28 | index := sort.Search(len(s)/4, func(i int) bool { 29 | return cmp(s[i*4:i*4+n], key) != -1 30 | }) 31 | i := index * 4 32 | if cmp(s[i:i+len(key)], key) != 0 { 33 | return -1 34 | } 35 | return index 36 | } 37 | 38 | // Next finds the next occurrence of key after index x, which must have been 39 | // obtained from a call to Index using the same key. It returns x+1 or -1. 40 | func (s Index) Next(key []byte, x int) int { 41 | if x++; x*4 < len(s) && cmp(s[x*4:x*4+len(key)], key) == 0 { 42 | return x 43 | } 44 | return -1 45 | } 46 | 47 | // cmp returns an integer comparing a and b lexicographically. 48 | func cmp(a Index, b []byte) int { 49 | n := len(a) 50 | if len(b) < n { 51 | n = len(b) 52 | } 53 | for i, c := range b[:n] { 54 | switch { 55 | case a[i] > c: 56 | return 1 57 | case a[i] < c: 58 | return -1 59 | } 60 | } 61 | switch { 62 | case len(a) < len(b): 63 | return -1 64 | case len(a) > len(b): 65 | return 1 66 | } 67 | return 0 68 | } 69 | 70 | // Compare returns an integer comparing a and b lexicographically. 71 | func Compare(a string, b []byte) int { 72 | return cmp(Index(a), b) 73 | } 74 | 75 | // FixCase reformats b to the same pattern of cases as form. 76 | // If returns false if string b is malformed. 77 | func FixCase(form string, b []byte) bool { 78 | if len(form) != len(b) { 79 | return false 80 | } 81 | for i, c := range b { 82 | if form[i] <= 'Z' { 83 | if c >= 'a' { 84 | c -= 'z' - 'Z' 85 | } 86 | if c < 'A' || 'Z' < c { 87 | return false 88 | } 89 | } else { 90 | if c <= 'Z' { 91 | c += 'z' - 'Z' 92 | } 93 | if c < 'a' || 'z' < c { 94 | return false 95 | } 96 | } 97 | b[i] = c 98 | } 99 | return true 100 | } 101 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/tag/tag_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tag 6 | 7 | import ( 8 | "strings" 9 | "testing" 10 | ) 11 | 12 | var strdata = []string{ 13 | "aa ", 14 | "aaa ", 15 | "aaaa", 16 | "aaab", 17 | "aab ", 18 | "ab ", 19 | "ba ", 20 | "xxxx", 21 | "\xff\xff\xff\xff", 22 | } 23 | 24 | var testCases = map[string]int{ 25 | "a": 0, 26 | "aa": 0, 27 | "aaa": 1, 28 | "aa ": 0, 29 | "aaaa": 2, 30 | "aaab": 3, 31 | "b": 6, 32 | "ba": 6, 33 | " ": -1, 34 | "aaax": -1, 35 | "bbbb": -1, 36 | "zzzz": -1, 37 | } 38 | 39 | func TestIndex(t *testing.T) { 40 | index := Index(strings.Join(strdata, "")) 41 | for k, v := range testCases { 42 | if i := index.Index([]byte(k)); i != v { 43 | t.Errorf("%s: got %d; want %d", k, i, v) 44 | } 45 | } 46 | } 47 | 48 | func TestFixCase(t *testing.T) { 49 | tests := []string{ 50 | "aaaa", "AbCD", "abcd", 51 | "Zzzz", "AbCD", "Abcd", 52 | "Zzzz", "AbC", "", 53 | "XXX", "ab ", "", 54 | "XXX", "usd", "USD", 55 | "cmn", "AB ", "", 56 | "gsw", "CMN", "cmn", 57 | } 58 | for tc := tests; len(tc) > 0; tc = tc[3:] { 59 | b := []byte(tc[1]) 60 | if !FixCase(tc[0], b) { 61 | b = nil 62 | } 63 | if string(b) != tc[2] { 64 | t.Errorf("FixCase(%q, %q) = %q; want %q", tc[0], tc[1], b, tc[2]) 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/testtext/codesize.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package testtext 6 | 7 | import ( 8 | "bytes" 9 | "fmt" 10 | "io/ioutil" 11 | "os" 12 | "os/exec" 13 | "path/filepath" 14 | "runtime" 15 | ) 16 | 17 | // CodeSize builds the given code sample and returns the binary size or en error 18 | // if an error occurred. The code sample typically will look like this: 19 | // package main 20 | // import "golang.org/x/text/somepackage" 21 | // func main() { 22 | // somepackage.Func() // reference Func to cause it to be linked in. 23 | // } 24 | // See dict_test.go in the display package for an example. 25 | func CodeSize(s string) (int, error) { 26 | // Write the file. 27 | tmpdir, err := ioutil.TempDir(os.TempDir(), "testtext") 28 | if err != nil { 29 | return 0, fmt.Errorf("testtext: failed to create tmpdir: %v", err) 30 | } 31 | defer os.RemoveAll(tmpdir) 32 | filename := filepath.Join(tmpdir, "main.go") 33 | if err := ioutil.WriteFile(filename, []byte(s), 0644); err != nil { 34 | return 0, fmt.Errorf("testtext: failed to write main.go: %v", err) 35 | } 36 | 37 | // Build the binary. 38 | w := &bytes.Buffer{} 39 | cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), "build", "-o", "main") 40 | cmd.Dir = tmpdir 41 | cmd.Stderr = w 42 | cmd.Stdout = w 43 | if err := cmd.Run(); err != nil { 44 | return 0, fmt.Errorf("testtext: failed to execute command: %v\nmain.go:\n%vErrors:%s", err, s, w) 45 | } 46 | 47 | // Determine the size. 48 | fi, err := os.Stat(filepath.Join(tmpdir, "main")) 49 | if err != nil { 50 | return 0, fmt.Errorf("testtext: failed to get file info: %v", err) 51 | } 52 | return int(fi.Size()), nil 53 | } 54 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/testtext/flag.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package testtext 6 | 7 | import ( 8 | "flag" 9 | "testing" 10 | 11 | "golang.org/x/text/internal/gen" 12 | ) 13 | 14 | var long = flag.Bool("long", false, 15 | "run tests that require fetching data online") 16 | 17 | // SkipIfNotLong returns whether long tests should be performed. 18 | func SkipIfNotLong(t *testing.T) { 19 | if testing.Short() || !(gen.IsLocal() || *long) { 20 | t.Skip("skipping test to prevent downloading; to run use -long or use -local or UNICODE_DIR to specify a local source") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/testtext/gc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !gccgo 6 | 7 | package testtext 8 | 9 | import "testing" 10 | 11 | // AllocsPerRun wraps testing.AllocsPerRun. 12 | func AllocsPerRun(runs int, f func()) (avg float64) { 13 | return testing.AllocsPerRun(runs, f) 14 | } 15 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/testtext/gccgo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gccgo 6 | 7 | package testtext 8 | 9 | // AllocsPerRun always returns 0 for gccgo until gccgo implements escape 10 | // analysis equal or better to that of gc. 11 | func AllocsPerRun(runs int, f func()) (avg float64) { return 0 } 12 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/testtext/go1_6.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.7 6 | 7 | package testtext 8 | 9 | import "testing" 10 | 11 | func Run(t *testing.T, name string, fn func(t *testing.T)) bool { 12 | t.Logf("Running %s...", name) 13 | fn(t) 14 | return t.Failed() 15 | } 16 | 17 | // Bench runs the given benchmark function. This pre-1.7 implementation renders 18 | // the measurement useless, but allows the code to be compiled at least. 19 | func Bench(b *testing.B, name string, fn func(b *testing.B)) bool { 20 | b.Logf("Running %s...", name) 21 | fn(b) 22 | return b.Failed() 23 | } 24 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/testtext/go1_7.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.7 6 | 7 | package testtext 8 | 9 | import "testing" 10 | 11 | func Run(t *testing.T, name string, fn func(t *testing.T)) bool { 12 | return t.Run(name, fn) 13 | } 14 | 15 | func Bench(b *testing.B, name string, fn func(b *testing.B)) bool { 16 | return b.Run(name, fn) 17 | } 18 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/ucd/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ucd_test 6 | 7 | import ( 8 | "fmt" 9 | "strings" 10 | 11 | "golang.org/x/text/internal/ucd" 12 | ) 13 | 14 | func Example() { 15 | // Read rune-by-rune from UnicodeData. 16 | var count int 17 | p := ucd.New(strings.NewReader(unicodeData)) 18 | for p.Next() { 19 | count++ 20 | if lower := p.Runes(ucd.SimpleLowercaseMapping); lower != nil { 21 | fmt.Printf("lower(%U) -> %U\n", p.Rune(0), lower[0]) 22 | } 23 | } 24 | if err := p.Err(); err != nil { 25 | fmt.Println(err) 26 | } 27 | fmt.Println("Number of runes visited:", count) 28 | 29 | // Read raw ranges from Scripts. 30 | p = ucd.New(strings.NewReader(scripts), ucd.KeepRanges) 31 | for p.Next() { 32 | start, end := p.Range(0) 33 | fmt.Printf("%04X..%04X: %s\n", start, end, p.String(1)) 34 | } 35 | if err := p.Err(); err != nil { 36 | fmt.Println(err) 37 | } 38 | 39 | // Output: 40 | // lower(U+00C0) -> U+00E0 41 | // lower(U+00C1) -> U+00E1 42 | // lower(U+00C2) -> U+00E2 43 | // lower(U+00C3) -> U+00E3 44 | // lower(U+00C4) -> U+00E4 45 | // Number of runes visited: 6594 46 | // 0000..001F: Common 47 | // 0020..0020: Common 48 | // 0021..0023: Common 49 | // 0024..0024: Common 50 | } 51 | 52 | // Excerpt from UnicodeData.txt 53 | const unicodeData = ` 54 | 00B9;SUPERSCRIPT ONE;No;0;EN; 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;; 55 | 00BA;MASCULINE ORDINAL INDICATOR;Lo;0;L; 006F;;;;N;;;;; 56 | 00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;; 57 | 00BC;VULGAR FRACTION ONE QUARTER;No;0;ON; 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;; 58 | 00BD;VULGAR FRACTION ONE HALF;No;0;ON; 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;; 59 | 00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON; 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;; 60 | 00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;; 61 | 00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0; 62 | 00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1; 63 | 00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2; 64 | 00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3; 65 | 00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4; 66 | 67 | # A legacy rune range. 68 | 3400;;Lo;0;L;;;;;N;;;;; 69 | 4DB5;;Lo;0;L;;;;;N;;;;; 70 | ` 71 | 72 | // Excerpt from Scripts.txt 73 | const scripts = ` 74 | # Property: Script 75 | # ================================================ 76 | 77 | 0000..001F ; Common # Cc [32] .. 78 | 0020 ; Common # Zs SPACE 79 | 0021..0023 ; Common # Po [3] EXCLAMATION MARK..NUMBER SIGN 80 | 0024 ; Common # Sc DOLLAR SIGN 81 | ` 82 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/ucd/ucd_test.go: -------------------------------------------------------------------------------- 1 | package ucd 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | const file = ` 9 | # Comments should be skipped 10 | # rune; bool; uint; int; float; runes; # Y 11 | 0..0005; Y; 0; 2; -5.25 ; 0 1 2 3 4 5; 12 | 6..0007; Yes ; 6; 1; -4.25 ; 0006 0007; 13 | 8; T ; 8 ; 0 ;-3.25 ;;# T 14 | 9; True ;9 ; -1;-2.25 ; 0009; 15 | 16 | # more comments to be ignored 17 | @Part0 18 | 19 | A; N; 10 ; -2; -1.25; ;# N 20 | B; No; 11 ; -3; -0.25; 21 | C; False;12; -4; 0.75; 22 | D; ;13;-5;1.75; 23 | 24 | @Part1 # Another part. 25 | # We test part comments get removed by not commenting the next line. 26 | E..10FFFF; F; 14 ; -6; 2.75; 27 | ` 28 | 29 | var want = []struct { 30 | start, end rune 31 | }{ 32 | {0x00, 0x05}, 33 | {0x06, 0x07}, 34 | {0x08, 0x08}, 35 | {0x09, 0x09}, 36 | {0x0A, 0x0A}, 37 | {0x0B, 0x0B}, 38 | {0x0C, 0x0C}, 39 | {0x0D, 0x0D}, 40 | {0x0E, 0x10FFFF}, 41 | } 42 | 43 | func TestGetters(t *testing.T) { 44 | parts := [][2]string{ 45 | {"Part0", ""}, 46 | {"Part1", "Another part."}, 47 | } 48 | handler := func(p *Parser) { 49 | if len(parts) == 0 { 50 | t.Error("Part handler invoked too many times.") 51 | return 52 | } 53 | want := parts[0] 54 | parts = parts[1:] 55 | if got0, got1 := p.String(0), p.Comment(); got0 != want[0] || got1 != want[1] { 56 | t.Errorf(`part: got %q, %q; want %q"`, got0, got1, want) 57 | } 58 | } 59 | 60 | p := New(strings.NewReader(file), KeepRanges, Part(handler)) 61 | for i := 0; p.Next(); i++ { 62 | start, end := p.Range(0) 63 | w := want[i] 64 | if start != w.start || end != w.end { 65 | t.Fatalf("%d:Range(0); got %#x..%#x; want %#x..%#x", i, start, end, w.start, w.end) 66 | } 67 | if w.start == w.end && p.Rune(0) != w.start { 68 | t.Errorf("%d:Range(0).start: got %U; want %U", i, p.Rune(0), w.start) 69 | } 70 | if got, want := p.Bool(1), w.start <= 9; got != want { 71 | t.Errorf("%d:Bool(1): got %v; want %v", i, got, want) 72 | } 73 | if got := p.Rune(4); got != 0 || p.Err() == nil { 74 | t.Errorf("%d:Rune(%q): got no error; want error", i, p.String(1)) 75 | } 76 | p.err = nil 77 | if got := p.Uint(2); rune(got) != start { 78 | t.Errorf("%d:Uint(2): got %v; want %v", i, got, start) 79 | } 80 | if got, want := p.Int(3), 2-i; got != want { 81 | t.Errorf("%d:Int(3): got %v; want %v", i, got, want) 82 | } 83 | if got, want := p.Float(4), -5.25+float64(i); got != want { 84 | t.Errorf("%d:Int(3): got %v; want %v", i, got, want) 85 | } 86 | if got := p.Runes(5); got == nil { 87 | if p.String(5) != "" { 88 | t.Errorf("%d:Runes(5): expected non-empty list", i) 89 | } 90 | } else { 91 | if got[0] != start || got[len(got)-1] != end { 92 | t.Errorf("%d:Runes(5): got %#x; want %#x..%#x", i, got, start, end) 93 | } 94 | } 95 | if got := p.Comment(); got != "" && got != p.String(1) { 96 | t.Errorf("%d:Comment(): got %v; want %v", i, got, p.String(1)) 97 | } 98 | } 99 | if err := p.Err(); err != nil { 100 | t.Errorf("Parser error: %v", err) 101 | } 102 | if len(parts) != 0 { 103 | t.Errorf("expected %d more invocations of part handler", len(parts)) 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/internal/utf8internal/utf8internal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package utf8internal contains low-level utf8-related constants, tables, etc. 6 | // that are used internally by the text package. 7 | package utf8internal 8 | 9 | // The default lowest and highest continuation byte. 10 | const ( 11 | LoCB = 0x80 // 1000 0000 12 | HiCB = 0xBF // 1011 1111 13 | ) 14 | 15 | // Constants related to getting information of first bytes of UTF-8 sequences. 16 | const ( 17 | // ASCII identifies a UTF-8 byte as ASCII. 18 | ASCII = as 19 | 20 | // FirstInvalid indicates a byte is invalid as a first byte of a UTF-8 21 | // sequence. 22 | FirstInvalid = xx 23 | 24 | // SizeMask is a mask for the size bits. Use use x&SizeMask to get the size. 25 | SizeMask = 7 26 | 27 | // AcceptShift is the right-shift count for the first byte info byte to get 28 | // the index into the AcceptRanges table. See AcceptRanges. 29 | AcceptShift = 4 30 | 31 | // The names of these constants are chosen to give nice alignment in the 32 | // table below. The first nibble is an index into acceptRanges or F for 33 | // special one-byte cases. The second nibble is the Rune length or the 34 | // Status for the special one-byte case. 35 | xx = 0xF1 // invalid: size 1 36 | as = 0xF0 // ASCII: size 1 37 | s1 = 0x02 // accept 0, size 2 38 | s2 = 0x13 // accept 1, size 3 39 | s3 = 0x03 // accept 0, size 3 40 | s4 = 0x23 // accept 2, size 3 41 | s5 = 0x34 // accept 3, size 4 42 | s6 = 0x04 // accept 0, size 4 43 | s7 = 0x44 // accept 4, size 4 44 | ) 45 | 46 | // First is information about the first byte in a UTF-8 sequence. 47 | var First = [256]uint8{ 48 | // 1 2 3 4 5 6 7 8 9 A B C D E F 49 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x00-0x0F 50 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x10-0x1F 51 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x20-0x2F 52 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x30-0x3F 53 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x40-0x4F 54 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x50-0x5F 55 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x60-0x6F 56 | as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x70-0x7F 57 | // 1 2 3 4 5 6 7 8 9 A B C D E F 58 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x80-0x8F 59 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x90-0x9F 60 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xA0-0xAF 61 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xB0-0xBF 62 | xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xC0-0xCF 63 | s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xD0-0xDF 64 | s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, // 0xE0-0xEF 65 | s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF 66 | } 67 | 68 | // AcceptRange gives the range of valid values for the second byte in a UTF-8 69 | // sequence for any value for First that is not ASCII or FirstInvalid. 70 | type AcceptRange struct { 71 | Lo uint8 // lowest value for second byte. 72 | Hi uint8 // highest value for second byte. 73 | } 74 | 75 | // AcceptRanges is a slice of AcceptRange values. For a given byte sequence b 76 | // 77 | // AcceptRanges[First[b[0]]>>AcceptShift] 78 | // 79 | // will give the value of AcceptRange for the multi-byte UTF-8 sequence starting 80 | // at b[0]. 81 | var AcceptRanges = [...]AcceptRange{ 82 | 0: {LoCB, HiCB}, 83 | 1: {0xA0, HiCB}, 84 | 2: {LoCB, 0x9F}, 85 | 3: {0x90, HiCB}, 86 | 4: {LoCB, 0x8F}, 87 | } 88 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/language/coverage_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package language 6 | 7 | import ( 8 | "fmt" 9 | "reflect" 10 | "testing" 11 | 12 | "golang.org/x/text/internal/language" 13 | ) 14 | 15 | func TestSupported(t *testing.T) { 16 | // To prove the results are correct for a type, we test that the number of 17 | // results is identical to the number of results on record, that all results 18 | // are distinct and that all results are valid. 19 | tests := map[string]int{ 20 | "BaseLanguages": language.NumLanguages, 21 | "Scripts": language.NumScripts, 22 | "Regions": language.NumRegions, 23 | "Tags": 0, 24 | } 25 | sup := reflect.ValueOf(Supported) 26 | for name, num := range tests { 27 | v := sup.MethodByName(name).Call(nil)[0] 28 | if n := v.Len(); n != num { 29 | t.Errorf("len(%s()) was %d; want %d", name, n, num) 30 | } 31 | dup := make(map[string]bool) 32 | for i := 0; i < v.Len(); i++ { 33 | x := v.Index(i).Interface() 34 | // An invalid value will either cause a crash or result in a 35 | // duplicate when passed to Sprint. 36 | s := fmt.Sprint(x) 37 | if dup[s] { 38 | t.Errorf("%s: duplicate entry %q", name, s) 39 | } 40 | dup[s] = true 41 | } 42 | if len(dup) != v.Len() { 43 | t.Errorf("%s: # unique entries was %d; want %d", name, len(dup), v.Len()) 44 | } 45 | } 46 | } 47 | 48 | func TestNewCoverage(t *testing.T) { 49 | bases := []Base{Base{0}, Base{3}, Base{7}} 50 | scripts := []Script{Script{11}, Script{17}, Script{23}} 51 | regions := []Region{Region{101}, Region{103}, Region{107}} 52 | tags := []Tag{Make("pt"), Make("en"), Make("en-GB"), Make("en-US"), Make("pt-PT")} 53 | fbases := func() []Base { return bases } 54 | fscripts := func() []Script { return scripts } 55 | fregions := func() []Region { return regions } 56 | ftags := func() []Tag { return tags } 57 | 58 | tests := []struct { 59 | desc string 60 | list []interface{} 61 | bases []Base 62 | scripts []Script 63 | regions []Region 64 | tags []Tag 65 | }{ 66 | { 67 | desc: "empty", 68 | }, 69 | { 70 | desc: "bases", 71 | list: []interface{}{bases}, 72 | bases: bases, 73 | }, 74 | { 75 | desc: "scripts", 76 | list: []interface{}{scripts}, 77 | scripts: scripts, 78 | }, 79 | { 80 | desc: "regions", 81 | list: []interface{}{regions}, 82 | regions: regions, 83 | }, 84 | { 85 | desc: "bases derives from tags", 86 | list: []interface{}{tags}, 87 | bases: []Base{Base{_en}, Base{_pt}}, 88 | tags: tags, 89 | }, 90 | { 91 | desc: "tags and bases", 92 | list: []interface{}{tags, bases}, 93 | bases: bases, 94 | tags: tags, 95 | }, 96 | { 97 | desc: "fully specified", 98 | list: []interface{}{tags, bases, scripts, regions}, 99 | bases: bases, 100 | scripts: scripts, 101 | regions: regions, 102 | tags: tags, 103 | }, 104 | { 105 | desc: "bases func", 106 | list: []interface{}{fbases}, 107 | bases: bases, 108 | }, 109 | { 110 | desc: "scripts func", 111 | list: []interface{}{fscripts}, 112 | scripts: scripts, 113 | }, 114 | { 115 | desc: "regions func", 116 | list: []interface{}{fregions}, 117 | regions: regions, 118 | }, 119 | { 120 | desc: "tags func", 121 | list: []interface{}{ftags}, 122 | bases: []Base{Base{_en}, Base{_pt}}, 123 | tags: tags, 124 | }, 125 | { 126 | desc: "tags and bases", 127 | list: []interface{}{ftags, fbases}, 128 | bases: bases, 129 | tags: tags, 130 | }, 131 | { 132 | desc: "fully specified", 133 | list: []interface{}{ftags, fbases, fscripts, fregions}, 134 | bases: bases, 135 | scripts: scripts, 136 | regions: regions, 137 | tags: tags, 138 | }, 139 | } 140 | 141 | for i, tt := range tests { 142 | l := NewCoverage(tt.list...) 143 | if a := l.BaseLanguages(); !reflect.DeepEqual(a, tt.bases) { 144 | t.Errorf("%d:%s: BaseLanguages was %v; want %v", i, tt.desc, a, tt.bases) 145 | } 146 | if a := l.Scripts(); !reflect.DeepEqual(a, tt.scripts) { 147 | t.Errorf("%d:%s: Scripts was %v; want %v", i, tt.desc, a, tt.scripts) 148 | } 149 | if a := l.Regions(); !reflect.DeepEqual(a, tt.regions) { 150 | t.Errorf("%d:%s: Regions was %v; want %v", i, tt.desc, a, tt.regions) 151 | } 152 | if a := l.Tags(); !reflect.DeepEqual(a, tt.tags) { 153 | t.Errorf("%d:%s: Tags was %v; want %v", i, tt.desc, a, tt.tags) 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/language/go1_1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.2 6 | 7 | package language 8 | 9 | import "sort" 10 | 11 | func sortStable(s sort.Interface) { 12 | ss := stableSort{ 13 | s: s, 14 | pos: make([]int, s.Len()), 15 | } 16 | for i := range ss.pos { 17 | ss.pos[i] = i 18 | } 19 | sort.Sort(&ss) 20 | } 21 | 22 | type stableSort struct { 23 | s sort.Interface 24 | pos []int 25 | } 26 | 27 | func (s *stableSort) Len() int { 28 | return len(s.pos) 29 | } 30 | 31 | func (s *stableSort) Less(i, j int) bool { 32 | return s.s.Less(i, j) || !s.s.Less(j, i) && s.pos[i] < s.pos[j] 33 | } 34 | 35 | func (s *stableSort) Swap(i, j int) { 36 | s.s.Swap(i, j) 37 | s.pos[i], s.pos[j] = s.pos[j], s.pos[i] 38 | } 39 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/language/go1_2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.2 6 | 7 | package language 8 | 9 | import "sort" 10 | 11 | var sortStable = sort.Stable 12 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/language/httpexample_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package language_test 6 | 7 | import ( 8 | "fmt" 9 | "net/http" 10 | "strings" 11 | 12 | "golang.org/x/text/language" 13 | ) 14 | 15 | // matcher is a language.Matcher configured for all supported languages. 16 | var matcher = language.NewMatcher([]language.Tag{ 17 | language.BritishEnglish, 18 | language.Norwegian, 19 | language.German, 20 | }) 21 | 22 | // handler is a http.HandlerFunc. 23 | func handler(w http.ResponseWriter, r *http.Request) { 24 | t, q, err := language.ParseAcceptLanguage(r.Header.Get("Accept-Language")) 25 | // We ignore the error: the default language will be selected for t == nil. 26 | tag, _, _ := matcher.Match(t...) 27 | fmt.Printf("%17v (t: %6v; q: %3v; err: %v)\n", tag, t, q, err) 28 | } 29 | 30 | func ExampleParseAcceptLanguage() { 31 | for _, al := range []string{ 32 | "nn;q=0.3, en-us;q=0.8, en,", 33 | "gsw, en;q=0.7, en-US;q=0.8", 34 | "gsw, nl, da", 35 | "invalid", 36 | } { 37 | // Create dummy request with Accept-Language set and pass it to handler. 38 | r, _ := http.NewRequest("GET", "example.com", strings.NewReader("Hello")) 39 | r.Header.Set("Accept-Language", al) 40 | handler(nil, r) 41 | } 42 | 43 | // Output: 44 | // en-GB (t: [ en en-US nn]; q: [ 1 0.8 0.3]; err: ) 45 | // en-GB-u-rg-uszzzz (t: [ gsw en-US en]; q: [ 1 0.8 0.7]; err: ) 46 | // de (t: [ gsw nl da]; q: [ 1 1 1]; err: ) 47 | // en-GB (t: []; q: []; err: language: tag is not well-formed) 48 | } 49 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/runes/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package runes_test 6 | 7 | import ( 8 | "fmt" 9 | "unicode" 10 | 11 | "golang.org/x/text/runes" 12 | "golang.org/x/text/transform" 13 | "golang.org/x/text/unicode/norm" 14 | "golang.org/x/text/width" 15 | ) 16 | 17 | func ExampleRemove() { 18 | t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC) 19 | s, _, _ := transform.String(t, "résumé") 20 | fmt.Println(s) 21 | 22 | // Output: 23 | // resume 24 | } 25 | 26 | func ExampleMap() { 27 | replaceHyphens := runes.Map(func(r rune) rune { 28 | if unicode.Is(unicode.Hyphen, r) { 29 | return '|' 30 | } 31 | return r 32 | }) 33 | s, _, _ := transform.String(replaceHyphens, "a-b‐c⸗d﹣e") 34 | fmt.Println(s) 35 | 36 | // Output: 37 | // a|b|c|d|e 38 | } 39 | 40 | func ExampleIn() { 41 | // Convert Latin characters to their canonical form, while keeping other 42 | // width distinctions. 43 | t := runes.If(runes.In(unicode.Latin), width.Fold, nil) 44 | s, _, _ := transform.String(t, "アルアノリウ tech / アルアノリウ tech") 45 | fmt.Println(s) 46 | 47 | // Output: 48 | // アルアノリウ tech / アルアノリウ tech 49 | } 50 | 51 | func ExampleIf() { 52 | // Widen everything but ASCII. 53 | isASCII := func(r rune) bool { return r <= unicode.MaxASCII } 54 | t := runes.If(runes.Predicate(isASCII), nil, width.Widen) 55 | s, _, _ := transform.String(t, "アルアノリウ tech / 中國 / 5₩") 56 | fmt.Println(s) 57 | 58 | // Output: 59 | // アルアノリウ tech / 中國 / 5₩ 60 | } 61 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/transform/examples_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package transform_test 6 | 7 | import ( 8 | "fmt" 9 | "unicode" 10 | 11 | "golang.org/x/text/transform" 12 | "golang.org/x/text/unicode/norm" 13 | ) 14 | 15 | func ExampleRemoveFunc() { 16 | input := []byte(`tschüß; до свидания`) 17 | 18 | b := make([]byte, len(input)) 19 | 20 | t := transform.RemoveFunc(unicode.IsSpace) 21 | n, _, _ := t.Transform(b, input, true) 22 | fmt.Println(string(b[:n])) 23 | 24 | t = transform.RemoveFunc(func(r rune) bool { 25 | return !unicode.Is(unicode.Latin, r) 26 | }) 27 | n, _, _ = t.Transform(b, input, true) 28 | fmt.Println(string(b[:n])) 29 | 30 | n, _, _ = t.Transform(b, norm.NFD.Bytes(input), true) 31 | fmt.Println(string(b[:n])) 32 | 33 | // Output: 34 | // tschüß;досвидания 35 | // tschüß 36 | // tschuß 37 | } 38 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/cldr/base.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cldr 6 | 7 | import ( 8 | "encoding/xml" 9 | "regexp" 10 | "strconv" 11 | ) 12 | 13 | // Elem is implemented by every XML element. 14 | type Elem interface { 15 | setEnclosing(Elem) 16 | setName(string) 17 | enclosing() Elem 18 | 19 | GetCommon() *Common 20 | } 21 | 22 | type hidden struct { 23 | CharData string `xml:",chardata"` 24 | Alias *struct { 25 | Common 26 | Source string `xml:"source,attr"` 27 | Path string `xml:"path,attr"` 28 | } `xml:"alias"` 29 | Def *struct { 30 | Common 31 | Choice string `xml:"choice,attr,omitempty"` 32 | Type string `xml:"type,attr,omitempty"` 33 | } `xml:"default"` 34 | } 35 | 36 | // Common holds several of the most common attributes and sub elements 37 | // of an XML element. 38 | type Common struct { 39 | XMLName xml.Name 40 | name string 41 | enclElem Elem 42 | Type string `xml:"type,attr,omitempty"` 43 | Reference string `xml:"reference,attr,omitempty"` 44 | Alt string `xml:"alt,attr,omitempty"` 45 | ValidSubLocales string `xml:"validSubLocales,attr,omitempty"` 46 | Draft string `xml:"draft,attr,omitempty"` 47 | hidden 48 | } 49 | 50 | // Default returns the default type to select from the enclosed list 51 | // or "" if no default value is specified. 52 | func (e *Common) Default() string { 53 | if e.Def == nil { 54 | return "" 55 | } 56 | if e.Def.Choice != "" { 57 | return e.Def.Choice 58 | } else if e.Def.Type != "" { 59 | // Type is still used by the default element in collation. 60 | return e.Def.Type 61 | } 62 | return "" 63 | } 64 | 65 | // Element returns the XML element name. 66 | func (e *Common) Element() string { 67 | return e.name 68 | } 69 | 70 | // GetCommon returns e. It is provided such that Common implements Elem. 71 | func (e *Common) GetCommon() *Common { 72 | return e 73 | } 74 | 75 | // Data returns the character data accumulated for this element. 76 | func (e *Common) Data() string { 77 | e.CharData = charRe.ReplaceAllStringFunc(e.CharData, replaceUnicode) 78 | return e.CharData 79 | } 80 | 81 | func (e *Common) setName(s string) { 82 | e.name = s 83 | } 84 | 85 | func (e *Common) enclosing() Elem { 86 | return e.enclElem 87 | } 88 | 89 | func (e *Common) setEnclosing(en Elem) { 90 | e.enclElem = en 91 | } 92 | 93 | // Escape characters that can be escaped without further escaping the string. 94 | var charRe = regexp.MustCompile(`&#x[0-9a-fA-F]*;|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\[abtnvfr]`) 95 | 96 | // replaceUnicode converts hexadecimal Unicode codepoint notations to a one-rune string. 97 | // It assumes the input string is correctly formatted. 98 | func replaceUnicode(s string) string { 99 | if s[1] == '#' { 100 | r, _ := strconv.ParseInt(s[3:len(s)-1], 16, 32) 101 | return string(r) 102 | } 103 | r, _, _, _ := strconv.UnquoteChar(s, 0) 104 | return string(r) 105 | } 106 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/cldr/cldr_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cldr 6 | 7 | import "testing" 8 | 9 | func TestParseDraft(t *testing.T) { 10 | tests := []struct { 11 | in string 12 | draft Draft 13 | err bool 14 | }{ 15 | {"unconfirmed", Unconfirmed, false}, 16 | {"provisional", Provisional, false}, 17 | {"contributed", Contributed, false}, 18 | {"approved", Approved, false}, 19 | {"", Approved, false}, 20 | {"foo", Approved, true}, 21 | } 22 | for _, tt := range tests { 23 | if d, err := ParseDraft(tt.in); d != tt.draft || (err != nil) != tt.err { 24 | t.Errorf("%q: was %v, %v; want %v, %v", tt.in, d, err != nil, tt.draft, tt.err) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/cldr/examples_test.go: -------------------------------------------------------------------------------- 1 | package cldr_test 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | 8 | "golang.org/x/text/internal/gen" 9 | "golang.org/x/text/unicode/cldr" 10 | ) 11 | 12 | func ExampleDecoder() { 13 | // Obtain the default CLDR reader (only for x/text packages). 14 | 15 | var d cldr.Decoder 16 | 17 | // Speed up decoding by setting filters for only what you need. 18 | d.SetDirFilter("main", "supplemental") 19 | d.SetSectionFilter("numbers", "plurals") 20 | 21 | cldr, err := d.DecodeZip(gen.OpenCLDRCoreZip()) 22 | if err != nil { 23 | fmt.Println("ERROR", err) 24 | return 25 | } 26 | supplemental := cldr.Supplemental() 27 | 28 | fmt.Println(supplemental.MeasurementData.MeasurementSystem[0].Type) 29 | for _, lang := range cldr.Locales() { 30 | data := cldr.RawLDML(lang) 31 | fmt.Println(lang, data.Identity.Version.Number) 32 | } 33 | } 34 | 35 | func ExampleDecoder_DecodePath() { 36 | // This directory will exist if a go generate has been run in any of the 37 | // packages in x/text using the cldr package. 38 | path := filepath.FromSlash("../../DATA/cldr/" + cldr.Version) 39 | 40 | var d cldr.Decoder 41 | 42 | // Speed up decoding by setting filters for only what you need. 43 | d.SetDirFilter("main") 44 | d.SetSectionFilter("numbers") 45 | 46 | cldr, err := d.DecodePath(path) 47 | if err != nil { 48 | // handle error 49 | fmt.Println("ERROR", err) 50 | return 51 | } 52 | for _, lang := range cldr.Locales() { 53 | if numbers := cldr.RawLDML(lang).Numbers; numbers != nil { 54 | fmt.Println(lang, len(numbers.Symbols)) 55 | } 56 | } 57 | } 58 | 59 | func ExampleDecoder_DecodeZip() { 60 | // This directory will exist if a go generate has been run in any of the 61 | // packages in x/text using the cldr package. 62 | path := filepath.FromSlash("../../DATA/cldr/" + cldr.Version) 63 | 64 | var d cldr.Decoder 65 | 66 | r, err := os.Open(filepath.Join(path, "core.zip")) 67 | if err != nil { 68 | fmt.Println("error:", err) 69 | return 70 | } 71 | 72 | // Only loading supplemental data can be done much faster using a dir 73 | // filter. 74 | d.SetDirFilter("supplemental") 75 | cldr, err := d.DecodeZip(r) 76 | if err != nil { 77 | fmt.Println("error:", err) 78 | return 79 | } 80 | 81 | fmt.Println(cldr.Supplemental().MeasurementData.MeasurementSystem[0].Type) 82 | } 83 | 84 | func ExampleSlice() { 85 | var dr *cldr.CLDR // assume this is initialized 86 | 87 | x, _ := dr.LDML("en") 88 | cs := x.Collations.Collation 89 | // remove all but the default 90 | cldr.MakeSlice(&cs).Filter(func(e cldr.Elem) bool { 91 | return e.GetCommon().Type != x.Collations.Default() 92 | }) 93 | for i, c := range cs { 94 | fmt.Println(i, c.Type) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/cldr/slice.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cldr 6 | 7 | import ( 8 | "fmt" 9 | "reflect" 10 | "sort" 11 | ) 12 | 13 | // Slice provides utilities for modifying slices of elements. 14 | // It can be wrapped around any slice of which the element type implements 15 | // interface Elem. 16 | type Slice struct { 17 | ptr reflect.Value 18 | typ reflect.Type 19 | } 20 | 21 | // Value returns the reflect.Value of the underlying slice. 22 | func (s *Slice) Value() reflect.Value { 23 | return s.ptr.Elem() 24 | } 25 | 26 | // MakeSlice wraps a pointer to a slice of Elems. 27 | // It replaces the array pointed to by the slice so that subsequent modifications 28 | // do not alter the data in a CLDR type. 29 | // It panics if an incorrect type is passed. 30 | func MakeSlice(slicePtr interface{}) Slice { 31 | ptr := reflect.ValueOf(slicePtr) 32 | if ptr.Kind() != reflect.Ptr { 33 | panic(fmt.Sprintf("MakeSlice: argument must be pointer to slice, found %v", ptr.Type())) 34 | } 35 | sl := ptr.Elem() 36 | if sl.Kind() != reflect.Slice { 37 | panic(fmt.Sprintf("MakeSlice: argument must point to a slice, found %v", sl.Type())) 38 | } 39 | intf := reflect.TypeOf((*Elem)(nil)).Elem() 40 | if !sl.Type().Elem().Implements(intf) { 41 | panic(fmt.Sprintf("MakeSlice: element type of slice (%v) does not implement Elem", sl.Type().Elem())) 42 | } 43 | nsl := reflect.MakeSlice(sl.Type(), sl.Len(), sl.Len()) 44 | reflect.Copy(nsl, sl) 45 | sl.Set(nsl) 46 | return Slice{ 47 | ptr: ptr, 48 | typ: sl.Type().Elem().Elem(), 49 | } 50 | } 51 | 52 | func (s Slice) indexForAttr(a string) []int { 53 | for i := iter(reflect.Zero(s.typ)); !i.done(); i.next() { 54 | if n, _ := xmlName(i.field()); n == a { 55 | return i.index 56 | } 57 | } 58 | panic(fmt.Sprintf("MakeSlice: no attribute %q for type %v", a, s.typ)) 59 | } 60 | 61 | // Filter filters s to only include elements for which fn returns true. 62 | func (s Slice) Filter(fn func(e Elem) bool) { 63 | k := 0 64 | sl := s.Value() 65 | for i := 0; i < sl.Len(); i++ { 66 | vi := sl.Index(i) 67 | if fn(vi.Interface().(Elem)) { 68 | sl.Index(k).Set(vi) 69 | k++ 70 | } 71 | } 72 | sl.Set(sl.Slice(0, k)) 73 | } 74 | 75 | // Group finds elements in s for which fn returns the same value and groups 76 | // them in a new Slice. 77 | func (s Slice) Group(fn func(e Elem) string) []Slice { 78 | m := make(map[string][]reflect.Value) 79 | sl := s.Value() 80 | for i := 0; i < sl.Len(); i++ { 81 | vi := sl.Index(i) 82 | key := fn(vi.Interface().(Elem)) 83 | m[key] = append(m[key], vi) 84 | } 85 | keys := []string{} 86 | for k, _ := range m { 87 | keys = append(keys, k) 88 | } 89 | sort.Strings(keys) 90 | res := []Slice{} 91 | for _, k := range keys { 92 | nsl := reflect.New(sl.Type()) 93 | nsl.Elem().Set(reflect.Append(nsl.Elem(), m[k]...)) 94 | res = append(res, MakeSlice(nsl.Interface())) 95 | } 96 | return res 97 | } 98 | 99 | // SelectAnyOf filters s to contain only elements for which attr matches 100 | // any of the values. 101 | func (s Slice) SelectAnyOf(attr string, values ...string) { 102 | index := s.indexForAttr(attr) 103 | s.Filter(func(e Elem) bool { 104 | vf := reflect.ValueOf(e).Elem().FieldByIndex(index) 105 | return in(values, vf.String()) 106 | }) 107 | } 108 | 109 | // SelectOnePerGroup filters s to include at most one element e per group of 110 | // elements matching Key(attr), where e has an attribute a that matches any 111 | // the values in v. 112 | // If more than one element in a group matches a value in v preference 113 | // is given to the element that matches the first value in v. 114 | func (s Slice) SelectOnePerGroup(a string, v []string) { 115 | index := s.indexForAttr(a) 116 | grouped := s.Group(func(e Elem) string { return Key(e, a) }) 117 | sl := s.Value() 118 | sl.Set(sl.Slice(0, 0)) 119 | for _, g := range grouped { 120 | e := reflect.Value{} 121 | found := len(v) 122 | gsl := g.Value() 123 | for i := 0; i < gsl.Len(); i++ { 124 | vi := gsl.Index(i).Elem().FieldByIndex(index) 125 | j := 0 126 | for ; j < len(v) && v[j] != vi.String(); j++ { 127 | } 128 | if j < found { 129 | found = j 130 | e = gsl.Index(i) 131 | } 132 | } 133 | if found < len(v) { 134 | sl.Set(reflect.Append(sl, e)) 135 | } 136 | } 137 | } 138 | 139 | // SelectDraft drops all elements from the list with a draft level smaller than d 140 | // and selects the highest draft level of the remaining. 141 | // This method assumes that the input CLDR is canonicalized. 142 | func (s Slice) SelectDraft(d Draft) { 143 | s.SelectOnePerGroup("draft", drafts[len(drafts)-2-int(d):]) 144 | } 145 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/composition_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm 6 | 7 | import "testing" 8 | 9 | // TestCase is used for most tests. 10 | type TestCase struct { 11 | in []rune 12 | out []rune 13 | } 14 | 15 | func runTests(t *testing.T, name string, fm Form, tests []TestCase) { 16 | rb := reorderBuffer{} 17 | rb.init(fm, nil) 18 | for i, test := range tests { 19 | rb.setFlusher(nil, appendFlush) 20 | for j, rune := range test.in { 21 | b := []byte(string(rune)) 22 | src := inputBytes(b) 23 | info := rb.f.info(src, 0) 24 | if j == 0 { 25 | rb.ss.first(info) 26 | } else { 27 | rb.ss.next(info) 28 | } 29 | if rb.insertFlush(src, 0, info) < 0 { 30 | t.Errorf("%s:%d: insert failed for rune %d", name, i, j) 31 | } 32 | } 33 | rb.doFlush() 34 | was := string(rb.out) 35 | want := string(test.out) 36 | if len(was) != len(want) { 37 | t.Errorf("%s:%d: length = %d; want %d", name, i, len(was), len(want)) 38 | } 39 | if was != want { 40 | k, pfx := pidx(was, want) 41 | t.Errorf("%s:%d: \nwas %s%+q; \nwant %s%+q", name, i, pfx, was[k:], pfx, want[k:]) 42 | } 43 | } 44 | } 45 | 46 | func TestFlush(t *testing.T) { 47 | const ( 48 | hello = "Hello " 49 | world = "world!" 50 | ) 51 | buf := make([]byte, maxByteBufferSize) 52 | p := copy(buf, hello) 53 | out := buf[p:] 54 | rb := reorderBuffer{} 55 | rb.initString(NFC, world) 56 | if i := rb.flushCopy(out); i != 0 { 57 | t.Errorf("wrote bytes on flush of empty buffer. (len(out) = %d)", i) 58 | } 59 | 60 | for i := range world { 61 | // No need to set streamSafe values for this test. 62 | rb.insertFlush(rb.src, i, rb.f.info(rb.src, i)) 63 | n := rb.flushCopy(out) 64 | out = out[n:] 65 | p += n 66 | } 67 | 68 | was := buf[:p] 69 | want := hello + world 70 | if string(was) != want { 71 | t.Errorf(`output after flush was "%s"; want "%s"`, string(was), want) 72 | } 73 | if rb.nrune != 0 { 74 | t.Errorf("non-null size of info buffer (rb.nrune == %d)", rb.nrune) 75 | } 76 | if rb.nbyte != 0 { 77 | t.Errorf("non-null size of byte buffer (rb.nbyte == %d)", rb.nbyte) 78 | } 79 | } 80 | 81 | var insertTests = []TestCase{ 82 | {[]rune{'a'}, []rune{'a'}}, 83 | {[]rune{0x300}, []rune{0x300}}, 84 | {[]rune{0x300, 0x316}, []rune{0x316, 0x300}}, // CCC(0x300)==230; CCC(0x316)==220 85 | {[]rune{0x316, 0x300}, []rune{0x316, 0x300}}, 86 | {[]rune{0x41, 0x316, 0x300}, []rune{0x41, 0x316, 0x300}}, 87 | {[]rune{0x41, 0x300, 0x316}, []rune{0x41, 0x316, 0x300}}, 88 | {[]rune{0x300, 0x316, 0x41}, []rune{0x316, 0x300, 0x41}}, 89 | {[]rune{0x41, 0x300, 0x40, 0x316}, []rune{0x41, 0x300, 0x40, 0x316}}, 90 | } 91 | 92 | func TestInsert(t *testing.T) { 93 | runTests(t, "TestInsert", NFD, insertTests) 94 | } 95 | 96 | var decompositionNFDTest = []TestCase{ 97 | {[]rune{0xC0}, []rune{0x41, 0x300}}, 98 | {[]rune{0xAC00}, []rune{0x1100, 0x1161}}, 99 | {[]rune{0x01C4}, []rune{0x01C4}}, 100 | {[]rune{0x320E}, []rune{0x320E}}, 101 | {[]rune("음ẻ과"), []rune{0x110B, 0x1173, 0x11B7, 0x65, 0x309, 0x1100, 0x116A}}, 102 | } 103 | 104 | var decompositionNFKDTest = []TestCase{ 105 | {[]rune{0xC0}, []rune{0x41, 0x300}}, 106 | {[]rune{0xAC00}, []rune{0x1100, 0x1161}}, 107 | {[]rune{0x01C4}, []rune{0x44, 0x5A, 0x030C}}, 108 | {[]rune{0x320E}, []rune{0x28, 0x1100, 0x1161, 0x29}}, 109 | } 110 | 111 | func TestDecomposition(t *testing.T) { 112 | runTests(t, "TestDecompositionNFD", NFD, decompositionNFDTest) 113 | runTests(t, "TestDecompositionNFKD", NFKD, decompositionNFKDTest) 114 | } 115 | 116 | var compositionTest = []TestCase{ 117 | {[]rune{0x41, 0x300}, []rune{0xC0}}, 118 | {[]rune{0x41, 0x316}, []rune{0x41, 0x316}}, 119 | {[]rune{0x41, 0x300, 0x35D}, []rune{0xC0, 0x35D}}, 120 | {[]rune{0x41, 0x316, 0x300}, []rune{0xC0, 0x316}}, 121 | // blocking starter 122 | {[]rune{0x41, 0x316, 0x40, 0x300}, []rune{0x41, 0x316, 0x40, 0x300}}, 123 | {[]rune{0x1100, 0x1161}, []rune{0xAC00}}, 124 | // parenthesized Hangul, alternate between ASCII and Hangul. 125 | {[]rune{0x28, 0x1100, 0x1161, 0x29}, []rune{0x28, 0xAC00, 0x29}}, 126 | } 127 | 128 | func TestComposition(t *testing.T) { 129 | runTests(t, "TestComposition", NFC, compositionTest) 130 | } 131 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/example_iter_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm_test 6 | 7 | import ( 8 | "bytes" 9 | "fmt" 10 | "io" 11 | "unicode/utf8" 12 | 13 | "golang.org/x/text/unicode/norm" 14 | ) 15 | 16 | // EqualSimple uses a norm.Iter to compare two non-normalized 17 | // strings for equivalence. 18 | func EqualSimple(a, b string) bool { 19 | var ia, ib norm.Iter 20 | ia.InitString(norm.NFKD, a) 21 | ib.InitString(norm.NFKD, b) 22 | for !ia.Done() && !ib.Done() { 23 | if !bytes.Equal(ia.Next(), ib.Next()) { 24 | return false 25 | } 26 | } 27 | return ia.Done() && ib.Done() 28 | } 29 | 30 | // FindPrefix finds the longest common prefix of ASCII characters 31 | // of a and b. 32 | func FindPrefix(a, b string) int { 33 | i := 0 34 | for ; i < len(a) && i < len(b) && a[i] < utf8.RuneSelf && a[i] == b[i]; i++ { 35 | } 36 | return i 37 | } 38 | 39 | // EqualOpt is like EqualSimple, but optimizes the special 40 | // case for ASCII characters. 41 | func EqualOpt(a, b string) bool { 42 | n := FindPrefix(a, b) 43 | a, b = a[n:], b[n:] 44 | var ia, ib norm.Iter 45 | ia.InitString(norm.NFKD, a) 46 | ib.InitString(norm.NFKD, b) 47 | for !ia.Done() && !ib.Done() { 48 | if !bytes.Equal(ia.Next(), ib.Next()) { 49 | return false 50 | } 51 | if n := int64(FindPrefix(a[ia.Pos():], b[ib.Pos():])); n != 0 { 52 | ia.Seek(n, io.SeekCurrent) 53 | ib.Seek(n, io.SeekCurrent) 54 | } 55 | } 56 | return ia.Done() && ib.Done() 57 | } 58 | 59 | var compareTests = []struct{ a, b string }{ 60 | {"aaa", "aaa"}, 61 | {"aaa", "aab"}, 62 | {"a\u0300a", "\u00E0a"}, 63 | {"a\u0300\u0320b", "a\u0320\u0300b"}, 64 | {"\u1E0A\u0323", "\x44\u0323\u0307"}, 65 | // A character that decomposes into multiple segments 66 | // spans several iterations. 67 | {"\u3304", "\u30A4\u30CB\u30F3\u30AF\u3099"}, 68 | } 69 | 70 | func ExampleIter() { 71 | for i, t := range compareTests { 72 | r0 := EqualSimple(t.a, t.b) 73 | r1 := EqualOpt(t.a, t.b) 74 | fmt.Printf("%d: %v %v\n", i, r0, r1) 75 | } 76 | // Output: 77 | // 0: true true 78 | // 1: false false 79 | // 2: true true 80 | // 3: true true 81 | // 4: true true 82 | // 5: true true 83 | } 84 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm_test 6 | 7 | import ( 8 | "fmt" 9 | 10 | "golang.org/x/text/unicode/norm" 11 | ) 12 | 13 | func ExampleForm_NextBoundary() { 14 | s := norm.NFD.String("Mêlée") 15 | 16 | for i := 0; i < len(s); { 17 | d := norm.NFC.NextBoundaryInString(s[i:], true) 18 | fmt.Printf("%[1]s: %+[1]q\n", s[i:i+d]) 19 | i += d 20 | } 21 | // Output: 22 | // M: "M" 23 | // ê: "e\u0302" 24 | // l: "l" 25 | // é: "e\u0301" 26 | // e: "e" 27 | } 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/forminfo_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build test 6 | 7 | package norm 8 | 9 | import "testing" 10 | 11 | func TestProperties(t *testing.T) { 12 | var d runeData 13 | CK := [2]string{"C", "K"} 14 | for k, r := 1, rune(0); r < 0x2ffff; r++ { 15 | if k < len(testData) && r == testData[k].r { 16 | d = testData[k] 17 | k++ 18 | } 19 | s := string(r) 20 | for j, p := range []Properties{NFC.PropertiesString(s), NFKC.PropertiesString(s)} { 21 | f := d.f[j] 22 | if p.CCC() != d.ccc { 23 | t.Errorf("%U: ccc(%s): was %d; want %d %X", r, CK[j], p.CCC(), d.ccc, p.index) 24 | } 25 | if p.isYesC() != (f.qc == Yes) { 26 | t.Errorf("%U: YesC(%s): was %v; want %v", r, CK[j], p.isYesC(), f.qc == Yes) 27 | } 28 | if p.combinesBackward() != (f.qc == Maybe) { 29 | t.Errorf("%U: combines backwards(%s): was %v; want %v", r, CK[j], p.combinesBackward(), f.qc == Maybe) 30 | } 31 | if p.nLeadingNonStarters() != d.nLead { 32 | t.Errorf("%U: nLead(%s): was %d; want %d %#v %#v", r, CK[j], p.nLeadingNonStarters(), d.nLead, p, d) 33 | } 34 | if p.nTrailingNonStarters() != d.nTrail { 35 | t.Errorf("%U: nTrail(%s): was %d; want %d %#v %#v", r, CK[j], p.nTrailingNonStarters(), d.nTrail, p, d) 36 | } 37 | if p.combinesForward() != f.combinesForward { 38 | t.Errorf("%U: combines forward(%s): was %v; want %v %#v", r, CK[j], p.combinesForward(), f.combinesForward, p) 39 | } 40 | // Skip Hangul as it is algorithmically computed. 41 | if r >= hangulBase && r < hangulEnd { 42 | continue 43 | } 44 | if p.hasDecomposition() { 45 | if has := f.decomposition != ""; !has { 46 | t.Errorf("%U: hasDecomposition(%s): was %v; want %v", r, CK[j], p.hasDecomposition(), has) 47 | } 48 | if string(p.Decomposition()) != f.decomposition { 49 | t.Errorf("%U: decomp(%s): was %+q; want %+q", r, CK[j], p.Decomposition(), f.decomposition) 50 | } 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/input.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm 6 | 7 | import "unicode/utf8" 8 | 9 | type input struct { 10 | str string 11 | bytes []byte 12 | } 13 | 14 | func inputBytes(str []byte) input { 15 | return input{bytes: str} 16 | } 17 | 18 | func inputString(str string) input { 19 | return input{str: str} 20 | } 21 | 22 | func (in *input) setBytes(str []byte) { 23 | in.str = "" 24 | in.bytes = str 25 | } 26 | 27 | func (in *input) setString(str string) { 28 | in.str = str 29 | in.bytes = nil 30 | } 31 | 32 | func (in *input) _byte(p int) byte { 33 | if in.bytes == nil { 34 | return in.str[p] 35 | } 36 | return in.bytes[p] 37 | } 38 | 39 | func (in *input) skipASCII(p, max int) int { 40 | if in.bytes == nil { 41 | for ; p < max && in.str[p] < utf8.RuneSelf; p++ { 42 | } 43 | } else { 44 | for ; p < max && in.bytes[p] < utf8.RuneSelf; p++ { 45 | } 46 | } 47 | return p 48 | } 49 | 50 | func (in *input) skipContinuationBytes(p int) int { 51 | if in.bytes == nil { 52 | for ; p < len(in.str) && !utf8.RuneStart(in.str[p]); p++ { 53 | } 54 | } else { 55 | for ; p < len(in.bytes) && !utf8.RuneStart(in.bytes[p]); p++ { 56 | } 57 | } 58 | return p 59 | } 60 | 61 | func (in *input) appendSlice(buf []byte, b, e int) []byte { 62 | if in.bytes != nil { 63 | return append(buf, in.bytes[b:e]...) 64 | } 65 | for i := b; i < e; i++ { 66 | buf = append(buf, in.str[i]) 67 | } 68 | return buf 69 | } 70 | 71 | func (in *input) copySlice(buf []byte, b, e int) int { 72 | if in.bytes == nil { 73 | return copy(buf, in.str[b:e]) 74 | } 75 | return copy(buf, in.bytes[b:e]) 76 | } 77 | 78 | func (in *input) charinfoNFC(p int) (uint16, int) { 79 | if in.bytes == nil { 80 | return nfcData.lookupString(in.str[p:]) 81 | } 82 | return nfcData.lookup(in.bytes[p:]) 83 | } 84 | 85 | func (in *input) charinfoNFKC(p int) (uint16, int) { 86 | if in.bytes == nil { 87 | return nfkcData.lookupString(in.str[p:]) 88 | } 89 | return nfkcData.lookup(in.bytes[p:]) 90 | } 91 | 92 | func (in *input) hangul(p int) (r rune) { 93 | var size int 94 | if in.bytes == nil { 95 | if !isHangulString(in.str[p:]) { 96 | return 0 97 | } 98 | r, size = utf8.DecodeRuneInString(in.str[p:]) 99 | } else { 100 | if !isHangul(in.bytes[p:]) { 101 | return 0 102 | } 103 | r, size = utf8.DecodeRune(in.bytes[p:]) 104 | } 105 | if size != hangulUTF8Size { 106 | return 0 107 | } 108 | return r 109 | } 110 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/iter_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm 6 | 7 | import ( 8 | "strings" 9 | "testing" 10 | ) 11 | 12 | func doIterNormString(f Form, s string) []byte { 13 | acc := []byte{} 14 | i := Iter{} 15 | i.InitString(f, s) 16 | for !i.Done() { 17 | acc = append(acc, i.Next()...) 18 | } 19 | return acc 20 | } 21 | 22 | func doIterNorm(f Form, s string) []byte { 23 | acc := []byte{} 24 | i := Iter{} 25 | i.Init(f, []byte(s)) 26 | for !i.Done() { 27 | acc = append(acc, i.Next()...) 28 | } 29 | return acc 30 | } 31 | 32 | func TestIterNext(t *testing.T) { 33 | runNormTests(t, "IterNext", func(f Form, out []byte, s string) []byte { 34 | return doIterNormString(f, string(append(out, s...))) 35 | }) 36 | runNormTests(t, "IterNext", func(f Form, out []byte, s string) []byte { 37 | return doIterNorm(f, string(append(out, s...))) 38 | }) 39 | } 40 | 41 | type SegmentTest struct { 42 | in string 43 | out []string 44 | } 45 | 46 | var segmentTests = []SegmentTest{ 47 | {"\u1E0A\u0323a", []string{"\x44\u0323\u0307", "a", ""}}, 48 | {rep('a', segSize), append(strings.Split(rep('a', segSize), ""), "")}, 49 | {rep('a', segSize+2), append(strings.Split(rep('a', segSize+2), ""), "")}, 50 | {rep('a', segSize) + "\u0300aa", 51 | append(strings.Split(rep('a', segSize-1), ""), "a\u0300", "a", "a", "")}, 52 | 53 | // U+0f73 is NOT treated as a starter as it is a modifier 54 | {"a" + grave(29) + "\u0f73", []string{"a" + grave(29), cgj + "\u0f73"}}, 55 | {"a\u0f73", []string{"a\u0f73"}}, 56 | 57 | // U+ff9e is treated as a non-starter. 58 | // TODO: should we? Note that this will only affect iteration, as whether 59 | // or not we do so does not affect the normalization output and will either 60 | // way result in consistent iteration output. 61 | {"a" + grave(30) + "\uff9e", []string{"a" + grave(30), cgj + "\uff9e"}}, 62 | {"a\uff9e", []string{"a\uff9e"}}, 63 | } 64 | 65 | var segmentTestsK = []SegmentTest{ 66 | {"\u3332", []string{"\u30D5", "\u30A1", "\u30E9", "\u30C3", "\u30C8\u3099", ""}}, 67 | // last segment of multi-segment decomposition needs normalization 68 | {"\u3332\u093C", []string{"\u30D5", "\u30A1", "\u30E9", "\u30C3", "\u30C8\u093C\u3099", ""}}, 69 | {"\u320E", []string{"\x28", "\uAC00", "\x29"}}, 70 | 71 | // last segment should be copied to start of buffer. 72 | {"\ufdfa", []string{"\u0635", "\u0644", "\u0649", " ", "\u0627", "\u0644", "\u0644", "\u0647", " ", "\u0639", "\u0644", "\u064a", "\u0647", " ", "\u0648", "\u0633", "\u0644", "\u0645", ""}}, 73 | {"\ufdfa" + grave(30), []string{"\u0635", "\u0644", "\u0649", " ", "\u0627", "\u0644", "\u0644", "\u0647", " ", "\u0639", "\u0644", "\u064a", "\u0647", " ", "\u0648", "\u0633", "\u0644", "\u0645" + grave(30), ""}}, 74 | {"\uFDFA" + grave(64), []string{"\u0635", "\u0644", "\u0649", " ", "\u0627", "\u0644", "\u0644", "\u0647", " ", "\u0639", "\u0644", "\u064a", "\u0647", " ", "\u0648", "\u0633", "\u0644", "\u0645" + grave(30), cgj + grave(30), cgj + grave(4), ""}}, 75 | 76 | // Hangul and Jamo are grouped together. 77 | {"\uAC00", []string{"\u1100\u1161", ""}}, 78 | {"\uAC01", []string{"\u1100\u1161\u11A8", ""}}, 79 | {"\u1100\u1161", []string{"\u1100\u1161", ""}}, 80 | } 81 | 82 | // Note that, by design, segmentation is equal for composing and decomposing forms. 83 | func TestIterSegmentation(t *testing.T) { 84 | segmentTest(t, "SegmentTestD", NFD, segmentTests) 85 | segmentTest(t, "SegmentTestC", NFC, segmentTests) 86 | segmentTest(t, "SegmentTestKD", NFKD, segmentTestsK) 87 | segmentTest(t, "SegmentTestKC", NFKC, segmentTestsK) 88 | } 89 | 90 | func segmentTest(t *testing.T, name string, f Form, tests []SegmentTest) { 91 | iter := Iter{} 92 | for i, tt := range tests { 93 | iter.InitString(f, tt.in) 94 | for j, seg := range tt.out { 95 | if seg == "" { 96 | if !iter.Done() { 97 | res := string(iter.Next()) 98 | t.Errorf(`%s:%d:%d: expected Done()==true, found segment %+q`, name, i, j, res) 99 | } 100 | continue 101 | } 102 | if iter.Done() { 103 | t.Errorf("%s:%d:%d: Done()==true, want false", name, i, j) 104 | } 105 | seg = f.String(seg) 106 | if res := string(iter.Next()); res != seg { 107 | t.Errorf(`%s:%d:%d" segment was %+q (%d); want %+q (%d)`, name, i, j, pc(res), len(res), pc(seg), len(seg)) 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/readwriter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm 6 | 7 | import "io" 8 | 9 | type normWriter struct { 10 | rb reorderBuffer 11 | w io.Writer 12 | buf []byte 13 | } 14 | 15 | // Write implements the standard write interface. If the last characters are 16 | // not at a normalization boundary, the bytes will be buffered for the next 17 | // write. The remaining bytes will be written on close. 18 | func (w *normWriter) Write(data []byte) (n int, err error) { 19 | // Process data in pieces to keep w.buf size bounded. 20 | const chunk = 4000 21 | 22 | for len(data) > 0 { 23 | // Normalize into w.buf. 24 | m := len(data) 25 | if m > chunk { 26 | m = chunk 27 | } 28 | w.rb.src = inputBytes(data[:m]) 29 | w.rb.nsrc = m 30 | w.buf = doAppend(&w.rb, w.buf, 0) 31 | data = data[m:] 32 | n += m 33 | 34 | // Write out complete prefix, save remainder. 35 | // Note that lastBoundary looks back at most 31 runes. 36 | i := lastBoundary(&w.rb.f, w.buf) 37 | if i == -1 { 38 | i = 0 39 | } 40 | if i > 0 { 41 | if _, err = w.w.Write(w.buf[:i]); err != nil { 42 | break 43 | } 44 | bn := copy(w.buf, w.buf[i:]) 45 | w.buf = w.buf[:bn] 46 | } 47 | } 48 | return n, err 49 | } 50 | 51 | // Close forces data that remains in the buffer to be written. 52 | func (w *normWriter) Close() error { 53 | if len(w.buf) > 0 { 54 | _, err := w.w.Write(w.buf) 55 | if err != nil { 56 | return err 57 | } 58 | } 59 | return nil 60 | } 61 | 62 | // Writer returns a new writer that implements Write(b) 63 | // by writing f(b) to w. The returned writer may use an 64 | // internal buffer to maintain state across Write calls. 65 | // Calling its Close method writes any buffered data to w. 66 | func (f Form) Writer(w io.Writer) io.WriteCloser { 67 | wr := &normWriter{rb: reorderBuffer{}, w: w} 68 | wr.rb.init(f, nil) 69 | return wr 70 | } 71 | 72 | type normReader struct { 73 | rb reorderBuffer 74 | r io.Reader 75 | inbuf []byte 76 | outbuf []byte 77 | bufStart int 78 | lastBoundary int 79 | err error 80 | } 81 | 82 | // Read implements the standard read interface. 83 | func (r *normReader) Read(p []byte) (int, error) { 84 | for { 85 | if r.lastBoundary-r.bufStart > 0 { 86 | n := copy(p, r.outbuf[r.bufStart:r.lastBoundary]) 87 | r.bufStart += n 88 | if r.lastBoundary-r.bufStart > 0 { 89 | return n, nil 90 | } 91 | return n, r.err 92 | } 93 | if r.err != nil { 94 | return 0, r.err 95 | } 96 | outn := copy(r.outbuf, r.outbuf[r.lastBoundary:]) 97 | r.outbuf = r.outbuf[0:outn] 98 | r.bufStart = 0 99 | 100 | n, err := r.r.Read(r.inbuf) 101 | r.rb.src = inputBytes(r.inbuf[0:n]) 102 | r.rb.nsrc, r.err = n, err 103 | if n > 0 { 104 | r.outbuf = doAppend(&r.rb, r.outbuf, 0) 105 | } 106 | if err == io.EOF { 107 | r.lastBoundary = len(r.outbuf) 108 | } else { 109 | r.lastBoundary = lastBoundary(&r.rb.f, r.outbuf) 110 | if r.lastBoundary == -1 { 111 | r.lastBoundary = 0 112 | } 113 | } 114 | } 115 | } 116 | 117 | // Reader returns a new reader that implements Read 118 | // by reading data from r and returning f(data). 119 | func (f Form) Reader(r io.Reader) io.Reader { 120 | const chunk = 4000 121 | buf := make([]byte, chunk) 122 | rr := &normReader{rb: reorderBuffer{}, r: r, inbuf: buf} 123 | rr.rb.init(f, buf) 124 | return rr 125 | } 126 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/readwriter_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm 6 | 7 | import ( 8 | "bytes" 9 | "fmt" 10 | "testing" 11 | ) 12 | 13 | var bufSizes = []int{1, 2, 3, 4, 5, 6, 7, 8, 100, 101, 102, 103, 4000, 4001, 4002, 4003} 14 | 15 | func readFunc(size int) appendFunc { 16 | return func(f Form, out []byte, s string) []byte { 17 | out = append(out, s...) 18 | r := f.Reader(bytes.NewBuffer(out)) 19 | buf := make([]byte, size) 20 | result := []byte{} 21 | for n, err := 0, error(nil); err == nil; { 22 | n, err = r.Read(buf) 23 | result = append(result, buf[:n]...) 24 | } 25 | return result 26 | } 27 | } 28 | 29 | func TestReader(t *testing.T) { 30 | for _, s := range bufSizes { 31 | name := fmt.Sprintf("TestReader%d", s) 32 | runNormTests(t, name, readFunc(s)) 33 | } 34 | } 35 | 36 | func writeFunc(size int) appendFunc { 37 | return func(f Form, out []byte, s string) []byte { 38 | in := append(out, s...) 39 | result := new(bytes.Buffer) 40 | w := f.Writer(result) 41 | buf := make([]byte, size) 42 | for n := 0; len(in) > 0; in = in[n:] { 43 | n = copy(buf, in) 44 | _, _ = w.Write(buf[:n]) 45 | } 46 | w.Close() 47 | return result.Bytes() 48 | } 49 | } 50 | 51 | func TestWriter(t *testing.T) { 52 | for _, s := range bufSizes { 53 | name := fmt.Sprintf("TestWriter%d", s) 54 | runNormTests(t, name, writeFunc(s)) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/transform.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm 6 | 7 | import ( 8 | "unicode/utf8" 9 | 10 | "golang.org/x/text/transform" 11 | ) 12 | 13 | // Reset implements the Reset method of the transform.Transformer interface. 14 | func (Form) Reset() {} 15 | 16 | // Transform implements the Transform method of the transform.Transformer 17 | // interface. It may need to write segments of up to MaxSegmentSize at once. 18 | // Users should either catch ErrShortDst and allow dst to grow or have dst be at 19 | // least of size MaxTransformChunkSize to be guaranteed of progress. 20 | func (f Form) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 21 | // Cap the maximum number of src bytes to check. 22 | b := src 23 | eof := atEOF 24 | if ns := len(dst); ns < len(b) { 25 | err = transform.ErrShortDst 26 | eof = false 27 | b = b[:ns] 28 | } 29 | i, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), eof) 30 | n := copy(dst, b[:i]) 31 | if !ok { 32 | nDst, nSrc, err = f.transform(dst[n:], src[n:], atEOF) 33 | return nDst + n, nSrc + n, err 34 | } 35 | 36 | if err == nil && n < len(src) && !atEOF { 37 | err = transform.ErrShortSrc 38 | } 39 | return n, n, err 40 | } 41 | 42 | func flushTransform(rb *reorderBuffer) bool { 43 | // Write out (must fully fit in dst, or else it is an ErrShortDst). 44 | if len(rb.out) < rb.nrune*utf8.UTFMax { 45 | return false 46 | } 47 | rb.out = rb.out[rb.flushCopy(rb.out):] 48 | return true 49 | } 50 | 51 | var errs = []error{nil, transform.ErrShortDst, transform.ErrShortSrc} 52 | 53 | // transform implements the transform.Transformer interface. It is only called 54 | // when quickSpan does not pass for a given string. 55 | func (f Form) transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { 56 | // TODO: get rid of reorderBuffer. See CL 23460044. 57 | rb := reorderBuffer{} 58 | rb.init(f, src) 59 | for { 60 | // Load segment into reorder buffer. 61 | rb.setFlusher(dst[nDst:], flushTransform) 62 | end := decomposeSegment(&rb, nSrc, atEOF) 63 | if end < 0 { 64 | return nDst, nSrc, errs[-end] 65 | } 66 | nDst = len(dst) - len(rb.out) 67 | nSrc = end 68 | 69 | // Next quickSpan. 70 | end = rb.nsrc 71 | eof := atEOF 72 | if n := nSrc + len(dst) - nDst; n < end { 73 | err = transform.ErrShortDst 74 | end = n 75 | eof = false 76 | } 77 | end, ok := rb.f.quickSpan(rb.src, nSrc, end, eof) 78 | n := copy(dst[nDst:], rb.src.bytes[nSrc:end]) 79 | nSrc += n 80 | nDst += n 81 | if ok { 82 | if err == nil && n < rb.nsrc && !atEOF { 83 | err = transform.ErrShortSrc 84 | } 85 | return nDst, nSrc, err 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/transform_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm 6 | 7 | import ( 8 | "fmt" 9 | "testing" 10 | 11 | "golang.org/x/text/transform" 12 | ) 13 | 14 | func TestTransform(t *testing.T) { 15 | tests := []struct { 16 | f Form 17 | in, out string 18 | eof bool 19 | dstSize int 20 | err error 21 | }{ 22 | {NFC, "ab", "ab", true, 2, nil}, 23 | {NFC, "qx", "qx", true, 2, nil}, 24 | {NFD, "qx", "qx", true, 2, nil}, 25 | {NFC, "", "", true, 1, nil}, 26 | {NFD, "", "", true, 1, nil}, 27 | {NFC, "", "", false, 1, nil}, 28 | {NFD, "", "", false, 1, nil}, 29 | 30 | // Normalized segment does not fit in destination. 31 | {NFD, "ö", "", true, 1, transform.ErrShortDst}, 32 | {NFD, "ö", "", true, 2, transform.ErrShortDst}, 33 | 34 | // As an artifact of the algorithm, only full segments are written. 35 | // This is not strictly required, and some bytes could be written. 36 | // In practice, for Transform to not block, the destination buffer 37 | // should be at least MaxSegmentSize to work anyway and these edge 38 | // conditions will be relatively rare. 39 | {NFC, "ab", "", true, 1, transform.ErrShortDst}, 40 | // This is even true for inert runes. 41 | {NFC, "qx", "", true, 1, transform.ErrShortDst}, 42 | {NFC, "a\u0300abc", "\u00e0a", true, 4, transform.ErrShortDst}, 43 | 44 | // We cannot write a segment if successive runes could still change the result. 45 | {NFD, "ö", "", false, 3, transform.ErrShortSrc}, 46 | {NFC, "a\u0300", "", false, 4, transform.ErrShortSrc}, 47 | {NFD, "a\u0300", "", false, 4, transform.ErrShortSrc}, 48 | {NFC, "ö", "", false, 3, transform.ErrShortSrc}, 49 | 50 | {NFD, "abc", "", false, 1, transform.ErrShortDst}, 51 | {NFC, "abc", "", false, 1, transform.ErrShortDst}, 52 | {NFC, "abc", "a", false, 2, transform.ErrShortDst}, 53 | {NFD, "éfff", "", false, 2, transform.ErrShortDst}, 54 | {NFC, "e\u0301fffff", "\u00e9fff", false, 6, transform.ErrShortDst}, 55 | {NFD, "ééééé", "e\u0301e\u0301e\u0301", false, 15, transform.ErrShortDst}, 56 | 57 | {NFC, "a\u0300", "", true, 1, transform.ErrShortDst}, 58 | // Theoretically could fit, but won't due to simplified checks. 59 | {NFC, "a\u0300", "", true, 2, transform.ErrShortDst}, 60 | {NFC, "a\u0300", "", true, 3, transform.ErrShortDst}, 61 | {NFC, "a\u0300", "\u00e0", true, 4, nil}, 62 | 63 | {NFD, "öa\u0300", "o\u0308", false, 8, transform.ErrShortSrc}, 64 | {NFD, "öa\u0300ö", "o\u0308a\u0300", true, 8, transform.ErrShortDst}, 65 | {NFD, "öa\u0300ö", "o\u0308a\u0300", false, 12, transform.ErrShortSrc}, 66 | 67 | // Illegal input is copied verbatim. 68 | {NFD, "\xbd\xb2=\xbc ", "\xbd\xb2=\xbc ", true, 8, nil}, 69 | } 70 | b := make([]byte, 100) 71 | for i, tt := range tests { 72 | t.Run(fmt.Sprintf("%d:%s", i, tt.in), func(t *testing.T) { 73 | nDst, _, err := tt.f.Transform(b[:tt.dstSize], []byte(tt.in), tt.eof) 74 | out := string(b[:nDst]) 75 | if out != tt.out || err != tt.err { 76 | t.Errorf("was %+q (%v); want %+q (%v)", out, err, tt.out, tt.err) 77 | } 78 | if want := tt.f.String(tt.in)[:nDst]; want != out { 79 | t.Errorf("incorrect normalization: was %+q; want %+q", out, want) 80 | } 81 | }) 82 | } 83 | } 84 | 85 | var transBufSizes = []int{ 86 | MaxTransformChunkSize, 87 | 3 * MaxTransformChunkSize / 2, 88 | 2 * MaxTransformChunkSize, 89 | 3 * MaxTransformChunkSize, 90 | 100 * MaxTransformChunkSize, 91 | } 92 | 93 | func doTransNorm(f Form, buf []byte, b []byte) []byte { 94 | acc := []byte{} 95 | for p := 0; p < len(b); { 96 | nd, ns, _ := f.Transform(buf[:], b[p:], true) 97 | p += ns 98 | acc = append(acc, buf[:nd]...) 99 | } 100 | return acc 101 | } 102 | 103 | func TestTransformNorm(t *testing.T) { 104 | for _, sz := range transBufSizes { 105 | buf := make([]byte, sz) 106 | runNormTests(t, fmt.Sprintf("Transform:%d", sz), func(f Form, out []byte, s string) []byte { 107 | return doTransNorm(f, buf, append(out, s...)) 108 | }) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/trie.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package norm 6 | 7 | type valueRange struct { 8 | value uint16 // header: value:stride 9 | lo, hi byte // header: lo:n 10 | } 11 | 12 | type sparseBlocks struct { 13 | values []valueRange 14 | offset []uint16 15 | } 16 | 17 | var nfcSparse = sparseBlocks{ 18 | values: nfcSparseValues[:], 19 | offset: nfcSparseOffset[:], 20 | } 21 | 22 | var nfkcSparse = sparseBlocks{ 23 | values: nfkcSparseValues[:], 24 | offset: nfkcSparseOffset[:], 25 | } 26 | 27 | var ( 28 | nfcData = newNfcTrie(0) 29 | nfkcData = newNfkcTrie(0) 30 | ) 31 | 32 | // lookupValue determines the type of block n and looks up the value for b. 33 | // For n < t.cutoff, the block is a simple lookup table. Otherwise, the block 34 | // is a list of ranges with an accompanying value. Given a matching range r, 35 | // the value for b is by r.value + (b - r.lo) * stride. 36 | func (t *sparseBlocks) lookup(n uint32, b byte) uint16 { 37 | offset := t.offset[n] 38 | header := t.values[offset] 39 | lo := offset + 1 40 | hi := lo + uint16(header.lo) 41 | for lo < hi { 42 | m := lo + (hi-lo)/2 43 | r := t.values[m] 44 | if r.lo <= b && b <= r.hi { 45 | return r.value + uint16(b-r.lo)*header.value 46 | } 47 | if b < r.lo { 48 | hi = m 49 | } else { 50 | lo = m + 1 51 | } 52 | } 53 | return 0 54 | } 55 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/norm/triegen.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | // Trie table generator. 8 | // Used by make*tables tools to generate a go file with trie data structures 9 | // for mapping UTF-8 to a 16-bit value. All but the last byte in a UTF-8 byte 10 | // sequence are used to lookup offsets in the index table to be used for the 11 | // next byte. The last byte is used to index into a table with 16-bit values. 12 | 13 | package norm 14 | 15 | import ( 16 | "fmt" 17 | "io" 18 | ) 19 | 20 | const maxSparseEntries = 16 21 | 22 | type normCompacter struct { 23 | sparseBlocks [][]uint64 24 | sparseOffset []uint16 25 | sparseCount int 26 | name string 27 | } 28 | 29 | func mostFrequentStride(a []uint64) int { 30 | counts := make(map[int]int) 31 | var v int 32 | for _, x := range a { 33 | if stride := int(x) - v; v != 0 && stride >= 0 { 34 | counts[stride]++ 35 | } 36 | v = int(x) 37 | } 38 | var maxs, maxc int 39 | for stride, cnt := range counts { 40 | if cnt > maxc || (cnt == maxc && stride < maxs) { 41 | maxs, maxc = stride, cnt 42 | } 43 | } 44 | return maxs 45 | } 46 | 47 | func countSparseEntries(a []uint64) int { 48 | stride := mostFrequentStride(a) 49 | var v, count int 50 | for _, tv := range a { 51 | if int(tv)-v != stride { 52 | if tv != 0 { 53 | count++ 54 | } 55 | } 56 | v = int(tv) 57 | } 58 | return count 59 | } 60 | 61 | func (c *normCompacter) Size(v []uint64) (sz int, ok bool) { 62 | if n := countSparseEntries(v); n <= maxSparseEntries { 63 | return (n+1)*4 + 2, true 64 | } 65 | return 0, false 66 | } 67 | 68 | func (c *normCompacter) Store(v []uint64) uint32 { 69 | h := uint32(len(c.sparseOffset)) 70 | c.sparseBlocks = append(c.sparseBlocks, v) 71 | c.sparseOffset = append(c.sparseOffset, uint16(c.sparseCount)) 72 | c.sparseCount += countSparseEntries(v) + 1 73 | return h 74 | } 75 | 76 | func (c *normCompacter) Handler() string { 77 | return c.name + "Sparse.lookup" 78 | } 79 | 80 | func (c *normCompacter) Print(w io.Writer) (retErr error) { 81 | p := func(f string, x ...interface{}) { 82 | if _, err := fmt.Fprintf(w, f, x...); retErr == nil && err != nil { 83 | retErr = err 84 | } 85 | } 86 | 87 | ls := len(c.sparseBlocks) 88 | p("// %sSparseOffset: %d entries, %d bytes\n", c.name, ls, ls*2) 89 | p("var %sSparseOffset = %#v\n\n", c.name, c.sparseOffset) 90 | 91 | ns := c.sparseCount 92 | p("// %sSparseValues: %d entries, %d bytes\n", c.name, ns, ns*4) 93 | p("var %sSparseValues = [%d]valueRange {", c.name, ns) 94 | for i, b := range c.sparseBlocks { 95 | p("\n// Block %#x, offset %#x", i, c.sparseOffset[i]) 96 | var v int 97 | stride := mostFrequentStride(b) 98 | n := countSparseEntries(b) 99 | p("\n{value:%#04x,lo:%#02x},", stride, uint8(n)) 100 | for i, nv := range b { 101 | if int(nv)-v != stride { 102 | if v != 0 { 103 | p(",hi:%#02x},", 0x80+i-1) 104 | } 105 | if nv != 0 { 106 | p("\n{value:%#04x,lo:%#02x", nv, 0x80+i) 107 | } 108 | } 109 | v = int(nv) 110 | } 111 | if v != 0 { 112 | p(",hi:%#02x},", 0x80+len(b)-1) 113 | } 114 | } 115 | p("\n}\n\n") 116 | return 117 | } 118 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/rangetable/gen.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package rangetable 8 | 9 | import ( 10 | "bytes" 11 | "flag" 12 | "fmt" 13 | "io" 14 | "log" 15 | "reflect" 16 | "strings" 17 | "unicode" 18 | 19 | "golang.org/x/text/collate" 20 | "golang.org/x/text/internal/gen" 21 | "golang.org/x/text/internal/ucd" 22 | "golang.org/x/text/language" 23 | "golang.org/x/text/unicode/rangetable" 24 | ) 25 | 26 | var versionList = flag.String("versions", "", 27 | "list of versions for which to generate RangeTables") 28 | 29 | const bootstrapMessage = `No versions specified. 30 | To bootstrap the code generation, run: 31 | go run gen.go --versions=4.1.0,5.0.0,6.0.0,6.1.0,6.2.0,6.3.0,7.0.0 32 | 33 | and ensure that the latest versions are included by checking: 34 | https://www.unicode.org/Public/` 35 | 36 | func getVersions() []string { 37 | if *versionList == "" { 38 | log.Fatal(bootstrapMessage) 39 | } 40 | 41 | c := collate.New(language.Und, collate.Numeric) 42 | versions := strings.Split(*versionList, ",") 43 | c.SortStrings(versions) 44 | 45 | // Ensure that at least the current version is included. 46 | for _, v := range versions { 47 | if v == gen.UnicodeVersion() { 48 | return versions 49 | } 50 | } 51 | 52 | versions = append(versions, gen.UnicodeVersion()) 53 | c.SortStrings(versions) 54 | return versions 55 | } 56 | 57 | func main() { 58 | gen.Init() 59 | 60 | versions := getVersions() 61 | 62 | w := &bytes.Buffer{} 63 | 64 | fmt.Fprintf(w, "//go:generate go run gen.go --versions=%s\n\n", strings.Join(versions, ",")) 65 | fmt.Fprintf(w, "import \"unicode\"\n\n") 66 | 67 | vstr := func(s string) string { return strings.Replace(s, ".", "_", -1) } 68 | 69 | fmt.Fprintf(w, "var assigned = map[string]*unicode.RangeTable{\n") 70 | for _, v := range versions { 71 | fmt.Fprintf(w, "\t%q: assigned%s,\n", v, vstr(v)) 72 | } 73 | fmt.Fprintf(w, "}\n\n") 74 | 75 | var size int 76 | for _, v := range versions { 77 | assigned := []rune{} 78 | 79 | r := gen.Open("https://www.unicode.org/Public/", "", v+"/ucd/UnicodeData.txt") 80 | ucd.Parse(r, func(p *ucd.Parser) { 81 | assigned = append(assigned, p.Rune(0)) 82 | }) 83 | 84 | rt := rangetable.New(assigned...) 85 | sz := int(reflect.TypeOf(unicode.RangeTable{}).Size()) 86 | sz += int(reflect.TypeOf(unicode.Range16{}).Size()) * len(rt.R16) 87 | sz += int(reflect.TypeOf(unicode.Range32{}).Size()) * len(rt.R32) 88 | 89 | fmt.Fprintf(w, "// size %d bytes (%d KiB)\n", sz, sz/1024) 90 | fmt.Fprintf(w, "var assigned%s = ", vstr(v)) 91 | print(w, rt) 92 | 93 | size += sz 94 | } 95 | 96 | fmt.Fprintf(w, "// Total size %d bytes (%d KiB)\n", size, size/1024) 97 | 98 | gen.WriteVersionedGoFile("tables.go", "rangetable", w.Bytes()) 99 | } 100 | 101 | func print(w io.Writer, rt *unicode.RangeTable) { 102 | fmt.Fprintln(w, "&unicode.RangeTable{") 103 | fmt.Fprintln(w, "\tR16: []unicode.Range16{") 104 | for _, r := range rt.R16 { 105 | fmt.Fprintf(w, "\t\t{%#04x, %#04x, %d},\n", r.Lo, r.Hi, r.Stride) 106 | } 107 | fmt.Fprintln(w, "\t},") 108 | fmt.Fprintln(w, "\tR32: []unicode.Range32{") 109 | for _, r := range rt.R32 { 110 | fmt.Fprintf(w, "\t\t{%#08x, %#08x, %d},\n", r.Lo, r.Hi, r.Stride) 111 | } 112 | fmt.Fprintln(w, "\t},") 113 | fmt.Fprintf(w, "\tLatinOffset: %d,\n", rt.LatinOffset) 114 | fmt.Fprintf(w, "}\n\n") 115 | } 116 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/rangetable/rangetable.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package rangetable provides utilities for creating and inspecting 6 | // unicode.RangeTables. 7 | package rangetable 8 | 9 | import ( 10 | "sort" 11 | "unicode" 12 | ) 13 | 14 | // New creates a RangeTable from the given runes, which may contain duplicates. 15 | func New(r ...rune) *unicode.RangeTable { 16 | if len(r) == 0 { 17 | return &unicode.RangeTable{} 18 | } 19 | 20 | sort.Sort(byRune(r)) 21 | 22 | // Remove duplicates. 23 | k := 1 24 | for i := 1; i < len(r); i++ { 25 | if r[k-1] != r[i] { 26 | r[k] = r[i] 27 | k++ 28 | } 29 | } 30 | 31 | var rt unicode.RangeTable 32 | for _, r := range r[:k] { 33 | if r <= 0xFFFF { 34 | rt.R16 = append(rt.R16, unicode.Range16{Lo: uint16(r), Hi: uint16(r), Stride: 1}) 35 | } else { 36 | rt.R32 = append(rt.R32, unicode.Range32{Lo: uint32(r), Hi: uint32(r), Stride: 1}) 37 | } 38 | } 39 | 40 | // Optimize RangeTable. 41 | return Merge(&rt) 42 | } 43 | 44 | type byRune []rune 45 | 46 | func (r byRune) Len() int { return len(r) } 47 | func (r byRune) Swap(i, j int) { r[i], r[j] = r[j], r[i] } 48 | func (r byRune) Less(i, j int) bool { return r[i] < r[j] } 49 | 50 | // Visit visits all runes in the given RangeTable in order, calling fn for each. 51 | func Visit(rt *unicode.RangeTable, fn func(rune)) { 52 | for _, r16 := range rt.R16 { 53 | for r := rune(r16.Lo); r <= rune(r16.Hi); r += rune(r16.Stride) { 54 | fn(r) 55 | } 56 | } 57 | for _, r32 := range rt.R32 { 58 | for r := rune(r32.Lo); r <= rune(r32.Hi); r += rune(r32.Stride) { 59 | fn(r) 60 | } 61 | } 62 | } 63 | 64 | // Assigned returns a RangeTable with all assigned code points for a given 65 | // Unicode version. This includes graphic, format, control, and private-use 66 | // characters. It returns nil if the data for the given version is not 67 | // available. 68 | func Assigned(version string) *unicode.RangeTable { 69 | return assigned[version] 70 | } 71 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/unicode/rangetable/rangetable_test.go: -------------------------------------------------------------------------------- 1 | package rangetable 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | "unicode" 7 | ) 8 | 9 | var ( 10 | empty = &unicode.RangeTable{} 11 | many = &unicode.RangeTable{ 12 | R16: []unicode.Range16{{0, 0xffff, 5}}, 13 | R32: []unicode.Range32{{0x10004, 0x10009, 5}}, 14 | LatinOffset: 0, 15 | } 16 | ) 17 | 18 | func TestVisit(t *testing.T) { 19 | Visit(empty, func(got rune) { 20 | t.Error("call from empty RangeTable") 21 | }) 22 | 23 | var want rune 24 | Visit(many, func(got rune) { 25 | if got != want { 26 | t.Errorf("got %U; want %U", got, want) 27 | } 28 | want += 5 29 | }) 30 | if want -= 5; want != 0x10009 { 31 | t.Errorf("last run was %U; want U+10009", want) 32 | } 33 | } 34 | 35 | func TestNew(t *testing.T) { 36 | for i, rt := range []*unicode.RangeTable{ 37 | empty, 38 | unicode.Co, 39 | unicode.Letter, 40 | unicode.ASCII_Hex_Digit, 41 | many, 42 | maxRuneTable, 43 | } { 44 | var got, want []rune 45 | Visit(rt, func(r rune) { 46 | want = append(want, r) 47 | }) 48 | Visit(New(want...), func(r rune) { 49 | got = append(got, r) 50 | }) 51 | if !reflect.DeepEqual(got, want) { 52 | t.Errorf("%d:\ngot %v;\nwant %v", i, got, want) 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/width/common_test.go: -------------------------------------------------------------------------------- 1 | // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. 2 | 3 | package width 4 | 5 | // This code is shared between the main code generator and the test code. 6 | 7 | import ( 8 | "flag" 9 | "log" 10 | "strconv" 11 | "strings" 12 | 13 | "golang.org/x/text/internal/gen" 14 | "golang.org/x/text/internal/ucd" 15 | ) 16 | 17 | var ( 18 | outputFile = flag.String("out", "tables.go", "output file") 19 | ) 20 | 21 | var typeMap = map[string]elem{ 22 | "A": tagAmbiguous, 23 | "N": tagNeutral, 24 | "Na": tagNarrow, 25 | "W": tagWide, 26 | "F": tagFullwidth, 27 | "H": tagHalfwidth, 28 | } 29 | 30 | // getWidthData calls f for every entry for which it is defined. 31 | // 32 | // f may be called multiple times for the same rune. The last call to f is the 33 | // correct value. f is not called for all runes. The default tag type is 34 | // Neutral. 35 | func getWidthData(f func(r rune, tag elem, alt rune)) { 36 | // Set the default values for Unified Ideographs. In line with Annex 11, 37 | // we encode full ranges instead of the defined runes in Unified_Ideograph. 38 | for _, b := range []struct{ lo, hi rune }{ 39 | {0x4E00, 0x9FFF}, // the CJK Unified Ideographs block, 40 | {0x3400, 0x4DBF}, // the CJK Unified Ideographs Externsion A block, 41 | {0xF900, 0xFAFF}, // the CJK Compatibility Ideographs block, 42 | {0x20000, 0x2FFFF}, // the Supplementary Ideographic Plane, 43 | {0x30000, 0x3FFFF}, // the Tertiary Ideographic Plane, 44 | } { 45 | for r := b.lo; r <= b.hi; r++ { 46 | f(r, tagWide, 0) 47 | } 48 | } 49 | 50 | inverse := map[rune]rune{} 51 | maps := map[string]bool{ 52 | "": true, 53 | "": true, 54 | } 55 | 56 | // We cannot reuse package norm's decomposition, as we need an unexpanded 57 | // decomposition. We make use of the opportunity to verify that the 58 | // decomposition type is as expected. 59 | ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) { 60 | r := p.Rune(0) 61 | s := strings.SplitN(p.String(ucd.DecompMapping), " ", 2) 62 | if !maps[s[0]] { 63 | return 64 | } 65 | x, err := strconv.ParseUint(s[1], 16, 32) 66 | if err != nil { 67 | log.Fatalf("Error parsing rune %q", s[1]) 68 | } 69 | if inverse[r] != 0 || inverse[rune(x)] != 0 { 70 | log.Fatalf("Circular dependency in mapping between %U and %U", r, x) 71 | } 72 | inverse[r] = rune(x) 73 | inverse[rune(x)] = r 74 | }) 75 | 76 | // ; 77 | ucd.Parse(gen.OpenUCDFile("EastAsianWidth.txt"), func(p *ucd.Parser) { 78 | tag, ok := typeMap[p.String(1)] 79 | if !ok { 80 | log.Fatalf("Unknown width type %q", p.String(1)) 81 | } 82 | r := p.Rune(0) 83 | alt, ok := inverse[r] 84 | if tag == tagFullwidth || tag == tagHalfwidth && r != wonSign { 85 | tag |= tagNeedsFold 86 | if !ok { 87 | log.Fatalf("Narrow or wide rune %U has no decomposition", r) 88 | } 89 | } 90 | f(r, tag, alt) 91 | }) 92 | } 93 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/width/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package width_test 6 | 7 | import ( 8 | "fmt" 9 | 10 | "golang.org/x/text/width" 11 | ) 12 | 13 | func ExampleTransformer_fold() { 14 | s := "abヲ₩○¥A" 15 | f := width.Fold.String(s) 16 | fmt.Printf("%U: %s\n", []rune(s), s) 17 | fmt.Printf("%U: %s\n", []rune(f), f) 18 | 19 | // Output: 20 | // [U+0061 U+0062 U+FF66 U+FFE6 U+FFEE U+FFE5 U+FF21]: abヲ₩○¥A 21 | // [U+0061 U+0062 U+30F2 U+20A9 U+25CB U+00A5 U+0041]: abヲ₩○¥A 22 | } 23 | 24 | func ExampleTransformer_widen() { 25 | s := "ab¥ヲ₩○" 26 | w := width.Widen.String(s) 27 | fmt.Printf("%U: %s\n", []rune(s), s) 28 | fmt.Printf("%U: %s\n", []rune(w), w) 29 | 30 | // Output: 31 | // [U+0061 U+0062 U+00A5 U+FF66 U+20A9 U+FFEE]: ab¥ヲ₩○ 32 | // [U+FF41 U+FF42 U+FFE5 U+30F2 U+FFE6 U+25CB]: ab¥ヲ₩○ 33 | } 34 | 35 | func ExampleTransformer_narrow() { 36 | s := "abヲ₩○¥A" 37 | n := width.Narrow.String(s) 38 | fmt.Printf("%U: %s\n", []rune(s), s) 39 | fmt.Printf("%U: %s\n", []rune(n), n) 40 | 41 | // Ambiguous characters with a halfwidth equivalent get mapped as well. 42 | s = "←" 43 | n = width.Narrow.String(s) 44 | fmt.Printf("%U: %s\n", []rune(s), s) 45 | fmt.Printf("%U: %s\n", []rune(n), n) 46 | 47 | // Output: 48 | // [U+0061 U+0062 U+30F2 U+FFE6 U+25CB U+FFE5 U+FF21]: abヲ₩○¥A 49 | // [U+0061 U+0062 U+FF66 U+20A9 U+FFEE U+00A5 U+0041]: abヲ₩○¥A 50 | // [U+2190]: ← 51 | // [U+FFE9]: ← 52 | } 53 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/width/gen.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | // This program generates the trie for width operations. The generated table 8 | // includes width category information as well as the normalization mappings. 9 | package width 10 | 11 | import ( 12 | "bytes" 13 | "fmt" 14 | "io" 15 | "log" 16 | "math" 17 | "unicode/utf8" 18 | 19 | "golang.org/x/text/internal/gen" 20 | "golang.org/x/text/internal/triegen" 21 | ) 22 | 23 | // See gen_common.go for flags. 24 | 25 | func main() { 26 | gen.Init() 27 | genTables() 28 | genTests() 29 | gen.Repackage("gen_trieval.go", "trieval.go", "width") 30 | gen.Repackage("gen_common.go", "common_test.go", "width") 31 | } 32 | 33 | func genTables() { 34 | t := triegen.NewTrie("width") 35 | // fold and inverse mappings. See mapComment for a description of the format 36 | // of each entry. Add dummy value to make an index of 0 mean no mapping. 37 | inverse := [][4]byte{{}} 38 | mapping := map[[4]byte]int{[4]byte{}: 0} 39 | 40 | getWidthData(func(r rune, tag elem, alt rune) { 41 | idx := 0 42 | if alt != 0 { 43 | var buf [4]byte 44 | buf[0] = byte(utf8.EncodeRune(buf[1:], alt)) 45 | s := string(r) 46 | buf[buf[0]] ^= s[len(s)-1] 47 | var ok bool 48 | if idx, ok = mapping[buf]; !ok { 49 | idx = len(mapping) 50 | if idx > math.MaxUint8 { 51 | log.Fatalf("Index %d does not fit in a byte.", idx) 52 | } 53 | mapping[buf] = idx 54 | inverse = append(inverse, buf) 55 | } 56 | } 57 | t.Insert(r, uint64(tag|elem(idx))) 58 | }) 59 | 60 | w := &bytes.Buffer{} 61 | gen.WriteUnicodeVersion(w) 62 | 63 | sz, err := t.Gen(w) 64 | if err != nil { 65 | log.Fatal(err) 66 | } 67 | 68 | sz += writeMappings(w, inverse) 69 | 70 | fmt.Fprintf(w, "// Total table size %d bytes (%dKiB)\n", sz, sz/1024) 71 | 72 | gen.WriteVersionedGoFile(*outputFile, "width", w.Bytes()) 73 | } 74 | 75 | const inverseDataComment = ` 76 | // inverseData contains 4-byte entries of the following format: 77 | // <0 padding> 78 | // The last byte of the UTF-8-encoded rune is xor-ed with the last byte of the 79 | // UTF-8 encoding of the original rune. Mappings often have the following 80 | // pattern: 81 | // A -> A (U+FF21 -> U+0041) 82 | // B -> B (U+FF22 -> U+0042) 83 | // ... 84 | // By xor-ing the last byte the same entry can be shared by many mappings. This 85 | // reduces the total number of distinct entries by about two thirds. 86 | // The resulting entry for the aforementioned mappings is 87 | // { 0x01, 0xE0, 0x00, 0x00 } 88 | // Using this entry to map U+FF21 (UTF-8 [EF BC A1]), we get 89 | // E0 ^ A1 = 41. 90 | // Similarly, for U+FF22 (UTF-8 [EF BC A2]), we get 91 | // E0 ^ A2 = 42. 92 | // Note that because of the xor-ing, the byte sequence stored in the entry is 93 | // not valid UTF-8.` 94 | 95 | func writeMappings(w io.Writer, data [][4]byte) int { 96 | fmt.Fprintln(w, inverseDataComment) 97 | fmt.Fprintf(w, "var inverseData = [%d][4]byte{\n", len(data)) 98 | for _, x := range data { 99 | fmt.Fprintf(w, "{ 0x%02x, 0x%02x, 0x%02x, 0x%02x },\n", x[0], x[1], x[2], x[3]) 100 | } 101 | fmt.Fprintln(w, "}") 102 | return len(data) * 4 103 | } 104 | 105 | func genTests() { 106 | w := &bytes.Buffer{} 107 | fmt.Fprintf(w, "\nvar mapRunes = map[rune]struct{r rune; e elem}{\n") 108 | getWidthData(func(r rune, tag elem, alt rune) { 109 | if alt != 0 { 110 | fmt.Fprintf(w, "\t0x%X: {0x%X, 0x%X},\n", r, alt, tag) 111 | } 112 | }) 113 | fmt.Fprintln(w, "}") 114 | gen.WriteGoFile("runes_test.go", "width", w.Bytes()) 115 | } 116 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/width/gen_common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package width 8 | 9 | // This code is shared between the main code generator and the test code. 10 | 11 | import ( 12 | "flag" 13 | "log" 14 | "strconv" 15 | "strings" 16 | 17 | "golang.org/x/text/internal/gen" 18 | "golang.org/x/text/internal/ucd" 19 | ) 20 | 21 | var ( 22 | outputFile = flag.String("out", "tables.go", "output file") 23 | ) 24 | 25 | var typeMap = map[string]elem{ 26 | "A": tagAmbiguous, 27 | "N": tagNeutral, 28 | "Na": tagNarrow, 29 | "W": tagWide, 30 | "F": tagFullwidth, 31 | "H": tagHalfwidth, 32 | } 33 | 34 | // getWidthData calls f for every entry for which it is defined. 35 | // 36 | // f may be called multiple times for the same rune. The last call to f is the 37 | // correct value. f is not called for all runes. The default tag type is 38 | // Neutral. 39 | func getWidthData(f func(r rune, tag elem, alt rune)) { 40 | // Set the default values for Unified Ideographs. In line with Annex 11, 41 | // we encode full ranges instead of the defined runes in Unified_Ideograph. 42 | for _, b := range []struct{ lo, hi rune }{ 43 | {0x4E00, 0x9FFF}, // the CJK Unified Ideographs block, 44 | {0x3400, 0x4DBF}, // the CJK Unified Ideographs Externsion A block, 45 | {0xF900, 0xFAFF}, // the CJK Compatibility Ideographs block, 46 | {0x20000, 0x2FFFF}, // the Supplementary Ideographic Plane, 47 | {0x30000, 0x3FFFF}, // the Tertiary Ideographic Plane, 48 | } { 49 | for r := b.lo; r <= b.hi; r++ { 50 | f(r, tagWide, 0) 51 | } 52 | } 53 | 54 | inverse := map[rune]rune{} 55 | maps := map[string]bool{ 56 | "": true, 57 | "": true, 58 | } 59 | 60 | // We cannot reuse package norm's decomposition, as we need an unexpanded 61 | // decomposition. We make use of the opportunity to verify that the 62 | // decomposition type is as expected. 63 | ucd.Parse(gen.OpenUCDFile("UnicodeData.txt"), func(p *ucd.Parser) { 64 | r := p.Rune(0) 65 | s := strings.SplitN(p.String(ucd.DecompMapping), " ", 2) 66 | if !maps[s[0]] { 67 | return 68 | } 69 | x, err := strconv.ParseUint(s[1], 16, 32) 70 | if err != nil { 71 | log.Fatalf("Error parsing rune %q", s[1]) 72 | } 73 | if inverse[r] != 0 || inverse[rune(x)] != 0 { 74 | log.Fatalf("Circular dependency in mapping between %U and %U", r, x) 75 | } 76 | inverse[r] = rune(x) 77 | inverse[rune(x)] = r 78 | }) 79 | 80 | // ; 81 | ucd.Parse(gen.OpenUCDFile("EastAsianWidth.txt"), func(p *ucd.Parser) { 82 | tag, ok := typeMap[p.String(1)] 83 | if !ok { 84 | log.Fatalf("Unknown width type %q", p.String(1)) 85 | } 86 | r := p.Rune(0) 87 | alt, ok := inverse[r] 88 | if tag == tagFullwidth || tag == tagHalfwidth && r != wonSign { 89 | tag |= tagNeedsFold 90 | if !ok { 91 | log.Fatalf("Narrow or wide rune %U has no decomposition", r) 92 | } 93 | } 94 | f(r, tag, alt) 95 | }) 96 | } 97 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/width/gen_trieval.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package width 8 | 9 | // elem is an entry of the width trie. The high byte is used to encode the type 10 | // of the rune. The low byte is used to store the index to a mapping entry in 11 | // the inverseData array. 12 | type elem uint16 13 | 14 | const ( 15 | tagNeutral elem = iota << typeShift 16 | tagAmbiguous 17 | tagWide 18 | tagNarrow 19 | tagFullwidth 20 | tagHalfwidth 21 | ) 22 | 23 | const ( 24 | numTypeBits = 3 25 | typeShift = 16 - numTypeBits 26 | 27 | // tagNeedsFold is true for all fullwidth and halfwidth runes except for 28 | // the Won sign U+20A9. 29 | tagNeedsFold = 0x1000 30 | 31 | // The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide 32 | // variant. 33 | wonSign rune = 0x20A9 34 | ) 35 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/width/kind_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=Kind"; DO NOT EDIT. 2 | 3 | package width 4 | 5 | import "strconv" 6 | 7 | const _Kind_name = "NeutralEastAsianAmbiguousEastAsianWideEastAsianNarrowEastAsianFullwidthEastAsianHalfwidth" 8 | 9 | var _Kind_index = [...]uint8{0, 7, 25, 38, 53, 71, 89} 10 | 11 | func (i Kind) String() string { 12 | if i < 0 || i >= Kind(len(_Kind_index)-1) { 13 | return "Kind(" + strconv.FormatInt(int64(i), 10) + ")" 14 | } 15 | return _Kind_name[_Kind_index[i]:_Kind_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/width/tables_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package width 6 | 7 | import ( 8 | "testing" 9 | 10 | "golang.org/x/text/internal/testtext" 11 | ) 12 | 13 | const ( 14 | loSurrogate = 0xD800 15 | hiSurrogate = 0xDFFF 16 | ) 17 | 18 | func TestTables(t *testing.T) { 19 | testtext.SkipIfNotLong(t) 20 | 21 | runes := map[rune]Kind{} 22 | getWidthData(func(r rune, tag elem, _ rune) { 23 | runes[r] = tag.kind() 24 | }) 25 | for r := rune(0); r < 0x10FFFF; r++ { 26 | if loSurrogate <= r && r <= hiSurrogate { 27 | continue 28 | } 29 | p := LookupRune(r) 30 | if got, want := p.Kind(), runes[r]; got != want { 31 | t.Errorf("Kind of %U was %s; want %s.", r, got, want) 32 | } 33 | want, mapped := foldRune(r) 34 | if got := p.Folded(); (got == 0) == mapped || got != 0 && got != want { 35 | t.Errorf("Folded(%U) = %U; want %U", r, got, want) 36 | } 37 | want, mapped = widenRune(r) 38 | if got := p.Wide(); (got == 0) == mapped || got != 0 && got != want { 39 | t.Errorf("Wide(%U) = %U; want %U", r, got, want) 40 | } 41 | want, mapped = narrowRune(r) 42 | if got := p.Narrow(); (got == 0) == mapped || got != 0 && got != want { 43 | t.Errorf("Narrow(%U) = %U; want %U", r, got, want) 44 | } 45 | } 46 | } 47 | 48 | // TestAmbiguous verifies that ambiguous runes with a mapping always map to 49 | // a halfwidth rune. 50 | func TestAmbiguous(t *testing.T) { 51 | for r, m := range mapRunes { 52 | if m.e != tagAmbiguous { 53 | continue 54 | } 55 | if k := mapRunes[m.r].e.kind(); k != EastAsianHalfwidth { 56 | t.Errorf("Rune %U is ambiguous and maps to a rune of type %v", r, k) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /vendor/golang.org/x/text/width/trieval.go: -------------------------------------------------------------------------------- 1 | // Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. 2 | 3 | package width 4 | 5 | // elem is an entry of the width trie. The high byte is used to encode the type 6 | // of the rune. The low byte is used to store the index to a mapping entry in 7 | // the inverseData array. 8 | type elem uint16 9 | 10 | const ( 11 | tagNeutral elem = iota << typeShift 12 | tagAmbiguous 13 | tagWide 14 | tagNarrow 15 | tagFullwidth 16 | tagHalfwidth 17 | ) 18 | 19 | const ( 20 | numTypeBits = 3 21 | typeShift = 16 - numTypeBits 22 | 23 | // tagNeedsFold is true for all fullwidth and halfwidth runes except for 24 | // the Won sign U+20A9. 25 | tagNeedsFold = 0x1000 26 | 27 | // The Korean Won sign is halfwidth, but SHOULD NOT be mapped to a wide 28 | // variant. 29 | wonSign rune = 0x20A9 30 | ) 31 | --------------------------------------------------------------------------------